/// /// import { openDB, DBSchema } from "../idb/mod.ts"; import { getLinks } from "../scrapbox-userscript-std/rest.ts"; import { sumOf } from "../deno_std%2Fcollections/mod.ts"; interface LinkSchema extends DBSchema { links: { key: [string, string]; value: { path: [string, string]; id: string; updated: number; image?: string; links: string[]; }; }; } const db = await openDB("multi-key-test", 1, { upgrade: (db) => { db.createObjectStore("links", { keyPath: "path" }); } }); /* const laps: number[] = []; for (const project of ["takker", "villagepump"]) { let followingId: string | undefined; const query = IDBKeyRange.bound([project, ""], [project, []]); while (true) { const result = await getLinks(project, { followingId }); if (!result.ok) break; const pages = result.value.pages; const now = Date.now(); const tx = db.transaction("links", "readwrite"); await Promise.all( result.value.pages.map( ({ title, ...page }) => tx.store.put({ path: [project, title], ...page, }) ) ); await tx.done; laps.push(Date.now() - now); if (!result.value.followingId) { followingId = undefined; break; } followingId = result.value.followingId; } await tx.done; } console.debug(`Opened ${laps.length} transactions in ${sumOf(laps, (v) => v)}ms, ave: ${(sumOf(laps, (v) => v) / laps.length).toFixed(1)}ms, max: ${Math.max(...laps)}ms, min: ${Math.min(...laps)}ms.`); */ const laps: number[] = []; for (const project of ["takker", "villagepump"]) { let followingId: string | undefined; const updatedLinks = new Set(); const query = IDBKeyRange.bound([project, ""], [project, []]); const LinksToDelete = new Set( (await db.getAllKeys("links", query)).map(([,title]) => title) ); while (true) { const result = await getLinks(project, { followingId }); if (!result.ok) break; const pages = result.value.pages; const now = Date.now(); const tx = db.transaction("links", "readwrite"); await Promise.all( result.value.pages.map( async ({ title, ...page }) => { const prev = await tx.store.get([project, title]); if (prev) LinksToDelete.delete(title); if (prev?.updated >= page.updated) return; updatedLinks.add(title); await tx.store.put({ path: [project, title], ...page, }); } ) ); await tx.done; laps.push(Date.now() - now); if (!result.value.followingId) { followingId = undefined; break; } followingId = result.value.followingId; } const tx = db.transaction("links", "readwrite"); await Promise.all( [...LinksToDelete].map( (title) => tx.store.delete([project, title]) ) ); await tx.done; console.debug(`Update ${updatedLinks.size} links and Delete ${LinksToDelete.size} links in "${project}"`); } console.debug(`Opened ${laps.length} transactions in ${sumOf(laps, (v) => v)}ms, ave: ${(sumOf(laps, (v) => v) / laps.length).toFixed(1)}ms, max: ${Math.max(...laps)}ms, min: ${Math.min(...laps)}ms.`); /* const laps: number[] = []; for (const project of ["takker", "villagepump"]) { let followingId: string | undefined; while (true) { const result = await getLinks(project, { followingId }); if (!result.ok) break; const pages = result.value.pages; const now = Date.now(); const tx = db.transaction("links", "readwrite"); await Promise.all( result.value.pages.map( ({ title, ...page }) => tx.store.put({ path: [project, title], ...page, }) ) ); await tx.done; laps.push(Date.now() - now); if (!result.value.followingId) { followingId = undefined; break; } followingId = result.value.followingId; } } console.debug(`Opened ${laps.length} transactions in ${sumOf(laps, (v) => v)}ms, ave: ${(sumOf(laps, (v) => v) / laps.length).toFixed(1)}ms, max: ${Math.max(...laps)}ms, min: ${Math.min(...laps)}ms.`); */