@effect-agent/storage-sqlite 0.1.0-beta.100 → 0.1.0-beta.102

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,15 +1,17 @@
1
1
  import { SqliteStorageConfig } from "./SqliteStorageConfig.mjs";
2
2
  import { SqliteAppendConflict, SqliteCheckpointConflict, SqliteFenceRejected, SqliteStorageCompatibilityError, SqliteStorageCorruptionError, SqliteStorageError, SqliteStorageFailpointLocation, SqliteWriteContention } from "./SqliteStorageError.mjs";
3
3
  import { SqliteStorageFailpoint } from "./SqliteStorageFailpoint.mjs";
4
- import { a as createMessageDeliveryTables, i as createRecoveryCheckpointTable, n as createNonterminalIndex, r as sqliteMigrations } from "./migrations-Dy5v0HGe.mjs";
4
+ import { a as createMessageDeliveryTables, i as createRecoveryCheckpointTable, n as createNonterminalIndex, r as sqliteMigrations } from "./migrations-BZ89iaTY.mjs";
5
5
  import { Effect, Exit, Schema } from "effect";
6
+ import { createMessageDeliveryPendingIndex } from "effect-agent/sql-message-delivery-store";
6
7
  import * as SqlClient from "effect/unstable/sql/SqlClient";
7
8
  import { NodeCrypto } from "@effect/platform-node";
8
9
  import { SqliteMigrator } from "@effect/sql-sqlite-node";
9
10
  import { EMPTY_TAIL_DIGEST } from "effect-agent/digest";
10
- import { CanonicalSequence, ProducerEpoch } from "effect-agent/records";
11
+ import { CanonicalRecord, CanonicalSequence, ProducerEpoch } from "effect-agent/records";
11
12
  import { ScheduleFailpoint, ScheduleFailpointError } from "effect-agent/schedule";
12
13
  import { checkV2ThreadLayout, upgradeV2Schedules, upgradeV2Subscriptions } from "effect-agent/sql-storage-v2-upgrade";
14
+ import { createNativeReadIndexes, indexCanonicalRecord, seedNativeReadIndexes } from "effect-agent/sql-thread-native-reads";
13
15
  import { SubscriptionFailpoint, SubscriptionFailpointError } from "effect-agent/subscription";
14
16
  import { CheckpointRejected, FenceRejected, MAX_THREAD_EXPORT_RECORDS, ThreadNotMaterialized } from "effect-agent/thread-store";
15
17
  //#region src/internal/sqlite-journal.ts
@@ -315,7 +317,7 @@ const checkPredecessorLayout = Effect.fn("SqliteJournal.checkPredecessorLayout")
315
317
  const names = new Set(expected);
316
318
  if (columns.length !== names.size || columns.some((column) => !names.has(column.name))) return yield* SqliteStorageCompatibilityError.make({
317
319
  actualVersion: version,
318
- supportedVersion: 11,
320
+ supportedVersion: 12,
319
321
  message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`
320
322
  });
321
323
  }
@@ -330,22 +332,22 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
330
332
  const journalMode = yield* decodeSingleRow(Schema.Array(SqliteJournalModeRow), "pragma_journal_mode", "singleton", journalModeRows);
331
333
  if (journalMode.journal_mode.toLowerCase() !== "wal") return yield* SqliteStorageCompatibilityError.make({
332
334
  actualVersion: 0,
333
- supportedVersion: 11,
335
+ supportedVersion: 12,
334
336
  message: `SQLite WAL mode is required; the database reported ${journalMode.journal_mode}.`
335
337
  });
336
338
  const versionRows = yield* sql`PRAGMA user_version`.pipe(Effect.mapError(storageError("read storage version")));
337
339
  const version = yield* decodeSingleRow(Schema.Array(SqliteVersionRow), "pragma_user_version", "singleton", versionRows);
338
- if (version.user_version !== 0 && version.user_version !== 7 && version.user_version !== 8 && version.user_version !== 9 && version.user_version !== 10 && version.user_version !== 11) return yield* SqliteStorageCompatibilityError.make({
340
+ if (version.user_version !== 0 && version.user_version !== 7 && version.user_version !== 8 && version.user_version !== 9 && version.user_version !== 10 && version.user_version !== 11 && version.user_version !== 12) return yield* SqliteStorageCompatibilityError.make({
339
341
  actualVersion: version.user_version,
340
- supportedVersion: 11,
341
- message: `The SQLite file uses unsupported storage version ${version.user_version}; this build supports exactly version 11. Only supported v7, v8, v9 and v10 can be upgraded automatically. Keep the original file and use a compatible library version.`
342
+ supportedVersion: 12,
343
+ message: `The SQLite file uses unsupported storage version ${version.user_version}; this build supports exactly version 12. Only supported v7, v8, v9, v10 and v11 can be upgraded automatically. Keep the original file and use a compatible library version.`
342
344
  });
343
345
  if (version.user_version === 7 || version.user_version === 8 || version.user_version === 9 || version.user_version === 10) yield* sql.withTransaction(Effect.gen(function* () {
344
346
  const current = yield* sql`PRAGMA user_version`;
345
- if (current.length === 1 && current[0].user_version === 11) return;
347
+ if (current.length === 1 && current[0].user_version === 12) return;
346
348
  if (current.length !== 1 || current[0].user_version !== 7 && current[0].user_version !== 8 && current[0].user_version !== 9 && current[0].user_version !== 10) return yield* SqliteStorageCompatibilityError.make({
347
349
  actualVersion: -1,
348
- supportedVersion: 11,
350
+ supportedVersion: 12,
349
351
  message: "Storage version changed while acquiring the upgrade transaction."
350
352
  });
351
353
  if ((yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name IN (
@@ -355,17 +357,17 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
355
357
  'effect_agent_approval_decisions', 'effect_agent_unknown_resolutions', 'effect_agent_schedules'
356
358
  )`).length !== 12) return yield* SqliteStorageCompatibilityError.make({
357
359
  actualVersion: current[0].user_version,
358
- supportedVersion: 11,
360
+ supportedVersion: 12,
359
361
  message: "The predecessor store is missing required tables; no upgrade was committed."
360
362
  });
361
363
  if ((yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name='effect_agent_recovery_checkpoints'`).length !== (current[0].user_version === 10 ? 1 : 0)) return yield* SqliteStorageCompatibilityError.make({
362
364
  actualVersion: current[0].user_version,
363
- supportedVersion: 11,
365
+ supportedVersion: 12,
364
366
  message: "The predecessor recovery checkpoint storage does not match its version; refusing ambiguous data without mutation."
365
367
  });
366
368
  if ((yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_submissions_nonterminal'`).length !== 0) return yield* SqliteStorageCompatibilityError.make({
367
369
  actualVersion: current[0].user_version,
368
- supportedVersion: 11,
370
+ supportedVersion: 12,
369
371
  message: "The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation."
370
372
  });
