@effect-agent/storage-sqlite 0.1.0-beta.63 → 0.1.0-beta.64

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.
@@ -1,4 +1,4 @@
1
- import { a as SqliteStorageCompatibilityError, o as SqliteStorageCorruptionError, s as SqliteStorageError } from "./SqliteStorageError-CzKmwCLl.mjs";
1
+ import { a as SqliteStorageCompatibilityError, o as SqliteStorageCorruptionError, s as SqliteStorageError } from "./SqliteStorageError-DVWeaWLm.mjs";
2
2
  import { SqliteStorageConfig } from "./SqliteStorageConfig.mjs";
3
3
  import { SqliteStorageFailpoint } from "./SqliteStorageFailpoint.mjs";
4
4
  import { MessageDeliveryError, MessageDeliveryStore, MessageDeliveryStoreLimits } from "@effect-agent/thread/MessageDelivery";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as initializeSqliteJournal } from "./sqlite-journal-lDduEakl.mjs";
2
+ import { a as initializeSqliteJournal } from "./sqlite-journal-CC4oPmgO.mjs";
3
3
  import { MessageDeliveryError, MessageDeliveryStore } from "@effect-agent/thread/MessageDelivery";
4
4
  import { SqlMessageDeliveryTransaction, makeSqlMessageDeliveryStore } from "@effect-agent/thread/SqlMessageDeliveryStore";
5
5
  import { Effect, Layer } from "effect";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as initializeSqliteJournal } from "./sqlite-journal-lDduEakl.mjs";
2
+ import { a as initializeSqliteJournal } from "./sqlite-journal-CC4oPmgO.mjs";
3
3
  import { Effect, Layer, Result, Schema } from "effect";
4
4
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
5
5
  import { ScheduleCapacityError, ScheduleChange, ScheduleConflict, ScheduleDueCursor, ScheduleFailpoint, ScheduleId, ScheduleInstant, ScheduleKey, ScheduleNotFound, ScheduleOwner, SchedulePageRequest, ScheduleRecord, ScheduleStorageError, ScheduleStore, defaultSchedulingLimits } from "@effect-agent/thread/Schedule";
@@ -72,10 +72,10 @@ declare const SqliteCheckpointConflict_base: Schema.Class<SqliteCheckpointConfli
72
72
  }>, import("effect/Cause").YieldableError>;
73
73
  /** A checkpoint conflicts with a previously stored checkpoint at the same offset. */
74
74
  declare class SqliteCheckpointConflict extends SqliteCheckpointConflict_base {}
75
- declare const SqliteStorageFailpointLocation: Schema.Literals<readonly ["upgrade:before-mutation", "upgrade:after-mutation", "upgrade:before-version", "upgrade:after-version", "materialize:before", "materialize:after", "append:before", "append:after-batch-insert", "append:after-record-insert", "append:after-tail-update", "append:after", "export:after-thread-read", "save-checkpoint:before", "save-checkpoint:after", "ledger:admit:before", "ledger:admit:after", "ledger:mark-ready:before", "ledger:mark-ready:after", "ledger:claim:before", "ledger:claim:after", "ledger:mark-input-applied:before", "ledger:mark-input-applied:after", "ledger:renew:before", "ledger:renew:after", "ledger:reserve-settlement:before", "ledger:reserve-settlement:after", "ledger:finalize-settlement:before", "ledger:finalize-settlement:after", "ledger:request-abort:before", "ledger:request-abort:after", "ledger:release:before", "ledger:release:after", "ledger:claim-joining:before", "ledger:claim-joining:after", "ledger:mark-joined:before", "ledger:mark-joined:after", "ledger:revert-joining:before", "ledger:revert-joining:after", "ledger:suspend:before", "ledger:suspend:after", "ledger:approval-decision:before", "ledger:approval-decision:after", "ledger:mark-unknown:before", "ledger:mark-unknown:after", "ledger:unknown-resolution:before", "ledger:unknown-resolution:after", "ledger:child-reservation:before", "ledger:child-reservation:after", "ledger:child-attach:before", "ledger:child-attach:after", "ledger:child-release-pending:before", "ledger:child-release-pending:after", "ledger:child-release:before", "ledger:child-release:after", "ledger:child-settled:before", "ledger:child-settled:after"]>;
75
+ declare const SqliteStorageFailpointLocation: Schema.Literals<readonly ["upgrade:before-mutation", "upgrade:after-mutation", "upgrade:before-version", "upgrade:after-version", "materialize:before", "materialize:after", "append:before", "append:after-batch-insert", "append:after-record-insert", "append:after-tail-update", "append:after", "export:after-thread-read", "save-checkpoint:before", "save-checkpoint:after", "save-recovery-checkpoint:before", "save-recovery-checkpoint:after", "ledger:admit:before", "ledger:admit:after", "ledger:mark-ready:before", "ledger:mark-ready:after", "ledger:claim:before", "ledger:claim:after", "ledger:mark-input-applied:before", "ledger:mark-input-applied:after", "ledger:renew:before", "ledger:renew:after", "ledger:reserve-settlement:before", "ledger:reserve-settlement:after", "ledger:finalize-settlement:before", "ledger:finalize-settlement:after", "ledger:request-abort:before", "ledger:request-abort:after", "ledger:release:before", "ledger:release:after", "ledger:claim-joining:before", "ledger:claim-joining:after", "ledger:mark-joined:before", "ledger:mark-joined:after", "ledger:revert-joining:before", "ledger:revert-joining:after", "ledger:suspend:before", "ledger:suspend:after", "ledger:approval-decision:before", "ledger:approval-decision:after", "ledger:mark-unknown:before", "ledger:mark-unknown:after", "ledger:unknown-resolution:before", "ledger:unknown-resolution:after", "ledger:child-reservation:before", "ledger:child-reservation:after", "ledger:child-attach:before", "ledger:child-attach:after", "ledger:child-release-pending:before", "ledger:child-release-pending:after", "ledger:child-release:before", "ledger:child-release:after", "ledger:child-settled:before", "ledger:child-settled:after"]>;
76
76
  type SqliteStorageFailpointLocation = typeof SqliteStorageFailpointLocation.Type;
