@effect-agent/storage-cloudflare 0.1.0-beta.84 → 0.1.0-beta.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/DoMemoryStore.d.mts +3 -3
  2. package/dist/DoMemoryStore.mjs +3 -3
  3. package/dist/DoMemoryStore.mjs.map +1 -1
  4. package/dist/DoMessageDeliveryStore.d.mts +1 -1
  5. package/dist/DoMessageDeliveryStore.mjs +3 -3
  6. package/dist/DoMessageDeliveryStore.mjs.map +1 -1
  7. package/dist/DoScheduleStore.d.mts +1 -1
  8. package/dist/DoScheduleStore.mjs +5 -5
  9. package/dist/DoScheduleStore.mjs.map +1 -1
  10. package/dist/DoStorageError.mjs +1 -1
  11. package/dist/DoStorageError.mjs.map +1 -1
  12. package/dist/DoSubmissionLedger.d.mts +1 -1
  13. package/dist/DoSubmissionLedger.mjs +35 -35
  14. package/dist/DoSubmissionLedger.mjs.map +1 -1
  15. package/dist/DoSubscriptionStore.d.mts +1 -1
  16. package/dist/DoSubscriptionStore.mjs +4 -4
  17. package/dist/DoSubscriptionStore.mjs.map +1 -1
  18. package/dist/DoThreadStore.d.mts +2 -2
  19. package/dist/DoThreadStore.mjs +26 -26
  20. package/dist/DoThreadStore.mjs.map +1 -1
  21. package/dist/MemoryProtocol.d.mts +272 -272
  22. package/dist/MemoryProtocol.mjs +8 -8
  23. package/dist/MemoryProtocol.mjs.map +1 -1
  24. package/dist/PortProtocol.d.mts +645 -48
  25. package/dist/PortProtocol.mjs +3 -3
  26. package/dist/PortProtocol.mjs.map +1 -1
  27. package/dist/PortRouting.d.mts +2 -2
  28. package/dist/PortRouting.mjs +2 -2
  29. package/dist/PortRouting.mjs.map +1 -1
  30. package/dist/{do-journal-DHqCQeBU.mjs → do-journal-dJ01KSKf.mjs} +7 -7
  31. package/dist/do-journal-dJ01KSKf.mjs.map +1 -0
  32. package/package.json +1 -1
  33. package/src/DoMemoryStore.ts +3 -6
  34. package/src/DoMessageDeliveryStore.ts +3 -3
  35. package/src/DoScheduleStore.ts +6 -6
  36. package/src/DoStorageError.ts +1 -1
  37. package/src/DoSubmissionLedger.ts +67 -67
  38. package/src/DoSubscriptionStore.ts +6 -6
  39. package/src/DoThreadStore.ts +51 -53
  40. package/src/MemoryProtocol.ts +9 -13
  41. package/src/PortProtocol.ts +4 -4
  42. package/src/PortRouting.ts +3 -3
  43. package/src/internal/do-journal.ts +8 -8
  44. package/dist/do-journal-DHqCQeBU.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
3
- import { SourcePartition, SubscriptionError, SubscriptionFailpointError, SubscriptionStore } from "@effect-agent/thread/Subscription";
3
+ import { SourcePartition, SubscriptionError, SubscriptionFailpointError, SubscriptionStore } from "effect-agent/subscription";
4
4
  declare namespace DoSubscriptionStore_d_exports {
5
5
  export { DoSubscriptionAlarmControl, DoSubscriptionAlarmReplacement, DoSubscriptionReplaceAlarm, DoSubscriptionTransaction, doSubscriptionStoreLayer };
6
6
  }
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { Context, Effect, Layer, Schema } from "effect";
3
3
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
4
- import { upgradeV2Subscriptions } from "@effect-agent/thread/SqlStorageV2Upgrade";
4
+ import { upgradeV2Subscriptions } from "effect-agent/sql-storage-v2-upgrade";
5
5
  import { BrowserCrypto } from "@effect/platform-browser";
6
- import { SqlSubscriptionTransaction, makeSqlSubscriptionStore } from "@effect-agent/thread/SqlSubscriptionStore";
7
- import { SourcePartition, SubscriptionError, SubscriptionFailpoint, SubscriptionStore } from "@effect-agent/thread/Subscription";
6
+ import { SqlSubscriptionTransaction, makeSqlSubscriptionStore } from "effect-agent/sql-subscription-store";
7
+ import { SourcePartition, SubscriptionError, SubscriptionFailpoint, SubscriptionStore } from "effect-agent/subscription";
8
8
  //#region src/DoSubscriptionStore.ts
