/** @import * as TYPES from "./types.ts" */ /** @type {TYPES.GraphBuilder} */ function Builder({user, role, part, desk, pass}, folderHandle, folderName) { // mutate users /** @type {Record} */ //@ts-ignore const UserList = user; for(let userId in user) { const name = user[userId]; UserList[userId] = {name, desk:new Set()}; } // mutate roles /** @type {Record} */ //@ts-ignore const RoleList = role; for(let roleId in role) { const [name, ...userIds] = role[roleId]; RoleList[roleId] = {name, user:userIds.map(uId=>UserList[/**@type{string}*/(uId)])}; } // mutate parts /** @type {Record} */ //@ts-ignore const PartList = part; for(let partId in part) { const name = part[partId]; PartList[partId] = /** @type {TYPES.Part} */({name, need:[], make:[], pass:new Map()}); } // mutate desks /** @type {Record} */ //@ts-ignore const DeskList = desk; for(let deskId in desk) { const [name, roleIDs, mode, needObj, ...makePartIDs] = desk[deskId]; /** @type {TYPES.Part[]}*/ const need =[]; /** @type {number[]}*/ const time =[]; /** @type {TYPES.Desk} */ const deskObj = { name, mode, need, time, make:[], role:[], pass:new Map() }; for(const partId in needObj) { const part = PartList[partId]; need.push(part); part.need.push(deskObj); time.push(needObj[partId]); } deskObj.role = roleIDs.map(roleId=> { const role = RoleList[/**@type{string}*/(roleId)]; role.user.forEach(u =>u.desk.add(deskObj)); return role; }); deskObj.make = makePartIDs.map( partId=> { const part = PartList[/**@type{string}*/(partId)]; part.make.push(deskObj); return part; } ) DeskList[deskId] = deskObj; } // Apply passes /** @type {Record} */ const PassList = {}; for(let passID in pass) { const [passName] = pass[passID]; /** @type {TYPES.Pass} */ PassList[passID] = { name: passName, path:passID, async load(){ const roomFolder = await folderHandle.getDirectoryHandle(folderName); const passFolder = await roomFolder.getDirectoryHandle(passID); for await (const [_, userFile] of passFolder.entries()) { if(userFile.name.endsWith(".json")) { const userID = userFile.name.substring(0, userFile.name.length-5); const userObject = UserList[userID]; try { /** @type {Record>} */ 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)=>{ if(condensedWork[0] > latest) { latest = condensedWork[0]; } condensedWork.push(userObject); }); let passCheck = PartList[partID].pass.get(this); if(!passCheck) { passCheck = {time:0, work:[]} PartList[partID].pass.set(this, passCheck); } if(latest > passCheck.time) { passCheck.time = latest; } passCheck.work = /** @type {TYPES.Work[]}*/(payload) }) } catch (e) { console.warn(`Couldn't parse user data: ${roomFolder.name} / ${passFolder.name} / ${userFile.name}`, e); } } } const selfPass = this; Object.entries(DeskList).forEach(([deskID, deskObj])=>{ Scan(deskObj, selfPass); }); this.live = true; }, dump(){ const selfPass = this; Object.entries(PartList).forEach(([partID, partObj])=>{ partObj.pass.delete(selfPass); }); Object.entries(DeskList).forEach(([deskID, deskObj])=>{ deskObj.pass.delete(selfPass); }); this.live = false; }, live:false }; } return { Desk:DeskList, Part:PartList, User:UserList, Role:RoleList, Pass:PassList }; } /** @type {TYPES.MassDscription} */ export default function Graph(params) { return (folderHandle)=>{ Object.entries(params).forEach( ([roomFolderName, roomData])=> { params[roomFolderName] = Builder(roomData, folderHandle, roomFolderName); }); return params; } } /** @type {TYPES.Scanner} */ const Scan =(desk, pass)=> { const dirtyNeed = []; const dirtyMake = []; let makeMin = Infinity; let needMax = -Infinity; for(let i=0; i needMax) needMax = partPassTime; } for(let i=0; i makeMin) { dirtyNeed.push(i); } } desk.pass.set(pass, [dirtyNeed, dirtyMake]) };