file handles only in service worker

This commit is contained in:
Seth Trowbridge 2025-08-23 08:58:13 -04:00
parent 276e09b2ca
commit 89908827fb
4 changed files with 50 additions and 55 deletions

4
app.js
View File

@ -30,7 +30,7 @@ async function getFolderHandle(dirHandle)
const workingFolder = await dirHandle.getDirectoryHandle("room"); const workingFolder = await dirHandle.getDirectoryHandle("room");
const module = await import("./data/room.js"); const module = await import("./data/room.js");
const rooms = module.default(workingFolder); const rooms = module.default();
button.innerText = "change directory"; button.innerText = "change directory";
listRoom.innerHTML = ""; listRoom.innerHTML = "";
@ -39,7 +39,7 @@ async function getFolderHandle(dirHandle)
const listPass = H("ul"); const listPass = H("ul");
Object.entries(roomData.Pass).forEach(([passID, passData])=>{ Object.entries(roomData.Pass).forEach(([passID, passData])=>{
listPass.appendChild(H("li", {}, listPass.appendChild(H("li", {},
H("button", { onclick(){ passData.load();console.log(roomData);globalThis.ROOM=roomData; } }, passID) H("button", { onclick(){ passData.load();console.log(roomData);globalThis.ROOM=roomData; } }, passData.name)
)) ))
}); });

View File