9
9
  var DoSubscriptionStore_exports = /* @__PURE__ */ __exportAll({
10
10
  DoSubscriptionAlarmControl: () => DoSubscriptionAlarmControl,
@@ -160,7 +160,7 @@ const makeSubscriptionStore = Effect.fn("DoSubscriptionStore.make")(function* (o
160
160
  yield* replaceAlarm(replace, yield* readIndexedDeadline());
161
161
  return value;
162
162
  }));
163
- const store = yield* makeSqlSubscriptionStore(partition, { maxStoredJsonLength: 19e5 }).pipe(Effect.provide(Layer.succeed(SqlSubscriptionTransaction)({ run: transact })));
163
+ const store = yield* makeSqlSubscriptionStore(partition, { maxStoredJsonLength: 19e5 }).pipe(Effect.provideService(SqlSubscriptionTransaction, { run: transact }));
164
164
  const prearm = Effect.fn("DoSubscriptionStore.prearm")(function* (deadlineAtMillis) {
165
165
  yield* transactions.run((replace) => replaceAlarm(replace, deadlineAtMillis));
166
166
  yield* failpoint.hit("subscription:prearm:after");
@@ -1 +1 @@
1
- {"version":3,"file":"DoSubscriptionStore.mjs","names":[],"sources":["../src/DoSubscriptionStore.ts"],"sourcesContent":["import { upgradeV2Subscriptions } from \"@effect-agent/thread/SqlStorageV2Upgrade\";\nimport {\n makeSqlSubscriptionStore,\n SqlSubscriptionTransaction,\n} from \"@effect-agent/thread/SqlSubscriptionStore\";\nimport {\n SourcePartition,\n SubscriptionError,\n SubscriptionFailpoint,\n type SubscriptionFailpointError,\n SubscriptionStore,\n} from \"@effect-agent/thread/Subscription\";\nimport { BrowserCrypto } from \"@effect/platform-browser\";\nimport { Context, Effect, Layer, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst CURRENT_SUBSCRIPTION_STORE_VERSION = 3;\n\nconst ScanRow = Schema.Struct({\n event_scan_cursor: Schema.String,\n delivery_scan_cursor: Schema.String,\n recovery_scan_cursor: Schema.Natural,\n});\n\nconst StoreStateRow = Schema.Struct({\n storage_version: Schema.Int,\n alarm_generation: Schema.Natural,\n});\n\nexport interface DoSubscriptionAlarmReplacement {\n readonly deadlineAtMillis: number | null;\n readonly generation: number;\n}\n\nexport type DoSubscriptionReplaceAlarm = (\n replacement: DoSubscriptionAlarmReplacement,\n) => Effect.Effect<void, SubscriptionError>;\n\n/** One Durable Object transaction combining subscription SQL and its single native alarm. */\nexport class DoSubscriptionTransaction extends Context.Service<\n DoSubscriptionTransaction,\n {\n readonly run: <A, E, R>(\n body: (replaceAlarm: DoSubscriptionReplaceAlarm) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SubscriptionError, R>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionTransaction\") {}\n\nexport class DoSubscriptionAlarmControl extends Context.Service<\n DoSubscriptionAlarmControl,\n {\n readonly prearm: (\n deadlineAtMillis: number,\n ) => Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n readonly reconcile: Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionAlarmControl\") {}\n\nconst error = (reason: SubscriptionError[\"reason\"], code: string) =>\n SubscriptionError.make({ reason, code });\n\nconst unavailable = (operation: string) => error(\"storage\", operation);\nconst corrupt = (operation: string) => error(\"corrupt\", operation);\n\nconst validate = <A, I>(schema: Schema.Codec<A, I>, value: unknown, code: string) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => error(\"validation\", code)));\n\nconst decodeRows = <A, I>(schema: Schema.Codec<A, I>, rows: unknown, code: string) =>\n Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(Effect.mapError(() => corrupt(code)));\n\nconst initializeDoSubscriptionStore = Effect.fn(\"DoSubscriptionStore.initialize\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n\n const names = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'effect_agent_subscription_%'\n `.pipe(Effect.mapError(() => unavailable(\"inspect subscription storage\")));\n\n const decodedNames = yield* decodeRows(\n Schema.Struct({ name: Schema.String }),\n names,\n \"inspect subscription storage\",\n );\n\n const expected = new Set([\n \"effect_agent_subscription_store_state\",\n \"effect_agent_subscription_sequences\",\n \"effect_agent_subscriptions\",\n \"effect_agent_subscription_events\",\n \"effect_agent_subscription_deliveries\",\n ]);\n\n const hasState = decodedNames.some(\n ({ name }) => name === \"effect_agent_subscription_store_state\",\n );\n\n if (!hasState && decodedNames.length > 0) return yield* corrupt(\"partial subscription storage\");\n if (!hasState) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`CREATE TABLE effect_agent_subscription_store_state (\n singleton INTEGER PRIMARY KEY NOT NULL CHECK(singleton=1), storage_version INTEGER NOT NULL, alarm_generation INTEGER NOT NULL\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_sequences (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, sequence INTEGER NOT NULL,\n event_scan_cursor TEXT NOT NULL, delivery_scan_cursor TEXT NOT NULL, recovery_scan_cursor INTEGER NOT NULL,\n PRIMARY KEY (tenant_id, source_address)\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscriptions (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n ordinal INTEGER NOT NULL, source_name TEXT NOT NULL, source_version TEXT NOT NULL, matching_key TEXT NOT NULL,\n state TEXT NOT NULL, expires_at_millis INTEGER, recovery_at_millis INTEGER, recovery_present INTEGER NOT NULL DEFAULT 0, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id), UNIQUE (tenant_id, source_address, ordinal)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_owner ON effect_agent_subscriptions (tenant_id, source_address, owner_id, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_candidates ON effect_agent_subscriptions (tenant_id, source_address, source_name, source_version, matching_key, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_recovery ON effect_agent_subscriptions (tenant_id, source_address, recovery_at_millis, ordinal) WHERE recovery_at_millis IS NOT NULL`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_events (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, event_id TEXT NOT NULL, source_name TEXT NOT NULL,\n source_version TEXT NOT NULL, matching_key TEXT NOT NULL, payload_digest TEXT NOT NULL, cutoff INTEGER NOT NULL,\n cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, tombstone INTEGER NOT NULL DEFAULT 0, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, event_id)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_events_pending ON effect_agent_subscription_events (tenant_id, source_address, routing_complete, next_attempt_at_millis, event_id)`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_deliveries (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n event_id TEXT NOT NULL, delivery_key TEXT NOT NULL, state TEXT NOT NULL, next_attempt_at_millis INTEGER NOT NULL,\n record_json TEXT NOT NULL, PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id, event_id),\n UNIQUE (tenant_id, source_address, delivery_key)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_pending ON effect_agent_subscription_deliveries (tenant_id, source_address, state, next_attempt_at_millis, delivery_key)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`\n .withoutTransform;\n yield* sql`INSERT INTO effect_agent_subscription_store_state (singleton, storage_version, alarm_generation)\n VALUES (1, ${CURRENT_SUBSCRIPTION_STORE_VERSION}, 0)`.withoutTransform;\n }),\n )\n .pipe(Effect.mapError(() => unavailable(\"initialize subscription storage\")));\n\n return;\n }\n if (decodedNames.length !== expected.size || decodedNames.some(({ name }) => !expected.has(name)))\n return yield* corrupt(\"subscription storage tables\");\n\n const rows = yield* sql<\n Record<string, unknown>\n >`SELECT storage_version, alarm_generation FROM effect_agent_subscription_store_state WHERE singleton=1`.pipe(\n Effect.mapError(() => unavailable(\"read subscription storage version\")),\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"read subscription storage version\");\n\n if (state.length === 1 && state[0].storage_version === 2) {\n const failpoint = yield* SubscriptionFailpoint;\n\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n storage_version: number;\n }>`SELECT storage_version FROM effect_agent_subscription_store_state WHERE singleton=1`;\n\n if (current.length === 1 && current[0].storage_version === 3) return;\n if (current.length !== 1 || current[0].storage_version !== 2)\n return yield* corrupt(\"subscription version changed during upgrade\");\n yield* upgradeV2Subscriptions(1_900_000);\n yield* failpoint.hit(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_subscription_store_state SET storage_version=3 WHERE singleton=1`;\n yield* failpoint.hit(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.provide(BrowserCrypto.layer),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n SubscriptionError.make({\n reason: \"corrupt\",\n code: \"upgrade-v2-subscriptions\",\n cause: error,\n }),\n ),\n Effect.catchTag(\"SqlError\", () => unavailable(\"upgrade v2 subscriptions\")),\n Effect.catchTag(\"SchemaError\", () => corrupt(\"upgrade v2 subscription encoding\")),\n Effect.catchTag(\"SubscriptionFailpointError\", () =>\n unavailable(\"upgrade v2 subscriptions failpoint\"),\n ),\n );\n\n return;\n }\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\n state.length === 1\n ? `incompatible subscription storage version ${state[0].storage_version}; expected ${CURRENT_SUBSCRIPTION_STORE_VERSION}`\n : \"invalid subscription storage version row\",\n );\n});\n\nconst makeSubscriptionStore = Effect.fn(\"DoSubscriptionStore.make\")(function* (\n owned: SourcePartition,\n) {\n const partition = yield* validate(SourcePartition, owned, \"partition\");\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* SubscriptionFailpoint;\n const transactions = yield* DoSubscriptionTransaction;\n\n yield* initializeDoSubscriptionStore();\n\n const query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n code: string,\n ) => effect.pipe(Effect.mapError(() => unavailable(code)));\n\n const readIndexedDeadline = Effect.fn(\"DoSubscriptionStore.readIndexedDeadline\")(function* () {\n const scanRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor FROM effect_agent_subscription_sequences\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"read scan cursor deadline\",\n );\n\n const scans = yield* decodeRows(ScanRow, scanRows, \"read scan cursor deadline\");\n\n if (scans.length !== 1) return yield* corrupt(\"scan cursor deadline\");\n if (\n scans[0].event_scan_cursor !== \"\" ||\n scans[0].delivery_scan_cursor !== \"\" ||\n scans[0].recovery_scan_cursor !== 0\n )\n return 0;\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT MIN(deadline) AS deadline FROM (\n SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0\n UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND CASE WHEN json_valid(record_json) THEN\n ((state NOT IN ('delivered','refused') AND COALESCE(json_extract(record_json, '$.retry.parked'), 0)=0) OR (state='delivered' AND json_extract(record_json, '$.observeSettlement')=1))\n ELSE state<>'refused' END\n UNION ALL SELECT next_maintenance_at_millis FROM effect_agent_event_retention\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL\n )\n `,\n \"read subscription deadline\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({ deadline: Schema.NullOr(Schema.Number) }),\n rows,\n \"read subscription deadline\",\n );\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription deadline\");\n\n return decoded[0].deadline;\n });\n\n const replaceAlarm = Effect.fn(\"DoSubscriptionStore.replaceAlarm\")(function* (\n replace: DoSubscriptionReplaceAlarm,\n deadlineAtMillis: number | null,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_store_state SET alarm_generation=alarm_generation+1\n WHERE singleton=1 RETURNING storage_version, alarm_generation\n `,\n \"advance subscription alarm generation\",\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"advance subscription alarm generation\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\"subscription alarm state\");\n yield* failpoint.hit(\"subscription:alarm:before\");\n yield* replace({ deadlineAtMillis, generation: state[0].alarm_generation });\n yield* failpoint.hit(\"subscription:alarm:after\");\n });\n\n const transact = <A>(effect: Effect.Effect<A, SubscriptionError | SubscriptionFailpointError>) =>\n transactions.run((replace) =>\n Effect.gen(function* () {\n const value = yield* effect;\n\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n\n return value;\n }),\n );\n\n const store = yield* makeSqlSubscriptionStore(partition, {\n maxStoredJsonLength: 1_900_000,\n }).pipe(Effect.provide(Layer.succeed(SqlSubscriptionTransaction)({ run: transact })));\n\n const prearm = Effect.fn(\"DoSubscriptionStore.prearm\")(function* (deadlineAtMillis: number) {\n yield* transactions.run((replace) => replaceAlarm(replace, deadlineAtMillis));\n yield* failpoint.hit(\"subscription:prearm:after\");\n });\n\n const reconcile = Effect.gen(function* () {\n yield* transactions.run((replace) =>\n Effect.gen(function* () {\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n }),\n );\n yield* failpoint.hit(\"subscription:reconcile:after\");\n });\n\n return Context.make(SubscriptionStore, store).pipe(\n Context.add(DoSubscriptionAlarmControl, { prearm, reconcile }),\n );\n});\n\nexport const doSubscriptionStoreLayer = (\n partition: SourcePartition,\n): Layer.Layer<\n SubscriptionStore | DoSubscriptionAlarmControl,\n SubscriptionError,\n DoSubscriptionTransaction | SqlClientService.SqlClient\n> => Layer.effectContext(makeSubscriptionStore(partition));\n"],"mappings":"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"}
1
+ {"version":3,"file":"DoSubscriptionStore.mjs","names":[],"sources":["../src/DoSubscriptionStore.ts"],"sourcesContent":["import { BrowserCrypto } from \"@effect/platform-browser\";\nimport { Context, Effect, Layer, Schema } from \"effect\";\nimport { upgradeV2Subscriptions } from \"effect-agent/sql-storage-v2-upgrade\";\nimport {\n makeSqlSubscriptionStore,\n SqlSubscriptionTransaction,\n} from \"effect-agent/sql-subscription-store\";\nimport {\n SourcePartition,\n SubscriptionError,\n SubscriptionFailpoint,\n type SubscriptionFailpointError,\n SubscriptionStore,\n} from \"effect-agent/subscription\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst CURRENT_SUBSCRIPTION_STORE_VERSION = 3;\n\nconst ScanRow = Schema.Struct({\n event_scan_cursor: Schema.String,\n delivery_scan_cursor: Schema.String,\n recovery_scan_cursor: Schema.Natural,\n});\n\nconst StoreStateRow = Schema.Struct({\n storage_version: Schema.Int,\n alarm_generation: Schema.Natural,\n});\n\nexport interface DoSubscriptionAlarmReplacement {\n readonly deadlineAtMillis: number | null;\n readonly generation: number;\n}\n\nexport type DoSubscriptionReplaceAlarm = (\n replacement: DoSubscriptionAlarmReplacement,\n) => Effect.Effect<void, SubscriptionError>;\n\n/** One Durable Object transaction combining subscription SQL and its single native alarm. */\nexport class DoSubscriptionTransaction extends Context.Service<\n DoSubscriptionTransaction,\n {\n readonly run: <A, E, R>(\n body: (replaceAlarm: DoSubscriptionReplaceAlarm) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SubscriptionError, R>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionTransaction\") {}\n\nexport class DoSubscriptionAlarmControl extends Context.Service<\n DoSubscriptionAlarmControl,\n {\n readonly prearm: (\n deadlineAtMillis: number,\n ) => Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n readonly reconcile: Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionAlarmControl\") {}\n\nconst error = (reason: SubscriptionError[\"reason\"], code: string) =>\n SubscriptionError.make({ reason, code });\n\nconst unavailable = (operation: string) => error(\"storage\", operation);\nconst corrupt = (operation: string) => error(\"corrupt\", operation);\n\nconst validate = <A, I>(schema: Schema.Codec<A, I>, value: unknown, code: string) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => error(\"validation\", code)));\n\nconst decodeRows = <A, I>(schema: Schema.Codec<A, I>, rows: unknown, code: string) =>\n Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(Effect.mapError(() => corrupt(code)));\n\nconst initializeDoSubscriptionStore = Effect.fn(\"DoSubscriptionStore.initialize\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n\n const names = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'effect_agent_subscription_%'\n `.pipe(Effect.mapError(() => unavailable(\"inspect subscription storage\")));\n\n const decodedNames = yield* decodeRows(\n Schema.Struct({ name: Schema.String }),\n names,\n \"inspect subscription storage\",\n );\n\n const expected = new Set([\n \"effect_agent_subscription_store_state\",\n \"effect_agent_subscription_sequences\",\n \"effect_agent_subscriptions\",\n \"effect_agent_subscription_events\",\n \"effect_agent_subscription_deliveries\",\n ]);\n\n const hasState = decodedNames.some(\n ({ name }) => name === \"effect_agent_subscription_store_state\",\n );\n\n if (!hasState && decodedNames.length > 0) return yield* corrupt(\"partial subscription storage\");\n if (!hasState) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`CREATE TABLE effect_agent_subscription_store_state (\n singleton INTEGER PRIMARY KEY NOT NULL CHECK(singleton=1), storage_version INTEGER NOT NULL, alarm_generation INTEGER NOT NULL\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_sequences (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, sequence INTEGER NOT NULL,\n event_scan_cursor TEXT NOT NULL, delivery_scan_cursor TEXT NOT NULL, recovery_scan_cursor INTEGER NOT NULL,\n PRIMARY KEY (tenant_id, source_address)\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscriptions (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n ordinal INTEGER NOT NULL, source_name TEXT NOT NULL, source_version TEXT NOT NULL, matching_key TEXT NOT NULL,\n state TEXT NOT NULL, expires_at_millis INTEGER, recovery_at_millis INTEGER, recovery_present INTEGER NOT NULL DEFAULT 0, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id), UNIQUE (tenant_id, source_address, ordinal)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_owner ON effect_agent_subscriptions (tenant_id, source_address, owner_id, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_candidates ON effect_agent_subscriptions (tenant_id, source_address, source_name, source_version, matching_key, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_recovery ON effect_agent_subscriptions (tenant_id, source_address, recovery_at_millis, ordinal) WHERE recovery_at_millis IS NOT NULL`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_events (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, event_id TEXT NOT NULL, source_name TEXT NOT NULL,\n source_version TEXT NOT NULL, matching_key TEXT NOT NULL, payload_digest TEXT NOT NULL, cutoff INTEGER NOT NULL,\n cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, tombstone INTEGER NOT NULL DEFAULT 0, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, event_id)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_events_pending ON effect_agent_subscription_events (tenant_id, source_address, routing_complete, next_attempt_at_millis, event_id)`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_deliveries (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n event_id TEXT NOT NULL, delivery_key TEXT NOT NULL, state TEXT NOT NULL, next_attempt_at_millis INTEGER NOT NULL,\n record_json TEXT NOT NULL, PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id, event_id),\n UNIQUE (tenant_id, source_address, delivery_key)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_pending ON effect_agent_subscription_deliveries (tenant_id, source_address, state, next_attempt_at_millis, delivery_key)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`\n .withoutTransform;\n yield* sql`INSERT INTO effect_agent_subscription_store_state (singleton, storage_version, alarm_generation)\n VALUES (1, ${CURRENT_SUBSCRIPTION_STORE_VERSION}, 0)`.withoutTransform;\n }),\n )\n .pipe(Effect.mapError(() => unavailable(\"initialize subscription storage\")));\n\n return;\n }\n if (decodedNames.length !== expected.size || decodedNames.some(({ name }) => !expected.has(name)))\n return yield* corrupt(\"subscription storage tables\");\n\n const rows = yield* sql<\n Record<string, unknown>\n >`SELECT storage_version, alarm_generation FROM effect_agent_subscription_store_state WHERE singleton=1`.pipe(\n Effect.mapError(() => unavailable(\"read subscription storage version\")),\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"read subscription storage version\");\n\n if (state.length === 1 && state[0].storage_version === 2) {\n const failpoint = yield* SubscriptionFailpoint;\n\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n storage_version: number;\n }>`SELECT storage_version FROM effect_agent_subscription_store_state WHERE singleton=1`;\n\n if (current.length === 1 && current[0].storage_version === 3) return;\n if (current.length !== 1 || current[0].storage_version !== 2)\n return yield* corrupt(\"subscription version changed during upgrade\");\n yield* upgradeV2Subscriptions(1_900_000);\n yield* failpoint.hit(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_subscription_store_state SET storage_version=3 WHERE singleton=1`;\n yield* failpoint.hit(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.provide(BrowserCrypto.layer),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n SubscriptionError.make({\n reason: \"corrupt\",\n code: \"upgrade-v2-subscriptions\",\n cause: error,\n }),\n ),\n Effect.catchTag(\"SqlError\", () => unavailable(\"upgrade v2 subscriptions\")),\n Effect.catchTag(\"SchemaError\", () => corrupt(\"upgrade v2 subscription encoding\")),\n Effect.catchTag(\"SubscriptionFailpointError\", () =>\n unavailable(\"upgrade v2 subscriptions failpoint\"),\n ),\n );\n\n return;\n }\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\n state.length === 1\n ? `incompatible subscription storage version ${state[0].storage_version}; expected ${CURRENT_SUBSCRIPTION_STORE_VERSION}`\n : \"invalid subscription storage version row\",\n );\n});\n\nconst makeSubscriptionStore = Effect.fn(\"DoSubscriptionStore.make\")(function* (\n owned: SourcePartition,\n) {\n const partition = yield* validate(SourcePartition, owned, \"partition\");\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* SubscriptionFailpoint;\n const transactions = yield* DoSubscriptionTransaction;\n\n yield* initializeDoSubscriptionStore();\n\n const query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n code: string,\n ) => effect.pipe(Effect.mapError(() => unavailable(code)));\n\n const readIndexedDeadline = Effect.fn(\"DoSubscriptionStore.readIndexedDeadline\")(function* () {\n const scanRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor FROM effect_agent_subscription_sequences\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"read scan cursor deadline\",\n );\n\n const scans = yield* decodeRows(ScanRow, scanRows, \"read scan cursor deadline\");\n\n if (scans.length !== 1) return yield* corrupt(\"scan cursor deadline\");\n if (\n scans[0].event_scan_cursor !== \"\" ||\n scans[0].delivery_scan_cursor !== \"\" ||\n scans[0].recovery_scan_cursor !== 0\n )\n return 0;\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT MIN(deadline) AS deadline FROM (\n SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0\n UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND CASE WHEN json_valid(record_json) THEN\n ((state NOT IN ('delivered','refused') AND COALESCE(json_extract(record_json, '$.retry.parked'), 0)=0) OR (state='delivered' AND json_extract(record_json, '$.observeSettlement')=1))\n ELSE state<>'refused' END\n UNION ALL SELECT next_maintenance_at_millis FROM effect_agent_event_retention\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL\n )\n `,\n \"read subscription deadline\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({ deadline: Schema.NullOr(Schema.Number) }),\n rows,\n \"read subscription deadline\",\n );\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription deadline\");\n\n return decoded[0].deadline;\n });\n\n const replaceAlarm = Effect.fn(\"DoSubscriptionStore.replaceAlarm\")(function* (\n replace: DoSubscriptionReplaceAlarm,\n deadlineAtMillis: number | null,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_store_state SET alarm_generation=alarm_generation+1\n WHERE singleton=1 RETURNING storage_version, alarm_generation\n `,\n \"advance subscription alarm generation\",\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"advance subscription alarm generation\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\"subscription alarm state\");\n yield* failpoint.hit(\"subscription:alarm:before\");\n yield* replace({ deadlineAtMillis, generation: state[0].alarm_generation });\n yield* failpoint.hit(\"subscription:alarm:after\");\n });\n\n const transact = <A>(effect: Effect.Effect<A, SubscriptionError | SubscriptionFailpointError>) =>\n transactions.run((replace) =>\n Effect.gen(function* () {\n const value = yield* effect;\n\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n\n return value;\n }),\n );\n\n const store = yield* makeSqlSubscriptionStore(partition, {\n maxStoredJsonLength: 1_900_000,\n }).pipe(Effect.provideService(SqlSubscriptionTransaction, { run: transact }));\n\n const prearm = Effect.fn(\"DoSubscriptionStore.prearm\")(function* (deadlineAtMillis: number) {\n yield* transactions.run((replace) => replaceAlarm(replace, deadlineAtMillis));\n yield* failpoint.hit(\"subscription:prearm:after\");\n });\n\n const reconcile = Effect.gen(function* () {\n yield* transactions.run((replace) =>\n Effect.gen(function* () {\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n }),\n );\n yield* failpoint.hit(\"subscription:reconcile:after\");\n });\n\n return Context.make(SubscriptionStore, store).pipe(\n Context.add(DoSubscriptionAlarmControl, { prearm, reconcile }),\n );\n});\n\nexport const doSubscriptionStoreLayer = (\n partition: SourcePartition,\n): Layer.Layer<\n SubscriptionStore | DoSubscriptionAlarmControl,\n SubscriptionError,\n DoSubscriptionTransaction | SqlClientService.SqlClient\n> => Layer.effectContext(makeSubscriptionStore(partition));\n"],"mappings":";;;;;;;;;;;;;AAiBA,MAAM,qCAAqC;AAE3C,MAAM,UAAU,OAAO,OAAO;CAC5B,mBAAmB,OAAO;CAC1B,sBAAsB,OAAO;CAC7B,sBAAsB,OAAO;AAC/B,CAAC;AAED,MAAM,gBAAgB,OAAO,OAAO;CAClC,iBAAiB,OAAO;CACxB,kBAAkB,OAAO;AAC3B,CAAC;;AAYD,IAAa,4BAAb,cAA+C,QAAQ,QAOrD,CAAC,CAAC,4DAA4D,CAAC,CAAC,CAAC;AAEnE,IAAa,6BAAb,cAAgD,QAAQ,QAQtD,CAAC,CAAC,6DAA6D,CAAC,CAAC,CAAC;AAEpE,MAAM,SAAS,QAAqC,SAClD,kBAAkB,KAAK;CAAE;CAAQ;AAAK,CAAC;AAEzC,MAAM,eAAe,cAAsB,MAAM,WAAW,SAAS;AACrE,MAAM,WAAW,cAAsB,MAAM,WAAW,SAAS;AAEjE,MAAM,YAAkB,QAA4B,OAAgB,SAClE,OAAO,oBAAoB,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,eAAe,MAAM,cAAc,IAAI,CAAC,CAAC;AAEjG,MAAM,cAAoB,QAA4B,MAAe,SACnE,OAAO,oBAAoB,OAAO,MAAM,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,OAAO,eAAe,QAAQ,IAAI,CAAC,CAAC;AAElG,MAAM,gCAAgC,OAAO,GAAG,gCAAgC,CAAC,CAAC,aAAa;CAC7F,MAAM,MAAM,OAAO,iBAAiB;CAEpC,MAAM,QAAQ,OAAO,GAA4B;;IAE/C,KAAK,OAAO,eAAe,YAAY,8BAA8B,CAAC,CAAC;CAEzE,MAAM,eAAe,OAAO,WAC1B,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC,GACrC,OACA,8BACF;CAEA,MAAM,2BAAW,IAAI,IAAI;EACvB;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,WAAW,aAAa,MAC3B,EAAE,WAAW,SAAS,uCACzB;CAEA,IAAI,CAAC,YAAY,aAAa,SAAS,GAAG,OAAO,OAAO,QAAQ,8BAA8B;CAC9F,IAAI,CAAC,UAAU;EACb,OAAO,IACJ,gBACC,OAAO,IAAI,aAAa;GACtB,OAAO,GAAG;;SAEX;GACC,OAAO,GAAG;;;;SAIX;GACC,OAAO,GAAG;;;;;SAKX;GACC,OAAO,GAAG,6HACP;GACH,OAAO,GAAG,mKACP;GACH,OAAO,GAAG,+KACP;GACH,OAAO,GAAG;;;;;SAKX;GACC,OAAO,GAAG,4KACP;GACH,OAAO,GAAG;;;;;SAKX;GACC,OAAO,GAAG,6KACP;GACH,OAAO,GAAG,8KACP;GACH,OAAO,GAAG;qBACC,mCAAmC,MAAM;EACtD,CAAC,CACH,CAAC,CACA,KAAK,OAAO,eAAe,YAAY,iCAAiC,CAAC,CAAC;EAE7E;CACF;CACA,IAAI,aAAa,WAAW,SAAS,QAAQ,aAAa,MAAM,EAAE,WAAW,CAAC,SAAS,IAAI,IAAI,CAAC,GAC9F,OAAO,OAAO,QAAQ,6BAA6B;CAErD,MAAM,OAAO,OAAO,GAEnB,wGAAwG,KACvG,OAAO,eAAe,YAAY,mCAAmC,CAAC,CACxE;CAEA,MAAM,QAAQ,OAAO,WAAW,eAAe,MAAM,mCAAmC;CAExF,IAAI,MAAM,WAAW,KAAK,MAAM,EAAE,CAAC,oBAAoB,GAAG;EACxD,MAAM,YAAY,OAAO;EAEzB,OAAO,IACJ,gBACC,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,GAErB;GAEF,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,oBAAoB,GAAG;GAC9D,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,oBAAoB,GACzD,OAAO,OAAO,QAAQ,6CAA6C;GACrE,OAAO,uBAAuB,IAAS;GACvC,OAAO,UAAU,IAAI,wBAAwB;GAC7C,OAAO,GAAG;GACV,OAAO,UAAU,IAAI,uBAAuB;EAC9C,CAAC,CACH,CAAC,CACA,KACC,OAAO,QAAQ,cAAc,KAAK,GAClC,OAAO,SAAS,wBAAwB,UACtC,kBAAkB,KAAK;GACrB,QAAQ;GACR,MAAM;GACN,OAAO;EACT,CAAC,CACH,GACA,OAAO,SAAS,kBAAkB,YAAY,0BAA0B,CAAC,GACzE,OAAO,SAAS,qBAAqB,QAAQ,kCAAkC,CAAC,GAChF,OAAO,SAAS,oCACd,YAAY,oCAAoC,CAClD,CACF;EAEF;CACF;CAEA,IAAI,MAAM,WAAW,KAAK,MAAM,EAAE,CAAC,oBAAoB,oCACrD,OAAO,OAAO,QACZ,MAAM,WAAW,IACb,6CAA6C,MAAM,EAAE,CAAC,gBAAgB,aAAa,uCACnF,0CACN;AACJ,CAAC;AAED,MAAM,wBAAwB,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAClE,OACA;CACA,MAAM,YAAY,OAAO,SAAS,iBAAiB,OAAO,WAAW;CACrE,MAAM,MAAM,OAAO,iBAAiB;CACpC,MAAM,YAAY,OAAO;CACzB,MAAM,eAAe,OAAO;CAE5B,OAAO,8BAA8B;CAErC,MAAM,SACJ,QACA,SACG,OAAO,KAAK,OAAO,eAAe,YAAY,IAAI,CAAC,CAAC;CAEzD,MAAM,sBAAsB,OAAO,GAAG,yCAAyC,CAAC,CAAC,aAAa;EAC5F,MAAM,WAAW,OAAO,MACtB,GAA4B;;wBAEV,UAAU,SAAS,sBAAsB,UAAU,QAAQ;OAE7E,2BACF;EAEA,MAAM,QAAQ,OAAO,WAAW,SAAS,UAAU,2BAA2B;EAE9E,IAAI,MAAM,WAAW,GAAG,OAAO,OAAO,QAAQ,sBAAsB;EACpE,IACE,MAAM,EAAE,CAAC,sBAAsB,MAC/B,MAAM,EAAE,CAAC,yBAAyB,MAClC,MAAM,EAAE,CAAC,yBAAyB,GAElC,OAAO;EAET,MAAM,OAAO,OAAO,MAClB,GAA4B;;;4BAGN,UAAU,SAAS,sBAAsB,UAAU,QAAQ;;4BAE3D,UAAU,SAAS,sBAAsB,UAAU,QAAQ;;;;4BAI3D,UAAU,SAAS,sBAAsB,UAAU,QAAQ;;4BAE3D,UAAU,SAAS,sBAAsB,UAAU,QAAQ;;OAGjF,4BACF;EAEA,MAAM,UAAU,OAAO,WACrB,OAAO,OAAO,EAAE,UAAU,OAAO,OAAO,OAAO,MAAM,EAAE,CAAC,GACxD,MACA,4BACF;EAEA,IAAI,QAAQ,WAAW,GAAG,OAAO,OAAO,QAAQ,uBAAuB;EAEvE,OAAO,QAAQ,EAAE,CAAC;CACpB,CAAC;CAED,MAAM,eAAe,OAAO,GAAG,kCAAkC,CAAC,CAAC,WACjE,SACA,kBACA;EACA,MAAM,OAAO,OAAO,MAClB,GAA4B;;;OAI5B,uCACF;EAEA,MAAM,QAAQ,OAAO,WAAW,eAAe,MAAM,uCAAuC;EAE5F,IAAI,MAAM,WAAW,KAAK,MAAM,EAAE,CAAC,oBAAoB,oCACrD,OAAO,OAAO,QAAQ,0BAA0B;EAClD,OAAO,UAAU,IAAI,2BAA2B;EAChD,OAAO,QAAQ;GAAE;GAAkB,YAAY,MAAM,EAAE,CAAC;EAAiB,CAAC;EAC1E,OAAO,UAAU,IAAI,0BAA0B;CACjD,CAAC;CAED,MAAM,YAAe,WACnB,aAAa,KAAK,YAChB,OAAO,IAAI,aAAa;EACtB,MAAM,QAAQ,OAAO;EAErB,OAAO,aAAa,SAAS,OAAO,oBAAoB,CAAC;EAEzD,OAAO;CACT,CAAC,CACH;CAEF,MAAM,QAAQ,OAAO,yBAAyB,WAAW,EACvD,qBAAqB,KACvB,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,4BAA4B,EAAE,KAAK,SAAS,CAAC,CAAC;CAE5E,MAAM,SAAS,OAAO,GAAG,4BAA4B,CAAC,CAAC,WAAW,kBAA0B;EAC1F,OAAO,aAAa,KAAK,YAAY,aAAa,SAAS,gBAAgB,CAAC;EAC5E,OAAO,UAAU,IAAI,2BAA2B;CAClD,CAAC;CAED,MAAM,YAAY,OAAO,IAAI,aAAa;EACxC,OAAO,aAAa,KAAK,YACvB,OAAO,IAAI,aAAa;GACtB,OAAO,aAAa,SAAS,OAAO,oBAAoB,CAAC;EAC3D,CAAC,CACH;EACA,OAAO,UAAU,IAAI,8BAA8B;CACrD,CAAC;CAED,OAAO,QAAQ,KAAK,mBAAmB,KAAK,CAAC,CAAC,KAC5C,QAAQ,IAAI,4BAA4B;EAAE;EAAQ;CAAU,CAAC,CAC/D;AACF,CAAC;AAED,MAAa,4BACX,cAKG,MAAM,cAAc,sBAAsB,SAAS,CAAC"}
@@ -3,7 +3,7 @@ import { DoStorageConfig } from "./DoStorageConfig.mjs";
3
3
  import { DoStorageFailpoint, DoStorageFailpointHandler } from "./DoStorageFailpoint.mjs";
4
4
  import { Crypto, Layer } from "effect";
5
5
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
6
- import { ThreadStore } from "@effect-agent/thread/ThreadStore";
6
+ import { ThreadStore } from "effect-agent/thread-store";
7
7
  declare namespace DoThreadStore_d_exports {
8
8
  export { DoStorageInitializationError, DoStorageOptions, layer, storageConfigLayer, storageFailpointLayer, threadStoreLayer };
9
9
  }
@@ -17,7 +17,7 @@ interface DoStorageOptions {
17
17
  readonly observationPollInterval?: number | undefined;
18
18
  /**
19
19
  * Submission ownership lease duration in milliseconds (D5). Defaults to
20
- * `DEFAULT_OWNERSHIP_LEASE_DURATION` from `@effect-agent/thread`.
20
+ * `DEFAULT_OWNERSHIP_LEASE_DURATION` from `effect-agent/submission-ledger`.
21
21
  */
22
22
  readonly ownershipLeaseDuration?: number | undefined;
23
23
  /**
@@ -2,15 +2,15 @@ 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-DHqCQeBU.mjs";
5
+ import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-dJ01KSKf.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
- import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@effect-agent/thread/Digest";
9
- import { CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, Digest, ObservationOffset } from "@effect-agent/thread/Records";
10
- import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, MAX_THREAD_EXPORT_RECORDS, SaveCheckpointRequest, SaveRecoveryCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadRead, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest } from "@effect-agent/thread/ThreadStore";
11
8
  import { SqliteClient } from "@effect/sql-sqlite-do";
12
- import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "@effect-agent/thread/SubmissionLedger";
9
+ import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "effect-agent/digest";
10
+ import { CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, Digest, ObservationOffset } from "effect-agent/records";
11
+ import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, MAX_THREAD_EXPORT_RECORDS, SaveCheckpointRequest, SaveRecoveryCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadRead, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest } from "effect-agent/thread-store";
13
12
  import { BrowserCrypto } from "@effect/platform-browser";
13
+ import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "effect-agent/submission-ledger";
14
14
  //#region src/DoThreadStore.ts
15
15
  var DoThreadStore_exports = /* @__PURE__ */ __exportAll({
16
16
  layer: () => layer,
@@ -36,11 +36,11 @@ const schemaStoreError = (operation, error) => ThreadStoreError.make({
36
36
  message: error.message
37
37
  });
38
38
  const makeOffset = Effect.fn(function* (threadId, sequence) {
39
- return yield* Schema.decodeUnknownEffect(CanonicalSequence)(sequence).pipe(Effect.flatMap((validatedSequence) => Schema.decodeUnknownEffect(ObservationOffset)(`${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`)), Effect.mapError((error) => schemaStoreError("encode observation offset", error)));
39
+ 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)));
40
40
  });
41
41
  const parseOffset = Effect.fn(function* (threadId, offset) {
42
42
  if (offset === void 0) return ZERO_CANONICAL_SEQUENCE;
43
- const text = yield* Schema.decodeUnknownEffect(OffsetText)(offset).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
43
+ const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
44
44
  const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;
45
45
  if (!text.startsWith(threadPrefix)) return yield* ThreadStoreError.make({
46
46
  operation: "decode observation offset",
@@ -51,7 +51,7 @@ const parseOffset = Effect.fn(function* (threadId, offset) {
51
51
  operation: "decode observation offset",
52
52
  message: "The observation offset is malformed."
53
53
  });
54
- return yield* Schema.decodeUnknownEffect(CanonicalSequence)(Number(sequenceText)).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
54
+ return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(Effect.mapError((error) => schemaStoreError("decode observation offset", error)));
55
55
  });
56
56
  const mapFence = (threadId, error) => FenceRejected.make({
57
57
  threadId,
@@ -72,9 +72,9 @@ const decodeEnvelope = Effect.fn(function* (row) {
72
72
  operation: "decode canonical record",
73
73
  message: error.message
74
74
  })));
75
- const threadId = yield* Schema.decodeUnknownEffect(CanonicalRecordEnvelope.fields.threadId)(row.thread_id).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
75
+ const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(row.thread_id).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
76
76
  const offset = yield* makeOffset(threadId, row.sequence);
77
- const batchId = yield* Schema.decodeUnknownEffect(CanonicalRecordEnvelope.fields.batchId)(row.batch_id).pipe(Effect.mapError((error) => schemaStoreError("decode batch identity", error)));
77
+ const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(row.batch_id).pipe(Effect.mapError((error) => schemaStoreError("decode batch identity", error)));
78
78
  return CanonicalRecordEnvelope.make({
79
79
  threadId,
80
80
  batchId,
@@ -98,7 +98,7 @@ const tailDigestAt = Effect.fn("DoThreadStore.tailDigestAt")(function* (journal,
98
98
  threadId,
99
99
  reason: "digest-mismatch"
100
100
  });
101
- return yield* Schema.decodeUnknownEffect(Digest)(digests[0]).pipe(Effect.mapError((error) => schemaStoreError("decode checkpoint digest", error)));
101
+ return yield* Schema.decodeEffect(Digest)(digests[0]).pipe(Effect.mapError((error) => schemaStoreError("decode checkpoint digest", error)));
102
102
  });
103
103
  const groupByKey = (rows, key) => {
104
104
  const grouped = /* @__PURE__ */ new Map();
@@ -225,14 +225,14 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
225
225
  const provideCrypto = (effect) => Effect.provideService(effect, Crypto.Crypto, crypto);
226
226
  const hitFailpoint = Effect.fn((location) => failpoint.hit(location).pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error))));
227
227
  const materialize = Effect.fn("DoThreadStore.materialize")(function* (request) {
228
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadMaterialization))(request).pipe(Effect.mapError((error) => schemaStoreError("validate materialization", error)));
228
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(request).pipe(Effect.mapError((error) => schemaStoreError("validate materialization", error)));
229
229
  const now = yield* Clock.currentTimeMillis;
230
230
  yield* hitFailpoint("materialize:before");
231
231
  yield* journal.materialize(validated.threadId, new Date(now).toISOString(), EMPTY_TAIL_DIGEST, validated.producerEpoch).pipe(Effect.mapError((error) => error._tag === "DoFenceRejected" ? mapFence(validated.threadId, error) : storeError("materialize thread", error)));
232
232
  yield* hitFailpoint("materialize:after");
233
233
  });
234
234
  const append = Effect.fn("DoThreadStore.append")(function* (request) {
235
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(FencedAppendRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate canonical append", error)));
235
+ const validated = yield* Schema.decodeEffect(Schema.toType(FencedAppendRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate canonical append", error)));
236
236
  yield* requireThread(journal, validated.threadId);
237
237
  const tailDigest = yield* provideCrypto(digestCanonicalBatch(validated.expectedTailDigest, validated.batch)).pipe(Effect.mapError((error) => storeError("digest canonical append", error)));
238
238
  const batchJson = yield* encodeCanonicalBatch(validated.batch);
@@ -240,7 +240,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
240
240
  recordId: record.recordId,
241
241
  recordJson
242
242
  }))));
243
- const rawRequest = yield* Schema.decodeUnknownEffect(RawAppendRequest)({
243
+ const rawRequest = yield* Schema.decodeEffect(RawAppendRequest)({
244
244
  threadId: validated.threadId,
245
245
  batchId: validated.batch.batchId,
246
246
  batchDigest: tailDigest,
@@ -266,7 +266,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
266
266
  reason: error.reason
267
267
  });
268
268
  return storeError("append canonical batch", error);
269
- }), Effect.flatMap((result) => Schema.decodeUnknownEffect(AppendResult)(result).pipe(Effect.mapError((error) => schemaStoreError("decode append result", error)))));
269
+ }), Effect.flatMap((result) => Schema.decodeEffect(AppendResult)(result).pipe(Effect.mapError((error) => schemaStoreError("decode append result", error)))));
270
270
  yield* hitFailpoint("append:after");
