@korajs/store 1.0.0-beta.12 → 1.0.0-beta.14
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/README.md +29 -37
- package/dist/adapters/better-sqlite3.cjs +90 -4
- package/dist/adapters/better-sqlite3.cjs.map +1 -1
- package/dist/adapters/better-sqlite3.d.cts +21 -12
- package/dist/adapters/better-sqlite3.d.ts +21 -12
- package/dist/adapters/better-sqlite3.js +69 -5
- package/dist/adapters/better-sqlite3.js.map +1 -1
- package/dist/adapters/indexeddb.cjs +1316 -610
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.d.cts +29 -3
- package/dist/adapters/indexeddb.d.ts +29 -3
- package/dist/adapters/indexeddb.js +247 -221
- package/dist/adapters/indexeddb.js.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.cjs +856 -63
- package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm-worker.js +529 -63
- package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
- package/dist/adapters/sqlite-wasm.cjs +1032 -344
- package/dist/adapters/sqlite-wasm.cjs.map +1 -1
- package/dist/adapters/sqlite-wasm.d.cts +239 -18
- package/dist/adapters/sqlite-wasm.d.ts +239 -18
- package/dist/adapters/sqlite-wasm.js +111 -5
- package/dist/adapters/sqlite-wasm.js.map +1 -1
- package/dist/backup-IHKVMUAM.js +25 -0
- package/dist/chunk-5AQSGMJV.js +5471 -0
- package/dist/chunk-5AQSGMJV.js.map +1 -0
- package/dist/chunk-5JMGMPUE.js +591 -0
- package/dist/chunk-5JMGMPUE.js.map +1 -0
- package/dist/{chunk-CYO3YKFL.js → chunk-5ZRRF6R2.js} +2 -2
- package/dist/chunk-A6GFH5IG.js +36 -0
- package/dist/chunk-A6GFH5IG.js.map +1 -0
- package/dist/chunk-BILSA6XZ.js +608 -0
- package/dist/chunk-BILSA6XZ.js.map +1 -0
- package/dist/chunk-BQSIL6TT.js +1095 -0
- package/dist/chunk-BQSIL6TT.js.map +1 -0
- package/dist/{chunk-GSJ7EEUC.js → chunk-J5AGXF3D.js} +58 -9
- package/dist/chunk-J5AGXF3D.js.map +1 -0
- package/dist/chunk-KK3GBONL.js +112 -0
- package/dist/chunk-KK3GBONL.js.map +1 -0
- package/dist/chunk-KTVNANUH.js +876 -0
- package/dist/chunk-KTVNANUH.js.map +1 -0
- package/dist/chunk-QW4UU7NG.js +1003 -0
- package/dist/chunk-QW4UU7NG.js.map +1 -0
- package/dist/chunk-SRHDJF5B.js +186 -0
- package/dist/chunk-SRHDJF5B.js.map +1 -0
- package/dist/chunk-UC2LGFPV.js +810 -0
- package/dist/chunk-UC2LGFPV.js.map +1 -0
- package/dist/{export-audit-ODGQTQIK.js → export-audit-J2QXRHD2.js} +3 -3
- package/dist/index.cjs +9533 -4246
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1143 -110
- package/dist/index.d.ts +1143 -110
- package/dist/index.js +298 -3191
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +581 -264
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +15 -85
- package/dist/internal.d.ts +15 -85
- package/dist/internal.js +10 -8
- package/dist/restore-MNDPR557.js +299 -0
- package/dist/restore-MNDPR557.js.map +1 -0
- package/dist/sql-builder-D0tC3sv9.d.cts +615 -0
- package/dist/sql-builder-D5UMzHEo.d.ts +615 -0
- package/dist/sqlite-wasm-channel-DVX93Uiq.d.cts +141 -0
- package/dist/sqlite-wasm-channel-DVX93Uiq.d.ts +141 -0
- package/dist/sqlite-wasm-channel-QCCNBYCU.js +12 -0
- package/dist/store-HNGX4KTT.js +16 -0
- package/dist/store-HNGX4KTT.js.map +1 -0
- package/dist/{types-BslDOTk0.d.ts → types-Dh-xyUjP.d.cts} +99 -26
- package/dist/{types-BslDOTk0.d.cts → types-Dh-xyUjP.d.ts} +99 -26
- package/package.json +3 -2
- package/dist/backup-5S7K2Z35.js +0 -14
- package/dist/chunk-GSJ7EEUC.js.map +0 -1
- package/dist/chunk-HS6DBMST.js +0 -383
- package/dist/chunk-HS6DBMST.js.map +0 -1
- package/dist/chunk-RJIEKEN4.js +0 -751
- package/dist/chunk-RJIEKEN4.js.map +0 -1
- package/dist/chunk-TUR7RGEP.js +0 -84
- package/dist/chunk-TUR7RGEP.js.map +0 -1
- package/dist/chunk-VDBJQ75K.js +0 -78
- package/dist/chunk-VDBJQ75K.js.map +0 -1
- package/dist/chunk-YT7MRFCP.js +0 -687
- package/dist/chunk-YT7MRFCP.js.map +0 -1
- package/dist/sqlite-wasm-channel-GGHA2BXU.js +0 -12
- package/dist/sqlite-wasm-channel-L6o3bWQK.d.cts +0 -92
- package/dist/sqlite-wasm-channel-L6o3bWQK.d.ts +0 -92
- package/dist/types-BOO9EPt1.d.ts +0 -170
- package/dist/types-C_GDavG-.d.cts +0 -170
- /package/dist/{backup-5S7K2Z35.js.map → backup-IHKVMUAM.js.map} +0 -0
- /package/dist/{chunk-CYO3YKFL.js.map → chunk-5ZRRF6R2.js.map} +0 -0
- /package/dist/{export-audit-ODGQTQIK.js.map → export-audit-J2QXRHD2.js.map} +0 -0
- /package/dist/{sqlite-wasm-channel-GGHA2BXU.js.map → sqlite-wasm-channel-QCCNBYCU.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sync/rehash-operation.ts","../src/store/sequence-allocator.ts","../src/store/sequence-repair.ts","../src/fold/record-folder.ts"],"sourcesContent":["import { quoteIdent } from '@korajs/core'\nimport type { Operation } from '@korajs/core'\nimport { computeOperationId } from '@korajs/core/internal'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeOperation } from '../serialization/serializer'\nimport type { OperationRow, Transaction } from '../types'\n\n/** Result of `Store.resequenceOperation` (RT-35 renumbering). */\nexport interface ResequenceResult {\n\t/** The renumbered operation (a version-2 one under a new id). */\n\toperation: Operation\n\t/** Never-sent dependents rewritten to name the new id (re-hashed), in sequence order. */\n\tdependents: Operation[]\n\t/** Old id -> new id, for the operation and every re-hashed dependent. */\n\tidMapping: Record<string, string>\n}\n\n/**\n * The content-addressed id of an operation whose stamp, node, sequence or causal deps\n * were rewritten locally before it was ever shared (clock rebase, node rotation,\n * SEQUENCE_CONFLICT renumbering). Uses the operation's own hash version: a version-2\n * operation (protocol v2) gets a version-2 id over all its semantic fields, and a\n * version-1 operation (written before beta.13) keeps the version-1 hash, so neither\n * fails id verification on its receivers.\n *\n * @param op - The operation with its new content (its `id` is ignored)\n * @returns The id matching that content under the operation's hash version\n */\nexport async function rehashOperation(op: Operation): Promise<string> {\n\treturn computeOperationId(\n\t\t{\n\t\t\tnodeId: op.nodeId,\n\t\t\ttype: op.type,\n\t\t\tcollection: op.collection,\n\t\t\trecordId: op.recordId,\n\t\t\tdata: op.data,\n\t\t\tpreviousData: op.previousData,\n\t\t\ttimestamp: op.timestamp,\n\t\t\tsequenceNumber: op.sequenceNumber,\n\t\t\tcausalDeps: op.causalDeps,\n\t\t\tschemaVersion: op.schemaVersion,\n\t\t\t...(op.atomicOps !== undefined ? { atomicOps: op.atomicOps } : {}),\n\t\t},\n\t\top.hashVersion === 2 ? 2 : 1,\n\t)\n}\n\n/**\n * Give a logged operation row a new sequence number inside `tx` (SEQUENCE_CONFLICT\n * recovery, RT-35; legacy duplicate repair, W6). A version-1 operation keeps its id:\n * its hash never covered the sequence number. A version-2 operation's id does cover it\n * (CORE-1), so it is re-hashed and its row replaced under the new id; it was never\n * stored by the server (that is why it is renumbered), so no replica knows the old id.\n *\n * @returns The operation as it is now logged\n */\nexport async function renumberOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\tsequenceNumber: number,\n): Promise<Operation> {\n\tconst table = quoteIdent(`_kora_ops_${collection}`)\n\tconst current = deserializeOperationWithCollection(row, collection)\n\tconst renumbered: Operation = { ...current, sequenceNumber }\n\tif (current.hashVersion !== 2) {\n\t\tawait tx.execute(`UPDATE ${table} SET sequence_number = ? WHERE id = ?`, [\n\t\t\tsequenceNumber,\n\t\t\trow.id,\n\t\t])\n\t\treturn renumbered\n\t}\n\tconst id = await rehashOperation(renumbered)\n\tconst moved: Operation = { ...renumbered, id }\n\tawait replaceOperationRow(tx, collection, row.id, moved)\n\treturn moved\n}\n\nasync function replaceOperationRow(\n\ttx: Transaction,\n\tcollection: string,\n\toldId: string,\n\tnext: Operation,\n): Promise<void> {\n\tawait tx.execute(`DELETE FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`, [oldId])\n\tconst insert = buildInsertQuery(\n\t\t`_kora_ops_${collection}`,\n\t\tserializeOperation(next) as unknown as Record<string, unknown>,\n\t)\n\tawait tx.execute(insert.sql, insert.params)\n}\n\n/**\n * After operations were re-hashed under new ids (`idMapping`, old id -> new id), make\n * the local operations that name an old id in `causalDeps` name the new one, inside\n * `tx`. Only operations in `rewritable` are touched: those the server never stored\n * (never sent). Each rewritten operation covers its causalDeps in its id (version 2),\n * so it is re-hashed too and its own dependents follow, transitively, in sequence\n * order (sequence order is authoring order, so a dependency is always rewritten before\n * its dependents). A version-1 operation keeps its id (its hash does not cover\n * causalDeps) but still gets the new dep. `idMapping` is extended in place.\n *\n * An operation outside `rewritable` (already sent: the server may hold it under its\n * id) is never rewritten; its dep on an old id resolves through `_kora_seq_conflicts`\n * (`reemitted_as`) on this device.\n *\n * @returns The rewritten operations, in sequence order\n */\nexport async function rewriteDependentsInTx(\n\ttx: Transaction,\n\tcollections: readonly string[],\n\tnodeId: string,\n\tidMapping: Record<string, string>,\n\trewritable: ReadonlySet<string>,\n): Promise<Operation[]> {\n\tif (rewritable.size === 0) return []\n\tconst candidates: Array<{ collection: string; row: OperationRow; op: Operation }> = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tfor (const row of rows) {\n\t\t\tif (!rewritable.has(row.id)) continue\n\t\t\tcandidates.push({ collection, row, op: deserializeOperationWithCollection(row, collection) })\n\t\t}\n\t}\n\tcandidates.sort((a, b) => a.op.sequenceNumber - b.op.sequenceNumber)\n\tconst rewritten: Operation[] = []\n\tfor (const { collection, row, op } of candidates) {\n\t\tif (!op.causalDeps.some((dep) => idMapping[dep] !== undefined)) continue\n\t\tconst causalDeps = op.causalDeps.map((dep) => idMapping[dep] ?? dep)\n\t\tconst updated: Operation = { ...op, causalDeps }\n\t\tconst id = op.hashVersion === 2 ? await rehashOperation(updated) : op.id\n\t\tconst next: Operation = { ...updated, id }\n\t\tawait replaceOperationRow(tx, collection, row.id, next)\n\t\tif (id !== op.id) idMapping[op.id] = id\n\t\trewritten.push(next)\n\t}\n\treturn rewritten\n}\n","import type { StorageAdapter, Transaction } from '../types'\n\ninterface SequenceRow {\n\tsequence_number: number\n}\n\n/**\n * Reserve the next sequence number for a node inside a write transaction\n * (UPSERT ... RETURNING on `_kora_version_vector`).\n *\n * This is the ONLY way a local operation gets its number: the reservation\n * commits or rolls back with the operation that uses it, and transactions are\n * serialized, so the numbers of one commit are contiguous and never shared. There\n * is deliberately no variant that allocates outside a transaction (W6).\n */\nexport async function allocateNextSequenceInTransaction(\n\ttx: Transaction,\n\tnodeId: string,\n): Promise<number> {\n\tconst rows = await tx.query<SequenceRow>(\n\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, 1)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = sequence_number + 1\n RETURNING sequence_number`,\n\t\t[nodeId],\n\t)\n\tconst seq = rows[0]?.sequence_number\n\tif (seq === undefined) {\n\t\tthrow new Error(`Failed to allocate sequence number for node \"${nodeId}\" in transaction`)\n\t}\n\treturn seq\n}\n\n/**\n * Read the current sequence for a node without incrementing.\n */\nexport async function readSequenceNumber(adapter: StorageAdapter, nodeId: string): Promise<number> {\n\tconst rows = await adapter.query<SequenceRow>(\n\t\t'SELECT sequence_number FROM _kora_version_vector WHERE node_id = ?',\n\t\t[nodeId],\n\t)\n\treturn rows[0]?.sequence_number ?? 0\n}\n","import { quoteIdent } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { deserializeOperationWithCollection } from '../serialization/serializer'\nimport { renumberOperationRow } from '../sync/rehash-operation'\nimport type { OperationRow, StorageAdapter, Transaction } from '../types'\nimport { allocateNextSequenceInTransaction } from './sequence-allocator'\n\n/**\n * Audit table for operation rows whose `(node_id, sequence_number)` identity\n * collided with another operation (STORE-1 / STORE-2 duplicates written by\n * beta.12, or a conflicting remote operation). Rows here are never deleted.\n *\n * - `reemitted_as` set: the operation was given a fresh sequence number and still\n * lives in the operation log under that number (`new_sequence_number`).\n * - `reemitted_as` NULL: the operation is kept ONLY here (another node's\n * operation whose number this log already holds). It still takes part in\n * dedup and in record folds, so no data is lost.\n */\nexport const SEQ_CONFLICTS_TABLE = '_kora_seq_conflicts'\n\nconst REPAIR_DONE_META_KEY = 'seq_unique_repair_v1'\n\n/** DDL for {@link SEQ_CONFLICTS_TABLE}. */\nconst CREATE_SEQ_CONFLICTS_SQL = `CREATE TABLE IF NOT EXISTS ${SEQ_CONFLICTS_TABLE} (\n id TEXT PRIMARY KEY NOT NULL,\n collection TEXT NOT NULL,\n node_id TEXT NOT NULL,\n type TEXT NOT NULL,\n record_id TEXT NOT NULL,\n data TEXT,\n previous_data TEXT,\n timestamp TEXT NOT NULL,\n sequence_number INTEGER NOT NULL,\n causal_deps TEXT NOT NULL,\n schema_version INTEGER NOT NULL,\n reason TEXT NOT NULL,\n reemitted_as TEXT,\n new_sequence_number INTEGER,\n recorded_at INTEGER NOT NULL\n)`\n\n/** Name of the unique `(node_id, sequence_number)` index on a collection's op log. */\nexport function uniqueSequenceIndexName(collection: string): string {\n\treturn `uidx_kora_ops_${collection.length}_${collection}_node_seq`\n}\n\n/** Outcome of {@link repairSequenceUniqueness}. */\nexport interface SequenceRepairResult {\n\t/** Own-node operations that were given a fresh sequence number. */\n\tresequenced: number\n\t/** Other nodes' operations moved out of the log into the conflicts table. */\n\tretained: number\n}\n\n/**\n * Make `(node_id, sequence_number)` unique in the local operation log, then\n * enforce it with a UNIQUE index on every operation table (W6 step 2).\n *\n * beta.12 could give two different operations of this device the same sequence\n * number (STORE-1/2). A plain UNIQUE index cannot be created over such a log, and\n * dropping either row would lose a write. The repair, in one transaction:\n *\n * 1. Raises this node's persisted counter to at least the highest sequence number\n * in its log (beta.12 could leave it behind, which would make the next write\n * collide).\n * 2. For every duplicated `(node, seq)` — across all collections, since one node\n * numbers all its operations in one sequence — keeps the first row by id.\n * 3. Every other row of THIS node is re-emitted with a fresh sequence number from\n * the counter, keeping its id and content (see the note below), and recorded\n * in {@link SEQ_CONFLICTS_TABLE}.\n * 4. Rows of OTHER nodes (this device cannot number them) move to\n * {@link SEQ_CONFLICTS_TABLE} with `reemitted_as` NULL; the store keeps using\n * them for dedup and record folds.\n * 5. Creates the UNIQUE index on every operation table.\n *\n * Why the re-emitted operation keeps its id: protocol v1 content-addresses\n * operations without the sequence number, and changing any hashed content (data\n * or HLC timestamp) would change what the write means under last-write-wins.\n * With the id kept, a server that already stored the operation deduplicates it\n * (acknowledging the new number), and a server that never got it — beta.12 could\n * skip the second of two same-numbered operations — stores it. Either way atomic\n * increments are never applied twice and no write is lost.\n *\n * Idempotent: the scan runs once per database (a meta flag records completion);\n * the index creation runs on every open so collections added later are covered.\n *\n * @param adapter - The store's adapter (already opened)\n * @param schema - The schema whose operation tables are repaired\n * @param nodeId - This device's node id\n */\nexport async function repairSequenceUniqueness(\n\tadapter: StorageAdapter,\n\tschema: SchemaDefinition,\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\tawait adapter.execute(CREATE_SEQ_CONFLICTS_SQL)\n\tconst collections = Object.keys(schema.collections)\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\n\tconst done = await adapter.query<{ value: string }>(\n\t\t'SELECT value FROM _kora_meta WHERE key = ?',\n\t\t[REPAIR_DONE_META_KEY],\n\t)\n\tif (done.length === 0 && collections.length > 0) {\n\t\tawait runRepair(adapter, collections, nodeId, result)\n\t}\n\n\tfor (const collection of collections) {\n\t\tconst createIndex = `CREATE UNIQUE INDEX IF NOT EXISTS ${quoteIdent(uniqueSequenceIndexName(collection))} ON ${quoteIdent(`_kora_ops_${collection}`)} (node_id, sequence_number)`\n\t\ttry {\n\t\t\tawait adapter.execute(createIndex)\n\t\t} catch (error) {\n\t\t\t// Duplicates written after an earlier repair (for example by an older\n\t\t\t// Kora version opening this database again): repair once more, then\n\t\t\t// create the index. A second failure propagates.\n\t\t\tif (!/UNIQUE/i.test(error instanceof Error ? error.message : String(error))) throw error\n\t\t\tawait runRepair(adapter, collections, nodeId, result)\n\t\t\tawait adapter.execute(createIndex)\n\t\t}\n\t}\n\treturn result\n}\n\nasync function runRepair(\n\tadapter: StorageAdapter,\n\tcollections: string[],\n\tnodeId: string,\n\tresult: SequenceRepairResult,\n): Promise<void> {\n\tlet resequenced = 0\n\tlet retained = 0\n\tawait adapter.transaction(async (tx) => {\n\t\tawait raiseOwnCounterToLog(tx, collections, nodeId)\n\t\tconst repaired = await repairDuplicates(tx, collections, nodeId)\n\t\tresequenced = repaired.resequenced\n\t\tretained = repaired.retained\n\t\tawait tx.execute('INSERT OR REPLACE INTO _kora_meta (key, value) VALUES (?, ?)', [\n\t\t\tREPAIR_DONE_META_KEY,\n\t\t\tString(Date.now()),\n\t\t])\n\t})\n\tresult.resequenced += resequenced\n\tresult.retained += retained\n\tif (resequenced > 0 || retained > 0) {\n\t\tconsole.warn(\n\t\t\t`[kora] Repaired ${resequenced + retained} operation(s) that shared a sequence number (written by an earlier Kora version). ${resequenced} were given fresh sequence numbers; ${retained} from other devices were kept in ${SEQ_CONFLICTS_TABLE}. No data was removed.`,\n\t\t)\n\t}\n}\n\nasync function raiseOwnCounterToLog(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<void> {\n\tlet maxSeq = 0\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<{ max_seq: number | null }>(\n\t\t\t`SELECT MAX(sequence_number) AS max_seq FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE node_id = ?`,\n\t\t\t[nodeId],\n\t\t)\n\t\tmaxSeq = Math.max(maxSeq, rows[0]?.max_seq ?? 0)\n\t}\n\tif (maxSeq > 0) {\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO _kora_version_vector (node_id, sequence_number) VALUES (?, ?)\n ON CONFLICT(node_id) DO UPDATE SET sequence_number = MAX(sequence_number, excluded.sequence_number)`,\n\t\t\t[nodeId, maxSeq],\n\t\t)\n\t}\n}\n\ninterface LoggedIdentity {\n\tcollection: string\n\tid: string\n\tnode_id: string\n\tsequence_number: number\n}\n\nasync function repairDuplicates(\n\ttx: Transaction,\n\tcollections: string[],\n\tnodeId: string,\n): Promise<SequenceRepairResult> {\n\t// One node numbers all its operations in one sequence, so duplicates are\n\t// found across every collection's table, not per table.\n\tconst all: LoggedIdentity[] = []\n\tfor (const collection of collections) {\n\t\tconst rows = await tx.query<Omit<LoggedIdentity, 'collection'>>(\n\t\t\t`SELECT id, node_id, sequence_number FROM ${quoteIdent(`_kora_ops_${collection}`)}`,\n\t\t)\n\t\tfor (const row of rows) all.push({ collection, ...row })\n\t}\n\tconst groups = new Map<string, LoggedIdentity[]>()\n\tfor (const row of all) {\n\t\tconst key = `${row.node_id}\\u0000${row.sequence_number}`\n\t\tconst group = groups.get(key)\n\t\tif (group) group.push(row)\n\t\telse groups.set(key, [row])\n\t}\n\n\tconst losers: LoggedIdentity[] = []\n\tfor (const group of groups.values()) {\n\t\tif (group.length < 2) continue\n\t\t// A version-2 operation (beta.13+) keeps its place: renumbering would re-hash it\n\t\t// under a new id, and if the server already stored it under the old id the new\n\t\t// copy would be stored as a second write (an atomic increment applied twice). A\n\t\t// version-1 loser keeps its id, which the server deduplicates (RT-31). Ties by id.\n\t\tconst version2 = new Set<string>()\n\t\tfor (const member of group) {\n\t\t\tif (await isVersion2Row(tx, member)) version2.add(member.id)\n\t\t}\n\t\tgroup.sort((a, b) => {\n\t\t\tconst va = version2.has(a.id) ? 0 : 1\n\t\t\tconst vb = version2.has(b.id) ? 0 : 1\n\t\t\tif (va !== vb) return va - vb\n\t\t\treturn a.id < b.id ? -1 : a.id > b.id ? 1 : 0\n\t\t})\n\t\tlosers.push(...group.slice(1))\n\t}\n\t// Re-emit in original order so the new numbers keep the authoring order.\n\tlosers.sort((a, b) =>\n\t\ta.sequence_number !== b.sequence_number\n\t\t\t? a.sequence_number - b.sequence_number\n\t\t\t: a.id < b.id\n\t\t\t\t? -1\n\t\t\t\t: a.id > b.id\n\t\t\t\t\t? 1\n\t\t\t\t\t: 0,\n\t)\n\n\tconst result: SequenceRepairResult = { resequenced: 0, retained: 0 }\n\tconst now = Date.now()\n\tfor (const loser of losers) {\n\t\tconst table = quoteIdent(`_kora_ops_${loser.collection}`)\n\t\tconst rows = await tx.query<OperationRow>(`SELECT * FROM ${table} WHERE id = ?`, [loser.id])\n\t\tconst row = rows[0]\n\t\tif (!row) continue\n\t\tif (loser.node_id === nodeId) {\n\t\t\tconst newSeq = await allocateNextSequenceInTransaction(tx, nodeId)\n\t\t\tconst moved = await renumberOperationRow(tx, loser.collection, row, newSeq)\n\t\t\tawait insertConflictRow(\n\t\t\t\ttx,\n\t\t\t\tloser.collection,\n\t\t\t\trow,\n\t\t\t\t'duplicate-sequence',\n\t\t\t\tmoved.id,\n\t\t\t\tnewSeq,\n\t\t\t\tnow,\n\t\t\t)\n\t\t\tresult.resequenced++\n\t\t} else {\n\t\t\tawait insertConflictRow(tx, loser.collection, row, 'duplicate-sequence', null, null, now)\n\t\t\tawait tx.execute(`DELETE FROM ${table} WHERE id = ?`, [loser.id])\n\t\t\tresult.retained++\n\t\t}\n\t}\n\treturn result\n}\n\n/** Whether a logged operation declares content-hash version 2. */\nasync function isVersion2Row(tx: Transaction, identity: LoggedIdentity): Promise<boolean> {\n\tconst rows = await tx.query<OperationRow>(\n\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${identity.collection}`)} WHERE id = ?`,\n\t\t[identity.id],\n\t)\n\tconst row = rows[0]\n\tif (!row) return false\n\treturn deserializeOperationWithCollection(row, identity.collection).hashVersion === 2\n}\n\n/**\n * Record an operation row in {@link SEQ_CONFLICTS_TABLE}.\n *\n * @param reemittedAs - Id of the operation that carries it in the log, or null\n * when the row is kept only in the conflicts table\n * @param newSequenceNumber - The sequence number it was re-emitted under\n */\nexport async function insertConflictRow(\n\ttx: Transaction,\n\tcollection: string,\n\trow: OperationRow,\n\treason: string,\n\treemittedAs: string | null,\n\tnewSequenceNumber: number | null,\n\trecordedAt: number,\n): Promise<void> {\n\tawait tx.execute(\n\t\t`INSERT OR IGNORE INTO ${SEQ_CONFLICTS_TABLE} (id, collection, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version, reason, reemitted_as, new_sequence_number, recorded_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t[\n\t\t\trow.id,\n\t\t\tcollection,\n\t\t\trow.node_id,\n\t\t\trow.type,\n\t\t\trow.record_id,\n\t\t\trow.data,\n\t\t\trow.previous_data,\n\t\t\trow.timestamp,\n\t\t\trow.sequence_number,\n\t\t\trow.causal_deps,\n\t\t\trow.schema_version,\n\t\t\treason,\n\t\t\treemittedAs,\n\t\t\tnewSequenceNumber,\n\t\t\trecordedAt,\n\t\t],\n\t)\n}\n\n/**\n * Operation rows kept only in the conflicts table for a record (other nodes'\n * operations whose sequence number collided). Record folds include them.\n */\nexport async function loadRetainedConflictRows(\n\tquery: <T>(sql: string, params?: unknown[]) => Promise<T[]>,\n\tcollection: string,\n\trecordId: string,\n\ttypes?: readonly string[],\n): Promise<OperationRow[]> {\n\tconst typeFilter =\n\t\ttypes && types.length > 0 ? ` AND type IN (${types.map(() => '?').join(', ')})` : ''\n\treturn query<OperationRow>(\n\t\t`SELECT id, node_id, type, record_id, data, previous_data, timestamp, sequence_number, causal_deps, schema_version FROM ${SEQ_CONFLICTS_TABLE} WHERE collection = ? AND record_id = ? AND reemitted_as IS NULL${typeFilter}`,\n\t\t[collection, recordId, ...(types ?? [])],\n\t)\n}\n\n/** Whether an operation id is already recorded (log or retained conflict). */\nexport async function isOperationLogged(\n\ttx: Transaction,\n\tcollection: string,\n\topId: string,\n): Promise<boolean> {\n\tconst inLog = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE id = ?`,\n\t\t[opId],\n\t)\n\tif (inLog.length > 0) return true\n\tconst retained = await tx.query<{ id: string }>(\n\t\t`SELECT id FROM ${SEQ_CONFLICTS_TABLE} WHERE id = ? AND reemitted_as IS NULL`,\n\t\t[opId],\n\t)\n\treturn retained.length > 0\n}\n","import {\n\tFOLD_STATE_VERSION,\n\ttype FoldOptions,\n\ttype FoldState,\n\tFoldStateError,\n\ttype FoldTrace,\n\tHybridLogicalClock,\n\ttype MergeTrace,\n\ttype Operation,\n\ttype OperationTransform,\n\ttype SchemaDefinition,\n\tadaptFoldState,\n\tbase64ToBytes,\n\tcreateFoldState,\n\tdeserializeFoldState,\n\tgetFoldFieldVersionStrings,\n\tisFoldStateLive,\n\tjoinStates,\n\tmaterialize,\n\tmergeOp,\n\tmismatchedFoldFields,\n\tquoteIdent,\n\tserializeFoldState,\n\ttoMergeTrace,\n} from '@korajs/core'\nimport * as Y from 'yjs'\nimport { buildInsertQuery } from '../query/sql-builder'\nimport { deserializeOperationWithCollection, serializeRecord } from '../serialization/serializer'\nimport { loadRetainedConflictRows } from '../store/sequence-repair'\nimport { TERMINAL_REJECTIONS_TABLE } from '../sync/local-sync-records'\nimport type { OperationRow, RawCollectionRow, Transaction } from '../types'\n\n/** Per-record fold state (serialized `FoldState`) of every record this database holds. */\nexport const FOLD_STATE_TABLE = '_kora_fold_state'\n/**\n * Per-record base state of operations no longer in the log (compacted, or a snapshot\n * of a row whose history was compacted or quarantined before W7). A record's state\n * is always `join(base, fold(log))`.\n */\nexport const FOLD_BASE_TABLE = '_kora_fold_base'\n/** Per-node sequence prefix removed by compaction: ids at or below it are duplicates. */\nexport const COMPACTED_THROUGH_TABLE = '_kora_compacted_through'\n/**\n * Per-record row snapshots (RT-68): the base built from a materialized row when the\n * record's history is not all in the log (a pre-W7 compaction, quarantined log rows).\n * Kept apart from `_kora_fold_base` (which holds only exact, operation-built states)\n * so the approximation can be dropped once the record's history is complete again:\n * when the server's fold state arrives in a scope entry, or after a full resync.\n * A record's state is `join(base, snapshot, fold(log))`.\n */\nexport const FOLD_SNAPSHOT_TABLE = '_kora_fold_snapshot'\n/**\n * Local-only provisional side effects (RT-69): the cascades / set-nulls a device\n * derives for a REMOTE delete. They fold into the record like operations but are\n * never logged, sequenced or uploaded (the server derives and relays its own\n * copy); each is retired when the server's copy for the same parent and record\n * arrives, or when the device's delivery stream has caught up.\n\n */\nexport const PROVISIONAL_OPS_TABLE = '_kora_provisional_ops'\n/**\n * Terminal-rejection codes the fold does NOT exclude: the user discarded a held\n * node's writes (they stay in the local database; only their upload stops).\n */\nconst KEPT_REJECTION_CODES: readonly string[] = ['HELD_DISCARDED']\n/** `_kora_meta` key recording how the rows of this database are materialized. */\nexport const FOLD_MATERIALIZATION_META_KEY = 'fold_materialization'\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} once rows are materializations of the current fold. */\nexport const FOLD_MATERIALIZATION_CURRENT = `fold-v${FOLD_STATE_VERSION}`\n/** Value of {@link FOLD_MATERIALIZATION_META_KEY} while the legacy (beta.12) paths write rows. */\nexport const FOLD_MATERIALIZATION_LEGACY = 'legacy'\n\n/** DDL for the fold tables. Idempotent. */\nexport const FOLD_TABLES_DDL: readonly string[] = [\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_STATE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_BASE_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${COMPACTED_THROUGH_TABLE} (node_id TEXT PRIMARY KEY, sequence_number INTEGER NOT NULL)`,\n\t`CREATE TABLE IF NOT EXISTS ${FOLD_SNAPSHOT_TABLE} (collection TEXT NOT NULL, record_id TEXT NOT NULL, state TEXT NOT NULL, PRIMARY KEY (collection, record_id))`,\n\t`CREATE TABLE IF NOT EXISTS ${PROVISIONAL_OPS_TABLE} (id TEXT PRIMARY KEY, collection TEXT NOT NULL, record_id TEXT NOT NULL, parent_id TEXT NOT NULL, operation TEXT NOT NULL)`,\n\t`CREATE INDEX IF NOT EXISTS ${PROVISIONAL_OPS_TABLE}_record ON ${PROVISIONAL_OPS_TABLE} (collection, record_id)`,\n]\n\n/**\n * Merges richtext Yjs updates for the fold (core has no Yjs dependency): applies\n * every update to one fresh document and encodes its state. The encoding depends\n * only on the document's content, not on how it was split into updates, so every\n * replica materializes byte-identical richtext.\n */\nexport function mergeYjsUpdates(updates: Uint8Array[]): Uint8Array {\n\tconst doc = new Y.Doc()\n\tfor (const update of updates) Y.applyUpdate(doc, update)\n\treturn Y.encodeStateAsUpdate(doc)\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n\tif (a.length !== b.length) return false\n\tfor (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\n\treturn true\n}\n\n/**\n * Whether Yjs update `a` adds nothing to update `b` (the fold's richtext space\n * bound): the canonical encoding of `b` alone equals that of `a` and `b` merged.\n */\nexport function yjsSubsumes(a: Uint8Array, b: Uint8Array): boolean {\n\treturn sameBytes(mergeYjsUpdates([b]), mergeYjsUpdates([a, b]))\n}\n\n/**\n * Whether an operation lies in a node's compacted prefix: its row is gone from the\n * log, but its effect is in the record's base state, so it is a duplicate (STORE-14).\n */\nexport async function isCompacted(tx: Transaction, op: Operation): Promise<boolean> {\n\tconst rows = await tx.query<{ sequence_number: number }>(\n\t\t`SELECT sequence_number FROM ${COMPACTED_THROUGH_TABLE} WHERE node_id = ?`,\n\t\t[op.nodeId],\n\t)\n\tconst through = rows[0]?.sequence_number\n\treturn through !== undefined && op.sequenceNumber <= through\n}\n\n/** Which fields of a row to (re)write from the fold state. */\nexport type MaterializeFields = 'all' | ReadonlySet<string>\n\n/** Result of merging one operation into its record. */\nexport interface FoldApplyOutcome {\n\t/** The merge changed the record's state. */\n\tchanged: boolean\n\t/** Merge traces (MergeTrace form), for `merge:*` events. */\n\ttraces: MergeTrace[]\n}\n\n/**\n * The client side of the W7 fold: every write to a materialized row — local\n * writes, remote operations, scope entries, rejection re-merges, re-materialization\n * — goes through this class, inside the write transaction that appends the\n * operation (\"append, then merge\"). A row is always the materialization of its\n * record's fold state.\n */\nexport class RecordFolder {\n\tprivate authoritative: ReadonlySet<string> = new Set()\n\n\tconstructor(\n\t\tprivate readonly schema: SchemaDefinition,\n\t\tprivate readonly transforms: readonly OperationTransform[] = [],\n\t) {}\n\n\t/** The schema transforms every merge applies (transforms at fold time, RT-84). */\n\tgetOperationTransforms(): readonly OperationTransform[] {\n\t\treturn this.transforms\n\t}\n\n\t/**\n\t * The fields an operation's merge can change: its own data's keys, or every field\n\t * when the fold reads it through a schema transform (whose view may name others).\n\t */\n\tprivate touchedFields(op: Operation): MaterializeFields {\n\t\tif (this.transforms.length > 0 && op.schemaVersion !== this.schema.version) return 'all'\n\t\treturn new Set(Object.keys(op.data ?? {}))\n\t}\n\n\t/** Node ids whose writes win `merge('server-authoritative')` fields. */\n\tgetAuthoritativeNodeIds(): ReadonlySet<string> {\n\t\treturn this.authoritative\n\t}\n\n\t/** @internal Set by the store from persisted meta / the sync handshake. */\n\tsetAuthoritativeNodeIds(ids: Iterable<string>): void {\n\t\tthis.authoritative = new Set(ids)\n\t}\n\n\t/** Fold options every merge of this database uses. */\n\toptions(traces: FoldOptions['traces'] = 'none'): FoldOptions {\n\t\treturn {\n\t\t\trichtext: mergeYjsUpdates,\n\t\t\trichtextSubsumes: yjsSubsumes,\n\t\t\ttraces,\n\t\t\t...(this.authoritative.size > 0 ? { authoritativeNodeIds: this.authoritative } : {}),\n\t\t\t...(this.transforms.length > 0 ? { transforms: this.transforms } : {}),\n\t\t}\n\t}\n\n\t/** Whether the schema has a `merge('server-authoritative')` field in `collection`. */\n\thasAuthoritativeFields(collection: string): boolean {\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return false\n\t\treturn Object.values(definition.fields).some(\n\t\t\t(field) => field.mergeStrategy === 'server-authoritative',\n\t\t)\n\t}\n\n\t/**\n\t * Merge one operation (already appended to the log) into its record and\n\t * re-materialize the row.\n\t *\n\t * @param tx - The write transaction that appended the operation\n\t * @param op - The operation\n\t * @param mode - 'remote' emits merge traces; 'local' does not (a local write is\n\t * computed from the row it updates, so it is never concurrent with it)\n\t */\n\tasync applyInTx(\n\t\ttx: Transaction,\n\t\top: Operation,\n\t\tmode: 'local' | 'remote',\n\t): Promise<FoldApplyOutcome> {\n\t\tconst scopeEntry = op.type === 'insert'\n\t\tif (mode === 'remote') {\n\t\t\t// The record's approximations end here: a provisional cascade of this parent\n\t\t\t// is replaced by the real one (RT-69), and a row snapshot by the server's\n\t\t\t// complete fold state (RT-68). The operation is already in the log, so the\n\t\t\t// record is re-folded without them.\n\t\t\tconst retired = await this.deleteProvisional(tx, op.collection, op.recordId, op.causalDeps)\n\t\t\tconst replaced = await this.dropSnapshotForCarriedState(tx, op)\n\t\t\tif (retired > 0 || replaced) {\n\t\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\t\treturn { changed: true, traces: [] }\n\t\t\t}\n\t\t}\n\t\t// A local insert has a fresh UUIDv7 record id: no state, log or row precedes it.\n\t\tconst fresh = mode === 'local' && op.type === 'insert'\n\t\tconst prior = fresh\n\t\t\t? { state: createFoldState(op.collection, op.recordId), rebuilt: false }\n\t\t\t: await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tlet result: ReturnType<typeof mergeOp>\n\t\ttry {\n\t\t\tresult = mergeOp(\n\t\t\t\tprior.state,\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(mode === 'remote' ? 'conflicts' : 'none'),\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof FoldStateError)) throw error\n\t\t\t// A stored state the current plan cannot take (RT-63): re-fold the record from\n\t\t\t// its base and log (the operation is already appended) once. A second\n\t\t\t// FoldStateError propagates; the sync engine then quarantines the operation\n\t\t\t// instead of stalling its delivery stream.\n\t\t\tawait this.refoldInTx(tx, op.collection, op.recordId, { clearRetraction: scopeEntry })\n\t\t\treturn { changed: true, traces: [] }\n\t\t}\n\t\tif (!result.changed && !prior.rebuilt && !scopeEntry) {\n\t\t\treturn { changed: false, traces: await this.toMergeTraces(tx, result.traces) }\n\t\t}\n\t\tawait this.saveState(tx, result.state)\n\t\tconst revived = isDeadState(prior.state) && !isDeadState(result.state)\n\t\tconst fields: MaterializeFields =\n\t\t\tprior.rebuilt || revived || op.foldState !== undefined ? 'all' : this.touchedFields(op)\n\t\tawait this.materializeRow(tx, result.state, fields, {\n\t\t\tclearRetraction: scopeEntry,\n\t\t\t...(fresh ? { absent: true } : {}),\n\t\t})\n\t\treturn { changed: result.changed, traces: await this.toMergeTraces(tx, result.traces) }\n\t}\n\n\t/**\n\t * Fold a record from its base state and its log, leaving out operations the\n\t * server terminally rejected, and re-materialize its row (all fields).\n\t *\n\t * @returns The new state (null when nothing of the record remains)\n\t */\n\tasync refoldInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\toptions: { clearRetraction?: boolean } = {},\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.foldFromLog(tx, collection, recordId)\n\t\tif (state === null) {\n\t\t\tawait tx.execute(`DELETE FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t])\n\t\t\t// Nothing of the record remains (its insert was refused): hide the row.\n\t\t\tawait tx.execute(`UPDATE ${quoteIdent(collection)} SET _deleted = 1 WHERE id = ?`, [recordId])\n\t\t\treturn null\n\t\t}\n\t\tawait this.saveState(tx, state)\n\t\tawait this.materializeRow(tx, state, 'all', {\n\t\t\tclearRetraction: options.clearRetraction ?? false,\n\t\t})\n\t\treturn state\n\t}\n\n\t/**\n\t * `join(base, snapshot, fold(log - terminally rejected, provisional effects))`, or\n\t * null when none exists. Base and snapshot are adapted to the current fold plan\n\t * (RT-63): a field whose kind changed is rebuilt from its materialized value.\n\t */\n\tasync foldFromLog(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst ops = [\n\t\t\t...(await this.loadRecordOperations(tx, collection, recordId)),\n\t\t\t...(await this.loadProvisional(tx, collection, recordId)),\n\t\t]\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tconst snapshot = await this.loadSnapshot(tx, collection, recordId)\n\t\tlet state =\n\t\t\tbase !== null && snapshot !== null\n\t\t\t\t? joinStates(base, snapshot, this.schema)\n\t\t\t\t: (base ?? snapshot)\n\t\tfor (const op of ops) {\n\t\t\tif (rejected.has(op.id)) continue\n\t\t\tstate = mergeOp(\n\t\t\t\tstate ?? createFoldState(collection, recordId),\n\t\t\t\top,\n\t\t\t\tthis.schema,\n\t\t\t\tthis.options(),\n\t\t\t).state\n\t\t}\n\t\treturn state\n\t}\n\n\t/** The record's operations (log + retained sequence-conflict rows). */\n\tasync loadRecordOperations(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = [\n\t\t\t...(await tx.query<OperationRow>(\n\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ?`,\n\t\t\t\t[recordId],\n\t\t\t)),\n\t\t\t...(await loadRetainedConflictRows(\n\t\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\t\tcollection,\n\t\t\t\trecordId,\n\t\t\t)),\n\t\t]\n\t\treturn rows.map((row) => deserializeOperationWithCollection(row, collection))\n\t}\n\n\t/**\n\t * Which of `ids` the fold leaves out: operations with a terminal-rejection marker\n\t * from the server (or quarantined by a scope retraction, which the server never\n\t * receives). Writes the user chose to discard from a held node are NOT left out:\n\t * discarding stops the upload, it is not a rollback.\n\t */\n\tasync loadTerminalRejections(tx: Transaction, ids: readonly string[]): Promise<Set<string>> {\n\t\tconst found = new Set<string>()\n\t\tconst CHUNK = 500\n\t\tfor (let i = 0; i < ids.length; i += CHUNK) {\n\t\t\tconst chunk = ids.slice(i, i + CHUNK)\n\t\t\tconst rows = await tx.query<{ operation_id: string }>(\n\t\t\t\t`SELECT operation_id FROM ${TERMINAL_REJECTIONS_TABLE} WHERE code NOT IN (${KEPT_REJECTION_CODES.map(() => '?').join(', ')}) AND operation_id IN (${chunk.map(() => '?').join(', ')})`,\n\t\t\t\t[...KEPT_REJECTION_CODES, ...chunk],\n\t\t\t)\n\t\t\tfor (const row of rows) found.add(row.operation_id)\n\t\t}\n\t\treturn found\n\t}\n\n\t/**\n\t * The record's stored state, or null (none, another format version, or a field\n\t * whose fold kind the schema has changed since: the caller re-folds, RT-63).\n\t */\n\tasync loadState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst state = await this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t\tif (state === null || mismatchedFoldFields(state, this.schema).length > 0) return null\n\t\treturn state\n\t}\n\n\t/** The stored state as it is, even when the plan changed (a snapshot seed). */\n\tasync loadStoredState(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\treturn this.readStateRow(tx, FOLD_STATE_TABLE, collection, recordId)\n\t}\n\n\t/** The record's compacted base, adapted to the current fold plan (RT-63). */\n\tasync loadBase(tx: Transaction, collection: string, recordId: string): Promise<FoldState | null> {\n\t\tconst base = await this.readStateRow(tx, FOLD_BASE_TABLE, collection, recordId)\n\t\treturn base === null ? null : adaptFoldState(base, this.schema, this.options()).state\n\t}\n\n\t/** The record's row snapshot (RT-68), adapted to the current fold plan. */\n\tasync loadSnapshot(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst snapshot = await this.readStateRow(tx, FOLD_SNAPSHOT_TABLE, collection, recordId)\n\t\treturn snapshot === null ? null : adaptFoldState(snapshot, this.schema, this.options()).state\n\t}\n\n\t/** Store `snapshot` as the record's row snapshot (joined with an existing one). */\n\tasync saveSnapshot(tx: Transaction, snapshot: FoldState): Promise<void> {\n\t\tconst existing = await this.loadSnapshot(tx, snapshot.c, snapshot.r)\n\t\tconst state = existing === null ? snapshot : joinStates(existing, snapshot, this.schema)\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_SNAPSHOT_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/**\n\t * A scope entry carrying the server's fold state (RT-29) replaces the record's row\n\t * snapshot (RT-68): the server's state is built from every operation of the record\n\t * the device was missing, so with the device's own log it is the exact state.\n\t * Only a carried state this schema can read and join counts (otherwise the entry\n\t * merges by its data and the snapshot stays).\n\t *\n\t * @returns Whether a snapshot was dropped\n\t */\n\tprivate async dropSnapshotForCarriedState(tx: Transaction, op: Operation): Promise<boolean> {\n\t\tif (op.type !== 'insert' || op.foldState === undefined) return false\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[op.collection, op.recordId],\n\t\t)\n\t\tif ((rows[0]?.n ?? 0) === 0) return false\n\t\tlet carried: FoldState\n\t\ttry {\n\t\t\tcarried = deserializeFoldState(op.foldState)\n\t\t} catch (error) {\n\t\t\tif (error instanceof FoldStateError) return false\n\t\t\tthrow error\n\t\t}\n\t\tif (carried.c !== op.collection || carried.r !== op.recordId) return false\n\t\tif (mismatchedFoldFields(carried, this.schema).length > 0) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\top.collection,\n\t\t\top.recordId,\n\t\t])\n\t\treturn true\n\t}\n\n\t/** Records that still fold against a row snapshot (approximate, RT-68). */\n\tasync listSnapshotRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT collection, record_id FROM ${FOLD_SNAPSHOT_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\t/**\n\t * After a full resync, a record whose log holds its insert again no longer needs\n\t * its row snapshot: drop it and re-fold the record from base and log (RT-68).\n\t *\n\t * @returns Whether the snapshot was dropped\n\t */\n\tasync settleSnapshotInTx(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst ops = await this.loadRecordOperations(tx, collection, recordId)\n\t\tconst rejected = await this.loadTerminalRejections(\n\t\t\ttx,\n\t\t\tops.map((op) => op.id),\n\t\t)\n\t\tconst hasInsert = ops.some((op) => op.type === 'insert' && !rejected.has(op.id))\n\t\tconst base = await this.loadBase(tx, collection, recordId)\n\t\tif (!hasInsert && (base?.cr ?? null) === null) return false\n\t\tawait tx.execute(`DELETE FROM ${FOLD_SNAPSHOT_TABLE} WHERE collection = ? AND record_id = ?`, [\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t])\n\t\tawait this.refoldInTx(tx, collection, recordId)\n\t\treturn true\n\t}\n\n\t/**\n\t * Fold a local-only provisional side effect (RT-69) into its record: stored apart\n\t * from the log (never sequenced, never uploaded) and kept until the real copy of\n\t * the effect arrives or the delivery stream catches up.\n\t *\n\t * @param parentId - The remote operation that caused it (the parent delete)\n\t */\n\tasync applyProvisionalInTx(tx: Transaction, op: Operation, parentId: string): Promise<void> {\n\t\tconst existing = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE id = ?`,\n\t\t\t[op.id],\n\t\t)\n\t\tif (existing.length > 0) return\n\t\tawait tx.execute(\n\t\t\t`INSERT INTO ${PROVISIONAL_OPS_TABLE} (id, collection, record_id, parent_id, operation) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t[op.id, op.collection, op.recordId, parentId, JSON.stringify(op)],\n\t\t)\n\t\tconst prior = await this.loadOrRebuild(tx, op.collection, op.recordId, op.id)\n\t\tconst result = mergeOp(prior.state, op, this.schema, this.options())\n\t\tif (!result.changed && !prior.rebuilt) return\n\t\tawait this.saveState(tx, result.state)\n\t\tawait this.materializeRow(tx, result.state, prior.rebuilt ? 'all' : this.touchedFields(op), {\n\t\t\tclearRetraction: false,\n\t\t})\n\t}\n\n\t/**\n\t * Remove provisional effects of a record (those caused by one of `parentIds`, or\n\t * all of them when null). The caller re-folds the record.\n\t *\n\t * @returns How many were removed\n\t */\n\tasync deleteProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tparentIds: readonly string[] | null,\n\t): Promise<number> {\n\t\tif (parentIds !== null && parentIds.length === 0) return 0\n\t\tconst filter =\n\t\t\tparentIds === null ? '' : ` AND parent_id IN (${parentIds.map(() => '?').join(', ')})`\n\t\tconst rows = await tx.query<{ id: string }>(\n\t\t\t`SELECT id FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?${filter}`,\n\t\t\t[collection, recordId, ...(parentIds ?? [])],\n\t\t)\n\t\tif (rows.length === 0) return 0\n\t\tawait tx.execute(\n\t\t\t`DELETE FROM ${PROVISIONAL_OPS_TABLE} WHERE id IN (${rows.map(() => '?').join(', ')})`,\n\t\t\trows.map((row) => row.id),\n\t\t)\n\t\treturn rows.length\n\t}\n\n\t/** Records with provisional effects. */\n\tasync listProvisionalRecords(\n\t\ttx: Transaction,\n\t): Promise<Array<{ collection: string; recordId: string }>> {\n\t\tconst rows = await tx.query<{ collection: string; record_id: string }>(\n\t\t\t`SELECT DISTINCT collection, record_id FROM ${PROVISIONAL_OPS_TABLE} ORDER BY collection, record_id`,\n\t\t)\n\t\treturn rows.map((row) => ({ collection: row.collection, recordId: row.record_id }))\n\t}\n\n\tprivate async loadProvisional(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<Operation[]> {\n\t\tconst rows = await tx.query<{ operation: string }>(\n\t\t\t`SELECT operation FROM ${PROVISIONAL_OPS_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn rows.map((row) => JSON.parse(row.operation) as Operation)\n\t}\n\n\tasync saveState(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_STATE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\tasync saveBase(tx: Transaction, state: FoldState): Promise<void> {\n\t\tawait tx.execute(\n\t\t\t`INSERT OR REPLACE INTO ${FOLD_BASE_TABLE} (collection, record_id, state) VALUES (?, ?, ?)`,\n\t\t\t[state.c, state.r, persistedForm(state)],\n\t\t)\n\t}\n\n\t/** Join `addition` into the record's base state. */\n\tasync joinIntoBase(tx: Transaction, addition: FoldState): Promise<void> {\n\t\tconst base = await this.loadBase(tx, addition.c, addition.r)\n\t\tawait this.saveBase(tx, base === null ? addition : joinStates(base, addition, this.schema))\n\t}\n\n\t/**\n\t * Write the row of a record from its fold state.\n\t *\n\t * - No insert merged: no row (an existing one is hidden).\n\t * - Otherwise the row holds the fold's values (also while deleted: a tombstone\n\t * keeps its last values), `_deleted` from the record's liveness, and versions\n\t * from the state: `_version` / `_updated_at` = newest operation, `_created_at` =\n\t * creation, `_field_versions` = each field's newest write.\n\t * - Only `fields` are written to an existing row; columns the fold never wrote\n\t * (a column a schema migration added with a default, a local-only backfill)\n\t * keep their stored value.\n\t * - A row hidden by a scope retraction stays hidden unless `clearRetraction`\n\t * (a scope-entry insert) is set.\n\t */\n\tasync materializeRow(\n\t\ttx: Transaction,\n\t\tstate: FoldState,\n\t\tfields: MaterializeFields,\n\t\toptions: { clearRetraction: boolean; absent?: boolean },\n\t): Promise<void> {\n\t\tconst collection = state.c\n\t\tconst definition = this.schema.collections[collection]\n\t\tif (!definition) return\n\t\tconst table = quoteIdent(collection)\n\t\tconst rows = options.absent\n\t\t\t? []\n\t\t\t: await tx.query<RawCollectionRow>(`SELECT id, _deleted FROM ${table} WHERE id = ?`, [\n\t\t\t\t\tstate.r,\n\t\t\t\t])\n\t\tconst existing = rows[0]\n\t\tif (state.cr === null || state.u === null) {\n\t\t\tif (existing && existing._deleted !== 1) {\n\t\t\t\tawait tx.execute(`UPDATE ${table} SET _deleted = 1 WHERE id = ?`, [state.r])\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst asLive: FoldState = { ...state, d: null }\n\t\tconst values = materialize(asLive, { richtext: mergeYjsUpdates }) ?? {}\n\t\tconst latest = HybridLogicalClock.deserialize(state.u.t)\n\t\tconst created = HybridLogicalClock.deserialize(state.cr.t)\n\t\t// Sorted keys: replicas holding the same state write byte-identical columns.\n\t\tconst fieldVersions = getFoldFieldVersionStrings(state)\n\t\tlet deleted = isDeadState(state) ? 1 : 0\n\t\tif (existing && deleted === 0) {\n\t\t\tconst retracted = await tx.query<{ record_id: string }>(\n\t\t\t\t'SELECT record_id FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t[collection, state.r],\n\t\t\t)\n\t\t\tif (retracted.length > 0) {\n\t\t\t\tif (options.clearRetraction) {\n\t\t\t\t\tawait tx.execute(\n\t\t\t\t\t\t'DELETE FROM _kora_scope_retractions WHERE collection = ? AND record_id = ?',\n\t\t\t\t\t\t[collection, state.r],\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tdeleted = 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst known = Object.keys(definition.fields)\n\t\t// A tombstone keeps the values it had when it was deleted: a write that lost to\n\t\t// the delete never shows, not even in the hidden row. A revival rewrites them all.\n\t\tconst writable =\n\t\t\texisting && deleted === 1\n\t\t\t\t? []\n\t\t\t\t: known.filter((field) => field in state.f && (fields === 'all' || fields.has(field)))\n\t\tconst fieldValues: Record<string, unknown> = {}\n\t\tfor (const field of writable) {\n\t\t\tconst value = values[field] ?? null\n\t\t\t// A richtext field with a single live update materializes as that update's\n\t\t\t// own bytes; re-encode it so every replica stores the same canonical bytes,\n\t\t\t// however its state happens to be split into updates.\n\t\t\tfieldValues[field] =\n\t\t\t\tdefinition.fields[field]?.kind === 'richtext' &&\n\t\t\t\tvalue !== null &&\n\t\t\t\ttypeof value === 'object' &&\n\t\t\t\t'$koraBytes' in value\n\t\t\t\t\t? mergeYjsUpdates([base64ToBytes(String((value as { $koraBytes: string }).$koraBytes))])\n\t\t\t\t\t: value\n\t\t}\n\t\tconst serialized = serializeRecord(fieldValues, definition.fields)\n\t\tconst meta: Record<string, unknown> = {\n\t\t\t_updated_at: latest.wallTime,\n\t\t\t_version: state.u.t,\n\t\t\t_field_versions: JSON.stringify(fieldVersions),\n\t\t\t_deleted: deleted,\n\t\t}\n\t\tif (!existing) {\n\t\t\tconst insert = buildInsertQuery(collection, {\n\t\t\t\tid: state.r,\n\t\t\t\t...serialized,\n\t\t\t\t...meta,\n\t\t\t\t_created_at: created.wallTime,\n\t\t\t})\n\t\t\tawait tx.execute(insert.sql, insert.params)\n\t\t\treturn\n\t\t}\n\t\tconst changes: Record<string, unknown> = {\n\t\t\t...serialized,\n\t\t\t...meta,\n\t\t\t_created_at: created.wallTime,\n\t\t}\n\t\tconst columns = Object.keys(changes)\n\t\tawait tx.execute(\n\t\t\t`UPDATE ${table} SET ${columns.map((c) => `${quoteIdent(c)} = ?`).join(', ')} WHERE id = ?`,\n\t\t\t[...columns.map((c) => changes[c]), state.r],\n\t\t)\n\t}\n\n\t/**\n\t * Load the record's state; rebuild it from base + log when it is missing or in\n\t * another format version. `rebuilt` tells the caller to rewrite the whole row.\n\t */\n\tprivate async loadOrRebuild(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t\tappendedId: string,\n\t): Promise<{ state: FoldState; rebuilt: boolean }> {\n\t\tconst stored = await this.loadState(tx, collection, recordId)\n\t\tif (stored !== null) return { state: stored, rebuilt: false }\n\t\tconst hasRow = await this.hasStateRow(tx, collection, recordId)\n\t\tconst others = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${quoteIdent(`_kora_ops_${collection}`)} WHERE record_id = ? AND id != ?`,\n\t\t\t[recordId, appendedId],\n\t\t)\n\t\tconst retained = await loadRetainedConflictRows(\n\t\t\t(sql, params) => tx.query(sql, params),\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t)\n\t\tconst hasBase =\n\t\t\t(await this.loadBase(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadSnapshot(tx, collection, recordId)) !== null ||\n\t\t\t(await this.loadProvisional(tx, collection, recordId)).some((p) => p.id !== appendedId)\n\t\tif (\n\t\t\t!hasRow &&\n\t\t\t!hasBase &&\n\t\t\t(others[0]?.n ?? 0) === 0 &&\n\t\t\tretained.every((row) => row.id === appendedId)\n\t\t) {\n\t\t\t// A new record: nothing to rebuild.\n\t\t\treturn { state: createFoldState(collection, recordId), rebuilt: false }\n\t\t}\n\t\tconst rebuilt = await this.foldFromLog(tx, collection, recordId)\n\t\treturn { state: rebuilt ?? createFoldState(collection, recordId), rebuilt: true }\n\t}\n\n\tprivate async hasStateRow(\n\t\ttx: Transaction,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<boolean> {\n\t\tconst rows = await tx.query<{ n: number }>(\n\t\t\t`SELECT COUNT(*) AS n FROM ${FOLD_STATE_TABLE} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\treturn (rows[0]?.n ?? 0) > 0\n\t}\n\n\tprivate async readStateRow(\n\t\ttx: Transaction,\n\t\ttable: string,\n\t\tcollection: string,\n\t\trecordId: string,\n\t): Promise<FoldState | null> {\n\t\tconst rows = await tx.query<{ state: string }>(\n\t\t\t`SELECT state FROM ${table} WHERE collection = ? AND record_id = ?`,\n\t\t\t[collection, recordId],\n\t\t)\n\t\tconst raw = rows[0]?.state\n\t\tif (raw === undefined) return null\n\t\ttry {\n\t\t\treturn deserializeFoldState(raw)\n\t\t} catch (error) {\n\t\t\t// Another format version: the caller re-folds the record.\n\t\t\tif (error instanceof FoldStateError) return null\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprivate async toMergeTraces(tx: Transaction, traces: FoldTrace[]): Promise<MergeTrace[]> {\n\t\tconst out: MergeTrace[] = []\n\t\tfor (const trace of traces) {\n\t\t\tlet prior: Operation | null = null\n\t\t\tif (trace.priorOperationId !== null) {\n\t\t\t\tconst rows = await tx.query<OperationRow>(\n\t\t\t\t\t`SELECT * FROM ${quoteIdent(`_kora_ops_${trace.operation.collection}`)} WHERE id = ?`,\n\t\t\t\t\t[trace.priorOperationId],\n\t\t\t\t)\n\t\t\t\tconst row = rows[0]\n\t\t\t\tif (row) prior = deserializeOperationWithCollection(row, trace.operation.collection)\n\t\t\t}\n\t\t\tout.push(toMergeTrace(trace, prior))\n\t\t}\n\t\treturn out\n\t}\n}\n\n/** No insert merged yet, or the newest delete is later than the newest write. */\n/**\n * The stored form of a fold state: plain JSON, read back by `deserializeFoldState`.\n * The canonical form (`serializeFoldState`, sorted keys) is for comparing and\n * exchanging states; a local row only needs to round-trip, and plain JSON is several\n * times cheaper on the write path.\n */\nfunction persistedForm(state: FoldState): string {\n\treturn JSON.stringify(state)\n}\n\nfunction isDeadState(state: FoldState): boolean {\n\treturn !isFoldStateLive(state)\n}\n"],"mappings":"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","names":["quoteIdent","quoteIdent","quoteIdent","quoteIdent"]}
|