@ -16,7 +16,7 @@ export default Graph(
}, },
desk: desk:
{ {
d1:["Desk 01", ["dev"], "all", {p1:3}, "p2"] d1:["Desk 01", ["dev"], "one", {p1:3}, "p2"]
}, },
pass:{ pass:{
pass_01:["pass 01"], pass_01:["pass 01"],

View File

@ -1,7 +1,7 @@
/** @import * as TYPES from "./types.ts" */ /** @import * as TYPES from "./types.ts" */
/** @type {TYPES.GraphBuilder} */ /** @type {TYPES.GraphBuilder} */
function Builder({user, role, part, desk, pass}, folderHandle, folderName) function Builder({user, role, part, desk, pass}, folderName)
{ {
// mutate users // mutate users
@ -92,10 +92,9 @@ function Builder({user, role, part, desk, pass}, folderHandle, folderName)
path:passID, path:passID,
async load(){ async load(){
const roomFolder = await folderHandle.getDirectoryHandle(folderName);
const passFolder = await roomFolder.getDirectoryHandle(passID);
Object.entries(PartList).forEach(([partID, partObj])=> // make room for this pass to each part and desk
Object.values(PartList).forEach((partObj)=>
{ {
partObj.pass.set(passObj, {time:0, work:[], make(user, data) partObj.pass.set(passObj, {time:0, work:[], make(user, data)
{ {
@ -105,66 +104,62 @@ function Builder({user, role, part, desk, pass}, folderHandle, folderName)
partObj.need.forEach((arg)=>{Scan(arg, passObj)}); partObj.need.forEach((arg)=>{Scan(arg, passObj)});
}}); }});
}); });
Object.entries(DeskList).forEach(([deskID, deskObj])=> Object.values(DeskList).forEach((deskObj)=>
{ {
deskObj.pass.set(passObj, {need:[], make:[]}); deskObj.pass.set(passObj, {need:[], make:[]});
}); });
for await (const [_, userFile] of passFolder.entries()) // actually load the pass
const userData = Object.entries(UserList);
for(let i=0; i<userData.length; i++)
{ {
if(userFile.name.endsWith(".json")) const [userID, userObject] = userData[i];
try
{ {
const userID = userFile.name.substring(0, userFile.name.length-5); const resp = await fetch(`./room/${folderName}/${passID}/${userID}.json`);
const userObject = UserList[userID]; /** @type {TYPES.UserPassFile} */
try const json = await resp.json();
{
/** @type {Record<string, Array<[time:number, data:string]>>} */ Object.entries(json).forEach(([partID, payload])=>{
const loadedData = await userFile.getFile().then(d=>d.text()).then(t=>JSON.parse(t));
Object.entries(loadedData).forEach(([partID, payload])=>{ let latest = 0;
payload.forEach((condensedWork)=>{
let latest = 0; if(condensedWork[0] > latest)
payload.forEach((condensedWork)=>{
if(condensedWork[0] > latest)
{
latest = condensedWork[0];
}
condensedWork.push(userObject);
});
const passCheck = PartList[partID].pass.get(this);
if(passCheck)
{ {
if(latest > passCheck.time) latest = condensedWork[0];
{
passCheck.time = latest;
}
passCheck.work = /** @type {TYPES.Work[]}*/(payload);
} }
condensedWork[2] = userObject;
});
}) const passCheck = PartList[partID].pass.get(this);
} if(passCheck)
catch (e) {
{ if(latest > passCheck.time)
console.warn(`Couldn't parse user data: ${roomFolder.name} / ${passFolder.name} / ${userFile.name}`, e); {
} passCheck.time = latest;
}
passCheck.work = /** @type {TYPES.Work[]}*/(payload);
}
})
} }
catch(e)
{
console.warn(`No data for user ${userID} on pass ${passID} yet.`)
continue;
}
} }
Object.entries(DeskList).forEach(([deskID, deskObj])=>{ // update the graph
Scan(deskObj, passObj); Object.values(DeskList).forEach((deskObj)=>Scan(deskObj, passObj));
});
this.live = true; this.live = true;
}, },
dump(){ dump(){
Object.entries(PartList).forEach(([partID, partObj])=>{ Object.values(PartList).forEach((partObj)=>partObj.pass.delete(passObj));
partObj.pass.delete(passObj); Object.values(DeskList).forEach((deskObj)=>deskObj.pass.delete(passObj));
});
Object.entries(DeskList).forEach(([deskID, deskObj])=>{
deskObj.pass.delete(passObj);
});
this.live = false; this.live = false;
}, },
live:false live:false
@ -185,10 +180,10 @@ function Builder({user, role, part, desk, pass}, folderHandle, folderName)
/** @type {TYPES.MassDscription} */ /** @type {TYPES.MassDscription} */
export default function Graph(params) export default function Graph(params)
{ {
return (folderHandle)=>{ return ()=>{
Object.entries(params).forEach( ([roomFolderName, roomData])=> Object.entries(params).forEach( ([roomFolderName, roomData])=>
{ {
params[roomFolderName] = Builder(roomData, folderHandle, roomFolderName); params[roomFolderName] = Builder(roomData, roomFolderName);
}); });
return params; return params;
} }

View File

@ -1,7 +1,7 @@
export type User = {name:string, desk:Set<Desk>}; export type User = {name:string, desk:Set<Desk>};
export type Role = {name:string, user:User[]}; export type Role = {name:string, user:User[]};
export type Desk = {name:string, need:Part[], time:number[], make:Part[], pass:Map<Pass, {need:number[], make:number[]}>, mode:string, role:Role[]}; export type Desk = {name:string, need:Part[], time:number[], make:Part[], pass:Map<Pass, {need:number[], make:number[]}>, mode:string, role:Role[]};
export type Work = [user:User, time:number, data:string]; export type Work = [time:number, data:string, user:User];
export type Pass = {name:string, path:string, live:boolean, load:()=>Promise<void>, dump:()=>void}; export type Pass = {name:string, path:string, live:boolean, load:()=>Promise<void>, dump:()=>void};
export type Part = {name:string, pass:Map<Pass, {time:number, work:Work[], make:(user:User, data:string)=>void}>, need:Desk[], make:Desk[]}; export type Part = {name:string, pass:Map<Pass, {time:number, work:Work[], make:(user:User, data:string)=>void}>, need:Desk[], make:Desk[]};
@ -21,7 +21,6 @@ export type GraphBuilder=
desk:Desks, desk:Desks,
pass:Record<string, [name:string]>, pass:Record<string, [name:string]>,
}, },
folderHandle:FileSystemDirectoryHandle,
folderName:string folderName:string
) )
=>{ =>{
@ -36,7 +35,8 @@ export type MassDscription=
( (
params:Record<string, Parameters<GraphBuilder>[0]> params:Record<string, Parameters<GraphBuilder>[0]>
) )
=>(folder:FileSystemDirectoryHandle)=>Record<string, ReturnType<GraphBuilder>> =>()=>Record<string, ReturnType<GraphBuilder>>
export type UserPassFile = Record<string, Array<[time:number, data:string, user?:User]>>
export type Scanner =(desk:Desk, pass:Pass)=>void; export type Scanner =(desk:Desk, pass:Pass)=>void;