271
271
  return result;
272
272
  });
@@ -278,7 +278,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
278
278
  };
279
279
  });
280
280
  const readEffect = Effect.fn("DoThreadStore.read")(function* (request) {
281
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadRead))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread read", error)));
281
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadRead))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread read", error)));
282
282
  yield* requireThread(journal, validated.threadId);
283
283
  return (yield* loadRecords(RawReadRequest.make({
284
284
  threadId: validated.threadId,
@@ -288,7 +288,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
288
288
  });
289
289
  const read = (request) => Stream.unwrap(readEffect(request));
290
290
  const observeEffect = Effect.fn("DoThreadStore.observe")(function* (request) {
291
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadObservation))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread observation", error)));
291
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread observation", error)));
292
292
  yield* requireThread(journal, validated.threadId);
293
293
  const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);
294
294
  const cursor = yield* Ref.make(initialSequence);
@@ -309,7 +309,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
309
309
  });
310
310
  const observe = (request) => Stream.unwrap(observeEffect(request));
311
311
  const exportThread = Effect.fn("DoThreadStore.export")(function* (request) {
312
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadExportRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread export", error)));
312
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadExportRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate thread export", error)));
313
313
  yield* requireThread(journal, validated.threadId);
314
314
  const exported = yield* journal.exportThread(validated.threadId).pipe(Effect.mapError((error) => storeError("export thread", error)));
315
315
  const records = yield* Effect.forEach(exported.records, decodeEnvelope);
@@ -317,7 +317,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
317
317
  operation: "decode thread export",
318
318
  message: "The thread exceeds the current export record limit."
319
319
  });