371
373
  if (current[0].user_version === 7) {
@@ -403,7 +405,14 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
403
405
  yield* createNonterminalIndex;
404
406
  yield* failpoint("upgrade:after-mutation");
405
407
  yield* failpoint("upgrade:before-version");
406
- yield* sql`PRAGMA user_version = 11`;
408
+ yield* createNativeReadIndexes;
409
+ yield* createMessageDeliveryPendingIndex;
410
+ yield* seedNativeReadIndexes.pipe(Effect.catchTag("ThreadStoreError", (error) => SqliteStorageCorruptionError.make({
411
+ table: "effect_agent_canonical_records",
412
+ rowKey: "upgrade",
413
+ message: error.message
414
+ })));
415
+ yield* sql`PRAGMA user_version = 12`;
407
416
  yield* failpoint("upgrade:after-version");
408
417
  })).pipe(Effect.provide(NodeCrypto.layer), Effect.catchTag("SqliteStorageFailpointError", (error) => SqliteStorageError.make({
409
418
  cause: error,
@@ -432,7 +441,7 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
432
441
  `.pipe(Effect.mapError(storageError("inspect unversioned storage")));
433
442
  if ((yield* decodeRows(Schema.Array(SqliteNameRow), "sqlite_master", "effect_agent_%", existingRows)).length > 0) return yield* SqliteStorageCompatibilityError.make({
434
443
  actualVersion: 0,
435
- supportedVersion: 11,
444
+ supportedVersion: 12,
436
445
  message: "The SQLite file contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer."
437
446
  });
438
447
  yield* SqliteMigrator.run({ loader: sqliteMigrations }).pipe(Effect.mapError((error) => SqliteStorageError.make({
@@ -441,6 +450,37 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
441
450
  message: error.message
442
451
  })));
443
452
  }
453
+ if (version.user_version === 11) yield* sql.withTransaction(Effect.gen(function* () {
454
+ const current = yield* sql`PRAGMA user_version`;
455
+ if (current[0]?.user_version === 12) return;
456
+ if (current[0]?.user_version !== 11) return yield* SqliteStorageCompatibilityError.make({
457
+ actualVersion: current[0]?.user_version ?? -1,
458
+ supportedVersion: 12,
459
+ message: "Storage version changed during native index upgrade"
460
+ });
461
+ yield* checkPredecessorLayout(10);
462
+ if ((yield* sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'effect_agent_submissions_nonterminal'`).length !== 1) return yield* SqliteStorageCompatibilityError.make({
463
+ actualVersion: 11,
464
+ supportedVersion: 12,
465
+ message: "Predecessor storage is missing its required nonterminal index"
466
+ });
467
+ yield* failpoint("upgrade:before-mutation");
468
+ yield* createNativeReadIndexes;
469
+ yield* createMessageDeliveryPendingIndex;
470
+ yield* seedNativeReadIndexes.pipe(Effect.catchTag("ThreadStoreError", (error) => SqliteStorageCorruptionError.make({
471
+ table: "effect_agent_canonical_records",
472
+ rowKey: "upgrade",
473
+ message: error.message
474
+ })));
475
+ yield* failpoint("upgrade:after-mutation");
476
+ yield* failpoint("upgrade:before-version");
477
+ yield* sql`PRAGMA user_version = 12`;
478
+ yield* failpoint("upgrade:after-version");
479
+ })).pipe(Effect.mapError((error) => SqliteStorageError.make({
480
+ operation: "upgrade native indexes",
481
+ message: error.message,
482
+ cause: error
483
+ })));
444
484
  const requiredRows = yield* sql`
445
485
  SELECT name
446
486
  FROM sqlite_master
@@ -460,12 +500,12 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
460
500
  'effect_agent_schedules',
461
501
  'effect_agent_message_deliveries',
462
502
  'effect_agent_recovery_checkpoints'
463
- )) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')
503
+ )) OR (type = 'index' AND name IN ('effect_agent_submissions_nonterminal', 'effect_agent_records_subtree', 'effect_agent_message_deliveries_pending', 'effect_agent_records_outstanding', 'effect_agent_records_call', 'effect_agent_records_run_input', 'effect_agent_records_worker_input'))
464
504
  ORDER BY name
465
505
  `.pipe(Effect.mapError(storageError("verify storage tables")));
