You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Internal refactor that lays the data-model foundation for user-created doc trees (#8), with an opportunistic attention-store index added while the schema is already being recreated. Deliberately ships no visible change — the doc-list panel looks and behaves identically — but introduces the primitives that #11, #12, #13 will build on, and kills the quadratic scaling in getDocumentAttention before any real data accumulates.
Context
Project is at single-user PoC stage with no external data to preserve. This issue uses the freedom to ship the simplest possible schema change rather than carrying back-fill logic across the version bump. Since onupgradeneeded(v2) is already recreating the attention store, a bySession index is added in the same pass — the cheapest possible moment to fix the existing full-table scan in getDocumentAttention and getLastViewedBlock.
Coexistence over uniformity. Bundled docs keep path-shaped IDs (docs/architecture.md); user-tree docs will get opaque IDs in Doc trees phase 3: import via typed entry and clipboard paste #12. StoredDocument.treeId is the discriminator. The two ID shapes reflect a real asymmetry (filesystem-structured vs. not), not tech debt.
Explicit about. The about tree becomes a real row in IDB, not the hardcoded label in doc-list.ts:154. System trees are distinguished from user trees via kind.
Clean-slate upgrade.onupgradeneeded(v2) drops existing stores and recreates them fresh. No back-fill, no conditional open-path logic. On next open, the bundle reimports everything from scratch.
Attention index in the same schema bump. Add a bySession index on the attention store and rewrite the two query sites to use it. Not a separate issue — folding it in now avoids a follow-up DB_VERSION bump later when there's actual data to worry about preserving.
Changes
store.ts
Bump DB_VERSION 1 → 2.
onupgradeneeded(v2):
Delete the existing documents, blocks, reading_sessions, attention stores if present.
Recreate documents, blocks, reading_sessions with their current schemas.
Recreate attention with a new bySession index on sessionId.
Create new trees object store, keyPath: 'id'.
Seed the canonical about record: { id: 'about', label: 'about', kind: 'system', created: Date.now() }.
Rewrite getDocumentAttention to use the new bySession index:
// before: for each session, getAll() the whole attention store (O(sessions × total_records))// after: for each session, index.getAll(session.id) (O(records for that session))
Rewrite getLastViewedBlock with the same pattern — currently also does a single unscoped getAll() on the attention store (store.ts:334-335).
Also update deleteDocumentData: the cursor-scan over the whole attention store (store.ts:249-257) can become per-session index.getAllKeys(sessionId) + delete. Same asymptotic improvement, same index, same price.
documents.ts
importFromBundle stamps treeId: 'about' on every StoredDocument it creates.
No back-fill logic anywhere (there are no legacy rows).
doc-list.ts
refresh() reads tree records via listTrees() and groups docs by treeId — the about label stops being hardcoded at line 154.
For the one tree that exists right now, output is identical to today.
No change at the call site for the attention query improvements — buildLeaf keeps calling getDocumentAttention(path), the speedup is internal.
Acceptance
Upgrade from v1 → v2 drops and recreates stores; existing data is wiped (expected and acceptable for the single-user PoC).
After upgrade, trees store contains exactly one record: the canonical about entry.
The attention store has a bySession index on sessionId.
getDocumentAttention returns the same results as before, but via the index — no full-store scan inside the session loop.
getLastViewedBlock and deleteDocumentData likewise use the index and no longer scan the whole attention store.
All bundled docs get treeId: 'about' set at import time; no docs have a missing treeId.
Doc-list panel renders identically to pre-refactor — same tree, same labels, same attention stats, same behavior.
Fresh install (no prior IDB) produces the same end state as an upgraded install.
Poll-refresh loop in doc-list.ts no longer reads the full attention store per tick.
Touchpoints
frontend/src/store.ts — schema bump, new trees store, bySession index on attention, CRUD helpers, three query rewrites
Internal refactor that lays the data-model foundation for user-created doc trees (#8), with an opportunistic attention-store index added while the schema is already being recreated. Deliberately ships no visible change — the doc-list panel looks and behaves identically — but introduces the primitives that #11, #12, #13 will build on, and kills the quadratic scaling in
getDocumentAttentionbefore any real data accumulates.Context
Project is at single-user PoC stage with no external data to preserve. This issue uses the freedom to ship the simplest possible schema change rather than carrying back-fill logic across the version bump. Since
onupgradeneeded(v2)is already recreating the attention store, abySessionindex is added in the same pass — the cheapest possible moment to fix the existing full-table scan ingetDocumentAttentionandgetLastViewedBlock.Decisions this issue bakes in
(From the planning discussion on #8.)
docs/architecture.md); user-tree docs will get opaque IDs in Doc trees phase 3: import via typed entry and clipboard paste #12.StoredDocument.treeIdis the discriminator. The two ID shapes reflect a real asymmetry (filesystem-structured vs. not), not tech debt.about. Theabouttree becomes a real row in IDB, not the hardcoded label indoc-list.ts:154. System trees are distinguished from user trees viakind.onupgradeneeded(v2)drops existing stores and recreates them fresh. No back-fill, no conditional open-path logic. On next open, the bundle reimports everything from scratch.bySessionindex on the attention store and rewrite the two query sites to use it. Not a separate issue — folding it in now avoids a follow-upDB_VERSIONbump later when there's actual data to worry about preserving.Changes
store.tsDB_VERSION1 → 2.onupgradeneeded(v2):documents,blocks,reading_sessions,attentionstores if present.documents,blocks,reading_sessionswith their current schemas.attentionwith a newbySessionindex onsessionId.treesobject store,keyPath: 'id'.aboutrecord:{ id: 'about', label: 'about', kind: 'system', created: Date.now() }.StoredDocumentgainstreeId: string(strictly non-optional — no legacy rows exist post-upgrade).StoredTreeinterface:listTrees(),getTree(id),putTree(tree),deleteTree(id).deleteTreeis unused in this issue but needed for Doc trees phase 2: create/rename/delete empty user trees #11.getDocumentAttentionto use the newbySessionindex:getLastViewedBlockwith the same pattern — currently also does a single unscopedgetAll()on the attention store (store.ts:334-335).deleteDocumentData: the cursor-scan over the whole attention store (store.ts:249-257) can become per-sessionindex.getAllKeys(sessionId)+ delete. Same asymptotic improvement, same index, same price.documents.tsimportFromBundlestampstreeId: 'about'on everyStoredDocumentit creates.doc-list.tsrefresh()reads tree records vialistTrees()and groups docs bytreeId— theaboutlabel stops being hardcoded at line 154.buildLeafkeeps callinggetDocumentAttention(path), the speedup is internal.Acceptance
treesstore contains exactly one record: the canonicalaboutentry.attentionstore has abySessionindex onsessionId.getDocumentAttentionreturns the same results as before, but via the index — no full-store scan inside the session loop.getLastViewedBlockanddeleteDocumentDatalikewise use the index and no longer scan the whole attention store.treeId: 'about'set at import time; no docs have a missingtreeId.doc-list.tsno longer reads the full attention store per tick.Touchpoints
frontend/src/store.ts— schema bump, newtreesstore,bySessionindex on attention, CRUD helpers, three query rewritesfrontend/src/documents.ts—importFromBundlestampstreeIdfrontend/src/doc-list.ts—refresh/buildTreeread from the trees storeOut of scope
byDoccomposite index on reading_sessions) — only the attention hot path is in scopeParent: #8