@bitcobblers/wod-wiki-storage 0.44.2159 → 0.45.2166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{chunk-MOGQICXM.mjs → chunk-7ICLFFYU.mjs} +2 -2
  2. package/dist/chunk-7ICLFFYU.mjs.map +1 -0
  3. package/dist/{chunk-IMNG2HY5.mjs → chunk-J6KVDPTL.mjs} +3 -3
  4. package/dist/chunk-J6KVDPTL.mjs.map +1 -0
  5. package/dist/{chunk-JFVXIJJI.mjs → chunk-PJ7GRYOZ.mjs} +8 -8
  6. package/dist/chunk-PJ7GRYOZ.mjs.map +1 -0
  7. package/dist/{chunk-IFLOX2TK.mjs → chunk-UN56ET7P.mjs} +3 -3
  8. package/dist/{chunk-IFLOX2TK.mjs.map → chunk-UN56ET7P.mjs.map} +1 -1
  9. package/dist/idb/index.cjs +1 -1
  10. package/dist/idb/index.cjs.map +1 -1
  11. package/dist/idb/index.d.cts +3 -3
  12. package/dist/idb/index.d.ts +3 -3
  13. package/dist/idb/index.mjs +3 -3
  14. package/dist/index.cjs +6 -6
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -3
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.mjs +5 -5
  19. package/dist/{policy-DRYF6Y8i.d.cts → policy-BBwCBMtp.d.cts} +3 -2
  20. package/dist/{policy-CPscN81J.d.ts → policy-C86TCPSM.d.ts} +3 -2
  21. package/dist/sql/index.cjs +60 -44
  22. package/dist/sql/index.cjs.map +1 -1
  23. package/dist/sql/index.d.cts +3 -3
  24. package/dist/sql/index.d.ts +3 -3
  25. package/dist/sql/index.mjs +64 -48
  26. package/dist/sql/index.mjs.map +1 -1
  27. package/dist/{sync-DG4Z-szj.d.cts → sync-BDu_Q__z.d.cts} +1 -1
  28. package/dist/{sync-Bjj_c1ea.d.ts → sync-BQ0g8ctt.d.ts} +1 -1
  29. package/dist/{wire-DGYxXt3I.d.ts → wire-BO8FM1LJ.d.cts} +17 -8
  30. package/dist/{wire-DGYxXt3I.d.cts → wire-BO8FM1LJ.d.ts} +17 -8
  31. package/package.json +6 -6
  32. package/dist/chunk-IMNG2HY5.mjs.map +0 -1
  33. package/dist/chunk-JFVXIJJI.mjs.map +0 -1
  34. package/dist/chunk-MOGQICXM.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema.ts","../../src/idb/catalog.ts","../../src/membership.ts","../../src/wire.ts","../../src/sql/errors.ts","../../src/validation.ts","../../src/policy.ts","../../src/sql/codec.ts","../../src/sql/sync.ts","../../src/idb/index.ts"],"names":["a","b","validateNoteBlocks","record","def","matchDialectFence","openDB","store","table","toEventRows","toSummaryEventRows","parseDocumentSections","KNOWN_SECTION_WIDGETS","actionableSectionKind","legacy"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Fresh schema shared by browser, SQL and in-memory adapters. */\n\nimport type { StoreName } from './contract';\n\n// DOMAIN_PROJECTION_VERSION lives in ./domain (re-exported by the package\n// index) — deliberately not re-exported here to avoid a star-export\n// ambiguity between ./schema and ./domain.\n\n// V30 adds the browser-local sync journal stores (sync_outbox/sync_state in\n// IndexedDBStorage) to the versioned browser schema. SQL/API StoreDefs are\n// UNCHANGED — the sync tables are layered separately (_wodwiki_sync_*) — so\n// SQL databases at v29 pass the StoreDef equality guard and migrate forward\n// without touching rows (see sql/store.ts initializeStore).\n//\n// V31 adds the `equipment` definition store and the `block_equipment`\n// containment-link store. Both are pure additions (no existing store's\n// keyPath, indexes or row shape changes), so initializeStore migrates v30\n// SQL databases by creating the two tables; every existing row survives.\n//\n// V32 is the user-scope sync cutover: no store/index/row shape changes —\n// the version bump marks the PAYLOAD semantics change (shared user policy,\n// policy-compliant snapshots/bootstraps). On upgrade the IndexedDB adapter\n// atomically converts any legacy full-data outbox: pending deletes and\n// user-scoped clears precede one terminal user snapshot. Legacy wipes\n// preserve peer seed rows and history. Seed-derived puts are omitted;\n// deletion intent still reaches independently converted targets. Old\n// full-data targets are NOT migrated in place by\n// ordinary sync — the CLI converts them into fresh wod-wiki-v32 targets.\nexport const DB_VERSION = 32;\n\n/**\n * Typed field metadata — column type per extracted field path, shared with\n * the API so its SQL DDL derives DOUBLE PRECISION / INTEGER / BOOLEAN /\n * TEXT from this table instead of a hardcoded per-index allowlist.\n *\n * Extraction rule (API side): a primary-key column `k<i>` takes the type of\n * STORE_DEFS store's keyPath[i]; an index column `i_<index>_<part>` takes the\n * type of that index's keyPath[part] here. Anything absent defaults to TEXT.\n * Civil-date strings stay TEXT on purpose (page.date is 'YYYY-MM-DD');\n * instants are epoch-ms numbers (notes.date, createdAt, timestamp).\n */\nexport type StorageColumnType = 'number' | 'text' | 'boolean';\n\nexport const COLUMN_TYPES: Record<StoreName, Record<string, StorageColumnType>> = {\n notes: { date: 'number', createdAt: 'number' },\n page: { createdAt: 'number' }, // page.date is a civil 'YYYY-MM-DD' string → TEXT\n page_notes: { position: 'number', createdAt: 'number' },\n tags: { createdAt: 'number' },\n tag_types: { createdAt: 'number' },\n note_tags: {},\n block_revisions: { version: 'number', savedAt: 'number' },\n sessions: {\n blockVersion: 'number',\n startTime: 'number',\n endTime: 'number',\n duration: 'number',\n roundsCompleted: 'number',\n totalRounds: 'number',\n repsCompleted: 'number',\n completed: 'boolean',\n createdAt: 'number',\n },\n attachments: { createdAt: 'number' },\n events: {\n timestamp: 'number',\n blockVersion: 'number',\n line: 'number',\n sourceStatementId: 'number',\n stackLevel: 'number',\n 'timeSpan.started': 'number',\n 'timeSpan.ended': 'number',\n },\n field_catalog: {},\n field_sources: {},\n field_values: {},\n field_catalog_meta: {},\n efforts: { 'baseAttributes.met': 'number' },\n equipment: {},\n block_index: {\n blockVersion: 'number',\n sourceRevision: 'number',\n from: 'number',\n to: 'number',\n position: 'number',\n createdAt: 'number',\n isStatic: 'boolean',\n },\n block_efforts: { createdAt: 'number', isStatic: 'boolean' },\n block_equipment: { createdAt: 'number', isStatic: 'boolean' },\n meta: {},\n memberships: { createdAt: 'number' },\n};\n\nexport interface IndexDef {\n name: string;\n keyPath: string[];\n unique?: boolean;\n multiEntry?: boolean;\n}\n\nexport interface StoreDef {\n name: StoreName;\n keyPath: string[];\n indexes: IndexDef[];\n /** System stores survive wipe() (identity must not be reset with data). */\n system?: boolean;\n}\n\nexport const STORE_DEFS: StoreDef[] = [\n // 1. notes\n { name: 'notes', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'] },\n { name: 'by-created', keyPath: ['createdAt'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2. page\n { name: 'page', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'], unique: true },\n { name: 'by-slug', keyPath: ['slug'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2b. page_notes (V22)\n { name: 'page_notes', keyPath: ['id'], indexes: [\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-page-note', keyPath: ['pageId', 'noteId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3. tags\n { name: 'tags', keyPath: ['id'], indexes: [\n { name: 'by-label', keyPath: ['label'], unique: true },\n { name: 'by-type', keyPath: ['type'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3a. tag_types (V23)\n { name: 'tag_types', keyPath: ['id'], indexes: [\n { name: 'by-name', keyPath: ['name'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 4. note_tags\n { name: 'note_tags', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-tag', keyPath: ['tagId'] },\n { name: 'by-note-tag', keyPath: ['noteId', 'tagId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n { name: 'block_revisions', keyPath: ['noteId', 'blockId', 'version'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-block', keyPath: ['noteId', 'blockId'] },\n ] },\n // 6. sessions\n { name: 'sessions', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-completed', keyPath: ['createdAt'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-block', keyPath: ['blockId'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-origin', keyPath: ['origin'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 8. attachments\n { name: 'attachments', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-time', keyPath: ['createdAt'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-result', keyPath: ['resultId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 9. events\n { name: 'events', keyPath: ['id'], indexes: [\n { name: 'by-timestamp', keyPath: ['timestamp'] },\n { name: 'by-result-grain', keyPath: ['resultId', 'grain'] },\n { name: 'by-content-grain', keyPath: ['blockContentId', 'grain'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-outputType', keyPath: ['outputType'] },\n { name: 'by-grain', keyPath: ['grain'] },\n { name: 'by-metric-date', keyPath: ['metricDateKeys'], multiEntry: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 10. field catalog\n { name: 'field_catalog', keyPath: ['id'], indexes: [\n { name: 'by-path', keyPath: ['path'] },\n ] },\n { name: 'field_sources', keyPath: ['id'], indexes: [] },\n { name: 'field_values', keyPath: ['key'], indexes: [\n { name: 'by-field', keyPath: ['fieldId'] },\n ] },\n { name: 'field_catalog_meta', keyPath: ['id'], indexes: [] },\n // 11. efforts\n { name: 'efforts', keyPath: ['slug'], indexes: [\n { name: 'by-discipline', keyPath: ['baseAttributes.discipline'] },\n { name: 'by-source', keyPath: ['registrySource'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 11b. equipment (V31) — canonical equipment definitions, keyed by slug\n { name: 'equipment', keyPath: ['slug'], indexes: [\n { name: 'by-source', keyPath: ['registrySource'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 12. block_index\n { name: 'block_index', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-type', keyPath: ['dataType'] },\n { name: 'by-source', keyPath: ['sourceId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 13. block_efforts\n { name: 'block_efforts', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-block', keyPath: ['blockContentId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 13b. block_equipment (V31) — containment links, mirroring block_efforts\n { name: 'block_equipment', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-equipment', keyPath: ['equipmentSlug'] },\n { name: 'by-block', keyPath: ['blockContentId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 14. meta\n { name: 'meta', keyPath: ['key'], indexes: [] },\n // 15. memberships (V25, system — survives wipe; truth lives in\n // localStorage locally, in the SQL table on the API)\n { name: 'memberships', keyPath: ['id'], indexes: [], system: true },\n];\n","/**\n * Local database catalog — enumerate/delete the browser-local IndexedDB\n * databases behind the active-profile selector. The default app database is\n * never created or destroyed here: the catalog only manages the auxiliary\n * (restore/scratch) databases that the database switcher offers.\n *\n * This module deliberately does NOT import the storage adapter: the adapter\n * lives in ./index, which re-exports this catalog, so an import back would\n * close a module cycle. Creating a database (which needs the adapter's\n * schema upgrade path) therefore lives beside the adapter in ./index.\n */\n\nexport interface LocalDatabaseInfo { name: string; version: number | null }\n\n/** Canonical app-database name (\"wodwiki-db\"). Defined HERE, not imported\n * from ./index, because the re-export cycle would read it before index.ts\n * initialized it (index.ts: export const IDB_DB_NAME = DEFAULT_LOCAL_DATABASE_NAME). */\nexport const DEFAULT_LOCAL_DATABASE_NAME: string = 'wodwiki-db';\n\n/** Same rule as the app-side isValidLocalDbName — one name vocabulary\n * everywhere (restore, catalog, settings persistence). */\nexport function isValidLocalDatabaseName(name: unknown): name is string {\n return typeof name === 'string' && /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(name);\n}\n\n/** Native enumeration when the browser exposes it; [] otherwise (old\n * Safari/Firefox lack databases()) — never throws. */\nexport async function listLocalDatabases(): Promise<LocalDatabaseInfo[]> {\n const idb = globalThis.indexedDB;\n if (!idb || typeof idb.databases !== 'function') return [];\n const entries = await idb.databases().catch(() => [] as IDBDatabaseInfo[]);\n return entries.flatMap((entry) =>\n typeof entry.name === 'string'\n ? [{ name: entry.name, version: typeof entry.version === 'number' ? entry.version : null }]\n : [],\n );\n}\n\n/** Delete one named database only; a blocked delete resolves (an open\n * connection elsewhere wins — the scratch data is disposable). */\nexport async function deleteLocalDatabase(name: string): Promise<void> {\n if (!isValidLocalDatabaseName(name)) throw new Error(`Invalid local database name \"${String(name)}\".`);\n const idb = globalThis.indexedDB;\n if (!idb) return;\n await new Promise<void>((resolve, reject) => {\n const request = idb.deleteDatabase(name);\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error ?? new Error(`Failed to delete local database \"${name}\".`));\n request.onblocked = () => resolve();\n });\n}\n","/**\n * membership.ts — identity contract shared by both backends.\n *\n * The single local membership (id 'default') is the owner of every\n * user-created record: adapters stamp `userId` onto rows on write (see\n * stampUserOwned), and the by-user index in STORE_DEFS is the ownership\n * crosswalk per store. Seed rows (seedOrigin === 'seed') stay unowned —\n * they are bundled content, not user data.\n */\n\nimport type { StoreName } from './contract';\nimport type { Membership } from './entities';\n\nexport const DEFAULT_MEMBERSHIP_ID = 'default';\n\nexport function createDefaultMembership(now: number = Date.now()): Membership {\n return { id: DEFAULT_MEMBERSHIP_ID, displayName: 'Anonymous', createdAt: now };\n}\n\n/** Stores that can hold user-created rows. Excluded: the pure seed catalog\n * (field_*), meta, and memberships itself. The by-user index in STORE_DEFS\n * mirrors this list — keep in lockstep. */\nexport const USER_OWNED_STORES: readonly StoreName[] = [\n 'notes', 'page', 'page_notes', 'tags', 'tag_types', 'note_tags',\n 'sessions', 'attachments', 'events',\n 'efforts', 'block_index', 'block_efforts',\n 'equipment', 'block_equipment',\n];\n\nconst STAMPABLE: Record<string, true> = Object.fromEntries(\n USER_OWNED_STORES.map((s) => [s, true as const])\n);\n\n/** Stamps `userId` onto a user-owned row. Seed rows pass through untouched;\n * already-stamped rows are returned as-is (no churn on re-put). Values in\n * non-user-owned stores are returned unchanged. */\nexport function stampUserOwned(store: StoreName, value: unknown, userId: string): unknown {\n if (!STAMPABLE[store]) return value;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n const row = value as Record<string, unknown>;\n if (row.seedOrigin === 'seed') return value;\n if (row.userId === userId) return value;\n return { ...row, userId };\n}\n","/**\n * Wire DTOs + key helpers shared by the storage client (ApiStorage) and the\n * API server. Keys are scalars or scalar tuples (keyPath order); ranges bound\n * them. Over HTTP, keys/ranges travel as urlencoded JSON query params.\n *\n * Range-typed helpers accept real IDBKeyRange instances AND plain RangeDTO\n * literals — non-IDB runtimes (Bun, node, tests) have no IDBKeyRange global,\n * so everything duck-types on field shape.\n */\n\nimport type { StoreName } from './contract';\nimport type { StoreDef } from './schema';\n\nexport type Scalar = string | number;\n\n/** Primary key: scalar for single-property keyPaths, tuple for compound. */\nexport type KeyDTO = Scalar | Scalar[];\n\nexport interface RangeDTO {\n only?: KeyDTO;\n /** Inclusive lower bound unless lowerOpen. Scalar or tuple (keyPath order). */\n lower?: KeyDTO;\n /** Inclusive upper bound unless upperOpen. Scalar or tuple (keyPath order). */\n upper?: KeyDTO;\n lowerOpen?: boolean;\n upperOpen?: boolean;\n}\n\nexport type TxOp =\n | { op: 'check'; store: StoreName; key: KeyDTO; value: unknown | null }\n | { op: 'put'; store: StoreName; value: unknown }\n | { op: 'delete'; store: StoreName; key: KeyDTO }\n | { op: 'clear'; store: StoreName };\n\n/** Anything shaped like a range: real IDBKeyRange or a plain RangeDTO literal. */\nexport function isRange(arg: unknown): arg is RangeDTO {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) &&\n ('only' in arg || 'lower' in arg || 'upper' in arg || 'lowerOpen' in arg || 'upperOpen' in arg);\n}\n\n/** Reads one dotted property path ('a.b.c') off a row. */\nexport function extractKeyPart(value: unknown, dottedPath: string): Scalar | undefined {\n let cur: unknown = value;\n for (const part of dottedPath.split('.')) {\n if (cur === null || typeof cur !== 'object') return undefined;\n // Dynamic key on an untyped row: index-signature view is the only way to read it.\n const row = cur as Record<string, unknown>;\n if (!(part in row)) return undefined;\n cur = row[part];\n }\n if (cur === null || typeof cur === 'object' || cur === undefined) return undefined;\n return cur as Scalar; // string/number/boolean leaf narrowed to the wire subset\n}\n\n/** Extracts a row's primary key per the store's inline keyPath. */\nexport function keyFromValue(def: StoreDef, value: unknown): KeyDTO {\n const parts = def.keyPath.map((p) => extractKeyPart(value, p));\n for (const [i, part] of parts.entries()) {\n if (part === undefined) {\n throw new Error(`keyFromValue(${def.name}): keyPath part '${def.keyPath[i]}' missing on value`);\n }\n }\n // Loop above proved every element defined.\n const key = parts as Scalar[];\n return key.length === 1 ? key[0] : key;\n}\n\n/** Canonical url-safe string form of a key (also the buffer/tx match key). */\nexport function encodeKey(key: KeyDTO): string {\n return encodeURIComponent(JSON.stringify(key));\n}\n\n/**\n * Converts an IndexedDB query — bare key, IDBKeyRange, or an already-wire\n * RangeDTO — to its wire form. Duck-types: objects with lower/upper/\n * lowerOpen/upperOpen fields (real ranges or plain literals) pass through;\n * scalars and tuple arrays become {only}.\n */\nexport function rangeFromIDB(query?: IDBValidKey | IDBKeyRange | RangeDTO): RangeDTO | undefined {\n if (query === undefined) return undefined;\n if (!isRange(query)) {\n // Bare IDBValidKey (scalar/tuple; exotic keys like Date pass through lossy).\n const key = query as KeyDTO;\n return { only: key };\n }\n if (query.only !== undefined) return query;\n const wire: RangeDTO = {};\n if (query.lower !== undefined && query.lower !== null) {\n wire.lower = query.lower;\n wire.lowerOpen = query.lowerOpen === true;\n }\n if (query.upper !== undefined && query.upper !== null) {\n // IDB upper bound idiom [prefix, []] uses [] > strings; normalize [] to \\uffff on wire.\n wire.upper = Array.isArray(query.upper)\n ? (query.upper.map((p) => (Array.isArray(p) && p.length === 0 ? '\\uffff' : p)) as KeyDTO)\n : query.upper;\n wire.upperOpen = query.upperOpen === true;\n }\n return wire.lower !== undefined || wire.upper !== undefined ? wire : undefined;\n}\n\n/** IndexedDB key ordering: numbers < strings < tuples; tuples lexicographic. */\nexport function compareKeys(a: KeyDTO, b: KeyDTO): number {\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return Array.isArray(a) ? 1 : -1;\n for (let i = 0; i < Math.min(a.length, b.length); i++) {\n const c = compareKeys(a[i], b[i]);\n if (c !== 0) return c;\n }\n return a.length - b.length;\n }\n if (typeof a === 'number' && typeof b === 'number') {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n if (typeof a === 'number' || typeof b === 'number') return typeof a === 'number' ? -1 : 1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** True when a key matches a wire range (IDB bound semantics). */\nexport function keyInRange(key: KeyDTO, range: RangeDTO): boolean {\n if (range.only !== undefined) return compareKeys(key, range.only) === 0;\n if (range.lower !== undefined) {\n const c = compareKeys(key, range.lower);\n if (c < 0 || (c === 0 && range.lowerOpen === true)) return false;\n }\n if (range.upper !== undefined) {\n const c = compareKeys(key, range.upper);\n if (c > 0 || (c === 0 && range.upperOpen === true)) return false;\n }\n return true;\n}\n","/**\n * StorageError — the single error type every shared SQL layer throws.\n * Replaces the API server's HTTP-specific error: `status` keeps the wire\n * mapping for the HTTP surface, `code` carries a stable machine identifier\n * (e.g. 'domain_projection_unavailable') for browser callers.\n */\nexport class StorageError extends Error {\n constructor(readonly status: number, message: string, readonly code?: string) {\n super(message);\n this.name = 'StorageError';\n }\n}\n","import { validateNoteBlocks, type BlockRevision, type Note, type Session } from '@bitcobblers/wod-wiki-core';\nimport type { StoreName } from './contract';\nimport { StorageError } from './sql/errors';\n\nexport function rowsEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (left instanceof ArrayBuffer && right instanceof ArrayBuffer) {\n const a = new Uint8Array(left), b = new Uint8Array(right);\n return a.length === b.length && a.every((value, i) => value === b[i]);\n }\n if (typeof left !== 'object' || left === null || typeof right !== 'object' || right === null) return false;\n if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right)\n && left.length === right.length && left.every((value, i) => rowsEqual(value, right[i]));\n const a = Object.keys(left).filter(key => Reflect.get(left, key) !== undefined);\n const b = Object.keys(right).filter(key => Reflect.get(right, key) !== undefined);\n return a.length === b.length && a.every(key => Object.hasOwn(right, key)\n && rowsEqual(Reflect.get(left, key), Reflect.get(right, key)));\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new StorageError(400, 'storage row must be an object');\n return value as Record<string, unknown>;\n}\n\nexport function validateStorageRow(store: StoreName, value: unknown): void {\n if (store !== 'notes' && store !== 'block_revisions' && store !== 'sessions' && store !== 'block_index') return;\n const row = record(value);\n const positive = (field: string): boolean => typeof row[field] === 'number' && Number.isSafeInteger(row[field]) && row[field] > 0;\n const required = (field: string): boolean => typeof row[field] === 'string' && row[field].length > 0;\n if (store === 'notes') {\n if (!required('id') || typeof row.title !== 'string' || typeof row.rawContent !== 'string'\n || !positive('sourceRevision') || typeof row.createdAt !== 'number' || !Number.isFinite(row.createdAt)\n || 'segments' in row || 'segmentIds' in row\n || (row.date !== undefined && (typeof row.date !== 'number' || !Number.isFinite(row.date)))\n || (row.seedOrigin !== undefined && row.seedOrigin !== 'seed' && row.seedOrigin !== 'user')\n || (row.seedVersion !== undefined && !(typeof row.seedVersion === 'number' && Number.isSafeInteger(row.seedVersion) && row.seedVersion >= 0))\n || (row.tags !== undefined && (!Array.isArray(row.tags) || !row.tags.every(tag => typeof tag === 'string')))\n || ['type', 'sourceId', 'sourcePath', 'catalog', 'notebookId', 'seedChunkId'].some(field => row[field] !== undefined && typeof row[field] !== 'string')) {\n throw new StorageError(400, 'invalid whole Note', 'invalid_note_blocks');\n }\n try { validateNoteBlocks(row.rawContent, record(row.blocks) as Note['blocks'], row.sourceRevision as number); }\n catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid block map', 'invalid_note_blocks'); }\n } else if (store === 'block_revisions') {\n if (!required('noteId') || !required('blockId') || !positive('version') || typeof row.rawContent !== 'string'\n || typeof row.savedAt !== 'number' || !Number.isFinite(row.savedAt)\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.kind))\n || (row.kind === 'wod' ? row.dialect !== 'time' && row.dialect !== 'log' : row.dialect !== undefined || row.sport !== undefined)\n || (row.sport !== undefined && typeof row.sport !== 'string')) throw new StorageError(400, 'invalid block revision', 'invalid_note_blocks');\n try {\n validateNoteBlocks(row.rawContent as string, { [String(row.blockId)]: {\n id: String(row.blockId), kind: row.kind as BlockRevision['kind'], version: row.version as number,\n sourceRevision: 1, from: 0, to: (row.rawContent as string).length,\n ...(row.dialect === undefined ? {} : { dialect: row.dialect as 'time' | 'log' }),\n ...(row.sport === undefined ? {} : { sport: row.sport as string }),\n } }, 1);\n } catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid revision source', 'invalid_note_blocks'); }\n } else if (store === 'sessions') {\n if (!required('noteId') || !required('blockId') || !positive('blockVersion')\n || ['segmentId', 'segmentVersion', 'version', 'rawContent', 'script', 'serializedScript', 'source', 'data', 'logs'].some(field => field in row)) {\n throw new StorageError(400, 'Session requires immutable block pin', 'invalid_session_pin');\n }\n } else if (!required('noteId') || !required('blockId') || !positive('blockVersion') || !positive('sourceRevision')\n || row.id !== `${row.noteId}:${row.blockId}` || !Number.isSafeInteger(row.from) || !Number.isSafeInteger(row.to)\n || 'segmentId' in row || 'segmentVersion' in row\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.dataType))\n || typeof row.rawContent !== 'string' || typeof row.noteTitle !== 'string'\n || typeof row.from !== 'number' || typeof row.to !== 'number' || row.from < 0 || row.to <= row.from) {\n throw new StorageError(400, 'invalid actionable block projection', 'invalid_note_blocks');\n }\n}\n\nexport function validateNoteWrite(previous: unknown, value: unknown): void {\n if (previous === undefined || rowsEqual(previous, value)) return;\n const before = record(previous), after = record(value);\n if (typeof before.sourceRevision !== 'number' || typeof after.sourceRevision !== 'number'\n || after.sourceRevision < before.sourceRevision\n || ((!rowsEqual(before.blocks, after.blocks) || before.rawContent !== after.rawContent)\n && after.sourceRevision <= before.sourceRevision)) throw new StorageError(409, 'stale Note source revision', 'transaction_conflict');\n}\n\nexport function validateSessionWrite(previous: unknown, value: unknown): void {\n if (previous === undefined) return;\n const before = record(previous), after = record(value);\n if (before.noteId !== after.noteId || before.blockId !== after.blockId || before.blockVersion !== after.blockVersion)\n throw new StorageError(409, 'Session pin is immutable', 'invalid_session_pin');\n}\n\nexport async function validateStoredPins(\n notes: Note[], sessions: Session[], getRevisions: (keys: IDBValidKey[]) => Promise<(BlockRevision | undefined)[]>,\n): Promise<void> {\n const keys: IDBValidKey[] = [];\n for (const note of notes) for (const block of Object.values(note.blocks)) keys.push([note.id, block.id, block.version]);\n for (const session of sessions) keys.push([session.noteId, session.blockId, session.blockVersion]);\n const revisions = await getRevisions(keys);\n let i = 0;\n for (const note of notes) for (const block of Object.values(note.blocks)) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== block.kind || revision.rawContent !== note.rawContent.slice(block.from, block.to)\n || revision.dialect !== block.dialect || revision.sport !== block.sport) throw new StorageError(409, 'Note block has no matching immutable revision', 'invalid_note_blocks');\n }\n for (let sessionIndex = 0; sessionIndex < sessions.length; sessionIndex++) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== 'wod') throw new StorageError(409, 'Session pin must reference a saved workout revision', 'invalid_session_pin');\n }\n}\n","/**\n * Shared user-scope sync policy (versioned-databases-backups-review §3.4).\n *\n * ONE ownership classification governs outbox journals, bootstrap\n * snapshots, the schema32 outbox cutover and cross-schema conversions. Rows\n * are classified by actual provenance — `seedOrigin` on notes, `isStatic`\n * plus owner note on projections, `registrySource` on bundled definitions,\n * `seed:` prefixes on meta checkpoints — never from `userId` or the ABSENCE\n * of a marker: uncertain rows are KEPT until their derivation and\n * reconstruction are proven.\n *\n * Excluded rows are exactly the ones the seed bundle re-derives: seed\n * notes, their static projections, bundled definitions and import\n * checkpoints. Everything else — sessions, events, attachments, revision\n * history, tags/pages/links, field-catalog data, non-seed meta — is user\n * data and always retained. Immutable block_revisions are kept\n * unconditionally until dependency closure is proven: sessions pin\n * revisions a re-import may not reproduce.\n */\n\nimport type { StoreName } from './contract';\n\n/** Durable seed-deletion intent: written atomically with the delete by\n * StorageService.deleteNote, honored by seed re-import (applySeedChunk) and\n * carried in every user-scope snapshot so fresh devices suppress too. */\nexport const USER_DELETED_SEED_PREFIX = 'user-deleted-seed:';\n\n/** Key constants shared by the writer (StorageService), the suppression\n * reader (seed runtime) and the policy passes — a durable contract. */\nexport function userDeletedSeedKey(noteId: string): string {\n return `${USER_DELETED_SEED_PREFIX}${noteId}`;\n}\n\n/** Inverse helper for readers; undefined for anything else. */\nexport function userDeletedSeedNoteId(key: unknown): string | undefined {\n if (typeof key !== 'string' || !key.startsWith(USER_DELETED_SEED_PREFIX)) return undefined;\n return key.slice(USER_DELETED_SEED_PREFIX.length) || undefined;\n}\n\n/** The one meta key family a user-scope snapshot excludes: import\n * checkpoints/claims (`seed:*`) are concurrency state re-derived from the\n * bundle. `user-deleted-seed:*` tombstones and every other key stay in. */\nexport function isSeedMetaKey(key: unknown): boolean {\n return typeof key === 'string' && key.startsWith('seed:');\n}\n\n/** Prior rows the policy needs: a projection's provenance is its owner\n * note's, so every policy pass collects seed note ids first. */\nexport interface UserScopeContext {\n seedNoteIds: ReadonlySet<string>;\n}\n\nexport function collectUserScopeContext(notes: readonly unknown[]): UserScopeContext {\n const seedNoteIds = new Set<string>();\n for (const row of notes) {\n if (row !== null && typeof row === 'object' && 'seedOrigin' in row\n && row.seedOrigin === 'seed' && 'id' in row && typeof row.id === 'string') {\n seedNoteIds.add(row.id);\n }\n }\n return { seedNoteIds };\n}\n\n/**\n * True when the row is user data a user-scope snapshot must retain.\n * Store-level default is true (keep uncertain rows); only provably\n * seed-rebuildable rows return false.\n */\nexport function isUserOwnedRow(store: StoreName, row: unknown, ctx: UserScopeContext): boolean {\n if (row === null || typeof row !== 'object') return true;\n switch (store) {\n case 'notes':\n return !('seedOrigin' in row && row.seedOrigin === 'seed');\n case 'block_index':\n case 'block_efforts':\n case 'block_equipment':\n // Static projections of seed notes are rebuilt by re-import; anything\n // else touching a seed note (user-created links included) is kept.\n return !('isStatic' in row && row.isStatic === true\n && 'noteId' in row && typeof row.noteId === 'string'\n && ctx.seedNoteIds.has(row.noteId));\n case 'efforts':\n case 'equipment':\n // 'bundled' is the provenance marker the seed importer writes;\n // 'user' and 'synthetic-unresolved' derive from user data.\n return !('registrySource' in row && row.registrySource === 'bundled');\n case 'meta':\n return !isSeedMetaKey('key' in row ? row.key : undefined);\n default:\n return true;\n }\n}\n","/**\n * Row codec for the SQL `data` column. Plain JSON.stringify destroys\n * ArrayBuffer values ({}); attachment rows carry raw blobs, so encoding tags\n * the declared binary field and decoding revives it.\n *\n * Collision safety: tagging applies ONLY to the declared binary field of the\n * declared store (attachments.data) — arbitrary rows (meta, notes, …) are\n * plain JSON in both directions, so authored {$binary:…}-shaped objects\n * anywhere else round-trip byte-for-byte. Within attachments.data the value\n * is typed `ArrayBuffer | string`; strings pass through, and only the exact\n * two-key tag revives.\n */\n\nconst TAG = '$binary';\nconst LEN = '$bytes';\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n const CHUNK = 0x8000; // String.fromCharCode.apply arg ceiling\n for (let i = 0; i < bytes.length; i += CHUNK) {\n binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length); // exact-length buffer: .buffer IS the decoded ArrayBuffer\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n/** Tag shape: exactly { $binary: base64, $bytes: length }. */\nfunction reviveBinary(value: unknown): unknown {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(TAG) || !keys.includes(LEN)) return value;\n const tag = value as Record<string, unknown>;\n if (typeof tag[TAG] !== 'string' || typeof tag[LEN] !== 'number') return value;\n const bytes = base64ToBytes(tag[TAG]);\n if (bytes.length !== tag[LEN]) {\n throw new Error(`corrupt binary cell: declared ${tag[LEN]} bytes, decoded ${bytes.length}`);\n }\n return bytes.buffer;\n}\n\n/** Serialize a row; when `binaryField` is set and holds an ArrayBuffer, it is\n * replaced by the lossless tag (shallow copy — the input row is untouched). */\nconst canonicalJson = (_key: string, value: unknown): unknown => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n return Object.fromEntries(Object.keys(value).sort().map(key => [key, Reflect.get(value, key)]));\n};\nexport function encodeRowJson(value: unknown, binaryField?: string): string {\n if (binaryField && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const row = value as Record<string, unknown>;\n const data = row[binaryField];\n if (data instanceof ArrayBuffer) {\n const bytes = new Uint8Array(data);\n return JSON.stringify({ ...row, [binaryField]: { [TAG]: bytesToBase64(bytes), [LEN]: bytes.length } }, canonicalJson);\n }\n }\n return JSON.stringify(value, canonicalJson);\n}\n\n/** Parse a row; when `binaryField` is set, a tagged value there revives as an\n * ArrayBuffer. Every other value — including tag-shaped data in other fields\n * or stores — is returned exactly as authored. */\nexport function decodeRowJson<T = unknown>(text: string, binaryField?: string): T {\n const row = JSON.parse(text) as unknown;\n if (binaryField && row !== null && typeof row === 'object' && !Array.isArray(row)) {\n const record = row as Record<string, unknown>;\n const revived = reviveBinary(record[binaryField]);\n if (revived !== record[binaryField]) record[binaryField] = revived;\n }\n return row as T;\n}\n","/**\n * Turso backup/sync protocol — the local-first sync tables layered on top of\n * any libsql database. The browser data plane is always IndexedDB; a saved\n * Turso target is a backup/sync destination, never the read/write provider.\n *\n * Design: the remote holds ONE op log (`_wodwiki_sync_ops`) plus a state row\n * (`_wodwiki_sync_state`) carrying {schema, rev}. Every committed local\n * transaction group appends one idempotent op-group (uuid op_id,\n * INSERT-or-ignore per op); `rev` is assigned monotonically per NEWLY applied\n * group — a retried group is recognized by its first op id, consumes no rev\n * and appends nothing. Pulls replay ops with rev > cursor in deterministic\n * (rev, idx) order. Tombstones (delete/clear/wipe) are ordinary ops —\n * deletions propagate.\n *\n * Fetch atomicity: a pull window is a set of WHOLE revision groups. The rev\n * boundary is chosen with a bounded subquery, then every row of those revs is\n * returned — a group is never split, so the cursor never skips the rest of\n * a group (one pathologically large group can exceed the nominal row bound;\n * that is the unavoidable atomicity ceiling).\n *\n * ponytail: op-log replay pulls — a fresh browser replays the whole log\n * (O(history)) instead of reading per-store current-state tables. Upgrade\n * path: add per-store state tables rev-indexed by primary key and collapse\n * the log into them periodically; the wire format (op_id, rev, mutation)\n * stays unchanged.\n *\n * Never-downgrade rule: the state row's `schema` is the managing client's\n * DB_VERSION at init time. Uploads verify `schema` INSIDE the write\n * transaction. Older schemas require explicit conversion into a fresh\n * target with the source retained; newer schemas are never rewritten.\n */\n\nimport { STORE_DEFS } from '../schema';\nimport type { StoreName } from '../contract';\nimport type { KeyDTO, Scalar } from '../wire';\nimport { keyFromValue } from '../wire';\nimport { rowsEqual } from '../validation';\nimport { decodeRowJson, encodeRowJson } from './codec';\nimport { StorageError } from './errors';\nimport { SCHEMA_TABLE } from './store';\nimport type { Database, SqlConnection, SqlStatement } from './connection';\n\nexport const SYNC_OPS_TABLE = '_wodwiki_sync_ops';\nexport const SYNC_STATE_TABLE = '_wodwiki_sync_state';\n\n/** One committed local transaction group, as journaled in IndexedDB. */\nexport type SyncMutation =\n | { op: 'put'; store: StoreName; key: KeyDTO; value: unknown }\n | { op: 'delete'; store: StoreName; key: KeyDTO }\n | { op: 'clear'; store: StoreName }\n | { op: 'wipe' };\n\nexport interface SyncEntry {\n /** Idempotency key — one uuid per committed local transaction group. */\n id: string;\n at: number;\n ops: SyncMutation[];\n}\n\nexport interface StoredSyncOp {\n opId: string;\n rev: number;\n idx: number;\n at: number;\n mutation: SyncMutation;\n}\n\nexport type SyncTargetKind =\n /** No tables at all (beyond libsql internals): fresh database. */\n | 'empty'\n /** Tables exist but neither sync state nor a legacy schema guard — not\n * ours; initializing over unknown data is refused by the caller. */\n | { kind: 'unknown' }\n /** Legacy direct-Turso SqlStorage layout (`_wodwiki_schema` guard). */\n | { kind: 'legacy'; schemaVersion: number }\n /** This sync protocol's layout; payload = state row. */\n | { kind: 'current'; schemaVersion: number; rev: number };\n\ninterface SyncStateRow {\n schema: number;\n rev: number;\n}\n\n/** Stores whose rows carry a raw binary field the codec must preserve. */\nconst BINARY_FIELD: Record<string, string> = { attachments: 'data' };\n\nconst STORE_NAMES: Record<string, true> = Object.fromEntries(STORE_DEFS.map((d) => [d.name, true]));\n\nconst STATE_KEY = 'meta';\n\nfunction isSafeInt(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value);\n}\n\nfunction isScalar(value: unknown): value is Scalar {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n}\n\n/** Trust-boundary key check — mirrors wire.validateKey (kept local to keep\n * the sql subpath free of runtime wire imports beyond types). */\nfunction assertKey(key: unknown, what: string): asserts key is KeyDTO {\n if (isScalar(key)) return;\n if (Array.isArray(key) && key.length > 0 && key.every(isScalar)) return;\n throw new StorageError(400, `${what} must be a string, finite number, or non-empty scalar tuple`, 'bad_sync_key');\n}\n\n/** Validate one decoded mutation at the external-data trust boundary. */\nfunction validateMutation(raw: unknown): SyncMutation {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new StorageError(400, 'sync mutation must be an object', 'bad_sync_mutation');\n }\n const mutation = raw as Record<string, unknown>;\n if (mutation.op === 'wipe') return { op: 'wipe' };\n if (typeof mutation.store !== 'string' || !STORE_NAMES[mutation.store]) {\n throw new StorageError(400, `sync mutation has unknown store ${String(mutation.store)}`, 'bad_sync_mutation');\n }\n const store = mutation.store as StoreName;\n if (mutation.op === 'clear') return { op: 'clear', store };\n if (mutation.op === 'delete') {\n assertKey(mutation.key, 'sync delete key');\n return { op: 'delete', store, key: mutation.key };\n }\n if (mutation.op === 'put') {\n assertKey(mutation.key, 'sync put key');\n if (mutation.value === null || typeof mutation.value !== 'object' || Array.isArray(mutation.value)) {\n throw new StorageError(400, 'sync put value must be an object row', 'bad_sync_mutation');\n }\n const def = STORE_DEFS.find(def => def.name === store)!;\n const valueKey = keyFromValue(def, mutation.value);\n assertKey(valueKey, 'sync row key');\n if (!rowsEqual(mutation.key, valueKey)) {\n throw new StorageError(400, 'sync put key differs from row key', 'bad_sync_key');\n }\n return { op: 'put', store, key: mutation.key, value: mutation.value };\n }\n throw new StorageError(400, `sync mutation has unknown op ${String(mutation.op)}`, 'bad_sync_mutation');\n}\n\nfunction validateEntry(entry: SyncEntry): void {\n if (typeof entry.id !== 'string' || entry.id.length === 0 || entry.id.length > 200) {\n throw new StorageError(400, 'sync entry id must be a non-empty string', 'bad_sync_entry');\n }\n if (!isSafeInt(entry.at) || entry.at < 0) {\n throw new StorageError(400, 'sync entry at must be a non-negative safe integer', 'bad_sync_entry');\n }\n if (!Array.isArray(entry.ops) || entry.ops.length === 0) {\n throw new StorageError(400, 'sync entry ops must be a non-empty array', 'bad_sync_entry');\n }\n for (const op of entry.ops) validateMutation(op);\n}\n\n/** Run statements inside a transaction, preferring one native batch. */\nasync function runStatements(tx: SqlConnection, statements: SqlStatement[]): Promise<unknown[][]> {\n if (statements.length === 0) return [];\n if (tx.batch) return tx.batch(statements);\n const results: unknown[][] = [];\n for (const statement of statements) {\n results.push(await tx.query(statement.sql, statement.params ?? []));\n }\n return results;\n}\n\nasync function tableExists(conn: SqlConnection, dialect: Database['dialect'], name: string): Promise<boolean> {\n const sql = dialect === 'postgres'\n ? `SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1`\n : `SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`;\n return (await conn.query(sql, [name])).length > 0;\n}\n\n/** Read + validate the sync state row (trusted shape afterwards). */\nasync function readSyncState(tx: SqlConnection): Promise<SyncStateRow> {\n const rows = await tx.query(`SELECT \"value\" FROM \"${SYNC_STATE_TABLE}\" WHERE \"key\" = ?`, [STATE_KEY]);\n if (!rows[0]) throw new StorageError(409, 'sync target is not initialized', 'sync_not_initialized');\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(rows[0].value));\n } catch {\n throw new StorageError(400, 'malformed sync state row', 'bad_sync_state');\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new StorageError(400, 'malformed sync state row', 'bad_sync_state');\n }\n const state = parsed as Record<string, unknown>;\n if (!isSafeInt(state.schema) || state.schema < 0 || !isSafeInt(state.rev) || state.rev < 0) {\n throw new StorageError(400, 'sync state schema/rev must be non-negative safe integers', 'bad_sync_state');\n }\n return { schema: state.schema, rev: state.rev };\n}\n\n/** Classify the sync target WITHOUT mutating it. */\nexport async function probeSyncTarget(db: Database): Promise<SyncTargetKind> {\n if (await tableExists(db, db.dialect, SYNC_STATE_TABLE)) {\n const state = await readSyncState(db);\n return { kind: 'current', schemaVersion: state.schema, rev: state.rev };\n }\n if (await tableExists(db, db.dialect, SCHEMA_TABLE)) {\n const rows = await db.query(`SELECT \"value\" FROM \"${SCHEMA_TABLE}\" WHERE \"key\" = 'schema'`);\n if (rows[0]) {\n const guard = JSON.parse(String(rows[0].value)) as { version?: unknown };\n if (typeof guard.version === 'number' && Number.isSafeInteger(guard.version) && guard.version >= 0) {\n return { kind: 'legacy', schemaVersion: guard.version };\n }\n }\n return { kind: 'legacy', schemaVersion: 0 };\n }\n // Fresh-vs-unknown: any user table we do not own means foreign data.\n const others = await db.query(\n db.dialect === 'postgres'\n ? `SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'`\n : `SELECT name FROM sqlite_master WHERE type = 'table'`,\n );\n const internal = (name: string): boolean => name.startsWith('_wodwiki_') || name.startsWith('sqlite_');\n return others.some((row) => !internal(String(Object.values(row)[0]))) ? { kind: 'unknown' } : 'empty';\n}\n\n/** Create the sync tables + state row. Only for empty targets; existing\n * state (current, legacy or unknown) is never overwritten by init. */\nexport async function initSyncTarget(db: Database, schemaVersion: number): Promise<void> {\n await db.transaction(async (tx) => {\n await tx.exec(`CREATE TABLE IF NOT EXISTS \"${SYNC_STATE_TABLE}\" (\"key\" TEXT PRIMARY KEY, \"value\" TEXT NOT NULL)`);\n await tx.exec(\n `CREATE TABLE IF NOT EXISTS \"${SYNC_OPS_TABLE}\" (` +\n `\"op_id\" TEXT PRIMARY KEY, \"rev\" INTEGER NOT NULL, \"idx\" INTEGER NOT NULL, \"at\" INTEGER NOT NULL, \"data\" TEXT NOT NULL)`,\n );\n await tx.exec(\n `CREATE INDEX IF NOT EXISTS \"${SYNC_OPS_TABLE}_rev\" ON \"${SYNC_OPS_TABLE}\" (\"rev\", \"idx\")`,\n );\n await tx.exec(\n `INSERT INTO \"${SYNC_STATE_TABLE}\" (\"key\", \"value\") VALUES (?, ?) ON CONFLICT (\"key\") DO NOTHING`,\n [STATE_KEY, JSON.stringify({ schema: schemaVersion, rev: 0 } satisfies SyncStateRow)],\n );\n });\n}\n\nfunction encodeMutation(mutation: SyncMutation): string {\n if (mutation.op !== 'put') return JSON.stringify(mutation);\n // The binary codec applies to the ROW (mutation.value), not the mutation\n // envelope — attachments.data carries the raw bytes.\n const encoded = encodeRowJson(mutation.value, BINARY_FIELD[mutation.store]);\n return `{\"key\":${JSON.stringify(mutation.key)},\"op\":\"put\",\"store\":${JSON.stringify(mutation.store)},\"value\":${encoded}}`;\n}\n\n/** Decode + validate one stored op payload at the external-data boundary. */\nfunction decodeMutation(data: unknown): SyncMutation {\n if (typeof data !== 'string') {\n throw new StorageError(400, 'sync op data must be a string', 'bad_sync_mutation');\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n throw new StorageError(400, 'sync op data is not valid JSON', 'bad_sync_mutation');\n }\n const mutation = validateMutation(parsed);\n if (mutation.op !== 'put') return mutation;\n return {\n op: 'put',\n store: mutation.store,\n key: mutation.key,\n value: decodeRowJson(JSON.stringify(mutation.value), BINARY_FIELD[mutation.store]),\n };\n}\n\nexport interface ApplySyncBatchOptions {\n /** Schema the caller verified at probe time — rechecked INSIDE the write\n * transaction so a schema change between probe and append aborts. */\n expectSchema?: number;\n}\n\n/**\n * Append op-groups to the log in ONE SQL transaction, idempotently by\n * group: a group whose first op id already exists is skipped entirely and\n * consumes no rev (retries never duplicate, never allocate revisions).\n * Returns the number of NEW groups committed — ack semantics for the\n * uploader's watermark.\n */\nexport async function applySyncBatch(\n db: Database,\n entries: SyncEntry[],\n opts: ApplySyncBatchOptions = {},\n): Promise<number> {\n if (entries.length === 0) return 0;\n for (const entry of entries) validateEntry(entry);\n return db.transaction(async (tx) => {\n const state = await readSyncState(tx);\n if (opts.expectSchema !== undefined && state.schema !== opts.expectSchema) {\n throw new StorageError(\n 409,\n `sync target schema changed from v${opts.expectSchema} to v${state.schema} between probe and write — retry the cycle`,\n 'sync_schema_conflict',\n );\n }\n // Group presence: one lookup on every group's first op id. Groups are\n // written whole by construction, so first-op presence ⇔ group present.\n const firstIds = entries.map((entry) => `${entry.id}:0`);\n const present = new Set<string>();\n for (let i = 0; i < firstIds.length; i += 100) {\n const chunk = firstIds.slice(i, i + 100);\n const rows = await tx.query(\n `SELECT \"op_id\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"op_id\" IN (${chunk.map(() => '?').join(', ')})`,\n chunk,\n );\n for (const row of rows) present.add(String(row.op_id));\n }\n const statements: SqlStatement[] = [];\n let rev = state.rev;\n let committed = 0;\n for (const entry of entries) {\n if (present.has(`${entry.id}:0`)) continue;\n rev += 1;\n committed += 1;\n entry.ops.forEach((mutation, idx) => {\n statements.push({\n sql:\n `INSERT INTO \"${SYNC_OPS_TABLE}\" (\"op_id\", \"rev\", \"idx\", \"at\", \"data\") VALUES (?, ?, ?, ?, ?) ` +\n `ON CONFLICT (\"op_id\") DO NOTHING`,\n params: [`${entry.id}:${idx}`, rev, idx, entry.at, encodeMutation(mutation)],\n });\n });\n }\n statements.push({\n sql: `UPDATE \"${SYNC_STATE_TABLE}\" SET \"value\" = ? WHERE \"key\" = ?`,\n params: [JSON.stringify({ schema: state.schema, rev } satisfies SyncStateRow), STATE_KEY],\n });\n await runStatements(tx, statements);\n return committed;\n });\n}\n\n/**\n * Replay window: ops with rev > afterRev, in deterministic commit order.\n * The window covers WHOLE revision groups: up to `limit` distinct revs are\n * chosen (bounded subquery), then every row of those revs is returned, so a\n * cursor advanced to the last returned rev never splits a group. A single\n * group larger than `limit` is returned whole — the atomicity ceiling.\n */\nexport async function fetchSyncOps(db: Database, afterRev: number, limit: number): Promise<StoredSyncOp[]> {\n if (!isSafeInt(afterRev) || afterRev < 0) {\n throw new StorageError(400, 'fetchSyncOps cursor must be a non-negative safe integer', 'bad_sync_cursor');\n }\n const bounded = Math.min(Math.max(1, Math.floor(limit)), 0xffffffff);\n const revRows = await db.query(\n `SELECT DISTINCT \"rev\" FROM (SELECT \"rev\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"rev\" > ? ORDER BY \"rev\" ASC LIMIT ?)`,\n [afterRev, bounded],\n );\n const revs = revRows.map((row) => {\n const rev = Number(row.rev);\n if (!Number.isSafeInteger(rev) || rev < 0) {\n throw new StorageError(400, 'sync op rev must be a non-negative safe integer', 'bad_sync_row');\n }\n return rev;\n });\n if (revs.length === 0) return [];\n const rows = await db.query(\n `SELECT \"op_id\", \"rev\", \"idx\", \"at\", \"data\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"rev\" IN (${revs.map(() => '?').join(', ')}) ORDER BY \"rev\", \"idx\"`,\n revs,\n );\n return rows.map((row, at) => {\n const opId = row.op_id;\n const rev = Number(row.rev);\n const idx = Number(row.idx);\n const atMs = Number(row.at);\n if (typeof opId !== 'string' || opId.length === 0 || !Number.isSafeInteger(rev) || rev < 0\n || !Number.isSafeInteger(idx) || idx < 0 || !Number.isSafeInteger(atMs) || atMs < 0) {\n throw new StorageError(400, `sync op row ${at} has malformed shape`, 'bad_sync_row');\n }\n return { opId, rev, idx, at: atMs, mutation: decodeMutation(row.data) };\n });\n}\n\n/** Migration-only raw replay: parsed op payloads WITHOUT store/key validation\n * (old logs reference era store names like `segments`). Only\n * convertSyncSource consumes this; ordinary pulls validate every row\n * against the current schema. Binary cells revive. */\nexport type RawSyncOp =\n | { op: 'wipe' }\n | { op: 'clear'; store: string }\n | { op: 'delete'; store: string; key: unknown }\n | { op: 'put'; store: string; key: unknown; value: unknown };\n\nexport async function readRawSyncOps(db: Database): Promise<RawSyncOp[]> {\n const rows = await db.query(`SELECT \"rev\", \"idx\", \"data\" FROM \"${SYNC_OPS_TABLE}\" ORDER BY \"rev\", \"idx\"`);\n return rows.map((row) => {\n const rev = Number(row.rev);\n const idx = Number(row.idx);\n if (!Number.isSafeInteger(rev) || rev < 0 || !Number.isSafeInteger(idx) || idx < 0 || typeof row.data !== 'string') {\n throw new StorageError(400, 'sync op row has malformed shape', 'bad_sync_row');\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(row.data);\n } catch {\n throw new StorageError(400, 'sync op data is not valid JSON', 'bad_sync_row');\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new StorageError(400, 'sync op data must be an object', 'bad_sync_row');\n }\n const mutation = parsed as Record<string, unknown>;\n if (mutation.op === 'wipe') return { op: 'wipe' };\n if (typeof mutation.store !== 'string') {\n throw new StorageError(400, 'sync op must carry a string store', 'bad_sync_row');\n }\n if (mutation.op === 'clear') return { op: 'clear', store: mutation.store };\n if (mutation.op === 'delete') return { op: 'delete', store: mutation.store, key: mutation.key };\n if (mutation.op !== 'put' || mutation.value === null || typeof mutation.value !== 'object' || Array.isArray(mutation.value)) {\n throw new StorageError(400, 'sync op has an unknown operation or invalid row', 'bad_sync_row');\n }\n return {\n op: 'put',\n store: mutation.store,\n key: mutation.key,\n value: decodeRowJson(JSON.stringify(mutation.value), BINARY_FIELD[mutation.store]),\n };\n });\n}\n\n/**\n * Import rows from a legacy direct-Turso (SqlStorage) database into op-\n * groups. Reads the per-store JSON `data` columns directly — the legacy\n * schema guard may hold an older version SqlStorage refuses to open, so the\n * rows are lifted raw, never through SqlStorage. Missing tables contribute\n * no rows; nothing is written or deleted remotely.\n */\nexport async function readLegacyRows(db: Database, table: string): Promise<unknown[]> {\n if (!(await tableExists(db, db.dialect, table))) return [];\n const rows = await db.query(`SELECT \"data\" FROM \"${table}\"`);\n return rows.map((row) => decodeRowJson(String(row.data), BINARY_FIELD[table]));\n}\n","/**\n * IndexedDB adapter — the browser data plane (moved verbatim from the\n * playground app; the shared user policy and the schema32 sync cutover live\n * here now). Local-first invariants:\n *\n * - Every committed local transaction group is durable in `sync_outbox`,\n * written in the SAME native transaction as the data writes.\n * - Snapshots (`snapshotRows`, bootstrap, conversion) are policy-compliant:\n * they carry user data only, per the shared policy in `../policy`.\n * - `sync_state` holds pull cursors, upload watermarks and frozen\n * bootstrap runs (durable retry identities), all per backup target.\n */\n\nimport { openDB, type IDBPDatabase, type IDBPTransaction } from 'idb';\nimport type {\n IReadOnlyStore, IReadWriteStore, IStorage, IStorageTransaction, StoreName, StoreType,\n} from '../contract';\nimport { DB_VERSION, STORE_DEFS } from '../schema';\nimport {\n DEFAULT_LOCAL_DATABASE_NAME, isValidLocalDatabaseName, type LocalDatabaseInfo,\n} from './catalog';\nimport { USER_OWNED_STORES, stampUserOwned } from '../membership';\nimport { keyFromValue, type KeyDTO } from '../wire';\nimport type { Note, Session, BlockRevision } from '../entities';\nimport {\n rowsEqual, validateStorageRow, validateNoteWrite, validateSessionWrite, validateStoredPins,\n} from '../validation';\nimport { collectUserScopeContext, isUserOwnedRow, USER_DELETED_SEED_PREFIX, type UserScopeContext } from '../policy';\nimport { readRawSyncOps, readLegacyRows, type SyncEntry, type SyncMutation } from '../sql/sync';\nimport type { Database } from '../sql/connection';\nimport {\n parseDocumentSections, actionableSectionKind, matchDialectFence, KNOWN_SECTION_WIDGETS,\n} from '@bitcobblers/wod-wiki-core';\nimport { toEventRows, toSummaryEventRows } from '@bitcobblers/wod-wiki-wql';\n\nexport const IDB_DB_NAME = DEFAULT_LOCAL_DATABASE_NAME;\n\nexport {\n DEFAULT_LOCAL_DATABASE_NAME, deleteLocalDatabase,\n isValidLocalDatabaseName, listLocalDatabases, type LocalDatabaseInfo,\n} from './catalog';\n\n/** Create a named database at the current schema (DB_VERSION) by opening it\n * through the regular adapter, then close. Refuses the default database —\n * the catalog never touches the live app profile.\n *\n * Lives beside the adapter (not in ./catalog) because it needs the\n * adapter's schema upgrade path, and the adapter's module re-exports the\n * catalog — importing the adapter back from the catalog would close a\n * module cycle. */\nexport async function createLocalDatabase(name: string): Promise<LocalDatabaseInfo> {\n if (!isValidLocalDatabaseName(name)) throw new Error(`Invalid local database name \"${String(name)}\".`);\n if (name === DEFAULT_LOCAL_DATABASE_NAME) throw new Error('The default database cannot be created here.');\n const storage = new IndexedDBStorage({ dbName: name });\n try {\n await storage.open();\n } finally {\n await storage.close().catch(() => undefined);\n }\n return { name, version: DB_VERSION };\n}\n\n// Browser-local sync stores — NOT part of the shared STORE_DEFS spec (the\n// SQL/API schema is unchanged). `sync_outbox` is the durable journal: one\n// entry per committed local transaction group, written in the SAME native\n// transaction as the data writes, so an aborted transaction never journals\n// and a journaled group always reflects committed data. `sync_state` holds\n// the pull cursor, the upload watermark and frozen bootstrap runs.\nconst OUTBOX_STORE = 'sync_outbox';\nconst SYNC_STATE_STORE = 'sync_state';\nconst LOCAL_SYNC_STORES = [\n { name: OUTBOX_STORE, keyPath: 'seq', autoIncrement: true },\n { name: SYNC_STATE_STORE, keyPath: 'key' },\n] as const;\n\n/** sync_state keys of frozen bootstrap runs (TursoSyncEngine naming). */\nconst BOOTSTRAP_RUN_PREFIX = 'bootstrap-run:';\n\nconst NON_SYSTEM_STORES: readonly StoreName[] = STORE_DEFS.filter(def => !def.system).map(def => def.name);\n\n// Bootstrap chunks: whole ops only, bounded per group for network batches.\nconst BOOTSTRAP_MAX_OPS = 500;\nconst BOOTSTRAP_MAX_BYTES = 1_000_000;\n\n/** Stores whose rows carry a raw binary field (base64 in the op log). */\nconst BINARY_SYNC_FIELDS: Record<string, string> = { attachments: 'data' };\n\n/** Legacy direct-Turso tables that predate the current STORE_DEFS spec. */\nconst LEGACY_EXTRA_TABLES: { name: string; keyPath: string | string[] }[] = [\n { name: 'segments', keyPath: ['id', 'version'] },\n { name: 'results', keyPath: 'id' },\n];\n\ntype Mode = 'readonly' | 'readwrite';\n/** Native tx handle; write methods are guarded at runtime by `mutable`, so\n * the handle is typed readwrite to keep put/delete/clear defined. */\ntype Tx = IDBPTransaction<unknown, string, 'readwrite'>;\n\n/** Per-transaction mutation collector — becomes one outbox entry on commit.\n * `ctx` lazily caches the tx's user-scope context (seed note ids) for\n * journal-time ownership classification; invalidated when notes change. */\nclass TxJournal {\n readonly ops: SyncMutation[] = [];\n ctx?: Promise<UserScopeContext>;\n}\n\n/** Post-commit outbox notification — the sync engine debounces uploads off\n * these instead of polling the network while the app is idle. Fired only\n * AFTER the committing transaction durably lands (fire-and-forget). */\nconst outboxListeners = new Set<() => void>();\n\nexport function subscribeOutboxWrites(listener: () => void): () => void {\n outboxListeners.add(listener);\n return () => {\n outboxListeners.delete(listener);\n };\n}\n\nfunction notifyOutboxCommit(): void {\n for (const listener of outboxListeners) listener();\n}\n\nfunction isKeyRange(key: unknown): key is IDBKeyRange {\n return key !== null && typeof key === 'object' && !Array.isArray(key)\n && ('lower' in key || 'upper' in key || 'lowerOpen' in key || 'upperOpen' in key);\n}\n\n/** Approximate encoded op-log size of one mutation: JSON envelope plus\n * base64-inflated binary cells (ArrayBuffer serializes as {} in JSON, so a\n * plain JSON.stringify would undercount attachment-heavy batches). */\nfunction mutationBytes(op: SyncMutation): number {\n if (op.op !== 'put') return 32; // envelope + key estimate\n let bytes = 32;\n const field = BINARY_SYNC_FIELDS[op.store];\n const value: unknown = op.value;\n const data = field && value !== null && typeof value === 'object' && !Array.isArray(value) && field in value\n ? Reflect.get(value, field)\n : undefined;\n bytes += typeof data === 'string' ? data.length\n : data instanceof ArrayBuffer ? Math.ceil(data.byteLength / 3) * 4 + 64\n : JSON.stringify(op.value)?.length ?? 0;\n return bytes;\n}\n\n/**\n * One policy-compliant snapshot as put mutations, in STORE_DEFS order.\n * Strict: a row whose key cannot be derived is corrupted data — it fails\n * the pass instead of being silently dropped.\n *\n * Immutable revision history is emitted BEFORE notes and sessions so chunk\n * boundaries (bootstrap/conversion grouping) can never split a pin from the\n * revision it references: every chunk that carries a consumer row already\n * carries its history.\n */\nconst SNAPSHOT_OP_ORDER: readonly StoreName[] = [\n 'block_revisions',\n 'notes',\n 'sessions',\n ...NON_SYSTEM_STORES.filter(\n name => name !== 'block_revisions' && name !== 'notes' && name !== 'sessions',\n ),\n];\n\n/** Snapshot ops are always puts — narrowed so callers can read store/key. */\ntype SnapshotPut = Extract<SyncMutation, { op: 'put' }>;\n\nasync function policySnapshotOps(\n readAll: (store: StoreName) => Promise<unknown[]>,\n): Promise<SnapshotPut[]> {\n const ctx = collectUserScopeContext(await readAll('notes'));\n const ops: SnapshotPut[] = [];\n for (const store of SNAPSHOT_OP_ORDER) {\n const def = STORE_DEFS.find(candidate => candidate.name === store)!;\n for (const row of await readAll(store)) {\n if (!isUserOwnedRow(store, row, ctx)) continue;\n ops.push({ op: 'put', store, key: keyFromValue(def, row), value: row });\n }\n }\n return ops;\n}\n\nclass IDBStore<T> implements IReadWriteStore<T> {\n constructor(\n private readonly owner: IndexedDBStorage,\n private readonly name: StoreName,\n private readonly tx?: Tx,\n private readonly mutable = false,\n private readonly touched?: { notes: Set<string>; sessions: Set<string> },\n private readonly journal?: TxJournal,\n ) {}\n\n async get(key: IDBValidKey): Promise<T | undefined> {\n if (this.tx) return this.tx.objectStore(this.name).get(key);\n return (await this.owner.open()).get(this.name, key);\n }\n\n async getMany(keys: IDBValidKey[]): Promise<(T | undefined)[]> {\n if (this.tx) return Promise.all(keys.map(key => this.tx!.objectStore(this.name).get(key)));\n return this.owner.transaction([this.name], 'readonly', tx => tx.readonly(this.name).getMany(keys)) as Promise<(T | undefined)[]>;\n }\n\n async getAll(query?: IDBValidKey | IDBKeyRange, count?: number): Promise<T[]> {\n if (this.tx) return this.tx.objectStore(this.name).getAll(query, count);\n return (await this.owner.open()).getAll(this.name, query, count);\n }\n\n async getAllFromIndex(index: string, query?: IDBValidKey | IDBKeyRange, count?: number): Promise<T[]> {\n if (this.tx) return this.tx.objectStore(this.name).index(index).getAll(query, count);\n return (await this.owner.open()).getAllFromIndex(this.name, index, query, count);\n }\n\n async getAllFromIndexMany(index: string, keys: IDBValidKey[]): Promise<T[][]> {\n if (this.tx) return Promise.all(keys.map(key => this.tx!.objectStore(this.name).index(index).getAll(key)));\n return this.owner.transaction([this.name], 'readonly', tx => tx.readonly(this.name).getAllFromIndexMany(index, keys)) as Promise<T[][]>;\n }\n\n async count(query?: IDBValidKey | IDBKeyRange): Promise<number> {\n if (this.tx) return this.tx.objectStore(this.name).count(query);\n return (await this.owner.open()).count(this.name, query);\n }\n\n async countFromIndex(index: string, query?: IDBValidKey | IDBKeyRange): Promise<number> {\n if (this.tx) return this.tx.objectStore(this.name).index(index).count(query);\n return (await this.owner.open()).countFromIndex(this.name, index, query);\n }\n\n async put(value: T, _key?: IDBValidKey): Promise<IDBValidKey> {\n if (!this.mutable) throw new Error('read-only store');\n if (!this.tx) {\n const scope = this.name === 'notes' ? [this.name, 'block_revisions'] as const : [this.name, 'block_revisions', 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).put(value as StoreType<typeof this.name>));\n }\n const stored = this.owner.stamp(this.name, value);\n validateStorageRow(this.name, stored);\n const def = STORE_DEFS.find(def => def.name === this.name)!;\n const key = keyFromValue(def, stored);\n const store = this.tx.objectStore(this.name);\n const previous = await store.get(key);\n if (this.name === 'block_revisions' && previous !== undefined && !rowsEqual(previous, stored)) throw new Error('immutable block revision collision');\n if (this.name === 'notes') validateNoteWrite(previous, stored);\n if (this.name === 'sessions') validateSessionWrite(previous, stored);\n if (rowsEqual(previous, stored)) return key;\n const result = await store.put(stored);\n if (!def.system && this.journal) {\n // Journal-time ownership classification (§3.4), INSIDE the write\n // transaction: user→user and seed→user emit complete user puts;\n // seed→seed ships nothing (the remote re-imports seed data itself);\n // user→seed emits a tombstone for the former user record instead of\n // silently dropping it.\n const ctx = this.name === 'notes'\n ? undefined\n : await (this.journal.ctx ??= this.owner.policyContext(this.tx!));\n const wasUser = previous !== undefined && isUserOwnedRow(this.name, previous, ctx ?? collectUserScopeContext([]));\n const isUser = isUserOwnedRow(this.name, stored, ctx ?? collectUserScopeContext([]));\n if (isUser) {\n if (this.name === 'notes' && stored !== null && typeof stored === 'object' && 'id' in stored) {\n for (const revision of await this.tx.objectStore('block_revisions').index('by-note').getAll(String(stored.id))) {\n this.journal.ops.push({ op: 'put', store: 'block_revisions', key: [revision.noteId, revision.blockId, revision.version], value: revision });\n }\n } else if (this.name === 'sessions' && stored !== null && typeof stored === 'object' && 'noteId' in stored && 'blockId' in stored && 'blockVersion' in stored) {\n const revisionKey = [stored.noteId, stored.blockId, stored.blockVersion] as IDBValidKey;\n const revision = await this.tx.objectStore('block_revisions').get(revisionKey);\n if (revision) this.journal.ops.push({ op: 'put', store: 'block_revisions', key: revisionKey as KeyDTO, value: revision });\n }\n this.journal.ops.push({ op: 'put', store: this.name, key: key as KeyDTO, value: stored });\n }\n else if (wasUser) this.journal.ops.push({ op: 'delete', store: this.name, key: key as KeyDTO });\n // notes writes shift seed provenance — reclassify later stores in\n // this transaction against the post-write notes.\n if (this.name === 'notes') this.journal.ctx = undefined;\n }\n if (this.name === 'notes') this.touched?.notes.add(String(key));\n if (this.name === 'sessions') this.touched?.sessions.add(String(key));\n return result;\n }\n\n async putMany(values: T[], keys?: IDBValidKey[]): Promise<IDBValidKey[]> {\n if (keys && keys.length !== values.length) throw new Error('putMany key count mismatch');\n if (!this.tx) {\n const scope = this.name === 'notes' ? [this.name, 'block_revisions'] as const : [this.name, 'block_revisions', 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).putMany(values as StoreType<typeof this.name>[], keys));\n }\n const out: IDBValidKey[] = [];\n for (let i = 0; i < values.length; i++) out.push(await this.put(values[i], keys?.[i]));\n return out;\n }\n\n async delete(key: IDBValidKey | IDBKeyRange): Promise<void> {\n if (!this.mutable) throw new Error('read-only store');\n if (this.name === 'block_revisions') throw new Error('block history requires explicit wipe');\n if (!this.tx) {\n // Journal-time ownership classification reads notes in the same tx.\n const scope = this.name === 'notes' ? [this.name] as const : [this.name, 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).delete(key));\n }\n if (this.name === 'notes') {\n for (const note of await this.tx.objectStore('notes').getAll(key)) {\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const store = this.tx.objectStore(name);\n for (const id of await store.index('by-note').getAllKeys(note.id)) {\n const projection = new IDBStore(this.owner, name, this.tx, true, this.touched, this.journal);\n await projection.delete(id);\n }\n }\n }\n }\n await this.recordDelete(key);\n await this.tx.objectStore(this.name).delete(key);\n }\n\n /** Journal a delete as per-key tombstones (ranges expand to their keys).\n * Journal-time ownership: only deletes of USER-scope rows ship — a seed\n * row's removal is re-imported remotely, not a user mutation (deleting a\n * seed NOTE carries intent via the user-deleted-seed meta tombstone the\n * caller writes in the same transaction). */\n private async recordDelete(key: IDBValidKey | IDBKeyRange): Promise<void> {\n if (!this.journal) return;\n const store = this.tx!.objectStore(this.name);\n const keys = isKeyRange(key) ? await store.getAllKeys(key) : [key as IDBValidKey];\n const ctx = this.name === 'notes'\n ? undefined\n : await (this.journal.ctx ??= this.owner.policyContext(this.tx!));\n for (const k of keys) {\n const previous = await store.get(k);\n if (previous !== undefined && !isUserOwnedRow(this.name, previous, ctx ?? collectUserScopeContext([]))) continue;\n this.journal.ops.push({ op: 'delete', store: this.name, key: k as KeyDTO });\n }\n }\n\n /**\n * User-scope clear: expands to per-key deletes of user-owned rows,\n * journaled the same way so replay preserves exactly what the local clear\n * preserved — seed content (re-importable), pinned revision history\n * (block_revisions requires explicit wipe) and seed-deletion tombstones\n * survive a clear. A journaled `{op:'clear'}` would wipe seed rows on\n * every replaying device.\n */\n async clear(): Promise<void> {\n if (!this.mutable) throw new Error('read-only store');\n if (this.name === 'block_revisions') throw new Error('block history requires explicit wipe');\n if (!this.tx) {\n const scope = this.name === 'notes' ? ['notes', 'block_index', 'block_efforts'] as const : [this.name, 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).clear());\n }\n const store = this.tx.objectStore(this.name);\n const rows = await store.getAll() as unknown[];\n const notes = this.name === 'notes' ? rows : await this.tx.objectStore('notes').getAll() as unknown[];\n const ctx = collectUserScopeContext(notes);\n for (const row of rows) {\n const key = keyFromValue(STORE_DEFS.find(def => def.name === this.name)!, row);\n if (!isUserOwnedRow(this.name, row, ctx)) continue;\n if (this.name === 'meta' && typeof key === 'string' && key.startsWith(USER_DELETED_SEED_PREFIX)) continue;\n if (this.name === 'notes' && typeof key === 'string') {\n // Cascade the note's projections first — keys read BEFORE deletion,\n // each journaled as its own tombstone.\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const projections = this.tx.objectStore(name);\n for (const id of await projections.index('by-note').getAllKeys(key)) {\n this.journal?.ops.push({ op: 'delete', store: name, key: id as KeyDTO });\n await projections.delete(id);\n }\n }\n }\n await this.recordDelete(key);\n await store.delete(key);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Legacy row shapes (V20–V28) — read-only migration input, never written back.\n// ---------------------------------------------------------------------------\n\ninterface LegacySessionData {\n logs?: unknown[];\n startTime?: number;\n endTime?: number;\n duration?: number;\n completed?: boolean;\n roundsCompleted?: number;\n totalRounds?: number;\n repsCompleted?: number;\n}\n\ntype LegacySession = Session & { data?: LegacySessionData; segmentId?: string; segmentVersion?: number; version?: number };\n\ninterface LegacySegment {\n id: string;\n version: number;\n noteId: string;\n position?: number;\n dataType: string;\n rawContent: string;\n sourceContent?: string;\n createdAt: number;\n isHistory?: boolean;\n}\n\ninterface LegacyBlockIndexRow {\n id: string;\n noteId: string;\n segmentId: string;\n segmentVersion?: number;\n position?: number;\n dataType: string;\n rawContent: string;\n noteTitle: string;\n createdAt: number;\n isStatic?: boolean;\n sourceId?: string;\n sourcePath?: string;\n routeId?: string;\n blockContentId?: string;\n}\n\nconst SEGMENT_TO_BLOCK_KIND: Record<string, 'wod'> = { script: 'wod', wod: 'wod' };\n\nfunction legacyDialect(rawContent: string): { dialect?: 'time' | 'log'; sport?: string } {\n const first = rawContent.slice(0, rawContent.indexOf('\\n'));\n return matchDialectFence(first.trim()) ?? {};\n}\n\nexport class IndexedDBStorage implements IStorage {\n private opening?: Promise<IDBPDatabase>;\n constructor(private readonly options: {\n getUserId?: () => string;\n /** Called just before a schema migration runs (oldVersion < DB_VERSION). */\n onUpgradeStart?: (fromVersion: number) => void;\n /** Database file name; the sync engine migrates scratch copies under\n * their own name so a remote-schema conversion never touches the\n * live database. Defaults to the app database. */\n dbName?: string;\n } = {}) {}\n\n open(): Promise<IDBPDatabase> {\n if (typeof indexedDB === 'undefined') return Promise.reject(new Error('IndexedDB is unavailable in this environment'));\n if (!this.opening) {\n let newer = false;\n let pre20 = 0;\n let migrationError: Error | undefined;\n this.opening = openDB(this.options.dbName ?? IDB_DB_NAME, DB_VERSION, {\n upgrade: async (db, oldVersion, _version, tx) => {\n void tx.done.catch(() => {});\n if (oldVersion > DB_VERSION) {\n // A newer client owns this database — never downgrade or rewrite it.\n newer = true;\n tx.abort();\n return;\n }\n if (oldVersion !== 0 && oldVersion < 20) {\n // Pre-V20 layouts predate the versioned migration chain. Their\n // rows are NEVER silently destroyed: the upgrade aborts with an\n // actionable error so the user can export from an older app or\n // explicitly clear site data. The database file stays untouched.\n pre20 = oldVersion;\n tx.abort();\n return;\n }\n try {\n createMissingStores(db, tx);\n if (oldVersion !== 0 && oldVersion < DB_VERSION) this.options.onUpgradeStart?.(oldVersion);\n await migrateSchema(db, oldVersion, tx);\n } catch (error) {\n migrationError = error instanceof Error ? error : new Error(String(error));\n try { tx.abort(); } catch { /* The failed request may already have aborted it. */ }\n }\n },\n blocking: () => { void this.close(); },\n }).catch(error => {\n this.opening = undefined;\n if (migrationError) throw migrationError;\n if (pre20 !== 0) {\n throw new Error(\n `local database schema v${pre20} predates the supported migration chain (v20+). `\n + 'Open this browser profile in an intermediate app version to export your data, '\n + 'or clear site data to start fresh — the old database was left untouched.',\n );\n }\n throw newer || (error instanceof DOMException && error.name === 'VersionError')\n ? new Error(`database schema is newer than this client supports (v${DB_VERSION}); refusing to downgrade`) : error;\n });\n }\n return this.opening;\n }\n\n stamp(store: StoreName, value: unknown): unknown {\n const userId = this.options.getUserId?.();\n return userId ? stampUserOwned(store, value, userId) : value;\n }\n\n /** User-scope context (proven seed note ids) from the notes of `tx` —\n * journal-time ownership classification reads it INSIDE the same\n * transaction, so a seed import's note writes are visible to the link\n * writes that follow in the same commit. Internal seam for IDBStore. */\n async policyContext(tx?: Tx): Promise<UserScopeContext> {\n const notes = tx\n ? await tx.objectStore('notes').getAll() as unknown[]\n : await (await this.open()).getAll('notes') as unknown[];\n return collectUserScopeContext(notes);\n }\n\n readonly<K extends StoreName>(store: K): IReadOnlyStore<StoreType<K>> { return new IDBStore(this, store); }\n readwrite<K extends StoreName>(store: K): IReadWriteStore<StoreType<K>> { return new IDBStore(this, store, undefined, true); }\n\n async transaction<K extends StoreName, R>(stores: K[], mode: Mode, fn: (tx: IStorageTransaction) => Promise<R>): Promise<R> {\n const db = await this.open();\n const journal = mode === 'readwrite' ? new TxJournal() : undefined;\n const scope = new Set<string>(stores);\n if (mode === 'readwrite') {\n scope.add('block_revisions');\n scope.add(OUTBOX_STORE);\n scope.add('notes');\n if (scope.has('notes')) {\n scope.add('block_index');\n scope.add('block_efforts');\n scope.add('block_equipment');\n }\n }\n const native = db.transaction([...scope], mode) as Tx;\n const done = native.done;\n void done.catch(() => {});\n const touched = { notes: new Set<string>(), sessions: new Set<string>() };\n const adapter: IStorageTransaction = {\n readonly: name => {\n if (!scope.has(name)) throw new Error('store outside transaction scope');\n return new IDBStore(this, name, native);\n },\n readwrite: name => {\n if (mode !== 'readwrite') throw new Error('read-only transaction');\n if (!scope.has(name)) throw new Error('store outside transaction scope');\n return new IDBStore(this, name, native, true, touched, journal);\n },\n };\n try {\n const result = await fn(adapter);\n const notes = (await Promise.all([...touched.notes].map(id => native.objectStore('notes').get(id)))).filter(Boolean) as Note[];\n const sessions = (await Promise.all([...touched.sessions].map(id => native.objectStore('sessions').get(id)))).filter(Boolean) as Session[];\n await validateStoredPins(notes, sessions, keys => Promise.all(keys.map(key => native.objectStore('block_revisions').get(key))) as Promise<(BlockRevision | undefined)[]>);\n // Durable outbox: the journal entry lands in the SAME transaction as\n // the data writes — it commits with them and vanishes with them.\n if (journal && journal.ops.length > 0) {\n await native.objectStore(OUTBOX_STORE).put({ id: crypto.randomUUID(), at: Date.now(), ops: journal.ops });\n }\n await done;\n if (journal && journal.ops.length > 0) notifyOutboxCommit();\n return result;\n } catch (error) {\n try { native.abort(); } catch { /* The native request may have already aborted. */ }\n await done.catch(() => {});\n throw error;\n }\n }\n\n async wipeUserData(): Promise<void> {\n const names = STORE_DEFS.filter(def => !def.system && def.name !== 'block_revisions').map(def => def.name);\n await this.transaction(names, 'readwrite', async tx => {\n for (const name of names) await tx.readwrite(name).clear();\n });\n }\n\n async wipe(): Promise<void> {\n const db = await this.open();\n const names = STORE_DEFS.filter(def => !def.system).map(def => def.name);\n const tx = db.transaction([...names, OUTBOX_STORE], 'readwrite');\n await Promise.all(names.map(name => tx.objectStore(name).clear()));\n await tx.objectStore(OUTBOX_STORE).put({ id: crypto.randomUUID(), at: Date.now(), ops: [{ op: 'wipe' }] });\n await tx.done;\n notifyOutboxCommit();\n }\n\n // -----------------------------------------------------------------------\n // Sync seams (Turso backup engine only — not part of IStorage).\n // -----------------------------------------------------------------------\n\n /** Pending committed transaction groups, in commit order. */\n async readOutbox(afterSeq: number, limit: number): Promise<{ seq: number; id: string; at: number; ops: SyncMutation[] }[]> {\n const db = await this.open();\n const range = IDBKeyRange.lowerBound(afterSeq, true);\n // IDB counts are unsigned long — clamp callers' \"unbounded\" shorthand.\n return (await db.getAll(OUTBOX_STORE, range, Math.min(limit, 0xffffffff))) as { seq: number; id: string; at: number; ops: SyncMutation[] }[];\n }\n\n /** Drop acknowledged groups. Callers pass only the contiguous acked\n * watermark — a failed upload never truncates pending writes. */\n async ackOutbox(upToSeq: number): Promise<void> {\n const db = await this.open();\n const keys = await db.getAllKeys(OUTBOX_STORE, IDBKeyRange.upperBound(upToSeq));\n const tx = db.transaction(OUTBOX_STORE, 'readwrite');\n await Promise.all(keys.map(key => tx.store.delete(key)));\n await tx.done;\n }\n\n async getSyncState<T>(key: string): Promise<T | undefined> {\n const row = (await (await this.open()).get(SYNC_STATE_STORE, key)) as { value: T } | undefined;\n return row?.value;\n }\n\n async setSyncState(key: string, value: unknown): Promise<void> {\n await (await this.open()).put(SYNC_STATE_STORE, { key, value });\n }\n\n /**\n * Freeze ONE durable bootstrap run for `key` (per backup target): a\n * policy-compliant snapshot of the current rows, chunked into ≤500-op /\n * ≤~1MB entries with a unique run UUID and stable chunk ids, persisted in\n * `sync_state[key]` in the SAME readwrite transaction that reads the data\n * — so a retry returns the byte-identical frozen entries (idempotent\n * remote replays), and a crash before the commit freezes nothing. No\n * network happens here.\n *\n * Pending outbox groups are read INSIDE the same transaction: their\n * touched keys/stores are excluded from the snapshot so the journal (which\n * ships after the bootstrap, in commit order) stays the last writer and\n * nothing ships twice. A pending wipe freezes an empty run — the journal\n * wipe itself still ships and decides the remote's end state.\n *\n * The engine deletes the frozen run (`db.delete('sync_state', key)`) only\n * after the remote commit; until then every retry replays these entries.\n */\n async captureSyncBootstrap(key: string): Promise<SyncEntry[]> {\n const db = await this.open();\n const tx = db.transaction([...NON_SYSTEM_STORES, OUTBOX_STORE, SYNC_STATE_STORE], 'readwrite');\n const state = tx.objectStore(SYNC_STATE_STORE);\n const frozen = await state.get(key) as { value?: SyncEntry[] } | undefined;\n if (frozen !== undefined && Array.isArray(frozen.value)) {\n await tx.done;\n return frozen.value;\n }\n const pendingKeys = new Set<string>();\n const clearedStores = new Set<string>();\n let wiped = false;\n for (const group of await tx.objectStore(OUTBOX_STORE).getAll() as { ops: SyncMutation[] }[]) {\n for (const op of group.ops) {\n if (op.op === 'put' || op.op === 'delete') pendingKeys.add(`${op.store}:${JSON.stringify(op.key)}`);\n else if (op.op === 'clear') clearedStores.add(op.store);\n else wiped = true;\n }\n }\n const run = crypto.randomUUID();\n const entries: SyncEntry[] = [];\n if (!wiped) {\n let ops: SyncMutation[] = [];\n let bytes = 0;\n const flush = (): void => {\n if (ops.length === 0) return;\n entries.push({ id: `bootstrap:${run}:${entries.length}`, at: Date.now(), ops });\n ops = [];\n bytes = 0;\n };\n for (const op of await policySnapshotOps(store => tx.objectStore(store).getAll() as Promise<unknown[]>)) {\n if (clearedStores.has(op.store)) continue;\n // Immutable history is NEVER excluded: a snapshotted note/session\n // may pin a revision still pending in the journal, and the snapshot\n // ships first — the pinned revision must already be on the remote.\n // Revision-first op ordering keeps every chunk self-contained.\n if (op.store !== 'block_revisions' && pendingKeys.has(`${op.store}:${JSON.stringify(op.key)}`)) continue;\n const size = mutationBytes(op);\n if (ops.length > 0 && (ops.length >= BOOTSTRAP_MAX_OPS || bytes + size > BOOTSTRAP_MAX_BYTES)) flush();\n ops.push(op);\n bytes += size;\n }\n flush();\n }\n // Frozen BEFORE any network I/O — same transaction as the snapshot read.\n await state.put({ key, value: entries });\n await tx.done;\n return entries;\n }\n\n /**\n * Validate every stored pin (note blocks + session pins against\n * block_revisions) in ONE consistent readonly read — the post-restore\n * gate: a replayed backup with missing history fails loudly here instead\n * of surfacing later as broken sessions.\n */\n async validateSyncState(): Promise<void> {\n const db = await this.open();\n const tx = db.transaction(['notes', 'sessions', 'block_revisions'], 'readonly');\n const notes = await tx.objectStore('notes').getAll() as Note[];\n const sessions = await tx.objectStore('sessions').getAll() as Session[];\n const revisions = tx.objectStore('block_revisions');\n await validateStoredPins(\n notes,\n sessions,\n keys => Promise.all(keys.map(key => revisions.get(key))) as Promise<(BlockRevision | undefined)[]>,\n );\n await tx.done;\n }\n\n /**\n * Apply remotely committed mutations locally (pull/replay) WITHOUT\n * journaling — a pulled mutation must never re-enter the outbox. Runs in\n * one native transaction together with the cursor update.\n *\n * Unsent-edit overlay: pending outbox groups (committed local writes not\n * yet acknowledged remotely) are read INSIDE the same transaction and\n * replayed after the remote rows — a local edit/delete/clear/wipe that\n * committed while the pull was on the network stays the visible state;\n * the remote row is backed up locally, not clobbered over the user.\n *\n * Conflict policy (deterministic, history-preserving):\n * - notes: an incoming row with a LOWER sourceRevision than the existing\n * row is stale — skipped, never clobbers newer history.\n * - block_revisions: same key with different contents keeps BOTH rows —\n * the incoming version is re-keyed to the next free version for that\n * block. Immutable history is never silently replaced.\n * - memberships (system): remote mutations are skipped — identity truth\n * stays local and snapshot/upload never include them.\n *\n * Returns committed-boundary counts of canonical consumer records (notes +\n * efforts only; internal/journal rows never reach the sync toast).\n * `cursorKey` keeps cursors per backup target.\n */\n async applySyncMutations(\n mutations: SyncMutation[],\n cursorRev: number | null,\n cursorKey = 'cursor',\n ): Promise<{ added: number; updated: number }> {\n const defsByName = new Map<string, (typeof STORE_DEFS)[number]>(STORE_DEFS.map(def => [def.name, def]));\n for (const mutation of mutations) {\n if (mutation.op === 'clear' || mutation.op === 'wipe') continue;\n const def = defsByName.get(mutation.store);\n if (!def) throw new Error(`unknown store in sync mutation: ${String(mutation.store)}`);\n if (mutation.op === 'put' || mutation.op === 'delete') {\n const parts = Array.isArray(mutation.key) ? mutation.key : [mutation.key];\n if (parts.length !== def.keyPath.length || !parts.every(part => typeof part === 'string' || typeof part === 'number')) {\n throw new Error(`sync ${mutation.op} key arity/shape mismatch for ${mutation.store}`);\n }\n }\n if (mutation.op === 'put') validateStorageRow(mutation.store, mutation.value);\n }\n const db = await this.open();\n const names = NON_SYSTEM_STORES as StoreName[];\n const tx = db.transaction([...names, OUTBOX_STORE, SYNC_STATE_STORE], 'readwrite');\n\n // Counting baseline: every canonical key this batch touches, read before\n // any write lands.\n const canonical = (store: StoreName): store is 'notes' | 'efforts' => store === 'notes' || store === 'efforts';\n const touched = new Map<string, { store: 'notes' | 'efforts'; key: IDBValidKey; before: unknown; beforeExists: boolean }>();\n for (const mutation of mutations) {\n if (mutation.op === 'clear' || mutation.op === 'wipe') continue;\n if (!canonical(mutation.store)) continue;\n const id = `${mutation.store}:${JSON.stringify(mutation.key)}`;\n if (touched.has(id)) continue;\n const key = mutation.key as IDBValidKey;\n const before = await tx.objectStore(mutation.store).get(key);\n touched.set(id, { store: mutation.store, key, before, beforeExists: before !== undefined });\n }\n\n const applyOne = async (mutation: SyncMutation, preferLocal: boolean): Promise<void> => {\n if (mutation.op === 'wipe') {\n for (const name of names) await tx.objectStore(name).clear();\n return;\n }\n if (mutation.store === 'memberships') return; // system store: never applied remotely\n if (mutation.op === 'clear') {\n if (mutation.store === 'block_revisions') return;\n const store = tx.objectStore(mutation.store);\n const ctx = collectUserScopeContext(await tx.objectStore('notes').getAll());\n for (const row of await store.getAll()) {\n if (!isUserOwnedRow(mutation.store, row, ctx)) continue;\n const key = keyFromValue(defsByName.get(mutation.store)!, row);\n if (mutation.store === 'meta' && typeof key === 'string' && key.startsWith(USER_DELETED_SEED_PREFIX)) continue;\n await applyOne({ op: 'delete', store: mutation.store, key }, preferLocal);\n }\n return;\n }\n if (mutation.op === 'delete') {\n if (mutation.store === 'notes') {\n const noteId = String(Array.isArray(mutation.key) ? mutation.key[0] : mutation.key);\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const store = tx.objectStore(name);\n for (const id of await store.index('by-note').getAllKeys(noteId)) await store.delete(id);\n }\n }\n if (mutation.store !== 'block_revisions') await tx.objectStore(mutation.store).delete(mutation.key as IDBValidKey);\n return;\n }\n // put\n const store = tx.objectStore(mutation.store);\n if (mutation.store === 'block_revisions') {\n const existing = await store.get(mutation.key as IDBValidKey);\n if (existing !== undefined && !rowsEqual(existing, mutation.value) && !preferLocal) {\n // Immutable-history collision: preserve BOTH as versioned records —\n // the incoming row moves to the next free version for that block.\n // Both rows passed validateStorageRow when written (the incoming row\n // just above; the existing row at its original commit), so the\n // revision shape is guaranteed here.\n const incoming = mutation.value as BlockRevision;\n const existingRow = existing as BlockRevision;\n let version = existingRow.version + 1;\n while (await store.get([incoming.noteId, incoming.blockId, version] as IDBValidKey) !== undefined) version += 1;\n await store.put({ ...incoming, version });\n return;\n }\n if (existing === undefined || !rowsEqual(existing, mutation.value)) await store.put(mutation.value);\n return;\n }\n if (mutation.store === 'notes' && !preferLocal) {\n const existing = await store.get(mutation.key as IDBValidKey);\n // Same validateStorageRow guarantee as above: rows in the store carry\n // the note shape, so comparing source revisions is safe.\n if (existing !== undefined) {\n const existingNote = existing as Note;\n const incomingNote = mutation.value as Note;\n if (existingNote.sourceRevision > incomingNote.sourceRevision) return; // stale remote write\n }\n }\n await store.put(mutation.value);\n };\n\n for (const mutation of mutations) await applyOne(mutation, false);\n\n // Unsent-edit overlay: replay pending outbox groups in commit order so\n // the user's latest local writes remain the visible latest state.\n const pending = ((await tx.objectStore(OUTBOX_STORE).getAll()) as { seq: number; ops: SyncMutation[] }[])\n .sort((a, b) => a.seq - b.seq);\n for (const group of pending) {\n for (const op of group.ops) await applyOne(op, true);\n }\n\n // Committed-boundary counts: canonical notes/efforts whose final visible\n // value is new or changed relative to the pre-pull baseline.\n let added = 0;\n let updated = 0;\n for (const entry of touched.values()) {\n const final = await tx.objectStore(entry.store).get(entry.key);\n if (final === undefined) continue; // deleted by the batch — not an add/update\n if (!entry.beforeExists) added += 1;\n else if (!rowsEqual(entry.before, final)) updated += 1;\n }\n\n if (cursorRev !== null) await tx.objectStore(SYNC_STATE_STORE).put({ key: cursorKey, value: { rev: cursorRev } });\n await tx.done;\n return { added, updated };\n }\n\n /**\n * Consistent atomic snapshot, policy-compliant (shared user policy): only\n * user-scope rows of the non-system stores, read in ONE readonly\n * transaction — the backup never mixes the pre/post state of a concurrent\n * local commit. System stores (memberships) are excluded: they never sync.\n * Use `snapshotAllRows` for the lossless (unfiltered) form.\n */\n async snapshotRows(): Promise<{ store: StoreName; rows: unknown[] }[]> {\n const db = await this.open();\n const defs = STORE_DEFS.filter(def => !def.system);\n const tx = db.transaction(defs.map(def => def.name), 'readonly');\n // Ownership context comes from the SAME snapshot transaction — reading\n // notes before opening it could diverge from a concurrent note write.\n const ctx = collectUserScopeContext(await tx.objectStore('notes').getAll() as unknown[]);\n const out = await Promise.all(\n defs.map(async def => ({\n store: def.name,\n rows: ((await tx.objectStore(def.name).getAll() as unknown[])).filter(row => isUserOwnedRow(def.name, row, ctx)),\n })),\n );\n await tx.done;\n return out;\n }\n\n /** Lossless snapshot of every NON-SYSTEM store (meta included) in one\n * readonly transaction — local export / restore emptiness checks. A\n * freshly initialized database may hold a default membership, so the\n * system store is excluded from both uses. */\n async snapshotAllRows(): Promise<{ store: StoreName; rows: unknown[] }[]> {\n const db = await this.open();\n const defs = STORE_DEFS.filter(def => !def.system);\n const tx = db.transaction(defs.map(def => def.name), 'readonly');\n const out = await Promise.all(\n defs.map(async def => ({ store: def.name, rows: await tx.objectStore(def.name).getAll() as unknown[] })),\n );\n await tx.done;\n return out;\n }\n\n async close(): Promise<void> {\n const opening = this.opening;\n this.opening = undefined;\n (await opening?.catch(() => undefined))?.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cross-schema conversion — the exact IndexedDB upgrade chain on a scratch\n// database. Reads the source WITHOUT writing it; used by the CLI to migrate\n// older remotes into fresh v32 targets (trusted runtimes load\n// fake-indexeddb as the browser adapter first).\n// ---------------------------------------------------------------------------\n\ntype ScratchOp =\n | { kind: 'put'; table: string; row: unknown }\n | { kind: 'delete'; table: string; key: IDBValidKey }\n | { kind: 'clear'; table: string };\n\n/** Scratch layout: current stores plus the pre-V26 legacy tables. */\nconst SCRATCH_TABLES: readonly { name: string; keyPath: string[] }[] = [\n ...STORE_DEFS.map(def => ({ name: def.name, keyPath: def.keyPath })),\n ...LEGACY_EXTRA_TABLES.map(table => ({ name: table.name, keyPath: Array.isArray(table.keyPath) ? table.keyPath : [table.keyPath] })),\n];\n\nconst SCRATCH_TABLE_BY_NAME: Record<string, string[]> = Object.fromEntries(\n SCRATCH_TABLES.map(table => [table.name, table.keyPath]),\n);\n\nfunction assertKnownStore(store: string): void {\n if (!SCRATCH_TABLE_BY_NAME[store]) throw new Error(`unknown store \"${store}\" in source op log; copy aborted`);\n}\n\n/** Derive a row's key from its keyPath fields — malformed rows fail. */\nfunction rowKey(table: string, row: Record<string, unknown>): IDBValidKey {\n const parts: IDBValidKey[] = [];\n for (const part of SCRATCH_TABLE_BY_NAME[table]) {\n const value = row[part];\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date)) {\n throw new Error(`row for store \"${table}\" is missing keyPath field \"${part}\"; copy aborted`);\n }\n parts.push(value);\n }\n return parts.length === 1 ? parts[0] : parts;\n}\n\n/** Narrow a raw (unvalidated) op key to what IndexedDB accepts. */\nfunction isIdbKey(value: unknown): value is IDBValidKey {\n return typeof value === 'string' || typeof value === 'number' || value instanceof Date\n || (Array.isArray(value) && value.length > 0 && value.every(isIdbKey));\n}\n\nfunction arrayBuffersEqual(a: ArrayBuffer, b: ArrayBuffer): boolean {\n if (a.byteLength !== b.byteLength) return false;\n const left = new Uint8Array(a);\n const right = new Uint8Array(b);\n return left.every((byte, i) => byte === right[i]);\n}\n\nfunction deleteIdbDatabase(name: string): Promise<void> {\n const idb = globalThis.indexedDB;\n if (!idb) return Promise.resolve();\n return new Promise<void>((resolve, reject) => {\n const request = idb.deleteDatabase(name);\n request.onsuccess = () => { resolve(); };\n request.onerror = () => { reject(request.error ?? new Error(`failed to delete ${name}`)); };\n // A still-open connection blocks deletion; the scratch rows are\n // disposable either way, so don't hang the conversion on it.\n request.onblocked = () => { resolve(); };\n });\n}\n\n/** Replay raw remote-era rows into a unique scratch IndexedDB created at the\n * SOURCE schema version (generic keyPath-only stores + legacy tables), so\n * opening it through IndexedDBStorage runs the same versioned chain the\n * browser runs locally. */\nasync function buildScratch(name: string, version: number, ops: ScratchOp[]): Promise<void> {\n const db = await openDB(name, version, {\n upgrade(scratch) {\n for (const table of SCRATCH_TABLES) {\n if (!scratch.objectStoreNames.contains(table.name)) {\n scratch.createObjectStore(table.name, { keyPath: table.keyPath.length === 1 ? table.keyPath[0] : table.keyPath });\n }\n }\n },\n });\n try {\n for (const op of ops) {\n if (!db.objectStoreNames.contains(op.table)) {\n throw new Error(`unknown store \"${op.table}\" in source; copy aborted`);\n }\n if (op.kind === 'put') await db.transaction(op.table, 'readwrite').objectStore(op.table).put(op.row);\n else if (op.kind === 'delete') await db.transaction(op.table, 'readwrite').objectStore(op.table).delete(op.key);\n else await db.transaction(op.table, 'readwrite').objectStore(op.table).clear();\n }\n } finally {\n db.close();\n }\n}\n\n/** Attachment rows are the binary payload. The terminal source map replays\n * the lifted ops in order (puts, deletes, clears — wipes already expanded\n * to clears), so deleted/wiped attachments are NOT required to survive;\n * surviving ones must match the converted rows byte-for-byte (zero-byte\n * buffers are valid). */\nasync function assertBinaryPreserved(sourceOps: ScratchOp[], converted: IndexedDBStorage): Promise<void> {\n const source = new Map<string, Record<string, unknown>>();\n for (const op of sourceOps) {\n if (op.kind === 'clear') {\n if (op.table === 'attachments') source.clear();\n } else if (op.kind === 'put' && op.table === 'attachments') {\n if (op.row === null || typeof op.row !== 'object' || Array.isArray(op.row) || !('id' in op.row)) {\n throw new Error('malformed attachment row in source; copy aborted');\n }\n source.set(String((op.row as Record<string, unknown>).id), op.row as Record<string, unknown>);\n } else if (op.kind === 'delete' && op.table === 'attachments') {\n source.delete(String(op.key));\n }\n }\n if (source.size === 0) return;\n const rows = await converted.readonly('attachments').getAll();\n const byId = new Map(rows.map(row => [row.id, row]));\n for (const [id, row] of source) {\n const restored = byId.get(id);\n if (!restored) throw new Error(`attachment ${id} missing after conversion; copy aborted, source untouched`);\n const before = row.data;\n const after = restored.data;\n if (typeof before === 'string' || typeof after === 'string') {\n if (before !== after) throw new Error(`attachment ${id} payload changed during conversion; copy aborted, source untouched`);\n } else if (!(before instanceof ArrayBuffer) || !(after instanceof ArrayBuffer) || !arrayBuffersEqual(before, after)) {\n throw new Error(`attachment ${id} payload changed during conversion; copy aborted, source untouched`);\n }\n }\n}\n\n/**\n * Convert an older backup into policy-compliant current-schema mutations\n * WITHOUT touching the source:\n *\n * 1. Lift the source data as ordered scratch ops (op-log replay in log\n * order, or legacy direct-Turso per-store rows incl. segments/results).\n * 2. Replay them into a unique scratch IndexedDB created AT `fromVersion`,\n * then open it through IndexedDBStorage — the same versioned migration\n * chain the browser runs locally rebuilds segments-era rows into\n * note-owned blocks, revisions, sessions and events.\n * 3. Validate strictly (all note/session pins, binary payloads, derivable\n * keys — any miss fails the copy) and return policy-compliant PUTS ONLY\n * (the caller applies them to a fresh, reserved target).\n */\nexport async function convertSyncSource(db: Database, fromVersion: number, legacy: boolean): Promise<SyncMutation[]> {\n if (!Number.isSafeInteger(fromVersion) || fromVersion < 20) {\n throw new Error(\n `Backup database schema v${fromVersion} predates the supported migration chain (v20+); the source was left untouched. `\n + 'Restore it with an intermediate app version, or point this app at a fresh backup database.',\n );\n }\n if (fromVersion > DB_VERSION) {\n throw new Error(`Backup database schema is newer than this converter supports (v${fromVersion} > v${DB_VERSION}); refusing to downgrade.`);\n }\n const raw: ScratchOp[] = [];\n if (legacy) {\n for (const table of [...NON_SYSTEM_STORES, ...LEGACY_EXTRA_TABLES.map(table => table.name)]) {\n for (const row of await readLegacyRows(db, table)) raw.push({ kind: 'put', table, row });\n }\n } else {\n // Raw replay with STRICT lift-time validation (§3.5): unknown stores,\n // unknown ops, malformed payloads and put keys that disagree with the\n // row's own keyPath fields fail the copy before anything is replayed.\n for (const op of await readRawSyncOps(db)) {\n if (op.op === 'wipe') {\n for (const name of [...NON_SYSTEM_STORES, ...LEGACY_EXTRA_TABLES.map(table => table.name)]) {\n raw.push({ kind: 'clear', table: name });\n }\n } else if (op.op === 'clear') {\n assertKnownStore(op.store);\n raw.push({ kind: 'clear', table: op.store });\n } else if (op.op === 'put') {\n assertKnownStore(op.store);\n if (op.value === undefined || op.value === null || typeof op.value !== 'object' || Array.isArray(op.value)) {\n throw new Error(`malformed put payload for store \"${op.store}\" in source op log; copy aborted`);\n }\n if (JSON.stringify(rowKey(op.store, op.value as Record<string, unknown>)) !== JSON.stringify(op.key)) {\n throw new Error(`put key ${JSON.stringify(op.key)} does not match store \"${op.store}\" keyPath fields; copy aborted`);\n }\n raw.push({ kind: 'put', table: op.store, row: op.value });\n } else if (op.op === 'delete') {\n assertKnownStore(op.store);\n if (!isIdbKey(op.key)) {\n throw new Error(`malformed delete key for store \"${op.store}\" in source op log; copy aborted`);\n }\n raw.push({ kind: 'delete', table: op.store, key: op.key });\n } else {\n throw new Error(`unknown op \"${String((op as { op?: unknown }).op)}\" in source op log; copy aborted`);\n }\n }\n }\n const scratch = `wodwiki-convert-${crypto.randomUUID()}`;\n const converted = new IndexedDBStorage({ dbName: scratch });\n try {\n await buildScratch(scratch, fromVersion, raw);\n await converted.open();\n await converted.validateSyncState(); // strict: missing pinned revisions fail the copy\n await assertBinaryPreserved(raw, converted);\n return await policySnapshotOps(store => converted.readonly(store).getAll() as Promise<unknown[]>);\n } finally {\n await converted.close();\n await deleteIdbDatabase(scratch).catch(() => undefined);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Schema creation + versioned data migration (V20 → V32).\n// ---------------------------------------------------------------------------\n\nfunction createMissingStores(db: IDBPDatabase, tx: IDBPTransaction<unknown, string, 'versionchange'>): void {\n for (const def of STORE_DEFS) {\n if (db.objectStoreNames.contains(def.name)) {\n // Existing stores (pre-DB_VERSION layouts) keep whatever index set\n // they were born with — backfill indexes the current schema needs.\n const existing = tx.objectStore(def.name);\n for (const index of def.indexes) {\n if (!existing.indexNames.contains(index.name)) existing.createIndex(index.name, index.keyPath.length === 1 ? index.keyPath[0] : index.keyPath, { unique: index.unique, multiEntry: index.multiEntry });\n }\n continue;\n }\n const store = db.createObjectStore(def.name, { keyPath: def.keyPath.length === 1 ? def.keyPath[0] : def.keyPath });\n for (const index of def.indexes) store.createIndex(index.name, index.keyPath.length === 1 ? index.keyPath[0] : index.keyPath, { unique: index.unique, multiEntry: index.multiEntry });\n }\n for (const local of LOCAL_SYNC_STORES) {\n if (db.objectStoreNames.contains(local.name)) continue;\n db.createObjectStore(local.name, { keyPath: local.keyPath, autoIncrement: 'autoIncrement' in local ? local.autoIncrement : false });\n }\n}\n\nasync function migrateSchema(db: IDBPDatabase, oldVersion: number, tx: IDBPTransaction<unknown, string, 'versionchange'>): Promise<void> {\n const store = (name: string) => tx.objectStore(name);\n\n // V20 → V21: flatten sessions, drop data.logs, project legacy logs\n // idempotently into event rows.\n if (oldVersion === 20 && db.objectStoreNames.contains('sessions')) {\n const sessionsStore = store('sessions');\n const eventsStore = store('events');\n for await (const cursor of sessionsStore) {\n const legacy = cursor.value as LegacySession;\n const logs = legacy.data?.logs ?? [];\n let alreadyProjected = false;\n for await (const _ev of eventsStore.index('by-result-grain').iterate(IDBKeyRange.bound([legacy.id, ''], [legacy.id, []]))) {\n alreadyProjected = true;\n break;\n }\n if (!alreadyProjected && logs.length > 0) {\n const identity = {\n noteId: legacy.noteId, resultId: legacy.id, segmentId: legacy.segmentId,\n segmentVersion: legacy.segmentVersion, blockContentId: legacy.blockContentId,\n origin: legacy.origin, pageId: legacy.pageId,\n workoutTimestamp: legacy.data?.endTime ?? legacy.createdAt,\n };\n for (const row of toEventRows(logs as never, identity)) await eventsStore.put(row);\n for (const row of toSummaryEventRows(logs as never, identity)) await eventsStore.put(row);\n }\n const flat: Session = {\n ...legacy,\n startTime: legacy.data?.startTime ?? legacy.createdAt,\n endTime: legacy.data?.endTime ?? legacy.createdAt,\n duration: legacy.data?.duration ?? 0,\n completed: legacy.data?.completed ?? true,\n roundsCompleted: legacy.data?.roundsCompleted,\n totalRounds: legacy.data?.totalRounds,\n repsCompleted: legacy.data?.repsCompleted,\n };\n delete (flat as unknown as Record<string, unknown>).data;\n await cursor.update(flat);\n }\n }\n\n // V21 → V22: invalidate the pre-V22 seed checkpoint so the V22 seed\n // data re-applies cleanly.\n if (oldVersion === 21 && db.objectStoreNames.contains('meta')) {\n await store('meta').delete('seed');\n }\n\n // V25: memberships store + by-user ownership index on every user-owned\n // store. Presence-guarded: mixed-state databases exist in the wild.\n if (oldVersion < 25) {\n for (const name of USER_OWNED_STORES) {\n if (!db.objectStoreNames.contains(name)) continue;\n const s = store(name);\n if (!s.indexNames.contains('by-user')) s.createIndex('by-user', 'userId');\n }\n }\n\n // V26: results → sessions. Residual legacy rows are read BEFORE the store\n // disappears; inline logs are projected per deterministic id (existing\n // rows never overwritten, absent detail/summary rows added). The legacy\n // duplicate is discarded only after the canonical row is safe.\n if (db.objectStoreNames.contains('results')) {\n const sessionsStore = store('sessions');\n const resultsStore = store('results');\n const eventsStore = store('events');\n for await (const cursor of resultsStore) {\n const { data: legacyData, ...legacyRow } = cursor.value as LegacySession;\n const logs = legacyData?.logs ?? [];\n if (logs.length > 0) {\n const identity = {\n noteId: legacyRow.noteId, resultId: legacyRow.id, segmentId: legacyRow.segmentId,\n segmentVersion: legacyRow.segmentVersion, blockContentId: legacyRow.blockContentId,\n origin: legacyRow.origin, pageId: legacyRow.pageId,\n workoutTimestamp: legacyData?.endTime ?? legacyRow.createdAt,\n };\n for (const row of toEventRows(logs as never, identity)) {\n if ((await eventsStore.get(row.id)) === undefined) await eventsStore.put(row);\n }\n for (const row of toSummaryEventRows(logs as never, identity)) {\n if ((await eventsStore.get(row.id)) === undefined) await eventsStore.put(row);\n }\n }\n if ((await sessionsStore.getKey(legacyRow.id)) !== undefined) continue;\n await sessionsStore.put({\n ...legacyRow,\n startTime: legacyData?.startTime ?? legacyRow.startTime ?? legacyRow.createdAt,\n endTime: legacyData?.endTime ?? legacyRow.endTime ?? legacyRow.createdAt,\n duration: legacyData?.duration ?? legacyRow.duration ?? 0,\n completed: legacyData?.completed ?? legacyRow.completed ?? true,\n roundsCompleted: legacyData?.roundsCompleted ?? legacyRow.roundsCompleted,\n totalRounds: legacyData?.totalRounds ?? legacyRow.totalRounds,\n repsCompleted: legacyData?.repsCompleted ?? legacyRow.repsCompleted,\n });\n }\n db.deleteObjectStore('results');\n }\n\n // V26/V27 repairs (presence-guarded — the first V26 cut shipped without\n // these on real databases, so version 26 is ambiguous).\n if (db.objectStoreNames.contains('block_index') && !store('block_index').indexNames.contains('by-source')) {\n store('block_index').createIndex('by-source', 'sourceId');\n }\n if (db.objectStoreNames.contains('notes') && !store('notes').indexNames.contains('by-created')) {\n store('notes').createIndex('by-created', 'createdAt');\n }\n if (db.objectStoreNames.contains('efforts') && !store('efforts').indexNames.contains('by-source')) {\n store('efforts').createIndex('by-source', 'registrySource');\n }\n if (db.objectStoreNames.contains('note_tags') && !store('note_tags').indexNames.contains('by-note-tag')) {\n const noteTags = store('note_tags');\n // Unique pair index requires deterministic duplicate cleanup first —\n // duplicate links keep the lexicographically smallest row id.\n const winnerByPair = new Map<string, string>();\n const dupes: string[] = [];\n for await (const cursor of noteTags) {\n const row = cursor.value as { id: string; noteId: string; tagId: string };\n const pair = `${row.noteId}${row.tagId}`;\n const winner = winnerByPair.get(pair);\n if (winner === undefined || row.id < winner) {\n winnerByPair.set(pair, row.id);\n if (winner !== undefined) dupes.push(winner);\n } else {\n dupes.push(row.id);\n }\n }\n for (const id of dupes) await noteTags.delete(id);\n noteTags.createIndex('by-note-tag', ['noteId', 'tagId'], { unique: true });\n }\n\n // V28: dashboard typing repair — a note whose frontmatter segment says\n // `dashboard: true` gains type 'dashboard' / sourceId 'dashboards'.\n // Runs BEFORE the V29 pass consumes the segments store. Idempotent.\n if (db.objectStoreNames.contains('notes') && db.objectStoreNames.contains('segments')) {\n const segments = store('segments');\n const notes = store('notes');\n const repaired = new Set<string>();\n for await (const cursor of segments) {\n const segment = cursor.value as LegacySegment;\n if (segment.dataType !== 'frontmatter' || repaired.has(segment.noteId)) continue;\n if (!/(^|\\n)dashboard:\\s*[\"']?true[\"']?\\s*(\\n|$)/.test(segment.rawContent)) continue;\n repaired.add(segment.noteId);\n const note = await notes.get(segment.noteId);\n if (!note || (note.type === 'dashboard' && note.sourceId === 'dashboards')) continue;\n await notes.put({ ...note, type: 'dashboard', sourceId: note.sourceId ?? 'dashboards' });\n }\n }\n\n // V29: segments → note-owned blocks + block_revisions; sessions/events\n // segment fields → block fields; block_index rows remapped. The segments\n // store is dropped only after every note is rebuilt — the source of truth\n // survives until the migration transaction commits.\n if (db.objectStoreNames.contains('segments')) {\n await migrateSegmentsToBlocks(db, tx);\n }\n\n // V32: pending puts already exist in the terminal snapshot. Keep deletion\n // intent before that snapshot, with legacy wipes narrowed to user clears.\n // One group keeps history and its consumers together during replay.\n if (oldVersion >= 30 && oldVersion < 32 && db.objectStoreNames.contains(OUTBOX_STORE)) {\n const outbox = store(OUTBOX_STORE);\n const ops: SyncMutation[] = [];\n for (const group of await outbox.getAll() as { ops: SyncMutation[] }[]) {\n for (const mutation of group.ops) {\n if (mutation.op === 'wipe') {\n for (const name of NON_SYSTEM_STORES) {\n if (name !== 'block_revisions') ops.push({ op: 'clear', store: name });\n }\n } else if (mutation.op !== 'put' && mutation.store !== 'memberships' && mutation.store !== 'block_revisions') {\n ops.push(mutation);\n }\n }\n }\n ops.push(...await policySnapshotOps(name => store(name).getAll() as Promise<unknown[]>));\n await outbox.clear();\n if (ops.length > 0) await outbox.put({ id: crypto.randomUUID(), at: Date.now(), ops });\n if (db.objectStoreNames.contains(SYNC_STATE_STORE)) {\n const state = store(SYNC_STATE_STORE);\n for (const key of await state.getAllKeys()) {\n if (typeof key === 'string' && key.startsWith(BOOTSTRAP_RUN_PREFIX)) await state.delete(key);\n }\n }\n }\n}\n\nasync function migrateSegmentsToBlocks(db: IDBPDatabase, tx: IDBPTransaction<unknown, string, 'versionchange'>): Promise<void> {\n const store = (name: string) => tx.objectStore(name);\n const segments = (await store('segments').getAll()) as LegacySegment[];\n const notesStore = store('notes');\n const revisionsStore = store('block_revisions');\n\n // Group every versioned segment by note, then by positional segment id.\n const byNote = new Map<string, LegacySegment[]>();\n for (const segment of segments) {\n const list = byNote.get(segment.noteId);\n if (list) list.push(segment);\n else byNote.set(segment.noteId, [segment]);\n }\n\n // blockId per (noteId, segmentId) — sessions and block_index join through it.\n const blockIdBySegment = new Map<string, string>();\n const blockById = new Map<string, { noteId: string; from?: number; to?: number; version: number }>();\n\n for (const [noteId, noteSegments] of byNote) {\n const latestById = new Map<string, LegacySegment>();\n for (const segment of noteSegments) {\n const current = latestById.get(segment.id);\n if (!current || segment.version > current.version) latestById.set(segment.id, segment);\n }\n const latest = [...latestById.values()].sort((a, b) => (a.position ?? Number.MAX_SAFE_INTEGER) - (b.position ?? Number.MAX_SAFE_INTEGER) || a.id.localeCompare(b.id));\n const rawContent = latest.map(segment => segment.sourceContent ?? `${segment.rawContent}\\n`).join('');\n\n const note = await notesStore.get(noteId);\n if (!note) continue; // orphan segments without their note keep no state\n\n // Reconcile actionable blocks against the rebuilt source, preserving the\n // legacy positional segment id as the block id so session/block_index\n // references stay valid. Blocks with no legacy counterpart get a stable\n // positional id.\n const sections = parseDocumentSections(rawContent, { registeredWidgets: KNOWN_SECTION_WIDGETS });\n const actionableSections = sections.filter(section => actionableSectionKind(section) !== null);\n const legacyActionable = latest.filter(segment => segment.dataType in SEGMENT_TO_BLOCK_KIND);\n const blocks: Note['blocks'] = {};\n actionableSections.forEach((section, index) => {\n const kind = actionableSectionKind(section)!;\n const legacy = legacyActionable[index];\n let id = legacy?.id ?? `migrated-${index}`;\n while (Object.hasOwn(blocks, id)) id = `${id}-${index}`;\n const dialect = kind === 'wod' && (section.type === 'time' || section.type === 'log')\n ? { dialect: section.type, ...(section.sport ? { sport: section.sport } : {}) }\n : {};\n blocks[id] = { id, kind, version: legacy?.version ?? 1, sourceRevision: 1, from: section.from, to: section.to, ...dialect };\n if (legacy) blockIdBySegment.set(`${noteId}${legacy.id}`, id);\n blockById.set(`${noteId}${id}`, { noteId, from: section.from, to: section.to, version: blocks[id].version });\n });\n\n const legacy = note as Record<string, unknown>;\n delete legacy.segments;\n delete legacy.segmentIds;\n await notesStore.put({ ...legacy, rawContent, sourceRevision: 1, blocks });\n\n // Every versioned segment of an actionable id becomes a block revision\n // (historical segments included — the revision store is the history).\n const revisioned = new Set(legacyActionable.map(segment => segment.id));\n for (const segment of noteSegments) {\n if (!revisioned.has(segment.id)) continue;\n const dialect = legacyDialect(segment.rawContent);\n await revisionsStore.put({\n noteId, blockId: segment.id, version: segment.version, kind: 'wod',\n rawContent: segment.rawContent, savedAt: segment.createdAt, ...dialect,\n } satisfies BlockRevision);\n }\n }\n\n // Sessions: segmentId/segmentVersion (and the retired compute `version`)\n // become blockId/blockVersion. Values carry over unchanged — the V29 pass\n // above preserved legacy segment ids as block ids.\n const sessionsStore = store('sessions');\n for (const row of (await sessionsStore.getAll()) as LegacySession[]) {\n if (row.segmentId === undefined && row.segmentVersion === undefined && row.version === undefined) continue;\n const { segmentId, segmentVersion, version, ...rest } = row;\n await sessionsStore.put({\n ...rest,\n blockId: rest.blockId ?? segmentId ?? '',\n blockVersion: rest.blockVersion ?? segmentVersion ?? version ?? 1,\n } as Session);\n }\n\n // Events: same rename on the version field.\n const eventsStore = store('events');\n for (const row of await eventsStore.getAll() as Record<string, unknown>[]) {\n if (row.segmentVersion === undefined && row.segmentId === undefined) continue;\n const { segmentVersion, segmentId, ...rest } = row;\n await eventsStore.put({\n ...rest,\n ...(rest.blockId === undefined && segmentId !== undefined ? { blockId: segmentId } : {}),\n ...(rest.blockVersion === undefined && segmentVersion !== undefined ? { blockVersion: segmentVersion } : {}),\n });\n }\n\n // block_index: `${noteId}:${segmentId}:${segmentVersion}` →\n // `${noteId}:${blockId}` with the note block's offsets. Rows whose segment\n // vanished from the segments store keep their legacy id as the block id —\n // the index is a derived projection, never silently dropped.\n const blockIndex = store('block_index');\n for (const row of (await blockIndex.getAll()) as LegacyBlockIndexRow[]) {\n const mapped = blockIdBySegment.get(`${row.noteId}${row.segmentId}`) ?? row.segmentId;\n const block = blockById.get(`${row.noteId}${mapped}`);\n const next = {\n ...row,\n id: `${row.noteId}:${mapped}`,\n blockId: mapped,\n blockVersion: block?.version ?? row.segmentVersion ?? 1,\n sourceRevision: 1,\n ...(block ? { from: block.from, to: block.to } : {}),\n dataType: row.dataType === 'script' ? 'wod' : row.dataType,\n };\n delete (next as Record<string, unknown>).segmentId;\n delete (next as Record<string, unknown>).segmentVersion;\n if (next.id !== row.id) await blockIndex.delete(row.id);\n await blockIndex.put(next);\n }\n // block_efforts already carries blockId = the legacy positional segment id,\n // which the V29 pass preserved — no remap needed.\n\n db.deleteObjectStore('segments');\n}\n"]}