466
- if ((yield* decodeRows(Schema.Array(SqliteNameRow), "sqlite_master", "required_tables", requiredRows)).length !== 15) return yield* SqliteStorageCompatibilityError.make({
467
- actualVersion: 11,
468
- supportedVersion: 11,
506
+ if ((yield* decodeRows(Schema.Array(SqliteNameRow), "sqlite_master", "required_tables", requiredRows)).length !== 21) return yield* SqliteStorageCompatibilityError.make({
507
+ actualVersion: 12,
508
+ supportedVersion: 12,
469
509
  message: "The SQLite file claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection."
470
510
  });
471
511
  const classifyWriteFailure = (operation) => (error) => error.reason._tag === "LockTimeoutError" ? SqliteWriteContention.make({
@@ -712,6 +752,12 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
712
752
  ${record.recordJson}
713
753
  )
714
754
  `.pipe(Effect.mapError(storageError("insert canonical record")));
755
+ const canonical = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(record.recordJson).pipe(Effect.mapError((error) => SqliteStorageCorruptionError.make({
756
+ table: "effect_agent_canonical_records",
757
+ rowKey: record.recordId,
758
+ message: error.message
759
+ })));
760
+ yield* indexCanonicalRecord(request.threadId, canonical).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.mapError(storageError("index canonical record")));
715
761
  yield* failpoint("append:after-record-insert");
716
762
  }), { discard: true });
717
763
  yield* sql`
@@ -995,4 +1041,4 @@ const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(function*
995
1041
  //#endregion
996
1042
  export { initializeSqliteJournal as a, decodeRows as i, RawCheckpoint as n, RawReadRequest as r, RawAppendRequest as t };
997
1043
 
998
- //# sourceMappingURL=sqlite-journal-CBOQDySe.mjs.map
1044
+ //# sourceMappingURL=sqlite-journal-BCyBc87Y.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-journal-BCyBc87Y.mjs","names":[],"sources":["../src/internal/sqlite-journal.ts"],"sourcesContent":["import { NodeCrypto } from \"@effect/platform-node\";\nimport { SqliteMigrator } from \"@effect/sql-sqlite-node\";\nimport { Effect, Exit, Schema } from \"effect\";\nimport { EMPTY_TAIL_DIGEST } from \"effect-agent/digest\";\nimport { CanonicalRecord, CanonicalSequence, ProducerEpoch } from \"effect-agent/records\";\nimport { ScheduleFailpoint, ScheduleFailpointError } from \"effect-agent/schedule\";\nimport { createMessageDeliveryPendingIndex } from \"effect-agent/sql-message-delivery-store\";\nimport {\n checkV2ThreadLayout,\n upgradeV2Schedules,\n upgradeV2Subscriptions,\n} from \"effect-agent/sql-storage-v2-upgrade\";\nimport {\n createNativeReadIndexes,\n seedNativeReadIndexes,\n indexCanonicalRecord,\n} from \"effect-agent/sql-thread-native-reads\";\nimport { SubscriptionFailpoint, SubscriptionFailpointError } from \"effect-agent/subscription\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n type SaveRecoveryCheckpointRequest,\n} from \"effect-agent/thread-store\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport { SqliteStorageConfig } from \"../SqliteStorageConfig.ts\";\nimport type { SqliteStorageFailpointError } from \"../SqliteStorageError.ts\";\nimport {\n SqliteAppendConflict,\n SqliteCheckpointConflict,\n SqliteFenceRejected,\n SqliteStorageCompatibilityError,\n SqliteStorageFailpointLocation,\n SqliteStorageCorruptionError,\n SqliteStorageError,\n SqliteWriteContention,\n} from \"../SqliteStorageError.ts\";\nimport { SqliteStorageFailpoint } from \"../SqliteStorageFailpoint.ts\";\nimport { createMessageDeliveryTables } from \"./message-delivery-schema.ts\";\nimport {\n CurrentSqliteStorageVersion,\n createNonterminalIndex,\n sqliteMigrations,\n} from \"./migrations.ts\";\nimport { createRecoveryCheckpointTable } from \"./recovery-checkpoint-schema.ts\";\n\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(16 * 1024 * 1024));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst NonNegativeInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));\nconst MAX_RECORDS_PER_THREAD = MAX_THREAD_EXPORT_RECORDS;\nconst ZERO_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst MAX_STORED_TEXT_BYTES = 16 * 1024 * 1024;\nconst MAX_IDENTIFIER_LENGTH = 1_024;\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nclass SqliteVersionRow extends Schema.Class<SqliteVersionRow>(\"SqliteVersionRow\")({\n user_version: NonNegativeInt,\n}) {}\n\nclass SqliteJournalModeRow extends Schema.Class<SqliteJournalModeRow>(\"SqliteJournalModeRow\")({\n journal_mode: Schema.NonEmptyString.check(Schema.isMaxLength(32)),\n}) {}\n\nclass SqliteNameRow extends Schema.Class<SqliteNameRow>(\"SqliteNameRow\")({\n name: BoundedIdentifier,\n}) {}\n\nclass ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n producer_epoch: ProducerEpoch,\n tail_digest: BoundedStoredText,\n tail_sequence: CanonicalSequence,\n}) {}\n\nclass BatchRow extends Schema.Class<BatchRow>(\"BatchRow\")({\n batch_digest: BoundedStoredText,\n batch_id: BoundedIdentifier,\n batch_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n first_sequence: CanonicalSequence,\n last_sequence: CanonicalSequence,\n tail_digest: BoundedStoredText,\n}) {}\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: BoundedIdentifier,\n thread_id: BoundedIdentifier,\n record_id: BoundedIdentifier,\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\nclass CheckpointRow extends Schema.Class<CheckpointRow>(\"CheckpointRow\")({\n checkpoint_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n tail_digest: BoundedStoredText,\n through_sequence: CanonicalSequence,\n}) {}\n\nexport class RawRecord extends Schema.Class<RawRecord>(\"@effect-agent/storage-sqlite/RawRecord\")({\n recordId: BoundedIdentifier,\n recordJson: BoundedStoredText,\n}) {}\n\nexport class RawAppendRequest extends Schema.Class<RawAppendRequest>(\n \"@effect-agent/storage-sqlite/RawAppendRequest\",\n)({\n batchDigest: BoundedStoredText,\n batchId: BoundedIdentifier,\n batchJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n expectedTailDigest: BoundedStoredText,\n expectedTailSequence: CanonicalSequence,\n producerEpoch: ProducerEpoch,\n records: Schema.NonEmptyArray(RawRecord).check(Schema.isMaxLength(256)),\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawAppendResult extends Schema.Class<RawAppendResult>(\n \"@effect-agent/storage-sqlite/RawAppendResult\",\n)({\n firstSequence: CanonicalSequence,\n lastSequence: CanonicalSequence,\n replayed: Schema.Boolean,\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawReadRequest extends Schema.Class<RawReadRequest>(\n \"@effect-agent/storage-sqlite/RawReadRequest\",\n)({\n threadId: BoundedIdentifier,\n fromSequenceExclusive: CanonicalSequence,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1_024)),\n}) {}\n\nexport class RawCheckpoint extends Schema.Class<RawCheckpoint>(\n \"@effect-agent/storage-sqlite/RawCheckpoint\",\n)({\n checkpointJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n tailDigest: BoundedStoredText,\n throughSequence: CanonicalSequence,\n}) {}\n\nexport class RawThreadExport extends Schema.Class<RawThreadExport>(\n \"@effect-agent/storage-sqlite/RawThreadExport\",\n)({\n thread: ThreadRow,\n records: Schema.Array(RecordRow),\n}) {}\n\ntype AppendError =\n | SqliteAppendConflict\n | SqliteFenceRejected\n | SqliteStorageCorruptionError\n | SqliteStorageError\n | SqliteStorageFailpointError\n | SqliteWriteContention;\n\ntype CheckpointError =\n | SqliteCheckpointConflict\n | SqliteStorageCorruptionError\n | SqliteStorageError\n | SqliteWriteContention;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): SqliteStorageError =>\n SqliteStorageError.make({\n cause: error,\n operation,\n message: error.message,\n });\n\n/** Decode raw SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = Effect.fn(\"SqliteJournal.decodeRows\")(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<ReadonlyArray<A>, SqliteStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n SqliteStorageCorruptionError.make({\n table,\n rowKey,\n message: String(error),\n }),\n ),\n ),\n);\n\n/** Decode exactly one raw SQLite row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = Effect.fn(\"SqliteJournal.decodeSingleRow\")(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<A, SqliteStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n SqliteStorageCorruptionError.make({\n table,\n rowKey,\n message: `Expected exactly one row but found ${decoded.length}.`,\n }),\n ),\n ),\n ),\n);\n\n/** Column inventory of the supported v8 predecessor, independent of physical column order. */\nconst predecessorColumns = {\n effect_agent_threads: [\n \"thread_id\",\n \"created_at\",\n \"tail_sequence\",\n \"tail_digest\",\n \"producer_epoch\",\n ],\n effect_agent_canonical_batches: [\n \"thread_id\",\n \"batch_id\",\n \"first_sequence\",\n \"last_sequence\",\n \"batch_digest\",\n \"tail_digest\",\n \"batch_json\",\n ],\n effect_agent_canonical_records: [\"thread_id\", \"sequence\", \"record_id\", \"batch_id\", \"record_json\"],\n effect_agent_checkpoints: [\"thread_id\", \"through_sequence\", \"tail_digest\", \"checkpoint_json\"],\n effect_agent_submissions: [\n \"submission_id\",\n \"thread_id\",\n \"queue_sequence\",\n \"principal\",\n \"idempotency_key\",\n \"agent_id\",\n \"agent_digests_json\",\n \"deployment_id\",\n \"input_json\",\n \"input_digest\",\n \"receipt_id\",\n \"state\",\n \"settled_outcome\",\n \"created_at\",\n \"ready_at\",\n \"input_applied_record_id\",\n \"input_applied_sequence\",\n \"joined_host_submission_id\",\n \"suspended_reason_json\",\n \"suspended_at\",\n \"unknown_reason\",\n \"unknown_tool_call_ids_json\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"admission_group\",\n \"admission_fence_json\",\n ],\n effect_agent_submission_ownership: [\n \"submission_id\",\n \"attempt_id\",\n \"ownership_token\",\n \"producer_epoch\",\n \"owner_producer_id\",\n \"lease_expires_at\",\n ],\n effect_agent_attempts: [\n \"attempt_id\",\n \"submission_id\",\n \"thread_id\",\n \"owner_producer_id\",\n \"producer_epoch\",\n \"claimed_at\",\n ],\n effect_agent_settlement_reservations: [\n \"submission_id\",\n \"settlement_id\",\n \"outcome\",\n \"record_id\",\n \"record_json\",\n \"record_digest\",\n \"reserved_at\",\n \"finalized_at\",\n ],\n effect_agent_abort_intents: [\n \"submission_id\",\n \"author\",\n \"reason\",\n \"requested_at\",\n \"canonical_record_id\",\n ],\n effect_agent_approval_decisions: [\n \"submission_id\",\n \"tool_call_id\",\n \"decision\",\n \"resolver\",\n \"reason\",\n \"decided_at\",\n ],\n effect_agent_unknown_resolutions: [\n \"submission_id\",\n \"tool_call_id\",\n \"author\",\n \"reason\",\n \"resolution_json\",\n \"resolved_at\",\n ],\n effect_agent_child_reservations: [\n \"reservation_id\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"child_submission_id\",\n \"status\",\n \"allocation_json\",\n \"allocation_digest\",\n \"accounting_json\",\n \"reserved_at\",\n \"release_began_at\",\n \"released_at\",\n ],\n effect_agent_schedules: [\n \"tenant_id\",\n \"owner_id\",\n \"schedule_id\",\n \"deadline_at_millis\",\n \"record_json\",\n ],\n effect_agent_subscription_sequences: [\n \"tenant_id\",\n \"source_address\",\n \"sequence\",\n \"event_scan_cursor\",\n \"delivery_scan_cursor\",\n \"recovery_scan_cursor\",\n ],\n effect_agent_subscriptions: [\n \"tenant_id\",\n \"source_address\",\n \"owner_id\",\n \"subscription_id\",\n \"ordinal\",\n \"source_name\",\n \"source_version\",\n \"matching_key\",\n \"state\",\n \"expires_at_millis\",\n \"recovery_at_millis\",\n \"recovery_present\",\n \"record_json\",\n ],\n effect_agent_subscription_events: [\n \"tenant_id\",\n \"source_address\",\n \"event_id\",\n \"source_name\",\n \"source_version\",\n \"matching_key\",\n \"payload_digest\",\n \"cutoff\",\n \"cursor\",\n \"routing_complete\",\n \"next_attempt_at_millis\",\n \"record_json\",\n \"tombstone\",\n ],\n effect_agent_subscription_deliveries: [\n \"tenant_id\",\n \"source_address\",\n \"owner_id\",\n \"subscription_id\",\n \"event_id\",\n \"delivery_key\",\n \"state\",\n \"next_attempt_at_millis\",\n \"record_json\",\n ],\n} as const;\n\nconst checkPredecessorLayout = Effect.fn(\"SqliteJournal.checkPredecessorLayout\")(function* (\n version: 8 | 9 | 10,\n) {\n const sql = yield* SqlClient.SqlClient;\n\n const messageColumns =\n version === 8\n ? predecessorColumns\n : {\n ...predecessorColumns,\n effect_agent_submissions: [\n ...predecessorColumns.effect_agent_submissions,\n \"worker_admission_json\",\n \"message_admission_json\",\n ],\n effect_agent_message_deliveries: [\n \"owner_thread_id\",\n \"message_id\",\n \"version\",\n \"state\",\n \"deadline_at_millis\",\n \"record_json\",\n ],\n };\n\n const expectedColumns = {\n ...messageColumns,\n ...(version === 10\n ? {\n effect_agent_recovery_checkpoints: [\n \"thread_id\",\n \"through_sequence\",\n \"tail_digest\",\n \"checkpoint_json\",\n ],\n }\n : {}),\n };\n\n for (const [table, expected] of Object.entries(expectedColumns)) {\n const columns = yield* decodeRows(\n Schema.Array(Schema.Struct({ name: BoundedIdentifier })),\n table,\n \"schema\",\n yield* sql.unsafe(`PRAGMA table_info(${table})`),\n );\n\n const names = new Set<string>(expected);\n\n if (columns.length !== names.size || columns.some((column) => !names.has(column.name)))\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: version,\n supportedVersion: CurrentSqliteStorageVersion,\n message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`,\n });\n }\n});\n\nexport const initializeSqliteJournal = Effect.fn(\"SqliteJournal.initialize\")(function* () {\n const sql = yield* SqlClient.SqlClient;\n const { hit: failpoint } = yield* SqliteStorageFailpoint;\n const { busyTimeout } = yield* SqliteStorageConfig;\n\n yield* sql`PRAGMA foreign_keys = ON`.pipe(Effect.mapError(storageError(\"enable foreign keys\")));\n // PRAGMA statements do not accept bound parameters; the value is a schema-validated\n // non-negative integer, never caller-controlled text.\n yield* sql\n .unsafe(`PRAGMA busy_timeout = ${busyTimeout}`)\n .pipe(Effect.mapError(storageError(\"configure busy timeout\")));\n\n const journalModeRows = yield* sql<Record<string, unknown>>`PRAGMA journal_mode`.pipe(\n Effect.mapError(storageError(\"read journal mode\")),\n );\n\n const journalMode = yield* decodeSingleRow(\n Schema.Array(SqliteJournalModeRow),\n \"pragma_journal_mode\",\n \"singleton\",\n journalModeRows,\n );\n\n if (journalMode.journal_mode.toLowerCase() !== \"wal\") {\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: 0,\n supportedVersion: CurrentSqliteStorageVersion,\n message: `SQLite WAL mode is required; the database reported ${journalMode.journal_mode}.`,\n });\n }\n\n const versionRows = yield* sql<Record<string, unknown>>`PRAGMA user_version`.pipe(\n Effect.mapError(storageError(\"read storage version\")),\n );\n\n const version = yield* decodeSingleRow(\n Schema.Array(SqliteVersionRow),\n \"pragma_user_version\",\n \"singleton\",\n versionRows,\n );\n\n // Support the known beta49/beta50 and immediate predecessor formats atomically.\n if (\n version.user_version !== 0 &&\n version.user_version !== 7 &&\n version.user_version !== 8 &&\n version.user_version !== 9 &&\n version.user_version !== 10 &&\n version.user_version !== 11 &&\n version.user_version !== CurrentSqliteStorageVersion\n ) {\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: version.user_version,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n `The SQLite file uses unsupported storage version ${version.user_version}; ` +\n `this build supports exactly version ${CurrentSqliteStorageVersion}. ` +\n \"Only supported v7, v8, v9, v10 and v11 can be upgraded automatically. Keep the original file and use a compatible library version.\",\n });\n }\n\n if (\n version.user_version === 7 ||\n version.user_version === 8 ||\n version.user_version === 9 ||\n version.user_version === 10\n ) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{ user_version: number }>`PRAGMA user_version`;\n\n if (current.length === 1 && current[0].user_version === CurrentSqliteStorageVersion)\n return;\n if (\n current.length !== 1 ||\n (current[0].user_version !== 7 &&\n current[0].user_version !== 8 &&\n current[0].user_version !== 9 &&\n current[0].user_version !== 10)\n )\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: CurrentSqliteStorageVersion,\n message: \"Storage version changed while acquiring the upgrade transaction.\",\n });\n\n const required = yield* sql<{\n name: string;\n }>`SELECT name FROM sqlite_master WHERE type='table' AND name IN (\n 'effect_agent_threads', 'effect_agent_canonical_batches', 'effect_agent_canonical_records',\n 'effect_agent_checkpoints', 'effect_agent_submissions', 'effect_agent_submission_ownership',\n 'effect_agent_attempts', 'effect_agent_settlement_reservations', 'effect_agent_abort_intents',\n 'effect_agent_approval_decisions', 'effect_agent_unknown_resolutions', 'effect_agent_schedules'\n )`;\n\n if (required.length !== 12)\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: current[0].user_version,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n \"The predecessor store is missing required tables; no upgrade was committed.\",\n });\n\n const recoveryTables =\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name='effect_agent_recovery_checkpoints'`;\n\n if (recoveryTables.length !== (current[0].user_version === 10 ? 1 : 0))\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: current[0].user_version,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n \"The predecessor recovery checkpoint storage does not match its version; refusing ambiguous data without mutation.\",\n });\n\n const indexes =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_submissions_nonterminal'`;\n\n if (indexes.length !== 0)\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: current[0].user_version,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n \"The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation.\",\n });\n if (current[0].user_version === 7) {\n yield* checkV2ThreadLayout();\n for (const statement of [\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_group TEXT`,\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_fence_json TEXT`,\n sql`CREATE INDEX effect_agent_submissions_group ON effect_agent_submissions (thread_id, admission_group, state)`,\n ]) {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* statement;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n yield* upgradeV2Schedules(16 * 1024 * 1024).pipe(\n Effect.provideService(ScheduleFailpoint, {\n hit: (point) =>\n Schema.decodeUnknownEffect(SqliteStorageFailpointLocation)(point).pipe(\n Effect.flatMap(failpoint),\n Effect.mapError(() => ScheduleFailpointError.make({ point })),\n ),\n }),\n );\n yield* upgradeV2Subscriptions(16 * 1024 * 1024).pipe(\n Effect.provideService(SubscriptionFailpoint, {\n hit: (point) =>\n Schema.decodeUnknownEffect(SqliteStorageFailpointLocation)(point).pipe(\n Effect.flatMap(failpoint),\n Effect.mapError(() => SubscriptionFailpointError.make({ point })),\n ),\n }),\n );\n }\n if (\n current[0].user_version === 8 ||\n current[0].user_version === 9 ||\n current[0].user_version === 10\n )\n yield* checkPredecessorLayout(current[0].user_version);\n if (current[0].user_version === 7 || current[0].user_version === 8) {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN worker_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN message_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createMessageDeliveryTables;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n if (current[0].user_version !== 10) {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createRecoveryCheckpointTable;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createNonterminalIndex;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* createNativeReadIndexes;\n yield* createMessageDeliveryPendingIndex;\n yield* seedNativeReadIndexes.pipe(\n Effect.catchTag(\"ThreadStoreError\", (error) =>\n SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: \"upgrade\",\n message: error.message,\n }),\n ),\n );\n yield* sql`PRAGMA user_version = 12`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.provide(NodeCrypto.layer),\n Effect.catchTag(\"SqliteStorageFailpointError\", (error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"upgrade storage\",\n message: error.message,\n }),\n ),\n Effect.catchTag([\"ScheduleFailpointError\", \"SubscriptionFailpointError\"], (error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"upgrade storage\",\n message: \"Injected storage upgrade failure\",\n }),\n ),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n SqliteStorageCorruptionError.make({\n table: error.table,\n rowKey: error.rowKey,\n message: error.message,\n }),\n ),\n Effect.catchTag(\"SqlError\", storageError(\"upgrade supported storage\")),\n Effect.catchTag(\"SchemaError\", (error) =>\n SqliteStorageCorruptionError.make({\n table: \"upgrade\",\n rowKey: \"v7\",\n message: error.message,\n }),\n ),\n );\n }\n\n if (version.user_version === 0) {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name LIKE 'effect_agent_%'\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"inspect unversioned storage\")));\n\n const existing = yield* decodeRows(\n Schema.Array(SqliteNameRow),\n \"sqlite_master\",\n \"effect_agent_%\",\n existingRows,\n );\n\n if (existing.length > 0) {\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: 0,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n \"The SQLite file contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer.\",\n });\n }\n\n yield* SqliteMigrator.run({ loader: sqliteMigrations }).pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"initialize current storage\",\n message: error.message,\n }),\n ),\n );\n }\n\n if (version.user_version === 11) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{ user_version: number }>`PRAGMA user_version`;\n\n if (current[0]?.user_version === 12) return;\n if (current[0]?.user_version !== 11)\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: current[0]?.user_version ?? -1,\n supportedVersion: 12,\n message: \"Storage version changed during native index upgrade\",\n });\n yield* checkPredecessorLayout(10);\n\n const requiredIndex =\n yield* sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'effect_agent_submissions_nonterminal'`;\n\n if (requiredIndex.length !== 1)\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: 11,\n supportedVersion: 12,\n message: \"Predecessor storage is missing its required nonterminal index\",\n });\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createNativeReadIndexes;\n yield* createMessageDeliveryPendingIndex;\n yield* seedNativeReadIndexes.pipe(\n Effect.catchTag(\"ThreadStoreError\", (error) =>\n SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: \"upgrade\",\n message: error.message,\n }),\n ),\n );\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* sql`PRAGMA user_version = 12`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n operation: \"upgrade native indexes\",\n message: error.message,\n cause: error,\n }),\n ),\n );\n }\n\n const requiredRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE (type = 'table'\n AND name IN (\n 'effect_agent_threads',\n 'effect_agent_canonical_batches',\n 'effect_agent_canonical_records',\n 'effect_agent_checkpoints',\n 'effect_agent_submissions',\n 'effect_agent_submission_ownership',\n 'effect_agent_attempts',\n 'effect_agent_settlement_reservations',\n 'effect_agent_abort_intents',\n 'effect_agent_approval_decisions',\n 'effect_agent_unknown_resolutions',\n 'effect_agent_schedules',\n 'effect_agent_message_deliveries',\n 'effect_agent_recovery_checkpoints'\n )) OR (type = 'index' AND name IN ('effect_agent_submissions_nonterminal', 'effect_agent_records_subtree', 'effect_agent_message_deliveries_pending', 'effect_agent_records_outstanding', 'effect_agent_records_call', 'effect_agent_records_run_input', 'effect_agent_records_worker_input'))\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"verify storage tables\")));\n\n const required = yield* decodeRows(\n Schema.Array(SqliteNameRow),\n \"sqlite_master\",\n \"required_tables\",\n requiredRows,\n );\n\n if (required.length !== 21) {\n return yield* SqliteStorageCompatibilityError.make({\n actualVersion: CurrentSqliteStorageVersion,\n supportedVersion: CurrentSqliteStorageVersion,\n message:\n \"The SQLite file claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection.\",\n });\n }\n\n const classifyWriteFailure =\n (operation: string) =>\n (error: SqlError): SqliteStorageError | SqliteWriteContention =>\n error.reason._tag === \"LockTimeoutError\"\n ? SqliteWriteContention.make({\n cause: error,\n operation,\n message: `Another producer holds the SQLite write lock; ${operation} is safe to retry.`,\n })\n : storageError(operation)(error);\n\n /**\n * Runs one journal write transaction under `BEGIN IMMEDIATE`. SQLite's deferred `BEGIN`\n * would let a read-then-write transaction start as a reader and fail with\n * SQLITE_BUSY_SNAPSHOT on upgrade, which `busy_timeout` never retries. Taking the write\n * lock up front keeps cross-owner contention inside the bounded busy retry; a lock\n * timeout is classified as the retryable SqliteWriteContention. A failed `BEGIN` leaves\n * no transaction, so no rollback is attempted for it.\n *\n * Journal write transactions are always top level. Nesting one inside another would\n * deadlock the single-connection client, so new journal operations must not wrap this\n * helper inside another transaction.\n */\n const withWriteTransaction =\n (operation: string) =>\n <A, E>(\n effect: Effect.Effect<A, E>,\n ): Effect.Effect<A, E | SqliteStorageError | SqliteWriteContention> =>\n Effect.uninterruptibleMask((restore) =>\n Effect.scoped(\n Effect.gen(function* () {\n const connection = yield* sql.reserve.pipe(\n Effect.mapError(classifyWriteFailure(operation)),\n );\n\n yield* connection\n .executeUnprepared(\"BEGIN IMMEDIATE\", [], undefined)\n .pipe(Effect.mapError(classifyWriteFailure(operation)));\n\n const exit = yield* restore(\n Effect.provideService(effect, sql.transactionService, [connection, 0] as const),\n ).pipe(Effect.exit);\n\n if (Exit.isSuccess(exit)) {\n yield* connection\n .executeUnprepared(\"COMMIT\", [], undefined)\n .pipe(Effect.mapError(classifyWriteFailure(operation)));\n\n return exit.value;\n }\n yield* Effect.orDie(connection.executeUnprepared(\"ROLLBACK\", [], undefined));\n\n return yield* exit;\n }),\n ).pipe(\n Effect.withSpan(\"SqliteJournal.withWriteTransaction\", { attributes: { operation } }),\n ),\n );\n\n /**\n * Runs a read-only snapshot under a deferred transaction. Effect's SQLite client now\n * starts every writable-client `withTransaction` with `BEGIN IMMEDIATE`, which is the\n * right default for mutations but would make exports take the write lock and block a\n * concurrent append. Reserving the connection and beginning explicitly preserves the\n * adapter's snapshot-with-concurrent-writer contract. As with the write helper, a failed\n * `BEGIN` is reported directly because there is no transaction to roll back.\n */\n const withReadTransaction =\n (operation: string) =>\n <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | SqliteStorageError> =>\n Effect.uninterruptibleMask((restore) =>\n Effect.scoped(\n Effect.gen(function* () {\n const connection = yield* sql.reserve.pipe(Effect.mapError(storageError(operation)));\n\n yield* connection\n .executeUnprepared(\"BEGIN\", [], undefined)\n .pipe(Effect.mapError(storageError(operation)));\n\n const exit = yield* restore(\n Effect.provideService(effect, sql.transactionService, [connection, 0] as const),\n ).pipe(Effect.exit);\n\n if (Exit.isSuccess(exit)) {\n yield* connection\n .executeUnprepared(\"COMMIT\", [], undefined)\n .pipe(Effect.mapError(storageError(operation)));\n\n return exit.value;\n }\n yield* Effect.orDie(connection.executeUnprepared(\"ROLLBACK\", [], undefined));\n\n return yield* exit;\n }),\n ).pipe(Effect.withSpan(\"SqliteJournal.withReadTransaction\", { attributes: { operation } })),\n );\n\n const materialize = Effect.fn(\"SqliteJournal.materialize\")(function* (\n threadId: string,\n createdAt: string,\n emptyTailDigest: string,\n producerEpoch: ProducerEpoch,\n ): Effect.fn.Return<\n void,\n SqliteFenceRejected | SqliteStorageCorruptionError | SqliteStorageError | SqliteWriteContention\n > {\n if (\n threadId.length > MAX_IDENTIFIER_LENGTH ||\n storedTextBytes(emptyTailDigest) > MAX_STORED_TEXT_BYTES\n ) {\n return yield* SqliteStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity or initial digest exceeds the SQLite storage bounds.\",\n });\n }\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read materialized thread\")));\n\n const existing = yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n existingRows,\n );\n\n if (existing.length > 1) {\n return yield* SqliteStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: threadId,\n message: \"A thread primary key returned more than one row.\",\n });\n }\n if (existing.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_threads (\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n ) VALUES (\n ${threadId},\n ${createdAt},\n 0,\n ${emptyTailDigest},\n ${producerEpoch}\n )\n `.pipe(Effect.mapError(storageError(\"materialize thread\")));\n\n return;\n }\n if (producerEpoch < existing[0].producer_epoch) {\n return yield* SqliteFenceRejected.make({\n producerEpoch,\n actualEpoch: existing[0].producer_epoch,\n message: `Producer epoch ${producerEpoch} is stale; current epoch is ${existing[0].producer_epoch}.`,\n });\n }\n if (producerEpoch > existing[0].producer_epoch) {\n yield* sql`\n UPDATE effect_agent_threads\n SET producer_epoch = ${producerEpoch}\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"advance materialization epoch\")));\n }\n }),\n );\n });\n\n const getThread = Effect.fn(\"SqliteJournal.getThread\")(function* (threadId: string) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read thread\")));\n\n return yield* decodeRows(Schema.Array(ThreadRow), \"effect_agent_threads\", threadId, rows);\n });\n\n const append = Effect.fn(\"SqliteJournal.append\")(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<RawAppendResult, AppendError> {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n storedTextBytes(request.batchJson) > MAX_STORED_TEXT_BYTES ||\n storedTextBytes(request.batchDigest) > MAX_STORED_TEXT_BYTES ||\n storedTextBytes(request.tailDigest) > MAX_STORED_TEXT_BYTES ||\n request.records.some(\n (record) =>\n record.recordId.length > MAX_IDENTIFIER_LENGTH ||\n storedTextBytes(record.recordJson) > MAX_STORED_TEXT_BYTES,\n )\n ) {\n return yield* SqliteStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers or encoded JSON exceed the SQLite storage bounds.\",\n });\n }\n\n return yield* withWriteTransaction(\"append transaction\")(\n Effect.gen(function* () {\n const recordIds = request.records.map((record) => record.recordId);\n\n if (new Set(recordIds).size !== recordIds.length) {\n return yield* SqliteAppendConflict.make({\n message: `Batch ${request.batchId} contains duplicate canonical record IDs.`,\n reason: \"record-identity\",\n });\n }\n\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"read append tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n request.threadId,\n threadRows,\n );\n\n if (request.producerEpoch !== thread.producer_epoch) {\n return yield* SqliteFenceRejected.make({\n producerEpoch: request.producerEpoch,\n actualEpoch: thread.producer_epoch,\n message: `Producer epoch ${request.producerEpoch} is not the current epoch ${thread.producer_epoch}.`,\n });\n }\n\n const batchRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId}\n AND batch_id = ${request.batchId}\n `.pipe(Effect.mapError(storageError(\"read idempotent batch\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${request.threadId}/${request.batchId}`,\n batchRows,\n );\n\n if (batches.length > 1) {\n return yield* SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: `${request.threadId}/${request.batchId}`,\n message: \"A canonical batch primary key returned more than one row.\",\n });\n }\n if (batches.length === 1) {\n const existing = batches[0];\n\n if (existing.batch_digest !== request.batchDigest) {\n return yield* SqliteAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-digest\",\n });\n }\n\n return RawAppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n tailDigest: existing.tail_digest,\n });\n }\n\n if (\n request.expectedTailSequence !== thread.tail_sequence ||\n request.expectedTailDigest !== thread.tail_digest\n ) {\n return yield* SqliteAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence}/${request.expectedTailDigest} ` +\n `but found ${thread.tail_sequence}/${thread.tail_digest}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\n actualTailDigest: thread.tail_digest,\n });\n }\n if (thread.tail_sequence + request.records.length > MAX_RECORDS_PER_THREAD) {\n return yield* SqliteStorageError.make({\n operation: \"append canonical batch\",\n message: `Thread record limit ${MAX_RECORDS_PER_THREAD} would be exceeded.`,\n });\n }\n\n const existingRecordRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND record_id IN ${sql.in(recordIds)}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"check canonical record identities\")));\n\n const existingRecords = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/record_ids`,\n existingRecordRows,\n );\n\n if (existingRecords.length > 0) {\n return yield* SqliteAppendConflict.make({\n message: `Canonical record ID ${existingRecords[0].record_id} already exists.`,\n reason: \"record-identity\",\n });\n }\n\n const firstSequence = yield* Schema.decodeEffect(CanonicalSequence)(\n thread.tail_sequence + 1,\n ).pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n const lastSequence = yield* Schema.decodeEffect(CanonicalSequence)(\n firstSequence + request.records.length - 1,\n ).pipe(\n Effect.mapError((error) =>\n SqliteStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n ) VALUES (\n ${request.threadId},\n ${request.batchId},\n ${firstSequence},\n ${lastSequence},\n ${request.batchDigest},\n ${request.tailDigest},\n ${request.batchJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n yield* failpoint(\"append:after-batch-insert\");\n\n yield* Effect.forEach(\n request.records,\n (record, index) =>\n Effect.gen(function* () {\n yield* sql`\n INSERT INTO effect_agent_canonical_records (\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n ) VALUES (\n ${request.threadId},\n ${firstSequence + index},\n ${record.recordId},\n ${request.batchId},\n ${record.recordJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical record\")));\n\n const canonical = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n record.recordJson,\n ).pipe(\n Effect.mapError((error) =>\n SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: record.recordId,\n message: error.message,\n }),\n ),\n );\n\n yield* indexCanonicalRecord(request.threadId, canonical).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError(storageError(\"index canonical record\")),\n );\n yield* failpoint(\"append:after-record-insert\");\n }),\n { discard: true },\n );\n\n yield* sql`\n UPDATE effect_agent_threads\n SET\n tail_sequence = ${lastSequence},\n tail_digest = ${request.tailDigest},\n producer_epoch = ${request.producerEpoch}\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"advance thread tail\")));\n yield* failpoint(\"append:after-tail-update\");\n\n return RawAppendResult.make({\n firstSequence,\n lastSequence,\n replayed: false,\n tailDigest: request.tailDigest,\n });\n }),\n );\n });\n\n const read = Effect.fn(\"SqliteJournal.read\")(function* (request: RawReadRequest) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence > ${request.fromSequenceExclusive}\n ORDER BY sequence\n LIMIT ${request.limit}\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n return yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n rows,\n );\n });\n\n const exportThread = Effect.fn(\"SqliteJournal.exportThread\")(function* (threadId: string) {\n return yield* withReadTransaction(\"export transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"export thread\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n threadRows,\n );\n\n yield* failpoint(\"export:after-thread-read\");\n\n if (thread.tail_sequence > MAX_RECORDS_PER_THREAD)\n return yield* SqliteStorageError.make({\n operation: \"export thread\",\n message: \"The thread exceeds the current export record limit.\",\n });\n const records: Array<RecordRow> = [];\n let afterSequence = ZERO_SEQUENCE;\n\n while (afterSequence < thread.tail_sequence) {\n const limit = Math.min(1_024, thread.tail_sequence - afterSequence);\n\n const request = RawReadRequest.make({\n threadId,\n fromSequenceExclusive: afterSequence,\n limit,\n });\n\n const page = yield* read(request);\n\n if (\n page.length !== limit ||\n page.some((record, index) => record.sequence !== afterSequence + index + 1)\n ) {\n return yield* SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message: \"The exported canonical prefix is not contiguous through its captured tail.\",\n });\n }\n records.push(...page);\n afterSequence = page[page.length - 1].sequence;\n }\n\n const beyondTail =\n yield* sql`SELECT sequence FROM effect_agent_canonical_records WHERE thread_id=${threadId} AND sequence > ${thread.tail_sequence} LIMIT 1`.pipe(\n Effect.mapError(storageError(\"verify export tail\")),\n );\n\n if (beyondTail.length !== 0)\n return yield* SqliteStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message: \"Canonical records exist beyond the captured thread tail.\",\n });\n\n return RawThreadExport.make({ thread, records });\n }),\n );\n });\n\n const saveCheckpoint = Effect.fn(\"SqliteJournal.saveCheckpoint\")(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (\n checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH ||\n storedTextBytes(checkpoint.checkpointJson) > MAX_STORED_TEXT_BYTES\n ) {\n return yield* SqliteStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity or encoded JSON exceeds the SQLite storage bounds.\",\n });\n }\n yield* withWriteTransaction(\"checkpoint transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${checkpoint.threadId}\n `.pipe(Effect.mapError(storageError(\"read checkpoint tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n checkpoint.threadId,\n threadRows,\n );\n\n if (checkpoint.throughSequence > thread.tail_sequence) {\n return yield* SqliteCheckpointConflict.make({\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${checkpoint.threadId}\n AND through_sequence = ${checkpoint.throughSequence}\n `.pipe(Effect.mapError(storageError(\"read idempotent checkpoint\")));\n\n const existing = yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n checkpointRows,\n );\n\n if (existing.length > 1) {\n return yield* SqliteStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n message: \"A checkpoint primary key returned more than one row.\",\n });\n }\n if (existing.length === 1) {\n if (\n existing[0].tail_digest !== checkpoint.tailDigest ||\n existing[0].checkpoint_json !== checkpoint.checkpointJson\n ) {\n return yield* SqliteCheckpointConflict.make({\n message: \"A different checkpoint already exists at this canonical sequence.\",\n });\n }\n\n return;\n }\n\n yield* sql`\n INSERT INTO effect_agent_checkpoints (\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.tailDigest},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const saveRecoveryCheckpoint = Effect.fn(\"SqliteJournal.saveRecoveryCheckpoint\")(function* (\n request: SaveRecoveryCheckpointRequest,\n checkpointJson: string,\n ) {\n const { checkpoint } = request;\n\n if (\n checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH ||\n storedTextBytes(checkpointJson) > MAX_STORED_TEXT_BYTES\n ) {\n return yield* SqliteStorageError.make({\n operation: \"save recovery checkpoint\",\n message: \"Checkpoint identity or encoded JSON exceeds the SQLite storage bounds.\",\n });\n }\n yield* withWriteTransaction(\"recovery checkpoint transaction\")(\n Effect.gen(function* () {\n const threads = yield* getThread(checkpoint.threadId);\n const thread = threads[0];\n\n if (thread === undefined)\n return yield* ThreadNotMaterialized.make({ threadId: checkpoint.threadId });\n if (request.producerEpoch !== thread.producer_epoch)\n return yield* FenceRejected.make({\n threadId: checkpoint.threadId,\n actualEpoch: thread.producer_epoch,\n attemptedEpoch: request.producerEpoch,\n });\n if (checkpoint.throughSequence > thread.tail_sequence)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n\n const digests =\n checkpoint.throughSequence === 0\n ? [EMPTY_TAIL_DIGEST]\n : yield* getTailDigestAt(checkpoint.threadId, checkpoint.throughSequence);\n\n if (digests.length !== 1 || digests[0] !== checkpoint.tailDigest)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n\n yield* failpoint(\"save-recovery-checkpoint:before\");\n yield* sql`\n INSERT INTO effect_agent_recovery_checkpoints (thread_id, through_sequence, tail_digest, checkpoint_json)\n VALUES (${checkpoint.threadId}, ${checkpoint.throughSequence}, ${checkpoint.tailDigest}, ${checkpointJson})\n ON CONFLICT (thread_id) DO UPDATE SET\n through_sequence = excluded.through_sequence,\n tail_digest = excluded.tail_digest,\n checkpoint_json = excluded.checkpoint_json\n WHERE excluded.through_sequence >= effect_agent_recovery_checkpoints.through_sequence\n `.pipe(Effect.mapError(storageError(\"save recovery checkpoint\")));\n }),\n );\n yield* failpoint(\"save-recovery-checkpoint:after\");\n });\n\n const loadRecoveryCheckpoint = Effect.fn(\"SqliteJournal.loadRecoveryCheckpoint\")(function* (\n threadId: string,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, through_sequence, tail_digest, checkpoint_json\n FROM effect_agent_recovery_checkpoints\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"load recovery checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_recovery_checkpoints\",\n threadId,\n rows,\n );\n });\n\n const loadCheckpoint = Effect.fn(\"SqliteJournal.loadCheckpoint\")(function* (\n threadId: string,\n atOrBeforeSequence: CanonicalSequence,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${threadId}\n AND through_sequence <= ${atOrBeforeSequence}\n ORDER BY through_sequence DESC\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"load checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${threadId}<=${atOrBeforeSequence}`,\n rows,\n );\n });\n\n const getTailDigestAt = Effect.fn(\"SqliteJournal.getTailDigestAt\")(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) {\n const threads = yield* getThread(threadId);\n\n return threads.length === 0\n ? []\n : [threads[0].tail_sequence === 0 ? threads[0].tail_digest : undefined].filter(\n (value): value is string => value !== undefined,\n );\n }\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical digest at sequence\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.map((batch) => batch.tail_digest);\n });\n\n const scanStoredPayloads = Effect.fn(\"SqliteJournal.scanStoredPayloads\")(function* () {\n return yield* withReadTransaction(\"startup scan transaction\")(\n Effect.gen(function* () {\n const threads = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n ORDER BY thread_id\n `.pipe(Effect.mapError(storageError(\"scan threads\")));\n\n const batches = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n ORDER BY thread_id, first_sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical batches\")));\n\n const records = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n ORDER BY thread_id, sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical records\")));\n\n const checkpoints = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n ORDER BY thread_id, through_sequence\n `.pipe(Effect.mapError(storageError(\"scan checkpoints\")));\n\n return {\n threads: yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n \"startup_scan\",\n threads,\n ),\n batches: yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n \"startup_scan\",\n batches,\n ),\n records: yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n \"startup_scan\",\n records,\n ),\n checkpoints: yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n \"startup_scan\",\n checkpoints,\n ),\n };\n }),\n );\n });\n\n return {\n append,\n exportThread,\n getThread,\n getTailDigestAt,\n loadCheckpoint,\n loadRecoveryCheckpoint,\n saveRecoveryCheckpoint,\n materialize,\n read,\n saveCheckpoint,\n scanStoredPayloads,\n withWriteTransaction,\n withReadTransaction,\n } as const;\n});\n\nexport type SqliteJournal = Effect.Success<ReturnType<typeof initializeSqliteJournal>>;\n"],"mappings":"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AC,KACtC,OAAO,SAAS,YACd,QAAQ,WAAW,IACf,OAAO,QAAQ,QAAQ,EAAE,IACzB,OAAO,KACL,6BAA6B,KAAK;CAChC;CACA;CACA,SAAS,sCAAsC,QAAQ,OAAO;AAChE,CAAC,CACH,CACN,CACF,CACJ;;AAGA,MAAM,qBAAqB;CACzB,sBAAsB;EACpB;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAAC;EAAa;EAAY;EAAa;EAAY;CAAa;CAChG,0BAA0B;EAAC;EAAa;EAAoB;EAAe;CAAiB;CAC5F,0BAA0B;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mCAAmC;EACjC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,uBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,sCAAsC;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,4BAA4B;EAC1B;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kCAAkC;EAChC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,wBAAwB;EACtB;EACA;EACA;EACA;EACA;CACF;CACA,qCAAqC;EACnC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,4BAA4B;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kCAAkC;EAChC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,sCAAsC;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,MA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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/storage-sqlite","version":"0.1.0-beta.100","dependencies":{"@effect/platform-node":"4.0.0-rc.115","@effect/sql-sqlite-node":"4.0.0-rc.115","effect-agent":"0.1.0-beta.100"},"devDependencies":{"@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.2"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./sqlite-activity-store":{"types":"./dist/SqliteActivityStore.d.mts","default":"./dist/SqliteActivityStore.mjs"},"./sqlite-schedule-store":{"types":"./dist/SqliteScheduleStore.d.mts","default":"./dist/SqliteScheduleStore.mjs"},"./sqlite-storage-config":{"types":"./dist/SqliteStorageConfig.d.mts","default":"./dist/SqliteStorageConfig.mjs"},"./sqlite-storage-error":{"types":"./dist/SqliteStorageError.d.mts","default":"./dist/SqliteStorageError.mjs"},"./sqlite-storage-failpoint":{"types":"./dist/SqliteStorageFailpoint.d.mts","default":"./dist/SqliteStorageFailpoint.mjs"},"./sqlite-storage-version":{"types":"./dist/SqliteStorageVersion.d.mts","default":"./dist/SqliteStorageVersion.mjs"},"./sqlite-submission-ledger":{"types":"./dist/SqliteSubmissionLedger.d.mts","default":"./dist/SqliteSubmissionLedger.mjs"},"./sqlite-subscription-store":{"types":"./dist/SqliteSubscriptionStore.d.mts","default":"./dist/SqliteSubscriptionStore.mjs"},"./sqlite-thread-store":{"types":"./dist/SqliteThreadStore.d.mts","default":"./dist/SqliteThreadStore.mjs"},"./testing/sqlite-storage-failpoint-testing":{"types":"./dist/SqliteStorageFailpointTesting.d.mts","default":"./dist/SqliteStorageFailpointTesting.mjs"},"./sqlite-message-delivery-store":{"types":"./dist/SqliteMessageDeliveryStore.d.mts","default":"./dist/SqliteMessageDeliveryStore.mjs"}},"description":"Node SQLite persistence adapters for the Effect Agent durable runtime and optional memory lifecycle.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-sqlite"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
1
+ {"name":"@effect-agent/storage-sqlite","version":"0.1.0-beta.102","dependencies":{"@effect/platform-node":"4.0.0-rc.115","@effect/sql-sqlite-node":"4.0.0-rc.115","effect-agent":"0.1.0-beta.102"},"devDependencies":{"@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.2"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./sqlite-activity-store":{"types":"./dist/SqliteActivityStore.d.mts","default":"./dist/SqliteActivityStore.mjs"},"./sqlite-schedule-store":{"types":"./dist/SqliteScheduleStore.d.mts","default":"./dist/SqliteScheduleStore.mjs"},"./sqlite-storage-config":{"types":"./dist/SqliteStorageConfig.d.mts","default":"./dist/SqliteStorageConfig.mjs"},"./sqlite-storage-error":{"types":"./dist/SqliteStorageError.d.mts","default":"./dist/SqliteStorageError.mjs"},"./sqlite-storage-failpoint":{"types":"./dist/SqliteStorageFailpoint.d.mts","default":"./dist/SqliteStorageFailpoint.mjs"},"./sqlite-storage-version":{"types":"./dist/SqliteStorageVersion.d.mts","default":"./dist/SqliteStorageVersion.mjs"},"./sqlite-submission-ledger":{"types":"./dist/SqliteSubmissionLedger.d.mts","default":"./dist/SqliteSubmissionLedger.mjs"},"./sqlite-subscription-store":{"types":"./dist/SqliteSubscriptionStore.d.mts","default":"./dist/SqliteSubscriptionStore.mjs"},"./sqlite-thread-store":{"types":"./dist/SqliteThreadStore.d.mts","default":"./dist/SqliteThreadStore.mjs"},"./testing/sqlite-storage-failpoint-testing":{"types":"./dist/SqliteStorageFailpointTesting.d.mts","default":"./dist/SqliteStorageFailpointTesting.mjs"},"./sqlite-message-delivery-store":{"types":"./dist/SqliteMessageDeliveryStore.d.mts","default":"./dist/SqliteMessageDeliveryStore.mjs"}},"description":"Node SQLite persistence adapters for the Effect Agent durable runtime and optional memory lifecycle.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-sqlite"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
@@ -21,6 +21,7 @@ import {
21
21
  Digest,
22
22
  ObservationOffset,
23
23
  } from "effect-agent/records";
24
+ import { makeSelectedReads } from "effect-agent/sql-thread-native-reads";
24
25
  import { DEFAULT_OWNERSHIP_LEASE_DURATION } from "effect-agent/submission-ledger";
25
26
  import {
26
27
  AppendConflict,
@@ -32,7 +33,7 @@ import {
32
33
  ThreadMaterialization,
33
34
  ThreadNotMaterialized,
34
35
  ThreadObservation,
35
- ThreadRead,
36
+ ThreadReadRequest,
36
37
  ThreadStore,
37
38
  type ThreadCheckpoints,
38
39
  ThreadStoreError,
@@ -618,11 +619,12 @@ const makeServices = Effect.fn("SqliteThreadStore.makeServices")(function* () {
618
619
  return yield* Effect.forEach(rows, decodeEnvelope);
619
620
  });
620
621
 
621
- const readEffect = Effect.fn("SqliteThreadStore.read")(function* (request: ThreadRead) {
622
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadRead))(request).pipe(
622
+ const readEffect = Effect.fn("SqliteThreadStore.read")(function* (request: ThreadReadRequest) {
623
+ const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(
623
624
  Effect.mapError((error) => schemaStoreError("validate thread read", error)),
624
625
  );
625
626
 
627
+ if ("selection" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));
626
628
  yield* requireThread(journal, validated.threadId);
627
629
 
628
630
  const records = yield* loadRecords(
@@ -918,7 +920,10 @@ const makeServices = Effect.fn("SqliteThreadStore.makeServices")(function* () {
918
920
  return Option.some(checkpoint);
919
921
  });
920
922
 
923
+ const selectedReads = yield* makeSelectedReads(decodeEnvelope);
924
+
921
925
  const threadStore = ThreadStore.of({
926
+ countPeerMessages: selectedReads.countPeerMessages,
922
927
  append,
923
928
  export: exportThread,
924
929
  inspectTail,
@@ -1,11 +1,13 @@
1
1
  import { SqliteMigrator } from "@effect/sql-sqlite-node";
2
2
  import { Effect } from "effect";
3
+ import { createMessageDeliveryPendingIndex } from "effect-agent/sql-message-delivery-store";
4
+ import { createNativeReadIndexes } from "effect-agent/sql-thread-native-reads";
3
5
  import * as SqlClient from "effect/unstable/sql/SqlClient";
4
6
 
5
7
  import { createMessageDeliveryTables } from "./message-delivery-schema.ts";
6
8
  import { createRecoveryCheckpointTable } from "./recovery-checkpoint-schema.ts";
7
9
 
8
- export const CurrentSqliteStorageVersion = 11;
10
+ export const CurrentSqliteStorageVersion = 12;
9
11
 
10
12
  /** Index only outstanding obligations, ordered by the recovery scan's stable cursor. */
11
13
  export const createNonterminalIndex = Effect.gen(function* () {
@@ -344,9 +346,11 @@ export const sqliteMigrations = SqliteMigrator.fromRecord({
344
346
  .withoutTransform;
345
347
  yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`
346
348
  .withoutTransform;
349
+ yield* createNativeReadIndexes;
347
350
  yield* createNonterminalIndex;
348
351
  yield* createMessageDeliveryTables;
352
+ yield* createMessageDeliveryPendingIndex;
349
353
  yield* createRecoveryCheckpointTable;
350
- yield* sql`PRAGMA user_version = 11`.withoutTransform;
354
+ yield* sql`PRAGMA user_version = 12`.withoutTransform;
351
355
  }),
352
356
  });
@@ -2,13 +2,19 @@ import { NodeCrypto } from "@effect/platform-node";
2
2
  import { SqliteMigrator } from "@effect/sql-sqlite-node";
3
3
  import { Effect, Exit, Schema } from "effect";
4
4
  import { EMPTY_TAIL_DIGEST } from "effect-agent/digest";
5
- import { CanonicalSequence, ProducerEpoch } from "effect-agent/records";
5
+ import { CanonicalRecord, CanonicalSequence, ProducerEpoch } from "effect-agent/records";
6
6
  import { ScheduleFailpoint, ScheduleFailpointError } from "effect-agent/schedule";
7
+ import { createMessageDeliveryPendingIndex } from "effect-agent/sql-message-delivery-store";
7
8
  import {
8
9
  checkV2ThreadLayout,
9
10
  upgradeV2Schedules,
10
11
  upgradeV2Subscriptions,
11
12
  } from "effect-agent/sql-storage-v2-upgrade";
13
+ import {
14
+ createNativeReadIndexes,
15
+ seedNativeReadIndexes,
16
+ indexCanonicalRecord,
17
+ } from "effect-agent/sql-thread-native-reads";
12
18
  import { SubscriptionFailpoint, SubscriptionFailpointError } from "effect-agent/subscription";
13
19
  import {
14
20
  MAX_THREAD_EXPORT_RECORDS,
@@ -488,6 +494,7 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
488
494
  version.user_version !== 8 &&
489
495
  version.user_version !== 9 &&
490
496
  version.user_version !== 10 &&
497
+ version.user_version !== 11 &&
491
498
  version.user_version !== CurrentSqliteStorageVersion
492
499
  ) {
493
500
  return yield* SqliteStorageCompatibilityError.make({
@@ -496,7 +503,7 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
496
503
  message:
497
504
  `The SQLite file uses unsupported storage version ${version.user_version}; ` +
498
505
  `this build supports exactly version ${CurrentSqliteStorageVersion}. ` +
499
- "Only supported v7, v8, v9 and v10 can be upgraded automatically. Keep the original file and use a compatible library version.",
506
+ "Only supported v7, v8, v9, v10 and v11 can be upgraded automatically. Keep the original file and use a compatible library version.",
500
507
  });
501
508
  }
502
509
 
@@ -620,7 +627,18 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
620
627
  yield* createNonterminalIndex;
621
628
  yield* failpoint("upgrade:after-mutation");
622
629
  yield* failpoint("upgrade:before-version");
623
- yield* sql`PRAGMA user_version = 11`;
630
+ yield* createNativeReadIndexes;
631
+ yield* createMessageDeliveryPendingIndex;
632
+ yield* seedNativeReadIndexes.pipe(
633
+ Effect.catchTag("ThreadStoreError", (error) =>
634
+ SqliteStorageCorruptionError.make({
635
+ table: "effect_agent_canonical_records",
636
+ rowKey: "upgrade",
637
+ message: error.message,
638
+ }),
639
+ ),
640
+ );
641
+ yield* sql`PRAGMA user_version = 12`;
624
642
  yield* failpoint("upgrade:after-version");
625
643
  }),
626
644
  )
@@ -694,6 +712,59 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
694
712
  );
695
713
  }
696
714
 
715
+ if (version.user_version === 11) {
716
+ yield* sql
717
+ .withTransaction(
718
+ Effect.gen(function* () {
719
+ const current = yield* sql<{ user_version: number }>`PRAGMA user_version`;
720
+
721
+ if (current[0]?.user_version === 12) return;
722
+ if (current[0]?.user_version !== 11)
723
+ return yield* SqliteStorageCompatibilityError.make({
724
+ actualVersion: current[0]?.user_version ?? -1,
725
+ supportedVersion: 12,
726
+ message: "Storage version changed during native index upgrade",
727
+ });
728
+ yield* checkPredecessorLayout(10);
729
+
730
+ const requiredIndex =
731
+ yield* sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'effect_agent_submissions_nonterminal'`;
732
+
733
+ if (requiredIndex.length !== 1)
734
+ return yield* SqliteStorageCompatibilityError.make({
735
+ actualVersion: 11,
736
+ supportedVersion: 12,
737
+ message: "Predecessor storage is missing its required nonterminal index",
738
+ });
739
+ yield* failpoint("upgrade:before-mutation");
740
+ yield* createNativeReadIndexes;
741
+ yield* createMessageDeliveryPendingIndex;
742
+ yield* seedNativeReadIndexes.pipe(
743
+ Effect.catchTag("ThreadStoreError", (error) =>
744
+ SqliteStorageCorruptionError.make({
745
+ table: "effect_agent_canonical_records",
746
+ rowKey: "upgrade",
747
+ message: error.message,
748
+ }),
749
+ ),
750
+ );
751
+ yield* failpoint("upgrade:after-mutation");
752
+ yield* failpoint("upgrade:before-version");
753
+ yield* sql`PRAGMA user_version = 12`;
754
+ yield* failpoint("upgrade:after-version");
755
+ }),
756
+ )
757
+ .pipe(
758
+ Effect.mapError((error) =>
759
+ SqliteStorageError.make({
760
+ operation: "upgrade native indexes",
761
+ message: error.message,
762
+ cause: error,
763
+ }),
764
+ ),
765
+ );
766
+ }
767
+
697
768
  const requiredRows = yield* sql<Record<string, unknown>>`
698
769
  SELECT name
699
770
  FROM sqlite_master
@@ -713,7 +784,7 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
713
784
  'effect_agent_schedules',
714
785
  'effect_agent_message_deliveries',
715
786
  'effect_agent_recovery_checkpoints'
716
- )) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')
787
+ )) OR (type = 'index' AND name IN ('effect_agent_submissions_nonterminal', 'effect_agent_records_subtree', 'effect_agent_message_deliveries_pending', 'effect_agent_records_outstanding', 'effect_agent_records_call', 'effect_agent_records_run_input', 'effect_agent_records_worker_input'))
717
788
  ORDER BY name
718
789
  `.pipe(Effect.mapError(storageError("verify storage tables")));
719
790
 
@@ -724,7 +795,7 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
724
795
  requiredRows,
725
796
  );
726
797
 
727
- if (required.length !== 15) {
798
+ if (required.length !== 21) {
728
799
  return yield* SqliteStorageCompatibilityError.make({
729
800
  actualVersion: CurrentSqliteStorageVersion,
730
801
  supportedVersion: CurrentSqliteStorageVersion,
@@ -1142,6 +1213,23 @@ export const initializeSqliteJournal = Effect.fn("SqliteJournal.initialize")(fun
1142
1213
  ${record.recordJson}
1143
1214
  )
1144
1215
  `.pipe(Effect.mapError(storageError("insert canonical record")));
1216
+
1217
+ const canonical = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(
1218
+ record.recordJson,
1219
+ ).pipe(
1220
+ Effect.mapError((error) =>
1221
+ SqliteStorageCorruptionError.make({
1222
+ table: "effect_agent_canonical_records",
1223
+ rowKey: record.recordId,
1224
+ message: error.message,
1225
+ }),
1226
+ ),
1227
+ );
1228
+
1229
+ yield* indexCanonicalRecord(request.threadId, canonical).pipe(
1230
+ Effect.provideService(SqlClient.SqlClient, sql),
1231
+ Effect.mapError(storageError("index canonical record")),
1232
+ );
1145
1233
  yield* failpoint("append:after-record-insert");
1146
1234
  }),
1147
1235
  { discard: true },