77
77
  declare const SqliteStorageFailpointError_base: Schema.Class<SqliteStorageFailpointError, Schema.TaggedStruct<"SqliteStorageFailpointError", {
78
- readonly location: Schema.Literals<readonly ["upgrade:before-mutation", "upgrade:after-mutation", "upgrade:before-version", "upgrade:after-version", "materialize:before", "materialize:after", "append:before", "append:after-batch-insert", "append:after-record-insert", "append:after-tail-update", "append:after", "export:after-thread-read", "save-checkpoint:before", "save-checkpoint:after", "ledger:admit:before", "ledger:admit:after", "ledger:mark-ready:before", "ledger:mark-ready:after", "ledger:claim:before", "ledger:claim:after", "ledger:mark-input-applied:before", "ledger:mark-input-applied:after", "ledger:renew:before", "ledger:renew:after", "ledger:reserve-settlement:before", "ledger:reserve-settlement:after", "ledger:finalize-settlement:before", "ledger:finalize-settlement:after", "ledger:request-abort:before", "ledger:request-abort:after", "ledger:release:before", "ledger:release:after", "ledger:claim-joining:before", "ledger:claim-joining:after", "ledger:mark-joined:before", "ledger:mark-joined:after", "ledger:revert-joining:before", "ledger:revert-joining:after", "ledger:suspend:before", "ledger:suspend:after", "ledger:approval-decision:before", "ledger:approval-decision:after", "ledger:mark-unknown:before", "ledger:mark-unknown:after", "ledger:unknown-resolution:before", "ledger:unknown-resolution:after", "ledger:child-reservation:before", "ledger:child-reservation:after", "ledger:child-attach:before", "ledger:child-attach:after", "ledger:child-release-pending:before", "ledger:child-release-pending:after", "ledger:child-release:before", "ledger:child-release:after", "ledger:child-settled:before", "ledger:child-settled:after"]>;
78
+ readonly location: Schema.Literals<readonly ["upgrade:before-mutation", "upgrade:after-mutation", "upgrade:before-version", "upgrade:after-version", "materialize:before", "materialize:after", "append:before", "append:after-batch-insert", "append:after-record-insert", "append:after-tail-update", "append:after", "export:after-thread-read", "save-checkpoint:before", "save-checkpoint:after", "save-recovery-checkpoint:before", "save-recovery-checkpoint:after", "ledger:admit:before", "ledger:admit:after", "ledger:mark-ready:before", "ledger:mark-ready:after", "ledger:claim:before", "ledger:claim:after", "ledger:mark-input-applied:before", "ledger:mark-input-applied:after", "ledger:renew:before", "ledger:renew:after", "ledger:reserve-settlement:before", "ledger:reserve-settlement:after", "ledger:finalize-settlement:before", "ledger:finalize-settlement:after", "ledger:request-abort:before", "ledger:request-abort:after", "ledger:release:before", "ledger:release:after", "ledger:claim-joining:before", "ledger:claim-joining:after", "ledger:mark-joined:before", "ledger:mark-joined:after", "ledger:revert-joining:before", "ledger:revert-joining:after", "ledger:suspend:before", "ledger:suspend:after", "ledger:approval-decision:before", "ledger:approval-decision:after", "ledger:mark-unknown:before", "ledger:mark-unknown:after", "ledger:unknown-resolution:before", "ledger:unknown-resolution:after", "ledger:child-reservation:before", "ledger:child-reservation:after", "ledger:child-attach:before", "ledger:child-attach:after", "ledger:child-release-pending:before", "ledger:child-release-pending:after", "ledger:child-release:before", "ledger:child-release:after", "ledger:child-settled:before", "ledger:child-settled:after"]>;
79
79
  }>, import("effect/Cause").YieldableError>;
80
80
  /** Deterministic test-only fault or pause injected at a SQLite operation boundary. */
81
81
  declare class SqliteStorageFailpointError extends SqliteStorageFailpointError_base {
@@ -83,4 +83,4 @@ declare class SqliteStorageFailpointError extends SqliteStorageFailpointError_ba
83
83
  }
84
84
  //#endregion
85
85
  export { SqliteStorageCompatibilityError as a, SqliteStorageError_d_exports as c, SqliteWriteContention as d, SqliteLedgerError as i, SqliteStorageFailpointError as l, SqliteCheckpointConflict as n, SqliteStorageCorruptionError as o, SqliteFenceRejected as r, SqliteStorageError as s, SqliteAppendConflict as t, SqliteStorageFailpointLocation as u };
86
- //# sourceMappingURL=SqliteStorageError-CzKmwCLl.d.mts.map
86
+ //# sourceMappingURL=SqliteStorageError-DVWeaWLm.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as SqliteStorageCompatibilityError, d as SqliteWriteContention, i as SqliteLedgerError, l as SqliteStorageFailpointError, n as SqliteCheckpointConflict, o as SqliteStorageCorruptionError, r as SqliteFenceRejected, s as SqliteStorageError, t as SqliteAppendConflict, u as SqliteStorageFailpointLocation } from "./SqliteStorageError-CzKmwCLl.mjs";
1
+ import { a as SqliteStorageCompatibilityError, d as SqliteWriteContention, i as SqliteLedgerError, l as SqliteStorageFailpointError, n as SqliteCheckpointConflict, o as SqliteStorageCorruptionError, r as SqliteFenceRejected, s as SqliteStorageError, t as SqliteAppendConflict, u as SqliteStorageFailpointLocation } from "./SqliteStorageError-DVWeaWLm.mjs";
2
2
  export { SqliteAppendConflict, SqliteCheckpointConflict, SqliteFenceRejected, SqliteLedgerError, SqliteStorageCompatibilityError, SqliteStorageCorruptionError, SqliteStorageError, SqliteStorageFailpointError, SqliteStorageFailpointLocation, SqliteWriteContention };
