@effect-agent/storage-cloudflare 0.1.0-beta.79 → 0.1.0-beta.80
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/DoSubmissionLedger.mjs +1 -1
- package/dist/DoThreadStore.mjs +1 -1
- package/dist/PortProtocol.d.mts +41 -41
- package/dist/PortRouting.d.mts +4 -4
- package/dist/PortRouting.mjs +19 -20
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-DnzUmhPA.mjs → do-journal-DHqCQeBU.mjs} +5 -2
- package/dist/do-journal-DHqCQeBU.mjs.map +1 -0
- package/package.json +1 -1
- package/src/PortRouting.ts +24 -24
- package/src/internal/do-journal.ts +7 -1
- package/dist/do-journal-DnzUmhPA.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
|
-
import { a as initializeDoJournal } from "./do-journal-
|
|
4
|
+
import { a as initializeDoJournal } from "./do-journal-DHqCQeBU.mjs";
|
|
5
5
|
import { MessageDeliveryError, MessageDeliveryStore } from "@effect-agent/thread/MessageDelivery";
|
|
6
6
|
import { SqlMessageDeliveryTransaction, makeSqlMessageDeliveryStore } from "@effect-agent/thread/SqlMessageDeliveryStore";
|
|
7
7
|
import { Effect, Layer } from "effect";
|
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { DoLedgerError, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
|
|
5
|
-
import { a as initializeDoJournal, i as decodeRows } from "./do-journal-
|
|
5
|
+
import { a as initializeDoJournal, i as decodeRows } from "./do-journal-DHqCQeBU.mjs";
|
|
6
6
|
import { storageConfigLayer, storageFailpointLayer } from "./DoThreadStore.mjs";
|
|
7
7
|
import { Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
8
8
|
import * as SqlClientService from "effect/unstable/sql/SqlClient";
|
package/dist/DoThreadStore.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { DoStorageConfig, DoStorageConfigValue } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
|
|
5
|
-
import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-
|
|
5
|
+
import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-DHqCQeBU.mjs";
|
|
6
6
|
import { Clock, Context, Crypto, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
|
|
7
7
|
import * as SqlClientService from "effect/unstable/sql/SqlClient";
|
|
8
8
|
import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@effect-agent/thread/Digest";
|
package/dist/PortProtocol.d.mts
CHANGED
|
@@ -350,6 +350,11 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
|
|
|
350
350
|
readonly createdAt: string;
|
|
351
351
|
readonly deploymentId: string;
|
|
352
352
|
readonly payload: {
|
|
353
|
+
readonly _tag: "AbortRequested";
|
|
354
|
+
readonly submissionId: string;
|
|
355
|
+
readonly author: string;
|
|
356
|
+
readonly reason: string;
|
|
357
|
+
} | {
|
|
353
358
|
readonly _tag: "ThreadCreated";
|
|
354
359
|
readonly agentId: string;
|
|
355
360
|
readonly definitions: {
|
|
@@ -524,11 +529,6 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
|
|
|
524
529
|
readonly runDisposition?: Schema.Json | undefined;
|
|
525
530
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
526
531
|
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
527
|
-
} | {
|
|
528
|
-
readonly _tag: "AbortRequested";
|
|
529
|
-
readonly submissionId: string;
|
|
530
|
-
readonly author: string;
|
|
531
|
-
readonly reason: string;
|
|
532
532
|
} | {
|
|
533
533
|
readonly _tag: "SubmissionSettled";
|
|
534
534
|
readonly submissionId: string;
|
|
@@ -963,6 +963,11 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
|
|
|
963
963
|
readonly createdAt: string;
|
|
964
964
|
readonly deploymentId: string;
|
|
965
965
|
readonly payload: {
|
|
966
|
+
readonly _tag: "AbortRequested";
|
|
967
|
+
readonly submissionId: string;
|
|
968
|
+
readonly author: string;
|
|
969
|
+
readonly reason: string;
|
|
970
|
+
} | {
|
|
966
971
|
readonly _tag: "ThreadCreated";
|
|
967
972
|
readonly agentId: string;
|
|
968
973
|
readonly definitions: {
|
|
@@ -1137,11 +1142,6 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
|
|
|
1137
1142
|
readonly runDisposition?: Schema.Json | undefined;
|
|
1138
1143
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
1139
1144
|
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
1140
|
-
} | {
|
|
1141
|
-
readonly _tag: "AbortRequested";
|
|
1142
|
-
readonly submissionId: string;
|
|
1143
|
-
readonly author: string;
|
|
1144
|
-
readonly reason: string;
|
|
1145
1145
|
} | {
|
|
1146
1146
|
readonly _tag: "SubmissionSettled";
|
|
1147
1147
|
readonly submissionId: string;
|
|
@@ -1905,6 +1905,11 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
1905
1905
|
readonly createdAt: string;
|
|
1906
1906
|
readonly deploymentId: string;
|
|
1907
1907
|
readonly payload: {
|
|
1908
|
+
readonly _tag: "AbortRequested";
|
|
1909
|
+
readonly submissionId: string;
|
|
1910
|
+
readonly author: string;
|
|
1911
|
+
readonly reason: string;
|
|
1912
|
+
} | {
|
|
1908
1913
|
readonly _tag: "ThreadCreated";
|
|
1909
1914
|
readonly agentId: string;
|
|
1910
1915
|
readonly definitions: {
|
|
@@ -2079,11 +2084,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
2079
2084
|
readonly runDisposition?: Schema.Json | undefined;
|
|
2080
2085
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
2081
2086
|
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
2082
|
-
} | {
|
|
2083
|
-
readonly _tag: "AbortRequested";
|
|
2084
|
-
readonly submissionId: string;
|
|
2085
|
-
readonly author: string;
|
|
2086
|
-
readonly reason: string;
|
|
2087
2087
|
} | {
|
|
2088
2088
|
readonly _tag: "SubmissionSettled";
|
|
2089
2089
|
readonly submissionId: string;
|
|
@@ -2540,6 +2540,11 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
2540
2540
|
readonly createdAt: string;
|
|
2541
2541
|
readonly deploymentId: string;
|
|
2542
2542
|
readonly payload: {
|
|
2543
|
+
readonly _tag: "AbortRequested";
|
|
2544
|
+
readonly submissionId: string;
|
|
2545
|
+
readonly author: string;
|
|
2546
|
+
readonly reason: string;
|
|
2547
|
+
} | {
|
|
2543
2548
|
readonly _tag: "ThreadCreated";
|
|
2544
2549
|
readonly agentId: string;
|
|
2545
2550
|
readonly definitions: {
|
|
@@ -2714,11 +2719,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
2714
2719
|
readonly runDisposition?: Schema.Json | undefined;
|
|
2715
2720
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
2716
2721
|
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
2717
|
-
} | {
|
|
2718
|
-
readonly _tag: "AbortRequested";
|
|
2719
|
-
readonly submissionId: string;
|
|
2720
|
-
readonly author: string;
|
|
2721
|
-
readonly reason: string;
|
|
2722
2722
|
} | {
|
|
2723
2723
|
readonly _tag: "SubmissionSettled";
|
|
2724
2724
|
readonly submissionId: string;
|
|
@@ -3153,25 +3153,8 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
3153
3153
|
} | {
|
|
3154
3154
|
readonly _tag: "PortFailed";
|
|
3155
3155
|
readonly failure: {
|
|
3156
|
-
readonly _tag: "
|
|
3157
|
-
readonly threadId: string;
|
|
3158
|
-
readonly actualEpoch: number;
|
|
3159
|
-
readonly attemptedEpoch: number;
|
|
3160
|
-
} | {
|
|
3161
|
-
readonly _tag: "ThreadStoreError";
|
|
3162
|
-
readonly operation: string;
|
|
3156
|
+
readonly _tag: "PortProtocolError";
|
|
3163
3157
|
readonly message: string;
|
|
3164
|
-
readonly cause?: Schema.Json | undefined;
|
|
3165
|
-
} | {
|
|
3166
|
-
readonly _tag: "ThreadNotMaterialized";
|
|
3167
|
-
readonly threadId: string;
|
|
3168
|
-
} | {
|
|
3169
|
-
readonly _tag: "AppendConflict";
|
|
3170
|
-
readonly threadId: string;
|
|
3171
|
-
readonly batchId: string;
|
|
3172
|
-
readonly reason: "batch-digest" | "record-identity" | "tail";
|
|
3173
|
-
readonly actualTailSequence?: number | undefined;
|
|
3174
|
-
readonly actualTailDigest?: string | undefined;
|
|
3175
3158
|
} | {
|
|
3176
3159
|
readonly _tag: "AdmissionConflict";
|
|
3177
3160
|
readonly threadId: string;
|
|
@@ -3188,17 +3171,34 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
|
|
|
3188
3171
|
readonly operation: string;
|
|
3189
3172
|
readonly message: string;
|
|
3190
3173
|
readonly cause?: Schema.Json | undefined;
|
|
3191
|
-
} | {
|
|
3192
|
-
readonly _tag: "PortProtocolError";
|
|
3193
|
-
readonly message: string;
|
|
3194
3174
|
} | {
|
|
3195
3175
|
readonly _tag: "SettlementConflict";
|
|
3196
3176
|
readonly submissionId: string;
|
|
3197
3177
|
readonly existingOutcome: "aborted" | "completed" | "failed";
|
|
3178
|
+
} | {
|
|
3179
|
+
readonly _tag: "ThreadNotMaterialized";
|
|
3180
|
+
readonly threadId: string;
|
|
3181
|
+
} | {
|
|
3182
|
+
readonly _tag: "FenceRejected";
|
|
3183
|
+
readonly threadId: string;
|
|
3184
|
+
readonly actualEpoch: number;
|
|
3185
|
+
readonly attemptedEpoch: number;
|
|
3198
3186
|
} | {
|
|
3199
3187
|
readonly _tag: "JoinedToHost";
|
|
3200
3188
|
readonly submissionId: string;
|
|
3201
3189
|
readonly hostSubmissionId: string;
|
|
3190
|
+
} | {
|
|
3191
|
+
readonly _tag: "ThreadStoreError";
|
|
3192
|
+
readonly operation: string;
|
|
3193
|
+
readonly message: string;
|
|
3194
|
+
readonly cause?: Schema.Json | undefined;
|
|
3195
|
+
} | {
|
|
3196
|
+
readonly _tag: "AppendConflict";
|
|
3197
|
+
readonly threadId: string;
|
|
3198
|
+
readonly batchId: string;
|
|
3199
|
+
readonly reason: "batch-digest" | "record-identity" | "tail";
|
|
3200
|
+
readonly actualTailSequence?: number | undefined;
|
|
3201
|
+
readonly actualTailDigest?: string | undefined;
|
|
3202
3202
|
};
|
|
3203
3203
|
}, Schema.SchemaError, never>;
|
|
3204
3204
|
declare const decodePortResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<PortFailed | PortSucceeded, Schema.SchemaError, never>;
|
package/dist/PortRouting.d.mts
CHANGED
|
@@ -40,11 +40,11 @@ declare class ThreadPortTransport extends ThreadPortTransport_base {}
|
|
|
40
40
|
/** Construction options shared by both routed port Layers. */
|
|
41
41
|
interface RoutedPortOptions {
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
43
|
+
* Decide whether this physical owner stores the addressed logical Thread. Local
|
|
44
|
+
* requests use the same SQLite facets; foreign requests use the transport or fail
|
|
45
|
+
* fast typed. The predicate determines placement, never caller authorization.
|
|
46
46
|
*/
|
|
47
|
-
readonly
|
|
47
|
+
readonly ownsThread: (threadId: ThreadId) => boolean;
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing
|
package/dist/PortRouting.mjs
CHANGED
|
@@ -85,7 +85,7 @@ const LOCAL = { _tag: "local" };
|
|
|
85
85
|
* Identities beyond the ledger's 1,024-character row bound fail typed: the minting side
|
|
86
86
|
* refused them at admission, so they cannot name any stored row anywhere.
|
|
87
87
|
*/
|
|
88
|
-
const routableSubmissionTarget = (
|
|
88
|
+
const routableSubmissionTarget = (ownsThread) => Effect.fn("DoPortRouting.routableSubmissionTarget")(function* (operation, submissionId) {
|
|
89
89
|
if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) return yield* LedgerError.make({
|
|
90
90
|
operation,
|
|
91
91
|
message: `A Submission identity of ${submissionId.length} characters exceeds the ${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission refuses such identities, so it cannot name any stored row.`
|
|
@@ -94,11 +94,10 @@ const routableSubmissionTarget = (localThreadId) => Effect.fn("DoPortRouting.rou
|
|
|
94
94
|
if (separator === -1) return LOCAL;
|
|
95
95
|
if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;
|
|
96
96
|
const tail = submissionId.slice(separator + 1);
|
|
97
|
-
|
|
98
|
-
return yield* decodeThreadId(tail).pipe(Effect.map((threadId) => ({
|
|
97
|
+
return yield* decodeThreadId(tail).pipe(Effect.map((threadId) => ownsThread(threadId) ? LOCAL : {
|
|
99
98
|
_tag: "foreign",
|
|
100
99
|
threadId
|
|
101
|
-
})
|
|
100
|
+
}), Effect.orElseSucceed(() => LOCAL));
|
|
102
101
|
});
|
|
103
102
|
const NoAdditionalPortFailure = Schema.Never;
|
|
104
103
|
const AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);
|
|
@@ -128,7 +127,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
128
127
|
const local = yield* SubmissionLedger;
|
|
129
128
|
const transport = yield* ThreadPortTransport;
|
|
130
129
|
const transportCall = makeTransportCall(transport);
|
|
131
|
-
const submissionTarget = routableSubmissionTarget(options.
|
|
130
|
+
const submissionTarget = routableSubmissionTarget(options.ownsThread);
|
|
132
131
|
const routeFailure = (operation, target) => (error) => LedgerError.make({
|
|
133
132
|
operation,
|
|
134
133
|
message: boundPortDiagnostic(`Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`),
|
|
@@ -225,14 +224,14 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
225
224
|
});
|
|
226
225
|
const routed = SubmissionLedger.of({
|
|
227
226
|
capabilities: local.capabilities,
|
|
228
|
-
admit: (request) => request.threadId
|
|
227
|
+
admit: (request) => options.ownsThread(request.threadId) ? local.admit(request) : foreignLedgerCall("ledger admit", request.threadId, LedgerAdmitCall.make({ request }), LedgerAdmitResult, Schema.Union([AdmissionConflict, AdmissionPolicyError])).pipe(Effect.map((reply) => reply.result)),
|
|
229
228
|
markReady: (request) => submissionTarget("ledger mark ready", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.markReady(request) : foreignLedgerCall("ledger mark ready", target.threadId, LedgerMarkReadyCall.make({ request }), LedgerMarkReadyResult, NoAdditionalPortFailure).pipe(Effect.asVoid))),
|
|
230
|
-
lookup: (request) => request._tag === "SubmissionLookupById" ? submissionTarget("ledger lookup", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.lookup(request) : foreignLookupById("ledger lookup", target.threadId, request.submissionId))) : request.threadId
|
|
231
|
-
resolveAdmission: (request) => request.threadId
|
|
229
|
+
lookup: (request) => request._tag === "SubmissionLookupById" ? submissionTarget("ledger lookup", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.lookup(request) : foreignLookupById("ledger lookup", target.threadId, request.submissionId))) : options.ownsThread(request.threadId) ? local.lookup(request) : foreignLedgerCall("ledger lookup", request.threadId, LedgerLookupCall.make({ request }), LedgerLookupResult, NoAdditionalPortFailure).pipe(Effect.map((result) => result.submission === void 0 ? Option.none() : Option.some(result.submission))),
|
|
230
|
+
resolveAdmission: (request) => options.ownsThread(request.threadId) ? local.resolveAdmission(request) : resolveForeignAdmission(request.threadId, request),
|
|
232
231
|
requestAbort: (request) => submissionTarget("ledger request abort", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.requestAbort(request) : foreignLedgerCall("ledger request abort", target.threadId, LedgerRequestAbortCall.make({ request }), LedgerRequestAbortResult, AbortPortFailure).pipe(Effect.map((reply) => reply.intent)))),
|
|
233
232
|
recordChildSettled: (request) => submissionTarget("ledger record child settled", request.parentSubmissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.recordChildSettled(request) : foreignLedgerCall("ledger record child settled", target.threadId, LedgerRecordChildSettledCall.make({ request }), LedgerRecordChildSettledResult, NoAdditionalPortFailure).pipe(Effect.map((reply) => reply.outcome)))),
|
|
234
|
-
claim: (request) => request.threadId
|
|
235
|
-
claimJoining: (request) => request.threadId
|
|
233
|
+
claim: (request) => options.ownsThread(request.threadId) ? local.claim(request) : Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
|
|
234
|
+
claimJoining: (request) => options.ownsThread(request.threadId) ? local.claimJoining(request) : Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
|
|
236
235
|
renewOwnership: (request) => submissionTarget("ledger renew ownership", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.renewOwnership(request) : Effect.fail(crossThreadLedgerError("ledger renew ownership", target.threadId)))),
|
|
237
236
|
releaseOwnership: (request) => submissionTarget("ledger release ownership", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.releaseOwnership(request) : Effect.fail(crossThreadLedgerError("ledger release ownership", target.threadId)))),
|
|
238
237
|
markInputApplied: (request) => submissionTarget("ledger mark input applied", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.markInputApplied(request) : Effect.fail(crossThreadLedgerError("ledger mark input applied", target.threadId)))),
|
|
@@ -292,19 +291,19 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
292
291
|
} }));
|
|
293
292
|
};
|
|
294
293
|
const routed = ThreadStore.of({
|
|
295
|
-
materialize: (request) => request.threadId
|
|
296
|
-
append: (request) => request.threadId
|
|
297
|
-
read: (request) => request.threadId
|
|
298
|
-
inspectTail: (request) => request.threadId
|
|
299
|
-
export: (request) => request.threadId
|
|
300
|
-
observe: (request) => request.threadId
|
|
294
|
+
materialize: (request) => options.ownsThread(request.threadId) ? local.materialize(request) : foreignStoreCall("thread materialize", request.threadId, StoreMaterializeCall.make({ request }), StoreMaterializeResult, FenceRejected).pipe(Effect.asVoid),
|
|
295
|
+
append: (request) => options.ownsThread(request.threadId) ? local.append(request) : foreignStoreCall("thread append", request.threadId, StoreAppendCall.make({ request }), StoreAppendResult, AppendPortFailure).pipe(Effect.map((reply) => reply.result)),
|
|
296
|
+
read: (request) => options.ownsThread(request.threadId) ? local.read(request) : Stream.unwrap(foreignStoreCall("thread read", request.threadId, StoreReadPageCall.make({ request }), StoreReadPageResult, ThreadNotMaterialized).pipe(Effect.map((reply) => Stream.fromIterable(reply.records)))),
|
|
297
|
+
inspectTail: (request) => options.ownsThread(request.threadId) ? local.inspectTail(request) : foreignStoreCall("thread inspect tail", request.threadId, StoreInspectTailCall.make({ request }), StoreInspectTailResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.tail)),
|
|
298
|
+
export: (request) => options.ownsThread(request.threadId) ? local.export(request) : foreignStoreCall("thread export", request.threadId, StoreExportCall.make({ request }), StoreExportResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.export)),
|
|
299
|
+
observe: (request) => options.ownsThread(request.threadId) ? local.observe(request) : Stream.unwrap(Effect.fail(crossThreadStoreError("thread observe", request.threadId))),
|
|
301
300
|
...recoveryCheckpoints === void 0 ? {} : { recoveryCheckpoints: {
|
|
302
|
-
save: (request) => request.checkpoint.threadId
|
|
303
|
-
load: (request) => request.threadId
|
|
301
|
+
save: (request) => options.ownsThread(request.checkpoint.threadId) ? recoveryCheckpoints.save(request) : Effect.fail(crossThreadStoreError("thread save recovery checkpoint", request.checkpoint.threadId)),
|
|
302
|
+
load: (request) => options.ownsThread(request.threadId) ? recoveryCheckpoints.load(request) : Effect.succeed(Option.none())
|
|
304
303
|
} },
|
|
305
304
|
...checkpoints === void 0 ? {} : { checkpoints: {
|
|
306
|
-
save: (request) => request.checkpoint.threadId
|
|
307
|
-
load: (request) => request.threadId
|
|
305
|
+
save: (request) => options.ownsThread(request.checkpoint.threadId) ? checkpoints.save(request) : Effect.fail(crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId)),
|
|
306
|
+
load: (request) => options.ownsThread(request.threadId) ? checkpoints.load(request) : Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId))
|
|
308
307
|
} }
|
|
309
308
|
});
|
|
310
309
|
return Context.make(ThreadStore, routed);
|
package/dist/PortRouting.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n AdmissionPolicyError,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * The Thread this Durable Object owns (the Object identity rule is\n * `namespace.idFromName(threadId)`). Requests addressed here execute on the local\n * facet; requests addressed anywhere else route through the transport or fail fast typed.\n */\n readonly localThreadId: ThreadId;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n localThreadId: ThreadId,\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n if (tail === localThreadId) return LOCAL;\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget => ({ _tag: \"foreign\", threadId })),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.localThreadId);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n request.threadId === options.localThreadId\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n Schema.Union([AdmissionConflict, AdmissionPolicyError]),\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : request.threadId === options.localThreadId\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n request.threadId === options.localThreadId\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n request.threadId === options.localThreadId\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n request.threadId === options.localThreadId\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n readAbortIntent: (request) =>\n submissionTarget(\"ledger read abort intent\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.readAbortIntent(request)\n : Effect.fail(crossThreadLedgerError(\"ledger read abort intent\", target.threadId)),\n ),\n ),\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const recoveryCheckpoints = local.recoveryCheckpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n request.threadId === options.localThreadId\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n request.threadId === options.localThreadId\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n request.threadId === options.localThreadId\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n request.threadId === options.localThreadId\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n request.threadId === options.localThreadId\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local: the closed route-capable store subset\n // is materialize/append/read/inspectTail/export. Recovery cache misses can fall back\n // to those canonical reads, including when the cache belongs to a foreign Object.\n observe: (request) =>\n request.threadId === options.localThreadId\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(recoveryCheckpoints === undefined\n ? {}\n : {\n recoveryCheckpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? recoveryCheckpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\n \"thread save recovery checkpoint\",\n request.checkpoint.threadId,\n ),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? recoveryCheckpoints.load(request)\n : Effect.succeed(Option.none()),\n },\n }),\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport. Foreign recovery-cache loads return none for canonical replay; other foreign\n * checkpoint operations and observation fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n AdmissionPolicyError,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * Decide whether this physical owner stores the addressed logical Thread. Local\n * requests use the same SQLite facets; foreign requests use the transport or fail\n * fast typed. The predicate determines placement, never caller authorization.\n */\n readonly ownsThread: (threadId: ThreadId) => boolean;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n ownsThread: RoutedPortOptions[\"ownsThread\"],\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget =>\n ownsThread(threadId) ? LOCAL : { _tag: \"foreign\", threadId },\n ),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.ownsThread);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n options.ownsThread(request.threadId)\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n Schema.Union([AdmissionConflict, AdmissionPolicyError]),\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : options.ownsThread(request.threadId)\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n options.ownsThread(request.threadId)\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n options.ownsThread(request.threadId)\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n options.ownsThread(request.threadId)\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n readAbortIntent: (request) =>\n submissionTarget(\"ledger read abort intent\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.readAbortIntent(request)\n : Effect.fail(crossThreadLedgerError(\"ledger read abort intent\", target.threadId)),\n ),\n ),\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const recoveryCheckpoints = local.recoveryCheckpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n options.ownsThread(request.threadId)\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n options.ownsThread(request.threadId)\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n options.ownsThread(request.threadId)\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n options.ownsThread(request.threadId)\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n options.ownsThread(request.threadId)\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local: the closed route-capable store subset\n // is materialize/append/read/inspectTail/export. Recovery cache misses can fall back\n // to those canonical reads, including when the cache belongs to a foreign Object.\n observe: (request) =>\n options.ownsThread(request.threadId)\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(recoveryCheckpoints === undefined\n ? {}\n : {\n recoveryCheckpoints: {\n save: (request) =>\n options.ownsThread(request.checkpoint.threadId)\n ? recoveryCheckpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\n \"thread save recovery checkpoint\",\n request.checkpoint.threadId,\n ),\n ),\n load: (request) =>\n options.ownsThread(request.threadId)\n ? recoveryCheckpoints.load(request)\n : Effect.succeed(Option.none()),\n },\n }),\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n options.ownsThread(request.checkpoint.threadId)\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n options.ownsThread(request.threadId)\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport. Foreign recovery-cache loads return none for canonical replay; other foreign\n * checkpoint operations and observation fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
|
|
@@ -325,7 +325,10 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
325
325
|
supportedVersion: 6,
|
|
326
326
|
message: "The Durable Object contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer."
|
|
327
327
|
});
|
|
328
|
-
yield* SqliteMigrator.run({
|
|
328
|
+
yield* SqliteMigrator.run({
|
|
329
|
+
loader: doMigrations,
|
|
330
|
+
table: "effect_sql_migrations_agent_threads"
|
|
331
|
+
}).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.mapError((error) => DoStorageError.make({
|
|
329
332
|
cause: error,
|
|
330
333
|
operation: "initialize current storage",
|
|
331
334
|
message: error.message
|
|
@@ -985,4 +988,4 @@ const initializeDoJournal = ensureCurrentStorage;
|
|
|
985
988
|
//#endregion
|
|
986
989
|
export { initializeDoJournal as a, decodeRows as i, RawCheckpoint as n, RawReadRequest as r, RawAppendRequest as t };
|
|
987
990
|
|
|
988
|
-
//# sourceMappingURL=do-journal-
|
|
991
|
+
//# sourceMappingURL=do-journal-DHqCQeBU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"do-journal-DHqCQeBU.mjs","names":[],"sources":["../src/internal/do-journal.ts"],"sourcesContent":["import { EMPTY_TAIL_DIGEST } from \"@effect-agent/thread/Digest\";\nimport { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { checkV2ThreadLayout } from \"@effect-agent/thread/SqlStorageV2Upgrade\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n type SaveRecoveryCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect, Schema, Stream } from \"effect\";\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 { CurrentDoStorageVersion, createNonterminalIndex, doMigrations } 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 });\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 ): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: String(error),\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,\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 === 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 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* sql`UPDATE effect_agent_meta SET value='6' 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(\"SqlError\", storageError(\"upgrade supported thread storage\")),\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 and v5 can be upgraded automatically. Keep the original store and use a compatible library version.\",\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 ${sql.in([...REQUIRED_TABLES, \"effect_agent_message_deliveries\", \"effect_agent_recovery_checkpoints\"])}\n ) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')\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 + 3) {\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 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.decodeUnknownEffect(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.decodeUnknownEffect(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 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(\"DoJournal.read\")(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 );\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 );\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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A,SAAS,OAAO,KAAK;AACvB,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;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB,CAAC,OAAO,OAAO;CAClC,gCAAgC;EAC9B;EACA;EACA;EACA;CACF;AACF;AAEA,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,SACA;CACA,MAAM,MAAM,OAAO,UAAU;CAsB7B,MAAM,kBAAkB;EACtB,GApBA,YAAY,IACR,qBACA;GACE,GAAG;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"}
|
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.80","dependencies":{"@effect-agent/core":"0.1.0-beta.80","@effect-agent/thread":"0.1.0-beta.80","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.80","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./DoMessageDeliveryStore":{"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"}}
|
package/src/PortRouting.ts
CHANGED
|
@@ -151,11 +151,11 @@ export class ThreadPortTransport extends Context.Service<
|
|
|
151
151
|
/** Construction options shared by both routed port Layers. */
|
|
152
152
|
export interface RoutedPortOptions {
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
154
|
+
* Decide whether this physical owner stores the addressed logical Thread. Local
|
|
155
|
+
* requests use the same SQLite facets; foreign requests use the transport or fail
|
|
156
|
+
* fast typed. The predicate determines placement, never caller authorization.
|
|
157
157
|
*/
|
|
158
|
-
readonly
|
|
158
|
+
readonly ownsThread: (threadId: ThreadId) => boolean;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/** Where one port request must execute. */
|
|
@@ -175,7 +175,7 @@ const LOCAL: RouteTarget = { _tag: "local" };
|
|
|
175
175
|
* refused them at admission, so they cannot name any stored row anywhere.
|
|
176
176
|
*/
|
|
177
177
|
const routableSubmissionTarget = (
|
|
178
|
-
|
|
178
|
+
ownsThread: RoutedPortOptions["ownsThread"],
|
|
179
179
|
): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>
|
|
180
180
|
Effect.fn("DoPortRouting.routableSubmissionTarget")(function* (
|
|
181
181
|
operation: string,
|
|
@@ -196,10 +196,10 @@ const routableSubmissionTarget = (
|
|
|
196
196
|
if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;
|
|
197
197
|
const tail = submissionId.slice(separator + 1);
|
|
198
198
|
|
|
199
|
-
if (tail === localThreadId) return LOCAL;
|
|
200
|
-
|
|
201
199
|
return yield* decodeThreadId(tail).pipe(
|
|
202
|
-
Effect.map((threadId): RouteTarget =>
|
|
200
|
+
Effect.map((threadId): RouteTarget =>
|
|
201
|
+
ownsThread(threadId) ? LOCAL : { _tag: "foreign", threadId },
|
|
202
|
+
),
|
|
203
203
|
Effect.orElseSucceed(() => LOCAL),
|
|
204
204
|
);
|
|
205
205
|
});
|
|
@@ -261,7 +261,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
261
261
|
const local = yield* SubmissionLedger;
|
|
262
262
|
const transport = yield* ThreadPortTransport;
|
|
263
263
|
const transportCall: TransportCall = makeTransportCall(transport);
|
|
264
|
-
const submissionTarget = routableSubmissionTarget(options.
|
|
264
|
+
const submissionTarget = routableSubmissionTarget(options.ownsThread);
|
|
265
265
|
|
|
266
266
|
const routeFailure =
|
|
267
267
|
(operation: string, target: string) =>
|
|
@@ -476,7 +476,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
476
476
|
capabilities: local.capabilities,
|
|
477
477
|
|
|
478
478
|
admit: (request) =>
|
|
479
|
-
request.threadId
|
|
479
|
+
options.ownsThread(request.threadId)
|
|
480
480
|
? local.admit(request)
|
|
481
481
|
: foreignLedgerCall(
|
|
482
482
|
"ledger admit",
|
|
@@ -510,7 +510,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
510
510
|
: foreignLookupById("ledger lookup", target.threadId, request.submissionId),
|
|
511
511
|
),
|
|
512
512
|
)
|
|
513
|
-
: request.threadId
|
|
513
|
+
: options.ownsThread(request.threadId)
|
|
514
514
|
? local.lookup(request)
|
|
515
515
|
: foreignLedgerCall(
|
|
516
516
|
"ledger lookup",
|
|
@@ -525,7 +525,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
525
525
|
),
|
|
526
526
|
|
|
527
527
|
resolveAdmission: (request) =>
|
|
528
|
-
request.threadId
|
|
528
|
+
options.ownsThread(request.threadId)
|
|
529
529
|
? local.resolveAdmission(request)
|
|
530
530
|
: resolveForeignAdmission(request.threadId, request),
|
|
531
531
|
|
|
@@ -562,12 +562,12 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
562
562
|
// Every operation below is lane-local by construction (plan §1.3): a foreign address is
|
|
563
563
|
// an out-of-contract call and fails fast typed instead of being quietly distributed.
|
|
564
564
|
claim: (request) =>
|
|
565
|
-
request.threadId
|
|
565
|
+
options.ownsThread(request.threadId)
|
|
566
566
|
? local.claim(request)
|
|
567
567
|
: Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
|
|
568
568
|
|
|
569
569
|
claimJoining: (request) =>
|
|
570
|
-
request.threadId
|
|
570
|
+
options.ownsThread(request.threadId)
|
|
571
571
|
? local.claimJoining(request)
|
|
572
572
|
: Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
|
|
573
573
|
|
|
@@ -793,7 +793,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
793
793
|
|
|
794
794
|
const routed = ThreadStore.of({
|
|
795
795
|
materialize: (request) =>
|
|
796
|
-
request.threadId
|
|
796
|
+
options.ownsThread(request.threadId)
|
|
797
797
|
? local.materialize(request)
|
|
798
798
|
: foreignStoreCall(
|
|
799
799
|
"thread materialize",
|
|
@@ -804,7 +804,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
804
804
|
).pipe(Effect.asVoid),
|
|
805
805
|
|
|
806
806
|
append: (request) =>
|
|
807
|
-
request.threadId
|
|
807
|
+
options.ownsThread(request.threadId)
|
|
808
808
|
? local.append(request)
|
|
809
809
|
: foreignStoreCall(
|
|
810
810
|
"thread append",
|
|
@@ -815,7 +815,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
815
815
|
).pipe(Effect.map((reply) => reply.result)),
|
|
816
816
|
|
|
817
817
|
read: (request) =>
|
|
818
|
-
request.threadId
|
|
818
|
+
options.ownsThread(request.threadId)
|
|
819
819
|
? local.read(request)
|
|
820
820
|
: Stream.unwrap(
|
|
821
821
|
foreignStoreCall(
|
|
@@ -828,7 +828,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
828
828
|
),
|
|
829
829
|
|
|
830
830
|
inspectTail: (request) =>
|
|
831
|
-
request.threadId
|
|
831
|
+
options.ownsThread(request.threadId)
|
|
832
832
|
? local.inspectTail(request)
|
|
833
833
|
: foreignStoreCall(
|
|
834
834
|
"thread inspect tail",
|
|
@@ -839,7 +839,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
839
839
|
).pipe(Effect.map((reply) => reply.tail)),
|
|
840
840
|
|
|
841
841
|
export: (request) =>
|
|
842
|
-
request.threadId
|
|
842
|
+
options.ownsThread(request.threadId)
|
|
843
843
|
? local.export(request)
|
|
844
844
|
: foreignStoreCall(
|
|
845
845
|
"thread export",
|
|
@@ -853,7 +853,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
853
853
|
// is materialize/append/read/inspectTail/export. Recovery cache misses can fall back
|
|
854
854
|
// to those canonical reads, including when the cache belongs to a foreign Object.
|
|
855
855
|
observe: (request) =>
|
|
856
|
-
request.threadId
|
|
856
|
+
options.ownsThread(request.threadId)
|
|
857
857
|
? local.observe(request)
|
|
858
858
|
: Stream.unwrap(Effect.fail(crossThreadStoreError("thread observe", request.threadId))),
|
|
859
859
|
|
|
@@ -862,7 +862,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
862
862
|
: {
|
|
863
863
|
recoveryCheckpoints: {
|
|
864
864
|
save: (request) =>
|
|
865
|
-
request.checkpoint.threadId
|
|
865
|
+
options.ownsThread(request.checkpoint.threadId)
|
|
866
866
|
? recoveryCheckpoints.save(request)
|
|
867
867
|
: Effect.fail(
|
|
868
868
|
crossThreadStoreError(
|
|
@@ -871,7 +871,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
871
871
|
),
|
|
872
872
|
),
|
|
873
873
|
load: (request) =>
|
|
874
|
-
request.threadId
|
|
874
|
+
options.ownsThread(request.threadId)
|
|
875
875
|
? recoveryCheckpoints.load(request)
|
|
876
876
|
: Effect.succeed(Option.none()),
|
|
877
877
|
},
|
|
@@ -881,13 +881,13 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
881
881
|
: {
|
|
882
882
|
checkpoints: {
|
|
883
883
|
save: (request) =>
|
|
884
|
-
request.checkpoint.threadId
|
|
884
|
+
options.ownsThread(request.checkpoint.threadId)
|
|
885
885
|
? checkpoints.save(request)
|
|
886
886
|
: Effect.fail(
|
|
887
887
|
crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId),
|
|
888
888
|
),
|
|
889
889
|
load: (request) =>
|
|
890
|
-
request.threadId
|
|
890
|
+
options.ownsThread(request.threadId)
|
|
891
891
|
? checkpoints.load(request)
|
|
892
892
|
: Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId)),
|
|
893
893
|
},
|
|
@@ -474,7 +474,13 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
|
|
|
474
474
|
});
|
|
475
475
|
}
|
|
476
476
|
|
|
477
|
-
yield* SqliteMigrator.run({
|
|
477
|
+
yield* SqliteMigrator.run({
|
|
478
|
+
loader: doMigrations,
|
|
479
|
+
// An application can share this SQL client and own its own migration history.
|
|
480
|
+
// Keep bookkeeping outside effect_agent_% so interrupted unversioned schemas
|
|
481
|
+
// still fail the ambiguity check above.
|
|
482
|
+
table: "effect_sql_migrations_agent_threads",
|
|
483
|
+
}).pipe(
|
|
478
484
|
// SqliteMigrator depends on the generic client supplied by this adapter. The concrete
|
|
479
485
|
// Durable Object client is kept at the outer Layer boundary.
|
|
480
486
|
Effect.provideService(SqlClient.SqlClient, sql),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"do-journal-DnzUmhPA.mjs","names":[],"sources":["../src/internal/do-journal.ts"],"sourcesContent":["import { EMPTY_TAIL_DIGEST } from \"@effect-agent/thread/Digest\";\nimport { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { checkV2ThreadLayout } from \"@effect-agent/thread/SqlStorageV2Upgrade\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n type SaveRecoveryCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect, Schema, Stream } from \"effect\";\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 { CurrentDoStorageVersion, createNonterminalIndex, doMigrations } 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 });\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 ): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: String(error),\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,\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 === 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 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({ loader: doMigrations }).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* sql`UPDATE effect_agent_meta SET value='6' 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(\"SqlError\", storageError(\"upgrade supported thread storage\")),\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 and v5 can be upgraded automatically. Keep the original store and use a compatible library version.\",\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 ${sql.in([...REQUIRED_TABLES, \"effect_agent_message_deliveries\", \"effect_agent_recovery_checkpoints\"])}\n ) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')\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 + 3) {\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 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.decodeUnknownEffect(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.decodeUnknownEffect(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 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(\"DoJournal.read\")(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 );\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 );\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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A,SAAS,OAAO,KAAK;AACvB,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;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB,CAAC,OAAO,OAAO;CAClC,gCAAgC;EAC9B;EACA;EACA;EACA;CACF;AACF;AAEA,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,SACA;CACA,MAAM,MAAM,OAAO,UAAU;CAsB7B,MAAM,kBAAkB;EACtB,GApBA,YAAY,IACR,qBACA;GACE,GAAG;GACH,0BAA0B;IACxB,GAAG,mBAAmB;IACtB;IACA;GACF;GACA,iCAAiC;IAC/B;IACA;IACA;IACA;IACA;IACA;GACF;EACF;EAIJ,GAAI,YAAY,IACZ,EACE,mCAAmC;GACjC;GACA;GACA;GACA;EACF,EACF,IACA,CAAC;CACP;CAEA,KAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,eAAe,GAAG;EAC/D,MAAM,UAAU,OAAO,WACrB,OAAO,MAAM,OAAO,OAAO,EAAE,MAAM,kBAAkB,CAAC,CAAC,GACvD,OACA,UACA,OAAO,IAAI,OAAO,qBAAqB,MAAM,EAAE,CACjD;EAEA,MAAM,QAAQ,IAAI,IAAY,QAAQ;EAEtC,IAAI,QAAQ,WAAW,MAAM,QAAQ,QAAQ,MAAM,WAAW,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,GACnF,OAAO,OAAO,4BAA4B,KAAK;GAC7C,eAAe;GACf,kBAAA;GACA,SAAS,QAAQ,QAAQ,GAAG,MAAM;EACpC,CAAC;CACL;AACF,CAAC;AAED,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAM,uBAAuB,OAAO,GAAG,gCAAgC,CAAC,CAAC,WACvE,KACA,YAAgC,aAChC,qBACA;CACA,MAAM,gBAAgB,OAAO,GAA4B;;;;;IAKvD,KAAK,OAAO,SAAS,aAAa,4BAA4B,CAAC,CAAC;CASlE,KAAI,OAPsB,WACxB,OAAO,MAAM,SAAS,GACtB,iBACA,qBACA,aACF,EAAA,CAEe,WAAW,GAAG;EAC3B,MAAM,eAAe,OAAO,GAA4B;;;;;;MAMtD,KAAK,OAAO,SAAS,aAAa,6BAA6B,CAAC,CAAC;EASnE,KAAI,OAPoB,WACtB,OAAO,MAAM,SAAS,GACtB,iBACA,kBACA,YACF,EAAA,CAEa,SAAS,GACpB,OAAO,OAAO,4BAA4B,KAAK;GAC7C,eAAe;GACf,kBAAA;GACA,SACE;EACJ,CAAC;EAGH,OAAO,eAAe,IAAI,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,KAGlD,OAAO,eAAe,UAAU,WAAW,GAAG,GAC9C,OAAO,UAAU,UACf,eAAe,KAAK;GAClB,OAAO;GACP,WAAW;GACX,SAAS,MAAM;EACjB,CAAC,CACH,CACF;CACF,OAAO;EACL,MAAM,cAAc,OAAO,GAA4B;;;;MAIrD,KAAK,OAAO,SAAS,aAAa,sBAAsB,CAAC,CAAC;EAE5D,MAAM,UAAU,OAAO,gBACrB,OAAO,MAAM,SAAS,GACtB,qBACA,mBACA,WACF;EAEA,IACE,QAAQ,UAAU,OAClB,QAAQ,UAAU,OAClB,QAAQ,UAAU,OAClB,QAAQ,UAAU,KAElB,OAAO,IACJ,gBACC,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,GAErB;GAEF,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,UAAU,OAAA,CAA8B,GAC7E;GACF,IACE,QAAQ,WAAW,KAClB,QAAQ,EAAE,CAAC,UAAU,OACpB,QAAQ,EAAE,CAAC,UAAU,OACrB,QAAQ,EAAE,CAAC,UAAU,OACrB,QAAQ,EAAE,CAAC,UAAU,KAEvB,OAAO,OAAO,4BAA4B,KAAK;IAC7C,eAAe;IACf,kBAAA;IACA,SAAS;GACX,CAAC;GASH,KAAI,OAPoB,WACtB,OAAO,MAAM,SAAS,GACtB,iBACA,mBACA,OAAO,GAAG,iEAAiE,IAAI,GAAG,CAAC,GAAG,eAAe,CAAC,GACxG,EAAA,CAEa,WAAW,gBAAgB,QACtC,OAAO,OAAO,4BAA4B,KAAK;IAC7C,eAAe,OAAO,QAAQ,EAAE,CAAC,KAAK;IACtC,kBAAA;IACA,SACE;GACJ,CAAC;GAKH,KAAI,OAFK,GAAG,iGAAA,CAEO,YAAY,QAAQ,EAAE,CAAC,UAAU,MAAM,IAAI,IAC5D,OAAO,OAAO,4BAA4B,KAAK;IAC7C,eAAe,OAAO,QAAQ,EAAE,CAAC,KAAK;IACtC,kBAAA;IACA,SACE;GACJ,CAAC;GAKH,KAAI,OAFK,GAAG,mFAAA,CAEA,WAAW,GACrB,OAAO,OAAO,4BAA4B,KAAK;IAC7C,eAAe,OAAO,QAAQ,EAAE,CAAC,KAAK;IACtC,kBAAA;IACA,SACE;GACJ,CAAC;GACH,IAAI,QAAQ,EAAE,CAAC,UAAU,KAAK;IAC5B,OAAO,oBAAoB;IAC3B,KAAK,MAAM,aAAa;KACtB,GAAG;KACH,GAAG;KACH,GAAG;IACL,GAAG;KACD,OAAO,UAAU,yBAAyB;KAC1C,OAAO;KACP,OAAO,UAAU,wBAAwB;IAC3C;GACF;GACA,IAAI,QAAQ,EAAE,CAAC,UAAU,KAAK,OAAO,uBAAuB,CAAC;GAC7D,IAAI,QAAQ,EAAE,CAAC,UAAU,KAAK,OAAO,uBAAuB,CAAC;GAC7D,IAAI,QAAQ,EAAE,CAAC,UAAU,KAAK,OAAO,uBAAuB,CAAC;GAC7D,IAAI,QAAQ,EAAE,CAAC,UAAU,OAAO,QAAQ,EAAE,CAAC,UAAU,KAAK;IACxD,OAAO,UAAU,yBAAyB;IAC1C,OAAO,GAAG;IACV,OAAO,UAAU,wBAAwB;IACzC,OAAO,UAAU,yBAAyB;IAC1C,OAAO,GAAG;IACV,OAAO,UAAU,wBAAwB;IACzC,OAAO,UAAU,yBAAyB;IAC1C,OAAO;IACP,OAAO,UAAU,wBAAwB;GAC3C;GACA,IAAI,QAAQ,EAAE,CAAC,UAAU,KAAK;IAC5B,OAAO,UAAU,yBAAyB;IAC1C,OAAO;IACP,OAAO,UAAU,wBAAwB;GAC3C;GACA,OAAO,UAAU,yBAAyB;GAC1C,OAAO;GACP,OAAO,UAAU,wBAAwB;GACzC,OAAO,UAAU,wBAAwB;GACzC,OAAO,GAAG;GACV,OAAO,UAAU,uBAAuB;EAC1C,CAAC,CACH,CAAC,CACA,KACC,OAAO,SAAS,4BAA4B,UAC1C,eAAe,KAAK;GAClB,OAAO;GACP,WAAW;GACX,SAAS,MAAM;EACjB,CAAC,CACH,GACA,OAAO,SAAS,wBAAwB,UACtC,yBAAyB,KAAK;GAC5B,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,SAAS,MAAM;EACjB,CAAC,CACH,GACA,OAAO,SAAS,YAAY,aAAa,kCAAkC,CAAC,CAC9E;OACG,IAAI,QAAQ,UAAU,OAAA,CAA8B,GAAG;GAC5D,MAAM,gBAAgB,OAAO,SAAS,QAAQ,OAAO,EAAE;GAEvD,OAAO,OAAO,4BAA4B,KAAK;IAC7C,eAAe,OAAO,cAAc,aAAa,IAAI,gBAAgB;IACrE,kBAAA;IACA,SACE,uDAAuD,QAAQ,MAAM;GAGzE,CAAC;EACH;CACF;CAEA,MAAM,eAAe,OAAO,GAA4B;;;;oBAItC,IAAI,GAAG;EAAC,GAAG;EAAiB;EAAmC;CAAmC,CAAC,EAAE;;;IAGrH,KAAK,OAAO,SAAS,aAAa,uBAAuB,CAAC,CAAC;CAS7D,KAAI,OAPoB,WACtB,OAAO,MAAM,SAAS,GACtB,iBACA,mBACA,YACF,EAAA,CAEa,WAAW,gBAAgB,SAAS,GAC/C,OAAO,OAAO,4BAA4B,KAAK;EAC7C,eAAA;EACA,kBAAA;EACA,SACE;CACJ,CAAC;CAGH,OAAO,YAAY,KAAK,WAAW,mBAAmB;AACxD,CAAC;AAED,MAAM,eACJ,KACA,WACA,wBACG;;CAEH,MAAM,mBACJ,WACA,UAC8C;EAC9C,MAAM,cAAc,gBAAgB,KAAK;EAEzC,OAAO,cAAc,sBACjB,OAAO,KACL,qBAAqB,KAAK;GACxB;GACA,UAAU;GACV;EACF,CAAC,CACH,IACA,OAAO;CACb;;;;;;;;;;;;;CAcA,MAAM,wBACH,eACM,WACL,IAAI,gBAAgB,MAAM,CAAC,CAAC,KAC1B,OAAO,UAAU,UAAW,WAAW,KAAK,IAAI,aAAa,SAAS,CAAC,CAAC,KAAK,IAAI,KAAM,GACvF,OAAO,SAAS,kCAAkC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CACjF;CAEJ,MAAM,cAAc,OAAO,GAAG,uBAAuB,CAAC,CAAC,WACrD,UACA,WACA,iBACA,eAIA;EACA,IAAI,SAAS,SAAS,uBACpB,OAAO,OAAO,eAAe,KAAK;GAChC,WAAW;GACX,SAAS;EACX,CAAC;EAEH,OAAO,gBAAgB,sBAAsB,eAAe;EAC5D,OAAO,qBAAqB,yBAAyB,CAAC,CACpD,OAAO,IAAI,aAAa;GACtB,MAAM,eAAe,OAAO,GAA4B;;;;;;;;8BAQlC,SAAS;UAC7B,KAAK,OAAO,SAAS,aAAa,0BAA0B,CAAC,CAAC;GAEhE,MAAM,WAAW,OAAO,WACtB,OAAO,MAAM,SAAS,GACtB,wBACA,UACA,YACF;GAEA,IAAI,SAAS,SAAS,GACpB,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ;IACR,SAAS;GACX,CAAC;GAEH,IAAI,SAAS,WAAW,GAAG;IACzB,OAAO,GAAG;;;;;;;;gBAQJ,SAAS;gBACT,UAAU;;gBAEV,gBAAgB;gBAChB,cAAc;;YAElB,KAAK,OAAO,SAAS,aAAa,oBAAoB,CAAC,CAAC;IAE1D;GACF;GACA,IAAI,gBAAgB,SAAS,EAAE,CAAC,gBAC9B,OAAO,OAAO,gBAAgB,KAAK;IACjC;IACA,aAAa,SAAS,EAAE,CAAC;IACzB,SAAS,kBAAkB,cAAc,8BAA8B,SAAS,EAAE,CAAC,eAAe;GACpG,CAAC;GAEH,IAAI,gBAAgB,SAAS,EAAE,CAAC,gBAC9B,OAAO,GAAG;;mCAEe,cAAc;gCACjB,SAAS;YAC7B,KAAK,OAAO,SAAS,aAAa,+BAA+B,CAAC,CAAC;EAEzE,CAAC,CACH;CACF,CAAC;CAED,MAAM,YAAY,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAAW,UAAkB;EAC9E,MAAM,OAAO,OAAO,GAA4B;;;;;;;;0BAQ1B,SAAS;MAC7B,KAAK,OAAO,SAAS,aAAa,aAAa,CAAC,CAAC;EAEnD,OAAO,OAAO,WAAW,OAAO,MAAM,SAAS,GAAG,wBAAwB,UAAU,IAAI;CAC1F,CAAC;CAED,MAAM,SAAS,OAAO,GAAG,kBAAkB,CAAC,CAAC,WAC3C,SACgD;EAChD,IACE,QAAQ,SAAS,SAAS,yBAC1B,QAAQ,QAAQ,SAAS,yBACzB,QAAQ,QAAQ,MAAM,WAAW,OAAO,SAAS,SAAS,qBAAqB,GAE/E,OAAO,OAAO,eAAe,KAAK;GAChC,WAAW;GACX,SAAS;EACX,CAAC;EAGH,OAAO,gBAAgB,0BAA0B,QAAQ,SAAS;EAClE,OAAO,gBAAgB,0BAA0B,QAAQ,WAAW;EACpE,OAAO,gBAAgB,0BAA0B,QAAQ,UAAU;EACnE,OAAO,OAAO,QACZ,QAAQ,UACP,WAAW,gBAAgB,2BAA2B,OAAO,UAAU,GACxE,EAAE,SAAS,KAAK,CAClB;EAEA,OAAO,OAAO,qBAAqB,oBAAoB,CAAC,CACtD,OAAO,IAAI,aAAa;GACtB,MAAM,YAAY,QAAQ,QAAQ,KAAK,WAAW,OAAO,QAAQ;GAEjE,IAAI,IAAI,IAAI,SAAS,CAAC,CAAC,SAAS,UAAU,QACxC,OAAO,OAAO,iBAAiB,KAAK;IAClC,SAAS,SAAS,QAAQ,QAAQ;IAClC,QAAQ;GACV,CAAC;GAGH,MAAM,aAAa,OAAO,GAA4B;;;;;;;;8BAQhC,QAAQ,SAAS;UACrC,KAAK,OAAO,SAAS,aAAa,kBAAkB,CAAC,CAAC;GAExD,MAAM,SAAS,OAAO,gBACpB,OAAO,MAAM,SAAS,GACtB,wBACA,QAAQ,UACR,UACF;GAEA,IAAI,QAAQ,kBAAkB,OAAO,gBACnC,OAAO,OAAO,gBAAgB,KAAK;IACjC,eAAe,QAAQ;IACvB,aAAa,OAAO;IACpB,SAAS,kBAAkB,QAAQ,cAAc,4BAA4B,OAAO,eAAe;GACrG,CAAC;GAGH,MAAM,YAAY,OAAO,GAA4B;;;;;;;;;;8BAU/B,QAAQ,SAAS;6BAClB,QAAQ,QAAQ;UACnC,KAAK,OAAO,SAAS,aAAa,uBAAuB,CAAC,CAAC;GAE7D,MAAM,UAAU,OAAO,WACrB,OAAO,MAAM,QAAQ,GACrB,kCACA,GAAG,QAAQ,SAAS,GAAG,QAAQ,WAC/B,SACF;GAEA,IAAI,QAAQ,SAAS,GACnB,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ,GAAG,QAAQ,SAAS,GAAG,QAAQ;IACvC,SAAS;GACX,CAAC;GAEH,IAAI,QAAQ,WAAW,GAAG;IACxB,MAAM,WAAW,QAAQ;IAEzB,IAAI,SAAS,iBAAiB,QAAQ,aACpC,OAAO,OAAO,iBAAiB,KAAK;KAClC,SAAS,SAAS,QAAQ,QAAQ;KAClC,QAAQ;IACV,CAAC;IAGH,OAAO,gBAAgB,KAAK;KAC1B,eAAe,SAAS;KACxB,cAAc,SAAS;KACvB,UAAU;KACV,YAAY,SAAS;IACvB,CAAC;GACH;GAEA,IACE,QAAQ,yBAAyB,OAAO,iBACxC,QAAQ,uBAAuB,OAAO,aAEtC,OAAO,OAAO,iBAAiB,KAAK;IAClC,SACE,iBAAiB,QAAQ,qBAAqB,GAAG,QAAQ,mBAAmB,aAC/D,OAAO,cAAc,GAAG,OAAO,YAAY;IAC1D,QAAQ;IACR,oBAAoB,OAAO;IAC3B,kBAAkB,OAAO;GAC3B,CAAC;GAEH,IAAI,OAAO,gBAAgB,QAAQ,QAAQ,SAAS,wBAClD,OAAO,OAAO,eAAe,KAAK;IAChC,WAAW;IACX,SAAS,uBAAuB,uBAAuB;GACzD,CAAC;GAKH,MAAM,kBAAoC,CAAC;GAE3C,KAAK,MAAM,SAAS,QAAQ,WAAW,EAAyB,GAAG;IACjE,MAAM,qBAAqB,OAAO,GAA4B;;;;;;;;gCAQxC,QAAQ,SAAS;iCAChB,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE;;YAExC,KAAK,OAAO,SAAS,aAAa,mCAAmC,CAAC,CAAC;IAEzE,gBAAgB,KACd,GAAI,OAAO,WACT,OAAO,MAAM,SAAS,GACtB,kCACA,GAAG,QAAQ,SAAS,cACpB,kBACF,CACF;GACF;GACA,IAAI,gBAAgB,SAAS,GAC3B,OAAO,OAAO,iBAAiB,KAAK;IAClC,SAAS,uBAAuB,gBAAgB,EAAE,CAAC,UAAU;IAC7D,QAAQ;GACV,CAAC;GAGH,MAAM,gBAAgB,OAAO,OAAO,oBAAoB,iBAAiB,CAAC,CACxE,OAAO,gBAAgB,CACzB,CAAC,CAAC,KACA,OAAO,UAAU,UACf,eAAe,KAAK;IAClB,OAAO;IACP,WAAW;IACX,SAAS,MAAM;GACjB,CAAC,CACH,CACF;GAEA,MAAM,eAAe,OAAO,OAAO,oBAAoB,iBAAiB,CAAC,CACvE,gBAAgB,QAAQ,QAAQ,SAAS,CAC3C,CAAC,CAAC,KACA,OAAO,UAAU,UACf,eAAe,KAAK;IAClB,OAAO;IACP,WAAW;IACX,SAAS,MAAM;GACjB,CAAC,CACH,CACF;GAEA,OAAO,GAAG;;;;;;;;;;cAUJ,QAAQ,SAAS;cACjB,QAAQ,QAAQ;cAChB,cAAc;cACd,aAAa;cACb,QAAQ,YAAY;cACpB,QAAQ,WAAW;cACnB,QAAQ,UAAU;;UAEtB,KAAK,OAAO,SAAS,aAAa,wBAAwB,CAAC,CAAC;GAC9D,OAAO,UAAU,2BAA2B;GAE5C,OAAO,OAAO,QACZ,QAAQ,UACP,QAAQ,UACP,OAAO,IAAI,aAAa;IACtB,OAAO,GAAG;;;;;;;;sBAQF,QAAQ,SAAS;sBACjB,gBAAgB,MAAM;sBACtB,OAAO,SAAS;sBAChB,QAAQ,QAAQ;sBAChB,OAAO,WAAW;;kBAEtB,KAAK,OAAO,SAAS,aAAa,yBAAyB,CAAC,CAAC;IACjE,OAAO,UAAU,4BAA4B;GAC/C,CAAC,GACH,EAAE,SAAS,KAAK,CAClB;GAEA,OAAO,GAAG;;;8BAGY,aAAa;4BACf,QAAQ,WAAW;+BAChB,QAAQ,cAAc;8BACvB,QAAQ,SAAS;UACrC,KAAK,OAAO,SAAS,aAAa,qBAAqB,CAAC,CAAC;GAC3D,OAAO,UAAU,0BAA0B;GAE3C,OAAO,gBAAgB,KAAK;IAC1B;IACA;IACA,UAAU;IACV,YAAY,QAAQ;GACtB,CAAC;EACH,CAAC,CACH;CACF,CAAC;CAED,MAAM,OAAO,OAAO,GAAG,gBAAgB,CAAC,CAAC,WAAW,SAAyB;EAG3E,MAAM,WAAW,OAAO,GAA4B;;;;;0BAK9B,QAAQ,SAAS;yBAClB,QAAQ,sBAAsB;;cAEzC,QAAQ,MAAM;MACtB,KAAK,OAAO,SAAS,aAAa,wBAAwB,CAAC,CAAC;EAE9D,MAAM,OAAO,OAAO,WAClB,OAAO,MAAM,WAAW,GACxB,kCACA,GAAG,QAAQ,SAAS,GAAG,QAAQ,yBAC/B,QACF;EAEA,MAAM,iBACJ,yBAAyB,KAAK;GAC5B,OAAO;GACP,QAAQ,GAAG,QAAQ,SAAS,GAAG,QAAQ;GACvC,SAAS;EACX,CAAC;EAEH,IAAI,KAAK,SAAS,QAAQ,OAAO,OAAO,OAAO,SAAS;EAExD,MAAM,QAAyB,CAAC;EAChC,IAAI;EACJ,IAAI,YAAY;EAChB,IAAI,mBAAmB,QAAQ;EAE/B,KAAK,MAAM,OAAO,MAAM;GACtB,IAAI,IAAI,aAAa,mBAAmB,GAAG,OAAO,OAAO,SAAS;GAClE,mBAAmB,IAAI;GACvB,IAAI,SAAS,KAAA,KAAa,YAAY,IAAI,oBAAoB,0BAA0B;IACtF,OAAO,CAAC,GAAG;IACX,MAAM,KAAK,IAAI;IACf,YAAY,IAAI;GAClB,OAAO;IACL,KAAK,KAAK,GAAG;IACb,aAAa,IAAI;GACnB;EACF;EAEA,MAAM,WAAW,OAAO,GAAG,oBAAoB,CAAC,CAAC,WAAW,MAAgB;GAC1E,MAAM,OAAO,OAAO,GAA4B;;;4BAG1B,QAAQ,SAAS;4BACjB,KAAK,EAAE,CAAC,SAAS;4BACjB,KAAK,KAAK,SAAS,EAAE,CAAC,SAAS;;QAEnD,KAAK,OAAO,SAAS,aAAa,wBAAwB,CAAC,CAAC;GAE9D,MAAM,UAAU,OAAO,WACrB,OAAO,MAAM,SAAS,GACtB,kCACA,GAAG,QAAQ,SAAS,GAAG,KAAK,EAAE,CAAC,YAC/B,IACF;GAEA,IACE,QAAQ,WAAW,KAAK,UACxB,QAAQ,MACL,KAAK,UACJ,IAAI,cAAc,QAAQ,YAC1B,IAAI,aAAa,KAAK,MAAM,CAAC,YAC7B,gBAAgB,IAAI,WAAW,MAAM,KAAK,MAAM,CAAC,iBACrD,GAEA,OAAO,OAAO,SAAS;GAGzB,OAAO;EACT,CAAC;EAED,OAAO;GACL,OAAO,KAAK;GACZ,SAAS,OAAO,aAAa,KAAK,CAAC,CAAC,KAClC,OAAO,SAAS,SAAS,OAAO,mBAAmB,SAAS,IAAI,CAAC,CAAC,CACpE;EACF;CACF,CAAC;CAED,MAAM,eAAe,OAAO,GAAG,wBAAwB,CAAC,CAAC,WAAW,UAAkB;EACpF,OAAO,OAAO,IACX,gBACC,OAAO,IAAI,aAAa;GACtB,MAAM,aAAa,OAAO,GAA4B;;;;;;;;gCAQhC,SAAS;YAC7B,KAAK,OAAO,SAAS,aAAa,eAAe,CAAC,CAAC;GAErD,MAAM,SAAS,OAAO,gBACpB,OAAO,MAAM,SAAS,GACtB,wBACA,UACA,UACF;GAEA,OAAO,UAAU,0BAA0B;GAE3C,IAAI,OAAO,gBAAgB,wBACzB,OAAO,OAAO,eAAe,KAAK;IAChC,WAAW;IACX,SAAS;GACX,CAAC;GACH,MAAM,UAA4B,CAAC;GACnC,IAAI,gBAAgB;GAEpB,OAAO,gBAAgB,OAAO,eAAe;IAC3C,MAAM,QAAQ,KAAK,IAAI,MAAO,OAAO,gBAAgB,aAAa;IAElE,MAAM,UAAU,eAAe,KAAK;KAClC;KACA,uBAAuB;KACvB;IACF,CAAC;IAED,MAAM,OAAO,OAAO,KAAK,OAAO;IAChC,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK,OAAO;IAElD,IACE,KAAK,WAAW,SAChB,KAAK,MAAM,QAAQ,UAAU,OAAO,aAAa,gBAAgB,QAAQ,CAAC,GAE1E,OAAO,OAAO,yBAAyB,KAAK;KAC1C,OAAO;KACP,QAAQ;KACR,SACE;IACJ,CAAC;IAEH,QAAQ,KAAK,GAAG,IAAI;IACpB,gBAAgB,KAAK,KAAK,SAAS,EAAE,CAAC;GACxC;GAOA,KAAI,OAJK,GAAG,uEAAuE,SAAS,kBAAkB,OAAO,cAAc,UAAU,KACzI,OAAO,SAAS,aAAa,oBAAoB,CAAC,CACpD,EAAA,CAEa,WAAW,GACxB,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ;IACR,SAAS;GACX,CAAC;GAEH,OAAO,gBAAgB,KAAK;IAAE;IAAQ;GAAQ,CAAC;EACjD,CAAC,CACH,CAAC,CACA,KACC,OAAO,SAAS,aAAa,UAC3B,OAAO,KAAK,aAAa,oBAAoB,CAAC,CAAC,KAAK,CAAC,CACvD,CACF;CACJ,CAAC;CAED,MAAM,iBAAiB,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAC3D,YACyC;EACzC,IAAI,WAAW,SAAS,SAAS,uBAC/B,OAAO,OAAO,eAAe,KAAK;GAChC,WAAW;GACX,SAAS;EACX,CAAC;EAEH,OAAO,gBAAgB,mBAAmB,WAAW,cAAc;EACnE,OAAO,qBAAqB,wBAAwB,CAAC,CACnD,OAAO,IAAI,aAAa;GACtB,MAAM,aAAa,OAAO,GAA4B;;;;;;;;8BAQhC,WAAW,SAAS;UACxC,KAAK,OAAO,SAAS,aAAa,sBAAsB,CAAC,CAAC;GAE5D,MAAM,SAAS,OAAO,gBACpB,OAAO,MAAM,SAAS,GACtB,wBACA,WAAW,UACX,UACF;GAEA,IAAI,WAAW,kBAAkB,OAAO,eACtC,OAAO,OAAO,qBAAqB,KAAK,EACtC,SACE,uBAAuB,WAAW,gBAAgB,2BAC/C,OAAO,cAAc,GAC5B,CAAC;GAGH,MAAM,iBAAiB,OAAO,GAA4B;;;;;;;8BAOpC,WAAW,SAAS;qCACb,WAAW,gBAAgB;UACtD,KAAK,OAAO,SAAS,aAAa,4BAA4B,CAAC,CAAC;GAElE,MAAM,WAAW,OAAO,WACtB,OAAO,MAAM,aAAa,GAC1B,4BACA,GAAG,WAAW,SAAS,GAAG,WAAW,mBACrC,cACF;GAEA,IAAI,SAAS,SAAS,GACpB,OAAO,OAAO,yBAAyB,KAAK;IAC1C,OAAO;IACP,QAAQ,GAAG,WAAW,SAAS,GAAG,WAAW;IAC7C,SAAS;GACX,CAAC;GAEH,IAAI,SAAS,WAAW,GAAG;IACzB,IACE,SAAS,EAAE,CAAC,gBAAgB,WAAW,cACvC,SAAS,EAAE,CAAC,oBAAoB,WAAW,gBAE3C,OAAO,OAAO,qBAAqB,KAAK,EACtC,SAAS,oEACX,CAAC;IAGH;GACF;GAEA,OAAO,GAAG;;;;;;;cAOJ,WAAW,SAAS;cACpB,WAAW,gBAAgB;cAC3B,WAAW,WAAW;cACtB,WAAW,eAAe;;UAE9B,KAAK,OAAO,SAAS,aAAa,mBAAmB,CAAC,CAAC;EAC3D,CAAC,CACH;CACF,CAAC;CAED,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,SACA,gBACA;EACA,MAAM,EAAE,eAAe;EAEvB,IAAI,WAAW,SAAS,SAAS,uBAC/B,OAAO,OAAO,eAAe,KAAK;GAChC,WAAW;GACX,SAAS;EACX,CAAC;EAEH,OAAO,gBAAgB,4BAA4B,cAAc;EAEjE,OAAO,UAAU,iCAAiC;EAClD,OAAO,qBAAqB,iCAAiC,CAAC,CAC5D,OAAO,IAAI,aAAa;GAEtB,MAAM,UAAS,OADQ,UAAU,WAAW,QAAQ,EAAA,CAC7B;GAEvB,IAAI,WAAW,KAAA,GACb,OAAO,OAAO,sBAAsB,KAAK,EAAE,UAAU,WAAW,SAAS,CAAC;GAC5E,IAAI,QAAQ,kBAAkB,OAAO,gBACnC,OAAO,OAAO,cAAc,KAAK;IAC/B,UAAU,WAAW;IACrB,aAAa,OAAO;IACpB,gBAAgB,QAAQ;GAC1B,CAAC;GACH,IAAI,WAAW,kBAAkB,OAAO,eACtC,OAAO,OAAO,mBAAmB,KAAK;IACpC,UAAU,WAAW;IACrB,QAAQ;GACV,CAAC;GAEH,MAAM,UACJ,WAAW,oBAAoB,IAC3B,CAAC,iBAAiB,IAClB,OAAO,gBAAgB,WAAW,UAAU,WAAW,eAAe;GAE5E,IAAI,QAAQ,WAAW,KAAK,QAAQ,OAAO,WAAW,YACpD,OAAO,OAAO,mBAAmB,KAAK;IACpC,UAAU,WAAW;IACrB,QAAQ;GACV,CAAC;GAEH,OAAO,GAAG;;oBAEE,WAAW,SAAS,IAAI,WAAW,gBAAgB,IAAI,WAAW,WAAW,IAAI,eAAe;;;;;;UAM1G,KAAK,OAAO,SAAS,aAAa,0BAA0B,CAAC,CAAC;EAClE,CAAC,CACH;EACA,OAAO,UAAU,gCAAgC;CACnD,CAAC;CAED,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,UACA;EACA,MAAM,OAAO,OAAO,GAA4B;;;0BAG1B,SAAS;MAC7B,KAAK,OAAO,SAAS,aAAa,0BAA0B,CAAC,CAAC;EAEhE,OAAO,OAAO,WACZ,OAAO,MAAM,aAAa,GAC1B,qCACA,UACA,IACF;CACF,CAAC;CAED,MAAM,iBAAiB,OAAO,GAAG,0BAA0B,CAAC,CAAC,WAC3D,UACA,oBACA;EACA,MAAM,OAAO,OAAO,GAA4B;;;;;;;0BAO1B,SAAS;kCACD,mBAAmB;;;MAG/C,KAAK,OAAO,SAAS,aAAa,iBAAiB,CAAC,CAAC;EAEvD,OAAO,OAAO,WACZ,OAAO,MAAM,aAAa,GAC1B,4BACA,GAAG,SAAS,IAAI,sBAChB,IACF;CACF,CAAC;CAED,MAAM,kBAAkB,OAAO,GAAG,2BAA2B,CAAC,CAAC,WAC7D,UACA,UACA;EACA,IAAI,aAAa,GAAG;GAClB,MAAM,UAAU,OAAO,UAAU,QAAQ;GAEzC,OAAO,QAAQ,WAAW,IACtB,CAAC,IACD,CAAC,QAAQ,EAAE,CAAC,kBAAkB,IAAI,QAAQ,EAAE,CAAC,cAAc,KAAA,CAAS,CAAC,CAAC,QACnE,UAA2B,UAAU,KAAA,CACxC;EACN;EAEA,MAAM,OAAO,OAAO,GAA4B;;;;;;;;;;0BAU1B,SAAS;8BACL,SAAS;MACjC,KAAK,OAAO,SAAS,aAAa,mCAAmC,CAAC,CAAC;EASzE,QAAO,OAPgB,WACrB,OAAO,MAAM,QAAQ,GACrB,kCACA,GAAG,SAAS,GAAG,YACf,IACF,EAAA,CAEe,KAAK,UAAU,MAAM,WAAW;CACjD,CAAC;CAsFD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,oBAhGyB,OAAO,GAAG,8BAA8B,CAAC,CAAC,aAAa;GAChF,OAAO,OAAO,IACX,gBACC,OAAO,IAAI,aAAa;IACtB,MAAM,UAAU,OAAO,GAA4B;;;;;;;;;YASjD,KAAK,OAAO,SAAS,aAAa,cAAc,CAAC,CAAC;IAEpD,MAAM,UAAU,OAAO,GAA4B;;;;;;;;;;;YAWjD,KAAK,OAAO,SAAS,aAAa,wBAAwB,CAAC,CAAC;IAE9D,MAAM,UAAU,OAAO,GAA4B;;;;;;;;;YASjD,KAAK,OAAO,SAAS,aAAa,wBAAwB,CAAC,CAAC;IAE9D,MAAM,cAAc,OAAO,GAA4B;;;;;;;;YAQrD,KAAK,OAAO,SAAS,aAAa,kBAAkB,CAAC,CAAC;IAExD,OAAO;KACL,SAAS,OAAO,WACd,OAAO,MAAM,SAAS,GACtB,wBACA,gBACA,OACF;KACA,SAAS,OAAO,WACd,OAAO,MAAM,QAAQ,GACrB,kCACA,gBACA,OACF;KACA,SAAS,OAAO,WACd,OAAO,MAAM,SAAS,GACtB,kCACA,gBACA,OACF;KACA,aAAa,OAAO,WAClB,OAAO,MAAM,aAAa,GAC1B,4BACA,gBACA,WACF;IACF;GACF,CAAC,CACH,CAAC,CACA,KACC,OAAO,SAAS,aAAa,UAC3B,OAAO,KAAK,aAAa,0BAA0B,CAAC,CAAC,KAAK,CAAC,CAC7D,CACF;EACJ,CAcmB;EACjB;CACF;AACF;AAIA,MAAa,sBAAsB"}
|