320
- const tailDigest = yield* Schema.decodeUnknownEffect(Digest)(exported.thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode export tail digest", error)));
320
+ const tailDigest = yield* Schema.decodeEffect(Digest)(exported.thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode export tail digest", error)));
321
321
  return ThreadExport.make({
322
322
  format: "effect-agent/thread@1",
323
323
  threadId: validated.threadId,
@@ -327,9 +327,9 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
327
327
  });
328
328
  });
329
329
  const inspectTail = Effect.fn("DoThreadStore.inspectTail")(function* (request) {
330
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadTailRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate tail inspection", error)));
330
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate tail inspection", error)));
331
331
  const thread = yield* requireThread(journal, validated.threadId);
332
- const tailDigest = yield* Schema.decodeUnknownEffect(Digest)(thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode tail digest", error)));
332
+ const tailDigest = yield* Schema.decodeEffect(Digest)(thread.tail_digest).pipe(Effect.mapError((error) => schemaStoreError("decode tail digest", error)));
333
333
  return ThreadTail.make({
334
334
  threadId: validated.threadId,
335
335
  tailSequence: thread.tail_sequence,
@@ -338,7 +338,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
338
338
  });
339
339
  });
340
340
  const saveCheckpoint = Effect.fn("DoThreadStore.saveCheckpoint")(function* (request) {
341
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SaveCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint", error)));
341
+ const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint", error)));
342
342
  const thread = yield* requireThread(journal, validated.checkpoint.threadId);
343
343
  if (validated.checkpoint.throughSequence > thread.tail_sequence) return yield* CheckpointRejected.make({
344
344
  threadId: validated.checkpoint.threadId,
@@ -363,7 +363,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
363
363
  yield* hitFailpoint("save-checkpoint:after");
364
364
  });
365
365
  const loadCheckpoint = Effect.fn("DoThreadStore.loadCheckpoint")(function* (request) {
366
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint lookup", error)));
366
+ const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint lookup", error)));
367
367
  const thread = yield* requireThread(journal, validated.threadId);
368
368
  const rows = yield* journal.loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence).pipe(Effect.mapError((error) => storeError("load checkpoint", error)));
369
369
  if (rows.length === 0) return Option.none();
@@ -384,12 +384,12 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
384
384
  return Option.some(checkpoint);
385
385
  });
386
386
  const saveRecoveryCheckpoint = Effect.fn("DoThreadStore.saveRecoveryCheckpoint")(function* (request) {
387
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SaveRecoveryCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint", error)));
387
+ const validated = yield* Schema.decodeEffect(Schema.toType(SaveRecoveryCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint", error)));
388
388
  const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);
389
389
  yield* journal.saveRecoveryCheckpoint(validated, checkpointJson).pipe(Effect.mapError((error) => error._tag === "CheckpointRejected" || error._tag === "FenceRejected" || error._tag === "ThreadNotMaterialized" ? error : storeError("save recovery checkpoint", error)));
390
390
  });
391
391
  const loadRecoveryCheckpoint = Effect.fn("DoThreadStore.loadRecoveryCheckpoint")(function* (request) {
392
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint lookup", error)));
392
+ const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint lookup", error)));
393
393
  const thread = yield* requireThread(journal, validated.threadId);
394
394
  const corrupt = () => CheckpointRejected.make({
395
395
  threadId: validated.threadId,
@@ -440,7 +440,7 @@ const threadStoreLayer = Layer.effectContext(makeServices());
440
440
  * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults
441
441
  * cannot drift.
442
442
  */
443
- const storageConfigLayer = (options) => Layer.effect(DoStorageConfig)(Schema.decodeUnknownEffect(DoStorageConfigValue)({
443
+ const storageConfigLayer = (options) => Layer.effect(DoStorageConfig)(Schema.decodeEffect(DoStorageConfigValue)({
444
444
  observationPollInterval: options.observationPollInterval ?? 25,
445
445
  ownershipLeaseDuration: options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),
446
446
  maxStoredValueBytes: options.maxStoredValueBytes ?? 19e5,
@@ -1 +1 @@
1
- {"version":3,"file":"DoThreadStore.mjs","names":[],"sources":["../src/DoThreadStore.ts"],"sourcesContent":["import { digestCanonicalBatch, EMPTY_TAIL_DIGEST } from \"@effect-agent/thread/Digest\";\nimport {\n CanonicalBatch,\n CanonicalRecord,\n CanonicalRecordEnvelope,\n CanonicalSequence,\n Digest,\n ObservationOffset,\n} from \"@effect-agent/thread/Records\";\nimport { DEFAULT_OWNERSHIP_LEASE_DURATION } from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n AppendResult,\n CheckpointRejected,\n ThreadCheckpoint,\n ThreadExport,\n ThreadExportRequest,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadObservation,\n ThreadRead,\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/ThreadStore\";\nimport { 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 * 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/thread`.\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.decodeUnknownEffect(CanonicalSequence)(sequence).pipe(\n Effect.flatMap((validatedSequence) =>\n Schema.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(Schema.toType(FencedAppendRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate canonical append\", error)));\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.decodeUnknownEffect(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.decodeUnknownEffect(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.fn(\"DoThreadStore.loadRecords\")(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: ThreadRead) {\n const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadRead))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\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.fn(\"DoThreadStore.observe\")(function* (request: ThreadObservation) {\n const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadObservation))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate thread observation\", error)));\n\n yield* requireThread(journal, validated.threadId);\n const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);\n const cursor = yield* Ref.make(initialSequence);\n\n const poll = Effect.fn(\"DoThreadStore.observePoll\")(function* () {\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 yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(Stream.tap((record) => Ref.set(cursor, record.sequence)));\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(Stream.flatten);\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request));\n\n const exportThread: ThreadStore[\"Service\"][\"export\"] = Effect.fn(\"DoThreadStore.export\")(\n function* (request: ThreadExportRequest) {\n const validated = yield* Schema.decodeUnknownEffect(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.decodeUnknownEffect(Digest)(\n exported.thread.tail_digest,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode export tail digest\", error)));\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.decodeUnknownEffect(Schema.toType(ThreadTailRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate tail inspection\", error)));\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const tailDigest = yield* Schema.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(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.decodeUnknownEffect(\n Schema.toType(SaveRecoveryCheckpointRequest),\n )(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate recovery checkpoint\", error)),\n );\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.decodeUnknownEffect(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 threadStore = ThreadStore.of({\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.decodeUnknownEffect(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":";;;;;;;;;;;;;;;;;;;;AAyGA,MAAM,aAAa,OAAO,OAAO,MAAM,OAAO,YAAY,IAAQ,CAAC;AACnE,MAAM,mBAAmB;AACzB,MAAM,0BAA0B,OAAO,WAAW,iBAAiB,CAAC,CAAC,CAAC;AACtE,MAAM,WAAW,OAAO,GAAG,MAAM;AACjC,MAAM,oBAAoB,OAAO,GAAG,eAAe;AACnD,MAAM,qBAAqB,OAAO,GAAG,gBAAgB;AACrD,MAAM,yBAAyB,OAAO,GAAG,oBAAoB;AAE7D,MAAM,cAAc,WAAmB,UACrC,iBAAiB,KAAK;CACpB,OAAO;CACP;CACA,SAAS,MAAM;AACjB,CAAC;AAEH,MAAM,oBAAoB,WAAmB,UAC3C,iBAAiB,KAAK;CACpB,OAAO;CACP;CACA,SAAS,MAAM;AACjB,CAAC;AAEH,MAAM,aAAa,OAAO,GAAG,WAC3B,UACA,UACuD;CACvD,OAAO,OAAO,OAAO,oBAAoB,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,KACpE,OAAO,SAAS,sBACd,OAAO,oBAAoB,iBAAiB,CAAC,CAC3C,GAAG,mBAAmB,mBAAmB,QAAQ,EAAE,GAAG,mBACxD,CACF,GACA,OAAO,UAAU,UAAU,iBAAiB,6BAA6B,KAAK,CAAC,CACjF;AACF,CAAC;AAED,MAAM,cAAc,OAAO,GAAG,WAC5B,UACA,QACuD;CACvD,IAAI,WAAW,KAAA,GAAW,OAAO;CAEjC,MAAM,OAAO,OAAO,OAAO,oBAAoB,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,KACjE,OAAO,UAAU,UAAU,iBAAiB,6BAA6B,KAAK,CAAC,CACjF;CAEA,MAAM,eAAe,GAAG,mBAAmB,mBAAmB,QAAQ,EAAE;CAExE,IAAI,CAAC,KAAK,WAAW,YAAY,GAC/B,OAAO,OAAO,iBAAiB,KAAK;EAClC,WAAW;EACX,SAAS;CACX,CAAC;CAEH,MAAM,eAAe,KAAK,MAAM,aAAa,MAAM;CAEnD,IAAI,CAAC,oBAAoB,KAAK,YAAY,GACxC,OAAO,OAAO,iBAAiB,KAAK;EAClC,WAAW;EACX,SAAS;CACX,CAAC;CAGH,OAAO,OAAO,OAAO,oBAAoB,iBAAiB,CAAC,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,KAChF,OAAO,UAAU,UAAU,iBAAiB,6BAA6B,KAAK,CAAC,CACjF;AACF,CAAC;AAED,MAAM,YAAY,UAA6C,UAC7D,cAAc,KAAK;CACjB;CACA,aAAa,MAAM;CACnB,gBAAgB,MAAM;AACxB,CAAC;AAEH,MAAM,wBAAwB,OAAO,GAAG,WACtC,QAC4C;CAC5C,OAAO,OAAO,OAAO,aAAa,OAAO,eAAe,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAChF,OAAO,UAAU,UAAU,iBAAiB,2BAA2B,KAAK,CAAC,CAC/E;AACF,CAAC;AAED,MAAM,uBAAuB,OAAO,GAAG,WACrC,OAC4C;CAC5C,OAAO,OAAO,OAAO,aAAa,OAAO,eAAe,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAC9E,OAAO,UAAU,UAAU,iBAAiB,0BAA0B,KAAK,CAAC,CAC9E;AACF,CAAC;AAED,MAAM,mBAAmB,OAAO,GAAG,WACjC,YAC4C;CAC5C,OAAO,OAAO,OAAO,aAAa,OAAO,eAAe,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KACrF,OAAO,UAAU,UAAU,iBAAiB,qBAAqB,KAAK,CAAC,CACzE;AACF,CAAC;AAED,MAAM,iBAAiB,OAAO,GAAG,WAAW,KAKzC;CACD,MAAM,SAAS,OAAO,OAAO,aAAa,OAAO,eAAe,eAAe,CAAC,CAAC,CAC/E,IAAI,WACN,CAAC,CAAC,KACA,OAAO,UAAU,UACf,iBAAiB,KAAK;EACpB,WAAW;EACX,SAAS,MAAM;CACjB,CAAC,CACH,CACF;CAEA,MAAM,WAAW,OAAO,OAAO,oBAAoB,wBAAwB,OAAO,QAAQ,CAAC,CACzF,IAAI,SACN,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,0BAA0B,KAAK,CAAC,CAAC;CAEpF,MAAM,SAAS,OAAO,WAAW,UAAU,IAAI,QAAQ;CAEvD,MAAM,UAAU,OAAO,OAAO,oBAAoB,wBAAwB,OAAO,OAAO,CAAC,CACvF,IAAI,QACN,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,yBAAyB,KAAK,CAAC,CAAC;CAEnF,OAAO,wBAAwB,KAAK;EAClC;EACA;EACA,UAAU,IAAI;EACd;EACA;CACF,CAAC;AACH,CAAC;AAED,MAAM,mBAAmB,OAAO,GAAG,WACjC,gBACsD;CACtD,OAAO,OAAO,OAAO,aAAa,OAAO,eAAe,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KACzF,OAAO,UAAU,UAAU,iBAAiB,qBAAqB,KAAK,CAAC,CACzE;AACF,CAAC;AAED,MAAM,gBAAgB,OAAO,GAAG,6BAA6B,CAAC,CAAC,WAC7D,SACA,UACA;CACA,MAAM,OAAO,OAAO,QACjB,UAAU,QAAQ,CAAC,CACnB,KAAK,OAAO,UAAU,UAAU,WAAW,eAAe,KAAK,CAAC,CAAC;CAEpE,IAAI,KAAK,WAAW,GAClB,OAAO,OAAO,sBAAsB,KAAK,EAAE,SAAS,CAAC;CAGvD,OAAO,KAAK;AACd,CAAC;AAED,MAAM,eAAe,OAAO,GAAG,4BAA4B,CAAC,CAAC,WAC3D,SACA,UACA,UACA;CACA,IAAI,aAAa,GAAG,OAAO;CAE3B,MAAM,UAAU,OAAO,QACpB,gBAAgB,UAAU,QAAQ,CAAC,CACnC,KAAK,OAAO,UAAU,UAAU,WAAW,0BAA0B,KAAK,CAAC,CAAC;CAE/E,IAAI,QAAQ,WAAW,GACrB,OAAO,OAAO,mBAAmB,KAAK;EACpC;EACA,QAAQ;CACV,CAAC;CAGH,OAAO,OAAO,OAAO,oBAAoB,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAC3D,OAAO,UAAU,UAAU,iBAAiB,4BAA4B,KAAK,CAAC,CAChF;AACF,CAAC;AAED,MAAM,cACJ,MACA,QAC0C;CAC1C,MAAM,0BAAU,IAAI,IAAsB;CAE1C,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,WAAW,QAAQ,IAAI,IAAI,GAAG,CAAC;EAErC,IAAI,aAAa,KAAA,GACf,QAAQ,IAAI,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;OAE3B,SAAS,KAAK,GAAG;CAErB;CAEA,OAAO;AACT;;;;;;AAOA,MAAM,wBAAwB,OAAO,GAAG,qCAAqC,CAAC,CAAC,WAC7E,SACA,QACA;CACA,MAAM,SAAS,OAAO,QAAQ,mBAAmB;CAEjD,MAAM,UAAU,OAAO,OAAO,QAAQ,OAAO,UAAU,UACrD,OAAO,aAAa,OAAO,eAAe,cAAc,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,KAC3E,OAAO,KAAK,aAAa;EAAE;EAAS,KAAK;CAAM,EAAE,GACjD,OAAO,UAAU,UACf,yBAAyB,KAAK;EAC5B,OAAO;EACP,QAAQ,GAAG,MAAM,UAAU,GAAG,MAAM;EACpC,SAAS,MAAM;CACjB,CAAC,CACH,CACF,CACF;CAEA,MAAM,UAAU,OAAO,OAAO,QAAQ,OAAO,UAAU,WACrD,OAAO,aAAa,OAAO,eAAe,eAAe,CAAC,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,KAC9E,OAAO,KAAK,aAAa;EAAE;EAAS,KAAK;CAAO,EAAE,GAClD,OAAO,UAAU,UACf,yBAAyB,KAAK;EAC5B,OAAO;EACP,QAAQ,GAAG,OAAO,UAAU,GAAG,OAAO;EACtC,SAAS,MAAM;CACjB,CAAC,CACH,CACF,CACF;CAEA,MAAM,cAAc,OAAO,OAAO,QAAQ,OAAO,cAAc,eAC7D,OAAO,aAAa,OAAO,eAAe,gBAAgB,CAAC,CAAC,CAAC,WAAW,eAAe,CAAC,CAAC,KACvF,OAAO,KAAK,aAAa;EAAE;EAAS,KAAK;CAAW,EAAE,GACtD,OAAO,UAAU,UACf,yBAAyB,KAAK;EAC5B,OAAO;EACP,QAAQ,GAAG,WAAW,UAAU,GAAG,WAAW;EAC9C,SAAS,MAAM;CACjB,CAAC,CACH,CACF,CACF;CAEA,MAAM,kBAAkB,WAAW,UAAU,EAAE,UAAU,IAAI,SAAS;CACtE,MAAM,kBAAkB,WAAW,UAAU,EAAE,UAAU,IAAI,SAAS;CACtE,MAAM,sBAAsB,WAAW,cAAc,EAAE,UAAU,IAAI,SAAS;CAC9E,MAAM,kBAAkB,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,OAAO,SAAS,CAAC;CAEhF,KAAK,MAAM,UAAU,OAAO,SAAS;EACnC,MAAM,gBAAgB,gBAAgB,IAAI,OAAO,SAAS,KAAK,CAAC;EAChE,MAAM,gBAAgB,gBAAgB,IAAI,OAAO,SAAS,KAAK,CAAC;EAChE,MAAM,oBAAoB,oBAAoB,IAAI,OAAO,SAAS,KAAK,CAAC;EACxE,MAAM,iBAAiB,WAAW,gBAAgB,EAAE,UAAU,IAAI,QAAQ;EAC1E,IAAI,iBAAiB;EACrB,IAAI,mBAAmB;EACvB,MAAM,8BAAc,IAAI,IAAoB,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;EAEpE,KAAK,MAAM,EAAE,SAAS,gBAAgB,KAAK,cAAc,eAAe;GACtE,MAAM,MAAM,GAAG,SAAS,UAAU,GAAG,SAAS;GAE9C,IACE,eAAe,YAAY,SAAS,YACpC,SAAS,mBAAmB,oBAC5B,SAAS,kBAAkB,SAAS,iBAAiB,eAAe,QAAQ,SAAS,GAErF,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ;IACR,SAAS;GACX,CAAC;GAGH,MAAM,SAAS,OAAO,qBAAqB,gBAAgB,cAAc,CAAC,CAAC,KACzE,OAAO,eAAe,OAAO,QAAQ,MAAM,GAC3C,OAAO,UAAU,UACf,yBAAyB,KAAK;IAC5B,OAAO;IACP,QAAQ;IACR,SAAS,MAAM;GACjB,CAAC,CACH,CACF;GAEA,IAAI,SAAS,iBAAiB,UAAU,SAAS,gBAAgB,QAC/D,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ;IACR,SAAS;GACX,CAAC;GAGH,MAAM,eAAe,eAAe,IAAI,SAAS,QAAQ,KAAK,CAAC;GAE/D,IAAI,aAAa,WAAW,eAAe,QAAQ,QACjD,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ;IACR,SAAS;GACX,CAAC;GAEH,KAAK,IAAI,QAAQ,GAAG,QAAQ,eAAe,QAAQ,QAAQ,SAAS;IAClE,MAAM,iBAAiB,eAAe,QAAQ;IAC9C,MAAM,eAAe,aAAa;IAElC,MAAM,eAAe,OAAO,OAAO,aAAa,OAAO,eAAe,eAAe,CAAC,CAAC,CACrF,cACF,CAAC,CAAC,KACA,OAAO,UAAU,UACf,yBAAyB,KAAK;KAC5B,OAAO;KACP,QAAQ;KACR,SAAS,MAAM;IACjB,CAAC,CACH,CACF;IAEA,MAAM,aAAa,OAAO,OAAO,aAAa,OAAO,eAAe,eAAe,CAAC,CAAC,CACnF,aAAa,OACf,CAAC,CAAC,KACA,OAAO,UAAU,UACf,yBAAyB,KAAK;KAC5B,OAAO;KACP,QAAQ,GAAG,IAAI,GAAG,aAAa,IAAI;KACnC,SAAS,MAAM;IACjB,CAAC,CACH,CACF;IAEA,IACE,aAAa,IAAI,aAAa,SAAS,iBAAiB,SACxD,aAAa,IAAI,cAAc,eAAe,YAC9C,iBAAiB,YAEjB,OAAO,OAAO,yBAAyB,KAAK;KAC1C,OAAO;KACP,QAAQ,GAAG,IAAI,GAAG,aAAa,IAAI;KACnC,SAAS;IACX,CAAC;GAEL;GAEA,iBAAiB;GACjB,mBAAmB,SAAS,gBAAgB;GAC5C,YAAY,IAAI,SAAS,eAAe,MAAM;EAChD;EAEA,IACE,cAAc,WAAW,OAAO,iBAChC,OAAO,kBAAkB,mBAAmB,KAC5C,OAAO,gBAAgB,gBAEvB,OAAO,OAAO,yBAAyB,KAAK;GAC1C,OAAO;GACP,QAAQ,OAAO;GACf,SAAS;EACX,CAAC;EAGH,KAAK,MAAM,cAAc,mBACvB,IACE,WAAW,QAAQ,aAAa,OAAO,aACvC,WAAW,QAAQ,oBAAoB,WAAW,IAAI,oBACtD,WAAW,QAAQ,eAAe,WAAW,IAAI,eACjD,YAAY,IAAI,WAAW,IAAI,gBAAgB,MAAM,WAAW,IAAI,aAEpE,OAAO,OAAO,yBAAyB,KAAK;GAC1C,OAAO;GACP,QAAQ,GAAG,OAAO,UAAU,GAAG,WAAW,IAAI;GAC9C,SAAS;EACX,CAAC;CAGP;CAEA,IACE,QAAQ,MAAM,EAAE,UAAU,CAAC,gBAAgB,IAAI,IAAI,SAAS,CAAC,KAC7D,QAAQ,MAAM,EAAE,UAAU,CAAC,gBAAgB,IAAI,IAAI,SAAS,CAAC,KAC7D,YAAY,MAAM,EAAE,UAAU,CAAC,gBAAgB,IAAI,IAAI,SAAS,CAAC,GAEjE,OAAO,OAAO,yBAAyB,KAAK;EAC1C,OAAO;EACP,QAAQ;EACR,SAAS;CACX,CAAC;AAEL,CAAC;AAED,MAAM,eAAe,OAAO,GAAG,4BAA4B,CAAC,CAAC,aAAa;CACxE,MAAM,SAAS,OAAO;CACtB,MAAM,YAAY,OAAO;CACzB,MAAM,MAAM,OAAO,iBAAiB;CACpC,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,UAAU,OAAO,oBAAoB,KAAK,UAAU,KAAK,OAAO,mBAAmB;CAEzF,IAAI,OAAO,cACT,OAAO,sBAAsB,SAAS,MAAM;CAG9C,MAAM,iBAAuB,WAC3B,OAAO,eAAe,QAAQ,OAAO,QAAQ,MAAM;CAErD,MAAM,eAAe,OAAO,IACzB,aACC,UACG,IAAI,QAAQ,CAAC,CACb,KAAK,OAAO,UAAU,UAAU,WAAW,qBAAqB,YAAY,KAAK,CAAC,CAAC,CAC1F;CAEA,MAAM,cAAqD,OAAO,GAAG,2BAA2B,CAAC,CAC/F,WAAW,SAAgC;EACzC,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,qBAAqB,CAAC,CAAC,CACvF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,4BAA4B,KAAK,CAAC,CAAC;EAEtF,MAAM,MAAM,OAAO,MAAM;EAEzB,OAAO,aAAa,oBAAoB;EACxC,OAAO,QACJ,YACC,UAAU,UACV,IAAI,KAAK,GAAG,CAAC,CAAC,YAAY,GAC1B,mBACA,UAAU,aACZ,CAAC,CACA,KACC,OAAO,UAAU,UACf,MAAM,SAAS,oBACX,SAAS,UAAU,UAAU,KAAK,IAClC,WAAW,sBAAsB,KAAK,CAC5C,CACF;EACF,OAAO,aAAa,mBAAmB;CACzC,CACF;CAEA,MAAM,SAA2C,OAAO,GAAG,sBAAsB,CAAC,CAAC,WACjF,SACA;EACA,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,mBAAmB,CAAC,CAAC,CACrF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,6BAA6B,KAAK,CAAC,CAAC;EAEvF,OAAO,cAAc,SAAS,UAAU,QAAQ;EAEhD,MAAM,aAAa,OAAO,cACxB,qBAAqB,UAAU,oBAAoB,UAAU,KAAK,CACpE,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,WAAW,2BAA2B,KAAK,CAAC,CAAC;EAE/E,MAAM,YAAY,OAAO,qBAAqB,UAAU,KAAK;EAE7D,MAAM,aAAa,OAAO,OAAO,QAAQ,UAAU,MAAM,UAAU,WACjE,sBAAsB,MAAM,CAAC,CAAC,KAC5B,OAAO,KAAK,gBAAgB;GAC1B,UAAU,OAAO;GACjB;EACF,EAAE,CACJ,CACF;EAEA,MAAM,aAAa,OAAO,OAAO,oBAAoB,gBAAgB,CAAC,CAAC;GACrE,UAAU,UAAU;GACpB,SAAS,UAAU,MAAM;GACzB,aAAa;GACb;GACA,sBAAsB,UAAU;GAChC,oBAAoB,UAAU;GAC9B,eAAe,UAAU;GACzB,SAAS;GACT;EACF,CAAC,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,2BAA2B,KAAK,CAAC,CAAC;EAEtF,OAAO,aAAa,eAAe;EAEnC,MAAM,SAAS,OAAO,QAAQ,OAAO,UAAU,CAAC,CAAC,KAC/C,OAAO,UAAU,UAAU;GACzB,IAAI,kBAAkB,KAAK,GACzB,OAAO,SAAS,UAAU,UAAU,KAAK;GAE3C,IAAI,mBAAmB,KAAK,GAC1B,OAAO,MAAM,uBAAuB,KAAA,KAAa,SAAS,MAAM,gBAAgB,IAC5E,eAAe,KAAK;IAClB,UAAU,UAAU;IACpB,SAAS,UAAU,MAAM;IACzB,QAAQ,MAAM;IACd,oBAAoB,MAAM;IAC1B,kBAAkB,MAAM;GAC1B,CAAC,IACD,eAAe,KAAK;IAClB,UAAU,UAAU;IACpB,SAAS,UAAU,MAAM;IACzB,QAAQ,MAAM;GAChB,CAAC;GAGP,OAAO,WAAW,0BAA0B,KAAK;EACnD,CAAC,GACD,OAAO,SAAS,WACd,OAAO,oBAAoB,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,KAC/C,OAAO,UAAU,UAAU,iBAAiB,wBAAwB,KAAK,CAAC,CAC5E,CACF,CACF;EAEA,OAAO,aAAa,cAAc;EAElC,OAAO;CACT,CAAC;CAED,MAAM,cAAc,OAAO,GAAG,2BAA2B,CAAC,CAAC,WAAW,SAAyB;EAC7F,MAAM,SAAS,OAAO,QACnB,KAAK,OAAO,CAAC,CACb,KAAK,OAAO,UAAU,UAAU,WAAW,0BAA0B,KAAK,CAAC,CAAC;EAE/E,OAAO;GACL,OAAO,OAAO;GACd,SAAS,OAAO,QAAQ,KACtB,OAAO,UAAU,UAAU,WAAW,0BAA0B,KAAK,CAAC,GACtE,OAAO,UAAU,cAAc,CACjC;EACF;CACF,CAAC;CAED,MAAM,aAAa,OAAO,GAAG,oBAAoB,CAAC,CAAC,WAAW,SAAqB;EACjF,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KACtF,OAAO,UAAU,UAAU,iBAAiB,wBAAwB,KAAK,CAAC,CAC5E;EAEA,OAAO,cAAc,SAAS,UAAU,QAAQ;EAUhD,QAAO,OARe,YACpB,eAAe,KAAK;GAClB,UAAU,UAAU;GACpB,uBAAuB,UAAU,iBAAiB;GAClD,OAAO,UAAU;EACnB,CAAC,CACH,EAAA,CAEc;CAChB,CAAC;CAED,MAAM,QAAwC,YAAY,OAAO,OAAO,WAAW,OAAO,CAAC;CAE3F,MAAM,gBAAgB,OAAO,GAAG,uBAAuB,CAAC,CAAC,WAAW,SAA4B;EAC9F,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,iBAAiB,CAAC,CAAC,CACnF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,+BAA+B,KAAK,CAAC,CAAC;EAEzF,OAAO,cAAc,SAAS,UAAU,QAAQ;EAChD,MAAM,kBAAkB,OAAO,YAAY,UAAU,UAAU,UAAU,WAAW;EACpF,MAAM,SAAS,OAAO,IAAI,KAAK,eAAe;EAE9C,MAAM,OAAO,OAAO,GAAG,2BAA2B,CAAC,CAAC,aAAa;GAC/D,MAAM,wBAAwB,OAAO,IAAI,IAAI,MAAM;GAEnD,MAAM,SAAS,OAAO,YACpB,eAAe,KAAK;IAClB,UAAU,UAAU;IACpB;IACA,OAAO;GACT,CAAC,CACH;GAEA,IAAI,OAAO,UAAU,GAAG;IACtB,OAAO,OAAO,MAAM,OAAO,uBAAuB;IAElD,OAAO,OAAO;GAChB;GAEA,OAAO,OAAO,QAAQ,KAAK,OAAO,KAAK,WAAW,IAAI,IAAI,QAAQ,OAAO,QAAQ,CAAC,CAAC;EACrF,CAAC;EAED,OAAO,OAAO,iBAAiB,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,OAAO;CAC5D,CAAC;CAED,MAAM,WAA8C,YAClD,OAAO,OAAO,cAAc,OAAO,CAAC;CAEtC,MAAM,eAAiD,OAAO,GAAG,sBAAsB,CAAC,CACtF,WAAW,SAA8B;EACvC,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,mBAAmB,CAAC,CAAC,CACrF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,0BAA0B,KAAK,CAAC,CAAC;EAEpF,OAAO,cAAc,SAAS,UAAU,QAAQ;EAEhD,MAAM,WAAW,OAAO,QACrB,aAAa,UAAU,QAAQ,CAAC,CAChC,KAAK,OAAO,UAAU,UAAU,WAAW,iBAAiB,KAAK,CAAC,CAAC;EAEtE,MAAM,UAAU,OAAO,OAAO,QAAQ,SAAS,SAAS,cAAc;EAEtE,IAAI,QAAQ,SAAS,2BACnB,OAAO,OAAO,iBAAiB,KAAK;GAClC,WAAW;GACX,SAAS;EACX,CAAC;EAGH,MAAM,aAAa,OAAO,OAAO,oBAAoB,MAAM,CAAC,CAC1D,SAAS,OAAO,WAClB,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,6BAA6B,KAAK,CAAC,CAAC;EAEvF,OAAO,aAAa,KAAK;GACvB,QAAQ;GACR,UAAU,UAAU;GACpB,cAAc,SAAS,OAAO;GAC9B;GACA;EACF,CAAC;CACH,CACF;CAEA,MAAM,cAAqD,OAAO,GAAG,2BAA2B,CAAC,CAC/F,WAAW,SAA4B;EACrC,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,iBAAiB,CAAC,CAAC,CACnF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,4BAA4B,KAAK,CAAC,CAAC;EAEtF,MAAM,SAAS,OAAO,cAAc,SAAS,UAAU,QAAQ;EAE/D,MAAM,aAAa,OAAO,OAAO,oBAAoB,MAAM,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,KAC/E,OAAO,UAAU,UAAU,iBAAiB,sBAAsB,KAAK,CAAC,CAC1E;EAEA,OAAO,WAAW,KAAK;GACrB,UAAU,UAAU;GACpB,cAAc,OAAO;GACrB;GACA,eAAe,OAAO;EACxB,CAAC;CACH,CACF;CAEA,MAAM,iBAA4C,OAAO,GAAG,8BAA8B,CAAC,CACzF,WAAW,SAAgC;EACzC,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,qBAAqB,CAAC,CAAC,CACvF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,uBAAuB,KAAK,CAAC,CAAC;EAEjF,MAAM,SAAS,OAAO,cAAc,SAAS,UAAU,WAAW,QAAQ;EAE1E,IAAI,UAAU,WAAW,kBAAkB,OAAO,eAChD,OAAO,OAAO,mBAAmB,KAAK;GACpC,UAAU,UAAU,WAAW;GAC/B,QAAQ;EACV,CAAC;EASH,KAAI,OAN2B,aAC7B,SACA,UAAU,WAAW,UACrB,UAAU,WAAW,eACvB,OAEwB,UAAU,WAAW,YAC3C,OAAO,OAAO,mBAAmB,KAAK;GACpC,UAAU,UAAU,WAAW;GAC/B,QAAQ;EACV,CAAC;EAEH,MAAM,iBAAiB,OAAO,iBAAiB,UAAU,UAAU;EAEnE,MAAM,MAAM,cAAc,KAAK;GAC7B,UAAU,UAAU,WAAW;GAC/B,iBAAiB,UAAU,WAAW;GACtC,YAAY,UAAU,WAAW;GACjC;EACF,CAAC;EAED,OAAO,aAAa,wBAAwB;EAC5C,OAAO,QAAQ,eAAe,GAAG,CAAC,CAAC,KACjC,OAAO,UAAU,UACf,uBAAuB,KAAK,IACxB,mBAAmB,KAAK;GACtB,UAAU,UAAU,WAAW;GAC/B,QAAQ;EACV,CAAC,IACD,WAAW,mBAAmB,KAAK,CACzC,CACF;EACA,OAAO,aAAa,uBAAuB;CAC7C,CACF;CAEA,MAAM,iBAA4C,OAAO,GAAG,8BAA8B,CAAC,CACzF,WAAW,SAAgC;EACzC,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,qBAAqB,CAAC,CAAC,CACvF,OACF,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,iBAAiB,8BAA8B,KAAK,CAAC,CAAC;EAExF,MAAM,SAAS,OAAO,cAAc,SAAS,UAAU,QAAQ;EAE/D,MAAM,OAAO,OAAO,QACjB,eAAe,UAAU,UAAU,UAAU,sBAAsB,OAAO,aAAa,CAAC,CACxF,KAAK,OAAO,UAAU,UAAU,WAAW,mBAAmB,KAAK,CAAC,CAAC;EAExE,IAAI,KAAK,WAAW,GAAG,OAAO,OAAO,KAAK;EAC1C,IAAI,KAAK,WAAW,GAClB,OAAO,OAAO,iBAAiB,KAAK;GAClC,WAAW;GACX,SAAS,iDAAiD,KAAK,OAAO;EACxE,CAAC;EAEH,MAAM,MAAM,KAAK;EACjB,MAAM,aAAa,OAAO,iBAAiB,IAAI,eAAe;EAE9D,IACE,IAAI,cAAc,UAAU,YAC5B,WAAW,aAAa,IAAI,aAC5B,WAAW,oBAAoB,IAAI,oBACnC,WAAW,eAAe,IAAI,aAE9B,OAAO,OAAO,iBAAiB,KAAK;GAClC,WAAW;GACX,SAAS;EACX,CAAC;EASH,KAAI,OAN2B,aAC7B,SACA,WAAW,UACX,WAAW,eACb,OAEwB,WAAW,YACjC,OAAO,OAAO,mBAAmB,KAAK;GACpC,UAAU,WAAW;GACrB,QAAQ;EACV,CAAC;EAGH,OAAO,OAAO,KAAK,UAAU;CAC/B,CACF;CAEA,MAAM,yBAA4D,OAAO,GACvE,sCACF,CAAC,CAAC,WAAW,SAAS;EACpB,MAAM,YAAY,OAAO,OAAO,oBAC9B,OAAO,OAAO,6BAA6B,CAC7C,CAAC,CAAC,OAAO,CAAC,CAAC,KACT,OAAO,UAAU,UAAU,iBAAiB,gCAAgC,KAAK,CAAC,CACpF;EAEA,MAAM,iBAAiB,OAAO,iBAAiB,UAAU,UAAU;EAEnE,OAAO,QACJ,uBAAuB,WAAW,cAAc,CAAC,CACjD,KACC,OAAO,UAAU,UACf,MAAM,SAAS,wBACf,MAAM,SAAS,mBACf,MAAM,SAAS,0BACX,QACA,WAAW,4BAA4B,KAAK,CAClD,CACF;CACJ,CAAC;CAED,MAAM,yBAA4D,OAAO,GACvE,sCACF,CAAC,CAAC,WAAW,SAAS;EACpB,MAAM,YAAY,OAAO,OAAO,oBAAoB,OAAO,OAAO,qBAAqB,CAAC,CAAC,CACvF,OACF,CAAC,CAAC,KACA,OAAO,UAAU,UAAU,iBAAiB,uCAAuC,KAAK,CAAC,CAC3F;EAEA,MAAM,SAAS,OAAO,cAAc,SAAS,UAAU,QAAQ;EAE/D,MAAM,gBACJ,mBAAmB,KAAK;GAAE,UAAU,UAAU;GAAU,QAAQ;EAAU,CAAC;EAE7E,MAAM,OAAO,OAAO,QACjB,uBAAuB,UAAU,QAAQ,CAAC,CAC1C,KACC,OAAO,UAAU,UACf,MAAM,SAAS,6BACX,QAAQ,IACR,WAAW,4BAA4B,KAAK,CAClD,CACF;EAEF,IAAI,KAAK,WAAW,GAAG,OAAO,OAAO,KAAK;EAC1C,IAAI,KAAK,WAAW,GAAG,OAAO,OAAO,QAAQ;EAC7C,MAAM,MAAM,KAAK;EAEjB,MAAM,aAAa,OAAO,OAAO,aAAa,OAAO,eAAe,gBAAgB,CAAC,CAAC,CACpF,IAAI,eACN,CAAC,CAAC,KAAK,OAAO,SAAS,OAAO,CAAC;EAE/B,IACE,IAAI,cAAc,UAAU,YAC5B,WAAW,aAAa,IAAI,aAC5B,WAAW,oBAAoB,IAAI,oBACnC,WAAW,eAAe,IAAI,aAE9B,OAAO,OAAO,QAAQ;EACxB,IAAI,WAAW,kBAAkB,OAAO,eACtC,OAAO,OAAO,mBAAmB,KAAK;GACpC,UAAU,UAAU;GACpB,QAAQ;EACV,CAAC;EACH,IAAI,WAAW,mBAAmB,UAAU,sBAAsB,OAAO,gBACvE,OAAO,OAAO,KAAK;EAQrB,KAAI,OAN2B,aAC7B,SACA,WAAW,UACX,WAAW,eACb,OAEwB,WAAW,YACjC,OAAO,OAAO,mBAAmB,KAAK;GACpC,UAAU,UAAU;GACpB,QAAQ;EACV,CAAC;EAEH,OAAO,OAAO,KAAK,UAAU;CAC/B,CAAC;CAED,MAAM,cAAc,YAAY,GAAG;EACjC;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA,aAAa;GAAE,MAAM;GAAgB,MAAM;EAAe;EAC1D,qBAAqB;GAAE,MAAM;GAAwB,MAAM;EAAuB;CACpF,CAAC;CAED,OAAO,QAAQ,KAAK,aAAa,WAAW;AAC9C,CAAC;;;;;AAMD,MAAa,mBAIT,MAAM,cAAc,aAAa,CAAC;;;;;;AAOtC,MAAa,sBACX,YAEA,MAAM,OAAO,eAAe,CAAC,CAC3B,OAAO,oBAAoB,oBAAoB,CAAC,CAAC;CAC/C,yBAAyB,QAAQ,2BAA2B;CAC5D,wBACE,QAAQ,0BAA0B,SAAS,SAAS,gCAAgC;CACtF,qBAAqB,QAAQ,uBAAA;CAC7B,cAAc,QAAQ,gBAAgB;AACxC,CAAC,CAAC,CAAC,KACD,OAAO,UAAU,UACf,eAAe,KAAK;CAClB,OAAO;CACP,WAAW;CACX,SAAS,MAAM;AACjB,CAAC,CACH,CACF,CACF;;AAGF,MAAa,yBACX,YAEA,QAAQ,cAAc,KAAA,IAClB,mBAAmB,QACnB,MAAM,QAAQ,kBAAkB,CAAC,CAAC,EAAE,KAAK,QAAQ,UAAU,CAAC;;;;;;;AAQlE,MAAa,SACX,YAEA,MAAM,OACJ,OAAO,IAAI,kBAAkB,WAC3B,iBAAiB,KACf,MAAM,QACJ,MAAM,SACJ,MAAM,QAAQ,eAAe,CAAC,CAAC,MAAM,GACrC,sBAAsB,OAAO,GAC7B,aAAa,MAAM,EAAE,SAAS,QAAQ,QAAQ,CAAC,GAC/C,cAAc,KAChB,CACF,CACF,CACF,CACF,CAAC,CAAC,KAAK,MAAM,QAAQ,mBAAmB,OAAO,CAAC,CAAC"}
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 { 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 ThreadRead,\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.fn(\"DoThreadStore.loadRecords\")(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: ThreadRead) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadRead))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\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.fn(\"DoThreadStore.observe\")(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\n const poll = Effect.fn(\"DoThreadStore.observePoll\")(function* () {\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 yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(Stream.tap((record) => Ref.set(cursor, record.sequence)));\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(Stream.flatten);\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request));\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 threadStore = ThreadStore.of({\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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"}