@@ -93,6 +93,8 @@ const SqliteStorageFailpointLocation = Schema.Literals([
93
93
  "export:after-thread-read",
94
94
  "save-checkpoint:before",
95
95
  "save-checkpoint:after",
96
+ "save-recovery-checkpoint:before",
97
+ "save-recovery-checkpoint:after",
96
98
  "ledger:admit:before",
97
99
  "ledger:admit:after",
98
100
  "ledger:mark-ready:before",
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteStorageError.mjs","names":[],"sources":["../src/SqliteStorageError.ts"],"sourcesContent":["import { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { Schema } from \"effect\";\n\n/** The SQLite file uses a private-development format this adapter cannot read. */\nexport class SqliteStorageCompatibilityError extends Schema.TaggedError<SqliteStorageCompatibilityError>()(\n \"SqliteStorageCompatibilityError\",\n {\n actualVersion: Schema.Int,\n message: Schema.String,\n supportedVersion: Schema.Int,\n },\n) {}\n\n/** Stored bytes failed the current Schema and cannot be used as recovery truth. */\nexport class SqliteStorageCorruptionError extends Schema.TaggedError<SqliteStorageCorruptionError>()(\n \"SqliteStorageCorruptionError\",\n {\n message: Schema.String,\n rowKey: Schema.String,\n table: Schema.String,\n },\n) {}\n\n/** SQLite infrastructure failed while opening or operating the store. */\nexport class SqliteStorageError extends Schema.TaggedError<SqliteStorageError>()(\n \"SqliteStorageError\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/**\n * SQLite infrastructure failed while operating the Submission Ledger. Surfaces at the\n * SubmissionLedger port as the typed `LedgerError` with this error preserved as its cause,\n * so the adapter-level tag is never erased.\n */\nexport class SqliteLedgerError extends Schema.TaggedError<SqliteLedgerError>()(\n \"SqliteLedgerError\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/**\n * A canonical batch retry conflicts with existing append state. Tail conflicts carry the\n * actual committed tail as a diagnostic resume hint.\n */\nexport class SqliteAppendConflict extends Schema.TaggedError<SqliteAppendConflict>()(\n \"SqliteAppendConflict\",\n {\n message: Schema.String,\n reason: Schema.Literals([\"batch-digest\", \"record-identity\", \"tail\"]),\n actualTailSequence: Schema.optionalKey(CanonicalSequence),\n actualTailDigest: Schema.optionalKey(Schema.String),\n },\n) {}\n\n/**\n * A producer epoch does not match the Thread's current writer registration. Appends\n * require the exact registered epoch, so both older and newer unregistered epochs are fenced;\n * a newer epoch takes over by materializing first.\n */\nexport class SqliteFenceRejected extends Schema.TaggedError<SqliteFenceRejected>()(\n \"SqliteFenceRejected\",\n {\n actualEpoch: ProducerEpoch,\n message: Schema.String,\n producerEpoch: ProducerEpoch,\n },\n) {}\n\n/**\n * A write transaction could not acquire the SQLite write lock within the configured busy\n * timeout (SQLITE_BUSY / SQLITE_LOCKED). Another transiently coexisting owner is writing;\n * the operation did not mutate canonical state and is safe to retry.\n */\nexport class SqliteWriteContention extends Schema.TaggedError<SqliteWriteContention>()(\n \"SqliteWriteContention\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/** A checkpoint conflicts with a previously stored checkpoint at the same offset. */\nexport class SqliteCheckpointConflict extends Schema.TaggedError<SqliteCheckpointConflict>()(\n \"SqliteCheckpointConflict\",\n {\n message: Schema.String,\n },\n) {}\n\nexport const SqliteStorageFailpointLocation = Schema.Literals([\n \"upgrade:before-mutation\",\n \"upgrade:after-mutation\",\n \"upgrade:before-version\",\n \"upgrade:after-version\",\n \"materialize:before\",\n \"materialize:after\",\n \"append:before\",\n \"append:after-batch-insert\",\n \"append:after-record-insert\",\n \"append:after-tail-update\",\n \"append:after\",\n \"export:after-thread-read\",\n \"save-checkpoint:before\",\n \"save-checkpoint:after\",\n \"ledger:admit:before\",\n \"ledger:admit:after\",\n \"ledger:mark-ready:before\",\n \"ledger:mark-ready:after\",\n \"ledger:claim:before\",\n \"ledger:claim:after\",\n \"ledger:mark-input-applied:before\",\n \"ledger:mark-input-applied:after\",\n \"ledger:renew:before\",\n \"ledger:renew:after\",\n \"ledger:reserve-settlement:before\",\n \"ledger:reserve-settlement:after\",\n \"ledger:finalize-settlement:before\",\n \"ledger:finalize-settlement:after\",\n \"ledger:request-abort:before\",\n \"ledger:request-abort:after\",\n \"ledger:release:before\",\n \"ledger:release:after\",\n \"ledger:claim-joining:before\",\n \"ledger:claim-joining:after\",\n \"ledger:mark-joined:before\",\n \"ledger:mark-joined:after\",\n \"ledger:revert-joining:before\",\n \"ledger:revert-joining:after\",\n \"ledger:suspend:before\",\n \"ledger:suspend:after\",\n \"ledger:approval-decision:before\",\n \"ledger:approval-decision:after\",\n \"ledger:mark-unknown:before\",\n \"ledger:mark-unknown:after\",\n \"ledger:unknown-resolution:before\",\n \"ledger:unknown-resolution:after\",\n \"ledger:child-reservation:before\",\n \"ledger:child-reservation:after\",\n \"ledger:child-attach:before\",\n \"ledger:child-attach:after\",\n \"ledger:child-release-pending:before\",\n \"ledger:child-release-pending:after\",\n \"ledger:child-release:before\",\n \"ledger:child-release:after\",\n \"ledger:child-settled:before\",\n \"ledger:child-settled:after\",\n]);\n\nexport type SqliteStorageFailpointLocation = typeof SqliteStorageFailpointLocation.Type;\n\n/** Deterministic test-only fault or pause injected at a SQLite operation boundary. */\nexport class SqliteStorageFailpointError extends Schema.TaggedError<SqliteStorageFailpointError>()(\n \"SqliteStorageFailpointError\",\n {\n location: SqliteStorageFailpointLocation,\n },\n) {\n override get message() {\n return `Injected SQLite storage failure at ${this.location}.`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAIA,IAAa,kCAAb,cAAqD,OAAO,YAA6C,CAAC,CACxG,mCACA;CACE,eAAe,OAAO;CACtB,SAAS,OAAO;CAChB,kBAAkB,OAAO;AAC3B,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,+BAAb,cAAkD,OAAO,YAA0C,CAAC,CAClG,gCACA;CACE,SAAS,OAAO;CAChB,QAAQ,OAAO;CACf,OAAO,OAAO;AAChB,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,qBAAb,cAAwC,OAAO,YAAgC,CAAC,CAC9E,sBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAC5E,qBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,uBAAb,cAA0C,OAAO,YAAkC,CAAC,CAClF,wBACA;CACE,SAAS,OAAO;CAChB,QAAQ,OAAO,SAAS;EAAC;EAAgB;EAAmB;CAAM,CAAC;CACnE,oBAAoB,OAAO,YAAY,iBAAiB;CACxD,kBAAkB,OAAO,YAAY,OAAO,MAAM;AACpD,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,sBAAb,cAAyC,OAAO,YAAiC,CAAC,CAChF,uBACA;CACE,aAAa;CACb,SAAS,OAAO;CAChB,eAAe;AACjB,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,wBAAb,cAA2C,OAAO,YAAmC,CAAC,CACpF,yBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,2BAAb,cAA8C,OAAO,YAAsC,CAAC,CAC1F,4BACA,EACE,SAAS,OAAO,OAClB,CACF,CAAC,CAAC,CAAC;AAEH,MAAa,iCAAiC,OAAO,SAAS;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAKD,IAAa,8BAAb,cAAiD,OAAO,YAAyC,CAAC,CAChG,+BACA,EACE,UAAU,+BACZ,CACF,CAAC,CAAC;CACA,IAAa,UAAU;EACrB,OAAO,sCAAsC,KAAK,SAAS;CAC7D;AACF"}
1
+ {"version":3,"file":"SqliteStorageError.mjs","names":[],"sources":["../src/SqliteStorageError.ts"],"sourcesContent":["import { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { Schema } from \"effect\";\n\n/** The SQLite file uses a private-development format this adapter cannot read. */\nexport class SqliteStorageCompatibilityError extends Schema.TaggedError<SqliteStorageCompatibilityError>()(\n \"SqliteStorageCompatibilityError\",\n {\n actualVersion: Schema.Int,\n message: Schema.String,\n supportedVersion: Schema.Int,\n },\n) {}\n\n/** Stored bytes failed the current Schema and cannot be used as recovery truth. */\nexport class SqliteStorageCorruptionError extends Schema.TaggedError<SqliteStorageCorruptionError>()(\n \"SqliteStorageCorruptionError\",\n {\n message: Schema.String,\n rowKey: Schema.String,\n table: Schema.String,\n },\n) {}\n\n/** SQLite infrastructure failed while opening or operating the store. */\nexport class SqliteStorageError extends Schema.TaggedError<SqliteStorageError>()(\n \"SqliteStorageError\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/**\n * SQLite infrastructure failed while operating the Submission Ledger. Surfaces at the\n * SubmissionLedger port as the typed `LedgerError` with this error preserved as its cause,\n * so the adapter-level tag is never erased.\n */\nexport class SqliteLedgerError extends Schema.TaggedError<SqliteLedgerError>()(\n \"SqliteLedgerError\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/**\n * A canonical batch retry conflicts with existing append state. Tail conflicts carry the\n * actual committed tail as a diagnostic resume hint.\n */\nexport class SqliteAppendConflict extends Schema.TaggedError<SqliteAppendConflict>()(\n \"SqliteAppendConflict\",\n {\n message: Schema.String,\n reason: Schema.Literals([\"batch-digest\", \"record-identity\", \"tail\"]),\n actualTailSequence: Schema.optionalKey(CanonicalSequence),\n actualTailDigest: Schema.optionalKey(Schema.String),\n },\n) {}\n\n/**\n * A producer epoch does not match the Thread's current writer registration. Appends\n * require the exact registered epoch, so both older and newer unregistered epochs are fenced;\n * a newer epoch takes over by materializing first.\n */\nexport class SqliteFenceRejected extends Schema.TaggedError<SqliteFenceRejected>()(\n \"SqliteFenceRejected\",\n {\n actualEpoch: ProducerEpoch,\n message: Schema.String,\n producerEpoch: ProducerEpoch,\n },\n) {}\n\n/**\n * A write transaction could not acquire the SQLite write lock within the configured busy\n * timeout (SQLITE_BUSY / SQLITE_LOCKED). Another transiently coexisting owner is writing;\n * the operation did not mutate canonical state and is safe to retry.\n */\nexport class SqliteWriteContention extends Schema.TaggedError<SqliteWriteContention>()(\n \"SqliteWriteContention\",\n {\n cause: Schema.optionalKey(Schema.Defect()),\n message: Schema.String,\n operation: Schema.String,\n },\n) {}\n\n/** A checkpoint conflicts with a previously stored checkpoint at the same offset. */\nexport class SqliteCheckpointConflict extends Schema.TaggedError<SqliteCheckpointConflict>()(\n \"SqliteCheckpointConflict\",\n {\n message: Schema.String,\n },\n) {}\n\nexport const SqliteStorageFailpointLocation = Schema.Literals([\n \"upgrade:before-mutation\",\n \"upgrade:after-mutation\",\n \"upgrade:before-version\",\n \"upgrade:after-version\",\n \"materialize:before\",\n \"materialize:after\",\n \"append:before\",\n \"append:after-batch-insert\",\n \"append:after-record-insert\",\n \"append:after-tail-update\",\n \"append:after\",\n \"export:after-thread-read\",\n \"save-checkpoint:before\",\n \"save-checkpoint:after\",\n \"save-recovery-checkpoint:before\",\n \"save-recovery-checkpoint:after\",\n \"ledger:admit:before\",\n \"ledger:admit:after\",\n \"ledger:mark-ready:before\",\n \"ledger:mark-ready:after\",\n \"ledger:claim:before\",\n \"ledger:claim:after\",\n \"ledger:mark-input-applied:before\",\n \"ledger:mark-input-applied:after\",\n \"ledger:renew:before\",\n \"ledger:renew:after\",\n \"ledger:reserve-settlement:before\",\n \"ledger:reserve-settlement:after\",\n \"ledger:finalize-settlement:before\",\n \"ledger:finalize-settlement:after\",\n \"ledger:request-abort:before\",\n \"ledger:request-abort:after\",\n \"ledger:release:before\",\n \"ledger:release:after\",\n \"ledger:claim-joining:before\",\n \"ledger:claim-joining:after\",\n \"ledger:mark-joined:before\",\n \"ledger:mark-joined:after\",\n \"ledger:revert-joining:before\",\n \"ledger:revert-joining:after\",\n \"ledger:suspend:before\",\n \"ledger:suspend:after\",\n \"ledger:approval-decision:before\",\n \"ledger:approval-decision:after\",\n \"ledger:mark-unknown:before\",\n \"ledger:mark-unknown:after\",\n \"ledger:unknown-resolution:before\",\n \"ledger:unknown-resolution:after\",\n \"ledger:child-reservation:before\",\n \"ledger:child-reservation:after\",\n \"ledger:child-attach:before\",\n \"ledger:child-attach:after\",\n \"ledger:child-release-pending:before\",\n \"ledger:child-release-pending:after\",\n \"ledger:child-release:before\",\n \"ledger:child-release:after\",\n \"ledger:child-settled:before\",\n \"ledger:child-settled:after\",\n]);\n\nexport type SqliteStorageFailpointLocation = typeof SqliteStorageFailpointLocation.Type;\n\n/** Deterministic test-only fault or pause injected at a SQLite operation boundary. */\nexport class SqliteStorageFailpointError extends Schema.TaggedError<SqliteStorageFailpointError>()(\n \"SqliteStorageFailpointError\",\n {\n location: SqliteStorageFailpointLocation,\n },\n) {\n override get message() {\n return `Injected SQLite storage failure at ${this.location}.`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAIA,IAAa,kCAAb,cAAqD,OAAO,YAA6C,CAAC,CACxG,mCACA;CACE,eAAe,OAAO;CACtB,SAAS,OAAO;CAChB,kBAAkB,OAAO;AAC3B,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,+BAAb,cAAkD,OAAO,YAA0C,CAAC,CAClG,gCACA;CACE,SAAS,OAAO;CAChB,QAAQ,OAAO;CACf,OAAO,OAAO;AAChB,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,qBAAb,cAAwC,OAAO,YAAgC,CAAC,CAC9E,sBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAC5E,qBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,uBAAb,cAA0C,OAAO,YAAkC,CAAC,CAClF,wBACA;CACE,SAAS,OAAO;CAChB,QAAQ,OAAO,SAAS;EAAC;EAAgB;EAAmB;CAAM,CAAC;CACnE,oBAAoB,OAAO,YAAY,iBAAiB;CACxD,kBAAkB,OAAO,YAAY,OAAO,MAAM;AACpD,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,sBAAb,cAAyC,OAAO,YAAiC,CAAC,CAChF,uBACA;CACE,aAAa;CACb,SAAS,OAAO;CAChB,eAAe;AACjB,CACF,CAAC,CAAC,CAAC;;;;;;AAOH,IAAa,wBAAb,cAA2C,OAAO,YAAmC,CAAC,CACpF,yBACA;CACE,OAAO,OAAO,YAAY,OAAO,OAAO,CAAC;CACzC,SAAS,OAAO;CAChB,WAAW,OAAO;AACpB,CACF,CAAC,CAAC,CAAC;;AAGH,IAAa,2BAAb,cAA8C,OAAO,YAAsC,CAAC,CAC1F,4BACA,EACE,SAAS,OAAO,OAClB,CACF,CAAC,CAAC,CAAC;AAEH,MAAa,iCAAiC,OAAO,SAAS;CAC5D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAKD,IAAa,8BAAb,cAAiD,OAAO,YAAyC,CAAC,CAChG,+BACA,EACE,UAAU,+BACZ,CACF,CAAC,CAAC;CACA,IAAa,UAAU;EACrB,OAAO,sCAAsC,KAAK,SAAS;CAC7D;AACF"}
@@ -1,4 +1,4 @@
1
- import { l as SqliteStorageFailpointError, u as SqliteStorageFailpointLocation } from "./SqliteStorageError-CzKmwCLl.mjs";
1
+ import { l as SqliteStorageFailpointError, u as SqliteStorageFailpointLocation } from "./SqliteStorageError-DVWeaWLm.mjs";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
  declare namespace SqliteStorageFailpoint_d_exports {
4
4
  export { SqliteStorageFailpoint, SqliteStorageFailpointHandler };
@@ -1,9 +1,9 @@
1
1
  import { SqliteMigrator } from "@effect/sql-sqlite-node";
2
2
  //#region src/internal/migrations.d.ts
3
- declare const CurrentSqliteStorageVersion = 9;
3
+ declare const CurrentSqliteStorageVersion = 10;
4
4
  declare namespace SqliteStorageVersion_d_exports {
5
5
  export { CurrentSqliteStorageVersion };
6
6
  }
7
7
  //#endregion
8
8
  export { CurrentSqliteStorageVersion as n, SqliteStorageVersion_d_exports as t };
9
- //# sourceMappingURL=SqliteStorageVersion-gA7_96xM.d.mts.map
9
+ //# sourceMappingURL=SqliteStorageVersion-GivCOblh.d.mts.map
@@ -1,2 +1,2 @@
1
- import { n as CurrentSqliteStorageVersion } from "./SqliteStorageVersion-gA7_96xM.mjs";
1
+ import { n as CurrentSqliteStorageVersion } from "./SqliteStorageVersion-GivCOblh.mjs";
2
2
  export { CurrentSqliteStorageVersion };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { t as CurrentSqliteStorageVersion } from "./migrations-dnTR0RKq.mjs";
2
+ import { t as CurrentSqliteStorageVersion } from "./migrations-NWxfq43W.mjs";
3
3
  //#region src/SqliteStorageVersion.ts
4
- var SqliteStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentSqliteStorageVersion: () => 9 });
4
+ var SqliteStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentSqliteStorageVersion: () => 10 });
5
5
  //#endregion
