@effect-agent/storage-cloudflare 0.1.0-beta.111 → 0.1.0-beta.113
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/DoMessageDeliveryStore.d.mts +1 -1
- package/dist/DoMessageDeliveryStore.mjs +1 -1
- package/dist/{DoStorageError-Cmhvl4TQ.d.mts → DoStorageError-DjpuLHmX.d.mts} +4 -1
- package/dist/DoStorageError.d.mts +1 -1
- package/dist/DoStorageError.mjs +5 -2
- package/dist/DoStorageError.mjs.map +1 -1
- package/dist/DoStorageFailpoint.d.mts +1 -1
- package/dist/DoStorageFailpointTesting.d.mts +1 -1
- package/dist/DoSubmissionLedger.mjs +30 -15
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/DoThreadStore.d.mts +1 -1
- package/dist/DoThreadStore.mjs +24 -6
- package/dist/DoThreadStore.mjs.map +1 -1
- package/dist/PortProtocol.d.mts +26 -19
- package/dist/{do-journal-THW8-ZeP.mjs → do-journal-BeHu8_Bh.mjs} +23 -7
- package/dist/do-journal-BeHu8_Bh.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/package.json +1 -1
- package/src/DoStorageError.ts +3 -0
- package/src/DoSubmissionLedger.ts +42 -42
- package/src/DoThreadStore.ts +30 -5
- package/src/internal/do-journal.ts +24 -1
- package/dist/do-journal-THW8-ZeP.mjs.map +0 -1
package/dist/DoThreadStore.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DoStorageCompatibilityError, o as DoStorageCorruptionError, s as DoStorageError } from "./DoStorageError-
|
|
1
|
+
import { a as DoStorageCompatibilityError, o as DoStorageCorruptionError, s as DoStorageError } from "./DoStorageError-DjpuLHmX.mjs";
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint, DoStorageFailpointHandler } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { Crypto, Layer } from "effect";
|
package/dist/DoThreadStore.mjs
CHANGED
|
@@ -2,14 +2,14 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { DoStorageConfig, DoStorageConfigValue } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
|
|
5
|
-
import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-
|
|
5
|
+
import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-BeHu8_Bh.mjs";
|
|
6
6
|
import { Clock, Context, Crypto, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
|
|
7
7
|
import * as SqlClientService from "effect/unstable/sql/SqlClient";
|
|
8
8
|
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
9
9
|
import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "effect-agent/digest";
|
|
10
10
|
import { CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, Digest, ObservationOffset } from "effect-agent/records";
|
|
11
11
|
import { makeSelectedReads } from "effect-agent/sql-thread-native-reads";
|
|
12
|
-
import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, MAX_THREAD_EXPORT_RECORDS, SaveCheckpointRequest, SaveRecoveryCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadReadRequest, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest } from "effect-agent/thread-store";
|
|
12
|
+
import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, MAX_THREAD_EXPORT_RECORDS, SaveCheckpointRequest, SaveRecoveryCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadReadRequest, ThreadStore, ThreadStoreDiagnostic, ThreadStoreError, ThreadTail, ThreadTailRequest } from "effect-agent/thread-store";
|
|
13
13
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
14
14
|
import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "effect-agent/submission-ledger";
|
|
15
15
|
//#region src/DoThreadStore.ts
|
|
@@ -29,12 +29,17 @@ const isDoCheckpointConflict = Schema.is(DoCheckpointConflict);
|
|
|
29
29
|
const storeError = (operation, error) => ThreadStoreError.make({
|
|
30
30
|
cause: error,
|
|
31
31
|
operation,
|
|
32
|
-
message: error.message
|
|
32
|
+
message: error.message,
|
|
33
|
+
...error.diagnostic === void 0 ? {} : { diagnostic: error.diagnostic }
|
|
33
34
|
});
|
|
34
35
|
const schemaStoreError = (operation, error) => ThreadStoreError.make({
|
|
35
|
-
cause: error,
|
|
36
36
|
operation,
|
|
37
|
-
message:
|
|
37
|
+
message: "A Thread storage value does not satisfy its schema",
|
|
38
|
+
diagnostic: ThreadStoreDiagnostic.make({
|
|
39
|
+
causeTag: error._tag,
|
|
40
|
+
operation,
|
|
41
|
+
issueTag: error.issue._tag
|
|
42
|
+
})
|
|
38
43
|
});
|
|
39
44
|
const makeOffset = Effect.fn(function* (threadId, sequence) {
|
|
40
45
|
return yield* Schema.decodeEffect(CanonicalSequence)(sequence).pipe(Effect.flatMap((validatedSequence) => Schema.decodeEffect(ObservationOffset)(`${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`)), Effect.mapError((error) => schemaStoreError("encode observation offset", error)));
|
|
@@ -71,7 +76,20 @@ const encodeCheckpoint = Effect.fn(function* (checkpoint) {
|
|
|
71
76
|
const decodeEnvelope = Effect.fn(function* (row) {
|
|
72
77
|
const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(row.record_json).pipe(Effect.mapError((error) => ThreadStoreError.make({
|
|
73
78
|
operation: "decode canonical record",
|
|
74
|
-
message:
|
|
79
|
+
message: "The canonical record does not satisfy its schema",
|
|
80
|
+
diagnostic: ThreadStoreDiagnostic.make({
|
|
81
|
+
causeTag: error._tag,
|
|
82
|
+
operation: "decode canonical record",
|
|
83
|
+
decoder: "CanonicalRecord",
|
|
84
|
+
sequence: row.sequence,
|
|
85
|
+
issueTag: error.issue._tag
|
|
86
|
+
})
|
|
87
|
+
})), Effect.tapError((error) => Effect.annotateCurrentSpan({
|
|
88
|
+
"storage.failure.operation": error.diagnostic?.operation,
|
|
89
|
+
"storage.failure.cause": error.diagnostic?.causeTag,
|
|
90
|
+
"storage.failure.decoder": error.diagnostic?.decoder,
|
|
91
|
+
"storage.failure.sequence": row.sequence,
|
|
92
|
+
"storage.failure.issue": error.diagnostic?.issueTag
|
|
75
93
|
})));
|
|
76
94
|
const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(row.thread_id).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
|
|
77
95
|
const offset = yield* makeOffset(threadId, row.sequence);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoThreadStore.mjs","names":[],"sources":["../src/DoThreadStore.ts"],"sourcesContent":["import { BrowserCrypto } from \"@effect/platform-browser\";\nimport { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport {\n Clock,\n Context,\n Crypto,\n Duration,\n Effect,\n Layer,\n Option,\n Ref,\n Schema,\n Stream,\n} from \"effect\";\nimport { digestCanonicalBatch, EMPTY_TAIL_DIGEST } from \"effect-agent/digest\";\nimport {\n CanonicalBatch,\n CanonicalRecord,\n CanonicalRecordEnvelope,\n CanonicalSequence,\n Digest,\n ObservationOffset,\n} from \"effect-agent/records\";\nimport { makeSelectedReads } from \"effect-agent/sql-thread-native-reads\";\nimport { DEFAULT_OWNERSHIP_LEASE_DURATION } from \"effect-agent/submission-ledger\";\nimport {\n AppendConflict,\n AppendResult,\n CheckpointRejected,\n ThreadCheckpoint,\n ThreadExport,\n ThreadExportRequest,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadObservation,\n ThreadReadRequest,\n ThreadStore,\n type ThreadCheckpoints,\n ThreadStoreError,\n ThreadTail,\n ThreadTailRequest,\n FenceRejected,\n FencedAppendRequest,\n LoadCheckpointRequest,\n SaveCheckpointRequest,\n SaveRecoveryCheckpointRequest,\n MAX_THREAD_EXPORT_RECORDS,\n type ThreadRecoveryCheckpoints,\n} from \"effect-agent/thread-store\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport {\n DEFAULT_MAX_STORED_VALUE_BYTES,\n DoStorageConfig,\n DoStorageConfigValue,\n} from \"./DoStorageConfig.ts\";\nimport {\n type DoStorageCompatibilityError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoFenceRejected,\n type DoStorageFailpointLocation,\n DoStorageCorruptionError,\n DoStorageError,\n} from \"./DoStorageError.ts\";\nimport { DoStorageFailpoint, type DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\nimport {\n initializeDoJournal,\n RawAppendRequest,\n RawCheckpoint,\n RawReadRequest,\n type DoJournal,\n} from \"./internal/do-journal.ts\";\n\n/**\n * Convenience-layer construction options. `storage` is the Durable Object's own\n * `ctx.storage` handle, injected as a value (DEPLOY-010: platform bindings enter only\n * through Layers; this package never imports `cloudflare:workers`).\n */\nexport interface DoStorageOptions {\n readonly storage: DurableObjectStorage;\n readonly observationPollInterval?: number | undefined;\n /**\n * Submission ownership lease duration in milliseconds (D5). Defaults to\n * `DEFAULT_OWNERSHIP_LEASE_DURATION` from `effect-agent/submission-ledger`.\n */\n readonly ownershipLeaseDuration?: number | undefined;\n /**\n * Maximum bytes for any single stored value; must stay under the platform's 2 MB\n * per-value limit. Defaults to `DEFAULT_MAX_STORED_VALUE_BYTES`.\n */\n readonly maxStoredValueBytes?: number | undefined;\n /**\n * Re-verify every stored payload and digest chain while opening the store. Defaults to\n * off: per-operation Schema decoding and the digest chain already fail clearly on corrupt\n * rows without scanning the whole database on every open.\n */\n readonly verifyOnOpen?: boolean | undefined;\n readonly failpoint?: DoStorageFailpointHandler | undefined;\n}\n\nexport type DoStorageInitializationError =\n | DoStorageCompatibilityError\n | DoStorageCorruptionError\n | DoStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst DO_OFFSET_PREFIX = \"effect-agent-do@1:\";\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDigest = Schema.is(Digest);\nconst isDoFenceRejected = Schema.is(DoFenceRejected);\nconst isDoAppendConflict = Schema.is(DoAppendConflict);\nconst isDoCheckpointConflict = Schema.is(DoCheckpointConflict);\n\nconst storeError = (operation: string, error: { readonly message: string }) =>\n ThreadStoreError.make({\n cause: error,\n operation,\n message: error.message,\n });\n\nconst schemaStoreError = (operation: string, error: { readonly message: string }) =>\n ThreadStoreError.make({\n cause: error,\n operation,\n message: error.message,\n });\n\nconst makeOffset = Effect.fn(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: number,\n): Effect.fn.Return<ObservationOffset, ThreadStoreError> {\n return yield* Schema.decodeEffect(CanonicalSequence)(sequence).pipe(\n Effect.flatMap((validatedSequence) =>\n Schema.decodeEffect(ObservationOffset)(\n `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n});\n\nconst parseOffset = Effect.fn(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n offset: ObservationOffset | undefined,\n): Effect.fn.Return<CanonicalSequence, ThreadStoreError> {\n if (offset === undefined) return ZERO_CANONICAL_SEQUENCE;\n\n const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n\n const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;\n\n if (!text.startsWith(threadPrefix)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset belongs to a different adapter, storage version, or Thread.\",\n });\n }\n const sequenceText = text.slice(threadPrefix.length);\n\n if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset is malformed.\",\n });\n }\n\n return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n});\n\nconst mapFence = (threadId: ThreadMaterialization[\"threadId\"], error: DoFenceRejected) =>\n FenceRejected.make({\n threadId,\n actualEpoch: error.actualEpoch,\n attemptedEpoch: error.producerEpoch,\n });\n\nconst encodeCanonicalRecord = Effect.fn(function* (\n record: CanonicalRecord,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(record).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode canonical record\", error)),\n );\n});\n\nconst encodeCanonicalBatch = Effect.fn(function* (\n batch: CanonicalBatch,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalBatch))(batch).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode canonical batch\", error)),\n );\n});\n\nconst encodeCheckpoint = Effect.fn(function* (\n checkpoint: ThreadCheckpoint,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode checkpoint\", error)),\n );\n});\n\nconst decodeEnvelope = Effect.fn(function* (row: {\n readonly batch_id: string;\n readonly thread_id: string;\n readonly record_json: string;\n readonly sequence: CanonicalSequence;\n}) {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n row.record_json,\n ).pipe(\n Effect.mapError((error) =>\n ThreadStoreError.make({\n operation: \"decode canonical record\",\n message: error.message,\n }),\n ),\n );\n\n const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(\n row.thread_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode thread identity\", error)));\n\n const offset = yield* makeOffset(threadId, row.sequence);\n\n const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(\n row.batch_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode batch identity\", error)));\n\n return CanonicalRecordEnvelope.make({\n threadId,\n batchId,\n sequence: row.sequence,\n offset,\n record,\n });\n});\n\nconst decodeCheckpoint = Effect.fn(function* (\n checkpointJson: string,\n): Effect.fn.Return<ThreadCheckpoint, ThreadStoreError> {\n return yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpointJson).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint\", error)),\n );\n});\n\nconst requireThread = Effect.fn(\"DoThreadStore.requireThread\")(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n) {\n const rows = yield* journal\n .getThread(threadId)\n .pipe(Effect.mapError((error) => storeError(\"read thread\", error)));\n\n if (rows.length === 0) {\n return yield* ThreadNotMaterialized.make({ threadId });\n }\n\n return rows[0];\n});\n\nconst tailDigestAt = Effect.fn(\"DoThreadStore.tailDigestAt\")(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: CanonicalSequence,\n) {\n if (sequence === 0) return EMPTY_TAIL_DIGEST;\n\n const digests = yield* journal\n .getTailDigestAt(threadId, sequence)\n .pipe(Effect.mapError((error) => storeError(\"read checkpoint digest\", error)));\n\n if (digests.length !== 1) {\n return yield* CheckpointRejected.make({\n threadId,\n reason: \"digest-mismatch\",\n });\n }\n\n return yield* Schema.decodeEffect(Digest)(digests[0]).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint digest\", error)),\n );\n});\n\nconst groupByKey = <A>(\n rows: ReadonlyArray<A>,\n key: (row: A) => string,\n): ReadonlyMap<string, ReadonlyArray<A>> => {\n const grouped = new Map<string, Array<A>>();\n\n for (const row of rows) {\n const existing = grouped.get(key(row));\n\n if (existing === undefined) {\n grouped.set(key(row), [row]);\n } else {\n existing.push(row);\n }\n }\n\n return grouped;\n};\n\n/**\n * Opt-in integrity audit (`verifyOnOpen`) of canonical payloads, their digest chains and generic\n * projection checkpoints. Disposable recovery checkpoints are validated when loaded. Routine opens\n * skip this scan: per-operation Schema decoding fails clearly on corrupt canonical rows.\n */\nconst decodeStartupPayloads = Effect.fn(\"DoThreadStore.decodeStartupPayloads\")(function* (\n journal: DoJournal,\n crypto: Crypto.Crypto,\n) {\n const stored = yield* journal.scanStoredPayloads();\n\n const batches = yield* Effect.forEach(stored.batches, (batch) =>\n Schema.decodeEffect(Schema.fromJsonString(CanonicalBatch))(batch.batch_json).pipe(\n Effect.map((decoded) => ({ decoded, row: batch })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: `${batch.thread_id}/${batch.batch_id}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const records = yield* Effect.forEach(stored.records, (record) =>\n Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(record.record_json).pipe(\n Effect.map((decoded) => ({ decoded, row: record })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${record.thread_id}/${record.sequence}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const checkpoints = yield* Effect.forEach(stored.checkpoints, (checkpoint) =>\n Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint.checkpoint_json).pipe(\n Effect.map((decoded) => ({ decoded, row: checkpoint })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.thread_id}/${checkpoint.through_sequence}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const batchesByThread = groupByKey(batches, ({ row }) => row.thread_id);\n const recordsByThread = groupByKey(records, ({ row }) => row.thread_id);\n const checkpointsByThread = groupByKey(checkpoints, ({ row }) => row.thread_id);\n const materializedIds = new Set(stored.threads.map((thread) => thread.thread_id));\n\n for (const thread of stored.threads) {\n const threadBatches = batchesByThread.get(thread.thread_id) ?? [];\n const threadRecords = recordsByThread.get(thread.thread_id) ?? [];\n const threadCheckpoints = checkpointsByThread.get(thread.thread_id) ?? [];\n const recordsByBatch = groupByKey(threadRecords, ({ row }) => row.batch_id);\n let previousDigest = EMPTY_TAIL_DIGEST;\n let expectedSequence = 1;\n const tailDigests = new Map<number, string>([[0, EMPTY_TAIL_DIGEST]]);\n\n for (const { decoded: canonicalBatch, row: batchRow } of threadBatches) {\n const key = `${batchRow.thread_id}/${batchRow.batch_id}`;\n\n if (\n canonicalBatch.batchId !== batchRow.batch_id ||\n batchRow.first_sequence !== expectedSequence ||\n batchRow.last_sequence !== batchRow.first_sequence + canonicalBatch.records.length - 1\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: \"Canonical batch identity, sequence, or record count is inconsistent.\",\n });\n }\n\n const digest = yield* digestCanonicalBatch(previousDigest, canonicalBatch).pipe(\n Effect.provideService(Crypto.Crypto, crypto),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: error.message,\n }),\n ),\n );\n\n if (batchRow.batch_digest !== digest || batchRow.tail_digest !== digest) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: \"Canonical batch digest does not match its decoded content and prior tail.\",\n });\n }\n\n const batchRecords = recordsByBatch.get(batchRow.batch_id) ?? [];\n\n if (batchRecords.length !== canonicalBatch.records.length) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: key,\n message: \"Canonical batch and record-table counts differ.\",\n });\n }\n for (let index = 0; index < canonicalBatch.records.length; index++) {\n const expectedRecord = canonicalBatch.records[index];\n const storedRecord = batchRecords[index];\n\n const expectedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(\n expectedRecord,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: error.message,\n }),\n ),\n );\n\n const storedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(\n storedRecord.decoded,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${key}/${storedRecord.row.sequence}`,\n message: error.message,\n }),\n ),\n );\n\n if (\n storedRecord.row.sequence !== batchRow.first_sequence + index ||\n storedRecord.row.record_id !== expectedRecord.recordId ||\n expectedJson !== storedJson\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${key}/${storedRecord.row.sequence}`,\n message: \"Canonical record identity, sequence, or payload differs from its batch.\",\n });\n }\n }\n\n previousDigest = digest;\n expectedSequence = batchRow.last_sequence + 1;\n tailDigests.set(batchRow.last_sequence, digest);\n }\n\n if (\n threadRecords.length !== thread.tail_sequence ||\n thread.tail_sequence !== expectedSequence - 1 ||\n thread.tail_digest !== previousDigest\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: thread.thread_id,\n message: \"Thread tail does not match its canonical batch chain.\",\n });\n }\n\n for (const checkpoint of threadCheckpoints) {\n if (\n checkpoint.decoded.threadId !== thread.thread_id ||\n checkpoint.decoded.throughSequence !== checkpoint.row.through_sequence ||\n checkpoint.decoded.tailDigest !== checkpoint.row.tail_digest ||\n tailDigests.get(checkpoint.row.through_sequence) !== checkpoint.row.tail_digest\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${thread.thread_id}/${checkpoint.row.through_sequence}`,\n message: \"Checkpoint identity or digest is not bound to a canonical batch tail.\",\n });\n }\n }\n }\n\n if (\n batches.some(({ row }) => !materializedIds.has(row.thread_id)) ||\n records.some(({ row }) => !materializedIds.has(row.thread_id)) ||\n checkpoints.some(({ row }) => !materializedIds.has(row.thread_id))\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: \"startup_scan\",\n message: \"Canonical rows exist without a materialized Thread.\",\n });\n }\n});\n\nconst makeServices = Effect.fn(\"DoThreadStore.makeServices\")(function* () {\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n const sql = yield* SqlClientService.SqlClient;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);\n\n if (config.verifyOnOpen) {\n yield* decodeStartupPayloads(journal, crypto);\n }\n\n const provideCrypto = <A, E>(effect: Effect.Effect<A, E, Crypto.Crypto>) =>\n Effect.provideService(effect, Crypto.Crypto, crypto);\n\n const hitFailpoint = Effect.fn(\n (location: DoStorageFailpointLocation): Effect.Effect<void, ThreadStoreError> =>\n failpoint\n .hit(location)\n .pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error))),\n );\n\n const materialize: ThreadStore[\"Service\"][\"materialize\"] = Effect.fn(\"DoThreadStore.materialize\")(\n function* (request: ThreadMaterialization) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate materialization\", error)));\n\n const now = yield* Clock.currentTimeMillis;\n\n yield* hitFailpoint(\"materialize:before\");\n yield* journal\n .materialize(\n validated.threadId,\n new Date(now).toISOString(),\n EMPTY_TAIL_DIGEST,\n validated.producerEpoch,\n )\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"DoFenceRejected\"\n ? mapFence(validated.threadId, error)\n : storeError(\"materialize thread\", error),\n ),\n );\n yield* hitFailpoint(\"materialize:after\");\n },\n );\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fn(\"DoThreadStore.append\")(function* (\n request: FencedAppendRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(FencedAppendRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate canonical append\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n\n const tailDigest = yield* provideCrypto(\n digestCanonicalBatch(validated.expectedTailDigest, validated.batch),\n ).pipe(Effect.mapError((error) => storeError(\"digest canonical append\", error)));\n\n const batchJson = yield* encodeCanonicalBatch(validated.batch);\n\n const rawRecords = yield* Effect.forEach(validated.batch.records, (record) =>\n encodeCanonicalRecord(record).pipe(\n Effect.map((recordJson) => ({\n recordId: record.recordId,\n recordJson,\n })),\n ),\n );\n\n const rawRequest = yield* Schema.decodeEffect(RawAppendRequest)({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n batchDigest: tailDigest,\n batchJson,\n expectedTailSequence: validated.expectedTailSequence,\n expectedTailDigest: validated.expectedTailDigest,\n producerEpoch: validated.producerEpoch,\n records: rawRecords,\n tailDigest,\n }).pipe(Effect.mapError((error) => schemaStoreError(\"encode canonical append\", error)));\n\n yield* hitFailpoint(\"append:before\");\n\n const result = yield* journal.append(rawRequest).pipe(\n Effect.mapError((error) => {\n if (isDoFenceRejected(error)) {\n return mapFence(validated.threadId, error);\n }\n if (isDoAppendConflict(error)) {\n return error.actualTailSequence !== undefined && isDigest(error.actualTailDigest)\n ? AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n actualTailSequence: error.actualTailSequence,\n actualTailDigest: error.actualTailDigest,\n })\n : AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n });\n }\n\n return storeError(\"append canonical batch\", error);\n }),\n Effect.flatMap((result) =>\n Schema.decodeEffect(AppendResult)(result).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode append result\", error)),\n ),\n ),\n );\n\n yield* hitFailpoint(\"append:after\");\n\n return result;\n });\n\n const loadRecords = Effect.fnUntraced(function* (request: RawReadRequest) {\n const result = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return {\n count: result.count,\n records: result.records.pipe(\n Stream.mapError((error) => storeError(\"read canonical records\", error)),\n Stream.mapEffect(decodeEnvelope),\n ),\n };\n });\n\n const readEffect = Effect.fn(\"DoThreadStore.read\")(function* (request: ThreadReadRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\n if (\"selection\" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));\n yield* requireThread(journal, validated.threadId);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive: validated.afterSequence ?? ZERO_CANONICAL_SEQUENCE,\n limit: validated.limit,\n }),\n );\n\n return result.records;\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fnUntraced(function* (request: ThreadObservation) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread observation\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);\n const cursor = yield* Ref.make(initialSequence);\n let polls = 0;\n let emptyPolls = 0;\n let deliveredRecords = 0;\n\n const poll = Effect.fnUntraced(function* () {\n polls++;\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (result.count === 0) {\n emptyPolls++;\n yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(\n Stream.tap((record) => {\n deliveredRecords++;\n\n return Ref.set(cursor, record.sequence);\n }),\n );\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(\n Stream.flatten,\n Stream.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n \"effect_agent.observation.polls\": polls,\n \"effect_agent.observation.empty_polls\": emptyPolls,\n \"effect_agent.observation.records\": deliveredRecords,\n }),\n ),\n ),\n );\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request)).pipe(Stream.withSpan(\"DoThreadStore.observe\"));\n\n const exportThread: ThreadStore[\"Service\"][\"export\"] = Effect.fn(\"DoThreadStore.export\")(\n function* (request: ThreadExportRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadExportRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate thread export\", error)));\n\n yield* requireThread(journal, validated.threadId);\n\n const exported = yield* journal\n .exportThread(validated.threadId)\n .pipe(Effect.mapError((error) => storeError(\"export thread\", error)));\n\n const records = yield* Effect.forEach(exported.records, decodeEnvelope);\n\n if (records.length > MAX_THREAD_EXPORT_RECORDS) {\n return yield* ThreadStoreError.make({\n operation: \"decode thread export\",\n message: \"The thread exceeds the current export record limit.\",\n });\n }\n\n const tailDigest = yield* Schema.decodeEffect(Digest)(exported.thread.tail_digest).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode export tail digest\", error)),\n );\n\n return ThreadExport.make({\n format: \"effect-agent/thread@1\",\n threadId: validated.threadId,\n tailSequence: exported.thread.tail_sequence,\n tailDigest,\n records,\n });\n },\n );\n\n const inspectTail: ThreadStore[\"Service\"][\"inspectTail\"] = Effect.fn(\"DoThreadStore.inspectTail\")(\n function* (request: ThreadTailRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate tail inspection\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const tailDigest = yield* Schema.decodeEffect(Digest)(thread.tail_digest).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode tail digest\", error)),\n );\n\n return ThreadTail.make({\n threadId: validated.threadId,\n tailSequence: thread.tail_sequence,\n tailDigest,\n producerEpoch: thread.producer_epoch,\n });\n },\n );\n\n const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fn(\"DoThreadStore.saveCheckpoint\")(\n function* (request: SaveCheckpointRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint\", error)));\n\n const thread = yield* requireThread(journal, validated.checkpoint.threadId);\n\n if (validated.checkpoint.throughSequence > thread.tail_sequence) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n }\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n validated.checkpoint.threadId,\n validated.checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== validated.checkpoint.tailDigest) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n }\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n const raw = RawCheckpoint.make({\n threadId: validated.checkpoint.threadId,\n throughSequence: validated.checkpoint.throughSequence,\n tailDigest: validated.checkpoint.tailDigest,\n checkpointJson,\n });\n\n yield* hitFailpoint(\"save-checkpoint:before\");\n yield* journal.saveCheckpoint(raw).pipe(\n Effect.mapError((error) =>\n isDoCheckpointConflict(error)\n ? CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"digest-mismatch\",\n })\n : storeError(\"save checkpoint\", error),\n ),\n );\n yield* hitFailpoint(\"save-checkpoint:after\");\n },\n );\n\n const loadCheckpoint: ThreadCheckpoints[\"load\"] = Effect.fn(\"DoThreadStore.loadCheckpoint\")(\n function* (request: LoadCheckpointRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint lookup\", error)));\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const rows = yield* journal\n .loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence)\n .pipe(Effect.mapError((error) => storeError(\"load checkpoint\", error)));\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: `Expected at most one checkpoint row but found ${rows.length}.`,\n });\n }\n const row = rows[0];\n const checkpoint = yield* decodeCheckpoint(row.checkpoint_json);\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence ||\n checkpoint.tailDigest !== row.tail_digest\n ) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: \"Stored checkpoint metadata does not match its canonical row.\",\n });\n }\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n checkpoint.threadId,\n checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== checkpoint.tailDigest) {\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n }\n\n return Option.some(checkpoint);\n },\n );\n\n const saveRecoveryCheckpoint: ThreadRecoveryCheckpoints[\"save\"] = Effect.fn(\n \"DoThreadStore.saveRecoveryCheckpoint\",\n )(function* (request) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveRecoveryCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate recovery checkpoint\", error)));\n\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n yield* journal\n .saveRecoveryCheckpoint(validated, checkpointJson)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"CheckpointRejected\" ||\n error._tag === \"FenceRejected\" ||\n error._tag === \"ThreadNotMaterialized\"\n ? error\n : storeError(\"save recovery checkpoint\", error),\n ),\n );\n });\n\n const loadRecoveryCheckpoint: ThreadRecoveryCheckpoints[\"load\"] = Effect.fn(\n \"DoThreadStore.loadRecoveryCheckpoint\",\n )(function* (request) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate recovery checkpoint lookup\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const corrupt = () =>\n CheckpointRejected.make({ threadId: validated.threadId, reason: \"corrupt\" });\n\n const rows = yield* journal\n .loadRecoveryCheckpoint(validated.threadId)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"DoStorageCorruptionError\"\n ? corrupt()\n : storeError(\"load recovery checkpoint\", error),\n ),\n );\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) return yield* corrupt();\n const row = rows[0];\n\n const checkpoint = yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(\n row.checkpoint_json,\n ).pipe(Effect.mapError(corrupt));\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence ||\n checkpoint.tailDigest !== row.tail_digest\n )\n return yield* corrupt();\n if (checkpoint.throughSequence > thread.tail_sequence)\n return yield* CheckpointRejected.make({\n threadId: validated.threadId,\n reason: \"ahead-of-tail\",\n });\n if (checkpoint.throughSequence > (validated.atOrBeforeSequence ?? thread.tail_sequence))\n return Option.none();\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n checkpoint.threadId,\n checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== checkpoint.tailDigest)\n return yield* CheckpointRejected.make({\n threadId: validated.threadId,\n reason: \"digest-mismatch\",\n });\n\n return Option.some(checkpoint);\n });\n\n const selectedReads = yield* makeSelectedReads(decodeEnvelope);\n\n const threadStore = ThreadStore.of({\n countPeerMessages: selectedReads.countPeerMessages,\n append,\n export: exportThread,\n inspectTail,\n materialize,\n observe,\n read,\n checkpoints: { save: saveCheckpoint, load: loadCheckpoint },\n recoveryCheckpoints: { save: saveRecoveryCheckpoint, load: loadRecoveryCheckpoint },\n });\n\n return Context.make(ThreadStore, threadStore);\n});\n\n/**\n * Durable Object Thread Store implementation with configuration, failpoint, SQL, and\n * Crypto authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore,\n DoStorageInitializationError,\n DoStorageConfig | DoStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = Layer.effectContext(makeServices());\n\n/**\n * Validated Durable Object storage configuration Layer with the documented defaults applied.\n * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults\n * cannot drift.\n */\nexport const storageConfigLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageConfig, DoStorageError> =>\n Layer.effect(DoStorageConfig)(\n Schema.decodeEffect(DoStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n ownershipLeaseDuration:\n options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),\n maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"configure Durable Object storage\",\n message: error.message,\n }),\n ),\n ),\n );\n\n/** The failpoint Layer selected by convenience options: explicit handler or the no-op default. */\nexport const storageFailpointLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageFailpoint> =>\n options.failpoint === undefined\n ? DoStorageFailpoint.layer\n : Layer.succeed(DoStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads inside one Durable Object,\n * built over `ctx.storage`. Durable accepted work is served by the separate SubmissionLedger\n * port; point both at the SAME `ctx.storage` so claims fence the same producer epochs\n * (ADR-0011 D7's \"same file\" rule, transposed to one object's private database).\n */\nexport const layer = (\n options: DoStorageOptions,\n): Layer.Layer<ThreadStore, DoStorageInitializationError> =>\n Layer.unwrap(\n Effect.map(DoStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(DoStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ storage: options.storage }),\n BrowserCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DoThreadStore.mjs","names":[],"sources":["../src/DoThreadStore.ts"],"sourcesContent":["import { BrowserCrypto } from \"@effect/platform-browser\";\nimport { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport {\n Clock,\n Context,\n Crypto,\n Duration,\n Effect,\n Layer,\n Option,\n Ref,\n Schema,\n Stream,\n} from \"effect\";\nimport { digestCanonicalBatch, EMPTY_TAIL_DIGEST } from \"effect-agent/digest\";\nimport {\n CanonicalBatch,\n CanonicalRecord,\n CanonicalRecordEnvelope,\n CanonicalSequence,\n Digest,\n ObservationOffset,\n} from \"effect-agent/records\";\nimport { makeSelectedReads } from \"effect-agent/sql-thread-native-reads\";\nimport { DEFAULT_OWNERSHIP_LEASE_DURATION } from \"effect-agent/submission-ledger\";\nimport {\n AppendConflict,\n AppendResult,\n CheckpointRejected,\n ThreadCheckpoint,\n ThreadExport,\n ThreadExportRequest,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadObservation,\n ThreadReadRequest,\n ThreadStore,\n type ThreadCheckpoints,\n ThreadStoreError,\n ThreadStoreDiagnostic,\n ThreadTail,\n ThreadTailRequest,\n FenceRejected,\n FencedAppendRequest,\n LoadCheckpointRequest,\n SaveCheckpointRequest,\n SaveRecoveryCheckpointRequest,\n MAX_THREAD_EXPORT_RECORDS,\n type ThreadRecoveryCheckpoints,\n} from \"effect-agent/thread-store\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport {\n DEFAULT_MAX_STORED_VALUE_BYTES,\n DoStorageConfig,\n DoStorageConfigValue,\n} from \"./DoStorageConfig.ts\";\nimport {\n type DoStorageCompatibilityError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoFenceRejected,\n type DoStorageFailpointLocation,\n DoStorageCorruptionError,\n DoStorageError,\n} from \"./DoStorageError.ts\";\nimport { DoStorageFailpoint, type DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\nimport {\n initializeDoJournal,\n RawAppendRequest,\n RawCheckpoint,\n RawReadRequest,\n type DoJournal,\n} from \"./internal/do-journal.ts\";\n\n/**\n * Convenience-layer construction options. `storage` is the Durable Object's own\n * `ctx.storage` handle, injected as a value (DEPLOY-010: platform bindings enter only\n * through Layers; this package never imports `cloudflare:workers`).\n */\nexport interface DoStorageOptions {\n readonly storage: DurableObjectStorage;\n readonly observationPollInterval?: number | undefined;\n /**\n * Submission ownership lease duration in milliseconds (D5). Defaults to\n * `DEFAULT_OWNERSHIP_LEASE_DURATION` from `effect-agent/submission-ledger`.\n */\n readonly ownershipLeaseDuration?: number | undefined;\n /**\n * Maximum bytes for any single stored value; must stay under the platform's 2 MB\n * per-value limit. Defaults to `DEFAULT_MAX_STORED_VALUE_BYTES`.\n */\n readonly maxStoredValueBytes?: number | undefined;\n /**\n * Re-verify every stored payload and digest chain while opening the store. Defaults to\n * off: per-operation Schema decoding and the digest chain already fail clearly on corrupt\n * rows without scanning the whole database on every open.\n */\n readonly verifyOnOpen?: boolean | undefined;\n readonly failpoint?: DoStorageFailpointHandler | undefined;\n}\n\nexport type DoStorageInitializationError =\n | DoStorageCompatibilityError\n | DoStorageCorruptionError\n | DoStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst DO_OFFSET_PREFIX = \"effect-agent-do@1:\";\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDigest = Schema.is(Digest);\nconst isDoFenceRejected = Schema.is(DoFenceRejected);\nconst isDoAppendConflict = Schema.is(DoAppendConflict);\nconst isDoCheckpointConflict = Schema.is(DoCheckpointConflict);\n\nconst storeError = (\n operation: string,\n error: { readonly message: string; readonly diagnostic?: ThreadStoreDiagnostic },\n) =>\n ThreadStoreError.make({\n cause: error,\n operation,\n message: error.message,\n ...(error.diagnostic === undefined ? {} : { diagnostic: error.diagnostic }),\n });\n\nconst schemaStoreError = (operation: string, error: Schema.SchemaError) =>\n ThreadStoreError.make({\n operation,\n message: \"A Thread storage value does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.issue._tag,\n }),\n });\n\nconst makeOffset = Effect.fn(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: number,\n): Effect.fn.Return<ObservationOffset, ThreadStoreError> {\n return yield* Schema.decodeEffect(CanonicalSequence)(sequence).pipe(\n Effect.flatMap((validatedSequence) =>\n Schema.decodeEffect(ObservationOffset)(\n `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n});\n\nconst parseOffset = Effect.fn(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n offset: ObservationOffset | undefined,\n): Effect.fn.Return<CanonicalSequence, ThreadStoreError> {\n if (offset === undefined) return ZERO_CANONICAL_SEQUENCE;\n\n const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n\n const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;\n\n if (!text.startsWith(threadPrefix)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset belongs to a different adapter, storage version, or Thread.\",\n });\n }\n const sequenceText = text.slice(threadPrefix.length);\n\n if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset is malformed.\",\n });\n }\n\n return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n});\n\nconst mapFence = (threadId: ThreadMaterialization[\"threadId\"], error: DoFenceRejected) =>\n FenceRejected.make({\n threadId,\n actualEpoch: error.actualEpoch,\n attemptedEpoch: error.producerEpoch,\n });\n\nconst encodeCanonicalRecord = Effect.fn(function* (\n record: CanonicalRecord,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(record).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode canonical record\", error)),\n );\n});\n\nconst encodeCanonicalBatch = Effect.fn(function* (\n batch: CanonicalBatch,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalBatch))(batch).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode canonical batch\", error)),\n );\n});\n\nconst encodeCheckpoint = Effect.fn(function* (\n checkpoint: ThreadCheckpoint,\n): Effect.fn.Return<string, ThreadStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode checkpoint\", error)),\n );\n});\n\nconst decodeEnvelope = Effect.fn(function* (row: {\n readonly batch_id: string;\n readonly thread_id: string;\n readonly record_json: string;\n readonly sequence: CanonicalSequence;\n}) {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n row.record_json,\n ).pipe(\n Effect.mapError((error) =>\n ThreadStoreError.make({\n operation: \"decode canonical record\",\n message: \"The canonical record does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode canonical record\",\n decoder: \"CanonicalRecord\",\n sequence: row.sequence,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": error.diagnostic?.decoder,\n \"storage.failure.sequence\": row.sequence,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(\n row.thread_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode thread identity\", error)));\n\n const offset = yield* makeOffset(threadId, row.sequence);\n\n const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(\n row.batch_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode batch identity\", error)));\n\n return CanonicalRecordEnvelope.make({\n threadId,\n batchId,\n sequence: row.sequence,\n offset,\n record,\n });\n});\n\nconst decodeCheckpoint = Effect.fn(function* (\n checkpointJson: string,\n): Effect.fn.Return<ThreadCheckpoint, ThreadStoreError> {\n return yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpointJson).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint\", error)),\n );\n});\n\nconst requireThread = Effect.fn(\"DoThreadStore.requireThread\")(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n) {\n const rows = yield* journal\n .getThread(threadId)\n .pipe(Effect.mapError((error) => storeError(\"read thread\", error)));\n\n if (rows.length === 0) {\n return yield* ThreadNotMaterialized.make({ threadId });\n }\n\n return rows[0];\n});\n\nconst tailDigestAt = Effect.fn(\"DoThreadStore.tailDigestAt\")(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: CanonicalSequence,\n) {\n if (sequence === 0) return EMPTY_TAIL_DIGEST;\n\n const digests = yield* journal\n .getTailDigestAt(threadId, sequence)\n .pipe(Effect.mapError((error) => storeError(\"read checkpoint digest\", error)));\n\n if (digests.length !== 1) {\n return yield* CheckpointRejected.make({\n threadId,\n reason: \"digest-mismatch\",\n });\n }\n\n return yield* Schema.decodeEffect(Digest)(digests[0]).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint digest\", error)),\n );\n});\n\nconst groupByKey = <A>(\n rows: ReadonlyArray<A>,\n key: (row: A) => string,\n): ReadonlyMap<string, ReadonlyArray<A>> => {\n const grouped = new Map<string, Array<A>>();\n\n for (const row of rows) {\n const existing = grouped.get(key(row));\n\n if (existing === undefined) {\n grouped.set(key(row), [row]);\n } else {\n existing.push(row);\n }\n }\n\n return grouped;\n};\n\n/**\n * Opt-in integrity audit (`verifyOnOpen`) of canonical payloads, their digest chains and generic\n * projection checkpoints. Disposable recovery checkpoints are validated when loaded. Routine opens\n * skip this scan: per-operation Schema decoding fails clearly on corrupt canonical rows.\n */\nconst decodeStartupPayloads = Effect.fn(\"DoThreadStore.decodeStartupPayloads\")(function* (\n journal: DoJournal,\n crypto: Crypto.Crypto,\n) {\n const stored = yield* journal.scanStoredPayloads();\n\n const batches = yield* Effect.forEach(stored.batches, (batch) =>\n Schema.decodeEffect(Schema.fromJsonString(CanonicalBatch))(batch.batch_json).pipe(\n Effect.map((decoded) => ({ decoded, row: batch })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: `${batch.thread_id}/${batch.batch_id}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const records = yield* Effect.forEach(stored.records, (record) =>\n Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(record.record_json).pipe(\n Effect.map((decoded) => ({ decoded, row: record })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${record.thread_id}/${record.sequence}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const checkpoints = yield* Effect.forEach(stored.checkpoints, (checkpoint) =>\n Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint.checkpoint_json).pipe(\n Effect.map((decoded) => ({ decoded, row: checkpoint })),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.thread_id}/${checkpoint.through_sequence}`,\n message: error.message,\n }),\n ),\n ),\n );\n\n const batchesByThread = groupByKey(batches, ({ row }) => row.thread_id);\n const recordsByThread = groupByKey(records, ({ row }) => row.thread_id);\n const checkpointsByThread = groupByKey(checkpoints, ({ row }) => row.thread_id);\n const materializedIds = new Set(stored.threads.map((thread) => thread.thread_id));\n\n for (const thread of stored.threads) {\n const threadBatches = batchesByThread.get(thread.thread_id) ?? [];\n const threadRecords = recordsByThread.get(thread.thread_id) ?? [];\n const threadCheckpoints = checkpointsByThread.get(thread.thread_id) ?? [];\n const recordsByBatch = groupByKey(threadRecords, ({ row }) => row.batch_id);\n let previousDigest = EMPTY_TAIL_DIGEST;\n let expectedSequence = 1;\n const tailDigests = new Map<number, string>([[0, EMPTY_TAIL_DIGEST]]);\n\n for (const { decoded: canonicalBatch, row: batchRow } of threadBatches) {\n const key = `${batchRow.thread_id}/${batchRow.batch_id}`;\n\n if (\n canonicalBatch.batchId !== batchRow.batch_id ||\n batchRow.first_sequence !== expectedSequence ||\n batchRow.last_sequence !== batchRow.first_sequence + canonicalBatch.records.length - 1\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: \"Canonical batch identity, sequence, or record count is inconsistent.\",\n });\n }\n\n const digest = yield* digestCanonicalBatch(previousDigest, canonicalBatch).pipe(\n Effect.provideService(Crypto.Crypto, crypto),\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: error.message,\n }),\n ),\n );\n\n if (batchRow.batch_digest !== digest || batchRow.tail_digest !== digest) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: \"Canonical batch digest does not match its decoded content and prior tail.\",\n });\n }\n\n const batchRecords = recordsByBatch.get(batchRow.batch_id) ?? [];\n\n if (batchRecords.length !== canonicalBatch.records.length) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: key,\n message: \"Canonical batch and record-table counts differ.\",\n });\n }\n for (let index = 0; index < canonicalBatch.records.length; index++) {\n const expectedRecord = canonicalBatch.records[index];\n const storedRecord = batchRecords[index];\n\n const expectedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(\n expectedRecord,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: key,\n message: error.message,\n }),\n ),\n );\n\n const storedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(\n storedRecord.decoded,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${key}/${storedRecord.row.sequence}`,\n message: error.message,\n }),\n ),\n );\n\n if (\n storedRecord.row.sequence !== batchRow.first_sequence + index ||\n storedRecord.row.record_id !== expectedRecord.recordId ||\n expectedJson !== storedJson\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${key}/${storedRecord.row.sequence}`,\n message: \"Canonical record identity, sequence, or payload differs from its batch.\",\n });\n }\n }\n\n previousDigest = digest;\n expectedSequence = batchRow.last_sequence + 1;\n tailDigests.set(batchRow.last_sequence, digest);\n }\n\n if (\n threadRecords.length !== thread.tail_sequence ||\n thread.tail_sequence !== expectedSequence - 1 ||\n thread.tail_digest !== previousDigest\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: thread.thread_id,\n message: \"Thread tail does not match its canonical batch chain.\",\n });\n }\n\n for (const checkpoint of threadCheckpoints) {\n if (\n checkpoint.decoded.threadId !== thread.thread_id ||\n checkpoint.decoded.throughSequence !== checkpoint.row.through_sequence ||\n checkpoint.decoded.tailDigest !== checkpoint.row.tail_digest ||\n tailDigests.get(checkpoint.row.through_sequence) !== checkpoint.row.tail_digest\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${thread.thread_id}/${checkpoint.row.through_sequence}`,\n message: \"Checkpoint identity or digest is not bound to a canonical batch tail.\",\n });\n }\n }\n }\n\n if (\n batches.some(({ row }) => !materializedIds.has(row.thread_id)) ||\n records.some(({ row }) => !materializedIds.has(row.thread_id)) ||\n checkpoints.some(({ row }) => !materializedIds.has(row.thread_id))\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: \"startup_scan\",\n message: \"Canonical rows exist without a materialized Thread.\",\n });\n }\n});\n\nconst makeServices = Effect.fn(\"DoThreadStore.makeServices\")(function* () {\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n const sql = yield* SqlClientService.SqlClient;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);\n\n if (config.verifyOnOpen) {\n yield* decodeStartupPayloads(journal, crypto);\n }\n\n const provideCrypto = <A, E>(effect: Effect.Effect<A, E, Crypto.Crypto>) =>\n Effect.provideService(effect, Crypto.Crypto, crypto);\n\n const hitFailpoint = Effect.fn(\n (location: DoStorageFailpointLocation): Effect.Effect<void, ThreadStoreError> =>\n failpoint\n .hit(location)\n .pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error))),\n );\n\n const materialize: ThreadStore[\"Service\"][\"materialize\"] = Effect.fn(\"DoThreadStore.materialize\")(\n function* (request: ThreadMaterialization) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate materialization\", error)));\n\n const now = yield* Clock.currentTimeMillis;\n\n yield* hitFailpoint(\"materialize:before\");\n yield* journal\n .materialize(\n validated.threadId,\n new Date(now).toISOString(),\n EMPTY_TAIL_DIGEST,\n validated.producerEpoch,\n )\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"DoFenceRejected\"\n ? mapFence(validated.threadId, error)\n : storeError(\"materialize thread\", error),\n ),\n );\n yield* hitFailpoint(\"materialize:after\");\n },\n );\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fn(\"DoThreadStore.append\")(function* (\n request: FencedAppendRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(FencedAppendRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate canonical append\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n\n const tailDigest = yield* provideCrypto(\n digestCanonicalBatch(validated.expectedTailDigest, validated.batch),\n ).pipe(Effect.mapError((error) => storeError(\"digest canonical append\", error)));\n\n const batchJson = yield* encodeCanonicalBatch(validated.batch);\n\n const rawRecords = yield* Effect.forEach(validated.batch.records, (record) =>\n encodeCanonicalRecord(record).pipe(\n Effect.map((recordJson) => ({\n recordId: record.recordId,\n recordJson,\n })),\n ),\n );\n\n const rawRequest = yield* Schema.decodeEffect(RawAppendRequest)({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n batchDigest: tailDigest,\n batchJson,\n expectedTailSequence: validated.expectedTailSequence,\n expectedTailDigest: validated.expectedTailDigest,\n producerEpoch: validated.producerEpoch,\n records: rawRecords,\n tailDigest,\n }).pipe(Effect.mapError((error) => schemaStoreError(\"encode canonical append\", error)));\n\n yield* hitFailpoint(\"append:before\");\n\n const result = yield* journal.append(rawRequest).pipe(\n Effect.mapError((error) => {\n if (isDoFenceRejected(error)) {\n return mapFence(validated.threadId, error);\n }\n if (isDoAppendConflict(error)) {\n return error.actualTailSequence !== undefined && isDigest(error.actualTailDigest)\n ? AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n actualTailSequence: error.actualTailSequence,\n actualTailDigest: error.actualTailDigest,\n })\n : AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n });\n }\n\n return storeError(\"append canonical batch\", error);\n }),\n Effect.flatMap((result) =>\n Schema.decodeEffect(AppendResult)(result).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode append result\", error)),\n ),\n ),\n );\n\n yield* hitFailpoint(\"append:after\");\n\n return result;\n });\n\n const loadRecords = Effect.fnUntraced(function* (request: RawReadRequest) {\n const result = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return {\n count: result.count,\n records: result.records.pipe(\n Stream.mapError((error) => storeError(\"read canonical records\", error)),\n Stream.mapEffect(decodeEnvelope),\n ),\n };\n });\n\n const readEffect = Effect.fn(\"DoThreadStore.read\")(function* (request: ThreadReadRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\n if (\"selection\" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));\n yield* requireThread(journal, validated.threadId);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive: validated.afterSequence ?? ZERO_CANONICAL_SEQUENCE,\n limit: validated.limit,\n }),\n );\n\n return result.records;\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fnUntraced(function* (request: ThreadObservation) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread observation\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);\n const cursor = yield* Ref.make(initialSequence);\n let polls = 0;\n let emptyPolls = 0;\n let deliveredRecords = 0;\n\n const poll = Effect.fnUntraced(function* () {\n polls++;\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (result.count === 0) {\n emptyPolls++;\n yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(\n Stream.tap((record) => {\n deliveredRecords++;\n\n return Ref.set(cursor, record.sequence);\n }),\n );\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(\n Stream.flatten,\n Stream.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n \"effect_agent.observation.polls\": polls,\n \"effect_agent.observation.empty_polls\": emptyPolls,\n \"effect_agent.observation.records\": deliveredRecords,\n }),\n ),\n ),\n );\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request)).pipe(Stream.withSpan(\"DoThreadStore.observe\"));\n\n const exportThread: ThreadStore[\"Service\"][\"export\"] = Effect.fn(\"DoThreadStore.export\")(\n function* (request: ThreadExportRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadExportRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate thread export\", error)));\n\n yield* requireThread(journal, validated.threadId);\n\n const exported = yield* journal\n .exportThread(validated.threadId)\n .pipe(Effect.mapError((error) => storeError(\"export thread\", error)));\n\n const records = yield* Effect.forEach(exported.records, decodeEnvelope);\n\n if (records.length > MAX_THREAD_EXPORT_RECORDS) {\n return yield* ThreadStoreError.make({\n operation: \"decode thread export\",\n message: \"The thread exceeds the current export record limit.\",\n });\n }\n\n const tailDigest = yield* Schema.decodeEffect(Digest)(exported.thread.tail_digest).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode export tail digest\", error)),\n );\n\n return ThreadExport.make({\n format: \"effect-agent/thread@1\",\n threadId: validated.threadId,\n tailSequence: exported.thread.tail_sequence,\n tailDigest,\n records,\n });\n },\n );\n\n const inspectTail: ThreadStore[\"Service\"][\"inspectTail\"] = Effect.fn(\"DoThreadStore.inspectTail\")(\n function* (request: ThreadTailRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate tail inspection\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const tailDigest = yield* Schema.decodeEffect(Digest)(thread.tail_digest).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode tail digest\", error)),\n );\n\n return ThreadTail.make({\n threadId: validated.threadId,\n tailSequence: thread.tail_sequence,\n tailDigest,\n producerEpoch: thread.producer_epoch,\n });\n },\n );\n\n const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fn(\"DoThreadStore.saveCheckpoint\")(\n function* (request: SaveCheckpointRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint\", error)));\n\n const thread = yield* requireThread(journal, validated.checkpoint.threadId);\n\n if (validated.checkpoint.throughSequence > thread.tail_sequence) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n }\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n validated.checkpoint.threadId,\n validated.checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== validated.checkpoint.tailDigest) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n }\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n const raw = RawCheckpoint.make({\n threadId: validated.checkpoint.threadId,\n throughSequence: validated.checkpoint.throughSequence,\n tailDigest: validated.checkpoint.tailDigest,\n checkpointJson,\n });\n\n yield* hitFailpoint(\"save-checkpoint:before\");\n yield* journal.saveCheckpoint(raw).pipe(\n Effect.mapError((error) =>\n isDoCheckpointConflict(error)\n ? CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"digest-mismatch\",\n })\n : storeError(\"save checkpoint\", error),\n ),\n );\n yield* hitFailpoint(\"save-checkpoint:after\");\n },\n );\n\n const loadCheckpoint: ThreadCheckpoints[\"load\"] = Effect.fn(\"DoThreadStore.loadCheckpoint\")(\n function* (request: LoadCheckpointRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint lookup\", error)));\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const rows = yield* journal\n .loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence)\n .pipe(Effect.mapError((error) => storeError(\"load checkpoint\", error)));\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: `Expected at most one checkpoint row but found ${rows.length}.`,\n });\n }\n const row = rows[0];\n const checkpoint = yield* decodeCheckpoint(row.checkpoint_json);\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence ||\n checkpoint.tailDigest !== row.tail_digest\n ) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: \"Stored checkpoint metadata does not match its canonical row.\",\n });\n }\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n checkpoint.threadId,\n checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== checkpoint.tailDigest) {\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n }\n\n return Option.some(checkpoint);\n },\n );\n\n const saveRecoveryCheckpoint: ThreadRecoveryCheckpoints[\"save\"] = Effect.fn(\n \"DoThreadStore.saveRecoveryCheckpoint\",\n )(function* (request) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveRecoveryCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate recovery checkpoint\", error)));\n\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n yield* journal\n .saveRecoveryCheckpoint(validated, checkpointJson)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"CheckpointRejected\" ||\n error._tag === \"FenceRejected\" ||\n error._tag === \"ThreadNotMaterialized\"\n ? error\n : storeError(\"save recovery checkpoint\", error),\n ),\n );\n });\n\n const loadRecoveryCheckpoint: ThreadRecoveryCheckpoints[\"load\"] = Effect.fn(\n \"DoThreadStore.loadRecoveryCheckpoint\",\n )(function* (request) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate recovery checkpoint lookup\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const corrupt = () =>\n CheckpointRejected.make({ threadId: validated.threadId, reason: \"corrupt\" });\n\n const rows = yield* journal\n .loadRecoveryCheckpoint(validated.threadId)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"DoStorageCorruptionError\"\n ? corrupt()\n : storeError(\"load recovery checkpoint\", error),\n ),\n );\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) return yield* corrupt();\n const row = rows[0];\n\n const checkpoint = yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(\n row.checkpoint_json,\n ).pipe(Effect.mapError(corrupt));\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence ||\n checkpoint.tailDigest !== row.tail_digest\n )\n return yield* corrupt();\n if (checkpoint.throughSequence > thread.tail_sequence)\n return yield* CheckpointRejected.make({\n threadId: validated.threadId,\n reason: \"ahead-of-tail\",\n });\n if (checkpoint.throughSequence > (validated.atOrBeforeSequence ?? thread.tail_sequence))\n return Option.none();\n\n const canonicalDigest = yield* tailDigestAt(\n journal,\n checkpoint.threadId,\n checkpoint.throughSequence,\n );\n\n if (canonicalDigest !== checkpoint.tailDigest)\n return yield* CheckpointRejected.make({\n threadId: validated.threadId,\n reason: \"digest-mismatch\",\n });\n\n return Option.some(checkpoint);\n });\n\n const selectedReads = yield* makeSelectedReads(decodeEnvelope);\n\n const threadStore = ThreadStore.of({\n countPeerMessages: selectedReads.countPeerMessages,\n append,\n export: exportThread,\n inspectTail,\n materialize,\n observe,\n read,\n checkpoints: { save: saveCheckpoint, load: loadCheckpoint },\n recoveryCheckpoints: { save: saveRecoveryCheckpoint, load: loadRecoveryCheckpoint },\n });\n\n return Context.make(ThreadStore, threadStore);\n});\n\n/**\n * Durable Object Thread Store implementation with configuration, failpoint, SQL, and\n * Crypto authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore,\n DoStorageInitializationError,\n DoStorageConfig | DoStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = Layer.effectContext(makeServices());\n\n/**\n * Validated Durable Object storage configuration Layer with the documented defaults applied.\n * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults\n * cannot drift.\n */\nexport const storageConfigLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageConfig, DoStorageError> =>\n Layer.effect(DoStorageConfig)(\n Schema.decodeEffect(DoStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n ownershipLeaseDuration:\n options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),\n maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"configure Durable Object storage\",\n message: error.message,\n }),\n ),\n ),\n );\n\n/** The failpoint Layer selected by convenience options: explicit handler or the no-op default. */\nexport const storageFailpointLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageFailpoint> =>\n options.failpoint === undefined\n ? DoStorageFailpoint.layer\n : Layer.succeed(DoStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads inside one Durable Object,\n * built over `ctx.storage`. Durable accepted work is served by the separate SubmissionLedger\n * port; point both at the SAME `ctx.storage` so claims fence the same producer epochs\n * (ADR-0011 D7's \"same file\" rule, transposed to one object's private database).\n */\nexport const layer = (\n options: DoStorageOptions,\n): Layer.Layer<ThreadStore, DoStorageInitializationError> =>\n Layer.unwrap(\n Effect.map(DoStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(DoStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ storage: options.storage }),\n BrowserCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n"],"mappings":"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"}
|
package/dist/PortProtocol.d.mts
CHANGED
|
@@ -2383,6 +2383,9 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
2383
2383
|
readonly queueSequence: number;
|
|
2384
2384
|
readonly principal: string;
|
|
2385
2385
|
readonly idempotencyKey: string;
|
|
2386
|
+
readonly deploymentId: string;
|
|
2387
|
+
readonly receiptId: string;
|
|
2388
|
+
readonly state: "admitted" | "input-applied" | "joined" | "joining" | "ready" | "running" | "settled" | "suspended" | "terminalizing" | "unknown";
|
|
2386
2389
|
readonly agentId: string;
|
|
2387
2390
|
readonly agentDigests: {
|
|
2388
2391
|
readonly agent: string;
|
|
@@ -2396,11 +2399,8 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
2396
2399
|
};
|
|
2397
2400
|
} | undefined;
|
|
2398
2401
|
};
|
|
2399
|
-
readonly deploymentId: string;
|
|
2400
2402
|
readonly inputPayload: Schema.Json;
|
|
2401
2403
|
readonly inputDigest: string;
|
|
2402
|
-
readonly receiptId: string;
|
|
2403
|
-
readonly state: "admitted" | "input-applied" | "joined" | "joining" | "ready" | "running" | "settled" | "suspended" | "terminalizing" | "unknown";
|
|
2404
2404
|
readonly settledOutcome?: "aborted" | "completed" | "failed" | undefined;
|
|
2405
2405
|
readonly createdAt: string;
|
|
2406
2406
|
readonly readyAt?: string | undefined;
|
|
@@ -2618,6 +2618,9 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
2618
2618
|
readonly queueSequence: number;
|
|
2619
2619
|
readonly principal: string;
|
|
2620
2620
|
readonly idempotencyKey: string;
|
|
2621
|
+
readonly deploymentId: string;
|
|
2622
|
+
readonly receiptId: string;
|
|
2623
|
+
readonly state: "admitted" | "input-applied" | "joined" | "joining" | "ready" | "running" | "settled" | "suspended" | "terminalizing" | "unknown";
|
|
2621
2624
|
readonly agentId: string;
|
|
2622
2625
|
readonly agentDigests: {
|
|
2623
2626
|
readonly agent: string;
|
|
@@ -2631,11 +2634,8 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
2631
2634
|
};
|
|
2632
2635
|
} | undefined;
|
|
2633
2636
|
};
|
|
2634
|
-
readonly deploymentId: string;
|
|
2635
2637
|
readonly inputPayload: Schema.Json;
|
|
2636
2638
|
readonly inputDigest: string;
|
|
2637
|
-
readonly receiptId: string;
|
|
2638
|
-
readonly state: "admitted" | "input-applied" | "joined" | "joining" | "ready" | "running" | "settled" | "suspended" | "terminalizing" | "unknown";
|
|
2639
2639
|
readonly settledOutcome?: "aborted" | "completed" | "failed" | undefined;
|
|
2640
2640
|
readonly createdAt: string;
|
|
2641
2641
|
readonly readyAt?: string | undefined;
|
|
@@ -4879,19 +4879,6 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
4879
4879
|
readonly stack?: string | undefined;
|
|
4880
4880
|
readonly reason: "capacity" | "conflict" | "corrupt" | "not-found" | "storage" | "validation";
|
|
4881
4881
|
readonly operation: string;
|
|
4882
|
-
} | {
|
|
4883
|
-
readonly _tag: "ThreadNotMaterialized";
|
|
4884
|
-
readonly threadId: string;
|
|
4885
|
-
} | {
|
|
4886
|
-
readonly _tag: "FenceRejected";
|
|
4887
|
-
readonly threadId: string;
|
|
4888
|
-
readonly actualEpoch: number;
|
|
4889
|
-
readonly attemptedEpoch: number;
|
|
4890
|
-
} | {
|
|
4891
|
-
readonly _tag: "ThreadStoreError";
|
|
4892
|
-
readonly operation: string;
|
|
4893
|
-
readonly message: string;
|
|
4894
|
-
readonly cause?: Schema.Json | undefined;
|
|
4895
4882
|
} | {
|
|
4896
4883
|
readonly _tag: "AdmissionConflict";
|
|
4897
4884
|
readonly threadId: string;
|
|
@@ -4918,6 +4905,21 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
4918
4905
|
readonly operation: string;
|
|
4919
4906
|
readonly message: string;
|
|
4920
4907
|
readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
|
|
4908
|
+
} | {
|
|
4909
|
+
readonly _tag: "ThreadStoreError";
|
|
4910
|
+
readonly operation: string;
|
|
4911
|
+
readonly message: string;
|
|
4912
|
+
readonly cause?: Schema.Json | undefined;
|
|
4913
|
+
readonly diagnostic?: {
|
|
4914
|
+
readonly causeTag: string;
|
|
4915
|
+
readonly operation: string;
|
|
4916
|
+
readonly decoder?: string | undefined;
|
|
4917
|
+
readonly issueTag?: string | undefined;
|
|
4918
|
+
readonly sequence?: number | undefined;
|
|
4919
|
+
} | undefined;
|
|
4920
|
+
} | {
|
|
4921
|
+
readonly _tag: "ThreadNotMaterialized";
|
|
4922
|
+
readonly threadId: string;
|
|
4921
4923
|
} | {
|
|
4922
4924
|
readonly _tag: "AppendConflict";
|
|
4923
4925
|
readonly threadId: string;
|
|
@@ -4925,6 +4927,11 @@ export declare const encodePortResponse: (input: PortFailed | PortSucceeded, opt
|
|
|
4925
4927
|
readonly reason: "batch-digest" | "record-identity" | "tail";
|
|
4926
4928
|
readonly actualTailSequence?: number | undefined;
|
|
4927
4929
|
readonly actualTailDigest?: string | undefined;
|
|
4930
|
+
} | {
|
|
4931
|
+
readonly _tag: "FenceRejected";
|
|
4932
|
+
readonly threadId: string;
|
|
4933
|
+
readonly actualEpoch: number;
|
|
4934
|
+
readonly attemptedEpoch: number;
|
|
4928
4935
|
};
|
|
4929
4936
|
}, Schema.SchemaError, never>;
|
|
4930
4937
|
export declare const decodePortResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<PortFailed | PortSucceeded, Schema.SchemaError, never>;
|
|
@@ -8,7 +8,7 @@ import { EMPTY_TAIL_DIGEST } from "effect-agent/digest";
|
|
|
8
8
|
import { CanonicalRecord, CanonicalSequence, ProducerEpoch } from "effect-agent/records";
|
|
9
9
|
import { checkV2ThreadLayout } from "effect-agent/sql-storage-v2-upgrade";
|
|
10
10
|
import { createNativeReadIndexes, indexCanonicalRecord, seedNativeReadIndexes } from "effect-agent/sql-thread-native-reads";
|
|
11
|
-
import { CheckpointRejected, FenceRejected, MAX_THREAD_EXPORT_RECORDS, ThreadNotMaterialized } from "effect-agent/thread-store";
|
|
11
|
+
import { CheckpointRejected, FenceRejected, MAX_THREAD_EXPORT_RECORDS, ThreadNotMaterialized, ThreadStoreDiagnostic } from "effect-agent/thread-store";
|
|
12
12
|
import { SqlError } from "effect/unstable/sql/SqlError";
|
|
13
13
|
//#region src/internal/do-journal.ts
|
|
14
14
|
/**
|
|
@@ -105,13 +105,29 @@ const noFailpoint = () => Effect.void;
|
|
|
105
105
|
const storageError = (operation) => (error) => DoStorageError.make({
|
|
106
106
|
cause: error,
|
|
107
107
|
operation,
|
|
108
|
-
message: error.message
|
|
108
|
+
message: error.message,
|
|
109
|
+
diagnostic: ThreadStoreDiagnostic.make({
|
|
110
|
+
causeTag: error._tag,
|
|
111
|
+
operation,
|
|
112
|
+
issueTag: error.reason._tag
|
|
113
|
+
})
|
|
109
114
|
});
|
|
110
115
|
/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */
|
|
111
|
-
const decodeRows = Effect.fn((schema, table, rowKey, rows) => Schema.decodeUnknownEffect(schema)(rows).pipe(Effect.mapError((error) => DoStorageCorruptionError.make({
|
|
116
|
+
const decodeRows = Effect.fn((schema, table, rowKey, rows, decoder = table) => Schema.decodeUnknownEffect(schema)(rows).pipe(Effect.mapError((error) => DoStorageCorruptionError.make({
|
|
112
117
|
table,
|
|
113
118
|
rowKey,
|
|
114
|
-
message:
|
|
119
|
+
message: "Stored rows do not satisfy the storage schema",
|
|
120
|
+
diagnostic: ThreadStoreDiagnostic.make({
|
|
121
|
+
causeTag: error._tag,
|
|
122
|
+
operation: "decode storage rows",
|
|
123
|
+
decoder,
|
|
124
|
+
issueTag: error.issue._tag
|
|
125
|
+
})
|
|
126
|
+
})), Effect.tapError((error) => Effect.annotateCurrentSpan({
|
|
127
|
+
"storage.failure.operation": error.diagnostic?.operation,
|
|
128
|
+
"storage.failure.cause": error.diagnostic?.causeTag,
|
|
129
|
+
"storage.failure.decoder": decoder,
|
|
130
|
+
"storage.failure.issue": error.diagnostic?.issueTag
|
|
115
131
|
}))));
|
|
116
132
|
/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */
|
|
117
133
|
const decodeSingleRow = Effect.fn((schema, table, rowKey, rows) => decodeRows(schema, table, rowKey, rows).pipe(Effect.flatMap((decoded) => decoded.length === 1 ? Effect.succeed(decoded[0]) : Effect.fail(DoStorageCorruptionError.make({
|
|
@@ -745,7 +761,7 @@ const makeJournal = (sql, failpoint, maxStoredValueBytes) => {
|
|
|
745
761
|
ORDER BY sequence
|
|
746
762
|
LIMIT ${request.limit}
|
|
747
763
|
`.pipe(Effect.mapError(storageError("read canonical records")));
|
|
748
|
-
const plan = yield* decodeRows(Schema.Array(ReadPlanRow), "effect_agent_canonical_records", `${request.threadId}>${request.fromSequenceExclusive}`, planRows);
|
|
764
|
+
const plan = yield* decodeRows(Schema.Array(ReadPlanRow), "effect_agent_canonical_records", `${request.threadId}>${request.fromSequenceExclusive}`, planRows, "ReadPlanRow");
|
|
749
765
|
const mismatch = () => DoStorageCorruptionError.make({
|
|
750
766
|
table: "effect_agent_canonical_records",
|
|
751
767
|
rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,
|
|
@@ -777,7 +793,7 @@ const makeJournal = (sql, failpoint, maxStoredValueBytes) => {
|
|
|
777
793
|
AND sequence <= ${page[page.length - 1].sequence}
|
|
778
794
|
ORDER BY sequence
|
|
779
795
|
`.pipe(Effect.mapError(storageError("read canonical records")));
|
|
780
|
-
const decoded = yield* decodeRows(Schema.Array(RecordRow), "effect_agent_canonical_records", `${request.threadId}/${page[0].sequence}`, rows);
|
|
796
|
+
const decoded = yield* decodeRows(Schema.Array(RecordRow), "effect_agent_canonical_records", `${request.threadId}/${page[0].sequence}`, rows, "RecordRow");
|
|
781
797
|
if (decoded.length !== page.length || decoded.some((row, index) => row.thread_id !== request.threadId || row.sequence !== page[index].sequence || storedTextBytes(row.record_json) !== page[index].record_json_bytes)) return yield* mismatch();
|
|
782
798
|
return decoded;
|
|
783
799
|
});
|
|
@@ -1038,4 +1054,4 @@ const initializeDoJournal = ensureCurrentStorage;
|
|
|
1038
1054
|
//#endregion
|
|
1039
1055
|
export { initializeDoJournal as a, decodeRows as i, RawCheckpoint as n, RawReadRequest as r, RawAppendRequest as t };
|
|
1040
1056
|
|
|
1041
|
-
//# sourceMappingURL=do-journal-
|
|
1057
|
+
//# sourceMappingURL=do-journal-BeHu8_Bh.mjs.map
|