save/load started

This commit is contained in:
Seth Trowbridge 2025-07-02 07:53:58 -04:00
parent 10ff8fda46
commit 8fde0f73c5
4 changed files with 142 additions and 135 deletions

196
app.js
View File

@ -1,93 +1,123 @@
/** @import DBTypes from "./types.d.ts" */
import DB from "./db.js"; import DB from "./db.js";
// build parts /** @type {DBTypes.Builder} */
const Part = {}; function DBBuilder(params)
function CreatePart(id, name)
{ {
const part = {name, _:{id, time:0, work:[], need:[], make:[]}}; return {
Part[id] = part; list:{},
return part; load(){
} const l = this.list;
await DB(import.meta.resolve('./db_part.csv'), 2, CreatePart); const loader =(id, data)=>l[id] = data;
return DB(import.meta.resolve(params.path), params.cols, (...args)=>{
params.load(loader, ...args);
// then build work });
const Work = []; },
function CreateWork(partId, user, time, data) save(){},
{ };
const part = Part[partId];
const work = {user: user, time, data}
part._.work.push(work);
if(time > part._.time)
{
part._.time = time;
}
Work.push(work);
return work;
}
await DB(import.meta.resolve('./db_work.csv'), 3, CreateWork);
// then build desks
const Desk = {};
/** @type {(need:string[], make:string[])=>[dirtyNeed:string[], dirtyMake:string[], needMax:number, needMin:number]} */
const Range =(need, make)=>
{
const dirtyNeed = [];
const dirtyMake = [];
let makeMin = Infinity;
let needMax = -Infinity;
need.forEach(partId => {
const part = Part[partId];
if(part._.time > needMax) needMax = part._.time;
});
make.forEach(partId => {
const part = Part[partId];
if(part._.time < makeMin) makeMin = part._.time;
if(part._.time < needMax)
{
dirtyMake.push(partId);
}
});
need.forEach(partId => {
const part = Part[partId];
if(part._.time > makeMin)
{
dirtyNeed.push(partId);
}
});
return [dirtyNeed, dirtyMake, needMax, makeMin];
};
/** @typedef {[need:Record<string, number]>, make:string[], mode:"one"|"all", role:string[]} StoredDesk */
/** @type {(id:string, name:string, data:StoredDesk)=>void} */
function CreateDesk(id, name, data, role, need, time, make, mode="one")
{
const need = Object.keys(data[0])
const time = Object.values(data[0]);
const desk = {name, need, time, make, role, _:{id}};
Desk[id] = desk;
need.forEach(partId => Part[partId]._.need.push(desk));
make.forEach(partId => Part[partId]._.make.push(desk));
const check = Range(need, make);
console.log(check);
return desk;
} }
await DB(import.meta.resolve('./db_work.csv'), 3, (id, name, /**@type{StoredDesk}*/data)=>{ const parts = DBBuilder({
path:"./db_part.csv",
const need = Object.keys(data[0]) cols:2,
CreateDesk(id, name, need, data[1], ); load:(commit, id, name)=>commit(id, {name}),
save:(commit, params)=> commit("a", params.name)
}); });
await parts.load();
console.log(parts.list);
console.log(Part);
console.log(Desk); // // build parts
// const Part = {};
// function CreatePart(id, name)
// {
// const part = {name, _:{id, time:0, work:[], need:[], make:[]}};
// Part[id] = part;
// return part;
// }
// await DB(import.meta.resolve('./db_part.csv'), 2, CreatePart);
//
//
// // then build work
// const Work = [];
// function CreateWork(partId, user, time, data)
// {
// const part = Part[partId];
// const work = {user: user, time, data}
// part._.work.push(work);
// if(time > part._.time)
// {
// part._.time = time;
// }
// Work.push(work);
// return work;
// }
// await DB(import.meta.resolve('./db_work.csv'), 3, CreateWork);
//
//
// // then build desks
// const Desk = {};
// /** @type {(need:string[], make:string[])=>[dirtyNeed:string[], dirtyMake:string[], needMax:number, needMin:number]} */
// const Range =(need, make)=>
// {
// const dirtyNeed = [];
// const dirtyMake = [];
//
// let makeMin = Infinity;
// let needMax = -Infinity;
// need.forEach(partId => {
// const part = Part[partId];
// if(part._.time > needMax) needMax = part._.time;
// });
//
// make.forEach(partId => {
// const part = Part[partId];
// if(part._.time < makeMin) makeMin = part._.time;
// if(part._.time < needMax)
// {
// dirtyMake.push(partId);
// }
// });
//
// need.forEach(partId => {
// const part = Part[partId];
// if(part._.time > makeMin)
// {
// dirtyNeed.push(partId);
// }
// });
//
// return [dirtyNeed, dirtyMake, needMax, makeMin];
// };
//
// /** @typedef {[need:Record<string, number]>, make:string[], mode:"one"|"all", role:string[]} StoredDesk */
//
// /** @type {(id:string, name:string, data:StoredDesk)=>void} */
// function CreateDesk(id, name, data, role, need, time, make, mode="one")
// {
// const need = Object.keys(data[0])
// const time = Object.values(data[0]);
// const desk = {name, need, time, make, role, _:{id}};
// Desk[id] = desk;
// need.forEach(partId => Part[partId]._.need.push(desk));
// make.forEach(partId => Part[partId]._.make.push(desk));
//
// const check = Range(need, make);
// console.log(check);
//
// return desk;
// }
//
// await DB(import.meta.resolve('./db_work.csv'), 3, (id, name, /**@type{StoredDesk}*/data)=>{
//
// const need = Object.keys(data[0])
// CreateDesk(id, name, need, data[1], );
// });
//
//
//
// console.log(Part);
// console.log(Desk);

52
db.js
View File

@ -1,4 +1,4 @@
function createCSVScanner(onRow, nonJsonCols) { function createCSVScanner(onRow, cols) {
let buffer = ''; let buffer = '';
return function scanChunk(chunk) { return function scanChunk(chunk) {
@ -6,48 +6,22 @@ function createCSVScanner(onRow, nonJsonCols) {
const lines = buffer.split('\n'); const lines = buffer.split('\n');
buffer = lines.pop(); // Save incomplete line buffer = lines.pop(); // Save incomplete line
if(nonJsonCols !== 0) for (const line of lines)
{ {
for (const line of lines) const fields = [];
{ let start = 0;
const fields = []; let col = 0;
let start = 0; for (let i = 0; i < line.length; i++) {
let commaCount = 0; if (line[i] === ',' && col < cols) {
fields.push(line.slice(start, i));
for (let i = 0; i < line.length; i++) { start = i + 1;
if (line[i] === ',' && commaCount < nonJsonCols) { col++;
fields.push(line.slice(start, i));
start = i + 1;
commaCount++;
}
} }
const jsonStr = line.slice(start);
let jsonData = null;
try {
jsonData = JSON.parse(jsonStr);
} catch (_e) {
console.error('Invalid JSON:', jsonStr);
}
onRow(...fields, jsonData);
} }
fields.push(line.slice(start, line.length-1));
onRow(...fields);
} }
else
{
for (const line of lines)
{
const fields = [];
let start = 0;
for (let i = 0; i < line.length; i++) {
if (line[i] === ',') {
fields.push(line.slice(start, i));
start = i + 1;
}
}
fields.push(line.slice(start, line.length-1))
onRow(...fields);
}
}
}; };
} }

5
deno.json Normal file
View File

@ -0,0 +1,5 @@
{
"compilerOptions": {
"checkJs": true
}
}

24
types.d.ts vendored
View File

@ -1,17 +1,15 @@
export {};
export type Row< export type Row<
L extends number, L extends number,
T extends any[] = [] T extends any[] = []
> = T["length"] extends L ? T : Row<L, [string, ...T]>; > = T["length"] extends L ? T : Row<L, [string, ...T]>;
export type Builder = <Count extends number, Loaded, Sized extends Row<Count>>(params:
declare global { {
namespace DB path:string,
{ cols:Count,
type DB<T, Count extends number>=(path:string, flat:Count, handler:(...args:[...Row<Count>, T])=>void)=>Promise<void> load:(commitLoad:(id:string, data:Loaded)=>Sized, ...args:Sized)=>[id:string, data:Loaded],
} save:(commitSave:(...args:Sized)=>Sized, internal:Loaded) => Sized
} }) => {
list:Record<string, Loaded>,
load:()=>Promise<void>,
save:()=>Promise<void>
}