1
+ {"version":3,"sources":["../../src/schema.ts","../../src/idb/catalog.ts","../../src/membership.ts","../../src/wire.ts","../../src/sql/errors.ts","../../src/validation.ts","../../src/policy.ts","../../src/sql/codec.ts","../../src/sql/sync.ts","../../src/idb/index.ts"],"names":["a","b","validateNoteBlocks","record","def","matchDialectFence","openDB","store","table","toEventRows","toSummaryEventRows","parseDocumentSections","KNOWN_SECTION_WIDGETS","actionableSectionKind","legacy"],"mappings":"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","file":"index.cjs","sourcesContent":["/** Fresh schema shared by browser, SQL and in-memory adapters. */\n\nimport type { StoreName } from './contract';\n\n// DOMAIN_PROJECTION_VERSION lives in ./domain (re-exported by the package\n// index) — deliberately not re-exported here to avoid a star-export\n// ambiguity between ./schema and ./domain.\n\n// V30 adds the browser-local sync journal stores (sync_outbox/sync_state in\n// IndexedDBStorage) to the versioned browser schema. SQL/API StoreDefs are\n// UNCHANGED — the sync tables are layered separately (_wodwiki_sync_*) — so\n// SQL databases at v29 pass the StoreDef equality guard and migrate forward\n// without touching rows (see sql/store.ts initializeStore).\n//\n// V31 adds the `equipment` definition store and the `block_equipment`\n// containment-link store. Both are pure additions (no existing store's\n// keyPath, indexes or row shape changes), so initializeStore migrates v30\n// SQL databases by creating the two tables; every existing row survives.\n//\n// V32 is the user-scope sync cutover: no store/index/row shape changes —\n// the version bump marks the PAYLOAD semantics change (shared user policy,\n// policy-compliant snapshots/bootstraps). On upgrade the IndexedDB adapter\n// atomically converts any legacy full-data outbox: pending deletes and\n// user-scoped clears precede one terminal user snapshot. Legacy wipes\n// preserve peer seed rows and history. Seed-derived puts are omitted;\n// deletion intent still reaches independently converted targets. Old\n// full-data targets are NOT migrated in place by\n// ordinary sync — the CLI converts them into fresh wod-wiki-v32 targets.\nexport const DB_VERSION = 32;\n\n/**\n * Typed field metadata — column type per extracted field path, shared with\n * the API so its SQL DDL derives DOUBLE PRECISION / INTEGER / BOOLEAN /\n * TEXT from this table instead of a hardcoded per-index allowlist.\n *\n * Extraction rule (API side): a primary-key column `k<i>` takes the type of\n * STORE_DEFS store's keyPath[i]; an index column `i_<index>_<part>` takes the\n * type of that index's keyPath[part] here. Anything absent defaults to TEXT.\n * Civil-date strings stay TEXT on purpose (page.date is 'YYYY-MM-DD');\n * instants are epoch-ms numbers (notes.date, createdAt, timestamp).\n */\nexport type StorageColumnType = 'number' | 'text' | 'boolean';\n\nexport const COLUMN_TYPES: Record<StoreName, Record<string, StorageColumnType>> = {\n notes: { date: 'number', createdAt: 'number' },\n page: { createdAt: 'number' }, // page.date is a civil 'YYYY-MM-DD' string → TEXT\n page_notes: { position: 'number', createdAt: 'number' },\n tags: { createdAt: 'number' },\n tag_types: { createdAt: 'number' },\n note_tags: {},\n block_revisions: { version: 'number', savedAt: 'number' },\n sessions: {\n blockVersion: 'number',\n startTime: 'number',\n endTime: 'number',\n duration: 'number',\n roundsCompleted: 'number',\n totalRounds: 'number',\n repsCompleted: 'number',\n completed: 'boolean',\n createdAt: 'number',\n },\n attachments: { createdAt: 'number' },\n events: {\n timestamp: 'number',\n blockVersion: 'number',\n line: 'number',\n sourceStatementId: 'number',\n stackLevel: 'number',\n 'timeSpan.started': 'number',\n 'timeSpan.ended': 'number',\n },\n field_catalog: {},\n field_sources: {},\n field_values: {},\n field_catalog_meta: {},\n efforts: { 'baseAttributes.met': 'number' },\n equipment: {},\n block_index: {\n blockVersion: 'number',\n sourceRevision: 'number',\n from: 'number',\n to: 'number',\n position: 'number',\n createdAt: 'number',\n isStatic: 'boolean',\n },\n block_efforts: { createdAt: 'number', isStatic: 'boolean' },\n block_equipment: { createdAt: 'number', isStatic: 'boolean' },\n meta: {},\n memberships: { createdAt: 'number' },\n};\n\nexport interface IndexDef {\n name: string;\n keyPath: string[];\n unique?: boolean;\n multiEntry?: boolean;\n}\n\nexport interface StoreDef {\n name: StoreName;\n keyPath: string[];\n indexes: IndexDef[];\n /** System stores survive wipe() (identity must not be reset with data). */\n system?: boolean;\n}\n\nexport const STORE_DEFS: StoreDef[] = [\n // 1. notes\n { name: 'notes', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'] },\n { name: 'by-created', keyPath: ['createdAt'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2. page\n { name: 'page', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'], unique: true },\n { name: 'by-slug', keyPath: ['slug'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2b. page_notes (V22)\n { name: 'page_notes', keyPath: ['id'], indexes: [\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-page-note', keyPath: ['pageId', 'noteId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3. tags\n { name: 'tags', keyPath: ['id'], indexes: [\n { name: 'by-label', keyPath: ['label'], unique: true },\n { name: 'by-type', keyPath: ['type'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3a. tag_types (V23)\n { name: 'tag_types', keyPath: ['id'], indexes: [\n { name: 'by-name', keyPath: ['name'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 4. note_tags\n { name: 'note_tags', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-tag', keyPath: ['tagId'] },\n { name: 'by-note-tag', keyPath: ['noteId', 'tagId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n { name: 'block_revisions', keyPath: ['noteId', 'blockId', 'version'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-block', keyPath: ['noteId', 'blockId'] },\n ] },\n // 6. sessions\n { name: 'sessions', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-completed', keyPath: ['createdAt'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-block', keyPath: ['blockId'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-origin', keyPath: ['origin'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 8. attachments\n { name: 'attachments', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-time', keyPath: ['createdAt'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-result', keyPath: ['resultId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 9. events\n { name: 'events', keyPath: ['id'], indexes: [\n { name: 'by-timestamp', keyPath: ['timestamp'] },\n { name: 'by-result-grain', keyPath: ['resultId', 'grain'] },\n { name: 'by-content-grain', keyPath: ['blockContentId', 'grain'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-outputType', keyPath: ['outputType'] },\n { name: 'by-grain', keyPath: ['grain'] },\n { name: 'by-metric-date', keyPath: ['metricDateKeys'], multiEntry: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 10. field catalog\n { name: 'field_catalog', keyPath: ['id'], indexes: [\n { name: 'by-path', keyPath: ['path'] },\n ] },\n { name: 'field_sources', keyPath: ['id'], indexes: [] },\n { name: 'field_values', keyPath: ['key'], indexes: [\n { name: 'by-field', keyPath: ['fieldId'] },\n ] },\n { name: 'field_catalog_meta', keyPath: ['id'], indexes: [] },\n // 11. efforts\n { name: 'efforts', keyPath: ['slug'], indexes: [\n { name: 'by-discipline', keyPath: ['baseAttributes.discipline'] },\n { name: 'by-source', keyPath: ['registrySource'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 11b. equipment (V31) — canonical equipment definitions, keyed by slug\n { name: 'equipment', keyPath: ['slug'], indexes: [\n { name: 'by-source', keyPath: ['registrySource'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 12. block_index\n { name: 'block_index', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-type', keyPath: ['dataType'] },\n { name: 'by-source', keyPath: ['sourceId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 13. block_efforts\n { name: 'block_efforts', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-block', keyPath: ['blockContentId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 13b. block_equipment (V31) — containment links, mirroring block_efforts\n { name: 'block_equipment', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-equipment', keyPath: ['equipmentSlug'] },\n { name: 'by-block', keyPath: ['blockContentId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 14. meta\n { name: 'meta', keyPath: ['key'], indexes: [] },\n // 15. memberships (V25, system — survives wipe; truth lives in\n // localStorage locally, in the SQL table on the API)\n { name: 'memberships', keyPath: ['id'], indexes: [], system: true },\n];\n","/**\n * Local database catalog — enumerate/delete the browser-local IndexedDB\n * databases behind the active-profile selector. The default app database is\n * never created or destroyed here: the catalog only manages the auxiliary\n * (restore/scratch) databases that the database switcher offers.\n *\n * This module deliberately does NOT import the storage adapter: the adapter\n * lives in ./index, which re-exports this catalog, so an import back would\n * close a module cycle. Creating a database (which needs the adapter's\n * schema upgrade path) therefore lives beside the adapter in ./index.\n */\n\nexport interface LocalDatabaseInfo { name: string; version: number | null }\n\n/** Canonical app-database name (\"wodwiki-db\"). Defined HERE, not imported\n * from ./index, because the re-export cycle would read it before index.ts\n * initialized it (index.ts: export const IDB_DB_NAME = DEFAULT_LOCAL_DATABASE_NAME). */\nexport const DEFAULT_LOCAL_DATABASE_NAME: string = 'wodwiki-db';\n\n/** Same rule as the app-side isValidLocalDbName — one name vocabulary\n * everywhere (restore, catalog, settings persistence). */\nexport function isValidLocalDatabaseName(name: unknown): name is string {\n return typeof name === 'string' && /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(name);\n}\n\n/** Native enumeration when the browser exposes it; [] otherwise (old\n * Safari/Firefox lack databases()) — never throws. */\nexport async function listLocalDatabases(): Promise<LocalDatabaseInfo[]> {\n const idb = globalThis.indexedDB;\n if (!idb || typeof idb.databases !== 'function') return [];\n const entries = await idb.databases().catch(() => [] as IDBDatabaseInfo[]);\n return entries.flatMap((entry) =>\n typeof entry.name === 'string'\n ? [{ name: entry.name, version: typeof entry.version === 'number' ? entry.version : null }]\n : [],\n );\n}\n\n/** Delete one named database only; a blocked delete resolves (an open\n * connection elsewhere wins — the scratch data is disposable). */\nexport async function deleteLocalDatabase(name: string): Promise<void> {\n if (!isValidLocalDatabaseName(name)) throw new Error(`Invalid local database name \"${String(name)}\".`);\n const idb = globalThis.indexedDB;\n if (!idb) return;\n await new Promise<void>((resolve, reject) => {\n const request = idb.deleteDatabase(name);\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error ?? new Error(`Failed to delete local database \"${name}\".`));\n request.onblocked = () => resolve();\n });\n}\n","/**\n * membership.ts — identity contract shared by both backends.\n *\n * The single local membership (id 'default') is the owner of every\n * user-created record: adapters stamp `userId` onto rows on write (see\n * stampUserOwned), and the by-user index in STORE_DEFS is the ownership\n * crosswalk per store. Seed rows (seedOrigin === 'seed') stay unowned —\n * they are bundled content, not user data.\n */\n\nimport type { StoreName } from './contract';\nimport type { Membership } from './entities';\n\nexport const DEFAULT_MEMBERSHIP_ID = 'default';\n\nexport function createDefaultMembership(now: number = Date.now()): Membership {\n return { id: DEFAULT_MEMBERSHIP_ID, displayName: 'Anonymous', createdAt: now };\n}\n\n/** Stores that can hold user-created rows. Excluded: the pure seed catalog\n * (field_*), meta, and memberships itself. The by-user index in STORE_DEFS\n * mirrors this list — keep in lockstep. */\nexport const USER_OWNED_STORES: readonly StoreName[] = [\n 'notes', 'page', 'page_notes', 'tags', 'tag_types', 'note_tags',\n 'sessions', 'attachments', 'events',\n 'efforts', 'block_index', 'block_efforts',\n 'equipment', 'block_equipment',\n];\n\nconst STAMPABLE: Record<string, true> = Object.fromEntries(\n USER_OWNED_STORES.map((s) => [s, true as const])\n);\n\n/** Stamps `userId` onto a user-owned row. Seed rows pass through untouched;\n * already-stamped rows are returned as-is (no churn on re-put). Values in\n * non-user-owned stores are returned unchanged. */\nexport function stampUserOwned(store: StoreName, value: unknown, userId: string): unknown {\n if (!STAMPABLE[store]) return value;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n const row = value as Record<string, unknown>;\n if (row.seedOrigin === 'seed') return value;\n if (row.userId === userId) return value;\n return { ...row, userId };\n}\n","/**\n * Wire DTOs + key helpers shared by the storage client (ApiStorage) and the\n * API server. Keys are scalars or scalar tuples (keyPath order); ranges bound\n * them. Over HTTP, keys/ranges travel as urlencoded JSON query params.\n *\n * Range-typed helpers accept real IDBKeyRange instances AND plain RangeDTO\n * literals — non-IDB runtimes (Bun, node, tests) have no IDBKeyRange global,\n * so everything duck-types on field shape.\n */\n\nimport type { StoreName } from './contract';\nimport type { StoreDef } from './schema';\n\nexport type Scalar = string | number;\n\n/** Primary key: scalar for single-property keyPaths, tuple for compound. */\nexport type KeyDTO = Scalar | Scalar[];\n\nexport interface RangeDTO {\n only?: KeyDTO;\n /** Inclusive lower bound unless lowerOpen. Scalar or tuple (keyPath order). */\n lower?: KeyDTO;\n /** Inclusive upper bound unless upperOpen. Scalar or tuple (keyPath order). */\n upper?: KeyDTO;\n lowerOpen?: boolean;\n upperOpen?: boolean;\n}\n\nexport type TxOp =\n | { op: 'check'; store: StoreName; key: KeyDTO; value: unknown | null }\n | { op: 'put'; store: StoreName; value: unknown }\n | { op: 'delete'; store: StoreName; key: KeyDTO }\n | { op: 'clear'; store: StoreName };\n\n/** Anything shaped like a range: real IDBKeyRange or a plain RangeDTO literal. */\nexport function isRange(arg: unknown): arg is RangeDTO {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) &&\n ('only' in arg || 'lower' in arg || 'upper' in arg || 'lowerOpen' in arg || 'upperOpen' in arg);\n}\n\n/** Reads one dotted property path ('a.b.c') off a row. */\nexport function extractKeyPart(value: unknown, dottedPath: string): Scalar | undefined {\n let cur: unknown = value;\n for (const part of dottedPath.split('.')) {\n if (cur === null || typeof cur !== 'object') return undefined;\n // Dynamic key on an untyped row: index-signature view is the only way to read it.\n const row = cur as Record<string, unknown>;\n if (!(part in row)) return undefined;\n cur = row[part];\n }\n if (cur === null || typeof cur === 'object' || cur === undefined) return undefined;\n return cur as Scalar; // string/number/boolean leaf narrowed to the wire subset\n}\n\n/** Extracts a row's primary key per the store's inline keyPath. */\nexport function keyFromValue(def: StoreDef, value: unknown): KeyDTO {\n const parts = def.keyPath.map((p) => extractKeyPart(value, p));\n for (const [i, part] of parts.entries()) {\n if (part === undefined) {\n throw new Error(`keyFromValue(${def.name}): keyPath part '${def.keyPath[i]}' missing on value`);\n }\n }\n // Loop above proved every element defined.\n const key = parts as Scalar[];\n return key.length === 1 ? key[0] : key;\n}\n\n/** Canonical url-safe string form of a key (also the buffer/tx match key). */\nexport function encodeKey(key: KeyDTO): string {\n return encodeURIComponent(JSON.stringify(key));\n}\n\n/**\n * Converts an IndexedDB query — bare key, IDBKeyRange, or an already-wire\n * RangeDTO — to its wire form. Duck-types: objects with lower/upper/\n * lowerOpen/upperOpen fields (real ranges or plain literals) pass through;\n * scalars and tuple arrays become {only}.\n */\nexport function rangeFromIDB(query?: IDBValidKey | IDBKeyRange | RangeDTO): RangeDTO | undefined {\n if (query === undefined) return undefined;\n if (!isRange(query)) {\n // Bare IDBValidKey (scalar/tuple; exotic keys like Date pass through lossy).\n const key = query as KeyDTO;\n return { only: key };\n }\n if (query.only !== undefined) return query;\n const wire: RangeDTO = {};\n if (query.lower !== undefined && query.lower !== null) {\n wire.lower = query.lower;\n wire.lowerOpen = query.lowerOpen === true;\n }\n if (query.upper !== undefined && query.upper !== null) {\n // IDB upper bound idiom [prefix, []] uses [] > strings; normalize [] to \\uffff on wire.\n wire.upper = Array.isArray(query.upper)\n ? (query.upper.map((p) => (Array.isArray(p) && p.length === 0 ? '\\uffff' : p)) as KeyDTO)\n : query.upper;\n wire.upperOpen = query.upperOpen === true;\n }\n return wire.lower !== undefined || wire.upper !== undefined ? wire : undefined;\n}\n\n/** IndexedDB key ordering: numbers < strings < tuples; tuples lexicographic. */\nexport function compareKeys(a: KeyDTO, b: KeyDTO): number {\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return Array.isArray(a) ? 1 : -1;\n for (let i = 0; i < Math.min(a.length, b.length); i++) {\n const c = compareKeys(a[i], b[i]);\n if (c !== 0) return c;\n }\n return a.length - b.length;\n }\n if (typeof a === 'number' && typeof b === 'number') {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n if (typeof a === 'number' || typeof b === 'number') return typeof a === 'number' ? -1 : 1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** True when a key matches a wire range (IDB bound semantics). */\nexport function keyInRange(key: KeyDTO, range: RangeDTO): boolean {\n if (range.only !== undefined) return compareKeys(key, range.only) === 0;\n if (range.lower !== undefined) {\n const c = compareKeys(key, range.lower);\n if (c < 0 || (c === 0 && range.lowerOpen === true)) return false;\n }\n if (range.upper !== undefined) {\n const c = compareKeys(key, range.upper);\n if (c > 0 || (c === 0 && range.upperOpen === true)) return false;\n }\n return true;\n}\n","/**\n * StorageError — the single error type every shared SQL layer throws.\n * Replaces the API server's HTTP-specific error: `status` keeps the wire\n * mapping for the HTTP surface, `code` carries a stable machine identifier\n * (e.g. 'domain_projection_unavailable') for browser callers.\n */\nexport class StorageError extends Error {\n constructor(readonly status: number, message: string, readonly code?: string) {\n super(message);\n this.name = 'StorageError';\n }\n}\n","import { validateNoteBlocks, type BlockRevision, type Note, type Session } from '@bitcobblers/wod-wiki-core';\nimport type { StoreName } from './contract';\nimport { StorageError } from './sql/errors';\n\nexport function rowsEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (left instanceof ArrayBuffer && right instanceof ArrayBuffer) {\n const a = new Uint8Array(left), b = new Uint8Array(right);\n return a.length === b.length && a.every((value, i) => value === b[i]);\n }\n if (typeof left !== 'object' || left === null || typeof right !== 'object' || right === null) return false;\n if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right)\n && left.length === right.length && left.every((value, i) => rowsEqual(value, right[i]));\n const a = Object.keys(left).filter(key => Reflect.get(left, key) !== undefined);\n const b = Object.keys(right).filter(key => Reflect.get(right, key) !== undefined);\n return a.length === b.length && a.every(key => Object.hasOwn(right, key)\n && rowsEqual(Reflect.get(left, key), Reflect.get(right, key)));\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new StorageError(400, 'storage row must be an object');\n return value as Record<string, unknown>;\n}\n\nexport function validateStorageRow(store: StoreName, value: unknown): void {\n if (store !== 'notes' && store !== 'block_revisions' && store !== 'sessions' && store !== 'block_index') return;\n const row = record(value);\n const positive = (field: string): boolean => typeof row[field] === 'number' && Number.isSafeInteger(row[field]) && row[field] > 0;\n const required = (field: string): boolean => typeof row[field] === 'string' && row[field].length > 0;\n if (store === 'notes') {\n if (!required('id') || typeof row.title !== 'string' || typeof row.rawContent !== 'string'\n || !positive('sourceRevision') || typeof row.createdAt !== 'number' || !Number.isFinite(row.createdAt)\n || 'segments' in row || 'segmentIds' in row\n || (row.date !== undefined && (typeof row.date !== 'number' || !Number.isFinite(row.date)))\n || (row.seedOrigin !== undefined && row.seedOrigin !== 'seed' && row.seedOrigin !== 'user')\n || (row.feedOrigin !== undefined && row.feedOrigin !== 'feed' && row.feedOrigin !== 'user')\n // Feed provenance and seed provenance describe the same import: a\n // feed-delivered note carries the seed provenance it arrived with,\n // and the two kinds never contradict each other. A seed-delivered\n // note with NO feed stamp is the pre-migration state and stays valid\n // until the backfill repairs it.\n || (row.feedOrigin === 'feed' && (row.seedOrigin === undefined || typeof row.feedSourceId !== 'string' || row.feedSourceId.length === 0))\n || (row.feedOrigin === 'user' && row.seedOrigin === 'seed')\n || (row.feedSourceId !== undefined && row.feedOrigin !== 'feed')\n || (row.seedVersion !== undefined && !(typeof row.seedVersion === 'number' && Number.isSafeInteger(row.seedVersion) && row.seedVersion >= 0))\n || (row.tags !== undefined && (!Array.isArray(row.tags) || !row.tags.every(tag => typeof tag === 'string')))\n || ['type', 'sourceId', 'sourcePath', 'notebookId', 'seedChunkId', 'feedSourceId'].some(field => row[field] !== undefined && typeof row[field] !== 'string')) {\n throw new StorageError(400, 'invalid whole Note', 'invalid_note_blocks');\n }\n try { validateNoteBlocks(row.rawContent, record(row.blocks) as Note['blocks'], row.sourceRevision as number); }\n catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid block map', 'invalid_note_blocks'); }\n } else if (store === 'block_revisions') {\n if (!required('noteId') || !required('blockId') || !positive('version') || typeof row.rawContent !== 'string'\n || typeof row.savedAt !== 'number' || !Number.isFinite(row.savedAt)\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.kind))\n || (row.kind === 'wod' ? row.dialect !== 'time' && row.dialect !== 'log' : row.dialect !== undefined || row.sport !== undefined)\n || (row.sport !== undefined && typeof row.sport !== 'string')) throw new StorageError(400, 'invalid block revision', 'invalid_note_blocks');\n try {\n validateNoteBlocks(row.rawContent as string, { [String(row.blockId)]: {\n id: String(row.blockId), kind: row.kind as BlockRevision['kind'], version: row.version as number,\n sourceRevision: 1, from: 0, to: (row.rawContent as string).length,\n ...(row.dialect === undefined ? {} : { dialect: row.dialect as 'time' | 'log' }),\n ...(row.sport === undefined ? {} : { sport: row.sport as string }),\n } }, 1);\n } catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid revision source', 'invalid_note_blocks'); }\n } else if (store === 'sessions') {\n if (!required('noteId') || !required('blockId') || !positive('blockVersion')\n || ['segmentId', 'segmentVersion', 'version', 'rawContent', 'script', 'serializedScript', 'source', 'data', 'logs'].some(field => field in row)) {\n throw new StorageError(400, 'Session requires immutable block pin', 'invalid_session_pin');\n }\n } else if (!required('noteId') || !required('blockId') || !positive('blockVersion') || !positive('sourceRevision')\n || row.id !== `${row.noteId}:${row.blockId}` || !Number.isSafeInteger(row.from) || !Number.isSafeInteger(row.to)\n || 'segmentId' in row || 'segmentVersion' in row\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.dataType))\n || typeof row.rawContent !== 'string' || typeof row.noteTitle !== 'string'\n || typeof row.from !== 'number' || typeof row.to !== 'number' || row.from < 0 || row.to <= row.from) {\n throw new StorageError(400, 'invalid actionable block projection', 'invalid_note_blocks');\n }\n}\n\nexport function validateNoteWrite(previous: unknown, value: unknown): void {\n if (previous === undefined || rowsEqual(previous, value)) return;\n const before = record(previous), after = record(value);\n if (typeof before.sourceRevision !== 'number' || typeof after.sourceRevision !== 'number'\n || after.sourceRevision < before.sourceRevision\n || ((!rowsEqual(before.blocks, after.blocks) || before.rawContent !== after.rawContent)\n && after.sourceRevision <= before.sourceRevision)) throw new StorageError(409, 'stale Note source revision', 'transaction_conflict');\n}\n\nexport function validateSessionWrite(previous: unknown, value: unknown): void {\n if (previous === undefined) return;\n const before = record(previous), after = record(value);\n if (before.noteId !== after.noteId || before.blockId !== after.blockId || before.blockVersion !== after.blockVersion)\n throw new StorageError(409, 'Session pin is immutable', 'invalid_session_pin');\n}\n\nexport async function validateStoredPins(\n notes: Note[], sessions: Session[], getRevisions: (keys: IDBValidKey[]) => Promise<(BlockRevision | undefined)[]>,\n): Promise<void> {\n const keys: IDBValidKey[] = [];\n for (const note of notes) for (const block of Object.values(note.blocks)) keys.push([note.id, block.id, block.version]);\n for (const session of sessions) keys.push([session.noteId, session.blockId, session.blockVersion]);\n const revisions = await getRevisions(keys);\n let i = 0;\n for (const note of notes) for (const block of Object.values(note.blocks)) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== block.kind || revision.rawContent !== note.rawContent.slice(block.from, block.to)\n || revision.dialect !== block.dialect || revision.sport !== block.sport) throw new StorageError(409, 'Note block has no matching immutable revision', 'invalid_note_blocks');\n }\n for (let sessionIndex = 0; sessionIndex < sessions.length; sessionIndex++) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== 'wod') throw new StorageError(409, 'Session pin must reference a saved workout revision', 'invalid_session_pin');\n }\n}\n","/**\n * Shared user-scope sync policy (the backup/restore contract in\n * docs/architecture/interfaces.md).\n *\n * ONE ownership classification governs outbox journals, bootstrap\n * snapshots, the schema32 outbox cutover and cross-schema conversions. Rows\n * are classified by actual provenance — `seedOrigin` on notes, `isStatic`\n * plus owner note on projections, `registrySource` on bundled definitions,\n * `seed:` prefixes on meta checkpoints — never from `userId` or the ABSENCE\n * of a marker: uncertain rows are KEPT until their derivation and\n * reconstruction are proven.\n *\n * Excluded rows are exactly the ones the seed bundle re-derives: seed\n * notes, their static projections, bundled definitions and import\n * checkpoints. Everything else — sessions, events, attachments, revision\n * history, tags/pages/links, field-catalog data, non-seed meta — is user\n * data and always retained. Immutable block_revisions are kept\n * unconditionally until dependency closure is proven: sessions pin\n * revisions a re-import may not reproduce.\n */\n\nimport type { StoreName } from './contract';\n\n/** Durable seed-deletion intent: written atomically with the delete by\n * StorageService.deleteNote, honored by seed re-import (applySeedChunk) and\n * carried in every user-scope snapshot so fresh devices suppress too. */\nexport const USER_DELETED_SEED_PREFIX = 'user-deleted-seed:';\n\n/** Key constants shared by the writer (StorageService), the suppression\n * reader (seed runtime) and the policy passes — a durable contract. */\nexport function userDeletedSeedKey(noteId: string): string {\n return `${USER_DELETED_SEED_PREFIX}${noteId}`;\n}\n\n/** Inverse helper for readers; undefined for anything else. */\nexport function userDeletedSeedNoteId(key: unknown): string | undefined {\n if (typeof key !== 'string' || !key.startsWith(USER_DELETED_SEED_PREFIX)) return undefined;\n return key.slice(USER_DELETED_SEED_PREFIX.length) || undefined;\n}\n\n/** The one meta key family a user-scope snapshot excludes: import\n * checkpoints/claims (`seed:*`) are concurrency state re-derived from the\n * bundle. `user-deleted-seed:*` tombstones and every other key stay in. */\nexport function isSeedMetaKey(key: unknown): boolean {\n return typeof key === 'string' && key.startsWith('seed:');\n}\n\n/** Prior rows the policy needs: a projection's provenance is its owner\n * note's, so every policy pass collects seed note ids first. */\nexport interface UserScopeContext {\n seedNoteIds: ReadonlySet<string>;\n}\n\nexport function collectUserScopeContext(notes: readonly unknown[]): UserScopeContext {\n const seedNoteIds = new Set<string>();\n for (const row of notes) {\n if (row !== null && typeof row === 'object' && 'seedOrigin' in row\n && row.seedOrigin === 'seed' && 'id' in row && typeof row.id === 'string') {\n seedNoteIds.add(row.id);\n }\n }\n return { seedNoteIds };\n}\n\n/**\n * True when the row is user data a user-scope snapshot must retain.\n * Store-level default is true (keep uncertain rows); only provably\n * seed-rebuildable rows return false.\n */\nexport function isUserOwnedRow(store: StoreName, row: unknown, ctx: UserScopeContext): boolean {\n if (row === null || typeof row !== 'object') return true;\n switch (store) {\n case 'notes':\n return !('seedOrigin' in row && row.seedOrigin === 'seed');\n case 'block_index':\n case 'block_efforts':\n case 'block_equipment':\n // Static projections of seed notes are rebuilt by re-import; anything\n // else touching a seed note (user-created links included) is kept.\n return !('isStatic' in row && row.isStatic === true\n && 'noteId' in row && typeof row.noteId === 'string'\n && ctx.seedNoteIds.has(row.noteId));\n case 'efforts':\n case 'equipment':\n // 'bundled' is the provenance marker the seed importer writes;\n // 'user' and 'synthetic-unresolved' derive from user data.\n return !('registrySource' in row && row.registrySource === 'bundled');\n case 'meta':\n return !isSeedMetaKey('key' in row ? row.key : undefined);\n default:\n return true;\n }\n}\n","/**\n * Row codec for the SQL `data` column. Plain JSON.stringify destroys\n * ArrayBuffer values ({}); attachment rows carry raw blobs, so encoding tags\n * the declared binary field and decoding revives it.\n *\n * Collision safety: tagging applies ONLY to the declared binary field of the\n * declared store (attachments.data) — arbitrary rows (meta, notes, …) are\n * plain JSON in both directions, so authored {$binary:…}-shaped objects\n * anywhere else round-trip byte-for-byte. Within attachments.data the value\n * is typed `ArrayBuffer | string`; strings pass through, and only the exact\n * two-key tag revives.\n */\n\nconst TAG = '$binary';\nconst LEN = '$bytes';\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n let binary = '';\n const CHUNK = 0x8000; // String.fromCharCode.apply arg ceiling\n for (let i = 0; i < bytes.length; i += CHUNK) {\n binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));\n }\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length); // exact-length buffer: .buffer IS the decoded ArrayBuffer\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n/** Tag shape: exactly { $binary: base64, $bytes: length }. */\nfunction reviveBinary(value: unknown): unknown {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n const keys = Object.keys(value);\n if (keys.length !== 2 || !keys.includes(TAG) || !keys.includes(LEN)) return value;\n const tag = value as Record<string, unknown>;\n if (typeof tag[TAG] !== 'string' || typeof tag[LEN] !== 'number') return value;\n const bytes = base64ToBytes(tag[TAG]);\n if (bytes.length !== tag[LEN]) {\n throw new Error(`corrupt binary cell: declared ${tag[LEN]} bytes, decoded ${bytes.length}`);\n }\n return bytes.buffer;\n}\n\n/** Serialize a row; when `binaryField` is set and holds an ArrayBuffer, it is\n * replaced by the lossless tag (shallow copy — the input row is untouched). */\nconst canonicalJson = (_key: string, value: unknown): unknown => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n return Object.fromEntries(Object.keys(value).sort().map(key => [key, Reflect.get(value, key)]));\n};\nexport function encodeRowJson(value: unknown, binaryField?: string): string {\n if (binaryField && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const row = value as Record<string, unknown>;\n const data = row[binaryField];\n if (data instanceof ArrayBuffer) {\n const bytes = new Uint8Array(data);\n return JSON.stringify({ ...row, [binaryField]: { [TAG]: bytesToBase64(bytes), [LEN]: bytes.length } }, canonicalJson);\n }\n }\n return JSON.stringify(value, canonicalJson);\n}\n\n/** Parse a row; when `binaryField` is set, a tagged value there revives as an\n * ArrayBuffer. Every other value — including tag-shaped data in other fields\n * or stores — is returned exactly as authored. */\nexport function decodeRowJson<T = unknown>(text: string, binaryField?: string): T {\n const row = JSON.parse(text) as unknown;\n if (binaryField && row !== null && typeof row === 'object' && !Array.isArray(row)) {\n const record = row as Record<string, unknown>;\n const revived = reviveBinary(record[binaryField]);\n if (revived !== record[binaryField]) record[binaryField] = revived;\n }\n return row as T;\n}\n","/**\n * Turso backup/sync protocol — the local-first sync tables layered on top of\n * any libsql database. The browser data plane is always IndexedDB; a saved\n * Turso target is a backup/sync destination, never the read/write provider.\n *\n * Design: the remote holds ONE op log (`_wodwiki_sync_ops`) plus a state row\n * (`_wodwiki_sync_state`) carrying {schema, rev}. Every committed local\n * transaction group appends one idempotent op-group (uuid op_id,\n * INSERT-or-ignore per op); `rev` is assigned monotonically per NEWLY applied\n * group — a retried group is recognized by its first op id, consumes no rev\n * and appends nothing. Pulls replay ops with rev > cursor in deterministic\n * (rev, idx) order. Tombstones (delete/clear/wipe) are ordinary ops —\n * deletions propagate.\n *\n * Fetch atomicity: a pull window is a set of WHOLE revision groups. The rev\n * boundary is chosen with a bounded subquery, then every row of those revs is\n * returned — a group is never split, so the cursor never skips the rest of\n * a group (one pathologically large group can exceed the nominal row bound;\n * that is the unavoidable atomicity ceiling).\n *\n * ponytail: op-log replay pulls — a fresh browser replays the whole log\n * (O(history)) instead of reading per-store current-state tables. Upgrade\n * path: add per-store state tables rev-indexed by primary key and collapse\n * the log into them periodically; the wire format (op_id, rev, mutation)\n * stays unchanged.\n *\n * Never-downgrade rule: the state row's `schema` is the managing client's\n * DB_VERSION at init time. Uploads verify `schema` INSIDE the write\n * transaction. Older schemas require explicit conversion into a fresh\n * target with the source retained; newer schemas are never rewritten.\n */\n\nimport { STORE_DEFS } from '../schema';\nimport type { StoreName } from '../contract';\nimport type { KeyDTO, Scalar } from '../wire';\nimport { keyFromValue } from '../wire';\nimport { rowsEqual } from '../validation';\nimport { decodeRowJson, encodeRowJson } from './codec';\nimport { StorageError } from './errors';\nimport { SCHEMA_TABLE } from './store';\nimport type { Database, SqlConnection, SqlStatement } from './connection';\n\nexport const SYNC_OPS_TABLE = '_wodwiki_sync_ops';\nexport const SYNC_STATE_TABLE = '_wodwiki_sync_state';\n\n/** One committed local transaction group, as journaled in IndexedDB. */\nexport type SyncMutation =\n | { op: 'put'; store: StoreName; key: KeyDTO; value: unknown }\n | { op: 'delete'; store: StoreName; key: KeyDTO }\n | { op: 'clear'; store: StoreName }\n | { op: 'wipe' };\n\nexport interface SyncEntry {\n /** Idempotency key — one uuid per committed local transaction group. */\n id: string;\n at: number;\n ops: SyncMutation[];\n}\n\nexport interface StoredSyncOp {\n opId: string;\n rev: number;\n idx: number;\n at: number;\n mutation: SyncMutation;\n}\n\nexport type SyncTargetKind =\n /** No tables at all (beyond libsql internals): fresh database. */\n | 'empty'\n /** Tables exist but neither sync state nor a legacy schema guard — not\n * ours; initializing over unknown data is refused by the caller. */\n | { kind: 'unknown' }\n /** Legacy direct-Turso SqlStorage layout (`_wodwiki_schema` guard). */\n | { kind: 'legacy'; schemaVersion: number }\n /** This sync protocol's layout; payload = state row. */\n | { kind: 'current'; schemaVersion: number; rev: number };\n\ninterface SyncStateRow {\n schema: number;\n rev: number;\n}\n\n/** Stores whose rows carry a raw binary field the codec must preserve. */\nconst BINARY_FIELD: Record<string, string> = { attachments: 'data' };\n\nconst STORE_NAMES: Record<string, true> = Object.fromEntries(STORE_DEFS.map((d) => [d.name, true]));\n\nconst STATE_KEY = 'meta';\n\nfunction isSafeInt(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value);\n}\n\nfunction isScalar(value: unknown): value is Scalar {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n}\n\n/** Trust-boundary key check — mirrors wire.validateKey (kept local to keep\n * the sql subpath free of runtime wire imports beyond types). */\nfunction assertKey(key: unknown, what: string): asserts key is KeyDTO {\n if (isScalar(key)) return;\n if (Array.isArray(key) && key.length > 0 && key.every(isScalar)) return;\n throw new StorageError(400, `${what} must be a string, finite number, or non-empty scalar tuple`, 'bad_sync_key');\n}\n\n/** Validate one decoded mutation at the external-data trust boundary. */\nfunction validateMutation(raw: unknown): SyncMutation {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new StorageError(400, 'sync mutation must be an object', 'bad_sync_mutation');\n }\n const mutation = raw as Record<string, unknown>;\n if (mutation.op === 'wipe') return { op: 'wipe' };\n if (typeof mutation.store !== 'string' || !STORE_NAMES[mutation.store]) {\n throw new StorageError(400, `sync mutation has unknown store ${String(mutation.store)}`, 'bad_sync_mutation');\n }\n const store = mutation.store as StoreName;\n if (mutation.op === 'clear') return { op: 'clear', store };\n if (mutation.op === 'delete') {\n assertKey(mutation.key, 'sync delete key');\n return { op: 'delete', store, key: mutation.key };\n }\n if (mutation.op === 'put') {\n assertKey(mutation.key, 'sync put key');\n if (mutation.value === null || typeof mutation.value !== 'object' || Array.isArray(mutation.value)) {\n throw new StorageError(400, 'sync put value must be an object row', 'bad_sync_mutation');\n }\n const def = STORE_DEFS.find(def => def.name === store)!;\n const valueKey = keyFromValue(def, mutation.value);\n assertKey(valueKey, 'sync row key');\n if (!rowsEqual(mutation.key, valueKey)) {\n throw new StorageError(400, 'sync put key differs from row key', 'bad_sync_key');\n }\n return { op: 'put', store, key: mutation.key, value: mutation.value };\n }\n throw new StorageError(400, `sync mutation has unknown op ${String(mutation.op)}`, 'bad_sync_mutation');\n}\n\nfunction validateEntry(entry: SyncEntry): void {\n if (typeof entry.id !== 'string' || entry.id.length === 0 || entry.id.length > 200) {\n throw new StorageError(400, 'sync entry id must be a non-empty string', 'bad_sync_entry');\n }\n if (!isSafeInt(entry.at) || entry.at < 0) {\n throw new StorageError(400, 'sync entry at must be a non-negative safe integer', 'bad_sync_entry');\n }\n if (!Array.isArray(entry.ops) || entry.ops.length === 0) {\n throw new StorageError(400, 'sync entry ops must be a non-empty array', 'bad_sync_entry');\n }\n for (const op of entry.ops) validateMutation(op);\n}\n\n/** Run statements inside a transaction, preferring one native batch. */\nasync function runStatements(tx: SqlConnection, statements: SqlStatement[]): Promise<unknown[][]> {\n if (statements.length === 0) return [];\n if (tx.batch) return tx.batch(statements);\n const results: unknown[][] = [];\n for (const statement of statements) {\n results.push(await tx.query(statement.sql, statement.params ?? []));\n }\n return results;\n}\n\nasync function tableExists(conn: SqlConnection, dialect: Database['dialect'], name: string): Promise<boolean> {\n const sql = dialect === 'postgres'\n ? `SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1`\n : `SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`;\n return (await conn.query(sql, [name])).length > 0;\n}\n\n/** Read + validate the sync state row (trusted shape afterwards). */\nasync function readSyncState(tx: SqlConnection): Promise<SyncStateRow> {\n const rows = await tx.query(`SELECT \"value\" FROM \"${SYNC_STATE_TABLE}\" WHERE \"key\" = ?`, [STATE_KEY]);\n if (!rows[0]) throw new StorageError(409, 'sync target is not initialized', 'sync_not_initialized');\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(rows[0].value));\n } catch {\n throw new StorageError(400, 'malformed sync state row', 'bad_sync_state');\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new StorageError(400, 'malformed sync state row', 'bad_sync_state');\n }\n const state = parsed as Record<string, unknown>;\n if (!isSafeInt(state.schema) || state.schema < 0 || !isSafeInt(state.rev) || state.rev < 0) {\n throw new StorageError(400, 'sync state schema/rev must be non-negative safe integers', 'bad_sync_state');\n }\n return { schema: state.schema, rev: state.rev };\n}\n\n/** Classify the sync target WITHOUT mutating it. */\nexport async function probeSyncTarget(db: Database): Promise<SyncTargetKind> {\n if (await tableExists(db, db.dialect, SYNC_STATE_TABLE)) {\n const state = await readSyncState(db);\n return { kind: 'current', schemaVersion: state.schema, rev: state.rev };\n }\n if (await tableExists(db, db.dialect, SCHEMA_TABLE)) {\n const rows = await db.query(`SELECT \"value\" FROM \"${SCHEMA_TABLE}\" WHERE \"key\" = 'schema'`);\n if (rows[0]) {\n const guard = JSON.parse(String(rows[0].value)) as { version?: unknown };\n if (typeof guard.version === 'number' && Number.isSafeInteger(guard.version) && guard.version >= 0) {\n return { kind: 'legacy', schemaVersion: guard.version };\n }\n }\n return { kind: 'legacy', schemaVersion: 0 };\n }\n // Fresh-vs-unknown: any user table we do not own means foreign data.\n const others = await db.query(\n db.dialect === 'postgres'\n ? `SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'`\n : `SELECT name FROM sqlite_master WHERE type = 'table'`,\n );\n const internal = (name: string): boolean => name.startsWith('_wodwiki_') || name.startsWith('sqlite_');\n return others.some((row) => !internal(String(Object.values(row)[0]))) ? { kind: 'unknown' } : 'empty';\n}\n\n/** Create the sync tables + state row. Only for empty targets; existing\n * state (current, legacy or unknown) is never overwritten by init. */\nexport async function initSyncTarget(db: Database, schemaVersion: number): Promise<void> {\n await db.transaction(async (tx) => {\n await tx.exec(`CREATE TABLE IF NOT EXISTS \"${SYNC_STATE_TABLE}\" (\"key\" TEXT PRIMARY KEY, \"value\" TEXT NOT NULL)`);\n await tx.exec(\n `CREATE TABLE IF NOT EXISTS \"${SYNC_OPS_TABLE}\" (` +\n `\"op_id\" TEXT PRIMARY KEY, \"rev\" INTEGER NOT NULL, \"idx\" INTEGER NOT NULL, \"at\" INTEGER NOT NULL, \"data\" TEXT NOT NULL)`,\n );\n await tx.exec(\n `CREATE INDEX IF NOT EXISTS \"${SYNC_OPS_TABLE}_rev\" ON \"${SYNC_OPS_TABLE}\" (\"rev\", \"idx\")`,\n );\n await tx.exec(\n `INSERT INTO \"${SYNC_STATE_TABLE}\" (\"key\", \"value\") VALUES (?, ?) ON CONFLICT (\"key\") DO NOTHING`,\n [STATE_KEY, JSON.stringify({ schema: schemaVersion, rev: 0 } satisfies SyncStateRow)],\n );\n });\n}\n\nfunction encodeMutation(mutation: SyncMutation): string {\n if (mutation.op !== 'put') return JSON.stringify(mutation);\n // The binary codec applies to the ROW (mutation.value), not the mutation\n // envelope — attachments.data carries the raw bytes.\n const encoded = encodeRowJson(mutation.value, BINARY_FIELD[mutation.store]);\n return `{\"key\":${JSON.stringify(mutation.key)},\"op\":\"put\",\"store\":${JSON.stringify(mutation.store)},\"value\":${encoded}}`;\n}\n\n/** Decode + validate one stored op payload at the external-data boundary. */\nfunction decodeMutation(data: unknown): SyncMutation {\n if (typeof data !== 'string') {\n throw new StorageError(400, 'sync op data must be a string', 'bad_sync_mutation');\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n throw new StorageError(400, 'sync op data is not valid JSON', 'bad_sync_mutation');\n }\n const mutation = validateMutation(parsed);\n if (mutation.op !== 'put') return mutation;\n return {\n op: 'put',\n store: mutation.store,\n key: mutation.key,\n value: decodeRowJson(JSON.stringify(mutation.value), BINARY_FIELD[mutation.store]),\n };\n}\n\nexport interface ApplySyncBatchOptions {\n /** Schema the caller verified at probe time — rechecked INSIDE the write\n * transaction so a schema change between probe and append aborts. */\n expectSchema?: number;\n}\n\n/**\n * Append op-groups to the log in ONE SQL transaction, idempotently by\n * group: a group whose first op id already exists is skipped entirely and\n * consumes no rev (retries never duplicate, never allocate revisions).\n * Returns the number of NEW groups committed — ack semantics for the\n * uploader's watermark.\n */\nexport async function applySyncBatch(\n db: Database,\n entries: SyncEntry[],\n opts: ApplySyncBatchOptions = {},\n): Promise<number> {\n if (entries.length === 0) return 0;\n for (const entry of entries) validateEntry(entry);\n return db.transaction(async (tx) => {\n const state = await readSyncState(tx);\n if (opts.expectSchema !== undefined && state.schema !== opts.expectSchema) {\n throw new StorageError(\n 409,\n `sync target schema changed from v${opts.expectSchema} to v${state.schema} between probe and write — retry the cycle`,\n 'sync_schema_conflict',\n );\n }\n // Group presence: one lookup on every group's first op id. Groups are\n // written whole by construction, so first-op presence ⇔ group present.\n const firstIds = entries.map((entry) => `${entry.id}:0`);\n const present = new Set<string>();\n for (let i = 0; i < firstIds.length; i += 100) {\n const chunk = firstIds.slice(i, i + 100);\n const rows = await tx.query(\n `SELECT \"op_id\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"op_id\" IN (${chunk.map(() => '?').join(', ')})`,\n chunk,\n );\n for (const row of rows) present.add(String(row.op_id));\n }\n const statements: SqlStatement[] = [];\n let rev = state.rev;\n let committed = 0;\n for (const entry of entries) {\n if (present.has(`${entry.id}:0`)) continue;\n rev += 1;\n committed += 1;\n entry.ops.forEach((mutation, idx) => {\n statements.push({\n sql:\n `INSERT INTO \"${SYNC_OPS_TABLE}\" (\"op_id\", \"rev\", \"idx\", \"at\", \"data\") VALUES (?, ?, ?, ?, ?) ` +\n `ON CONFLICT (\"op_id\") DO NOTHING`,\n params: [`${entry.id}:${idx}`, rev, idx, entry.at, encodeMutation(mutation)],\n });\n });\n }\n statements.push({\n sql: `UPDATE \"${SYNC_STATE_TABLE}\" SET \"value\" = ? WHERE \"key\" = ?`,\n params: [JSON.stringify({ schema: state.schema, rev } satisfies SyncStateRow), STATE_KEY],\n });\n await runStatements(tx, statements);\n return committed;\n });\n}\n\n/**\n * Replay window: ops with rev > afterRev, in deterministic commit order.\n * The window covers WHOLE revision groups: up to `limit` distinct revs are\n * chosen (bounded subquery), then every row of those revs is returned, so a\n * cursor advanced to the last returned rev never splits a group. A single\n * group larger than `limit` is returned whole — the atomicity ceiling.\n */\nexport async function fetchSyncOps(db: Database, afterRev: number, limit: number): Promise<StoredSyncOp[]> {\n if (!isSafeInt(afterRev) || afterRev < 0) {\n throw new StorageError(400, 'fetchSyncOps cursor must be a non-negative safe integer', 'bad_sync_cursor');\n }\n const bounded = Math.min(Math.max(1, Math.floor(limit)), 0xffffffff);\n const revRows = await db.query(\n `SELECT DISTINCT \"rev\" FROM (SELECT \"rev\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"rev\" > ? ORDER BY \"rev\" ASC LIMIT ?)`,\n [afterRev, bounded],\n );\n const revs = revRows.map((row) => {\n const rev = Number(row.rev);\n if (!Number.isSafeInteger(rev) || rev < 0) {\n throw new StorageError(400, 'sync op rev must be a non-negative safe integer', 'bad_sync_row');\n }\n return rev;\n });\n if (revs.length === 0) return [];\n const rows = await db.query(\n `SELECT \"op_id\", \"rev\", \"idx\", \"at\", \"data\" FROM \"${SYNC_OPS_TABLE}\" WHERE \"rev\" IN (${revs.map(() => '?').join(', ')}) ORDER BY \"rev\", \"idx\"`,\n revs,\n );\n return rows.map((row, at) => {\n const opId = row.op_id;\n const rev = Number(row.rev);\n const idx = Number(row.idx);\n const atMs = Number(row.at);\n if (typeof opId !== 'string' || opId.length === 0 || !Number.isSafeInteger(rev) || rev < 0\n || !Number.isSafeInteger(idx) || idx < 0 || !Number.isSafeInteger(atMs) || atMs < 0) {\n throw new StorageError(400, `sync op row ${at} has malformed shape`, 'bad_sync_row');\n }\n return { opId, rev, idx, at: atMs, mutation: decodeMutation(row.data) };\n });\n}\n\n/** Migration-only raw replay: parsed op payloads WITHOUT store/key validation\n * (old logs reference era store names like `segments`). Only\n * convertSyncSource consumes this; ordinary pulls validate every row\n * against the current schema. Binary cells revive. */\nexport type RawSyncOp =\n | { op: 'wipe' }\n | { op: 'clear'; store: string }\n | { op: 'delete'; store: string; key: unknown }\n | { op: 'put'; store: string; key: unknown; value: unknown };\n\nexport async function readRawSyncOps(db: Database): Promise<RawSyncOp[]> {\n const rows = await db.query(`SELECT \"rev\", \"idx\", \"data\" FROM \"${SYNC_OPS_TABLE}\" ORDER BY \"rev\", \"idx\"`);\n return rows.map((row) => {\n const rev = Number(row.rev);\n const idx = Number(row.idx);\n if (!Number.isSafeInteger(rev) || rev < 0 || !Number.isSafeInteger(idx) || idx < 0 || typeof row.data !== 'string') {\n throw new StorageError(400, 'sync op row has malformed shape', 'bad_sync_row');\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(row.data);\n } catch {\n throw new StorageError(400, 'sync op data is not valid JSON', 'bad_sync_row');\n }\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new StorageError(400, 'sync op data must be an object', 'bad_sync_row');\n }\n const mutation = parsed as Record<string, unknown>;\n if (mutation.op === 'wipe') return { op: 'wipe' };\n if (typeof mutation.store !== 'string') {\n throw new StorageError(400, 'sync op must carry a string store', 'bad_sync_row');\n }\n if (mutation.op === 'clear') return { op: 'clear', store: mutation.store };\n if (mutation.op === 'delete') return { op: 'delete', store: mutation.store, key: mutation.key };\n if (mutation.op !== 'put' || mutation.value === null || typeof mutation.value !== 'object' || Array.isArray(mutation.value)) {\n throw new StorageError(400, 'sync op has an unknown operation or invalid row', 'bad_sync_row');\n }\n return {\n op: 'put',\n store: mutation.store,\n key: mutation.key,\n value: decodeRowJson(JSON.stringify(mutation.value), BINARY_FIELD[mutation.store]),\n };\n });\n}\n\n/**\n * Import rows from a legacy direct-Turso (SqlStorage) database into op-\n * groups. Reads the per-store JSON `data` columns directly — the legacy\n * schema guard may hold an older version SqlStorage refuses to open, so the\n * rows are lifted raw, never through SqlStorage. Missing tables contribute\n * no rows; nothing is written or deleted remotely.\n */\nexport async function readLegacyRows(db: Database, table: string): Promise<unknown[]> {\n if (!(await tableExists(db, db.dialect, table))) return [];\n const rows = await db.query(`SELECT \"data\" FROM \"${table}\"`);\n return rows.map((row) => decodeRowJson(String(row.data), BINARY_FIELD[table]));\n}\n","/**\n * IndexedDB adapter — the browser data plane (moved verbatim from the\n * playground app; the shared user policy and the schema32 sync cutover live\n * here now). Local-first invariants:\n *\n * - Every committed local transaction group is durable in `sync_outbox`,\n * written in the SAME native transaction as the data writes.\n * - Snapshots (`snapshotRows`, bootstrap, conversion) are policy-compliant:\n * they carry user data only, per the shared policy in `../policy`.\n * - `sync_state` holds pull cursors, upload watermarks and frozen\n * bootstrap runs (durable retry identities), all per backup target.\n */\n\nimport { openDB, type IDBPDatabase, type IDBPTransaction } from 'idb';\nimport type {\n IReadOnlyStore, IReadWriteStore, IStorage, IStorageTransaction, StoreName, StoreType,\n} from '../contract';\nimport { DB_VERSION, STORE_DEFS } from '../schema';\nimport {\n DEFAULT_LOCAL_DATABASE_NAME, isValidLocalDatabaseName, type LocalDatabaseInfo,\n} from './catalog';\nimport { USER_OWNED_STORES, stampUserOwned } from '../membership';\nimport { keyFromValue, type KeyDTO } from '../wire';\nimport type { Note, Session, BlockRevision } from '../entities';\nimport {\n rowsEqual, validateStorageRow, validateNoteWrite, validateSessionWrite, validateStoredPins,\n} from '../validation';\nimport { collectUserScopeContext, isUserOwnedRow, USER_DELETED_SEED_PREFIX, type UserScopeContext } from '../policy';\nimport { readRawSyncOps, readLegacyRows, type SyncEntry, type SyncMutation } from '../sql/sync';\nimport type { Database } from '../sql/connection';\nimport {\n parseDocumentSections, actionableSectionKind, matchDialectFence, KNOWN_SECTION_WIDGETS,\n} from '@bitcobblers/wod-wiki-core';\nimport { toEventRows, toSummaryEventRows } from '@bitcobblers/wod-wiki-wql';\n\nexport const IDB_DB_NAME = DEFAULT_LOCAL_DATABASE_NAME;\n\nexport {\n DEFAULT_LOCAL_DATABASE_NAME, deleteLocalDatabase,\n isValidLocalDatabaseName, listLocalDatabases, type LocalDatabaseInfo,\n} from './catalog';\n\n/** Create a named database at the current schema (DB_VERSION) by opening it\n * through the regular adapter, then close. Refuses the default database —\n * the catalog never touches the live app profile.\n *\n * Lives beside the adapter (not in ./catalog) because it needs the\n * adapter's schema upgrade path, and the adapter's module re-exports the\n * catalog — importing the adapter back from the catalog would close a\n * module cycle. */\nexport async function createLocalDatabase(name: string): Promise<LocalDatabaseInfo> {\n if (!isValidLocalDatabaseName(name)) throw new Error(`Invalid local database name \"${String(name)}\".`);\n if (name === DEFAULT_LOCAL_DATABASE_NAME) throw new Error('The default database cannot be created here.');\n const storage = new IndexedDBStorage({ dbName: name });\n try {\n await storage.open();\n } finally {\n await storage.close().catch(() => undefined);\n }\n return { name, version: DB_VERSION };\n}\n\n// Browser-local sync stores — NOT part of the shared STORE_DEFS spec (the\n// SQL/API schema is unchanged). `sync_outbox` is the durable journal: one\n// entry per committed local transaction group, written in the SAME native\n// transaction as the data writes, so an aborted transaction never journals\n// and a journaled group always reflects committed data. `sync_state` holds\n// the pull cursor, the upload watermark and frozen bootstrap runs.\nconst OUTBOX_STORE = 'sync_outbox';\nconst SYNC_STATE_STORE = 'sync_state';\nconst LOCAL_SYNC_STORES = [\n { name: OUTBOX_STORE, keyPath: 'seq', autoIncrement: true },\n { name: SYNC_STATE_STORE, keyPath: 'key' },\n] as const;\n\n/** sync_state keys of frozen bootstrap runs (TursoSyncEngine naming). */\nconst BOOTSTRAP_RUN_PREFIX = 'bootstrap-run:';\n\nconst NON_SYSTEM_STORES: readonly StoreName[] = STORE_DEFS.filter(def => !def.system).map(def => def.name);\n\n// Bootstrap chunks: whole ops only, bounded per group for network batches.\nconst BOOTSTRAP_MAX_OPS = 500;\nconst BOOTSTRAP_MAX_BYTES = 1_000_000;\n\n/** Stores whose rows carry a raw binary field (base64 in the op log). */\nconst BINARY_SYNC_FIELDS: Record<string, string> = { attachments: 'data' };\n\n/** Legacy direct-Turso tables that predate the current STORE_DEFS spec. */\nconst LEGACY_EXTRA_TABLES: { name: string; keyPath: string | string[] }[] = [\n { name: 'segments', keyPath: ['id', 'version'] },\n { name: 'results', keyPath: 'id' },\n];\n\ntype Mode = 'readonly' | 'readwrite';\n/** Native tx handle; write methods are guarded at runtime by `mutable`, so\n * the handle is typed readwrite to keep put/delete/clear defined. */\ntype Tx = IDBPTransaction<unknown, string, 'readwrite'>;\n\n/** Per-transaction mutation collector — becomes one outbox entry on commit.\n * `ctx` lazily caches the tx's user-scope context (seed note ids) for\n * journal-time ownership classification; invalidated when notes change. */\nclass TxJournal {\n readonly ops: SyncMutation[] = [];\n ctx?: Promise<UserScopeContext>;\n}\n\n/** Post-commit outbox notification — the sync engine debounces uploads off\n * these instead of polling the network while the app is idle. Fired only\n * AFTER the committing transaction durably lands (fire-and-forget). */\nconst outboxListeners = new Set<() => void>();\n\nexport function subscribeOutboxWrites(listener: () => void): () => void {\n outboxListeners.add(listener);\n return () => {\n outboxListeners.delete(listener);\n };\n}\n\nfunction notifyOutboxCommit(): void {\n for (const listener of outboxListeners) listener();\n}\n\nfunction isKeyRange(key: unknown): key is IDBKeyRange {\n return key !== null && typeof key === 'object' && !Array.isArray(key)\n && ('lower' in key || 'upper' in key || 'lowerOpen' in key || 'upperOpen' in key);\n}\n\n/** Approximate encoded op-log size of one mutation: JSON envelope plus\n * base64-inflated binary cells (ArrayBuffer serializes as {} in JSON, so a\n * plain JSON.stringify would undercount attachment-heavy batches). */\nfunction mutationBytes(op: SyncMutation): number {\n if (op.op !== 'put') return 32; // envelope + key estimate\n let bytes = 32;\n const field = BINARY_SYNC_FIELDS[op.store];\n const value: unknown = op.value;\n const data = field && value !== null && typeof value === 'object' && !Array.isArray(value) && field in value\n ? Reflect.get(value, field)\n : undefined;\n bytes += typeof data === 'string' ? data.length\n : data instanceof ArrayBuffer ? Math.ceil(data.byteLength / 3) * 4 + 64\n : JSON.stringify(op.value)?.length ?? 0;\n return bytes;\n}\n\n/**\n * One policy-compliant snapshot as put mutations, in STORE_DEFS order.\n * Strict: a row whose key cannot be derived is corrupted data — it fails\n * the pass instead of being silently dropped.\n *\n * Immutable revision history is emitted BEFORE notes and sessions so chunk\n * boundaries (bootstrap/conversion grouping) can never split a pin from the\n * revision it references: every chunk that carries a consumer row already\n * carries its history.\n */\nconst SNAPSHOT_OP_ORDER: readonly StoreName[] = [\n 'block_revisions',\n 'notes',\n 'sessions',\n ...NON_SYSTEM_STORES.filter(\n name => name !== 'block_revisions' && name !== 'notes' && name !== 'sessions',\n ),\n];\n\n/** Snapshot ops are always puts — narrowed so callers can read store/key. */\ntype SnapshotPut = Extract<SyncMutation, { op: 'put' }>;\n\nasync function policySnapshotOps(\n readAll: (store: StoreName) => Promise<unknown[]>,\n): Promise<SnapshotPut[]> {\n const ctx = collectUserScopeContext(await readAll('notes'));\n const ops: SnapshotPut[] = [];\n for (const store of SNAPSHOT_OP_ORDER) {\n const def = STORE_DEFS.find(candidate => candidate.name === store)!;\n for (const row of await readAll(store)) {\n if (!isUserOwnedRow(store, row, ctx)) continue;\n ops.push({ op: 'put', store, key: keyFromValue(def, row), value: row });\n }\n }\n return ops;\n}\n\nclass IDBStore<T> implements IReadWriteStore<T> {\n constructor(\n private readonly owner: IndexedDBStorage,\n private readonly name: StoreName,\n private readonly tx?: Tx,\n private readonly mutable = false,\n private readonly touched?: { notes: Set<string>; sessions: Set<string> },\n private readonly journal?: TxJournal,\n ) {}\n\n async get(key: IDBValidKey): Promise<T | undefined> {\n if (this.tx) return this.tx.objectStore(this.name).get(key);\n return (await this.owner.open()).get(this.name, key);\n }\n\n async getMany(keys: IDBValidKey[]): Promise<(T | undefined)[]> {\n if (this.tx) return Promise.all(keys.map(key => this.tx!.objectStore(this.name).get(key)));\n return this.owner.transaction([this.name], 'readonly', tx => tx.readonly(this.name).getMany(keys)) as Promise<(T | undefined)[]>;\n }\n\n async getAll(query?: IDBValidKey | IDBKeyRange, count?: number): Promise<T[]> {\n if (this.tx) return this.tx.objectStore(this.name).getAll(query, count);\n return (await this.owner.open()).getAll(this.name, query, count);\n }\n\n async getAllFromIndex(index: string, query?: IDBValidKey | IDBKeyRange, count?: number): Promise<T[]> {\n if (this.tx) return this.tx.objectStore(this.name).index(index).getAll(query, count);\n return (await this.owner.open()).getAllFromIndex(this.name, index, query, count);\n }\n\n async getAllFromIndexMany(index: string, keys: IDBValidKey[]): Promise<T[][]> {\n if (this.tx) return Promise.all(keys.map(key => this.tx!.objectStore(this.name).index(index).getAll(key)));\n return this.owner.transaction([this.name], 'readonly', tx => tx.readonly(this.name).getAllFromIndexMany(index, keys)) as Promise<T[][]>;\n }\n\n async count(query?: IDBValidKey | IDBKeyRange): Promise<number> {\n if (this.tx) return this.tx.objectStore(this.name).count(query);\n return (await this.owner.open()).count(this.name, query);\n }\n\n async countFromIndex(index: string, query?: IDBValidKey | IDBKeyRange): Promise<number> {\n if (this.tx) return this.tx.objectStore(this.name).index(index).count(query);\n return (await this.owner.open()).countFromIndex(this.name, index, query);\n }\n\n async put(value: T, _key?: IDBValidKey): Promise<IDBValidKey> {\n if (!this.mutable) throw new Error('read-only store');\n if (!this.tx) {\n const scope = this.name === 'notes' ? [this.name, 'block_revisions'] as const : [this.name, 'block_revisions', 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).put(value as StoreType<typeof this.name>));\n }\n const stored = this.owner.stamp(this.name, value);\n validateStorageRow(this.name, stored);\n const def = STORE_DEFS.find(def => def.name === this.name)!;\n const key = keyFromValue(def, stored);\n const store = this.tx.objectStore(this.name);\n const previous = await store.get(key);\n if (this.name === 'block_revisions' && previous !== undefined && !rowsEqual(previous, stored)) throw new Error('immutable block revision collision');\n if (this.name === 'notes') validateNoteWrite(previous, stored);\n if (this.name === 'sessions') validateSessionWrite(previous, stored);\n if (rowsEqual(previous, stored)) return key;\n const result = await store.put(stored);\n if (!def.system && this.journal) {\n // Journal-time ownership classification (§3.4), INSIDE the write\n // transaction: user→user and seed→user emit complete user puts;\n // seed→seed ships nothing (the remote re-imports seed data itself);\n // user→seed emits a tombstone for the former user record instead of\n // silently dropping it.\n const ctx = this.name === 'notes'\n ? undefined\n : await (this.journal.ctx ??= this.owner.policyContext(this.tx!));\n const wasUser = previous !== undefined && isUserOwnedRow(this.name, previous, ctx ?? collectUserScopeContext([]));\n const isUser = isUserOwnedRow(this.name, stored, ctx ?? collectUserScopeContext([]));\n if (isUser) {\n if (this.name === 'notes' && stored !== null && typeof stored === 'object' && 'id' in stored) {\n for (const revision of await this.tx.objectStore('block_revisions').index('by-note').getAll(String(stored.id))) {\n this.journal.ops.push({ op: 'put', store: 'block_revisions', key: [revision.noteId, revision.blockId, revision.version], value: revision });\n }\n } else if (this.name === 'sessions' && stored !== null && typeof stored === 'object' && 'noteId' in stored && 'blockId' in stored && 'blockVersion' in stored) {\n const revisionKey = [stored.noteId, stored.blockId, stored.blockVersion] as IDBValidKey;\n const revision = await this.tx.objectStore('block_revisions').get(revisionKey);\n if (revision) this.journal.ops.push({ op: 'put', store: 'block_revisions', key: revisionKey as KeyDTO, value: revision });\n }\n this.journal.ops.push({ op: 'put', store: this.name, key: key as KeyDTO, value: stored });\n }\n else if (wasUser) this.journal.ops.push({ op: 'delete', store: this.name, key: key as KeyDTO });\n // notes writes shift seed provenance — reclassify later stores in\n // this transaction against the post-write notes.\n if (this.name === 'notes') this.journal.ctx = undefined;\n }\n if (this.name === 'notes') this.touched?.notes.add(String(key));\n if (this.name === 'sessions') this.touched?.sessions.add(String(key));\n return result;\n }\n\n async putMany(values: T[], keys?: IDBValidKey[]): Promise<IDBValidKey[]> {\n if (keys && keys.length !== values.length) throw new Error('putMany key count mismatch');\n if (!this.tx) {\n const scope = this.name === 'notes' ? [this.name, 'block_revisions'] as const : [this.name, 'block_revisions', 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).putMany(values as StoreType<typeof this.name>[], keys));\n }\n const out: IDBValidKey[] = [];\n for (let i = 0; i < values.length; i++) out.push(await this.put(values[i], keys?.[i]));\n return out;\n }\n\n async delete(key: IDBValidKey | IDBKeyRange): Promise<void> {\n if (!this.mutable) throw new Error('read-only store');\n if (this.name === 'block_revisions') throw new Error('block history requires explicit wipe');\n if (!this.tx) {\n // Journal-time ownership classification reads notes in the same tx.\n const scope = this.name === 'notes' ? [this.name] as const : [this.name, 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).delete(key));\n }\n if (this.name === 'notes') {\n for (const note of await this.tx.objectStore('notes').getAll(key)) {\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const store = this.tx.objectStore(name);\n for (const id of await store.index('by-note').getAllKeys(note.id)) {\n const projection = new IDBStore(this.owner, name, this.tx, true, this.touched, this.journal);\n await projection.delete(id);\n }\n }\n }\n }\n await this.recordDelete(key);\n await this.tx.objectStore(this.name).delete(key);\n }\n\n /** Journal a delete as per-key tombstones (ranges expand to their keys).\n * Journal-time ownership: only deletes of USER-scope rows ship — a seed\n * row's removal is re-imported remotely, not a user mutation (deleting a\n * seed NOTE carries intent via the user-deleted-seed meta tombstone the\n * caller writes in the same transaction). */\n private async recordDelete(key: IDBValidKey | IDBKeyRange): Promise<void> {\n if (!this.journal) return;\n const store = this.tx!.objectStore(this.name);\n const keys = isKeyRange(key) ? await store.getAllKeys(key) : [key as IDBValidKey];\n const ctx = this.name === 'notes'\n ? undefined\n : await (this.journal.ctx ??= this.owner.policyContext(this.tx!));\n for (const k of keys) {\n const previous = await store.get(k);\n if (previous !== undefined && !isUserOwnedRow(this.name, previous, ctx ?? collectUserScopeContext([]))) continue;\n this.journal.ops.push({ op: 'delete', store: this.name, key: k as KeyDTO });\n }\n }\n\n /**\n * User-scope clear: expands to per-key deletes of user-owned rows,\n * journaled the same way so replay preserves exactly what the local clear\n * preserved — seed content (re-importable), pinned revision history\n * (block_revisions requires explicit wipe) and seed-deletion tombstones\n * survive a clear. A journaled `{op:'clear'}` would wipe seed rows on\n * every replaying device.\n */\n async clear(): Promise<void> {\n if (!this.mutable) throw new Error('read-only store');\n if (this.name === 'block_revisions') throw new Error('block history requires explicit wipe');\n if (!this.tx) {\n const scope = this.name === 'notes' ? ['notes', 'block_index', 'block_efforts'] as const : [this.name, 'notes'] as const;\n return this.owner.transaction([...scope], 'readwrite', tx => tx.readwrite(this.name).clear());\n }\n const store = this.tx.objectStore(this.name);\n const rows = await store.getAll() as unknown[];\n const notes = this.name === 'notes' ? rows : await this.tx.objectStore('notes').getAll() as unknown[];\n const ctx = collectUserScopeContext(notes);\n for (const row of rows) {\n const key = keyFromValue(STORE_DEFS.find(def => def.name === this.name)!, row);\n if (!isUserOwnedRow(this.name, row, ctx)) continue;\n if (this.name === 'meta' && typeof key === 'string' && key.startsWith(USER_DELETED_SEED_PREFIX)) continue;\n if (this.name === 'notes' && typeof key === 'string') {\n // Cascade the note's projections first — keys read BEFORE deletion,\n // each journaled as its own tombstone.\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const projections = this.tx.objectStore(name);\n for (const id of await projections.index('by-note').getAllKeys(key)) {\n this.journal?.ops.push({ op: 'delete', store: name, key: id as KeyDTO });\n await projections.delete(id);\n }\n }\n }\n await this.recordDelete(key);\n await store.delete(key);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Legacy row shapes (V20–V28) — read-only migration input, never written back.\n// ---------------------------------------------------------------------------\n\ninterface LegacySessionData {\n logs?: unknown[];\n startTime?: number;\n endTime?: number;\n duration?: number;\n completed?: boolean;\n roundsCompleted?: number;\n totalRounds?: number;\n repsCompleted?: number;\n}\n\ntype LegacySession = Session & { data?: LegacySessionData; segmentId?: string; segmentVersion?: number; version?: number };\n\ninterface LegacySegment {\n id: string;\n version: number;\n noteId: string;\n position?: number;\n dataType: string;\n rawContent: string;\n sourceContent?: string;\n createdAt: number;\n isHistory?: boolean;\n}\n\ninterface LegacyBlockIndexRow {\n id: string;\n noteId: string;\n segmentId: string;\n segmentVersion?: number;\n position?: number;\n dataType: string;\n rawContent: string;\n noteTitle: string;\n createdAt: number;\n isStatic?: boolean;\n sourceId?: string;\n sourcePath?: string;\n routeId?: string;\n blockContentId?: string;\n}\n\nconst SEGMENT_TO_BLOCK_KIND: Record<string, 'wod'> = { script: 'wod', wod: 'wod' };\n\nfunction legacyDialect(rawContent: string): { dialect?: 'time' | 'log'; sport?: string } {\n const first = rawContent.slice(0, rawContent.indexOf('\\n'));\n return matchDialectFence(first.trim()) ?? {};\n}\n\nexport class IndexedDBStorage implements IStorage {\n private opening?: Promise<IDBPDatabase>;\n constructor(private readonly options: {\n getUserId?: () => string;\n /** Called just before a schema migration runs (oldVersion < DB_VERSION). */\n onUpgradeStart?: (fromVersion: number) => void;\n /** Database file name; the sync engine migrates scratch copies under\n * their own name so a remote-schema conversion never touches the\n * live database. Defaults to the app database. */\n dbName?: string;\n } = {}) {}\n\n open(): Promise<IDBPDatabase> {\n if (typeof indexedDB === 'undefined') return Promise.reject(new Error('IndexedDB is unavailable in this environment'));\n if (!this.opening) {\n let newer = false;\n let pre20 = 0;\n let migrationError: Error | undefined;\n this.opening = openDB(this.options.dbName ?? IDB_DB_NAME, DB_VERSION, {\n upgrade: async (db, oldVersion, _version, tx) => {\n void tx.done.catch(() => {});\n if (oldVersion > DB_VERSION) {\n // A newer client owns this database — never downgrade or rewrite it.\n newer = true;\n tx.abort();\n return;\n }\n if (oldVersion !== 0 && oldVersion < 20) {\n // Pre-V20 layouts predate the versioned migration chain. Their\n // rows are NEVER silently destroyed: the upgrade aborts with an\n // actionable error so the user can export from an older app or\n // explicitly clear site data. The database file stays untouched.\n pre20 = oldVersion;\n tx.abort();\n return;\n }\n try {\n createMissingStores(db, tx);\n if (oldVersion !== 0 && oldVersion < DB_VERSION) this.options.onUpgradeStart?.(oldVersion);\n await migrateSchema(db, oldVersion, tx);\n } catch (error) {\n migrationError = error instanceof Error ? error : new Error(String(error));\n try { tx.abort(); } catch { /* The failed request may already have aborted it. */ }\n }\n },\n blocking: () => { void this.close(); },\n }).catch(error => {\n this.opening = undefined;\n if (migrationError) throw migrationError;\n if (pre20 !== 0) {\n throw new Error(\n `local database schema v${pre20} predates the supported migration chain (v20+). `\n + 'Open this browser profile in an intermediate app version to export your data, '\n + 'or clear site data to start fresh — the old database was left untouched.',\n );\n }\n throw newer || (error instanceof DOMException && error.name === 'VersionError')\n ? new Error(`database schema is newer than this client supports (v${DB_VERSION}); refusing to downgrade`) : error;\n });\n }\n return this.opening;\n }\n\n stamp(store: StoreName, value: unknown): unknown {\n const userId = this.options.getUserId?.();\n return userId ? stampUserOwned(store, value, userId) : value;\n }\n\n /** User-scope context (proven seed note ids) from the notes of `tx` —\n * journal-time ownership classification reads it INSIDE the same\n * transaction, so a seed import's note writes are visible to the link\n * writes that follow in the same commit. Internal seam for IDBStore. */\n async policyContext(tx?: Tx): Promise<UserScopeContext> {\n const notes = tx\n ? await tx.objectStore('notes').getAll() as unknown[]\n : await (await this.open()).getAll('notes') as unknown[];\n return collectUserScopeContext(notes);\n }\n\n readonly<K extends StoreName>(store: K): IReadOnlyStore<StoreType<K>> { return new IDBStore(this, store); }\n readwrite<K extends StoreName>(store: K): IReadWriteStore<StoreType<K>> { return new IDBStore(this, store, undefined, true); }\n\n async transaction<K extends StoreName, R>(stores: K[], mode: Mode, fn: (tx: IStorageTransaction) => Promise<R>): Promise<R> {\n const db = await this.open();\n const journal = mode === 'readwrite' ? new TxJournal() : undefined;\n const scope = new Set<string>(stores);\n if (mode === 'readwrite') {\n scope.add('block_revisions');\n scope.add(OUTBOX_STORE);\n scope.add('notes');\n if (scope.has('notes')) {\n scope.add('block_index');\n scope.add('block_efforts');\n scope.add('block_equipment');\n }\n }\n const native = db.transaction([...scope], mode) as Tx;\n const done = native.done;\n void done.catch(() => {});\n const touched = { notes: new Set<string>(), sessions: new Set<string>() };\n const adapter: IStorageTransaction = {\n readonly: name => {\n if (!scope.has(name)) throw new Error('store outside transaction scope');\n return new IDBStore(this, name, native);\n },\n readwrite: name => {\n if (mode !== 'readwrite') throw new Error('read-only transaction');\n if (!scope.has(name)) throw new Error('store outside transaction scope');\n return new IDBStore(this, name, native, true, touched, journal);\n },\n };\n try {\n const result = await fn(adapter);\n const notes = (await Promise.all([...touched.notes].map(id => native.objectStore('notes').get(id)))).filter(Boolean) as Note[];\n const sessions = (await Promise.all([...touched.sessions].map(id => native.objectStore('sessions').get(id)))).filter(Boolean) as Session[];\n await validateStoredPins(notes, sessions, keys => Promise.all(keys.map(key => native.objectStore('block_revisions').get(key))) as Promise<(BlockRevision | undefined)[]>);\n // Durable outbox: the journal entry lands in the SAME transaction as\n // the data writes — it commits with them and vanishes with them.\n if (journal && journal.ops.length > 0) {\n await native.objectStore(OUTBOX_STORE).put({ id: crypto.randomUUID(), at: Date.now(), ops: journal.ops });\n }\n await done;\n if (journal && journal.ops.length > 0) notifyOutboxCommit();\n return result;\n } catch (error) {\n try { native.abort(); } catch { /* The native request may have already aborted. */ }\n await done.catch(() => {});\n throw error;\n }\n }\n\n async wipeUserData(): Promise<void> {\n const names = STORE_DEFS.filter(def => !def.system && def.name !== 'block_revisions').map(def => def.name);\n await this.transaction(names, 'readwrite', async tx => {\n for (const name of names) await tx.readwrite(name).clear();\n });\n }\n\n async wipe(): Promise<void> {\n const db = await this.open();\n const names = STORE_DEFS.filter(def => !def.system).map(def => def.name);\n const tx = db.transaction([...names, OUTBOX_STORE], 'readwrite');\n await Promise.all(names.map(name => tx.objectStore(name).clear()));\n await tx.objectStore(OUTBOX_STORE).put({ id: crypto.randomUUID(), at: Date.now(), ops: [{ op: 'wipe' }] });\n await tx.done;\n notifyOutboxCommit();\n }\n\n // -----------------------------------------------------------------------\n // Sync seams (Turso backup engine only — not part of IStorage).\n // -----------------------------------------------------------------------\n\n /** Pending committed transaction groups, in commit order. */\n async readOutbox(afterSeq: number, limit: number): Promise<{ seq: number; id: string; at: number; ops: SyncMutation[] }[]> {\n const db = await this.open();\n const range = IDBKeyRange.lowerBound(afterSeq, true);\n // IDB counts are unsigned long — clamp callers' \"unbounded\" shorthand.\n return (await db.getAll(OUTBOX_STORE, range, Math.min(limit, 0xffffffff))) as { seq: number; id: string; at: number; ops: SyncMutation[] }[];\n }\n\n /** Drop acknowledged groups. Callers pass only the contiguous acked\n * watermark — a failed upload never truncates pending writes. */\n async ackOutbox(upToSeq: number): Promise<void> {\n const db = await this.open();\n const keys = await db.getAllKeys(OUTBOX_STORE, IDBKeyRange.upperBound(upToSeq));\n const tx = db.transaction(OUTBOX_STORE, 'readwrite');\n await Promise.all(keys.map(key => tx.store.delete(key)));\n await tx.done;\n }\n\n async getSyncState<T>(key: string): Promise<T | undefined> {\n const row = (await (await this.open()).get(SYNC_STATE_STORE, key)) as { value: T } | undefined;\n return row?.value;\n }\n\n async setSyncState(key: string, value: unknown): Promise<void> {\n await (await this.open()).put(SYNC_STATE_STORE, { key, value });\n }\n\n /**\n * Freeze ONE durable bootstrap run for `key` (per backup target): a\n * policy-compliant snapshot of the current rows, chunked into ≤500-op /\n * ≤~1MB entries with a unique run UUID and stable chunk ids, persisted in\n * `sync_state[key]` in the SAME readwrite transaction that reads the data\n * — so a retry returns the byte-identical frozen entries (idempotent\n * remote replays), and a crash before the commit freezes nothing. No\n * network happens here.\n *\n * Pending outbox groups are read INSIDE the same transaction: their\n * touched keys/stores are excluded from the snapshot so the journal (which\n * ships after the bootstrap, in commit order) stays the last writer and\n * nothing ships twice. A pending wipe freezes an empty run — the journal\n * wipe itself still ships and decides the remote's end state.\n *\n * The engine deletes the frozen run (`db.delete('sync_state', key)`) only\n * after the remote commit; until then every retry replays these entries.\n */\n async captureSyncBootstrap(key: string): Promise<SyncEntry[]> {\n const db = await this.open();\n const tx = db.transaction([...NON_SYSTEM_STORES, OUTBOX_STORE, SYNC_STATE_STORE], 'readwrite');\n const state = tx.objectStore(SYNC_STATE_STORE);\n const frozen = await state.get(key) as { value?: SyncEntry[] } | undefined;\n if (frozen !== undefined && Array.isArray(frozen.value)) {\n await tx.done;\n return frozen.value;\n }\n const pendingKeys = new Set<string>();\n const clearedStores = new Set<string>();\n let wiped = false;\n for (const group of await tx.objectStore(OUTBOX_STORE).getAll() as { ops: SyncMutation[] }[]) {\n for (const op of group.ops) {\n if (op.op === 'put' || op.op === 'delete') pendingKeys.add(`${op.store}:${JSON.stringify(op.key)}`);\n else if (op.op === 'clear') clearedStores.add(op.store);\n else wiped = true;\n }\n }\n const run = crypto.randomUUID();\n const entries: SyncEntry[] = [];\n if (!wiped) {\n let ops: SyncMutation[] = [];\n let bytes = 0;\n const flush = (): void => {\n if (ops.length === 0) return;\n entries.push({ id: `bootstrap:${run}:${entries.length}`, at: Date.now(), ops });\n ops = [];\n bytes = 0;\n };\n for (const op of await policySnapshotOps(store => tx.objectStore(store).getAll() as Promise<unknown[]>)) {\n if (clearedStores.has(op.store)) continue;\n // Immutable history is NEVER excluded: a snapshotted note/session\n // may pin a revision still pending in the journal, and the snapshot\n // ships first — the pinned revision must already be on the remote.\n // Revision-first op ordering keeps every chunk self-contained.\n if (op.store !== 'block_revisions' && pendingKeys.has(`${op.store}:${JSON.stringify(op.key)}`)) continue;\n const size = mutationBytes(op);\n if (ops.length > 0 && (ops.length >= BOOTSTRAP_MAX_OPS || bytes + size > BOOTSTRAP_MAX_BYTES)) flush();\n ops.push(op);\n bytes += size;\n }\n flush();\n }\n // Frozen BEFORE any network I/O — same transaction as the snapshot read.\n await state.put({ key, value: entries });\n await tx.done;\n return entries;\n }\n\n /**\n * Validate every stored pin (note blocks + session pins against\n * block_revisions) in ONE consistent readonly read — the post-restore\n * gate: a replayed backup with missing history fails loudly here instead\n * of surfacing later as broken sessions.\n */\n async validateSyncState(): Promise<void> {\n const db = await this.open();\n const tx = db.transaction(['notes', 'sessions', 'block_revisions'], 'readonly');\n const notes = await tx.objectStore('notes').getAll() as Note[];\n const sessions = await tx.objectStore('sessions').getAll() as Session[];\n const revisions = tx.objectStore('block_revisions');\n await validateStoredPins(\n notes,\n sessions,\n keys => Promise.all(keys.map(key => revisions.get(key))) as Promise<(BlockRevision | undefined)[]>,\n );\n await tx.done;\n }\n\n /**\n * Apply remotely committed mutations locally (pull/replay) WITHOUT\n * journaling — a pulled mutation must never re-enter the outbox. Runs in\n * one native transaction together with the cursor update.\n *\n * Unsent-edit overlay: pending outbox groups (committed local writes not\n * yet acknowledged remotely) are read INSIDE the same transaction and\n * replayed after the remote rows — a local edit/delete/clear/wipe that\n * committed while the pull was on the network stays the visible state;\n * the remote row is backed up locally, not clobbered over the user.\n *\n * Conflict policy (deterministic, history-preserving):\n * - notes: an incoming row with a LOWER sourceRevision than the existing\n * row is stale — skipped, never clobbers newer history.\n * - block_revisions: same key with different contents keeps BOTH rows —\n * the incoming version is re-keyed to the next free version for that\n * block. Immutable history is never silently replaced.\n * - memberships (system): remote mutations are skipped — identity truth\n * stays local and snapshot/upload never include them.\n *\n * Returns committed-boundary counts of canonical consumer records (notes +\n * efforts only; internal/journal rows never reach the sync toast).\n * `cursorKey` keeps cursors per backup target.\n */\n async applySyncMutations(\n mutations: SyncMutation[],\n cursorRev: number | null,\n cursorKey = 'cursor',\n ): Promise<{ added: number; updated: number }> {\n const defsByName = new Map<string, (typeof STORE_DEFS)[number]>(STORE_DEFS.map(def => [def.name, def]));\n for (const mutation of mutations) {\n if (mutation.op === 'clear' || mutation.op === 'wipe') continue;\n const def = defsByName.get(mutation.store);\n if (!def) throw new Error(`unknown store in sync mutation: ${String(mutation.store)}`);\n if (mutation.op === 'put' || mutation.op === 'delete') {\n const parts = Array.isArray(mutation.key) ? mutation.key : [mutation.key];\n if (parts.length !== def.keyPath.length || !parts.every(part => typeof part === 'string' || typeof part === 'number')) {\n throw new Error(`sync ${mutation.op} key arity/shape mismatch for ${mutation.store}`);\n }\n }\n if (mutation.op === 'put') validateStorageRow(mutation.store, mutation.value);\n }\n const db = await this.open();\n const names = NON_SYSTEM_STORES as StoreName[];\n const tx = db.transaction([...names, OUTBOX_STORE, SYNC_STATE_STORE], 'readwrite');\n\n // Counting baseline: every canonical key this batch touches, read before\n // any write lands.\n const canonical = (store: StoreName): store is 'notes' | 'efforts' => store === 'notes' || store === 'efforts';\n const touched = new Map<string, { store: 'notes' | 'efforts'; key: IDBValidKey; before: unknown; beforeExists: boolean }>();\n for (const mutation of mutations) {\n if (mutation.op === 'clear' || mutation.op === 'wipe') continue;\n if (!canonical(mutation.store)) continue;\n const id = `${mutation.store}:${JSON.stringify(mutation.key)}`;\n if (touched.has(id)) continue;\n const key = mutation.key as IDBValidKey;\n const before = await tx.objectStore(mutation.store).get(key);\n touched.set(id, { store: mutation.store, key, before, beforeExists: before !== undefined });\n }\n\n const applyOne = async (mutation: SyncMutation, preferLocal: boolean): Promise<void> => {\n if (mutation.op === 'wipe') {\n for (const name of names) await tx.objectStore(name).clear();\n return;\n }\n if (mutation.store === 'memberships') return; // system store: never applied remotely\n if (mutation.op === 'clear') {\n if (mutation.store === 'block_revisions') return;\n const store = tx.objectStore(mutation.store);\n const ctx = collectUserScopeContext(await tx.objectStore('notes').getAll());\n for (const row of await store.getAll()) {\n if (!isUserOwnedRow(mutation.store, row, ctx)) continue;\n const key = keyFromValue(defsByName.get(mutation.store)!, row);\n if (mutation.store === 'meta' && typeof key === 'string' && key.startsWith(USER_DELETED_SEED_PREFIX)) continue;\n await applyOne({ op: 'delete', store: mutation.store, key }, preferLocal);\n }\n return;\n }\n if (mutation.op === 'delete') {\n if (mutation.store === 'notes') {\n const noteId = String(Array.isArray(mutation.key) ? mutation.key[0] : mutation.key);\n for (const name of ['block_index', 'block_efforts', 'block_equipment'] as const) {\n const store = tx.objectStore(name);\n for (const id of await store.index('by-note').getAllKeys(noteId)) await store.delete(id);\n }\n }\n if (mutation.store !== 'block_revisions') await tx.objectStore(mutation.store).delete(mutation.key as IDBValidKey);\n return;\n }\n // put\n const store = tx.objectStore(mutation.store);\n if (mutation.store === 'block_revisions') {\n const existing = await store.get(mutation.key as IDBValidKey);\n if (existing !== undefined && !rowsEqual(existing, mutation.value) && !preferLocal) {\n // Immutable-history collision: preserve BOTH as versioned records —\n // the incoming row moves to the next free version for that block.\n // Both rows passed validateStorageRow when written (the incoming row\n // just above; the existing row at its original commit), so the\n // revision shape is guaranteed here.\n const incoming = mutation.value as BlockRevision;\n const existingRow = existing as BlockRevision;\n let version = existingRow.version + 1;\n while (await store.get([incoming.noteId, incoming.blockId, version] as IDBValidKey) !== undefined) version += 1;\n await store.put({ ...incoming, version });\n return;\n }\n if (existing === undefined || !rowsEqual(existing, mutation.value)) await store.put(mutation.value);\n return;\n }\n if (mutation.store === 'notes' && !preferLocal) {\n const existing = await store.get(mutation.key as IDBValidKey);\n // Same validateStorageRow guarantee as above: rows in the store carry\n // the note shape, so comparing source revisions is safe.\n if (existing !== undefined) {\n const existingNote = existing as Note;\n const incomingNote = mutation.value as Note;\n if (existingNote.sourceRevision > incomingNote.sourceRevision) return; // stale remote write\n }\n }\n await store.put(mutation.value);\n };\n\n for (const mutation of mutations) await applyOne(mutation, false);\n\n // Unsent-edit overlay: replay pending outbox groups in commit order so\n // the user's latest local writes remain the visible latest state.\n const pending = ((await tx.objectStore(OUTBOX_STORE).getAll()) as { seq: number; ops: SyncMutation[] }[])\n .sort((a, b) => a.seq - b.seq);\n for (const group of pending) {\n for (const op of group.ops) await applyOne(op, true);\n }\n\n // Committed-boundary counts: canonical notes/efforts whose final visible\n // value is new or changed relative to the pre-pull baseline.\n let added = 0;\n let updated = 0;\n for (const entry of touched.values()) {\n const final = await tx.objectStore(entry.store).get(entry.key);\n if (final === undefined) continue; // deleted by the batch — not an add/update\n if (!entry.beforeExists) added += 1;\n else if (!rowsEqual(entry.before, final)) updated += 1;\n }\n\n if (cursorRev !== null) await tx.objectStore(SYNC_STATE_STORE).put({ key: cursorKey, value: { rev: cursorRev } });\n await tx.done;\n return { added, updated };\n }\n\n /**\n * Consistent atomic snapshot, policy-compliant (shared user policy): only\n * user-scope rows of the non-system stores, read in ONE readonly\n * transaction — the backup never mixes the pre/post state of a concurrent\n * local commit. System stores (memberships) are excluded: they never sync.\n * Use `snapshotAllRows` for the lossless (unfiltered) form.\n */\n async snapshotRows(): Promise<{ store: StoreName; rows: unknown[] }[]> {\n const db = await this.open();\n const defs = STORE_DEFS.filter(def => !def.system);\n const tx = db.transaction(defs.map(def => def.name), 'readonly');\n // Ownership context comes from the SAME snapshot transaction — reading\n // notes before opening it could diverge from a concurrent note write.\n const ctx = collectUserScopeContext(await tx.objectStore('notes').getAll() as unknown[]);\n const out = await Promise.all(\n defs.map(async def => ({\n store: def.name,\n rows: ((await tx.objectStore(def.name).getAll() as unknown[])).filter(row => isUserOwnedRow(def.name, row, ctx)),\n })),\n );\n await tx.done;\n return out;\n }\n\n /** Lossless snapshot of every NON-SYSTEM store (meta included) in one\n * readonly transaction — local export / restore emptiness checks. A\n * freshly initialized database may hold a default membership, so the\n * system store is excluded from both uses. */\n async snapshotAllRows(): Promise<{ store: StoreName; rows: unknown[] }[]> {\n const db = await this.open();\n const defs = STORE_DEFS.filter(def => !def.system);\n const tx = db.transaction(defs.map(def => def.name), 'readonly');\n const out = await Promise.all(\n defs.map(async def => ({ store: def.name, rows: await tx.objectStore(def.name).getAll() as unknown[] })),\n );\n await tx.done;\n return out;\n }\n\n async close(): Promise<void> {\n const opening = this.opening;\n this.opening = undefined;\n (await opening?.catch(() => undefined))?.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Cross-schema conversion — the exact IndexedDB upgrade chain on a scratch\n// database. Reads the source WITHOUT writing it; used by the CLI to migrate\n// older remotes into fresh v32 targets (trusted runtimes load\n// fake-indexeddb as the browser adapter first).\n// ---------------------------------------------------------------------------\n\ntype ScratchOp =\n | { kind: 'put'; table: string; row: unknown }\n | { kind: 'delete'; table: string; key: IDBValidKey }\n | { kind: 'clear'; table: string };\n\n/** Scratch layout: current stores plus the pre-V26 legacy tables. */\nconst SCRATCH_TABLES: readonly { name: string; keyPath: string[] }[] = [\n ...STORE_DEFS.map(def => ({ name: def.name, keyPath: def.keyPath })),\n ...LEGACY_EXTRA_TABLES.map(table => ({ name: table.name, keyPath: Array.isArray(table.keyPath) ? table.keyPath : [table.keyPath] })),\n];\n\nconst SCRATCH_TABLE_BY_NAME: Record<string, string[]> = Object.fromEntries(\n SCRATCH_TABLES.map(table => [table.name, table.keyPath]),\n);\n\nfunction assertKnownStore(store: string): void {\n if (!SCRATCH_TABLE_BY_NAME[store]) throw new Error(`unknown store \"${store}\" in source op log; copy aborted`);\n}\n\n/** Derive a row's key from its keyPath fields — malformed rows fail. */\nfunction rowKey(table: string, row: Record<string, unknown>): IDBValidKey {\n const parts: IDBValidKey[] = [];\n for (const part of SCRATCH_TABLE_BY_NAME[table]) {\n const value = row[part];\n if (typeof value !== 'string' && typeof value !== 'number' && !(value instanceof Date)) {\n throw new Error(`row for store \"${table}\" is missing keyPath field \"${part}\"; copy aborted`);\n }\n parts.push(value);\n }\n return parts.length === 1 ? parts[0] : parts;\n}\n\n/** Narrow a raw (unvalidated) op key to what IndexedDB accepts. */\nfunction isIdbKey(value: unknown): value is IDBValidKey {\n return typeof value === 'string' || typeof value === 'number' || value instanceof Date\n || (Array.isArray(value) && value.length > 0 && value.every(isIdbKey));\n}\n\nfunction arrayBuffersEqual(a: ArrayBuffer, b: ArrayBuffer): boolean {\n if (a.byteLength !== b.byteLength) return false;\n const left = new Uint8Array(a);\n const right = new Uint8Array(b);\n return left.every((byte, i) => byte === right[i]);\n}\n\nfunction deleteIdbDatabase(name: string): Promise<void> {\n const idb = globalThis.indexedDB;\n if (!idb) return Promise.resolve();\n return new Promise<void>((resolve, reject) => {\n const request = idb.deleteDatabase(name);\n request.onsuccess = () => { resolve(); };\n request.onerror = () => { reject(request.error ?? new Error(`failed to delete ${name}`)); };\n // A still-open connection blocks deletion; the scratch rows are\n // disposable either way, so don't hang the conversion on it.\n request.onblocked = () => { resolve(); };\n });\n}\n\n/** Replay raw remote-era rows into a unique scratch IndexedDB created at the\n * SOURCE schema version (generic keyPath-only stores + legacy tables), so\n * opening it through IndexedDBStorage runs the same versioned chain the\n * browser runs locally. */\nasync function buildScratch(name: string, version: number, ops: ScratchOp[]): Promise<void> {\n const db = await openDB(name, version, {\n upgrade(scratch) {\n for (const table of SCRATCH_TABLES) {\n if (!scratch.objectStoreNames.contains(table.name)) {\n scratch.createObjectStore(table.name, { keyPath: table.keyPath.length === 1 ? table.keyPath[0] : table.keyPath });\n }\n }\n },\n });\n try {\n for (const op of ops) {\n if (!db.objectStoreNames.contains(op.table)) {\n throw new Error(`unknown store \"${op.table}\" in source; copy aborted`);\n }\n if (op.kind === 'put') await db.transaction(op.table, 'readwrite').objectStore(op.table).put(op.row);\n else if (op.kind === 'delete') await db.transaction(op.table, 'readwrite').objectStore(op.table).delete(op.key);\n else await db.transaction(op.table, 'readwrite').objectStore(op.table).clear();\n }\n } finally {\n db.close();\n }\n}\n\n/** Attachment rows are the binary payload. The terminal source map replays\n * the lifted ops in order (puts, deletes, clears — wipes already expanded\n * to clears), so deleted/wiped attachments are NOT required to survive;\n * surviving ones must match the converted rows byte-for-byte (zero-byte\n * buffers are valid). */\nasync function assertBinaryPreserved(sourceOps: ScratchOp[], converted: IndexedDBStorage): Promise<void> {\n const source = new Map<string, Record<string, unknown>>();\n for (const op of sourceOps) {\n if (op.kind === 'clear') {\n if (op.table === 'attachments') source.clear();\n } else if (op.kind === 'put' && op.table === 'attachments') {\n if (op.row === null || typeof op.row !== 'object' || Array.isArray(op.row) || !('id' in op.row)) {\n throw new Error('malformed attachment row in source; copy aborted');\n }\n source.set(String((op.row as Record<string, unknown>).id), op.row as Record<string, unknown>);\n } else if (op.kind === 'delete' && op.table === 'attachments') {\n source.delete(String(op.key));\n }\n }\n if (source.size === 0) return;\n const rows = await converted.readonly('attachments').getAll();\n const byId = new Map(rows.map(row => [row.id, row]));\n for (const [id, row] of source) {\n const restored = byId.get(id);\n if (!restored) throw new Error(`attachment ${id} missing after conversion; copy aborted, source untouched`);\n const before = row.data;\n const after = restored.data;\n if (typeof before === 'string' || typeof after === 'string') {\n if (before !== after) throw new Error(`attachment ${id} payload changed during conversion; copy aborted, source untouched`);\n } else if (!(before instanceof ArrayBuffer) || !(after instanceof ArrayBuffer) || !arrayBuffersEqual(before, after)) {\n throw new Error(`attachment ${id} payload changed during conversion; copy aborted, source untouched`);\n }\n }\n}\n\n/**\n * Convert an older backup into policy-compliant current-schema mutations\n * WITHOUT touching the source:\n *\n * 1. Lift the source data as ordered scratch ops (op-log replay in log\n * order, or legacy direct-Turso per-store rows incl. segments/results).\n * 2. Replay them into a unique scratch IndexedDB created AT `fromVersion`,\n * then open it through IndexedDBStorage — the same versioned migration\n * chain the browser runs locally rebuilds segments-era rows into\n * note-owned blocks, revisions, sessions and events.\n * 3. Validate strictly (all note/session pins, binary payloads, derivable\n * keys — any miss fails the copy) and return policy-compliant PUTS ONLY\n * (the caller applies them to a fresh, reserved target).\n */\nexport async function convertSyncSource(db: Database, fromVersion: number, legacy: boolean): Promise<SyncMutation[]> {\n if (!Number.isSafeInteger(fromVersion) || fromVersion < 20) {\n throw new Error(\n `Backup database schema v${fromVersion} predates the supported migration chain (v20+); the source was left untouched. `\n + 'Restore it with an intermediate app version, or point this app at a fresh backup database.',\n );\n }\n if (fromVersion > DB_VERSION) {\n throw new Error(`Backup database schema is newer than this converter supports (v${fromVersion} > v${DB_VERSION}); refusing to downgrade.`);\n }\n const raw: ScratchOp[] = [];\n if (legacy) {\n for (const table of [...NON_SYSTEM_STORES, ...LEGACY_EXTRA_TABLES.map(table => table.name)]) {\n for (const row of await readLegacyRows(db, table)) raw.push({ kind: 'put', table, row });\n }\n } else {\n // Raw replay with STRICT lift-time validation (§3.5): unknown stores,\n // unknown ops, malformed payloads and put keys that disagree with the\n // row's own keyPath fields fail the copy before anything is replayed.\n for (const op of await readRawSyncOps(db)) {\n if (op.op === 'wipe') {\n for (const name of [...NON_SYSTEM_STORES, ...LEGACY_EXTRA_TABLES.map(table => table.name)]) {\n raw.push({ kind: 'clear', table: name });\n }\n } else if (op.op === 'clear') {\n assertKnownStore(op.store);\n raw.push({ kind: 'clear', table: op.store });\n } else if (op.op === 'put') {\n assertKnownStore(op.store);\n if (op.value === undefined || op.value === null || typeof op.value !== 'object' || Array.isArray(op.value)) {\n throw new Error(`malformed put payload for store \"${op.store}\" in source op log; copy aborted`);\n }\n if (JSON.stringify(rowKey(op.store, op.value as Record<string, unknown>)) !== JSON.stringify(op.key)) {\n throw new Error(`put key ${JSON.stringify(op.key)} does not match store \"${op.store}\" keyPath fields; copy aborted`);\n }\n raw.push({ kind: 'put', table: op.store, row: op.value });\n } else if (op.op === 'delete') {\n assertKnownStore(op.store);\n if (!isIdbKey(op.key)) {\n throw new Error(`malformed delete key for store \"${op.store}\" in source op log; copy aborted`);\n }\n raw.push({ kind: 'delete', table: op.store, key: op.key });\n } else {\n throw new Error(`unknown op \"${String((op as { op?: unknown }).op)}\" in source op log; copy aborted`);\n }\n }\n }\n const scratch = `wodwiki-convert-${crypto.randomUUID()}`;\n const converted = new IndexedDBStorage({ dbName: scratch });\n try {\n await buildScratch(scratch, fromVersion, raw);\n await converted.open();\n await converted.validateSyncState(); // strict: missing pinned revisions fail the copy\n await assertBinaryPreserved(raw, converted);\n return await policySnapshotOps(store => converted.readonly(store).getAll() as Promise<unknown[]>);\n } finally {\n await converted.close();\n await deleteIdbDatabase(scratch).catch(() => undefined);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Schema creation + versioned data migration (V20 → V32).\n// ---------------------------------------------------------------------------\n\nfunction createMissingStores(db: IDBPDatabase, tx: IDBPTransaction<unknown, string, 'versionchange'>): void {\n for (const def of STORE_DEFS) {\n if (db.objectStoreNames.contains(def.name)) {\n // Existing stores (pre-DB_VERSION layouts) keep whatever index set\n // they were born with — backfill indexes the current schema needs.\n const existing = tx.objectStore(def.name);\n for (const index of def.indexes) {\n if (!existing.indexNames.contains(index.name)) existing.createIndex(index.name, index.keyPath.length === 1 ? index.keyPath[0] : index.keyPath, { unique: index.unique, multiEntry: index.multiEntry });\n }\n continue;\n }\n const store = db.createObjectStore(def.name, { keyPath: def.keyPath.length === 1 ? def.keyPath[0] : def.keyPath });\n for (const index of def.indexes) store.createIndex(index.name, index.keyPath.length === 1 ? index.keyPath[0] : index.keyPath, { unique: index.unique, multiEntry: index.multiEntry });\n }\n for (const local of LOCAL_SYNC_STORES) {\n if (db.objectStoreNames.contains(local.name)) continue;\n db.createObjectStore(local.name, { keyPath: local.keyPath, autoIncrement: 'autoIncrement' in local ? local.autoIncrement : false });\n }\n}\n\nasync function migrateSchema(db: IDBPDatabase, oldVersion: number, tx: IDBPTransaction<unknown, string, 'versionchange'>): Promise<void> {\n const store = (name: string) => tx.objectStore(name);\n\n // V20 → V21: flatten sessions, drop data.logs, project legacy logs\n // idempotently into event rows.\n if (oldVersion === 20 && db.objectStoreNames.contains('sessions')) {\n const sessionsStore = store('sessions');\n const eventsStore = store('events');\n for await (const cursor of sessionsStore) {\n const legacy = cursor.value as LegacySession;\n const logs = legacy.data?.logs ?? [];\n let alreadyProjected = false;\n for await (const _ev of eventsStore.index('by-result-grain').iterate(IDBKeyRange.bound([legacy.id, ''], [legacy.id, []]))) {\n alreadyProjected = true;\n break;\n }\n if (!alreadyProjected && logs.length > 0) {\n const identity = {\n noteId: legacy.noteId, resultId: legacy.id, segmentId: legacy.segmentId,\n segmentVersion: legacy.segmentVersion, blockContentId: legacy.blockContentId,\n origin: legacy.origin, pageId: legacy.pageId,\n workoutTimestamp: legacy.data?.endTime ?? legacy.createdAt,\n };\n for (const row of toEventRows(logs as never, identity)) await eventsStore.put(row);\n for (const row of toSummaryEventRows(logs as never, identity)) await eventsStore.put(row);\n }\n const flat: Session = {\n ...legacy,\n startTime: legacy.data?.startTime ?? legacy.createdAt,\n endTime: legacy.data?.endTime ?? legacy.createdAt,\n duration: legacy.data?.duration ?? 0,\n completed: legacy.data?.completed ?? true,\n roundsCompleted: legacy.data?.roundsCompleted,\n totalRounds: legacy.data?.totalRounds,\n repsCompleted: legacy.data?.repsCompleted,\n };\n delete (flat as unknown as Record<string, unknown>).data;\n await cursor.update(flat);\n }\n }\n\n // V21 → V22: invalidate the pre-V22 seed checkpoint so the V22 seed\n // data re-applies cleanly.\n if (oldVersion === 21 && db.objectStoreNames.contains('meta')) {\n await store('meta').delete('seed');\n }\n\n // V25: memberships store + by-user ownership index on every user-owned\n // store. Presence-guarded: mixed-state databases exist in the wild.\n if (oldVersion < 25) {\n for (const name of USER_OWNED_STORES) {\n if (!db.objectStoreNames.contains(name)) continue;\n const s = store(name);\n if (!s.indexNames.contains('by-user')) s.createIndex('by-user', 'userId');\n }\n }\n\n // V26: results → sessions. Residual legacy rows are read BEFORE the store\n // disappears; inline logs are projected per deterministic id (existing\n // rows never overwritten, absent detail/summary rows added). The legacy\n // duplicate is discarded only after the canonical row is safe.\n if (db.objectStoreNames.contains('results')) {\n const sessionsStore = store('sessions');\n const resultsStore = store('results');\n const eventsStore = store('events');\n for await (const cursor of resultsStore) {\n const { data: legacyData, ...legacyRow } = cursor.value as LegacySession;\n const logs = legacyData?.logs ?? [];\n if (logs.length > 0) {\n const identity = {\n noteId: legacyRow.noteId, resultId: legacyRow.id, segmentId: legacyRow.segmentId,\n segmentVersion: legacyRow.segmentVersion, blockContentId: legacyRow.blockContentId,\n origin: legacyRow.origin, pageId: legacyRow.pageId,\n workoutTimestamp: legacyData?.endTime ?? legacyRow.createdAt,\n };\n for (const row of toEventRows(logs as never, identity)) {\n if ((await eventsStore.get(row.id)) === undefined) await eventsStore.put(row);\n }\n for (const row of toSummaryEventRows(logs as never, identity)) {\n if ((await eventsStore.get(row.id)) === undefined) await eventsStore.put(row);\n }\n }\n if ((await sessionsStore.getKey(legacyRow.id)) !== undefined) continue;\n await sessionsStore.put({\n ...legacyRow,\n startTime: legacyData?.startTime ?? legacyRow.startTime ?? legacyRow.createdAt,\n endTime: legacyData?.endTime ?? legacyRow.endTime ?? legacyRow.createdAt,\n duration: legacyData?.duration ?? legacyRow.duration ?? 0,\n completed: legacyData?.completed ?? legacyRow.completed ?? true,\n roundsCompleted: legacyData?.roundsCompleted ?? legacyRow.roundsCompleted,\n totalRounds: legacyData?.totalRounds ?? legacyRow.totalRounds,\n repsCompleted: legacyData?.repsCompleted ?? legacyRow.repsCompleted,\n });\n }\n db.deleteObjectStore('results');\n }\n\n // V26/V27 repairs (presence-guarded — the first V26 cut shipped without\n // these on real databases, so version 26 is ambiguous).\n if (db.objectStoreNames.contains('block_index') && !store('block_index').indexNames.contains('by-source')) {\n store('block_index').createIndex('by-source', 'sourceId');\n }\n if (db.objectStoreNames.contains('notes') && !store('notes').indexNames.contains('by-created')) {\n store('notes').createIndex('by-created', 'createdAt');\n }\n if (db.objectStoreNames.contains('efforts') && !store('efforts').indexNames.contains('by-source')) {\n store('efforts').createIndex('by-source', 'registrySource');\n }\n if (db.objectStoreNames.contains('note_tags') && !store('note_tags').indexNames.contains('by-note-tag')) {\n const noteTags = store('note_tags');\n // Unique pair index requires deterministic duplicate cleanup first —\n // duplicate links keep the lexicographically smallest row id.\n const winnerByPair = new Map<string, string>();\n const dupes: string[] = [];\n for await (const cursor of noteTags) {\n const row = cursor.value as { id: string; noteId: string; tagId: string };\n const pair = `${row.noteId}${row.tagId}`;\n const winner = winnerByPair.get(pair);\n if (winner === undefined || row.id < winner) {\n winnerByPair.set(pair, row.id);\n if (winner !== undefined) dupes.push(winner);\n } else {\n dupes.push(row.id);\n }\n }\n for (const id of dupes) await noteTags.delete(id);\n noteTags.createIndex('by-note-tag', ['noteId', 'tagId'], { unique: true });\n }\n\n // V28: dashboard typing repair — a note whose frontmatter segment says\n // `dashboard: true` gains type 'dashboard' / sourceId 'dashboards'.\n // Runs BEFORE the V29 pass consumes the segments store. Idempotent.\n if (db.objectStoreNames.contains('notes') && db.objectStoreNames.contains('segments')) {\n const segments = store('segments');\n const notes = store('notes');\n const repaired = new Set<string>();\n for await (const cursor of segments) {\n const segment = cursor.value as LegacySegment;\n if (segment.dataType !== 'frontmatter' || repaired.has(segment.noteId)) continue;\n if (!/(^|\\n)dashboard:\\s*[\"']?true[\"']?\\s*(\\n|$)/.test(segment.rawContent)) continue;\n repaired.add(segment.noteId);\n const note = await notes.get(segment.noteId);\n if (!note || (note.type === 'dashboard' && note.sourceId === 'dashboards')) continue;\n await notes.put({ ...note, type: 'dashboard', sourceId: note.sourceId ?? 'dashboards' });\n }\n }\n\n // V29: segments → note-owned blocks + block_revisions; sessions/events\n // segment fields → block fields; block_index rows remapped. The segments\n // store is dropped only after every note is rebuilt — the source of truth\n // survives until the migration transaction commits.\n if (db.objectStoreNames.contains('segments')) {\n await migrateSegmentsToBlocks(db, tx);\n }\n\n // V32: pending puts already exist in the terminal snapshot. Keep deletion\n // intent before that snapshot, with legacy wipes narrowed to user clears.\n // One group keeps history and its consumers together during replay.\n if (oldVersion >= 30 && oldVersion < 32 && db.objectStoreNames.contains(OUTBOX_STORE)) {\n const outbox = store(OUTBOX_STORE);\n const ops: SyncMutation[] = [];\n for (const group of await outbox.getAll() as { ops: SyncMutation[] }[]) {\n for (const mutation of group.ops) {\n if (mutation.op === 'wipe') {\n for (const name of NON_SYSTEM_STORES) {\n if (name !== 'block_revisions') ops.push({ op: 'clear', store: name });\n }\n } else if (mutation.op !== 'put' && mutation.store !== 'memberships' && mutation.store !== 'block_revisions') {\n ops.push(mutation);\n }\n }\n }\n ops.push(...await policySnapshotOps(name => store(name).getAll() as Promise<unknown[]>));\n await outbox.clear();\n if (ops.length > 0) await outbox.put({ id: crypto.randomUUID(), at: Date.now(), ops });\n if (db.objectStoreNames.contains(SYNC_STATE_STORE)) {\n const state = store(SYNC_STATE_STORE);\n for (const key of await state.getAllKeys()) {\n if (typeof key === 'string' && key.startsWith(BOOTSTRAP_RUN_PREFIX)) await state.delete(key);\n }\n }\n }\n}\n\nasync function migrateSegmentsToBlocks(db: IDBPDatabase, tx: IDBPTransaction<unknown, string, 'versionchange'>): Promise<void> {\n const store = (name: string) => tx.objectStore(name);\n const segments = (await store('segments').getAll()) as LegacySegment[];\n const notesStore = store('notes');\n const revisionsStore = store('block_revisions');\n\n // Group every versioned segment by note, then by positional segment id.\n const byNote = new Map<string, LegacySegment[]>();\n for (const segment of segments) {\n const list = byNote.get(segment.noteId);\n if (list) list.push(segment);\n else byNote.set(segment.noteId, [segment]);\n }\n\n // blockId per (noteId, segmentId) — sessions and block_index join through it.\n const blockIdBySegment = new Map<string, string>();\n const blockById = new Map<string, { noteId: string; from?: number; to?: number; version: number }>();\n\n for (const [noteId, noteSegments] of byNote) {\n const latestById = new Map<string, LegacySegment>();\n for (const segment of noteSegments) {\n const current = latestById.get(segment.id);\n if (!current || segment.version > current.version) latestById.set(segment.id, segment);\n }\n const latest = [...latestById.values()].sort((a, b) => (a.position ?? Number.MAX_SAFE_INTEGER) - (b.position ?? Number.MAX_SAFE_INTEGER) || a.id.localeCompare(b.id));\n const rawContent = latest.map(segment => segment.sourceContent ?? `${segment.rawContent}\\n`).join('');\n\n const note = await notesStore.get(noteId);\n if (!note) continue; // orphan segments without their note keep no state\n\n // Reconcile actionable blocks against the rebuilt source, preserving the\n // legacy positional segment id as the block id so session/block_index\n // references stay valid. Blocks with no legacy counterpart get a stable\n // positional id.\n const sections = parseDocumentSections(rawContent, { registeredWidgets: KNOWN_SECTION_WIDGETS });\n const actionableSections = sections.filter(section => actionableSectionKind(section) !== null);\n const legacyActionable = latest.filter(segment => segment.dataType in SEGMENT_TO_BLOCK_KIND);\n const blocks: Note['blocks'] = {};\n actionableSections.forEach((section, index) => {\n const kind = actionableSectionKind(section)!;\n const legacy = legacyActionable[index];\n let id = legacy?.id ?? `migrated-${index}`;\n while (Object.hasOwn(blocks, id)) id = `${id}-${index}`;\n const dialect = kind === 'wod' && (section.type === 'time' || section.type === 'log')\n ? { dialect: section.type, ...(section.sport ? { sport: section.sport } : {}) }\n : {};\n blocks[id] = { id, kind, version: legacy?.version ?? 1, sourceRevision: 1, from: section.from, to: section.to, ...dialect };\n if (legacy) blockIdBySegment.set(`${noteId}${legacy.id}`, id);\n blockById.set(`${noteId}${id}`, { noteId, from: section.from, to: section.to, version: blocks[id].version });\n });\n\n const legacy = note as Record<string, unknown>;\n delete legacy.segments;\n delete legacy.segmentIds;\n await notesStore.put({ ...legacy, rawContent, sourceRevision: 1, blocks });\n\n // Every versioned segment of an actionable id becomes a block revision\n // (historical segments included — the revision store is the history).\n const revisioned = new Set(legacyActionable.map(segment => segment.id));\n for (const segment of noteSegments) {\n if (!revisioned.has(segment.id)) continue;\n const dialect = legacyDialect(segment.rawContent);\n await revisionsStore.put({\n noteId, blockId: segment.id, version: segment.version, kind: 'wod',\n rawContent: segment.rawContent, savedAt: segment.createdAt, ...dialect,\n } satisfies BlockRevision);\n }\n }\n\n // Sessions: segmentId/segmentVersion (and the retired compute `version`)\n // become blockId/blockVersion. Values carry over unchanged — the V29 pass\n // above preserved legacy segment ids as block ids.\n const sessionsStore = store('sessions');\n for (const row of (await sessionsStore.getAll()) as LegacySession[]) {\n if (row.segmentId === undefined && row.segmentVersion === undefined && row.version === undefined) continue;\n const { segmentId, segmentVersion, version, ...rest } = row;\n await sessionsStore.put({\n ...rest,\n blockId: rest.blockId ?? segmentId ?? '',\n blockVersion: rest.blockVersion ?? segmentVersion ?? version ?? 1,\n } as Session);\n }\n\n // Events: same rename on the version field.\n const eventsStore = store('events');\n for (const row of await eventsStore.getAll() as Record<string, unknown>[]) {\n if (row.segmentVersion === undefined && row.segmentId === undefined) continue;\n const { segmentVersion, segmentId, ...rest } = row;\n await eventsStore.put({\n ...rest,\n ...(rest.blockId === undefined && segmentId !== undefined ? { blockId: segmentId } : {}),\n ...(rest.blockVersion === undefined && segmentVersion !== undefined ? { blockVersion: segmentVersion } : {}),\n });\n }\n\n // block_index: `${noteId}:${segmentId}:${segmentVersion}` →\n // `${noteId}:${blockId}` with the note block's offsets. Rows whose segment\n // vanished from the segments store keep their legacy id as the block id —\n // the index is a derived projection, never silently dropped.\n const blockIndex = store('block_index');\n for (const row of (await blockIndex.getAll()) as LegacyBlockIndexRow[]) {\n const mapped = blockIdBySegment.get(`${row.noteId}${row.segmentId}`) ?? row.segmentId;\n const block = blockById.get(`${row.noteId}${mapped}`);\n const next = {\n ...row,\n id: `${row.noteId}:${mapped}`,\n blockId: mapped,\n blockVersion: block?.version ?? row.segmentVersion ?? 1,\n sourceRevision: 1,\n ...(block ? { from: block.from, to: block.to } : {}),\n dataType: row.dataType === 'script' ? 'wod' : row.dataType,\n };\n delete (next as Record<string, unknown>).segmentId;\n delete (next as Record<string, unknown>).segmentVersion;\n if (next.id !== row.id) await blockIndex.delete(row.id);\n await blockIndex.put(next);\n }\n // block_efforts already carries blockId = the legacy positional segment id,\n // which the V29 pass preserved — no remap needed.\n\n db.deleteObjectStore('segments');\n}\n"]}