@ny4n/durable 0.0.0-stage → 1.0.0
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/LICENSE +21 -0
- package/README.md +711 -2
- package/dist/documents.d.ts +66 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +98 -0
- package/dist/documents.js.map +1 -0
- package/dist/entries.d.ts +31 -0
- package/dist/entries.d.ts.map +1 -0
- package/dist/entries.js +31 -0
- package/dist/entries.js.map +1 -0
- package/dist/env/decode.d.ts +16 -0
- package/dist/env/decode.d.ts.map +1 -0
- package/dist/env/decode.js +28 -0
- package/dist/env/decode.js.map +1 -0
- package/dist/env/index.d.ts +263 -0
- package/dist/env/index.d.ts.map +1 -0
- package/dist/env/index.js +49 -0
- package/dist/env/index.js.map +1 -0
- package/dist/env/line-scan.d.ts +13 -0
- package/dist/env/line-scan.d.ts.map +1 -0
- package/dist/env/line-scan.js +147 -0
- package/dist/env/line-scan.js.map +1 -0
- package/dist/env/node-watch.d.ts +29 -0
- package/dist/env/node-watch.d.ts.map +1 -0
- package/dist/env/node-watch.js +485 -0
- package/dist/env/node-watch.js.map +1 -0
- package/dist/env/node.d.ts +56 -0
- package/dist/env/node.d.ts.map +1 -0
- package/dist/env/node.js +1166 -0
- package/dist/env/node.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/harness/agent.d.ts +33 -0
- package/dist/harness/agent.d.ts.map +1 -0
- package/dist/harness/agent.js +235 -0
- package/dist/harness/agent.js.map +1 -0
- package/dist/harness/assistant.d.ts +15 -0
- package/dist/harness/assistant.d.ts.map +1 -0
- package/dist/harness/assistant.js +23 -0
- package/dist/harness/assistant.js.map +1 -0
- package/dist/harness/compaction.d.ts +56 -0
- package/dist/harness/compaction.d.ts.map +1 -0
- package/dist/harness/compaction.js +384 -0
- package/dist/harness/compaction.js.map +1 -0
- package/dist/harness/context.d.ts +63 -0
- package/dist/harness/context.d.ts.map +1 -0
- package/dist/harness/context.js +221 -0
- package/dist/harness/context.js.map +1 -0
- package/dist/harness/define.d.ts +18 -0
- package/dist/harness/define.d.ts.map +1 -0
- package/dist/harness/define.js +25 -0
- package/dist/harness/define.js.map +1 -0
- package/dist/harness/events.d.ts +180 -0
- package/dist/harness/events.d.ts.map +1 -0
- package/dist/harness/events.js +370 -0
- package/dist/harness/events.js.map +1 -0
- package/dist/harness/generation.d.ts +54 -0
- package/dist/harness/generation.d.ts.map +1 -0
- package/dist/harness/generation.js +514 -0
- package/dist/harness/generation.js.map +1 -0
- package/dist/harness/harness.d.ts +17 -0
- package/dist/harness/harness.d.ts.map +1 -0
- package/dist/harness/harness.js +332 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/inbox.d.ts +59 -0
- package/dist/harness/inbox.d.ts.map +1 -0
- package/dist/harness/inbox.js +97 -0
- package/dist/harness/inbox.js.map +1 -0
- package/dist/harness/json.d.ts +10 -0
- package/dist/harness/json.d.ts.map +1 -0
- package/dist/harness/json.js +33 -0
- package/dist/harness/json.js.map +1 -0
- package/dist/harness/live.d.ts +142 -0
- package/dist/harness/live.d.ts.map +1 -0
- package/dist/harness/live.js +149 -0
- package/dist/harness/live.js.map +1 -0
- package/dist/harness/output.d.ts +69 -0
- package/dist/harness/output.d.ts.map +1 -0
- package/dist/harness/output.js +318 -0
- package/dist/harness/output.js.map +1 -0
- package/dist/harness/prompt.d.ts +27 -0
- package/dist/harness/prompt.d.ts.map +1 -0
- package/dist/harness/prompt.js +131 -0
- package/dist/harness/prompt.js.map +1 -0
- package/dist/harness/provider.d.ts +14 -0
- package/dist/harness/provider.d.ts.map +1 -0
- package/dist/harness/provider.js +30 -0
- package/dist/harness/provider.js.map +1 -0
- package/dist/harness/registry.d.ts +6 -0
- package/dist/harness/registry.d.ts.map +1 -0
- package/dist/harness/registry.js +101 -0
- package/dist/harness/registry.js.map +1 -0
- package/dist/harness/run.d.ts +17 -0
- package/dist/harness/run.d.ts.map +1 -0
- package/dist/harness/run.js +26 -0
- package/dist/harness/run.js.map +1 -0
- package/dist/harness/scheduler.d.ts +106 -0
- package/dist/harness/scheduler.d.ts.map +1 -0
- package/dist/harness/scheduler.js +1743 -0
- package/dist/harness/scheduler.js.map +1 -0
- package/dist/harness/submissions.d.ts +29 -0
- package/dist/harness/submissions.d.ts.map +1 -0
- package/dist/harness/submissions.js +175 -0
- package/dist/harness/submissions.js.map +1 -0
- package/dist/harness/task-graph.d.ts +49 -0
- package/dist/harness/task-graph.d.ts.map +1 -0
- package/dist/harness/task-graph.js +168 -0
- package/dist/harness/task-graph.js.map +1 -0
- package/dist/harness/tool.d.ts +76 -0
- package/dist/harness/tool.d.ts.map +1 -0
- package/dist/harness/tool.js +736 -0
- package/dist/harness/tool.js.map +1 -0
- package/dist/harness/types.d.ts +713 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +2 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/harness/usage.d.ts +18 -0
- package/dist/harness/usage.d.ts.map +1 -0
- package/dist/harness/usage.js +57 -0
- package/dist/harness/usage.js.map +1 -0
- package/dist/harness/util.d.ts +19 -0
- package/dist/harness/util.d.ts.map +1 -0
- package/dist/harness/util.js +58 -0
- package/dist/harness/util.js.map +1 -0
- package/dist/harness/view.d.ts +47 -0
- package/dist/harness/view.d.ts.map +1 -0
- package/dist/harness/view.js +206 -0
- package/dist/harness/view.js.map +1 -0
- package/dist/ids.d.ts +6 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +9 -0
- package/dist/ids.js.map +1 -0
- package/dist/images/cloudflare.d.ts +4 -0
- package/dist/images/cloudflare.d.ts.map +1 -0
- package/dist/images/cloudflare.js +9 -0
- package/dist/images/cloudflare.js.map +1 -0
- package/dist/images/exif.d.ts +3 -0
- package/dist/images/exif.d.ts.map +1 -0
- package/dist/images/exif.js +71 -0
- package/dist/images/exif.js.map +1 -0
- package/dist/images/index.d.ts +18 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +125 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/node-worker.d.ts +17 -0
- package/dist/images/node-worker.d.ts.map +1 -0
- package/dist/images/node-worker.js +16 -0
- package/dist/images/node-worker.js.map +1 -0
- package/dist/images/node.d.ts +21 -0
- package/dist/images/node.d.ts.map +1 -0
- package/dist/images/node.js +121 -0
- package/dist/images/node.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/session/forks.d.ts +10 -0
- package/dist/session/forks.d.ts.map +1 -0
- package/dist/session/forks.js +42 -0
- package/dist/session/forks.js.map +1 -0
- package/dist/session/observation.d.ts +42 -0
- package/dist/session/observation.d.ts.map +1 -0
- package/dist/session/observation.js +281 -0
- package/dist/session/observation.js.map +1 -0
- package/dist/session/session.d.ts +133 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +811 -0
- package/dist/session/session.js.map +1 -0
- package/dist/session/transaction.d.ts +119 -0
- package/dist/session/transaction.d.ts.map +1 -0
- package/dist/session/transaction.js +795 -0
- package/dist/session/transaction.js.map +1 -0
- package/dist/storage/jsonl/index.d.ts +2 -0
- package/dist/storage/jsonl/index.d.ts.map +1 -0
- package/dist/storage/jsonl/index.js +2 -0
- package/dist/storage/jsonl/index.js.map +1 -0
- package/dist/storage/jsonl/node.d.ts +6 -0
- package/dist/storage/jsonl/node.d.ts.map +1 -0
- package/dist/storage/jsonl/node.js +8 -0
- package/dist/storage/jsonl/node.js.map +1 -0
- package/dist/storage/jsonl/storage.d.ts +143 -0
- package/dist/storage/jsonl/storage.d.ts.map +1 -0
- package/dist/storage/jsonl/storage.js +682 -0
- package/dist/storage/jsonl/storage.js.map +1 -0
- package/dist/storage/memory.d.ts +62 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +733 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/scan.d.ts +18 -0
- package/dist/storage/scan.d.ts.map +1 -0
- package/dist/storage/scan.js +29 -0
- package/dist/storage/scan.js.map +1 -0
- package/dist/storage/sqlite/cloudflare.d.ts +46 -0
- package/dist/storage/sqlite/cloudflare.d.ts.map +1 -0
- package/dist/storage/sqlite/cloudflare.js +106 -0
- package/dist/storage/sqlite/cloudflare.js.map +1 -0
- package/dist/storage/sqlite/database.d.ts +37 -0
- package/dist/storage/sqlite/database.d.ts.map +1 -0
- package/dist/storage/sqlite/database.js +2 -0
- package/dist/storage/sqlite/database.js.map +1 -0
- package/dist/storage/sqlite/index.d.ts +4 -0
- package/dist/storage/sqlite/index.d.ts.map +1 -0
- package/dist/storage/sqlite/index.js +3 -0
- package/dist/storage/sqlite/index.js.map +1 -0
- package/dist/storage/sqlite/migrations.d.ts +11 -0
- package/dist/storage/sqlite/migrations.d.ts.map +1 -0
- package/dist/storage/sqlite/migrations.js +111 -0
- package/dist/storage/sqlite/migrations.js.map +1 -0
- package/dist/storage/sqlite/node.d.ts +41 -0
- package/dist/storage/sqlite/node.d.ts.map +1 -0
- package/dist/storage/sqlite/node.js +179 -0
- package/dist/storage/sqlite/node.js.map +1 -0
- package/dist/storage/sqlite/storage.d.ts +65 -0
- package/dist/storage/sqlite/storage.d.ts.map +1 -0
- package/dist/storage/sqlite/storage.js +670 -0
- package/dist/storage/sqlite/storage.js.map +1 -0
- package/dist/tasks.d.ts +6 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +5 -0
- package/dist/tasks.js.map +1 -0
- package/dist/testing/assertions.d.ts +5 -0
- package/dist/testing/assertions.d.ts.map +1 -0
- package/dist/testing/assertions.js +25 -0
- package/dist/testing/assertions.js.map +1 -0
- package/dist/testing/env-conformance.d.ts +7 -0
- package/dist/testing/env-conformance.d.ts.map +1 -0
- package/dist/testing/env-conformance.js +431 -0
- package/dist/testing/env-conformance.js.map +1 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +6 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/runner.d.ts +12 -0
- package/dist/testing/runner.d.ts.map +1 -0
- package/dist/testing/runner.js +23 -0
- package/dist/testing/runner.js.map +1 -0
- package/dist/testing/storage-benchmark.d.ts +41 -0
- package/dist/testing/storage-benchmark.d.ts.map +1 -0
- package/dist/testing/storage-benchmark.js +350 -0
- package/dist/testing/storage-benchmark.js.map +1 -0
- package/dist/testing/storage-conformance.d.ts +4 -0
- package/dist/testing/storage-conformance.d.ts.map +1 -0
- package/dist/testing/storage-conformance.js +1213 -0
- package/dist/testing/storage-conformance.js.map +1 -0
- package/dist/testing/types.d.ts +37 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +2 -0
- package/dist/testing/types.js.map +1 -0
- package/dist/tools/bash.d.ts +55 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +138 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit-diff.d.ts +89 -0
- package/dist/tools/edit-diff.d.ts.map +1 -0
- package/dist/tools/edit-diff.js +386 -0
- package/dist/tools/edit-diff.js.map +1 -0
- package/dist/tools/edit.d.ts +18 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +117 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/env.d.ts +5 -0
- package/dist/tools/env.d.ts.map +1 -0
- package/dist/tools/env.js +7 -0
- package/dist/tools/env.js.map +1 -0
- package/dist/tools/file-mutation-queue.d.ts +9 -0
- package/dist/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/tools/file-mutation-queue.js +52 -0
- package/dist/tools/file-mutation-queue.js.map +1 -0
- package/dist/tools/image-processor.d.ts +47 -0
- package/dist/tools/image-processor.d.ts.map +1 -0
- package/dist/tools/image-processor.js +30 -0
- package/dist/tools/image-processor.js.map +1 -0
- package/dist/tools/image.d.ts +20 -0
- package/dist/tools/image.d.ts.map +1 -0
- package/dist/tools/image.js +178 -0
- package/dist/tools/image.js.map +1 -0
- package/dist/tools/index.d.ts +46 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +23 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/path-utils.d.ts +5 -0
- package/dist/tools/path-utils.d.ts.map +1 -0
- package/dist/tools/path-utils.js +26 -0
- package/dist/tools/path-utils.js.map +1 -0
- package/dist/tools/read.d.ts +25 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +235 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/write.d.ts +10 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +31 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/truncate.d.ts +64 -0
- package/dist/truncate.d.ts.map +1 -0
- package/dist/truncate.js +154 -0
- package/dist/truncate.js.map +1 -0
- package/dist/types.d.ts +932 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +140 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@ny4n/chord\";\nimport { applyImmutableBatches, type Op } from \"@ny4n/chord/delta\";\nimport { StorageRequestError } from \"../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tScanOrder,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../types.ts\";\nimport { nextCursor, type ScanStart, scanStart } from \"./scan.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TaskStatus = StoredTask[\"state\"][\"status\"];\ntype SubmissionStatus = SubmissionRecord[\"status\"];\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype DocumentRevision = DocumentContent & { readonly seq: Seq };\ntype StoredDocumentState = {\n\trecord: DocumentRecord;\n\trevisions: DocumentRevision[];\n};\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\n\nfunction* documentDeltaBatches(\n\tid: DocumentId,\n\tversion: number,\n\trevisions: readonly DocumentRevision[],\n\tstart: number,\n): Generator<readonly Op[]> {\n\tfor (let index = start; index < revisions.length; index++) {\n\t\tconst revision = revisions[index]!;\n\t\tif (revision.kind !== \"delta\" || revision.version !== version) {\n\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t}\n\t\tyield revision.ops;\n\t}\n}\n\ntype DocumentAddressIndex = {\n\tids: DocumentId[];\n\tcurrentId?: DocumentId;\n};\n\ntype State = {\n\trecordTypes: Map<Id<string>, TableName>;\n\tconversations: Map<ConversationId, ConversationRecord>;\n\tconversationIds: ConversationId[];\n\tconversationIdsByOwnerConversation: Map<ConversationId, ConversationId[]>;\n\tconversationIdsByOwnerTask: Map<TaskId, ConversationId[]>;\n\tentries: Map<EntryId, EntryRecord>;\n\tentryIds: Map<ConversationId, EntryId[]>;\n\theadEntryIds: Map<ConversationId, EntryId[]>;\n\tentryCommitSeqs: Map<EntryId, Seq>;\n\ttasks: Map<TaskId, StoredTask>;\n\ttaskIds: TaskId[];\n\ttaskIdsByStatus: Record<TaskStatus, TaskId[]>;\n\tsubmissions: Map<SubmissionId, SubmissionRecord>;\n\tsubmissionIds: SubmissionId[];\n\tsubmissionIdsByStatus: Record<SubmissionStatus, SubmissionId[]>;\n\tsubmissionIdsByRequest: Map<ConversationId, Map<string, SubmissionId>>;\n\tdocuments: Map<DocumentId, StoredDocumentState>;\n\tdocumentAddresses: Map<string, DocumentAddressIndex>;\n\tdocumentIdsByScope: Map<string, DocumentId[]>;\n};\n\nconst clone = <T>(value: T): T => {\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return value.map((item) => clone(item)) as T;\n\tconst source = value as Record<string, unknown>;\n\tconst nullPrototype = Object.getPrototypeOf(value) === null;\n\tconst result = (nullPrototype ? Object.create(null) : {}) as Record<string, unknown>;\n\tfor (const key of Object.keys(source)) {\n\t\tconst copied = clone(source[key]);\n\t\tif (!nullPrototype && key in result) {\n\t\t\tObject.defineProperty(result, key, {\n\t\t\t\tvalue: copied,\n\t\t\t\twritable: true,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t});\n\t\t} else {\n\t\t\tresult[key] = copied;\n\t\t}\n\t}\n\treturn result as T;\n};\n\nconst freeze = <T>(value: T): T => {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const child of Object.values(value)) freeze(child);\n\treturn Object.freeze(value);\n};\n\nconst cursorId = <I extends Id<string>>(cursor: Readonly<Record<string, JsonValue>> | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after))\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst lowerBound = <I extends Id<string>>(ids: readonly I[], target: number): number => {\n\tlet low = 0;\n\tlet high = ids.length;\n\twhile (low < high) {\n\t\tconst middle = (low + high) >>> 1;\n\t\tif (ids[middle] < target) low = middle + 1;\n\t\telse high = middle;\n\t}\n\treturn low;\n};\n\nconst upperBound = <I extends Id<string>>(ids: readonly I[], target: number): number => {\n\tlet low = 0;\n\tlet high = ids.length;\n\twhile (low < high) {\n\t\tconst middle = (low + high) >>> 1;\n\t\tif (ids[middle] <= target) low = middle + 1;\n\t\telse high = middle;\n\t}\n\treturn low;\n};\n\nconst insertSorted = <I extends Id<string>>(ids: I[], id: I): void => {\n\tif (ids.length === 0 || ids[ids.length - 1] < id) ids.push(id);\n\telse ids.splice(lowerBound(ids, id), 0, id);\n};\n\nconst removeSorted = <I extends Id<string>>(ids: I[], id: I): void => {\n\tconst index = lowerBound(ids, id);\n\tif (ids[index] === id) ids.splice(index, 1);\n};\n\nconst insertMapId = <K, I extends Id<string>>(index: Map<K, I[]>, key: K, id: I): void => {\n\tlet ids = index.get(key);\n\tif (ids === undefined) {\n\t\tids = [];\n\t\tindex.set(key, ids);\n\t}\n\tinsertSorted(ids, id);\n};\n\nconst scopeKey = (scope: DocumentRecord[\"scope\"]): string => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn JSON.stringify([\"session\"]);\n\t\tcase \"conversation\":\n\t\t\treturn JSON.stringify([\"conversation\", scope.conversationId]);\n\t\tcase \"task\":\n\t\t\treturn JSON.stringify([\"task\", scope.taskId]);\n\t}\n};\n\nconst addressKey = (address: DocumentAddress): string =>\n\tJSON.stringify([\n\t\taddress.kind,\n\t\tscopeKey(address.scope),\n\t\taddress.key === undefined ? [\"singleton\"] : [\"family\", address.key],\n\t]);\n\nconst recordAddressKey = (record: DocumentRecord | DocumentCreate): string =>\n\taddressKey({ kind: record.kind, scope: record.scope, key: record.key });\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst tableContaining = (state: State, id: Id<string>): TableName | undefined => state.recordTypes.get(id);\n\nconst page = <T extends { readonly id: Id<string> }>(\n\tvalues: readonly T[],\n\tlimit: number,\n\torder: ScanOrder = \"ascending\",\n): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items: clone(items) };\n\treturn { items: clone(items), next: nextCursor(items.at(-1)!.id, order) };\n};\n\n/** Indexes of sorted `ids` in scan order, after the cursor's ID when there is one. */\nfunction* scanIndexes(ids: readonly Id<string>[], start: ScanStart): Generator<number> {\n\tif (start.order === \"ascending\") {\n\t\tconst first = start.after === undefined ? 0 : upperBound(ids, start.after);\n\t\tfor (let index = first; index < ids.length; index++) yield index;\n\t} else {\n\t\tconst end = start.after === undefined ? ids.length : lowerBound(ids, start.after);\n\t\tfor (let index = end - 1; index >= 0; index--) yield index;\n\t}\n}\n\n/** A fully validated, detached state mutation whose application performs no fallible preparation. */\nexport interface PreparedMemoryCommit {\n\treadonly seq: Seq;\n\t/** Deeply frozen detached writes for persistence. */\n\treadonly writes: readonly StorageWrite[];\n\tapply(): Seq;\n}\n\n/**\n * Detached in-memory reference implementation of `Storage`.\n *\n * Reads and retained writes are cloned intentionally to match the ownership boundary\n * of serialization-backed stores. This is backend conformance, not validation.\n */\nexport class MemoryStorage implements Storage {\n\tprivate readonly state: State = {\n\t\trecordTypes: new Map(),\n\t\tconversations: new Map(),\n\t\tconversationIds: [],\n\t\tconversationIdsByOwnerConversation: new Map(),\n\t\tconversationIdsByOwnerTask: new Map(),\n\t\tentries: new Map(),\n\t\tentryIds: new Map(),\n\t\theadEntryIds: new Map(),\n\t\tentryCommitSeqs: new Map(),\n\t\ttasks: new Map(),\n\t\ttaskIds: [],\n\t\ttaskIdsByStatus: { pending: [], running: [], waiting: [], completing: [], terminal: [] },\n\t\tsubmissions: new Map(),\n\t\tsubmissionIds: [],\n\t\tsubmissionIdsByStatus: { queued: [], placed: [], done: [], unanswered: [] },\n\t\tsubmissionIdsByRequest: new Map(),\n\t\tdocuments: new Map(),\n\t\tdocumentAddresses: new Map(),\n\t\tdocumentIdsByScope: new Map(),\n\t};\n\tprivate nextId = 2;\n\tprivate nextSeq = 1;\n\tprivate closed = false;\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\treturn this.prepareCommit(writes).apply();\n\t}\n\n\t/** Validate and detach one commit without changing observable state. */\n\tprepareCommit(writes: readonly StorageWrite[], seq: Seq = seqFromNumber(this.nextSeq)): PreparedMemoryCommit {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(seq) || seq < this.nextSeq) {\n\t\t\tthrow new Error(`Commit sequence ${seq} does not strictly increase`);\n\t\t}\n\t\tconst detachedWrites = freeze(this.resolveDocumentCopies(writes.map((write) => clone(write))));\n\t\tthis.checkGlobalIds(detachedWrites);\n\t\tconst documentActions = this.prepareDocumentActions(detachedWrites);\n\t\tthis.checkDocumentActions(documentActions);\n\t\tlet applied = false;\n\t\treturn {\n\t\t\tseq,\n\t\t\twrites: detachedWrites,\n\t\t\tapply: () => {\n\t\t\t\tif (!applied) {\n\t\t\t\t\tapplied = true;\n\t\t\t\t\tthis.applyPreparedCommit(detachedWrites, documentActions, seq);\n\t\t\t\t}\n\t\t\t\treturn seq;\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate resolveDocumentCopies(writes: StorageWrite[]): StorageWrite[] {\n\t\tif (!writes.some((write) => write.type === \"document.copy\")) return writes;\n\t\tconst changedDocumentIds = new Set<DocumentId>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.create\" || write.type === \"document.copy\") {\n\t\t\t\tchangedDocumentIds.add(write.record.id);\n\t\t\t} else if (write.type === \"document.change\" || write.type === \"document.retire\") {\n\t\t\t\tchangedDocumentIds.add(write.id);\n\t\t\t}\n\t\t}\n\t\treturn writes.map((write) => {\n\t\t\tif (write.type !== \"document.copy\") return write;\n\t\t\ttry {\n\t\t\t\tif (changedDocumentIds.has(write.source.id)) {\n\t\t\t\t\tthrow new Error(`Fork source document ${write.source.id} is changed in the copy batch`);\n\t\t\t\t}\n\t\t\t\tconst stored = this.materializeDocument(write.source.id, write.source.at);\n\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${write.source.id} cannot be read`);\n\t\t\t\tif (\n\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\twrite.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\tstored.record.kind !== write.record.kind ||\n\t\t\t\t\tstored.record.key !== write.record.key ||\n\t\t\t\t\tstored.record.history !== write.record.history ||\n\t\t\t\t\tstored.record.fork !== write.record.fork\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(`Fork source document ${write.source.id} does not match the copied record`);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"document.create\",\n\t\t\t\t\trecord: write.record,\n\t\t\t\t\tcontent: { kind: \"base\", version: stored.version, value: stored.value },\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(`Document copy ${write.record.id} was rejected`, { cause: error });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate applyPreparedCommit(\n\t\tprepared: readonly StorageWrite[],\n\t\tdocumentActions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Seq {\n\t\tfor (const write of prepared) {\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"conversation\": {\n\t\t\t\t\tthis.state.recordTypes.set(write.value.id, \"conversation\");\n\t\t\t\t\tthis.state.conversations.set(write.value.id, write.value);\n\t\t\t\t\tinsertSorted(this.state.conversationIds, write.value.id);\n\t\t\t\t\tconst owner = write.value.owner;\n\t\t\t\t\tif (owner !== undefined) {\n\t\t\t\t\t\tinsertMapId(this.state.conversationIdsByOwnerConversation, owner.conversationId, write.value.id);\n\t\t\t\t\t\tinsertMapId(this.state.conversationIdsByOwnerTask, owner.taskId, write.value.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis.nextId = Math.max(this.nextId, write.value.id + 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"entry\": {\n\t\t\t\t\tthis.state.recordTypes.set(write.value.id, \"entry\");\n\t\t\t\t\tthis.state.entries.set(write.value.id, write.value);\n\t\t\t\t\tthis.state.entryCommitSeqs.set(write.value.id, seq);\n\t\t\t\t\tlet ids = this.state.entryIds.get(write.value.conversationId);\n\t\t\t\t\tif (ids === undefined) {\n\t\t\t\t\t\tids = [];\n\t\t\t\t\t\tthis.state.entryIds.set(write.value.conversationId, ids);\n\t\t\t\t\t}\n\t\t\t\t\tinsertSorted(ids, write.value.id);\n\t\t\t\t\tif (write.value.head !== undefined) {\n\t\t\t\t\t\tlet headIds = this.state.headEntryIds.get(write.value.conversationId);\n\t\t\t\t\t\tif (headIds === undefined) {\n\t\t\t\t\t\t\theadIds = [];\n\t\t\t\t\t\t\tthis.state.headEntryIds.set(write.value.conversationId, headIds);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tinsertSorted(headIds, write.value.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis.nextId = Math.max(this.nextId, write.value.id + 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"task\": {\n\t\t\t\t\tthis.state.recordTypes.set(write.value.id, \"task\");\n\t\t\t\t\tconst previous = this.state.tasks.get(write.value.id);\n\t\t\t\t\tif (previous === undefined) {\n\t\t\t\t\t\tinsertSorted(this.state.taskIds, write.value.id);\n\t\t\t\t\t\tinsertSorted(this.state.taskIdsByStatus[write.value.state.status], write.value.id);\n\t\t\t\t\t} else if (previous.state.status !== write.value.state.status) {\n\t\t\t\t\t\tremoveSorted(this.state.taskIdsByStatus[previous.state.status], write.value.id);\n\t\t\t\t\t\tinsertSorted(this.state.taskIdsByStatus[write.value.state.status], write.value.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis.state.tasks.set(write.value.id, write.value);\n\t\t\t\t\tthis.nextId = Math.max(this.nextId, write.value.id + 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"submission\": {\n\t\t\t\t\tthis.state.recordTypes.set(write.value.id, \"submission\");\n\t\t\t\t\tconst previous = this.state.submissions.get(write.value.id);\n\t\t\t\t\tif (previous === undefined) {\n\t\t\t\t\t\tinsertSorted(this.state.submissionIds, write.value.id);\n\t\t\t\t\t\tinsertSorted(this.state.submissionIdsByStatus[write.value.status], write.value.id);\n\t\t\t\t\t} else if (previous.status !== write.value.status) {\n\t\t\t\t\t\tremoveSorted(this.state.submissionIdsByStatus[previous.status], write.value.id);\n\t\t\t\t\t\tinsertSorted(this.state.submissionIdsByStatus[write.value.status], write.value.id);\n\t\t\t\t\t}\n\t\t\t\t\tif (previous?.requestId !== undefined) {\n\t\t\t\t\t\tconst previousRequests = this.state.submissionIdsByRequest.get(previous.conversationId);\n\t\t\t\t\t\tif (previousRequests?.get(previous.requestId) === write.value.id) {\n\t\t\t\t\t\t\tpreviousRequests.delete(previous.requestId);\n\t\t\t\t\t\t\tif (previousRequests.size === 0) this.state.submissionIdsByRequest.delete(previous.conversationId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.state.submissions.set(write.value.id, write.value);\n\t\t\t\t\tif (write.value.requestId !== undefined) {\n\t\t\t\t\t\tlet requests = this.state.submissionIdsByRequest.get(write.value.conversationId);\n\t\t\t\t\t\tif (requests === undefined) {\n\t\t\t\t\t\t\trequests = new Map();\n\t\t\t\t\t\t\tthis.state.submissionIdsByRequest.set(write.value.conversationId, requests);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trequests.set(write.value.requestId, write.value.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis.nextId = Math.max(this.nextId, write.value.id + 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tthrow new Error(\"Prepared document copy was not resolved\");\n\t\t\t\tcase \"document.create\":\n\t\t\t\tcase \"document.change\":\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.applyDocumentActions(documentActions, seq);\n\t\tthis.nextSeq = seq + 1;\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst value = this.state.conversations.get(id);\n\t\treturn value === undefined ? undefined : clone(value);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst ids =\n\t\t\tquery.ownerTaskId !== undefined\n\t\t\t\t? (this.state.conversationIdsByOwnerTask.get(query.ownerTaskId) ?? [])\n\t\t\t\t: query.ownerConversationId !== undefined\n\t\t\t\t\t? (this.state.conversationIdsByOwnerConversation.get(query.ownerConversationId) ?? [])\n\t\t\t\t\t: this.state.conversationIds;\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst values: ConversationRecord[] = [];\n\t\tfor (const index of scanIndexes(ids, start)) {\n\t\t\tif (values.length > limit) break;\n\t\t\tconst value = this.state.conversations.get(ids[index]!)!;\n\t\t\tif (query.ownerConversationId !== undefined && value.owner?.conversationId !== query.ownerConversationId) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvalues.push(value);\n\t\t}\n\t\treturn page(values, limit, start.order);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tasync entry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tthis.assertOpen();\n\t\tif (context === undefined) {\n\t\t\tconst id = idFromNumber<EntryId>(idOrConversationId);\n\t\t\tconst entry = this.state.entries.get(id);\n\t\t\tif (entry === undefined) return undefined;\n\t\t\treturn { entry: clone(entry), commitSeq: this.state.entryCommitSeqs.get(id)! };\n\t\t}\n\t\tif (typeof idOrContext !== \"number\") throw new StorageRequestError(\"Storage.entry() requires an entry ID\");\n\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\tconst id = idFromNumber<EntryId>(idOrContext);\n\t\tconst entry = this.visibleEntries(conversationId, id, id).next().value;\n\t\tif (entry === undefined) return undefined;\n\t\treturn { entry: clone(entry), commitSeq: this.state.entryCommitSeqs.get(id)! };\n\t}\n\n\tasync findLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tthis.assertOpen();\n\t\tif (!this.state.conversations.has(conversationId)) {\n\t\t\tthrow new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tlet currentId = conversationId;\n\t\tlet upperEntryId = atOrBeforeEntryId ?? Number.POSITIVE_INFINITY;\n\t\twhile (true) {\n\t\t\tconst ids = this.state.headEntryIds.get(currentId) ?? [];\n\t\t\tconst index = upperBound(ids, upperEntryId) - 1;\n\t\t\tif (index >= 0) {\n\t\t\t\tconst entry = this.state.entries.get(ids[index])!;\n\t\t\t\treturn clone({ ...entry, head: entry.head! });\n\t\t\t}\n\t\t\tconst conversation = this.state.conversations.get(currentId)!;\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\tcurrentId = conversation.parent.conversationId;\n\t\t}\n\t}\n\n\tasync scanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst { order, after } = scanStart(query.order, cursor, \"descending\");\n\t\t// The cursor narrows the bound on the side the scan moves away from.\n\t\tlet minEntryId: number | undefined = query.minEntryId;\n\t\tlet maxEntryId: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined && order === \"descending\") maxEntryId = Math.min(maxEntryId ?? after, after - 1);\n\t\tif (after !== undefined && order === \"ascending\") minEntryId = Math.max(minEntryId ?? after, after + 1);\n\t\tconst visible: EntryRecord[] = [];\n\t\tconst entries =\n\t\t\torder === \"descending\"\n\t\t\t\t? this.visibleEntries(query.conversationId, minEntryId, maxEntryId)\n\t\t\t\t: this.visibleEntriesAscending(query.conversationId, minEntryId, maxEntryId);\n\t\tfor (const entry of entries) {\n\t\t\tvisible.push(entry);\n\t\t\tif (visible.length > limit) break;\n\t\t}\n\t\treturn page(visible, limit, order);\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst value = this.state.tasks.get(id);\n\t\treturn value === undefined ? undefined : clone(value);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst ids = query.status === undefined ? this.state.taskIds : this.state.taskIdsByStatus[query.status];\n\t\tconst values: StoredTask[] = [];\n\t\tfor (const index of scanIndexes(ids, start)) {\n\t\t\tif (values.length > limit) break;\n\t\t\tconst value = this.state.tasks.get(ids[index]!)!;\n\t\t\tif (query.conversationId !== undefined && value.conversationId !== query.conversationId) continue;\n\t\t\tif (query.kind !== undefined && value.kind !== query.kind) continue;\n\t\t\tif (query.abortRequested !== undefined && value.abortRequested !== query.abortRequested) continue;\n\t\t\tif (query.background !== undefined && value.background !== query.background) continue;\n\t\t\tvalues.push(value);\n\t\t}\n\t\treturn page(values, limit, start.order);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst value = this.state.submissions.get(id);\n\t\treturn value === undefined ? undefined : clone(value);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst ids =\n\t\t\tquery.status === undefined ? this.state.submissionIds : this.state.submissionIdsByStatus[query.status];\n\t\tconst values: SubmissionRecord[] = [];\n\t\tfor (const index of scanIndexes(ids, start)) {\n\t\t\tif (values.length > limit) break;\n\t\t\tconst value = this.state.submissions.get(ids[index]!)!;\n\t\t\tif (query.conversationId !== undefined && value.conversationId !== query.conversationId) continue;\n\t\t\tvalues.push(value);\n\t\t}\n\t\treturn page(values, limit, start.order);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst id = this.state.submissionIdsByRequest.get(conversationId)?.get(requestId);\n\t\tif (id === undefined) return undefined;\n\t\treturn clone(this.state.submissions.get(id)!);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst index = this.state.documentAddresses.get(addressKey(address));\n\t\tif (at === \"current\") {\n\t\t\treturn index?.currentId === undefined ? undefined : clone(this.state.documents.get(index.currentId)!.record);\n\t\t}\n\t\tfor (const id of index?.ids ?? []) {\n\t\t\tconst record = this.state.documents.get(id)!.record;\n\t\t\tif (isAliveAt(record, at)) return clone(record);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\tconst stored = this.materializeDocument(id, at);\n\t\treturn stored === undefined\n\t\t\t? undefined\n\t\t\t: {\n\t\t\t\t\trecord: clone(stored.record),\n\t\t\t\t\tversion: stored.version,\n\t\t\t\t\tvalue: clone(stored.value),\n\t\t\t\t\tdeltasSinceBase: stored.deltasSinceBase,\n\t\t\t\t};\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst ids = this.state.documentIdsByScope.get(scopeKey(query.scope)) ?? [];\n\t\tconst after = cursorId(cursor);\n\t\tconst start = after === undefined ? 0 : upperBound(ids, after);\n\t\tconst values: DocumentRecord[] = [];\n\t\tfor (let index = start; index < ids.length && values.length <= limit; index++) {\n\t\t\tconst record = this.state.documents.get(ids[index]!)!.record;\n\t\t\tif (query.kind !== undefined && record.kind !== query.kind) continue;\n\t\t\tif (isAliveAt(record, query.at)) values.push(record);\n\t\t}\n\t\treturn page(values, limit);\n\t}\n\n\tasync close(_context: Context): Promise<void> {\n\t\tthis.closed = true;\n\t}\n\n\tprivate materializeDocument(id: DocumentId, at: DocumentPoint): StoredDocument | undefined {\n\t\tconst stored = this.state.documents.get(id);\n\t\tif (stored === undefined) return undefined;\n\t\tif (at !== \"current\" && isCurrentOnly(stored.record)) {\n\t\t\tthrow new StorageRequestError(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(stored.record, at)) return undefined;\n\t\tconst revisions = at === \"current\" ? stored.revisions : stored.revisions.filter((revision) => revision.seq <= at);\n\t\tlet baseIndex = revisions.length - 1;\n\t\twhile (baseIndex >= 0 && revisions[baseIndex]!.kind !== \"base\") baseIndex--;\n\t\tconst base = revisions[baseIndex];\n\t\tif (base?.kind !== \"base\") throw new Error(`Document ${id} is missing a required base`);\n\t\tconst value = applyImmutableBatches(\n\t\t\tbase.value,\n\t\t\tdocumentDeltaBatches(id, base.version, revisions, baseIndex + 1),\n\t\t) as JsonObject;\n\t\treturn { record: stored.record, version: base.version, value, deltasSinceBase: revisions.length - baseIndex - 1 };\n\t}\n\n\tprivate *visibleEntries(\n\t\tconversationId: ConversationId,\n\t\tminEntryId: number = Number.NEGATIVE_INFINITY,\n\t\tmaxEntryId: number = Number.POSITIVE_INFINITY,\n\t): Generator<EntryRecord> {\n\t\tif (!this.state.conversations.has(conversationId)) {\n\t\t\tthrow new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tlet currentId = conversationId;\n\t\tlet upperEntryId = maxEntryId;\n\t\twhile (true) {\n\t\t\tconst ids = this.state.entryIds.get(currentId) ?? [];\n\t\t\tfor (let index = upperBound(ids, upperEntryId) - 1; index >= 0; index--) {\n\t\t\t\tconst id = ids[index];\n\t\t\t\tif (id < minEntryId) break;\n\t\t\t\tyield this.state.entries.get(id)!;\n\t\t\t}\n\t\t\tconst conversation = this.state.conversations.get(currentId)!;\n\t\t\tif (conversation.parent === undefined) break;\n\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\tif (upperEntryId < minEntryId) break;\n\t\t\tcurrentId = conversation.parent.conversationId;\n\t\t}\n\t}\n\n\t/** Visible entries oldest first: the fork chain's segments from the root conversation forward. */\n\tprivate *visibleEntriesAscending(\n\t\tconversationId: ConversationId,\n\t\tminEntryId: number = Number.NEGATIVE_INFINITY,\n\t\tmaxEntryId: number = Number.POSITIVE_INFINITY,\n\t): Generator<EntryRecord> {\n\t\tif (!this.state.conversations.has(conversationId)) {\n\t\t\tthrow new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst segments: { readonly conversationId: ConversationId; readonly upper: number }[] = [];\n\t\tlet currentId = conversationId;\n\t\tlet upperEntryId = maxEntryId;\n\t\twhile (true) {\n\t\t\tsegments.push({ conversationId: currentId, upper: upperEntryId });\n\t\t\tconst conversation = this.state.conversations.get(currentId)!;\n\t\t\tif (conversation.parent === undefined) break;\n\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\tif (upperEntryId < minEntryId) break;\n\t\t\tcurrentId = conversation.parent.conversationId;\n\t\t}\n\t\tfor (const segment of segments.reverse()) {\n\t\t\tconst ids = this.state.entryIds.get(segment.conversationId) ?? [];\n\t\t\tfor (let index = lowerBound(ids, minEntryId); index < ids.length; index++) {\n\t\t\t\tconst id = ids[index]!;\n\t\t\t\tif (id > segment.upper) break;\n\t\t\t\tyield this.state.entries.get(id)!;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate checkGlobalIds(writes: readonly StorageWrite[]): void {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = tableContaining(this.state, id);\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table) {\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\t}\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type !== \"document.create\" && write.type !== \"document.change\" && write.type !== \"document.retire\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined) throw new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate checkDocumentActions(actions: ReadonlyMap<DocumentId, DocumentAction>): void {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tconst existing = this.state.documents.get(id);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.record.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tconst previous = existing?.revisions.at(-1);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst key = action.create === undefined ? recordAddressKey(existing!.record) : recordAddressKey(action.create);\n\t\t\tconst currentId = this.state.documentAddresses.get(key)?.currentId;\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = currentId === undefined ? 0 : 1;\n\t\t\tif (action.retire && currentId === id) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(`Document address already has a current incarnation`);\n\t\t}\n\t}\n\n\tprivate applyDocumentActions(actions: ReadonlyMap<DocumentId, DocumentAction>, seq: Seq): void {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet stored = this.state.documents.get(id);\n\t\t\tif (action.create !== undefined) {\n\t\t\t\tconst record: DocumentRecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tstored = { record, revisions: [{ ...action.content!, seq }] };\n\t\t\t\tthis.state.recordTypes.set(id, \"document\");\n\t\t\t\tthis.state.documents.set(id, stored);\n\n\t\t\t\tconst key = recordAddressKey(record);\n\t\t\t\tlet address = this.state.documentAddresses.get(key);\n\t\t\t\tif (address === undefined) {\n\t\t\t\t\taddress = { ids: [] };\n\t\t\t\t\tthis.state.documentAddresses.set(key, address);\n\t\t\t\t}\n\t\t\t\tinsertSorted(address.ids, id);\n\n\t\t\t\tlet scopeIds = this.state.documentIdsByScope.get(scopeKey(record.scope));\n\t\t\t\tif (scopeIds === undefined) {\n\t\t\t\t\tscopeIds = [];\n\t\t\t\t\tthis.state.documentIdsByScope.set(scopeKey(record.scope), scopeIds);\n\t\t\t\t}\n\t\t\t\tinsertSorted(scopeIds, id);\n\t\t\t\tthis.nextId = Math.max(this.nextId, id + 1);\n\t\t\t} else if (action.content !== undefined) {\n\t\t\t\tconst revision = { ...action.content, seq } as DocumentRevision;\n\t\t\t\tif (revision.kind === \"base\" && isCurrentOnly(stored!.record)) stored!.revisions = [revision];\n\t\t\t\telse stored!.revisions.push(revision);\n\t\t\t}\n\n\t\t\tif (action.retire && action.create === undefined) stored!.record = { ...stored!.record, retiredAt: seq };\n\t\t\tif (action.retire && isCurrentOnly(stored!.record)) stored!.revisions = [];\n\t\t\tif (action.create !== undefined || action.retire) {\n\t\t\t\tconst address = this.state.documentAddresses.get(recordAddressKey(stored!.record))!;\n\t\t\t\tif (action.retire && address.currentId === id) delete address.currentId;\n\t\t\t\tif (action.create !== undefined && !action.retire) address.currentId = id;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"MemoryStorage is closed\");\n\t}\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Id, ScanOrder } from "../types.ts";
|
|
2
|
+
/** Where a built-in storage scan starts: its order and the last ID a previous page returned. */
|
|
3
|
+
export type ScanStart = {
|
|
4
|
+
readonly order: ScanOrder;
|
|
5
|
+
readonly after: number | undefined;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a scan's order and position. A cursor continues in the order it was created with, whether the query repeats
|
|
9
|
+
* that order or omits it; a different `order` throws. A cursor without an order, written before scans had one,
|
|
10
|
+
* continues in the scan's default order.
|
|
11
|
+
*/
|
|
12
|
+
export declare function scanStart(requested: ScanOrder | undefined, cursor: Readonly<Record<string, unknown>> | undefined, fallback: ScanOrder): ScanStart;
|
|
13
|
+
/** The continuation of a scan whose last returned item has `id`. */
|
|
14
|
+
export declare function nextCursor(id: Id<string>, order: ScanOrder): {
|
|
15
|
+
readonly after: number;
|
|
16
|
+
readonly order: ScanOrder;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/storage/scan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEjD,gGAAgG;AAChG,MAAM,MAAM,SAAS,GAAG;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACrD,QAAQ,EAAE,SAAS,GACjB,SAAS,CAgBX;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAElH"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StorageRequestError } from "../errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a scan's order and position. A cursor continues in the order it was created with, whether the query repeats
|
|
4
|
+
* that order or omits it; a different `order` throws. A cursor without an order, written before scans had one,
|
|
5
|
+
* continues in the scan's default order.
|
|
6
|
+
*/
|
|
7
|
+
export function scanStart(requested, cursor, fallback) {
|
|
8
|
+
if (requested !== undefined && requested !== "ascending" && requested !== "descending") {
|
|
9
|
+
throw new StorageRequestError(`Invalid scan order: ${String(requested)}`);
|
|
10
|
+
}
|
|
11
|
+
if (cursor === undefined)
|
|
12
|
+
return { order: requested ?? fallback, after: undefined };
|
|
13
|
+
const { after, order: stored } = cursor;
|
|
14
|
+
if (typeof after !== "number" || !Number.isSafeInteger(after))
|
|
15
|
+
throw new StorageRequestError("Invalid storage cursor");
|
|
16
|
+
if (stored !== undefined && stored !== "ascending" && stored !== "descending") {
|
|
17
|
+
throw new StorageRequestError("Invalid storage cursor");
|
|
18
|
+
}
|
|
19
|
+
const order = stored ?? fallback;
|
|
20
|
+
if (requested !== undefined && requested !== order) {
|
|
21
|
+
throw new StorageRequestError(`The cursor continues a ${order} scan; the query asks for ${requested}`);
|
|
22
|
+
}
|
|
23
|
+
return { order, after };
|
|
24
|
+
}
|
|
25
|
+
/** The continuation of a scan whose last returned item has `id`. */
|
|
26
|
+
export function nextCursor(id, order) {
|
|
27
|
+
return { after: id, order };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/storage/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACxB,SAAgC,EAChC,MAAqD,EACrD,QAAmB;IAEnB,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QACxF,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,IAAI,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACpF,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;QAC5D,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;IACzD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC/E,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC;IACjC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;QACpD,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,KAAK,6BAA6B,SAAS,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,EAAc,EAAE,KAAgB;IAC1D,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import { StorageRequestError } from \"../errors.ts\";\nimport type { Id, ScanOrder } from \"../types.ts\";\n\n/** Where a built-in storage scan starts: its order and the last ID a previous page returned. */\nexport type ScanStart = {\n\treadonly order: ScanOrder;\n\treadonly after: number | undefined;\n};\n\n/**\n * Resolve a scan's order and position. A cursor continues in the order it was created with, whether the query repeats\n * that order or omits it; a different `order` throws. A cursor without an order, written before scans had one,\n * continues in the scan's default order.\n */\nexport function scanStart(\n\trequested: ScanOrder | undefined,\n\tcursor: Readonly<Record<string, unknown>> | undefined,\n\tfallback: ScanOrder,\n): ScanStart {\n\tif (requested !== undefined && requested !== \"ascending\" && requested !== \"descending\") {\n\t\tthrow new StorageRequestError(`Invalid scan order: ${String(requested)}`);\n\t}\n\tif (cursor === undefined) return { order: requested ?? fallback, after: undefined };\n\tconst { after, order: stored } = cursor;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after))\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\tif (stored !== undefined && stored !== \"ascending\" && stored !== \"descending\") {\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\t}\n\tconst order = stored ?? fallback;\n\tif (requested !== undefined && requested !== order) {\n\t\tthrow new StorageRequestError(`The cursor continues a ${order} scan; the query asks for ${requested}`);\n\t}\n\treturn { order, after };\n}\n\n/** The continuation of a scan whose last returned item has `id`. */\nexport function nextCursor(id: Id<string>, order: ScanOrder): { readonly after: number; readonly order: ScanOrder } {\n\treturn { after: id, order };\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
|
|
2
|
+
import { SqliteStorage } from "./storage.ts";
|
|
3
|
+
/** Values a Durable Object SQL binding accepts and returns. */
|
|
4
|
+
type DurableObjectSqlValue = ArrayBuffer | string | number | null;
|
|
5
|
+
/**
|
|
6
|
+
* The parts of a SQLite-backed Durable Object's `ctx.storage` this adapter uses, typed structurally so the package
|
|
7
|
+
* needs no Workers type dependency.
|
|
8
|
+
*/
|
|
9
|
+
export type DurableObjectSqliteStorage = {
|
|
10
|
+
readonly sql: {
|
|
11
|
+
exec(query: string, ...bindings: DurableObjectSqlValue[]): {
|
|
12
|
+
toArray(): Record<string, DurableObjectSqlValue>[];
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
transaction<T>(closure: () => Promise<T>): Promise<T>;
|
|
16
|
+
};
|
|
17
|
+
/** Executes SQL through `ctx.storage.sql`, which has no separate prepare step. */
|
|
18
|
+
declare class DurableObjectSqliteExecutor implements SqliteExecutor {
|
|
19
|
+
protected readonly storage: DurableObjectSqliteStorage;
|
|
20
|
+
constructor(storage: DurableObjectSqliteStorage);
|
|
21
|
+
exec(sql: string): Promise<void>;
|
|
22
|
+
run(sql: string, ...params: SqliteValue[]): Promise<void>;
|
|
23
|
+
get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
|
|
24
|
+
all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
|
|
25
|
+
/** Throws when this handle may no longer run SQL. */
|
|
26
|
+
protected check(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `SqliteDatabase` adapter for the SQLite storage of a Cloudflare Durable Object. Integers are JavaScript numbers;
|
|
30
|
+
* binding a `bigint` outside the safe integer range throws.
|
|
31
|
+
*/
|
|
32
|
+
export declare class DurableObjectSqliteDatabase extends DurableObjectSqliteExecutor implements SqliteDatabase {
|
|
33
|
+
private readonly queue;
|
|
34
|
+
exec(sql: string): Promise<void>;
|
|
35
|
+
run(sql: string, ...params: SqliteValue[]): Promise<void>;
|
|
36
|
+
get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
|
|
37
|
+
all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
|
|
38
|
+
/** `ctx.storage.transaction()` commits when the callback resolves and rolls back when it rejects. */
|
|
39
|
+
transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;
|
|
40
|
+
/** Waits for queued work. The Durable Object owns its storage, so nothing else closes. */
|
|
41
|
+
close(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/** Open durable storage on a SQLite-backed Durable Object's `ctx.storage`. */
|
|
44
|
+
export declare function openDurableObjectSqliteStorage(storage: DurableObjectSqliteStorage): Promise<SqliteStorage>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,+DAA+D;AAC/D,KAAK,qBAAqB,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACxC,QAAQ,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,qBAAqB,EAAE,GAAG;YAAE,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,CAAA;SAAE,CAAC;KAClH,CAAC;IACF,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD,CAAC;AAoCF,kFAAkF;AAClF,cAAM,2BAA4B,YAAW,cAAc;IAC1D,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAC;IAEvD,YAAY,OAAO,EAAE,0BAA0B,EAE9C;IAEK,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrC;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;IAEK,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAGzF;IAEK,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAG/E;IAED,qDAAqD;IACrD,SAAS,CAAC,KAAK,IAAI,IAAI,CAAG;CAC1B;AAWD;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,2BAA4B,YAAW,cAAc;IACrG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAElC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExC;IAEQ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAEQ,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAE5F;IAEQ,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAElF;IAED,qGAAqG;IACrG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWhF;IAED,0FAA0F;IAC1F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErB;CACD;AAED,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,aAAa,CAAC,CAE1G"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { SqliteStorage } from "./storage.js";
|
|
2
|
+
/** Runs operations one at a time in call order, so a transaction excludes every other operation. */
|
|
3
|
+
class SerialQueue {
|
|
4
|
+
tail = Promise.resolve();
|
|
5
|
+
run(operation) {
|
|
6
|
+
const result = this.tail.then(operation);
|
|
7
|
+
this.tail = result.catch(() => { });
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Durable Object SQL binds numbers as doubles: a `bigint` outside the safe integer range would lose precision. */
|
|
12
|
+
function bindValue(value) {
|
|
13
|
+
if (value instanceof Uint8Array)
|
|
14
|
+
return value.slice().buffer;
|
|
15
|
+
if (typeof value !== "bigint")
|
|
16
|
+
return value;
|
|
17
|
+
if (value < BigInt(Number.MIN_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
18
|
+
throw new RangeError(`Durable Object SQL cannot bind ${value} without losing precision`);
|
|
19
|
+
}
|
|
20
|
+
return Number(value);
|
|
21
|
+
}
|
|
22
|
+
const bind = (params) => params.map(bindValue);
|
|
23
|
+
/** Rows as returned, with `BLOB` columns converted to `Uint8Array` in place; no other copy is made. */
|
|
24
|
+
function rows(rows) {
|
|
25
|
+
for (const row of rows) {
|
|
26
|
+
for (const key in row) {
|
|
27
|
+
const value = row[key];
|
|
28
|
+
if (value instanceof ArrayBuffer)
|
|
29
|
+
row[key] = new Uint8Array(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return rows;
|
|
33
|
+
}
|
|
34
|
+
/** Executes SQL through `ctx.storage.sql`, which has no separate prepare step. */
|
|
35
|
+
class DurableObjectSqliteExecutor {
|
|
36
|
+
storage;
|
|
37
|
+
constructor(storage) {
|
|
38
|
+
this.storage = storage;
|
|
39
|
+
}
|
|
40
|
+
async exec(sql) {
|
|
41
|
+
this.check();
|
|
42
|
+
this.storage.sql.exec(sql);
|
|
43
|
+
}
|
|
44
|
+
async run(sql, ...params) {
|
|
45
|
+
this.check();
|
|
46
|
+
this.storage.sql.exec(sql, ...bind(params));
|
|
47
|
+
}
|
|
48
|
+
async get(sql, ...params) {
|
|
49
|
+
this.check();
|
|
50
|
+
return rows(this.storage.sql.exec(sql, ...bind(params)).toArray())[0];
|
|
51
|
+
}
|
|
52
|
+
async all(sql, ...params) {
|
|
53
|
+
this.check();
|
|
54
|
+
return rows(this.storage.sql.exec(sql, ...bind(params)).toArray());
|
|
55
|
+
}
|
|
56
|
+
/** Throws when this handle may no longer run SQL. */
|
|
57
|
+
check() { }
|
|
58
|
+
}
|
|
59
|
+
/** The handle a transaction callback receives; invalid once the callback settles. */
|
|
60
|
+
class DurableObjectSqliteTransaction extends DurableObjectSqliteExecutor {
|
|
61
|
+
active = true;
|
|
62
|
+
check() {
|
|
63
|
+
if (!this.active)
|
|
64
|
+
throw new Error("SQLite transaction handle is no longer active");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* `SqliteDatabase` adapter for the SQLite storage of a Cloudflare Durable Object. Integers are JavaScript numbers;
|
|
69
|
+
* binding a `bigint` outside the safe integer range throws.
|
|
70
|
+
*/
|
|
71
|
+
export class DurableObjectSqliteDatabase extends DurableObjectSqliteExecutor {
|
|
72
|
+
queue = new SerialQueue();
|
|
73
|
+
exec(sql) {
|
|
74
|
+
return this.queue.run(() => super.exec(sql));
|
|
75
|
+
}
|
|
76
|
+
run(sql, ...params) {
|
|
77
|
+
return this.queue.run(() => super.run(sql, ...params));
|
|
78
|
+
}
|
|
79
|
+
get(sql, ...params) {
|
|
80
|
+
return this.queue.run(() => super.get(sql, ...params));
|
|
81
|
+
}
|
|
82
|
+
all(sql, ...params) {
|
|
83
|
+
return this.queue.run(() => super.all(sql, ...params));
|
|
84
|
+
}
|
|
85
|
+
/** `ctx.storage.transaction()` commits when the callback resolves and rolls back when it rejects. */
|
|
86
|
+
transaction(callback) {
|
|
87
|
+
return this.queue.run(() => this.storage.transaction(async () => {
|
|
88
|
+
const transaction = new DurableObjectSqliteTransaction(this.storage);
|
|
89
|
+
try {
|
|
90
|
+
return await callback(transaction);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
transaction.active = false;
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
/** Waits for queued work. The Durable Object owns its storage, so nothing else closes. */
|
|
98
|
+
close() {
|
|
99
|
+
return this.queue.run(() => { });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Open durable storage on a SQLite-backed Durable Object's `ctx.storage`. */
|
|
103
|
+
export function openDurableObjectSqliteStorage(storage) {
|
|
104
|
+
return SqliteStorage.open(new DurableObjectSqliteDatabase(storage));
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../src/storage/sqlite/cloudflare.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { SqliteStorage } from \"./storage.ts\";\n\n/** Values a Durable Object SQL binding accepts and returns. */\ntype DurableObjectSqlValue = ArrayBuffer | string | number | null;\n\n/**\n * The parts of a SQLite-backed Durable Object's `ctx.storage` this adapter uses, typed structurally so the package\n * needs no Workers type dependency.\n */\nexport type DurableObjectSqliteStorage = {\n\treadonly sql: {\n\t\texec(query: string, ...bindings: DurableObjectSqlValue[]): { toArray(): Record<string, DurableObjectSqlValue>[] };\n\t};\n\ttransaction<T>(closure: () => Promise<T>): Promise<T>;\n};\n\n/** Runs operations one at a time in call order, so a transaction excludes every other operation. */\nclass SerialQueue {\n\tprivate tail: Promise<unknown> = Promise.resolve();\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tconst result = this.tail.then(operation);\n\t\tthis.tail = result.catch(() => {});\n\t\treturn result;\n\t}\n}\n\n/** Durable Object SQL binds numbers as doubles: a `bigint` outside the safe integer range would lose precision. */\nfunction bindValue(value: SqliteValue): DurableObjectSqlValue {\n\tif (value instanceof Uint8Array) return value.slice().buffer as ArrayBuffer;\n\tif (typeof value !== \"bigint\") return value;\n\tif (value < BigInt(Number.MIN_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER)) {\n\t\tthrow new RangeError(`Durable Object SQL cannot bind ${value} without losing precision`);\n\t}\n\treturn Number(value);\n}\n\nconst bind = (params: readonly SqliteValue[]): DurableObjectSqlValue[] => params.map(bindValue);\n\n/** Rows as returned, with `BLOB` columns converted to `Uint8Array` in place; no other copy is made. */\nfunction rows<T>(rows: Record<string, DurableObjectSqlValue>[]): T[] {\n\tfor (const row of rows) {\n\t\tfor (const key in row) {\n\t\t\tconst value = row[key];\n\t\t\tif (value instanceof ArrayBuffer) (row as Record<string, unknown>)[key] = new Uint8Array(value);\n\t\t}\n\t}\n\treturn rows as T[];\n}\n\n/** Executes SQL through `ctx.storage.sql`, which has no separate prepare step. */\nclass DurableObjectSqliteExecutor implements SqliteExecutor {\n\tprotected readonly storage: DurableObjectSqliteStorage;\n\n\tconstructor(storage: DurableObjectSqliteStorage) {\n\t\tthis.storage = storage;\n\t}\n\n\tasync exec(sql: string): Promise<void> {\n\t\tthis.check();\n\t\tthis.storage.sql.exec(sql);\n\t}\n\n\tasync run(sql: string, ...params: SqliteValue[]): Promise<void> {\n\t\tthis.check();\n\t\tthis.storage.sql.exec(sql, ...bind(params));\n\t}\n\n\tasync get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined> {\n\t\tthis.check();\n\t\treturn rows<T>(this.storage.sql.exec(sql, ...bind(params)).toArray())[0];\n\t}\n\n\tasync all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]> {\n\t\tthis.check();\n\t\treturn rows<T>(this.storage.sql.exec(sql, ...bind(params)).toArray());\n\t}\n\n\t/** Throws when this handle may no longer run SQL. */\n\tprotected check(): void {}\n}\n\n/** The handle a transaction callback receives; invalid once the callback settles. */\nclass DurableObjectSqliteTransaction extends DurableObjectSqliteExecutor {\n\tactive = true;\n\n\tprotected override check(): void {\n\t\tif (!this.active) throw new Error(\"SQLite transaction handle is no longer active\");\n\t}\n}\n\n/**\n * `SqliteDatabase` adapter for the SQLite storage of a Cloudflare Durable Object. Integers are JavaScript numbers;\n * binding a `bigint` outside the safe integer range throws.\n */\nexport class DurableObjectSqliteDatabase extends DurableObjectSqliteExecutor implements SqliteDatabase {\n\tprivate readonly queue = new SerialQueue();\n\n\toverride exec(sql: string): Promise<void> {\n\t\treturn this.queue.run(() => super.exec(sql));\n\t}\n\n\toverride run(sql: string, ...params: SqliteValue[]): Promise<void> {\n\t\treturn this.queue.run(() => super.run(sql, ...params));\n\t}\n\n\toverride get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined> {\n\t\treturn this.queue.run(() => super.get<T>(sql, ...params));\n\t}\n\n\toverride all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]> {\n\t\treturn this.queue.run(() => super.all<T>(sql, ...params));\n\t}\n\n\t/** `ctx.storage.transaction()` commits when the callback resolves and rolls back when it rejects. */\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T> {\n\t\treturn this.queue.run(() =>\n\t\t\tthis.storage.transaction(async () => {\n\t\t\t\tconst transaction = new DurableObjectSqliteTransaction(this.storage);\n\t\t\t\ttry {\n\t\t\t\t\treturn await callback(transaction);\n\t\t\t\t} finally {\n\t\t\t\t\ttransaction.active = false;\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t/** Waits for queued work. The Durable Object owns its storage, so nothing else closes. */\n\tclose(): Promise<void> {\n\t\treturn this.queue.run(() => {});\n\t}\n}\n\n/** Open durable storage on a SQLite-backed Durable Object's `ctx.storage`. */\nexport function openDurableObjectSqliteStorage(storage: DurableObjectSqliteStorage): Promise<SqliteStorage> {\n\treturn SqliteStorage.open(new DurableObjectSqliteDatabase(storage));\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Values supported by the portable SQLite storage core. */
|
|
2
|
+
export type SqliteValue = null | number | bigint | string | Uint8Array;
|
|
3
|
+
/**
|
|
4
|
+
* Asynchronous SQL operations shared by a database and its transaction handles.
|
|
5
|
+
*
|
|
6
|
+
* `exec` runs SQL text without bindings and may contain several statements. `run`, `get`, and `all`
|
|
7
|
+
* execute one statement with positional bindings. Adapters may cache prepared statements by SQL text,
|
|
8
|
+
* so callers pass values as bindings instead of interpolating them.
|
|
9
|
+
*/
|
|
10
|
+
export interface SqliteExecutor {
|
|
11
|
+
exec(sql: string): Promise<void>;
|
|
12
|
+
run(sql: string, ...params: SqliteValue[]): Promise<void>;
|
|
13
|
+
get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
|
|
14
|
+
all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Minimal database facade required by `SqliteStorage`.
|
|
18
|
+
*
|
|
19
|
+
* All operations are asynchronous so adapters may execute outside the harness runtime.
|
|
20
|
+
*
|
|
21
|
+
* `transaction` passes the callback a transaction handle. All work in the transaction
|
|
22
|
+
* must use that handle; the handle is invalid after the callback settles. Adapters must
|
|
23
|
+
* queue unrelated operations and other transactions until the transaction finishes. The
|
|
24
|
+
* returned promise settles after commit or rollback. Calling the database itself (including
|
|
25
|
+
* `transaction` or `close`) from inside a callback therefore waits for that transaction and
|
|
26
|
+
* never settles.
|
|
27
|
+
*
|
|
28
|
+
* When the callback rejects, the adapter must roll the transaction back before rejecting
|
|
29
|
+
* with that same error. If rollback fails, it must reject with a different error (for
|
|
30
|
+
* example an `AggregateError`) so callers cannot mistake the callback error for a
|
|
31
|
+
* guaranteed rollback.
|
|
32
|
+
*/
|
|
33
|
+
export interface SqliteDatabase extends SqliteExecutor {
|
|
34
|
+
transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/database.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACrF,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACrD,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/storage/sqlite/database.ts"],"names":[],"mappings":"","sourcesContent":["/** Values supported by the portable SQLite storage core. */\nexport type SqliteValue = null | number | bigint | string | Uint8Array;\n\n/**\n * Asynchronous SQL operations shared by a database and its transaction handles.\n *\n * `exec` runs SQL text without bindings and may contain several statements. `run`, `get`, and `all`\n * execute one statement with positional bindings. Adapters may cache prepared statements by SQL text,\n * so callers pass values as bindings instead of interpolating them.\n */\nexport interface SqliteExecutor {\n\texec(sql: string): Promise<void>;\n\trun(sql: string, ...params: SqliteValue[]): Promise<void>;\n\tget<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;\n\tall<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;\n}\n\n/**\n * Minimal database facade required by `SqliteStorage`.\n *\n * All operations are asynchronous so adapters may execute outside the harness runtime.\n *\n * `transaction` passes the callback a transaction handle. All work in the transaction\n * must use that handle; the handle is invalid after the callback settles. Adapters must\n * queue unrelated operations and other transactions until the transaction finishes. The\n * returned promise settles after commit or rollback. Calling the database itself (including\n * `transaction` or `close`) from inside a callback therefore waits for that transaction and\n * never settles.\n *\n * When the callback rejects, the adapter must roll the transaction back before rejecting\n * with that same error. If rollback fails, it must reject with a different error (for\n * example an `AggregateError`) so callers cannot mistake the callback error for a\n * guaranteed rollback.\n */\nexport interface SqliteDatabase extends SqliteExecutor {\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;\n\tclose(): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
|
|
2
|
+
export { applySqliteMigrations, CURRENT_SQLITE_SCHEMA_VERSION, SQLITE_MIGRATIONS, type SqliteMigration, } from "./migrations.ts";
|
|
3
|
+
export { SqliteStorage } from "./storage.ts";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,EACjB,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,GAEjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nexport {\n\tapplySqliteMigrations,\n\tCURRENT_SQLITE_SCHEMA_VERSION,\n\tSQLITE_MIGRATIONS,\n\ttype SqliteMigration,\n} from \"./migrations.ts\";\nexport { SqliteStorage } from \"./storage.ts\";\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SqliteDatabase } from "./database.ts";
|
|
2
|
+
export type SqliteMigration = {
|
|
3
|
+
readonly version: number;
|
|
4
|
+
readonly statements: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
/** Immutable, ordered schema history. Append new migrations after the initial schema ships. */
|
|
7
|
+
export declare const SQLITE_MIGRATIONS: readonly SqliteMigration[];
|
|
8
|
+
export declare const CURRENT_SQLITE_SCHEMA_VERSION: number;
|
|
9
|
+
/** Apply all pending schema migrations atomically. */
|
|
10
|
+
export declare function applySqliteMigrations(database: SqliteDatabase, migrations?: readonly SqliteMigration[]): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,CAAC;AAiFF,+FAA+F;AAC/F,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAAiD,CAAC;AAE1G,eAAO,MAAM,6BAA6B,QAAyC,CAAC;AAIpF,sDAAsD;AACtD,wBAAsB,qBAAqB,CAC1C,QAAQ,EAAE,cAAc,EACxB,UAAU,GAAE,SAAS,eAAe,EAAsB,GACxD,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// next_id is TEXT because node:sqlite rejects INTEGER results outside JavaScript's safe integer range.
|
|
2
|
+
const INITIAL_SCHEMA = [
|
|
3
|
+
`CREATE TABLE durable_metadata (
|
|
4
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
5
|
+
next_id TEXT NOT NULL,
|
|
6
|
+
next_seq INTEGER NOT NULL
|
|
7
|
+
) STRICT`,
|
|
8
|
+
`INSERT INTO durable_metadata (singleton, next_id, next_seq) VALUES (1, '2', 1)`,
|
|
9
|
+
`CREATE TABLE record_ids (
|
|
10
|
+
id INTEGER PRIMARY KEY,
|
|
11
|
+
record_type TEXT NOT NULL CHECK (record_type IN ('conversation', 'entry', 'task', 'submission', 'document'))
|
|
12
|
+
) STRICT`,
|
|
13
|
+
`CREATE TABLE conversations (
|
|
14
|
+
id INTEGER PRIMARY KEY,
|
|
15
|
+
owner_conversation_id INTEGER,
|
|
16
|
+
owner_task_id INTEGER,
|
|
17
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
18
|
+
) STRICT`,
|
|
19
|
+
"CREATE INDEX conversations_by_owner_conversation ON conversations (owner_conversation_id, id)",
|
|
20
|
+
"CREATE INDEX conversations_by_owner_task ON conversations (owner_task_id, id)",
|
|
21
|
+
`CREATE TABLE entries (
|
|
22
|
+
id INTEGER PRIMARY KEY,
|
|
23
|
+
conversation_id INTEGER NOT NULL,
|
|
24
|
+
head INTEGER,
|
|
25
|
+
commit_seq INTEGER NOT NULL,
|
|
26
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
27
|
+
) STRICT`,
|
|
28
|
+
"CREATE INDEX entries_by_conversation ON entries (conversation_id, id DESC)",
|
|
29
|
+
"CREATE INDEX entry_heads_by_conversation ON entries (conversation_id, id DESC) WHERE head IS NOT NULL",
|
|
30
|
+
`CREATE TABLE tasks (
|
|
31
|
+
id INTEGER PRIMARY KEY,
|
|
32
|
+
conversation_id INTEGER NOT NULL,
|
|
33
|
+
kind TEXT NOT NULL,
|
|
34
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'waiting', 'completing', 'terminal')),
|
|
35
|
+
abort_requested INTEGER NOT NULL CHECK (abort_requested IN (0, 1)),
|
|
36
|
+
background INTEGER NOT NULL CHECK (background IN (0, 1)),
|
|
37
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
38
|
+
) STRICT`,
|
|
39
|
+
"CREATE INDEX tasks_by_status ON tasks (status, id)",
|
|
40
|
+
"CREATE INDEX tasks_by_conversation ON tasks (conversation_id, id)",
|
|
41
|
+
"CREATE INDEX tasks_by_kind ON tasks (kind, id)",
|
|
42
|
+
"CREATE INDEX tasks_by_abort_requested ON tasks (abort_requested, id)",
|
|
43
|
+
"CREATE INDEX tasks_by_background ON tasks (background, id)",
|
|
44
|
+
`CREATE TABLE submissions (
|
|
45
|
+
id INTEGER PRIMARY KEY,
|
|
46
|
+
conversation_id INTEGER NOT NULL,
|
|
47
|
+
request_id TEXT,
|
|
48
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'placed', 'done', 'unanswered')),
|
|
49
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
50
|
+
) STRICT`,
|
|
51
|
+
"CREATE INDEX submissions_by_request ON submissions (conversation_id, request_id)",
|
|
52
|
+
"CREATE INDEX submissions_by_conversation ON submissions (conversation_id, id)",
|
|
53
|
+
"CREATE INDEX submissions_by_status ON submissions (status, id)",
|
|
54
|
+
`CREATE TABLE documents (
|
|
55
|
+
id INTEGER PRIMARY KEY,
|
|
56
|
+
kind TEXT NOT NULL,
|
|
57
|
+
family INTEGER NOT NULL CHECK (family IN (0, 1)),
|
|
58
|
+
key_value TEXT NOT NULL,
|
|
59
|
+
scope_kind TEXT NOT NULL CHECK (scope_kind IN ('session', 'conversation', 'task')),
|
|
60
|
+
owner_id INTEGER NOT NULL,
|
|
61
|
+
created_at INTEGER NOT NULL,
|
|
62
|
+
retired_at INTEGER,
|
|
63
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
64
|
+
) STRICT`,
|
|
65
|
+
`CREATE INDEX documents_by_address
|
|
66
|
+
ON documents (kind, scope_kind, owner_id, family, key_value, created_at DESC, retired_at)`,
|
|
67
|
+
"CREATE INDEX documents_by_scope ON documents (scope_kind, owner_id, id)",
|
|
68
|
+
"CREATE INDEX documents_by_scope_kind ON documents (scope_kind, owner_id, kind, id)",
|
|
69
|
+
`CREATE TABLE document_revisions (
|
|
70
|
+
document_id INTEGER NOT NULL,
|
|
71
|
+
seq INTEGER NOT NULL,
|
|
72
|
+
kind TEXT NOT NULL CHECK (kind IN ('base', 'delta')),
|
|
73
|
+
version INTEGER NOT NULL,
|
|
74
|
+
content TEXT NOT NULL CHECK (json_valid(content)),
|
|
75
|
+
PRIMARY KEY (document_id, seq)
|
|
76
|
+
) STRICT`,
|
|
77
|
+
"CREATE INDEX document_revisions_by_kind ON document_revisions (document_id, kind, seq DESC)",
|
|
78
|
+
];
|
|
79
|
+
/** Immutable, ordered schema history. Append new migrations after the initial schema ships. */
|
|
80
|
+
export const SQLITE_MIGRATIONS = [{ version: 1, statements: INITIAL_SCHEMA }];
|
|
81
|
+
export const CURRENT_SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.at(-1)?.version ?? 0;
|
|
82
|
+
/** Apply all pending schema migrations atomically. */
|
|
83
|
+
export async function applySqliteMigrations(database, migrations = SQLITE_MIGRATIONS) {
|
|
84
|
+
for (let index = 0; index < migrations.length; index++) {
|
|
85
|
+
if (migrations[index]?.version !== index + 1) {
|
|
86
|
+
throw new Error("Durable SQLite migrations must have contiguous versions starting at 1");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
await database.transaction(async (transaction) => {
|
|
90
|
+
await transaction.exec(`CREATE TABLE IF NOT EXISTS durable_schema (
|
|
91
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
92
|
+
version INTEGER NOT NULL CHECK (version >= 0)
|
|
93
|
+
) STRICT`);
|
|
94
|
+
await transaction.run("INSERT OR IGNORE INTO durable_schema (singleton, version) VALUES (1, 0)");
|
|
95
|
+
const row = await transaction.get("SELECT version FROM durable_schema WHERE singleton = 1");
|
|
96
|
+
if (row === undefined)
|
|
97
|
+
throw new Error("Durable SQLite schema metadata is missing");
|
|
98
|
+
const currentVersion = migrations.at(-1)?.version ?? 0;
|
|
99
|
+
if (row.version > currentVersion) {
|
|
100
|
+
throw new Error(`Durable SQLite schema version ${row.version} is newer than supported version ${currentVersion}`);
|
|
101
|
+
}
|
|
102
|
+
for (const migration of migrations) {
|
|
103
|
+
if (migration.version <= row.version)
|
|
104
|
+
continue;
|
|
105
|
+
for (const statement of migration.statements)
|
|
106
|
+
await transaction.exec(statement);
|
|
107
|
+
await transaction.run("UPDATE durable_schema SET version = ? WHERE singleton = 1", migration.version);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=migrations.js.map
|