@effect-agent/storage-cloudflare 0.1.0-beta.113 → 0.1.0-beta.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DoMessageDeliveryStore.mjs +1 -1
- package/dist/{DoStorageVersion-Db6fjP-I.d.mts → DoStorageVersion-DJwZzqel.d.mts} +2 -2
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoSubmissionLedger.mjs +63 -3
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/DoThreadStore.mjs +1 -1
- package/dist/PortProtocol.d.mts +781 -200
- package/dist/PortProtocol.mjs +15 -2
- package/dist/PortProtocol.mjs.map +1 -1
- package/dist/PortRouting.d.mts +2 -2
- package/dist/PortRouting.mjs +23 -1
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-BeHu8_Bh.mjs → do-journal-D65Iuln6.mjs} +97 -35
- package/dist/do-journal-D65Iuln6.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/{migrations-DZKTNU88.mjs → migrations-Br6QqMIf.mjs} +19 -4
- package/dist/migrations-Br6QqMIf.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoSubmissionLedger.ts +136 -2
- package/src/PortProtocol.ts +27 -0
- package/src/PortRouting.ts +66 -0
- package/src/internal/do-journal.ts +143 -33
- package/src/internal/migrations.ts +18 -1
- package/dist/do-journal-BeHu8_Bh.mjs.map +0 -1
- package/dist/migrations-DZKTNU88.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoStorageCompatibilityError, DoStorageCorruptionError, DoStorageError, DoValueBoundExceeded } from "./DoStorageError.mjs";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as createRecoveryCheckpointTable, i as doMigrations, n as createNonterminalIndex, o as createMessageDeliveryTables, r as createWorkerStops } from "./migrations-Br6QqMIf.mjs";
|
|
3
3
|
import { Effect, Schema, Stream } from "effect";
|
|
4
4
|
import { createMessageDeliveryPendingIndex } from "effect-agent/sql-message-delivery-store";
|
|
5
5
|
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
@@ -283,7 +283,8 @@ const checkPredecessorLayout = Effect.fn("DoJournal.checkPredecessorLayout")(fun
|
|
|
283
283
|
"record_json"
|
|
284
284
|
]
|
|
285
285
|
},
|
|
286
|
-
...version ===
|
|
286
|
+
...version === 7 ? { effect_agent_canonical_records: [...predecessorColumns.effect_agent_canonical_records, "outstanding"] } : {},
|
|
287
|
+
...version >= 5 ? { effect_agent_recovery_checkpoints: [
|
|
287
288
|
"thread_id",
|
|
288
289
|
"through_sequence",
|
|
289
290
|
"tail_digest",
|
|
@@ -295,7 +296,7 @@ const checkPredecessorLayout = Effect.fn("DoJournal.checkPredecessorLayout")(fun
|
|
|
295
296
|
const names = new Set(expected);
|
|
296
297
|
if (columns.length !== names.size || columns.some((column) => !names.has(column.name))) return yield* DoStorageCompatibilityError.make({
|
|
297
298
|
actualVersion: version,
|
|
298
|
-
supportedVersion:
|
|
299
|
+
supportedVersion: 9,
|
|
299
300
|
message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`
|
|
300
301
|
});
|
|
301
302
|
}
|
|
@@ -324,6 +325,26 @@ const REQUIRED_TABLES = [
|
|
|
324
325
|
* Node machinery those served has no DC analogue and is deliberately absent.
|
|
325
326
|
*/
|
|
326
327
|
const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(function* (sql, failpoint = noFailpoint, maxStoredValueBytes) {
|
|
328
|
+
const verifyWorkerPredecessor = Effect.fnUntraced(function* (workerContract) {
|
|
329
|
+
const requiredRows = yield* sql`
|
|
330
|
+
SELECT name
|
|
331
|
+
FROM sqlite_master
|
|
332
|
+
WHERE (type = 'table'
|
|
333
|
+
AND name IN ${sql.in([
|
|
334
|
+
...REQUIRED_TABLES,
|
|
335
|
+
"effect_agent_message_deliveries",
|
|
336
|
+
"effect_agent_recovery_checkpoints"
|
|
337
|
+
])}
|
|
338
|
+
) 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'))
|
|
339
|
+
OR (${workerContract ? 1 : 0} = 1 AND name IN ('effect_agent_worker_stops', 'effect_agent_worker_starts', 'effect_agent_worker_pending', 'effect_agent_worker_execution'))
|
|
340
|
+
ORDER BY name
|
|
341
|
+
`.pipe(Effect.mapError(storageError("verify storage tables")));
|
|
342
|
+
if ((yield* decodeRows(Schema.Array(DoNameRow), "sqlite_master", "required_tables", requiredRows)).length !== REQUIRED_TABLES.length + 9 + (workerContract ? 4 : 0)) return yield* DoStorageCompatibilityError.make({
|
|
343
|
+
actualVersion: 9,
|
|
344
|
+
supportedVersion: 9,
|
|
345
|
+
message: "The Durable Object claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection."
|
|
346
|
+
});
|
|
347
|
+
});
|
|
327
348
|
const metaTableRows = yield* sql`
|
|
328
349
|
SELECT name
|
|
329
350
|
FROM sqlite_master
|
|
@@ -340,7 +361,7 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
340
361
|
`.pipe(Effect.mapError(storageError("inspect unversioned storage")));
|
|
341
362
|
if ((yield* decodeRows(Schema.Array(DoNameRow), "sqlite_master", "effect_agent_%", existingRows)).length > 0) return yield* DoStorageCompatibilityError.make({
|
|
342
363
|
actualVersion: 0,
|
|
343
|
-
supportedVersion:
|
|
364
|
+
supportedVersion: 9,
|
|
344
365
|
message: "The Durable Object contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer."
|
|
345
366
|
});
|
|
346
367
|
yield* SqliteMigrator.run({
|
|
@@ -360,25 +381,25 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
360
381
|
const version = yield* decodeSingleRow(Schema.Array(DoMetaRow), "effect_agent_meta", "storage_version", versionRows);
|
|
361
382
|
if (version.value === "2" || version.value === "3" || version.value === "4" || version.value === "5") yield* sql.withTransaction(Effect.gen(function* () {
|
|
362
383
|
const current = yield* sql`SELECT value FROM effect_agent_meta WHERE key='storage_version'`;
|
|
363
|
-
if (current.length === 1 && current[0].value === String(
|
|
384
|
+
if (current.length === 1 && current[0].value === String(9)) return;
|
|
364
385
|
if (current.length !== 1 || current[0].value !== "2" && current[0].value !== "3" && current[0].value !== "4" && current[0].value !== "5") return yield* DoStorageCompatibilityError.make({
|
|
365
386
|
actualVersion: -1,
|
|
366
|
-
supportedVersion:
|
|
387
|
+
supportedVersion: 9,
|
|
367
388
|
message: "Storage version changed while acquiring the upgrade transaction."
|
|
368
389
|
});
|
|
369
390
|
if ((yield* decodeRows(Schema.Array(DoNameRow), "sqlite_master", "required_tables", yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name IN ${sql.in([...REQUIRED_TABLES])}`)).length !== REQUIRED_TABLES.length) return yield* DoStorageCompatibilityError.make({
|
|
370
391
|
actualVersion: Number(current[0].value),
|
|
371
|
-
supportedVersion:
|
|
392
|
+
supportedVersion: 9,
|
|
372
393
|
message: "The predecessor store is missing required tables. Retain the original store for inspection; no upgrade was committed."
|
|
373
394
|
});
|
|
374
395
|
if ((yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name='effect_agent_recovery_checkpoints'`).length !== (current[0].value === "5" ? 1 : 0)) return yield* DoStorageCompatibilityError.make({
|
|
375
396
|
actualVersion: Number(current[0].value),
|
|
376
|
-
supportedVersion:
|
|
397
|
+
supportedVersion: 9,
|
|
377
398
|
message: "The predecessor recovery checkpoint storage does not match its version; refusing ambiguous data without mutation."
|
|
378
399
|
});
|
|
379
400
|
if ((yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_submissions_nonterminal'`).length !== 0) return yield* DoStorageCompatibilityError.make({
|
|
380
401
|
actualVersion: Number(current[0].value),
|
|
381
|
-
supportedVersion:
|
|
402
|
+
supportedVersion: 9,
|
|
382
403
|
message: "The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation."
|
|
383
404
|
});
|
|
384
405
|
if (current[0].value === "2") {
|
|
@@ -423,7 +444,8 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
423
444
|
rowKey: "upgrade",
|
|
424
445
|
message: error.message
|
|
425
446
|
})));
|
|
426
|
-
yield*
|
|
447
|
+
yield* createWorkerStops;
|
|
448
|
+
yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;
|
|
427
449
|
yield* failpoint("upgrade:after-version");
|
|
428
450
|
})).pipe(Effect.catchTag("DoStorageFailpointError", (error) => DoStorageError.make({
|
|
429
451
|
cause: error,
|
|
@@ -440,16 +462,16 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
440
462
|
})), Effect.catchTag("SqlError", storageError("upgrade supported thread storage")));
|
|
441
463
|
else if (version.value === "6") yield* sql.withTransaction(Effect.gen(function* () {
|
|
442
464
|
const current = yield* sql`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;
|
|
443
|
-
if (current[0]?.value === "
|
|
465
|
+
if (current[0]?.value === "9") return;
|
|
444
466
|
if (current[0]?.value !== "6") return yield* DoStorageCompatibilityError.make({
|
|
445
467
|
actualVersion: -1,
|
|
446
|
-
supportedVersion:
|
|
468
|
+
supportedVersion: 9,
|
|
447
469
|
message: "Storage version changed during native index upgrade"
|
|
448
470
|
});
|
|
449
471
|
yield* checkPredecessorLayout(5);
|
|
450
472
|
if ((yield* sql`SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'effect_agent_submissions_nonterminal'`).length !== 1) return yield* DoStorageCompatibilityError.make({
|
|
451
473
|
actualVersion: 6,
|
|
452
|
-
supportedVersion:
|
|
474
|
+
supportedVersion: 9,
|
|
453
475
|
message: "Predecessor storage is missing its required nonterminal index"
|
|
454
476
|
});
|
|
455
477
|
yield* failpoint("upgrade:before-mutation");
|
|
@@ -462,39 +484,79 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
462
484
|
})));
|
|
463
485
|
yield* failpoint("upgrade:after-mutation");
|
|
464
486
|
yield* failpoint("upgrade:before-version");
|
|
465
|
-
yield*
|
|
487
|
+
yield* createWorkerStops;
|
|
488
|
+
yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;
|
|
466
489
|
yield* failpoint("upgrade:after-version");
|
|
467
490
|
})).pipe(Effect.mapError((error) => DoStorageError.make({
|
|
468
491
|
operation: "upgrade native indexes",
|
|
469
492
|
message: error.message,
|
|
470
493
|
cause: error
|
|
471
494
|
})));
|
|
472
|
-
else if (version.value
|
|
495
|
+
else if (version.value === "7") yield* sql.withTransaction(Effect.gen(function* () {
|
|
496
|
+
const current = yield* sql`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;
|
|
497
|
+
if (current[0]?.value === "9") return;
|
|
498
|
+
if (current[0]?.value !== "7") return yield* DoStorageCompatibilityError.make({
|
|
499
|
+
actualVersion: -1,
|
|
500
|
+
supportedVersion: 9,
|
|
501
|
+
message: "Storage version changed during worker stop upgrade"
|
|
502
|
+
});
|
|
503
|
+
yield* checkPredecessorLayout(7);
|
|
504
|
+
yield* verifyWorkerPredecessor(false);
|
|
505
|
+
yield* failpoint("upgrade:before-mutation");
|
|
506
|
+
yield* createWorkerStops;
|
|
507
|
+
yield* failpoint("upgrade:after-mutation");
|
|
508
|
+
yield* failpoint("upgrade:before-version");
|
|
509
|
+
yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;
|
|
510
|
+
yield* failpoint("upgrade:after-version");
|
|
511
|
+
})).pipe(Effect.mapError((cause) => DoStorageError.make({
|
|
512
|
+
operation: "upgrade worker stop",
|
|
513
|
+
message: "Worker stop upgrade failed",
|
|
514
|
+
cause
|
|
515
|
+
})));
|
|
516
|
+
else if (version.value === "8") yield* sql.withTransaction(Effect.gen(function* () {
|
|
517
|
+
const current = yield* sql`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;
|
|
518
|
+
if (current[0]?.value === "9") return;
|
|
519
|
+
if (current[0]?.value !== "8") return yield* DoStorageCompatibilityError.make({
|
|
520
|
+
actualVersion: -1,
|
|
521
|
+
supportedVersion: 9,
|
|
522
|
+
message: "Storage version changed during assignment seal upgrade"
|
|
523
|
+
});
|
|
524
|
+
yield* checkPredecessorLayout(7);
|
|
525
|
+
yield* verifyWorkerPredecessor(true);
|
|
526
|
+
const columns = yield* sql`PRAGMA table_info(effect_agent_worker_stops)`;
|
|
527
|
+
yield* Schema.decodeUnknownEffect(Schema.Tuple([Schema.Struct({
|
|
528
|
+
cid: Schema.Literal(0),
|
|
529
|
+
name: Schema.Literal("thread_id"),
|
|
530
|
+
type: Schema.Literal("TEXT"),
|
|
531
|
+
notnull: Schema.Literal(1),
|
|
532
|
+
dflt_value: Schema.Null,
|
|
533
|
+
pk: Schema.Literal(1)
|
|
534
|
+
})]))(columns).pipe(Effect.mapError(() => DoStorageCompatibilityError.make({
|
|
535
|
+
actualVersion: 8,
|
|
536
|
+
supportedVersion: 9,
|
|
537
|
+
message: "Unsupported worker seal layout; no upgrade was committed"
|
|
538
|
+
})));
|
|
539
|
+
yield* failpoint("upgrade:before-mutation");
|
|
540
|
+
yield* sql`ALTER TABLE effect_agent_worker_stops ADD COLUMN terminal TEXT`;
|
|
541
|
+
yield* failpoint("upgrade:after-mutation");
|
|
542
|
+
yield* failpoint("upgrade:before-version");
|
|
543
|
+
yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;
|
|
544
|
+
yield* failpoint("upgrade:after-version");
|
|
545
|
+
})).pipe(Effect.mapError((cause) => DoStorageError.make({
|
|
546
|
+
operation: "upgrade assignment seals",
|
|
547
|
+
message: "Assignment seal upgrade failed",
|
|
548
|
+
cause
|
|
549
|
+
})));
|
|
550
|
+
else if (version.value !== String(9)) {
|
|
473
551
|
const actualVersion = Number.parseInt(version.value, 10);
|
|
474
552
|
return yield* DoStorageCompatibilityError.make({
|
|
475
553
|
actualVersion: Number.isSafeInteger(actualVersion) ? actualVersion : -1,
|
|
476
|
-
supportedVersion:
|
|
477
|
-
message: `The Durable Object uses unsupported storage version ${version.value}; this build supports exactly version
|
|
554
|
+
supportedVersion: 9,
|
|
555
|
+
message: `The Durable Object uses unsupported storage version ${version.value}; this build supports exactly version 9. Only supported v2, v3, v4, v5, v6, v7 and v8 can be upgraded automatically. Keep the original store and use a compatible library version.`
|
|
478
556
|
});
|
|
479
557
|
}
|
|
480
558
|
}
|
|
481
|
-
|
|
482
|
-
SELECT name
|
|
483
|
-
FROM sqlite_master
|
|
484
|
-
WHERE (type = 'table'
|
|
485
|
-
AND name IN ${sql.in([
|
|
486
|
-
...REQUIRED_TABLES,
|
|
487
|
-
"effect_agent_message_deliveries",
|
|
488
|
-
"effect_agent_recovery_checkpoints"
|
|
489
|
-
])}
|
|
490
|
-
) 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'))
|
|
491
|
-
ORDER BY name
|
|
492
|
-
`.pipe(Effect.mapError(storageError("verify storage tables")));
|
|
493
|
-
if ((yield* decodeRows(Schema.Array(DoNameRow), "sqlite_master", "required_tables", requiredRows)).length !== REQUIRED_TABLES.length + 9) return yield* DoStorageCompatibilityError.make({
|
|
494
|
-
actualVersion: 7,
|
|
495
|
-
supportedVersion: 7,
|
|
496
|
-
message: "The Durable Object claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection."
|
|
497
|
-
});
|
|
559
|
+
yield* verifyWorkerPredecessor(true);
|
|
498
560
|
return makeJournal(sql, failpoint, maxStoredValueBytes);
|
|
499
561
|
});
|
|
500
562
|
const makeJournal = (sql, failpoint, maxStoredValueBytes) => {
|
|
@@ -1054,4 +1116,4 @@ const initializeDoJournal = ensureCurrentStorage;
|
|
|
1054
1116
|
//#endregion
|
|
1055
1117
|
export { initializeDoJournal as a, decodeRows as i, RawCheckpoint as n, RawReadRequest as r, RawAppendRequest as t };
|
|
1056
1118
|
|
|
1057
|
-
//# sourceMappingURL=do-journal-
|
|
1119
|
+
//# sourceMappingURL=do-journal-D65Iuln6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-journal-D65Iuln6.mjs","names":[],"sources":["../src/internal/do-journal.ts"],"sourcesContent":["import { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect, Schema, Stream } from \"effect\";\nimport { EMPTY_TAIL_DIGEST } from \"effect-agent/digest\";\nimport { CanonicalRecord, CanonicalSequence, ProducerEpoch } from \"effect-agent/records\";\nimport { createMessageDeliveryPendingIndex } from \"effect-agent/sql-message-delivery-store\";\nimport { checkV2ThreadLayout } from \"effect-agent/sql-storage-v2-upgrade\";\nimport {\n createNativeReadIndexes,\n seedNativeReadIndexes,\n indexCanonicalRecord,\n} from \"effect-agent/sql-thread-native-reads\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n ThreadStoreDiagnostic,\n type SaveRecoveryCheckpointRequest,\n} from \"effect-agent/thread-store\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\nimport { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoFenceRejected,\n DoStorageCompatibilityError,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { createMessageDeliveryTables } from \"./message-delivery-schema.ts\";\nimport {\n CurrentDoStorageVersion,\n createNonterminalIndex,\n createWorkerStops,\n doMigrations,\n} from \"./migrations.ts\";\nimport { createRecoveryCheckpointTable } from \"./recovery-checkpoint-schema.ts\";\n\n/**\n * Static schema ceiling for stored text columns. Writes are bounded in BYTES by the\n * configured `maxStoredValueBytes` (always ≤ 2,000,000); UTF-8 byte length is never smaller\n * than UTF-16 string length, so any value that passed the byte bound also passes this\n * decode-side character ceiling.\n */\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(2_000_000));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst MAX_RECORDS_PER_THREAD = MAX_THREAD_EXPORT_RECORDS;\nconst ZERO_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst MAX_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n/** Durable Object SQL storage allows at most 100 bound parameters per statement. */\nconst MAX_BOUND_PARAMETERS = 100;\nconst isSqlError = Schema.is(SqlError);\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nconst chunked = <A>(values: ReadonlyArray<A>, size: number): Array<ReadonlyArray<A>> => {\n const chunks: Array<ReadonlyArray<A>> = [];\n\n for (let index = 0; index < values.length; index += size) {\n chunks.push(values.slice(index, index + size));\n }\n\n return chunks;\n};\n\nclass DoMetaRow extends Schema.Class<DoMetaRow>(\"DoMetaRow\")({\n value: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n}) {}\n\nclass DoNameRow extends Schema.Class<DoNameRow>(\"DoNameRow\")({\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\nconst ReadPlanRow = Schema.Struct({\n sequence: CanonicalSequence,\n record_json_bytes: Schema.Natural.check(Schema.isLessThanOrEqualTo(MAX_READ_PAGE_JSON_BYTES)),\n});\n\ntype ReadPage = [typeof ReadPlanRow.Type, ...Array<typeof ReadPlanRow.Type>];\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>(\n \"@effect-agent/storage-cloudflare/RawRecord\",\n)({\n recordId: BoundedIdentifier,\n recordJson: BoundedStoredText,\n}) {}\n\nexport class RawAppendRequest extends Schema.Class<RawAppendRequest>(\n \"@effect-agent/storage-cloudflare/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-cloudflare/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-cloudflare/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-cloudflare/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-cloudflare/RawThreadExport\",\n)({\n thread: ThreadRow,\n records: Schema.Array(RecordRow),\n}) {}\n\ntype AppendError =\n | DoAppendConflict\n | DoFenceRejected\n | DoStorageCorruptionError\n | DoStorageError\n | DoStorageFailpointError\n | DoValueBoundExceeded;\n\ntype CheckpointError =\n | DoCheckpointConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoValueBoundExceeded;\n\ntype DoJournalFailpoint = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoJournalFailpoint = () => Effect.void;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): DoStorageError =>\n DoStorageError.make({\n cause: error,\n operation,\n message: error.message,\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.reason._tag,\n }),\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n decoder: string = table,\n ): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: \"Stored rows do not satisfy the storage schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode storage rows\",\n decoder,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": decoder,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n ),\n);\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<A, DoStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n DoStorageCorruptionError.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 v3 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_meta: [\"key\", \"value\"],\n effect_agent_child_settlements: [\n \"parent_submission_id\",\n \"child_submission_id\",\n \"child_outcome\",\n \"recorded_at\",\n ],\n} as const;\n\nconst checkPredecessorLayout = Effect.fn(\"DoJournal.checkPredecessorLayout\")(function* (\n version: 3 | 4 | 5 | 7,\n) {\n const sql = yield* SqlClient.SqlClient;\n\n const messageColumns =\n version === 3\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 === 7\n ? {\n effect_agent_canonical_records: [\n ...predecessorColumns.effect_agent_canonical_records,\n \"outstanding\",\n ],\n }\n : {}),\n ...(version >= 5\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* DoStorageCompatibilityError.make({\n actualVersion: version,\n supportedVersion: CurrentDoStorageVersion,\n message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`,\n });\n }\n});\n\nconst REQUIRED_TABLES = [\n \"effect_agent_abort_intents\",\n \"effect_agent_approval_decisions\",\n \"effect_agent_attempts\",\n \"effect_agent_canonical_batches\",\n \"effect_agent_canonical_records\",\n \"effect_agent_checkpoints\",\n \"effect_agent_child_reservations\",\n \"effect_agent_child_settlements\",\n \"effect_agent_threads\",\n \"effect_agent_meta\",\n \"effect_agent_settlement_reservations\",\n \"effect_agent_submission_ownership\",\n \"effect_agent_submissions\",\n \"effect_agent_unknown_resolutions\",\n] as const;\n\n/**\n * Supported-predecessor or fresh storage gate (DEPLOY-008) over `effect_agent_meta` instead of\n * `PRAGMA user_version` (unverified on Durable Object SQL storage; a meta table is portable\n * regardless). No WAL check (Durable Object storage owns durability and confirms writes\n * through output gates) and no busy timeout (a Durable Object has exactly one writer): the\n * Node machinery those served has no DC analogue and is deliberately absent.\n */\nconst ensureCurrentStorage = Effect.fn(\"DoJournal.ensureCurrentStorage\")(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n const verifyWorkerPredecessor = Effect.fnUntraced(function* (workerContract: boolean) {\n const requiredRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE (type = 'table'\n AND name IN ${sql.in([...REQUIRED_TABLES, \"effect_agent_message_deliveries\", \"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 OR (${workerContract ? 1 : 0} = 1 AND name IN ('effect_agent_worker_stops', 'effect_agent_worker_starts', 'effect_agent_worker_pending', 'effect_agent_worker_execution'))\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"verify storage tables\")));\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n requiredRows,\n );\n\n if (required.length !== REQUIRED_TABLES.length + 9 + (workerContract ? 4 : 0)) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: CurrentDoStorageVersion,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection.\",\n });\n }\n });\n\n const metaTableRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name = 'effect_agent_meta'\n `.pipe(Effect.mapError(storageError(\"read storage version table\")));\n\n const metaTables = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_meta\",\n metaTableRows,\n );\n\n if (metaTables.length === 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(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_%\",\n existingRows,\n );\n\n if (existing.length > 0) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: 0,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object 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({\n loader: doMigrations,\n // An application can share this SQL client and own its own migration history.\n // Keep bookkeeping outside effect_agent_% so interrupted unversioned schemas\n // still fail the ambiguity check above.\n table: \"effect_sql_migrations_agent_threads\",\n }).pipe(\n // SqliteMigrator depends on the generic client supplied by this adapter. The concrete\n // Durable Object client is kept at the outer Layer boundary.\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"initialize current storage\",\n message: error.message,\n }),\n ),\n );\n } else {\n const versionRows = yield* sql<Record<string, unknown>>`\n SELECT value\n FROM effect_agent_meta\n WHERE key = 'storage_version'\n `.pipe(Effect.mapError(storageError(\"read storage version\")));\n\n const version = yield* decodeSingleRow(\n Schema.Array(DoMetaRow),\n \"effect_agent_meta\",\n \"storage_version\",\n versionRows,\n );\n\n if (\n version.value === \"2\" ||\n version.value === \"3\" ||\n version.value === \"4\" ||\n version.value === \"5\"\n ) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key='storage_version'`;\n\n if (current.length === 1 && current[0].value === String(CurrentDoStorageVersion))\n return;\n if (\n current.length !== 1 ||\n (current[0].value !== \"2\" &&\n current[0].value !== \"3\" &&\n current[0].value !== \"4\" &&\n current[0].value !== \"5\")\n )\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: CurrentDoStorageVersion,\n message: \"Storage version changed while acquiring the upgrade transaction.\",\n });\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name IN ${sql.in([...REQUIRED_TABLES])}`,\n );\n\n if (required.length !== REQUIRED_TABLES.length)\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor store is missing required tables. Retain the original store for inspection; 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].value === \"5\" ? 1 : 0))\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\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* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation.\",\n });\n if (current[0].value === \"2\") {\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 }\n if (current[0].value === \"3\") yield* checkPredecessorLayout(3);\n if (current[0].value === \"4\") yield* checkPredecessorLayout(4);\n if (current[0].value === \"5\") yield* checkPredecessorLayout(5);\n if (current[0].value === \"2\" || current[0].value === \"3\") {\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].value !== \"5\") {\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 DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: \"upgrade\",\n message: error.message,\n }),\n ),\n );\n yield* createWorkerStops;\n yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.catchTag(\"DoStorageFailpointError\", (error) =>\n DoStorageError.make({\n cause: error,\n operation: \"upgrade storage\",\n message: error.message,\n }),\n ),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n DoStorageCorruptionError.make({\n table: error.table,\n rowKey: error.rowKey,\n message: error.message,\n }),\n ),\n Effect.catchTag(\"SchemaError\", (error) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: \"upgrade\",\n message: error.message,\n }),\n ),\n Effect.catchTag(\"SqlError\", storageError(\"upgrade supported thread storage\")),\n );\n } else if (version.value === \"6\") {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;\n\n if (current[0]?.value === \"9\") return;\n if (current[0]?.value !== \"6\")\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: 9,\n message: \"Storage version changed during native index upgrade\",\n });\n yield* checkPredecessorLayout(5);\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* DoStorageCompatibilityError.make({\n actualVersion: 6,\n supportedVersion: 9,\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 DoStorageCorruptionError.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* createWorkerStops;\n yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n operation: \"upgrade native indexes\",\n message: error.message,\n cause: error,\n }),\n ),\n );\n } else if (version.value === \"7\") {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;\n\n if (current[0]?.value === \"9\") return;\n if (current[0]?.value !== \"7\")\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: 9,\n message: \"Storage version changed during worker stop upgrade\",\n });\n yield* checkPredecessorLayout(7);\n yield* verifyWorkerPredecessor(false);\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createWorkerStops;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"upgrade worker stop\",\n message: \"Worker stop upgrade failed\",\n cause,\n }),\n ),\n );\n } else if (version.value === \"8\") {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key = 'storage_version'`;\n\n if (current[0]?.value === \"9\") return;\n if (current[0]?.value !== \"8\")\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: 9,\n message: \"Storage version changed during assignment seal upgrade\",\n });\n yield* checkPredecessorLayout(7);\n yield* verifyWorkerPredecessor(true);\n const columns = yield* sql`PRAGMA table_info(effect_agent_worker_stops)`;\n\n yield* Schema.decodeUnknownEffect(\n Schema.Tuple([\n Schema.Struct({\n cid: Schema.Literal(0),\n name: Schema.Literal(\"thread_id\"),\n type: Schema.Literal(\"TEXT\"),\n notnull: Schema.Literal(1),\n dflt_value: Schema.Null,\n pk: Schema.Literal(1),\n }),\n ]),\n )(columns).pipe(\n Effect.mapError(() =>\n DoStorageCompatibilityError.make({\n actualVersion: 8,\n supportedVersion: 9,\n message: \"Unsupported worker seal layout; no upgrade was committed\",\n }),\n ),\n );\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_worker_stops ADD COLUMN terminal TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_meta SET value='9' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"upgrade assignment seals\",\n message: \"Assignment seal upgrade failed\",\n cause,\n }),\n ),\n );\n } else if (version.value !== String(CurrentDoStorageVersion)) {\n const actualVersion = Number.parseInt(version.value, 10);\n\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number.isSafeInteger(actualVersion) ? actualVersion : -1,\n supportedVersion: CurrentDoStorageVersion,\n message:\n `The Durable Object uses unsupported storage version ${version.value}; ` +\n `this build supports exactly version ${CurrentDoStorageVersion}. ` +\n \"Only supported v2, v3, v4, v5, v6, v7 and v8 can be upgraded automatically. Keep the original store and use a compatible library version.\",\n });\n }\n }\n\n yield* verifyWorkerPredecessor(true);\n\n return makeJournal(sql, failpoint, maxStoredValueBytes);\n});\n\nconst makeJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n) => {\n /** Typed pre-write refusal for any single value over the configured byte bound. */\n const checkValueBound = (\n operation: string,\n value: string,\n ): Effect.Effect<void, DoValueBoundExceeded> => {\n const actualBytes = storedTextBytes(value);\n\n return actualBytes > maxStoredValueBytes\n ? Effect.fail(\n DoValueBoundExceeded.make({\n actualBytes,\n maxBytes: maxStoredValueBytes,\n operation,\n }),\n )\n : Effect.void;\n };\n\n /**\n * Runs one journal write transaction on the Durable Object storage-backed\n * `withTransaction` (`ctx.storage.transaction()` under the hood). Within one Durable\n * Object there is exactly ONE writer, so the Node `BEGIN IMMEDIATE` + busy-retry +\n * `SqliteWriteContention` machinery has no analogue here and is deliberately absent.\n * Ownership-token and epoch checks still run INSIDE the transaction, so fencing atomicity\n * (DUR-006) is preserved identically.\n *\n * Journal write transactions are always top level: the Durable Object client rejects\n * nested transactions, so new journal operations must not wrap this helper inside another\n * transaction.\n */\n const withWriteTransaction =\n (operation: string) =>\n <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | DoStorageError> =>\n sql.withTransaction(effect).pipe(\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n );\n\n const materialize = Effect.fn(\"DoJournal.materialize\")(function* (\n threadId: string,\n createdAt: string,\n emptyTailDigest: string,\n producerEpoch: ProducerEpoch,\n ): Effect.fn.Return<\n void,\n DoFenceRejected | DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded\n > {\n if (threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"materialize thread\", emptyTailDigest);\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* DoStorageCorruptionError.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* DoFenceRejected.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(\"DoJournal.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(\"DoJournal.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 request.records.some((record) => record.recordId.length > MAX_IDENTIFIER_LENGTH)\n ) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers exceed the Durable Object storage bounds.\",\n });\n }\n // The platform's ~2 MB per-value limit, enforced typed BEFORE any write (plan §1.2).\n yield* checkValueBound(\"append canonical batch\", request.batchJson);\n yield* checkValueBound(\"append canonical batch\", request.batchDigest);\n yield* checkValueBound(\"append canonical batch\", request.tailDigest);\n yield* Effect.forEach(\n request.records,\n (record) => checkValueBound(\"append canonical record\", record.recordJson),\n { discard: true },\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* DoAppendConflict.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* DoFenceRejected.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* DoStorageCorruptionError.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* DoAppendConflict.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* DoAppendConflict.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* DoStorageError.make({\n operation: \"append canonical batch\",\n message: `Thread record limit ${MAX_RECORDS_PER_THREAD} would be exceeded.`,\n });\n }\n\n // Chunked to respect the Durable Object platform's 100-bound-parameter statement\n // limit: a batch may carry up to 256 records.\n const existingRecords: Array<RecordRow> = [];\n\n for (const chunk of chunked(recordIds, MAX_BOUND_PARAMETERS - 10)) {\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([...chunk])}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"check canonical record identities\")));\n\n existingRecords.push(\n ...(yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/record_ids`,\n existingRecordRows,\n )),\n );\n }\n if (existingRecords.length > 0) {\n return yield* DoAppendConflict.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 DoStorageError.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 DoStorageError.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 DoStorageCorruptionError.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.fnUntraced(function* (request: RawReadRequest) {\n // Capture membership without retaining payloads. Append-only sequences keep each later\n // payload query inside this snapshot, even when new records arrive during consumption.\n const planRows = yield* sql<Record<string, unknown>>`\n SELECT\n sequence,\n length(CAST(record_json AS BLOB)) AS record_json_bytes\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 const plan = yield* decodeRows(\n Schema.Array(ReadPlanRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n planRows,\n \"ReadPlanRow\",\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message: \"Canonical read membership, sequence, or payload size changed from its read plan.\",\n });\n\n if (plan.length > request.limit) return yield* mismatch();\n\n const pages: Array<ReadPage> = [];\n let page: ReadPage | undefined;\n let pageBytes = 0;\n let previousSequence = request.fromSequenceExclusive;\n\n for (const row of plan) {\n if (row.sequence !== previousSequence + 1) return yield* mismatch();\n previousSequence = row.sequence;\n if (page === undefined || pageBytes + row.record_json_bytes > MAX_READ_PAGE_JSON_BYTES) {\n page = [row];\n pages.push(page);\n pageBytes = row.record_json_bytes;\n } else {\n page.push(row);\n pageBytes += row.record_json_bytes;\n }\n }\n\n const readPage = Effect.fn(\"DoJournal.readPage\")(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, batch_id, record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence >= ${page[0].sequence}\n AND sequence <= ${page[page.length - 1].sequence}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const decoded = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/${page[0].sequence}`,\n rows,\n \"RecordRow\",\n );\n\n if (\n decoded.length !== page.length ||\n decoded.some(\n (row, index) =>\n row.thread_id !== request.threadId ||\n row.sequence !== page[index].sequence ||\n storedTextBytes(row.record_json) !== page[index].record_json_bytes,\n )\n ) {\n return yield* mismatch();\n }\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(readPage(page))),\n ),\n };\n });\n\n const exportThread = Effect.fn(\"DoJournal.exportThread\")(function* (threadId: string) {\n return yield* sql\n .withTransaction(\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* DoStorageError.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 plan = yield* read(request);\n const page = yield* Stream.runCollect(plan.records);\n\n if (\n page.length !== limit ||\n page.some((record, index) => record.sequence !== afterSequence + index + 1)\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message:\n \"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* DoStorageCorruptionError.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 .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"export transaction\")(error)),\n ),\n );\n });\n\n const saveCheckpoint = Effect.fn(\"DoJournal.saveCheckpoint\")(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save checkpoint\", checkpoint.checkpointJson);\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* DoCheckpointConflict.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* DoStorageCorruptionError.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* DoCheckpointConflict.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(\"DoJournal.saveRecoveryCheckpoint\")(function* (\n request: SaveRecoveryCheckpointRequest,\n checkpointJson: string,\n ) {\n const { checkpoint } = request;\n\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save recovery checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save recovery checkpoint\", checkpointJson);\n // Keep injected waits outside the storage-backed transaction callback.\n yield* failpoint(\"save-recovery-checkpoint:before\");\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* 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(\"DoJournal.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(\"DoJournal.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(\"DoJournal.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(\"DoJournal.scanStoredPayloads\")(function* () {\n return yield* sql\n .withTransaction(\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 .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"startup scan transaction\")(error)),\n ),\n );\n });\n\n return {\n append,\n checkValueBound,\n exportThread,\n getThread,\n getTailDigestAt,\n loadCheckpoint,\n loadRecoveryCheckpoint,\n saveRecoveryCheckpoint,\n materialize,\n read,\n saveCheckpoint,\n scanStoredPayloads,\n withWriteTransaction,\n } as const;\n};\n\nexport type DoJournal = ReturnType<typeof makeJournal>;\n\nexport const initializeDoJournal = ensureCurrentStorage;\n"],"mappings":"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AAO,oBAAoB,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KACvC,OAAO,UAAU,UACf,yBAAyB,KAAK;CAC5B;CACA;CACA,SAAS;CACT,YAAY,sBAAsB,KAAK;EACrC,UAAU,MAAM;EAChB,WAAW;EACX;EACA,UAAU,MAAM,MAAM;CACxB,CAAC;AACH,CAAC,CACH,GACA,OAAO,UAAU,UACf,OAAO,oBAAoB;CACzB,6BAA6B,MAAM,YAAY;CAC/C,yBAAyB,MAAM,YAAY;CAC3C,2BAA2B;CAC3B,yBAAyB,MAAM,YAAY;AAC7C,CAAC,CACH,CACF,CACJ;;AAGA,MAAa,kBAAkB,OAAO,IAElC,QACA,OACA,QACA,SAEA,WAAW,QAAQ,OAAO,QAAQ,IAAI,CAAC,CAAC,KACtC,OAAO,SAAS,YACd,QAAQ,WAAW,IACf,OAAO,QAAQ,QAAQ,EAAE,IACzB,OAAO,KACL,yBAAyB,KAAK;CAC5B;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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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ import { t as DoStorageConfig_d_exports } from "./DoStorageConfig.mjs";
|
|
|
4
4
|
import { t as DoStorageFailpoint_d_exports } from "./DoStorageFailpoint.mjs";
|
|
5
5
|
import { t as DoMessageDeliveryStore_d_exports } from "./DoMessageDeliveryStore.mjs";
|
|
6
6
|
import { t as DoScheduleStore_d_exports } from "./DoScheduleStore.mjs";
|
|
7
|
-
import { t as DoStorageVersion_d_exports } from "./DoStorageVersion-
|
|
7
|
+
import { t as DoStorageVersion_d_exports } from "./DoStorageVersion-DJwZzqel.mjs";
|
|
8
8
|
import { t as DoThreadStore_d_exports } from "./DoThreadStore.mjs";
|
|
9
9
|
import { t as DoSubmissionLedger_d_exports } from "./DoSubmissionLedger.mjs";
|
|
10
10
|
import { t as DoSubscriptionStore_d_exports } from "./DoSubscriptionStore.mjs";
|
|
@@ -41,7 +41,21 @@ const createRecoveryCheckpointTable = Effect.gen(function* () {
|
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region src/internal/migrations.ts
|
|
43
43
|
/** The current storage version recorded in `effect_agent_meta`. */
|
|
44
|
-
const CurrentDoStorageVersion =
|
|
44
|
+
const CurrentDoStorageVersion = 9;
|
|
45
|
+
/** One permanent destination inbox fence, including workers stopped before admission. */
|
|
46
|
+
const createWorkerStops = Effect.gen(function* () {
|
|
47
|
+
const sql = yield* SqlClient.SqlClient;
|
|
48
|
+
yield* sql`CREATE TABLE effect_agent_worker_stops (thread_id TEXT PRIMARY KEY NOT NULL, terminal TEXT)`;
|
|
49
|
+
yield* sql`CREATE INDEX effect_agent_worker_starts ON effect_agent_message_deliveries(owner_thread_id,
|
|
50
|
+
json_extract(record_json, '$.envelope.workerAdmission.origin.worker.delegationId'),
|
|
51
|
+
json_extract(record_json, '$.envelope.workerAdmission.origin.worker.targetAgentId'), message_id)
|
|
52
|
+
WHERE message_id = json_extract(record_json, '$.envelope.workerAdmission.origin.firstMessageId')`;
|
|
53
|
+
yield* sql`CREATE INDEX effect_agent_worker_pending ON effect_agent_message_deliveries(owner_thread_id,
|
|
54
|
+
json_extract(record_json, '$.envelope.workerAdmission.origin.worker.threadId'), message_id)
|
|
55
|
+
WHERE state IN ('pending', 'parked') AND json_extract(record_json, '$.receipt') IS NULL`;
|
|
56
|
+
yield* sql`CREATE INDEX effect_agent_worker_execution ON effect_agent_canonical_records(thread_id,
|
|
57
|
+
json_extract(record_json, '$.payload._tag'), sequence) WHERE json_extract(record_json, '$.payload.runId') IS NOT NULL`;
|
|
58
|
+
});
|
|
45
59
|
/** Index only outstanding obligations, ordered by the recovery scan's stable cursor. */
|
|
46
60
|
const createNonterminalIndex = Effect.gen(function* () {
|
|
47
61
|
yield* (yield* SqlClient.SqlClient)`CREATE INDEX effect_agent_submissions_nonterminal ON effect_agent_submissions (thread_id, queue_sequence) WHERE state <> 'settled'`.withoutTransform;
|
|
@@ -274,6 +288,7 @@ const doMigrations = SqliteMigrator.fromRecord({ "1_current_cloudflare_thread_ob
|
|
|
274
288
|
yield* createMessageDeliveryTables;
|
|
275
289
|
yield* createMessageDeliveryPendingIndex;
|
|
276
290
|
yield* createRecoveryCheckpointTable;
|
|
291
|
+
yield* createWorkerStops;
|
|
277
292
|
yield* sql`
|
|
278
293
|
CREATE TABLE effect_agent_meta (
|
|
279
294
|
key TEXT PRIMARY KEY NOT NULL,
|
|
@@ -282,10 +297,10 @@ const doMigrations = SqliteMigrator.fromRecord({ "1_current_cloudflare_thread_ob
|
|
|
282
297
|
`.withoutTransform;
|
|
283
298
|
yield* sql`
|
|
284
299
|
INSERT INTO effect_agent_meta (key, value)
|
|
285
|
-
VALUES ('storage_version', ${String(
|
|
300
|
+
VALUES ('storage_version', ${String(9)})
|
|
286
301
|
`.withoutTransform;
|
|
287
302
|
}) });
|
|
288
303
|
//#endregion
|
|
289
|
-
export {
|
|
304
|
+
export { createRecoveryCheckpointTable as a, doMigrations as i, createNonterminalIndex as n, createMessageDeliveryTables as o, createWorkerStops as r, CurrentDoStorageVersion as t };
|
|
290
305
|
|
|
291
|
-
//# sourceMappingURL=migrations-
|
|
306
|
+
//# sourceMappingURL=migrations-Br6QqMIf.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations-Br6QqMIf.mjs","names":[],"sources":["../src/internal/message-delivery-schema.ts","../src/internal/recovery-checkpoint-schema.ts","../src/internal/migrations.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\n\n/** Additive storage owned by this adapter; creation participates in its version transaction. */\nexport const createMessageDeliveryTables = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`\n CREATE TABLE effect_agent_message_deliveries (\n owner_thread_id TEXT NOT NULL,\n message_id TEXT NOT NULL,\n version INTEGER NOT NULL,\n state TEXT NOT NULL,\n deadline_at_millis INTEGER,\n record_json TEXT NOT NULL,\n PRIMARY KEY (owner_thread_id, message_id)\n )\n `.withoutTransform;\n yield* sql`\n CREATE INDEX effect_agent_message_deliveries_due\n ON effect_agent_message_deliveries (deadline_at_millis, owner_thread_id, message_id)\n WHERE deadline_at_millis IS NOT NULL\n `.withoutTransform;\n});\n","import { Effect } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\n\n/** One disposable recovery snapshot per Thread, independent of generic projections. */\nexport const createRecoveryCheckpointTable = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`\n CREATE TABLE effect_agent_recovery_checkpoints (\n thread_id TEXT PRIMARY KEY NOT NULL,\n through_sequence INTEGER NOT NULL,\n tail_digest TEXT NOT NULL,\n checkpoint_json TEXT NOT NULL,\n FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT\n )\n `.withoutTransform;\n});\n","import { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect } from \"effect\";\nimport { createMessageDeliveryPendingIndex } from \"effect-agent/sql-message-delivery-store\";\nimport { createNativeReadIndexes } from \"effect-agent/sql-thread-native-reads\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\n\nimport { createMessageDeliveryTables } from \"./message-delivery-schema.ts\";\nimport { createRecoveryCheckpointTable } from \"./recovery-checkpoint-schema.ts\";\n\n/** The current storage version recorded in `effect_agent_meta`. */\nexport const CurrentDoStorageVersion = 9;\n\n/** One permanent destination inbox fence, including workers stopped before admission. */\nexport const createWorkerStops = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`CREATE TABLE effect_agent_worker_stops (thread_id TEXT PRIMARY KEY NOT NULL, terminal TEXT)`;\n yield* sql`CREATE INDEX effect_agent_worker_starts ON effect_agent_message_deliveries(owner_thread_id,\n json_extract(record_json, '$.envelope.workerAdmission.origin.worker.delegationId'),\n json_extract(record_json, '$.envelope.workerAdmission.origin.worker.targetAgentId'), message_id)\n WHERE message_id = json_extract(record_json, '$.envelope.workerAdmission.origin.firstMessageId')`;\n yield* sql`CREATE INDEX effect_agent_worker_pending ON effect_agent_message_deliveries(owner_thread_id,\n json_extract(record_json, '$.envelope.workerAdmission.origin.worker.threadId'), message_id)\n WHERE state IN ('pending', 'parked') AND json_extract(record_json, '$.receipt') IS NULL`;\n yield* sql`CREATE INDEX effect_agent_worker_execution ON effect_agent_canonical_records(thread_id,\n json_extract(record_json, '$.payload._tag'), sequence) WHERE json_extract(record_json, '$.payload.runId') IS NOT NULL`;\n});\n\n/** Index only outstanding obligations, ordered by the recovery scan's stable cursor. */\nexport const createNonterminalIndex = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`CREATE INDEX effect_agent_submissions_nonterminal ON effect_agent_submissions (thread_id, queue_sequence) WHERE state <> 'settled'`\n .withoutTransform;\n});\n\n/**\n * The Thread Durable Object schema shares its thread and ledger tables with Node/SQLite.\n * Schedules and subscriptions use separate Durable Objects. Two DC-specific additions:\n *\n * 1. `effect_agent_meta` replaces `PRAGMA user_version` as the exact-or-fresh version gate —\n * a meta table is portable regardless of which PRAGMAs Durable Object SQL storage allows.\n * 2. `effect_agent_child_settlements` is the durable cross-store notification marker the\n * SubmissionLedger port contract mandates for cross-store adapters (`suspend`'s covering\n * check and `recordChildSettled`'s wake both consult it): parent and child Threads\n * live in different Durable Objects, so a child settlement reported before the parent's\n * suspend commits must be observable from the PARENT's own storage.\n */\nexport const doMigrations = SqliteMigrator.fromRecord({\n \"1_current_cloudflare_thread_object\": Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`\n CREATE TABLE effect_agent_threads (\n thread_id TEXT PRIMARY KEY NOT NULL,\n created_at TEXT NOT NULL,\n tail_sequence INTEGER NOT NULL,\n tail_digest TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_canonical_batches (\n thread_id TEXT NOT NULL,\n batch_id TEXT NOT NULL,\n first_sequence INTEGER NOT NULL,\n last_sequence INTEGER NOT NULL,\n batch_digest TEXT NOT NULL,\n tail_digest TEXT NOT NULL,\n batch_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, batch_id),\n FOREIGN KEY (thread_id)\n REFERENCES effect_agent_threads(thread_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_canonical_records (\n thread_id TEXT NOT NULL,\n sequence INTEGER NOT NULL,\n record_id TEXT NOT NULL,\n batch_id TEXT NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, sequence),\n UNIQUE (thread_id, record_id),\n FOREIGN KEY (thread_id, batch_id)\n REFERENCES effect_agent_canonical_batches(thread_id, batch_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_canonical_records_batch\n ON effect_agent_canonical_records (thread_id, batch_id, sequence)\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_checkpoints (\n thread_id TEXT NOT NULL,\n through_sequence INTEGER NOT NULL,\n tail_digest TEXT NOT NULL,\n checkpoint_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, through_sequence),\n FOREIGN KEY (thread_id)\n REFERENCES effect_agent_threads(thread_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n // Admission rows exist before Thread materialization (durability §4), so\n // thread_id intentionally carries no foreign key into effect_agent_threads.\n yield* sql`\n CREATE TABLE effect_agent_submissions (\n submission_id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL,\n queue_sequence INTEGER NOT NULL,\n principal TEXT NOT NULL,\n idempotency_key TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n agent_digests_json TEXT NOT NULL,\n deployment_id TEXT NOT NULL,\n input_json TEXT NOT NULL,\n input_digest TEXT NOT NULL,\n receipt_id TEXT NOT NULL,\n state TEXT NOT NULL,\n settled_outcome TEXT,\n created_at TEXT NOT NULL,\n ready_at TEXT,\n input_applied_record_id TEXT,\n input_applied_sequence INTEGER,\n joined_host_submission_id TEXT,\n suspended_reason_json TEXT,\n suspended_at TEXT,\n unknown_reason TEXT,\n unknown_tool_call_ids_json TEXT,\n parent_submission_id TEXT,\n parent_tool_call_id TEXT,\n admission_group TEXT,\n admission_fence_json TEXT,\n worker_admission_json TEXT,\n message_admission_json TEXT,\n UNIQUE (thread_id, principal, idempotency_key),\n UNIQUE (thread_id, queue_sequence)\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_submissions_joined_host\n ON effect_agent_submissions (joined_host_submission_id)\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_submissions_parent\n ON effect_agent_submissions (parent_submission_id)\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_submissions_group\n ON effect_agent_submissions (thread_id, admission_group, state)\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_submission_ownership (\n submission_id TEXT PRIMARY KEY NOT NULL,\n attempt_id TEXT NOT NULL,\n ownership_token TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL,\n owner_producer_id TEXT NOT NULL,\n lease_expires_at TEXT NOT NULL,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_attempts (\n attempt_id TEXT PRIMARY KEY NOT NULL,\n submission_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n owner_producer_id TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL,\n claimed_at TEXT NOT NULL,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_settlement_reservations (\n submission_id TEXT PRIMARY KEY NOT NULL,\n settlement_id TEXT NOT NULL,\n outcome TEXT NOT NULL,\n record_id TEXT NOT NULL,\n record_json TEXT NOT NULL,\n record_digest TEXT NOT NULL,\n reserved_at TEXT NOT NULL,\n finalized_at TEXT,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_abort_intents (\n submission_id TEXT PRIMARY KEY NOT NULL,\n author TEXT NOT NULL,\n reason TEXT NOT NULL,\n requested_at TEXT NOT NULL,\n canonical_record_id TEXT,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_approval_decisions (\n submission_id TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n decision TEXT NOT NULL,\n resolver TEXT NOT NULL,\n reason TEXT NOT NULL,\n decided_at TEXT NOT NULL,\n PRIMARY KEY (submission_id, tool_call_id),\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_unknown_resolutions (\n submission_id TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n author TEXT NOT NULL,\n reason TEXT NOT NULL,\n resolution_json TEXT NOT NULL,\n resolved_at TEXT NOT NULL,\n PRIMARY KEY (submission_id, tool_call_id),\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_child_reservations (\n reservation_id TEXT PRIMARY KEY NOT NULL,\n parent_submission_id TEXT NOT NULL,\n parent_tool_call_id TEXT NOT NULL,\n child_submission_id TEXT,\n status TEXT NOT NULL,\n allocation_json TEXT NOT NULL,\n allocation_digest TEXT NOT NULL,\n accounting_json TEXT,\n reserved_at TEXT NOT NULL,\n release_began_at TEXT,\n released_at TEXT,\n UNIQUE (parent_submission_id, parent_tool_call_id),\n FOREIGN KEY (parent_submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n // Durable cross-store child-settlement notification marker (parent-side; the child's row\n // lives in ANOTHER Durable Object). child_outcome is nullable: the notification command\n // carries identities only, and the child's canonical Settlement stays the outcome\n // authority (DUR-015). No foreign keys: the parent row is checked by the operation, and\n // the child row is intentionally foreign.\n yield* sql`\n CREATE TABLE effect_agent_child_settlements (\n parent_submission_id TEXT NOT NULL,\n child_submission_id TEXT NOT NULL,\n child_outcome TEXT,\n recorded_at TEXT NOT NULL,\n PRIMARY KEY (parent_submission_id, child_submission_id)\n )\n `.withoutTransform;\n\n yield* createNativeReadIndexes;\n yield* createNonterminalIndex;\n yield* createMessageDeliveryTables;\n yield* createMessageDeliveryPendingIndex;\n yield* createRecoveryCheckpointTable;\n yield* createWorkerStops;\n yield* sql`\n CREATE TABLE effect_agent_meta (\n key TEXT PRIMARY KEY NOT NULL,\n value TEXT NOT NULL\n )\n `.withoutTransform;\n\n yield* sql`\n INSERT INTO effect_agent_meta (key, value)\n VALUES ('storage_version', ${String(CurrentDoStorageVersion)})\n `.withoutTransform;\n }),\n});\n"],"mappings":";;;;;;;AAIA,MAAa,8BAA8B,OAAO,IAAI,aAAa;CACjE,MAAM,MAAM,OAAO,UAAU;CAE7B,OAAO,GAAG;;;;;;;;;;IAUR;CACF,OAAO,GAAG;;;;IAIR;AACJ,CAAC;;;;ACnBD,MAAa,gCAAgC,OAAO,IAAI,aAAa;CAGnE,OAAO,CAAA,OAFY,UAAU,UAAA,AAEnB;;;;;;;;IAQR;AACJ,CAAC;;;;ACND,MAAa,0BAA0B;;AAGvC,MAAa,oBAAoB,OAAO,IAAI,aAAa;CACvD,MAAM,MAAM,OAAO,UAAU;CAE7B,OAAO,GAAG;CACV,OAAO,GAAG;;;;CAIV,OAAO,GAAG;;;CAGV,OAAO,GAAG;;AAEZ,CAAC;;AAGD,MAAa,yBAAyB,OAAO,IAAI,aAAa;CAG5D,OAAO,CAAA,OAFY,UAAU,UAAA,AAEnB,qIACP;AACL,CAAC;;;;;;;;;;;;;AAcD,MAAa,eAAe,eAAe,WAAW,EACpD,sCAAsC,OAAO,IAAI,aAAa;CAC5D,MAAM,MAAM,OAAO,UAAU;CAE7B,OAAO,GAAG;;;;;;;;MAQR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;MAcR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;;;;;;;;;MAWR;CAIF,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiCR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;;;;;;;;;;MAYR;CAEF,OAAO,GAAG;;;;;;;;;;;;MAYR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;MAcR;CAEF,OAAO,GAAG;;;;;;;;;;;MAWR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;;;;;MAkBR;CAOF,OAAO,GAAG;;;;;;;;MAQR;CAEF,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO,GAAG;;;;;MAKR;CAEF,OAAO,GAAG;;mCAEqB,OAAA,CAA8B,EAAE;MAC7D;AACJ,CAAC,EACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.
|
|
1
|
+
{"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.115","dependencies":{"@effect/platform-browser":"4.0.0-rc.116","@effect/sql-sqlite-do":"4.0.0-rc.116","effect-agent":"0.1.0-beta.115"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.115","@effect/vitest":"4.0.0-rc.116","effect":"4.0.0-rc.116","typescript":"7.0.2","vite-plus":"0.3.2","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.116"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./do-memory-store":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./do-schedule-store":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./do-storage-config":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./do-storage-error":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./do-storage-failpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./do-storage-version":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./do-submission-ledger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./do-subscription-store":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./do-thread-store":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./memory-protocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./port-protocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./port-routing":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/do-storage-failpoint-testing":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./do-message-delivery-store":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
|