@yielded/agent-storage-cloudflare 0.1.0-beta.167 → 0.1.0-beta.168
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/DoMemoryStore.mjs +1 -1
- package/dist/DoMessageDeliveryStore.d.mts +1 -1
- package/dist/DoMessageDeliveryStore.mjs +3 -2
- package/dist/DoMessageDeliveryStore.mjs.map +1 -1
- package/dist/DoScheduleStore.mjs +16 -37
- package/dist/DoScheduleStore.mjs.map +1 -1
- package/dist/DoStorageConfig.d.mts +2 -10
- package/dist/DoStorageConfig.mjs +2 -11
- package/dist/DoStorageConfig.mjs.map +1 -1
- package/dist/{DoStorageError-CGuAfSwF.d.mts → DoStorageError-CxjMnzUA.d.mts} +7 -18
- package/dist/DoStorageError.d.mts +2 -2
- package/dist/DoStorageError.mjs +14 -30
- package/dist/DoStorageError.mjs.map +1 -1
- package/dist/DoStorageFailpoint.d.mts +1 -1
- package/dist/DoStorageFailpointTesting.d.mts +1 -1
- package/dist/{DoStorageVersion-iNSyi3cJ.d.mts → DoStorageVersion-DTFoLglB.d.mts} +3 -4
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoStorageVersion.mjs.map +1 -1
- package/dist/DoSubmissionLedger.d.mts +7 -5
- package/dist/DoSubmissionLedger.mjs +378 -528
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/DoSubscriptionStore.mjs +5 -24
- package/dist/DoSubscriptionStore.mjs.map +1 -1
- package/dist/{DoThreadStore-D_83OjCH.d.mts → DoThreadStore-Bd4fTns3.d.mts} +17 -18
- package/dist/DoThreadStore-CwBvTLoq.mjs +468 -0
- package/dist/DoThreadStore-CwBvTLoq.mjs.map +1 -0
- package/dist/DoThreadStore.d.mts +2 -2
- package/dist/DoThreadStore.mjs +4 -529
- package/dist/MemoryProtocol.mjs +3 -3
- package/dist/MemoryProtocol.mjs.map +1 -1
- package/dist/PortProtocol.d.mts +11727 -3410
- package/dist/PortProtocol.mjs +103 -15
- package/dist/PortProtocol.mjs.map +1 -1
- package/dist/PortRouting.d.mts +14 -9
- package/dist/PortRouting.mjs +155 -29
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/do-journal-Cawnsetj.mjs +761 -0
- package/dist/do-journal-Cawnsetj.mjs.map +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/migrations-D_EP3KYf.mjs +148 -0
- package/dist/migrations-D_EP3KYf.mjs.map +1 -0
- package/dist/{owned-state-DHm2aRXx.mjs → owned-state-BHzUi0eb.mjs} +50 -19
- package/dist/owned-state-BHzUi0eb.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoMessageDeliveryStore.ts +2 -1
- package/src/DoScheduleStore.ts +19 -59
- package/src/DoStorageConfig.ts +2 -11
- package/src/DoStorageError.ts +3 -26
- package/src/DoStorageVersion.ts +1 -1
- package/src/DoSubmissionLedger.ts +1806 -2030
- package/src/DoSubscriptionStore.ts +5 -47
- package/src/DoThreadStore.ts +276 -622
- package/src/MemoryProtocol.ts +3 -3
- package/src/PortProtocol.ts +198 -12
- package/src/PortRouting.ts +527 -108
- package/src/internal/canonical-append.ts +15 -0
- package/src/internal/do-journal.ts +548 -1440
- package/src/internal/migrations.ts +184 -287
- package/src/internal/owned-state.ts +81 -30
- package/src/internal/prompt-checkpoint.ts +158 -0
- package/src/internal/storage-span.ts +2 -5
- package/dist/DoThreadStore.mjs.map +0 -1
- package/dist/do-journal-DUhjZkOf.mjs +0 -1352
- package/dist/do-journal-DUhjZkOf.mjs.map +0 -1
- package/dist/migrations-DtKz_Gxr.mjs +0 -306
- package/dist/migrations-DtKz_Gxr.mjs.map +0 -1
- package/dist/owned-state-DHm2aRXx.mjs.map +0 -1
- package/src/internal/message-delivery-schema.ts +0 -24
- package/src/internal/recovery-checkpoint-schema.ts +0 -17
package/src/PortRouting.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { DurableRuntimeFailpoint } from "@yielded/agent/durable-failpoint";
|
|
2
2
|
import { LifecyclePublicationError } from "@yielded/agent/lifecycle-publication";
|
|
3
3
|
import { MessageDeliveryStore, MessageDeliveryError } from "@yielded/agent/message-delivery";
|
|
4
|
+
import {
|
|
5
|
+
SettlementPublisher,
|
|
6
|
+
type SettlementPublicationResult,
|
|
7
|
+
type SettlementPublicationFailure,
|
|
8
|
+
} from "@yielded/agent/settlement-publisher";
|
|
4
9
|
import {
|
|
5
10
|
AdmissionIndeterminate,
|
|
6
11
|
AdmissionConflict,
|
|
@@ -8,6 +13,7 @@ import {
|
|
|
8
13
|
ChildAttachmentSnapshot,
|
|
9
14
|
JoinedToHost,
|
|
10
15
|
LedgerError,
|
|
16
|
+
OwnershipLost,
|
|
11
17
|
RecoverySnapshot,
|
|
12
18
|
SettlementConflict,
|
|
13
19
|
SubmissionLedger,
|
|
@@ -19,10 +25,13 @@ import {
|
|
|
19
25
|
AppendConflict,
|
|
20
26
|
ThreadMaterialization,
|
|
21
27
|
ThreadNotMaterialized,
|
|
28
|
+
ThreadExportRejected,
|
|
22
29
|
ThreadStore,
|
|
30
|
+
ThreadReader,
|
|
23
31
|
ThreadStoreError,
|
|
24
|
-
FenceRejected,
|
|
25
32
|
} from "@yielded/agent/thread-store";
|
|
33
|
+
import { checkExportSource } from "@yielded/agent/thread-transfer";
|
|
34
|
+
import { WorkDiscoveryUnavailable } from "@yielded/agent/thread-work";
|
|
26
35
|
import type { WakeScheduler } from "@yielded/agent/wake-scheduler";
|
|
27
36
|
import {
|
|
28
37
|
admitWorker,
|
|
@@ -32,6 +41,8 @@ import {
|
|
|
32
41
|
import { Cause, Clock, Context, Effect, Layer, Option, Predicate, Schema, Stream } from "effect";
|
|
33
42
|
|
|
34
43
|
import {
|
|
44
|
+
SettlementPublishCall,
|
|
45
|
+
SettlementPublishResult,
|
|
35
46
|
WorkerAdmitCall,
|
|
36
47
|
WorkerAdmitResult,
|
|
37
48
|
MessageDeliveryListCall,
|
|
@@ -45,6 +56,8 @@ import {
|
|
|
45
56
|
encodePortResponse,
|
|
46
57
|
LedgerAdmitCall,
|
|
47
58
|
LedgerAdmitResult,
|
|
59
|
+
LedgerFundingOwnerCall,
|
|
60
|
+
LedgerFundingOwnerResult,
|
|
48
61
|
LedgerLookupCall,
|
|
49
62
|
LedgerLookupResult,
|
|
50
63
|
LedgerMarkReadyCall,
|
|
@@ -62,6 +75,14 @@ import {
|
|
|
62
75
|
PortFailed,
|
|
63
76
|
PortProtocolError,
|
|
64
77
|
PortSucceeded,
|
|
78
|
+
StoreRangePageCall,
|
|
79
|
+
StoreRangePageResult,
|
|
80
|
+
StoreRangeSealCall,
|
|
81
|
+
StoreRangeSealResult,
|
|
82
|
+
StoreRangeArchiveCall,
|
|
83
|
+
StoreRangeArchiveResult,
|
|
84
|
+
StoreRangeVerifyCall,
|
|
85
|
+
StoreRangeVerifyResult,
|
|
65
86
|
StoreAppendCall,
|
|
66
87
|
StoreAppendResult,
|
|
67
88
|
StoreCountPeerMessagesCall,
|
|
@@ -70,12 +91,24 @@ import {
|
|
|
70
91
|
StoreExportResult,
|
|
71
92
|
StoreInspectTailCall,
|
|
72
93
|
StoreInspectTailResult,
|
|
94
|
+
StoreWorkerCapacityCall,
|
|
95
|
+
StoreWorkerCapacityResult,
|
|
96
|
+
StoreVerificationCall,
|
|
97
|
+
StoreVerificationResult,
|
|
73
98
|
StoreReadIdentityCall,
|
|
74
99
|
StoreReadIdentityResult,
|
|
100
|
+
StoreReadExecutionCall,
|
|
101
|
+
StoreReadExecutionResult,
|
|
75
102
|
StoreMaterializeCall,
|
|
76
103
|
StoreMaterializeResult,
|
|
77
104
|
StoreReadPageCall,
|
|
78
105
|
StoreReadPageResult,
|
|
106
|
+
StoreReadPromptCall,
|
|
107
|
+
StoreReadPromptResult,
|
|
108
|
+
StoreWorkPageCall,
|
|
109
|
+
StoreWorkPageResult,
|
|
110
|
+
StoreWorkRebuildCall,
|
|
111
|
+
StoreWorkRebuildResult,
|
|
79
112
|
type PortFailure,
|
|
80
113
|
type PortRequest,
|
|
81
114
|
type PortRequestEnvelope,
|
|
@@ -89,6 +122,12 @@ type SubmissionId = SubmissionSnapshot["submissionId"];
|
|
|
89
122
|
const ThreadIdSchema = ThreadMaterialization.fields.threadId;
|
|
90
123
|
const decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);
|
|
91
124
|
|
|
125
|
+
/** Owner-local maintenance scope; permits local inventory without global Object enumeration. */
|
|
126
|
+
export const CurrentNativeSource = Context.Reference<boolean>(
|
|
127
|
+
"@effect-agent/storage-cloudflare/CurrentNativeSource",
|
|
128
|
+
{ defaultValue: () => false },
|
|
129
|
+
);
|
|
130
|
+
|
|
92
131
|
/**
|
|
93
132
|
* The ledger row bound routable Submission identities must respect (mirrors the local
|
|
94
133
|
* facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed
|
|
@@ -200,7 +239,7 @@ const LOCAL: RouteTarget = { _tag: "local" };
|
|
|
200
239
|
const routableSubmissionTarget = (
|
|
201
240
|
ownsThread: RoutedPortOptions["ownsThread"],
|
|
202
241
|
): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>
|
|
203
|
-
Effect.
|
|
242
|
+
Effect.fnUntraced(function* (
|
|
204
243
|
operation: string,
|
|
205
244
|
submissionId: string,
|
|
206
245
|
): Effect.fn.Return<RouteTarget, LedgerError> {
|
|
@@ -239,7 +278,7 @@ export const makeLocalSubmissionLookup = (
|
|
|
239
278
|
) => Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError, SubmissionLedger>) => {
|
|
240
279
|
const submissionTarget = routableSubmissionTarget(options.ownsThread);
|
|
241
280
|
|
|
242
|
-
return Effect.
|
|
281
|
+
return Effect.fnUntraced(function* (submissionId: SubmissionId) {
|
|
243
282
|
const operation = "local Submission lookup";
|
|
244
283
|
const target = yield* submissionTarget(operation, submissionId);
|
|
245
284
|
|
|
@@ -264,7 +303,7 @@ export const makeLocalSubmissionLookup = (
|
|
|
264
303
|
|
|
265
304
|
const NoAdditionalPortFailure = Schema.Never;
|
|
266
305
|
const AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);
|
|
267
|
-
const AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict,
|
|
306
|
+
const AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, OwnershipLost]);
|
|
268
307
|
|
|
269
308
|
/**
|
|
270
309
|
* The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset
|
|
@@ -285,13 +324,13 @@ const crossThreadStoreError = (operation: string, target: string): ThreadStoreEr
|
|
|
285
324
|
operation,
|
|
286
325
|
message:
|
|
287
326
|
`${operation} addressed to foreign Thread ${target} is not route-capable; the ` +
|
|
288
|
-
"closed cross-Object subset is materialize, append, read (paged), inspectTail, and " +
|
|
327
|
+
"closed cross-Object subset is materialize, append, read and readPrompt (paged), inspectTail, and " +
|
|
289
328
|
"export. Observation and checkpoints are lane-local by construction and must execute " +
|
|
290
329
|
"inside the owning Thread's Durable Object.",
|
|
291
330
|
});
|
|
292
331
|
|
|
293
332
|
const makeTransportCall = (transport: ThreadPortTransport["Service"]) =>
|
|
294
|
-
Effect.
|
|
333
|
+
Effect.fnUntraced(function* (target: ThreadId, call: PortRequest) {
|
|
295
334
|
const encoded = yield* encodePortRequest(call).pipe(
|
|
296
335
|
Effect.mapError((error) =>
|
|
297
336
|
PortProtocolError.make({
|
|
@@ -313,9 +352,7 @@ const makeTransportCall = (transport: ThreadPortTransport["Service"]) =>
|
|
|
313
352
|
|
|
314
353
|
type TransportCall = ReturnType<typeof makeTransportCall>;
|
|
315
354
|
|
|
316
|
-
const makeRoutedLedgerServices = Effect.
|
|
317
|
-
options: RoutedPortOptions,
|
|
318
|
-
) {
|
|
355
|
+
const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPortOptions) {
|
|
319
356
|
const local = yield* SubmissionLedger;
|
|
320
357
|
const transport = yield* ThreadPortTransport;
|
|
321
358
|
const transportCall: TransportCall = makeTransportCall(transport);
|
|
@@ -480,7 +517,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
480
517
|
* local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm
|
|
481
518
|
* pass retries; the child's canonical Settlement remains the only authority (DUR-015).
|
|
482
519
|
*/
|
|
483
|
-
const enrichChildAttachments = Effect.
|
|
520
|
+
const enrichChildAttachments = Effect.fnUntraced(function* (
|
|
484
521
|
snapshot: RecoverySnapshot,
|
|
485
522
|
): Effect.fn.Return<RecoverySnapshot, LedgerError> {
|
|
486
523
|
const operation = "ledger load recovery snapshot";
|
|
@@ -582,6 +619,37 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
582
619
|
),
|
|
583
620
|
),
|
|
584
621
|
|
|
622
|
+
resolveFundingOwner: (request) =>
|
|
623
|
+
(options.ownsThread(request.threadId)
|
|
624
|
+
? local.resolveFundingOwner === undefined
|
|
625
|
+
? Effect.fail(
|
|
626
|
+
LedgerError.make({
|
|
627
|
+
operation: "resolve funding owner",
|
|
628
|
+
message: "Native funding-owner lookup unavailable.",
|
|
629
|
+
}),
|
|
630
|
+
)
|
|
631
|
+
: local.resolveFundingOwner(request)
|
|
632
|
+
: foreignLedgerCall(
|
|
633
|
+
"resolve funding owner",
|
|
634
|
+
request.threadId,
|
|
635
|
+
LedgerFundingOwnerCall.make({ request }),
|
|
636
|
+
LedgerFundingOwnerResult,
|
|
637
|
+
NoAdditionalPortFailure,
|
|
638
|
+
).pipe(Effect.map((reply) => reply.funding))
|
|
639
|
+
).pipe(
|
|
640
|
+
Effect.filterOrFail(
|
|
641
|
+
(funding) =>
|
|
642
|
+
funding.selected.submissionId === request.submissionId &&
|
|
643
|
+
funding.selected.threadId === request.threadId &&
|
|
644
|
+
funding.owner.threadId === request.threadId,
|
|
645
|
+
() =>
|
|
646
|
+
LedgerError.make({
|
|
647
|
+
operation: "resolve funding owner",
|
|
648
|
+
message: "Funding-owner response belongs to another input or Thread.",
|
|
649
|
+
}),
|
|
650
|
+
),
|
|
651
|
+
),
|
|
652
|
+
|
|
585
653
|
resolveAdmission: (request) =>
|
|
586
654
|
options.ownsThread(request.threadId)
|
|
587
655
|
? local.resolveAdmission(request)
|
|
@@ -652,9 +720,9 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
652
720
|
|
|
653
721
|
// Every operation below is lane-local by construction (plan §1.3): a foreign address is
|
|
654
722
|
// an out-of-contract call and fails fast typed instead of being quietly distributed.
|
|
655
|
-
|
|
723
|
+
selectHead: (request) =>
|
|
656
724
|
options.ownsThread(request.threadId)
|
|
657
|
-
? local.
|
|
725
|
+
? local.selectHead(request)
|
|
658
726
|
: Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
|
|
659
727
|
|
|
660
728
|
claimJoining: (request) =>
|
|
@@ -662,24 +730,6 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
662
730
|
? local.claimJoining(request)
|
|
663
731
|
: Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
|
|
664
732
|
|
|
665
|
-
renewOwnership: (request) =>
|
|
666
|
-
submissionTarget("ledger renew ownership", request.submissionId).pipe(
|
|
667
|
-
Effect.flatMap((target) =>
|
|
668
|
-
target._tag === "local"
|
|
669
|
-
? local.renewOwnership(request)
|
|
670
|
-
: Effect.fail(crossThreadLedgerError("ledger renew ownership", target.threadId)),
|
|
671
|
-
),
|
|
672
|
-
),
|
|
673
|
-
|
|
674
|
-
releaseOwnership: (request) =>
|
|
675
|
-
submissionTarget("ledger release ownership", request.submissionId).pipe(
|
|
676
|
-
Effect.flatMap((target) =>
|
|
677
|
-
target._tag === "local"
|
|
678
|
-
? local.releaseOwnership(request)
|
|
679
|
-
: Effect.fail(crossThreadLedgerError("ledger release ownership", target.threadId)),
|
|
680
|
-
),
|
|
681
|
-
),
|
|
682
|
-
|
|
683
733
|
markInputApplied: (request) =>
|
|
684
734
|
submissionTarget("ledger mark input applied", request.submissionId).pipe(
|
|
685
735
|
Effect.flatMap((target) =>
|
|
@@ -689,15 +739,6 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
689
739
|
),
|
|
690
740
|
),
|
|
691
741
|
|
|
692
|
-
reserveSettlement: (request) =>
|
|
693
|
-
submissionTarget("ledger reserve settlement", request.submissionId).pipe(
|
|
694
|
-
Effect.flatMap((target) =>
|
|
695
|
-
target._tag === "local"
|
|
696
|
-
? local.reserveSettlement(request)
|
|
697
|
-
: Effect.fail(crossThreadLedgerError("ledger reserve settlement", target.threadId)),
|
|
698
|
-
),
|
|
699
|
-
),
|
|
700
|
-
|
|
701
742
|
finalizeSettlement: (request) =>
|
|
702
743
|
submissionTarget("ledger finalize settlement", request.submissionId).pipe(
|
|
703
744
|
Effect.flatMap((target) =>
|
|
@@ -806,12 +847,71 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
806
847
|
return Context.make(SubmissionLedger, routed);
|
|
807
848
|
});
|
|
808
849
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
)
|
|
850
|
+
/** Route the data-only atomic publication to the same owner as its canonical Thread. */
|
|
851
|
+
export const routedSettlementPublisherLayer = (options: RoutedPortOptions) =>
|
|
852
|
+
Layer.effect(SettlementPublisher)(
|
|
853
|
+
Effect.gen(function* () {
|
|
854
|
+
const local = yield* SettlementPublisher;
|
|
855
|
+
const call = makeTransportCall(yield* ThreadPortTransport);
|
|
856
|
+
|
|
857
|
+
const isFailure = Schema.is(
|
|
858
|
+
Schema.Union([
|
|
859
|
+
LedgerError,
|
|
860
|
+
OwnershipLost,
|
|
861
|
+
SettlementConflict,
|
|
862
|
+
ThreadStoreError,
|
|
863
|
+
ThreadNotMaterialized,
|
|
864
|
+
AppendConflict,
|
|
865
|
+
]),
|
|
866
|
+
);
|
|
867
|
+
|
|
868
|
+
return SettlementPublisher.of({
|
|
869
|
+
publish: (request) => {
|
|
870
|
+
if (options.ownsThread(request.append.threadId)) return local.publish(request);
|
|
871
|
+
|
|
872
|
+
return call(request.append.threadId, SettlementPublishCall.make({ request })).pipe(
|
|
873
|
+
Effect.mapError((cause) =>
|
|
874
|
+
LedgerError.make({
|
|
875
|
+
operation: "route settlement publication",
|
|
876
|
+
message: cause.message,
|
|
877
|
+
cause,
|
|
878
|
+
}),
|
|
879
|
+
),
|
|
880
|
+
Effect.flatMap(
|
|
881
|
+
(
|
|
882
|
+
response,
|
|
883
|
+
): Effect.Effect<SettlementPublicationResult, SettlementPublicationFailure> => {
|
|
884
|
+
if (response._tag === "PortFailed")
|
|
885
|
+
return isFailure(response.failure)
|
|
886
|
+
? Effect.fail(response.failure)
|
|
887
|
+
: Effect.fail(
|
|
888
|
+
LedgerError.make({
|
|
889
|
+
operation: "route settlement publication",
|
|
890
|
+
message: "Unexpected publication failure",
|
|
891
|
+
cause: response.failure,
|
|
892
|
+
}),
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
return response.result._tag === "SettlementPublishResult"
|
|
896
|
+
? Effect.succeed(response.result.result)
|
|
897
|
+
: Effect.fail(
|
|
898
|
+
LedgerError.make({
|
|
899
|
+
operation: "route settlement publication",
|
|
900
|
+
message: "Mismatched publication result",
|
|
901
|
+
}),
|
|
902
|
+
);
|
|
903
|
+
},
|
|
904
|
+
),
|
|
905
|
+
);
|
|
906
|
+
},
|
|
907
|
+
});
|
|
908
|
+
}),
|
|
909
|
+
);
|
|
910
|
+
|
|
911
|
+
const makeRoutedStoreServices = Effect.fnUntraced(function* (options: RoutedPortOptions) {
|
|
812
912
|
const local = yield* ThreadStore;
|
|
813
913
|
const checkpoints = local.checkpoints;
|
|
814
|
-
const
|
|
914
|
+
const promptCheckpoints = local.promptCheckpoints;
|
|
815
915
|
const lifecyclePublications = local.lifecyclePublications;
|
|
816
916
|
const acknowledgeMany = lifecyclePublications?.acknowledgeMany;
|
|
817
917
|
const transport = yield* ThreadPortTransport;
|
|
@@ -885,6 +985,161 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
885
985
|
};
|
|
886
986
|
|
|
887
987
|
const routed = ThreadStore.of({
|
|
988
|
+
readExecution: (request) =>
|
|
989
|
+
options.ownsThread(request.threadId)
|
|
990
|
+
? local.readExecution(request)
|
|
991
|
+
: foreignStoreCall(
|
|
992
|
+
"read execution",
|
|
993
|
+
request.threadId,
|
|
994
|
+
StoreReadExecutionCall.make({ request }),
|
|
995
|
+
StoreReadExecutionResult,
|
|
996
|
+
ThreadNotMaterialized,
|
|
997
|
+
).pipe(Effect.map((reply) => reply.checkpoint)),
|
|
998
|
+
archives: {
|
|
999
|
+
page: (request) =>
|
|
1000
|
+
options.ownsThread(request.threadId)
|
|
1001
|
+
? local.archives === undefined
|
|
1002
|
+
? Effect.fail(crossThreadStoreError("archive unavailable", request.threadId))
|
|
1003
|
+
: local.archives.page(request)
|
|
1004
|
+
: foreignStoreCall(
|
|
1005
|
+
"archive page",
|
|
1006
|
+
request.threadId,
|
|
1007
|
+
StoreRangePageCall.make({ request }),
|
|
1008
|
+
StoreRangePageResult,
|
|
1009
|
+
ThreadNotMaterialized,
|
|
1010
|
+
).pipe(Effect.map((reply) => reply.page)),
|
|
1011
|
+
seal: (request) =>
|
|
1012
|
+
options.ownsThread(request.threadId)
|
|
1013
|
+
? local.archives === undefined
|
|
1014
|
+
? Effect.fail(crossThreadStoreError("archive unavailable", request.threadId))
|
|
1015
|
+
: local.archives.seal(request)
|
|
1016
|
+
: foreignStoreCall(
|
|
1017
|
+
"archive seal",
|
|
1018
|
+
request.threadId,
|
|
1019
|
+
StoreRangeSealCall.make({ request }),
|
|
1020
|
+
StoreRangeSealResult,
|
|
1021
|
+
ThreadNotMaterialized,
|
|
1022
|
+
).pipe(Effect.map((reply) => reply.range)),
|
|
1023
|
+
archive: (request) =>
|
|
1024
|
+
options.ownsThread(request.threadId)
|
|
1025
|
+
? local.archives === undefined
|
|
1026
|
+
? Effect.fail(crossThreadStoreError("archive unavailable", request.threadId))
|
|
1027
|
+
: local.archives.archive(request)
|
|
1028
|
+
: foreignStoreCall(
|
|
1029
|
+
"archive archive",
|
|
1030
|
+
request.threadId,
|
|
1031
|
+
StoreRangeArchiveCall.make({ request }),
|
|
1032
|
+
StoreRangeArchiveResult,
|
|
1033
|
+
ThreadNotMaterialized,
|
|
1034
|
+
).pipe(Effect.map((reply) => reply.range)),
|
|
1035
|
+
verify: (request) =>
|
|
1036
|
+
options.ownsThread(request.threadId)
|
|
1037
|
+
? local.archives === undefined
|
|
1038
|
+
? Effect.fail(crossThreadStoreError("archive unavailable", request.threadId))
|
|
1039
|
+
: local.archives.verify(request)
|
|
1040
|
+
: foreignStoreCall(
|
|
1041
|
+
"archive verify",
|
|
1042
|
+
request.threadId,
|
|
1043
|
+
StoreRangeVerifyCall.make({ request }),
|
|
1044
|
+
StoreRangeVerifyResult,
|
|
1045
|
+
ThreadNotMaterialized,
|
|
1046
|
+
).pipe(Effect.map((reply) => reply.range)),
|
|
1047
|
+
},
|
|
1048
|
+
work: {
|
|
1049
|
+
threads: (request) =>
|
|
1050
|
+
Effect.flatMap(CurrentNativeSource, (nativeSource) =>
|
|
1051
|
+
nativeSource && local.work !== undefined
|
|
1052
|
+
? local.work.threads(request)
|
|
1053
|
+
: Effect.fail(
|
|
1054
|
+
ThreadStoreError.make({
|
|
1055
|
+
operation: "work threads",
|
|
1056
|
+
message: nativeSource
|
|
1057
|
+
? "The local Thread owner does not provide work inventory."
|
|
1058
|
+
: "Global Thread enumeration is unsupported by the owner-local Durable Object namespace. Use the local owner's work storage.",
|
|
1059
|
+
}),
|
|
1060
|
+
),
|
|
1061
|
+
),
|
|
1062
|
+
page: (request) =>
|
|
1063
|
+
options.ownsThread(request.threadId)
|
|
1064
|
+
? local.work === undefined
|
|
1065
|
+
? Effect.fail(
|
|
1066
|
+
WorkDiscoveryUnavailable.make({
|
|
1067
|
+
threadId: request.threadId,
|
|
1068
|
+
reason: "unsupported",
|
|
1069
|
+
}),
|
|
1070
|
+
)
|
|
1071
|
+
: local.work.page(request)
|
|
1072
|
+
: foreignStoreCall(
|
|
1073
|
+
"work page",
|
|
1074
|
+
request.threadId,
|
|
1075
|
+
StoreWorkPageCall.make({ request }),
|
|
1076
|
+
StoreWorkPageResult,
|
|
1077
|
+
WorkDiscoveryUnavailable,
|
|
1078
|
+
).pipe(Effect.map((reply) => reply.page)),
|
|
1079
|
+
rebuild: (request) =>
|
|
1080
|
+
options.ownsThread(request.threadId)
|
|
1081
|
+
? local.work === undefined
|
|
1082
|
+
? Effect.fail(
|
|
1083
|
+
WorkDiscoveryUnavailable.make({
|
|
1084
|
+
threadId: request.threadId,
|
|
1085
|
+
reason: "unsupported",
|
|
1086
|
+
}),
|
|
1087
|
+
)
|
|
1088
|
+
: local.work.rebuild(request)
|
|
1089
|
+
: foreignStoreCall(
|
|
1090
|
+
"rebuild work",
|
|
1091
|
+
request.threadId,
|
|
1092
|
+
StoreWorkRebuildCall.make({ request }),
|
|
1093
|
+
StoreWorkRebuildResult,
|
|
1094
|
+
WorkDiscoveryUnavailable,
|
|
1095
|
+
).pipe(
|
|
1096
|
+
Effect.flatMap((reply) =>
|
|
1097
|
+
reply.progress.threadId === request.threadId
|
|
1098
|
+
? Effect.succeed(reply.progress)
|
|
1099
|
+
: Effect.fail(
|
|
1100
|
+
ThreadStoreError.make({
|
|
1101
|
+
operation: "rebuild work",
|
|
1102
|
+
message: "The rebuild progress belongs to another Thread.",
|
|
1103
|
+
}),
|
|
1104
|
+
),
|
|
1105
|
+
),
|
|
1106
|
+
),
|
|
1107
|
+
},
|
|
1108
|
+
readWorkerCapacity: (request) =>
|
|
1109
|
+
(options.ownsThread(request.threadId)
|
|
1110
|
+
? local.readWorkerCapacity === undefined
|
|
1111
|
+
? Effect.fail(crossThreadStoreError("worker capacity unavailable", request.threadId))
|
|
1112
|
+
: local.readWorkerCapacity(request)
|
|
1113
|
+
: foreignStoreCall(
|
|
1114
|
+
"worker capacity",
|
|
1115
|
+
request.threadId,
|
|
1116
|
+
StoreWorkerCapacityCall.make({ request }),
|
|
1117
|
+
StoreWorkerCapacityResult,
|
|
1118
|
+
ThreadNotMaterialized,
|
|
1119
|
+
).pipe(Effect.map((reply) => reply.capacity))
|
|
1120
|
+
).pipe(
|
|
1121
|
+
Effect.filterOrFail(
|
|
1122
|
+
(capacity) =>
|
|
1123
|
+
capacity.threadId === request.threadId &&
|
|
1124
|
+
capacity.tailSequence === request.expectedTailSequence,
|
|
1125
|
+
() => crossThreadStoreError("worker capacity response mismatch", request.threadId),
|
|
1126
|
+
),
|
|
1127
|
+
),
|
|
1128
|
+
verification: {
|
|
1129
|
+
verify: (request) =>
|
|
1130
|
+
options.ownsThread(request.threadId)
|
|
1131
|
+
? local.verification === undefined
|
|
1132
|
+
? Effect.fail(crossThreadStoreError("verification unavailable", request.threadId))
|
|
1133
|
+
: local.verification.verify(request)
|
|
1134
|
+
: foreignStoreCall(
|
|
1135
|
+
"thread verification",
|
|
1136
|
+
request.threadId,
|
|
1137
|
+
StoreVerificationCall.make({ request }),
|
|
1138
|
+
StoreVerificationResult,
|
|
1139
|
+
ThreadNotMaterialized,
|
|
1140
|
+
).pipe(Effect.map((reply) => reply.report)),
|
|
1141
|
+
},
|
|
1142
|
+
|
|
888
1143
|
countPeerMessages: (request) =>
|
|
889
1144
|
options.ownsThread(request.threadId)
|
|
890
1145
|
? local.countPeerMessages === undefined
|
|
@@ -906,7 +1161,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
906
1161
|
request.threadId,
|
|
907
1162
|
StoreMaterializeCall.make({ request }),
|
|
908
1163
|
StoreMaterializeResult,
|
|
909
|
-
|
|
1164
|
+
NoAdditionalPortFailure,
|
|
910
1165
|
).pipe(Effect.asVoid),
|
|
911
1166
|
|
|
912
1167
|
append: (request) =>
|
|
@@ -933,6 +1188,19 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
933
1188
|
).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),
|
|
934
1189
|
),
|
|
935
1190
|
|
|
1191
|
+
readPrompt: (request) =>
|
|
1192
|
+
options.ownsThread(request.threadId)
|
|
1193
|
+
? local.readPrompt(request)
|
|
1194
|
+
: Stream.unwrap(
|
|
1195
|
+
foreignStoreCall(
|
|
1196
|
+
"thread read prompt",
|
|
1197
|
+
request.threadId,
|
|
1198
|
+
StoreReadPromptCall.make({ request }),
|
|
1199
|
+
StoreReadPromptResult,
|
|
1200
|
+
ThreadNotMaterialized,
|
|
1201
|
+
).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),
|
|
1202
|
+
),
|
|
1203
|
+
|
|
936
1204
|
inspectTail: (request) =>
|
|
937
1205
|
options.ownsThread(request.threadId)
|
|
938
1206
|
? local.inspectTail(request)
|
|
@@ -967,19 +1235,22 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
967
1235
|
),
|
|
968
1236
|
|
|
969
1237
|
export: (request) =>
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1238
|
+
checkExportSource(request.threadId).pipe(
|
|
1239
|
+
Effect.andThen(
|
|
1240
|
+
options.ownsThread(request.threadId)
|
|
1241
|
+
? local.export(request)
|
|
1242
|
+
: foreignStoreCall(
|
|
1243
|
+
"thread export",
|
|
1244
|
+
request.threadId,
|
|
1245
|
+
StoreExportCall.make({ request }),
|
|
1246
|
+
StoreExportResult,
|
|
1247
|
+
Schema.Union([ThreadNotMaterialized, ThreadExportRejected]),
|
|
1248
|
+
).pipe(Effect.map((reply) => reply.export)),
|
|
1249
|
+
),
|
|
1250
|
+
),
|
|
979
1251
|
|
|
980
1252
|
// Observation and checkpoints are lane-local: the closed route-capable store subset
|
|
981
|
-
//
|
|
982
|
-
// to those canonical reads, including when the cache belongs to a foreign Object.
|
|
1253
|
+
// includes exact-Thread work pages and rebuild, but no global Object enumeration.
|
|
983
1254
|
observe: (request) =>
|
|
984
1255
|
options.ownsThread(request.threadId)
|
|
985
1256
|
? local.observe(request)
|
|
@@ -1015,39 +1286,34 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
|
|
|
1015
1286
|
: Effect.fail(LifecyclePublicationError.make({ reason: "unavailable" })),
|
|
1016
1287
|
},
|
|
1017
1288
|
}),
|
|
1018
|
-
...(
|
|
1289
|
+
...(checkpoints === undefined
|
|
1019
1290
|
? {}
|
|
1020
1291
|
: {
|
|
1021
|
-
|
|
1292
|
+
checkpoints: {
|
|
1022
1293
|
save: (request) =>
|
|
1023
1294
|
options.ownsThread(request.checkpoint.threadId)
|
|
1024
|
-
?
|
|
1295
|
+
? checkpoints.save(request)
|
|
1025
1296
|
: Effect.fail(
|
|
1026
|
-
crossThreadStoreError(
|
|
1027
|
-
"thread save recovery checkpoint",
|
|
1028
|
-
request.checkpoint.threadId,
|
|
1029
|
-
),
|
|
1297
|
+
crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId),
|
|
1030
1298
|
),
|
|
1031
1299
|
load: (request) =>
|
|
1032
1300
|
options.ownsThread(request.threadId)
|
|
1033
|
-
?
|
|
1034
|
-
: Effect.
|
|
1301
|
+
? checkpoints.load(request)
|
|
1302
|
+
: Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId)),
|
|
1035
1303
|
},
|
|
1036
1304
|
}),
|
|
1037
|
-
...(
|
|
1305
|
+
...(promptCheckpoints === undefined
|
|
1038
1306
|
? {}
|
|
1039
1307
|
: {
|
|
1040
|
-
|
|
1308
|
+
promptCheckpoints: {
|
|
1041
1309
|
save: (request) =>
|
|
1042
|
-
options.ownsThread(request.
|
|
1043
|
-
?
|
|
1044
|
-
: Effect.fail(
|
|
1045
|
-
crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId),
|
|
1046
|
-
),
|
|
1310
|
+
options.ownsThread(request.threadId)
|
|
1311
|
+
? promptCheckpoints.save(request)
|
|
1312
|
+
: Effect.fail(crossThreadStoreError("save prompt checkpoint", request.threadId)),
|
|
1047
1313
|
load: (request) =>
|
|
1048
1314
|
options.ownsThread(request.threadId)
|
|
1049
|
-
?
|
|
1050
|
-
: Effect.fail(crossThreadStoreError("
|
|
1315
|
+
? promptCheckpoints.load(request)
|
|
1316
|
+
: Effect.fail(crossThreadStoreError("load prompt checkpoint", request.threadId)),
|
|
1051
1317
|
},
|
|
1052
1318
|
}),
|
|
1053
1319
|
});
|
|
@@ -1069,14 +1335,16 @@ export const routedSubmissionLedgerLayer = (
|
|
|
1069
1335
|
|
|
1070
1336
|
/**
|
|
1071
1337
|
* Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread
|
|
1072
|
-
* requests execute locally; foreign
|
|
1073
|
-
* transport.
|
|
1074
|
-
*
|
|
1338
|
+
* requests execute locally; foreign store reads, writes, and exact-Thread work pages/rebuild
|
|
1339
|
+
* travel the transport. Work enumeration stays local under CurrentNativeSource; global
|
|
1340
|
+
* enumeration, foreign checkpoints, and observation fail typed.
|
|
1075
1341
|
*/
|
|
1076
1342
|
export const routedThreadStoreLayer = (
|
|
1077
1343
|
options: RoutedPortOptions,
|
|
1078
|
-
): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>
|
|
1079
|
-
|
|
1344
|
+
): Layer.Layer<ThreadStore | ThreadReader, never, ThreadStore | ThreadPortTransport> =>
|
|
1345
|
+
ThreadReader.layer().pipe(
|
|
1346
|
+
Layer.provideMerge(Layer.effectContext(makeRoutedStoreServices(options))),
|
|
1347
|
+
);
|
|
1080
1348
|
|
|
1081
1349
|
/** Route validated worker admission as one operation; source policy hooks stay at the caller. */
|
|
1082
1350
|
export const routedWorkerAdmissionLayer = (options: RoutedPortOptions) =>
|
|
@@ -1223,14 +1491,105 @@ const capture = <Failure extends PortFailure, R>(
|
|
|
1223
1491
|
* Failures never escape — every typed port failure becomes a `PortFailed` envelope that
|
|
1224
1492
|
* re-decodes on the caller side.
|
|
1225
1493
|
*/
|
|
1226
|
-
export const executePortRequest = Effect.
|
|
1494
|
+
export const executePortRequest = Effect.fnUntraced(function* (
|
|
1227
1495
|
request: PortRequest,
|
|
1228
1496
|
): Effect.fn.Return<
|
|
1229
1497
|
PortResponse,
|
|
1230
1498
|
never,
|
|
1231
|
-
|
|
1499
|
+
| SubmissionLedger
|
|
1500
|
+
| SettlementPublisher
|
|
1501
|
+
| ThreadStore
|
|
1502
|
+
| MessageDeliveryStore
|
|
1503
|
+
| WakeScheduler
|
|
1504
|
+
| DurableRuntimeFailpoint
|
|
1232
1505
|
> {
|
|
1233
1506
|
switch (request._tag) {
|
|
1507
|
+
case "StoreRangePage": {
|
|
1508
|
+
const store = yield* ThreadStore;
|
|
1509
|
+
|
|
1510
|
+
return yield* capture(
|
|
1511
|
+
store.archives === undefined
|
|
1512
|
+
? crossThreadStoreError("archive unavailable", request.request.threadId)
|
|
1513
|
+
: store.archives
|
|
1514
|
+
.page(request.request)
|
|
1515
|
+
.pipe(Effect.map((page) => StoreRangePageResult.make({ page }))),
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
case "StoreRangeSeal": {
|
|
1519
|
+
const store = yield* ThreadStore;
|
|
1520
|
+
|
|
1521
|
+
return yield* capture(
|
|
1522
|
+
store.archives === undefined
|
|
1523
|
+
? crossThreadStoreError("archive unavailable", request.request.threadId)
|
|
1524
|
+
: store.archives
|
|
1525
|
+
.seal(request.request)
|
|
1526
|
+
.pipe(Effect.map((range) => StoreRangeSealResult.make({ range }))),
|
|
1527
|
+
);
|
|
1528
|
+
}
|
|
1529
|
+
case "StoreRangeArchive": {
|
|
1530
|
+
const store = yield* ThreadStore;
|
|
1531
|
+
|
|
1532
|
+
return yield* capture(
|
|
1533
|
+
store.archives === undefined
|
|
1534
|
+
? crossThreadStoreError("archive unavailable", request.request.threadId)
|
|
1535
|
+
: store.archives
|
|
1536
|
+
.archive(request.request)
|
|
1537
|
+
.pipe(Effect.map((range) => StoreRangeArchiveResult.make({ range }))),
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
case "StoreRangeVerify": {
|
|
1541
|
+
const store = yield* ThreadStore;
|
|
1542
|
+
|
|
1543
|
+
return yield* capture(
|
|
1544
|
+
store.archives === undefined
|
|
1545
|
+
? crossThreadStoreError("archive unavailable", request.request.threadId)
|
|
1546
|
+
: store.archives
|
|
1547
|
+
.verify(request.request)
|
|
1548
|
+
.pipe(Effect.map((range) => StoreRangeVerifyResult.make({ range }))),
|
|
1549
|
+
);
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
case "StoreWorkPage": {
|
|
1553
|
+
const store = yield* ThreadStore;
|
|
1554
|
+
|
|
1555
|
+
return yield* capture(
|
|
1556
|
+
store.work === undefined
|
|
1557
|
+
? Effect.fail(
|
|
1558
|
+
WorkDiscoveryUnavailable.make({
|
|
1559
|
+
threadId: request.request.threadId,
|
|
1560
|
+
reason: "unsupported",
|
|
1561
|
+
}),
|
|
1562
|
+
)
|
|
1563
|
+
: store.work
|
|
1564
|
+
.page(request.request)
|
|
1565
|
+
.pipe(Effect.map((page) => StoreWorkPageResult.make({ page }))),
|
|
1566
|
+
);
|
|
1567
|
+
}
|
|
1568
|
+
case "StoreWorkRebuild": {
|
|
1569
|
+
const store = yield* ThreadStore;
|
|
1570
|
+
|
|
1571
|
+
return yield* capture(
|
|
1572
|
+
store.work === undefined
|
|
1573
|
+
? Effect.fail(
|
|
1574
|
+
WorkDiscoveryUnavailable.make({
|
|
1575
|
+
threadId: request.request.threadId,
|
|
1576
|
+
reason: "unsupported",
|
|
1577
|
+
}),
|
|
1578
|
+
)
|
|
1579
|
+
: store.work
|
|
1580
|
+
.rebuild(request.request)
|
|
1581
|
+
.pipe(Effect.map((progress) => StoreWorkRebuildResult.make({ progress }))),
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
case "SettlementPublish": {
|
|
1585
|
+
const publisher = yield* SettlementPublisher;
|
|
1586
|
+
|
|
1587
|
+
return yield* capture(
|
|
1588
|
+
publisher
|
|
1589
|
+
.publish(request.request)
|
|
1590
|
+
.pipe(Effect.map((result) => SettlementPublishResult.make({ result }))),
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1234
1593
|
case "MessageDeliveryComplete": {
|
|
1235
1594
|
const store = yield* MessageDeliveryStore;
|
|
1236
1595
|
|
|
@@ -1301,6 +1660,22 @@ export const executePortRequest = Effect.fn("DoPortRouting.executePortRequest")(
|
|
|
1301
1660
|
),
|
|
1302
1661
|
);
|
|
1303
1662
|
}
|
|
1663
|
+
case "LedgerFundingOwner": {
|
|
1664
|
+
const ledger = yield* SubmissionLedger;
|
|
1665
|
+
|
|
1666
|
+
return yield* capture(
|
|
1667
|
+
ledger.resolveFundingOwner === undefined
|
|
1668
|
+
? Effect.fail(
|
|
1669
|
+
LedgerError.make({
|
|
1670
|
+
operation: "resolve funding owner",
|
|
1671
|
+
message: "Native funding-owner lookup unavailable.",
|
|
1672
|
+
}),
|
|
1673
|
+
)
|
|
1674
|
+
: ledger
|
|
1675
|
+
.resolveFundingOwner(request.request)
|
|
1676
|
+
.pipe(Effect.map((funding) => LedgerFundingOwnerResult.make({ funding }))),
|
|
1677
|
+
);
|
|
1678
|
+
}
|
|
1304
1679
|
case "LedgerResolveAdmission": {
|
|
1305
1680
|
const ledger = yield* SubmissionLedger;
|
|
1306
1681
|
|
|
@@ -1383,6 +1758,16 @@ export const executePortRequest = Effect.fn("DoPortRouting.executePortRequest")(
|
|
|
1383
1758
|
),
|
|
1384
1759
|
);
|
|
1385
1760
|
}
|
|
1761
|
+
case "StoreReadPrompt": {
|
|
1762
|
+
const store = yield* ThreadStore;
|
|
1763
|
+
|
|
1764
|
+
return yield* capture(
|
|
1765
|
+
store.readPrompt(request.request).pipe(
|
|
1766
|
+
Stream.runCollect,
|
|
1767
|
+
Effect.map((records) => StoreReadPromptResult.make({ records })),
|
|
1768
|
+
),
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1386
1771
|
case "StoreInspectTail": {
|
|
1387
1772
|
const store = yield* ThreadStore;
|
|
1388
1773
|
|
|
@@ -1392,6 +1777,15 @@ export const executePortRequest = Effect.fn("DoPortRouting.executePortRequest")(
|
|
|
1392
1777
|
.pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),
|
|
1393
1778
|
);
|
|
1394
1779
|
}
|
|
1780
|
+
case "StoreReadExecution": {
|
|
1781
|
+
const store = yield* ThreadStore;
|
|
1782
|
+
|
|
1783
|
+
return yield* capture(
|
|
1784
|
+
store
|
|
1785
|
+
.readExecution(request.request)
|
|
1786
|
+
.pipe(Effect.map((checkpoint) => StoreReadExecutionResult.make({ checkpoint }))),
|
|
1787
|
+
);
|
|
1788
|
+
}
|
|
1395
1789
|
case "StoreReadIdentity": {
|
|
1396
1790
|
const store = yield* ThreadStore;
|
|
1397
1791
|
|
|
@@ -1401,6 +1795,30 @@ export const executePortRequest = Effect.fn("DoPortRouting.executePortRequest")(
|
|
|
1401
1795
|
.pipe(Effect.map((identity) => StoreReadIdentityResult.make({ identity }))),
|
|
1402
1796
|
);
|
|
1403
1797
|
}
|
|
1798
|
+
case "StoreWorkerCapacity": {
|
|
1799
|
+
const store = yield* ThreadStore;
|
|
1800
|
+
|
|
1801
|
+
return yield* capture(
|
|
1802
|
+
store.readWorkerCapacity === undefined
|
|
1803
|
+
? Effect.fail(
|
|
1804
|
+
crossThreadStoreError("worker capacity unavailable", request.request.threadId),
|
|
1805
|
+
)
|
|
1806
|
+
: store
|
|
1807
|
+
.readWorkerCapacity(request.request)
|
|
1808
|
+
.pipe(Effect.map((capacity) => StoreWorkerCapacityResult.make({ capacity }))),
|
|
1809
|
+
);
|
|
1810
|
+
}
|
|
1811
|
+
case "StoreVerification": {
|
|
1812
|
+
const store = yield* ThreadStore;
|
|
1813
|
+
|
|
1814
|
+
return yield* capture(
|
|
1815
|
+
store.verification === undefined
|
|
1816
|
+
? Effect.fail(crossThreadStoreError("verification unavailable", request.request.threadId))
|
|
1817
|
+
: store.verification
|
|
1818
|
+
.verify(request.request)
|
|
1819
|
+
.pipe(Effect.map((report) => StoreVerificationResult.make({ report }))),
|
|
1820
|
+
);
|
|
1821
|
+
}
|
|
1404
1822
|
case "StoreExport": {
|
|
1405
1823
|
const store = yield* ThreadStore;
|
|
1406
1824
|
|
|
@@ -1430,35 +1848,36 @@ const encodedProtocolFailure = (message: string): unknown => ({
|
|
|
1430
1848
|
* cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the
|
|
1431
1849
|
* transport never has to interpret exceptions as protocol answers.
|
|
1432
1850
|
*/
|
|
1433
|
-
export const handleEncodedPortRequest = Effect.
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1851
|
+
export const handleEncodedPortRequest = Effect.fnUntraced(function* (
|
|
1852
|
+
encoded: unknown,
|
|
1853
|
+
): Effect.fn.Return<
|
|
1854
|
+
unknown,
|
|
1855
|
+
never,
|
|
1856
|
+
| SubmissionLedger
|
|
1857
|
+
| SettlementPublisher
|
|
1858
|
+
| ThreadStore
|
|
1859
|
+
| MessageDeliveryStore
|
|
1860
|
+
| WakeScheduler
|
|
1861
|
+
| DurableRuntimeFailpoint
|
|
1862
|
+
> {
|
|
1863
|
+
const response = yield* decodePortRequest(encoded).pipe(
|
|
1864
|
+
Effect.flatMap(executePortRequest),
|
|
1865
|
+
Effect.catch((error) =>
|
|
1866
|
+
Effect.succeed<PortResponse>(
|
|
1867
|
+
PortFailed.make({
|
|
1868
|
+
failure: PortProtocolError.make({
|
|
1869
|
+
message: boundPortDiagnostic(`The port request could not be decoded: ${error.message}`),
|
|
1451
1870
|
}),
|
|
1452
|
-
),
|
|
1871
|
+
}),
|
|
1453
1872
|
),
|
|
1454
|
-
)
|
|
1873
|
+
),
|
|
1874
|
+
);
|
|
1455
1875
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
),
|
|
1876
|
+
return yield* encodePortResponse(response).pipe(
|
|
1877
|
+
Effect.catch((error) =>
|
|
1878
|
+
Effect.succeed(
|
|
1879
|
+
encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),
|
|
1461
1880
|
),
|
|
1462
|
-
)
|
|
1463
|
-
|
|
1464
|
-
);
|
|
1881
|
+
),
|
|
1882
|
+
);
|
|
1883
|
+
});
|