@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.
Files changed (92) hide show
  1. package/README.md +29 -37
  2. package/dist/adapters/better-sqlite3.cjs +90 -4
  3. package/dist/adapters/better-sqlite3.cjs.map +1 -1
  4. package/dist/adapters/better-sqlite3.d.cts +21 -12
  5. package/dist/adapters/better-sqlite3.d.ts +21 -12
  6. package/dist/adapters/better-sqlite3.js +69 -5
  7. package/dist/adapters/better-sqlite3.js.map +1 -1
  8. package/dist/adapters/indexeddb.cjs +1316 -610
  9. package/dist/adapters/indexeddb.cjs.map +1 -1
  10. package/dist/adapters/indexeddb.d.cts +29 -3
  11. package/dist/adapters/indexeddb.d.ts +29 -3
  12. package/dist/adapters/indexeddb.js +247 -221
  13. package/dist/adapters/indexeddb.js.map +1 -1
  14. package/dist/adapters/sqlite-wasm-worker.cjs +856 -63
  15. package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -1
  16. package/dist/adapters/sqlite-wasm-worker.js +529 -63
  17. package/dist/adapters/sqlite-wasm-worker.js.map +1 -1
  18. package/dist/adapters/sqlite-wasm.cjs +1032 -344
  19. package/dist/adapters/sqlite-wasm.cjs.map +1 -1
  20. package/dist/adapters/sqlite-wasm.d.cts +239 -18
  21. package/dist/adapters/sqlite-wasm.d.ts +239 -18
  22. package/dist/adapters/sqlite-wasm.js +111 -5
  23. package/dist/adapters/sqlite-wasm.js.map +1 -1
  24. package/dist/backup-IHKVMUAM.js +25 -0
  25. package/dist/chunk-5AQSGMJV.js +5471 -0
  26. package/dist/chunk-5AQSGMJV.js.map +1 -0
  27. package/dist/chunk-5JMGMPUE.js +591 -0
  28. package/dist/chunk-5JMGMPUE.js.map +1 -0
  29. package/dist/{chunk-CYO3YKFL.js → chunk-5ZRRF6R2.js} +2 -2
  30. package/dist/chunk-A6GFH5IG.js +36 -0
  31. package/dist/chunk-A6GFH5IG.js.map +1 -0
  32. package/dist/chunk-BILSA6XZ.js +608 -0
  33. package/dist/chunk-BILSA6XZ.js.map +1 -0
  34. package/dist/chunk-BQSIL6TT.js +1095 -0
  35. package/dist/chunk-BQSIL6TT.js.map +1 -0
  36. package/dist/{chunk-GSJ7EEUC.js → chunk-J5AGXF3D.js} +58 -9
  37. package/dist/chunk-J5AGXF3D.js.map +1 -0
  38. package/dist/chunk-KK3GBONL.js +112 -0
  39. package/dist/chunk-KK3GBONL.js.map +1 -0
  40. package/dist/chunk-KTVNANUH.js +876 -0
  41. package/dist/chunk-KTVNANUH.js.map +1 -0
  42. package/dist/chunk-QW4UU7NG.js +1003 -0
  43. package/dist/chunk-QW4UU7NG.js.map +1 -0
  44. package/dist/chunk-SRHDJF5B.js +186 -0
  45. package/dist/chunk-SRHDJF5B.js.map +1 -0
  46. package/dist/chunk-UC2LGFPV.js +810 -0
  47. package/dist/chunk-UC2LGFPV.js.map +1 -0
  48. package/dist/{export-audit-ODGQTQIK.js → export-audit-J2QXRHD2.js} +3 -3
  49. package/dist/index.cjs +9533 -4246
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +1143 -110
  52. package/dist/index.d.ts +1143 -110
  53. package/dist/index.js +298 -3191
  54. package/dist/index.js.map +1 -1
  55. package/dist/internal.cjs +581 -264
  56. package/dist/internal.cjs.map +1 -1
  57. package/dist/internal.d.cts +15 -85
  58. package/dist/internal.d.ts +15 -85
  59. package/dist/internal.js +10 -8
  60. package/dist/restore-MNDPR557.js +299 -0
  61. package/dist/restore-MNDPR557.js.map +1 -0
  62. package/dist/sql-builder-D0tC3sv9.d.cts +615 -0
  63. package/dist/sql-builder-D5UMzHEo.d.ts +615 -0
  64. package/dist/sqlite-wasm-channel-DVX93Uiq.d.cts +141 -0
  65. package/dist/sqlite-wasm-channel-DVX93Uiq.d.ts +141 -0
  66. package/dist/sqlite-wasm-channel-QCCNBYCU.js +12 -0
  67. package/dist/store-HNGX4KTT.js +16 -0
  68. package/dist/store-HNGX4KTT.js.map +1 -0
  69. package/dist/{types-BslDOTk0.d.ts → types-Dh-xyUjP.d.cts} +99 -26
  70. package/dist/{types-BslDOTk0.d.cts → types-Dh-xyUjP.d.ts} +99 -26
  71. package/package.json +3 -2
  72. package/dist/backup-5S7K2Z35.js +0 -14
  73. package/dist/chunk-GSJ7EEUC.js.map +0 -1
  74. package/dist/chunk-HS6DBMST.js +0 -383
  75. package/dist/chunk-HS6DBMST.js.map +0 -1
  76. package/dist/chunk-RJIEKEN4.js +0 -751
  77. package/dist/chunk-RJIEKEN4.js.map +0 -1
  78. package/dist/chunk-TUR7RGEP.js +0 -84
  79. package/dist/chunk-TUR7RGEP.js.map +0 -1
  80. package/dist/chunk-VDBJQ75K.js +0 -78
  81. package/dist/chunk-VDBJQ75K.js.map +0 -1
  82. package/dist/chunk-YT7MRFCP.js +0 -687
  83. package/dist/chunk-YT7MRFCP.js.map +0 -1
  84. package/dist/sqlite-wasm-channel-GGHA2BXU.js +0 -12
  85. package/dist/sqlite-wasm-channel-L6o3bWQK.d.cts +0 -92
  86. package/dist/sqlite-wasm-channel-L6o3bWQK.d.ts +0 -92
  87. package/dist/types-BOO9EPt1.d.ts +0 -170
  88. package/dist/types-C_GDavG-.d.cts +0 -170
  89. /package/dist/{backup-5S7K2Z35.js.map → backup-IHKVMUAM.js.map} +0 -0
  90. /package/dist/{chunk-CYO3YKFL.js.map → chunk-5ZRRF6R2.js.map} +0 -0
  91. /package/dist/{export-audit-ODGQTQIK.js.map → export-audit-J2QXRHD2.js.map} +0 -0
  92. /package/dist/{sqlite-wasm-channel-GGHA2BXU.js.map → sqlite-wasm-channel-QCCNBYCU.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mutations/write-context.ts","../src/lww/field-versions.ts","../src/state-machine/state-validator.ts","../src/mutations/run-local-write.ts","../src/mutations/write-ops.ts","../src/mutations/secret-write.ts","../src/mutations/execute-delete.ts","../src/mutations/execute-insert.ts","../src/mutations/execute-update.ts"],"sourcesContent":["import type {\n\tCausalTracker,\n\tHybridLogicalClock,\n\tOperation,\n\tSchemaDefinition,\n\tSecretKeyProvider,\n} from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { RecordFolder } from '../fold/record-folder'\nimport type { RelationEnforcer } from '../relations/relation-enforcer'\nimport type { Transaction } from '../types'\n\n/**\n * Called inside the write transaction for every local delete, after the delete\n * operation is built and before referential side effects run. Lets the unified\n * apply pipeline run its referential checks (and emit their traces) against the\n * rows the transaction sees. Throwing aborts the whole write.\n */\nexport type LocalDeleteHook = (operation: Operation, tx: Transaction) => Promise<void>\n\n/**\n * Everything the single local write path needs to build and persist an\n * operation inside a storage transaction. One environment serves single-record\n * writes, `app.transaction` commits and referential cascades, so every local\n * operation is built the same way (W6).\n */\nexport interface WriteEnv {\n\treadonly schema: SchemaDefinition\n\treadonly clock: HybridLogicalClock\n\treadonly nodeId: string\n\treadonly relationEnforcer: RelationEnforcer | null\n\treadonly secretKeyProvider?: SecretKeyProvider\n\t/** Shared by every operation of an `app.transaction` / `app.mutation` commit. */\n\treadonly transactionId?: string\n\t/** Human-readable mutation name propagated to every operation (DevTools). */\n\treadonly mutationName?: string\n\t/** See {@link LocalDeleteHook}. */\n\treadonly beforeLocalDelete?: LocalDeleteHook\n\t/**\n\t * The W7 record fold. When set, a local write appends its operation and then\n\t * merges it into the record's fold state, which re-materializes the row (the\n\t * same path remote operations take). Absent only under\n\t * `experimental.legacyMerge` (and while a pre-W7 database is migrated, before its\n\t * re-materialization): the row is then written directly, as in beta.12.\n\t */\n\treadonly fold?: RecordFolder\n\t/**\n\t * Largest operation a local write may produce (RT-86), the server's\n\t * `maxOperationBytes`. Default `DEFAULT_MAX_OPERATION_BYTES` (256 KiB).\n\t */\n\treadonly maxOperationBytes?: number\n\t/**\n\t * Throws when local writes are not allowed right now: the store's pinned node\n\t * belongs to another user than the one signed in (F9). Called before every local\n\t * operation is built.\n\t */\n\treadonly assertLocalWriteAllowed?: () => void\n}\n\n/**\n * Causal bookkeeping for the operations built inside ONE storage transaction.\n *\n * Dependencies are computed from the committed causal heads (the shared\n * {@link CausalTracker}) overlaid with the operations already built in this\n * transaction. Heads are published to the shared tracker only after the\n * transaction commits, so a rolled-back write never leaves a dependency on an\n * operation that does not exist.\n */\nexport class CausalScope {\n\tprivate readonly lastByCollection = new Map<string, string>()\n\tprivate lastInScope: string | null = null\n\tprivate readonly recorded: Array<{ collection: string; id: string }> = []\n\n\tconstructor(\n\t\tprivate readonly tracker: CausalTracker | null,\n\t\t/** When true, every operation also depends on the previous one in this scope. */\n\t\tprivate readonly chainOperations: boolean,\n\t) {}\n\n\t/**\n\t * Direct causal parents for the next operation in `collection`.\n\t *\n\t * @param collection - Collection of the operation being built\n\t * @param extra - Explicit parents (e.g. the delete that caused a cascade)\n\t */\n\tdepsFor(collection: string, extra: readonly string[] = []): string[] {\n\t\tconst deps: string[] = []\n\t\tconst add = (id: string | undefined | null): void => {\n\t\t\tif (id && !deps.includes(id)) deps.push(id)\n\t\t}\n\t\tfor (const id of extra) add(id)\n\t\tconst local = this.lastByCollection.get(collection)\n\t\tif (local !== undefined) {\n\t\t\tadd(local)\n\t\t} else {\n\t\t\tfor (const id of this.tracker?.nextCausalDeps(collection, false) ?? []) add(id)\n\t\t}\n\t\tif (this.chainOperations) add(this.lastInScope)\n\t\treturn deps\n\t}\n\n\t/** Record an operation built in this scope. */\n\trecord(collection: string, operationId: string): void {\n\t\tthis.lastByCollection.set(collection, operationId)\n\t\tthis.lastInScope = operationId\n\t\tthis.recorded.push({ collection, id: operationId })\n\t}\n\n\t/** Publish this scope's heads to the shared tracker. Call only after commit. */\n\tpublish(): void {\n\t\tfor (const { collection, id } of this.recorded) {\n\t\t\tthis.tracker?.afterOperation(collection, id, false)\n\t\t}\n\t}\n}\n\n/**\n * The sequence-number block of ONE write transaction.\n *\n * The first number is reserved with one `UPSERT ... RETURNING` on\n * `_kora_version_vector`, inside the transaction; later numbers continue the block\n * in memory, and {@link SequenceBlock.close} persists the block's end with one\n * write before the transaction commits. Write transactions are serialized and no\n * code path allocates numbers outside one, so the block is contiguous and never\n * shared; the UNIQUE `(node_id, sequence_number)` index on every op table is the\n * backstop. A rollback discards the reservation with everything else.\n */\nexport class SequenceBlock {\n\tprivate last: number | null = null\n\tprivate persisted = 0\n\n\tconstructor(\n\t\tprivate readonly tx: Transaction,\n\t\tprivate readonly nodeId: string,\n\t) {}\n\n\t/** The next number of the block. */\n\tasync take(): Promise<number> {\n\t\tif (this.last === null) {\n\t\t\tconst rows = await this.tx.query<{ sequence_number: number }>(\n\t\t\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\t\t[this.nodeId],\n\t\t\t)\n\t\t\tconst first = rows[0]?.sequence_number\n\t\t\tif (first === undefined) {\n\t\t\t\tthrow new KoraError(\n\t\t\t\t\t`Failed to reserve a sequence number for node \"${this.nodeId}\"`,\n\t\t\t\t\t'SEQUENCE_RESERVATION_FAILED',\n\t\t\t\t\t{ nodeId: this.nodeId },\n\t\t\t\t)\n\t\t\t}\n\t\t\tthis.last = first\n\t\t\tthis.persisted = first\n\t\t\treturn first\n\t\t}\n\t\tthis.last += 1\n\t\treturn this.last\n\t}\n\n\t/** Persist the end of the block. Must run inside the transaction, before commit. */\n\tasync close(): Promise<void> {\n\t\tif (this.last === null || this.last === this.persisted) return\n\t\tawait this.tx.execute(\n\t\t\t'UPDATE _kora_version_vector SET sequence_number = MAX(sequence_number, ?) WHERE node_id = ?',\n\t\t\t[this.last, this.nodeId],\n\t\t)\n\t\tthis.persisted = this.last\n\t}\n}\n\n/**\n * The per-transaction state of a local write: the transaction handle, its\n * sequence block and its causal scope. Every operation built in one transaction\n * takes the next number of the same contiguous block.\n */\nexport interface WriteScope {\n\treadonly tx: Transaction\n\treadonly sequence: SequenceBlock\n\treadonly causal: CausalScope\n}\n\n/**\n * Run `write` with a fresh {@link WriteScope} on `tx`, then close the sequence\n * block (still inside the transaction).\n */\nexport async function withWriteScope<T>(\n\ttx: Transaction,\n\tnodeId: string,\n\tcausal: CausalScope,\n\twrite: (scope: WriteScope) => Promise<T>,\n): Promise<T> {\n\tconst scope: WriteScope = { tx, sequence: new SequenceBlock(tx, nodeId), causal }\n\tconst result = await write(scope)\n\tawait scope.sequence.close()\n\treturn result\n}\n\n/**\n * Whether a storage error means the device ran out of space: SQLite's\n * `SQLITE_FULL` (\"database or disk is full\") or a browser quota error from OPFS /\n * IndexedDB. The store maps these to a `store:quota-exceeded` event (STORE-15).\n */\nexport function isStorageFullError(error: unknown): boolean {\n\tif (error === null || typeof error !== 'object') return false\n\tconst candidate = error as { name?: unknown; code?: unknown; message?: unknown; cause?: unknown }\n\tif (candidate.name === 'QuotaExceededError') return true\n\tif (candidate.code === 'SQLITE_FULL' || candidate.code === 'QUOTA_EXCEEDED') return true\n\tconst message = typeof candidate.message === 'string' ? candidate.message : ''\n\tif (/SQLITE_FULL|database or disk is full|quota ?exceeded/i.test(message)) return true\n\treturn candidate.cause !== undefined && candidate.cause !== error\n\t\t? isStorageFullError(candidate.cause)\n\t\t: false\n}\n","import { EMPTY_ROW_VERSION } from './row-version'\n\n/**\n * Per-field last-writer versions for a materialized row.\n *\n * Each entry maps a field name to a serialized HLC timestamp (the same\n * lexicographically-sortable form used by the row `_version` column). Because\n * the serialized form sorts identically to {@link HybridLogicalClock.compare},\n * per-field last-write-wins is a plain string comparison: the greater string is\n * the newer writer. This makes field-level convergence deterministic and\n * independent of the order operations happen to arrive in.\n */\nexport type FieldVersions = Record<string, string>\n\n/**\n * Parse the `_field_versions` JSON column into a map. Tolerates null, empty,\n * and malformed values by returning an empty map — a row that predates\n * per-field tracking simply has no field versions and falls back to `_version`.\n */\nexport function parseFieldVersions(raw: unknown): FieldVersions {\n\tif (typeof raw !== 'string' || raw.length === 0) {\n\t\treturn {}\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown\n\t\tif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n\t\t\treturn {}\n\t\t}\n\t\tconst result: FieldVersions = {}\n\t\tfor (const [key, value] of Object.entries(parsed as Record<string, unknown>)) {\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tresult[key] = value\n\t\t\t}\n\t\t}\n\t\treturn result\n\t} catch {\n\t\treturn {}\n\t}\n}\n\n/**\n * Serialize a field-version map for storage in the `_field_versions` column.\n */\nexport function serializeFieldVersions(versions: FieldVersions): string {\n\treturn JSON.stringify(versions)\n}\n\n/**\n * Build the initial field-version map for an insert: every supplied field is\n * stamped with the operation's version.\n */\nexport function fieldVersionsForFields(\n\tfieldNames: Iterable<string>,\n\tversion: string,\n): FieldVersions {\n\tconst versions: FieldVersions = {}\n\tfor (const field of fieldNames) {\n\t\tversions[field] = version\n\t}\n\treturn versions\n}\n\n/**\n * The effective stored version for a field: its own tracked version if present,\n * otherwise the row-level `_version` (so rows written before per-field tracking\n * still compare correctly), otherwise the empty sentinel (older than anything).\n */\nexport function effectiveFieldVersion(\n\tcurrent: FieldVersions,\n\tfield: string,\n\trowVersion: string | undefined,\n): string {\n\tconst own = current[field]\n\tif (own !== undefined) {\n\t\treturn own\n\t}\n\treturn rowVersion ?? EMPTY_ROW_VERSION\n}\n\n/**\n * Result of resolving an incoming operation against the current per-field\n * versions of a row.\n */\nexport interface PerFieldLwwResult {\n\t/** Fields the incoming operation wins (strictly newer than the stored version). */\n\twinners: string[]\n\t/** The merged field-version map to persist (winners advanced to `incomingVersion`). */\n\tmerged: FieldVersions\n}\n\n/**\n * Resolve per-field last-write-wins for an incoming operation.\n *\n * For each incoming field, the operation wins only when its version is strictly\n * greater than the field's effective stored version. Ties (identical version,\n * i.e. the same operation re-applied) are losses, keeping the resolution\n * idempotent. The comparison is a total order, so every node resolves the same\n * winner regardless of the order operations arrive.\n *\n * @param current - Parsed `_field_versions` of the target row\n * @param incomingFields - Field names carried by the incoming operation\n * @param incomingVersion - Serialized HLC version of the incoming operation\n * @param rowVersion - The row's `_version` (fallback for untracked fields)\n */\nexport function resolvePerFieldLww(\n\tcurrent: FieldVersions,\n\tincomingFields: Iterable<string>,\n\tincomingVersion: string,\n\trowVersion: string | undefined,\n): PerFieldLwwResult {\n\tconst winners: string[] = []\n\tconst merged: FieldVersions = { ...current }\n\tfor (const field of incomingFields) {\n\t\tconst stored = effectiveFieldVersion(current, field, rowVersion)\n\t\tif (incomingVersion > stored) {\n\t\t\twinners.push(field)\n\t\t\tmerged[field] = incomingVersion\n\t\t}\n\t\t// Losing fields are left untouched: their existing tracked version (or the\n\t\t// row-level `_version` fallback) already reflects the newer writer.\n\t}\n\treturn { winners, merged }\n}\n\n/**\n * Stamp `fields` with `version` on top of a stored `_field_versions` value and\n * return the serialized column. This is the one per-field stamp every local\n * write uses (insert, update, transaction entries, cascades), so every field a\n * device writes carries the HLC of the operation that wrote it.\n *\n * Stamps only move forward: a field already holding a newer version keeps it.\n * The map is keyed by field name with one HLC register per field, the shape the\n * per-field fold (W7) builds on.\n *\n * @param currentRaw - The stored `_field_versions` column (or null for a new row)\n * @param fields - Field names this write sets\n * @param version - The writing operation's serialized HLC version\n */\nexport function stampFieldVersions(\n\tcurrentRaw: unknown,\n\tfields: Iterable<string>,\n\tversion: string,\n): string {\n\tconst versions = parseFieldVersions(currentRaw)\n\tfor (const field of fields) {\n\t\tconst existing = versions[field]\n\t\tif (existing === undefined || existing < version) {\n\t\t\tversions[field] = version\n\t\t}\n\t}\n\treturn serializeFieldVersions(versions)\n}\n","import { KoraError, validateTransition } from '@korajs/core'\nimport type {\n\tCollectionDefinition,\n\tStateMachineConstraint,\n\tStateMachineDefinition,\n} from '@korajs/core'\n\n/**\n * Error thrown when a local mutation attempts an invalid state transition.\n *\n * Contains enough context to debug without reproduction:\n * the collection, record, field, current state, attempted state, and allowed transitions.\n */\nexport class InvalidStateTransitionError extends KoraError {\n\tconstructor(\n\t\tpublic readonly collection: string,\n\t\tpublic readonly recordId: string,\n\t\tpublic readonly field: string,\n\t\tpublic readonly fromState: string,\n\t\tpublic readonly toState: string,\n\t\tpublic readonly allowedStates: string[],\n\t) {\n\t\tsuper(\n\t\t\t`Invalid state transition in collection \"${collection}\": ` +\n\t\t\t\t`cannot transition field \"${field}\" from \"${fromState}\" to \"${toState}\". ` +\n\t\t\t\t`Allowed transitions from \"${fromState}\": ${allowedStates.length > 0 ? allowedStates.join(', ') : '(none -- terminal state)'}`,\n\t\t\t'INVALID_STATE_TRANSITION',\n\t\t\t{ collection, recordId, field, fromState, toState, allowedStates },\n\t\t)\n\t\tthis.name = 'InvalidStateTransitionError'\n\t}\n}\n\n/**\n * Validates a state machine transition for a local mutation (insert or update).\n *\n * For inserts: validates that the initial state (from the data or the default value)\n * is a known state in the state machine.\n *\n * For updates: looks up the current state field value and checks whether\n * the transition to the new value is allowed.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being mutated\n * @param stateMachine - The state machine definition\n * @param currentState - The current value of the state field (null for inserts)\n * @param newState - The new value being set for the state field\n * @returns An object indicating whether the transition is valid, and if not, the allowed states.\n * When `onInvalidTransition` is 'last-valid-state', callers should suppress the field update\n * rather than throwing.\n */\nexport function validateStateTransition(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentState: string | null,\n\tnewState: string,\n): { valid: boolean; allowedStates: string[] } {\n\t// For inserts, any valid enum value is acceptable as the initial state\n\t// (schema validation already ensures the value is a valid enum value)\n\tif (currentState === null) {\n\t\treturn { valid: true, allowedStates: [] }\n\t}\n\n\t// Same-state transitions are always valid (idempotent updates)\n\tif (currentState === newState) {\n\t\treturn { valid: true, allowedStates: stateMachine.transitions[currentState] ?? [] }\n\t}\n\n\tconst constraint: StateMachineConstraint = {\n\t\tfield: stateMachine.field,\n\t\tcollection: collectionName,\n\t\ttransitions: stateMachine.transitions,\n\t}\n\tconst transitionResult = validateTransition(constraint, currentState, newState)\n\tif (transitionResult.valid) {\n\t\treturn { valid: true, allowedStates: transitionResult.allowedTargets }\n\t}\n\n\tconst allowedStates = transitionResult.allowedTargets\n\n\tif (stateMachine.onInvalidTransition === 'reject') {\n\t\tthrow new InvalidStateTransitionError(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\tstateMachine.field,\n\t\t\tcurrentState,\n\t\t\tnewState,\n\t\t\tallowedStates,\n\t\t)\n\t}\n\n\t// 'last-valid-state': return invalid so the caller can suppress the field update\n\treturn { valid: false, allowedStates }\n}\n\n/**\n * Checks whether a collection update data object contains a change to the state machine field,\n * and if so, validates the transition.\n *\n * If the state field is not in the update data, returns the data unchanged.\n * If the transition is invalid and mode is 'last-valid-state', removes the field from the data.\n * If the transition is invalid and mode is 'reject', throws InvalidStateTransitionError.\n *\n * @param collectionName - Name of the collection\n * @param recordId - The record being updated\n * @param collectionDef - The collection definition from the schema\n * @param currentRecord - The current record data (must include the state field)\n * @param updateData - The partial update data\n * @returns The update data, potentially with the state field removed if invalid and mode is 'last-valid-state'\n */\nexport function validateUpdateStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tcollectionDef: CollectionDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tlet result = updateData\n\tconst stateMachine = collectionDef.stateMachine\n\tif (stateMachine !== undefined) {\n\t\tresult = applyStateMachine(collectionName, recordId, stateMachine, currentRecord, result)\n\t}\n\t// Field-level `t.enum(...).transitions()` maps are state machines too, in the\n\t// default 'reject' mode (NEW-STORE-3). A collection-level machine on the same\n\t// field takes precedence.\n\tfor (const [field, descriptor] of Object.entries(collectionDef.fields)) {\n\t\tif (descriptor.kind !== 'enum' || !descriptor.transitions) continue\n\t\tif (stateMachine?.field === field) continue\n\t\tresult = applyStateMachine(\n\t\t\tcollectionName,\n\t\t\trecordId,\n\t\t\t{ field, transitions: descriptor.transitions, onInvalidTransition: 'reject' },\n\t\t\tcurrentRecord,\n\t\t\tresult,\n\t\t)\n\t}\n\treturn result\n}\n\nfunction applyStateMachine(\n\tcollectionName: string,\n\trecordId: string,\n\tstateMachine: StateMachineDefinition,\n\tcurrentRecord: Record<string, unknown>,\n\tupdateData: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst stateField = stateMachine.field\n\tif (!(stateField in updateData)) {\n\t\t// State field not being changed -- no validation needed\n\t\treturn updateData\n\t}\n\n\tconst currentState = currentRecord[stateField]\n\tconst newState = updateData[stateField]\n\n\t// Both values must be strings for state machine validation\n\tif (typeof currentState !== 'string' || typeof newState !== 'string') {\n\t\treturn updateData\n\t}\n\n\tconst result = validateStateTransition(\n\t\tcollectionName,\n\t\trecordId,\n\t\tstateMachine,\n\t\tcurrentState,\n\t\tnewState,\n\t)\n\n\tif (result.valid) {\n\t\treturn updateData\n\t}\n\n\t// Mode is 'last-valid-state': silently remove the state field from the update\n\tconst filtered = { ...updateData }\n\tdelete filtered[stateField]\n\n\t// If no fields remain after removing the state field, the update becomes a no-op.\n\t// Return the empty object -- the caller can decide whether to proceed.\n\treturn filtered\n}\n","import type { Operation } from '@korajs/core'\nimport { KoraError } from '@korajs/core'\nimport type { LocalMutationContext } from './types'\nimport { CausalScope, type WriteScope, withWriteScope } from './write-context'\nimport type { WriteResult } from './write-ops'\n\n/**\n * Run one local write in its own storage transaction, then publish it.\n *\n * Post-commit work (causal heads, in-memory version vector, subscriptions,\n * `operation:created`) runs only after the transaction commits, so nothing\n * observable ever points at an operation that was rolled back (STORE-15).\n */\nexport async function runLocalWrite(\n\tctx: LocalMutationContext,\n\twrite: (scope: WriteScope) => Promise<WriteResult>,\n): Promise<WriteResult> {\n\tconst causal = new CausalScope(ctx.causalTracker, false)\n\tlet result: WriteResult | undefined\n\ttry {\n\t\tawait ctx.adapter.transaction(async (tx) => {\n\t\t\tresult = await withWriteScope(tx, ctx.nodeId, causal, write)\n\t\t})\n\t} catch (error) {\n\t\tctx.onStorageError?.(error)\n\t\tthrow error\n\t}\n\tif (!result) {\n\t\tthrow new KoraError('Local write transaction completed without a result', 'WRITE_INCOMPLETE', {\n\t\t\tcollection: ctx.collection,\n\t\t})\n\t}\n\tcausal.publish()\n\tpublishOperations(ctx, result)\n\treturn result\n}\n\n/** Notify the store about every operation of a committed write, in creation order. */\nfunction publishOperations(ctx: LocalMutationContext, result: WriteResult): void {\n\tconst ops: Operation[] = []\n\tif (result.operation) ops.push(result.operation)\n\tops.push(...result.sideEffects)\n\tfor (const op of ops) {\n\t\tctx.onMutation(op.collection, op)\n\t}\n}\n","import type { AtomicOp, CollectionDefinition, Operation } from '@korajs/core'\nimport {\n\tDEFAULT_MAX_OPERATION_BYTES,\n\tKoraError,\n\tOperationTooLargeError,\n\tassertResolvedFieldValue,\n\tcreateOperation,\n\tgenerateUUIDv7,\n\tisAtomicOp,\n\tmeasureOperationBytes,\n\tquoteIdent,\n\tresolveAtomicOp,\n\ttoAtomicOp,\n\tvalidateRecord,\n} from '@korajs/core'\nimport { RecordNotFoundError } from '../errors'\nimport { stampFieldVersions } from '../lww/field-versions'\nimport { serializeRowVersion } from '../lww/row-version'\nimport { buildInsertQuery, buildSoftDeleteQuery, buildUpdateQuery } from '../query/sql-builder'\nimport { encodeRichtextFieldsForOpData } from '../serialization/op-data-encoding'\nimport {\n\tdeserializeRecord,\n\tserializeOperation,\n\tserializeRecord,\n\ttoRichtextReadShape,\n} from '../serialization/serializer'\nimport { validateUpdateStateMachine } from '../state-machine/state-validator'\nimport type { CollectionRecord, RawCollectionRow } from '../types'\nimport { toAtRestWriteData } from './secret-write'\nimport type { WriteEnv, WriteScope } from './write-context'\n\n/*\n * THE local write path (W6). Every local operation — a single-record write, each\n * entry of an `app.transaction` / `app.mutation` commit, and every referential\n * cascade — is built and persisted by the functions in this file, inside the\n * storage transaction that commits it:\n *\n * 1. the current row is read through the transaction handle, so validation\n * (existence, state machine) and atomic ops resolve against committed state;\n * 2. the sequence number comes from the transaction's SequenceBlock (reserved\n * with UPSERT ... RETURNING on `_kora_version_vector` inside the transaction,\n * end persisted before commit); transactions are serialized, so the numbers of\n * one commit form one contiguous block and two commits can never share one;\n * 3. the operation is built only AFTER its sequence number is reserved, and is\n * never re-stamped (protocol v2 hashes the sequence number into the id);\n * 4. the row is written with per-field version stamps and the operation row is\n * appended, in the same transaction.\n */\n\n/** An insert whose values are validated and in their at-rest form. */\nexport interface PreparedInsert {\n\treadonly collection: string\n\treadonly recordId: string\n\t/** Record-shaped, at-rest values (secret fields hashed / encrypted). */\n\treadonly data: Record<string, unknown>\n}\n\n/**\n * Validate insert data, fill auto fields and transform secrets. Pure with\n * respect to storage, so `app.transaction` can do it when the developer calls\n * `insert` (returning the new id immediately) and write it at commit.\n */\nexport async function prepareInsert(\n\tenv: WriteEnv,\n\tcollection: string,\n\tdata: Record<string, unknown>,\n): Promise<PreparedInsert> {\n\tconst definition = requireDefinition(env, collection)\n\tconst validated = validateRecord(collection, definition, data, 'insert')\n\tconst now = Date.now()\n\tfor (const [fieldName, descriptor] of Object.entries(definition.fields)) {\n\t\tif (descriptor.auto && descriptor.kind === 'timestamp') {\n\t\t\tvalidated[fieldName] = now\n\t\t}\n\t}\n\t// Secret fields reach their at-rest form BEFORE the operation is built, so\n\t// plaintext never enters the op log, the row, or the wire (STORE-4).\n\tconst writeData = await toAtRestWriteData(validated, definition, env.secretKeyProvider)\n\treturn { collection, recordId: generateUUIDv7(), data: writeData }\n}\n\n/** Result of writing one local operation. */\nexport interface WriteResult {\n\t/** The operation, or null when the write turned out to be a no-op. */\n\treadonly operation: Operation | null\n\t/** The record as stored after the write. */\n\treadonly record: CollectionRecord\n\t/** Operations created as side effects (referential cascades), in creation order. */\n\treadonly sideEffects: Operation[]\n}\n\n/**\n * Write a prepared insert inside `scope.tx`.\n */\nexport async function writeInsertInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinsert: PreparedInsert,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, insert.collection)\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'insert',\n\t\tcollection: insert.collection,\n\t\trecordId: insert.recordId,\n\t\t// Binary richtext values are tagged as canonical JSON BEFORE hashing, so the\n\t\t// hash input, persisted JSON and wire payload are the identical value.\n\t\tdata: encodeRichtextFieldsForOpData(insert.data, definition.fields),\n\t\tpreviousData: null,\n\t\textraCausalDeps,\n\t})\n\n\tif (env.fold) {\n\t\t// Append, then merge: the row is the materialization of the record's state.\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serialized = serializeRecord(insert.data, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst row: Record<string, unknown> = {\n\t\t\tid: insert.recordId,\n\t\t\t...serialized,\n\t\t\t_created_at: operation.timestamp.wallTime,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t// Every inserted field is stamped with this operation's version, so later\n\t\t\t// per-field LWW compares against a real writer, not the row fallback.\n\t\t\t_field_versions: stampFieldVersions(null, Object.keys(serialized), version),\n\t\t}\n\t\tconst rowInsert = buildInsertQuery(insert.collection, row)\n\t\tawait scope.tx.execute(rowInsert.sql, rowInsert.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: {\n\t\t\tid: insert.recordId,\n\t\t\t// A richtext value written as a string returns as the bytes reads return.\n\t\t\t...toRichtextReadShape(insert.data, definition.fields),\n\t\t\tcreatedAt: operation.timestamp.wallTime,\n\t\t\tupdatedAt: operation.timestamp.wallTime,\n\t\t},\n\t\tsideEffects: [],\n\t}\n}\n\n/**\n * Write a local update inside `scope.tx`.\n *\n * `data` must already be schema-validated (it may contain atomic op descriptors).\n * The state machine, atomic ops and `previousData` are all resolved against the\n * row read through the transaction, so concurrent writers serialize correctly\n * (STORE-9, NEW-STORE-2).\n */\nexport async function writeUpdateInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\tdata: Record<string, unknown>,\n\textraCausalDeps: readonly string[] = [],\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst currentRecord = deserializeRecord(currentRow, definition.fields)\n\tconst allowed = validateUpdateStateMachine(collection, id, definition, currentRecord, data)\n\tif (Object.keys(allowed).length === 0) {\n\t\treturn { operation: null, record: currentRecord, sideEffects: [] }\n\t}\n\n\tconst previousData: Record<string, unknown> = {}\n\tconst resolved: Record<string, unknown> = {}\n\tconst atomicOps: Record<string, AtomicOp> = {}\n\tfor (const [key, value] of Object.entries(allowed)) {\n\t\tpreviousData[key] = currentRecord[key]\n\t\tif (isAtomicOp(value)) {\n\t\t\tresolved[key] = resolveAtomicOp(currentRecord[key], value)\n\t\t\t// The resolved value must be in the field's domain like any written value\n\t\t\t// (RT-87): `op.increment(0.5)` on a timestamp, an increment past the largest\n\t\t\t// finite number.\n\t\t\tconst descriptor = definition.fields[key]\n\t\t\tif (descriptor) assertResolvedFieldValue(collection, key, descriptor, resolved[key])\n\t\t\tatomicOps[key] = toAtomicOp(value)\n\t\t} else {\n\t\t\tresolved[key] = value\n\t\t}\n\t}\n\t// previousData already holds the stored (at-rest) values, so only the new\n\t// values need the secret transform.\n\tconst writeData = await toAtRestWriteData(resolved, definition, env.secretKeyProvider)\n\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'update',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: encodeRichtextFieldsForOpData(writeData, definition.fields),\n\t\tpreviousData: encodeRichtextFieldsForOpData(previousData, definition.fields),\n\t\textraCausalDeps,\n\t\t...(Object.keys(atomicOps).length > 0 ? { atomicOps } : {}),\n\t})\n\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst serializedChanges = serializeRecord(writeData, definition.fields)\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\t// A local edit is the newest writer of every field it touches (the HLC is past\n\t\t// every timestamp this device has seen), so each changed field gets its stamp.\n\t\tconst rowUpdate = buildUpdateQuery(collection, id, {\n\t\t\t...serializedChanges,\n\t\t\t_updated_at: operation.timestamp.wallTime,\n\t\t\t_version: version,\n\t\t\t_field_versions: stampFieldVersions(\n\t\t\t\tcurrentRow._field_versions,\n\t\t\t\tObject.keys(serializedChanges),\n\t\t\t\tversion,\n\t\t\t),\n\t\t})\n\t\tawait scope.tx.execute(rowUpdate.sql, rowUpdate.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst updatedRow = await readLiveRow(scope, collection, id)\n\tif (!updatedRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(updatedRow, definition.fields),\n\t\tsideEffects: [],\n\t}\n}\n\n/** Options for {@link writeDeleteInTx}. */\nexport interface WriteDeleteOptions {\n\t/** Skip referential checks and cascades (the caller already applied them). */\n\treadonly skipReferentialEnforcement?: boolean\n\t/** Explicit causal parents (e.g. the delete that caused this cascade). */\n\treadonly extraCausalDeps?: readonly string[]\n}\n\n/**\n * Soft-delete a record inside `scope.tx`, then apply the schema's referential\n * policies (cascade, set-null, restrict) in the same transaction. Cascaded\n * operations are built through this same write path, after the parent, so their\n * sequence numbers follow the parent's in the commit's block (STORE-2).\n */\nexport async function writeDeleteInTx(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n\toptions: WriteDeleteOptions = {},\n): Promise<WriteResult> {\n\tconst definition = requireDefinition(env, collection)\n\tconst currentRow = await readLiveRow(scope, collection, id)\n\tif (!currentRow) {\n\t\tthrow new RecordNotFoundError(collection, id)\n\t}\n\tconst operation = await buildLocalOperation(env, scope, {\n\t\ttype: 'delete',\n\t\tcollection,\n\t\trecordId: id,\n\t\tdata: null,\n\t\tpreviousData: null,\n\t\textraCausalDeps: options.extraCausalDeps ?? [],\n\t})\n\n\tif (!options.skipReferentialEnforcement && env.beforeLocalDelete) {\n\t\tawait env.beforeLocalDelete(operation, scope.tx)\n\t}\n\n\t// The row is tombstoned BEFORE side effects run, so a reference cycle\n\t// (self-referencing or mutually-referencing records) cannot cascade back\n\t// into this record.\n\tif (env.fold) {\n\t\tawait appendOperationRow(scope, operation)\n\t\tawait env.fold.applyInTx(scope.tx, operation, 'local')\n\t} else {\n\t\tconst version = serializeRowVersion(operation.timestamp)\n\t\tconst softDelete = buildSoftDeleteQuery(collection, id, operation.timestamp.wallTime, version)\n\t\tawait scope.tx.execute(softDelete.sql, softDelete.params)\n\t\tawait appendOperationRow(scope, operation)\n\t}\n\n\tconst sideEffects: Operation[] = []\n\tif (!options.skipReferentialEnforcement && env.relationEnforcer) {\n\t\tconst result = await env.relationEnforcer.enforceDelete(\n\t\t\tcollection,\n\t\t\tid,\n\t\t\tscope,\n\t\t\tenv,\n\t\t\toperation.id,\n\t\t)\n\t\tsideEffects.push(...result.operations)\n\t}\n\n\treturn {\n\t\toperation,\n\t\trecord: deserializeRecord(currentRow, definition.fields),\n\t\tsideEffects,\n\t}\n}\n\ninterface LocalOperationInput {\n\ttype: Operation['type']\n\tcollection: string\n\trecordId: string\n\tdata: Record<string, unknown> | null\n\tpreviousData: Record<string, unknown> | null\n\textraCausalDeps: readonly string[]\n\tatomicOps?: Record<string, AtomicOp>\n}\n\n/**\n * Reserve the next sequence number through the transaction, THEN build the\n * operation. The order matters: the operation is final the moment it exists.\n */\nasync function buildLocalOperation(\n\tenv: WriteEnv,\n\tscope: WriteScope,\n\tinput: LocalOperationInput,\n): Promise<Operation> {\n\tenv.assertLocalWriteAllowed?.()\n\tconst sequenceNumber = await scope.sequence.take()\n\tconst causalDeps = scope.causal.depsFor(input.collection, input.extraCausalDeps)\n\tconst operation = await createOperation(\n\t\t{\n\t\t\tnodeId: env.nodeId,\n\t\t\ttype: input.type,\n\t\t\tcollection: input.collection,\n\t\t\trecordId: input.recordId,\n\t\t\tdata: input.data,\n\t\t\tpreviousData: input.previousData,\n\t\t\tsequenceNumber,\n\t\t\tcausalDeps,\n\t\t\tschemaVersion: env.schema.version,\n\t\t\t...(input.atomicOps !== undefined ? { atomicOps: input.atomicOps } : {}),\n\t\t\t...(env.transactionId !== undefined ? { transactionId: env.transactionId } : {}),\n\t\t\t...(env.mutationName !== undefined ? { mutationName: env.mutationName } : {}),\n\t\t},\n\t\tenv.clock,\n\t)\n\t// Every operation must fit the server's maxOperationBytes (RT-86): refused here, in\n\t// the write's transaction (nothing is written), rather than accepted and then refused\n\t// by the server.\n\tconst maxBytes = env.maxOperationBytes ?? DEFAULT_MAX_OPERATION_BYTES\n\tconst bytes = measureOperationBytes(operation)\n\tif (bytes > maxBytes) {\n\t\tthrow new OperationTooLargeError(input.collection, input.recordId, bytes, maxBytes)\n\t}\n\tscope.causal.record(input.collection, operation.id)\n\treturn operation\n}\n\nasync function appendOperationRow(scope: WriteScope, operation: Operation): Promise<void> {\n\tconst opInsert = buildInsertQuery(\n\t\t`_kora_ops_${operation.collection}`,\n\t\tserializeOperation(operation) as unknown as Record<string, unknown>,\n\t)\n\tawait scope.tx.execute(opInsert.sql, opInsert.params)\n}\n\nasync function readLiveRow(\n\tscope: WriteScope,\n\tcollection: string,\n\tid: string,\n): Promise<RawCollectionRow | undefined> {\n\tconst rows = await scope.tx.query<RawCollectionRow>(\n\t\t`SELECT * FROM ${quoteIdent(collection)} WHERE id = ? AND _deleted = 0`,\n\t\t[id],\n\t)\n\treturn rows[0]\n}\n\nfunction requireDefinition(env: WriteEnv, collection: string): CollectionDefinition {\n\tconst definition = env.schema.collections[collection]\n\tif (!definition) {\n\t\tthrow new KoraError(\n\t\t\t`Unknown collection \"${collection}\". Available: ${Object.keys(env.schema.collections).join(', ')}`,\n\t\t\t'UNKNOWN_COLLECTION',\n\t\t\t{ collection },\n\t\t)\n\t}\n\treturn definition\n}\n","import type { CollectionDefinition, SecretKeyProvider } from '@korajs/core'\nimport { transformSecretFieldsForWrite } from '@korajs/core'\n\n/**\n * Convert the values a local write is about to persist into their at-rest form.\n *\n * Every local write path (single-record insert/update and the buffered\n * `TransactionContext` used by `app.transaction` / `app.mutation`) MUST route\n * its data through this helper BEFORE the operation is built, so plaintext\n * secrets never reach the operation log, the materialized row, or the wire.\n * Keeping one helper means a new write path cannot forget the transform\n * without also bypassing this function (STORE-4).\n *\n * @param data - Validated (and atomic-op-resolved) field values for the write\n * @param definition - The collection definition, used to find secret fields\n * @param secretKeyProvider - Key provider for `t.secret()` encrypted fields\n * @returns A copy of `data` with secret fields hashed or encrypted\n */\nexport function toAtRestWriteData(\n\tdata: Record<string, unknown>,\n\tdefinition: CollectionDefinition,\n\tsecretKeyProvider: SecretKeyProvider | undefined,\n): Promise<Record<string, unknown>> {\n\treturn transformSecretFieldsForWrite(data, definition, secretKeyProvider)\n}\n","import type { Operation } from '@korajs/core'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeDeleteInTx } from './write-ops'\n\nexport interface ExecuteDeleteOptions {\n\t/** When true, skip referential checks and cascades (caller already enforced them). */\n\tskipReferentialEnforcement?: boolean\n}\n\n/**\n * Soft-delete a record and persist the operation log entry atomically, together\n * with any referential side effects (cascades / set-null), in one transaction.\n * Returns the primary delete operation followed by the side-effect operations.\n */\nexport async function executeDelete(\n\tctx: LocalMutationContext,\n\tid: string,\n\toptions?: ExecuteDeleteOptions,\n): Promise<Operation[]> {\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteDeleteInTx(ctx, scope, ctx.collection, id, {\n\t\t\tskipReferentialEnforcement: options?.skipReferentialEnforcement ?? false,\n\t\t\textraCausalDeps: ctx.extraCausalDeps ?? [],\n\t\t}),\n\t)\n\treturn result.operation ? [result.operation, ...result.sideEffects] : result.sideEffects\n}\n","import type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { prepareInsert, writeInsertInTx } from './write-ops'\n\n/**\n * Insert a record and persist its operation, atomically, through the single\n * local write path (sequence reserved and operation built inside the write\n * transaction).\n */\nexport async function executeInsert(\n\tctx: LocalMutationContext,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst prepared = await prepareInsert(ctx, ctx.collection, data)\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteInsertInTx(ctx, scope, prepared, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n","import { validateRecord } from '@korajs/core'\nimport type { CollectionRecord } from '../types'\nimport { runLocalWrite } from './run-local-write'\nimport type { LocalMutationContext } from './types'\nimport { writeUpdateInTx } from './write-ops'\n\n/**\n * Update a record and persist its operation, atomically. The row read, the\n * state-machine check and atomic-op resolution all happen inside the write\n * transaction, so concurrent increments compose (STORE-9).\n */\nexport async function executeUpdate(\n\tctx: LocalMutationContext,\n\tid: string,\n\tdata: Record<string, unknown>,\n): Promise<CollectionRecord> {\n\tconst validated = validateRecord(ctx.collection, ctx.definition, data, 'update')\n\tconst result = await runLocalWrite(ctx, (scope) =>\n\t\twriteUpdateInTx(ctx, scope, ctx.collection, id, validated, ctx.extraCausalDeps ?? []),\n\t)\n\treturn result.record\n}\n"],"mappings":"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","names":["KoraError","KoraError","KoraError","KoraError","KoraError","validateRecord","validateRecord"]}