@bitcobblers/wod-wiki-storage 0.39.2143 → 0.40.2145

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sql/codec.ts","../src/sql/store.ts","../src/sql/sync.ts"],"names":["clauses","order","rows","params","BINARY_FIELD","def"],"mappings":"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","file":"chunk-IFLOX2TK.mjs","sourcesContent":["/**\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 * Schema-driven store operations: IDB-style stores persisted into SQL tables\n * (one per store, extracted key/index columns + full JSON in `data`). The\n * schema derives entirely from STORE_DEFS / COLUMN_TYPES; JSON payloads stay\n * the source of truth. Shared by the API server and the browser\n * BrowserTursoStorage/SqlStorage backends.\n */\nimport {\n COLUMN_TYPES,\n DB_VERSION,\n STORE_DEFS,\n type IndexDef,\n type StorageColumnType,\n type StoreDef,\n} from '../schema';\nimport {\n compareKeys,\n extractKeyPart,\n isRange,\n keyInRange,\n type KeyDTO,\n type RangeDTO,\n type Scalar,\n} from '../wire';\nimport type { Database, SqlConnection, SqlRow, SqlValue } from './connection';\nimport { StorageError } from './errors';\nimport type { StoreName } from '../contract';\nimport { decodeRowJson, encodeRowJson } from './codec';\nimport { validateStorageRow } from '../validation';\n\nexport const SCHEMA_TABLE = '_wodwiki_schema';\nconst SCHEMA_KEY = 'schema';\n\n/**\n * Store tables introduced AFTER an already-shipped schema version, keyed by\n * the version that added them. A stored database below DB_VERSION migrates\n * forward by creating exactly these tables (additive — no existing row is\n * read, rewritten or erased; ensureStoreTables below creates them); any\n * other table-set difference still fails closed (foreign/recreated database).\n */\nconst ADDED_STORES_BY_VERSION: Readonly<Record<number, readonly string[]>> = {\n 31: ['equipment', 'block_equipment'],\n};\n\n/** Store tables this server may create on a database stamped `stored`. */\nfunction additiveStoresSince(stored: number): Set<string> {\n const added = new Set<string>();\n for (const [version, names] of Object.entries(ADDED_STORES_BY_VERSION)) {\n if (Number(version) > stored) for (const name of names) added.add(name);\n }\n return added;\n}\n\n/** Stores whose rows carry a raw binary field the codec must preserve. */\nconst BINARY_FIELD: Partial<Record<StoreName, string>> = { attachments: 'data' };\n\nconst binaryFieldOf = (def: StoreDef): string | undefined => BINARY_FIELD[def.name];\n\nexport function storeDefinition(name: string): StoreDef {\n const def = STORE_DEFS.find((d) => d.name === name);\n if (!def) throw new StorageError(404, `unknown store: ${name}`);\n return def;\n}\n\nfunction indexDefinition(def: StoreDef, indexName: string): IndexDef {\n const idx = def.indexes.find((i) => i.name === indexName);\n if (!idx) throw new StorageError(404, `unknown index: ${def.name}.${indexName}`);\n return idx;\n}\n\n/** ASCII identifier chars only; everything else → '_' (safe inside quotes). */\nfunction sanitize(name: string): string {\n return name.replace(/[^A-Za-z0-9_]/g, '_');\n}\n\nconst indexCol = (indexName: string, part: number): string => `i_${sanitize(indexName)}_${part}`;\n\nfunction keyCols(def: StoreDef): string[] {\n return def.keyPath.map((_, i) => `k${i}`);\n}\n\nconst junctionTable = (def: StoreDef, idx: IndexDef): string => `${def.name}__${sanitize(idx.name)}`;\n\nconst multiEntryIndex = (def: StoreDef): IndexDef | undefined => def.indexes.find((i) => i.multiEntry);\n\nfunction pathType(def: StoreDef, path: string): StorageColumnType {\n return COLUMN_TYPES[def.name][path] ?? 'text';\n}\n\n/** SQLite store columns stay untyped (BLOB affinity) so values keep their\n * storage class and IDB ordering; PostgreSQL needs concrete types. Numbers\n * and booleans bind as float8 (booleans as 0/1), so both get DOUBLE\n * PRECISION. Text uses COLLATE \"C\" so PG ordering matches SQLite bytes. */\nfunction colSql(dialect: 'sqlite' | 'postgres', type: StorageColumnType): string {\n if (dialect === 'sqlite') return '';\n return type === 'text' ? ' TEXT COLLATE \"C\"' : ' DOUBLE PRECISION';\n}\n\n/** Runtime scalar → bound SQL value: null→NULL, bool→1/0, number/string as-is,\n * anything else → JSON text. */\nfunction toSqlScalar(v: unknown): SqlValue {\n if (v === null || v === undefined) return null;\n if (typeof v === 'boolean') return v ? 1 : 0;\n if (typeof v === 'number' || typeof v === 'string') return v;\n return JSON.stringify(v);\n}\n\nfunction validateKey(key: unknown): asserts key is KeyDTO {\n const scalar = (v: unknown): v is Scalar =>\n typeof v === 'string' || (typeof v === 'number' && Number.isFinite(v));\n if (!scalar(key) && !(Array.isArray(key) && key.length > 0 && key.every(scalar))) {\n throw new StorageError(400, 'key must be a string, finite number, or non-empty scalar tuple');\n }\n}\n\nfunction validateRange(range: RangeDTO | undefined): void {\n if (range === undefined) return;\n if (range === null || typeof range !== 'object' || Array.isArray(range)) {\n throw new StorageError(400, 'range must be an object');\n }\n for (const key of [range.only, range.lower, range.upper]) {\n if (key !== undefined) validateKey(key);\n }\n for (const open of [range.lowerOpen, range.upperOpen]) {\n if (open !== undefined && typeof open !== 'boolean') {\n throw new StorageError(400, 'range open flags must be boolean');\n }\n }\n}\n\nfunction toParts(key: KeyDTO): Scalar[] {\n validateKey(key);\n return Array.isArray(key) ? key : [key];\n}\n\n/** Reads a dotted path whose leaf must be an array (multiEntry values).\n * Shared extractKeyPart deliberately rejects array leaves, so the last hop\n * is traversed here over the parsed JSON row. */\nfunction arrayPart(value: unknown, dotted: string): unknown[] | undefined {\n let cur: unknown = value;\n for (const part of dotted.split('.')) {\n if (cur === null || typeof cur !== 'object') return undefined;\n // Traversal over parsed JSON: only plain rows are ever stored.\n const row = cur as Record<string, unknown>;\n cur = row[part];\n }\n return Array.isArray(cur) ? cur : undefined;\n}\n\n/** Primary-key extraction at the trust boundary: a missing keyPath part is\n * required-input validation → 400 (not an internal error). */\nfunction requireKey(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 StorageError(400, `keyPath part '${def.keyPath[i]}' missing on ${def.name} value`);\n }\n }\n const key = parts as Scalar[];\n return key.length === 1 ? key[0] : key;\n}\n\n/** Scalar bounds compile to the first key column; tuple bounds compile\n * part-wise when their arity fits the target columns; anything else returns\n * null → caller falls back to a scan + shared keyInRange filter. Returns the WHERE\n * clause ('' when unfiltered) and pushes bound params in order. */\nfunction rangeWhere(cols: string[], range: RangeDTO | undefined, params: SqlValue[]): string | null {\n if (!range) return '';\n if (range.only !== undefined) {\n const parts = toParts(range.only);\n if (parts.length > cols.length) return null;\n const clauses = parts.map((p, i) => {\n params.push(toSqlScalar(p));\n return `\"${cols[i]}\" = ?`;\n });\n return ` WHERE ${clauses.join(' AND ')}`;\n }\n const bounds: Array<[Scalar[], string]> = [];\n if (range.lower !== undefined && range.lower !== null) {\n bounds.push([toParts(range.lower), range.lowerOpen ? '>' : '>=']);\n }\n if (range.upper !== undefined && range.upper !== null) {\n bounds.push([toParts(range.upper), range.upperOpen ? '<' : '<=']);\n }\n const clauses: string[] = [];\n for (const [parts, op] of bounds) {\n if (parts.length > cols.length) return null;\n if (parts.length === 1) {\n params.push(toSqlScalar(parts[0]));\n clauses.push(`\"${cols[0]}\" ${op} ?`);\n } else {\n // Tuple compare: (c0,c1) >= (p0,p1) ⇔ c0 > p0 OR (c0 = p0 AND c1 >= p1)\n const ors = parts.map((p, i) => {\n const eqs: string[] = [];\n for (let j = 0; j < i; j++) {\n params.push(toSqlScalar(parts[j]));\n eqs.push(`\"${cols[j]}\" = ?`);\n }\n params.push(toSqlScalar(p));\n const cmpOp = i === parts.length - 1 ? op : op[0];\n eqs.push(`\"${cols[i]}\" ${cmpOp} ?`);\n return `(${eqs.join(' AND ')})`;\n });\n clauses.push(`(${ors.join(' OR ')})`);\n }\n }\n return clauses.length ? ` WHERE ${clauses.join(' AND ')}` : '';\n}\n\nfunction clampLimit(count: number | undefined): number | undefined {\n if (count === undefined) return undefined;\n if (typeof count !== 'number' || !Number.isFinite(count)) {\n throw new StorageError(400, `invalid count: ${String(count)}`);\n }\n return Math.max(0, Math.floor(count));\n}\n\nconst limitClause = (count: number | undefined): string =>\n count === undefined ? '' : ` LIMIT ${clampLimit(count)}`;\n\nfunction parseRows(rows: SqlRow[], binaryField?: string): unknown[] {\n return rows.map((r) => decodeRowJson(r.data as string, binaryField));\n}\n\n/** Full-table scan + in-memory IDB filtering/ordering via the shared wire\n * helpers. Only reachable for range shapes the column compile cannot express\n * (arity mismatches). Rows missing an index field are NOT in the index\n * (IDB semantics) and are skipped; a missing primary key is a 400. */\nasync function scanRows(\n conn: SqlConnection,\n def: StoreDef,\n idx: IndexDef | undefined,\n range: RangeDTO | undefined,\n limit: number | undefined,\n): Promise<unknown[]> {\n const rows = await conn.query(`SELECT \"data\" FROM \"${def.name}\"`);\n const keyed: Array<[KeyDTO, unknown]> = [];\n for (const row of rows) {\n const value = decodeRowJson(row.data as string, binaryFieldOf(def));\n if (idx) {\n const parts = idx.keyPath.map((p) => extractKeyPart(value, p));\n if (!parts.every((p): p is Scalar => p !== undefined)) continue;\n const key = parts.length === 1 ? parts[0] : parts;\n if (range && !keyInRange(key, range)) continue;\n keyed.push([key, value]);\n } else {\n const key = requireKey(def, value);\n if (range && !keyInRange(key, range)) continue;\n keyed.push([key, value]);\n }\n }\n keyed.sort((a, b) => compareKeys(a[0], b[0]));\n const out = keyed.map(([, v]) => v);\n return limit === undefined ? out : out.slice(0, limit);\n}\n\nexport async function getRow(conn: SqlConnection, def: StoreDef, key: KeyDTO): Promise<unknown | undefined> {\n const parts = toParts(key);\n if (parts.length !== def.keyPath.length) {\n throw new StorageError(400, `key arity ${parts.length} != keyPath arity ${def.keyPath.length} for ${def.name}`);\n }\n const cond = keyCols(def).map((c) => `\"${c}\" = ?`).join(' AND ');\n const rows = await conn.query(\n `SELECT \"data\" FROM \"${def.name}\" WHERE ${cond}`,\n parts.map(toSqlScalar),\n );\n return rows[0] ? decodeRowJson(rows[0].data as string, binaryFieldOf(def)) : undefined;\n}\n\nexport async function getRows(conn: SqlConnection, def: StoreDef, keys: KeyDTO[]): Promise<(unknown | undefined)[]> {\n const found = new Map<string, unknown>();\n // Batch in chunks of 50 to respect SQLite/D1 SQLITE_LIMIT_EXPR_DEPTH (100) on chained OR expressions\n for (const part of chunks(keys, 50)) {\n const params: SqlValue[] = [];\n const conditions = part.map(key => {\n const parts = toParts(key);\n if (parts.length !== def.keyPath.length) throw new StorageError(400, 'invalid compound key arity');\n params.push(...parts.map(toSqlScalar));\n return `(${keyCols(def).map(col => `\"${col}\" = ?`).join(' AND ')})`;\n });\n for (const row of await conn.query(`SELECT \"data\" FROM \"${def.name}\" WHERE ${conditions.join(' OR ')}`, params)) {\n const value = decodeRowJson(String(row.data), binaryFieldOf(def));\n found.set(JSON.stringify(requireKey(def, value)), value);\n }\n }\n return keys.map(key => found.get(JSON.stringify(key)));\n}\n\nexport async function listRowsFromIndexMany(conn: SqlConnection, def: StoreDef, indexName: string, keys: KeyDTO[]): Promise<unknown[][]> {\n const idx = indexDefinition(def, indexName);\n if (idx.multiEntry) {\n const out: unknown[][] = [];\n for (const key of keys) out.push(await listRows(conn, def, { only: key }, undefined, indexName));\n return out;\n }\n const found = new Map<string, unknown[]>();\n // Batch in chunks of 50 to respect SQLite/D1 SQLITE_LIMIT_EXPR_DEPTH (100) on chained OR expressions\n for (const part of chunks(keys, 50)) {\n const params: SqlValue[] = [];\n const conditions = part.map(key => {\n const parts = toParts(key);\n if (parts.length !== idx.keyPath.length) throw new StorageError(400, 'invalid index key arity');\n params.push(...parts.map(toSqlScalar));\n return `(${parts.map((_, i) => `\"${indexCol(idx.name, i)}\" = ?`).join(' AND ')})`;\n });\n for (const row of await conn.query(`SELECT \"data\" FROM \"${def.name}\" WHERE ${conditions.join(' OR ')} ORDER BY ${keyCols(def).map(col => `\"${col}\"`).join(', ')}`, params)) {\n const value = decodeRowJson(String(row.data), binaryFieldOf(def));\n const parts = idx.keyPath.map(path => extractKeyPart(value, path));\n const key = JSON.stringify(parts.length === 1 ? parts[0] : parts);\n const bucket = found.get(key);\n if (bucket) bucket.push(value); else found.set(key, [value]);\n }\n }\n return keys.map(key => found.get(JSON.stringify(key)) ?? []);\n}\n\nexport async function listRows(\n conn: SqlConnection,\n def: StoreDef,\n range?: RangeDTO,\n count?: number,\n indexName?: string,\n): Promise<unknown[]> {\n validateRange(range);\n const idx = indexName ? indexDefinition(def, indexName) : undefined;\n const binaryField = binaryFieldOf(def);\n if (idx?.multiEntry) {\n // JSON encoding preserves numeric/string equality in both SQL dialects.\n const only = range?.only;\n if (only === undefined || typeof only === 'object') {\n throw new StorageError(400, `multi-entry index ${def.name}.${idx.name} supports exact-match queries only`);\n }\n const joinOn = keyCols(def).map((c) => `j.\"${c}\" = e.\"${c}\"`).join(' AND ');\n // IDB multi-entry ordering: junction value first, then the primary key.\n const order = ['j.\"v\"', ...keyCols(def).map((c) => `j.\"${c}\"`)].join(', ');\n const rows = await conn.query(\n `SELECT e.\"data\" AS \"data\" FROM \"${def.name}\" e JOIN \"${junctionTable(def, idx)}\" j ON ${joinOn}` +\n ` WHERE j.\"v\" = ? ORDER BY ${order}${limitClause(count)}`,\n [JSON.stringify(only)],\n );\n return parseRows(rows, binaryField);\n }\n const cols = idx ? idx.keyPath.map((_, part) => indexCol(idx.name, part)) : keyCols(def);\n const params: SqlValue[] = [];\n const where = rangeWhere(cols, range, params);\n if (where === null) return scanRows(conn, def, idx, range, clampLimit(count));\n // IDB: rows whose index key is missing/invalid are not in the index —\n // exclude them even from unfiltered listings (SQL NULL comparison alone\n // only drops them from bounded ranges). NULLS never reach ORDER BY.\n const notNull = cols.map((c) => `\"${c}\" IS NOT NULL`).join(' AND ');\n const cond = where ? `${where} AND ${notNull}` : ` WHERE ${notNull}`;\n // IDB orders index results by (index key, primary key).\n const keyNames = keyCols(def).filter((k) => !cols.includes(k));\n const order = ` ORDER BY ${[...cols, ...keyNames].map((c) => `\"${c}\"`).join(', ')}`;\n const rows = await conn.query(\n `SELECT \"data\" FROM \"${def.name}\"${cond}${order}${limitClause(count)}`,\n params,\n );\n return parseRows(rows, binaryField);\n}\n\nexport async function countRows(\n conn: SqlConnection,\n def: StoreDef,\n range?: RangeDTO,\n indexName?: string,\n): Promise<number> {\n validateRange(range);\n const idx = indexName ? indexDefinition(def, indexName) : undefined;\n if (idx?.multiEntry) {\n const only = range?.only;\n if (only === undefined || typeof only === 'object') {\n throw new StorageError(400, `multi-entry index ${def.name}.${idx.name} supports exact-match queries only`);\n }\n const joinOn = keyCols(def).map((c) => `j.\"${c}\" = e.\"${c}\"`).join(' AND ');\n const rows = await conn.query(\n `SELECT COUNT(*) AS \"n\" FROM \"${def.name}\" e JOIN \"${junctionTable(def, idx)}\" j ON ${joinOn} WHERE j.\"v\" = ?`,\n [JSON.stringify(only)],\n );\n return Number(rows[0]?.n ?? 0);\n }\n const cols = idx ? idx.keyPath.map((_, part) => indexCol(idx.name, part)) : keyCols(def);\n const params: SqlValue[] = [];\n const where = rangeWhere(cols, range, params);\n if (where === null) {\n const all = await scanRows(conn, def, idx, range, undefined);\n return all.length;\n }\n const cond = idx ? (where ? `${where} AND ${cols.map((c) => `\"${c}\" IS NOT NULL`).join(' AND ')}` : ` WHERE ${cols.map((c) => `\"${c}\" IS NOT NULL`).join(' AND ')}`) : where;\n const rows = await conn.query(`SELECT COUNT(*) AS \"n\" FROM \"${def.name}\"${cond}`, params);\n return Number(rows[0]?.n ?? 0);\n}\n\n/** Bound-parameter budget per statement. SQLite ≥3.32 allows 32766; 20k\n * leaves headroom, and the row cap keeps single request bodies ≤ ~1 MB. */\nconst PARAM_BUDGET = 20000;\nconst ROW_CAP = 100;\n\nconst chunks = <T>(arr: T[], size: number): T[][] => {\n const out: T[][] = [];\n for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));\n return out;\n};\n\n/** Multi-row `INSERT … ON CONFLICT` in param-budgeted chunks. One round trip\n * per chunk over Turso instead of one per row. `cols` are internal schema\n * identifiers (never user input); `onConflict` is the full trailing clause. */\nexport async function batchInsert(\n conn: SqlConnection,\n table: string,\n cols: string[],\n rows: SqlValue[][],\n onConflict: string,\n): Promise<void> {\n if (rows.length === 0) return;\n const collist = cols.map((c) => `\"${c}\"`).join(', ');\n const tuple = `(${cols.map(() => '?').join(', ')})`;\n const per = Math.max(1, Math.min(ROW_CAP, Math.floor(PARAM_BUDGET / cols.length)));\n const statements = chunks(rows, per).map(part => ({\n sql: `INSERT INTO \"${table}\" (${collist}) VALUES ${part.map(() => tuple).join(', ')} ${onConflict}`,\n params: part.flat(),\n }));\n if (conn.batch) await conn.batch(statements);\n else for (const statement of statements) await conn.exec(statement.sql, statement.params);\n}\n\n/** Chunked `DELETE … WHERE col IN (…)` — one round trip per chunk. */\nexport async function deleteIn(conn: SqlConnection, table: string, col: string, vals: SqlValue[]): Promise<void> {\n for (const part of chunks(vals, 500)) {\n if (part.length === 0) continue;\n await conn.exec(`DELETE FROM \"${table}\" WHERE \"${col}\" IN (${part.map(() => '?').join(', ')})`, part);\n }\n}\n\nexport async function putRows(conn: SqlConnection, def: StoreDef, values: unknown[], changedKeys?: KeyDTO[]): Promise<KeyDTO[]> {\n if (values.length === 0) return [];\n for (const value of values) validateStorageRow(def.name, value);\n const keys = keyCols(def);\n const cols = [...keys];\n for (const idx of def.indexes) {\n if (idx.multiEntry) continue;\n idx.keyPath.forEach((_, part) => cols.push(indexCol(idx.name, part)));\n }\n cols.push('data');\n const keySet = new Set(keys);\n const updates = cols.filter((c) => !keySet.has(c)).map((c) => `\"${c}\" = excluded.\"${c}\"`).join(', ');\n const pk = keys.map((k) => `\"${k}\"`).join(', ');\n\n const rows: SqlValue[][] = [];\n const out: KeyDTO[] = [];\n const junction: SqlValue[][] = [];\n const multi = multiEntryIndex(def);\n for (const value of values) {\n const k = requireKey(def, value);\n const keyParts = toParts(k).map(toSqlScalar);\n const vals = [...keyParts];\n for (const idx of def.indexes) {\n if (idx.multiEntry) continue;\n idx.keyPath.forEach((path) => vals.push(toSqlScalar(extractKeyPart(value, path) ?? null)));\n }\n vals.push(encodeRowJson(value, binaryFieldOf(def)));\n rows.push(vals);\n out.push(k);\n if (multi) {\n const items = arrayPart(value, multi.keyPath[0]);\n if (Array.isArray(items)) {\n for (const item of items) junction.push([...keyParts, JSON.stringify(item)]);\n }\n }\n }\n const tuple = `(${cols.map(() => '?').join(', ')})`;\n const per = Math.max(1, Math.min(ROW_CAP, Math.floor(PARAM_BUDGET / cols.length)));\n const statements = chunks(rows, per).map(part => ({\n sql: `INSERT INTO \"${def.name}\" (${cols.map(col => `\"${col}\"`).join(', ')}) VALUES ${part.map(() => tuple).join(', ')} `\n + (def.name === 'block_revisions' ? `ON CONFLICT (${pk}) DO NOTHING` : `ON CONFLICT (${pk}) DO UPDATE SET ${updates} WHERE \"${def.name}\".\"data\" <> excluded.\"data\"`)\n + ` RETURNING ${keys.map(col => `\"${col}\"`).join(', ')}`,\n params: part.flat(),\n }));\n let returned: SqlRow[][];\n try {\n if (conn.batch) returned = await conn.batch(statements);\n else {\n returned = [];\n for (const statement of statements) returned.push(await conn.query(statement.sql, statement.params));\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n for (const code of ['revision_conflict', 'transaction_conflict', 'invalid_session_pin']) {\n if (message.includes(code)) throw new StorageError(409, message, code);\n }\n throw error;\n }\n const changed = returned.flat().map(row => {\n const parts = keys.map(col => row[col]) as Scalar[];\n return parts.length === 1 ? parts[0] : parts;\n });\n changedKeys?.push(...changed);\n if (multi) {\n const jt = junctionTable(def, multi);\n const changedSet = new Set(changed.map(key => JSON.stringify(key)));\n const deletes = values.flatMap(value => {\n const key = requireKey(def, value);\n if (!changedSet.has(JSON.stringify(key))) return [];\n const items = arrayPart(value, multi.keyPath[0]) ?? [];\n return [{ sql: `DELETE FROM \"${jt}\" WHERE ${keys.map(col => `\"${col}\" = ?`).join(' AND ')}`\n + (items.length ? ` AND \"v\" NOT IN (${items.map(() => '?').join(', ')})` : ''),\n params: [...toParts(key).map(toSqlScalar), ...items.map(item => JSON.stringify(item))] }];\n });\n if (conn.batch && deletes.length) await conn.batch(deletes);\n else for (const statement of deletes) await conn.exec(statement.sql, statement.params);\n await batchInsert(conn, jt, [...keys, 'v'], junction.filter(row => changedSet.has(JSON.stringify(keys.length === 1 ? row[0] : row.slice(0, keys.length)))), 'ON CONFLICT DO NOTHING');\n }\n return out;\n}\n\nexport async function putRow(conn: SqlConnection, def: StoreDef, value: unknown): Promise<KeyDTO> {\n return (await putRows(conn, def, [value]))[0];\n}\n\nexport async function deleteRows(conn: SqlConnection, def: StoreDef, keyOrRange: KeyDTO | RangeDTO): Promise<void> {\n if (def.name === 'block_revisions') throw new StorageError(409, 'block history may only be removed by explicit wipe', 'revision_conflict');\n const multi = multiEntryIndex(def);\n if (!isRange(keyOrRange)) {\n const parts = toParts(keyOrRange);\n if (parts.length > def.keyPath.length) {\n throw new StorageError(400, `key arity ${parts.length} > keyPath arity ${def.keyPath.length} for ${def.name}`);\n }\n const n = Math.min(parts.length, def.keyPath.length);\n const cond = keyCols(def).slice(0, n).map((c) => `\"${c}\" = ?`).join(' AND ');\n const params = parts.slice(0, n).map(toSqlScalar);\n if (multi) await conn.exec(`DELETE FROM \"${junctionTable(def, multi)}\" WHERE ${cond}`, params);\n await conn.exec(`DELETE FROM \"${def.name}\" WHERE ${cond}`, params);\n return;\n }\n validateRange(keyOrRange);\n const cols = keyCols(def);\n const params: SqlValue[] = [];\n const where = rangeWhere(cols, keyOrRange, params);\n if (where === null) {\n // Uncompilable shape: enumerate matching rows, delete per key.\n for (const row of await listRows(conn, def, keyOrRange)) {\n await deleteRows(conn, def, requireKey(def, row));\n }\n return;\n }\n const collist = cols.map((c) => `\"${c}\"`).join(', ');\n if (multi) {\n await conn.exec(\n `DELETE FROM \"${junctionTable(def, multi)}\" WHERE (${collist}) IN (SELECT ${collist} FROM \"${def.name}\"${where})`,\n params,\n );\n }\n await conn.exec(`DELETE FROM \"${def.name}\"${where}`, params);\n}\n\nexport async function clearRows(conn: SqlConnection, def: StoreDef, wipe = false): Promise<void> {\n if (def.name === 'block_revisions' && !wipe) throw new StorageError(409, 'block history may only be removed by explicit wipe', 'revision_conflict');\n const multi = multiEntryIndex(def);\n if (multi) await conn.exec(`DELETE FROM \"${junctionTable(def, multi)}\"`);\n await conn.exec(`DELETE FROM \"${def.name}\"`);\n}\n\n/** Wipe all user stores; system stores (memberships) survive and the internal\n * schema metadata table is not a store, so the version guard is untouched. */\nexport async function wipeRows(conn: SqlConnection): Promise<void> {\n for (const def of STORE_DEFS) {\n if (!def.system) await clearRows(conn, def, true);\n }\n}\n\nfunction tableListSql(dialect: 'sqlite' | 'postgres'): string {\n return dialect === 'sqlite'\n ? `SELECT \"name\" FROM \"sqlite_master\" WHERE \"type\" = 'table'`\n : `SELECT \"table_name\" FROM \"information_schema\".\"tables\" WHERE \"table_schema\" = current_schema()`;\n}\n\n/** Create the current schema only. Existing incompatible versions fail closed. */\nasync function ensureStoreTables(\n conn: SqlConnection,\n dialect: 'sqlite' | 'postgres',\n def: StoreDef,\n): Promise<void> {\n const keys = keyCols(def);\n const cols: Array<[string, string]> = keys.map((k, i) => [k, colSql(dialect, pathType(def, def.keyPath[i]))]);\n for (const idx of def.indexes) {\n if (idx.multiEntry) continue;\n idx.keyPath.forEach((path, part) => {\n cols.push([indexCol(idx.name, part), colSql(dialect, pathType(def, path))]);\n });\n }\n cols.push(['data', ' TEXT NOT NULL']);\n const colDefs = cols.map(([c, t]) => `\"${c}\"${t}`);\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS \"${def.name}\" (${colDefs.join(', ')}, PRIMARY KEY (${keys.map((k) => `\"${k}\"`).join(', ')}))`,\n );\n for (const idx of def.indexes) {\n if (idx.multiEntry) continue;\n const parts = idx.keyPath.map((_, part) => `\"${indexCol(idx.name, part)}\"`).join(', ');\n await conn.exec(\n `CREATE ${idx.unique ? 'UNIQUE ' : ''}INDEX IF NOT EXISTS \"${def.name}__${sanitize(idx.name)}\" ON \"${def.name}\" (${parts})`,\n );\n }\n const multi = multiEntryIndex(def);\n if (multi) {\n const jt = junctionTable(def, multi);\n const jkeys = keys.map((k, i) => `\"${k}\"${colSql(dialect, pathType(def, def.keyPath[i]))}`);\n // v: BLOB affinity on sqlite (storage class preserved), byte-order C on PG.\n await conn.exec(\n `CREATE TABLE IF NOT EXISTS \"${jt}\" (${jkeys.join(', ')}, \"v\"${colSql(dialect, 'text')}, PRIMARY KEY (${[...keys, '\"v\"'].join(', ')}))`,\n );\n await conn.exec(`CREATE INDEX IF NOT EXISTS \"${jt}__v\" ON \"${jt}\" (\"v\")`);\n }\n if (def.name === 'notes' && dialect === 'sqlite') {\n await conn.exec(`CREATE TRIGGER IF NOT EXISTS \"notes_revision_guard\" BEFORE UPDATE ON \"notes\"\n WHEN json_extract(NEW.\"data\", '$.sourceRevision') < json_extract(OLD.\"data\", '$.sourceRevision')\n OR ((json_extract(NEW.\"data\", '$.rawContent') IS NOT json_extract(OLD.\"data\", '$.rawContent')\n OR json_extract(NEW.\"data\", '$.blocks') IS NOT json_extract(OLD.\"data\", '$.blocks'))\n AND json_extract(NEW.\"data\", '$.sourceRevision') <= json_extract(OLD.\"data\", '$.sourceRevision'))\n BEGIN SELECT RAISE(ABORT, 'transaction_conflict: stale Note source revision'); END`);\n }\n if (def.name === 'block_revisions' && dialect === 'sqlite') {\n await conn.exec(`CREATE TRIGGER IF NOT EXISTS \"block_revision_guard\" BEFORE INSERT ON \"block_revisions\"\n WHEN EXISTS (SELECT 1 FROM \"block_revisions\" old WHERE old.\"k0\" = NEW.\"k0\" AND old.\"k1\" = NEW.\"k1\" AND old.\"k2\" = NEW.\"k2\" AND old.\"data\" <> NEW.\"data\")\n BEGIN SELECT RAISE(ABORT, 'revision_conflict: immutable block revision collision'); END`);\n }\n if (def.name === 'sessions' && dialect === 'sqlite') {\n await conn.exec(`CREATE TRIGGER IF NOT EXISTS \"session_pin_guard\" BEFORE UPDATE ON \"sessions\"\n WHEN json_extract(NEW.\"data\", '$.noteId') IS NOT json_extract(OLD.\"data\", '$.noteId')\n OR json_extract(NEW.\"data\", '$.blockId') IS NOT json_extract(OLD.\"data\", '$.blockId')\n OR json_extract(NEW.\"data\", '$.blockVersion') IS NOT json_extract(OLD.\"data\", '$.blockVersion')\n BEGIN SELECT RAISE(ABORT, 'invalid_session_pin: Session pin is immutable'); END`);\n }\n if (dialect === 'postgres' && ['notes', 'block_revisions', 'sessions'].includes(def.name)) {\n const condition = def.name === 'block_revisions'\n ? `EXISTS (SELECT 1 FROM \"block_revisions\" saved WHERE saved.\"k0\" = NEW.\"k0\" AND saved.\"k1\" = NEW.\"k1\" AND saved.\"k2\" = NEW.\"k2\" AND saved.\"data\" <> NEW.\"data\")`\n : def.name === 'notes'\n ? `(NEW.\"data\"::jsonb->>'sourceRevision')::bigint < (OLD.\"data\"::jsonb->>'sourceRevision')::bigint OR ((NEW.\"data\"::jsonb->'rawContent' IS DISTINCT FROM OLD.\"data\"::jsonb->'rawContent' OR NEW.\"data\"::jsonb->'blocks' IS DISTINCT FROM OLD.\"data\"::jsonb->'blocks') AND (NEW.\"data\"::jsonb->>'sourceRevision')::bigint <= (OLD.\"data\"::jsonb->>'sourceRevision')::bigint)`\n : `NEW.\"data\"::jsonb->'noteId' IS DISTINCT FROM OLD.\"data\"::jsonb->'noteId' OR NEW.\"data\"::jsonb->'blockId' IS DISTINCT FROM OLD.\"data\"::jsonb->'blockId' OR NEW.\"data\"::jsonb->'blockVersion' IS DISTINCT FROM OLD.\"data\"::jsonb->'blockVersion'`;\n const code = def.name === 'block_revisions' ? 'revision_conflict' : def.name === 'notes' ? 'transaction_conflict' : 'invalid_session_pin';\n const guard = `${def.name}_guard`;\n await conn.exec(`CREATE OR REPLACE FUNCTION \"${guard}\"() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF ${condition} THEN RAISE EXCEPTION '${code}'; END IF; RETURN NEW; END; $$`);\n await conn.exec(`DROP TRIGGER IF EXISTS \"${guard}\" ON \"${def.name}\"`);\n await conn.exec(`CREATE TRIGGER \"${guard}\" BEFORE ${def.name === 'block_revisions' ? 'INSERT' : 'UPDATE'} ON \"${def.name}\" FOR EACH ROW EXECUTE FUNCTION \"${guard}\"()`);\n }\n}\n\n/** Internal schema metadata is not exposed or cleared by the store API.\n *\n * Version policy: the SQL DDL derives entirely from STORE_DEFS, so two\n * schema versions are compatible iff their derived table sets are equal.\n * - stored > DB_VERSION → refuse (never downgrade).\n * - stored < DB_VERSION with EQUAL table sets (v29 → v30: defs unchanged,\n * only browser-local sync stores were added) → bump the guard in place;\n * no row is read, rewritten or erased.\n * - stored < DB_VERSION with different tables → fail closed with the same\n * actionable schema_incompatible error as before.\n * - no guard + store tables → foreign database, refuse. */\nexport async function initializeStore(db: Database): Promise<void> {\n await db.transaction(async (tx) => {\n await tx.exec(\n `CREATE TABLE IF NOT EXISTS \"${SCHEMA_TABLE}\" (\"key\" TEXT PRIMARY KEY, \"value\" TEXT NOT NULL)`,\n );\n // Layered sync protocol tables + libsql internals are not part of the\n // STORE_DEFS-derived schema and never participate in the comparison.\n const ignored = (name: string): boolean =>\n name.startsWith('_wodwiki_') || name.startsWith('sqlite_') || name === 'domain_note' || name === 'query_block';\n const storeTables = new Set<string>(STORE_DEFS.map((d) => d.name));\n for (const def of STORE_DEFS) {\n const multi = def.indexes.find((i) => i.multiEntry);\n if (multi) storeTables.add(junctionTable(def, multi));\n }\n const tableNames = new Set(\n (await tx.query(tableListSql(db.dialect))).map((r) => String(Object.values(r)[0])).filter((n) => !ignored(n)),\n );\n const guardRows = await tx.query(`SELECT \"value\" FROM \"${SCHEMA_TABLE}\" WHERE \"key\" = ?`, [SCHEMA_KEY]);\n let stored: number | undefined;\n if (guardRows[0]) {\n const guard = JSON.parse(String(guardRows[0].value)) as { version?: unknown };\n if (typeof guard.version !== 'number' || !Number.isSafeInteger(guard.version) || guard.version < 0) {\n throw new StorageError(500, `corrupt ${SCHEMA_TABLE} guard row`, 'bad_schema_guard');\n }\n stored = guard.version;\n if (stored > DB_VERSION) {\n throw new StorageError(\n 500,\n `database schema v${stored} is newer than this server supports (v${DB_VERSION}); refusing to downgrade`,\n 'schema_incompatible',\n );\n }\n if (stored < DB_VERSION) {\n const missing = [...storeTables].filter((name) => !tableNames.has(name));\n const unexpected = [...tableNames].filter((name) => name !== SCHEMA_TABLE && !storeTables.has(name));\n const additive = additiveStoresSince(stored);\n if (stored < 30 || unexpected.length > 0 || missing.some((name) => !additive.has(name))) {\n throw new StorageError(\n 500,\n `database schema v${stored} is incompatible with v${DB_VERSION} (missing tables: ${missing.join(', ') || 'none'}; unrecognized tables: ${unexpected.join(', ') || 'none'}); recreation required using an explicitly disposable database`,\n 'schema_incompatible',\n );\n }\n // Only recognized additive stores are missing — ensureStoreTables\n // below creates them; the stored rows are never touched. Everything\n // else equalities hold and only the guard version moves forward.\n }\n } else if ([...tableNames].some((name) => storeTables.has(name))) {\n throw new StorageError(\n 500,\n 'database contains store tables but no wod-wiki schema guard; refusing to adopt a foreign database — point SQLITE_PATH/DATABASE_URL at a fresh database',\n 'foreign_database',\n );\n }\n for (const def of STORE_DEFS) await ensureStoreTables(tx, db.dialect, def);\n if (stored !== DB_VERSION) {\n await tx.exec(\n `INSERT INTO \"${SCHEMA_TABLE}\" (\"key\", \"value\") VALUES (?, ?) ON CONFLICT (\"key\") DO UPDATE SET \"value\" = excluded.\"value\"`,\n [SCHEMA_KEY, JSON.stringify({ version: DB_VERSION })],\n );\n }\n });\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"]}
@@ -2,7 +2,7 @@ import { StorageError } from './chunk-XRQKLSOT.mjs';
2
2
  import { validateNoteBlocks } from '@bitcobblers/wod-wiki-core';
3
3
 
4
4
  // src/schema.ts
5
- var DB_VERSION = 31;
5
+ var DB_VERSION = 32;
6
6
  var COLUMN_TYPES = {
7
7
  notes: { date: "number", createdAt: "number" },
8
8
  page: { createdAt: "number" },
@@ -279,58 +279,6 @@ function keyInRange(key, range) {
279
279
  }
280
280
  return true;
281
281
  }
282
- var DOMAIN_PROJECTION_VERSION = 2;
283
- function isObject(value) {
284
- return typeof value === "object" && value !== null && !Array.isArray(value);
285
- }
286
- function optionalStrings(row, fields) {
287
- return fields.every((field) => row[field] === void 0 || typeof row[field] === "string");
288
- }
289
- function finiteNumbers(row, fields) {
290
- return fields.every((field) => typeof row[field] === "number" && Number.isFinite(row[field]));
291
- }
292
- function isNote(value) {
293
- if (!isObject(value) || typeof value.id !== "string" || typeof value.title !== "string" || typeof value.rawContent !== "string" || !Number.isSafeInteger(value.sourceRevision) || typeof value.sourceRevision !== "number" || value.sourceRevision < 1 || !isObject(value.blocks) || !finiteNumbers(value, ["createdAt"]) || value.date !== void 0 && !finiteNumbers(value, ["date"]) || !optionalStrings(value, ["type", "sourceId", "catalog", "notebookId", "sourcePath", "seedOrigin", "seedChunkId"]) || value.tags !== void 0 && (!Array.isArray(value.tags) || !value.tags.every((tag) => typeof tag === "string"))) return false;
294
- try {
295
- validateNoteBlocks(value.rawContent, value.blocks, value.sourceRevision);
296
- return true;
297
- } catch {
298
- return false;
299
- }
300
- }
301
- function isBlock(value) {
302
- return isObject(value) && typeof value.id === "string" && typeof value.noteId === "string" && typeof value.blockId === "string" && finiteNumbers(value, ["blockVersion", "sourceRevision", "from", "to", "createdAt"]) && value.id === `${value.noteId}:${value.blockId}` && typeof value.blockVersion === "number" && Number.isSafeInteger(value.blockVersion) && value.blockVersion > 0 && typeof value.sourceRevision === "number" && Number.isSafeInteger(value.sourceRevision) && value.sourceRevision > 0 && typeof value.from === "number" && Number.isSafeInteger(value.from) && value.from >= 0 && typeof value.to === "number" && Number.isSafeInteger(value.to) && value.to > value.from && ["wod", "query", "widget", "embed"].includes(String(value.dataType)) && typeof value.rawContent === "string" && typeof value.noteTitle === "string" && optionalStrings(value, ["blockContentId", "sourceId", "sourcePath", "routeId"]) && (value.position === void 0 || finiteNumbers(value, ["position"])) && (value.isStatic === void 0 || typeof value.isStatic === "boolean");
303
- }
304
- function isTag(value) {
305
- return isObject(value) && typeof value.id === "string" && typeof value.label === "string" && finiteNumbers(value, ["createdAt"]) && optionalStrings(value, ["type"]);
306
- }
307
- function isPage(value) {
308
- return isObject(value) && typeof value.id === "string" && finiteNumbers(value, ["createdAt"]) && optionalStrings(value, ["date", "slug", "title"]);
309
- }
310
- function isLink(value) {
311
- return isObject(value) && typeof value.id === "string" && typeof value.noteId === "string" && typeof value.pageId === "string" && finiteNumbers(value, ["createdAt"]) && (value.position === void 0 || finiteNumbers(value, ["position"]));
312
- }
313
- function isEntry(value) {
314
- return isObject(value) && isNote(value.note) && Array.isArray(value.tags) && value.tags.every(isTag) && Array.isArray(value.links) && value.links.every(isLink) && Array.isArray(value.pages) && value.pages.every(isPage);
315
- }
316
- function parseDomainQueryResult(value, plan) {
317
- if (!isObject(value) || value.projectionVersion !== DOMAIN_PROJECTION_VERSION || value.plan !== plan || !Array.isArray(value.rows) || typeof value.selectedCount !== "number" || !Number.isSafeInteger(value.selectedCount) || value.selectedCount < 0 || typeof value.matchedCount !== "number" || !Number.isSafeInteger(value.matchedCount) || value.matchedCount < 0 || value.matchedCount > value.selectedCount || value.rows.length > value.matchedCount) {
318
- throw new Error("ApiStorage: invalid or stale domain projection response");
319
- }
320
- const counts = { projectionVersion: DOMAIN_PROJECTION_VERSION, selectedCount: value.selectedCount, matchedCount: value.matchedCount };
321
- switch (plan) {
322
- case "notes":
323
- if (value.rows.every(isNote)) return { ...counts, plan, rows: value.rows };
324
- break;
325
- case "blocks":
326
- if (value.rows.every(isBlock)) return { ...counts, plan, rows: value.rows };
327
- break;
328
- case "entries":
329
- if (value.rows.every(isEntry)) return { ...counts, plan, rows: value.rows };
330
- break;
331
- }
332
- throw new Error("ApiStorage: invalid domain query rows");
333
- }
334
282
  function rowsEqual(left, right) {
335
283
  if (Object.is(left, right)) return true;
336
284
  if (left instanceof ArrayBuffer && right instanceof ArrayBuffer) {
@@ -412,81 +360,6 @@ async function validateStoredPins(notes, sessions, getRevisions) {
412
360
  }
413
361
  }
414
362
 
415
- // src/overlay.ts
416
- var bufferSlot = (store, key) => `${store}\0${JSON.stringify(key)}`;
417
- function isDirty(store, buffer, cleared) {
418
- if (cleared?.has(store)) return true;
419
- if (!buffer) return false;
420
- const prefix = `${store}\0`;
421
- for (const slot of buffer.keys()) {
422
- if (slot.startsWith(prefix)) return true;
423
- }
424
- return false;
425
- }
426
- function bufferedGet(store, key, buffer) {
427
- if (!buffer) return void 0;
428
- const entry = buffer.get(bufferSlot(store, key));
429
- if (!entry) return void 0;
430
- return entry.kind === "put" ? { hit: true, value: entry.value } : { hit: false };
431
- }
432
- function overlayRows(def, store, buffer, cleared, rows, count, range, indexName) {
433
- if (!buffer || !isDirty(store, buffer, cleared)) return count !== void 0 ? rows.slice(0, count) : rows;
434
- const out = /* @__PURE__ */ new Map();
435
- if (!cleared?.has(store)) {
436
- for (const row of rows) out.set(JSON.stringify(keyFromValue(def, row)), row);
437
- }
438
- const prefix = `${store}\0`;
439
- for (const [slot, entry] of buffer) {
440
- if (!slot.startsWith(prefix)) continue;
441
- if (entry.kind === "put") out.set(slot.slice(prefix.length), entry.value);
442
- else out.delete(slot.slice(prefix.length));
443
- }
444
- const index = indexName ? def.indexes.find((i) => i.name === indexName) : void 0;
445
- if (indexName && !index) throw new Error(`unknown index '${indexName}' for ${store}`);
446
- const keyOf = (row) => {
447
- if (!index) return keyFromValue(def, row);
448
- const parts = index.keyPath.map((path) => extractKeyPart(row, path));
449
- if (parts.some((part) => part === void 0)) return void 0;
450
- const keys = parts.filter((part) => part !== void 0);
451
- return keys.length === 1 ? keys[0] : keys;
452
- };
453
- const matches = (row) => {
454
- if (index?.multiEntry) {
455
- let values = row;
456
- for (const part of index.keyPath[0].split(".")) {
457
- if (values === null || typeof values !== "object" || !(part in values)) return false;
458
- values = Reflect.get(values, part);
459
- }
460
- return Array.isArray(values) && values.some((value) => (typeof value === "string" || typeof value === "number") && (!range || keyInRange(value, range)));
461
- }
462
- const key = keyOf(row);
463
- return key !== void 0 && (!range || keyInRange(key, range));
464
- };
465
- const merged = [...out.values()].filter(matches);
466
- merged.sort((a, b) => {
467
- const primary = compareKeys(keyFromValue(def, a), keyFromValue(def, b));
468
- if (index?.multiEntry) return primary;
469
- const ak = keyOf(a), bk = keyOf(b);
470
- return ak !== void 0 && bk !== void 0 ? compareKeys(ak, bk) || primary : primary;
471
- });
472
- return count !== void 0 ? merged.slice(0, count) : merged;
473
- }
474
- function bufferToOps(storeNames, buffer, cleared) {
475
- const known = new Set(storeNames);
476
- const ops = [];
477
- for (const store of cleared) {
478
- if (known.has(store)) ops.push({ op: "clear", store });
479
- }
480
- for (const [slot, entry] of buffer) {
481
- const sep = slot.indexOf("\0");
482
- const store = slot.slice(0, sep);
483
- if (!known.has(store)) continue;
484
- if (entry.kind === "put") ops.push({ op: "put", store, value: entry.value });
485
- else ops.push({ op: "delete", store, key: JSON.parse(slot.slice(sep + 1)) });
486
- }
487
- return ops;
488
- }
489
-
490
- export { COLUMN_TYPES, DB_VERSION, DEFAULT_MEMBERSHIP_ID, DOMAIN_PROJECTION_VERSION, STORE_DEFS, USER_OWNED_STORES, bufferSlot, bufferToOps, bufferedGet, compareKeys, createDefaultMembership, encodeKey, extractKeyPart, isDirty, isRange, keyFromValue, keyInRange, overlayRows, parseDomainQueryResult, rangeFromIDB, rowsEqual, stampUserOwned, validateNoteWrite, validateSessionWrite, validateStorageRow, validateStoredPins };
491
- //# sourceMappingURL=chunk-NUJEAUAK.mjs.map
492
- //# sourceMappingURL=chunk-NUJEAUAK.mjs.map
363
+ export { COLUMN_TYPES, DB_VERSION, DEFAULT_MEMBERSHIP_ID, STORE_DEFS, USER_OWNED_STORES, compareKeys, createDefaultMembership, encodeKey, extractKeyPart, isRange, keyFromValue, keyInRange, rangeFromIDB, rowsEqual, stampUserOwned, validateNoteWrite, validateSessionWrite, validateStorageRow, validateStoredPins };
364
+ //# sourceMappingURL=chunk-IMNG2HY5.mjs.map
365
+ //# sourceMappingURL=chunk-IMNG2HY5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/membership.ts","../src/wire.ts","../src/validation.ts"],"names":["a","b"],"mappings":"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","file":"chunk-IMNG2HY5.mjs","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 * 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","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"]}