@bitcobblers/wod-wiki-storage 0.44.2160 → 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.
- package/dist/{chunk-MOGQICXM.mjs → chunk-7ICLFFYU.mjs} +2 -2
- package/dist/chunk-7ICLFFYU.mjs.map +1 -0
- package/dist/{chunk-IMNG2HY5.mjs → chunk-J6KVDPTL.mjs} +3 -3
- package/dist/chunk-J6KVDPTL.mjs.map +1 -0
- package/dist/{chunk-JFVXIJJI.mjs → chunk-PJ7GRYOZ.mjs} +8 -8
- package/dist/chunk-PJ7GRYOZ.mjs.map +1 -0
- package/dist/{chunk-IFLOX2TK.mjs → chunk-UN56ET7P.mjs} +3 -3
- package/dist/{chunk-IFLOX2TK.mjs.map → chunk-UN56ET7P.mjs.map} +1 -1
- package/dist/idb/index.cjs +1 -1
- package/dist/idb/index.cjs.map +1 -1
- package/dist/idb/index.d.cts +3 -3
- package/dist/idb/index.d.ts +3 -3
- package/dist/idb/index.mjs +3 -3
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +5 -5
- package/dist/{policy-DRYF6Y8i.d.cts → policy-BBwCBMtp.d.cts} +3 -2
- package/dist/{policy-CPscN81J.d.ts → policy-C86TCPSM.d.ts} +3 -2
- package/dist/sql/index.cjs +60 -44
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.d.cts +3 -3
- package/dist/sql/index.d.ts +3 -3
- package/dist/sql/index.mjs +64 -48
- package/dist/sql/index.mjs.map +1 -1
- package/dist/{sync-DG4Z-szj.d.cts → sync-BDu_Q__z.d.cts} +1 -1
- package/dist/{sync-Bjj_c1ea.d.ts → sync-BQ0g8ctt.d.ts} +1 -1
- package/dist/{wire-DGYxXt3I.d.ts → wire-BO8FM1LJ.d.cts} +17 -8
- package/dist/{wire-DGYxXt3I.d.cts → wire-BO8FM1LJ.d.ts} +17 -8
- package/package.json +6 -6
- package/dist/chunk-IMNG2HY5.mjs.map +0 -1
- package/dist/chunk-JFVXIJJI.mjs.map +0 -1
- package/dist/chunk-MOGQICXM.mjs.map +0 -1
|
@@ -1 +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"]}
|
|
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-UN56ET7P.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"]}
|
package/dist/idb/index.cjs
CHANGED
|
@@ -240,7 +240,7 @@ function validateStorageRow(store, value) {
|
|
|
240
240
|
const positive = (field) => typeof row[field] === "number" && Number.isSafeInteger(row[field]) && row[field] > 0;
|
|
241
241
|
const required = (field) => typeof row[field] === "string" && row[field].length > 0;
|
|
242
242
|
if (store === "notes") {
|
|
243
|
-
if (!required("id") || typeof row.title !== "string" || typeof row.rawContent !== "string" || !positive("sourceRevision") || typeof row.createdAt !== "number" || !Number.isFinite(row.createdAt) || "segments" in row || "segmentIds" in row || row.date !== void 0 && (typeof row.date !== "number" || !Number.isFinite(row.date)) || row.seedOrigin !== void 0 && row.seedOrigin !== "seed" && row.seedOrigin !== "user" || row.seedVersion !== void 0 && !(typeof row.seedVersion === "number" && Number.isSafeInteger(row.seedVersion) && row.seedVersion >= 0) || row.tags !== void 0 && (!Array.isArray(row.tags) || !row.tags.every((tag) => typeof tag === "string")) || ["type", "sourceId", "sourcePath", "
|
|
243
|
+
if (!required("id") || typeof row.title !== "string" || typeof row.rawContent !== "string" || !positive("sourceRevision") || typeof row.createdAt !== "number" || !Number.isFinite(row.createdAt) || "segments" in row || "segmentIds" in row || row.date !== void 0 && (typeof row.date !== "number" || !Number.isFinite(row.date)) || row.seedOrigin !== void 0 && row.seedOrigin !== "seed" && row.seedOrigin !== "user" || row.feedOrigin !== void 0 && row.feedOrigin !== "feed" && row.feedOrigin !== "user" || row.feedOrigin === "feed" && (row.seedOrigin === void 0 || typeof row.feedSourceId !== "string" || row.feedSourceId.length === 0) || row.feedOrigin === "user" && row.seedOrigin === "seed" || row.feedSourceId !== void 0 && row.feedOrigin !== "feed" || row.seedVersion !== void 0 && !(typeof row.seedVersion === "number" && Number.isSafeInteger(row.seedVersion) && row.seedVersion >= 0) || row.tags !== void 0 && (!Array.isArray(row.tags) || !row.tags.every((tag) => typeof tag === "string")) || ["type", "sourceId", "sourcePath", "notebookId", "seedChunkId", "feedSourceId"].some((field) => row[field] !== void 0 && typeof row[field] !== "string")) {
|
|
244
244
|
throw new StorageError(400, "invalid whole Note", "invalid_note_blocks");
|
|
245
245
|
}
|
|
246
246
|
try {
|