6
6
  export { CurrentSqliteStorageVersion, SqliteStorageVersion_exports as t };
7
7
 
@@ -2,15 +2,15 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { SqliteStorageConfig } from "./SqliteStorageConfig.mjs";
3
3
  import { SqliteLedgerError, SqliteStorageCorruptionError, SqliteStorageError, SqliteWriteContention } from "./SqliteStorageError.mjs";
4
4
  import { SqliteStorageFailpoint } from "./SqliteStorageFailpoint.mjs";
5
- import { a as initializeSqliteJournal, i as decodeRows } from "./sqlite-journal-lDduEakl.mjs";
5
+ import { a as initializeSqliteJournal, i as decodeRows } from "./sqlite-journal-CC4oPmgO.mjs";
6
6
  import { storageConfigLayer, storageFailpointLayer } from "./SqliteThreadStore.mjs";
7
7
  import { Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
8
8
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
9
+ import { EMPTY_TAIL_DIGEST } from "@effect-agent/thread/Digest";
9
10
  import { ApprovalDecision, CanonicalSequence, DefinitionDigests, Digest, PersistedJson, ProducerEpoch, RecordEnvelope, SettlementOutcome, WorkerAdmission } from "@effect-agent/thread/Records";
10
11
  import { NodeCrypto } from "@effect/platform-node";
11
12
  import { SqliteClient } from "@effect/sql-sqlite-node";
12
13
  import { MessageAdmission } from "@effect-agent/core/Messaging";
13
- import { EMPTY_TAIL_DIGEST } from "@effect-agent/thread/Digest";
14
14
  import { AbortCommand, AbortIntent, AbortIntentRequest, AdmissionAdmitted, AdmissionConflict, AdmissionFence, AdmissionGroup, AdmissionNotAdmitted, AdmissionPolicyError, AdmissionRequest, AdmissionResult, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, Claim, ClaimJoiningRequest, ClaimRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipLost, OwnershipRenewal, OwnershipSnapshot, ParentLinkage, QueueSequence, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, ReservedChildBudget, ReservedSettlement, RevertJoiningRequest, Settlement, SettlementConflict, SettlementFinalization, SettlementReservation, SettlementReservationSnapshot, SubmissionAdmissionFence, SubmissionLedger, SubmissionLookup, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SuspendRequest, SuspensionReason, SuspensionSnapshot, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, settlementFailureFromRecord, submissionAbortRecordId } from "@effect-agent/thread/SubmissionLedger";
15
15
  //#region src/SqliteSubmissionLedger.ts
16
16
  var SqliteSubmissionLedger_exports = /* @__PURE__ */ __exportAll({
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as initializeSqliteJournal } from "./sqlite-journal-lDduEakl.mjs";
2
+ import { a as initializeSqliteJournal } from "./sqlite-journal-CC4oPmgO.mjs";
3
3
  import { Effect, Layer, Schema } from "effect";
4
4
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
5
5
  import { SourcePartition, SubscriptionError, SubscriptionStore } from "@effect-agent/thread/Subscription";
@@ -1,4 +1,4 @@
1
- import { a as SqliteStorageCompatibilityError, o as SqliteStorageCorruptionError, s as SqliteStorageError } from "./SqliteStorageError-CzKmwCLl.mjs";
1
+ import { a as SqliteStorageCompatibilityError, o as SqliteStorageCorruptionError, s as SqliteStorageError } from "./SqliteStorageError-DVWeaWLm.mjs";
2
2
  import { SqliteStorageConfig } from "./SqliteStorageConfig.mjs";
3
3
  import { SqliteStorageFailpoint, SqliteStorageFailpointHandler } from "./SqliteStorageFailpoint.mjs";
4
4
  import { Crypto, Layer } from "effect";
@@ -2,14 +2,14 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { SqliteStorageConfig, SqliteStorageConfigValue } from "./SqliteStorageConfig.mjs";
3
3
  import { SqliteAppendConflict, SqliteCheckpointConflict, SqliteFenceRejected, SqliteStorageCorruptionError, SqliteStorageError } from "./SqliteStorageError.mjs";
4
4
  import { SqliteStorageFailpoint } from "./SqliteStorageFailpoint.mjs";
5
- import { a as initializeSqliteJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./sqlite-journal-lDduEakl.mjs";
5
+ import { a as initializeSqliteJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./sqlite-journal-CC4oPmgO.mjs";
6
6
  import { Clock, Context, Crypto, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
7
+ import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@effect-agent/thread/Digest";
7
8
  import { CanonicalBatch, CanonicalRecord, CanonicalRecordEnvelope, CanonicalSequence, Digest, ObservationOffset } from "@effect-agent/thread/Records";
9
+ 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";
8
10
  import { NodeCrypto } from "@effect/platform-node";
9
11
  import { SqliteClient } from "@effect/sql-sqlite-node";
10
- import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@effect-agent/thread/Digest";
11
12
  import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "@effect-agent/thread/SubmissionLedger";
12
- import { AppendConflict, AppendResult, CheckpointRejected, FenceRejected, FencedAppendRequest, LoadCheckpointRequest, SaveCheckpointRequest, ThreadCheckpoint, ThreadExport, ThreadExportRequest, ThreadMaterialization, ThreadNotMaterialized, ThreadObservation, ThreadRead, ThreadStore, ThreadStoreError, ThreadTail, ThreadTailRequest } from "@effect-agent/thread/ThreadStore";
13
13
  //#region src/SqliteThreadStore.ts
14
14
  var SqliteThreadStore_exports = /* @__PURE__ */ __exportAll({
15
15
  layer: () => layer,
@@ -109,9 +109,9 @@ const groupByKey = (rows, key) => {
109
109
  return grouped;
110
110
  };
111
111
  /**
112
- * Opt-in full integrity audit (`verifyOnOpen`). Every stored payload is decoded, re-encoded,
113
- * and re-digested against the canonical chain. Routine opens skip this scan: per-operation
114
- * Schema decoding plus the digest chain already fail clearly on corrupt rows.
112
+ * Opt-in integrity audit (`verifyOnOpen`) of canonical payloads, their digest chains and generic
113
+ * projection checkpoints. Disposable recovery checkpoints are validated when loaded. Routine opens
114
+ * skip this scan: per-operation Schema decoding fails clearly on corrupt canonical rows.
115
115
  */
116
116
  const decodeStartupPayloads = Effect.fn("SqliteThreadStore.decodeStartupPayloads")(function* (journal, crypto) {
117
117
  const stored = yield* journal.scanStoredPayloads();
@@ -310,7 +310,7 @@ const makeServices = Effect.fn("SqliteThreadStore.makeServices")(function* () {
310
310
  yield* requireThread(journal, validated.threadId);
311
311
  const exported = yield* journal.exportThread(validated.threadId).pipe(Effect.mapError((error) => storeError("export thread", error)));
312
312
  const records = yield* Effect.forEach(exported.records, decodeEnvelope);
313
- if (records.length > 65536) return yield* ThreadStoreError.make({
313
+ if (records.length > MAX_THREAD_EXPORT_RECORDS) return yield* ThreadStoreError.make({
314
314
  operation: "decode thread export",
315
315
  message: "The thread exceeds the current export record limit."
316
316
  });
@@ -380,6 +380,35 @@ const makeServices = Effect.fn("SqliteThreadStore.makeServices")(function* () {
380
380
  });
381
381
  return Option.some(checkpoint);
382
382
  });
383
+ const saveRecoveryCheckpoint = Effect.fn("SqliteThreadStore.saveRecoveryCheckpoint")(function* (request) {
384
+ const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SaveRecoveryCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint", error)));
385
+ const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);
386
+ yield* journal.saveRecoveryCheckpoint(validated, checkpointJson).pipe(Effect.mapError((error) => error._tag === "CheckpointRejected" || error._tag === "FenceRejected" || error._tag === "ThreadNotMaterialized" ? error : storeError("save recovery checkpoint", error)));
387
+ });
388
+ const loadRecoveryCheckpoint = Effect.fn("SqliteThreadStore.loadRecoveryCheckpoint")(function* (request) {
389
+ const validated = yield* Schema.decodeUnknownEffect(Schema.toType(LoadCheckpointRequest))(request).pipe(Effect.mapError((error) => schemaStoreError("validate recovery checkpoint lookup", error)));
390
+ const thread = yield* requireThread(journal, validated.threadId);
391
+ const corrupt = () => CheckpointRejected.make({
392
+ threadId: validated.threadId,
393
+ reason: "corrupt"
394
+ });
395
+ const rows = yield* journal.loadRecoveryCheckpoint(validated.threadId).pipe(Effect.mapError((error) => error._tag === "SqliteStorageCorruptionError" ? corrupt() : storeError("load recovery checkpoint", error)));
396
+ if (rows.length === 0) return Option.none();
397
+ if (rows.length !== 1) return yield* corrupt();
398
+ const row = rows[0];
399
+ const checkpoint = yield* Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(row.checkpoint_json).pipe(Effect.mapError(corrupt));
400
+ if (row.thread_id !== validated.threadId || checkpoint.threadId !== row.thread_id || checkpoint.throughSequence !== row.through_sequence || checkpoint.tailDigest !== row.tail_digest) return yield* corrupt();
401
+ if (checkpoint.throughSequence > thread.tail_sequence) return yield* CheckpointRejected.make({
402
+ threadId: validated.threadId,
403
+ reason: "ahead-of-tail"
404
+ });
405
+ if (checkpoint.throughSequence > (validated.atOrBeforeSequence ?? thread.tail_sequence)) return Option.none();
406
+ if ((yield* tailDigestAt(journal, checkpoint.threadId, checkpoint.throughSequence)) !== checkpoint.tailDigest) return yield* CheckpointRejected.make({
407
+ threadId: validated.threadId,
408
+ reason: "digest-mismatch"
409
+ });
410
+ return Option.some(checkpoint);
411
+ });
383
412
  const threadStore = ThreadStore.of({
384
413
  append,
385
414
  export: exportThread,
@@ -390,6 +419,10 @@ const makeServices = Effect.fn("SqliteThreadStore.makeServices")(function* () {
390
419
  checkpoints: {
391
420
  save: saveCheckpoint,
392
421
  load: loadCheckpoint
422
+ },
423
+ recoveryCheckpoints: {
424
+ save: saveRecoveryCheckpoint,
425
+ load: loadRecoveryCheckpoint
393
426
  }
394
427
  });
395
428
  return Context.make(ThreadStore, threadStore);
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteThreadStore.mjs","names":[],"sources":["../src/SqliteThreadStore.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} from \"@effect-agent/thread/ThreadStore\";\nimport { NodeCrypto } from \"@effect/platform-node\";\nimport { SqliteClient } from \"@effect/sql-sqlite-node\";\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 type * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport {\n initializeSqliteJournal,\n RawAppendRequest,\n RawCheckpoint,\n RawReadRequest,\n type SqliteJournal,\n} from \"./internal/sqlite-journal.ts\";\nimport { SqliteStorageConfig, SqliteStorageConfigValue } from \"./SqliteStorageConfig.ts\";\nimport {\n type SqliteStorageCompatibilityError,\n SqliteAppendConflict,\n SqliteCheckpointConflict,\n SqliteFenceRejected,\n type SqliteStorageFailpointLocation,\n SqliteStorageCorruptionError,\n SqliteStorageError,\n} from \"./SqliteStorageError.ts\";\nimport {\n SqliteStorageFailpoint,\n type SqliteStorageFailpointHandler,\n} from \"./SqliteStorageFailpoint.ts\";\n\nexport interface SqliteStorageOptions {\n readonly filename: string;\n readonly observationPollInterval?: number | undefined;\n /** Bounded SQLITE_BUSY retry window for write-lock acquisition, in milliseconds. */\n readonly busyTimeout?: 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 * 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?: SqliteStorageFailpointHandler | undefined;\n}\n\nexport type SqliteStorageInitializationError =\n | SqliteStorageCompatibilityError\n | SqliteStorageCorruptionError\n | SqliteStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst SQLITE_OFFSET_PREFIX = \"effect-agent-sqlite@1:\";\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDigest = Schema.is(Digest);\nconst isSqliteFenceRejected = Schema.is(SqliteFenceRejected);\nconst isSqliteAppendConflict = Schema.is(SqliteAppendConflict);\nconst isSqliteCheckpointConflict = Schema.is(SqliteCheckpointConflict);\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(\"SqliteThreadStore.makeOffset\")(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 `${SQLITE_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n});\n\nconst parseOffset = Effect.fn(\"SqliteThreadStore.parseOffset\")(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 = `${SQLITE_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: SqliteFenceRejected) =>\n FenceRejected.make({\n threadId,\n actualEpoch: error.actualEpoch,\n attemptedEpoch: error.producerEpoch,\n });\n\nconst encodeCanonicalRecord = Effect.fn(\"SqliteThreadStore.encodeCanonicalRecord\")(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(\"SqliteThreadStore.encodeCanonicalBatch\")(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(\"SqliteThreadStore.encodeCheckpoint\")(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(\"SqliteThreadStore.decodeEnvelope\")(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(\"SqliteThreadStore.decodeCheckpoint\")(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(\"SqliteThreadStore.requireThread\")(function* (\n journal: SqliteJournal,\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(\"SqliteThreadStore.tailDigestAt\")(function* (\n journal: SqliteJournal,\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 full integrity audit (`verifyOnOpen`). Every stored payload is decoded, re-encoded,\n * and re-digested against the canonical chain. Routine opens skip this scan: per-operation\n * Schema decoding plus the digest chain already fail clearly on corrupt rows.\n */\nconst decodeStartupPayloads = Effect.fn(\"SqliteThreadStore.decodeStartupPayloads\")(function* (\n journal: SqliteJournal,\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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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(\"SqliteThreadStore.makeServices\")(function* () {\n const config = yield* SqliteStorageConfig;\n const failpoint = yield* SqliteStorageFailpoint;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeSqliteJournal();\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(\"SqliteThreadStore.hitFailpoint\")(\n (location: SqliteStorageFailpointLocation): 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(\n \"SqliteThreadStore.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 === \"SqliteFenceRejected\"\n ? mapFence(validated.threadId, error)\n : storeError(\"materialize thread\", error),\n ),\n );\n yield* hitFailpoint(\"materialize:after\");\n });\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fn(\"SqliteThreadStore.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 (isSqliteFenceRejected(error)) {\n return mapFence(validated.threadId, error);\n }\n if (isSqliteAppendConflict(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(\"SqliteThreadStore.loadRecords\")(function* (\n request: RawReadRequest,\n ) {\n const rows = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return yield* Effect.forEach(rows, decodeEnvelope);\n });\n\n const readEffect = Effect.fn(\"SqliteThreadStore.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 records = 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 Stream.fromIterable(records);\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fn(\"SqliteThreadStore.observe\")(function* (\n request: ThreadObservation,\n ) {\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(\"SqliteThreadStore.observePoll\")(function* () {\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const records = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (records.length === 0) {\n yield* Effect.sleep(config.observationPollInterval);\n\n return [];\n }\n yield* Ref.set(cursor, records[records.length - 1].sequence);\n\n return records;\n });\n\n return Stream.fromIterableEffectRepeat(poll());\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request));\n\n const exportThread: ThreadStore[\"Service\"][\"export\"] = Effect.fn(\"SqliteThreadStore.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 > 65_536) {\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(\n \"SqliteThreadStore.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 const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fn(\"SqliteThreadStore.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 isSqliteCheckpointConflict(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(\"SqliteThreadStore.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 threadStore = ThreadStore.of({\n append,\n export: exportThread,\n inspectTail,\n materialize,\n observe,\n read,\n checkpoints: { save: saveCheckpoint, load: loadCheckpoint },\n });\n\n return Context.make(ThreadStore, threadStore);\n});\n\n/**\n * SQLite Thread Store implementation with configuration, failpoint, SQL, and Crypto\n * authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore,\n SqliteStorageInitializationError,\n SqliteStorageConfig | SqliteStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = Layer.effectContext(makeServices());\n\n/**\n * Validated SQLite storage configuration Layer with the documented defaults applied. Shared\n * by the ThreadStore and SubmissionLedger convenience layers so their defaults cannot\n * drift.\n */\nexport const storageConfigLayer = (\n options: SqliteStorageOptions,\n): Layer.Layer<SqliteStorageConfig, SqliteStorageError> =>\n Layer.effect(SqliteStorageConfig)(\n Schema.decodeUnknownEffect(SqliteStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n busyTimeout: options.busyTimeout ?? 5_000,\n ownershipLeaseDuration:\n options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"configure SQLite 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: SqliteStorageOptions,\n): Layer.Layer<SqliteStorageFailpoint> =>\n options.failpoint === undefined\n ? SqliteStorageFailpoint.layer\n : Layer.succeed(SqliteStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads. Durable accepted work is\n * served by the separate SubmissionLedger port.\n */\nexport const layer = (\n options: SqliteStorageOptions,\n): Layer.Layer<ThreadStore, SqliteStorageInitializationError> =>\n Layer.unwrap(\n Effect.map(SqliteStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(SqliteStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ filename: options.filename }),\n NodeCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n"],"mappings":"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"}
1
+ {"version":3,"file":"SqliteThreadStore.mjs","names":[],"sources":["../src/SqliteThreadStore.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 { NodeCrypto } from \"@effect/platform-node\";\nimport { SqliteClient } from \"@effect/sql-sqlite-node\";\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 type * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport {\n initializeSqliteJournal,\n RawAppendRequest,\n RawCheckpoint,\n RawReadRequest,\n type SqliteJournal,\n} from \"./internal/sqlite-journal.ts\";\nimport { SqliteStorageConfig, SqliteStorageConfigValue } from \"./SqliteStorageConfig.ts\";\nimport {\n type SqliteStorageCompatibilityError,\n SqliteAppendConflict,\n SqliteCheckpointConflict,\n SqliteFenceRejected,\n type SqliteStorageFailpointLocation,\n SqliteStorageCorruptionError,\n SqliteStorageError,\n} from \"./SqliteStorageError.ts\";\nimport {\n SqliteStorageFailpoint,\n type SqliteStorageFailpointHandler,\n} from \"./SqliteStorageFailpoint.ts\";\n\nexport interface SqliteStorageOptions {\n readonly filename: string;\n readonly observationPollInterval?: number | undefined;\n /** Bounded SQLITE_BUSY retry window for write-lock acquisition, in milliseconds. */\n readonly busyTimeout?: 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 * 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?: SqliteStorageFailpointHandler | undefined;\n}\n\nexport type SqliteStorageInitializationError =\n | SqliteStorageCompatibilityError\n | SqliteStorageCorruptionError\n | SqliteStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst SQLITE_OFFSET_PREFIX = \"effect-agent-sqlite@1:\";\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDigest = Schema.is(Digest);\nconst isSqliteFenceRejected = Schema.is(SqliteFenceRejected);\nconst isSqliteAppendConflict = Schema.is(SqliteAppendConflict);\nconst isSqliteCheckpointConflict = Schema.is(SqliteCheckpointConflict);\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(\"SqliteThreadStore.makeOffset\")(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 `${SQLITE_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n});\n\nconst parseOffset = Effect.fn(\"SqliteThreadStore.parseOffset\")(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 = `${SQLITE_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: SqliteFenceRejected) =>\n FenceRejected.make({\n threadId,\n actualEpoch: error.actualEpoch,\n attemptedEpoch: error.producerEpoch,\n });\n\nconst encodeCanonicalRecord = Effect.fn(\"SqliteThreadStore.encodeCanonicalRecord\")(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(\"SqliteThreadStore.encodeCanonicalBatch\")(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(\"SqliteThreadStore.encodeCheckpoint\")(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(\"SqliteThreadStore.decodeEnvelope\")(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(\"SqliteThreadStore.decodeCheckpoint\")(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(\"SqliteThreadStore.requireThread\")(function* (\n journal: SqliteJournal,\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(\"SqliteThreadStore.tailDigestAt\")(function* (\n journal: SqliteJournal,\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(\"SqliteThreadStore.decodeStartupPayloads\")(function* (\n journal: SqliteJournal,\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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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 SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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* SqliteStorageCorruptionError.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(\"SqliteThreadStore.makeServices\")(function* () {\n const config = yield* SqliteStorageConfig;\n const failpoint = yield* SqliteStorageFailpoint;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeSqliteJournal();\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(\"SqliteThreadStore.hitFailpoint\")(\n (location: SqliteStorageFailpointLocation): 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(\n \"SqliteThreadStore.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 === \"SqliteFenceRejected\"\n ? mapFence(validated.threadId, error)\n : storeError(\"materialize thread\", error),\n ),\n );\n yield* hitFailpoint(\"materialize:after\");\n });\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fn(\"SqliteThreadStore.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 (isSqliteFenceRejected(error)) {\n return mapFence(validated.threadId, error);\n }\n if (isSqliteAppendConflict(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(\"SqliteThreadStore.loadRecords\")(function* (\n request: RawReadRequest,\n ) {\n const rows = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return yield* Effect.forEach(rows, decodeEnvelope);\n });\n\n const readEffect = Effect.fn(\"SqliteThreadStore.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 records = 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 Stream.fromIterable(records);\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fn(\"SqliteThreadStore.observe\")(function* (\n request: ThreadObservation,\n ) {\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(\"SqliteThreadStore.observePoll\")(function* () {\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const records = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (records.length === 0) {\n yield* Effect.sleep(config.observationPollInterval);\n\n return [];\n }\n yield* Ref.set(cursor, records[records.length - 1].sequence);\n\n return records;\n });\n\n return Stream.fromIterableEffectRepeat(poll());\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request));\n\n const exportThread: ThreadStore[\"Service\"][\"export\"] = Effect.fn(\"SqliteThreadStore.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(\n \"SqliteThreadStore.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 const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fn(\"SqliteThreadStore.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 isSqliteCheckpointConflict(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(\"SqliteThreadStore.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 \"SqliteThreadStore.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 \"SqliteThreadStore.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 === \"SqliteStorageCorruptionError\"\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 * SQLite Thread Store implementation with configuration, failpoint, SQL, and Crypto\n * authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore,\n SqliteStorageInitializationError,\n SqliteStorageConfig | SqliteStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = Layer.effectContext(makeServices());\n\n/**\n * Validated SQLite storage configuration Layer with the documented defaults applied. Shared\n * by the ThreadStore and SubmissionLedger convenience layers so their defaults cannot\n * drift.\n */\nexport const storageConfigLayer = (\n options: SqliteStorageOptions,\n): Layer.Layer<SqliteStorageConfig, SqliteStorageError> =>\n Layer.effect(SqliteStorageConfig)(\n Schema.decodeUnknownEffect(SqliteStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n busyTimeout: options.busyTimeout ?? 5_000,\n ownershipLeaseDuration:\n options.ownershipLeaseDuration ?? Duration.toMillis(DEFAULT_OWNERSHIP_LEASE_DURATION),\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"configure SQLite 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: SqliteStorageOptions,\n): Layer.Layer<SqliteStorageFailpoint> =>\n options.failpoint === undefined\n ? SqliteStorageFailpoint.layer\n : Layer.succeed(SqliteStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads. Durable accepted work is\n * served by the separate SubmissionLedger port.\n */\nexport const layer = (\n options: SqliteStorageOptions,\n): Layer.Layer<ThreadStore, SqliteStorageInitializationError> =>\n Layer.unwrap(\n Effect.map(SqliteStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(SqliteStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ filename: options.filename }),\n NodeCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { t as SqliteActivityStore_d_exports } from "./SqliteActivityStore.mjs";
2
- import { c as SqliteStorageError_d_exports } from "./SqliteStorageError-CzKmwCLl.mjs";
2
+ import { c as SqliteStorageError_d_exports } from "./SqliteStorageError-DVWeaWLm.mjs";
3
3
  import { t as SqliteStorageConfig_d_exports } from "./SqliteStorageConfig.mjs";
4
4
  import { t as SqliteStorageFailpoint_d_exports } from "./SqliteStorageFailpoint.mjs";
5
5
  import { t as SqliteMessageDeliveryStore_d_exports } from "./SqliteMessageDeliveryStore.mjs";
6
6
  import { t as SqliteThreadStore_d_exports } from "./SqliteThreadStore.mjs";
7
7
  import { t as SqliteScheduleStore_d_exports } from "./SqliteScheduleStore.mjs";
8
- import { t as SqliteStorageVersion_d_exports } from "./SqliteStorageVersion-gA7_96xM.mjs";
8
+ import { t as SqliteStorageVersion_d_exports } from "./SqliteStorageVersion-GivCOblh.mjs";
9
9
  import { t as SqliteSubmissionLedger_d_exports } from "./SqliteSubmissionLedger.mjs";
10
10
  import { t as SqliteSubscriptionStore_d_exports } from "./SqliteSubscriptionStore.mjs";
11
11
  export { SqliteActivityStore_d_exports as SqliteActivityStore, SqliteMessageDeliveryStore_d_exports as SqliteMessageDeliveryStore, SqliteScheduleStore_d_exports as SqliteScheduleStore, SqliteStorageConfig_d_exports as SqliteStorageConfig, SqliteStorageError_d_exports as SqliteStorageError, SqliteStorageFailpoint_d_exports as SqliteStorageFailpoint, SqliteStorageVersion_d_exports as SqliteStorageVersion, SqliteSubmissionLedger_d_exports as SqliteSubmissionLedger, SqliteSubscriptionStore_d_exports as SqliteSubscriptionStore, SqliteThreadStore_d_exports as SqliteThreadStore };
@@ -23,8 +23,22 @@ const createMessageDeliveryTables = Effect.gen(function* () {
23
23
  `.withoutTransform;
24
24
  });
25
25
  //#endregion
26
+ //#region src/internal/recovery-checkpoint-schema.ts
27
+ /** One disposable recovery snapshot per Thread, independent of generic projections. */
28
+ const createRecoveryCheckpointTable = Effect.gen(function* () {
29
+ yield* (yield* SqlClient.SqlClient)`
30
+ CREATE TABLE effect_agent_recovery_checkpoints (
31
+ thread_id TEXT PRIMARY KEY NOT NULL,
32
+ through_sequence INTEGER NOT NULL,
33
+ tail_digest TEXT NOT NULL,
34
+ checkpoint_json TEXT NOT NULL,
35
+ FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT
36
+ )
37
+ `.withoutTransform;
38
+ });
39
+ //#endregion
26
40
  //#region src/internal/migrations.ts
27
- const CurrentSqliteStorageVersion = 9;
41
+ const CurrentSqliteStorageVersion = 10;
28
42
  /** Initialize empty storage with the complete current schema. */
29
43
  const sqliteMigrations = SqliteMigrator.fromRecord({ "1_current_thread_storage": Effect.gen(function* () {
30
44
  const sql = yield* SqlClient.SqlClient;
@@ -318,9 +332,10 @@ const sqliteMigrations = SqliteMigrator.fromRecord({ "1_current_thread_storage":
318
332
  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)`.withoutTransform;
319
333
  yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`.withoutTransform;
320
334
  yield* createMessageDeliveryTables;
321
- yield* sql`PRAGMA user_version = 9`.withoutTransform;
335
+ yield* createRecoveryCheckpointTable;
336
+ yield* sql`PRAGMA user_version = 10`.withoutTransform;
322
337
  }) });
323
338
  //#endregion
324
- export { sqliteMigrations as n, createMessageDeliveryTables as r, CurrentSqliteStorageVersion as t };
339
+ export { createMessageDeliveryTables as i, sqliteMigrations as n, createRecoveryCheckpointTable as r, CurrentSqliteStorageVersion as t };
325
340
 
326
- //# sourceMappingURL=migrations-dnTR0RKq.mjs.map
341
+ //# sourceMappingURL=migrations-NWxfq43W.mjs.map