@powerhousedao/reactor-hypercore 6.2.3-dev.0 → 6.2.3-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../reactor/dist/drive-container-types-yZrksiJR.js","../src/hypercore-atomic-transaction.ts","../src/key-encoding.ts","../src/hypercore-operation-store.ts","../src/storage-manager.ts"],"sourcesContent":["import { n as ReactorEventTypes, t as EventBusAggregateError } from \"./types-DMKLa0Ok.js\";\nimport { AUTH_ACTION_TYPES, AUTH_DENIED_BY_GRANT_REASON, AUTH_NO_GRANT_REASON, AUTH_VERSION_UNSUPPORTED_REASON, DOCUMENT_DELETED_REASON, DowngradeNotSupportedError as DowngradeNotSupportedError$1, appendWithoutApplying, applyAuthAction, applyDeleteDocumentAction, applyDeleteDocumentAction as applyDeleteDocumentAction$1, applyUpgradeDocumentAction, applyUpgradeDocumentAction as applyUpgradeDocumentAction$1, baseReducerVersion, createPresignedHeader, decide, defaultBaseState, deriveOperationId, evaluate, garbageCollect, groupDocumentType, groupMembershipActionTypes, hashDocumentStateForScope, isDenied, isUndoRedo, mentionedGroupIds, normalizeDocumentModelVersion, referencedGroupIds, sortOperations } from \"@powerhousedao/shared/document-model\";\nimport { v4 } from \"uuid\";\nimport { Migrator, sql } from \"kysely\";\n//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\n//#region src/shared/utils.ts\nfunction matchesScope(view = {}, scope) {\n\tif (view.scopes) return view.scopes.includes(scope);\n\treturn true;\n}\nfunction yieldToMain() {\n\tconst s = globalThis.scheduler;\n\tif (s?.yield) return s.yield();\n\treturn new Promise((resolve) => setTimeout(resolve, 0));\n}\nconst defaultAbortError = () => /* @__PURE__ */ new Error(\"Operation aborted\");\nfunction throwIfAborted(signal, makeError = defaultAbortError) {\n\tif (signal?.aborted) throw makeError();\n}\n/**\n* Validates PagingOptions and returns a normalized offset and limit.\n* Throws if the cursor is not empty and not a non-negative integer, or if\n* limit is less than 1. When `paging` is undefined, returns offset 0 and\n* the caller-supplied `defaultLimit`.\n*/\nfunction parsePagingOptions(paging, defaultLimit) {\n\tif (paging === void 0) return {\n\t\toffset: 0,\n\t\tlimit: defaultLimit\n\t};\n\tif (!Number.isInteger(paging.limit) || paging.limit < 1) throw new Error(`Invalid paging limit: ${String(paging.limit)} (must be an integer >= 1)`);\n\tif (paging.cursor === \"\") return {\n\t\toffset: 0,\n\t\tlimit: paging.limit\n\t};\n\tconst parsed = Number(paging.cursor);\n\tif (!Number.isInteger(parsed) || parsed < 0) throw new Error(`Invalid paging cursor: ${JSON.stringify(paging.cursor)} (must be empty or a non-negative integer)`);\n\treturn {\n\t\toffset: parsed,\n\t\tlimit: paging.limit\n\t};\n}\n//#endregion\n//#region src/shared/errors.ts\n/**\n* Error thrown when attempting to access a deleted document.\n*/\nvar DocumentDeletedError = class DocumentDeletedError extends Error {\n\tdocumentId;\n\tdeletedAtUtcIso;\n\tconstructor(documentId, deletedAtUtcIso = null) {\n\t\tconst message = deletedAtUtcIso ? `Document ${documentId} was deleted at ${deletedAtUtcIso}` : `Document ${documentId} has been deleted`;\n\t\tsuper(message);\n\t\tthis.name = \"DocumentDeletedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.deletedAtUtcIso = deletedAtUtcIso;\n\t\tError.captureStackTrace(this, DocumentDeletedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentDeletedError\";\n\t}\n};\n/**\n* Error thrown when the auth policy denies an action at the executor gate.\n*/\nvar AuthorizationDeniedError = class AuthorizationDeniedError extends Error {\n\tdocumentId;\n\tscope;\n\toperation;\n\tsubject;\n\tconstructor(documentId, scope, operation, subject) {\n\t\tsuper(`Authorization denied: ${subject ?? \"anonymous\"} may not execute ${operation} in scope \"${scope}\" of document ${documentId}`);\n\t\tthis.name = \"AuthorizationDeniedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.operation = operation;\n\t\tthis.subject = subject;\n\t\tError.captureStackTrace(this, AuthorizationDeniedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthorizationDeniedError\";\n\t}\n};\n/**\n* An auth operation did not strictly exceed the newest timestamp in its stream.\n*\n* Terminal and asymmetric by design: no ordering rule can reconcile two replicas\n* that each accepted an auth operation offline, because either order hands one\n* authority the other never granted, so the replica ahead holds the arrival.\n*/\nvar AuthTimestampNotMonotonicError = class AuthTimestampNotMonotonicError extends Error {\n\tdocumentId;\n\tbranch;\n\ttimestampUtcMs;\n\tnewestTimestampUtcMs;\n\tconstructor(documentId, branch, timestampUtcMs, newestTimestampUtcMs) {\n\t\tsuper(`Auth timestamp not monotonic: ${timestampUtcMs} does not exceed ${newestTimestampUtcMs} in the auth stream of document ${documentId} on branch ${branch}`);\n\t\tthis.name = \"AuthTimestampNotMonotonicError\";\n\t\tthis.documentId = documentId;\n\t\tthis.branch = branch;\n\t\tthis.timestampUtcMs = timestampUtcMs;\n\t\tthis.newestTimestampUtcMs = newestTimestampUtcMs;\n\t\tError.captureStackTrace(this, AuthTimestampNotMonotonicError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthTimestampNotMonotonicError\";\n\t}\n};\n/**\n* An operation or action carried a timestamp that is not an ISO-8601 UTC\n* instant.\n*\n* Terminal rather than retryable: the value does not change between attempts,\n* so a retry re-runs the whole job to fail identically. Quarantining, unlike a\n* held auth operation — this is malformed data rather than two replicas\n* disagreeing, and nothing further from that source should be trusted until it\n* is looked at.\n*/\nvar InvalidOperationTimestampError = class InvalidOperationTimestampError extends Error {\n\tdocumentId;\n\tscope;\n\ttimestampUtcMs;\n\tconstructor(documentId, scope, timestampUtcMs, context) {\n\t\tsuper(`Invalid timestamp \"${timestampUtcMs}\" on ${context} in scope \"${scope}\" of document ${documentId}`);\n\t\tthis.name = \"InvalidOperationTimestampError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.timestampUtcMs = timestampUtcMs;\n\t\tError.captureStackTrace(this, InvalidOperationTimestampError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"InvalidOperationTimestampError\";\n\t}\n};\n/**\n* A load would move more operations than the bound allows, indicating a real\n* divergence between local and incoming history. Counts only first-time moves,\n* so a re-evaluation pass's re-appends do not make busy documents\n* revocation-proof. Terminal: the condition is deterministic.\n*/\nvar ExcessiveReshuffleError = class ExcessiveReshuffleError extends Error {\n\tdocumentId;\n\tscope;\n\tcount;\n\tthreshold;\n\tconstructor(documentId, scope, count, threshold) {\n\t\tsuper(`Excessive reshuffle detected: ${count} operations in scope \"${scope}\" of document ${documentId} exceeds the threshold of ${threshold}. This indicates a significant divergence between local and incoming operations.`);\n\t\tthis.name = \"ExcessiveReshuffleError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.count = count;\n\t\tthis.threshold = threshold;\n\t\tError.captureStackTrace(this, ExcessiveReshuffleError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"ExcessiveReshuffleError\";\n\t}\n};\n/**\n* Error thrown when an operation has an invalid signature.\n*/\nvar InvalidSignatureError = class InvalidSignatureError extends Error {\n\tdocumentId;\n\treason;\n\tconstructor(documentId, reason) {\n\t\tsuper(`Invalid signature in document ${documentId}: ${reason}`);\n\t\tthis.name = \"InvalidSignatureError\";\n\t\tthis.documentId = documentId;\n\t\tthis.reason = reason;\n\t\tError.captureStackTrace(this, InvalidSignatureError);\n\t}\n};\n/**\n* An UPGRADE_DOCUMENT action's preconditions (fromVersion and the per-scope\n* revision snapshot) did not match the document state the executor loaded.\n*\n* Terminal rather than retryable: the action carries the client's snapshot,\n* which stays stale no matter how often the job re-runs. The client is\n* expected to re-read the document and submit a fresh action instead.\n*/\nvar UpgradePreconditionFailedError = class UpgradePreconditionFailedError extends Error {\n\tdocumentId;\n\tdetail;\n\tconstructor(documentId, detail) {\n\t\tsuper(`Upgrade precondition failed for document ${documentId}: ${detail}`);\n\t\tthis.name = \"UpgradePreconditionFailedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.detail = detail;\n\t\tError.captureStackTrace(this, UpgradePreconditionFailedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"UpgradePreconditionFailedError\";\n\t}\n};\n/**\n* Error thrown when a document is not found (no operations exist for the document ID).\n*/\nvar DocumentNotFoundError = class DocumentNotFoundError extends Error {\n\tdocumentId;\n\t/**\n\t* @param message Overrides the default text. A handler that knows which of\n\t* several documents an action reads - a relationship's source, say - says so\n\t* here rather than rewrapping in a bare Error, which would strip the name the\n\t* executor classifies by.\n\t*/\n\tconstructor(documentId, message) {\n\t\tsuper(message ?? `Document ${documentId} not found`);\n\t\tthis.name = \"DocumentNotFoundError\";\n\t\tthis.documentId = documentId;\n\t\tError.captureStackTrace(this, DocumentNotFoundError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentNotFoundError\";\n\t}\n};\n/**\n* An authorization preflight was asked for while the reactor's decision model\n* is off, so there is no model to answer from.\n*\n* Thrown rather than answered from the legacy host-side permission tables. The\n* two systems do not compose: the tables record which addresses a host lets\n* near a drive, the policy records what a document's own grants permit, and an\n* answer stitched from both would report an admission verdict neither system\n* would reach. A caller that cannot get a prediction disables nothing, which\n* leaves the submit path -- and its real gate -- as the only authority.\n*\n* Detection is by `name`, not `instanceof`: the SharedWorker RPC boundary\n* rebuilds a thrown error from `{ name, message, stack, cause }` alone\n* (`reactor-browser/src/rpc/error-info.ts`), so the class identity and any\n* custom field are lost in transit. This error therefore carries no fields.\n*/\nvar AuthEnforcementDisabledError = class AuthEnforcementDisabledError extends Error {\n\tconstructor() {\n\t\tsuper(\"Authorization evaluation requires the authEnforcement feature flag; this reactor holds no decision model, and the legacy host-table permission system cannot answer for one\");\n\t\tthis.name = \"AuthEnforcementDisabledError\";\n\t\tError.captureStackTrace(this, AuthEnforcementDisabledError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthEnforcementDisabledError\";\n\t}\n};\n//#endregion\n//#region src/storage/interfaces.ts\n/**\n* Thrown when an operation with the same identity already exists in the store.\n*/\nvar DuplicateOperationError = class extends Error {\n\tconstructor(description) {\n\t\tsuper(`Duplicate operation: ${description}`);\n\t\tthis.name = \"DuplicateOperationError\";\n\t}\n};\n/**\n* Thrown when a concurrent write conflict is detected during an atomic apply.\n*/\nvar OptimisticLockError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"OptimisticLockError\";\n\t}\n};\n/**\n* Thrown when the caller-provided revision does not match the current\n* stored revision, indicating a stale read.\n*/\nvar RevisionMismatchError = class extends Error {\n\tconstructor(expected, actual) {\n\t\tsuper(`Revision mismatch: expected ${expected}, got ${actual}`);\n\t\tthis.name = \"RevisionMismatchError\";\n\t}\n};\n/**\n* A create based on an empty stream that already has operations: the id is\n* taken, and no retry can resolve it. Matched by `name`, all the RPC boundary keeps.\n*/\nvar DocumentAlreadyExistsError = class extends Error {\n\tdocumentId;\n\tconstructor(documentId, scope, headRevision) {\n\t\tsuper(`Document ${documentId} already exists: create requested revision 0 but the \"${scope}\" stream is at revision ${headRevision}`);\n\t\tthis.name = \"DocumentAlreadyExistsError\";\n\t\tthis.documentId = documentId;\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentAlreadyExistsError\";\n\t}\n};\n/** Error history keeps messages, not classes, so failures match by prefix. */\nconst APPEND_CONDITION_FAILED_PREFIX = \"Append condition failed: \";\n/**\n* A read-set stream grew before the append committed. A concurrency\n* conflict, not a fault: the caller retries against the new stream heads.\n*/\nvar AppendConditionFailedError = class extends Error {\n\tconstructor(condition) {\n\t\tconst streams = condition.streams.map((s) => `${s.documentId}:${s.scope}:${s.branch}@${s.revision}`).join(\", \");\n\t\tsuper(`${APPEND_CONDITION_FAILED_PREFIX}a read-set stream advanced [${streams}]`);\n\t\tthis.condition = condition;\n\t\tthis.name = \"AppendConditionFailedError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AppendConditionFailedError\";\n\t}\n\t/** True when a recorded error message is an append-condition failure. */\n\tstatic isFailureMessage(message) {\n\t\treturn message.startsWith(APPEND_CONDITION_FAILED_PREFIX);\n\t}\n};\n/**\n* Which sense of \"exists\" a caller of {@link IDocumentView.exists} means.\n*/\nlet DocumentExistence = /* @__PURE__ */ function(DocumentExistence) {\n\t/**\n\t* A document that is present and not deleted. This is the question a read\n\t* asks: a deleted document is not readable, so it does not exist.\n\t*/\n\tDocumentExistence[\"LiveOnly\"] = \"LiveOnly\";\n\t/**\n\t* Whether the id is taken, deleted or not. This is the question a write\n\t* asks: a deleted document keeps its operation stream, so its id can never\n\t* be reused, and answering from snapshots alone would say otherwise whenever\n\t* a snapshot row is missing while the stream is intact.\n\t*/\n\tDocumentExistence[\"IncludingDeleted\"] = \"IncludingDeleted\";\n\treturn DocumentExistence;\n}({});\n//#endregion\n//#region src/decision/build-decision-model.ts\n/**\n* Reads each projection's stream through the supplied reader, recording the\n* revision observed. Static projections resolve first; derived projections\n* see only those and contribute a map from document id to state. Each\n* distinct stream is read once and yields one append condition entry.\n*/\nasync function buildDecisionModel(reader, definition, target, signal) {\n\tconst decisionModel = definition(target);\n\tconst projections = Object.entries(decisionModel.projections);\n\tconst reads = /* @__PURE__ */ new Map();\n\tconst model = {};\n\tfor (const [key, projection] of projections) {\n\t\tif (typeof projection.query === \"function\") continue;\n\t\tmodel[key] = (await readStream(reader, projection.query, reads, signal)).state;\n\t}\n\tconst staticModel = { ...model };\n\tfor (const [key, projection] of projections) {\n\t\tif (typeof projection.query !== \"function\") continue;\n\t\tconst queries = projection.query(staticModel);\n\t\tconst value = {};\n\t\tfor (const query of queries) {\n\t\t\tlet read;\n\t\t\ttry {\n\t\t\t\tread = await readStream(reader, query, reads, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DocumentNotFoundError) {\n\t\t\t\t\trecordEmptyStream(query, reads);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tvalue[query.documentId] = read.state;\n\t\t}\n\t\tmodel[key] = value;\n\t}\n\treturn {\n\t\tmodel,\n\t\tappendCondition: { streams: [...reads.values()].map((read) => read.stream) }\n\t};\n}\n/** Guards a stream that holds nothing yet: any operation appearing is growth. */\nfunction recordEmptyStream(query, reads) {\n\tconst key = `${query.documentId}:${query.scope}:${query.branch}`;\n\tif (reads.has(key)) return;\n\treads.set(key, {\n\t\tstate: void 0,\n\t\tstream: {\n\t\t\tdocumentId: query.documentId,\n\t\t\tscope: query.scope,\n\t\t\tbranch: query.branch,\n\t\t\trevision: -1\n\t\t}\n\t});\n}\nasync function readStream(reader, query, reads, signal) {\n\tconst key = `${query.documentId}:${query.scope}:${query.branch}`;\n\tconst existing = reads.get(key);\n\tif (existing) return existing;\n\tconst document = await reader.getState(query.documentId, query.scope, query.branch, void 0, signal);\n\tconst read = {\n\t\tstate: document.state[query.scope],\n\t\tstream: {\n\t\t\tdocumentId: query.documentId,\n\t\t\tscope: query.scope,\n\t\t\tbranch: query.branch,\n\t\t\trevision: observedRevision(document, query.scope)\n\t\t}\n\t};\n\treads.set(key, read);\n\treturn read;\n}\n/**\n* The highest operation index the document reflects for the scope, or -1 if\n* empty. `header.revision` is authoritative, not the rebuilt operation list.\n*/\nfunction observedRevision(document, scope) {\n\tif (scope in document.header.revision) return document.header.revision[scope] - 1;\n\tif (scope in document.operations) {\n\t\tconst operations = document.operations[scope];\n\t\tif (operations.length > 0) return operations[operations.length - 1].index;\n\t}\n\tif (!(scope in document.header.revision)) return -1;\n\treturn document.header.revision[scope] - 1;\n}\n/**\n* The projections whose queries depend on folded state. A positional walk\n* resolves their streams through `queryOverHistory`; a projection without one\n* contributes no streams to a walk.\n*/\nfunction derivedReadSet(definition) {\n\tconst projections = [];\n\tfor (const [name, projection] of Object.entries(definition.projections)) {\n\t\tif (typeof projection.query !== \"function\") continue;\n\t\tprojections.push({\n\t\t\tname,\n\t\t\tdecidingActions: projection.decidingActions,\n\t\t\tapply: projection.apply,\n\t\t\tqueryOverHistory: projection.queryOverHistory\n\t\t});\n\t}\n\treturn projections;\n}\n/**\n* The streams a model reads whose queries are known before it is built. A\n* derived query needs the statically-queried projections first, so it is not\n* included here.\n*/\nfunction staticReadSet(definition) {\n\tconst streams = [];\n\tfor (const [name, projection] of Object.entries(definition.projections)) {\n\t\tif (typeof projection.query === \"function\") continue;\n\t\tstreams.push({\n\t\t\tname,\n\t\t\tquery: projection.query,\n\t\t\tdecidingActions: projection.decidingActions,\n\t\t\tapply: projection.apply\n\t\t});\n\t}\n\treturn streams;\n}\n//#endregion\n//#region src/decision/auth-decision-model.ts\nfunction refusalReason(refusal) {\n\tswitch (refusal) {\n\t\tcase \"version-unsupported\": return AUTH_VERSION_UNSUPPORTED_REASON;\n\t\tcase \"denied-by-grant\": return AUTH_DENIED_BY_GRANT_REASON;\n\t\tcase \"no-applicable-grant\": return AUTH_NO_GRANT_REASON;\n\t}\n}\nfunction decideAuthModel(model, subject, request, groups, conditions) {\n\tif (request.verb === \"execute\" && model.document.isDeleted) return {\n\t\tdecision: \"deny\",\n\t\treason: DOCUMENT_DELETED_REASON\n\t};\n\tconst evaluation = evaluate(model.auth, subject, request, groups, conditions);\n\tif (evaluation.decision === \"allow\") return { decision: \"allow\" };\n\treturn {\n\t\tdecision: \"deny\",\n\t\treason: refusalReason(evaluation.refusal)\n\t};\n}\nfunction documentProjection(target) {\n\treturn {\n\t\tdecidingActions: [\"DELETE_DOCUMENT\"],\n\t\tapply: (document, operation) => operation.action.type === \"DELETE_DOCUMENT\" ? applyDeleteDocumentAction({\n\t\t\t...document,\n\t\t\tstate: { ...document.state }\n\t\t}, operation.action) : document,\n\t\tquery: {\n\t\t\tdocumentId: target.documentId,\n\t\t\tbranch: target.branch,\n\t\t\tscope: \"document\"\n\t\t}\n\t};\n}\nfunction authProjection(target) {\n\treturn {\n\t\tdecidingActions: [...AUTH_ACTION_TYPES],\n\t\tapply: (document, operation) => applyAuthAction(document, operation.action),\n\t\tquery: {\n\t\t\tdocumentId: target.documentId,\n\t\t\tbranch: target.branch,\n\t\t\tscope: \"auth\"\n\t\t}\n\t};\n}\n/** This decision model uses both the document and the auth streams. */\nfunction authDecisionModel(target) {\n\treturn {\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target)\n\t\t},\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn decideAuthModel(model, subject, request);\n\t\t}\n\t};\n}\n/**\n* Folds one group-stream operation with the registered group model's reducer.\n* A reactor without the module registered folds nothing, so the member list\n* stays as read and a missing reducer never widens access.\n*/\nfunction applyGroupOperation(registry, document, operation) {\n\tlet reducer;\n\ttry {\n\t\treducer = registry.getModule(groupDocumentType).reducer;\n\t} catch {\n\t\treturn document;\n\t}\n\treturn reducer(document, operation.action);\n}\n/**\n* Folds one evaluated-scope operation with the reducer registered for the\n* document's own type, at the document's stamped version. A reactor without\n* that module folds nothing, so conditions read the base state and an\n* unresolvable reducer never widens access.\n*/\nfunction applyModelOperation(registry, document, operation) {\n\tlet reducer;\n\ttry {\n\t\tconst version = normalizeDocumentModelVersion(document.state.document?.version);\n\t\treducer = registry.getModule(document.header.documentType, version).reducer;\n\t} catch {\n\t\treturn document;\n\t}\n\treturn reducer(document, operation.action);\n}\n/**\n* The auth model extended with a derived groups projection: the streams it\n* reads are the group documents the folded grant list names, so adding a\n* grant that names a new group pulls that group's stream into the read-set.\n* Group queries pin the main branch, because a group's member list lives on\n* its main branch no matter which branch the referencing document is on.\n*/\nfunction groupsProjection(registry) {\n\treturn {\n\t\tdecidingActions: [...groupMembershipActionTypes],\n\t\tapply: (document, operation) => applyGroupOperation(registry, document, operation),\n\t\tquery: (model) => referencedGroupIds(model.auth?.grants ?? []).map((id) => ({\n\t\t\tdocumentId: id,\n\t\t\tbranch: \"main\",\n\t\t\tscope: \"global\"\n\t\t})),\n\t\tqueryOverHistory: (reads) => {\n\t\t\tconst ids = [];\n\t\t\tfor (const read of reads) {\n\t\t\t\tif (read.name !== \"auth\") continue;\n\t\t\t\tfor (const operation of read.operations) for (const id of mentionedGroupIds(operation.action)) if (!ids.includes(id)) ids.push(id);\n\t\t\t}\n\t\t\treturn ids.map((id) => ({\n\t\t\t\tdocumentId: id,\n\t\t\t\tbranch: \"main\",\n\t\t\t\tscope: \"global\"\n\t\t\t}));\n\t\t}\n\t};\n}\nfunction authGroupsDecisionModel(registry) {\n\treturn (target) => ({\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target),\n\t\t\tgroups: groupsProjection(registry)\n\t\t},\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn decideAuthModel(model, subject, request, model.groups);\n\t\t}\n\t});\n}\n/**\n* The groups model with conditions live: decide hands the executing scope's\n* state and the action input through to the evaluator, so `where` clauses\n* and { match } principals apply. The model folds the evaluated scope during\n* a positional walk, so a condition reads the state as it stood at each\n* operation's position.\n*/\nfunction authConditionsDecisionModel(registry) {\n\treturn (target) => ({\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target),\n\t\t\tgroups: groupsProjection(registry)\n\t\t},\n\t\tfoldEvaluatedScope: (document, operation) => applyModelOperation(registry, document, operation),\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request, ctx) {\n\t\t\treturn decideAuthModel(model, subject, request, model.groups, {\n\t\t\t\tscopeState: ctx.scopeState,\n\t\t\t\tactionInput: ctx.actionInput\n\t\t\t});\n\t\t}\n\t});\n}\n//#endregion\n//#region src/decision/document-decision-model.ts\n/**\n* The simplest decision model: one projection over the document scope, which\n* rejects on a deleted document.\n*/\nfunction documentDecisionModel(target) {\n\treturn {\n\t\tprojections: { document: {\n\t\t\tdecidingActions: [\"DELETE_DOCUMENT\"],\n\t\t\tapply: (document, operation) => operation.action.type === \"DELETE_DOCUMENT\" ? applyDeleteDocumentAction({\n\t\t\t\t...document,\n\t\t\t\tstate: { ...document.state }\n\t\t\t}, operation.action) : document,\n\t\t\tquery: {\n\t\t\t\tdocumentId: target.documentId,\n\t\t\t\tbranch: target.branch,\n\t\t\t\tscope: \"document\"\n\t\t\t}\n\t\t} },\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn request.verb === \"execute\" && model.document.isDeleted ? {\n\t\t\t\tdecision: \"deny\",\n\t\t\t\treason: DOCUMENT_DELETED_REASON\n\t\t\t} : { decision: \"allow\" };\n\t\t}\n\t};\n}\n//#endregion\n//#region src/decision/registered-model.ts\n/**\n* Builds the model at the stream heads and decides one request against it. The\n* append condition it returns is the read-set the store enforces at write time.\n*\n* With `conditions` supplied, the executing scope's state is read at the head\n* for `doc.<scope>.*` paths, or taken from the run's carried document when the\n* caller has already reduced earlier writes into it. That read carries no\n* append-condition entry of its own: the written stream's expected-revision\n* check already refuses a write whose scope grew between the read and the\n* append.\n*/\nasync function decideAtHead(model, cache, target, subject, request, signal, conditions) {\n\tconst built = await buildDecisionModel(cache, model, target, signal);\n\tlet scopeState;\n\tif (conditions !== void 0) scopeState = (conditions.carriedDocument ?? await cache.getState(target.documentId, request.scope, target.branch, void 0, signal)).state[request.scope];\n\treturn {\n\t\tevaluation: model(target).decide(built.model, subject, request, {\n\t\t\tscopeState,\n\t\t\tactionInput: conditions?.actionInput\n\t\t}),\n\t\tappendCondition: built.appendCondition,\n\t\tdocumentVersion: built.model.document.version,\n\t\tdeletedAtUtcIso: built.model.document.deletedAtUtcIso ?? null\n\t};\n}\n/**\n* The model this reactor enforces. With `authEnforcement` off the auth scope is\n* absent from every append condition and no load walks it; with `authGroups`\n* on, the group documents the grant list names join the read-set and the\n* registry supplies the reducer that folds them.\n*/\nfunction selectDecisionModel(flags, registry) {\n\tif (flags.authConditions) return authConditionsDecisionModel(registry);\n\tif (flags.authGroups) return authGroupsDecisionModel(registry);\n\treturn flags.authEnforcement ? authDecisionModel : documentDecisionModel;\n}\n//#endregion\n//#region src/executor/util.ts\n/** Actions the reactor reduces itself, onto the document scope. */\nconst DOCUMENT_SCOPE_ACTIONS = new Set([\n\t\"CREATE_DOCUMENT\",\n\t\"DELETE_DOCUMENT\",\n\t\"UPGRADE_DOCUMENT\",\n\t\"ADD_RELATIONSHIP\",\n\t\"REMOVE_RELATIONSHIP\",\n\t\"UPDATE_RELATIONSHIP\"\n]);\n/**\n* `CREATE_DOCUMENT` is exempt by necessity: it runs before the document exists,\n* so building a decision model would throw and defer the job forever.\n*/\nconst GATED_DOCUMENT_ACTIONS = new Set([...DOCUMENT_SCOPE_ACTIONS].filter((type) => type !== \"CREATE_DOCUMENT\"));\n/**\n* The document a document-scope action writes to, which is not always the job's\n* own document: delete and upgrade name it in `input.documentId`, and the\n* relationship actions in `input.sourceId`. `execute` only checks that a batch\n* shares one scope, so a caller can submit an action whose target is a document\n* other than the one the job is keyed by. The policy gate has to follow the\n* action rather than the job, or it decides against a policy the caller may\n* control instead of the one guarding the write.\n*/\nfunction targetDocumentId(action, fallback) {\n\tconst input = action.input;\n\tif (action.type === \"ADD_RELATIONSHIP\" || action.type === \"REMOVE_RELATIONSHIP\" || action.type === \"UPDATE_RELATIONSHIP\") return typeof input?.sourceId === \"string\" && input.sourceId.length > 0 ? input.sourceId : fallback;\n\treturn typeof input?.documentId === \"string\" && input.documentId.length > 0 ? input.documentId : fallback;\n}\n/**\n* Creates a PHDocument from a CREATE_DOCUMENT action input.\n* Reconstructs the document header and initializes the base state.\n*\n* @param action - The CREATE_DOCUMENT action containing the document parameters\n* @returns A newly constructed PHDocument with initialized header and base state\n*/\nfunction createDocumentFromAction(action) {\n\tconst input = action.input;\n\tconst header = createPresignedHeader();\n\theader.id = input.documentId;\n\theader.documentType = input.model;\n\tif (input.signing) {\n\t\theader.createdAtUtcIso = input.signing.createdAtUtcIso;\n\t\theader.lastModifiedAtUtcIso = input.signing.createdAtUtcIso;\n\t\theader.sig = {\n\t\t\tpublicKey: input.signing.publicKey,\n\t\t\tnonce: input.signing.nonce\n\t\t};\n\t}\n\tif (input.slug !== void 0) header.slug = input.slug;\n\tif (!header.slug) header.slug = input.documentId;\n\tif (input.name !== void 0) header.name = input.name;\n\tif (input.branch !== void 0) header.branch = input.branch;\n\tif (input.meta !== void 0) header.meta = input.meta;\n\tif (input.protocolVersions !== void 0) header.protocolVersions = input.protocolVersions;\n\tconst baseState = defaultBaseState();\n\treturn {\n\t\theader,\n\t\toperations: {},\n\t\tstate: baseState,\n\t\tinitialState: baseState,\n\t\tclipboard: []\n\t};\n}\n/**\n* Calculate the next operation index for a specific scope.\n* Each scope maintains its own independent index sequence.\n*\n* Per-scope indexing means:\n* - Each scope (document, global, local, etc.) has independent indexes\n* - Indexes start at 0 for each scope\n* - Different scopes can have operations with the same index value\n*\n* This function uses header.revision which is populated by the cache/storage layer\n* and contains the next available index for each scope. This design avoids requiring\n* the full operation history to be loaded, which is crucial for snapshot-based caching.\n*\n* @param document - The document whose header.revision to inspect\n* @param scope - The scope to calculate the next index for\n* @returns The next available index in the specified scope\n*/\nconst getNextIndexForScope = (document, scope) => {\n\treturn document.header.revision[scope] || 0;\n};\n/**\n* Creates an empty consistency token with no coordinates.\n* Used when a job is registered or fails without writing operations.\n*\n* @returns A consistency token with an empty coordinates array\n*/\nfunction createEmptyConsistencyToken() {\n\treturn {\n\t\tversion: 1,\n\t\tcreatedAtUtcIso: (/* @__PURE__ */ new Date()).toISOString(),\n\t\tcoordinates: []\n\t};\n}\n/**\n* Creates a consistency token from operations written during job execution.\n* Maps each operation to a consistency coordinate tracking (documentId, scope, branch, operationIndex).\n* If no operations are provided, returns an empty token.\n*\n* @param operationsWithContext - Array of operations with their execution context\n* @returns A consistency token representing all operations written\n*/\nfunction createConsistencyToken(operationsWithContext) {\n\tif (operationsWithContext.length === 0) return createEmptyConsistencyToken();\n\tconst coordinates = [];\n\tfor (let i = 0; i < operationsWithContext.length; i++) {\n\t\tconst opWithContext = operationsWithContext[i];\n\t\tcoordinates.push({\n\t\t\tdocumentId: opWithContext.context.documentId,\n\t\t\tscope: opWithContext.context.scope,\n\t\t\tbranch: opWithContext.context.branch,\n\t\t\toperationIndex: opWithContext.operation.index\n\t\t});\n\t}\n\treturn {\n\t\tversion: 1,\n\t\tcreatedAtUtcIso: (/* @__PURE__ */ new Date()).toISOString(),\n\t\tcoordinates\n\t};\n}\nfunction createOperation(action, index, skip, context) {\n\treturn {\n\t\tid: deriveOperationId(context.documentId, context.scope, context.branch, action.id),\n\t\tindex,\n\t\ttimestampUtcMs: action.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString(),\n\t\thash: \"\",\n\t\tskip,\n\t\taction\n\t};\n}\nfunction updateDocumentRevision(document, scope, operationIndex) {\n\tdocument.header.revision = {\n\t\t...document.header.revision,\n\t\t[scope]: operationIndex + 1\n\t};\n}\nfunction buildSuccessResult(job, operation, documentId, documentType, resultingState, startTime) {\n\treturn {\n\t\tjob,\n\t\tsuccess: true,\n\t\toperations: [operation],\n\t\toperationsWithContext: [{\n\t\t\toperation,\n\t\t\tcontext: {\n\t\t\t\tdocumentId,\n\t\t\t\tscope: job.scope,\n\t\t\t\tbranch: job.branch,\n\t\t\t\tdocumentType,\n\t\t\t\tresultingState,\n\t\t\t\tordinal: 0\n\t\t\t}\n\t\t}],\n\t\tduration: Date.now() - startTime\n\t};\n}\nfunction buildErrorResult(job, error, startTime) {\n\treturn {\n\t\tjob,\n\t\tsuccess: false,\n\t\terror,\n\t\tduration: Date.now() - startTime\n\t};\n}\n/**\n* The error a refusal surfaces as. Both classes are already terminal in the job\n* result handler, so a refusal never burns a retry.\n*/\nfunction refusalError(reason, documentId, deletedAtUtcIso, action) {\n\tif (reason === DOCUMENT_DELETED_REASON) return new DocumentDeletedError(documentId, deletedAtUtcIso);\n\treturn new AuthorizationDeniedError(documentId, action.scope, action.type, action.context?.signer?.user.address);\n}\n/**\n* Whether this operation is part of the document's creation. The create and the\n* upgrade from version zero hold the first two indexes for the life of the\n* document, so a reshuffle has to leave them where they are.\n*/\nfunction isGenesisOperation(operation) {\n\tif (operation.action.type === \"CREATE_DOCUMENT\") return true;\n\tif (operation.action.type !== \"UPGRADE_DOCUMENT\") return false;\n\treturn operation.action.input.fromVersion === 0;\n}\n/**\n* The distinct streams a job wrote, collected so a rollback knows what to evict.\n*\n* A write records its stream on every apply, and a long run applies the same\n* stream hundreds of times, so this keeps one entry per stream rather than one\n* per write: the eviction only cares which streams were touched, and the\n* successful jobs that never read this back pay for a lookup instead of an\n* allocation.\n*/\nvar TouchedStreams = class {\n\tstreams = /* @__PURE__ */ new Map();\n\tadd(documentId, scope, branch) {\n\t\tconst key = `${documentId}\\u0000${scope}\\u0000${branch}`;\n\t\tif (this.streams.has(key)) return;\n\t\tthis.streams.set(key, {\n\t\t\tdocumentId,\n\t\t\tscope,\n\t\t\tbranch\n\t\t});\n\t}\n\t[Symbol.iterator]() {\n\t\treturn this.streams.values();\n\t}\n};\n//#endregion\n//#region src/registry/errors.ts\n/**\n* Error thrown when a document model module is not found in the registry.\n*/\nvar ModuleNotFoundError = class extends Error {\n\tdocumentType;\n\trequestedVersion;\n\tconstructor(documentType, version) {\n\t\tconst versionSuffix = version !== void 0 ? ` version ${version}` : \"\";\n\t\tsuper(`Document model module not found for type: ${documentType}${versionSuffix}`);\n\t\tthis.name = \"ModuleNotFoundError\";\n\t\tthis.documentType = documentType;\n\t\tthis.requestedVersion = version;\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"ModuleNotFoundError\";\n\t}\n};\n/**\n* Error thrown when attempting to register a module that already exists.\n*/\nvar DuplicateModuleError = class extends Error {\n\tconstructor(documentType, version) {\n\t\tconst versionSuffix = version !== void 0 ? ` (version ${version})` : \"\";\n\t\tsuper(`Document model module already registered for type: ${documentType}${versionSuffix}`);\n\t\tthis.name = \"DuplicateModuleError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DuplicateModuleError\";\n\t}\n};\n/**\n* Error thrown when a module is invalid or malformed.\n*/\nvar InvalidModuleError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(`Invalid document model module: ${message}`);\n\t\tthis.name = \"InvalidModuleError\";\n\t}\n};\n/**\n* Error thrown when attempting to register an upgrade manifest that already exists.\n*/\nvar DuplicateManifestError = class extends Error {\n\tconstructor(documentType) {\n\t\tsuper(`Upgrade manifest already registered for type: ${documentType}`);\n\t\tthis.name = \"DuplicateManifestError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DuplicateManifestError\";\n\t}\n};\n/**\n* Error thrown when an upgrade manifest is not found.\n*/\nvar ManifestNotFoundError = class extends Error {\n\tconstructor(documentType) {\n\t\tsuper(`Upgrade manifest not found for type: ${documentType}`);\n\t\tthis.name = \"ManifestNotFoundError\";\n\t}\n};\n/**\n* Error thrown when a required upgrade transition is missing from the manifest.\n*/\nvar MissingUpgradeTransitionError = class extends Error {\n\tconstructor(documentType, fromVersion, toVersion) {\n\t\tsuper(`Missing upgrade transition for ${documentType}: v${fromVersion} to v${toVersion}`);\n\t\tthis.name = \"MissingUpgradeTransitionError\";\n\t}\n};\n/**\n* Error thrown when getUpgradeReducer is called with a non-single-step version increment.\n*/\nvar InvalidUpgradeStepError = class extends Error {\n\tconstructor(documentType, fromVersion, toVersion) {\n\t\tsuper(`Invalid upgrade step for ${documentType}: must be single version increment, got v${fromVersion} to v${toVersion}`);\n\t\tthis.name = \"InvalidUpgradeStepError\";\n\t}\n};\n//#endregion\n//#region src/executor/types.ts\n/** How long a deferred job waits for its document before it fails. */\nconst DEFAULT_DEFERRED_JOB_TTL_MS = 3e4;\n/**\n* Event types for the job executor\n*/\nconst JobExecutorEventTypes = {\n\tJOB_STARTED: 2e4,\n\tJOB_COMPLETED: 20001,\n\tJOB_FAILED: 20002,\n\tEXECUTOR_STARTED: 20003,\n\tEXECUTOR_STOPPED: 20004\n};\n//#endregion\n//#region src/cache/collection-membership-cache.ts\nvar CollectionMembershipCache = class CollectionMembershipCache {\n\tcache = /* @__PURE__ */ new Map();\n\tconstructor(operationIndex) {\n\t\tthis.operationIndex = operationIndex;\n\t}\n\twithScopedIndex(operationIndex) {\n\t\tconst scoped = new CollectionMembershipCache(operationIndex);\n\t\tscoped.cache = this.cache;\n\t\treturn scoped;\n\t}\n\tasync getCollectionsForDocuments(documentIds) {\n\t\tconst result = {};\n\t\tconst missing = [];\n\t\tfor (const docId of documentIds) {\n\t\t\tconst cached = this.cache.get(docId);\n\t\t\tif (cached !== void 0) result[docId] = cached;\n\t\t\telse missing.push(docId);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tconst fromDb = await this.operationIndex.getCollectionsForDocuments(missing);\n\t\t\tfor (const docId of missing) {\n\t\t\t\tconst collections = fromDb[docId] ?? [];\n\t\t\t\tresult[docId] = collections;\n\t\t\t\tthis.cache.set(docId, collections);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\tinvalidate(documentId) {\n\t\tthis.cache.delete(documentId);\n\t}\n};\n//#endregion\n//#region src/cache/lru/lru-tracker.ts\nvar LRUNode = class {\n\tkey;\n\tprev;\n\tnext;\n\tconstructor(key) {\n\t\tthis.key = key;\n\t\tthis.prev = void 0;\n\t\tthis.next = void 0;\n\t}\n};\nvar LRUTracker = class {\n\tmap;\n\thead;\n\ttail;\n\tconstructor() {\n\t\tthis.map = /* @__PURE__ */ new Map();\n\t\tthis.head = void 0;\n\t\tthis.tail = void 0;\n\t}\n\tget size() {\n\t\treturn this.map.size;\n\t}\n\ttouch(key) {\n\t\tconst node = this.map.get(key);\n\t\tif (node) this.moveToFront(node);\n\t\telse this.addToFront(key);\n\t}\n\tevict() {\n\t\tif (!this.tail) return;\n\t\tconst key = this.tail.key;\n\t\tthis.remove(key);\n\t\treturn key;\n\t}\n\tremove(key) {\n\t\tconst node = this.map.get(key);\n\t\tif (!node) return;\n\t\tthis.removeNode(node);\n\t\tthis.map.delete(key);\n\t}\n\tclear() {\n\t\tthis.map.clear();\n\t\tthis.head = void 0;\n\t\tthis.tail = void 0;\n\t}\n\taddToFront(key) {\n\t\tconst node = new LRUNode(key);\n\t\tthis.map.set(key, node);\n\t\tif (!this.head) {\n\t\t\tthis.head = node;\n\t\t\tthis.tail = node;\n\t\t} else {\n\t\t\tnode.next = this.head;\n\t\t\tthis.head.prev = node;\n\t\t\tthis.head = node;\n\t\t}\n\t}\n\tmoveToFront(node) {\n\t\tif (node === this.head) return;\n\t\tthis.removeNode(node);\n\t\tnode.prev = void 0;\n\t\tnode.next = this.head;\n\t\tif (this.head) this.head.prev = node;\n\t\tthis.head = node;\n\t\tif (!this.tail) this.tail = node;\n\t}\n\tremoveNode(node) {\n\t\tif (node.prev) node.prev.next = node.next;\n\t\telse this.head = node.next;\n\t\tif (node.next) node.next.prev = node.prev;\n\t\telse this.tail = node.prev;\n\t}\n};\n//#endregion\n//#region src/cache/document-meta-cache.ts\n/**\n* In-memory document metadata cache with LRU eviction.\n*\n* Caches PHDocumentState per (documentId, branch) key. On cache miss,\n* rebuilds from document scope operations. Provides an explicit cross-scope\n* contract for accessing document scope metadata.\n*\n* **Thread Safety:**\n* Not thread-safe. Designed for single-threaded job executor environment.\n*/\nvar DocumentMetaCache = class DocumentMetaCache {\n\tcache;\n\tlruTracker;\n\toperationStore;\n\tconfig;\n\tconstructor(operationStore, config) {\n\t\tthis.operationStore = operationStore;\n\t\tthis.config = { maxDocuments: config.maxDocuments };\n\t\tthis.cache = /* @__PURE__ */ new Map();\n\t\tthis.lruTracker = new LRUTracker();\n\t}\n\twithScopedStore(operationStore) {\n\t\tconst scoped = new DocumentMetaCache(operationStore, this.config);\n\t\tscoped.cache = this.cache;\n\t\tscoped.lruTracker = this.lruTracker;\n\t\treturn scoped;\n\t}\n\tasync startup() {\n\t\treturn Promise.resolve();\n\t}\n\tasync shutdown() {\n\t\treturn Promise.resolve();\n\t}\n\tasync getDocumentMeta(documentId, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst key = this.makeKey(documentId, branch);\n\t\tconst cached = this.cache.get(key);\n\t\tif (cached) {\n\t\t\tthis.lruTracker.touch(key);\n\t\t\treturn cached;\n\t\t}\n\t\tconst meta = await this.rebuildLatest(documentId, branch, signal);\n\t\tthis.putDocumentMeta(documentId, branch, meta);\n\t\treturn meta;\n\t}\n\tasync rebuildAtRevision(documentId, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn this.rebuildFromOperations(documentId, branch, targetRevision, signal);\n\t}\n\tputDocumentMeta(documentId, branch, meta) {\n\t\tconst key = this.makeKey(documentId, branch);\n\t\tif (!this.cache.has(key) && this.cache.size >= this.config.maxDocuments) {\n\t\t\tconst evictKey = this.lruTracker.evict();\n\t\t\tif (evictKey) this.cache.delete(evictKey);\n\t\t}\n\t\tthis.cache.set(key, structuredClone(meta));\n\t\tthis.lruTracker.touch(key);\n\t}\n\tinvalidate(documentId, branch) {\n\t\tlet evicted = 0;\n\t\tif (branch === void 0) {\n\t\t\tfor (const key of this.cache.keys()) if (key.startsWith(`${documentId}:`)) {\n\t\t\t\tthis.cache.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else {\n\t\t\tconst key = this.makeKey(documentId, branch);\n\t\t\tif (this.cache.has(key)) {\n\t\t\t\tthis.cache.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted = 1;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n\tclear() {\n\t\tthis.cache.clear();\n\t\tthis.lruTracker.clear();\n\t}\n\tmakeKey(documentId, branch) {\n\t\treturn `${documentId}:${branch}`;\n\t}\n\tasync rebuildLatest(documentId, branch, signal) {\n\t\treturn this.rebuildFromOperations(documentId, branch, void 0, signal);\n\t}\n\tasync rebuildFromOperations(documentId, branch, targetRevision, signal) {\n\t\tconst docScopeOps = await this.operationStore.getSince(documentId, \"document\", branch, -1, void 0, void 0, signal);\n\t\tif (docScopeOps.results.length === 0) throw new DocumentNotFoundError(documentId);\n\t\tconst createOp = docScopeOps.results[0];\n\t\tif (createOp.action.type !== \"CREATE_DOCUMENT\") throw new Error(`Invalid document: first operation must be CREATE_DOCUMENT, found ${createOp.action.type}`);\n\t\tconst createAction = createOp.action;\n\t\tconst documentType = createAction.input.model;\n\t\tlet document = createDocumentFromAction(createAction);\n\t\tlet documentScopeRevision = 0;\n\t\tfor (const op of docScopeOps.results) {\n\t\t\tif (targetRevision !== void 0 && op.index > targetRevision) break;\n\t\t\tdocumentScopeRevision = op.index;\n\t\t\tif (op.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\tconst upgradeAction = op.action;\n\t\t\t\tdocument = applyUpgradeDocumentAction$1(document, upgradeAction);\n\t\t\t} else if (op.action.type === \"DELETE_DOCUMENT\") document = applyDeleteDocumentAction$1(document, op.action);\n\t\t}\n\t\treturn {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType,\n\t\t\tdocumentScopeRevision: documentScopeRevision + 1\n\t\t};\n\t}\n};\nvar KyselyOperationIndexTxn = class {\n\tcollections = [];\n\tcollectionMemberships = [];\n\tcollectionRemovals = [];\n\tgroupReferences = [];\n\toperations = [];\n\tmembershipInvalidations = /* @__PURE__ */ new Set();\n\t/** Called by the commit as it writes each document_collections row. */\n\trecordMembershipInvalidation(documentId) {\n\t\tthis.membershipInvalidations.add(documentId);\n\t}\n\tgetMembershipInvalidations() {\n\t\treturn [...this.membershipInvalidations];\n\t}\n\tcreateCollection(collectionId) {\n\t\tthis.collections.push(collectionId);\n\t}\n\taddToCollection(collectionId, documentId) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"addToCollection must be called after write() - no operations in transaction\");\n\t\tthis.collectionMemberships.push({\n\t\t\tcollectionId,\n\t\t\tdocumentId,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\tremoveFromCollection(collectionId, documentId) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"removeFromCollection must be called after write() - no operations in transaction\");\n\t\tthis.collectionRemovals.push({\n\t\t\tcollectionId,\n\t\t\tdocumentId,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\trecordGroupReferences(documentId, groupIds) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"recordGroupReferences must be called after write() - no operations in transaction\");\n\t\tif (groupIds.length === 0) return;\n\t\tthis.groupReferences.push({\n\t\t\tdocumentId,\n\t\t\tgroupIds,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\twrite(operations) {\n\t\tthis.operations.push(...operations);\n\t}\n\tgetCollections() {\n\t\treturn this.collections;\n\t}\n\tgetGroupReferenceRecords() {\n\t\treturn this.groupReferences;\n\t}\n\tgetCollectionMembershipRecords() {\n\t\treturn this.collectionMemberships;\n\t}\n\tgetCollectionRemovals() {\n\t\treturn this.collectionRemovals;\n\t}\n\tgetOperations() {\n\t\treturn this.operations;\n\t}\n};\nvar KyselyOperationIndex = class KyselyOperationIndex {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyOperationIndex(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tstart() {\n\t\treturn new KyselyOperationIndexTxn();\n\t}\n\tasync commit(txn, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst kyselyTxn = txn;\n\t\tif (this.trx) return this.executeCommit(this.trx, kyselyTxn);\n\t\tlet resultOrdinals = [];\n\t\tawait this.db.transaction().execute(async (trx) => {\n\t\t\tresultOrdinals = await this.executeCommit(trx, kyselyTxn);\n\t\t});\n\t\treturn resultOrdinals;\n\t}\n\t/**\n\t* A policy-driven join: keeps the earliest join so a rediscovered reference\n\t* never shrinks a backfill window remotes already rely on, and reopens a\n\t* closed membership because a policy reference is not a removable one.\n\t*/\n\tasync joinKeepingEarliest(trx, kyselyTxn, documentId, collectionId, ordinal) {\n\t\tkyselyTxn.recordMembershipInvalidation(documentId);\n\t\tawait trx.insertInto(\"document_collections\").values({\n\t\t\tdocumentId,\n\t\t\tcollectionId,\n\t\t\tjoinedOrdinal: ordinal,\n\t\t\tleftOrdinal: null\n\t\t}).onConflict((oc) => oc.columns([\"documentId\", \"collectionId\"]).doUpdateSet({\n\t\t\tjoinedOrdinal: sql`LEAST(\"document_collections\".\"joinedOrdinal\", EXCLUDED.\"joinedOrdinal\")`,\n\t\t\tleftOrdinal: null\n\t\t})).execute();\n\t}\n\tasync executeCommit(trx, kyselyTxn) {\n\t\tconst collections = kyselyTxn.getCollections();\n\t\tconst memberships = kyselyTxn.getCollectionMembershipRecords();\n\t\tconst removals = kyselyTxn.getCollectionRemovals();\n\t\tconst groupReferences = kyselyTxn.getGroupReferenceRecords();\n\t\tconst operations = kyselyTxn.getOperations();\n\t\tif (collections.length > 0) {\n\t\t\tconst collectionRows = collections.map((collectionId) => ({\n\t\t\t\tdocumentId: collectionId,\n\t\t\t\tcollectionId,\n\t\t\t\tjoinedOrdinal: BigInt(0),\n\t\t\t\tleftOrdinal: null\n\t\t\t}));\n\t\t\tfor (const collectionId of collections) kyselyTxn.recordMembershipInvalidation(collectionId);\n\t\t\tawait trx.insertInto(\"document_collections\").values(collectionRows).onConflict((oc) => oc.doNothing()).execute();\n\t\t}\n\t\tlet operationOrdinals = [];\n\t\tif (operations.length > 0) {\n\t\t\tconst operationRows = operations.map((op) => ({\n\t\t\t\topId: op.id || \"\",\n\t\t\t\tdocumentId: op.documentId,\n\t\t\t\tdocumentType: op.documentType,\n\t\t\t\tscope: op.scope,\n\t\t\t\tbranch: op.branch,\n\t\t\t\ttimestampUtcMs: op.timestampUtcMs,\n\t\t\t\tindex: op.index,\n\t\t\t\tskip: op.skip,\n\t\t\t\thash: op.hash,\n\t\t\t\taction: op.action,\n\t\t\t\tdeniedReason: op.deniedReason ?? null,\n\t\t\t\tsourceRemote: op.sourceRemote\n\t\t\t}));\n\t\t\toperationOrdinals = (await trx.insertInto(\"operation_index_operations\").values(operationRows).returning(\"ordinal\").execute()).map((row) => row.ordinal);\n\t\t}\n\t\tif (memberships.length > 0) for (const m of memberships) {\n\t\t\tconst ordinal = operationOrdinals[m.operationIndex];\n\t\t\tkyselyTxn.recordMembershipInvalidation(m.documentId);\n\t\t\tawait trx.insertInto(\"document_collections\").values({\n\t\t\t\tdocumentId: m.documentId,\n\t\t\t\tcollectionId: m.collectionId,\n\t\t\t\tjoinedOrdinal: BigInt(ordinal),\n\t\t\t\tleftOrdinal: null\n\t\t\t}).onConflict((oc) => oc.columns([\"documentId\", \"collectionId\"]).doUpdateSet({\n\t\t\t\tjoinedOrdinal: BigInt(ordinal),\n\t\t\t\tleftOrdinal: null\n\t\t\t})).execute();\n\t\t\tconst references = await trx.selectFrom(\"group_references\").select(\"groupId\").where(\"documentId\", \"=\", m.documentId).execute();\n\t\t\tfor (const { groupId } of references) await this.joinKeepingEarliest(trx, kyselyTxn, groupId, m.collectionId, BigInt(ordinal));\n\t\t}\n\t\tif (removals.length > 0) for (const r of removals) {\n\t\t\tconst ordinal = operationOrdinals[r.operationIndex];\n\t\t\tkyselyTxn.recordMembershipInvalidation(r.documentId);\n\t\t\tawait trx.updateTable(\"document_collections\").set({ leftOrdinal: BigInt(ordinal) }).where(\"collectionId\", \"=\", r.collectionId).where(\"documentId\", \"=\", r.documentId).where(\"leftOrdinal\", \"is\", null).execute();\n\t\t}\n\t\tif (groupReferences.length > 0) for (const record of groupReferences) {\n\t\t\tconst ordinal = operationOrdinals[record.operationIndex];\n\t\t\tawait trx.insertInto(\"group_references\").values(record.groupIds.map((groupId) => ({\n\t\t\t\tdocumentId: record.documentId,\n\t\t\t\tgroupId\n\t\t\t}))).onConflict((oc) => oc.doNothing()).execute();\n\t\t\tconst rows = await trx.selectFrom(\"document_collections\").select(\"collectionId\").where(\"documentId\", \"=\", record.documentId).execute();\n\t\t\tfor (const groupId of record.groupIds) for (const { collectionId } of rows) await this.joinKeepingEarliest(trx, kyselyTxn, groupId, collectionId, BigInt(ordinal));\n\t\t}\n\t\treturn operationOrdinals;\n\t}\n\tasync getGroupReferencers(groupId, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn (await this.queryExecutor.selectFrom(\"group_references\").select(\"documentId\").where(\"groupId\", \"=\", groupId).orderBy(\"documentId\").execute()).map((row) => row.documentId);\n\t}\n\tasync find(collectionId, cursor, view, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst outerCursor = cursor ?? -1;\n\t\tconst limit = paging?.limit ?? 500;\n\t\tconst pagingCursorOrdinal = paging?.cursor !== void 0 ? Number.parseInt(paging.cursor, 10) : -1;\n\t\tconst buildBranch = (kind) => {\n\t\t\tlet qb = this.queryExecutor.selectFrom(\"operation_index_operations as oi\").innerJoin(\"document_collections as dc\", \"oi.documentId\", \"dc.documentId\").selectAll(\"oi\").select([\"dc.documentId\", \"dc.collectionId\"]).where(\"dc.collectionId\", \"=\", collectionId).where(sql`(dc.\"leftOrdinal\" IS NULL OR oi.ordinal < dc.\"leftOrdinal\")`);\n\t\t\tif (kind === \"joiner\") qb = qb.where(\"dc.joinedOrdinal\", \">\", BigInt(outerCursor)).where(\"oi.ordinal\", \"<=\", outerCursor);\n\t\t\telse qb = qb.where(\"oi.ordinal\", \">\", outerCursor);\n\t\t\tqb = qb.where(\"oi.ordinal\", \">\", pagingCursorOrdinal);\n\t\t\tif (view?.branch) qb = qb.where(\"oi.branch\", \"=\", view.branch);\n\t\t\tif (view?.scopes && view.scopes.length > 0) qb = qb.where(\"oi.scope\", \"in\", view.scopes);\n\t\t\tif (view?.excludeSourceRemote) qb = qb.where(\"oi.sourceRemote\", \"!=\", view.excludeSourceRemote);\n\t\t\treturn qb;\n\t\t};\n\t\tconst rows = await buildBranch(\"joiner\").unionAll(buildBranch(\"newOps\")).orderBy(\"ordinal\", \"asc\").limit(limit + 1).execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationIndexEntry(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.find(collectionId, cursor, view, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\tasync get(documentId, view, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst limit = paging?.limit ?? 500;\n\t\tlet query = this.queryExecutor.selectFrom(\"operation_index_operations\").selectAll().where(\"documentId\", \"=\", documentId).orderBy(\"ordinal\", \"asc\");\n\t\tif (view?.branch) query = query.where(\"branch\", \"=\", view.branch);\n\t\tif (view?.scopes && view.scopes.length > 0) query = query.where(\"scope\", \"in\", view.scopes);\n\t\tif (paging?.cursor) {\n\t\t\tconst cursorOrdinal = Number.parseInt(paging.cursor, 10);\n\t\t\tquery = query.where(\"ordinal\", \">\", cursorOrdinal);\n\t\t}\n\t\tquery = query.limit(limit + 1);\n\t\tconst rows = await query.execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationIndexEntry(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.get(documentId, view, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\tasync getSinceOrdinal(ordinal, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst limit = paging?.limit ?? 500;\n\t\tlet query = this.queryExecutor.selectFrom(\"operation_index_operations\").selectAll().where(\"ordinal\", \">\", ordinal).orderBy(\"ordinal\", \"asc\");\n\t\tif (paging?.cursor) {\n\t\t\tconst cursorOrdinal = Number.parseInt(paging.cursor, 10);\n\t\t\tquery = query.where(\"ordinal\", \">\", cursorOrdinal);\n\t\t}\n\t\tquery = query.limit(limit + 1);\n\t\tconst rows = await query.execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationWithContext(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.getSinceOrdinal(ordinal, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\trowToOperationWithContext(row) {\n\t\treturn {\n\t\t\toperation: {\n\t\t\t\tindex: row.index,\n\t\t\t\ttimestampUtcMs: row.timestampUtcMs,\n\t\t\t\thash: row.hash,\n\t\t\t\tskip: row.skip,\n\t\t\t\taction: row.action,\n\t\t\t\tdeniedReason: row.deniedReason ?? void 0,\n\t\t\t\tid: row.opId\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tdocumentId: row.documentId,\n\t\t\t\tdocumentType: row.documentType,\n\t\t\t\tscope: row.scope,\n\t\t\t\tbranch: row.branch,\n\t\t\t\tordinal: row.ordinal\n\t\t\t}\n\t\t};\n\t}\n\trowToOperationIndexEntry(row) {\n\t\treturn {\n\t\t\tordinal: row.ordinal,\n\t\t\tdocumentId: row.documentId,\n\t\t\tdocumentType: row.documentType,\n\t\t\tbranch: row.branch,\n\t\t\tscope: row.scope,\n\t\t\tindex: row.index,\n\t\t\ttimestampUtcMs: row.timestampUtcMs,\n\t\t\thash: row.hash,\n\t\t\tskip: row.skip,\n\t\t\taction: row.action,\n\t\t\tdeniedReason: row.deniedReason ?? void 0,\n\t\t\tid: row.opId,\n\t\t\tsourceRemote: row.sourceRemote\n\t\t};\n\t}\n\tasync getLatestTimestampForCollection(collectionId, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn (await this.queryExecutor.selectFrom(\"operation_index_operations as oi\").innerJoin(\"document_collections as dc\", \"oi.documentId\", \"dc.documentId\").select(\"oi.timestampUtcMs\").where(\"dc.collectionId\", \"=\", collectionId).where(sql`(dc.\"leftOrdinal\" IS NULL OR oi.ordinal < dc.\"leftOrdinal\")`).orderBy(\"oi.ordinal\", \"desc\").limit(1).executeTakeFirst())?.timestampUtcMs ?? null;\n\t}\n\tasync getCollectionsForDocuments(documentIds) {\n\t\tif (documentIds.length === 0) return {};\n\t\tconst rows = await this.queryExecutor.selectFrom(\"document_collections\").select([\"documentId\", \"collectionId\"]).where(\"documentId\", \"in\", documentIds).where(\"leftOrdinal\", \"is\", null).execute();\n\t\tconst result = {};\n\t\tfor (const row of rows) {\n\t\t\tif (!(row.documentId in result)) result[row.documentId] = [];\n\t\t\tresult[row.documentId].push(row.collectionId);\n\t\t}\n\t\treturn result;\n\t}\n};\n//#endregion\n//#region src/cache/buffer/ring-buffer.ts\n/**\n* RingBuffer is a generic circular buffer implementation that stores a fixed number\n* of items. When the buffer is full, new items overwrite the oldest items.\n*\n* This implementation maintains O(1) time complexity for push operations and provides\n* items in chronological order (oldest to newest) via getAll().\n*\n* @template T - The type of items stored in the buffer\n*/\nvar RingBuffer = class {\n\tbuffer;\n\thead = 0;\n\tsize = 0;\n\tcapacity;\n\tconstructor(capacity) {\n\t\tif (capacity <= 0) throw new Error(\"Ring buffer capacity must be greater than 0\");\n\t\tthis.capacity = capacity;\n\t\tthis.buffer = new Array(capacity);\n\t}\n\t/**\n\t* Adds an item to the buffer. If the buffer is full, overwrites the oldest item.\n\t*\n\t* @param item - The item to add\n\t*/\n\tpush(item) {\n\t\tconst index = (this.head + this.size) % this.capacity;\n\t\tif (this.size < this.capacity) {\n\t\t\tthis.buffer[index] = item;\n\t\t\tthis.size++;\n\t\t} else {\n\t\t\tthis.buffer[this.head] = item;\n\t\t\tthis.head = (this.head + 1) % this.capacity;\n\t\t}\n\t}\n\t/**\n\t* Returns all items in the buffer in chronological order (oldest to newest).\n\t*\n\t* @returns Array of items in insertion order\n\t*/\n\tgetAll() {\n\t\tif (this.size === 0) return [];\n\t\tconst result = [];\n\t\tfor (let i = 0; i < this.size; i++) {\n\t\t\tconst index = (this.head + i) % this.capacity;\n\t\t\tresult.push(this.buffer[index]);\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t* Clears all items from the buffer.\n\t*/\n\tclear() {\n\t\tthis.buffer = new Array(this.capacity);\n\t\tthis.head = 0;\n\t\tthis.size = 0;\n\t}\n\t/**\n\t* Gets the current number of items in the buffer.\n\t*/\n\tget length() {\n\t\treturn this.size;\n\t}\n};\n//#endregion\n//#region src/cache/write-cache-types.ts\n/**\n* Where a snapshot sits in its stream.\n*\n* - `Head`: the newest revision of the stream when it was stored. Only these\n* can answer a read that asks for the head.\n* - `Historical`: state at an earlier revision. Usable as a starting point to\n* replay forward from, and as an answer to a read for that same revision.\n*/\nlet SnapshotPosition = /* @__PURE__ */ function(SnapshotPosition) {\n\tSnapshotPosition[\"Head\"] = \"head\";\n\tSnapshotPosition[\"Historical\"] = \"historical\";\n\treturn SnapshotPosition;\n}({});\n//#endregion\n//#region src/cache/kysely-write-cache.ts\n/**\n* The last operation index a keyframe's document reflects for the scope. A\n* keyframe only exists for a scope that has operations, so a missing entry\n* means the stored row is corrupt.\n*/\nfunction keyframeRevision(keyframe, documentId, scope) {\n\tconst nextIndex = keyframe.document.header.revision[scope];\n\tif (typeof nextIndex !== \"number\") throw new Error(`Corrupt keyframe for document ${documentId} at revision ${keyframe.revision}: header carries no ${scope} revision`);\n\treturn nextIndex - 1;\n}\nfunction extractModuleVersion(doc) {\n\tconst v = doc.state.document.version;\n\treturn normalizeDocumentModelVersion(v);\n}\n/** The highest revision held, latest push winning a tie. */\nfunction highestRevision(snapshots) {\n\tlet newest = void 0;\n\tfor (const snapshot of snapshots) if (!newest || snapshot.revision >= newest.revision) newest = snapshot;\n\treturn newest;\n}\n/**\n* Copies a document far enough that the caller cannot write through it. Inside\n* this class, callers only ever replace whole fields on these four, so one\n* level each is enough.\n*/\nfunction copyDocument(document) {\n\treturn {\n\t\t...document,\n\t\theader: { ...document.header },\n\t\tstate: { ...document.state },\n\t\toperations: { ...document.operations }\n\t};\n}\n/**\n* In-memory write cache with keyframe persistence for PHDocuments.\n*\n* Caches document snapshots in ring buffers with LRU eviction. On cache miss,\n* rebuilds documents from nearest keyframe or full operation history.\n*\n* **Performance Characteristics:**\n* - Cache hit: O(1) lookup in ring buffer\n* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe\n* - Warm miss: O(m) where m is operations since cached revision\n* - Eviction: O(1) for LRU tracking and removal\n*\n* **Thread Safety:**\n* Not thread-safe. Designed for single-threaded job executor environment.\n* External synchronization required for concurrent access across multiple executors.\n*\n* **Example:**\n* ```typescript\n* const cache = new KyselyWriteCache(\n* keyframeStore,\n* operationStore,\n* registry,\n* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }\n* );\n*\n* await cache.startup();\n*\n* // Retrieve or rebuild document\n* const doc = await cache.getState(docId, docType, scope, branch, revision);\n*\n* // Cache result after job execution\n* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);\n*\n* await cache.shutdown();\n* ```\n*/\nvar KyselyWriteCache = class KyselyWriteCache {\n\tstreams;\n\tlruTracker;\n\tkeyframeStore;\n\toperationStore;\n\tregistry;\n\tconfig;\n\tconstructor(keyframeStore, operationStore, registry, config) {\n\t\tthis.keyframeStore = keyframeStore;\n\t\tthis.operationStore = operationStore;\n\t\tthis.registry = registry;\n\t\tthis.config = {\n\t\t\tmaxDocuments: config.maxDocuments,\n\t\t\tringBufferSize: config.ringBufferSize,\n\t\t\tkeyframeInterval: config.keyframeInterval\n\t\t};\n\t\tthis.streams = /* @__PURE__ */ new Map();\n\t\tthis.lruTracker = new LRUTracker();\n\t}\n\twithScopedStores(operationStore, keyframeStore) {\n\t\tconst scoped = new KyselyWriteCache(keyframeStore, operationStore, this.registry, this.config);\n\t\tscoped.streams = this.streams;\n\t\tscoped.lruTracker = this.lruTracker;\n\t\treturn scoped;\n\t}\n\t/**\n\t* Initializes the write cache.\n\t* Currently a no-op as keyframe store lifecycle is managed externally.\n\t*/\n\tasync startup() {\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t* Shuts down the write cache.\n\t* Currently a no-op as keyframe store lifecycle is managed externally.\n\t*/\n\tasync shutdown() {\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t* Retrieves document state at a specific revision from cache or rebuilds it.\n\t*\n\t* Note: this returns a _shallow_ copy of the document.\n\t*\n\t* Cache hit path: Returns cached snapshot if available (O(1))\n\t* Warm miss path: Rebuilds from cached base revision + incremental ops\n\t* Cold miss path: Rebuilds from keyframe or from scratch using all operations\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - The operation scope\n\t* @param branch - The operation branch\n\t* @param targetRevision - The target revision, or undefined for newest\n\t* @param signal - Optional abort signal to cancel the operation\n\t* @returns The document at the target revision\n\t* @throws {Error} \"Operation aborted\" if signal is aborted\n\t* @throws {ModuleNotFoundError} If document type not registered in registry\n\t* @throws {Error} \"Failed to rebuild document\" if operation store fails\n\t* @throws {Error} If reducer throws during operation application\n\t* @throws {Error} If document serialization fails\n\t*/\n\tasync getState(documentId, scope, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst streamKey = this.makeStreamKey(documentId, scope, branch);\n\t\tconst stream = this.streams.get(streamKey);\n\t\tif (stream) {\n\t\t\tconst snapshots = stream.ringBuffer.getAll();\n\t\t\tif (targetRevision === void 0) {\n\t\t\t\tconst newest = highestRevision(snapshots);\n\t\t\t\tif (newest?.position === SnapshotPosition.Head) {\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn copyDocument(newest.document);\n\t\t\t\t}\n\t\t\t\tif (newest) {\n\t\t\t\t\tconst document = await this.warmMissRebuild(newest.document, newest.revision, documentId, scope, branch, void 0, signal);\n\t\t\t\t\tthis.store(documentId, scope, branch, (document.header.revision[scope] ?? 0) - 1, document, SnapshotPosition.Head);\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn document;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst exactMatch = snapshots.findLast((s) => s.revision === targetRevision);\n\t\t\t\tif (exactMatch) {\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn copyDocument(exactMatch.document);\n\t\t\t\t}\n\t\t\t\tconst newestOlder = this.findNearestOlderSnapshot(snapshots, targetRevision);\n\t\t\t\tif (newestOlder) {\n\t\t\t\t\tconst document = await this.warmMissRebuild(newestOlder.document, newestOlder.revision, documentId, scope, branch, targetRevision, signal);\n\t\t\t\t\tthis.store(documentId, scope, branch, targetRevision, document, SnapshotPosition.Historical);\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn document;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst document = await this.coldMissRebuild(documentId, scope, branch, targetRevision, signal);\n\t\tconst revision = targetRevision ?? (document.header.revision[scope] ?? 0) - 1;\n\t\tthis.store(documentId, scope, branch, revision, document, targetRevision === void 0 ? SnapshotPosition.Head : SnapshotPosition.Historical);\n\t\treturn document;\n\t}\n\t/**\n\t* Stores a document snapshot in the cache at a specific revision.\n\t*\n\t* The cached document is a shallow copy of the input with its operation history\n\t* truncated to the last operation per scope and its clipboard cleared. This keeps\n\t* memory use and copy costs constant regardless of operation count. Consumers of\n\t* getState() must not rely on the full operation history being present; the only\n\t* guaranteed invariant is that operations[scope].at(-1) reflects the latest\n\t* operation index for each scope.\n\t*\n\t* Updates LRU tracker and may evict least recently used stream if at capacity.\n\t* Asynchronously persists keyframes at configured intervals (fire-and-forget).\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - The operation scope\n\t* @param branch - The operation branch\n\t* @param revision - The revision number\n\t* @param document - The document to cache\n\t* @throws {Error} If document serialization fails\n\t*/\n\tputState(documentId, scope, branch, revision, document, position) {\n\t\tthis.store(documentId, scope, branch, revision, document, position);\n\t}\n\t/**\n\t* Stores the run's head and mints a keyframe for every interval the run\n\t* crossed on its way there. Only the head enters the ring buffer; the\n\t* earlier revisions are keyframe candidates and nothing more.\n\t*/\n\tputRun(documentId, scope, branch, run) {\n\t\tif (run.length === 0) return;\n\t\tfor (const entry of run.slice(0, -1)) this.persistKeyframe(documentId, scope, branch, entry.revision, entry.document);\n\t\tconst head = run[run.length - 1];\n\t\tthis.store(documentId, scope, branch, head.revision, head.document, SnapshotPosition.Head);\n\t}\n\tstore(documentId, scope, branch, revision, document, position) {\n\t\tconst streamKey = this.makeStreamKey(documentId, scope, branch);\n\t\tconst stream = this.getOrCreateStream(streamKey);\n\t\tconst snapshot = {\n\t\t\trevision,\n\t\t\tdocument: {\n\t\t\t\t...copyDocument(document),\n\t\t\t\toperations: Object.fromEntries(Object.entries(document.operations).map(([k, ops]) => [k, ops.length ? [ops.at(-1)] : []])),\n\t\t\t\tclipboard: []\n\t\t\t},\n\t\t\tposition\n\t\t};\n\t\tstream.ringBuffer.push(snapshot);\n\t\tthis.persistKeyframe(documentId, scope, branch, revision, document);\n\t}\n\t/** Persists the snapshot if this revision is one the interval falls on. */\n\tpersistKeyframe(documentId, scope, branch, revision, document) {\n\t\tif (!this.isKeyframeRevision(revision)) return;\n\t\tthis.keyframeStore.putKeyframe(documentId, scope, branch, revision, {\n\t\t\t...document,\n\t\t\toperations: {},\n\t\t\tclipboard: []\n\t\t}).catch((err) => {\n\t\t\tconsole.error(`Failed to persist keyframe ${documentId}@${revision}:`, err);\n\t\t});\n\t}\n\t/**\n\t* Invalidates cached document streams.\n\t*\n\t* Supports three invalidation scopes:\n\t* - Document-level: invalidate(documentId) - removes all streams for document\n\t* - Scope-level: invalidate(documentId, scope) - removes all branches for scope\n\t* - Stream-level: invalidate(documentId, scope, branch) - removes specific stream\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - Optional scope to narrow invalidation\n\t* @param branch - Optional branch to narrow invalidation (requires scope)\n\t* @returns The number of streams evicted\n\t*/\n\tinvalidate(documentId, scope, branch) {\n\t\tlet evicted = 0;\n\t\tif (scope === void 0 && branch === void 0) {\n\t\t\tfor (const [key] of this.streams.entries()) if (key.startsWith(`${documentId}:`)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else if (scope !== void 0 && branch === void 0) {\n\t\t\tfor (const [key] of this.streams.entries()) if (key.startsWith(`${documentId}:${scope}:`)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else if (scope !== void 0 && branch !== void 0) {\n\t\t\tconst key = this.makeStreamKey(documentId, scope, branch);\n\t\t\tif (this.streams.has(key)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted = 1;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n\t/**\n\t* Clears the entire cache, removing all cached document streams.\n\t* Resets LRU tracking state. This operation always succeeds.\n\t*/\n\tclear() {\n\t\tthis.streams.clear();\n\t\tthis.lruTracker.clear();\n\t}\n\t/**\n\t* Retrieves a specific stream for a document. Exposed on the implementation\n\t* for testing, but not on the interface.\n\t*\n\t* @internal\n\t*/\n\tgetStream(documentId, scope, branch) {\n\t\tconst key = this.makeStreamKey(documentId, scope, branch);\n\t\treturn this.streams.get(key);\n\t}\n\tasync findNearestKeyframe(documentId, scope, branch, targetRevision, signal) {\n\t\tif (targetRevision === Number.MAX_SAFE_INTEGER || targetRevision <= 0) return;\n\t\tconst keyframe = await this.keyframeStore.findNearestKeyframe(documentId, scope, branch, targetRevision, signal);\n\t\tif (!keyframe) return;\n\t\treturn {\n\t\t\trevision: Math.min(keyframeRevision(keyframe, documentId, scope), keyframe.revision),\n\t\t\tdocument: keyframe.document\n\t\t};\n\t}\n\t/**\n\t* Rebuilds a scope from a keyframe or from the whole operation history.\n\t*\n\t* The document scope is always rebuilt first, because it carries the type,\n\t* the upgrades and the deletion marker. Its version-changing upgrades are not\n\t* applied there though: an upgrade reducer must see the state the requested\n\t* scope has reached at that upgrade's boundary, so each one is held back and\n\t* applied when the replay below crosses the boundary that\n\t* resolveModuleVersionForOp derives from it. Upgrades whose boundary lies past\n\t* the last replayed operation are applied at the end. Creation-time 0->N seed\n\t* upgrades carry the initial state, so they still apply immediately.\n\t*/\n\tasync coldMissRebuild(documentId, scope, branch, targetRevision, signal) {\n\t\tconst effectiveTargetRevision = targetRevision || Number.MAX_SAFE_INTEGER;\n\t\tconst keyframe = await this.findNearestKeyframe(documentId, scope, branch, effectiveTargetRevision, signal);\n\t\tconst documentScopeBound = scope === \"document\" ? targetRevision : void 0;\n\t\tlet document;\n\t\tlet startRevision;\n\t\tlet documentType;\n\t\tconst validatedUpgrades = [];\n\t\tconst pendingUpgrades = [];\n\t\tlet lastDocumentScopeOperation;\n\t\tif (keyframe) {\n\t\t\tdocument = keyframe.document;\n\t\t\tstartRevision = keyframe.revision;\n\t\t\tdocumentType = keyframe.document.header.documentType;\n\t\t\tconst documentScopeResume = scope === \"document\" ? keyframe.revision : keyframeRevision(keyframe, documentId, \"document\");\n\t\t\tconst docScopeOpsAfterKeyframe = await this.operationStore.getSince(documentId, \"document\", branch, documentScopeResume, void 0, void 0, signal);\n\t\t\tfor (const operation of docScopeOpsAfterKeyframe.results) {\n\t\t\t\tif (documentScopeBound !== void 0 && operation.index > documentScopeBound) break;\n\t\t\t\tlastDocumentScopeOperation = operation;\n\t\t\t\tif (operation.error || isDenied(operation)) continue;\n\t\t\t\tif (operation.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\t\tconst upgradeAction = operation.action;\n\t\t\t\t\tconst fromVersion = upgradeAction.input.fromVersion;\n\t\t\t\t\tconst toVersion = upgradeAction.input.toVersion;\n\t\t\t\t\tif (fromVersion > 0 && fromVersion < toVersion) {\n\t\t\t\t\t\tlet upgradePath;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tupgradePath = this.registry.computeUpgradePath(documentType, fromVersion, toVersion);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tif (upgradeAction.input.initialState !== void 0) upgradePath = void 0;\n\t\t\t\t\t\t\telse throw new Error(`Failed to rebuild document ${documentId}: no upgrade manifest for ${documentType} v${fromVersion}→v${toVersion} and no initialState snapshot. ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalidatedUpgrades.push({\n\t\t\t\t\t\t\tfromVersion,\n\t\t\t\t\t\t\ttoVersion,\n\t\t\t\t\t\t\trevision: upgradeAction.input.revision,\n\t\t\t\t\t\t\ttimestampUtcMs: operation.timestampUtcMs\n\t\t\t\t\t\t});\n\t\t\t\t\t\tpendingUpgrades.push({\n\t\t\t\t\t\t\taction: upgradeAction,\n\t\t\t\t\t\t\tupgradePath,\n\t\t\t\t\t\t\tindex: operation.index,\n\t\t\t\t\t\t\tsubsequentDeletes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (operation.action.type === \"DELETE_DOCUMENT\") {\n\t\t\t\t\tapplyDeleteDocumentAction(document, operation.action);\n\t\t\t\t\tfor (const pending of pendingUpgrades) pending.subsequentDeletes.push(operation.action);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tstartRevision = -1;\n\t\t\tconst createOpResult = await this.operationStore.getSince(documentId, \"document\", branch, -1, void 0, {\n\t\t\t\tcursor: \"0\",\n\t\t\t\tlimit: 1\n\t\t\t}, signal);\n\t\t\tif (createOpResult.results.length === 0) throw new DocumentNotFoundError(documentId);\n\t\t\tconst createOp = createOpResult.results[0];\n\t\t\tif (createOp.action.type !== \"CREATE_DOCUMENT\") throw new Error(`Failed to rebuild document ${documentId}: first operation in document scope must be CREATE_DOCUMENT, found ${createOp.action.type}`);\n\t\t\tconst documentCreateAction = createOp.action;\n\t\t\tdocumentType = documentCreateAction.input.model;\n\t\t\tif (!documentType) throw new Error(`Failed to rebuild document ${documentId}: CREATE_DOCUMENT action missing model in input`);\n\t\t\tdocument = createDocumentFromAction(documentCreateAction);\n\t\t\tlastDocumentScopeOperation = createOp;\n\t\t\tlet docModule = this.registry.getModule(documentType, extractModuleVersion(document));\n\t\t\tconst docScopeOps = await this.operationStore.getSince(documentId, \"document\", branch, 0, void 0, void 0, signal);\n\t\t\tfor (const operation of docScopeOps.results) {\n\t\t\t\tif (documentScopeBound !== void 0 && operation.index > documentScopeBound) break;\n\t\t\t\tlastDocumentScopeOperation = operation;\n\t\t\t\tif (operation.index === 0) continue;\n\t\t\t\tif (operation.error || isDenied(operation)) continue;\n\t\t\t\tif (operation.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\t\tconst upgradeAction = operation.action;\n\t\t\t\t\tconst fromVersion = upgradeAction.input.fromVersion;\n\t\t\t\t\tconst toVersion = upgradeAction.input.toVersion;\n\t\t\t\t\tif (fromVersion > 0 && fromVersion < toVersion) {\n\t\t\t\t\t\tlet upgradePath;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tupgradePath = this.registry.computeUpgradePath(documentType, fromVersion, toVersion);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tif (upgradeAction.input.initialState !== void 0) upgradePath = void 0;\n\t\t\t\t\t\t\telse throw new Error(`Failed to rebuild document ${documentId}: no upgrade manifest for ${documentType} v${fromVersion}→v${toVersion} and no initialState snapshot. ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalidatedUpgrades.push({\n\t\t\t\t\t\t\tfromVersion,\n\t\t\t\t\t\t\ttoVersion,\n\t\t\t\t\t\t\trevision: upgradeAction.input.revision,\n\t\t\t\t\t\t\ttimestampUtcMs: operation.timestampUtcMs\n\t\t\t\t\t\t});\n\t\t\t\t\t\tpendingUpgrades.push({\n\t\t\t\t\t\t\taction: upgradeAction,\n\t\t\t\t\t\t\tupgradePath,\n\t\t\t\t\t\t\tindex: operation.index,\n\t\t\t\t\t\t\tsubsequentDeletes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t} else document = applyUpgradeDocumentAction(document, upgradeAction, void 0);\n\t\t\t\t\tdocModule = this.registry.getModule(documentType, normalizeDocumentModelVersion(toVersion));\n\t\t\t\t} else if (operation.action.type === \"DELETE_DOCUMENT\") {\n\t\t\t\t\tapplyDeleteDocumentAction(document, operation.action);\n\t\t\t\t\tfor (const pending of pendingUpgrades) pending.subsequentDeletes.push(operation.action);\n\t\t\t\t} else {\n\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\tdocument = docModule.reducer(document, operation.action, void 0, {\n\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\tprotocolVersion\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (scope === \"document\") {\n\t\t\tdocument = this.applyPendingUpgrades(document, pendingUpgrades, Number.MAX_SAFE_INTEGER);\n\t\t\tconst last = lastDocumentScopeOperation ?? await this.operationAt(documentId, \"document\", branch, startRevision, signal);\n\t\t\tdocument.operations = {\n\t\t\t\t...document.operations,\n\t\t\t\tdocument: last ? [last] : []\n\t\t\t};\n\t\t\treturn this.stampRevisions(document, documentId, scope, branch, targetRevision, signal);\n\t\t}\n\t\tif (keyframe) {\n\t\t\tconst resumeOperation = await this.operationAt(documentId, scope, branch, startRevision, signal);\n\t\t\tif (resumeOperation) document.operations = {\n\t\t\t\t...document.operations,\n\t\t\t\t[scope]: [resumeOperation]\n\t\t\t};\n\t\t}\n\t\tconst moduleCache = /* @__PURE__ */ new Map();\n\t\tconst getModuleCached = (version) => {\n\t\t\tconst key = version ?? 0;\n\t\t\tlet mod = moduleCache.get(key);\n\t\t\tif (!mod) {\n\t\t\t\tmod = this.registry.getModule(documentType, version);\n\t\t\t\tmoduleCache.set(key, mod);\n\t\t\t}\n\t\t\treturn mod;\n\t\t};\n\t\tconst finalVersion = validatedUpgrades.at(-1)?.toVersion ?? extractModuleVersion(document);\n\t\tlet cursor = void 0;\n\t\tconst pageSize = 100;\n\t\tlet hasMorePages;\n\t\tdo {\n\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\tconst paging = {\n\t\t\t\tcursor: cursor || \"0\",\n\t\t\t\tlimit: pageSize\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = await this.operationStore.getSince(documentId, scope, branch, startRevision, void 0, paging, signal);\n\t\t\t\tfor (const operation of result.results) {\n\t\t\t\t\tif (targetRevision !== void 0 && operation.index > targetRevision) break;\n\t\t\t\t\tconst moduleVersion = this.resolveModuleVersionForOp(operation.index, operation.timestampUtcMs, scope, validatedUpgrades, finalVersion);\n\t\t\t\t\tdocument = this.applyPendingUpgrades(document, pendingUpgrades, moduleVersion ?? Number.MAX_SAFE_INTEGER);\n\t\t\t\t\tif (isDenied(operation)) document = appendWithoutApplying(document, operation, scope);\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\t\tdocument = getModuleCached(moduleVersion).reducer(document, operation.action, void 0, {\n\t\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\t\tprotocolVersion,\n\t\t\t\t\t\t\treplayOptions: { operation },\n\t\t\t\t\t\t\tskipIndexValidation: true\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst reachedTarget = targetRevision !== void 0 && result.results.some((op) => op.index >= targetRevision);\n\t\t\t\thasMorePages = Boolean(result.nextCursor) && !reachedTarget;\n\t\t\t\tif (hasMorePages) cursor = result.nextCursor;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new Error(`Failed to rebuild document ${documentId}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t}\n\t\t} while (hasMorePages);\n\t\tdocument = this.applyTailPendingUpgrades(document, pendingUpgrades, scope, targetRevision);\n\t\tdocument = await this.stampRevisions(document, documentId, scope, branch, targetRevision, signal);\n\t\tif (pendingUpgrades.length > 0) {\n\t\t\tconst firstHeldBack = pendingUpgrades[0];\n\t\t\tconst stamped = document.header.revision[\"document\"] ?? 0;\n\t\t\tdocument.header.revision = {\n\t\t\t\t...document.header.revision,\n\t\t\t\tdocument: Math.min(stamped, firstHeldBack.index)\n\t\t\t};\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies and removes every held-back upgrade whose target version is at or\n\t* below `throughVersion`, in the order the document scope recorded them.\n\t*/\n\tapplyPendingUpgrades(document, pendingUpgrades, throughVersion) {\n\t\twhile (pendingUpgrades.length > 0) {\n\t\t\tconst pending = pendingUpgrades[0];\n\t\t\tif (throughVersion < pending.action.input.toVersion) break;\n\t\t\tpendingUpgrades.shift();\n\t\t\tdocument = this.applyPendingUpgrade(document, pending);\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies the remaining held-back upgrades after the requested scope's\n\t* replay has finished. A head read applies them all. A positional read\n\t* applies only those whose boundary for this scope lies at or before the\n\t* target position: applying a later one would label migrated state with a\n\t* pre-upgrade revision, and a keyframe stored from that poisons every\n\t* rebuild that resumes from it. Boundaries come from the upgrade's revision\n\t* snapshot; an upgrade without one records no position for this scope, and\n\t* the replay loop not having crossed it already places it past the target.\n\t*/\n\tapplyTailPendingUpgrades(document, pendingUpgrades, scope, targetRevision) {\n\t\twhile (pendingUpgrades.length > 0) {\n\t\t\tconst pending = pendingUpgrades[0];\n\t\t\tif (targetRevision !== void 0) {\n\t\t\t\tconst snapshot = pending.action.input.revision;\n\t\t\t\tif (snapshot === void 0) break;\n\t\t\t\tif ((snapshot[scope] ?? 0) > targetRevision) break;\n\t\t\t}\n\t\t\tpendingUpgrades.shift();\n\t\t\tdocument = this.applyPendingUpgrade(document, pending);\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies one held-back upgrade, then re-applies the deletes the document\n\t* scope recorded after it so the hold-back cannot invert their order.\n\t*/\n\tapplyPendingUpgrade(document, pending) {\n\t\tdocument = applyUpgradeDocumentAction(document, pending.action, pending.upgradePath);\n\t\tfor (const deleteAction of pending.subsequentDeletes) document = applyDeleteDocumentAction(document, deleteAction);\n\t\treturn document;\n\t}\n\t/**\n\t* Copies the current document revisions onto the document. Overwrites the\n\t* requested scope revision with the target revision, if provided.\n\t*/\n\tasync stampRevisions(document, documentId, scope, branch, targetRevision, signal) {\n\t\tconst revisions = await this.operationStore.getRevisions(documentId, branch, signal);\n\t\tdocument.header.revision = revisions.revision;\n\t\tif (targetRevision !== void 0) document.header.revision = {\n\t\t\t...document.header.revision,\n\t\t\t[scope]: targetRevision + 1\n\t\t};\n\t\tdocument.header.lastModifiedAtUtcIso = revisions.latestTimestamp;\n\t\treturn document;\n\t}\n\t/** The stored operation at `index`, or undefined if it is no longer there. */\n\tasync operationAt(documentId, scope, branch, index, signal) {\n\t\tif (index < 0) return;\n\t\tconst operation = (await this.operationStore.getSince(documentId, scope, branch, index - 1, void 0, {\n\t\t\tcursor: \"0\",\n\t\t\tlimit: 1\n\t\t}, signal)).results[0];\n\t\treturn operation && operation.index === index ? operation : void 0;\n\t}\n\t/**\n\t* Resolves which module version to use for a given operation in phase 2.\n\t*\n\t* Uses the validated-upgrade boundary rules from D7:\n\t* - If `input.revision` is present: op.index < revision[scope] → before the upgrade boundary\n\t* - Otherwise: timestamp fallback\n\t* - Falls back to final module version when neither is decidable\n\t*/\n\tresolveModuleVersionForOp(opIndex, opTimestamp, scope, validatedUpgrades, finalVersion) {\n\t\tif (validatedUpgrades.length === 0) return finalVersion;\n\t\tlet currentVersion = validatedUpgrades[0]?.fromVersion;\n\t\tfor (const upgrade of validatedUpgrades) {\n\t\t\tlet beforeUpgrade;\n\t\t\tif (upgrade.revision !== void 0) beforeUpgrade = opIndex < (upgrade.revision[scope] ?? 0);\n\t\t\telse beforeUpgrade = opTimestamp < upgrade.timestampUtcMs;\n\t\t\tif (beforeUpgrade) return currentVersion;\n\t\t\tcurrentVersion = upgrade.toVersion;\n\t\t}\n\t\treturn currentVersion;\n\t}\n\tasync warmMissRebuild(baseDocument, baseRevision, documentId, scope, branch, targetRevision, signal) {\n\t\tconst documentType = baseDocument.header.documentType;\n\t\tconst docScopeNextIndex = baseDocument.header.revision[\"document\"] ?? 0;\n\t\tif ((await this.operationStore.getSince(documentId, \"document\", branch, docScopeNextIndex - 1, void 0, void 0, signal)).results.length > 0) return this.coldMissRebuild(documentId, scope, branch, targetRevision, signal);\n\t\tconst module = this.registry.getModule(documentType, extractModuleVersion(baseDocument));\n\t\tlet document = copyDocument(baseDocument);\n\t\ttry {\n\t\t\tconst pagedResults = await this.operationStore.getSince(documentId, scope, branch, baseRevision, void 0, void 0, signal);\n\t\t\tfor (const operation of pagedResults.results) {\n\t\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\tif (targetRevision !== void 0 && operation.index > targetRevision) break;\n\t\t\t\tif (isDenied(operation)) document = appendWithoutApplying(document, operation, scope);\n\t\t\t\telse {\n\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\tdocument = module.reducer(document, operation.action, void 0, {\n\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\tprotocolVersion,\n\t\t\t\t\t\treplayOptions: { operation },\n\t\t\t\t\t\tskipIndexValidation: true\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (targetRevision !== void 0 && operation.index === targetRevision) break;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Failed to rebuild document ${documentId}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t}\n\t\tconst revisions = await this.operationStore.getRevisions(documentId, branch, signal);\n\t\tdocument.header.revision = revisions.revision;\n\t\tif (targetRevision !== void 0) document.header.revision = {\n\t\t\t...document.header.revision,\n\t\t\t[scope]: targetRevision + 1\n\t\t};\n\t\tdocument.header.lastModifiedAtUtcIso = revisions.latestTimestamp;\n\t\treturn document;\n\t}\n\tfindNearestOlderSnapshot(snapshots, targetRevision) {\n\t\tlet nearest = void 0;\n\t\tfor (const snapshot of snapshots) if (snapshot.revision < targetRevision) {\n\t\t\tif (!nearest || snapshot.revision > nearest.revision) nearest = snapshot;\n\t\t}\n\t\treturn nearest;\n\t}\n\tmakeStreamKey(documentId, scope, branch) {\n\t\treturn `${documentId}:${scope}:${branch}`;\n\t}\n\tgetOrCreateStream(key) {\n\t\tlet stream = this.streams.get(key);\n\t\tif (!stream) {\n\t\t\tif (this.streams.size >= this.config.maxDocuments) {\n\t\t\t\tconst evictKey = this.lruTracker.evict();\n\t\t\t\tif (evictKey) this.streams.delete(evictKey);\n\t\t\t}\n\t\t\tstream = {\n\t\t\t\tkey,\n\t\t\t\tringBuffer: new RingBuffer(this.config.ringBufferSize)\n\t\t\t};\n\t\t\tthis.streams.set(key, stream);\n\t\t}\n\t\tthis.lruTracker.touch(key);\n\t\treturn stream;\n\t}\n\tisKeyframeRevision(revision) {\n\t\treturn revision > 0 && revision % this.config.keyframeInterval === 0;\n\t}\n};\n//#endregion\n//#region src/events/event-bus.ts\nvar EventBus = class {\n\teventTypeToSubscribers = /* @__PURE__ */ new Map();\n\tsubscribe(type, subscriber) {\n\t\tlet list = this.eventTypeToSubscribers.get(type);\n\t\tif (!list) {\n\t\t\tlist = [];\n\t\t\tthis.eventTypeToSubscribers.set(type, list);\n\t\t}\n\t\tlist.push(subscriber);\n\t\tlet done = false;\n\t\treturn () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tconst arr = this.eventTypeToSubscribers.get(type);\n\t\t\tif (!arr) return;\n\t\t\tconst idx = arr.indexOf(subscriber);\n\t\t\tif (idx !== -1) arr.splice(idx, 1);\n\t\t\tif (arr.length === 0) this.eventTypeToSubscribers.delete(type);\n\t\t};\n\t}\n\tasync emit(type, data) {\n\t\tconst list = this.eventTypeToSubscribers.get(type);\n\t\tif (!list || list.length === 0) return;\n\t\tconst snapshot = list.slice();\n\t\tconst errors = [];\n\t\tfor (const fn of snapshot) try {\n\t\t\tawait Promise.resolve(fn(type, data));\n\t\t} catch (err) {\n\t\t\terrors.push(err);\n\t\t}\n\t\tif (errors.length > 0) throw new EventBusAggregateError(errors);\n\t}\n};\n//#endregion\n//#region src/core/feature-flags.ts\n/**\n* Every flag this reactor knows, with the flags it requires. A stage adds its\n* flag here when it ships, so asking an older reactor for a later stage's flag\n* is an unrecognized name rather than a flag that quietly does nothing.\n*/\nconst FLAG_PREREQUISITES = {\n\tdocumentDecisions: [],\n\tauthEnforcement: [\"documentDecisions\"],\n\tauthGroups: [\"authEnforcement\"],\n\tauthConditions: [\"authGroups\"]\n};\n/**\n* The flags as plain booleans, with anything unset off, validated. Callers hold\n* a partial set, because that is what crosses to a pooled worker, and every\n* consumer needs the same resolution of it.\n*/\nfunction resolveFeatureFlags(flags = {}) {\n\tconst resolved = {\n\t\tdocumentDecisions: flags.documentDecisions ?? false,\n\t\tauthEnforcement: flags.authEnforcement ?? false,\n\t\tauthGroups: flags.authGroups ?? false,\n\t\tauthConditions: flags.authConditions ?? false\n\t};\n\tvalidateFeatureFlags(flags, FLAG_PREREQUISITES);\n\treturn resolved;\n}\n/**\n* Throws when the flags ask for enforcement the reactor cannot deliver. Either\n* failure would otherwise read as enforcement being on while the reactor\n* applies less than the caller asked for.\n*/\nfunction validateFeatureFlags(flags, prerequisites) {\n\tconst known = Object.keys(prerequisites);\n\tconst unrecognized = Object.keys(flags).filter((name) => !known.includes(name));\n\tif (unrecognized.length > 0) throw new Error(`Unrecognized reactor feature flag: ${unrecognized.join(\", \")}. This reactor knows: ${known.join(\", \")}.`);\n\tfor (const name of known) {\n\t\tif (flags[name] !== true) continue;\n\t\tconst missing = prerequisites[name].filter((required) => flags[required] !== true);\n\t\tif (missing.length > 0) throw new Error(`Reactor feature flag ${name} requires ${missing.join(\", \")}.`);\n\t}\n}\n//#endregion\n//#region src/executor/execution-scope.ts\nvar DefaultExecutionScope = class {\n\tconstructor(operationStore, operationIndex, writeCache, documentMetaCache, collectionMembershipCache) {\n\t\tthis.operationStore = operationStore;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.writeCache = writeCache;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t}\n\tasync run(fn, signal) {\n\t\tsignal?.throwIfAborted();\n\t\treturn fn({\n\t\t\toperationStore: this.operationStore,\n\t\t\toperationIndex: this.operationIndex,\n\t\t\twriteCache: this.writeCache,\n\t\t\tdocumentMetaCache: this.documentMetaCache,\n\t\t\tcollectionMembershipCache: this.collectionMembershipCache\n\t\t});\n\t}\n};\nvar KyselyExecutionScope = class {\n\tconstructor(db, operationStore, operationIndex, keyframeStore, writeCache, documentMetaCache, collectionMembershipCache) {\n\t\tthis.db = db;\n\t\tthis.operationStore = operationStore;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.keyframeStore = keyframeStore;\n\t\tthis.writeCache = writeCache;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t}\n\tasync run(fn, signal) {\n\t\tsignal?.throwIfAborted();\n\t\treturn this.db.transaction().execute(async (trx) => {\n\t\t\tconst scopedOperationStore = this.operationStore.withTransaction(trx);\n\t\t\tconst scopedOperationIndex = this.operationIndex.withTransaction(trx);\n\t\t\tconst scopedKeyframeStore = this.keyframeStore.withTransaction(trx);\n\t\t\treturn fn({\n\t\t\t\toperationStore: scopedOperationStore,\n\t\t\t\toperationIndex: scopedOperationIndex,\n\t\t\t\twriteCache: this.writeCache.withScopedStores(scopedOperationStore, scopedKeyframeStore),\n\t\t\t\tdocumentMetaCache: this.documentMetaCache.withScopedStore(scopedOperationStore),\n\t\t\t\tcollectionMembershipCache: this.collectionMembershipCache.withScopedIndex(scopedOperationIndex)\n\t\t\t});\n\t\t});\n\t}\n};\n//#endregion\n//#region src/utils/reshuffle.ts\nconst STRICT_ORDER_ACTION_TYPES = new Set([\n\t\"CREATE_DOCUMENT\",\n\t\"DELETE_DOCUMENT\",\n\t\"UPGRADE_DOCUMENT\",\n\t\"ADD_RELATIONSHIP\",\n\t\"REMOVE_RELATIONSHIP\",\n\t\"UPDATE_RELATIONSHIP\",\n\t\"ADD_FOLDER\",\n\t\"UPDATE_FOLDER\",\n\t\"REMOVE_FOLDER\"\n]);\n/**\n* Reshuffles operations by timestamp, then applies deterministic tie-breaking.\n* Used for merging concurrent operations from different branches.\n*\n* For strict document-structure actions (e.g., CREATE_DOCUMENT/UPGRADE_DOCUMENT),\n* logical index (index - skip) is prioritized to preserve causal replay order.\n*\n* For other actions, action ID is prioritized to ensure a canonical cross-reactor order\n* for concurrent operations that may have diverged local indices due to prior reshuffles.\n* Logical index and operation ID are then used as deterministic tie-breakers.\n*\n* Example:\n* [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n* GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n* Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n* Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n* merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n*/\nfunction reshuffleByTimestamp(startIndex, opsA, opsB) {\n\treturn [...opsA, ...opsB].sort((a, b) => {\n\t\tconst timestampDiff = new Date(a.timestampUtcMs).getTime() - new Date(b.timestampUtcMs).getTime();\n\t\tif (timestampDiff !== 0) return timestampDiff;\n\t\tconst rank = (op) => STRICT_ORDER_ACTION_TYPES.has(op.action?.type ?? \"\") ? 0 : 1;\n\t\tconst rankDiff = rank(a) - rank(b);\n\t\tif (rankDiff !== 0) return rankDiff;\n\t\tif (rank(a) === 0) {\n\t\t\tconst logicalIndexDiff = a.index - a.skip - (b.index - b.skip);\n\t\t\tif (logicalIndexDiff !== 0) return logicalIndexDiff;\n\t\t}\n\t\tconst actionIdDiff = (a.action?.id ?? \"\").localeCompare(b.action?.id ?? \"\");\n\t\tif (actionIdDiff !== 0) return actionIdDiff;\n\t\treturn a.id.localeCompare(b.id);\n\t}).map((op, i) => ({\n\t\t...op,\n\t\tindex: startIndex.index + i,\n\t\tskip: i === 0 ? startIndex.skip : 0\n\t}));\n}\n//#endregion\n//#region src/decision/merged-order.ts\n/** Identifies a stream within a walk. */\nfunction streamKey(query) {\n\treturn `${query.documentId}:${query.scope}:${query.branch}`;\n}\n/**\n* Orders two operations from different streams by position. Timestamp decides;\n* an equal timestamp puts an auth operation first, and otherwise falls to the\n* action id and then the operation id, so that two replicas holding the same\n* operations agree on the order whatever order they happen to store them in.\n*/\nfunction comparePositions(a, b) {\n\tconst aTime = Date.parse(a.operation.timestampUtcMs);\n\tconst bTime = Date.parse(b.operation.timestampUtcMs);\n\tif (aTime !== bTime) return aTime - bTime;\n\tif (a.streamKey === b.streamKey) return a.operation.index - b.operation.index;\n\tconst aAuth = a.scope === \"auth\";\n\tif (aAuth !== (b.scope === \"auth\")) return aAuth ? -1 : 1;\n\tconst actionIds = (a.operation.action.id ?? \"\").localeCompare(b.operation.action.id ?? \"\");\n\tif (actionIds !== 0) return actionIds;\n\treturn (a.operation.id ?? \"\").localeCompare(b.operation.id ?? \"\");\n}\n/**\n* Merges the read-set streams into one sequence by position. An operation's\n* place in the result is the bound a decision at that operation reads to: every\n* operation before it has been applied, and it has not.\n*/\nfunction mergeByPosition(streams) {\n\tconst merged = [];\n\tfor (const stream of streams) for (const operation of stream.operations) merged.push({\n\t\tstreamKey: stream.streamKey,\n\t\tscope: stream.scope,\n\t\toperation\n\t});\n\treturn merged.sort(comparePositions);\n}\n/**\n* The skip that retracts everything from `firstRetractedIndex` up to where the\n* re-appended operation lands. It spans the indexes rather than counting the\n* operations, because a stream with a gap in it makes those differ.\n*/\nfunction retractionSkip(nextIndex, firstRetractedIndex) {\n\treturn nextIndex - firstRetractedIndex;\n}\n//#endregion\n//#region src/decision/walk.ts\n/**\n* A single forward pass is only correct while a stream's effective operations\n* are ordered.\n*/\nfunction assertPositionOrder(streamKey, scope, operations) {\n\tfor (let i = 1; i < operations.length; i++) {\n\t\tconst previous = operations[i - 1];\n\t\tconst current = operations[i];\n\t\tif (comparePositions({\n\t\t\tstreamKey,\n\t\t\tscope,\n\t\t\toperation: previous\n\t\t}, {\n\t\t\tstreamKey,\n\t\t\tscope,\n\t\t\toperation: current\n\t\t}) > 0) throw new Error(`Stream ${streamKey} is out of position order: index ${previous.index} at ${previous.timestampUtcMs} precedes index ${current.index} at ${current.timestampUtcMs}`);\n\t}\n}\n/**\n* Visits every operation in the read-set once, in the order their positions\n* fall, and hands back the state each stream held just before it. That state is\n* what a decision at that operation reads.\n*\n* Skips are resolved first (i.e. this is performed on a garbage collected\n* stream), which means we can do a single forward pass.\n*\n* An operation that contributes no state, whether denied or holding a reducer\n* error, is visited but not applied (this matches the write cache's rebuild).\n*\n* The consumer sends back whether it refused the operation it was handed: a\n* refusal this pass produced must suppress it the same way a stored one does.\n*/\nfunction* walkByPosition(streams) {\n\tconst merged = mergeByPosition(streams.map((stream) => {\n\t\tconst operations = garbageCollect(sortOperations([...stream.operations]));\n\t\tassertPositionOrder(stream.streamKey, stream.scope, operations);\n\t\treturn {\n\t\t\tstreamKey: stream.streamKey,\n\t\t\tscope: stream.scope,\n\t\t\toperations\n\t\t};\n\t}));\n\tconst byKey = new Map(streams.map((stream) => [stream.streamKey, stream]));\n\tconst states = new Map(streams.map((stream) => [stream.streamKey, stream.document]));\n\tfor (const { streamKey, operation } of merged) {\n\t\tif ((yield {\n\t\t\tstreamKey,\n\t\t\toperation,\n\t\t\tstates: new Map(states)\n\t\t}) || operation.error !== void 0 || isDenied(operation)) continue;\n\t\tconst stream = byKey.get(streamKey);\n\t\tconst before = states.get(streamKey);\n\t\tif (before === void 0 || stream === void 0) throw new Error(`No state for stream ${streamKey}`);\n\t\tstates.set(streamKey, stream.apply(before, operation));\n\t}\n}\n//#endregion\n//#region src/decision/evaluation.ts\n/** The stream key for evaluated operations whose scope no projection reads. */\nconst EVALUATED_ONLY = \"evaluated\";\n/**\n* Whether any stream the model reads declares this operation's action type as\n* one that can change an evaluation.\n*/\nfunction isDecidingAction(operation, readSet) {\n\treturn readSet.some((stream) => stream.decidingActions.includes(operation.action.type));\n}\n/**\n* Who an operation acts as. A replayed operation is evaluated as its own signer,\n* so an address-scoped policy does not deny its own author's history.\n*/\nfunction subjectOf(operation) {\n\tconst signer = operation.action.context?.signer;\n\treturn {\n\t\taddress: signer?.user.address,\n\t\tkey: signer?.app.key\n\t};\n}\n/**\n* The model as the walk reached this operation: each static projection's value\n* is its own scope's state, and each derived projection's value maps document\n* id to that document's state, holding only the streams this replica walked. A\n* derived stream it does not hold stays out of the map, which fails closed.\n*/\nfunction modelAt(readSet, derivedNames, derived, states) {\n\tconst model = {};\n\tfor (const stream of readSet) {\n\t\tconst document = states.get(streamKey(stream.query));\n\t\tif (document === void 0) throw new Error(`No state walked for projection ${stream.name}`);\n\t\tmodel[stream.name] = document.state[stream.query.scope];\n\t}\n\tfor (const name of derivedNames) model[name] = {};\n\tfor (const entry of derived) {\n\t\tconst map = model[entry.name];\n\t\tconst document = states.get(streamKey(entry.query));\n\t\tif (document !== void 0) map[entry.query.documentId] = document.state[entry.query.scope];\n\t}\n\treturn model;\n}\n/**\n* Evaluates each operation at its own position and returns the refusals in an\n* array parallel to the operations, where undefined means allowed.\n*\n* A position is a timestamp, so an operation refused by a delete is one that\n* sorts after it, and the operations before it are left alone. That holds\n* whether the delete is already stored or is among the operations passed in.\n*/\nasync function evaluateByPosition(model, target, subject, stores, signal) {\n\tconst { scope, operations } = subject;\n\tconst { writeCache, operationStore } = stores;\n\tconst definition = model(target);\n\tconst readSet = staticReadSet(definition);\n\tconst derivedSet = derivedReadSet(definition);\n\tif (!definition.evaluatesScope(scope)) return operations.map(() => void 0);\n\tconst evaluating = new Set(operations.map((operation) => operation.id));\n\tconst readStreams = await Promise.all(readSet.map(async (stream) => ({\n\t\tstream,\n\t\toperations: (await operationStore.getSince(stream.query.documentId, stream.query.scope, stream.query.branch, -1, { actionTypes: stream.decidingActions }, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id))\n\t})));\n\tconst decidingOperations = operations.filter((operation) => isDecidingAction(operation, readSet));\n\tif (readStreams.every((read) => read.operations.length === 0) && decidingOperations.length === 0) return operations.map(() => void 0);\n\tif (readStreams.length === 0) throw new Error(`Decision model for ${target.documentId} reads no stream whose query is known before it is built`);\n\tconst writtenProjection = readSet.find((stream) => stream.query.scope === scope);\n\tconst walked = [];\n\tconst histories = [];\n\tfor (const read of readStreams) {\n\t\tconst streamOperations = read.stream === writtenProjection ? [...read.operations, ...operations] : read.operations;\n\t\tconst before = await writeCache.getState(read.stream.query.documentId, read.stream.query.scope, read.stream.query.branch, -1, signal);\n\t\twalked.push({\n\t\t\tstreamKey: streamKey(read.stream.query),\n\t\t\tscope: read.stream.query.scope,\n\t\t\tdocument: before,\n\t\t\toperations: streamOperations,\n\t\t\tapply: read.stream.apply\n\t\t});\n\t\thistories.push({\n\t\t\tname: read.stream.name,\n\t\t\toperations: streamOperations\n\t\t});\n\t}\n\tlet evaluatedStateKey;\n\tif (writtenProjection !== void 0) evaluatedStateKey = streamKey(writtenProjection.query);\n\telse if (definition.foldEvaluatedScope !== void 0) {\n\t\tconst query = {\n\t\t\tdocumentId: target.documentId,\n\t\t\tscope,\n\t\t\tbranch: target.branch\n\t\t};\n\t\tconst storedOperations = (await operationStore.getSince(query.documentId, query.scope, query.branch, -1, void 0, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id));\n\t\tconst before = await writeCache.getState(query.documentId, query.scope, query.branch, -1, signal);\n\t\tevaluatedStateKey = streamKey(query);\n\t\twalked.push({\n\t\t\tstreamKey: evaluatedStateKey,\n\t\t\tscope,\n\t\t\tdocument: before,\n\t\t\toperations: [...storedOperations, ...operations],\n\t\t\tapply: definition.foldEvaluatedScope\n\t\t});\n\t} else walked.push({\n\t\tstreamKey: EVALUATED_ONLY,\n\t\tscope,\n\t\tdocument: walked[0].document,\n\t\toperations,\n\t\tapply: (document) => document\n\t});\n\tconst derivedEntries = [];\n\tconst walkedKeys = new Set(walked.map((stream) => stream.streamKey));\n\tfor (const projection of derivedSet) {\n\t\tconst queries = projection.queryOverHistory?.(histories) ?? [];\n\t\tfor (const query of queries) {\n\t\t\tconst key = streamKey(query);\n\t\t\tif (walkedKeys.has(key)) continue;\n\t\t\tlet before;\n\t\t\ttry {\n\t\t\t\tbefore = await writeCache.getState(query.documentId, query.scope, query.branch, -1, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DocumentNotFoundError) continue;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst streamOperations = (await operationStore.getSince(query.documentId, query.scope, query.branch, -1, { actionTypes: projection.decidingActions }, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id));\n\t\t\twalkedKeys.add(key);\n\t\t\twalked.push({\n\t\t\t\tstreamKey: key,\n\t\t\t\tscope: query.scope,\n\t\t\t\tdocument: before,\n\t\t\t\toperations: streamOperations,\n\t\t\t\tapply: projection.apply\n\t\t\t});\n\t\t\tderivedEntries.push({\n\t\t\t\tname: projection.name,\n\t\t\t\tquery\n\t\t\t});\n\t\t}\n\t}\n\tconst reasons = /* @__PURE__ */ new Map();\n\tconst walk = walkByPosition(walked);\n\tlet step = walk.next(false);\n\twhile (!step.done) {\n\t\tconst position = step.value;\n\t\tif (!evaluating.has(position.operation.id)) {\n\t\t\tstep = walk.next(false);\n\t\t\tcontinue;\n\t\t}\n\t\tconst evaluatedDocument = evaluatedStateKey === void 0 ? void 0 : position.states.get(evaluatedStateKey);\n\t\tconst scopeState = evaluatedDocument === void 0 ? void 0 : evaluatedDocument.state[scope];\n\t\tconst evaluation = definition.decide(modelAt(readSet, derivedSet.map((projection) => projection.name), derivedEntries, position.states), subjectOf(position.operation), {\n\t\t\tverb: \"execute\",\n\t\t\tscope: position.operation.action.scope,\n\t\t\toperation: position.operation.action.type\n\t\t}, {\n\t\t\tscopeState,\n\t\t\tactionInput: position.operation.action.input\n\t\t});\n\t\tconst denied = evaluation.decision === \"deny\";\n\t\treasons.set(position.operation.id, denied ? evaluation.reason : void 0);\n\t\tstep = walk.next(denied);\n\t}\n\treturn operations.map((operation) => reasons.get(operation.id));\n}\n//#endregion\n//#region src/cache/operation-index-types.ts\nconst DRIVE_COLLECTION_PREFIX = \"drive.\";\n/**\n* Identifies the collection a remote synchronizes. Collections are drive-level\n* abstractions (document-drive and reactor-drive), so a collection id is the\n* drive document id plus the branch it scopes to rather than an opaque string.\n*\n* The canonical string form (`drive.${branch}.${driveId}`) is produced only by\n* `key` and parsed only by `fromKey`; that string is the wire and storage\n* representation and is byte-for-byte identical to the legacy\n* `driveCollectionId(branch, driveId)` output, so existing `document_collections`\n* rows and persisted remotes remain valid without migration.\n*/\nvar DriveCollectionId = class DriveCollectionId {\n\tconstructor(driveId, branch) {\n\t\tthis.driveId = driveId;\n\t\tthis.branch = branch;\n\t}\n\tstatic forDrive(driveId, branch = \"main\") {\n\t\treturn new DriveCollectionId(driveId, branch);\n\t}\n\t/**\n\t* The single deserializer for the wire/storage form. `branch` may contain\n\t* dots, while `driveId` is a dot-free document id, so the drive id is the\n\t* final dot-delimited segment.\n\t*/\n\tstatic fromKey(key) {\n\t\tif (!key.startsWith(DRIVE_COLLECTION_PREFIX)) throw new Error(`Unsupported collection id: ${key}`);\n\t\tconst rest = key.slice(6);\n\t\tconst lastDot = rest.lastIndexOf(\".\");\n\t\tif (lastDot === -1 || lastDot === rest.length - 1) throw new Error(`Malformed drive collection id: ${key}`);\n\t\treturn new DriveCollectionId(rest.slice(lastDot + 1), rest.slice(0, lastDot));\n\t}\n\tget key() {\n\t\treturn `${DRIVE_COLLECTION_PREFIX}${this.branch}.${this.driveId}`;\n\t}\n\ttoString() {\n\t\treturn this.key;\n\t}\n\tequals(other) {\n\t\treturn this.driveId === other.driveId && this.branch === other.branch;\n\t}\n};\n//#endregion\n//#region src/executor/document-action-handler.ts\nvar DocumentActionHandler = class {\n\tconstructor(registry, logger, driveContainerTypes, featureFlags, decisionModel) {\n\t\tthis.registry = registry;\n\t\tthis.logger = logger;\n\t\tthis.driveContainerTypes = driveContainerTypes;\n\t\tthis.featureFlags = featureFlags;\n\t\tthis.decisionModel = decisionModel;\n\t}\n\t/** Whether the write arrives with its evaluation already decided. */\n\talreadyEvaluated(executing) {\n\t\treturn this.featureFlags.documentDecisions && (executing.replayingAcceptedHistory || executing.evaluatedByPosition);\n\t}\n\tasync execute(write, executing) {\n\t\tconst { action } = write;\n\t\tif (write.deniedReason !== void 0) return this.writeDenied(write, executing);\n\t\tconst refusal = await this.refuseIfPolicyDenies(write, executing);\n\t\tif (refusal) return refusal;\n\t\tswitch (action.type) {\n\t\t\tcase \"CREATE_DOCUMENT\": return this.executeCreate(write, executing);\n\t\t\tcase \"DELETE_DOCUMENT\": return this.executeDelete(write, executing);\n\t\t\tcase \"UPGRADE_DOCUMENT\": return this.executeUpgrade(write, executing);\n\t\t\tcase \"ADD_RELATIONSHIP\": return this.executeAddRelationship(write, executing);\n\t\t\tcase \"REMOVE_RELATIONSHIP\": return this.executeRemoveRelationship(write, executing);\n\t\t\tcase \"UPDATE_RELATIONSHIP\": return this.executeUpdateRelationship(write, executing);\n\t\t\tdefault: return buildErrorResult(executing.job, /* @__PURE__ */ new Error(`Unknown document action type: ${action.type}`), executing.startTime);\n\t\t}\n\t}\n\t/**\n\t* Refuses a document-scope write the policy denies, or undefined to proceed.\n\t* Without this an `execute`-on-`document` grant is unenforceable.\n\t*/\n\tasync refuseIfPolicyDenies(write, executing) {\n\t\tconst { action } = write;\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\tif (!this.featureFlags.documentDecisions || !this.featureFlags.authEnforcement || this.alreadyEvaluated(executing) || !GATED_DOCUMENT_ACTIONS.has(action.type)) return;\n\t\tconst documentId = targetDocumentId(action, job.documentId);\n\t\tlet admission;\n\t\ttry {\n\t\t\tadmission = await decideAtHead(this.decisionModel, stores.writeCache, {\n\t\t\t\tdocumentId,\n\t\t\t\tbranch: job.branch\n\t\t\t}, {\n\t\t\t\taddress: action.context?.signer?.user.address,\n\t\t\t\tkey: action.context?.signer?.app.key\n\t\t\t}, {\n\t\t\t\tverb: \"execute\",\n\t\t\t\tscope: action.scope,\n\t\t\t\toperation: action.type\n\t\t\t}, signal, this.featureFlags.authConditions ? { actionInput: action.input } : void 0);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tif (admission.evaluation.decision === \"allow\") return;\n\t\treturn buildErrorResult(job, refusalError(admission.evaluation.reason, documentId, admission.deletedAtUtcIso, action), startTime);\n\t}\n\t/** A refused operation holds a position in the stream but changes nothing. */\n\tasync writeDenied(write, executing) {\n\t\tconst { action, skip, sourceRemote, deniedReason } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(job.documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tconst index = getNextIndexForScope(document, job.scope);\n\t\tlet standing = document;\n\t\tif (skip > 0) try {\n\t\t\tstanding = await stores.writeCache.getState(job.documentId, job.scope, job.branch, index - skip - 1, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, index, skip, {\n\t\t\tdocumentId: job.documentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\toperation.deniedReason = deniedReason;\n\t\toperation.hash = hashDocumentStateForScope(standing, job.scope);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(standing, job.scope, operation.index);\n\t\tstanding.operations = {\n\t\t\t...standing.operations,\n\t\t\t[job.scope]: [...standing.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(job.documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(job.documentId, job.scope, job.branch, operation.index, standing, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(job.documentId, job.branch, {\n\t\t\tstate: standing.state.document,\n\t\t\tdocumentType: standing.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, job.documentId, standing.header.documentType, JSON.stringify({\n\t\t\theader: standing.header,\n\t\t\tdocument: standing.state.document\n\t\t}), startTime);\n\t}\n\tasync executeCreate(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.scope !== \"document\") return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: /* @__PURE__ */ new Error(`CREATE_DOCUMENT must be in \"document\" scope, got \"${job.scope}\"`),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst document = createDocumentFromAction(action);\n\t\tlet operation = createOperation(action, 0, skip, {\n\t\t\tdocumentId: document.header.id,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\t...document.state\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: document.header.id,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(document.header.id, job.scope, job.branch);\n\t\tstores.writeCache.putState(document.header.id, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: document.header.id,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tif (this.driveContainerTypes.has(document.header.documentType)) {\n\t\t\tconst collectionId = DriveCollectionId.forDrive(document.header.id, job.branch).key;\n\t\t\tindexTxn.createCollection(collectionId);\n\t\t\tindexTxn.addToCollection(collectionId, document.header.id);\n\t\t}\n\t\tstores.documentMetaCache.putDocumentMeta(document.header.id, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, document.header.id, document.header.documentType, resultingState, startTime);\n\t}\n\tasync executeDelete(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst input = action.input;\n\t\tif (!input.documentId) return buildErrorResult(job, /* @__PURE__ */ new Error(\"DELETE_DOCUMENT action requires a documentId in input\"), startTime);\n\t\tconst documentId = input.documentId;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch document before deletion: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tconst documentState = document.state.document;\n\t\tif (documentState.isDeleted && !this.alreadyEvaluated(executing)) return buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);\n\t\tlet operation = createOperation(action, getNextIndexForScope(document, job.scope), skip, {\n\t\t\tdocumentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tapplyDeleteDocumentAction$1(document, action);\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\tdocument: document.state.document\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(documentId, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(documentId, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);\n\t}\n\tasync executeUpgrade(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst input = action.input;\n\t\tif (!input.documentId) return buildErrorResult(job, /* @__PURE__ */ new Error(\"UPGRADE_DOCUMENT action requires a documentId in input\"), startTime);\n\t\tconst documentId = input.documentId;\n\t\tconst fromVersion = input.fromVersion;\n\t\tconst toVersion = input.toVersion;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch document for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tconst documentState = document.state.document;\n\t\tif (documentState.isDeleted && !this.alreadyEvaluated(executing)) return buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);\n\t\tif (fromVersion === toVersion && fromVersion > 0) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst arrivesDecided = executing.replayingAcceptedHistory || executing.evaluatedByPosition;\n\t\tif (fromVersion > 0 && !arrivesDecided) {\n\t\t\tconst stampedVersion = normalizeDocumentModelVersion(documentState.version);\n\t\t\tif (fromVersion !== stampedVersion) return buildErrorResult(job, new UpgradePreconditionFailedError(documentId, `fromVersion ${fromVersion} does not match the document's version ${stampedVersion}`), startTime);\n\t\t\tif (input.revision !== void 0) {\n\t\t\t\tlet actualRevisions;\n\t\t\t\ttry {\n\t\t\t\t\tactualRevisions = (await stores.operationStore.getRevisions(documentId, job.branch, signal)).revision;\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch revisions for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t\t\t}\n\t\t\t\tconst revisionScopes = new Set([...Object.keys(input.revision), ...Object.keys(actualRevisions)]);\n\t\t\t\tfor (const revisionScope of revisionScopes) {\n\t\t\t\t\tconst snapshot = input.revision[revisionScope] ?? 0;\n\t\t\t\t\tconst actual = actualRevisions[revisionScope] ?? 0;\n\t\t\t\t\tif (snapshot !== actual) return buildErrorResult(job, new UpgradePreconditionFailedError(documentId, `revision snapshot for scope \"${revisionScope}\" is ${snapshot} but the document is at ${actual}`), startTime);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet upgradePath;\n\t\tif (fromVersion > 0 && fromVersion < toVersion) try {\n\t\t\tupgradePath = this.registry.computeUpgradePath(document.header.documentType, fromVersion, toVersion);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tconst otherScopes = Object.keys(document.state).filter((scope) => scope !== job.scope);\n\t\tif (fromVersion > 0) for (const scope of otherScopes) {\n\t\t\tlet scopedDocument;\n\t\t\ttry {\n\t\t\t\tscopedDocument = await stores.writeCache.getState(documentId, scope, job.branch, void 0, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch ${scope} scope for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t\t}\n\t\t\tdocument = {\n\t\t\t\t...document,\n\t\t\t\tstate: {\n\t\t\t\t\t...document.state,\n\t\t\t\t\t[scope]: scopedDocument.state[scope]\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tconst nextIndex = getNextIndexForScope(document, job.scope);\n\t\ttry {\n\t\t\tdocument = applyUpgradeDocumentAction$1(document, action, upgradePath);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, nextIndex, skip, {\n\t\t\tdocumentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\t...document.state\n\t\t};\n\t\tif (fromVersion > 0) resultingStateObj.__migrated = true;\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(documentId, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tfor (const scope of otherScopes) executing.postCommitInvalidations.push({\n\t\t\tdocumentId,\n\t\t\tscope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(documentId, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);\n\t}\n\texecuteAddRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"ADD_RELATIONSHIP\", write, executing, (input) => input.sourceId === input.targetId ? /* @__PURE__ */ new Error(\"ADD_RELATIONSHIP: sourceId and targetId cannot be the same (self-relationships not allowed)\") : null, ({ indexTxn: txn, stores: s, sourceDoc, input, job: j }) => {\n\t\t\tif (this.driveContainerTypes.has(sourceDoc.header.documentType)) {\n\t\t\t\tconst collectionId = DriveCollectionId.forDrive(input.sourceId, j.branch).key;\n\t\t\t\ttxn.addToCollection(collectionId, input.targetId);\n\t\t\t\ts.collectionMembershipCache.invalidate(input.targetId);\n\t\t\t}\n\t\t});\n\t}\n\texecuteRemoveRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"REMOVE_RELATIONSHIP\", write, executing, null, ({ indexTxn: txn, stores: s, sourceDoc, input, job: j }) => {\n\t\t\tif (this.driveContainerTypes.has(sourceDoc.header.documentType)) {\n\t\t\t\tconst collectionId = DriveCollectionId.forDrive(input.sourceId, j.branch).key;\n\t\t\t\ttxn.removeFromCollection(collectionId, input.targetId);\n\t\t\t\ts.collectionMembershipCache.invalidate(input.targetId);\n\t\t\t}\n\t\t});\n\t}\n\texecuteUpdateRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"UPDATE_RELATIONSHIP\", write, executing, null, null);\n\t}\n\tasync withRelationshipAction(actionTypeName, write, executing, preValidate, postWrite) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.scope !== \"document\") return buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName} must be in \"document\" scope, got \"${job.scope}\"`), startTime);\n\t\tconst input = action.input;\n\t\tif (!input.sourceId || !input.targetId || !input.relationshipType) return buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName} action requires sourceId, targetId, and relationshipType in input`), startTime);\n\t\tif (preValidate !== null) {\n\t\t\tconst validationError = preValidate(input);\n\t\t\tif (validationError !== null) return buildErrorResult(job, validationError, startTime);\n\t\t}\n\t\tlet sourceDoc;\n\t\ttry {\n\t\t\tsourceDoc = await stores.writeCache.getState(input.sourceId, \"document\", job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\tif (DocumentNotFoundError.isError(error)) return buildErrorResult(job, new DocumentNotFoundError(input.sourceId, `${actionTypeName}: source document ${input.sourceId} not found`), startTime);\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName}: source document ${input.sourceId} not found: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, getNextIndexForScope(sourceDoc, job.scope), skip, {\n\t\t\tdocumentId: input.sourceId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: input.sourceId,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tsourceDoc.header.lastModifiedAtUtcIso = operation.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString();\n\t\tupdateDocumentRevision(sourceDoc, job.scope, operation.index);\n\t\tsourceDoc.operations = {\n\t\t\t...sourceDoc.operations,\n\t\t\t[job.scope]: [...sourceDoc.operations[job.scope] ?? [], operation]\n\t\t};\n\t\tconst scopeState = sourceDoc.state[job.scope];\n\t\tconst resultingStateObj = {\n\t\t\theader: structuredClone(sourceDoc.header),\n\t\t\t[job.scope]: scopeState === void 0 ? {} : structuredClone(scopeState)\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\texecuting.touchedStreams.add(input.sourceId, job.scope, job.branch);\n\t\texecuting.touchedStreams.add(input.targetId, job.scope, job.branch);\n\t\tstores.writeCache.putState(input.sourceId, job.scope, job.branch, operation.index, sourceDoc, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: input.sourceId,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tif (postWrite !== null) postWrite({\n\t\t\tindexTxn,\n\t\t\tstores,\n\t\t\tsourceDoc,\n\t\t\tinput,\n\t\t\tjob\n\t\t});\n\t\tstores.documentMetaCache.putDocumentMeta(input.sourceId, job.branch, {\n\t\t\tstate: sourceDoc.state.document,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, input.sourceId, sourceDoc.header.documentType, resultingState, startTime);\n\t}\n\tasync writeOperationToStore(target, operation, executing) {\n\t\tconst { documentId, documentType, scope, branch } = target;\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\texecuting.touchedStreams.add(documentId, scope, branch);\n\t\tlet storedOperations;\n\t\ttry {\n\t\t\tstoredOperations = await stores.operationStore.apply(documentId, documentType, scope, branch, operation.index, (txn) => {\n\t\t\t\ttxn.addOperations(operation);\n\t\t\t}, signal);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to write operation to IOperationStore (@documentId @scope @branch): @Operation @Error\", documentId, scope, branch, operation, error);\n\t\t\tstores.writeCache.invalidate(documentId, scope, branch);\n\t\t\tif (AppendConditionFailedError.isError(error)) for (const stream of error.condition.streams) stores.writeCache.invalidate(stream.documentId, stream.scope, stream.branch);\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(`Failed to write operation to IOperationStore: ${String(error)}`),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\treturn storedOperations;\n\t}\n};\n//#endregion\n//#region src/executor/signature-verifier.ts\nvar SignatureVerifier = class {\n\tconstructor(verifier) {\n\t\tthis.verifier = verifier;\n\t}\n\tasync verifyActions(documentId, branch, actions) {\n\t\tif (!this.verifier) return;\n\t\tfor (const action of actions) {\n\t\t\tconst signer = action.context?.signer;\n\t\t\tif (!signer) continue;\n\t\t\tif (signer.signatures.length === 0) throw new InvalidSignatureError(documentId, `Action ${action.id} has signer but no signatures`);\n\t\t\tconst publicKey = signer.app.key;\n\t\t\tlet isValid;\n\t\t\ttry {\n\t\t\t\tconst tempOperation = {\n\t\t\t\t\tid: deriveOperationId(documentId, action.scope, branch, action.id),\n\t\t\t\t\tindex: 0,\n\t\t\t\t\ttimestampUtcMs: action.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString(),\n\t\t\t\t\thash: \"\",\n\t\t\t\t\tskip: 0,\n\t\t\t\t\taction\n\t\t\t\t};\n\t\t\t\tisValid = await this.verifier(tempOperation, publicKey);\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new InvalidSignatureError(documentId, `Action ${action.id} verification failed: ${errorMessage}`);\n\t\t\t}\n\t\t\tif (!isValid) throw new InvalidSignatureError(documentId, `Action ${action.id} signature verification returned false`);\n\t\t}\n\t}\n\tasync verifyOperations(documentId, operations) {\n\t\tif (!this.verifier) return;\n\t\tfor (let i = 0; i < operations.length; i++) {\n\t\t\tconst operation = operations[i];\n\t\t\tconst signer = operation.action.context?.signer;\n\t\t\tif (!signer) continue;\n\t\t\tif (signer.signatures.length === 0) throw new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} has signer but no signatures`);\n\t\t\tconst publicKey = signer.app.key;\n\t\t\tlet isValid;\n\t\t\ttry {\n\t\t\t\tisValid = await this.verifier(operation, publicKey);\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} verification failed: ${errorMessage}`);\n\t\t\t}\n\t\t\tif (!isValid) throw new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} signature verification returned false`);\n\t\t}\n\t}\n};\n//#endregion\n//#region src/executor/simple-job-executor.ts\nconst MAX_SKIP_THRESHOLD = 1e3;\nconst ISO_TIMESTAMP_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$/;\nfunction isValidISOTimestamp(value) {\n\tif (!ISO_TIMESTAMP_REGEX.test(value)) return false;\n\treturn !isNaN(new Date(value).getTime());\n}\n/**\n* Carries a failed job out of the execution scope so its transaction rolls\n* back. A scope callback that returns commits, whatever result it returns, so\n* a returned failure would leave the writes the job made before it failed\n* standing. Never escapes executeJob: the failure goes back to being a\n* returned JobResult there, which is what the queue, the worker protocol and\n* every test expect a failed job to look like.\n*/\nvar JobRollbackSignal = class extends Error {\n\tconstructor(result) {\n\t\tsuper(\"job rolled back\");\n\t\tthis.result = result;\n\t\tthis.name = \"JobRollbackSignal\";\n\t}\n};\nvar SimpleJobExecutor = class {\n\tconfig;\n\tfeatureFlags;\n\tdecisionModel;\n\tsignatureVerifierModule;\n\tdocumentActionHandler;\n\texecutionScope;\n\tconstructor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes, config, signatureVerifier, executionScope) {\n\t\tthis.logger = logger;\n\t\tthis.registry = registry;\n\t\tthis.operationStore = operationStore;\n\t\tthis.eventBus = eventBus;\n\t\tthis.writeCache = writeCache;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t\tthis.driveContainerTypes = driveContainerTypes;\n\t\tthis.config = {\n\t\t\tfeatureFlags: config.featureFlags ?? {},\n\t\t\tmaxSkipThreshold: config.maxSkipThreshold ?? MAX_SKIP_THRESHOLD,\n\t\t\tmaxConcurrency: config.maxConcurrency ?? 1,\n\t\t\tjobTimeoutMs: config.jobTimeoutMs ?? 3e4,\n\t\t\tdeferredJobTtlMs: config.deferredJobTtlMs ?? 3e4,\n\t\t\tretryBaseDelayMs: config.retryBaseDelayMs ?? 100,\n\t\t\tretryMaxDelayMs: config.retryMaxDelayMs ?? 5e3,\n\t\t\tyieldDeadlineMs: config.yieldDeadlineMs ?? 50,\n\t\t\tbatchApplies: config.batchApplies ?? true\n\t\t};\n\t\tthis.featureFlags = resolveFeatureFlags(config.featureFlags);\n\t\tthis.decisionModel = selectDecisionModel(this.featureFlags, registry);\n\t\tthis.signatureVerifierModule = new SignatureVerifier(signatureVerifier);\n\t\tthis.documentActionHandler = new DocumentActionHandler(registry, logger, driveContainerTypes, this.featureFlags, this.decisionModel);\n\t\tthis.executionScope = executionScope ?? new DefaultExecutionScope(operationStore, operationIndex, writeCache, documentMetaCache, collectionMembershipCache);\n\t}\n\t/**\n\t* Execute a single job by applying all its actions through the appropriate reducers.\n\t* Actions are processed sequentially in order.\n\t*\n\t* The whole job runs inside one execution scope, and a scope callback that\n\t* returns commits. A failed job must therefore leave the scope by throwing,\n\t* or the writes it made before it failed would be durable: JobRollbackSignal\n\t* carries the failure out through the transaction and this method turns it\n\t* back into the returned JobResult every caller expects. A job either fully\n\t* applies or leaves nothing durable behind.\n\t*\n\t* Durable is the whole of the guarantee. The caches are shared with the\n\t* copies the scope hands the job, so a failed job's writes sit in them from\n\t* the moment it makes them until the eviction below, and a concurrent read\n\t* in that window sees a write that is never going to commit. The window is\n\t* not new -- it has always been there for a job that failed by throwing --\n\t* but nothing here closes it, and a caller that needs to know a write is\n\t* real has the job status to ask.\n\t*/\n\tasync executeJob(job, signal) {\n\t\tconst startTime = Date.now();\n\t\tconst touchedStreams = new TouchedStreams();\n\t\tconst postCommitInvalidations = [];\n\t\tconst postCommitMembershipInvalidations = [];\n\t\tlet outcome;\n\t\ttry {\n\t\t\toutcome = await this.executionScope.run(async (stores) => {\n\t\t\t\tconst scoped = await this.executeInScope({\n\t\t\t\t\tjob,\n\t\t\t\t\tstartTime,\n\t\t\t\t\tstores,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttouchedStreams,\n\t\t\t\t\tpostCommitInvalidations,\n\t\t\t\t\tpostCommitMembershipInvalidations\n\t\t\t\t});\n\t\t\t\tif (!scoped.result.success) throw new JobRollbackSignal(scoped.result);\n\t\t\t\treturn scoped;\n\t\t\t}, signal);\n\t\t} catch (error) {\n\t\t\tthis.evictTouchedStreams(touchedStreams);\n\t\t\tif (error instanceof JobRollbackSignal) return error.result;\n\t\t\tthrow error;\n\t\t}\n\t\tfor (const entry of postCommitInvalidations) this.writeCache.invalidate(entry.documentId, entry.scope, entry.branch);\n\t\tfor (const documentId of postCommitMembershipInvalidations) this.collectionMembershipCache.invalidate(documentId);\n\t\tconst { pendingEvent } = outcome;\n\t\tif (pendingEvent) this.eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, pendingEvent).catch((error) => {\n\t\t\tthis.logger.error(\"Failed to emit JOB_WRITE_READY event: @Event : @Error\", pendingEvent, error);\n\t\t});\n\t\treturn outcome.result;\n\t}\n\t/**\n\t* The body of a job, run inside the execution scope's transaction.\n\t*\n\t* The stores and caches it works through are the copies scoped to that\n\t* transaction, so nothing it does is durable until the scope commits. The\n\t* write-ready event is handed back rather than emitted, because a job that\n\t* has not committed yet has nothing to announce.\n\t*/\n\tasync executeInScope(params) {\n\t\tconst { job, startTime, stores, signal, touchedStreams, postCommitInvalidations, postCommitMembershipInvalidations } = params;\n\t\tlet pendingEvent;\n\t\tconst indexTxn = stores.operationIndex.start();\n\t\tif (job.kind === \"load\") {\n\t\t\tconst loadResult = await this.executeLoadJob({\n\t\t\t\tjob,\n\t\t\t\tstartTime,\n\t\t\t\tindexTxn,\n\t\t\t\tstores,\n\t\t\t\tsignal,\n\t\t\t\treplayingAcceptedHistory: true,\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\tpostCommitInvalidations,\n\t\t\t\tpostCommitMembershipInvalidations,\n\t\t\t\ttouchedStreams\n\t\t\t});\n\t\t\tif (loadResult.success && loadResult.operationsWithContext) {\n\t\t\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\t\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\t\t\tfor (let i = 0; i < loadResult.operationsWithContext.length; i++) loadResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\t\tconst collectionMemberships = loadResult.operationsWithContext.length > 0 ? await this.getCollectionMembershipsForOperations(loadResult.operationsWithContext, stores) : {};\n\t\t\t\tpendingEvent = {\n\t\t\t\t\tjobId: job.id,\n\t\t\t\t\toperations: loadResult.operationsWithContext,\n\t\t\t\t\tjobMeta: job.meta,\n\t\t\t\t\tcollectionMemberships\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult: loadResult,\n\t\t\t\tpendingEvent\n\t\t\t};\n\t\t}\n\t\tif (job.kind === \"reevaluation\") {\n\t\t\tconst reevalResult = await this.executeReevaluationJob({\n\t\t\t\tjob,\n\t\t\t\tstartTime,\n\t\t\t\tindexTxn,\n\t\t\t\tstores,\n\t\t\t\tsignal,\n\t\t\t\treplayingAcceptedHistory: false,\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\tpostCommitInvalidations,\n\t\t\t\tpostCommitMembershipInvalidations,\n\t\t\t\ttouchedStreams\n\t\t\t});\n\t\t\tif (reevalResult.success && reevalResult.operationsWithContext) {\n\t\t\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\t\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\t\t\tfor (let i = 0; i < reevalResult.operationsWithContext.length; i++) reevalResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\t\tif (reevalResult.operationsWithContext.length > 0) {\n\t\t\t\t\tconst collectionMemberships = await this.getCollectionMembershipsForOperations(reevalResult.operationsWithContext, stores);\n\t\t\t\t\tpendingEvent = {\n\t\t\t\t\t\tjobId: job.id,\n\t\t\t\t\t\toperations: reevalResult.operationsWithContext,\n\t\t\t\t\t\tjobMeta: job.meta,\n\t\t\t\t\t\tcollectionMemberships\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult: reevalResult,\n\t\t\t\tpendingEvent\n\t\t\t};\n\t\t}\n\t\tconst positioned = await this.positionByTimestamp(job, stores, signal);\n\t\tif (positioned.error) return { result: buildErrorResult(job, positioned.error, startTime) };\n\t\tconst executing = {\n\t\t\tjob,\n\t\t\tstartTime,\n\t\t\tindexTxn,\n\t\t\tstores,\n\t\t\tsignal,\n\t\t\treplayingAcceptedHistory: false,\n\t\t\tevaluatedByPosition: positioned.evaluatedByPosition,\n\t\t\tpostCommitInvalidations,\n\t\t\tpostCommitMembershipInvalidations,\n\t\t\ttouchedStreams\n\t\t};\n\t\tconst actionResult = await this.processActions(positioned.writes, executing);\n\t\tif (!actionResult.success) return { result: {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: actionResult.error,\n\t\t\tduration: Date.now() - startTime\n\t\t} };\n\t\tconst reevaluationError = await this.reevaluateIfCriteriaMet({\n\t\t\tscope: job.scope,\n\t\t\toperations: actionResult.generatedOperations\n\t\t}, executing);\n\t\tif (reevaluationError) return { result: {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: reevaluationError,\n\t\t\tduration: Date.now() - startTime\n\t\t} };\n\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\tif (actionResult.operationsWithContext.length > 0) {\n\t\t\tfor (let i = 0; i < actionResult.operationsWithContext.length; i++) actionResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\tconst collectionMemberships = await this.getCollectionMembershipsForOperations(actionResult.operationsWithContext, stores);\n\t\t\tpendingEvent = {\n\t\t\t\tjobId: job.id,\n\t\t\t\toperations: actionResult.operationsWithContext,\n\t\t\t\tjobMeta: job.meta,\n\t\t\t\tcollectionMemberships\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tresult: {\n\t\t\t\tjob,\n\t\t\t\tsuccess: true,\n\t\t\t\toperations: actionResult.generatedOperations,\n\t\t\t\toperationsWithContext: actionResult.operationsWithContext,\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t},\n\t\t\tpendingEvent\n\t\t};\n\t}\n\t/**\n\t* Drops the cached state of every stream a job wrote, after its transaction\n\t* did not commit.\n\t*\n\t* The caches are shared by reference with the copies the scope hands the job,\n\t* so a rollback undoes nothing in them: what the job put there survives, as\n\t* does anything a read filled from the store while the job's own writes were\n\t* still uncommitted. An eviction that throws is swallowed rather than allowed\n\t* to replace the failure the caller is owed, and the remaining streams are\n\t* still evicted.\n\t*/\n\tevictTouchedStreams(touchedStreams) {\n\t\tfor (const entry of touchedStreams) try {\n\t\t\tthis.writeCache.invalidate(entry.documentId, entry.scope, entry.branch);\n\t\t\tthis.documentMetaCache.invalidate(entry.documentId, entry.branch);\n\t\t\tthis.collectionMembershipCache.invalidate(entry.documentId);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to evict cached state for rolled back @Stream : @Error\", entry, error);\n\t\t}\n\t}\n\tasync getCollectionMembershipsForOperations(operations, stores) {\n\t\tconst documentIds = [...new Set(operations.map((op) => op.context.documentId))];\n\t\treturn stores.collectionMembershipCache.getCollectionsForDocuments(documentIds);\n\t}\n\tasync processActions(writes, executing) {\n\t\tconst { job, signal } = executing;\n\t\tconst actions = writes.map((write) => write.action);\n\t\tconst generatedOperations = [];\n\t\tconst operationsWithContext = [];\n\t\ttry {\n\t\t\tawait this.signatureVerifierModule.verifyActions(job.documentId, job.branch, actions);\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t};\n\t\t}\n\t\tfor (const action of actions) if (action.timestampUtcMs && !isValidISOTimestamp(action.timestampUtcMs)) return {\n\t\t\tsuccess: false,\n\t\t\tgeneratedOperations,\n\t\t\toperationsWithContext,\n\t\t\terror: new InvalidOperationTimestampError(job.documentId, action.scope, action.timestampUtcMs, `action ${action.type} (id: ${action.id})`)\n\t\t};\n\t\tlet lastYield = performance.now();\n\t\tif (this.config.batchApplies && this.canBatch(writes, executing)) {\n\t\t\tconst batched = await this.executeRegularActionsBatched(writes, executing);\n\t\t\tconst error = this.accumulateResultOrReturnError(batched, generatedOperations, operationsWithContext);\n\t\t\tif (error !== null) return {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error.error\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext\n\t\t\t};\n\t\t}\n\t\tfor (const write of writes) {\n\t\t\tconst result = DOCUMENT_SCOPE_ACTIONS.has(write.action.type) ? await this.documentActionHandler.execute(write, executing) : await this.executeRegularAction(write, executing);\n\t\t\tconst error = this.accumulateResultOrReturnError(result, generatedOperations, operationsWithContext);\n\t\t\tif (error !== null) return {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error.error\n\t\t\t};\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (signal?.aborted) return {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tgeneratedOperations,\n\t\t\t\t\toperationsWithContext,\n\t\t\t\t\terror: /* @__PURE__ */ new Error(\"Aborted\")\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tgeneratedOperations,\n\t\t\toperationsWithContext\n\t\t};\n\t}\n\t/**\n\t* Decides a write and reduces it, without persisting anything.\n\t*\n\t* Split from the commit so one write and a batch of them share this logic\n\t* rather than keeping two copies of it. `baseDocument` lets a batch thread\n\t* the previous action's result forward instead of reading its own write back\n\t* out of the cache, which is the only reason the reduce has to be sequential.\n\t*/\n\tasync prepareRegularWrite(write, executing, baseDocument) {\n\t\tconst { action, skip, sourceOperation, sourceRemote, deniedReason } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tlet appendCondition;\n\t\tlet documentVersion;\n\t\tconst alreadyEvaluated = this.featureFlags.documentDecisions && (executing.replayingAcceptedHistory || executing.evaluatedByPosition);\n\t\tif (this.featureFlags.documentDecisions && !alreadyEvaluated) {\n\t\t\tconst target = {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tbranch: job.branch\n\t\t\t};\n\t\t\tlet admission;\n\t\t\ttry {\n\t\t\t\tadmission = await decideAtHead(this.decisionModel, stores.writeCache, target, {\n\t\t\t\t\taddress: action.context?.signer?.user.address,\n\t\t\t\t\tkey: action.context?.signer?.app.key\n\t\t\t\t}, {\n\t\t\t\t\tverb: \"execute\",\n\t\t\t\t\tscope: action.scope,\n\t\t\t\t\toperation: action.type\n\t\t\t\t}, signal, this.featureFlags.authConditions ? {\n\t\t\t\t\tactionInput: action.input,\n\t\t\t\t\tcarriedDocument: baseDocument\n\t\t\t\t} : void 0);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tif (admission.evaluation.decision === \"deny\") return buildErrorResult(job, refusalError(admission.evaluation.reason, job.documentId, admission.deletedAtUtcIso, action), startTime);\n\t\t\tappendCondition = admission.appendCondition;\n\t\t\tdocumentVersion = admission.documentVersion;\n\t\t} else if (alreadyEvaluated) documentVersion = (await stores.writeCache.getState(job.documentId, \"document\", job.branch, void 0, signal)).state.document.version;\n\t\telse {\n\t\t\tlet docMeta;\n\t\t\ttry {\n\t\t\t\tdocMeta = await stores.documentMetaCache.getDocumentMeta(job.documentId, job.branch, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tif (docMeta.state.isDeleted) return buildErrorResult(job, new DocumentDeletedError(job.documentId, docMeta.state.deletedAtUtcIso), startTime);\n\t\t\tdocumentVersion = docMeta.state.version;\n\t\t}\n\t\tif (isUndoRedo(action) || action.type === \"PRUNE\" || skip > 0) stores.writeCache.invalidate(job.documentId, job.scope, job.branch);\n\t\tlet document;\n\t\tif (baseDocument !== void 0) document = baseDocument;\n\t\telse try {\n\t\t\tdocument = await stores.writeCache.getState(job.documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tif (!this.featureFlags.authEnforcement && !executing.replayingAcceptedHistory) {\n\t\t\tconst subject = {\n\t\t\t\taddress: write.action.context?.signer?.user.address,\n\t\t\t\tkey: write.action.context?.signer?.app.key\n\t\t\t};\n\t\t\tif (decide(document.state.auth, subject, {\n\t\t\t\tverb: \"execute\",\n\t\t\t\tscope: action.scope,\n\t\t\t\toperation: action.type\n\t\t\t}) === \"deny\") return buildErrorResult(job, new AuthorizationDeniedError(job.documentId, action.scope, action.type, subject.address), startTime);\n\t\t}\n\t\tlet module;\n\t\ttry {\n\t\t\tmodule = this.registry.getModule(document.header.documentType, normalizeDocumentModelVersion(documentVersion));\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet updatedDocument;\n\t\tif (deniedReason !== void 0) {\n\t\t\tconst index = getNextIndexForScope(document, job.scope);\n\t\t\tconst denied = createOperation(action, index, skip, {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tscope: job.scope,\n\t\t\t\tbranch: job.branch\n\t\t\t});\n\t\t\tdenied.deniedReason = deniedReason;\n\t\t\tlet standing = document;\n\t\t\tif (skip > 0) try {\n\t\t\t\tstanding = await stores.writeCache.getState(job.documentId, job.scope, job.branch, index - skip - 1, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tdenied.hash = hashDocumentStateForScope(standing, job.scope);\n\t\t\tupdatedDocument = {\n\t\t\t\t...standing,\n\t\t\t\toperations: {\n\t\t\t\t\t...standing.operations,\n\t\t\t\t\t[job.scope]: [...standing.operations[job.scope] ?? [], denied]\n\t\t\t\t}\n\t\t\t};\n\t\t} else try {\n\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\tconst reducerOptions = sourceOperation ? {\n\t\t\t\tskip,\n\t\t\t\tbranch: job.branch,\n\t\t\t\treplayOptions: { operation: sourceOperation },\n\t\t\t\tprotocolVersion\n\t\t\t} : {\n\t\t\t\tskip,\n\t\t\t\tbranch: job.branch,\n\t\t\t\tprotocolVersion\n\t\t\t};\n\t\t\tupdatedDocument = module.reducer(document, action, void 0, reducerOptions);\n\t\t} catch (error) {\n\t\t\tconst contextMessage = `Failed to apply action to document:\\n Action type: ${action.type}\\n Document ID: ${job.documentId}\\n Document type: ${document.header.documentType}\\n Scope: ${job.scope}\\n Original error: ${error instanceof Error ? error.message : String(error)}`;\n\t\t\tconst enhancedError = new Error(contextMessage);\n\t\t\tif (error instanceof Error && error.stack) enhancedError.stack = `${contextMessage}\\n\\nOriginal stack trace:\\n${error.stack}`;\n\t\t\treturn buildErrorResult(job, enhancedError, startTime);\n\t\t}\n\t\tconst scope = job.scope;\n\t\tconst operations = updatedDocument.operations[scope];\n\t\tif (operations.length === 0) return buildErrorResult(job, /* @__PURE__ */ new Error(\"No operation generated from action\"), startTime);\n\t\tconst newOperation = operations[operations.length - 1];\n\t\tif (!isUndoRedo(action)) newOperation.skip = skip;\n\t\tconst resultingState = JSON.stringify({\n\t\t\t...updatedDocument.state,\n\t\t\theader: updatedDocument.header\n\t\t});\n\t\treturn {\n\t\t\taction,\n\t\t\tsourceRemote,\n\t\t\tscope,\n\t\t\tdocument,\n\t\t\tupdatedDocument,\n\t\t\toperation: newOperation,\n\t\t\tresultingState,\n\t\t\tappendCondition,\n\t\t\tdenied: deniedReason !== void 0\n\t\t};\n\t}\n\t/**\n\t* Persists a run of prepared writes in one store transaction.\n\t*\n\t* The store has always accepted many operations per apply; the executor only\n\t* ever handed it one. Passing the whole run means one advisory lock over the\n\t* read set and one guarded insert for the batch, instead of one of each per\n\t* operation.\n\t*\n\t* The append condition is taken from the first write. Every write in a run\n\t* reads the same streams at the same revisions, because nothing outside the\n\t* run can change them mid-batch, and the caller has already refused to batch\n\t* the scopes where that does not hold.\n\t*/\n\tasync commitPreparedWrites(prepared, executing) {\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst first = prepared[0];\n\t\tconst last = prepared[prepared.length - 1];\n\t\tconst scope = first.scope;\n\t\tconst documentType = first.document.header.documentType;\n\t\tconst operations = prepared.map((write) => write.operation);\n\t\texecuting.touchedStreams.add(job.documentId, scope, job.branch);\n\t\tlet storedOperations;\n\t\ttry {\n\t\t\tstoredOperations = await stores.operationStore.apply(job.documentId, documentType, scope, job.branch, first.operation.index, (txn) => {\n\t\t\t\ttxn.addOperations(...operations);\n\t\t\t}, signal, first.appendCondition);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to write operation to IOperationStore (@documentId @scope @branch): @Operation @Error\", job.documentId, scope, job.branch, operations, error);\n\t\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\t\tif (AppendConditionFailedError.isError(error)) for (const stream of error.condition.streams) stores.writeCache.invalidate(stream.documentId, stream.scope, stream.branch);\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(`Failed to write operation to IOperationStore: ${String(error)}`),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst head = storedOperations[storedOperations.length - 1];\n\t\tlast.updatedDocument.header.revision = {\n\t\t\t...last.updatedDocument.header.revision,\n\t\t\t[scope]: head.index + 1\n\t\t};\n\t\tstores.writeCache.putRun(job.documentId, scope, job.branch, storedOperations.map((operation, position) => ({\n\t\t\trevision: operation.index,\n\t\t\tdocument: prepared[position].updatedDocument\n\t\t})));\n\t\tindexTxn.write(storedOperations.map((operation, position) => ({\n\t\t\t...operation,\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope,\n\t\t\tsourceRemote: prepared[position].sourceRemote\n\t\t})));\n\t\tif (scope === \"auth\") for (const write of prepared) indexTxn.recordGroupReferences(job.documentId, mentionedGroupIds(write.action));\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: storedOperations,\n\t\t\toperationsWithContext: storedOperations.map((operation, position) => ({\n\t\t\t\toperation,\n\t\t\t\tcontext: {\n\t\t\t\t\tdocumentId: job.documentId,\n\t\t\t\t\tscope,\n\t\t\t\t\tbranch: job.branch,\n\t\t\t\t\tdocumentType,\n\t\t\t\t\tresultingState: prepared[position].resultingState,\n\t\t\t\t\tordinal: 0\n\t\t\t\t}\n\t\t\t})),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\t/**\n\t* Whether a job's writes may share one store transaction.\n\t*\n\t* Deliberately narrow. Batching changes only how many transactions the\n\t* operations arrive in, and every condition below is a case where that would\n\t* change something else as well:\n\t*\n\t* - A document-scope action goes through its own handler, which has its own\n\t* apply and its own reasons for it.\n\t* - A positional or replayed run carries skips and re-appended operations,\n\t* whose indices are not a simple ascending run from the head.\n\t* - UNDO, REDO, PRUNE and NOOP-with-skip each invalidate the write cache to\n\t* force a full-history rebuild, so they cannot be reduced against state\n\t* threaded from the write before them.\n\t* - The auth scope decides later writes against the policy earlier ones\n\t* install, so a batch would decide them all against the policy as it stood\n\t* before the batch.\n\t* - The document scope is read by every decision model, so writing it is\n\t* writing part of the read set; the per-write conditions would not agree.\n\t*\n\t* A run that fails any of these is executed one write at a time, unchanged.\n\t*/\n\tcanBatch(writes, executing) {\n\t\tif (writes.length < 2) return false;\n\t\tif (executing.evaluatedByPosition || executing.replayingAcceptedHistory) return false;\n\t\tconst scope = executing.job.scope;\n\t\tif (scope === \"auth\" || scope === \"document\") return false;\n\t\treturn writes.every((write) => {\n\t\t\tconst type = write.action.type;\n\t\t\treturn write.skip === 0 && write.deniedReason === void 0 && write.sourceOperation === void 0 && !DOCUMENT_SCOPE_ACTIONS.has(type) && !isUndoRedo(write.action) && type !== \"PRUNE\" && type !== \"NOOP\";\n\t\t});\n\t}\n\t/**\n\t* Decides and reduces a run of writes, then persists them together.\n\t*\n\t* The reduce stays sequential - each action needs the state the one before it\n\t* produced - but the result is threaded in memory rather than read back from\n\t* the cache, and the whole run reaches the store in a single apply.\n\t*\n\t* A write that turns out to be denied abandons the batch and replays the run\n\t* one write at a time, because a denied write holds a position of its own and\n\t* that is the path where the per-write behaviour is load-bearing. A write\n\t* that cannot be prepared fails the job outright: preparing is a read, so the\n\t* replay would only reach the same failure, and the job leaves nothing behind\n\t* either way.\n\t*/\n\tasync executeRegularActionsBatched(writes, executing) {\n\t\tconst prepared = [];\n\t\tlet carried;\n\t\tlet lastYield = performance.now();\n\t\tfor (const write of writes) {\n\t\t\tconst outcome = await this.prepareRegularWrite(write, executing, carried);\n\t\t\tif (\"success\" in outcome) return outcome;\n\t\t\tif (outcome.denied) return this.executeRegularActionsSequentially(writes, executing);\n\t\t\tprepared.push(outcome);\n\t\t\tcarried = outcome.updatedDocument;\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (executing.signal?.aborted) return buildErrorResult(executing.job, /* @__PURE__ */ new Error(\"Aborted\"), executing.startTime);\n\t\t\t}\n\t\t}\n\t\tif (!this.conditionsAgree(prepared)) return this.executeRegularActionsSequentially(writes, executing);\n\t\treturn this.commitPreparedWrites(prepared, executing);\n\t}\n\t/** Whether every prepared write carries the same read-set condition. */\n\tconditionsAgree(prepared) {\n\t\tconst shape = (write) => write.appendCondition === void 0 ? \"none\" : JSON.stringify([...write.appendCondition.streams].map((stream) => [\n\t\t\tstream.documentId,\n\t\t\tstream.scope,\n\t\t\tstream.branch,\n\t\t\tstream.revision\n\t\t]).sort());\n\t\tconst first = shape(prepared[0]);\n\t\treturn prepared.every((write) => shape(write) === first);\n\t}\n\t/**\n\t* The unbatched path, for a run that turned out not to qualify after its\n\t* writes were prepared. Nothing has been persisted at that point, so\n\t* replaying the whole run per write is safe.\n\t*/\n\tasync executeRegularActionsSequentially(writes, executing) {\n\t\tconst operations = [];\n\t\tconst contexts = [];\n\t\tlet lastYield = performance.now();\n\t\tfor (const write of writes) {\n\t\t\tconst result = await this.executeRegularAction(write, executing);\n\t\t\tif (!result.success) return result;\n\t\t\toperations.push(...result.operations ?? []);\n\t\t\tcontexts.push(...result.operationsWithContext ?? []);\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (executing.signal?.aborted) return buildErrorResult(executing.job, /* @__PURE__ */ new Error(\"Aborted\"), executing.startTime);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tjob: executing.job,\n\t\t\tsuccess: true,\n\t\t\toperations,\n\t\t\toperationsWithContext: contexts,\n\t\t\tduration: Date.now() - executing.startTime\n\t\t};\n\t}\n\t/** Decides, reduces and persists one write. */\n\tasync executeRegularAction(write, executing) {\n\t\tconst prepared = await this.prepareRegularWrite(write, executing);\n\t\tif (\"success\" in prepared) return prepared;\n\t\treturn this.commitPreparedWrites([prepared], executing);\n\t}\n\t/**\n\t* Orders a write by timestamp and decides it where it lands. The caller\n\t* supplies the timestamp, so a write can belong before operations already\n\t* stored; those are re-appended alongside it, the way a load reshuffles.\n\t*\n\t* Deciding a backdated write at the stream heads instead of at its position\n\t* would overwrite the verdict every other replica computes for it.\n\t*/\n\tasync positionByTimestamp(job, stores, signal) {\n\t\tconst plain = () => ({\n\t\t\twrites: job.actions.map((action) => ({\n\t\t\t\taction,\n\t\t\t\tskip: 0,\n\t\t\t\tsourceRemote: \"\"\n\t\t\t})),\n\t\t\tevaluatedByPosition: false\n\t\t});\n\t\tif (!this.featureFlags.documentDecisions || job.actions.length === 0) return plain();\n\t\tlet earliest = job.actions[0].timestampUtcMs;\n\t\tlet earliestAt = Date.parse(earliest);\n\t\tfor (const action of job.actions) {\n\t\t\tconst at = Date.parse(action.timestampUtcMs);\n\t\t\tif (at < earliestAt) {\n\t\t\t\tearliest = action.timestampUtcMs;\n\t\t\t\tearliestAt = at;\n\t\t\t}\n\t\t}\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tconst backdated = earliestAt < Date.parse(revisions.latestTimestamp);\n\t\tif (this.featureFlags.authEnforcement && job.scope === \"auth\") {\n\t\t\tconst newest = await stores.operationStore.getStreamLatestTimestamp(job.documentId, \"auth\", job.branch, signal);\n\t\t\tconst violation = this.firstNonMonotonicTimestamp(job.actions, newest, job.documentId, job.branch);\n\t\t\tif (violation) return {\n\t\t\t\twrites: [],\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\terror: violation\n\t\t\t};\n\t\t\tif (!backdated) return plain();\n\t\t\treturn this.evaluatePositioned(job, stores, this.appendedOperations(job, revisions.revision[job.scope] ?? 0), signal);\n\t\t}\n\t\tif (!backdated) return plain();\n\t\tconst conflicting = (await stores.operationStore.getConflicting(job.documentId, job.scope, job.branch, earliest, void 0, signal)).results.filter((operation) => !isGenesisOperation(operation));\n\t\tif (conflicting.length === 0) {\n\t\t\tif (!this.featureFlags.authEnforcement) return plain();\n\t\t\treturn this.evaluatePositioned(job, stores, this.appendedOperations(job, revisions.revision[job.scope] ?? 0), signal);\n\t\t}\n\t\tconst nextIndex = revisions.revision[job.scope] ?? 0;\n\t\tlet firstConflicting = conflicting[0].index;\n\t\tfor (const operation of conflicting) if (operation.index < firstConflicting) firstConflicting = operation.index;\n\t\tconst incoming = job.actions.map((action, i) => ({\n\t\t\tid: action.id,\n\t\t\tindex: nextIndex + i,\n\t\t\tskip: 0,\n\t\t\thash: \"\",\n\t\t\ttimestampUtcMs: action.timestampUtcMs,\n\t\t\taction\n\t\t}));\n\t\tconst merged = reshuffleByTimestamp({\n\t\t\tindex: nextIndex,\n\t\t\tskip: retractionSkip(nextIndex, firstConflicting)\n\t\t}, conflicting, incoming);\n\t\tstores.writeCache.invalidate(job.documentId, job.scope, job.branch);\n\t\tif (!this.featureFlags.authEnforcement) return {\n\t\t\twrites: merged.map((operation) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: operation.skip,\n\t\t\t\tsourceRemote: \"\"\n\t\t\t})),\n\t\t\tevaluatedByPosition: false\n\t\t};\n\t\treturn this.evaluatePositioned(job, stores, merged, signal);\n\t}\n\t/**\n\t* Decides each operation where it lands and carries the verdict on it. A\n\t* refused submitted action is reported to the caller and nothing is stored; a\n\t* refused operation the reshuffle merely moved keeps its verdict, because it\n\t* already holds a position.\n\t*\n\t* The operations carry the indexes and skips they will be stored at, because\n\t* the walk resolves skips before it orders them.\n\t*/\n\tasync evaluatePositioned(job, stores, operations, signal) {\n\t\tconst reasons = await evaluateByPosition(this.decisionModel, {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t}, {\n\t\t\tscope: job.scope,\n\t\t\toperations\n\t\t}, stores, signal);\n\t\tconst submitted = new Set(job.actions.map((action) => action.id));\n\t\tfor (let i = 0; i < operations.length; i++) {\n\t\t\tconst reason = reasons[i];\n\t\t\tif (reason !== void 0 && submitted.has(operations[i].action.id)) return {\n\t\t\t\twrites: [],\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\terror: refusalError(reason, job.documentId, null, operations[i].action)\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\twrites: operations.map((operation, i) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: operation.skip,\n\t\t\t\tsourceRemote: \"\",\n\t\t\t\tdeniedReason: reasons[i]\n\t\t\t})),\n\t\t\tevaluatedByPosition: true\n\t\t};\n\t}\n\t/**\n\t* The scopes a re-evaluation pass visits, in a fixed order.\n\t*\n\t* The revisions map comes from a query with no ORDER BY, and the order is\n\t* load-bearing: each scope's pass re-reads the auth stream, and the walk skips\n\t* an operation by its stored denial, so a denial this pass just wrote is\n\t* visible to a later-visited scope and invisible to an earlier one. The model's\n\t* own projection order leads, then the rest sorted, so the pass is reproducible\n\t* across replicas and across runs.\n\t*/\n\tevaluationOrder(target, revision) {\n\t\tconst definition = this.decisionModel(target);\n\t\tconst evaluated = Object.keys(revision).filter((scope) => definition.evaluatesScope(scope));\n\t\tconst leading = [];\n\t\tfor (const stream of staticReadSet(definition)) {\n\t\t\tconst scope = stream.query.scope;\n\t\t\tif (evaluated.includes(scope) && !leading.includes(scope)) leading.push(scope);\n\t\t}\n\t\tconst rest = evaluated.filter((scope) => !leading.includes(scope)).sort((a, b) => a.localeCompare(b));\n\t\treturn [...leading, ...rest];\n\t}\n\t/**\n\t* The first timestamp in the batch that does not strictly exceed everything\n\t* ahead of it, or undefined when the whole batch is monotonic.\n\t*\n\t* The bound is carried forward rather than compared against one stored maximum,\n\t* because a single execute can carry several auth actions stamped in the same\n\t* millisecond. Letting a tie through would store a stream the position walk\n\t* then refuses to read, with no repair path.\n\t*/\n\tfirstNonMonotonicTimestamp(entries, newest, documentId, branch) {\n\t\tlet boundIso = newest;\n\t\tlet bound = newest === void 0 ? Number.NEGATIVE_INFINITY : Date.parse(newest);\n\t\tfor (const entry of entries) {\n\t\t\tif (!isValidISOTimestamp(entry.timestampUtcMs)) return new InvalidOperationTimestampError(documentId, \"auth\", entry.timestampUtcMs, \"auth operation\");\n\t\t\tconst at = Date.parse(entry.timestampUtcMs);\n\t\t\tif (boundIso !== void 0 && at <= bound) return new AuthTimestampNotMonotonicError(documentId, branch, entry.timestampUtcMs, boundIso);\n\t\t\tbound = at;\n\t\t\tboundIso = entry.timestampUtcMs;\n\t\t}\n\t}\n\t/** The operations a batch of submitted actions appends at the scope's tail. */\n\tappendedOperations(job, nextIndex) {\n\t\treturn job.actions.map((action, i) => ({\n\t\t\tid: action.id,\n\t\t\tindex: nextIndex + i,\n\t\t\tskip: 0,\n\t\t\thash: \"\",\n\t\t\ttimestampUtcMs: action.timestampUtcMs,\n\t\t\taction\n\t\t}));\n\t}\n\t/**\n\t* Re-evaluates the document when a write meets both criteria: it was written\n\t* to a stream the model reads, and it is timestamped before an operation\n\t* already stored. The caller supplies the timestamp and the reactor does not replace\n\t* it, so a mutation job can write such an operation just as a load job can,\n\t* which is why both executeJob and executeLoadJob call this.\n\t*/\n\tasync reevaluateIfCriteriaMet(criteria, executing) {\n\t\tif (!this.featureFlags.documentDecisions) return;\n\t\tconst { job, stores, signal } = executing;\n\t\tconst target = {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t};\n\t\tif (!staticReadSet(this.decisionModel(target)).some((stream) => stream.query.documentId === job.documentId && stream.query.scope === criteria.scope && stream.query.branch === job.branch)) return;\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tconst latest = Date.parse(revisions.latestTimestamp);\n\t\tif (!criteria.operations.some((operation) => Date.parse(operation.timestampUtcMs) < latest)) return;\n\t\treturn (await this.reevaluateDocument(executing)).error;\n\t}\n\t/**\n\t* Re-evaluates every scope the model evaluates. Where an operation's\n\t* evaluation differs from what is stored, the tail from that operation is\n\t* re-appended, carrying a skip that spans the indices it supersedes.\n\t*/\n\tasync reevaluateDocument(executing) {\n\t\tconst { job, stores, signal } = executing;\n\t\tconst target = {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t};\n\t\tconst reappended = [];\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tfor (const scope of this.evaluationOrder(target, revisions.revision)) {\n\t\t\tconst stored = (await stores.operationStore.getSince(job.documentId, scope, job.branch, -1, void 0, void 0, signal)).results;\n\t\t\tconst effective = garbageCollect(sortOperations([...stored]));\n\t\t\tif (effective.length === 0) continue;\n\t\t\tconst reevaluated = await evaluateByPosition(this.decisionModel, target, {\n\t\t\t\tscope,\n\t\t\t\toperations: effective\n\t\t\t}, stores, signal);\n\t\t\tconst firstChange = effective.findIndex((operation, i) => operation.deniedReason !== reevaluated[i]);\n\t\t\tif (firstChange === -1) continue;\n\t\t\tconst tail = effective.slice(firstChange);\n\t\t\tconst nextIndex = revisions.revision[scope];\n\t\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\t\tconst result = await this.processActions(tail.map((operation, i) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: i === 0 ? retractionSkip(nextIndex, tail[0].index) : 0,\n\t\t\t\tsourceRemote: \"\",\n\t\t\t\tdeniedReason: reevaluated[firstChange + i]\n\t\t\t})), {\n\t\t\t\t...executing,\n\t\t\t\tjob: {\n\t\t\t\t\t...job,\n\t\t\t\t\tscope\n\t\t\t\t},\n\t\t\t\treplayingAcceptedHistory: true,\n\t\t\t\tevaluatedByPosition: true\n\t\t\t});\n\t\t\tif (!result.success) return {\n\t\t\t\terror: result.error ?? /* @__PURE__ */ new Error(`Re-evaluation of ${job.documentId} ${scope} failed`),\n\t\t\t\toperationsWithContext: reappended\n\t\t\t};\n\t\t\treappended.push(...result.operationsWithContext);\n\t\t}\n\t\treturn { operationsWithContext: reappended };\n\t}\n\t/**\n\t* Re-judges a document's stored operations because a read-set stream in\n\t* another document (a group) gained an operation. The trigger timestamp\n\t* bounds the work: an operation later than everything this document holds\n\t* cannot change any evaluation, so the pass is skipped.\n\t*/\n\tasync executeReevaluationJob(executing) {\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\tif (!this.featureFlags.documentDecisions) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst trigger = job.meta.triggerTimestampUtcMs;\n\t\tif (typeof trigger === \"string\") {\n\t\t\tlet latestTimestamp;\n\t\t\ttry {\n\t\t\t\tlatestTimestamp = (await stores.operationStore.getRevisions(job.documentId, job.branch, signal)).latestTimestamp;\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tjob,\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toperations: [],\n\t\t\t\t\toperationsWithContext: [],\n\t\t\t\t\tduration: Date.now() - startTime\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (Date.parse(trigger) > Date.parse(latestTimestamp)) return {\n\t\t\t\tjob,\n\t\t\t\tsuccess: true,\n\t\t\t\toperations: [],\n\t\t\t\toperationsWithContext: [],\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst outcome = await this.reevaluateDocument(executing);\n\t\tif (outcome.error) return buildErrorResult(job, outcome.error, startTime);\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: outcome.operationsWithContext.map((owc) => owc.operation),\n\t\t\toperationsWithContext: outcome.operationsWithContext,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\tasync executeLoadJob(executing) {\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.operations.length === 0) return buildErrorResult(job, /* @__PURE__ */ new Error(\"Load job must include at least one operation\"), startTime);\n\t\tlet docMeta;\n\t\ttry {\n\t\t\tdocMeta = await stores.documentMetaCache.getDocumentMeta(job.documentId, job.branch, signal);\n\t\t} catch {}\n\t\tif (docMeta?.state.isDeleted && !this.featureFlags.documentDecisions) return buildErrorResult(job, new DocumentDeletedError(job.documentId, docMeta.state.deletedAtUtcIso), startTime);\n\t\tconst scope = job.scope;\n\t\tconst monotonicAuthStream = this.featureFlags.authEnforcement && scope === \"auth\";\n\t\tlet latestRevision;\n\t\ttry {\n\t\t\tlatestRevision = (await stores.operationStore.getRevisions(job.documentId, job.branch, signal)).revision[scope] ?? 0;\n\t\t} catch {\n\t\t\tlatestRevision = 0;\n\t\t}\n\t\tfor (const operation of job.operations) if (operation.timestampUtcMs && !isValidISOTimestamp(operation.timestampUtcMs)) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: new InvalidOperationTimestampError(job.documentId, scope, operation.timestampUtcMs, `operation (index: ${operation.index})`),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tlet minIncomingIndex = Number.POSITIVE_INFINITY;\n\t\tlet minIncomingTimestamp = job.operations[0]?.timestampUtcMs || \"\";\n\t\tfor (const operation of job.operations) {\n\t\t\tminIncomingIndex = Math.min(minIncomingIndex, operation.index);\n\t\t\tconst ts = operation.timestampUtcMs || \"\";\n\t\t\tif (Date.parse(ts) < Date.parse(minIncomingTimestamp)) minIncomingTimestamp = ts;\n\t\t}\n\t\tlet conflictingOps;\n\t\ttry {\n\t\t\tconflictingOps = (await stores.operationStore.getConflicting(job.documentId, scope, job.branch, minIncomingTimestamp, void 0, signal)).results;\n\t\t} catch {\n\t\t\tconflictingOps = [];\n\t\t}\n\t\tlet allOpsFromMinConflictingIndex = conflictingOps;\n\t\tif (conflictingOps.length > 0) {\n\t\t\tconst minConflictingIndex = Math.min(...conflictingOps.map((op) => op.index));\n\t\t\ttry {\n\t\t\t\tallOpsFromMinConflictingIndex = (await stores.operationStore.getSince(job.documentId, scope, job.branch, minConflictingIndex - 1, void 0, void 0, signal)).results;\n\t\t\t} catch {\n\t\t\t\tallOpsFromMinConflictingIndex = conflictingOps;\n\t\t\t}\n\t\t}\n\t\tconst incomingActionIds = new Set(job.operations.map((op) => op.action.id));\n\t\tconst nonSupersededOps = conflictingOps.filter((op) => {\n\t\t\tif (op.index < minIncomingIndex && !incomingActionIds.has(op.action.id)) return false;\n\t\t\tfor (const laterOp of allOpsFromMinConflictingIndex) if (laterOp.index > op.index && laterOp.skip > 0) {\n\t\t\t\tif (laterOp.index - laterOp.skip <= op.index) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\t\tconst existingOpsToReshuffle = monotonicAuthStream ? [] : nonSupersededOps.filter((operation) => !isGenesisOperation(operation));\n\t\tconst actionIdCounts = /* @__PURE__ */ new Map();\n\t\tfor (const operation of allOpsFromMinConflictingIndex) actionIdCounts.set(operation.action.id, (actionIdCounts.get(operation.action.id) ?? 0) + 1);\n\t\tconst reshuffleCost = existingOpsToReshuffle.filter((operation) => (actionIdCounts.get(operation.action.id) ?? 0) < 2).length;\n\t\tif (reshuffleCost > this.config.maxSkipThreshold) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: new ExcessiveReshuffleError(job.documentId, scope, reshuffleCost, this.config.maxSkipThreshold),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tlet skipCount = existingOpsToReshuffle.length;\n\t\tif (existingOpsToReshuffle.length > 0) {\n\t\t\tlet minLogicalIndex = Number.POSITIVE_INFINITY;\n\t\t\tfor (const op of existingOpsToReshuffle) {\n\t\t\t\tconst logical = op.index - op.skip;\n\t\t\t\tif (logical < minLogicalIndex) minLogicalIndex = logical;\n\t\t\t}\n\t\t\tconst logicalSkip = latestRevision - minLogicalIndex;\n\t\t\tif (logicalSkip > skipCount) skipCount = logicalSkip;\n\t\t}\n\t\tconst existingActionIds = new Set(nonSupersededOps.map((op) => op.action.id));\n\t\tconst seenIncomingActionIds = /* @__PURE__ */ new Set();\n\t\tconst incomingOpsToApply = job.operations.filter((op) => {\n\t\t\tif (existingActionIds.has(op.action.id)) return false;\n\t\t\tif (seenIncomingActionIds.has(op.action.id)) return false;\n\t\t\tseenIncomingActionIds.add(op.action.id);\n\t\t\treturn true;\n\t\t});\n\t\tif (incomingOpsToApply.length === 0) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tif (monotonicAuthStream) {\n\t\t\tconst newest = await stores.operationStore.getStreamLatestTimestamp(job.documentId, \"auth\", job.branch, signal);\n\t\t\tconst violation = this.firstNonMonotonicTimestamp([...incomingOpsToApply].sort((a, b) => a.index - b.index), newest, job.documentId, job.branch);\n\t\t\tif (violation) return {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: violation,\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst reshuffledOperations = existingOpsToReshuffle.length === 0 && skipCount === 0 ? incomingOpsToApply.slice().sort((a, b) => a.index - b.index).map((operation, i) => ({\n\t\t\t...operation,\n\t\t\tindex: latestRevision + i\n\t\t})) : reshuffleByTimestamp({\n\t\t\tindex: latestRevision,\n\t\t\tskip: skipCount\n\t\t}, existingOpsToReshuffle, incomingOpsToApply.map((operation) => ({\n\t\t\t...operation,\n\t\t\tid: operation.id\n\t\t})));\n\t\tfor (const operation of reshuffledOperations) if (operation.action.type === \"NOOP\" && operation.skip === 0) operation.skip = 1;\n\t\tlet deniedReasons;\n\t\tif (this.featureFlags.documentDecisions) try {\n\t\t\tdeniedReasons = await evaluateByPosition(this.decisionModel, {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tbranch: job.branch\n\t\t\t}, {\n\t\t\t\tscope,\n\t\t\t\toperations: reshuffledOperations\n\t\t\t}, stores, signal);\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : new Error(String(error)),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst effectiveSourceRemote = skipCount > 0 ? \"\" : job.meta.sourceRemote || \"\";\n\t\tconst result = await this.processActions(reshuffledOperations.map((operation, i) => ({\n\t\t\taction: operation.action,\n\t\t\tskip: operation.skip,\n\t\t\tsourceOperation: operation,\n\t\t\tsourceRemote: effectiveSourceRemote,\n\t\t\tdeniedReason: deniedReasons?.[i]\n\t\t})), executing);\n\t\tif (!result.success) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: result.error,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\tif (scope === \"document\") stores.documentMetaCache.invalidate(job.documentId, job.branch);\n\t\tconst reevaluationError = await this.reevaluateIfCriteriaMet({\n\t\t\tscope,\n\t\t\toperations: result.generatedOperations\n\t\t}, executing);\n\t\tif (reevaluationError) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: reevaluationError,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: result.generatedOperations,\n\t\t\toperationsWithContext: result.operationsWithContext,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\taccumulateResultOrReturnError(result, generatedOperations, operationsWithContext) {\n\t\tif (!result.success) return result;\n\t\tif (result.operations && result.operations.length > 0) generatedOperations.push(...result.operations);\n\t\tif (result.operationsWithContext) operationsWithContext.push(...result.operationsWithContext);\n\t\treturn null;\n\t}\n};\n//#endregion\n//#region src/registry/implementation.ts\n/**\n* In-memory implementation of the IDocumentModelRegistry interface.\n* Manages document model modules with version-aware storage and upgrade manifest support.\n*/\nvar DocumentModelRegistry = class {\n\tmodules = [];\n\tmanifests = [];\n\tregisterModules(...modules) {\n\t\treturn modules.map((module) => {\n\t\t\ttry {\n\t\t\t\tconst documentType = module.documentModel.global.id;\n\t\t\t\tconst version = module.version ?? 1;\n\t\t\t\tfor (let i = 0; i < this.modules.length; i++) {\n\t\t\t\t\tconst existing = this.modules[i];\n\t\t\t\t\tconst existingType = existing.documentModel.global.id;\n\t\t\t\t\tconst existingVersion = existing.version ?? 1;\n\t\t\t\t\tif (existingType === documentType && existingVersion === version) throw new DuplicateModuleError(documentType, version);\n\t\t\t\t}\n\t\t\t\tthis.modules.push(module);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\titem: module\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\titem: module,\n\t\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t}\n\tunregisterModules(...documentTypes) {\n\t\tlet allFound = true;\n\t\tfor (const documentType of documentTypes) {\n\t\t\tif (!this.modules.some((m) => m.documentModel.global.id === documentType)) allFound = false;\n\t\t\tthis.modules = this.modules.filter((m) => m.documentModel.global.id !== documentType);\n\t\t}\n\t\treturn allFound;\n\t}\n\tgetModule(documentType, version) {\n\t\tlet latestModule;\n\t\tlet latestVersion = -1;\n\t\tfor (let i = 0; i < this.modules.length; i++) {\n\t\t\tconst module = this.modules[i];\n\t\t\tconst moduleType = module.documentModel.global.id;\n\t\t\tconst moduleVersion = module.version ?? 1;\n\t\t\tif (moduleType === documentType) {\n\t\t\t\tif (version !== void 0 && moduleVersion === version) return module;\n\t\t\t\tif (moduleVersion > latestVersion) {\n\t\t\t\t\tlatestModule = module;\n\t\t\t\t\tlatestVersion = moduleVersion;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (version === void 0 && latestModule !== void 0) return latestModule;\n\t\tthrow new ModuleNotFoundError(documentType, version);\n\t}\n\tgetAllModules() {\n\t\treturn [...this.modules];\n\t}\n\tclear() {\n\t\tthis.modules = [];\n\t\tthis.manifests = [];\n\t}\n\tgetSupportedVersions(documentType) {\n\t\tconst versions = [];\n\t\tfor (const module of this.modules) if (module.documentModel.global.id === documentType) versions.push(module.version ?? 1);\n\t\tif (versions.length === 0) throw new ModuleNotFoundError(documentType);\n\t\treturn versions.sort((a, b) => a - b);\n\t}\n\tgetLatestVersion(documentType) {\n\t\tlet latest = -1;\n\t\tlet found = false;\n\t\tfor (const module of this.modules) if (module.documentModel.global.id === documentType) {\n\t\t\tfound = true;\n\t\t\tconst version = module.version ?? 1;\n\t\t\tif (version > latest) latest = version;\n\t\t}\n\t\tif (!found) throw new ModuleNotFoundError(documentType);\n\t\treturn latest;\n\t}\n\tregisterUpgradeManifests(...manifestsToRegister) {\n\t\treturn manifestsToRegister.map((manifestToRegister) => {\n\t\t\ttry {\n\t\t\t\tif (!manifestToRegister.documentType) throw new Error(\"Upgrade manifest is missing a documentType\");\n\t\t\t\tfor (const registeredManifest of this.manifests) if (registeredManifest.documentType === manifestToRegister.documentType) throw new DuplicateManifestError(manifestToRegister.documentType);\n\t\t\t\tthis.manifests.push(manifestToRegister);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\titem: manifestToRegister\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\titem: manifestToRegister,\n\t\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t}\n\tunregisterUpgradeManifests(...documentTypes) {\n\t\tlet allFound = true;\n\t\tfor (const documentType of documentTypes) {\n\t\t\tif (!this.manifests.some((m) => m.documentType === documentType)) allFound = false;\n\t\t\tthis.manifests = this.manifests.filter((m) => m.documentType !== documentType);\n\t\t}\n\t\treturn allFound;\n\t}\n\tgetUpgradeManifest(documentType) {\n\t\tfor (let i = 0; i < this.manifests.length; i++) if (this.manifests[i].documentType === documentType) return this.manifests[i];\n\t\tthrow new ManifestNotFoundError(documentType);\n\t}\n\tcomputeUpgradePath(documentType, fromVersion, toVersion) {\n\t\tif (fromVersion === toVersion) return [];\n\t\tif (toVersion < fromVersion) throw new DowngradeNotSupportedError$1(documentType, fromVersion, toVersion);\n\t\tconst manifest = this.getUpgradeManifest(documentType);\n\t\tconst path = [];\n\t\tfor (let v = fromVersion + 1; v <= toVersion; v++) {\n\t\t\tconst key = `v${v}`;\n\t\t\tif (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, v - 1, v);\n\t\t\tconst transition = manifest.upgrades[key];\n\t\t\tpath.push(transition);\n\t\t}\n\t\treturn path;\n\t}\n\tgetUpgradeReducer(documentType, fromVersion, toVersion) {\n\t\tif (toVersion !== fromVersion + 1) throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);\n\t\tconst manifest = this.getUpgradeManifest(documentType);\n\t\tconst key = `v${toVersion}`;\n\t\tif (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, fromVersion, toVersion);\n\t\treturn manifest.upgrades[key].upgradeReducer;\n\t}\n};\n//#endregion\n//#region src/storage/kysely/keyframe-store.ts\nvar KyselyKeyframeStore = class KyselyKeyframeStore {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyKeyframeStore(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tasync putKeyframe(documentId, scope, branch, revision, document, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tawait this.queryExecutor.insertInto(\"Keyframe\").values({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope,\n\t\t\tbranch,\n\t\t\trevision,\n\t\t\tdocument\n\t\t}).onConflict((oc) => oc.columns([\n\t\t\t\"documentId\",\n\t\t\t\"scope\",\n\t\t\t\"branch\",\n\t\t\t\"revision\"\n\t\t]).doUpdateSet({ document })).execute();\n\t}\n\tasync findNearestKeyframe(documentId, scope, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst row = await this.queryExecutor.selectFrom(\"Keyframe\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"revision\", \"<=\", targetRevision).orderBy(\"revision\", \"desc\").limit(1).executeTakeFirst();\n\t\tif (!row) return;\n\t\treturn {\n\t\t\trevision: row.revision,\n\t\t\tdocument: row.document\n\t\t};\n\t}\n\tasync listKeyframes(documentId, scope, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tlet query = this.queryExecutor.selectFrom(\"Keyframe\").selectAll().where(\"documentId\", \"=\", documentId).orderBy(\"revision\", \"asc\");\n\t\tif (scope !== void 0) query = query.where(\"scope\", \"=\", scope);\n\t\tif (branch !== void 0) query = query.where(\"branch\", \"=\", branch);\n\t\treturn (await query.execute()).map((row) => ({\n\t\t\tscope: row.scope,\n\t\t\tbranch: row.branch,\n\t\t\trevision: row.revision,\n\t\t\tdocument: row.document\n\t\t}));\n\t}\n\tasync deleteKeyframes(documentId, scope, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tlet query = this.queryExecutor.deleteFrom(\"Keyframe\").where(\"documentId\", \"=\", documentId);\n\t\tif (scope !== void 0 && branch !== void 0) query = query.where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch);\n\t\telse if (scope !== void 0) query = query.where(\"scope\", \"=\", scope);\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows || 0n);\n\t}\n};\n//#endregion\n//#region src/storage/kysely/pagination.ts\nconst DEFAULT_LIMIT = 100;\nfunction paginateRows(rows, paging, cursorOf, toItem, refetch) {\n\tlet hasMore = false;\n\tlet items = rows;\n\tif (paging?.limit && rows.length > paging.limit) {\n\t\thasMore = true;\n\t\titems = rows.slice(0, paging.limit);\n\t}\n\tconst nextCursor = hasMore && items.length > 0 ? cursorOf(items[items.length - 1]).toString() : void 0;\n\tconst cursor = paging?.cursor || \"0\";\n\tconst limit = paging?.limit || DEFAULT_LIMIT;\n\treturn {\n\t\tresults: items.map(toItem),\n\t\toptions: {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t},\n\t\tnextCursor,\n\t\tnext: hasMore ? () => refetch(nextCursor, limit) : void 0\n\t};\n}\n//#endregion\n//#region src/storage/txn.ts\nvar AtomicTransaction = class {\n\toperations = [];\n\tconstructor(documentId, documentType, scope, branch, baseRevision) {\n\t\tthis.documentId = documentId;\n\t\tthis.documentType = documentType;\n\t\tthis.scope = scope;\n\t\tthis.branch = branch;\n\t\tthis.baseRevision = baseRevision;\n\t}\n\taddOperations(...operations) {\n\t\tfor (const op of operations) this.operations.push({\n\t\t\tjobId: v4(),\n\t\t\topId: op.id,\n\t\t\tprevOpId: \"\",\n\t\t\tdocumentId: this.documentId,\n\t\t\tdocumentType: this.documentType,\n\t\t\tscope: this.scope,\n\t\t\tbranch: this.branch,\n\t\t\ttimestampUtcMs: new Date(op.timestampUtcMs),\n\t\t\tindex: op.index,\n\t\t\taction: JSON.stringify(op.action),\n\t\t\tskip: op.skip,\n\t\t\terror: op.error || null,\n\t\t\tdeniedReason: op.deniedReason || null,\n\t\t\thash: op.hash\n\t\t});\n\t}\n\tgetOperations() {\n\t\treturn this.operations;\n\t}\n};\n//#endregion\n//#region src/storage/kysely/store.ts\nvar _UniqueConstraintContext = class extends Error {\n\tconstructor(documentId, scope, branch, revision, stagedOps) {\n\t\tsuper(\"unique constraint\");\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.branch = branch;\n\t\tthis.revision = revision;\n\t\tthis.stagedOps = stagedOps;\n\t\tthis.name = \"UniqueConstraintContext\";\n\t}\n};\nvar KyselyOperationStore = class KyselyOperationStore {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyOperationStore(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tasync apply(documentId, documentType, scope, branch, revision, fn, signal, condition) {\n\t\tif (this.trx) {\n\t\t\tlet executeResult = null;\n\t\t\tlet uniqueCtx = null;\n\t\t\ttry {\n\t\t\t\texecuteResult = await this.executeApply(this.trx, documentId, documentType, scope, branch, revision, fn, signal, condition);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof _UniqueConstraintContext) uniqueCtx = error;\n\t\t\t\telse throw error;\n\t\t\t}\n\t\t\tif (uniqueCtx !== null) return this.resolveUniqueConstraint(uniqueCtx);\n\t\t\treturn executeResult;\n\t\t} else {\n\t\t\tlet transactionResult = null;\n\t\t\tlet uniqueCtx = null;\n\t\t\ttry {\n\t\t\t\ttransactionResult = await this.db.transaction().execute(async (trx) => {\n\t\t\t\t\treturn this.executeApply(trx, documentId, documentType, scope, branch, revision, fn, signal, condition);\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof _UniqueConstraintContext) uniqueCtx = error;\n\t\t\t\telse throw error;\n\t\t\t}\n\t\t\tif (uniqueCtx !== null) return this.resolveUniqueConstraint(uniqueCtx);\n\t\t\treturn transactionResult;\n\t\t}\n\t}\n\tasync resolveUniqueConstraint(ctx) {\n\t\tlet replayOps = null;\n\t\ttry {\n\t\t\treplayOps = await this.findIdempotentReplay(this.db, ctx.documentId, ctx.scope, ctx.branch, ctx.revision, ctx.stagedOps);\n\t\t} catch {}\n\t\tif (replayOps !== null) return replayOps;\n\t\tconst op = ctx.stagedOps[0];\n\t\tthrow new DuplicateOperationError(`${op.opId} at index ${op.index} with skip ${op.skip}`);\n\t}\n\tasync executeApply(trx, documentId, documentType, scope, branch, revision, fn, signal, condition) {\n\t\tthrowIfAborted(signal);\n\t\tconst atomicTxn = new AtomicTransaction(documentId, documentType, scope, branch, revision);\n\t\tawait fn(atomicTxn);\n\t\tconst operations = atomicTxn.getOperations();\n\t\tif (operations.length === 0) return [];\n\t\tif (condition) await this.acquireStreamLocks(trx, documentId, scope, branch, condition);\n\t\tconst latestOp = await trx.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).orderBy(\"index\", \"desc\").limit(1).executeTakeFirst();\n\t\tconst currentRevision = latestOp ? latestOp.index : -1;\n\t\tif (currentRevision !== revision - 1) {\n\t\t\tlet replayOps = null;\n\t\t\ttry {\n\t\t\t\treplayOps = await this.findIdempotentReplay(trx, documentId, scope, branch, revision, operations);\n\t\t\t} catch {}\n\t\t\tif (replayOps !== null) return replayOps;\n\t\t\tif (revision === 0 && this.isCreate(operations)) throw new DocumentAlreadyExistsError(documentId, scope, currentRevision);\n\t\t\tthrow new RevisionMismatchError(currentRevision + 1, revision);\n\t\t}\n\t\tlet prevOpId = latestOp?.opId || \"\";\n\t\tfor (const op of operations) {\n\t\t\top.prevOpId = prevOpId;\n\t\t\tprevOpId = op.opId;\n\t\t}\n\t\tlet insertedCount = operations.length;\n\t\ttry {\n\t\t\tif (condition && condition.streams.length > 0) insertedCount = await this.insertGuarded(trx, operations, condition);\n\t\t\telse await trx.insertInto(\"Operation\").values(operations).execute();\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.includes(\"unique constraint\")) throw new _UniqueConstraintContext(documentId, scope, branch, revision, operations);\n\t\t\tthrow error;\n\t\t}\n\t\tif (insertedCount !== operations.length) throw new AppendConditionFailedError(condition);\n\t\treturn operations.map((op) => ({\n\t\t\tindex: op.index,\n\t\t\ttimestampUtcMs: op.timestampUtcMs.toISOString(),\n\t\t\thash: op.hash,\n\t\t\tskip: op.skip,\n\t\t\terror: op.error || void 0,\n\t\t\tdeniedReason: op.deniedReason || void 0,\n\t\t\tid: op.opId,\n\t\t\taction: JSON.parse(op.action)\n\t\t}));\n\t}\n\t/**\n\t* Locks the written stream and every read-set stream, in sorted key order\n\t* so that overlapping concurrent appends serialize rather than deadlock.\n\t* The locks are still taken one row at a time, so the query preserves that\n\t* order. It must stay separate from the guarded insert, which would\n\t* otherwise read a snapshot taken before the locks were held.\n\t*/\n\tasync acquireStreamLocks(trx, documentId, scope, branch, condition) {\n\t\tconst keys = new Set([`${documentId}:${scope}:${branch}`]);\n\t\tfor (const stream of condition.streams) keys.add(`${stream.documentId}:${stream.scope}:${stream.branch}`);\n\t\tawait sql`\n with ordered as materialized (\n select key\n from unnest(array[${sql.join([...keys].sort())}]::text[]) with ordinality as t(key, ord)\n order by ord\n )\n select pg_advisory_xact_lock(hashtext(key)) from ordered\n `.execute(trx);\n\t}\n\t/**\n\t* Inserts the staged operations with the condition compiled in as a WHERE\n\t* NOT EXISTS guard, making the check and the append one statement. Returns\n\t* the rows inserted; zero means the guard failed and nothing was written.\n\t*/\n\tasync insertGuarded(trx, operations, condition) {\n\t\tconst branches = operations.map((op) => trx.selectNoFrom([\n\t\t\tsql`${op.jobId}::text`.as(\"jobId\"),\n\t\t\tsql`${op.opId}::text`.as(\"opId\"),\n\t\t\tsql`${op.prevOpId}::text`.as(\"prevOpId\"),\n\t\t\tsql`${op.documentId}::text`.as(\"documentId\"),\n\t\t\tsql`${op.documentType}::text`.as(\"documentType\"),\n\t\t\tsql`${op.scope}::text`.as(\"scope\"),\n\t\t\tsql`${op.branch}::text`.as(\"branch\"),\n\t\t\tsql`${op.timestampUtcMs}::timestamptz`.as(\"timestampUtcMs\"),\n\t\t\tsql`${op.index}::integer`.as(\"index\"),\n\t\t\tsql`${op.action}::jsonb`.as(\"action\"),\n\t\t\tsql`${op.skip}::integer`.as(\"skip\"),\n\t\t\tsql`${op.error ?? null}::text`.as(\"error\"),\n\t\t\tsql`${op.deniedReason ?? null}::text`.as(\"deniedReason\"),\n\t\t\tsql`${op.hash}::text`.as(\"hash\")\n\t\t]).where((eb) => eb.not(eb.exists(eb.selectFrom(\"Operation\").select(\"Operation.id\").where((web) => web.or(condition.streams.map((s) => web.and([\n\t\t\tweb(\"Operation.documentId\", \"=\", s.documentId),\n\t\t\tweb(\"Operation.scope\", \"=\", s.scope),\n\t\t\tweb(\"Operation.branch\", \"=\", s.branch),\n\t\t\tweb(\"Operation.index\", \">\", s.revision)\n\t\t]))))))));\n\t\tlet expression = branches[0];\n\t\tfor (let i = 1; i < branches.length; i++) expression = expression.unionAll(branches[i]);\n\t\treturn (await trx.insertInto(\"Operation\").columns([\n\t\t\t\"jobId\",\n\t\t\t\"opId\",\n\t\t\t\"prevOpId\",\n\t\t\t\"documentId\",\n\t\t\t\"documentType\",\n\t\t\t\"scope\",\n\t\t\t\"branch\",\n\t\t\t\"timestampUtcMs\",\n\t\t\t\"index\",\n\t\t\t\"action\",\n\t\t\t\"skip\",\n\t\t\t\"error\",\n\t\t\t\"deniedReason\",\n\t\t\t\"hash\"\n\t\t]).expression(expression).returning(\"id\").execute()).length;\n\t}\n\tasync findIdempotentReplay(executor, documentId, scope, branch, revision, stagedOps) {\n\t\tconst minIndex = revision;\n\t\tconst maxIndex = revision + stagedOps.length - 1;\n\t\tconst storedRows = await executor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"index\", \">=\", minIndex).where(\"index\", \"<=\", maxIndex).orderBy(\"index\", \"asc\").execute();\n\t\tif (storedRows.length !== stagedOps.length) return null;\n\t\tfor (let i = 0; i < stagedOps.length; i++) {\n\t\t\tconst staged = stagedOps[i];\n\t\t\tconst stored = storedRows[i];\n\t\t\tif (stored.opId !== staged.opId || stored.index !== staged.index || stored.skip !== staged.skip) return null;\n\t\t}\n\t\treturn storedRows.map((row) => this.rowToOperation(row));\n\t}\n\t/** True when the staged write creates a document rather than appending to one. */\n\tisCreate(operations) {\n\t\tfor (const operation of operations) {\n\t\t\tlet action = operation.action;\n\t\t\tif (typeof action === \"string\") try {\n\t\t\t\taction = JSON.parse(action);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof action === \"object\" && action !== null && \"type\" in action && typeof action.type === \"string\" && action.type === \"CREATE_DOCUMENT\") return true;\n\t\t}\n\t\treturn false;\n\t}\n\tasync getSince(documentId, scope, branch, revision, filter, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"index\", \">\", revision).orderBy(\"index\", \"asc\");\n\t\tif (filter) {\n\t\t\tif (filter.actionTypes && filter.actionTypes.length > 0) {\n\t\t\t\tconst actionTypesArray = filter.actionTypes.map((t) => `'${t.replace(/'/g, \"''\")}'`).join(\",\");\n\t\t\t\tquery = query.where(sql`action->>'type' = ANY(ARRAY[${sql.raw(actionTypesArray)}]::text[])`);\n\t\t\t}\n\t\t\tif (filter.timestampFrom) query = query.where(\"timestampUtcMs\", \">=\", new Date(filter.timestampFrom));\n\t\t\tif (filter.timestampTo) query = query.where(\"timestampUtcMs\", \"<=\", new Date(filter.timestampTo));\n\t\t\tif (filter.sinceRevision !== void 0) query = query.where(\"index\", \">=\", filter.sinceRevision);\n\t\t}\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"index\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getSince(documentId, scope, branch, revision, filter, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getSinceId(id, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"id\", \">\", id).orderBy(\"id\", \"asc\");\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"id\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.id, (row) => this.rowToOperationWithContext(row), (cursor, limit) => this.getSinceId(id, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getConflicting(documentId, scope, branch, minTimestamp, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"timestampUtcMs\", \">=\", new Date(minTimestamp)).orderBy(\"index\", \"asc\");\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"index\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getConflicting(documentId, scope, branch, minTimestamp, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getRevisions(documentId, branch, signal) {\n\t\tthrowIfAborted(signal);\n\t\tconst scopeRevisions = await this.queryExecutor.selectFrom(\"Operation as o1\").select([\n\t\t\t\"o1.scope\",\n\t\t\t\"o1.index\",\n\t\t\t\"o1.timestampUtcMs\"\n\t\t]).where(\"o1.documentId\", \"=\", documentId).where(\"o1.branch\", \"=\", branch).where((eb) => eb(\"o1.index\", \"=\", eb.selectFrom(\"Operation as o2\").select((eb2) => eb2.fn.max(\"o2.index\").as(\"maxIndex\")).where(\"o2.documentId\", \"=\", eb.ref(\"o1.documentId\")).where(\"o2.branch\", \"=\", eb.ref(\"o1.branch\")).where(\"o2.scope\", \"=\", eb.ref(\"o1.scope\")))).execute();\n\t\tconst latest = await this.queryExecutor.selectFrom(\"Operation\").select((eb) => eb.fn.max(\"timestampUtcMs\").as(\"latestTimestamp\")).where(\"documentId\", \"=\", documentId).where(\"branch\", \"=\", branch).executeTakeFirst();\n\t\tconst revision = {};\n\t\tfor (const row of scopeRevisions) revision[row.scope] = row.index + 1;\n\t\treturn {\n\t\t\trevision,\n\t\t\tlatestTimestamp: latest?.latestTimestamp ? new Date(latest.latestTimestamp).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString()\n\t\t};\n\t}\n\tasync getStreamLatestTimestamp(documentId, scope, branch, signal) {\n\t\tconst latest = await this.queryExecutor.selectFrom(\"Operation\").select((eb) => eb.fn.max(\"timestampUtcMs\").as(\"latestTimestamp\")).where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).executeTakeFirst();\n\t\treturn latest?.latestTimestamp ? new Date(latest.latestTimestamp).toISOString() : void 0;\n\t}\n\trowToOperation(row) {\n\t\treturn {\n\t\t\tindex: row.index,\n\t\t\ttimestampUtcMs: row.timestampUtcMs.toISOString(),\n\t\t\thash: row.hash,\n\t\t\tskip: row.skip,\n\t\t\terror: row.error || void 0,\n\t\t\tdeniedReason: row.deniedReason || void 0,\n\t\t\tid: row.opId,\n\t\t\taction: row.action\n\t\t};\n\t}\n\trowToOperationWithContext(row) {\n\t\treturn {\n\t\t\toperation: this.rowToOperation(row),\n\t\t\tcontext: {\n\t\t\t\tdocumentId: row.documentId,\n\t\t\t\tdocumentType: row.documentType,\n\t\t\t\tscope: row.scope,\n\t\t\t\tbranch: row.branch,\n\t\t\t\tordinal: row.id\n\t\t\t}\n\t\t};\n\t}\n};\n//#endregion\n//#region src/storage/pool-instrumentation.ts\n/**\n* Wraps an existing pg.Pool with acquire-wait timing and an event\n* subscription surface. The pool is mutated in place: pool.connect()\n* is replaced with a timing wrapper so all callers (Kysely included)\n* pick up the instrumentation transparently.\n*/\nfunction instrumentPgPool(pool, name) {\n\tconst listeners = /* @__PURE__ */ new Set();\n\tconst originalConnect = pool.connect.bind(pool);\n\tconst wrappedConnect = async () => {\n\t\tconst start = performance.now();\n\t\tconst client = await originalConnect();\n\t\tconst durationMs = performance.now() - start;\n\t\tfor (const listener of listeners) try {\n\t\t\tlistener(durationMs);\n\t\t} catch {}\n\t\treturn client;\n\t};\n\tpool.connect = wrappedConnect;\n\treturn {\n\t\tname,\n\t\tgetStats() {\n\t\t\treturn {\n\t\t\t\tsize: pool.totalCount,\n\t\t\t\tidle: pool.idleCount,\n\t\t\t\twaiting: pool.waitingCount\n\t\t\t};\n\t\t},\n\t\tonAcquire(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t};\n\t\t}\n\t};\n}\nfunction createForwardingPoolInstrumentation(name) {\n\tconst listeners = /* @__PURE__ */ new Set();\n\tlet stats = {\n\t\tsize: 0,\n\t\tidle: 0,\n\t\twaiting: 0\n\t};\n\treturn {\n\t\tname,\n\t\tgetStats() {\n\t\t\treturn stats;\n\t\t},\n\t\tonAcquire(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t};\n\t\t},\n\t\tpushSamples(durations) {\n\t\t\tfor (const durationMs of durations) for (const listener of listeners) try {\n\t\t\t\tlistener(durationMs);\n\t\t\t} catch {}\n\t\t},\n\t\tupdateStats(next) {\n\t\t\tstats = next;\n\t\t}\n\t};\n}\n//#endregion\n//#region src/storage/migrations/001_create_operation_table.ts\nvar _001_create_operation_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$18 });\nasync function up$18(db) {\n\tawait db.schema.createTable(\"Operation\").addColumn(\"id\", \"serial\", (col) => col.primaryKey()).addColumn(\"jobId\", \"text\", (col) => col.notNull()).addColumn(\"opId\", \"text\", (col) => col.notNull()).addColumn(\"prevOpId\", \"text\", (col) => col.notNull()).addColumn(\"writeTimestampUtcMs\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"timestampUtcMs\", \"timestamptz\", (col) => col.notNull()).addColumn(\"index\", \"integer\", (col) => col.notNull()).addColumn(\"action\", \"jsonb\", (col) => col.notNull()).addColumn(\"skip\", \"integer\", (col) => col.notNull()).addColumn(\"error\", \"text\").addColumn(\"hash\", \"text\", (col) => col.notNull()).addUniqueConstraint(\"unique_revision\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"index\"\n\t]).addUniqueConstraint(\"unique_operation_instance\", [\n\t\t\"opId\",\n\t\t\"index\",\n\t\t\"skip\"\n\t]).execute();\n\tawait db.schema.createIndex(\"streamOperations\").on(\"Operation\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"id\"\n\t]).execute();\n\tawait db.schema.createIndex(\"branchlessStreamOperations\").on(\"Operation\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"id\"\n\t]).execute();\n}\n//#endregion\n//#region src/storage/migrations/002_create_keyframe_table.ts\nvar _002_create_keyframe_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$17 });\nasync function up$17(db) {\n\tawait db.schema.createTable(\"Keyframe\").addColumn(\"id\", \"serial\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"revision\", \"integer\", (col) => col.notNull()).addColumn(\"document\", \"jsonb\", (col) => col.notNull()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_keyframe\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"revision\"\n\t]).execute();\n\tawait db.schema.createIndex(\"keyframe_lookup\").on(\"Keyframe\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"revision\"\n\t]).execute();\n}\n//#endregion\n//#region src/storage/migrations/003_create_document_table.ts\nvar _003_create_document_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$16 });\nasync function up$16(db) {\n\tawait db.schema.createTable(\"Document\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/004_create_document_relationship_table.ts\nvar _004_create_document_relationship_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$15 });\nasync function up$15(db) {\n\tawait db.schema.createTable(\"DocumentRelationship\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"sourceId\", \"text\", (col) => col.notNull().references(\"Document.id\").onDelete(\"cascade\")).addColumn(\"targetId\", \"text\", (col) => col.notNull().references(\"Document.id\").onDelete(\"cascade\")).addColumn(\"relationshipType\", \"text\", (col) => col.notNull()).addColumn(\"metadata\", \"jsonb\").addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_source_target_type\", [\n\t\t\"sourceId\",\n\t\t\"targetId\",\n\t\t\"relationshipType\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_relationship_source\").on(\"DocumentRelationship\").column(\"sourceId\").execute();\n\tawait db.schema.createIndex(\"idx_relationship_target\").on(\"DocumentRelationship\").column(\"targetId\").execute();\n\tawait db.schema.createIndex(\"idx_relationship_type\").on(\"DocumentRelationship\").column(\"relationshipType\").execute();\n}\n//#endregion\n//#region src/storage/migrations/005_create_indexer_state_table.ts\nvar _005_create_indexer_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$14 });\nasync function up$14(db) {\n\tawait db.schema.createTable(\"IndexerState\").addColumn(\"id\", \"integer\", (col) => col.primaryKey().generatedAlwaysAsIdentity()).addColumn(\"lastOperationId\", \"integer\", (col) => col.notNull()).addColumn(\"lastOperationTimestamp\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/006_create_document_snapshot_table.ts\nvar _006_create_document_snapshot_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$13 });\nasync function up$13(db) {\n\tawait db.schema.createTable(\"DocumentSnapshot\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"slug\", \"text\").addColumn(\"name\", \"text\").addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"content\", \"jsonb\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"lastOperationIndex\", \"integer\", (col) => col.notNull()).addColumn(\"lastOperationHash\", \"text\", (col) => col.notNull()).addColumn(\"lastUpdatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"snapshotVersion\", \"integer\", (col) => col.notNull().defaultTo(1)).addColumn(\"identifiers\", \"jsonb\").addColumn(\"metadata\", \"jsonb\").addColumn(\"isDeleted\", \"boolean\", (col) => col.notNull().defaultTo(false)).addColumn(\"deletedAt\", \"timestamptz\").addUniqueConstraint(\"unique_doc_scope_branch\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_slug_scope_branch\").on(\"DocumentSnapshot\").columns([\n\t\t\"slug\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_doctype_scope_branch\").on(\"DocumentSnapshot\").columns([\n\t\t\"documentType\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_last_updated\").on(\"DocumentSnapshot\").column(\"lastUpdatedAt\").execute();\n\tawait db.schema.createIndex(\"idx_is_deleted\").on(\"DocumentSnapshot\").column(\"isDeleted\").execute();\n}\n//#endregion\n//#region src/storage/migrations/007_create_slug_mapping_table.ts\nvar _007_create_slug_mapping_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$12 });\nasync function up$12(db) {\n\tawait db.schema.createTable(\"SlugMapping\").addColumn(\"slug\", \"text\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_docid_scope_branch\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_slug_documentid\").on(\"SlugMapping\").column(\"documentId\").execute();\n}\n//#endregion\n//#region src/storage/migrations/008_create_view_state_table.ts\nvar _008_create_view_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$11 });\nasync function up$11(db) {\n\tawait db.schema.createTable(\"ViewState\").addColumn(\"readModelId\", \"text\", (col) => col.primaryKey()).addColumn(\"lastOrdinal\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"lastOperationTimestamp\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/009_create_operation_index_tables.ts\nvar _009_create_operation_index_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$10 });\nasync function up$10(db) {\n\tawait db.schema.createTable(\"document_collections\").addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"collectionId\", \"text\", (col) => col.notNull()).addColumn(\"joinedOrdinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"leftOrdinal\", \"bigint\").addPrimaryKeyConstraint(\"document_collections_pkey\", [\"documentId\", \"collectionId\"]).execute();\n\tawait db.schema.createIndex(\"idx_document_collections_collectionId\").on(\"document_collections\").column(\"collectionId\").execute();\n\tawait db.schema.createIndex(\"idx_doc_collections_collection_range\").on(\"document_collections\").columns([\"collectionId\", \"joinedOrdinal\"]).execute();\n\tawait db.schema.createTable(\"operation_index_operations\").addColumn(\"ordinal\", \"serial\", (col) => col.primaryKey()).addColumn(\"opId\", \"text\", (col) => col.notNull()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"timestampUtcMs\", \"text\", (col) => col.notNull()).addColumn(\"writeTimestampUtcMs\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"index\", \"integer\", (col) => col.notNull()).addColumn(\"skip\", \"integer\", (col) => col.notNull()).addColumn(\"hash\", \"text\", (col) => col.notNull()).addColumn(\"action\", \"jsonb\", (col) => col.notNull()).execute();\n\tawait db.schema.createIndex(\"idx_operation_index_operations_document\").on(\"operation_index_operations\").columns([\n\t\t\"documentId\",\n\t\t\"branch\",\n\t\t\"scope\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_operation_index_operations_ordinal\").on(\"operation_index_operations\").column(\"ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/010_create_sync_tables.ts\nvar _010_create_sync_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$9 });\nasync function up$9(db) {\n\tawait db.schema.createTable(\"sync_remotes\").addColumn(\"name\", \"text\", (col) => col.primaryKey()).addColumn(\"collection_id\", \"text\", (col) => col.notNull()).addColumn(\"channel_type\", \"text\", (col) => col.notNull()).addColumn(\"channel_id\", \"text\", (col) => col.notNull().defaultTo(\"\")).addColumn(\"remote_name\", \"text\", (col) => col.notNull().defaultTo(\"\")).addColumn(\"channel_parameters\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'{}'::jsonb`)).addColumn(\"filter_document_ids\", \"jsonb\").addColumn(\"filter_scopes\", \"jsonb\").addColumn(\"filter_branch\", \"text\", (col) => col.notNull().defaultTo(\"main\")).addColumn(\"push_state\", \"text\", (col) => col.notNull().defaultTo(\"idle\")).addColumn(\"push_last_success_utc_ms\", \"text\").addColumn(\"push_last_failure_utc_ms\", \"text\").addColumn(\"push_failure_count\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"pull_state\", \"text\", (col) => col.notNull().defaultTo(\"idle\")).addColumn(\"pull_last_success_utc_ms\", \"text\").addColumn(\"pull_last_failure_utc_ms\", \"text\").addColumn(\"pull_failure_count\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"created_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_remotes_collection\").on(\"sync_remotes\").column(\"collection_id\").execute();\n\tawait db.schema.createTable(\"sync_cursors\").addColumn(\"remote_name\", \"text\", (col) => col.primaryKey().references(\"sync_remotes.name\").onDelete(\"cascade\")).addColumn(\"cursor_ordinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"last_synced_at_utc_ms\", \"text\").addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_cursors_ordinal\").on(\"sync_cursors\").column(\"cursor_ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/011_add_cursor_type_column.ts\nvar _011_add_cursor_type_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$8 });\nasync function up$8(db) {\n\tawait db.deleteFrom(\"sync_cursors\").where(\"remote_name\", \"like\", \"outbox::%\").execute();\n\tawait db.deleteFrom(\"sync_remotes\").where(\"name\", \"like\", \"outbox::%\").execute();\n\tawait db.schema.dropTable(\"sync_cursors\").execute();\n\tawait db.schema.createTable(\"sync_cursors\").addColumn(\"remote_name\", \"text\", (col) => col.notNull()).addColumn(\"cursor_type\", \"text\", (col) => col.notNull().defaultTo(\"inbox\")).addColumn(\"cursor_ordinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"last_synced_at_utc_ms\", \"text\").addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addPrimaryKeyConstraint(\"sync_cursors_pk\", [\"remote_name\", \"cursor_type\"]).execute();\n\tawait db.schema.createIndex(\"idx_sync_cursors_ordinal\").on(\"sync_cursors\").column(\"cursor_ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/012_add_source_remote_column.ts\nvar _012_add_source_remote_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$7 });\nasync function up$7(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").addColumn(\"sourceRemote\", \"text\", (col) => col.notNull().defaultTo(\"\")).execute();\n}\n//#endregion\n//#region src/storage/migrations/013_create_sync_dead_letters_table.ts\nvar _013_create_sync_dead_letters_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$6 });\nasync function up$6(db) {\n\tawait db.schema.createTable(\"sync_dead_letters\").addColumn(\"ordinal\", \"serial\", (col) => col.primaryKey()).addColumn(\"id\", \"text\", (col) => col.unique().notNull()).addColumn(\"job_id\", \"text\", (col) => col.notNull()).addColumn(\"job_dependencies\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"remote_name\", \"text\", (col) => col.notNull().references(\"sync_remotes.name\").onDelete(\"cascade\")).addColumn(\"document_id\", \"text\", (col) => col.notNull()).addColumn(\"scopes\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"operations\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"error_source\", \"text\", (col) => col.notNull()).addColumn(\"error_message\", \"text\", (col) => col.notNull()).addColumn(\"created_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_dead_letters_remote\").on(\"sync_dead_letters\").column(\"remote_name\").execute();\n}\n//#endregion\n//#region src/storage/migrations/014_create_processor_cursor_table.ts\nvar _014_create_processor_cursor_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$5 });\nasync function up$5(db) {\n\tawait db.schema.createTable(\"ProcessorCursor\").addColumn(\"processorId\", \"text\", (col) => col.primaryKey()).addColumn(\"factoryId\", \"text\", (col) => col.notNull()).addColumn(\"driveId\", \"text\", (col) => col.notNull()).addColumn(\"processorIndex\", \"integer\", (col) => col.notNull()).addColumn(\"lastOrdinal\", \"integer\", (col) => col.notNull().defaultTo(sql`0`)).addColumn(\"status\", \"text\", (col) => col.notNull().defaultTo(sql`'active'`)).addColumn(\"lastError\", \"text\").addColumn(\"lastErrorTimestamp\", \"timestamptz\").addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/015_add_operation_denied_reason.ts\nvar _015_add_operation_denied_reason_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$4,\n\tup: () => up$4\n});\n/**\n* Records why authorization refused an operation. Separate from `error` so a\n* denial is distinguishable from a reducer failure without matching on a\n* message. Null for every operation written before decisions were enforced.\n*/\nasync function up$4(db) {\n\tawait db.schema.alterTable(\"Operation\").addColumn(\"deniedReason\", \"text\").execute();\n\tawait db.schema.alterTable(\"operation_index_operations\").addColumn(\"deniedReason\", \"text\").execute();\n}\nasync function down$4(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").dropColumn(\"deniedReason\").execute();\n\tawait db.schema.alterTable(\"Operation\").dropColumn(\"deniedReason\").execute();\n}\n//#endregion\n//#region src/storage/migrations/016_add_dead_letter_error_type.ts\nvar _016_add_dead_letter_error_type_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$3,\n\tup: () => up$3\n});\n/**\n* The classification a dead letter falls into, stored because it decides whether\n* the document stays quarantined and the in-memory error is gone after a restart.\n* Defaulted rather than nullable, so a pre-existing row rehydrates.\n*/\nasync function up$3(db) {\n\tawait db.schema.alterTable(\"sync_dead_letters\").addColumn(\"error_type\", \"text\", (col) => col.notNull().defaultTo(\"UNCLASSIFIED\")).execute();\n}\nasync function down$3(db) {\n\tawait db.schema.alterTable(\"sync_dead_letters\").dropColumn(\"error_type\").execute();\n}\n//#endregion\n//#region src/storage/migrations/017_create_group_references.ts\nvar _017_create_group_references_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$2,\n\tup: () => up$2\n});\n/**\n* One row per (document, group) reference ever discovered from an auth\n* operation's input. Rows are never updated or deleted: auth evaluation is\n* positional, so a grant that named a group at any position keeps that\n* group's stream in the document's read-set even after a later operation\n* removes the reference. Read by documentId for the groups a document\n* requires (sync), and by groupId for the documents a group change affects\n* (re-evaluation).\n*/\nasync function up$2(db) {\n\tawait db.schema.createTable(\"group_references\").addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"groupId\", \"text\", (col) => col.notNull()).addPrimaryKeyConstraint(\"group_references_pkey\", [\"documentId\", \"groupId\"]).execute();\n\tawait db.schema.createIndex(\"idx_group_references_groupId\").on(\"group_references\").column(\"groupId\").execute();\n}\nasync function down$2(db) {\n\tawait db.schema.dropTable(\"group_references\").execute();\n}\n//#endregion\n//#region src/storage/migrations/018_add_sync_remote_bound_address.ts\nvar _018_add_sync_remote_bound_address_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$1,\n\tup: () => up$1\n});\n/**\n* The address a sync channel is bound to, so a channel created by one subject\n* cannot be polled by another.\n*\n* Nullable rather than defaulted: null is a channel nobody has claimed, which is\n* what every pre-existing row is and what an anonymously created channel stays\n* until its first authenticated poll adopts it. A default would claim them all\n* for one address.\n*/\nasync function up$1(db) {\n\tawait db.schema.alterTable(\"sync_remotes\").addColumn(\"bound_address\", \"text\").execute();\n}\nasync function down$1(db) {\n\tawait db.schema.alterTable(\"sync_remotes\").dropColumn(\"bound_address\").execute();\n}\n//#endregion\n//#region src/storage/migrations/019_require_action_id.ts\nvar _019_require_action_id_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down,\n\tup: () => up\n});\n/**\n* Makes an operation whose action carries no id physically unstorable.\n*\n* The id is not decoration: `deriveOperationId` hashes it into the operation id\n* and replay dedupes incoming operations by it, so an action without one\n* collapses every id-less operation on a document/scope/branch onto a single\n* derived operation id. The API rejects such an action now, and this is the\n* last line of defense behind it.\n*\n* Both tables are constrained because sync reads operations from the index\n* rather than the operation table, so poison reaching only the index would\n* still be served to a replica.\n*\n* Pre-existing rows are backfilled rather than left behind a NOT VALID\n* constraint: a row the index and the operation table disagree about is worse\n* than a missing id, because dedup keys off the value each side serves. The\n* backfill therefore mints one id per operation and writes that same id to both\n* tables, joined on the identity they share. Rewriting the action is safe: the\n* operation hash is taken over the resulting state, not over the action, and a\n* signature is verified from the params carried in the signature tuple, which\n* do not include the action id.\n*\n* The empty string is rejected alongside null. It derives the same colliding\n* operation id as an absent id, so admitting it would leave the hole open.\n*/\nasync function up(db) {\n\tawait db.updateTable(\"Operation\").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();\n\tawait db.updateTable(\"operation_index_operations as oio\").from(\"Operation as op\").set({ action: sql`jsonb_set(oio.action, '{id}', to_jsonb(op.action->>'id'))` }).whereRef(\"oio.opId\", \"=\", \"op.opId\").whereRef(\"oio.index\", \"=\", \"op.index\").whereRef(\"oio.skip\", \"=\", \"op.skip\").where(sql`jsonb_typeof(oio.action) = 'object' and coalesce(oio.action->>'id', '') = ''`).where(sql`coalesce(op.action->>'id', '') <> ''`).execute();\n\tawait db.updateTable(\"operation_index_operations\").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();\n\tawait db.schema.alterTable(\"Operation\").addCheckConstraint(\"action_must_have_id\", sql`action->>'id' is not null and action->>'id' <> ''`).execute();\n\tawait db.schema.alterTable(\"operation_index_operations\").addCheckConstraint(\"action_must_have_id\", sql`action->>'id' is not null and action->>'id' <> ''`).execute();\n}\n/**\n* Only the constraints are dropped. The backfilled ids stay: they are the ids\n* their operations are now known by, and reverting them would reintroduce the\n* collision the migration removed.\n*/\nasync function down(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").dropConstraint(\"action_must_have_id\").execute();\n\tawait db.schema.alterTable(\"Operation\").dropConstraint(\"action_must_have_id\").execute();\n}\n//#endregion\n//#region src/storage/migrations/migrator.ts\nconst REACTOR_SCHEMA = \"reactor\";\nconst migrations = {\n\t\"001_create_operation_table\": _001_create_operation_table_exports,\n\t\"002_create_keyframe_table\": _002_create_keyframe_table_exports,\n\t\"003_create_document_table\": _003_create_document_table_exports,\n\t\"004_create_document_relationship_table\": _004_create_document_relationship_table_exports,\n\t\"005_create_indexer_state_table\": _005_create_indexer_state_table_exports,\n\t\"006_create_document_snapshot_table\": _006_create_document_snapshot_table_exports,\n\t\"007_create_slug_mapping_table\": _007_create_slug_mapping_table_exports,\n\t\"008_create_view_state_table\": _008_create_view_state_table_exports,\n\t\"009_create_operation_index_tables\": _009_create_operation_index_tables_exports,\n\t\"010_create_sync_tables\": _010_create_sync_tables_exports,\n\t\"011_add_cursor_type_column\": _011_add_cursor_type_column_exports,\n\t\"012_add_source_remote_column\": _012_add_source_remote_column_exports,\n\t\"013_create_sync_dead_letters_table\": _013_create_sync_dead_letters_table_exports,\n\t\"014_create_processor_cursor_table\": _014_create_processor_cursor_table_exports,\n\t\"015_add_operation_denied_reason\": _015_add_operation_denied_reason_exports,\n\t\"016_add_dead_letter_error_type\": _016_add_dead_letter_error_type_exports,\n\t\"017_create_group_references\": _017_create_group_references_exports,\n\t\"018_add_sync_remote_bound_address\": _018_add_sync_remote_bound_address_exports,\n\t\"019_require_action_id\": _019_require_action_id_exports\n};\nvar ProgrammaticMigrationProvider = class {\n\tgetMigrations() {\n\t\treturn Promise.resolve(migrations);\n\t}\n};\n/**\n* Applies every pending migration, or every one up to and including `upTo`.\n*\n* The bound exists so a test can reach the schema a data migration is written\n* against, populate it, and then migrate across the migration under test.\n*/\nasync function runMigrations(db, schema = REACTOR_SCHEMA, upTo) {\n\ttry {\n\t\tawait sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schema)}`.execute(db);\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmigrationsExecuted: [],\n\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Failed to create schema\")\n\t\t};\n\t}\n\tconst migrator = new Migrator({\n\t\tdb: db.withSchema(schema),\n\t\tprovider: new ProgrammaticMigrationProvider(),\n\t\tmigrationTableSchema: schema\n\t});\n\tlet error;\n\tlet results;\n\ttry {\n\t\tconst result = upTo ? await migrator.migrateTo(upTo) : await migrator.migrateToLatest();\n\t\terror = result.error;\n\t\tresults = result.results;\n\t} catch (e) {\n\t\terror = e;\n\t\tresults = [];\n\t}\n\tconst migrationsExecuted = results?.map((result) => result.migrationName) ?? [];\n\tif (error) return {\n\t\tsuccess: false,\n\t\tmigrationsExecuted,\n\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Unknown migration error\")\n\t};\n\treturn {\n\t\tsuccess: true,\n\t\tmigrationsExecuted\n\t};\n}\nasync function getMigrationStatus(db, schema = REACTOR_SCHEMA) {\n\treturn await new Migrator({\n\t\tdb: db.withSchema(schema),\n\t\tprovider: new ProgrammaticMigrationProvider(),\n\t\tmigrationTableSchema: schema\n\t}).getMigrations();\n}\n//#endregion\n//#region src/core/drive-container-types.ts\nconst DEFAULT_DRIVE_CONTAINER_TYPES = new Set([\"powerhouse/document-drive\", \"powerhouse/reactor-drive\"]);\n//#endregion\nexport { selectDecisionModel as A, RevisionMismatchError as B, InvalidModuleError as C, createEmptyConsistencyToken as D, createConsistencyToken as E, AppendConditionFailedError as F, DocumentNotFoundError as G, AuthTimestampNotMonotonicError as H, DocumentAlreadyExistsError as I, UpgradePreconditionFailedError as J, ExcessiveReshuffleError as K, DocumentExistence as L, authDecisionModel as M, buildDecisionModel as N, targetDocumentId as O, APPEND_CONDITION_FAILED_PREFIX as P, __exportAll as Q, DuplicateOperationError as R, DuplicateModuleError as S, GATED_DOCUMENT_ACTIONS as T, AuthorizationDeniedError as U, AuthEnforcementDisabledError as V, DocumentDeletedError as W, parsePagingOptions as X, matchesScope as Y, throwIfAborted as Z, DocumentMetaCache as _, createForwardingPoolInstrumentation as a, JobExecutorEventTypes as b, KyselyKeyframeStore as c, DriveCollectionId as d, KyselyExecutionScope as f, KyselyOperationIndex as g, KyselyWriteCache as h, runMigrations as i, documentDecisionModel as j, decideAtHead as k, DocumentModelRegistry as l, EventBus as m, REACTOR_SCHEMA as n, instrumentPgPool as o, resolveFeatureFlags as p, InvalidOperationTimestampError as q, getMigrationStatus as r, KyselyOperationStore as s, DEFAULT_DRIVE_CONTAINER_TYPES as t, SimpleJobExecutor as u, CollectionMembershipCache as v, ModuleNotFoundError as w, DuplicateManifestError as x, DEFAULT_DEFERRED_JOB_TTL_MS as y, OptimisticLockError as z };\n\n//# sourceMappingURL=drive-container-types-yZrksiJR.js.map","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport type { AtomicTxn } from \"@powerhousedao/reactor\";\nimport type { StoredOperation } from \"./types.js\";\n\nexport class HypercoreAtomicTransaction implements AtomicTxn {\n private operations: StoredOperation[] = [];\n\n constructor(\n private documentId: string,\n private documentType: string,\n private scope: string,\n private branch: string,\n ) {}\n\n addOperations(...operations: Operation[]): void {\n for (const op of operations) {\n this.operations.push({\n ...op,\n documentId: this.documentId,\n documentType: this.documentType,\n scope: this.scope,\n branch: this.branch,\n });\n }\n }\n\n getOperations(): StoredOperation[] {\n return this.operations;\n }\n}\n","import type { StoredOperation } from \"./types.js\";\n\nconst PAD_WIDTH = 10;\n\nexport const RANGE_UPPER_BOUND = \"9\".repeat(PAD_WIDTH) + \"~\";\n\nexport function pad(n: number): string {\n return n.toString().padStart(PAD_WIDTH, \"0\");\n}\n\nexport function operationKey(\n documentId: string,\n scope: string,\n branch: string,\n index: number,\n): string {\n return `op/${documentId}/${scope}/${branch}/${pad(index)}`;\n}\n\nexport function operationPrefix(\n documentId: string,\n scope: string,\n branch: string,\n): string {\n return `op/${documentId}/${scope}/${branch}/`;\n}\n\nexport function ordinalKey(ordinal: number): string {\n return `ord/${pad(ordinal)}`;\n}\n\nexport function ordinalPrefix(): string {\n return \"ord/\";\n}\n\nexport function duplicateKey(\n opId: string,\n index: number,\n skip: number,\n): string {\n return `dup/${opId}/${pad(index)}/${pad(skip)}`;\n}\n\nexport function headKey(\n documentId: string,\n scope: string,\n branch: string,\n): string {\n return `_meta/head/${documentId}/${scope}/${branch}`;\n}\n\nexport function headPrefix(documentId: string): string {\n return `_meta/head/${documentId}/`;\n}\n\nexport const ORDINAL_COUNTER_KEY = \"_meta/ordinal\";\n\nexport type ParsedOperationKey = {\n documentId: string;\n scope: string;\n branch: string;\n index: number;\n};\n\nexport function parseOperationKey(key: string): ParsedOperationKey {\n const parts = key.split(\"/\");\n return {\n documentId: parts[1],\n scope: parts[2],\n branch: parts[3],\n index: parseInt(parts[4], 10),\n };\n}\n\nexport type OrdinalEntry = {\n documentId: string;\n documentType: string;\n scope: string;\n branch: string;\n index: number;\n operation: StoredOperation;\n};\n\nexport type HeadEntryValue = {\n index: number;\n latestTimestampUtcMs: string;\n};\n","import type {\n Operation,\n OperationWithContext,\n} from \"@powerhousedao/shared/document-model\";\nimport type {\n AppendCondition,\n AtomicTxn,\n DocumentRevisions,\n IOperationStore,\n OperationFilter,\n PagedResults,\n PagingOptions,\n} from \"@powerhousedao/reactor\";\nimport {\n AppendConditionFailedError,\n DocumentAlreadyExistsError,\n DuplicateOperationError,\n RevisionMismatchError,\n} from \"@powerhousedao/reactor\";\nimport type Hyperbee from \"hyperbee\";\nimport { HypercoreAtomicTransaction } from \"./hypercore-atomic-transaction.js\";\nimport {\n ORDINAL_COUNTER_KEY,\n RANGE_UPPER_BOUND,\n duplicateKey,\n headKey,\n headPrefix,\n operationKey,\n operationPrefix,\n ordinalKey,\n ordinalPrefix,\n pad,\n} from \"./key-encoding.js\";\nimport type { HeadEntryValue, OrdinalEntry } from \"./key-encoding.js\";\nimport type { StoredOperation } from \"./types.js\";\n\nexport class HypercoreOperationStore implements IOperationStore {\n private applyLock: Promise<void> = Promise.resolve();\n\n constructor(private bee: Hyperbee) {}\n\n async apply(\n documentId: string,\n documentType: string,\n scope: string,\n branch: string,\n revision: number,\n fn: (txn: AtomicTxn) => void | Promise<void>,\n signal?: AbortSignal,\n condition?: AppendCondition,\n ): Promise<Operation[]> {\n const prevLock = this.applyLock;\n let releaseLock: () => void;\n this.applyLock = new Promise<void>((resolve) => {\n releaseLock = resolve;\n });\n\n await prevLock;\n\n try {\n // Single writer on applyLock: nothing can append between check and write.\n if (condition) {\n await this.assertConditionHolds(condition, signal);\n }\n\n return await this.executeApply(\n documentId,\n documentType,\n scope,\n branch,\n revision,\n fn,\n signal,\n );\n } finally {\n releaseLock!();\n }\n }\n\n /** Throws if any read-set stream has grown past its recorded revision. */\n private async assertConditionHolds(\n condition: AppendCondition,\n signal?: AbortSignal,\n ): Promise<void> {\n for (const stream of condition.streams) {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const entry = await this.bee.get(\n headKey(stream.documentId, stream.scope, stream.branch),\n );\n const head = entry ? (entry.value as HeadEntryValue).index : -1;\n\n if (head > stream.revision) {\n throw new AppendConditionFailedError(condition);\n }\n }\n }\n\n private async executeApply(\n documentId: string,\n documentType: string,\n scope: string,\n branch: string,\n revision: number,\n fn: (txn: AtomicTxn) => void | Promise<void>,\n signal?: AbortSignal,\n ): Promise<Operation[]> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const hKey = headKey(documentId, scope, branch);\n const headEntry = await this.bee.get(hKey);\n const currentRevision = headEntry\n ? (headEntry.value as HeadEntryValue).index\n : -1;\n\n const atomicTxn = new HypercoreAtomicTransaction(\n documentId,\n documentType,\n scope,\n branch,\n );\n await fn(atomicTxn);\n\n const operations = atomicTxn.getOperations();\n\n if (currentRevision !== revision - 1) {\n if (revision === 0 && this.isCreate(operations)) {\n throw new DocumentAlreadyExistsError(\n documentId,\n scope,\n currentRevision,\n );\n }\n\n throw new RevisionMismatchError(currentRevision + 1, revision);\n }\n\n if (operations.length === 0) {\n return [];\n }\n\n for (const op of operations) {\n const dupKey = duplicateKey(op.id, op.index, op.skip);\n const existing = await this.bee.get(dupKey);\n if (existing) {\n throw new DuplicateOperationError(\n `${op.id} at index ${op.index} with skip ${op.skip}`,\n );\n }\n }\n\n const ordinalEntry = await this.bee.get(ORDINAL_COUNTER_KEY);\n let nextOrdinal: number = ordinalEntry ? (ordinalEntry.value as number) : 0;\n\n const batch = this.bee.batch();\n\n for (const op of operations) {\n const opKey = operationKey(documentId, scope, branch, op.index);\n const serialized = this.serializeOperation(op);\n await batch.put(opKey, serialized);\n\n const ordEntry: OrdinalEntry = {\n documentId,\n documentType,\n scope,\n branch,\n index: op.index,\n operation: serialized,\n };\n await batch.put(ordinalKey(nextOrdinal), ordEntry);\n\n await batch.put(duplicateKey(op.id, op.index, op.skip), \"\");\n\n nextOrdinal++;\n }\n\n const lastOp = operations[operations.length - 1];\n const headValue: HeadEntryValue = {\n index: lastOp.index,\n latestTimestampUtcMs: lastOp.timestampUtcMs,\n };\n await batch.put(hKey, headValue);\n await batch.put(ORDINAL_COUNTER_KEY, nextOrdinal);\n\n await batch.flush();\n\n return operations.map((op) => this.toOperation(op));\n }\n\n private isCreate(operations: StoredOperation[]): boolean {\n return operations.some((op) => op.action.type === \"CREATE_DOCUMENT\");\n }\n\n async getSince(\n documentId: string,\n scope: string,\n branch: string,\n revision: number,\n filter?: OperationFilter,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Operation>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = operationPrefix(documentId, scope, branch);\n const startIndex = revision + 1;\n const cursorIndex =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10) + 1\n : startIndex;\n const effectiveStart = Math.max(startIndex, cursorIndex);\n\n const gt = prefix + pad(effectiveStart - 1);\n const lt = prefix + RANGE_UPPER_BOUND;\n const limit = paging?.limit ? paging.limit + 1 : undefined;\n\n const items: Operation[] = [];\n const stream = this.bee.createReadStream({ gt, lt, limit });\n\n for await (const entry of stream) {\n const stored = entry.value as StoredOperation;\n\n if (filter) {\n if (\n filter.actionTypes &&\n filter.actionTypes.length > 0 &&\n !filter.actionTypes.includes((stored.action as { type: string }).type)\n ) {\n continue;\n }\n if (\n filter.timestampFrom &&\n stored.timestampUtcMs < filter.timestampFrom\n ) {\n continue;\n }\n if (filter.timestampTo && stored.timestampUtcMs > filter.timestampTo) {\n continue;\n }\n if (\n filter.sinceRevision !== undefined &&\n stored.index < filter.sinceRevision\n ) {\n continue;\n }\n }\n\n items.push(this.toOperation(stored));\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].index.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getSince(\n documentId,\n scope,\n branch,\n revision,\n filter,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getSinceId(\n id: number,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<OperationWithContext>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const cursorValue =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10)\n : id;\n const effectiveId = Math.max(id, cursorValue);\n\n const gt = ordinalPrefix() + pad(effectiveId);\n const lt = ordinalPrefix() + RANGE_UPPER_BOUND;\n const limit = paging?.limit ? paging.limit + 1 : undefined;\n\n const items: OperationWithContext[] = [];\n const stream = this.bee.createReadStream({ gt, lt, limit });\n\n for await (const entry of stream) {\n const ordEntry = entry.value as OrdinalEntry;\n const ordinal = parseInt(entry.key.split(\"/\")[1], 10);\n\n items.push({\n operation: this.toOperation(ordEntry.operation),\n context: {\n documentId: ordEntry.documentId,\n documentType: ordEntry.documentType,\n scope: ordEntry.scope,\n branch: ordEntry.branch,\n ordinal,\n },\n });\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].context.ordinal.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getSinceId(\n id,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getConflicting(\n documentId: string,\n scope: string,\n branch: string,\n minTimestamp: string,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Operation>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = operationPrefix(documentId, scope, branch);\n const cursorIndex =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10)\n : -1;\n\n const gt = cursorIndex >= 0 ? prefix + pad(cursorIndex) : prefix;\n const lt = prefix + RANGE_UPPER_BOUND;\n\n const stream = this.bee.createReadStream({\n gt: cursorIndex >= 0 ? gt : undefined,\n gte: cursorIndex >= 0 ? undefined : gt,\n lt,\n });\n\n const items: Operation[] = [];\n\n for await (const entry of stream) {\n const stored = entry.value as StoredOperation;\n if (stored.timestampUtcMs >= minTimestamp) {\n items.push(this.toOperation(stored));\n }\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].index.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getConflicting(\n documentId,\n scope,\n branch,\n minTimestamp,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getRevisions(\n documentId: string,\n branch: string,\n signal?: AbortSignal,\n ): Promise<DocumentRevisions> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = headPrefix(documentId);\n const stream = this.bee.createReadStream({\n gte: prefix,\n lt: prefix + \"~\",\n });\n\n const revision: Record<string, number> = {};\n let latestTimestamp = new Date(0).toISOString();\n\n for await (const entry of stream) {\n const parts = entry.key.split(\"/\");\n const entryScope = parts[3];\n const entryBranch = parts[4];\n\n if (entryBranch !== branch) {\n continue;\n }\n\n const headValue = entry.value as HeadEntryValue;\n revision[entryScope] = headValue.index + 1;\n\n if (headValue.latestTimestampUtcMs > latestTimestamp) {\n latestTimestamp = headValue.latestTimestampUtcMs;\n }\n }\n\n return { revision, latestTimestamp };\n }\n\n /**\n * A real maximum over the rows, not the head record's `latestTimestampUtcMs`:\n * that holds the last-indexed timestamp, which a re-append can leave behind a\n * later one, so it would under-report and admit a backdated auth write.\n */\n async getStreamLatestTimestamp(\n documentId: string,\n scope: string,\n branch: string,\n signal?: AbortSignal,\n ): Promise<string | undefined> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const stored = await this.getSince(\n documentId,\n scope,\n branch,\n -1,\n undefined,\n undefined,\n signal,\n );\n\n let latest: string | undefined;\n for (const operation of stored.results) {\n if (latest === undefined || operation.timestampUtcMs > latest) {\n latest = operation.timestampUtcMs;\n }\n }\n\n return latest;\n }\n\n private serializeOperation(op: StoredOperation): StoredOperation {\n return {\n id: op.id,\n index: op.index,\n skip: op.skip,\n timestampUtcMs: op.timestampUtcMs,\n hash: op.hash,\n error: op.error,\n deniedReason: op.deniedReason,\n action: op.action,\n documentId: op.documentId,\n documentType: op.documentType,\n scope: op.scope,\n branch: op.branch,\n };\n }\n\n private toOperation(stored: StoredOperation): Operation {\n return {\n id: stored.id,\n index: stored.index,\n skip: stored.skip,\n timestampUtcMs: stored.timestampUtcMs,\n hash: stored.hash,\n error: stored.error || undefined,\n deniedReason: stored.deniedReason || undefined,\n action: stored.action,\n };\n }\n}\n","import Corestore from \"corestore\";\nimport Hyperbee from \"hyperbee\";\n\nexport class StorageManager {\n private store: Corestore;\n private bee: Hyperbee | undefined;\n\n constructor(storagePath: string) {\n this.store = new Corestore(storagePath);\n }\n\n async open(): Promise<void> {\n await this.store.ready();\n const core = this.store.get({ name: \"operations\" });\n this.bee = new Hyperbee(core, {\n keyEncoding: \"utf-8\",\n valueEncoding: \"json\",\n });\n await this.bee.ready();\n }\n\n async close(): Promise<void> {\n if (this.bee) {\n await this.bee.close();\n }\n await this.store.close();\n }\n\n getBee(): Hyperbee {\n if (!this.bee) {\n throw new Error(\"StorageManager not opened. Call open() first.\");\n }\n return this.bee;\n }\n}\n"],"mappings":";;;;;;;AAiQA,IAAI,0BAA0B,cAAc,MAAM;CACjD,YAAY,aAAa;AACxB,QAAM,wBAAwB,cAAc;AAC5C,OAAK,OAAO;;;;;;;AAgBd,IAAI,wBAAwB,cAAc,MAAM;CAC/C,YAAY,UAAU,QAAQ;AAC7B,QAAM,+BAA+B,SAAS,QAAQ,SAAS;AAC/D,OAAK,OAAO;;;;;;;AAOd,IAAI,6BAA6B,cAAc,MAAM;CACpD;CACA,YAAY,YAAY,OAAO,cAAc;AAC5C,QAAM,YAAY,WAAW,wDAAwD,MAAM,0BAA0B,eAAe;AACpI,OAAK,OAAO;AACZ,OAAK,aAAa;;CAEnB,OAAO,QAAQ,OAAO;AACrB,SAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS;;;;AAIhD,MAAM,iCAAiC;;;;;AAKvC,IAAI,6BAA6B,cAAc,MAAM;CACpD,YAAY,WAAW;EACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,MAAM,GAAG,EAAE,WAAW,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,GAAG,EAAE,WAAW,CAAC,KAAK,KAAK;AAC/G,QAAM,GAAG,+BAA+B,8BAA8B,QAAQ,GAAG;AACjF,OAAK,YAAY;AACjB,OAAK,OAAO;;CAEb,OAAO,QAAQ,OAAO;AACrB,SAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS;;;CAG/C,OAAO,iBAAiB,SAAS;AAChC,SAAO,QAAQ,WAAW,+BAA+B;;;;AAyX3D,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAK6B,IAAI,IAAI,CAAC,GAAG,uBAAuB,CAAC,QAAQ,SAAS,SAAS,kBAAkB,CAAC;;;AC5rBhH,IAAa,6BAAb,MAA6D;CAC3D,aAAwC,EAAE;CAE1C,YACE,YACA,cACA,OACA,QACA;AAJQ,OAAA,aAAA;AACA,OAAA,eAAA;AACA,OAAA,QAAA;AACA,OAAA,SAAA;;CAGV,cAAc,GAAG,YAA+B;AAC9C,OAAK,MAAM,MAAM,WACf,MAAK,WAAW,KAAK;GACnB,GAAG;GACH,YAAY,KAAK;GACjB,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,QAAQ,KAAK;GACd,CAAC;;CAIN,gBAAmC;AACjC,SAAO,KAAK;;;;;ACzBhB,MAAM,YAAY;AAElB,MAAa,oBAAoB,IAAI,OAAO,UAAU,GAAG;AAEzD,SAAgB,IAAI,GAAmB;AACrC,QAAO,EAAE,UAAU,CAAC,SAAS,WAAW,IAAI;;AAG9C,SAAgB,aACd,YACA,OACA,QACA,OACQ;AACR,QAAO,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,MAAM;;AAG1D,SAAgB,gBACd,YACA,OACA,QACQ;AACR,QAAO,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO;;AAG7C,SAAgB,WAAW,SAAyB;AAClD,QAAO,OAAO,IAAI,QAAQ;;AAG5B,SAAgB,gBAAwB;AACtC,QAAO;;AAGT,SAAgB,aACd,MACA,OACA,MACQ;AACR,QAAO,OAAO,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,KAAK;;AAG/C,SAAgB,QACd,YACA,OACA,QACQ;AACR,QAAO,cAAc,WAAW,GAAG,MAAM,GAAG;;AAG9C,SAAgB,WAAW,YAA4B;AACrD,QAAO,cAAc,WAAW;;AAGlC,MAAa,sBAAsB;AASnC,SAAgB,kBAAkB,KAAiC;CACjE,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAO;EACL,YAAY,MAAM;EAClB,OAAO,MAAM;EACb,QAAQ,MAAM;EACd,OAAO,SAAS,MAAM,IAAI,GAAG;EAC9B;;;;ACnCH,IAAa,0BAAb,MAAgE;CAC9D,YAAmC,QAAQ,SAAS;CAEpD,YAAY,KAAuB;AAAf,OAAA,MAAA;;CAEpB,MAAM,MACJ,YACA,cACA,OACA,QACA,UACA,IACA,QACA,WACsB;EACtB,MAAM,WAAW,KAAK;EACtB,IAAI;AACJ,OAAK,YAAY,IAAI,SAAe,YAAY;AAC9C,iBAAc;IACd;AAEF,QAAM;AAEN,MAAI;AAEF,OAAI,UACF,OAAM,KAAK,qBAAqB,WAAW,OAAO;AAGpD,UAAO,MAAM,KAAK,aAChB,YACA,cACA,OACA,QACA,UACA,IACA,OACD;YACO;AACR,gBAAc;;;;CAKlB,MAAc,qBACZ,WACA,QACe;AACf,OAAK,MAAM,UAAU,UAAU,SAAS;AACtC,OAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;GAGtC,MAAM,QAAQ,MAAM,KAAK,IAAI,IAC3B,QAAQ,OAAO,YAAY,OAAO,OAAO,OAAO,OAAO,CACxD;AAGD,QAFa,QAAS,MAAM,MAAyB,QAAQ,MAElD,OAAO,SAChB,OAAM,IAAI,2BAA2B,UAAU;;;CAKrD,MAAc,aACZ,YACA,cACA,OACA,QACA,UACA,IACA,QACsB;AACtB,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,OAAO,QAAQ,YAAY,OAAO,OAAO;EAC/C,MAAM,YAAY,MAAM,KAAK,IAAI,IAAI,KAAK;EAC1C,MAAM,kBAAkB,YACnB,UAAU,MAAyB,QACpC;EAEJ,MAAM,YAAY,IAAI,2BACpB,YACA,cACA,OACA,OACD;AACD,QAAM,GAAG,UAAU;EAEnB,MAAM,aAAa,UAAU,eAAe;AAE5C,MAAI,oBAAoB,WAAW,GAAG;AACpC,OAAI,aAAa,KAAK,KAAK,SAAS,WAAW,CAC7C,OAAM,IAAI,2BACR,YACA,OACA,gBACD;AAGH,SAAM,IAAI,sBAAsB,kBAAkB,GAAG,SAAS;;AAGhE,MAAI,WAAW,WAAW,EACxB,QAAO,EAAE;AAGX,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,SAAS,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK;AAErD,OADiB,MAAM,KAAK,IAAI,IAAI,OAAO,CAEzC,OAAM,IAAI,wBACR,GAAG,GAAG,GAAG,YAAY,GAAG,MAAM,aAAa,GAAG,OAC/C;;EAIL,MAAM,eAAe,MAAM,KAAK,IAAI,IAAI,oBAAoB;EAC5D,IAAI,cAAsB,eAAgB,aAAa,QAAmB;EAE1E,MAAM,QAAQ,KAAK,IAAI,OAAO;AAE9B,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,QAAQ,aAAa,YAAY,OAAO,QAAQ,GAAG,MAAM;GAC/D,MAAM,aAAa,KAAK,mBAAmB,GAAG;AAC9C,SAAM,MAAM,IAAI,OAAO,WAAW;GAElC,MAAM,WAAyB;IAC7B;IACA;IACA;IACA;IACA,OAAO,GAAG;IACV,WAAW;IACZ;AACD,SAAM,MAAM,IAAI,WAAW,YAAY,EAAE,SAAS;AAElD,SAAM,MAAM,IAAI,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,EAAE,GAAG;AAE3D;;EAGF,MAAM,SAAS,WAAW,WAAW,SAAS;EAC9C,MAAM,YAA4B;GAChC,OAAO,OAAO;GACd,sBAAsB,OAAO;GAC9B;AACD,QAAM,MAAM,IAAI,MAAM,UAAU;AAChC,QAAM,MAAM,IAAI,qBAAqB,YAAY;AAEjD,QAAM,MAAM,OAAO;AAEnB,SAAO,WAAW,KAAK,OAAO,KAAK,YAAY,GAAG,CAAC;;CAGrD,SAAiB,YAAwC;AACvD,SAAO,WAAW,MAAM,OAAO,GAAG,OAAO,SAAS,kBAAkB;;CAGtE,MAAM,SACJ,YACA,OACA,QACA,UACA,QACA,QACA,QACkC;AAClC,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,gBAAgB,YAAY,OAAO,OAAO;EACzD,MAAM,aAAa,WAAW;EAC9B,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC9B;EAGN,MAAM,KAAK,SAAS,IAFG,KAAK,IAAI,YAAY,YAAY,GAEf,EAAE;EAC3C,MAAM,KAAK,SAAS;EACpB,MAAM,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,IAAI,KAAA;EAEjD,MAAM,QAAqB,EAAE;EAC7B,MAAM,SAAS,KAAK,IAAI,iBAAiB;GAAE;GAAI;GAAI;GAAO,CAAC;AAE3D,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,SAAS,MAAM;AAErB,OAAI,QAAQ;AACV,QACE,OAAO,eACP,OAAO,YAAY,SAAS,KAC5B,CAAC,OAAO,YAAY,SAAU,OAAO,OAA4B,KAAK,CAEtE;AAEF,QACE,OAAO,iBACP,OAAO,iBAAiB,OAAO,cAE/B;AAEF,QAAI,OAAO,eAAe,OAAO,iBAAiB,OAAO,YACvD;AAEF,QACE,OAAO,kBAAkB,KAAA,KACzB,OAAO,QAAQ,OAAO,cAEtB;;AAIJ,SAAM,KAAK,KAAK,YAAY,OAAO,CAAC;;EAGtC,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,MAAM,UAAU,GACpD,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,SACH,YACA,OACA,QACA,UACA,QACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,WACJ,IACA,QACA,QAC6C;AAC7C,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAC3B;EACN,MAAM,cAAc,KAAK,IAAI,IAAI,YAAY;EAE7C,MAAM,KAAK,eAAe,GAAG,IAAI,YAAY;EAC7C,MAAM,KAAK,eAAe,GAAG;EAC7B,MAAM,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,IAAI,KAAA;EAEjD,MAAM,QAAgC,EAAE;EACxC,MAAM,SAAS,KAAK,IAAI,iBAAiB;GAAE;GAAI;GAAI;GAAO,CAAC;AAE3D,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,WAAW,MAAM;GACvB,MAAM,UAAU,SAAS,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,GAAG;AAErD,SAAM,KAAK;IACT,WAAW,KAAK,YAAY,SAAS,UAAU;IAC/C,SAAS;KACP,YAAY,SAAS;KACrB,cAAc,SAAS;KACvB,OAAO,SAAS;KAChB,QAAQ,SAAS;KACjB;KACD;IACF,CAAC;;EAGJ,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,QAAQ,QAAQ,UAAU,GAC9D,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,WACH,IACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,eACJ,YACA,OACA,QACA,cACA,QACA,QACkC;AAClC,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,gBAAgB,YAAY,OAAO,OAAO;EACzD,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAC3B;EAEN,MAAM,KAAK,eAAe,IAAI,SAAS,IAAI,YAAY,GAAG;EAC1D,MAAM,KAAK,SAAS;EAEpB,MAAM,SAAS,KAAK,IAAI,iBAAiB;GACvC,IAAI,eAAe,IAAI,KAAK,KAAA;GAC5B,KAAK,eAAe,IAAI,KAAA,IAAY;GACpC;GACD,CAAC;EAEF,MAAM,QAAqB,EAAE;AAE7B,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,SAAS,MAAM;AACrB,OAAI,OAAO,kBAAkB,aAC3B,OAAM,KAAK,KAAK,YAAY,OAAO,CAAC;;EAIxC,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,MAAM,UAAU,GACpD,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,eACH,YACA,OACA,QACA,cACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,aACJ,YACA,QACA,QAC4B;AAC5B,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,WAAW,WAAW;EACrC,MAAM,SAAS,KAAK,IAAI,iBAAiB;GACvC,KAAK;GACL,IAAI,SAAS;GACd,CAAC;EAEF,MAAM,WAAmC,EAAE;EAC3C,IAAI,mCAAkB,IAAI,KAAK,EAAE,EAAC,aAAa;AAE/C,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,QAAQ,MAAM,IAAI,MAAM,IAAI;GAClC,MAAM,aAAa,MAAM;AAGzB,OAFoB,MAAM,OAEN,OAClB;GAGF,MAAM,YAAY,MAAM;AACxB,YAAS,cAAc,UAAU,QAAQ;AAEzC,OAAI,UAAU,uBAAuB,gBACnC,mBAAkB,UAAU;;AAIhC,SAAO;GAAE;GAAU;GAAiB;;;;;;;CAQtC,MAAM,yBACJ,YACA,OACA,QACA,QAC6B;AAC7B,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,MAAM,KAAK,SACxB,YACA,OACA,QACA,IACA,KAAA,GACA,KAAA,GACA,OACD;EAED,IAAI;AACJ,OAAK,MAAM,aAAa,OAAO,QAC7B,KAAI,WAAW,KAAA,KAAa,UAAU,iBAAiB,OACrD,UAAS,UAAU;AAIvB,SAAO;;CAGT,mBAA2B,IAAsC;AAC/D,SAAO;GACL,IAAI,GAAG;GACP,OAAO,GAAG;GACV,MAAM,GAAG;GACT,gBAAgB,GAAG;GACnB,MAAM,GAAG;GACT,OAAO,GAAG;GACV,cAAc,GAAG;GACjB,QAAQ,GAAG;GACX,YAAY,GAAG;GACf,cAAc,GAAG;GACjB,OAAO,GAAG;GACV,QAAQ,GAAG;GACZ;;CAGH,YAAoB,QAAoC;AACtD,SAAO;GACL,IAAI,OAAO;GACX,OAAO,OAAO;GACd,MAAM,OAAO;GACb,gBAAgB,OAAO;GACvB,MAAM,OAAO;GACb,OAAO,OAAO,SAAS,KAAA;GACvB,cAAc,OAAO,gBAAgB,KAAA;GACrC,QAAQ,OAAO;GAChB;;;;;AC/gBL,IAAa,iBAAb,MAA4B;CAC1B;CACA;CAEA,YAAY,aAAqB;AAC/B,OAAK,QAAQ,IAAI,UAAU,YAAY;;CAGzC,MAAM,OAAsB;AAC1B,QAAM,KAAK,MAAM,OAAO;AAExB,OAAK,MAAM,IAAI,SADF,KAAK,MAAM,IAAI,EAAE,MAAM,cAAc,CAAC,EACrB;GAC5B,aAAa;GACb,eAAe;GAChB,CAAC;AACF,QAAM,KAAK,IAAI,OAAO;;CAGxB,MAAM,QAAuB;AAC3B,MAAI,KAAK,IACP,OAAM,KAAK,IAAI,OAAO;AAExB,QAAM,KAAK,MAAM,OAAO;;CAG1B,SAAmB;AACjB,MAAI,CAAC,KAAK,IACR,OAAM,IAAI,MAAM,gDAAgD;AAElE,SAAO,KAAK"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../reactor/dist/drive-container-types-CE7dxz0_.js","../src/hypercore-atomic-transaction.ts","../src/key-encoding.ts","../src/hypercore-operation-store.ts","../src/storage-manager.ts"],"sourcesContent":["import { n as ReactorEventTypes, t as EventBusAggregateError } from \"./types-DMKLa0Ok.js\";\nimport { AUTH_ACTION_TYPES, AUTH_DENIED_BY_GRANT_REASON, AUTH_NO_GRANT_REASON, AUTH_VERSION_UNSUPPORTED_REASON, DOCUMENT_DELETED_REASON, DowngradeNotSupportedError as DowngradeNotSupportedError$1, appendWithoutApplying, applyAuthAction, applyDeleteDocumentAction, applyDeleteDocumentAction as applyDeleteDocumentAction$1, applyUpgradeDocumentAction, applyUpgradeDocumentAction as applyUpgradeDocumentAction$1, baseReducerVersion, createPresignedHeader, decide, defaultBaseState, deriveOperationId, evaluate, garbageCollect, groupDocumentType, groupMembershipActionTypes, hashDocumentStateForScope, isDenied, isUndoRedo, mentionedGroupIds, normalizeDocumentModelVersion, operationOutcome, referencedGroupIds, sortOperations } from \"@powerhousedao/shared/document-model\";\nimport { v4 } from \"uuid\";\nimport { Migrator, sql } from \"kysely\";\n//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\n//#region src/shared/utils.ts\nfunction matchesScope(view = {}, scope) {\n\tif (view.scopes) return view.scopes.includes(scope);\n\treturn true;\n}\nfunction yieldToMain() {\n\tconst s = globalThis.scheduler;\n\tif (s?.yield) return s.yield();\n\treturn new Promise((resolve) => setTimeout(resolve, 0));\n}\nconst defaultAbortError = () => /* @__PURE__ */ new Error(\"Operation aborted\");\nfunction throwIfAborted(signal, makeError = defaultAbortError) {\n\tif (signal?.aborted) throw makeError();\n}\n/**\n* Validates PagingOptions and returns a normalized offset and limit.\n* Throws if the cursor is not empty and not a non-negative integer, or if\n* limit is less than 1. When `paging` is undefined, returns offset 0 and\n* the caller-supplied `defaultLimit`.\n*/\nfunction parsePagingOptions(paging, defaultLimit) {\n\tif (paging === void 0) return {\n\t\toffset: 0,\n\t\tlimit: defaultLimit\n\t};\n\tif (!Number.isInteger(paging.limit) || paging.limit < 1) throw new Error(`Invalid paging limit: ${String(paging.limit)} (must be an integer >= 1)`);\n\tif (paging.cursor === \"\") return {\n\t\toffset: 0,\n\t\tlimit: paging.limit\n\t};\n\tconst parsed = Number(paging.cursor);\n\tif (!Number.isInteger(parsed) || parsed < 0) throw new Error(`Invalid paging cursor: ${JSON.stringify(paging.cursor)} (must be empty or a non-negative integer)`);\n\treturn {\n\t\toffset: parsed,\n\t\tlimit: paging.limit\n\t};\n}\n//#endregion\n//#region src/shared/errors.ts\n/**\n* Error thrown when attempting to access a deleted document.\n*/\nvar DocumentDeletedError = class DocumentDeletedError extends Error {\n\tdocumentId;\n\tdeletedAtUtcIso;\n\tconstructor(documentId, deletedAtUtcIso = null) {\n\t\tconst message = deletedAtUtcIso ? `Document ${documentId} was deleted at ${deletedAtUtcIso}` : `Document ${documentId} has been deleted`;\n\t\tsuper(message);\n\t\tthis.name = \"DocumentDeletedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.deletedAtUtcIso = deletedAtUtcIso;\n\t\tError.captureStackTrace(this, DocumentDeletedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentDeletedError\";\n\t}\n};\n/**\n* Error thrown when the auth policy denies an action at the executor gate.\n*/\nvar AuthorizationDeniedError = class AuthorizationDeniedError extends Error {\n\tdocumentId;\n\tscope;\n\toperation;\n\tsubject;\n\tconstructor(documentId, scope, operation, subject) {\n\t\tsuper(`Authorization denied: ${subject ?? \"anonymous\"} may not execute ${operation} in scope \"${scope}\" of document ${documentId}`);\n\t\tthis.name = \"AuthorizationDeniedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.operation = operation;\n\t\tthis.subject = subject;\n\t\tError.captureStackTrace(this, AuthorizationDeniedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthorizationDeniedError\";\n\t}\n};\n/**\n* An auth operation did not strictly exceed the newest timestamp in its stream.\n*\n* Terminal and asymmetric by design: no ordering rule can reconcile two replicas\n* that each accepted an auth operation offline, because either order hands one\n* authority the other never granted, so the replica ahead holds the arrival.\n*/\nvar AuthTimestampNotMonotonicError = class AuthTimestampNotMonotonicError extends Error {\n\tdocumentId;\n\tbranch;\n\ttimestampUtcMs;\n\tnewestTimestampUtcMs;\n\tconstructor(documentId, branch, timestampUtcMs, newestTimestampUtcMs) {\n\t\tsuper(`Auth timestamp not monotonic: ${timestampUtcMs} does not exceed ${newestTimestampUtcMs} in the auth stream of document ${documentId} on branch ${branch}`);\n\t\tthis.name = \"AuthTimestampNotMonotonicError\";\n\t\tthis.documentId = documentId;\n\t\tthis.branch = branch;\n\t\tthis.timestampUtcMs = timestampUtcMs;\n\t\tthis.newestTimestampUtcMs = newestTimestampUtcMs;\n\t\tError.captureStackTrace(this, AuthTimestampNotMonotonicError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthTimestampNotMonotonicError\";\n\t}\n};\n/**\n* An operation or action carried a timestamp that is not an ISO-8601 UTC\n* instant.\n*\n* Terminal rather than retryable: the value does not change between attempts,\n* so a retry re-runs the whole job to fail identically. Quarantining, unlike a\n* held auth operation — this is malformed data rather than two replicas\n* disagreeing, and nothing further from that source should be trusted until it\n* is looked at.\n*/\nvar InvalidOperationTimestampError = class InvalidOperationTimestampError extends Error {\n\tdocumentId;\n\tscope;\n\ttimestampUtcMs;\n\tconstructor(documentId, scope, timestampUtcMs, context) {\n\t\tsuper(`Invalid timestamp \"${timestampUtcMs}\" on ${context} in scope \"${scope}\" of document ${documentId}`);\n\t\tthis.name = \"InvalidOperationTimestampError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.timestampUtcMs = timestampUtcMs;\n\t\tError.captureStackTrace(this, InvalidOperationTimestampError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"InvalidOperationTimestampError\";\n\t}\n};\n/**\n* A load would move more operations than the bound allows, indicating a real\n* divergence between local and incoming history. Counts only first-time moves,\n* so a re-evaluation pass's re-appends do not make busy documents\n* revocation-proof. Terminal: the condition is deterministic.\n*/\nvar ExcessiveReshuffleError = class ExcessiveReshuffleError extends Error {\n\tdocumentId;\n\tscope;\n\tcount;\n\tthreshold;\n\tconstructor(documentId, scope, count, threshold) {\n\t\tsuper(`Excessive reshuffle detected: ${count} operations in scope \"${scope}\" of document ${documentId} exceeds the threshold of ${threshold}. This indicates a significant divergence between local and incoming operations.`);\n\t\tthis.name = \"ExcessiveReshuffleError\";\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.count = count;\n\t\tthis.threshold = threshold;\n\t\tError.captureStackTrace(this, ExcessiveReshuffleError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"ExcessiveReshuffleError\";\n\t}\n};\n/**\n* Error thrown when an operation has an invalid signature.\n*/\nvar InvalidSignatureError = class InvalidSignatureError extends Error {\n\tdocumentId;\n\treason;\n\tconstructor(documentId, reason) {\n\t\tsuper(`Invalid signature in document ${documentId}: ${reason}`);\n\t\tthis.name = \"InvalidSignatureError\";\n\t\tthis.documentId = documentId;\n\t\tthis.reason = reason;\n\t\tError.captureStackTrace(this, InvalidSignatureError);\n\t}\n};\n/**\n* An UPGRADE_DOCUMENT action's preconditions (fromVersion and the per-scope\n* revision snapshot) did not match the document state the executor loaded.\n*\n* Terminal rather than retryable: the action carries the client's snapshot,\n* which stays stale no matter how often the job re-runs. The client is\n* expected to re-read the document and submit a fresh action instead.\n*/\nvar UpgradePreconditionFailedError = class UpgradePreconditionFailedError extends Error {\n\tdocumentId;\n\tdetail;\n\tconstructor(documentId, detail) {\n\t\tsuper(`Upgrade precondition failed for document ${documentId}: ${detail}`);\n\t\tthis.name = \"UpgradePreconditionFailedError\";\n\t\tthis.documentId = documentId;\n\t\tthis.detail = detail;\n\t\tError.captureStackTrace(this, UpgradePreconditionFailedError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"UpgradePreconditionFailedError\";\n\t}\n};\n/**\n* Error thrown when a document is not found (no operations exist for the document ID).\n*/\nvar DocumentNotFoundError = class DocumentNotFoundError extends Error {\n\tdocumentId;\n\t/**\n\t* @param message Overrides the default text. A handler that knows which of\n\t* several documents an action reads - a relationship's source, say - says so\n\t* here rather than rewrapping in a bare Error, which would strip the name the\n\t* executor classifies by.\n\t*/\n\tconstructor(documentId, message) {\n\t\tsuper(message ?? `Document ${documentId} not found`);\n\t\tthis.name = \"DocumentNotFoundError\";\n\t\tthis.documentId = documentId;\n\t\tError.captureStackTrace(this, DocumentNotFoundError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentNotFoundError\";\n\t}\n};\n/**\n* An authorization preflight was asked for while the reactor's decision model\n* is off, so there is no model to answer from.\n*\n* Thrown rather than answered from the legacy host-side permission tables. The\n* two systems do not compose: the tables record which addresses a host lets\n* near a drive, the policy records what a document's own grants permit, and an\n* answer stitched from both would report an admission verdict neither system\n* would reach. A caller that cannot get a prediction disables nothing, which\n* leaves the submit path -- and its real gate -- as the only authority.\n*\n* Detection is by `name`, not `instanceof`: the SharedWorker RPC boundary\n* rebuilds a thrown error from `{ name, message, stack, cause }` alone\n* (`reactor-browser/src/rpc/error-info.ts`), so the class identity and any\n* custom field are lost in transit. This error therefore carries no fields.\n*/\nvar AuthEnforcementDisabledError = class AuthEnforcementDisabledError extends Error {\n\tconstructor() {\n\t\tsuper(\"Authorization evaluation requires the authEnforcement feature flag; this reactor holds no decision model, and the legacy host-table permission system cannot answer for one\");\n\t\tthis.name = \"AuthEnforcementDisabledError\";\n\t\tError.captureStackTrace(this, AuthEnforcementDisabledError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AuthEnforcementDisabledError\";\n\t}\n};\n/**\n* Error thrown when a relationship edge an operation names does not exist.\n*\n* Detection is by `name`, not `instanceof`: the SharedWorker RPC boundary\n* rebuilds a thrown error from `{ name, message, stack, cause }` alone\n* (`reactor-browser/src/rpc/error-info.ts`), so the class identity is lost in\n* transit.\n*/\nvar RelationshipNotFoundError = class RelationshipNotFoundError extends Error {\n\tsourceId;\n\ttargetId;\n\trelationshipType;\n\tconstructor(sourceId, targetId, relationshipType) {\n\t\tsuper(`No ${relationshipType} relationship from ${sourceId} to ${targetId}`);\n\t\tthis.name = \"RelationshipNotFoundError\";\n\t\tthis.sourceId = sourceId;\n\t\tthis.targetId = targetId;\n\t\tthis.relationshipType = relationshipType;\n\t\tError.captureStackTrace(this, RelationshipNotFoundError);\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"RelationshipNotFoundError\";\n\t}\n};\n//#endregion\n//#region src/storage/interfaces.ts\n/**\n* Thrown when an operation with the same identity already exists in the store.\n*/\nvar DuplicateOperationError = class extends Error {\n\tconstructor(description) {\n\t\tsuper(`Duplicate operation: ${description}`);\n\t\tthis.name = \"DuplicateOperationError\";\n\t}\n};\n/**\n* Thrown when a concurrent write conflict is detected during an atomic apply.\n*/\nvar OptimisticLockError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"OptimisticLockError\";\n\t}\n};\n/**\n* Thrown when the caller-provided revision does not match the current\n* stored revision, indicating a stale read.\n*/\nvar RevisionMismatchError = class extends Error {\n\tconstructor(expected, actual) {\n\t\tsuper(`Revision mismatch: expected ${expected}, got ${actual}`);\n\t\tthis.name = \"RevisionMismatchError\";\n\t}\n};\n/**\n* A create based on an empty stream that already has operations: the id is\n* taken, and no retry can resolve it. Matched by `name`, all the RPC boundary keeps.\n*/\nvar DocumentAlreadyExistsError = class extends Error {\n\tdocumentId;\n\tconstructor(documentId, scope, headRevision) {\n\t\tsuper(`Document ${documentId} already exists: create requested revision 0 but the \"${scope}\" stream is at revision ${headRevision}`);\n\t\tthis.name = \"DocumentAlreadyExistsError\";\n\t\tthis.documentId = documentId;\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DocumentAlreadyExistsError\";\n\t}\n};\n/** Error history keeps messages, not classes, so failures match by prefix. */\nconst APPEND_CONDITION_FAILED_PREFIX = \"Append condition failed: \";\n/**\n* A read-set stream grew before the append committed. A concurrency\n* conflict, not a fault: the caller retries against the new stream heads.\n*/\nvar AppendConditionFailedError = class extends Error {\n\tconstructor(condition) {\n\t\tconst streams = condition.streams.map((s) => `${s.documentId}:${s.scope}:${s.branch}@${s.revision}`).join(\", \");\n\t\tsuper(`${APPEND_CONDITION_FAILED_PREFIX}a read-set stream advanced [${streams}]`);\n\t\tthis.condition = condition;\n\t\tthis.name = \"AppendConditionFailedError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"AppendConditionFailedError\";\n\t}\n\t/** True when a recorded error message is an append-condition failure. */\n\tstatic isFailureMessage(message) {\n\t\treturn message.startsWith(APPEND_CONDITION_FAILED_PREFIX);\n\t}\n};\n/**\n* Which sense of \"exists\" a caller of {@link IDocumentView.exists} means.\n*/\nlet DocumentExistence = /* @__PURE__ */ function(DocumentExistence) {\n\t/**\n\t* A document that is present and not deleted. This is the question a read\n\t* asks: a deleted document is not readable, so it does not exist.\n\t*/\n\tDocumentExistence[\"LiveOnly\"] = \"LiveOnly\";\n\t/**\n\t* Whether the id is taken, deleted or not. This is the question a write\n\t* asks: a deleted document keeps its operation stream, so its id can never\n\t* be reused, and answering from snapshots alone would say otherwise whenever\n\t* a snapshot row is missing while the stream is intact.\n\t*/\n\tDocumentExistence[\"IncludingDeleted\"] = \"IncludingDeleted\";\n\treturn DocumentExistence;\n}({});\n//#endregion\n//#region src/decision/build-decision-model.ts\n/**\n* Reads each projection's stream through the supplied reader, recording the\n* revision observed. Static projections resolve first; derived projections\n* see only those and contribute a map from document id to state. Each\n* distinct stream is read once and yields one append condition entry.\n*/\nasync function buildDecisionModel(reader, definition, target, signal) {\n\tconst decisionModel = definition(target);\n\tconst projections = Object.entries(decisionModel.projections);\n\tconst reads = /* @__PURE__ */ new Map();\n\tconst model = {};\n\tfor (const [key, projection] of projections) {\n\t\tif (typeof projection.query === \"function\") continue;\n\t\tmodel[key] = (await readStream(reader, projection.query, reads, signal)).state;\n\t}\n\tconst staticModel = { ...model };\n\tfor (const [key, projection] of projections) {\n\t\tif (typeof projection.query !== \"function\") continue;\n\t\tconst queries = projection.query(staticModel);\n\t\tconst value = {};\n\t\tfor (const query of queries) {\n\t\t\tlet read;\n\t\t\ttry {\n\t\t\t\tread = await readStream(reader, query, reads, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DocumentNotFoundError) {\n\t\t\t\t\trecordEmptyStream(query, reads);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tvalue[query.documentId] = read.state;\n\t\t}\n\t\tmodel[key] = value;\n\t}\n\treturn {\n\t\tmodel,\n\t\tappendCondition: { streams: [...reads.values()].map((read) => read.stream) }\n\t};\n}\n/** Guards a stream that holds nothing yet: any operation appearing is growth. */\nfunction recordEmptyStream(query, reads) {\n\tconst key = `${query.documentId}:${query.scope}:${query.branch}`;\n\tif (reads.has(key)) return;\n\treads.set(key, {\n\t\tstate: void 0,\n\t\tstream: {\n\t\t\tdocumentId: query.documentId,\n\t\t\tscope: query.scope,\n\t\t\tbranch: query.branch,\n\t\t\trevision: -1\n\t\t}\n\t});\n}\nasync function readStream(reader, query, reads, signal) {\n\tconst key = `${query.documentId}:${query.scope}:${query.branch}`;\n\tconst existing = reads.get(key);\n\tif (existing) return existing;\n\tconst document = await reader.getState(query.documentId, query.scope, query.branch, void 0, signal);\n\tconst read = {\n\t\tstate: document.state[query.scope],\n\t\tstream: {\n\t\t\tdocumentId: query.documentId,\n\t\t\tscope: query.scope,\n\t\t\tbranch: query.branch,\n\t\t\trevision: observedRevision(document, query.scope)\n\t\t}\n\t};\n\treads.set(key, read);\n\treturn read;\n}\n/**\n* The highest operation index the document reflects for the scope, or -1 if\n* empty. `header.revision` is authoritative, not the rebuilt operation list.\n*/\nfunction observedRevision(document, scope) {\n\tif (scope in document.header.revision) return document.header.revision[scope] - 1;\n\tif (scope in document.operations) {\n\t\tconst operations = document.operations[scope];\n\t\tif (operations.length > 0) return operations[operations.length - 1].index;\n\t}\n\tif (!(scope in document.header.revision)) return -1;\n\treturn document.header.revision[scope] - 1;\n}\n/**\n* The projections whose queries depend on folded state. A positional walk\n* resolves their streams through `queryOverHistory`; a projection without one\n* contributes no streams to a walk.\n*/\nfunction derivedReadSet(definition) {\n\tconst projections = [];\n\tfor (const [name, projection] of Object.entries(definition.projections)) {\n\t\tif (typeof projection.query !== \"function\") continue;\n\t\tprojections.push({\n\t\t\tname,\n\t\t\tdecidingActions: projection.decidingActions,\n\t\t\tapply: projection.apply,\n\t\t\tqueryOverHistory: projection.queryOverHistory\n\t\t});\n\t}\n\treturn projections;\n}\n/**\n* The streams a model reads whose queries are known before it is built. A\n* derived query needs the statically-queried projections first, so it is not\n* included here.\n*/\nfunction staticReadSet(definition) {\n\tconst streams = [];\n\tfor (const [name, projection] of Object.entries(definition.projections)) {\n\t\tif (typeof projection.query === \"function\") continue;\n\t\tstreams.push({\n\t\t\tname,\n\t\t\tquery: projection.query,\n\t\t\tdecidingActions: projection.decidingActions,\n\t\t\tapply: projection.apply\n\t\t});\n\t}\n\treturn streams;\n}\n//#endregion\n//#region src/decision/auth-decision-model.ts\nfunction refusalReason(refusal) {\n\tswitch (refusal) {\n\t\tcase \"version-unsupported\": return AUTH_VERSION_UNSUPPORTED_REASON;\n\t\tcase \"denied-by-grant\": return AUTH_DENIED_BY_GRANT_REASON;\n\t\tcase \"no-applicable-grant\": return AUTH_NO_GRANT_REASON;\n\t}\n}\nfunction decideAuthModel(model, subject, request, groups, conditions) {\n\tif (request.verb === \"execute\" && model.document.isDeleted) return {\n\t\tdecision: \"deny\",\n\t\treason: DOCUMENT_DELETED_REASON\n\t};\n\tconst evaluation = evaluate(model.auth, subject, request, groups, conditions);\n\tif (evaluation.decision === \"allow\") return { decision: \"allow\" };\n\treturn {\n\t\tdecision: \"deny\",\n\t\treason: refusalReason(evaluation.refusal)\n\t};\n}\nfunction documentProjection(target) {\n\treturn {\n\t\tdecidingActions: [\"DELETE_DOCUMENT\"],\n\t\tapply: (document, operation) => operation.action.type === \"DELETE_DOCUMENT\" ? applyDeleteDocumentAction({\n\t\t\t...document,\n\t\t\tstate: { ...document.state }\n\t\t}, operation.action) : document,\n\t\tquery: {\n\t\t\tdocumentId: target.documentId,\n\t\t\tbranch: target.branch,\n\t\t\tscope: \"document\"\n\t\t}\n\t};\n}\nfunction authProjection(target) {\n\treturn {\n\t\tdecidingActions: [...AUTH_ACTION_TYPES],\n\t\tapply: (document, operation) => applyAuthAction(document, operation.action),\n\t\tquery: {\n\t\t\tdocumentId: target.documentId,\n\t\t\tbranch: target.branch,\n\t\t\tscope: \"auth\"\n\t\t}\n\t};\n}\n/** This decision model uses both the document and the auth streams. */\nfunction authDecisionModel(target) {\n\treturn {\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target)\n\t\t},\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn decideAuthModel(model, subject, request);\n\t\t}\n\t};\n}\n/**\n* Folds one group-stream operation with the registered group model's reducer.\n* A reactor without the module registered folds nothing, so the member list\n* stays as read and a missing reducer never widens access.\n*/\nfunction applyGroupOperation(registry, document, operation) {\n\tlet reducer;\n\ttry {\n\t\treducer = registry.getModule(groupDocumentType).reducer;\n\t} catch {\n\t\treturn document;\n\t}\n\treturn reducer(document, operation.action);\n}\n/**\n* Folds one evaluated-scope operation with the reducer registered for the\n* document's own type, at the document's stamped version. A reactor without\n* that module folds nothing, so conditions read the base state and an\n* unresolvable reducer never widens access.\n*/\nfunction applyModelOperation(registry, document, operation) {\n\tlet reducer;\n\ttry {\n\t\tconst version = normalizeDocumentModelVersion(document.state.document?.version);\n\t\treducer = registry.getModule(document.header.documentType, version).reducer;\n\t} catch {\n\t\treturn document;\n\t}\n\treturn reducer(document, operation.action);\n}\n/**\n* The auth model extended with a derived groups projection: the streams it\n* reads are the group documents the folded grant list names, so adding a\n* grant that names a new group pulls that group's stream into the read-set.\n* Group queries pin the main branch, because a group's member list lives on\n* its main branch no matter which branch the referencing document is on.\n*/\nfunction groupsProjection(registry) {\n\treturn {\n\t\tdecidingActions: [...groupMembershipActionTypes],\n\t\tapply: (document, operation) => applyGroupOperation(registry, document, operation),\n\t\tquery: (model) => referencedGroupIds(model.auth?.grants ?? []).map((id) => ({\n\t\t\tdocumentId: id,\n\t\t\tbranch: \"main\",\n\t\t\tscope: \"global\"\n\t\t})),\n\t\tqueryOverHistory: (reads) => {\n\t\t\tconst ids = [];\n\t\t\tfor (const read of reads) {\n\t\t\t\tif (read.name !== \"auth\") continue;\n\t\t\t\tfor (const operation of read.operations) for (const id of mentionedGroupIds(operation.action)) if (!ids.includes(id)) ids.push(id);\n\t\t\t}\n\t\t\treturn ids.map((id) => ({\n\t\t\t\tdocumentId: id,\n\t\t\t\tbranch: \"main\",\n\t\t\t\tscope: \"global\"\n\t\t\t}));\n\t\t}\n\t};\n}\nfunction authGroupsDecisionModel(registry) {\n\treturn (target) => ({\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target),\n\t\t\tgroups: groupsProjection(registry)\n\t\t},\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn decideAuthModel(model, subject, request, model.groups);\n\t\t}\n\t});\n}\n/**\n* The groups model with conditions live: decide hands the executing scope's\n* state and the action input through to the evaluator, so `where` clauses\n* and { match } principals apply. The model folds the evaluated scope during\n* a positional walk, so a condition reads the state as it stood at each\n* operation's position.\n*/\nfunction authConditionsDecisionModel(registry) {\n\treturn (target) => ({\n\t\tprojections: {\n\t\t\tdocument: documentProjection(target),\n\t\t\tauth: authProjection(target),\n\t\t\tgroups: groupsProjection(registry)\n\t\t},\n\t\tfoldEvaluatedScope: (document, operation) => applyModelOperation(registry, document, operation),\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request, ctx) {\n\t\t\treturn decideAuthModel(model, subject, request, model.groups, {\n\t\t\t\tscopeState: ctx.scopeState,\n\t\t\t\tactionInput: ctx.actionInput\n\t\t\t});\n\t\t}\n\t});\n}\n//#endregion\n//#region src/decision/document-decision-model.ts\n/**\n* The simplest decision model: one projection over the document scope, which\n* rejects on a deleted document.\n*/\nfunction documentDecisionModel(target) {\n\treturn {\n\t\tprojections: { document: {\n\t\t\tdecidingActions: [\"DELETE_DOCUMENT\"],\n\t\t\tapply: (document, operation) => operation.action.type === \"DELETE_DOCUMENT\" ? applyDeleteDocumentAction({\n\t\t\t\t...document,\n\t\t\t\tstate: { ...document.state }\n\t\t\t}, operation.action) : document,\n\t\t\tquery: {\n\t\t\t\tdocumentId: target.documentId,\n\t\t\t\tbranch: target.branch,\n\t\t\t\tscope: \"document\"\n\t\t\t}\n\t\t} },\n\t\tevaluatesScope() {\n\t\t\treturn true;\n\t\t},\n\t\tdecide(model, subject, request) {\n\t\t\treturn request.verb === \"execute\" && model.document.isDeleted ? {\n\t\t\t\tdecision: \"deny\",\n\t\t\t\treason: DOCUMENT_DELETED_REASON\n\t\t\t} : { decision: \"allow\" };\n\t\t}\n\t};\n}\n//#endregion\n//#region src/decision/registered-model.ts\n/**\n* Builds the model at the stream heads and decides one request against it. The\n* append condition it returns is the read-set the store enforces at write time.\n*\n* With `conditions` supplied, the executing scope's state is read at the head\n* for `doc.<scope>.*` paths, or taken from the run's carried document when the\n* caller has already reduced earlier writes into it. That read carries no\n* append-condition entry of its own: the written stream's expected-revision\n* check already refuses a write whose scope grew between the read and the\n* append.\n*/\nasync function decideAtHead(model, cache, target, subject, request, signal, conditions) {\n\tconst built = await buildDecisionModel(cache, model, target, signal);\n\tlet scopeState;\n\tif (conditions !== void 0) scopeState = (conditions.carriedDocument ?? await cache.getState(target.documentId, request.scope, target.branch, void 0, signal)).state[request.scope];\n\treturn {\n\t\tevaluation: model(target).decide(built.model, subject, request, {\n\t\t\tscopeState,\n\t\t\tactionInput: conditions?.actionInput\n\t\t}),\n\t\tappendCondition: built.appendCondition,\n\t\tdocumentVersion: built.model.document.version,\n\t\tdeletedAtUtcIso: built.model.document.deletedAtUtcIso ?? null\n\t};\n}\n/**\n* The model this reactor enforces. With `authEnforcement` off the auth scope is\n* absent from every append condition and no load walks it; with `authGroups`\n* on, the group documents the grant list names join the read-set and the\n* registry supplies the reducer that folds them.\n*/\nfunction selectDecisionModel(flags, registry) {\n\tif (flags.authConditions) return authConditionsDecisionModel(registry);\n\tif (flags.authGroups) return authGroupsDecisionModel(registry);\n\treturn flags.authEnforcement ? authDecisionModel : documentDecisionModel;\n}\n//#endregion\n//#region src/executor/util.ts\n/** Actions the reactor reduces itself, onto the document scope. */\nconst DOCUMENT_SCOPE_ACTIONS = new Set([\n\t\"CREATE_DOCUMENT\",\n\t\"DELETE_DOCUMENT\",\n\t\"UPGRADE_DOCUMENT\",\n\t\"ADD_RELATIONSHIP\",\n\t\"REMOVE_RELATIONSHIP\",\n\t\"UPDATE_RELATIONSHIP\"\n]);\n/**\n* `CREATE_DOCUMENT` is exempt by necessity: it runs before the document exists,\n* so building a decision model would throw and defer the job forever.\n*/\nconst GATED_DOCUMENT_ACTIONS = new Set([...DOCUMENT_SCOPE_ACTIONS].filter((type) => type !== \"CREATE_DOCUMENT\"));\n/**\n* The document a document-scope action writes to, which is not always the job's\n* own document: delete and upgrade name it in `input.documentId`, and the\n* relationship actions in `input.sourceId`. `execute` only checks that a batch\n* shares one scope, so a caller can submit an action whose target is a document\n* other than the one the job is keyed by. The policy gate has to follow the\n* action rather than the job, or it decides against a policy the caller may\n* control instead of the one guarding the write.\n*/\nfunction targetDocumentId(action, fallback) {\n\tconst input = action.input;\n\tif (action.type === \"ADD_RELATIONSHIP\" || action.type === \"REMOVE_RELATIONSHIP\" || action.type === \"UPDATE_RELATIONSHIP\") return typeof input?.sourceId === \"string\" && input.sourceId.length > 0 ? input.sourceId : fallback;\n\treturn typeof input?.documentId === \"string\" && input.documentId.length > 0 ? input.documentId : fallback;\n}\n/**\n* Creates a PHDocument from a CREATE_DOCUMENT action input.\n* Reconstructs the document header and initializes the base state.\n*\n* @param action - The CREATE_DOCUMENT action containing the document parameters\n* @returns A newly constructed PHDocument with initialized header and base state\n*/\nfunction createDocumentFromAction(action) {\n\tconst input = action.input;\n\tconst header = createPresignedHeader();\n\theader.id = input.documentId;\n\theader.documentType = input.model;\n\tif (input.signing) {\n\t\theader.createdAtUtcIso = input.signing.createdAtUtcIso;\n\t\theader.lastModifiedAtUtcIso = input.signing.createdAtUtcIso;\n\t\theader.sig = {\n\t\t\tpublicKey: input.signing.publicKey,\n\t\t\tnonce: input.signing.nonce\n\t\t};\n\t}\n\tif (input.slug !== void 0) header.slug = input.slug;\n\tif (!header.slug) header.slug = input.documentId;\n\tif (input.name !== void 0) header.name = input.name;\n\tif (input.branch !== void 0) header.branch = input.branch;\n\tif (input.meta !== void 0) header.meta = input.meta;\n\tif (input.protocolVersions !== void 0) header.protocolVersions = input.protocolVersions;\n\tconst baseState = defaultBaseState();\n\treturn {\n\t\theader,\n\t\toperations: {},\n\t\tstate: baseState,\n\t\tinitialState: baseState,\n\t\tclipboard: []\n\t};\n}\n/**\n* Calculate the next operation index for a specific scope.\n* Each scope maintains its own independent index sequence.\n*\n* Per-scope indexing means:\n* - Each scope (document, global, local, etc.) has independent indexes\n* - Indexes start at 0 for each scope\n* - Different scopes can have operations with the same index value\n*\n* This function uses header.revision which is populated by the cache/storage layer\n* and contains the next available index for each scope. This design avoids requiring\n* the full operation history to be loaded, which is crucial for snapshot-based caching.\n*\n* @param document - The document whose header.revision to inspect\n* @param scope - The scope to calculate the next index for\n* @returns The next available index in the specified scope\n*/\nconst getNextIndexForScope = (document, scope) => {\n\treturn document.header.revision[scope] || 0;\n};\n/**\n* Creates an empty consistency token with no coordinates.\n* Used when a job is registered or fails without writing operations.\n*\n* @returns A consistency token with an empty coordinates array\n*/\nfunction createEmptyConsistencyToken() {\n\treturn {\n\t\tversion: 1,\n\t\tcreatedAtUtcIso: (/* @__PURE__ */ new Date()).toISOString(),\n\t\tcoordinates: []\n\t};\n}\n/**\n* Creates a consistency token from operations written during job execution.\n* Maps each operation to a consistency coordinate tracking (documentId, scope, branch, operationIndex).\n* If no operations are provided, returns an empty token.\n*\n* @param operationsWithContext - Array of operations with their execution context\n* @returns A consistency token representing all operations written\n*/\nfunction createConsistencyToken(operationsWithContext) {\n\tif (operationsWithContext.length === 0) return createEmptyConsistencyToken();\n\tconst coordinates = [];\n\tfor (let i = 0; i < operationsWithContext.length; i++) {\n\t\tconst opWithContext = operationsWithContext[i];\n\t\tcoordinates.push({\n\t\t\tdocumentId: opWithContext.context.documentId,\n\t\t\tscope: opWithContext.context.scope,\n\t\t\tbranch: opWithContext.context.branch,\n\t\t\toperationIndex: opWithContext.operation.index\n\t\t});\n\t}\n\treturn {\n\t\tversion: 1,\n\t\tcreatedAtUtcIso: (/* @__PURE__ */ new Date()).toISOString(),\n\t\tcoordinates\n\t};\n}\nfunction createOperation(action, index, skip, context) {\n\treturn {\n\t\tid: deriveOperationId(context.documentId, context.scope, context.branch, action.id),\n\t\tindex,\n\t\ttimestampUtcMs: action.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString(),\n\t\thash: \"\",\n\t\tskip,\n\t\taction\n\t};\n}\nfunction updateDocumentRevision(document, scope, operationIndex) {\n\tdocument.header.revision = {\n\t\t...document.header.revision,\n\t\t[scope]: operationIndex + 1\n\t};\n}\nfunction buildSuccessResult(job, operation, documentId, documentType, resultingState, startTime) {\n\treturn {\n\t\tjob,\n\t\tsuccess: true,\n\t\toperations: [operation],\n\t\toperationsWithContext: [{\n\t\t\toperation,\n\t\t\tcontext: {\n\t\t\t\tdocumentId,\n\t\t\t\tscope: job.scope,\n\t\t\t\tbranch: job.branch,\n\t\t\t\tdocumentType,\n\t\t\t\tresultingState,\n\t\t\t\tordinal: 0\n\t\t\t}\n\t\t}],\n\t\tduration: Date.now() - startTime\n\t};\n}\nfunction buildErrorResult(job, error, startTime) {\n\treturn {\n\t\tjob,\n\t\tsuccess: false,\n\t\terror,\n\t\tduration: Date.now() - startTime\n\t};\n}\n/**\n* The error a refusal surfaces as. Both classes are already terminal in the job\n* result handler, so a refusal never burns a retry.\n*/\nfunction refusalError(reason, documentId, deletedAtUtcIso, action) {\n\tif (reason === DOCUMENT_DELETED_REASON) return new DocumentDeletedError(documentId, deletedAtUtcIso);\n\treturn new AuthorizationDeniedError(documentId, action.scope, action.type, action.context?.signer?.user.address);\n}\n/**\n* Whether this operation is part of the document's creation. The create and the\n* upgrade from version zero hold the first two indexes for the life of the\n* document, so a reshuffle has to leave them where they are.\n*/\nfunction isGenesisOperation(operation) {\n\tif (operation.action.type === \"CREATE_DOCUMENT\") return true;\n\tif (operation.action.type !== \"UPGRADE_DOCUMENT\") return false;\n\treturn operation.action.input.fromVersion === 0;\n}\n/**\n* The distinct streams a job wrote, collected so a rollback knows what to evict.\n*\n* A write records its stream on every apply, and a long run applies the same\n* stream hundreds of times, so this keeps one entry per stream rather than one\n* per write: the eviction only cares which streams were touched, and the\n* successful jobs that never read this back pay for a lookup instead of an\n* allocation.\n*/\nvar TouchedStreams = class {\n\tstreams = /* @__PURE__ */ new Map();\n\tadd(documentId, scope, branch) {\n\t\tconst key = `${documentId}\\u0000${scope}\\u0000${branch}`;\n\t\tif (this.streams.has(key)) return;\n\t\tthis.streams.set(key, {\n\t\t\tdocumentId,\n\t\t\tscope,\n\t\t\tbranch\n\t\t});\n\t}\n\t[Symbol.iterator]() {\n\t\treturn this.streams.values();\n\t}\n};\n/**\n* The ids of the actions the caller handed to a job. Load and reevaluation\n* jobs write operations nobody submitted, so they report none.\n*/\nfunction submittedActionIds(job) {\n\treturn job.kind === \"mutation\" ? job.actions.map((action) => action.id) : [];\n}\n/**\n* Reports what became of each submitted action.\n*\n* A job's operations can include ones it only moved to a new index, so only\n* those carrying a submitted action are reported. Returns undefined when the\n* job submitted nothing, which keeps `JobInfo.result` null for the jobs that\n* have no caller to answer to.\n*/\nfunction summarizeSubmittedActions(operations, submitted) {\n\tif (!submitted || submitted.length === 0) return;\n\tconst ids = new Set(submitted);\n\tconst actions = [];\n\tfor (const { operation, context } of operations) {\n\t\tif (!ids.has(operation.action.id)) continue;\n\t\tactions.push({\n\t\t\tactionId: operation.action.id,\n\t\t\tscope: context.scope,\n\t\t\tindex: operation.index,\n\t\t\t...operationOutcome(operation)\n\t\t});\n\t}\n\tif (actions.length === 0) return;\n\treturn {\n\t\tactions,\n\t\tallApplied: actions.every((action) => action.kind === \"applied\")\n\t};\n}\n//#endregion\n//#region src/registry/errors.ts\n/**\n* Error thrown when a document model module is not found in the registry.\n*/\nvar ModuleNotFoundError = class extends Error {\n\tdocumentType;\n\trequestedVersion;\n\tconstructor(documentType, version) {\n\t\tconst versionSuffix = version !== void 0 ? ` version ${version}` : \"\";\n\t\tsuper(`Document model module not found for type: ${documentType}${versionSuffix}`);\n\t\tthis.name = \"ModuleNotFoundError\";\n\t\tthis.documentType = documentType;\n\t\tthis.requestedVersion = version;\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"ModuleNotFoundError\";\n\t}\n};\n/**\n* Error thrown when attempting to register a module that already exists.\n*/\nvar DuplicateModuleError = class extends Error {\n\tconstructor(documentType, version) {\n\t\tconst versionSuffix = version !== void 0 ? ` (version ${version})` : \"\";\n\t\tsuper(`Document model module already registered for type: ${documentType}${versionSuffix}`);\n\t\tthis.name = \"DuplicateModuleError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DuplicateModuleError\";\n\t}\n};\n/**\n* Error thrown when a module is invalid or malformed.\n*/\nvar InvalidModuleError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(`Invalid document model module: ${message}`);\n\t\tthis.name = \"InvalidModuleError\";\n\t}\n};\n/**\n* Error thrown when attempting to register an upgrade manifest that already exists.\n*/\nvar DuplicateManifestError = class extends Error {\n\tconstructor(documentType) {\n\t\tsuper(`Upgrade manifest already registered for type: ${documentType}`);\n\t\tthis.name = \"DuplicateManifestError\";\n\t}\n\tstatic isError(error) {\n\t\treturn Error.isError(error) && error.name === \"DuplicateManifestError\";\n\t}\n};\n/**\n* Error thrown when an upgrade manifest is not found.\n*/\nvar ManifestNotFoundError = class extends Error {\n\tconstructor(documentType) {\n\t\tsuper(`Upgrade manifest not found for type: ${documentType}`);\n\t\tthis.name = \"ManifestNotFoundError\";\n\t}\n};\n/**\n* Error thrown when a required upgrade transition is missing from the manifest.\n*/\nvar MissingUpgradeTransitionError = class extends Error {\n\tconstructor(documentType, fromVersion, toVersion) {\n\t\tsuper(`Missing upgrade transition for ${documentType}: v${fromVersion} to v${toVersion}`);\n\t\tthis.name = \"MissingUpgradeTransitionError\";\n\t}\n};\n/**\n* Error thrown when getUpgradeReducer is called with a non-single-step version increment.\n*/\nvar InvalidUpgradeStepError = class extends Error {\n\tconstructor(documentType, fromVersion, toVersion) {\n\t\tsuper(`Invalid upgrade step for ${documentType}: must be single version increment, got v${fromVersion} to v${toVersion}`);\n\t\tthis.name = \"InvalidUpgradeStepError\";\n\t}\n};\n//#endregion\n//#region src/executor/types.ts\n/** How long a deferred job waits for its document before it fails. */\nconst DEFAULT_DEFERRED_JOB_TTL_MS = 3e4;\n/**\n* Event types for the job executor\n*/\nconst JobExecutorEventTypes = {\n\tJOB_STARTED: 2e4,\n\tJOB_COMPLETED: 20001,\n\tJOB_FAILED: 20002,\n\tEXECUTOR_STARTED: 20003,\n\tEXECUTOR_STOPPED: 20004\n};\n//#endregion\n//#region src/cache/collection-membership-cache.ts\nvar CollectionMembershipCache = class CollectionMembershipCache {\n\tcache = /* @__PURE__ */ new Map();\n\tconstructor(operationIndex) {\n\t\tthis.operationIndex = operationIndex;\n\t}\n\twithScopedIndex(operationIndex) {\n\t\tconst scoped = new CollectionMembershipCache(operationIndex);\n\t\tscoped.cache = this.cache;\n\t\treturn scoped;\n\t}\n\tasync getCollectionsForDocuments(documentIds) {\n\t\tconst result = {};\n\t\tconst missing = [];\n\t\tfor (const docId of documentIds) {\n\t\t\tconst cached = this.cache.get(docId);\n\t\t\tif (cached !== void 0) result[docId] = cached;\n\t\t\telse missing.push(docId);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tconst fromDb = await this.operationIndex.getCollectionsForDocuments(missing);\n\t\t\tfor (const docId of missing) {\n\t\t\t\tconst collections = fromDb[docId] ?? [];\n\t\t\t\tresult[docId] = collections;\n\t\t\t\tthis.cache.set(docId, collections);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\tinvalidate(documentId) {\n\t\tthis.cache.delete(documentId);\n\t}\n};\n//#endregion\n//#region src/cache/lru/lru-tracker.ts\nvar LRUNode = class {\n\tkey;\n\tprev;\n\tnext;\n\tconstructor(key) {\n\t\tthis.key = key;\n\t\tthis.prev = void 0;\n\t\tthis.next = void 0;\n\t}\n};\nvar LRUTracker = class {\n\tmap;\n\thead;\n\ttail;\n\tconstructor() {\n\t\tthis.map = /* @__PURE__ */ new Map();\n\t\tthis.head = void 0;\n\t\tthis.tail = void 0;\n\t}\n\tget size() {\n\t\treturn this.map.size;\n\t}\n\ttouch(key) {\n\t\tconst node = this.map.get(key);\n\t\tif (node) this.moveToFront(node);\n\t\telse this.addToFront(key);\n\t}\n\tevict() {\n\t\tif (!this.tail) return;\n\t\tconst key = this.tail.key;\n\t\tthis.remove(key);\n\t\treturn key;\n\t}\n\tremove(key) {\n\t\tconst node = this.map.get(key);\n\t\tif (!node) return;\n\t\tthis.removeNode(node);\n\t\tthis.map.delete(key);\n\t}\n\tclear() {\n\t\tthis.map.clear();\n\t\tthis.head = void 0;\n\t\tthis.tail = void 0;\n\t}\n\taddToFront(key) {\n\t\tconst node = new LRUNode(key);\n\t\tthis.map.set(key, node);\n\t\tif (!this.head) {\n\t\t\tthis.head = node;\n\t\t\tthis.tail = node;\n\t\t} else {\n\t\t\tnode.next = this.head;\n\t\t\tthis.head.prev = node;\n\t\t\tthis.head = node;\n\t\t}\n\t}\n\tmoveToFront(node) {\n\t\tif (node === this.head) return;\n\t\tthis.removeNode(node);\n\t\tnode.prev = void 0;\n\t\tnode.next = this.head;\n\t\tif (this.head) this.head.prev = node;\n\t\tthis.head = node;\n\t\tif (!this.tail) this.tail = node;\n\t}\n\tremoveNode(node) {\n\t\tif (node.prev) node.prev.next = node.next;\n\t\telse this.head = node.next;\n\t\tif (node.next) node.next.prev = node.prev;\n\t\telse this.tail = node.prev;\n\t}\n};\n//#endregion\n//#region src/cache/document-meta-cache.ts\n/**\n* In-memory document metadata cache with LRU eviction.\n*\n* Caches PHDocumentState per (documentId, branch) key. On cache miss,\n* rebuilds from document scope operations. Provides an explicit cross-scope\n* contract for accessing document scope metadata.\n*\n* **Thread Safety:**\n* Not thread-safe. Designed for single-threaded job executor environment.\n*/\nvar DocumentMetaCache = class DocumentMetaCache {\n\tcache;\n\tlruTracker;\n\toperationStore;\n\tconfig;\n\tconstructor(operationStore, config) {\n\t\tthis.operationStore = operationStore;\n\t\tthis.config = { maxDocuments: config.maxDocuments };\n\t\tthis.cache = /* @__PURE__ */ new Map();\n\t\tthis.lruTracker = new LRUTracker();\n\t}\n\twithScopedStore(operationStore) {\n\t\tconst scoped = new DocumentMetaCache(operationStore, this.config);\n\t\tscoped.cache = this.cache;\n\t\tscoped.lruTracker = this.lruTracker;\n\t\treturn scoped;\n\t}\n\tasync startup() {\n\t\treturn Promise.resolve();\n\t}\n\tasync shutdown() {\n\t\treturn Promise.resolve();\n\t}\n\tasync getDocumentMeta(documentId, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst key = this.makeKey(documentId, branch);\n\t\tconst cached = this.cache.get(key);\n\t\tif (cached) {\n\t\t\tthis.lruTracker.touch(key);\n\t\t\treturn cached;\n\t\t}\n\t\tconst meta = await this.rebuildLatest(documentId, branch, signal);\n\t\tthis.putDocumentMeta(documentId, branch, meta);\n\t\treturn meta;\n\t}\n\tasync rebuildAtRevision(documentId, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn this.rebuildFromOperations(documentId, branch, targetRevision, signal);\n\t}\n\tputDocumentMeta(documentId, branch, meta) {\n\t\tconst key = this.makeKey(documentId, branch);\n\t\tif (!this.cache.has(key) && this.cache.size >= this.config.maxDocuments) {\n\t\t\tconst evictKey = this.lruTracker.evict();\n\t\t\tif (evictKey) this.cache.delete(evictKey);\n\t\t}\n\t\tthis.cache.set(key, structuredClone(meta));\n\t\tthis.lruTracker.touch(key);\n\t}\n\tinvalidate(documentId, branch) {\n\t\tlet evicted = 0;\n\t\tif (branch === void 0) {\n\t\t\tfor (const key of this.cache.keys()) if (key.startsWith(`${documentId}:`)) {\n\t\t\t\tthis.cache.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else {\n\t\t\tconst key = this.makeKey(documentId, branch);\n\t\t\tif (this.cache.has(key)) {\n\t\t\t\tthis.cache.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted = 1;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n\tclear() {\n\t\tthis.cache.clear();\n\t\tthis.lruTracker.clear();\n\t}\n\tmakeKey(documentId, branch) {\n\t\treturn `${documentId}:${branch}`;\n\t}\n\tasync rebuildLatest(documentId, branch, signal) {\n\t\treturn this.rebuildFromOperations(documentId, branch, void 0, signal);\n\t}\n\tasync rebuildFromOperations(documentId, branch, targetRevision, signal) {\n\t\tconst docScopeOps = await this.operationStore.getSince(documentId, \"document\", branch, -1, void 0, void 0, signal);\n\t\tif (docScopeOps.results.length === 0) throw new DocumentNotFoundError(documentId);\n\t\tconst createOp = docScopeOps.results[0];\n\t\tif (createOp.action.type !== \"CREATE_DOCUMENT\") throw new Error(`Invalid document: first operation must be CREATE_DOCUMENT, found ${createOp.action.type}`);\n\t\tconst createAction = createOp.action;\n\t\tconst documentType = createAction.input.model;\n\t\tlet document = createDocumentFromAction(createAction);\n\t\tlet documentScopeRevision = 0;\n\t\tfor (const op of docScopeOps.results) {\n\t\t\tif (targetRevision !== void 0 && op.index > targetRevision) break;\n\t\t\tdocumentScopeRevision = op.index;\n\t\t\tif (op.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\tconst upgradeAction = op.action;\n\t\t\t\tdocument = applyUpgradeDocumentAction$1(document, upgradeAction);\n\t\t\t} else if (op.action.type === \"DELETE_DOCUMENT\") document = applyDeleteDocumentAction$1(document, op.action);\n\t\t}\n\t\treturn {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType,\n\t\t\tdocumentScopeRevision: documentScopeRevision + 1\n\t\t};\n\t}\n};\nvar KyselyOperationIndexTxn = class {\n\tcollections = [];\n\tcollectionMemberships = [];\n\tcollectionRemovals = [];\n\tgroupReferences = [];\n\toperations = [];\n\tmembershipInvalidations = /* @__PURE__ */ new Set();\n\t/** Called by the commit as it writes each document_collections row. */\n\trecordMembershipInvalidation(documentId) {\n\t\tthis.membershipInvalidations.add(documentId);\n\t}\n\tgetMembershipInvalidations() {\n\t\treturn [...this.membershipInvalidations];\n\t}\n\tcreateCollection(collectionId) {\n\t\tthis.collections.push(collectionId);\n\t}\n\taddToCollection(collectionId, documentId) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"addToCollection must be called after write() - no operations in transaction\");\n\t\tthis.collectionMemberships.push({\n\t\t\tcollectionId,\n\t\t\tdocumentId,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\tremoveFromCollection(collectionId, documentId) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"removeFromCollection must be called after write() - no operations in transaction\");\n\t\tthis.collectionRemovals.push({\n\t\t\tcollectionId,\n\t\t\tdocumentId,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\trecordGroupReferences(documentId, groupIds) {\n\t\tconst lastOpIndex = this.operations.length - 1;\n\t\tif (lastOpIndex < 0) throw new Error(\"recordGroupReferences must be called after write() - no operations in transaction\");\n\t\tif (groupIds.length === 0) return;\n\t\tthis.groupReferences.push({\n\t\t\tdocumentId,\n\t\t\tgroupIds,\n\t\t\toperationIndex: lastOpIndex\n\t\t});\n\t}\n\twrite(operations) {\n\t\tthis.operations.push(...operations);\n\t}\n\tgetCollections() {\n\t\treturn this.collections;\n\t}\n\tgetGroupReferenceRecords() {\n\t\treturn this.groupReferences;\n\t}\n\tgetCollectionMembershipRecords() {\n\t\treturn this.collectionMemberships;\n\t}\n\tgetCollectionRemovals() {\n\t\treturn this.collectionRemovals;\n\t}\n\tgetOperations() {\n\t\treturn this.operations;\n\t}\n};\nvar KyselyOperationIndex = class KyselyOperationIndex {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyOperationIndex(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tstart() {\n\t\treturn new KyselyOperationIndexTxn();\n\t}\n\tasync commit(txn, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst kyselyTxn = txn;\n\t\tif (this.trx) return this.executeCommit(this.trx, kyselyTxn);\n\t\tlet resultOrdinals = [];\n\t\tawait this.db.transaction().execute(async (trx) => {\n\t\t\tresultOrdinals = await this.executeCommit(trx, kyselyTxn);\n\t\t});\n\t\treturn resultOrdinals;\n\t}\n\t/**\n\t* A policy-driven join: keeps the earliest join so a rediscovered reference\n\t* never shrinks a backfill window remotes already rely on, and reopens a\n\t* closed membership because a policy reference is not a removable one.\n\t*/\n\tasync joinKeepingEarliest(trx, kyselyTxn, documentId, collectionId, ordinal) {\n\t\tkyselyTxn.recordMembershipInvalidation(documentId);\n\t\tawait trx.insertInto(\"document_collections\").values({\n\t\t\tdocumentId,\n\t\t\tcollectionId,\n\t\t\tjoinedOrdinal: ordinal,\n\t\t\tleftOrdinal: null\n\t\t}).onConflict((oc) => oc.columns([\"documentId\", \"collectionId\"]).doUpdateSet({\n\t\t\tjoinedOrdinal: sql`LEAST(\"document_collections\".\"joinedOrdinal\", EXCLUDED.\"joinedOrdinal\")`,\n\t\t\tleftOrdinal: null\n\t\t})).execute();\n\t}\n\tasync executeCommit(trx, kyselyTxn) {\n\t\tconst collections = kyselyTxn.getCollections();\n\t\tconst memberships = kyselyTxn.getCollectionMembershipRecords();\n\t\tconst removals = kyselyTxn.getCollectionRemovals();\n\t\tconst groupReferences = kyselyTxn.getGroupReferenceRecords();\n\t\tconst operations = kyselyTxn.getOperations();\n\t\tif (collections.length > 0) {\n\t\t\tconst collectionRows = collections.map((collectionId) => ({\n\t\t\t\tdocumentId: collectionId,\n\t\t\t\tcollectionId,\n\t\t\t\tjoinedOrdinal: BigInt(0),\n\t\t\t\tleftOrdinal: null\n\t\t\t}));\n\t\t\tfor (const collectionId of collections) kyselyTxn.recordMembershipInvalidation(collectionId);\n\t\t\tawait trx.insertInto(\"document_collections\").values(collectionRows).onConflict((oc) => oc.doNothing()).execute();\n\t\t}\n\t\tlet operationOrdinals = [];\n\t\tif (operations.length > 0) {\n\t\t\tconst operationRows = operations.map((op) => ({\n\t\t\t\topId: op.id || \"\",\n\t\t\t\tdocumentId: op.documentId,\n\t\t\t\tdocumentType: op.documentType,\n\t\t\t\tscope: op.scope,\n\t\t\t\tbranch: op.branch,\n\t\t\t\ttimestampUtcMs: op.timestampUtcMs,\n\t\t\t\tindex: op.index,\n\t\t\t\tskip: op.skip,\n\t\t\t\thash: op.hash,\n\t\t\t\taction: op.action,\n\t\t\t\tdeniedReason: op.deniedReason ?? null,\n\t\t\t\tsourceRemote: op.sourceRemote\n\t\t\t}));\n\t\t\toperationOrdinals = (await trx.insertInto(\"operation_index_operations\").values(operationRows).returning(\"ordinal\").execute()).map((row) => row.ordinal);\n\t\t}\n\t\tif (memberships.length > 0) for (const m of memberships) {\n\t\t\tconst ordinal = operationOrdinals[m.operationIndex];\n\t\t\tkyselyTxn.recordMembershipInvalidation(m.documentId);\n\t\t\tawait trx.insertInto(\"document_collections\").values({\n\t\t\t\tdocumentId: m.documentId,\n\t\t\t\tcollectionId: m.collectionId,\n\t\t\t\tjoinedOrdinal: BigInt(ordinal),\n\t\t\t\tleftOrdinal: null\n\t\t\t}).onConflict((oc) => oc.columns([\"documentId\", \"collectionId\"]).doUpdateSet({\n\t\t\t\tjoinedOrdinal: BigInt(ordinal),\n\t\t\t\tleftOrdinal: null\n\t\t\t})).execute();\n\t\t\tconst references = await trx.selectFrom(\"group_references\").select(\"groupId\").where(\"documentId\", \"=\", m.documentId).execute();\n\t\t\tfor (const { groupId } of references) await this.joinKeepingEarliest(trx, kyselyTxn, groupId, m.collectionId, BigInt(ordinal));\n\t\t}\n\t\tif (removals.length > 0) for (const r of removals) {\n\t\t\tconst ordinal = operationOrdinals[r.operationIndex];\n\t\t\tkyselyTxn.recordMembershipInvalidation(r.documentId);\n\t\t\tawait trx.updateTable(\"document_collections\").set({ leftOrdinal: BigInt(ordinal) }).where(\"collectionId\", \"=\", r.collectionId).where(\"documentId\", \"=\", r.documentId).where(\"leftOrdinal\", \"is\", null).execute();\n\t\t}\n\t\tif (groupReferences.length > 0) for (const record of groupReferences) {\n\t\t\tconst ordinal = operationOrdinals[record.operationIndex];\n\t\t\tawait trx.insertInto(\"group_references\").values(record.groupIds.map((groupId) => ({\n\t\t\t\tdocumentId: record.documentId,\n\t\t\t\tgroupId\n\t\t\t}))).onConflict((oc) => oc.doNothing()).execute();\n\t\t\tconst rows = await trx.selectFrom(\"document_collections\").select(\"collectionId\").where(\"documentId\", \"=\", record.documentId).execute();\n\t\t\tfor (const groupId of record.groupIds) for (const { collectionId } of rows) await this.joinKeepingEarliest(trx, kyselyTxn, groupId, collectionId, BigInt(ordinal));\n\t\t}\n\t\treturn operationOrdinals;\n\t}\n\tasync getGroupReferencers(groupId, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn (await this.queryExecutor.selectFrom(\"group_references\").select(\"documentId\").where(\"groupId\", \"=\", groupId).orderBy(\"documentId\").execute()).map((row) => row.documentId);\n\t}\n\tasync find(collectionId, cursor, view, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst outerCursor = cursor ?? -1;\n\t\tconst limit = paging?.limit ?? 500;\n\t\tconst pagingCursorOrdinal = paging?.cursor !== void 0 ? Number.parseInt(paging.cursor, 10) : -1;\n\t\tconst buildBranch = (kind) => {\n\t\t\tlet qb = this.queryExecutor.selectFrom(\"operation_index_operations as oi\").innerJoin(\"document_collections as dc\", \"oi.documentId\", \"dc.documentId\").selectAll(\"oi\").select([\"dc.documentId\", \"dc.collectionId\"]).where(\"dc.collectionId\", \"=\", collectionId).where(sql`(dc.\"leftOrdinal\" IS NULL OR oi.ordinal < dc.\"leftOrdinal\")`);\n\t\t\tif (kind === \"joiner\") qb = qb.where(\"dc.joinedOrdinal\", \">\", BigInt(outerCursor)).where(\"oi.ordinal\", \"<=\", outerCursor);\n\t\t\telse qb = qb.where(\"oi.ordinal\", \">\", outerCursor);\n\t\t\tqb = qb.where(\"oi.ordinal\", \">\", pagingCursorOrdinal);\n\t\t\tif (view?.branch) qb = qb.where(\"oi.branch\", \"=\", view.branch);\n\t\t\tif (view?.scopes && view.scopes.length > 0) qb = qb.where(\"oi.scope\", \"in\", view.scopes);\n\t\t\tif (view?.excludeSourceRemote) qb = qb.where(\"oi.sourceRemote\", \"!=\", view.excludeSourceRemote);\n\t\t\treturn qb;\n\t\t};\n\t\tconst rows = await buildBranch(\"joiner\").unionAll(buildBranch(\"newOps\")).orderBy(\"ordinal\", \"asc\").limit(limit + 1).execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationIndexEntry(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.find(collectionId, cursor, view, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\tasync get(documentId, view, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst limit = paging?.limit ?? 500;\n\t\tlet query = this.queryExecutor.selectFrom(\"operation_index_operations\").selectAll().where(\"documentId\", \"=\", documentId).orderBy(\"ordinal\", \"asc\");\n\t\tif (view?.branch) query = query.where(\"branch\", \"=\", view.branch);\n\t\tif (view?.scopes && view.scopes.length > 0) query = query.where(\"scope\", \"in\", view.scopes);\n\t\tif (paging?.cursor) {\n\t\t\tconst cursorOrdinal = Number.parseInt(paging.cursor, 10);\n\t\t\tquery = query.where(\"ordinal\", \">\", cursorOrdinal);\n\t\t}\n\t\tquery = query.limit(limit + 1);\n\t\tconst rows = await query.execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationIndexEntry(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.get(documentId, view, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\tasync getSinceOrdinal(ordinal, paging, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst limit = paging?.limit ?? 500;\n\t\tlet query = this.queryExecutor.selectFrom(\"operation_index_operations\").selectAll().where(\"ordinal\", \">\", ordinal).orderBy(\"ordinal\", \"asc\");\n\t\tif (paging?.cursor) {\n\t\t\tconst cursorOrdinal = Number.parseInt(paging.cursor, 10);\n\t\t\tquery = query.where(\"ordinal\", \">\", cursorOrdinal);\n\t\t}\n\t\tquery = query.limit(limit + 1);\n\t\tconst rows = await query.execute();\n\t\tlet hasMore = false;\n\t\tlet items = rows;\n\t\tif (rows.length > limit) {\n\t\t\thasMore = true;\n\t\t\titems = rows.slice(0, limit);\n\t\t}\n\t\tconst nextCursor = hasMore && items.length > 0 ? items[items.length - 1].ordinal.toString() : void 0;\n\t\tconst cursorValue = paging?.cursor || \"0\";\n\t\treturn {\n\t\t\tresults: items.map((row) => this.rowToOperationWithContext(row)),\n\t\t\toptions: {\n\t\t\t\tcursor: cursorValue,\n\t\t\t\tlimit\n\t\t\t},\n\t\t\tnextCursor,\n\t\t\tnext: hasMore ? () => this.getSinceOrdinal(ordinal, {\n\t\t\t\tcursor: nextCursor,\n\t\t\t\tlimit\n\t\t\t}, signal) : void 0\n\t\t};\n\t}\n\trowToOperationWithContext(row) {\n\t\treturn {\n\t\t\toperation: {\n\t\t\t\tindex: row.index,\n\t\t\t\ttimestampUtcMs: row.timestampUtcMs,\n\t\t\t\thash: row.hash,\n\t\t\t\tskip: row.skip,\n\t\t\t\taction: row.action,\n\t\t\t\tdeniedReason: row.deniedReason ?? void 0,\n\t\t\t\tid: row.opId\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tdocumentId: row.documentId,\n\t\t\t\tdocumentType: row.documentType,\n\t\t\t\tscope: row.scope,\n\t\t\t\tbranch: row.branch,\n\t\t\t\tordinal: row.ordinal\n\t\t\t}\n\t\t};\n\t}\n\trowToOperationIndexEntry(row) {\n\t\treturn {\n\t\t\tordinal: row.ordinal,\n\t\t\tdocumentId: row.documentId,\n\t\t\tdocumentType: row.documentType,\n\t\t\tbranch: row.branch,\n\t\t\tscope: row.scope,\n\t\t\tindex: row.index,\n\t\t\ttimestampUtcMs: row.timestampUtcMs,\n\t\t\thash: row.hash,\n\t\t\tskip: row.skip,\n\t\t\taction: row.action,\n\t\t\tdeniedReason: row.deniedReason ?? void 0,\n\t\t\tid: row.opId,\n\t\t\tsourceRemote: row.sourceRemote\n\t\t};\n\t}\n\tasync getLatestTimestampForCollection(collectionId, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\treturn (await this.queryExecutor.selectFrom(\"operation_index_operations as oi\").innerJoin(\"document_collections as dc\", \"oi.documentId\", \"dc.documentId\").select(\"oi.timestampUtcMs\").where(\"dc.collectionId\", \"=\", collectionId).where(sql`(dc.\"leftOrdinal\" IS NULL OR oi.ordinal < dc.\"leftOrdinal\")`).orderBy(\"oi.ordinal\", \"desc\").limit(1).executeTakeFirst())?.timestampUtcMs ?? null;\n\t}\n\tasync getCollectionsForDocuments(documentIds) {\n\t\tif (documentIds.length === 0) return {};\n\t\tconst rows = await this.queryExecutor.selectFrom(\"document_collections\").select([\"documentId\", \"collectionId\"]).where(\"documentId\", \"in\", documentIds).where(\"leftOrdinal\", \"is\", null).execute();\n\t\tconst result = {};\n\t\tfor (const row of rows) {\n\t\t\tif (!(row.documentId in result)) result[row.documentId] = [];\n\t\t\tresult[row.documentId].push(row.collectionId);\n\t\t}\n\t\treturn result;\n\t}\n};\n//#endregion\n//#region src/cache/buffer/ring-buffer.ts\n/**\n* RingBuffer is a generic circular buffer implementation that stores a fixed number\n* of items. When the buffer is full, new items overwrite the oldest items.\n*\n* This implementation maintains O(1) time complexity for push operations and provides\n* items in chronological order (oldest to newest) via getAll().\n*\n* @template T - The type of items stored in the buffer\n*/\nvar RingBuffer = class {\n\tbuffer;\n\thead = 0;\n\tsize = 0;\n\tcapacity;\n\tconstructor(capacity) {\n\t\tif (capacity <= 0) throw new Error(\"Ring buffer capacity must be greater than 0\");\n\t\tthis.capacity = capacity;\n\t\tthis.buffer = new Array(capacity);\n\t}\n\t/**\n\t* Adds an item to the buffer. If the buffer is full, overwrites the oldest item.\n\t*\n\t* @param item - The item to add\n\t*/\n\tpush(item) {\n\t\tconst index = (this.head + this.size) % this.capacity;\n\t\tif (this.size < this.capacity) {\n\t\t\tthis.buffer[index] = item;\n\t\t\tthis.size++;\n\t\t} else {\n\t\t\tthis.buffer[this.head] = item;\n\t\t\tthis.head = (this.head + 1) % this.capacity;\n\t\t}\n\t}\n\t/**\n\t* Returns all items in the buffer in chronological order (oldest to newest).\n\t*\n\t* @returns Array of items in insertion order\n\t*/\n\tgetAll() {\n\t\tif (this.size === 0) return [];\n\t\tconst result = [];\n\t\tfor (let i = 0; i < this.size; i++) {\n\t\t\tconst index = (this.head + i) % this.capacity;\n\t\t\tresult.push(this.buffer[index]);\n\t\t}\n\t\treturn result;\n\t}\n\t/**\n\t* Clears all items from the buffer.\n\t*/\n\tclear() {\n\t\tthis.buffer = new Array(this.capacity);\n\t\tthis.head = 0;\n\t\tthis.size = 0;\n\t}\n\t/**\n\t* Gets the current number of items in the buffer.\n\t*/\n\tget length() {\n\t\treturn this.size;\n\t}\n};\n//#endregion\n//#region src/cache/write-cache-types.ts\n/**\n* Where a snapshot sits in its stream.\n*\n* - `Head`: the newest revision of the stream when it was stored. Only these\n* can answer a read that asks for the head.\n* - `Historical`: state at an earlier revision. Usable as a starting point to\n* replay forward from, and as an answer to a read for that same revision.\n*/\nlet SnapshotPosition = /* @__PURE__ */ function(SnapshotPosition) {\n\tSnapshotPosition[\"Head\"] = \"head\";\n\tSnapshotPosition[\"Historical\"] = \"historical\";\n\treturn SnapshotPosition;\n}({});\n//#endregion\n//#region src/cache/kysely-write-cache.ts\n/**\n* The last operation index a keyframe's document reflects for the scope. A\n* keyframe only exists for a scope that has operations, so a missing entry\n* means the stored row is corrupt.\n*/\nfunction keyframeRevision(keyframe, documentId, scope) {\n\tconst nextIndex = keyframe.document.header.revision[scope];\n\tif (typeof nextIndex !== \"number\") throw new Error(`Corrupt keyframe for document ${documentId} at revision ${keyframe.revision}: header carries no ${scope} revision`);\n\treturn nextIndex - 1;\n}\nfunction extractModuleVersion(doc) {\n\tconst v = doc.state.document.version;\n\treturn normalizeDocumentModelVersion(v);\n}\n/** The highest revision held, latest push winning a tie. */\nfunction highestRevision(snapshots) {\n\tlet newest = void 0;\n\tfor (const snapshot of snapshots) if (!newest || snapshot.revision >= newest.revision) newest = snapshot;\n\treturn newest;\n}\n/**\n* Copies a document far enough that the caller cannot write through it. Inside\n* this class, callers only ever replace whole fields on these four, so one\n* level each is enough.\n*/\nfunction copyDocument(document) {\n\treturn {\n\t\t...document,\n\t\theader: { ...document.header },\n\t\tstate: { ...document.state },\n\t\toperations: { ...document.operations }\n\t};\n}\n/**\n* In-memory write cache with keyframe persistence for PHDocuments.\n*\n* Caches document snapshots in ring buffers with LRU eviction. On cache miss,\n* rebuilds documents from nearest keyframe or full operation history.\n*\n* **Performance Characteristics:**\n* - Cache hit: O(1) lookup in ring buffer\n* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe\n* - Warm miss: O(m) where m is operations since cached revision\n* - Eviction: O(1) for LRU tracking and removal\n*\n* **Thread Safety:**\n* Not thread-safe. Designed for single-threaded job executor environment.\n* External synchronization required for concurrent access across multiple executors.\n*\n* **Example:**\n* ```typescript\n* const cache = new KyselyWriteCache(\n* keyframeStore,\n* operationStore,\n* registry,\n* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }\n* );\n*\n* await cache.startup();\n*\n* // Retrieve or rebuild document\n* const doc = await cache.getState(docId, docType, scope, branch, revision);\n*\n* // Cache result after job execution\n* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);\n*\n* await cache.shutdown();\n* ```\n*/\nvar KyselyWriteCache = class KyselyWriteCache {\n\tstreams;\n\tlruTracker;\n\tkeyframeStore;\n\toperationStore;\n\tregistry;\n\tconfig;\n\tconstructor(keyframeStore, operationStore, registry, config) {\n\t\tthis.keyframeStore = keyframeStore;\n\t\tthis.operationStore = operationStore;\n\t\tthis.registry = registry;\n\t\tthis.config = {\n\t\t\tmaxDocuments: config.maxDocuments,\n\t\t\tringBufferSize: config.ringBufferSize,\n\t\t\tkeyframeInterval: config.keyframeInterval\n\t\t};\n\t\tthis.streams = /* @__PURE__ */ new Map();\n\t\tthis.lruTracker = new LRUTracker();\n\t}\n\twithScopedStores(operationStore, keyframeStore) {\n\t\tconst scoped = new KyselyWriteCache(keyframeStore, operationStore, this.registry, this.config);\n\t\tscoped.streams = this.streams;\n\t\tscoped.lruTracker = this.lruTracker;\n\t\treturn scoped;\n\t}\n\t/**\n\t* Initializes the write cache.\n\t* Currently a no-op as keyframe store lifecycle is managed externally.\n\t*/\n\tasync startup() {\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t* Shuts down the write cache.\n\t* Currently a no-op as keyframe store lifecycle is managed externally.\n\t*/\n\tasync shutdown() {\n\t\treturn Promise.resolve();\n\t}\n\t/**\n\t* Retrieves document state at a specific revision from cache or rebuilds it.\n\t*\n\t* Note: this returns a _shallow_ copy of the document.\n\t*\n\t* Cache hit path: Returns cached snapshot if available (O(1))\n\t* Warm miss path: Rebuilds from cached base revision + incremental ops\n\t* Cold miss path: Rebuilds from keyframe or from scratch using all operations\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - The operation scope\n\t* @param branch - The operation branch\n\t* @param targetRevision - The target revision, or undefined for newest\n\t* @param signal - Optional abort signal to cancel the operation\n\t* @returns The document at the target revision\n\t* @throws {Error} \"Operation aborted\" if signal is aborted\n\t* @throws {ModuleNotFoundError} If document type not registered in registry\n\t* @throws {Error} \"Failed to rebuild document\" if operation store fails\n\t* @throws {Error} If reducer throws during operation application\n\t* @throws {Error} If document serialization fails\n\t*/\n\tasync getState(documentId, scope, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst streamKey = this.makeStreamKey(documentId, scope, branch);\n\t\tconst stream = this.streams.get(streamKey);\n\t\tif (stream) {\n\t\t\tconst snapshots = stream.ringBuffer.getAll();\n\t\t\tif (targetRevision === void 0) {\n\t\t\t\tconst newest = highestRevision(snapshots);\n\t\t\t\tif (newest?.position === SnapshotPosition.Head) {\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn copyDocument(newest.document);\n\t\t\t\t}\n\t\t\t\tif (newest) {\n\t\t\t\t\tconst document = await this.warmMissRebuild(newest.document, newest.revision, documentId, scope, branch, void 0, signal);\n\t\t\t\t\tthis.store(documentId, scope, branch, (document.header.revision[scope] ?? 0) - 1, document, SnapshotPosition.Head);\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn document;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst exactMatch = snapshots.findLast((s) => s.revision === targetRevision);\n\t\t\t\tif (exactMatch) {\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn copyDocument(exactMatch.document);\n\t\t\t\t}\n\t\t\t\tconst newestOlder = this.findNearestOlderSnapshot(snapshots, targetRevision);\n\t\t\t\tif (newestOlder) {\n\t\t\t\t\tconst document = await this.warmMissRebuild(newestOlder.document, newestOlder.revision, documentId, scope, branch, targetRevision, signal);\n\t\t\t\t\tthis.store(documentId, scope, branch, targetRevision, document, SnapshotPosition.Historical);\n\t\t\t\t\tthis.lruTracker.touch(streamKey);\n\t\t\t\t\treturn document;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst document = await this.coldMissRebuild(documentId, scope, branch, targetRevision, signal);\n\t\tconst revision = targetRevision ?? (document.header.revision[scope] ?? 0) - 1;\n\t\tthis.store(documentId, scope, branch, revision, document, targetRevision === void 0 ? SnapshotPosition.Head : SnapshotPosition.Historical);\n\t\treturn document;\n\t}\n\t/**\n\t* Stores a document snapshot in the cache at a specific revision.\n\t*\n\t* The cached document is a shallow copy of the input with its operation history\n\t* truncated to the last operation per scope and its clipboard cleared. This keeps\n\t* memory use and copy costs constant regardless of operation count. Consumers of\n\t* getState() must not rely on the full operation history being present; the only\n\t* guaranteed invariant is that operations[scope].at(-1) reflects the latest\n\t* operation index for each scope.\n\t*\n\t* Updates LRU tracker and may evict least recently used stream if at capacity.\n\t* Asynchronously persists keyframes at configured intervals (fire-and-forget).\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - The operation scope\n\t* @param branch - The operation branch\n\t* @param revision - The revision number\n\t* @param document - The document to cache\n\t* @throws {Error} If document serialization fails\n\t*/\n\tputState(documentId, scope, branch, revision, document, position) {\n\t\tthis.store(documentId, scope, branch, revision, document, position);\n\t}\n\t/**\n\t* Stores the run's head and mints a keyframe for every interval the run\n\t* crossed on its way there. Only the head enters the ring buffer; the\n\t* earlier revisions are keyframe candidates and nothing more.\n\t*/\n\tputRun(documentId, scope, branch, run) {\n\t\tif (run.length === 0) return;\n\t\tfor (const entry of run.slice(0, -1)) this.persistKeyframe(documentId, scope, branch, entry.revision, entry.document);\n\t\tconst head = run[run.length - 1];\n\t\tthis.store(documentId, scope, branch, head.revision, head.document, SnapshotPosition.Head);\n\t}\n\tstore(documentId, scope, branch, revision, document, position) {\n\t\tconst streamKey = this.makeStreamKey(documentId, scope, branch);\n\t\tconst stream = this.getOrCreateStream(streamKey);\n\t\tconst snapshot = {\n\t\t\trevision,\n\t\t\tdocument: {\n\t\t\t\t...copyDocument(document),\n\t\t\t\toperations: Object.fromEntries(Object.entries(document.operations).map(([k, ops]) => [k, ops.length ? [ops.at(-1)] : []])),\n\t\t\t\tclipboard: []\n\t\t\t},\n\t\t\tposition\n\t\t};\n\t\tstream.ringBuffer.push(snapshot);\n\t\tthis.persistKeyframe(documentId, scope, branch, revision, document);\n\t}\n\t/** Persists the snapshot if this revision is one the interval falls on. */\n\tpersistKeyframe(documentId, scope, branch, revision, document) {\n\t\tif (!this.isKeyframeRevision(revision)) return;\n\t\tthis.keyframeStore.putKeyframe(documentId, scope, branch, revision, {\n\t\t\t...document,\n\t\t\toperations: {},\n\t\t\tclipboard: []\n\t\t}).catch((err) => {\n\t\t\tconsole.error(`Failed to persist keyframe ${documentId}@${revision}:`, err);\n\t\t});\n\t}\n\t/**\n\t* Invalidates cached document streams.\n\t*\n\t* Supports three invalidation scopes:\n\t* - Document-level: invalidate(documentId) - removes all streams for document\n\t* - Scope-level: invalidate(documentId, scope) - removes all branches for scope\n\t* - Stream-level: invalidate(documentId, scope, branch) - removes specific stream\n\t*\n\t* @param documentId - The document identifier\n\t* @param scope - Optional scope to narrow invalidation\n\t* @param branch - Optional branch to narrow invalidation (requires scope)\n\t* @returns The number of streams evicted\n\t*/\n\tinvalidate(documentId, scope, branch) {\n\t\tlet evicted = 0;\n\t\tif (scope === void 0 && branch === void 0) {\n\t\t\tfor (const [key] of this.streams.entries()) if (key.startsWith(`${documentId}:`)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else if (scope !== void 0 && branch === void 0) {\n\t\t\tfor (const [key] of this.streams.entries()) if (key.startsWith(`${documentId}:${scope}:`)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t} else if (scope !== void 0 && branch !== void 0) {\n\t\t\tconst key = this.makeStreamKey(documentId, scope, branch);\n\t\t\tif (this.streams.has(key)) {\n\t\t\t\tthis.streams.delete(key);\n\t\t\t\tthis.lruTracker.remove(key);\n\t\t\t\tevicted = 1;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n\t/**\n\t* Clears the entire cache, removing all cached document streams.\n\t* Resets LRU tracking state. This operation always succeeds.\n\t*/\n\tclear() {\n\t\tthis.streams.clear();\n\t\tthis.lruTracker.clear();\n\t}\n\t/**\n\t* Retrieves a specific stream for a document. Exposed on the implementation\n\t* for testing, but not on the interface.\n\t*\n\t* @internal\n\t*/\n\tgetStream(documentId, scope, branch) {\n\t\tconst key = this.makeStreamKey(documentId, scope, branch);\n\t\treturn this.streams.get(key);\n\t}\n\tasync findNearestKeyframe(documentId, scope, branch, targetRevision, signal) {\n\t\tif (targetRevision === Number.MAX_SAFE_INTEGER || targetRevision <= 0) return;\n\t\tconst keyframe = await this.keyframeStore.findNearestKeyframe(documentId, scope, branch, targetRevision, signal);\n\t\tif (!keyframe) return;\n\t\treturn {\n\t\t\trevision: Math.min(keyframeRevision(keyframe, documentId, scope), keyframe.revision),\n\t\t\tdocument: keyframe.document\n\t\t};\n\t}\n\t/**\n\t* Rebuilds a scope from a keyframe or from the whole operation history.\n\t*\n\t* The document scope is always rebuilt first, because it carries the type,\n\t* the upgrades and the deletion marker. Its version-changing upgrades are not\n\t* applied there though: an upgrade reducer must see the state the requested\n\t* scope has reached at that upgrade's boundary, so each one is held back and\n\t* applied when the replay below crosses the boundary that\n\t* resolveModuleVersionForOp derives from it. Upgrades whose boundary lies past\n\t* the last replayed operation are applied at the end. Creation-time 0->N seed\n\t* upgrades carry the initial state, so they still apply immediately.\n\t*/\n\tasync coldMissRebuild(documentId, scope, branch, targetRevision, signal) {\n\t\tconst effectiveTargetRevision = targetRevision || Number.MAX_SAFE_INTEGER;\n\t\tconst keyframe = await this.findNearestKeyframe(documentId, scope, branch, effectiveTargetRevision, signal);\n\t\tconst documentScopeBound = scope === \"document\" ? targetRevision : void 0;\n\t\tlet document;\n\t\tlet startRevision;\n\t\tlet documentType;\n\t\tconst validatedUpgrades = [];\n\t\tconst pendingUpgrades = [];\n\t\tlet lastDocumentScopeOperation;\n\t\tif (keyframe) {\n\t\t\tdocument = keyframe.document;\n\t\t\tstartRevision = keyframe.revision;\n\t\t\tdocumentType = keyframe.document.header.documentType;\n\t\t\tconst documentScopeResume = scope === \"document\" ? keyframe.revision : keyframeRevision(keyframe, documentId, \"document\");\n\t\t\tconst docScopeOpsAfterKeyframe = await this.operationStore.getSince(documentId, \"document\", branch, documentScopeResume, void 0, void 0, signal);\n\t\t\tfor (const operation of docScopeOpsAfterKeyframe.results) {\n\t\t\t\tif (documentScopeBound !== void 0 && operation.index > documentScopeBound) break;\n\t\t\t\tlastDocumentScopeOperation = operation;\n\t\t\t\tif (operation.error || isDenied(operation)) continue;\n\t\t\t\tif (operation.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\t\tconst upgradeAction = operation.action;\n\t\t\t\t\tconst fromVersion = upgradeAction.input.fromVersion;\n\t\t\t\t\tconst toVersion = upgradeAction.input.toVersion;\n\t\t\t\t\tif (fromVersion > 0 && fromVersion < toVersion) {\n\t\t\t\t\t\tlet upgradePath;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tupgradePath = this.registry.computeUpgradePath(documentType, fromVersion, toVersion);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tif (upgradeAction.input.initialState !== void 0) upgradePath = void 0;\n\t\t\t\t\t\t\telse throw new Error(`Failed to rebuild document ${documentId}: no upgrade manifest for ${documentType} v${fromVersion}→v${toVersion} and no initialState snapshot. ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalidatedUpgrades.push({\n\t\t\t\t\t\t\tfromVersion,\n\t\t\t\t\t\t\ttoVersion,\n\t\t\t\t\t\t\trevision: upgradeAction.input.revision,\n\t\t\t\t\t\t\ttimestampUtcMs: operation.timestampUtcMs\n\t\t\t\t\t\t});\n\t\t\t\t\t\tpendingUpgrades.push({\n\t\t\t\t\t\t\taction: upgradeAction,\n\t\t\t\t\t\t\tupgradePath,\n\t\t\t\t\t\t\tindex: operation.index,\n\t\t\t\t\t\t\tsubsequentDeletes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else if (operation.action.type === \"DELETE_DOCUMENT\") {\n\t\t\t\t\tapplyDeleteDocumentAction(document, operation.action);\n\t\t\t\t\tfor (const pending of pendingUpgrades) pending.subsequentDeletes.push(operation.action);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tstartRevision = -1;\n\t\t\tconst createOpResult = await this.operationStore.getSince(documentId, \"document\", branch, -1, void 0, {\n\t\t\t\tcursor: \"0\",\n\t\t\t\tlimit: 1\n\t\t\t}, signal);\n\t\t\tif (createOpResult.results.length === 0) throw new DocumentNotFoundError(documentId);\n\t\t\tconst createOp = createOpResult.results[0];\n\t\t\tif (createOp.action.type !== \"CREATE_DOCUMENT\") throw new Error(`Failed to rebuild document ${documentId}: first operation in document scope must be CREATE_DOCUMENT, found ${createOp.action.type}`);\n\t\t\tconst documentCreateAction = createOp.action;\n\t\t\tdocumentType = documentCreateAction.input.model;\n\t\t\tif (!documentType) throw new Error(`Failed to rebuild document ${documentId}: CREATE_DOCUMENT action missing model in input`);\n\t\t\tdocument = createDocumentFromAction(documentCreateAction);\n\t\t\tlastDocumentScopeOperation = createOp;\n\t\t\tlet docModule = this.registry.getModule(documentType, extractModuleVersion(document));\n\t\t\tconst docScopeOps = await this.operationStore.getSince(documentId, \"document\", branch, 0, void 0, void 0, signal);\n\t\t\tfor (const operation of docScopeOps.results) {\n\t\t\t\tif (documentScopeBound !== void 0 && operation.index > documentScopeBound) break;\n\t\t\t\tlastDocumentScopeOperation = operation;\n\t\t\t\tif (operation.index === 0) continue;\n\t\t\t\tif (operation.error || isDenied(operation)) continue;\n\t\t\t\tif (operation.action.type === \"UPGRADE_DOCUMENT\") {\n\t\t\t\t\tconst upgradeAction = operation.action;\n\t\t\t\t\tconst fromVersion = upgradeAction.input.fromVersion;\n\t\t\t\t\tconst toVersion = upgradeAction.input.toVersion;\n\t\t\t\t\tif (fromVersion > 0 && fromVersion < toVersion) {\n\t\t\t\t\t\tlet upgradePath;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tupgradePath = this.registry.computeUpgradePath(documentType, fromVersion, toVersion);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tif (upgradeAction.input.initialState !== void 0) upgradePath = void 0;\n\t\t\t\t\t\t\telse throw new Error(`Failed to rebuild document ${documentId}: no upgrade manifest for ${documentType} v${fromVersion}→v${toVersion} and no initialState snapshot. ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalidatedUpgrades.push({\n\t\t\t\t\t\t\tfromVersion,\n\t\t\t\t\t\t\ttoVersion,\n\t\t\t\t\t\t\trevision: upgradeAction.input.revision,\n\t\t\t\t\t\t\ttimestampUtcMs: operation.timestampUtcMs\n\t\t\t\t\t\t});\n\t\t\t\t\t\tpendingUpgrades.push({\n\t\t\t\t\t\t\taction: upgradeAction,\n\t\t\t\t\t\t\tupgradePath,\n\t\t\t\t\t\t\tindex: operation.index,\n\t\t\t\t\t\t\tsubsequentDeletes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t} else document = applyUpgradeDocumentAction(document, upgradeAction, void 0);\n\t\t\t\t\tdocModule = this.registry.getModule(documentType, normalizeDocumentModelVersion(toVersion));\n\t\t\t\t} else if (operation.action.type === \"DELETE_DOCUMENT\") {\n\t\t\t\t\tapplyDeleteDocumentAction(document, operation.action);\n\t\t\t\t\tfor (const pending of pendingUpgrades) pending.subsequentDeletes.push(operation.action);\n\t\t\t\t} else {\n\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\tdocument = docModule.reducer(document, operation.action, void 0, {\n\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\tprotocolVersion\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (scope === \"document\") {\n\t\t\tdocument = this.applyPendingUpgrades(document, pendingUpgrades, Number.MAX_SAFE_INTEGER);\n\t\t\tconst last = lastDocumentScopeOperation ?? await this.operationAt(documentId, \"document\", branch, startRevision, signal);\n\t\t\tdocument.operations = {\n\t\t\t\t...document.operations,\n\t\t\t\tdocument: last ? [last] : []\n\t\t\t};\n\t\t\treturn this.stampRevisions(document, documentId, scope, branch, targetRevision, signal);\n\t\t}\n\t\tif (keyframe) {\n\t\t\tconst resumeOperation = await this.operationAt(documentId, scope, branch, startRevision, signal);\n\t\t\tif (resumeOperation) document.operations = {\n\t\t\t\t...document.operations,\n\t\t\t\t[scope]: [resumeOperation]\n\t\t\t};\n\t\t}\n\t\tconst moduleCache = /* @__PURE__ */ new Map();\n\t\tconst getModuleCached = (version) => {\n\t\t\tconst key = version ?? 0;\n\t\t\tlet mod = moduleCache.get(key);\n\t\t\tif (!mod) {\n\t\t\t\tmod = this.registry.getModule(documentType, version);\n\t\t\t\tmoduleCache.set(key, mod);\n\t\t\t}\n\t\t\treturn mod;\n\t\t};\n\t\tconst finalVersion = validatedUpgrades.at(-1)?.toVersion ?? extractModuleVersion(document);\n\t\tlet cursor = void 0;\n\t\tconst pageSize = 100;\n\t\tlet hasMorePages;\n\t\tdo {\n\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\tconst paging = {\n\t\t\t\tcursor: cursor || \"0\",\n\t\t\t\tlimit: pageSize\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = await this.operationStore.getSince(documentId, scope, branch, startRevision, void 0, paging, signal);\n\t\t\t\tfor (const operation of result.results) {\n\t\t\t\t\tif (targetRevision !== void 0 && operation.index > targetRevision) break;\n\t\t\t\t\tconst moduleVersion = this.resolveModuleVersionForOp(operation.index, operation.timestampUtcMs, scope, validatedUpgrades, finalVersion);\n\t\t\t\t\tdocument = this.applyPendingUpgrades(document, pendingUpgrades, moduleVersion ?? Number.MAX_SAFE_INTEGER);\n\t\t\t\t\tif (isDenied(operation)) document = appendWithoutApplying(document, operation, scope);\n\t\t\t\t\telse {\n\t\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\t\tdocument = getModuleCached(moduleVersion).reducer(document, operation.action, void 0, {\n\t\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\t\tprotocolVersion,\n\t\t\t\t\t\t\treplayOptions: { operation },\n\t\t\t\t\t\t\tskipIndexValidation: true\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst reachedTarget = targetRevision !== void 0 && result.results.some((op) => op.index >= targetRevision);\n\t\t\t\thasMorePages = Boolean(result.nextCursor) && !reachedTarget;\n\t\t\t\tif (hasMorePages) cursor = result.nextCursor;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new Error(`Failed to rebuild document ${documentId}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t\t}\n\t\t} while (hasMorePages);\n\t\tdocument = this.applyTailPendingUpgrades(document, pendingUpgrades, scope, targetRevision);\n\t\tdocument = await this.stampRevisions(document, documentId, scope, branch, targetRevision, signal);\n\t\tif (pendingUpgrades.length > 0) {\n\t\t\tconst firstHeldBack = pendingUpgrades[0];\n\t\t\tconst stamped = document.header.revision[\"document\"] ?? 0;\n\t\t\tdocument.header.revision = {\n\t\t\t\t...document.header.revision,\n\t\t\t\tdocument: Math.min(stamped, firstHeldBack.index)\n\t\t\t};\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies and removes every held-back upgrade whose target version is at or\n\t* below `throughVersion`, in the order the document scope recorded them.\n\t*/\n\tapplyPendingUpgrades(document, pendingUpgrades, throughVersion) {\n\t\twhile (pendingUpgrades.length > 0) {\n\t\t\tconst pending = pendingUpgrades[0];\n\t\t\tif (throughVersion < pending.action.input.toVersion) break;\n\t\t\tpendingUpgrades.shift();\n\t\t\tdocument = this.applyPendingUpgrade(document, pending);\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies the remaining held-back upgrades after the requested scope's\n\t* replay has finished. A head read applies them all. A positional read\n\t* applies only those whose boundary for this scope lies at or before the\n\t* target position: applying a later one would label migrated state with a\n\t* pre-upgrade revision, and a keyframe stored from that poisons every\n\t* rebuild that resumes from it. Boundaries come from the upgrade's revision\n\t* snapshot; an upgrade without one records no position for this scope, and\n\t* the replay loop not having crossed it already places it past the target.\n\t*/\n\tapplyTailPendingUpgrades(document, pendingUpgrades, scope, targetRevision) {\n\t\twhile (pendingUpgrades.length > 0) {\n\t\t\tconst pending = pendingUpgrades[0];\n\t\t\tif (targetRevision !== void 0) {\n\t\t\t\tconst snapshot = pending.action.input.revision;\n\t\t\t\tif (snapshot === void 0) break;\n\t\t\t\tif ((snapshot[scope] ?? 0) > targetRevision) break;\n\t\t\t}\n\t\t\tpendingUpgrades.shift();\n\t\t\tdocument = this.applyPendingUpgrade(document, pending);\n\t\t}\n\t\treturn document;\n\t}\n\t/**\n\t* Applies one held-back upgrade, then re-applies the deletes the document\n\t* scope recorded after it so the hold-back cannot invert their order.\n\t*/\n\tapplyPendingUpgrade(document, pending) {\n\t\tdocument = applyUpgradeDocumentAction(document, pending.action, pending.upgradePath);\n\t\tfor (const deleteAction of pending.subsequentDeletes) document = applyDeleteDocumentAction(document, deleteAction);\n\t\treturn document;\n\t}\n\t/**\n\t* Copies the current document revisions onto the document. Overwrites the\n\t* requested scope revision with the target revision, if provided.\n\t*/\n\tasync stampRevisions(document, documentId, scope, branch, targetRevision, signal) {\n\t\tconst revisions = await this.operationStore.getRevisions(documentId, branch, signal);\n\t\tdocument.header.revision = revisions.revision;\n\t\tif (targetRevision !== void 0) document.header.revision = {\n\t\t\t...document.header.revision,\n\t\t\t[scope]: targetRevision + 1\n\t\t};\n\t\tdocument.header.lastModifiedAtUtcIso = revisions.latestTimestamp;\n\t\treturn document;\n\t}\n\t/** The stored operation at `index`, or undefined if it is no longer there. */\n\tasync operationAt(documentId, scope, branch, index, signal) {\n\t\tif (index < 0) return;\n\t\tconst operation = (await this.operationStore.getSince(documentId, scope, branch, index - 1, void 0, {\n\t\t\tcursor: \"0\",\n\t\t\tlimit: 1\n\t\t}, signal)).results[0];\n\t\treturn operation && operation.index === index ? operation : void 0;\n\t}\n\t/**\n\t* Resolves which module version to use for a given operation in phase 2.\n\t*\n\t* Uses the validated-upgrade boundary rules from D7:\n\t* - If `input.revision` is present: op.index < revision[scope] → before the upgrade boundary\n\t* - Otherwise: timestamp fallback\n\t* - Falls back to final module version when neither is decidable\n\t*/\n\tresolveModuleVersionForOp(opIndex, opTimestamp, scope, validatedUpgrades, finalVersion) {\n\t\tif (validatedUpgrades.length === 0) return finalVersion;\n\t\tlet currentVersion = validatedUpgrades[0]?.fromVersion;\n\t\tfor (const upgrade of validatedUpgrades) {\n\t\t\tlet beforeUpgrade;\n\t\t\tif (upgrade.revision !== void 0) beforeUpgrade = opIndex < (upgrade.revision[scope] ?? 0);\n\t\t\telse beforeUpgrade = opTimestamp < upgrade.timestampUtcMs;\n\t\t\tif (beforeUpgrade) return currentVersion;\n\t\t\tcurrentVersion = upgrade.toVersion;\n\t\t}\n\t\treturn currentVersion;\n\t}\n\tasync warmMissRebuild(baseDocument, baseRevision, documentId, scope, branch, targetRevision, signal) {\n\t\tconst documentType = baseDocument.header.documentType;\n\t\tconst docScopeNextIndex = baseDocument.header.revision[\"document\"] ?? 0;\n\t\tif ((await this.operationStore.getSince(documentId, \"document\", branch, docScopeNextIndex - 1, void 0, void 0, signal)).results.length > 0) return this.coldMissRebuild(documentId, scope, branch, targetRevision, signal);\n\t\tconst module = this.registry.getModule(documentType, extractModuleVersion(baseDocument));\n\t\tlet document = copyDocument(baseDocument);\n\t\ttry {\n\t\t\tconst pagedResults = await this.operationStore.getSince(documentId, scope, branch, baseRevision, void 0, void 0, signal);\n\t\t\tfor (const operation of pagedResults.results) {\n\t\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\t\t\tif (targetRevision !== void 0 && operation.index > targetRevision) break;\n\t\t\t\tif (isDenied(operation)) document = appendWithoutApplying(document, operation, scope);\n\t\t\t\telse {\n\t\t\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\t\t\tdocument = module.reducer(document, operation.action, void 0, {\n\t\t\t\t\t\tskip: operation.skip,\n\t\t\t\t\t\tprotocolVersion,\n\t\t\t\t\t\treplayOptions: { operation },\n\t\t\t\t\t\tskipIndexValidation: true\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (targetRevision !== void 0 && operation.index === targetRevision) break;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Failed to rebuild document ${documentId}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });\n\t\t}\n\t\tconst revisions = await this.operationStore.getRevisions(documentId, branch, signal);\n\t\tdocument.header.revision = revisions.revision;\n\t\tif (targetRevision !== void 0) document.header.revision = {\n\t\t\t...document.header.revision,\n\t\t\t[scope]: targetRevision + 1\n\t\t};\n\t\tdocument.header.lastModifiedAtUtcIso = revisions.latestTimestamp;\n\t\treturn document;\n\t}\n\tfindNearestOlderSnapshot(snapshots, targetRevision) {\n\t\tlet nearest = void 0;\n\t\tfor (const snapshot of snapshots) if (snapshot.revision < targetRevision) {\n\t\t\tif (!nearest || snapshot.revision > nearest.revision) nearest = snapshot;\n\t\t}\n\t\treturn nearest;\n\t}\n\tmakeStreamKey(documentId, scope, branch) {\n\t\treturn `${documentId}:${scope}:${branch}`;\n\t}\n\tgetOrCreateStream(key) {\n\t\tlet stream = this.streams.get(key);\n\t\tif (!stream) {\n\t\t\tif (this.streams.size >= this.config.maxDocuments) {\n\t\t\t\tconst evictKey = this.lruTracker.evict();\n\t\t\t\tif (evictKey) this.streams.delete(evictKey);\n\t\t\t}\n\t\t\tstream = {\n\t\t\t\tkey,\n\t\t\t\tringBuffer: new RingBuffer(this.config.ringBufferSize)\n\t\t\t};\n\t\t\tthis.streams.set(key, stream);\n\t\t}\n\t\tthis.lruTracker.touch(key);\n\t\treturn stream;\n\t}\n\tisKeyframeRevision(revision) {\n\t\treturn revision > 0 && revision % this.config.keyframeInterval === 0;\n\t}\n};\n//#endregion\n//#region src/events/event-bus.ts\nvar EventBus = class {\n\teventTypeToSubscribers = /* @__PURE__ */ new Map();\n\tsubscribe(type, subscriber) {\n\t\tlet list = this.eventTypeToSubscribers.get(type);\n\t\tif (!list) {\n\t\t\tlist = [];\n\t\t\tthis.eventTypeToSubscribers.set(type, list);\n\t\t}\n\t\tlist.push(subscriber);\n\t\tlet done = false;\n\t\treturn () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tconst arr = this.eventTypeToSubscribers.get(type);\n\t\t\tif (!arr) return;\n\t\t\tconst idx = arr.indexOf(subscriber);\n\t\t\tif (idx !== -1) arr.splice(idx, 1);\n\t\t\tif (arr.length === 0) this.eventTypeToSubscribers.delete(type);\n\t\t};\n\t}\n\tasync emit(type, data) {\n\t\tconst list = this.eventTypeToSubscribers.get(type);\n\t\tif (!list || list.length === 0) return;\n\t\tconst snapshot = list.slice();\n\t\tconst errors = [];\n\t\tfor (const fn of snapshot) try {\n\t\t\tawait Promise.resolve(fn(type, data));\n\t\t} catch (err) {\n\t\t\terrors.push(err);\n\t\t}\n\t\tif (errors.length > 0) throw new EventBusAggregateError(errors);\n\t}\n};\n//#endregion\n//#region src/core/feature-flags.ts\n/**\n* Every flag this reactor knows, with the flags it requires. A stage adds its\n* flag here when it ships, so asking an older reactor for a later stage's flag\n* is an unrecognized name rather than a flag that quietly does nothing.\n*/\nconst FLAG_PREREQUISITES = {\n\tdocumentDecisions: [],\n\tauthEnforcement: [\"documentDecisions\"],\n\tauthGroups: [\"authEnforcement\"],\n\tauthConditions: [\"authGroups\"]\n};\n/**\n* The flags as plain booleans, with anything unset off, validated. Callers hold\n* a partial set, because that is what crosses to a pooled worker, and every\n* consumer needs the same resolution of it.\n*/\nfunction resolveFeatureFlags(flags = {}) {\n\tconst resolved = {\n\t\tdocumentDecisions: flags.documentDecisions ?? false,\n\t\tauthEnforcement: flags.authEnforcement ?? false,\n\t\tauthGroups: flags.authGroups ?? false,\n\t\tauthConditions: flags.authConditions ?? false\n\t};\n\tvalidateFeatureFlags(flags, FLAG_PREREQUISITES);\n\treturn resolved;\n}\n/**\n* Throws when the flags ask for enforcement the reactor cannot deliver. Either\n* failure would otherwise read as enforcement being on while the reactor\n* applies less than the caller asked for.\n*/\nfunction validateFeatureFlags(flags, prerequisites) {\n\tconst known = Object.keys(prerequisites);\n\tconst unrecognized = Object.keys(flags).filter((name) => !known.includes(name));\n\tif (unrecognized.length > 0) throw new Error(`Unrecognized reactor feature flag: ${unrecognized.join(\", \")}. This reactor knows: ${known.join(\", \")}.`);\n\tfor (const name of known) {\n\t\tif (flags[name] !== true) continue;\n\t\tconst missing = prerequisites[name].filter((required) => flags[required] !== true);\n\t\tif (missing.length > 0) throw new Error(`Reactor feature flag ${name} requires ${missing.join(\", \")}.`);\n\t}\n}\n//#endregion\n//#region src/executor/execution-scope.ts\nvar DefaultExecutionScope = class {\n\tconstructor(operationStore, operationIndex, writeCache, documentMetaCache, collectionMembershipCache) {\n\t\tthis.operationStore = operationStore;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.writeCache = writeCache;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t}\n\tasync run(fn, signal) {\n\t\tsignal?.throwIfAborted();\n\t\treturn fn({\n\t\t\toperationStore: this.operationStore,\n\t\t\toperationIndex: this.operationIndex,\n\t\t\twriteCache: this.writeCache,\n\t\t\tdocumentMetaCache: this.documentMetaCache,\n\t\t\tcollectionMembershipCache: this.collectionMembershipCache\n\t\t});\n\t}\n};\nvar KyselyExecutionScope = class {\n\tconstructor(db, operationStore, operationIndex, keyframeStore, writeCache, documentMetaCache, collectionMembershipCache) {\n\t\tthis.db = db;\n\t\tthis.operationStore = operationStore;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.keyframeStore = keyframeStore;\n\t\tthis.writeCache = writeCache;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t}\n\tasync run(fn, signal) {\n\t\tsignal?.throwIfAborted();\n\t\treturn this.db.transaction().execute(async (trx) => {\n\t\t\tconst scopedOperationStore = this.operationStore.withTransaction(trx);\n\t\t\tconst scopedOperationIndex = this.operationIndex.withTransaction(trx);\n\t\t\tconst scopedKeyframeStore = this.keyframeStore.withTransaction(trx);\n\t\t\treturn fn({\n\t\t\t\toperationStore: scopedOperationStore,\n\t\t\t\toperationIndex: scopedOperationIndex,\n\t\t\t\twriteCache: this.writeCache.withScopedStores(scopedOperationStore, scopedKeyframeStore),\n\t\t\t\tdocumentMetaCache: this.documentMetaCache.withScopedStore(scopedOperationStore),\n\t\t\t\tcollectionMembershipCache: this.collectionMembershipCache.withScopedIndex(scopedOperationIndex)\n\t\t\t});\n\t\t});\n\t}\n};\n//#endregion\n//#region src/utils/reshuffle.ts\nconst STRICT_ORDER_ACTION_TYPES = new Set([\n\t\"CREATE_DOCUMENT\",\n\t\"DELETE_DOCUMENT\",\n\t\"UPGRADE_DOCUMENT\",\n\t\"ADD_RELATIONSHIP\",\n\t\"REMOVE_RELATIONSHIP\",\n\t\"UPDATE_RELATIONSHIP\",\n\t\"ADD_FOLDER\",\n\t\"UPDATE_FOLDER\",\n\t\"REMOVE_FOLDER\"\n]);\n/**\n* Reshuffles operations by timestamp, then applies deterministic tie-breaking.\n* Used for merging concurrent operations from different branches.\n*\n* For strict document-structure actions (e.g., CREATE_DOCUMENT/UPGRADE_DOCUMENT),\n* logical index (index - skip) is prioritized to preserve causal replay order.\n*\n* For other actions, action ID is prioritized to ensure a canonical cross-reactor order\n* for concurrent operations that may have diverged local indices due to prior reshuffles.\n* Logical index and operation ID are then used as deterministic tie-breakers.\n*\n* Example:\n* [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n* GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n* Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n* Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n* merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n*/\nfunction reshuffleByTimestamp(startIndex, opsA, opsB) {\n\treturn [...opsA, ...opsB].sort((a, b) => {\n\t\tconst timestampDiff = new Date(a.timestampUtcMs).getTime() - new Date(b.timestampUtcMs).getTime();\n\t\tif (timestampDiff !== 0) return timestampDiff;\n\t\tconst rank = (op) => STRICT_ORDER_ACTION_TYPES.has(op.action?.type ?? \"\") ? 0 : 1;\n\t\tconst rankDiff = rank(a) - rank(b);\n\t\tif (rankDiff !== 0) return rankDiff;\n\t\tif (rank(a) === 0) {\n\t\t\tconst logicalIndexDiff = a.index - a.skip - (b.index - b.skip);\n\t\t\tif (logicalIndexDiff !== 0) return logicalIndexDiff;\n\t\t}\n\t\tconst actionIdDiff = (a.action?.id ?? \"\").localeCompare(b.action?.id ?? \"\");\n\t\tif (actionIdDiff !== 0) return actionIdDiff;\n\t\treturn a.id.localeCompare(b.id);\n\t}).map((op, i) => ({\n\t\t...op,\n\t\tindex: startIndex.index + i,\n\t\tskip: i === 0 ? startIndex.skip : 0\n\t}));\n}\n//#endregion\n//#region src/decision/merged-order.ts\n/** Identifies a stream within a walk. */\nfunction streamKey(query) {\n\treturn `${query.documentId}:${query.scope}:${query.branch}`;\n}\n/**\n* Orders two operations from different streams by position. Timestamp decides;\n* an equal timestamp puts an auth operation first, and otherwise falls to the\n* action id and then the operation id, so that two replicas holding the same\n* operations agree on the order whatever order they happen to store them in.\n*/\nfunction comparePositions(a, b) {\n\tconst aTime = Date.parse(a.operation.timestampUtcMs);\n\tconst bTime = Date.parse(b.operation.timestampUtcMs);\n\tif (aTime !== bTime) return aTime - bTime;\n\tif (a.streamKey === b.streamKey) return a.operation.index - b.operation.index;\n\tconst aAuth = a.scope === \"auth\";\n\tif (aAuth !== (b.scope === \"auth\")) return aAuth ? -1 : 1;\n\tconst actionIds = (a.operation.action.id ?? \"\").localeCompare(b.operation.action.id ?? \"\");\n\tif (actionIds !== 0) return actionIds;\n\treturn (a.operation.id ?? \"\").localeCompare(b.operation.id ?? \"\");\n}\n/**\n* Merges the read-set streams into one sequence by position. An operation's\n* place in the result is the bound a decision at that operation reads to: every\n* operation before it has been applied, and it has not.\n*/\nfunction mergeByPosition(streams) {\n\tconst merged = [];\n\tfor (const stream of streams) for (const operation of stream.operations) merged.push({\n\t\tstreamKey: stream.streamKey,\n\t\tscope: stream.scope,\n\t\toperation\n\t});\n\treturn merged.sort(comparePositions);\n}\n/**\n* The skip that retracts everything from `firstRetractedIndex` up to where the\n* re-appended operation lands. It spans the indexes rather than counting the\n* operations, because a stream with a gap in it makes those differ.\n*/\nfunction retractionSkip(nextIndex, firstRetractedIndex) {\n\treturn nextIndex - firstRetractedIndex;\n}\n//#endregion\n//#region src/decision/walk.ts\n/**\n* A single forward pass is only correct while a stream's effective operations\n* are ordered.\n*/\nfunction assertPositionOrder(streamKey, scope, operations) {\n\tfor (let i = 1; i < operations.length; i++) {\n\t\tconst previous = operations[i - 1];\n\t\tconst current = operations[i];\n\t\tif (comparePositions({\n\t\t\tstreamKey,\n\t\t\tscope,\n\t\t\toperation: previous\n\t\t}, {\n\t\t\tstreamKey,\n\t\t\tscope,\n\t\t\toperation: current\n\t\t}) > 0) throw new Error(`Stream ${streamKey} is out of position order: index ${previous.index} at ${previous.timestampUtcMs} precedes index ${current.index} at ${current.timestampUtcMs}`);\n\t}\n}\n/**\n* Visits every operation in the read-set once, in the order their positions\n* fall, and hands back the state each stream held just before it. That state is\n* what a decision at that operation reads.\n*\n* Skips are resolved first (i.e. this is performed on a garbage collected\n* stream), which means we can do a single forward pass.\n*\n* An operation that contributes no state, whether denied or holding a reducer\n* error, is visited but not applied (this matches the write cache's rebuild).\n*\n* The consumer sends back whether it refused the operation it was handed: a\n* refusal this pass produced must suppress it the same way a stored one does.\n*/\nfunction* walkByPosition(streams) {\n\tconst merged = mergeByPosition(streams.map((stream) => {\n\t\tconst operations = garbageCollect(sortOperations([...stream.operations]));\n\t\tassertPositionOrder(stream.streamKey, stream.scope, operations);\n\t\treturn {\n\t\t\tstreamKey: stream.streamKey,\n\t\t\tscope: stream.scope,\n\t\t\toperations\n\t\t};\n\t}));\n\tconst byKey = new Map(streams.map((stream) => [stream.streamKey, stream]));\n\tconst states = new Map(streams.map((stream) => [stream.streamKey, stream.document]));\n\tfor (const { streamKey, operation } of merged) {\n\t\tif ((yield {\n\t\t\tstreamKey,\n\t\t\toperation,\n\t\t\tstates: new Map(states)\n\t\t}) || operation.error !== void 0 || isDenied(operation)) continue;\n\t\tconst stream = byKey.get(streamKey);\n\t\tconst before = states.get(streamKey);\n\t\tif (before === void 0 || stream === void 0) throw new Error(`No state for stream ${streamKey}`);\n\t\tstates.set(streamKey, stream.apply(before, operation));\n\t}\n}\n//#endregion\n//#region src/decision/evaluation.ts\n/** The stream key for evaluated operations whose scope no projection reads. */\nconst EVALUATED_ONLY = \"evaluated\";\n/**\n* Whether any stream the model reads declares this operation's action type as\n* one that can change an evaluation.\n*/\nfunction isDecidingAction(operation, readSet) {\n\treturn readSet.some((stream) => stream.decidingActions.includes(operation.action.type));\n}\n/**\n* Who an operation acts as. A replayed operation is evaluated as its own signer,\n* so an address-scoped policy does not deny its own author's history.\n*/\nfunction subjectOf(operation) {\n\tconst signer = operation.action.context?.signer;\n\treturn {\n\t\taddress: signer?.user.address,\n\t\tkey: signer?.app.key\n\t};\n}\n/**\n* The model as the walk reached this operation: each static projection's value\n* is its own scope's state, and each derived projection's value maps document\n* id to that document's state, holding only the streams this replica walked. A\n* derived stream it does not hold stays out of the map, which fails closed.\n*/\nfunction modelAt(readSet, derivedNames, derived, states) {\n\tconst model = {};\n\tfor (const stream of readSet) {\n\t\tconst document = states.get(streamKey(stream.query));\n\t\tif (document === void 0) throw new Error(`No state walked for projection ${stream.name}`);\n\t\tmodel[stream.name] = document.state[stream.query.scope];\n\t}\n\tfor (const name of derivedNames) model[name] = {};\n\tfor (const entry of derived) {\n\t\tconst map = model[entry.name];\n\t\tconst document = states.get(streamKey(entry.query));\n\t\tif (document !== void 0) map[entry.query.documentId] = document.state[entry.query.scope];\n\t}\n\treturn model;\n}\n/**\n* Evaluates each operation at its own position and returns the refusals in an\n* array parallel to the operations, where undefined means allowed.\n*\n* A position is a timestamp, so an operation refused by a delete is one that\n* sorts after it, and the operations before it are left alone. That holds\n* whether the delete is already stored or is among the operations passed in.\n*/\nasync function evaluateByPosition(model, target, subject, stores, signal) {\n\tconst { scope, operations } = subject;\n\tconst { writeCache, operationStore } = stores;\n\tconst definition = model(target);\n\tconst readSet = staticReadSet(definition);\n\tconst derivedSet = derivedReadSet(definition);\n\tif (!definition.evaluatesScope(scope)) return operations.map(() => void 0);\n\tconst evaluating = new Set(operations.map((operation) => operation.id));\n\tconst readStreams = await Promise.all(readSet.map(async (stream) => ({\n\t\tstream,\n\t\toperations: (await operationStore.getSince(stream.query.documentId, stream.query.scope, stream.query.branch, -1, { actionTypes: stream.decidingActions }, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id))\n\t})));\n\tconst decidingOperations = operations.filter((operation) => isDecidingAction(operation, readSet));\n\tif (readStreams.every((read) => read.operations.length === 0) && decidingOperations.length === 0) return operations.map(() => void 0);\n\tif (readStreams.length === 0) throw new Error(`Decision model for ${target.documentId} reads no stream whose query is known before it is built`);\n\tconst writtenProjection = readSet.find((stream) => stream.query.scope === scope);\n\tconst walked = [];\n\tconst histories = [];\n\tfor (const read of readStreams) {\n\t\tconst streamOperations = read.stream === writtenProjection ? [...read.operations, ...operations] : read.operations;\n\t\tconst before = await writeCache.getState(read.stream.query.documentId, read.stream.query.scope, read.stream.query.branch, -1, signal);\n\t\twalked.push({\n\t\t\tstreamKey: streamKey(read.stream.query),\n\t\t\tscope: read.stream.query.scope,\n\t\t\tdocument: before,\n\t\t\toperations: streamOperations,\n\t\t\tapply: read.stream.apply\n\t\t});\n\t\thistories.push({\n\t\t\tname: read.stream.name,\n\t\t\toperations: streamOperations\n\t\t});\n\t}\n\tlet evaluatedStateKey;\n\tif (writtenProjection !== void 0) evaluatedStateKey = streamKey(writtenProjection.query);\n\telse if (definition.foldEvaluatedScope !== void 0) {\n\t\tconst query = {\n\t\t\tdocumentId: target.documentId,\n\t\t\tscope,\n\t\t\tbranch: target.branch\n\t\t};\n\t\tconst storedOperations = (await operationStore.getSince(query.documentId, query.scope, query.branch, -1, void 0, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id));\n\t\tconst before = await writeCache.getState(query.documentId, query.scope, query.branch, -1, signal);\n\t\tevaluatedStateKey = streamKey(query);\n\t\twalked.push({\n\t\t\tstreamKey: evaluatedStateKey,\n\t\t\tscope,\n\t\t\tdocument: before,\n\t\t\toperations: [...storedOperations, ...operations],\n\t\t\tapply: definition.foldEvaluatedScope\n\t\t});\n\t} else walked.push({\n\t\tstreamKey: EVALUATED_ONLY,\n\t\tscope,\n\t\tdocument: walked[0].document,\n\t\toperations,\n\t\tapply: (document) => document\n\t});\n\tconst derivedEntries = [];\n\tconst walkedKeys = new Set(walked.map((stream) => stream.streamKey));\n\tfor (const projection of derivedSet) {\n\t\tconst queries = projection.queryOverHistory?.(histories) ?? [];\n\t\tfor (const query of queries) {\n\t\t\tconst key = streamKey(query);\n\t\t\tif (walkedKeys.has(key)) continue;\n\t\t\tlet before;\n\t\t\ttry {\n\t\t\t\tbefore = await writeCache.getState(query.documentId, query.scope, query.branch, -1, signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DocumentNotFoundError) continue;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst streamOperations = (await operationStore.getSince(query.documentId, query.scope, query.branch, -1, { actionTypes: projection.decidingActions }, void 0, signal)).results.filter((operation) => !evaluating.has(operation.id));\n\t\t\twalkedKeys.add(key);\n\t\t\twalked.push({\n\t\t\t\tstreamKey: key,\n\t\t\t\tscope: query.scope,\n\t\t\t\tdocument: before,\n\t\t\t\toperations: streamOperations,\n\t\t\t\tapply: projection.apply\n\t\t\t});\n\t\t\tderivedEntries.push({\n\t\t\t\tname: projection.name,\n\t\t\t\tquery\n\t\t\t});\n\t\t}\n\t}\n\tconst reasons = /* @__PURE__ */ new Map();\n\tconst walk = walkByPosition(walked);\n\tlet step = walk.next(false);\n\twhile (!step.done) {\n\t\tconst position = step.value;\n\t\tif (!evaluating.has(position.operation.id)) {\n\t\t\tstep = walk.next(false);\n\t\t\tcontinue;\n\t\t}\n\t\tconst evaluatedDocument = evaluatedStateKey === void 0 ? void 0 : position.states.get(evaluatedStateKey);\n\t\tconst scopeState = evaluatedDocument === void 0 ? void 0 : evaluatedDocument.state[scope];\n\t\tconst evaluation = definition.decide(modelAt(readSet, derivedSet.map((projection) => projection.name), derivedEntries, position.states), subjectOf(position.operation), {\n\t\t\tverb: \"execute\",\n\t\t\tscope: position.operation.action.scope,\n\t\t\toperation: position.operation.action.type\n\t\t}, {\n\t\t\tscopeState,\n\t\t\tactionInput: position.operation.action.input\n\t\t});\n\t\tconst denied = evaluation.decision === \"deny\";\n\t\treasons.set(position.operation.id, denied ? evaluation.reason : void 0);\n\t\tstep = walk.next(denied);\n\t}\n\treturn operations.map((operation) => reasons.get(operation.id));\n}\n//#endregion\n//#region src/cache/operation-index-types.ts\nconst DRIVE_COLLECTION_PREFIX = \"drive.\";\n/**\n* Identifies the collection a remote synchronizes. Collections are drive-level\n* abstractions (document-drive and reactor-drive), so a collection id is the\n* drive document id plus the branch it scopes to rather than an opaque string.\n*\n* The canonical string form (`drive.${branch}.${driveId}`) is produced only by\n* `key` and parsed only by `fromKey`; that string is the wire and storage\n* representation and is byte-for-byte identical to the legacy\n* `driveCollectionId(branch, driveId)` output, so existing `document_collections`\n* rows and persisted remotes remain valid without migration.\n*/\nvar DriveCollectionId = class DriveCollectionId {\n\tconstructor(driveId, branch) {\n\t\tthis.driveId = driveId;\n\t\tthis.branch = branch;\n\t}\n\tstatic forDrive(driveId, branch = \"main\") {\n\t\treturn new DriveCollectionId(driveId, branch);\n\t}\n\t/**\n\t* The single deserializer for the wire/storage form. `branch` may contain\n\t* dots, while `driveId` is a dot-free document id, so the drive id is the\n\t* final dot-delimited segment.\n\t*/\n\tstatic fromKey(key) {\n\t\tif (!key.startsWith(DRIVE_COLLECTION_PREFIX)) throw new Error(`Unsupported collection id: ${key}`);\n\t\tconst rest = key.slice(6);\n\t\tconst lastDot = rest.lastIndexOf(\".\");\n\t\tif (lastDot === -1 || lastDot === rest.length - 1) throw new Error(`Malformed drive collection id: ${key}`);\n\t\treturn new DriveCollectionId(rest.slice(lastDot + 1), rest.slice(0, lastDot));\n\t}\n\tget key() {\n\t\treturn `${DRIVE_COLLECTION_PREFIX}${this.branch}.${this.driveId}`;\n\t}\n\ttoString() {\n\t\treturn this.key;\n\t}\n\tequals(other) {\n\t\treturn this.driveId === other.driveId && this.branch === other.branch;\n\t}\n};\n//#endregion\n//#region src/executor/document-action-handler.ts\nvar DocumentActionHandler = class {\n\tconstructor(registry, logger, driveContainerTypes, featureFlags, decisionModel) {\n\t\tthis.registry = registry;\n\t\tthis.logger = logger;\n\t\tthis.driveContainerTypes = driveContainerTypes;\n\t\tthis.featureFlags = featureFlags;\n\t\tthis.decisionModel = decisionModel;\n\t}\n\t/** Whether the write arrives with its evaluation already decided. */\n\talreadyEvaluated(executing) {\n\t\treturn this.featureFlags.documentDecisions && (executing.replayingAcceptedHistory || executing.evaluatedByPosition);\n\t}\n\tasync execute(write, executing) {\n\t\tconst { action } = write;\n\t\tif (write.deniedReason !== void 0) return this.writeDenied(write, executing);\n\t\tconst refusal = await this.refuseIfPolicyDenies(write, executing);\n\t\tif (refusal) return refusal;\n\t\tswitch (action.type) {\n\t\t\tcase \"CREATE_DOCUMENT\": return this.executeCreate(write, executing);\n\t\t\tcase \"DELETE_DOCUMENT\": return this.executeDelete(write, executing);\n\t\t\tcase \"UPGRADE_DOCUMENT\": return this.executeUpgrade(write, executing);\n\t\t\tcase \"ADD_RELATIONSHIP\": return this.executeAddRelationship(write, executing);\n\t\t\tcase \"REMOVE_RELATIONSHIP\": return this.executeRemoveRelationship(write, executing);\n\t\t\tcase \"UPDATE_RELATIONSHIP\": return this.executeUpdateRelationship(write, executing);\n\t\t\tdefault: return buildErrorResult(executing.job, /* @__PURE__ */ new Error(`Unknown document action type: ${action.type}`), executing.startTime);\n\t\t}\n\t}\n\t/**\n\t* Refuses a document-scope write the policy denies, or undefined to proceed.\n\t* Without this an `execute`-on-`document` grant is unenforceable.\n\t*/\n\tasync refuseIfPolicyDenies(write, executing) {\n\t\tconst { action } = write;\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\tif (!this.featureFlags.documentDecisions || !this.featureFlags.authEnforcement || this.alreadyEvaluated(executing) || !GATED_DOCUMENT_ACTIONS.has(action.type)) return;\n\t\tconst documentId = targetDocumentId(action, job.documentId);\n\t\tlet admission;\n\t\ttry {\n\t\t\tadmission = await decideAtHead(this.decisionModel, stores.writeCache, {\n\t\t\t\tdocumentId,\n\t\t\t\tbranch: job.branch\n\t\t\t}, {\n\t\t\t\taddress: action.context?.signer?.user.address,\n\t\t\t\tkey: action.context?.signer?.app.key\n\t\t\t}, {\n\t\t\t\tverb: \"execute\",\n\t\t\t\tscope: action.scope,\n\t\t\t\toperation: action.type\n\t\t\t}, signal, this.featureFlags.authConditions ? { actionInput: action.input } : void 0);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tif (admission.evaluation.decision === \"allow\") return;\n\t\treturn buildErrorResult(job, refusalError(admission.evaluation.reason, documentId, admission.deletedAtUtcIso, action), startTime);\n\t}\n\t/** A refused operation holds a position in the stream but changes nothing. */\n\tasync writeDenied(write, executing) {\n\t\tconst { action, skip, sourceRemote, deniedReason } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(job.documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tconst index = getNextIndexForScope(document, job.scope);\n\t\tlet standing = document;\n\t\tif (skip > 0) try {\n\t\t\tstanding = await stores.writeCache.getState(job.documentId, job.scope, job.branch, index - skip - 1, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, index, skip, {\n\t\t\tdocumentId: job.documentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\toperation.deniedReason = deniedReason;\n\t\toperation.hash = hashDocumentStateForScope(standing, job.scope);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(standing, job.scope, operation.index);\n\t\tstanding.operations = {\n\t\t\t...standing.operations,\n\t\t\t[job.scope]: [...standing.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(job.documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(job.documentId, job.scope, job.branch, operation.index, standing, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(job.documentId, job.branch, {\n\t\t\tstate: standing.state.document,\n\t\t\tdocumentType: standing.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, job.documentId, standing.header.documentType, JSON.stringify({\n\t\t\theader: standing.header,\n\t\t\tdocument: standing.state.document\n\t\t}), startTime);\n\t}\n\tasync executeCreate(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.scope !== \"document\") return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: /* @__PURE__ */ new Error(`CREATE_DOCUMENT must be in \"document\" scope, got \"${job.scope}\"`),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst document = createDocumentFromAction(action);\n\t\tlet operation = createOperation(action, 0, skip, {\n\t\t\tdocumentId: document.header.id,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\t...document.state\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: document.header.id,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(document.header.id, job.scope, job.branch);\n\t\tstores.writeCache.putState(document.header.id, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: document.header.id,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tif (this.driveContainerTypes.has(document.header.documentType)) {\n\t\t\tconst collectionId = DriveCollectionId.forDrive(document.header.id, job.branch).key;\n\t\t\tindexTxn.createCollection(collectionId);\n\t\t\tindexTxn.addToCollection(collectionId, document.header.id);\n\t\t}\n\t\tstores.documentMetaCache.putDocumentMeta(document.header.id, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, document.header.id, document.header.documentType, resultingState, startTime);\n\t}\n\tasync executeDelete(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst input = action.input;\n\t\tif (!input.documentId) return buildErrorResult(job, /* @__PURE__ */ new Error(\"DELETE_DOCUMENT action requires a documentId in input\"), startTime);\n\t\tconst documentId = input.documentId;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch document before deletion: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tconst documentState = document.state.document;\n\t\tif (documentState.isDeleted && !this.alreadyEvaluated(executing)) return buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);\n\t\tlet operation = createOperation(action, getNextIndexForScope(document, job.scope), skip, {\n\t\t\tdocumentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tapplyDeleteDocumentAction$1(document, action);\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\tdocument: document.state.document\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(documentId, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(documentId, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);\n\t}\n\tasync executeUpgrade(write, executing) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst input = action.input;\n\t\tif (!input.documentId) return buildErrorResult(job, /* @__PURE__ */ new Error(\"UPGRADE_DOCUMENT action requires a documentId in input\"), startTime);\n\t\tconst documentId = input.documentId;\n\t\tconst fromVersion = input.fromVersion;\n\t\tconst toVersion = input.toVersion;\n\t\tlet document;\n\t\ttry {\n\t\t\tdocument = await stores.writeCache.getState(documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch document for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tconst documentState = document.state.document;\n\t\tif (documentState.isDeleted && !this.alreadyEvaluated(executing)) return buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);\n\t\tif (fromVersion === toVersion && fromVersion > 0) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst arrivesDecided = executing.replayingAcceptedHistory || executing.evaluatedByPosition;\n\t\tif (fromVersion > 0 && !arrivesDecided) {\n\t\t\tconst stampedVersion = normalizeDocumentModelVersion(documentState.version);\n\t\t\tif (fromVersion !== stampedVersion) return buildErrorResult(job, new UpgradePreconditionFailedError(documentId, `fromVersion ${fromVersion} does not match the document's version ${stampedVersion}`), startTime);\n\t\t\tif (input.revision !== void 0) {\n\t\t\t\tlet actualRevisions;\n\t\t\t\ttry {\n\t\t\t\t\tactualRevisions = (await stores.operationStore.getRevisions(documentId, job.branch, signal)).revision;\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch revisions for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t\t\t}\n\t\t\t\tconst revisionScopes = new Set([...Object.keys(input.revision), ...Object.keys(actualRevisions)]);\n\t\t\t\tfor (const revisionScope of revisionScopes) {\n\t\t\t\t\tconst snapshot = input.revision[revisionScope] ?? 0;\n\t\t\t\t\tconst actual = actualRevisions[revisionScope] ?? 0;\n\t\t\t\t\tif (snapshot !== actual) return buildErrorResult(job, new UpgradePreconditionFailedError(documentId, `revision snapshot for scope \"${revisionScope}\" is ${snapshot} but the document is at ${actual}`), startTime);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet upgradePath;\n\t\tif (fromVersion > 0 && fromVersion < toVersion) try {\n\t\t\tupgradePath = this.registry.computeUpgradePath(document.header.documentType, fromVersion, toVersion);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tconst otherScopes = Object.keys(document.state).filter((scope) => scope !== job.scope);\n\t\tif (fromVersion > 0) for (const scope of otherScopes) {\n\t\t\tlet scopedDocument;\n\t\t\ttry {\n\t\t\t\tscopedDocument = await stores.writeCache.getState(documentId, scope, job.branch, void 0, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`Failed to fetch ${scope} scope for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t\t}\n\t\t\tdocument = {\n\t\t\t\t...document,\n\t\t\t\tstate: {\n\t\t\t\t\t...document.state,\n\t\t\t\t\t[scope]: scopedDocument.state[scope]\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tconst nextIndex = getNextIndexForScope(document, job.scope);\n\t\ttry {\n\t\t\tdocument = applyUpgradeDocumentAction$1(document, action, upgradePath);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, nextIndex, skip, {\n\t\t\tdocumentId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst resultingStateObj = {\n\t\t\theader: document.header,\n\t\t\t...document.state\n\t\t};\n\t\tif (fromVersion > 0) resultingStateObj.__migrated = true;\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tupdateDocumentRevision(document, job.scope, operation.index);\n\t\tdocument.operations = {\n\t\t\t...document.operations,\n\t\t\t[job.scope]: [...document.operations[job.scope] ?? [], operation]\n\t\t};\n\t\texecuting.touchedStreams.add(documentId, job.scope, job.branch);\n\t\tstores.writeCache.putState(documentId, job.scope, job.branch, operation.index, document, SnapshotPosition.Head);\n\t\tfor (const scope of otherScopes) executing.postCommitInvalidations.push({\n\t\t\tdocumentId,\n\t\t\tscope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tstores.documentMetaCache.putDocumentMeta(documentId, job.branch, {\n\t\t\tstate: document.state.document,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);\n\t}\n\texecuteAddRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"ADD_RELATIONSHIP\", write, executing, (input) => input.sourceId === input.targetId ? /* @__PURE__ */ new Error(\"ADD_RELATIONSHIP: sourceId and targetId cannot be the same (self-relationships not allowed)\") : null, ({ indexTxn: txn, stores: s, sourceDoc, input, job: j }) => {\n\t\t\tif (this.driveContainerTypes.has(sourceDoc.header.documentType)) {\n\t\t\t\tconst collectionId = DriveCollectionId.forDrive(input.sourceId, j.branch).key;\n\t\t\t\ttxn.addToCollection(collectionId, input.targetId);\n\t\t\t\ts.collectionMembershipCache.invalidate(input.targetId);\n\t\t\t}\n\t\t});\n\t}\n\texecuteRemoveRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"REMOVE_RELATIONSHIP\", write, executing, null, ({ indexTxn: txn, stores: s, sourceDoc, input, job: j }) => {\n\t\t\tif (this.driveContainerTypes.has(sourceDoc.header.documentType)) {\n\t\t\t\tconst collectionId = DriveCollectionId.forDrive(input.sourceId, j.branch).key;\n\t\t\t\ttxn.removeFromCollection(collectionId, input.targetId);\n\t\t\t\ts.collectionMembershipCache.invalidate(input.targetId);\n\t\t\t}\n\t\t});\n\t}\n\texecuteUpdateRelationship(write, executing) {\n\t\treturn this.withRelationshipAction(\"UPDATE_RELATIONSHIP\", write, executing, null, null);\n\t}\n\tasync withRelationshipAction(actionTypeName, write, executing, preValidate, postWrite) {\n\t\tconst { action, skip, sourceRemote } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.scope !== \"document\") return buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName} must be in \"document\" scope, got \"${job.scope}\"`), startTime);\n\t\tconst input = action.input;\n\t\tif (!input.sourceId || !input.targetId || !input.relationshipType) return buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName} action requires sourceId, targetId, and relationshipType in input`), startTime);\n\t\tif (preValidate !== null) {\n\t\t\tconst validationError = preValidate(input);\n\t\t\tif (validationError !== null) return buildErrorResult(job, validationError, startTime);\n\t\t}\n\t\tlet sourceDoc;\n\t\ttry {\n\t\t\tsourceDoc = await stores.writeCache.getState(input.sourceId, \"document\", job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\tif (DocumentNotFoundError.isError(error)) return buildErrorResult(job, new DocumentNotFoundError(input.sourceId, `${actionTypeName}: source document ${input.sourceId} not found`), startTime);\n\t\t\treturn buildErrorResult(job, /* @__PURE__ */ new Error(`${actionTypeName}: source document ${input.sourceId} not found: ${error instanceof Error ? error.message : String(error)}`), startTime);\n\t\t}\n\t\tlet operation = createOperation(action, getNextIndexForScope(sourceDoc, job.scope), skip, {\n\t\t\tdocumentId: input.sourceId,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t});\n\t\tconst writeResult = await this.writeOperationToStore({\n\t\t\tdocumentId: input.sourceId,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tscope: job.scope,\n\t\t\tbranch: job.branch\n\t\t}, operation, executing);\n\t\tif (!Array.isArray(writeResult)) return writeResult;\n\t\toperation = writeResult[0];\n\t\tsourceDoc.header.lastModifiedAtUtcIso = operation.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString();\n\t\tupdateDocumentRevision(sourceDoc, job.scope, operation.index);\n\t\tsourceDoc.operations = {\n\t\t\t...sourceDoc.operations,\n\t\t\t[job.scope]: [...sourceDoc.operations[job.scope] ?? [], operation]\n\t\t};\n\t\tconst scopeState = sourceDoc.state[job.scope];\n\t\tconst resultingStateObj = {\n\t\t\theader: structuredClone(sourceDoc.header),\n\t\t\t[job.scope]: scopeState === void 0 ? {} : structuredClone(scopeState)\n\t\t};\n\t\tconst resultingState = JSON.stringify(resultingStateObj);\n\t\texecuting.touchedStreams.add(input.sourceId, job.scope, job.branch);\n\t\texecuting.touchedStreams.add(input.targetId, job.scope, job.branch);\n\t\tstores.writeCache.putState(input.sourceId, job.scope, job.branch, operation.index, sourceDoc, SnapshotPosition.Head);\n\t\tindexTxn.write([{\n\t\t\t...operation,\n\t\t\tdocumentId: input.sourceId,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope: job.scope,\n\t\t\tsourceRemote\n\t\t}]);\n\t\tif (postWrite !== null) postWrite({\n\t\t\tindexTxn,\n\t\t\tstores,\n\t\t\tsourceDoc,\n\t\t\tinput,\n\t\t\tjob\n\t\t});\n\t\tstores.documentMetaCache.putDocumentMeta(input.sourceId, job.branch, {\n\t\t\tstate: sourceDoc.state.document,\n\t\t\tdocumentType: sourceDoc.header.documentType,\n\t\t\tdocumentScopeRevision: operation.index + 1\n\t\t});\n\t\treturn buildSuccessResult(job, operation, input.sourceId, sourceDoc.header.documentType, resultingState, startTime);\n\t}\n\tasync writeOperationToStore(target, operation, executing) {\n\t\tconst { documentId, documentType, scope, branch } = target;\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\texecuting.touchedStreams.add(documentId, scope, branch);\n\t\tlet storedOperations;\n\t\ttry {\n\t\t\tstoredOperations = await stores.operationStore.apply(documentId, documentType, scope, branch, operation.index, (txn) => {\n\t\t\t\ttxn.addOperations(operation);\n\t\t\t}, signal);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to write operation to IOperationStore (@documentId @scope @branch): @Operation @Error\", documentId, scope, branch, operation, error);\n\t\t\tstores.writeCache.invalidate(documentId, scope, branch);\n\t\t\tif (AppendConditionFailedError.isError(error)) for (const stream of error.condition.streams) stores.writeCache.invalidate(stream.documentId, stream.scope, stream.branch);\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(`Failed to write operation to IOperationStore: ${String(error)}`),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\treturn storedOperations;\n\t}\n};\n//#endregion\n//#region src/executor/signature-verifier.ts\nvar SignatureVerifier = class {\n\tconstructor(verifier) {\n\t\tthis.verifier = verifier;\n\t}\n\tasync verifyActions(documentId, branch, actions) {\n\t\tif (!this.verifier) return;\n\t\tfor (const action of actions) {\n\t\t\tconst signer = action.context?.signer;\n\t\t\tif (!signer) continue;\n\t\t\tif (signer.signatures.length === 0) throw new InvalidSignatureError(documentId, `Action ${action.id} has signer but no signatures`);\n\t\t\tconst publicKey = signer.app.key;\n\t\t\tlet isValid;\n\t\t\ttry {\n\t\t\t\tconst tempOperation = {\n\t\t\t\t\tid: deriveOperationId(documentId, action.scope, branch, action.id),\n\t\t\t\t\tindex: 0,\n\t\t\t\t\ttimestampUtcMs: action.timestampUtcMs || (/* @__PURE__ */ new Date()).toISOString(),\n\t\t\t\t\thash: \"\",\n\t\t\t\t\tskip: 0,\n\t\t\t\t\taction\n\t\t\t\t};\n\t\t\t\tisValid = await this.verifier(tempOperation, publicKey);\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new InvalidSignatureError(documentId, `Action ${action.id} verification failed: ${errorMessage}`);\n\t\t\t}\n\t\t\tif (!isValid) throw new InvalidSignatureError(documentId, `Action ${action.id} signature verification returned false`);\n\t\t}\n\t}\n\tasync verifyOperations(documentId, operations) {\n\t\tif (!this.verifier) return;\n\t\tfor (let i = 0; i < operations.length; i++) {\n\t\t\tconst operation = operations[i];\n\t\t\tconst signer = operation.action.context?.signer;\n\t\t\tif (!signer) continue;\n\t\t\tif (signer.signatures.length === 0) throw new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} has signer but no signatures`);\n\t\t\tconst publicKey = signer.app.key;\n\t\t\tlet isValid;\n\t\t\ttry {\n\t\t\t\tisValid = await this.verifier(operation, publicKey);\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} verification failed: ${errorMessage}`);\n\t\t\t}\n\t\t\tif (!isValid) throw new InvalidSignatureError(documentId, `Operation ${operation.id} at index ${operation.index} signature verification returned false`);\n\t\t}\n\t}\n};\n//#endregion\n//#region src/executor/simple-job-executor.ts\nconst MAX_SKIP_THRESHOLD = 1e3;\nconst ISO_TIMESTAMP_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$/;\nfunction isValidISOTimestamp(value) {\n\tif (!ISO_TIMESTAMP_REGEX.test(value)) return false;\n\treturn !isNaN(new Date(value).getTime());\n}\n/**\n* Carries a failed job out of the execution scope so its transaction rolls\n* back. A scope callback that returns commits, whatever result it returns, so\n* a returned failure would leave the writes the job made before it failed\n* standing. Never escapes executeJob: the failure goes back to being a\n* returned JobResult there, which is what the queue, the worker protocol and\n* every test expect a failed job to look like.\n*/\nvar JobRollbackSignal = class extends Error {\n\tconstructor(result) {\n\t\tsuper(\"job rolled back\");\n\t\tthis.result = result;\n\t\tthis.name = \"JobRollbackSignal\";\n\t}\n};\nvar SimpleJobExecutor = class {\n\tconfig;\n\tfeatureFlags;\n\tdecisionModel;\n\tsignatureVerifierModule;\n\tdocumentActionHandler;\n\texecutionScope;\n\tconstructor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes, config, signatureVerifier, executionScope) {\n\t\tthis.logger = logger;\n\t\tthis.registry = registry;\n\t\tthis.operationStore = operationStore;\n\t\tthis.eventBus = eventBus;\n\t\tthis.writeCache = writeCache;\n\t\tthis.operationIndex = operationIndex;\n\t\tthis.documentMetaCache = documentMetaCache;\n\t\tthis.collectionMembershipCache = collectionMembershipCache;\n\t\tthis.driveContainerTypes = driveContainerTypes;\n\t\tthis.config = {\n\t\t\tfeatureFlags: config.featureFlags ?? {},\n\t\t\tmaxSkipThreshold: config.maxSkipThreshold ?? MAX_SKIP_THRESHOLD,\n\t\t\tmaxConcurrency: config.maxConcurrency ?? 1,\n\t\t\tjobTimeoutMs: config.jobTimeoutMs ?? 3e4,\n\t\t\tdeferredJobTtlMs: config.deferredJobTtlMs ?? 3e4,\n\t\t\tretryBaseDelayMs: config.retryBaseDelayMs ?? 100,\n\t\t\tretryMaxDelayMs: config.retryMaxDelayMs ?? 5e3,\n\t\t\tyieldDeadlineMs: config.yieldDeadlineMs ?? 50,\n\t\t\tbatchApplies: config.batchApplies ?? true\n\t\t};\n\t\tthis.featureFlags = resolveFeatureFlags(config.featureFlags);\n\t\tthis.decisionModel = selectDecisionModel(this.featureFlags, registry);\n\t\tthis.signatureVerifierModule = new SignatureVerifier(signatureVerifier);\n\t\tthis.documentActionHandler = new DocumentActionHandler(registry, logger, driveContainerTypes, this.featureFlags, this.decisionModel);\n\t\tthis.executionScope = executionScope ?? new DefaultExecutionScope(operationStore, operationIndex, writeCache, documentMetaCache, collectionMembershipCache);\n\t}\n\t/**\n\t* Execute a single job by applying all its actions through the appropriate reducers.\n\t* Actions are processed sequentially in order.\n\t*\n\t* The whole job runs inside one execution scope, and a scope callback that\n\t* returns commits. A failed job must therefore leave the scope by throwing,\n\t* or the writes it made before it failed would be durable: JobRollbackSignal\n\t* carries the failure out through the transaction and this method turns it\n\t* back into the returned JobResult every caller expects. A job either fully\n\t* applies or leaves nothing durable behind.\n\t*\n\t* Durable is the whole of the guarantee. The caches are shared with the\n\t* copies the scope hands the job, so a failed job's writes sit in them from\n\t* the moment it makes them until the eviction below, and a concurrent read\n\t* in that window sees a write that is never going to commit. The window is\n\t* not new -- it has always been there for a job that failed by throwing --\n\t* but nothing here closes it, and a caller that needs to know a write is\n\t* real has the job status to ask.\n\t*/\n\tasync executeJob(job, signal) {\n\t\tconst startTime = Date.now();\n\t\tconst touchedStreams = new TouchedStreams();\n\t\tconst postCommitInvalidations = [];\n\t\tconst postCommitMembershipInvalidations = [];\n\t\tlet outcome;\n\t\ttry {\n\t\t\toutcome = await this.executionScope.run(async (stores) => {\n\t\t\t\tconst scoped = await this.executeInScope({\n\t\t\t\t\tjob,\n\t\t\t\t\tstartTime,\n\t\t\t\t\tstores,\n\t\t\t\t\tsignal,\n\t\t\t\t\ttouchedStreams,\n\t\t\t\t\tpostCommitInvalidations,\n\t\t\t\t\tpostCommitMembershipInvalidations\n\t\t\t\t});\n\t\t\t\tif (!scoped.result.success) throw new JobRollbackSignal(scoped.result);\n\t\t\t\treturn scoped;\n\t\t\t}, signal);\n\t\t} catch (error) {\n\t\t\tthis.evictTouchedStreams(touchedStreams);\n\t\t\tif (error instanceof JobRollbackSignal) return error.result;\n\t\t\tthrow error;\n\t\t}\n\t\tfor (const entry of postCommitInvalidations) this.writeCache.invalidate(entry.documentId, entry.scope, entry.branch);\n\t\tfor (const documentId of postCommitMembershipInvalidations) this.collectionMembershipCache.invalidate(documentId);\n\t\tconst { pendingEvent } = outcome;\n\t\tif (pendingEvent) this.eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, pendingEvent).catch((error) => {\n\t\t\tthis.logger.error(\"Failed to emit JOB_WRITE_READY event: @Event : @Error\", pendingEvent, error);\n\t\t});\n\t\treturn outcome.result;\n\t}\n\t/**\n\t* The body of a job, run inside the execution scope's transaction.\n\t*\n\t* The stores and caches it works through are the copies scoped to that\n\t* transaction, so nothing it does is durable until the scope commits. The\n\t* write-ready event is handed back rather than emitted, because a job that\n\t* has not committed yet has nothing to announce.\n\t*/\n\tasync executeInScope(params) {\n\t\tconst { job, startTime, stores, signal, touchedStreams, postCommitInvalidations, postCommitMembershipInvalidations } = params;\n\t\tlet pendingEvent;\n\t\tconst indexTxn = stores.operationIndex.start();\n\t\tif (job.kind === \"load\") {\n\t\t\tconst loadResult = await this.executeLoadJob({\n\t\t\t\tjob,\n\t\t\t\tstartTime,\n\t\t\t\tindexTxn,\n\t\t\t\tstores,\n\t\t\t\tsignal,\n\t\t\t\treplayingAcceptedHistory: true,\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\tpostCommitInvalidations,\n\t\t\t\tpostCommitMembershipInvalidations,\n\t\t\t\ttouchedStreams\n\t\t\t});\n\t\t\tif (loadResult.success && loadResult.operationsWithContext) {\n\t\t\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\t\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\t\t\tfor (let i = 0; i < loadResult.operationsWithContext.length; i++) loadResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\t\tconst collectionMemberships = loadResult.operationsWithContext.length > 0 ? await this.getCollectionMembershipsForOperations(loadResult.operationsWithContext, stores) : {};\n\t\t\t\tpendingEvent = {\n\t\t\t\t\tjobId: job.id,\n\t\t\t\t\toperations: loadResult.operationsWithContext,\n\t\t\t\t\tjobMeta: job.meta,\n\t\t\t\t\tcollectionMemberships\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult: loadResult,\n\t\t\t\tpendingEvent\n\t\t\t};\n\t\t}\n\t\tif (job.kind === \"reevaluation\") {\n\t\t\tconst reevalResult = await this.executeReevaluationJob({\n\t\t\t\tjob,\n\t\t\t\tstartTime,\n\t\t\t\tindexTxn,\n\t\t\t\tstores,\n\t\t\t\tsignal,\n\t\t\t\treplayingAcceptedHistory: false,\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\tpostCommitInvalidations,\n\t\t\t\tpostCommitMembershipInvalidations,\n\t\t\t\ttouchedStreams\n\t\t\t});\n\t\t\tif (reevalResult.success && reevalResult.operationsWithContext) {\n\t\t\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\t\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\t\t\tfor (let i = 0; i < reevalResult.operationsWithContext.length; i++) reevalResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\t\tif (reevalResult.operationsWithContext.length > 0) {\n\t\t\t\t\tconst collectionMemberships = await this.getCollectionMembershipsForOperations(reevalResult.operationsWithContext, stores);\n\t\t\t\t\tpendingEvent = {\n\t\t\t\t\t\tjobId: job.id,\n\t\t\t\t\t\toperations: reevalResult.operationsWithContext,\n\t\t\t\t\t\tjobMeta: job.meta,\n\t\t\t\t\t\tcollectionMemberships\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tresult: reevalResult,\n\t\t\t\tpendingEvent\n\t\t\t};\n\t\t}\n\t\tconst positioned = await this.positionByTimestamp(job, stores, signal);\n\t\tif (positioned.error) return { result: buildErrorResult(job, positioned.error, startTime) };\n\t\tconst executing = {\n\t\t\tjob,\n\t\t\tstartTime,\n\t\t\tindexTxn,\n\t\t\tstores,\n\t\t\tsignal,\n\t\t\treplayingAcceptedHistory: false,\n\t\t\tevaluatedByPosition: positioned.evaluatedByPosition,\n\t\t\tpostCommitInvalidations,\n\t\t\tpostCommitMembershipInvalidations,\n\t\t\ttouchedStreams\n\t\t};\n\t\tconst actionResult = await this.processActions(positioned.writes, executing);\n\t\tif (!actionResult.success) return { result: {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: actionResult.error,\n\t\t\tduration: Date.now() - startTime\n\t\t} };\n\t\tconst reevaluationError = await this.reevaluateIfCriteriaMet({\n\t\t\tscope: job.scope,\n\t\t\toperations: actionResult.generatedOperations\n\t\t}, executing);\n\t\tif (reevaluationError) return { result: {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: reevaluationError,\n\t\t\tduration: Date.now() - startTime\n\t\t} };\n\t\tconst ordinals = await stores.operationIndex.commit(indexTxn, signal);\n\t\tpostCommitMembershipInvalidations.push(...indexTxn.getMembershipInvalidations());\n\t\tif (actionResult.operationsWithContext.length > 0) {\n\t\t\tfor (let i = 0; i < actionResult.operationsWithContext.length; i++) actionResult.operationsWithContext[i].context.ordinal = ordinals[i];\n\t\t\tconst collectionMemberships = await this.getCollectionMembershipsForOperations(actionResult.operationsWithContext, stores);\n\t\t\tpendingEvent = {\n\t\t\t\tjobId: job.id,\n\t\t\t\toperations: actionResult.operationsWithContext,\n\t\t\t\tjobMeta: job.meta,\n\t\t\t\tsubmittedActionIds: submittedActionIds(job),\n\t\t\t\tcollectionMemberships\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tresult: {\n\t\t\t\tjob,\n\t\t\t\tsuccess: true,\n\t\t\t\toperations: actionResult.generatedOperations,\n\t\t\t\toperationsWithContext: actionResult.operationsWithContext,\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t},\n\t\t\tpendingEvent\n\t\t};\n\t}\n\t/**\n\t* Drops the cached state of every stream a job wrote, after its transaction\n\t* did not commit.\n\t*\n\t* The caches are shared by reference with the copies the scope hands the job,\n\t* so a rollback undoes nothing in them: what the job put there survives, as\n\t* does anything a read filled from the store while the job's own writes were\n\t* still uncommitted. An eviction that throws is swallowed rather than allowed\n\t* to replace the failure the caller is owed, and the remaining streams are\n\t* still evicted.\n\t*/\n\tevictTouchedStreams(touchedStreams) {\n\t\tfor (const entry of touchedStreams) try {\n\t\t\tthis.writeCache.invalidate(entry.documentId, entry.scope, entry.branch);\n\t\t\tthis.documentMetaCache.invalidate(entry.documentId, entry.branch);\n\t\t\tthis.collectionMembershipCache.invalidate(entry.documentId);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to evict cached state for rolled back @Stream : @Error\", entry, error);\n\t\t}\n\t}\n\tasync getCollectionMembershipsForOperations(operations, stores) {\n\t\tconst documentIds = [...new Set(operations.map((op) => op.context.documentId))];\n\t\treturn stores.collectionMembershipCache.getCollectionsForDocuments(documentIds);\n\t}\n\tasync processActions(writes, executing) {\n\t\tconst { job, signal } = executing;\n\t\tconst actions = writes.map((write) => write.action);\n\t\tconst generatedOperations = [];\n\t\tconst operationsWithContext = [];\n\t\ttry {\n\t\t\tawait this.signatureVerifierModule.verifyActions(job.documentId, job.branch, actions);\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t};\n\t\t}\n\t\tfor (const action of actions) if (action.timestampUtcMs && !isValidISOTimestamp(action.timestampUtcMs)) return {\n\t\t\tsuccess: false,\n\t\t\tgeneratedOperations,\n\t\t\toperationsWithContext,\n\t\t\terror: new InvalidOperationTimestampError(job.documentId, action.scope, action.timestampUtcMs, `action ${action.type} (id: ${action.id})`)\n\t\t};\n\t\tlet lastYield = performance.now();\n\t\tif (this.config.batchApplies && this.canBatch(writes, executing)) {\n\t\t\tconst batched = await this.executeRegularActionsBatched(writes, executing);\n\t\t\tconst error = this.accumulateResultOrReturnError(batched, generatedOperations, operationsWithContext);\n\t\t\tif (error !== null) return {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error.error\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext\n\t\t\t};\n\t\t}\n\t\tfor (const write of writes) {\n\t\t\tconst result = DOCUMENT_SCOPE_ACTIONS.has(write.action.type) ? await this.documentActionHandler.execute(write, executing) : await this.executeRegularAction(write, executing);\n\t\t\tconst error = this.accumulateResultOrReturnError(result, generatedOperations, operationsWithContext);\n\t\t\tif (error !== null) return {\n\t\t\t\tsuccess: false,\n\t\t\t\tgeneratedOperations,\n\t\t\t\toperationsWithContext,\n\t\t\t\terror: error.error\n\t\t\t};\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (signal?.aborted) return {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tgeneratedOperations,\n\t\t\t\t\toperationsWithContext,\n\t\t\t\t\terror: /* @__PURE__ */ new Error(\"Aborted\")\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tgeneratedOperations,\n\t\t\toperationsWithContext\n\t\t};\n\t}\n\t/**\n\t* Decides a write and reduces it, without persisting anything.\n\t*\n\t* Split from the commit so one write and a batch of them share this logic\n\t* rather than keeping two copies of it. `baseDocument` lets a batch thread\n\t* the previous action's result forward instead of reading its own write back\n\t* out of the cache, which is the only reason the reduce has to be sequential.\n\t*/\n\tasync prepareRegularWrite(write, executing, baseDocument) {\n\t\tconst { action, skip, sourceOperation, sourceRemote, deniedReason } = write;\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tlet appendCondition;\n\t\tlet documentVersion;\n\t\tconst alreadyEvaluated = this.featureFlags.documentDecisions && (executing.replayingAcceptedHistory || executing.evaluatedByPosition);\n\t\tif (this.featureFlags.documentDecisions && !alreadyEvaluated) {\n\t\t\tconst target = {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tbranch: job.branch\n\t\t\t};\n\t\t\tlet admission;\n\t\t\ttry {\n\t\t\t\tadmission = await decideAtHead(this.decisionModel, stores.writeCache, target, {\n\t\t\t\t\taddress: action.context?.signer?.user.address,\n\t\t\t\t\tkey: action.context?.signer?.app.key\n\t\t\t\t}, {\n\t\t\t\t\tverb: \"execute\",\n\t\t\t\t\tscope: action.scope,\n\t\t\t\t\toperation: action.type\n\t\t\t\t}, signal, this.featureFlags.authConditions ? {\n\t\t\t\t\tactionInput: action.input,\n\t\t\t\t\tcarriedDocument: baseDocument\n\t\t\t\t} : void 0);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tif (admission.evaluation.decision === \"deny\") return buildErrorResult(job, refusalError(admission.evaluation.reason, job.documentId, admission.deletedAtUtcIso, action), startTime);\n\t\t\tappendCondition = admission.appendCondition;\n\t\t\tdocumentVersion = admission.documentVersion;\n\t\t} else if (alreadyEvaluated) documentVersion = (await stores.writeCache.getState(job.documentId, \"document\", job.branch, void 0, signal)).state.document.version;\n\t\telse {\n\t\t\tlet docMeta;\n\t\t\ttry {\n\t\t\t\tdocMeta = await stores.documentMetaCache.getDocumentMeta(job.documentId, job.branch, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tif (docMeta.state.isDeleted) return buildErrorResult(job, new DocumentDeletedError(job.documentId, docMeta.state.deletedAtUtcIso), startTime);\n\t\t\tdocumentVersion = docMeta.state.version;\n\t\t}\n\t\tif (isUndoRedo(action) || action.type === \"PRUNE\" || skip > 0) stores.writeCache.invalidate(job.documentId, job.scope, job.branch);\n\t\tlet document;\n\t\tif (baseDocument !== void 0) document = baseDocument;\n\t\telse try {\n\t\t\tdocument = await stores.writeCache.getState(job.documentId, job.scope, job.branch, void 0, signal);\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tif (!this.featureFlags.authEnforcement && !executing.replayingAcceptedHistory) {\n\t\t\tconst subject = {\n\t\t\t\taddress: write.action.context?.signer?.user.address,\n\t\t\t\tkey: write.action.context?.signer?.app.key\n\t\t\t};\n\t\t\tif (decide(document.state.auth, subject, {\n\t\t\t\tverb: \"execute\",\n\t\t\t\tscope: action.scope,\n\t\t\t\toperation: action.type\n\t\t\t}) === \"deny\") return buildErrorResult(job, new AuthorizationDeniedError(job.documentId, action.scope, action.type, subject.address), startTime);\n\t\t}\n\t\tlet module;\n\t\ttry {\n\t\t\tmodule = this.registry.getModule(document.header.documentType, normalizeDocumentModelVersion(documentVersion));\n\t\t} catch (error) {\n\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t}\n\t\tlet updatedDocument;\n\t\tif (deniedReason !== void 0) {\n\t\t\tconst index = getNextIndexForScope(document, job.scope);\n\t\t\tconst denied = createOperation(action, index, skip, {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tscope: job.scope,\n\t\t\t\tbranch: job.branch\n\t\t\t});\n\t\t\tdenied.deniedReason = deniedReason;\n\t\t\tlet standing = document;\n\t\t\tif (skip > 0) try {\n\t\t\t\tstanding = await stores.writeCache.getState(job.documentId, job.scope, job.branch, index - skip - 1, signal);\n\t\t\t} catch (error) {\n\t\t\t\treturn buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);\n\t\t\t}\n\t\t\tdenied.hash = hashDocumentStateForScope(standing, job.scope);\n\t\t\tupdatedDocument = {\n\t\t\t\t...standing,\n\t\t\t\toperations: {\n\t\t\t\t\t...standing.operations,\n\t\t\t\t\t[job.scope]: [...standing.operations[job.scope] ?? [], denied]\n\t\t\t\t}\n\t\t\t};\n\t\t} else try {\n\t\t\tconst protocolVersion = baseReducerVersion(document.header);\n\t\t\tconst reducerOptions = sourceOperation ? {\n\t\t\t\tskip,\n\t\t\t\tbranch: job.branch,\n\t\t\t\treplayOptions: { operation: sourceOperation },\n\t\t\t\tprotocolVersion\n\t\t\t} : {\n\t\t\t\tskip,\n\t\t\t\tbranch: job.branch,\n\t\t\t\tprotocolVersion\n\t\t\t};\n\t\t\tupdatedDocument = module.reducer(document, action, void 0, reducerOptions);\n\t\t} catch (error) {\n\t\t\tconst contextMessage = `Failed to apply action to document:\\n Action type: ${action.type}\\n Document ID: ${job.documentId}\\n Document type: ${document.header.documentType}\\n Scope: ${job.scope}\\n Original error: ${error instanceof Error ? error.message : String(error)}`;\n\t\t\tconst enhancedError = new Error(contextMessage);\n\t\t\tif (error instanceof Error && error.stack) enhancedError.stack = `${contextMessage}\\n\\nOriginal stack trace:\\n${error.stack}`;\n\t\t\treturn buildErrorResult(job, enhancedError, startTime);\n\t\t}\n\t\tconst scope = job.scope;\n\t\tconst operations = updatedDocument.operations[scope];\n\t\tif (operations.length === 0) return buildErrorResult(job, /* @__PURE__ */ new Error(\"No operation generated from action\"), startTime);\n\t\tconst newOperation = operations[operations.length - 1];\n\t\tif (!isUndoRedo(action)) newOperation.skip = skip;\n\t\tconst resultingState = JSON.stringify({\n\t\t\t...updatedDocument.state,\n\t\t\theader: updatedDocument.header\n\t\t});\n\t\treturn {\n\t\t\taction,\n\t\t\tsourceRemote,\n\t\t\tscope,\n\t\t\tdocument,\n\t\t\tupdatedDocument,\n\t\t\toperation: newOperation,\n\t\t\tresultingState,\n\t\t\tappendCondition,\n\t\t\tdenied: deniedReason !== void 0\n\t\t};\n\t}\n\t/**\n\t* Persists a run of prepared writes in one store transaction.\n\t*\n\t* The store has always accepted many operations per apply; the executor only\n\t* ever handed it one. Passing the whole run means one advisory lock over the\n\t* read set and one guarded insert for the batch, instead of one of each per\n\t* operation.\n\t*\n\t* The append condition is taken from the first write. Every write in a run\n\t* reads the same streams at the same revisions, because nothing outside the\n\t* run can change them mid-batch, and the caller has already refused to batch\n\t* the scopes where that does not hold.\n\t*/\n\tasync commitPreparedWrites(prepared, executing) {\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tconst first = prepared[0];\n\t\tconst last = prepared[prepared.length - 1];\n\t\tconst scope = first.scope;\n\t\tconst documentType = first.document.header.documentType;\n\t\tconst operations = prepared.map((write) => write.operation);\n\t\texecuting.touchedStreams.add(job.documentId, scope, job.branch);\n\t\tlet storedOperations;\n\t\ttry {\n\t\t\tstoredOperations = await stores.operationStore.apply(job.documentId, documentType, scope, job.branch, first.operation.index, (txn) => {\n\t\t\t\ttxn.addOperations(...operations);\n\t\t\t}, signal, first.appendCondition);\n\t\t} catch (error) {\n\t\t\tthis.logger.error(\"Failed to write operation to IOperationStore (@documentId @scope @branch): @Operation @Error\", job.documentId, scope, job.branch, operations, error);\n\t\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\t\tif (AppendConditionFailedError.isError(error)) for (const stream of error.condition.streams) stores.writeCache.invalidate(stream.documentId, stream.scope, stream.branch);\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(`Failed to write operation to IOperationStore: ${String(error)}`),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst head = storedOperations[storedOperations.length - 1];\n\t\tlast.updatedDocument.header.revision = {\n\t\t\t...last.updatedDocument.header.revision,\n\t\t\t[scope]: head.index + 1\n\t\t};\n\t\tstores.writeCache.putRun(job.documentId, scope, job.branch, storedOperations.map((operation, position) => ({\n\t\t\trevision: operation.index,\n\t\t\tdocument: prepared[position].updatedDocument\n\t\t})));\n\t\tindexTxn.write(storedOperations.map((operation, position) => ({\n\t\t\t...operation,\n\t\t\tdocumentId: job.documentId,\n\t\t\tdocumentType,\n\t\t\tbranch: job.branch,\n\t\t\tscope,\n\t\t\tsourceRemote: prepared[position].sourceRemote\n\t\t})));\n\t\tif (scope === \"auth\") for (const write of prepared) indexTxn.recordGroupReferences(job.documentId, mentionedGroupIds(write.action));\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: storedOperations,\n\t\t\toperationsWithContext: storedOperations.map((operation, position) => ({\n\t\t\t\toperation,\n\t\t\t\tcontext: {\n\t\t\t\t\tdocumentId: job.documentId,\n\t\t\t\t\tscope,\n\t\t\t\t\tbranch: job.branch,\n\t\t\t\t\tdocumentType,\n\t\t\t\t\tresultingState: prepared[position].resultingState,\n\t\t\t\t\tordinal: 0\n\t\t\t\t}\n\t\t\t})),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\t/**\n\t* Whether a job's writes may share one store transaction.\n\t*\n\t* Deliberately narrow. Batching changes only how many transactions the\n\t* operations arrive in, and every condition below is a case where that would\n\t* change something else as well:\n\t*\n\t* - A document-scope action goes through its own handler, which has its own\n\t* apply and its own reasons for it.\n\t* - A positional or replayed run carries skips and re-appended operations,\n\t* whose indices are not a simple ascending run from the head.\n\t* - UNDO, REDO, PRUNE and NOOP-with-skip each invalidate the write cache to\n\t* force a full-history rebuild, so they cannot be reduced against state\n\t* threaded from the write before them.\n\t* - The auth scope decides later writes against the policy earlier ones\n\t* install, so a batch would decide them all against the policy as it stood\n\t* before the batch.\n\t* - The document scope is read by every decision model, so writing it is\n\t* writing part of the read set; the per-write conditions would not agree.\n\t*\n\t* A run that fails any of these is executed one write at a time, unchanged.\n\t*/\n\tcanBatch(writes, executing) {\n\t\tif (writes.length < 2) return false;\n\t\tif (executing.evaluatedByPosition || executing.replayingAcceptedHistory) return false;\n\t\tconst scope = executing.job.scope;\n\t\tif (scope === \"auth\" || scope === \"document\") return false;\n\t\treturn writes.every((write) => {\n\t\t\tconst type = write.action.type;\n\t\t\treturn write.skip === 0 && write.deniedReason === void 0 && write.sourceOperation === void 0 && !DOCUMENT_SCOPE_ACTIONS.has(type) && !isUndoRedo(write.action) && type !== \"PRUNE\" && type !== \"NOOP\";\n\t\t});\n\t}\n\t/**\n\t* Decides and reduces a run of writes, then persists them together.\n\t*\n\t* The reduce stays sequential - each action needs the state the one before it\n\t* produced - but the result is threaded in memory rather than read back from\n\t* the cache, and the whole run reaches the store in a single apply.\n\t*\n\t* A write that turns out to be denied abandons the batch and replays the run\n\t* one write at a time, because a denied write holds a position of its own and\n\t* that is the path where the per-write behaviour is load-bearing. A write\n\t* that cannot be prepared fails the job outright: preparing is a read, so the\n\t* replay would only reach the same failure, and the job leaves nothing behind\n\t* either way.\n\t*/\n\tasync executeRegularActionsBatched(writes, executing) {\n\t\tconst prepared = [];\n\t\tlet carried;\n\t\tlet lastYield = performance.now();\n\t\tfor (const write of writes) {\n\t\t\tconst outcome = await this.prepareRegularWrite(write, executing, carried);\n\t\t\tif (\"success\" in outcome) return outcome;\n\t\t\tif (outcome.denied) return this.executeRegularActionsSequentially(writes, executing);\n\t\t\tprepared.push(outcome);\n\t\t\tcarried = outcome.updatedDocument;\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (executing.signal?.aborted) return buildErrorResult(executing.job, /* @__PURE__ */ new Error(\"Aborted\"), executing.startTime);\n\t\t\t}\n\t\t}\n\t\tif (!this.conditionsAgree(prepared)) return this.executeRegularActionsSequentially(writes, executing);\n\t\treturn this.commitPreparedWrites(prepared, executing);\n\t}\n\t/** Whether every prepared write carries the same read-set condition. */\n\tconditionsAgree(prepared) {\n\t\tconst shape = (write) => write.appendCondition === void 0 ? \"none\" : JSON.stringify([...write.appendCondition.streams].map((stream) => [\n\t\t\tstream.documentId,\n\t\t\tstream.scope,\n\t\t\tstream.branch,\n\t\t\tstream.revision\n\t\t]).sort());\n\t\tconst first = shape(prepared[0]);\n\t\treturn prepared.every((write) => shape(write) === first);\n\t}\n\t/**\n\t* The unbatched path, for a run that turned out not to qualify after its\n\t* writes were prepared. Nothing has been persisted at that point, so\n\t* replaying the whole run per write is safe.\n\t*/\n\tasync executeRegularActionsSequentially(writes, executing) {\n\t\tconst operations = [];\n\t\tconst contexts = [];\n\t\tlet lastYield = performance.now();\n\t\tfor (const write of writes) {\n\t\t\tconst result = await this.executeRegularAction(write, executing);\n\t\t\tif (!result.success) return result;\n\t\t\toperations.push(...result.operations ?? []);\n\t\t\tcontexts.push(...result.operationsWithContext ?? []);\n\t\t\tif (performance.now() - lastYield > this.config.yieldDeadlineMs) {\n\t\t\t\tawait yieldToMain();\n\t\t\t\tlastYield = performance.now();\n\t\t\t\tif (executing.signal?.aborted) return buildErrorResult(executing.job, /* @__PURE__ */ new Error(\"Aborted\"), executing.startTime);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tjob: executing.job,\n\t\t\tsuccess: true,\n\t\t\toperations,\n\t\t\toperationsWithContext: contexts,\n\t\t\tduration: Date.now() - executing.startTime\n\t\t};\n\t}\n\t/** Decides, reduces and persists one write. */\n\tasync executeRegularAction(write, executing) {\n\t\tconst prepared = await this.prepareRegularWrite(write, executing);\n\t\tif (\"success\" in prepared) return prepared;\n\t\treturn this.commitPreparedWrites([prepared], executing);\n\t}\n\t/**\n\t* Orders a write by timestamp and decides it where it lands. The caller\n\t* supplies the timestamp, so a write can belong before operations already\n\t* stored; those are re-appended alongside it, the way a load reshuffles.\n\t*\n\t* Deciding a backdated write at the stream heads instead of at its position\n\t* would overwrite the verdict every other replica computes for it.\n\t*/\n\tasync positionByTimestamp(job, stores, signal) {\n\t\tconst plain = () => ({\n\t\t\twrites: job.actions.map((action) => ({\n\t\t\t\taction,\n\t\t\t\tskip: 0,\n\t\t\t\tsourceRemote: \"\"\n\t\t\t})),\n\t\t\tevaluatedByPosition: false\n\t\t});\n\t\tif (!this.featureFlags.documentDecisions || job.actions.length === 0) return plain();\n\t\tlet earliest = job.actions[0].timestampUtcMs;\n\t\tlet earliestAt = Date.parse(earliest);\n\t\tfor (const action of job.actions) {\n\t\t\tconst at = Date.parse(action.timestampUtcMs);\n\t\t\tif (at < earliestAt) {\n\t\t\t\tearliest = action.timestampUtcMs;\n\t\t\t\tearliestAt = at;\n\t\t\t}\n\t\t}\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tconst backdated = earliestAt < Date.parse(revisions.latestTimestamp);\n\t\tif (this.featureFlags.authEnforcement && job.scope === \"auth\") {\n\t\t\tconst newest = await stores.operationStore.getStreamLatestTimestamp(job.documentId, \"auth\", job.branch, signal);\n\t\t\tconst violation = this.firstNonMonotonicTimestamp(job.actions, newest, job.documentId, job.branch);\n\t\t\tif (violation) return {\n\t\t\t\twrites: [],\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\terror: violation\n\t\t\t};\n\t\t\tif (!backdated) return plain();\n\t\t\treturn this.evaluatePositioned(job, stores, this.appendedOperations(job, revisions.revision[job.scope] ?? 0), signal);\n\t\t}\n\t\tif (!backdated) return plain();\n\t\tconst conflicting = (await stores.operationStore.getConflicting(job.documentId, job.scope, job.branch, earliest, void 0, signal)).results.filter((operation) => !isGenesisOperation(operation));\n\t\tconst nothingToMove = async () => {\n\t\t\tif (!this.featureFlags.authEnforcement) return plain();\n\t\t\treturn this.evaluatePositioned(job, stores, this.appendedOperations(job, revisions.revision[job.scope] ?? 0), signal);\n\t\t};\n\t\tif (conflicting.length === 0) return nothingToMove();\n\t\tconst nextIndex = revisions.revision[job.scope] ?? 0;\n\t\tlet firstConflicting = conflicting[0].index;\n\t\tfor (const operation of conflicting) if (operation.index < firstConflicting) firstConflicting = operation.index;\n\t\tconst stored = (await stores.operationStore.getSince(job.documentId, job.scope, job.branch, firstConflicting - 1, void 0, void 0, signal)).results;\n\t\tconst conflictingIds = new Set(conflicting.map((operation) => operation.id));\n\t\tconst effective = garbageCollect(sortOperations(stored)).filter((operation) => !isGenesisOperation(operation));\n\t\tconst firstMoving = effective.findIndex((operation) => conflictingIds.has(operation.id));\n\t\tconst moving = firstMoving === -1 ? [] : effective.slice(firstMoving);\n\t\tif (moving.length === 0) return nothingToMove();\n\t\tlet firstRetracted = moving[0].index;\n\t\tfor (const operation of moving) firstRetracted = Math.min(firstRetracted, operation.index - operation.skip);\n\t\tconst incoming = job.actions.map((action, i) => ({\n\t\t\tid: action.id,\n\t\t\tindex: nextIndex + i,\n\t\t\tskip: 0,\n\t\t\thash: \"\",\n\t\t\ttimestampUtcMs: action.timestampUtcMs,\n\t\t\taction\n\t\t}));\n\t\tconst merged = reshuffleByTimestamp({\n\t\t\tindex: nextIndex,\n\t\t\tskip: retractionSkip(nextIndex, firstRetracted)\n\t\t}, moving, incoming);\n\t\tstores.writeCache.invalidate(job.documentId, job.scope, job.branch);\n\t\tif (!this.featureFlags.authEnforcement) return {\n\t\t\twrites: merged.map((operation) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: operation.skip,\n\t\t\t\tsourceRemote: \"\"\n\t\t\t})),\n\t\t\tevaluatedByPosition: false\n\t\t};\n\t\treturn this.evaluatePositioned(job, stores, merged, signal);\n\t}\n\t/**\n\t* Decides each operation where it lands and carries the verdict on it. A\n\t* refused submitted action is reported to the caller and nothing is stored; a\n\t* refused operation the reshuffle merely moved keeps its verdict, because it\n\t* already holds a position.\n\t*\n\t* The operations carry the indexes and skips they will be stored at, because\n\t* the walk resolves skips before it orders them.\n\t*/\n\tasync evaluatePositioned(job, stores, operations, signal) {\n\t\tconst reasons = await evaluateByPosition(this.decisionModel, {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t}, {\n\t\t\tscope: job.scope,\n\t\t\toperations\n\t\t}, stores, signal);\n\t\tconst submitted = new Set(job.actions.map((action) => action.id));\n\t\tfor (let i = 0; i < operations.length; i++) {\n\t\t\tconst reason = reasons[i];\n\t\t\tif (reason !== void 0 && submitted.has(operations[i].action.id)) return {\n\t\t\t\twrites: [],\n\t\t\t\tevaluatedByPosition: false,\n\t\t\t\terror: refusalError(reason, job.documentId, null, operations[i].action)\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\twrites: operations.map((operation, i) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: operation.skip,\n\t\t\t\tsourceRemote: \"\",\n\t\t\t\tdeniedReason: reasons[i]\n\t\t\t})),\n\t\t\tevaluatedByPosition: true\n\t\t};\n\t}\n\t/**\n\t* The scopes a re-evaluation pass visits, in a fixed order.\n\t*\n\t* The revisions map comes from a query with no ORDER BY, and the order is\n\t* load-bearing: each scope's pass re-reads the auth stream, and the walk skips\n\t* an operation by its stored denial, so a denial this pass just wrote is\n\t* visible to a later-visited scope and invisible to an earlier one. The model's\n\t* own projection order leads, then the rest sorted, so the pass is reproducible\n\t* across replicas and across runs.\n\t*/\n\tevaluationOrder(target, revision) {\n\t\tconst definition = this.decisionModel(target);\n\t\tconst evaluated = Object.keys(revision).filter((scope) => definition.evaluatesScope(scope));\n\t\tconst leading = [];\n\t\tfor (const stream of staticReadSet(definition)) {\n\t\t\tconst scope = stream.query.scope;\n\t\t\tif (evaluated.includes(scope) && !leading.includes(scope)) leading.push(scope);\n\t\t}\n\t\tconst rest = evaluated.filter((scope) => !leading.includes(scope)).sort((a, b) => a.localeCompare(b));\n\t\treturn [...leading, ...rest];\n\t}\n\t/**\n\t* The first timestamp in the batch that does not strictly exceed everything\n\t* ahead of it, or undefined when the whole batch is monotonic.\n\t*\n\t* The bound is carried forward rather than compared against one stored maximum,\n\t* because a single execute can carry several auth actions stamped in the same\n\t* millisecond. Letting a tie through would store a stream the position walk\n\t* then refuses to read, with no repair path.\n\t*/\n\tfirstNonMonotonicTimestamp(entries, newest, documentId, branch) {\n\t\tlet boundIso = newest;\n\t\tlet bound = newest === void 0 ? Number.NEGATIVE_INFINITY : Date.parse(newest);\n\t\tfor (const entry of entries) {\n\t\t\tif (!isValidISOTimestamp(entry.timestampUtcMs)) return new InvalidOperationTimestampError(documentId, \"auth\", entry.timestampUtcMs, \"auth operation\");\n\t\t\tconst at = Date.parse(entry.timestampUtcMs);\n\t\t\tif (boundIso !== void 0 && at <= bound) return new AuthTimestampNotMonotonicError(documentId, branch, entry.timestampUtcMs, boundIso);\n\t\t\tbound = at;\n\t\t\tboundIso = entry.timestampUtcMs;\n\t\t}\n\t}\n\t/** The operations a batch of submitted actions appends at the scope's tail. */\n\tappendedOperations(job, nextIndex) {\n\t\treturn job.actions.map((action, i) => ({\n\t\t\tid: action.id,\n\t\t\tindex: nextIndex + i,\n\t\t\tskip: 0,\n\t\t\thash: \"\",\n\t\t\ttimestampUtcMs: action.timestampUtcMs,\n\t\t\taction\n\t\t}));\n\t}\n\t/**\n\t* Re-evaluates the document when a write meets both criteria: it was written\n\t* to a stream the model reads, and it is timestamped before an operation\n\t* already stored. The caller supplies the timestamp and the reactor does not replace\n\t* it, so a mutation job can write such an operation just as a load job can,\n\t* which is why both executeJob and executeLoadJob call this.\n\t*/\n\tasync reevaluateIfCriteriaMet(criteria, executing) {\n\t\tif (!this.featureFlags.documentDecisions) return;\n\t\tconst { job, stores, signal } = executing;\n\t\tconst target = {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t};\n\t\tif (!staticReadSet(this.decisionModel(target)).some((stream) => stream.query.documentId === job.documentId && stream.query.scope === criteria.scope && stream.query.branch === job.branch)) return;\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tconst latest = Date.parse(revisions.latestTimestamp);\n\t\tif (!criteria.operations.some((operation) => Date.parse(operation.timestampUtcMs) < latest)) return;\n\t\treturn (await this.reevaluateDocument(executing)).error;\n\t}\n\t/**\n\t* Re-evaluates every scope the model evaluates. Where an operation's\n\t* evaluation differs from what is stored, the tail from that operation is\n\t* re-appended, carrying a skip that spans the indices it supersedes.\n\t*/\n\tasync reevaluateDocument(executing) {\n\t\tconst { job, stores, signal } = executing;\n\t\tconst target = {\n\t\t\tdocumentId: job.documentId,\n\t\t\tbranch: job.branch\n\t\t};\n\t\tconst reappended = [];\n\t\tconst revisions = await stores.operationStore.getRevisions(job.documentId, job.branch, signal);\n\t\tfor (const scope of this.evaluationOrder(target, revisions.revision)) {\n\t\t\tconst stored = (await stores.operationStore.getSince(job.documentId, scope, job.branch, -1, void 0, void 0, signal)).results;\n\t\t\tconst effective = garbageCollect(sortOperations([...stored]));\n\t\t\tif (effective.length === 0) continue;\n\t\t\tconst reevaluated = await evaluateByPosition(this.decisionModel, target, {\n\t\t\t\tscope,\n\t\t\t\toperations: effective\n\t\t\t}, stores, signal);\n\t\t\tconst firstChange = effective.findIndex((operation, i) => operation.deniedReason !== reevaluated[i]);\n\t\t\tif (firstChange === -1) continue;\n\t\t\tconst tail = effective.slice(firstChange);\n\t\t\tconst nextIndex = revisions.revision[scope];\n\t\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\t\tconst result = await this.processActions(tail.map((operation, i) => ({\n\t\t\t\taction: operation.action,\n\t\t\t\tskip: i === 0 ? retractionSkip(nextIndex, tail[0].index) : 0,\n\t\t\t\tsourceRemote: \"\",\n\t\t\t\tdeniedReason: reevaluated[firstChange + i]\n\t\t\t})), {\n\t\t\t\t...executing,\n\t\t\t\tjob: {\n\t\t\t\t\t...job,\n\t\t\t\t\tscope\n\t\t\t\t},\n\t\t\t\treplayingAcceptedHistory: true,\n\t\t\t\tevaluatedByPosition: true\n\t\t\t});\n\t\t\tif (!result.success) return {\n\t\t\t\terror: result.error ?? /* @__PURE__ */ new Error(`Re-evaluation of ${job.documentId} ${scope} failed`),\n\t\t\t\toperationsWithContext: reappended\n\t\t\t};\n\t\t\treappended.push(...result.operationsWithContext);\n\t\t}\n\t\treturn { operationsWithContext: reappended };\n\t}\n\t/**\n\t* Re-judges a document's stored operations because a read-set stream in\n\t* another document (a group) gained an operation. The trigger timestamp\n\t* bounds the work: an operation later than everything this document holds\n\t* cannot change any evaluation, so the pass is skipped.\n\t*/\n\tasync executeReevaluationJob(executing) {\n\t\tconst { job, startTime, stores, signal } = executing;\n\t\tif (!this.featureFlags.documentDecisions) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tconst trigger = job.meta.triggerTimestampUtcMs;\n\t\tif (typeof trigger === \"string\") {\n\t\t\tlet latestTimestamp;\n\t\t\ttry {\n\t\t\t\tlatestTimestamp = (await stores.operationStore.getRevisions(job.documentId, job.branch, signal)).latestTimestamp;\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tjob,\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toperations: [],\n\t\t\t\t\toperationsWithContext: [],\n\t\t\t\t\tduration: Date.now() - startTime\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (Date.parse(trigger) > Date.parse(latestTimestamp)) return {\n\t\t\t\tjob,\n\t\t\t\tsuccess: true,\n\t\t\t\toperations: [],\n\t\t\t\toperationsWithContext: [],\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst outcome = await this.reevaluateDocument(executing);\n\t\tif (outcome.error) return buildErrorResult(job, outcome.error, startTime);\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: outcome.operationsWithContext.map((owc) => owc.operation),\n\t\t\toperationsWithContext: outcome.operationsWithContext,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\tasync executeLoadJob(executing) {\n\t\tconst { job, startTime, indexTxn, stores, signal } = executing;\n\t\tif (job.operations.length === 0) return buildErrorResult(job, /* @__PURE__ */ new Error(\"Load job must include at least one operation\"), startTime);\n\t\tlet docMeta;\n\t\ttry {\n\t\t\tdocMeta = await stores.documentMetaCache.getDocumentMeta(job.documentId, job.branch, signal);\n\t\t} catch {}\n\t\tif (docMeta?.state.isDeleted && !this.featureFlags.documentDecisions) return buildErrorResult(job, new DocumentDeletedError(job.documentId, docMeta.state.deletedAtUtcIso), startTime);\n\t\tconst scope = job.scope;\n\t\tconst monotonicAuthStream = this.featureFlags.authEnforcement && scope === \"auth\";\n\t\tlet latestRevision;\n\t\ttry {\n\t\t\tlatestRevision = (await stores.operationStore.getRevisions(job.documentId, job.branch, signal)).revision[scope] ?? 0;\n\t\t} catch {\n\t\t\tlatestRevision = 0;\n\t\t}\n\t\tfor (const operation of job.operations) if (operation.timestampUtcMs && !isValidISOTimestamp(operation.timestampUtcMs)) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: new InvalidOperationTimestampError(job.documentId, scope, operation.timestampUtcMs, `operation (index: ${operation.index})`),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tlet minIncomingIndex = Number.POSITIVE_INFINITY;\n\t\tlet minIncomingTimestamp = job.operations[0]?.timestampUtcMs || \"\";\n\t\tfor (const operation of job.operations) {\n\t\t\tminIncomingIndex = Math.min(minIncomingIndex, operation.index);\n\t\t\tconst ts = operation.timestampUtcMs || \"\";\n\t\t\tif (Date.parse(ts) < Date.parse(minIncomingTimestamp)) minIncomingTimestamp = ts;\n\t\t}\n\t\tlet conflictingOps;\n\t\ttry {\n\t\t\tconflictingOps = (await stores.operationStore.getConflicting(job.documentId, scope, job.branch, minIncomingTimestamp, void 0, signal)).results;\n\t\t} catch {\n\t\t\tconflictingOps = [];\n\t\t}\n\t\tlet allOpsFromMinConflictingIndex = conflictingOps;\n\t\tif (conflictingOps.length > 0) {\n\t\t\tconst minConflictingIndex = Math.min(...conflictingOps.map((op) => op.index));\n\t\t\ttry {\n\t\t\t\tallOpsFromMinConflictingIndex = (await stores.operationStore.getSince(job.documentId, scope, job.branch, minConflictingIndex - 1, void 0, void 0, signal)).results;\n\t\t\t} catch {\n\t\t\t\tallOpsFromMinConflictingIndex = conflictingOps;\n\t\t\t}\n\t\t}\n\t\tconst incomingActionIds = new Set(job.operations.map((op) => op.action.id));\n\t\tconst nonSupersededOps = conflictingOps.filter((op) => {\n\t\t\tif (op.index < minIncomingIndex && !incomingActionIds.has(op.action.id)) return false;\n\t\t\tfor (const laterOp of allOpsFromMinConflictingIndex) if (laterOp.index > op.index && laterOp.skip > 0) {\n\t\t\t\tif (laterOp.index - laterOp.skip <= op.index) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\t\tconst existingOpsToReshuffle = monotonicAuthStream ? [] : nonSupersededOps.filter((operation) => !isGenesisOperation(operation));\n\t\tconst actionIdCounts = /* @__PURE__ */ new Map();\n\t\tfor (const operation of allOpsFromMinConflictingIndex) actionIdCounts.set(operation.action.id, (actionIdCounts.get(operation.action.id) ?? 0) + 1);\n\t\tconst reshuffleCost = existingOpsToReshuffle.filter((operation) => (actionIdCounts.get(operation.action.id) ?? 0) < 2).length;\n\t\tif (reshuffleCost > this.config.maxSkipThreshold) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: new ExcessiveReshuffleError(job.documentId, scope, reshuffleCost, this.config.maxSkipThreshold),\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tlet skipCount = existingOpsToReshuffle.length;\n\t\tif (existingOpsToReshuffle.length > 0) {\n\t\t\tlet minLogicalIndex = Number.POSITIVE_INFINITY;\n\t\t\tfor (const op of existingOpsToReshuffle) {\n\t\t\t\tconst logical = op.index - op.skip;\n\t\t\t\tif (logical < minLogicalIndex) minLogicalIndex = logical;\n\t\t\t}\n\t\t\tconst logicalSkip = latestRevision - minLogicalIndex;\n\t\t\tif (logicalSkip > skipCount) skipCount = logicalSkip;\n\t\t}\n\t\tconst existingActionIds = new Set(nonSupersededOps.map((op) => op.action.id));\n\t\tconst seenIncomingActionIds = /* @__PURE__ */ new Set();\n\t\tconst incomingOpsToApply = job.operations.filter((op) => {\n\t\t\tif (existingActionIds.has(op.action.id)) return false;\n\t\t\tif (seenIncomingActionIds.has(op.action.id)) return false;\n\t\t\tseenIncomingActionIds.add(op.action.id);\n\t\t\treturn true;\n\t\t});\n\t\tif (incomingOpsToApply.length === 0) return {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: [],\n\t\t\toperationsWithContext: [],\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tif (monotonicAuthStream) {\n\t\t\tconst newest = await stores.operationStore.getStreamLatestTimestamp(job.documentId, \"auth\", job.branch, signal);\n\t\t\tconst violation = this.firstNonMonotonicTimestamp([...incomingOpsToApply].sort((a, b) => a.index - b.index), newest, job.documentId, job.branch);\n\t\t\tif (violation) return {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: violation,\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst reshuffledOperations = existingOpsToReshuffle.length === 0 && skipCount === 0 ? incomingOpsToApply.slice().sort((a, b) => a.index - b.index).map((operation, i) => ({\n\t\t\t...operation,\n\t\t\tindex: latestRevision + i\n\t\t})) : reshuffleByTimestamp({\n\t\t\tindex: latestRevision,\n\t\t\tskip: skipCount\n\t\t}, existingOpsToReshuffle, incomingOpsToApply.map((operation) => ({\n\t\t\t...operation,\n\t\t\tid: operation.id\n\t\t})));\n\t\tfor (const operation of reshuffledOperations) if (operation.action.type === \"NOOP\" && operation.skip === 0) operation.skip = 1;\n\t\tlet deniedReasons;\n\t\tif (this.featureFlags.documentDecisions) try {\n\t\t\tdeniedReasons = await evaluateByPosition(this.decisionModel, {\n\t\t\t\tdocumentId: job.documentId,\n\t\t\t\tbranch: job.branch\n\t\t\t}, {\n\t\t\t\tscope,\n\t\t\t\toperations: reshuffledOperations\n\t\t\t}, stores, signal);\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tjob,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error : new Error(String(error)),\n\t\t\t\tduration: Date.now() - startTime\n\t\t\t};\n\t\t}\n\t\tconst effectiveSourceRemote = skipCount > 0 ? \"\" : job.meta.sourceRemote || \"\";\n\t\tconst result = await this.processActions(reshuffledOperations.map((operation, i) => ({\n\t\t\taction: operation.action,\n\t\t\tskip: operation.skip,\n\t\t\tsourceOperation: operation,\n\t\t\tsourceRemote: effectiveSourceRemote,\n\t\t\tdeniedReason: deniedReasons?.[i]\n\t\t})), executing);\n\t\tif (!result.success) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: result.error,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\tstores.writeCache.invalidate(job.documentId, scope, job.branch);\n\t\tif (scope === \"document\") stores.documentMetaCache.invalidate(job.documentId, job.branch);\n\t\tconst reevaluationError = await this.reevaluateIfCriteriaMet({\n\t\t\tscope,\n\t\t\toperations: result.generatedOperations\n\t\t}, executing);\n\t\tif (reevaluationError) return {\n\t\t\tjob,\n\t\t\tsuccess: false,\n\t\t\terror: reevaluationError,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t\treturn {\n\t\t\tjob,\n\t\t\tsuccess: true,\n\t\t\toperations: result.generatedOperations,\n\t\t\toperationsWithContext: result.operationsWithContext,\n\t\t\tduration: Date.now() - startTime\n\t\t};\n\t}\n\taccumulateResultOrReturnError(result, generatedOperations, operationsWithContext) {\n\t\tif (!result.success) return result;\n\t\tif (result.operations && result.operations.length > 0) generatedOperations.push(...result.operations);\n\t\tif (result.operationsWithContext) operationsWithContext.push(...result.operationsWithContext);\n\t\treturn null;\n\t}\n};\n//#endregion\n//#region src/registry/implementation.ts\n/**\n* In-memory implementation of the IDocumentModelRegistry interface.\n* Manages document model modules with version-aware storage and upgrade manifest support.\n*/\nvar DocumentModelRegistry = class {\n\tmodules = [];\n\tmanifests = [];\n\tregisterModules(...modules) {\n\t\treturn modules.map((module) => {\n\t\t\ttry {\n\t\t\t\tconst documentType = module.documentModel.global.id;\n\t\t\t\tconst version = module.version ?? 1;\n\t\t\t\tfor (let i = 0; i < this.modules.length; i++) {\n\t\t\t\t\tconst existing = this.modules[i];\n\t\t\t\t\tconst existingType = existing.documentModel.global.id;\n\t\t\t\t\tconst existingVersion = existing.version ?? 1;\n\t\t\t\t\tif (existingType === documentType && existingVersion === version) throw new DuplicateModuleError(documentType, version);\n\t\t\t\t}\n\t\t\t\tthis.modules.push(module);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\titem: module\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\titem: module,\n\t\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t}\n\tunregisterModules(...documentTypes) {\n\t\tlet allFound = true;\n\t\tfor (const documentType of documentTypes) {\n\t\t\tif (!this.modules.some((m) => m.documentModel.global.id === documentType)) allFound = false;\n\t\t\tthis.modules = this.modules.filter((m) => m.documentModel.global.id !== documentType);\n\t\t}\n\t\treturn allFound;\n\t}\n\tgetModule(documentType, version) {\n\t\tlet latestModule;\n\t\tlet latestVersion = -1;\n\t\tfor (let i = 0; i < this.modules.length; i++) {\n\t\t\tconst module = this.modules[i];\n\t\t\tconst moduleType = module.documentModel.global.id;\n\t\t\tconst moduleVersion = module.version ?? 1;\n\t\t\tif (moduleType === documentType) {\n\t\t\t\tif (version !== void 0 && moduleVersion === version) return module;\n\t\t\t\tif (moduleVersion > latestVersion) {\n\t\t\t\t\tlatestModule = module;\n\t\t\t\t\tlatestVersion = moduleVersion;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (version === void 0 && latestModule !== void 0) return latestModule;\n\t\tthrow new ModuleNotFoundError(documentType, version);\n\t}\n\tgetAllModules() {\n\t\treturn [...this.modules];\n\t}\n\tclear() {\n\t\tthis.modules = [];\n\t\tthis.manifests = [];\n\t}\n\tgetSupportedVersions(documentType) {\n\t\tconst versions = [];\n\t\tfor (const module of this.modules) if (module.documentModel.global.id === documentType) versions.push(module.version ?? 1);\n\t\tif (versions.length === 0) throw new ModuleNotFoundError(documentType);\n\t\treturn versions.sort((a, b) => a - b);\n\t}\n\tgetLatestVersion(documentType) {\n\t\tlet latest = -1;\n\t\tlet found = false;\n\t\tfor (const module of this.modules) if (module.documentModel.global.id === documentType) {\n\t\t\tfound = true;\n\t\t\tconst version = module.version ?? 1;\n\t\t\tif (version > latest) latest = version;\n\t\t}\n\t\tif (!found) throw new ModuleNotFoundError(documentType);\n\t\treturn latest;\n\t}\n\tregisterUpgradeManifests(...manifestsToRegister) {\n\t\treturn manifestsToRegister.map((manifestToRegister) => {\n\t\t\ttry {\n\t\t\t\tif (!manifestToRegister.documentType) throw new Error(\"Upgrade manifest is missing a documentType\");\n\t\t\t\tfor (const registeredManifest of this.manifests) if (registeredManifest.documentType === manifestToRegister.documentType) throw new DuplicateManifestError(manifestToRegister.documentType);\n\t\t\t\tthis.manifests.push(manifestToRegister);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\titem: manifestToRegister\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\titem: manifestToRegister,\n\t\t\t\t\terror: error instanceof Error ? error : new Error(String(error))\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\t}\n\tunregisterUpgradeManifests(...documentTypes) {\n\t\tlet allFound = true;\n\t\tfor (const documentType of documentTypes) {\n\t\t\tif (!this.manifests.some((m) => m.documentType === documentType)) allFound = false;\n\t\t\tthis.manifests = this.manifests.filter((m) => m.documentType !== documentType);\n\t\t}\n\t\treturn allFound;\n\t}\n\tgetUpgradeManifest(documentType) {\n\t\tfor (let i = 0; i < this.manifests.length; i++) if (this.manifests[i].documentType === documentType) return this.manifests[i];\n\t\tthrow new ManifestNotFoundError(documentType);\n\t}\n\tcomputeUpgradePath(documentType, fromVersion, toVersion) {\n\t\tif (fromVersion === toVersion) return [];\n\t\tif (toVersion < fromVersion) throw new DowngradeNotSupportedError$1(documentType, fromVersion, toVersion);\n\t\tconst manifest = this.getUpgradeManifest(documentType);\n\t\tconst path = [];\n\t\tfor (let v = fromVersion + 1; v <= toVersion; v++) {\n\t\t\tconst key = `v${v}`;\n\t\t\tif (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, v - 1, v);\n\t\t\tconst transition = manifest.upgrades[key];\n\t\t\tpath.push(transition);\n\t\t}\n\t\treturn path;\n\t}\n\tgetUpgradeReducer(documentType, fromVersion, toVersion) {\n\t\tif (toVersion !== fromVersion + 1) throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);\n\t\tconst manifest = this.getUpgradeManifest(documentType);\n\t\tconst key = `v${toVersion}`;\n\t\tif (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, fromVersion, toVersion);\n\t\treturn manifest.upgrades[key].upgradeReducer;\n\t}\n};\n//#endregion\n//#region src/storage/kysely/keyframe-store.ts\nvar KyselyKeyframeStore = class KyselyKeyframeStore {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyKeyframeStore(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tasync putKeyframe(documentId, scope, branch, revision, document, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tawait this.queryExecutor.insertInto(\"Keyframe\").values({\n\t\t\tdocumentId,\n\t\t\tdocumentType: document.header.documentType,\n\t\t\tscope,\n\t\t\tbranch,\n\t\t\trevision,\n\t\t\tdocument\n\t\t}).onConflict((oc) => oc.columns([\n\t\t\t\"documentId\",\n\t\t\t\"scope\",\n\t\t\t\"branch\",\n\t\t\t\"revision\"\n\t\t]).doUpdateSet({ document })).execute();\n\t}\n\tasync findNearestKeyframe(documentId, scope, branch, targetRevision, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tconst row = await this.queryExecutor.selectFrom(\"Keyframe\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"revision\", \"<=\", targetRevision).orderBy(\"revision\", \"desc\").limit(1).executeTakeFirst();\n\t\tif (!row) return;\n\t\treturn {\n\t\t\trevision: row.revision,\n\t\t\tdocument: row.document\n\t\t};\n\t}\n\tasync listKeyframes(documentId, scope, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tlet query = this.queryExecutor.selectFrom(\"Keyframe\").selectAll().where(\"documentId\", \"=\", documentId).orderBy(\"revision\", \"asc\");\n\t\tif (scope !== void 0) query = query.where(\"scope\", \"=\", scope);\n\t\tif (branch !== void 0) query = query.where(\"branch\", \"=\", branch);\n\t\treturn (await query.execute()).map((row) => ({\n\t\t\tscope: row.scope,\n\t\t\tbranch: row.branch,\n\t\t\trevision: row.revision,\n\t\t\tdocument: row.document\n\t\t}));\n\t}\n\tasync deleteKeyframes(documentId, scope, branch, signal) {\n\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\t\tlet query = this.queryExecutor.deleteFrom(\"Keyframe\").where(\"documentId\", \"=\", documentId);\n\t\tif (scope !== void 0 && branch !== void 0) query = query.where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch);\n\t\telse if (scope !== void 0) query = query.where(\"scope\", \"=\", scope);\n\t\tconst result = await query.executeTakeFirst();\n\t\treturn Number(result.numDeletedRows || 0n);\n\t}\n};\n//#endregion\n//#region src/storage/kysely/pagination.ts\nconst DEFAULT_LIMIT = 100;\nfunction paginateRows(rows, paging, cursorOf, toItem, refetch) {\n\tlet hasMore = false;\n\tlet items = rows;\n\tif (paging?.limit && rows.length > paging.limit) {\n\t\thasMore = true;\n\t\titems = rows.slice(0, paging.limit);\n\t}\n\tconst nextCursor = hasMore && items.length > 0 ? cursorOf(items[items.length - 1]).toString() : void 0;\n\tconst cursor = paging?.cursor || \"0\";\n\tconst limit = paging?.limit || DEFAULT_LIMIT;\n\treturn {\n\t\tresults: items.map(toItem),\n\t\toptions: {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t},\n\t\tnextCursor,\n\t\tnext: hasMore ? () => refetch(nextCursor, limit) : void 0\n\t};\n}\n//#endregion\n//#region src/storage/txn.ts\nvar AtomicTransaction = class {\n\toperations = [];\n\tconstructor(documentId, documentType, scope, branch, baseRevision) {\n\t\tthis.documentId = documentId;\n\t\tthis.documentType = documentType;\n\t\tthis.scope = scope;\n\t\tthis.branch = branch;\n\t\tthis.baseRevision = baseRevision;\n\t}\n\taddOperations(...operations) {\n\t\tfor (const op of operations) this.operations.push({\n\t\t\tjobId: v4(),\n\t\t\topId: op.id,\n\t\t\tprevOpId: \"\",\n\t\t\tdocumentId: this.documentId,\n\t\t\tdocumentType: this.documentType,\n\t\t\tscope: this.scope,\n\t\t\tbranch: this.branch,\n\t\t\ttimestampUtcMs: new Date(op.timestampUtcMs),\n\t\t\tindex: op.index,\n\t\t\taction: JSON.stringify(op.action),\n\t\t\tskip: op.skip,\n\t\t\terror: op.error || null,\n\t\t\tdeniedReason: op.deniedReason || null,\n\t\t\thash: op.hash\n\t\t});\n\t}\n\tgetOperations() {\n\t\treturn this.operations;\n\t}\n};\n//#endregion\n//#region src/storage/kysely/store.ts\nvar _UniqueConstraintContext = class extends Error {\n\tconstructor(documentId, scope, branch, revision, stagedOps) {\n\t\tsuper(\"unique constraint\");\n\t\tthis.documentId = documentId;\n\t\tthis.scope = scope;\n\t\tthis.branch = branch;\n\t\tthis.revision = revision;\n\t\tthis.stagedOps = stagedOps;\n\t\tthis.name = \"UniqueConstraintContext\";\n\t}\n};\nvar KyselyOperationStore = class KyselyOperationStore {\n\ttrx;\n\tconstructor(db) {\n\t\tthis.db = db;\n\t}\n\tget queryExecutor() {\n\t\treturn this.trx ?? this.db;\n\t}\n\twithTransaction(trx) {\n\t\tconst instance = new KyselyOperationStore(this.db);\n\t\tinstance.trx = trx;\n\t\treturn instance;\n\t}\n\tasync apply(documentId, documentType, scope, branch, revision, fn, signal, condition) {\n\t\tif (this.trx) {\n\t\t\tlet executeResult = null;\n\t\t\tlet uniqueCtx = null;\n\t\t\ttry {\n\t\t\t\texecuteResult = await this.executeApply(this.trx, documentId, documentType, scope, branch, revision, fn, signal, condition);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof _UniqueConstraintContext) uniqueCtx = error;\n\t\t\t\telse throw error;\n\t\t\t}\n\t\t\tif (uniqueCtx !== null) return this.resolveUniqueConstraint(uniqueCtx);\n\t\t\treturn executeResult;\n\t\t} else {\n\t\t\tlet transactionResult = null;\n\t\t\tlet uniqueCtx = null;\n\t\t\ttry {\n\t\t\t\ttransactionResult = await this.db.transaction().execute(async (trx) => {\n\t\t\t\t\treturn this.executeApply(trx, documentId, documentType, scope, branch, revision, fn, signal, condition);\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof _UniqueConstraintContext) uniqueCtx = error;\n\t\t\t\telse throw error;\n\t\t\t}\n\t\t\tif (uniqueCtx !== null) return this.resolveUniqueConstraint(uniqueCtx);\n\t\t\treturn transactionResult;\n\t\t}\n\t}\n\tasync resolveUniqueConstraint(ctx) {\n\t\tlet replayOps = null;\n\t\ttry {\n\t\t\treplayOps = await this.findIdempotentReplay(this.db, ctx.documentId, ctx.scope, ctx.branch, ctx.revision, ctx.stagedOps);\n\t\t} catch {}\n\t\tif (replayOps !== null) return replayOps;\n\t\tconst op = ctx.stagedOps[0];\n\t\tthrow new DuplicateOperationError(`${op.opId} at index ${op.index} with skip ${op.skip}`);\n\t}\n\tasync executeApply(trx, documentId, documentType, scope, branch, revision, fn, signal, condition) {\n\t\tthrowIfAborted(signal);\n\t\tconst atomicTxn = new AtomicTransaction(documentId, documentType, scope, branch, revision);\n\t\tawait fn(atomicTxn);\n\t\tconst operations = atomicTxn.getOperations();\n\t\tif (operations.length === 0) return [];\n\t\tif (condition) await this.acquireStreamLocks(trx, documentId, scope, branch, condition);\n\t\tconst latestOp = await trx.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).orderBy(\"index\", \"desc\").limit(1).executeTakeFirst();\n\t\tconst currentRevision = latestOp ? latestOp.index : -1;\n\t\tif (currentRevision !== revision - 1) {\n\t\t\tlet replayOps = null;\n\t\t\ttry {\n\t\t\t\treplayOps = await this.findIdempotentReplay(trx, documentId, scope, branch, revision, operations);\n\t\t\t} catch {}\n\t\t\tif (replayOps !== null) return replayOps;\n\t\t\tif (revision === 0 && this.isCreate(operations)) throw new DocumentAlreadyExistsError(documentId, scope, currentRevision);\n\t\t\tthrow new RevisionMismatchError(currentRevision + 1, revision);\n\t\t}\n\t\tlet prevOpId = latestOp?.opId || \"\";\n\t\tfor (const op of operations) {\n\t\t\top.prevOpId = prevOpId;\n\t\t\tprevOpId = op.opId;\n\t\t}\n\t\tlet insertedCount = operations.length;\n\t\ttry {\n\t\t\tif (condition && condition.streams.length > 0) insertedCount = await this.insertGuarded(trx, operations, condition);\n\t\t\telse await trx.insertInto(\"Operation\").values(operations).execute();\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.includes(\"unique constraint\")) throw new _UniqueConstraintContext(documentId, scope, branch, revision, operations);\n\t\t\tthrow error;\n\t\t}\n\t\tif (insertedCount !== operations.length) throw new AppendConditionFailedError(condition);\n\t\treturn operations.map((op) => ({\n\t\t\tindex: op.index,\n\t\t\ttimestampUtcMs: op.timestampUtcMs.toISOString(),\n\t\t\thash: op.hash,\n\t\t\tskip: op.skip,\n\t\t\terror: op.error || void 0,\n\t\t\tdeniedReason: op.deniedReason || void 0,\n\t\t\tid: op.opId,\n\t\t\taction: JSON.parse(op.action)\n\t\t}));\n\t}\n\t/**\n\t* Locks the written stream and every read-set stream, in sorted key order\n\t* so that overlapping concurrent appends serialize rather than deadlock.\n\t* The locks are still taken one row at a time, so the query preserves that\n\t* order. It must stay separate from the guarded insert, which would\n\t* otherwise read a snapshot taken before the locks were held.\n\t*/\n\tasync acquireStreamLocks(trx, documentId, scope, branch, condition) {\n\t\tconst keys = new Set([`${documentId}:${scope}:${branch}`]);\n\t\tfor (const stream of condition.streams) keys.add(`${stream.documentId}:${stream.scope}:${stream.branch}`);\n\t\tawait sql`\n with ordered as materialized (\n select key\n from unnest(array[${sql.join([...keys].sort())}]::text[]) with ordinality as t(key, ord)\n order by ord\n )\n select pg_advisory_xact_lock(hashtext(key)) from ordered\n `.execute(trx);\n\t}\n\t/**\n\t* Inserts the staged operations with the condition compiled in as a WHERE\n\t* NOT EXISTS guard, making the check and the append one statement. Returns\n\t* the rows inserted; zero means the guard failed and nothing was written.\n\t*/\n\tasync insertGuarded(trx, operations, condition) {\n\t\tconst branches = operations.map((op) => trx.selectNoFrom([\n\t\t\tsql`${op.jobId}::text`.as(\"jobId\"),\n\t\t\tsql`${op.opId}::text`.as(\"opId\"),\n\t\t\tsql`${op.prevOpId}::text`.as(\"prevOpId\"),\n\t\t\tsql`${op.documentId}::text`.as(\"documentId\"),\n\t\t\tsql`${op.documentType}::text`.as(\"documentType\"),\n\t\t\tsql`${op.scope}::text`.as(\"scope\"),\n\t\t\tsql`${op.branch}::text`.as(\"branch\"),\n\t\t\tsql`${op.timestampUtcMs}::timestamptz`.as(\"timestampUtcMs\"),\n\t\t\tsql`${op.index}::integer`.as(\"index\"),\n\t\t\tsql`${op.action}::jsonb`.as(\"action\"),\n\t\t\tsql`${op.skip}::integer`.as(\"skip\"),\n\t\t\tsql`${op.error ?? null}::text`.as(\"error\"),\n\t\t\tsql`${op.deniedReason ?? null}::text`.as(\"deniedReason\"),\n\t\t\tsql`${op.hash}::text`.as(\"hash\")\n\t\t]).where((eb) => eb.not(eb.exists(eb.selectFrom(\"Operation\").select(\"Operation.id\").where((web) => web.or(condition.streams.map((s) => web.and([\n\t\t\tweb(\"Operation.documentId\", \"=\", s.documentId),\n\t\t\tweb(\"Operation.scope\", \"=\", s.scope),\n\t\t\tweb(\"Operation.branch\", \"=\", s.branch),\n\t\t\tweb(\"Operation.index\", \">\", s.revision)\n\t\t]))))))));\n\t\tlet expression = branches[0];\n\t\tfor (let i = 1; i < branches.length; i++) expression = expression.unionAll(branches[i]);\n\t\treturn (await trx.insertInto(\"Operation\").columns([\n\t\t\t\"jobId\",\n\t\t\t\"opId\",\n\t\t\t\"prevOpId\",\n\t\t\t\"documentId\",\n\t\t\t\"documentType\",\n\t\t\t\"scope\",\n\t\t\t\"branch\",\n\t\t\t\"timestampUtcMs\",\n\t\t\t\"index\",\n\t\t\t\"action\",\n\t\t\t\"skip\",\n\t\t\t\"error\",\n\t\t\t\"deniedReason\",\n\t\t\t\"hash\"\n\t\t]).expression(expression).returning(\"id\").execute()).length;\n\t}\n\tasync findIdempotentReplay(executor, documentId, scope, branch, revision, stagedOps) {\n\t\tconst minIndex = revision;\n\t\tconst maxIndex = revision + stagedOps.length - 1;\n\t\tconst storedRows = await executor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"index\", \">=\", minIndex).where(\"index\", \"<=\", maxIndex).orderBy(\"index\", \"asc\").execute();\n\t\tif (storedRows.length !== stagedOps.length) return null;\n\t\tfor (let i = 0; i < stagedOps.length; i++) {\n\t\t\tconst staged = stagedOps[i];\n\t\t\tconst stored = storedRows[i];\n\t\t\tif (stored.opId !== staged.opId || stored.index !== staged.index || stored.skip !== staged.skip) return null;\n\t\t}\n\t\treturn storedRows.map((row) => this.rowToOperation(row));\n\t}\n\t/** True when the staged write creates a document rather than appending to one. */\n\tisCreate(operations) {\n\t\tfor (const operation of operations) {\n\t\t\tlet action = operation.action;\n\t\t\tif (typeof action === \"string\") try {\n\t\t\t\taction = JSON.parse(action);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof action === \"object\" && action !== null && \"type\" in action && typeof action.type === \"string\" && action.type === \"CREATE_DOCUMENT\") return true;\n\t\t}\n\t\treturn false;\n\t}\n\tasync getSince(documentId, scope, branch, revision, filter, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"index\", \">\", revision).orderBy(\"index\", \"asc\");\n\t\tif (filter) {\n\t\t\tif (filter.actionTypes && filter.actionTypes.length > 0) {\n\t\t\t\tconst actionTypesArray = filter.actionTypes.map((t) => `'${t.replace(/'/g, \"''\")}'`).join(\",\");\n\t\t\t\tquery = query.where(sql`action->>'type' = ANY(ARRAY[${sql.raw(actionTypesArray)}]::text[])`);\n\t\t\t}\n\t\t\tif (filter.timestampFrom) query = query.where(\"timestampUtcMs\", \">=\", new Date(filter.timestampFrom));\n\t\t\tif (filter.timestampTo) query = query.where(\"timestampUtcMs\", \"<=\", new Date(filter.timestampTo));\n\t\t\tif (filter.sinceRevision !== void 0) query = query.where(\"index\", \">=\", filter.sinceRevision);\n\t\t}\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"index\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getSince(documentId, scope, branch, revision, filter, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getSinceId(id, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"id\", \">\", id).orderBy(\"id\", \"asc\");\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"id\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.id, (row) => this.rowToOperationWithContext(row), (cursor, limit) => this.getSinceId(id, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getConflicting(documentId, scope, branch, minTimestamp, paging, signal) {\n\t\tthrowIfAborted(signal);\n\t\tlet query = this.queryExecutor.selectFrom(\"Operation\").selectAll().where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).where(\"timestampUtcMs\", \">=\", new Date(minTimestamp)).orderBy(\"index\", \"asc\");\n\t\tif (paging) {\n\t\t\tconst cursorValue = Number.parseInt(paging.cursor, 10);\n\t\t\tif (cursorValue > 0) query = query.where(\"index\", \">\", cursorValue);\n\t\t\tif (paging.limit) query = query.limit(paging.limit + 1);\n\t\t}\n\t\treturn paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getConflicting(documentId, scope, branch, minTimestamp, {\n\t\t\tcursor,\n\t\t\tlimit\n\t\t}, signal));\n\t}\n\tasync getRevisions(documentId, branch, signal) {\n\t\tthrowIfAborted(signal);\n\t\tconst scopeRevisions = await this.queryExecutor.selectFrom(\"Operation as o1\").select([\n\t\t\t\"o1.scope\",\n\t\t\t\"o1.index\",\n\t\t\t\"o1.timestampUtcMs\"\n\t\t]).where(\"o1.documentId\", \"=\", documentId).where(\"o1.branch\", \"=\", branch).where((eb) => eb(\"o1.index\", \"=\", eb.selectFrom(\"Operation as o2\").select((eb2) => eb2.fn.max(\"o2.index\").as(\"maxIndex\")).where(\"o2.documentId\", \"=\", eb.ref(\"o1.documentId\")).where(\"o2.branch\", \"=\", eb.ref(\"o1.branch\")).where(\"o2.scope\", \"=\", eb.ref(\"o1.scope\")))).execute();\n\t\tconst latest = await this.queryExecutor.selectFrom(\"Operation\").select((eb) => eb.fn.max(\"timestampUtcMs\").as(\"latestTimestamp\")).where(\"documentId\", \"=\", documentId).where(\"branch\", \"=\", branch).executeTakeFirst();\n\t\tconst revision = {};\n\t\tfor (const row of scopeRevisions) revision[row.scope] = row.index + 1;\n\t\treturn {\n\t\t\trevision,\n\t\t\tlatestTimestamp: latest?.latestTimestamp ? new Date(latest.latestTimestamp).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString()\n\t\t};\n\t}\n\tasync getStreamLatestTimestamp(documentId, scope, branch, signal) {\n\t\tconst latest = await this.queryExecutor.selectFrom(\"Operation\").select((eb) => eb.fn.max(\"timestampUtcMs\").as(\"latestTimestamp\")).where(\"documentId\", \"=\", documentId).where(\"scope\", \"=\", scope).where(\"branch\", \"=\", branch).executeTakeFirst();\n\t\treturn latest?.latestTimestamp ? new Date(latest.latestTimestamp).toISOString() : void 0;\n\t}\n\trowToOperation(row) {\n\t\treturn {\n\t\t\tindex: row.index,\n\t\t\ttimestampUtcMs: row.timestampUtcMs.toISOString(),\n\t\t\thash: row.hash,\n\t\t\tskip: row.skip,\n\t\t\terror: row.error || void 0,\n\t\t\tdeniedReason: row.deniedReason || void 0,\n\t\t\tid: row.opId,\n\t\t\taction: row.action\n\t\t};\n\t}\n\trowToOperationWithContext(row) {\n\t\treturn {\n\t\t\toperation: this.rowToOperation(row),\n\t\t\tcontext: {\n\t\t\t\tdocumentId: row.documentId,\n\t\t\t\tdocumentType: row.documentType,\n\t\t\t\tscope: row.scope,\n\t\t\t\tbranch: row.branch,\n\t\t\t\tordinal: row.id\n\t\t\t}\n\t\t};\n\t}\n};\n//#endregion\n//#region src/storage/pool-instrumentation.ts\n/**\n* Wraps an existing pg.Pool with acquire-wait timing and an event\n* subscription surface. The pool is mutated in place: pool.connect()\n* is replaced with a timing wrapper so all callers (Kysely included)\n* pick up the instrumentation transparently.\n*/\nfunction instrumentPgPool(pool, name) {\n\tconst listeners = /* @__PURE__ */ new Set();\n\tconst originalConnect = pool.connect.bind(pool);\n\tconst wrappedConnect = async () => {\n\t\tconst start = performance.now();\n\t\tconst client = await originalConnect();\n\t\tconst durationMs = performance.now() - start;\n\t\tfor (const listener of listeners) try {\n\t\t\tlistener(durationMs);\n\t\t} catch {}\n\t\treturn client;\n\t};\n\tpool.connect = wrappedConnect;\n\treturn {\n\t\tname,\n\t\tgetStats() {\n\t\t\treturn {\n\t\t\t\tsize: pool.totalCount,\n\t\t\t\tidle: pool.idleCount,\n\t\t\t\twaiting: pool.waitingCount\n\t\t\t};\n\t\t},\n\t\tonAcquire(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t};\n\t\t}\n\t};\n}\nfunction createForwardingPoolInstrumentation(name) {\n\tconst listeners = /* @__PURE__ */ new Set();\n\tlet stats = {\n\t\tsize: 0,\n\t\tidle: 0,\n\t\twaiting: 0\n\t};\n\treturn {\n\t\tname,\n\t\tgetStats() {\n\t\t\treturn stats;\n\t\t},\n\t\tonAcquire(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(listener);\n\t\t\t};\n\t\t},\n\t\tpushSamples(durations) {\n\t\t\tfor (const durationMs of durations) for (const listener of listeners) try {\n\t\t\t\tlistener(durationMs);\n\t\t\t} catch {}\n\t\t},\n\t\tupdateStats(next) {\n\t\t\tstats = next;\n\t\t}\n\t};\n}\n//#endregion\n//#region src/storage/migrations/001_create_operation_table.ts\nvar _001_create_operation_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$18 });\nasync function up$18(db) {\n\tawait db.schema.createTable(\"Operation\").addColumn(\"id\", \"serial\", (col) => col.primaryKey()).addColumn(\"jobId\", \"text\", (col) => col.notNull()).addColumn(\"opId\", \"text\", (col) => col.notNull()).addColumn(\"prevOpId\", \"text\", (col) => col.notNull()).addColumn(\"writeTimestampUtcMs\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"timestampUtcMs\", \"timestamptz\", (col) => col.notNull()).addColumn(\"index\", \"integer\", (col) => col.notNull()).addColumn(\"action\", \"jsonb\", (col) => col.notNull()).addColumn(\"skip\", \"integer\", (col) => col.notNull()).addColumn(\"error\", \"text\").addColumn(\"hash\", \"text\", (col) => col.notNull()).addUniqueConstraint(\"unique_revision\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"index\"\n\t]).addUniqueConstraint(\"unique_operation_instance\", [\n\t\t\"opId\",\n\t\t\"index\",\n\t\t\"skip\"\n\t]).execute();\n\tawait db.schema.createIndex(\"streamOperations\").on(\"Operation\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"id\"\n\t]).execute();\n\tawait db.schema.createIndex(\"branchlessStreamOperations\").on(\"Operation\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"id\"\n\t]).execute();\n}\n//#endregion\n//#region src/storage/migrations/002_create_keyframe_table.ts\nvar _002_create_keyframe_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$17 });\nasync function up$17(db) {\n\tawait db.schema.createTable(\"Keyframe\").addColumn(\"id\", \"serial\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"revision\", \"integer\", (col) => col.notNull()).addColumn(\"document\", \"jsonb\", (col) => col.notNull()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_keyframe\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"revision\"\n\t]).execute();\n\tawait db.schema.createIndex(\"keyframe_lookup\").on(\"Keyframe\").columns([\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\",\n\t\t\"revision\"\n\t]).execute();\n}\n//#endregion\n//#region src/storage/migrations/003_create_document_table.ts\nvar _003_create_document_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$16 });\nasync function up$16(db) {\n\tawait db.schema.createTable(\"Document\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/004_create_document_relationship_table.ts\nvar _004_create_document_relationship_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$15 });\nasync function up$15(db) {\n\tawait db.schema.createTable(\"DocumentRelationship\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"sourceId\", \"text\", (col) => col.notNull().references(\"Document.id\").onDelete(\"cascade\")).addColumn(\"targetId\", \"text\", (col) => col.notNull().references(\"Document.id\").onDelete(\"cascade\")).addColumn(\"relationshipType\", \"text\", (col) => col.notNull()).addColumn(\"metadata\", \"jsonb\").addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_source_target_type\", [\n\t\t\"sourceId\",\n\t\t\"targetId\",\n\t\t\"relationshipType\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_relationship_source\").on(\"DocumentRelationship\").column(\"sourceId\").execute();\n\tawait db.schema.createIndex(\"idx_relationship_target\").on(\"DocumentRelationship\").column(\"targetId\").execute();\n\tawait db.schema.createIndex(\"idx_relationship_type\").on(\"DocumentRelationship\").column(\"relationshipType\").execute();\n}\n//#endregion\n//#region src/storage/migrations/005_create_indexer_state_table.ts\nvar _005_create_indexer_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$14 });\nasync function up$14(db) {\n\tawait db.schema.createTable(\"IndexerState\").addColumn(\"id\", \"integer\", (col) => col.primaryKey().generatedAlwaysAsIdentity()).addColumn(\"lastOperationId\", \"integer\", (col) => col.notNull()).addColumn(\"lastOperationTimestamp\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/006_create_document_snapshot_table.ts\nvar _006_create_document_snapshot_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$13 });\nasync function up$13(db) {\n\tawait db.schema.createTable(\"DocumentSnapshot\").addColumn(\"id\", \"text\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"slug\", \"text\").addColumn(\"name\", \"text\").addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"content\", \"jsonb\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"lastOperationIndex\", \"integer\", (col) => col.notNull()).addColumn(\"lastOperationHash\", \"text\", (col) => col.notNull()).addColumn(\"lastUpdatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"snapshotVersion\", \"integer\", (col) => col.notNull().defaultTo(1)).addColumn(\"identifiers\", \"jsonb\").addColumn(\"metadata\", \"jsonb\").addColumn(\"isDeleted\", \"boolean\", (col) => col.notNull().defaultTo(false)).addColumn(\"deletedAt\", \"timestamptz\").addUniqueConstraint(\"unique_doc_scope_branch\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_slug_scope_branch\").on(\"DocumentSnapshot\").columns([\n\t\t\"slug\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_doctype_scope_branch\").on(\"DocumentSnapshot\").columns([\n\t\t\"documentType\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_last_updated\").on(\"DocumentSnapshot\").column(\"lastUpdatedAt\").execute();\n\tawait db.schema.createIndex(\"idx_is_deleted\").on(\"DocumentSnapshot\").column(\"isDeleted\").execute();\n}\n//#endregion\n//#region src/storage/migrations/007_create_slug_mapping_table.ts\nvar _007_create_slug_mapping_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$12 });\nasync function up$12(db) {\n\tawait db.schema.createTable(\"SlugMapping\").addColumn(\"slug\", \"text\", (col) => col.primaryKey()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addUniqueConstraint(\"unique_docid_scope_branch\", [\n\t\t\"documentId\",\n\t\t\"scope\",\n\t\t\"branch\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_slug_documentid\").on(\"SlugMapping\").column(\"documentId\").execute();\n}\n//#endregion\n//#region src/storage/migrations/008_create_view_state_table.ts\nvar _008_create_view_state_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$11 });\nasync function up$11(db) {\n\tawait db.schema.createTable(\"ViewState\").addColumn(\"readModelId\", \"text\", (col) => col.primaryKey()).addColumn(\"lastOrdinal\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"lastOperationTimestamp\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/009_create_operation_index_tables.ts\nvar _009_create_operation_index_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$10 });\nasync function up$10(db) {\n\tawait db.schema.createTable(\"document_collections\").addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"collectionId\", \"text\", (col) => col.notNull()).addColumn(\"joinedOrdinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"leftOrdinal\", \"bigint\").addPrimaryKeyConstraint(\"document_collections_pkey\", [\"documentId\", \"collectionId\"]).execute();\n\tawait db.schema.createIndex(\"idx_document_collections_collectionId\").on(\"document_collections\").column(\"collectionId\").execute();\n\tawait db.schema.createIndex(\"idx_doc_collections_collection_range\").on(\"document_collections\").columns([\"collectionId\", \"joinedOrdinal\"]).execute();\n\tawait db.schema.createTable(\"operation_index_operations\").addColumn(\"ordinal\", \"serial\", (col) => col.primaryKey()).addColumn(\"opId\", \"text\", (col) => col.notNull()).addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"documentType\", \"text\", (col) => col.notNull()).addColumn(\"scope\", \"text\", (col) => col.notNull()).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"timestampUtcMs\", \"text\", (col) => col.notNull()).addColumn(\"writeTimestampUtcMs\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"index\", \"integer\", (col) => col.notNull()).addColumn(\"skip\", \"integer\", (col) => col.notNull()).addColumn(\"hash\", \"text\", (col) => col.notNull()).addColumn(\"action\", \"jsonb\", (col) => col.notNull()).execute();\n\tawait db.schema.createIndex(\"idx_operation_index_operations_document\").on(\"operation_index_operations\").columns([\n\t\t\"documentId\",\n\t\t\"branch\",\n\t\t\"scope\"\n\t]).execute();\n\tawait db.schema.createIndex(\"idx_operation_index_operations_ordinal\").on(\"operation_index_operations\").column(\"ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/010_create_sync_tables.ts\nvar _010_create_sync_tables_exports = /* @__PURE__ */ __exportAll({ up: () => up$9 });\nasync function up$9(db) {\n\tawait db.schema.createTable(\"sync_remotes\").addColumn(\"name\", \"text\", (col) => col.primaryKey()).addColumn(\"collection_id\", \"text\", (col) => col.notNull()).addColumn(\"channel_type\", \"text\", (col) => col.notNull()).addColumn(\"channel_id\", \"text\", (col) => col.notNull().defaultTo(\"\")).addColumn(\"remote_name\", \"text\", (col) => col.notNull().defaultTo(\"\")).addColumn(\"channel_parameters\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'{}'::jsonb`)).addColumn(\"filter_document_ids\", \"jsonb\").addColumn(\"filter_scopes\", \"jsonb\").addColumn(\"filter_branch\", \"text\", (col) => col.notNull().defaultTo(\"main\")).addColumn(\"push_state\", \"text\", (col) => col.notNull().defaultTo(\"idle\")).addColumn(\"push_last_success_utc_ms\", \"text\").addColumn(\"push_last_failure_utc_ms\", \"text\").addColumn(\"push_failure_count\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"pull_state\", \"text\", (col) => col.notNull().defaultTo(\"idle\")).addColumn(\"pull_last_success_utc_ms\", \"text\").addColumn(\"pull_last_failure_utc_ms\", \"text\").addColumn(\"pull_failure_count\", \"integer\", (col) => col.notNull().defaultTo(0)).addColumn(\"created_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_remotes_collection\").on(\"sync_remotes\").column(\"collection_id\").execute();\n\tawait db.schema.createTable(\"sync_cursors\").addColumn(\"remote_name\", \"text\", (col) => col.primaryKey().references(\"sync_remotes.name\").onDelete(\"cascade\")).addColumn(\"cursor_ordinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"last_synced_at_utc_ms\", \"text\").addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_cursors_ordinal\").on(\"sync_cursors\").column(\"cursor_ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/011_add_cursor_type_column.ts\nvar _011_add_cursor_type_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$8 });\nasync function up$8(db) {\n\tawait db.deleteFrom(\"sync_cursors\").where(\"remote_name\", \"like\", \"outbox::%\").execute();\n\tawait db.deleteFrom(\"sync_remotes\").where(\"name\", \"like\", \"outbox::%\").execute();\n\tawait db.schema.dropTable(\"sync_cursors\").execute();\n\tawait db.schema.createTable(\"sync_cursors\").addColumn(\"remote_name\", \"text\", (col) => col.notNull()).addColumn(\"cursor_type\", \"text\", (col) => col.notNull().defaultTo(\"inbox\")).addColumn(\"cursor_ordinal\", \"bigint\", (col) => col.notNull().defaultTo(0)).addColumn(\"last_synced_at_utc_ms\", \"text\").addColumn(\"updated_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addPrimaryKeyConstraint(\"sync_cursors_pk\", [\"remote_name\", \"cursor_type\"]).execute();\n\tawait db.schema.createIndex(\"idx_sync_cursors_ordinal\").on(\"sync_cursors\").column(\"cursor_ordinal\").execute();\n}\n//#endregion\n//#region src/storage/migrations/012_add_source_remote_column.ts\nvar _012_add_source_remote_column_exports = /* @__PURE__ */ __exportAll({ up: () => up$7 });\nasync function up$7(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").addColumn(\"sourceRemote\", \"text\", (col) => col.notNull().defaultTo(\"\")).execute();\n}\n//#endregion\n//#region src/storage/migrations/013_create_sync_dead_letters_table.ts\nvar _013_create_sync_dead_letters_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$6 });\nasync function up$6(db) {\n\tawait db.schema.createTable(\"sync_dead_letters\").addColumn(\"ordinal\", \"serial\", (col) => col.primaryKey()).addColumn(\"id\", \"text\", (col) => col.unique().notNull()).addColumn(\"job_id\", \"text\", (col) => col.notNull()).addColumn(\"job_dependencies\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"remote_name\", \"text\", (col) => col.notNull().references(\"sync_remotes.name\").onDelete(\"cascade\")).addColumn(\"document_id\", \"text\", (col) => col.notNull()).addColumn(\"scopes\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"branch\", \"text\", (col) => col.notNull()).addColumn(\"operations\", \"jsonb\", (col) => col.notNull().defaultTo(sql`'[]'::jsonb`)).addColumn(\"error_source\", \"text\", (col) => col.notNull()).addColumn(\"error_message\", \"text\", (col) => col.notNull()).addColumn(\"created_at\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n\tawait db.schema.createIndex(\"idx_sync_dead_letters_remote\").on(\"sync_dead_letters\").column(\"remote_name\").execute();\n}\n//#endregion\n//#region src/storage/migrations/014_create_processor_cursor_table.ts\nvar _014_create_processor_cursor_table_exports = /* @__PURE__ */ __exportAll({ up: () => up$5 });\nasync function up$5(db) {\n\tawait db.schema.createTable(\"ProcessorCursor\").addColumn(\"processorId\", \"text\", (col) => col.primaryKey()).addColumn(\"factoryId\", \"text\", (col) => col.notNull()).addColumn(\"driveId\", \"text\", (col) => col.notNull()).addColumn(\"processorIndex\", \"integer\", (col) => col.notNull()).addColumn(\"lastOrdinal\", \"integer\", (col) => col.notNull().defaultTo(sql`0`)).addColumn(\"status\", \"text\", (col) => col.notNull().defaultTo(sql`'active'`)).addColumn(\"lastError\", \"text\").addColumn(\"lastErrorTimestamp\", \"timestamptz\").addColumn(\"createdAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).addColumn(\"updatedAt\", \"timestamptz\", (col) => col.notNull().defaultTo(sql`NOW()`)).execute();\n}\n//#endregion\n//#region src/storage/migrations/015_add_operation_denied_reason.ts\nvar _015_add_operation_denied_reason_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$4,\n\tup: () => up$4\n});\n/**\n* Records why authorization refused an operation. Separate from `error` so a\n* denial is distinguishable from a reducer failure without matching on a\n* message. Null for every operation written before decisions were enforced.\n*/\nasync function up$4(db) {\n\tawait db.schema.alterTable(\"Operation\").addColumn(\"deniedReason\", \"text\").execute();\n\tawait db.schema.alterTable(\"operation_index_operations\").addColumn(\"deniedReason\", \"text\").execute();\n}\nasync function down$4(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").dropColumn(\"deniedReason\").execute();\n\tawait db.schema.alterTable(\"Operation\").dropColumn(\"deniedReason\").execute();\n}\n//#endregion\n//#region src/storage/migrations/016_add_dead_letter_error_type.ts\nvar _016_add_dead_letter_error_type_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$3,\n\tup: () => up$3\n});\n/**\n* The classification a dead letter falls into, stored because it decides whether\n* the document stays quarantined and the in-memory error is gone after a restart.\n* Defaulted rather than nullable, so a pre-existing row rehydrates.\n*/\nasync function up$3(db) {\n\tawait db.schema.alterTable(\"sync_dead_letters\").addColumn(\"error_type\", \"text\", (col) => col.notNull().defaultTo(\"UNCLASSIFIED\")).execute();\n}\nasync function down$3(db) {\n\tawait db.schema.alterTable(\"sync_dead_letters\").dropColumn(\"error_type\").execute();\n}\n//#endregion\n//#region src/storage/migrations/017_create_group_references.ts\nvar _017_create_group_references_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$2,\n\tup: () => up$2\n});\n/**\n* One row per (document, group) reference ever discovered from an auth\n* operation's input. Rows are never updated or deleted: auth evaluation is\n* positional, so a grant that named a group at any position keeps that\n* group's stream in the document's read-set even after a later operation\n* removes the reference. Read by documentId for the groups a document\n* requires (sync), and by groupId for the documents a group change affects\n* (re-evaluation).\n*/\nasync function up$2(db) {\n\tawait db.schema.createTable(\"group_references\").addColumn(\"documentId\", \"text\", (col) => col.notNull()).addColumn(\"groupId\", \"text\", (col) => col.notNull()).addPrimaryKeyConstraint(\"group_references_pkey\", [\"documentId\", \"groupId\"]).execute();\n\tawait db.schema.createIndex(\"idx_group_references_groupId\").on(\"group_references\").column(\"groupId\").execute();\n}\nasync function down$2(db) {\n\tawait db.schema.dropTable(\"group_references\").execute();\n}\n//#endregion\n//#region src/storage/migrations/018_add_sync_remote_bound_address.ts\nvar _018_add_sync_remote_bound_address_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down$1,\n\tup: () => up$1\n});\n/**\n* The address a sync channel is bound to, so a channel created by one subject\n* cannot be polled by another.\n*\n* Nullable rather than defaulted: null is a channel nobody has claimed, which is\n* what every pre-existing row is and what an anonymously created channel stays\n* until its first authenticated poll adopts it. A default would claim them all\n* for one address.\n*/\nasync function up$1(db) {\n\tawait db.schema.alterTable(\"sync_remotes\").addColumn(\"bound_address\", \"text\").execute();\n}\nasync function down$1(db) {\n\tawait db.schema.alterTable(\"sync_remotes\").dropColumn(\"bound_address\").execute();\n}\n//#endregion\n//#region src/storage/migrations/019_require_action_id.ts\nvar _019_require_action_id_exports = /* @__PURE__ */ __exportAll({\n\tdown: () => down,\n\tup: () => up\n});\n/**\n* Makes an operation whose action carries no id physically unstorable.\n*\n* The id is not decoration: `deriveOperationId` hashes it into the operation id\n* and replay dedupes incoming operations by it, so an action without one\n* collapses every id-less operation on a document/scope/branch onto a single\n* derived operation id. The API rejects such an action now, and this is the\n* last line of defense behind it.\n*\n* Both tables are constrained because sync reads operations from the index\n* rather than the operation table, so poison reaching only the index would\n* still be served to a replica.\n*\n* Pre-existing rows are backfilled rather than left behind a NOT VALID\n* constraint: a row the index and the operation table disagree about is worse\n* than a missing id, because dedup keys off the value each side serves. The\n* backfill therefore mints one id per operation and writes that same id to both\n* tables, joined on the identity they share. Rewriting the action is safe: the\n* operation hash is taken over the resulting state, not over the action, and a\n* signature is verified from the params carried in the signature tuple, which\n* do not include the action id.\n*\n* The empty string is rejected alongside null. It derives the same colliding\n* operation id as an absent id, so admitting it would leave the hole open.\n*/\nasync function up(db) {\n\tawait db.updateTable(\"Operation\").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();\n\tawait db.updateTable(\"operation_index_operations as oio\").from(\"Operation as op\").set({ action: sql`jsonb_set(oio.action, '{id}', to_jsonb(op.action->>'id'))` }).whereRef(\"oio.opId\", \"=\", \"op.opId\").whereRef(\"oio.index\", \"=\", \"op.index\").whereRef(\"oio.skip\", \"=\", \"op.skip\").where(sql`jsonb_typeof(oio.action) = 'object' and coalesce(oio.action->>'id', '') = ''`).where(sql`coalesce(op.action->>'id', '') <> ''`).execute();\n\tawait db.updateTable(\"operation_index_operations\").set({ action: sql`jsonb_set(action, '{id}', to_jsonb(gen_random_uuid()::text))` }).where(sql`jsonb_typeof(action) = 'object' and coalesce(action->>'id', '') = ''`).execute();\n\tawait db.schema.alterTable(\"Operation\").addCheckConstraint(\"action_must_have_id\", sql`action->>'id' is not null and action->>'id' <> ''`).execute();\n\tawait db.schema.alterTable(\"operation_index_operations\").addCheckConstraint(\"action_must_have_id\", sql`action->>'id' is not null and action->>'id' <> ''`).execute();\n}\n/**\n* Only the constraints are dropped. The backfilled ids stay: they are the ids\n* their operations are now known by, and reverting them would reintroduce the\n* collision the migration removed.\n*/\nasync function down(db) {\n\tawait db.schema.alterTable(\"operation_index_operations\").dropConstraint(\"action_must_have_id\").execute();\n\tawait db.schema.alterTable(\"Operation\").dropConstraint(\"action_must_have_id\").execute();\n}\n//#endregion\n//#region src/storage/migrations/migrator.ts\nconst REACTOR_SCHEMA = \"reactor\";\nconst migrations = {\n\t\"001_create_operation_table\": _001_create_operation_table_exports,\n\t\"002_create_keyframe_table\": _002_create_keyframe_table_exports,\n\t\"003_create_document_table\": _003_create_document_table_exports,\n\t\"004_create_document_relationship_table\": _004_create_document_relationship_table_exports,\n\t\"005_create_indexer_state_table\": _005_create_indexer_state_table_exports,\n\t\"006_create_document_snapshot_table\": _006_create_document_snapshot_table_exports,\n\t\"007_create_slug_mapping_table\": _007_create_slug_mapping_table_exports,\n\t\"008_create_view_state_table\": _008_create_view_state_table_exports,\n\t\"009_create_operation_index_tables\": _009_create_operation_index_tables_exports,\n\t\"010_create_sync_tables\": _010_create_sync_tables_exports,\n\t\"011_add_cursor_type_column\": _011_add_cursor_type_column_exports,\n\t\"012_add_source_remote_column\": _012_add_source_remote_column_exports,\n\t\"013_create_sync_dead_letters_table\": _013_create_sync_dead_letters_table_exports,\n\t\"014_create_processor_cursor_table\": _014_create_processor_cursor_table_exports,\n\t\"015_add_operation_denied_reason\": _015_add_operation_denied_reason_exports,\n\t\"016_add_dead_letter_error_type\": _016_add_dead_letter_error_type_exports,\n\t\"017_create_group_references\": _017_create_group_references_exports,\n\t\"018_add_sync_remote_bound_address\": _018_add_sync_remote_bound_address_exports,\n\t\"019_require_action_id\": _019_require_action_id_exports\n};\nvar ProgrammaticMigrationProvider = class {\n\tgetMigrations() {\n\t\treturn Promise.resolve(migrations);\n\t}\n};\n/**\n* Applies every pending migration, or every one up to and including `upTo`.\n*\n* The bound exists so a test can reach the schema a data migration is written\n* against, populate it, and then migrate across the migration under test.\n*/\nasync function runMigrations(db, schema = REACTOR_SCHEMA, upTo) {\n\ttry {\n\t\tawait sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schema)}`.execute(db);\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmigrationsExecuted: [],\n\t\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Failed to create schema\")\n\t\t};\n\t}\n\tconst migrator = new Migrator({\n\t\tdb: db.withSchema(schema),\n\t\tprovider: new ProgrammaticMigrationProvider(),\n\t\tmigrationTableSchema: schema\n\t});\n\tlet error;\n\tlet results;\n\ttry {\n\t\tconst result = upTo ? await migrator.migrateTo(upTo) : await migrator.migrateToLatest();\n\t\terror = result.error;\n\t\tresults = result.results;\n\t} catch (e) {\n\t\terror = e;\n\t\tresults = [];\n\t}\n\tconst migrationsExecuted = results?.map((result) => result.migrationName) ?? [];\n\tif (error) return {\n\t\tsuccess: false,\n\t\tmigrationsExecuted,\n\t\terror: error instanceof Error ? error : /* @__PURE__ */ new Error(\"Unknown migration error\")\n\t};\n\treturn {\n\t\tsuccess: true,\n\t\tmigrationsExecuted\n\t};\n}\nasync function getMigrationStatus(db, schema = REACTOR_SCHEMA) {\n\treturn await new Migrator({\n\t\tdb: db.withSchema(schema),\n\t\tprovider: new ProgrammaticMigrationProvider(),\n\t\tmigrationTableSchema: schema\n\t}).getMigrations();\n}\n//#endregion\n//#region src/core/drive-container-types.ts\nconst DEFAULT_DRIVE_CONTAINER_TYPES = new Set([\"powerhouse/document-drive\", \"powerhouse/reactor-drive\"]);\n//#endregion\nexport { parsePagingOptions as $, targetDocumentId as A, DuplicateOperationError as B, InvalidModuleError as C, createEmptyConsistencyToken as D, createConsistencyToken as E, buildDecisionModel as F, AuthorizationDeniedError as G, RevisionMismatchError as H, APPEND_CONDITION_FAILED_PREFIX as I, ExcessiveReshuffleError as J, DocumentDeletedError as K, AppendConditionFailedError as L, selectDecisionModel as M, documentDecisionModel as N, submittedActionIds as O, authDecisionModel as P, matchesScope as Q, DocumentAlreadyExistsError as R, DuplicateModuleError as S, GATED_DOCUMENT_ACTIONS as T, AuthEnforcementDisabledError as U, OptimisticLockError as V, AuthTimestampNotMonotonicError as W, RelationshipNotFoundError as X, InvalidOperationTimestampError as Y, UpgradePreconditionFailedError as Z, DocumentMetaCache as _, createForwardingPoolInstrumentation as a, JobExecutorEventTypes as b, KyselyKeyframeStore as c, DriveCollectionId as d, throwIfAborted as et, KyselyExecutionScope as f, KyselyOperationIndex as g, KyselyWriteCache as h, runMigrations as i, decideAtHead as j, summarizeSubmittedActions as k, DocumentModelRegistry as l, EventBus as m, REACTOR_SCHEMA as n, instrumentPgPool as o, resolveFeatureFlags as p, DocumentNotFoundError as q, getMigrationStatus as r, KyselyOperationStore as s, DEFAULT_DRIVE_CONTAINER_TYPES as t, __exportAll as tt, SimpleJobExecutor as u, CollectionMembershipCache as v, ModuleNotFoundError as w, DuplicateManifestError as x, DEFAULT_DEFERRED_JOB_TTL_MS as y, DocumentExistence as z };\n\n//# sourceMappingURL=drive-container-types-CE7dxz0_.js.map","import type { Operation } from \"@powerhousedao/shared/document-model\";\nimport type { AtomicTxn } from \"@powerhousedao/reactor\";\nimport type { StoredOperation } from \"./types.js\";\n\nexport class HypercoreAtomicTransaction implements AtomicTxn {\n private operations: StoredOperation[] = [];\n\n constructor(\n private documentId: string,\n private documentType: string,\n private scope: string,\n private branch: string,\n ) {}\n\n addOperations(...operations: Operation[]): void {\n for (const op of operations) {\n this.operations.push({\n ...op,\n documentId: this.documentId,\n documentType: this.documentType,\n scope: this.scope,\n branch: this.branch,\n });\n }\n }\n\n getOperations(): StoredOperation[] {\n return this.operations;\n }\n}\n","import type { StoredOperation } from \"./types.js\";\n\nconst PAD_WIDTH = 10;\n\nexport const RANGE_UPPER_BOUND = \"9\".repeat(PAD_WIDTH) + \"~\";\n\nexport function pad(n: number): string {\n return n.toString().padStart(PAD_WIDTH, \"0\");\n}\n\nexport function operationKey(\n documentId: string,\n scope: string,\n branch: string,\n index: number,\n): string {\n return `op/${documentId}/${scope}/${branch}/${pad(index)}`;\n}\n\nexport function operationPrefix(\n documentId: string,\n scope: string,\n branch: string,\n): string {\n return `op/${documentId}/${scope}/${branch}/`;\n}\n\nexport function ordinalKey(ordinal: number): string {\n return `ord/${pad(ordinal)}`;\n}\n\nexport function ordinalPrefix(): string {\n return \"ord/\";\n}\n\nexport function duplicateKey(\n opId: string,\n index: number,\n skip: number,\n): string {\n return `dup/${opId}/${pad(index)}/${pad(skip)}`;\n}\n\nexport function headKey(\n documentId: string,\n scope: string,\n branch: string,\n): string {\n return `_meta/head/${documentId}/${scope}/${branch}`;\n}\n\nexport function headPrefix(documentId: string): string {\n return `_meta/head/${documentId}/`;\n}\n\nexport const ORDINAL_COUNTER_KEY = \"_meta/ordinal\";\n\nexport type ParsedOperationKey = {\n documentId: string;\n scope: string;\n branch: string;\n index: number;\n};\n\nexport function parseOperationKey(key: string): ParsedOperationKey {\n const parts = key.split(\"/\");\n return {\n documentId: parts[1],\n scope: parts[2],\n branch: parts[3],\n index: parseInt(parts[4], 10),\n };\n}\n\nexport type OrdinalEntry = {\n documentId: string;\n documentType: string;\n scope: string;\n branch: string;\n index: number;\n operation: StoredOperation;\n};\n\nexport type HeadEntryValue = {\n index: number;\n latestTimestampUtcMs: string;\n};\n","import type {\n Operation,\n OperationWithContext,\n} from \"@powerhousedao/shared/document-model\";\nimport type {\n AppendCondition,\n AtomicTxn,\n DocumentRevisions,\n IOperationStore,\n OperationFilter,\n PagedResults,\n PagingOptions,\n} from \"@powerhousedao/reactor\";\nimport {\n AppendConditionFailedError,\n DocumentAlreadyExistsError,\n DuplicateOperationError,\n RevisionMismatchError,\n} from \"@powerhousedao/reactor\";\nimport type Hyperbee from \"hyperbee\";\nimport { HypercoreAtomicTransaction } from \"./hypercore-atomic-transaction.js\";\nimport {\n ORDINAL_COUNTER_KEY,\n RANGE_UPPER_BOUND,\n duplicateKey,\n headKey,\n headPrefix,\n operationKey,\n operationPrefix,\n ordinalKey,\n ordinalPrefix,\n pad,\n} from \"./key-encoding.js\";\nimport type { HeadEntryValue, OrdinalEntry } from \"./key-encoding.js\";\nimport type { StoredOperation } from \"./types.js\";\n\nexport class HypercoreOperationStore implements IOperationStore {\n private applyLock: Promise<void> = Promise.resolve();\n\n constructor(private bee: Hyperbee) {}\n\n async apply(\n documentId: string,\n documentType: string,\n scope: string,\n branch: string,\n revision: number,\n fn: (txn: AtomicTxn) => void | Promise<void>,\n signal?: AbortSignal,\n condition?: AppendCondition,\n ): Promise<Operation[]> {\n const prevLock = this.applyLock;\n let releaseLock: () => void;\n this.applyLock = new Promise<void>((resolve) => {\n releaseLock = resolve;\n });\n\n await prevLock;\n\n try {\n // Single writer on applyLock: nothing can append between check and write.\n if (condition) {\n await this.assertConditionHolds(condition, signal);\n }\n\n return await this.executeApply(\n documentId,\n documentType,\n scope,\n branch,\n revision,\n fn,\n signal,\n );\n } finally {\n releaseLock!();\n }\n }\n\n /** Throws if any read-set stream has grown past its recorded revision. */\n private async assertConditionHolds(\n condition: AppendCondition,\n signal?: AbortSignal,\n ): Promise<void> {\n for (const stream of condition.streams) {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const entry = await this.bee.get(\n headKey(stream.documentId, stream.scope, stream.branch),\n );\n const head = entry ? (entry.value as HeadEntryValue).index : -1;\n\n if (head > stream.revision) {\n throw new AppendConditionFailedError(condition);\n }\n }\n }\n\n private async executeApply(\n documentId: string,\n documentType: string,\n scope: string,\n branch: string,\n revision: number,\n fn: (txn: AtomicTxn) => void | Promise<void>,\n signal?: AbortSignal,\n ): Promise<Operation[]> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const hKey = headKey(documentId, scope, branch);\n const headEntry = await this.bee.get(hKey);\n const currentRevision = headEntry\n ? (headEntry.value as HeadEntryValue).index\n : -1;\n\n const atomicTxn = new HypercoreAtomicTransaction(\n documentId,\n documentType,\n scope,\n branch,\n );\n await fn(atomicTxn);\n\n const operations = atomicTxn.getOperations();\n\n if (currentRevision !== revision - 1) {\n if (revision === 0 && this.isCreate(operations)) {\n throw new DocumentAlreadyExistsError(\n documentId,\n scope,\n currentRevision,\n );\n }\n\n throw new RevisionMismatchError(currentRevision + 1, revision);\n }\n\n if (operations.length === 0) {\n return [];\n }\n\n for (const op of operations) {\n const dupKey = duplicateKey(op.id, op.index, op.skip);\n const existing = await this.bee.get(dupKey);\n if (existing) {\n throw new DuplicateOperationError(\n `${op.id} at index ${op.index} with skip ${op.skip}`,\n );\n }\n }\n\n const ordinalEntry = await this.bee.get(ORDINAL_COUNTER_KEY);\n let nextOrdinal: number = ordinalEntry ? (ordinalEntry.value as number) : 0;\n\n const batch = this.bee.batch();\n\n for (const op of operations) {\n const opKey = operationKey(documentId, scope, branch, op.index);\n const serialized = this.serializeOperation(op);\n await batch.put(opKey, serialized);\n\n const ordEntry: OrdinalEntry = {\n documentId,\n documentType,\n scope,\n branch,\n index: op.index,\n operation: serialized,\n };\n await batch.put(ordinalKey(nextOrdinal), ordEntry);\n\n await batch.put(duplicateKey(op.id, op.index, op.skip), \"\");\n\n nextOrdinal++;\n }\n\n const lastOp = operations[operations.length - 1];\n const headValue: HeadEntryValue = {\n index: lastOp.index,\n latestTimestampUtcMs: lastOp.timestampUtcMs,\n };\n await batch.put(hKey, headValue);\n await batch.put(ORDINAL_COUNTER_KEY, nextOrdinal);\n\n await batch.flush();\n\n return operations.map((op) => this.toOperation(op));\n }\n\n private isCreate(operations: StoredOperation[]): boolean {\n return operations.some((op) => op.action.type === \"CREATE_DOCUMENT\");\n }\n\n async getSince(\n documentId: string,\n scope: string,\n branch: string,\n revision: number,\n filter?: OperationFilter,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Operation>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = operationPrefix(documentId, scope, branch);\n const startIndex = revision + 1;\n const cursorIndex =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10) + 1\n : startIndex;\n const effectiveStart = Math.max(startIndex, cursorIndex);\n\n const gt = prefix + pad(effectiveStart - 1);\n const lt = prefix + RANGE_UPPER_BOUND;\n const limit = paging?.limit ? paging.limit + 1 : undefined;\n\n const items: Operation[] = [];\n const stream = this.bee.createReadStream({ gt, lt, limit });\n\n for await (const entry of stream) {\n const stored = entry.value as StoredOperation;\n\n if (filter) {\n if (\n filter.actionTypes &&\n filter.actionTypes.length > 0 &&\n !filter.actionTypes.includes((stored.action as { type: string }).type)\n ) {\n continue;\n }\n if (\n filter.timestampFrom &&\n stored.timestampUtcMs < filter.timestampFrom\n ) {\n continue;\n }\n if (filter.timestampTo && stored.timestampUtcMs > filter.timestampTo) {\n continue;\n }\n if (\n filter.sinceRevision !== undefined &&\n stored.index < filter.sinceRevision\n ) {\n continue;\n }\n }\n\n items.push(this.toOperation(stored));\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].index.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getSince(\n documentId,\n scope,\n branch,\n revision,\n filter,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getSinceId(\n id: number,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<OperationWithContext>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const cursorValue =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10)\n : id;\n const effectiveId = Math.max(id, cursorValue);\n\n const gt = ordinalPrefix() + pad(effectiveId);\n const lt = ordinalPrefix() + RANGE_UPPER_BOUND;\n const limit = paging?.limit ? paging.limit + 1 : undefined;\n\n const items: OperationWithContext[] = [];\n const stream = this.bee.createReadStream({ gt, lt, limit });\n\n for await (const entry of stream) {\n const ordEntry = entry.value as OrdinalEntry;\n const ordinal = parseInt(entry.key.split(\"/\")[1], 10);\n\n items.push({\n operation: this.toOperation(ordEntry.operation),\n context: {\n documentId: ordEntry.documentId,\n documentType: ordEntry.documentType,\n scope: ordEntry.scope,\n branch: ordEntry.branch,\n ordinal,\n },\n });\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].context.ordinal.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getSinceId(\n id,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getConflicting(\n documentId: string,\n scope: string,\n branch: string,\n minTimestamp: string,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Operation>> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = operationPrefix(documentId, scope, branch);\n const cursorIndex =\n paging?.cursor && parseInt(paging.cursor, 10) > 0\n ? parseInt(paging.cursor, 10)\n : -1;\n\n const gt = cursorIndex >= 0 ? prefix + pad(cursorIndex) : prefix;\n const lt = prefix + RANGE_UPPER_BOUND;\n\n const stream = this.bee.createReadStream({\n gt: cursorIndex >= 0 ? gt : undefined,\n gte: cursorIndex >= 0 ? undefined : gt,\n lt,\n });\n\n const items: Operation[] = [];\n\n for await (const entry of stream) {\n const stored = entry.value as StoredOperation;\n if (stored.timestampUtcMs >= minTimestamp) {\n items.push(this.toOperation(stored));\n }\n }\n\n let hasMore = false;\n let resultItems = items;\n\n if (paging?.limit && items.length > paging.limit) {\n hasMore = true;\n resultItems = items.slice(0, paging.limit);\n }\n\n const nextCursor =\n hasMore && resultItems.length > 0\n ? resultItems[resultItems.length - 1].index.toString()\n : undefined;\n\n const cursor = paging?.cursor || \"0\";\n const resultLimit = paging?.limit || 100;\n\n return {\n results: resultItems,\n options: { cursor, limit: resultLimit },\n nextCursor,\n next: hasMore\n ? () =>\n this.getConflicting(\n documentId,\n scope,\n branch,\n minTimestamp,\n { cursor: nextCursor!, limit: resultLimit },\n signal,\n )\n : undefined,\n };\n }\n\n async getRevisions(\n documentId: string,\n branch: string,\n signal?: AbortSignal,\n ): Promise<DocumentRevisions> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const prefix = headPrefix(documentId);\n const stream = this.bee.createReadStream({\n gte: prefix,\n lt: prefix + \"~\",\n });\n\n const revision: Record<string, number> = {};\n let latestTimestamp = new Date(0).toISOString();\n\n for await (const entry of stream) {\n const parts = entry.key.split(\"/\");\n const entryScope = parts[3];\n const entryBranch = parts[4];\n\n if (entryBranch !== branch) {\n continue;\n }\n\n const headValue = entry.value as HeadEntryValue;\n revision[entryScope] = headValue.index + 1;\n\n if (headValue.latestTimestampUtcMs > latestTimestamp) {\n latestTimestamp = headValue.latestTimestampUtcMs;\n }\n }\n\n return { revision, latestTimestamp };\n }\n\n /**\n * A real maximum over the rows, not the head record's `latestTimestampUtcMs`:\n * that holds the last-indexed timestamp, which a re-append can leave behind a\n * later one, so it would under-report and admit a backdated auth write.\n */\n async getStreamLatestTimestamp(\n documentId: string,\n scope: string,\n branch: string,\n signal?: AbortSignal,\n ): Promise<string | undefined> {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n const stored = await this.getSince(\n documentId,\n scope,\n branch,\n -1,\n undefined,\n undefined,\n signal,\n );\n\n let latest: string | undefined;\n for (const operation of stored.results) {\n if (latest === undefined || operation.timestampUtcMs > latest) {\n latest = operation.timestampUtcMs;\n }\n }\n\n return latest;\n }\n\n private serializeOperation(op: StoredOperation): StoredOperation {\n return {\n id: op.id,\n index: op.index,\n skip: op.skip,\n timestampUtcMs: op.timestampUtcMs,\n hash: op.hash,\n error: op.error,\n deniedReason: op.deniedReason,\n action: op.action,\n documentId: op.documentId,\n documentType: op.documentType,\n scope: op.scope,\n branch: op.branch,\n };\n }\n\n private toOperation(stored: StoredOperation): Operation {\n return {\n id: stored.id,\n index: stored.index,\n skip: stored.skip,\n timestampUtcMs: stored.timestampUtcMs,\n hash: stored.hash,\n error: stored.error || undefined,\n deniedReason: stored.deniedReason || undefined,\n action: stored.action,\n };\n }\n}\n","import Corestore from \"corestore\";\nimport Hyperbee from \"hyperbee\";\n\nexport class StorageManager {\n private store: Corestore;\n private bee: Hyperbee | undefined;\n\n constructor(storagePath: string) {\n this.store = new Corestore(storagePath);\n }\n\n async open(): Promise<void> {\n await this.store.ready();\n const core = this.store.get({ name: \"operations\" });\n this.bee = new Hyperbee(core, {\n keyEncoding: \"utf-8\",\n valueEncoding: \"json\",\n });\n await this.bee.ready();\n }\n\n async close(): Promise<void> {\n if (this.bee) {\n await this.bee.close();\n }\n await this.store.close();\n }\n\n getBee(): Hyperbee {\n if (!this.bee) {\n throw new Error(\"StorageManager not opened. Call open() first.\");\n }\n return this.bee;\n }\n}\n"],"mappings":";;;;;;AAyRA,IAAI,0BAA0B,cAAc,MAAM;CACjD,YAAY,aAAa;AACxB,QAAM,wBAAwB,cAAc;AAC5C,OAAK,OAAO;;;;;;;AAgBd,IAAI,wBAAwB,cAAc,MAAM;CAC/C,YAAY,UAAU,QAAQ;AAC7B,QAAM,+BAA+B,SAAS,QAAQ,SAAS;AAC/D,OAAK,OAAO;;;;;;;AAOd,IAAI,6BAA6B,cAAc,MAAM;CACpD;CACA,YAAY,YAAY,OAAO,cAAc;AAC5C,QAAM,YAAY,WAAW,wDAAwD,MAAM,0BAA0B,eAAe;AACpI,OAAK,OAAO;AACZ,OAAK,aAAa;;CAEnB,OAAO,QAAQ,OAAO;AACrB,SAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS;;;;AAIhD,MAAM,iCAAiC;;;;;AAKvC,IAAI,6BAA6B,cAAc,MAAM;CACpD,YAAY,WAAW;EACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,MAAM,GAAG,EAAE,WAAW,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,GAAG,EAAE,WAAW,CAAC,KAAK,KAAK;AAC/G,QAAM,GAAG,+BAA+B,8BAA8B,QAAQ,GAAG;AACjF,OAAK,YAAY;AACjB,OAAK,OAAO;;CAEb,OAAO,QAAQ,OAAO;AACrB,SAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS;;;CAG/C,OAAO,iBAAiB,SAAS;AAChC,SAAO,QAAQ,WAAW,+BAA+B;;;;AAyX3D,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAK6B,IAAI,IAAI,CAAC,GAAG,uBAAuB,CAAC,QAAQ,SAAS,SAAS,kBAAkB,CAAC;;;ACptBhH,IAAa,6BAAb,MAA6D;CAC3D,aAAwC,EAAE;CAE1C,YACE,YACA,cACA,OACA,QACA;AAJQ,OAAA,aAAA;AACA,OAAA,eAAA;AACA,OAAA,QAAA;AACA,OAAA,SAAA;;CAGV,cAAc,GAAG,YAA+B;AAC9C,OAAK,MAAM,MAAM,WACf,MAAK,WAAW,KAAK;GACnB,GAAG;GACH,YAAY,KAAK;GACjB,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,QAAQ,KAAK;GACd,CAAC;;CAIN,gBAAmC;AACjC,SAAO,KAAK;;;;;ACzBhB,MAAM,YAAY;AAElB,MAAa,oBAAoB,IAAI,OAAO,UAAU,GAAG;AAEzD,SAAgB,IAAI,GAAmB;AACrC,QAAO,EAAE,UAAU,CAAC,SAAS,WAAW,IAAI;;AAG9C,SAAgB,aACd,YACA,OACA,QACA,OACQ;AACR,QAAO,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,MAAM;;AAG1D,SAAgB,gBACd,YACA,OACA,QACQ;AACR,QAAO,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO;;AAG7C,SAAgB,WAAW,SAAyB;AAClD,QAAO,OAAO,IAAI,QAAQ;;AAG5B,SAAgB,gBAAwB;AACtC,QAAO;;AAGT,SAAgB,aACd,MACA,OACA,MACQ;AACR,QAAO,OAAO,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,KAAK;;AAG/C,SAAgB,QACd,YACA,OACA,QACQ;AACR,QAAO,cAAc,WAAW,GAAG,MAAM,GAAG;;AAG9C,SAAgB,WAAW,YAA4B;AACrD,QAAO,cAAc,WAAW;;AAGlC,MAAa,sBAAsB;AASnC,SAAgB,kBAAkB,KAAiC;CACjE,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAO;EACL,YAAY,MAAM;EAClB,OAAO,MAAM;EACb,QAAQ,MAAM;EACd,OAAO,SAAS,MAAM,IAAI,GAAG;EAC9B;;;;ACnCH,IAAa,0BAAb,MAAgE;CAC9D,YAAmC,QAAQ,SAAS;CAEpD,YAAY,KAAuB;AAAf,OAAA,MAAA;;CAEpB,MAAM,MACJ,YACA,cACA,OACA,QACA,UACA,IACA,QACA,WACsB;EACtB,MAAM,WAAW,KAAK;EACtB,IAAI;AACJ,OAAK,YAAY,IAAI,SAAe,YAAY;AAC9C,iBAAc;IACd;AAEF,QAAM;AAEN,MAAI;AAEF,OAAI,UACF,OAAM,KAAK,qBAAqB,WAAW,OAAO;AAGpD,UAAO,MAAM,KAAK,aAChB,YACA,cACA,OACA,QACA,UACA,IACA,OACD;YACO;AACR,gBAAc;;;;CAKlB,MAAc,qBACZ,WACA,QACe;AACf,OAAK,MAAM,UAAU,UAAU,SAAS;AACtC,OAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;GAGtC,MAAM,QAAQ,MAAM,KAAK,IAAI,IAC3B,QAAQ,OAAO,YAAY,OAAO,OAAO,OAAO,OAAO,CACxD;AAGD,QAFa,QAAS,MAAM,MAAyB,QAAQ,MAElD,OAAO,SAChB,OAAM,IAAI,2BAA2B,UAAU;;;CAKrD,MAAc,aACZ,YACA,cACA,OACA,QACA,UACA,IACA,QACsB;AACtB,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,OAAO,QAAQ,YAAY,OAAO,OAAO;EAC/C,MAAM,YAAY,MAAM,KAAK,IAAI,IAAI,KAAK;EAC1C,MAAM,kBAAkB,YACnB,UAAU,MAAyB,QACpC;EAEJ,MAAM,YAAY,IAAI,2BACpB,YACA,cACA,OACA,OACD;AACD,QAAM,GAAG,UAAU;EAEnB,MAAM,aAAa,UAAU,eAAe;AAE5C,MAAI,oBAAoB,WAAW,GAAG;AACpC,OAAI,aAAa,KAAK,KAAK,SAAS,WAAW,CAC7C,OAAM,IAAI,2BACR,YACA,OACA,gBACD;AAGH,SAAM,IAAI,sBAAsB,kBAAkB,GAAG,SAAS;;AAGhE,MAAI,WAAW,WAAW,EACxB,QAAO,EAAE;AAGX,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,SAAS,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK;AAErD,OADiB,MAAM,KAAK,IAAI,IAAI,OAAO,CAEzC,OAAM,IAAI,wBACR,GAAG,GAAG,GAAG,YAAY,GAAG,MAAM,aAAa,GAAG,OAC/C;;EAIL,MAAM,eAAe,MAAM,KAAK,IAAI,IAAI,oBAAoB;EAC5D,IAAI,cAAsB,eAAgB,aAAa,QAAmB;EAE1E,MAAM,QAAQ,KAAK,IAAI,OAAO;AAE9B,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,QAAQ,aAAa,YAAY,OAAO,QAAQ,GAAG,MAAM;GAC/D,MAAM,aAAa,KAAK,mBAAmB,GAAG;AAC9C,SAAM,MAAM,IAAI,OAAO,WAAW;GAElC,MAAM,WAAyB;IAC7B;IACA;IACA;IACA;IACA,OAAO,GAAG;IACV,WAAW;IACZ;AACD,SAAM,MAAM,IAAI,WAAW,YAAY,EAAE,SAAS;AAElD,SAAM,MAAM,IAAI,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,EAAE,GAAG;AAE3D;;EAGF,MAAM,SAAS,WAAW,WAAW,SAAS;EAC9C,MAAM,YAA4B;GAChC,OAAO,OAAO;GACd,sBAAsB,OAAO;GAC9B;AACD,QAAM,MAAM,IAAI,MAAM,UAAU;AAChC,QAAM,MAAM,IAAI,qBAAqB,YAAY;AAEjD,QAAM,MAAM,OAAO;AAEnB,SAAO,WAAW,KAAK,OAAO,KAAK,YAAY,GAAG,CAAC;;CAGrD,SAAiB,YAAwC;AACvD,SAAO,WAAW,MAAM,OAAO,GAAG,OAAO,SAAS,kBAAkB;;CAGtE,MAAM,SACJ,YACA,OACA,QACA,UACA,QACA,QACA,QACkC;AAClC,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,gBAAgB,YAAY,OAAO,OAAO;EACzD,MAAM,aAAa,WAAW;EAC9B,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC9B;EAGN,MAAM,KAAK,SAAS,IAFG,KAAK,IAAI,YAAY,YAAY,GAEf,EAAE;EAC3C,MAAM,KAAK,SAAS;EACpB,MAAM,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,IAAI,KAAA;EAEjD,MAAM,QAAqB,EAAE;EAC7B,MAAM,SAAS,KAAK,IAAI,iBAAiB;GAAE;GAAI;GAAI;GAAO,CAAC;AAE3D,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,SAAS,MAAM;AAErB,OAAI,QAAQ;AACV,QACE,OAAO,eACP,OAAO,YAAY,SAAS,KAC5B,CAAC,OAAO,YAAY,SAAU,OAAO,OAA4B,KAAK,CAEtE;AAEF,QACE,OAAO,iBACP,OAAO,iBAAiB,OAAO,cAE/B;AAEF,QAAI,OAAO,eAAe,OAAO,iBAAiB,OAAO,YACvD;AAEF,QACE,OAAO,kBAAkB,KAAA,KACzB,OAAO,QAAQ,OAAO,cAEtB;;AAIJ,SAAM,KAAK,KAAK,YAAY,OAAO,CAAC;;EAGtC,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,MAAM,UAAU,GACpD,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,SACH,YACA,OACA,QACA,UACA,QACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,WACJ,IACA,QACA,QAC6C;AAC7C,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAC3B;EACN,MAAM,cAAc,KAAK,IAAI,IAAI,YAAY;EAE7C,MAAM,KAAK,eAAe,GAAG,IAAI,YAAY;EAC7C,MAAM,KAAK,eAAe,GAAG;EAC7B,MAAM,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,IAAI,KAAA;EAEjD,MAAM,QAAgC,EAAE;EACxC,MAAM,SAAS,KAAK,IAAI,iBAAiB;GAAE;GAAI;GAAI;GAAO,CAAC;AAE3D,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,WAAW,MAAM;GACvB,MAAM,UAAU,SAAS,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,GAAG;AAErD,SAAM,KAAK;IACT,WAAW,KAAK,YAAY,SAAS,UAAU;IAC/C,SAAS;KACP,YAAY,SAAS;KACrB,cAAc,SAAS;KACvB,OAAO,SAAS;KAChB,QAAQ,SAAS;KACjB;KACD;IACF,CAAC;;EAGJ,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,QAAQ,QAAQ,UAAU,GAC9D,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,WACH,IACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,eACJ,YACA,OACA,QACA,cACA,QACA,QACkC;AAClC,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,gBAAgB,YAAY,OAAO,OAAO;EACzD,MAAM,cACJ,QAAQ,UAAU,SAAS,OAAO,QAAQ,GAAG,GAAG,IAC5C,SAAS,OAAO,QAAQ,GAAG,GAC3B;EAEN,MAAM,KAAK,eAAe,IAAI,SAAS,IAAI,YAAY,GAAG;EAC1D,MAAM,KAAK,SAAS;EAEpB,MAAM,SAAS,KAAK,IAAI,iBAAiB;GACvC,IAAI,eAAe,IAAI,KAAK,KAAA;GAC5B,KAAK,eAAe,IAAI,KAAA,IAAY;GACpC;GACD,CAAC;EAEF,MAAM,QAAqB,EAAE;AAE7B,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,SAAS,MAAM;AACrB,OAAI,OAAO,kBAAkB,aAC3B,OAAM,KAAK,KAAK,YAAY,OAAO,CAAC;;EAIxC,IAAI,UAAU;EACd,IAAI,cAAc;AAElB,MAAI,QAAQ,SAAS,MAAM,SAAS,OAAO,OAAO;AAChD,aAAU;AACV,iBAAc,MAAM,MAAM,GAAG,OAAO,MAAM;;EAG5C,MAAM,aACJ,WAAW,YAAY,SAAS,IAC5B,YAAY,YAAY,SAAS,GAAG,MAAM,UAAU,GACpD,KAAA;EAEN,MAAM,SAAS,QAAQ,UAAU;EACjC,MAAM,cAAc,QAAQ,SAAS;AAErC,SAAO;GACL,SAAS;GACT,SAAS;IAAE;IAAQ,OAAO;IAAa;GACvC;GACA,MAAM,gBAEA,KAAK,eACH,YACA,OACA,QACA,cACA;IAAE,QAAQ;IAAa,OAAO;IAAa,EAC3C,OACD,GACH,KAAA;GACL;;CAGH,MAAM,aACJ,YACA,QACA,QAC4B;AAC5B,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,WAAW,WAAW;EACrC,MAAM,SAAS,KAAK,IAAI,iBAAiB;GACvC,KAAK;GACL,IAAI,SAAS;GACd,CAAC;EAEF,MAAM,WAAmC,EAAE;EAC3C,IAAI,mCAAkB,IAAI,KAAK,EAAE,EAAC,aAAa;AAE/C,aAAW,MAAM,SAAS,QAAQ;GAChC,MAAM,QAAQ,MAAM,IAAI,MAAM,IAAI;GAClC,MAAM,aAAa,MAAM;AAGzB,OAFoB,MAAM,OAEN,OAClB;GAGF,MAAM,YAAY,MAAM;AACxB,YAAS,cAAc,UAAU,QAAQ;AAEzC,OAAI,UAAU,uBAAuB,gBACnC,mBAAkB,UAAU;;AAIhC,SAAO;GAAE;GAAU;GAAiB;;;;;;;CAQtC,MAAM,yBACJ,YACA,OACA,QACA,QAC6B;AAC7B,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,oBAAoB;EAGtC,MAAM,SAAS,MAAM,KAAK,SACxB,YACA,OACA,QACA,IACA,KAAA,GACA,KAAA,GACA,OACD;EAED,IAAI;AACJ,OAAK,MAAM,aAAa,OAAO,QAC7B,KAAI,WAAW,KAAA,KAAa,UAAU,iBAAiB,OACrD,UAAS,UAAU;AAIvB,SAAO;;CAGT,mBAA2B,IAAsC;AAC/D,SAAO;GACL,IAAI,GAAG;GACP,OAAO,GAAG;GACV,MAAM,GAAG;GACT,gBAAgB,GAAG;GACnB,MAAM,GAAG;GACT,OAAO,GAAG;GACV,cAAc,GAAG;GACjB,QAAQ,GAAG;GACX,YAAY,GAAG;GACf,cAAc,GAAG;GACjB,OAAO,GAAG;GACV,QAAQ,GAAG;GACZ;;CAGH,YAAoB,QAAoC;AACtD,SAAO;GACL,IAAI,OAAO;GACX,OAAO,OAAO;GACd,MAAM,OAAO;GACb,gBAAgB,OAAO;GACvB,MAAM,OAAO;GACb,OAAO,OAAO,SAAS,KAAA;GACvB,cAAc,OAAO,gBAAgB,KAAA;GACrC,QAAQ,OAAO;GAChB;;;;;AC/gBL,IAAa,iBAAb,MAA4B;CAC1B;CACA;CAEA,YAAY,aAAqB;AAC/B,OAAK,QAAQ,IAAI,UAAU,YAAY;;CAGzC,MAAM,OAAsB;AAC1B,QAAM,KAAK,MAAM,OAAO;AAExB,OAAK,MAAM,IAAI,SADF,KAAK,MAAM,IAAI,EAAE,MAAM,cAAc,CAAC,EACrB;GAC5B,aAAa;GACb,eAAe;GAChB,CAAC;AACF,QAAM,KAAK,IAAI,OAAO;;CAGxB,MAAM,QAAuB;AAC3B,MAAI,KAAK,IACP,OAAM,KAAK,IAAI,OAAO;AAExB,QAAM,KAAK,MAAM,OAAO;;CAG1B,SAAmB;AACjB,MAAI,CAAC,KAAK,IACR,OAAM,IAAI,MAAM,gDAAgD;AAElE,SAAO,KAAK"}