@yielded/agent-storage-cloudflare 0.1.0-beta.174 → 0.1.0-beta.176
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.mjs +1 -1
- package/dist/DoStorageFailpoint.d.mts +3 -1
- package/dist/DoStorageFailpoint.mjs +7 -2
- package/dist/DoStorageFailpoint.mjs.map +1 -1
- package/dist/{DoStorageVersion-NKnQU3eR.d.mts → DoStorageVersion-Mc7CXMdN.d.mts} +2 -2
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoSubmissionLedger.d.mts +1 -1
- package/dist/DoSubmissionLedger.mjs +194 -98
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/{DoThreadStore-Bd4fTns3.d.mts → DoThreadStore-BzYJjm4O.d.mts} +18 -8
- package/dist/{DoThreadStore-DyzOZDXK.mjs → DoThreadStore-DG0h5J6u.mjs} +25 -19
- package/dist/DoThreadStore-DG0h5J6u.mjs.map +1 -0
- package/dist/DoThreadStore.d.mts +2 -2
- package/dist/DoThreadStore.mjs +3 -2
- package/dist/PortProtocol.d.mts +7201 -7201
- package/dist/PortRouting.mjs +21 -11
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-ZMAzzENZ.mjs → do-journal-ySC3eXNv.mjs} +144 -45
- package/dist/do-journal-ySC3eXNv.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{migrations-C3N9GN6A.mjs → migrations-CAO_akhD.mjs} +45 -22
- package/dist/migrations-CAO_akhD.mjs.map +1 -0
- package/dist/{owned-state-DcFh0YNo.mjs → owned-state-BgGOA2Ak.mjs} +4 -3
- package/dist/owned-state-BgGOA2Ak.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoStorageFailpoint.ts +4 -0
- package/src/DoSubmissionLedger.ts +430 -228
- package/src/DoThreadStore.ts +25 -44
- package/src/PortRouting.ts +57 -31
- package/src/internal/do-journal.ts +318 -70
- package/src/internal/migrations.ts +52 -10
- package/src/internal/owned-state.ts +12 -5
- package/src/internal/prompt-checkpoint.ts +6 -3
- package/src/internal/storage-span.ts +14 -10
- package/dist/DoThreadStore-DyzOZDXK.mjs.map +0 -1
- package/dist/do-journal-ZMAzzENZ.mjs.map +0 -1
- package/dist/migrations-C3N9GN6A.mjs.map +0 -1
- package/dist/owned-state-DcFh0YNo.mjs.map +0 -1
package/src/DoThreadStore.ts
CHANGED
|
@@ -18,7 +18,6 @@ import { ThreadImport } from "@yielded/agent/thread-import";
|
|
|
18
18
|
import {
|
|
19
19
|
type ThreadExportRequest,
|
|
20
20
|
AppendConflict,
|
|
21
|
-
AppendResult,
|
|
22
21
|
CheckpointRejected,
|
|
23
22
|
ThreadCheckpoint,
|
|
24
23
|
ThreadMaterialization,
|
|
@@ -104,6 +103,11 @@ const isDoCheckpointConflict = Schema.is(DoCheckpointConflict);
|
|
|
104
103
|
const ThreadCheckpointJson = Schema.fromJsonString(ThreadCheckpoint);
|
|
105
104
|
const decodeCanonicalRecord = decodeExportRecordJson;
|
|
106
105
|
|
|
106
|
+
const decodeThreadMaterializationType = Schema.decodeEffect(Schema.toType(ThreadMaterialization));
|
|
107
|
+
const decodeThreadReadRequestType = Schema.decodeEffect(Schema.toType(ThreadReadRequest));
|
|
108
|
+
const decodeThreadTailRequestType = Schema.decodeEffect(Schema.toType(ThreadTailRequest));
|
|
109
|
+
const decodeStorageConfig = Schema.decodeEffect(DoStorageConfigValue);
|
|
110
|
+
|
|
107
111
|
const storeError = (
|
|
108
112
|
operation: string,
|
|
109
113
|
error: { readonly message: string; readonly diagnostic?: ThreadStoreDiagnostic },
|
|
@@ -126,19 +130,6 @@ const schemaStoreError = (operation: string, error: Schema.SchemaError) =>
|
|
|
126
130
|
}),
|
|
127
131
|
});
|
|
128
132
|
|
|
129
|
-
const makeOffset = (
|
|
130
|
-
threadId: ThreadMaterialization["threadId"],
|
|
131
|
-
sequence: number,
|
|
132
|
-
): Effect.Effect<ObservationOffset, ThreadStoreError> =>
|
|
133
|
-
Schema.decodeEffect(CanonicalSequence)(sequence).pipe(
|
|
134
|
-
Effect.flatMap((validatedSequence) =>
|
|
135
|
-
Schema.decodeEffect(ObservationOffset)(
|
|
136
|
-
`${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,
|
|
137
|
-
),
|
|
138
|
-
),
|
|
139
|
-
Effect.mapError((error) => schemaStoreError("encode observation offset", error)),
|
|
140
|
-
);
|
|
141
|
-
|
|
142
133
|
const parseOffset = Effect.fnUntraced(function* (
|
|
143
134
|
threadId: ThreadMaterialization["threadId"],
|
|
144
135
|
offset: ObservationOffset | undefined,
|
|
@@ -179,8 +170,8 @@ const encodeCheckpoint = (checkpoint: ThreadCheckpoint): Effect.Effect<string, T
|
|
|
179
170
|
const envelopes = new WeakMap<object, CanonicalRecordEnvelope>();
|
|
180
171
|
|
|
181
172
|
const decodeEnvelope = Effect.fnUntraced(function* (row: {
|
|
182
|
-
readonly batch_id:
|
|
183
|
-
readonly thread_id:
|
|
173
|
+
readonly batch_id: CanonicalRecordEnvelope["batchId"];
|
|
174
|
+
readonly thread_id: CanonicalRecordEnvelope["threadId"];
|
|
184
175
|
readonly record_json: string;
|
|
185
176
|
readonly sequence: CanonicalSequence;
|
|
186
177
|
}) {
|
|
@@ -213,15 +204,11 @@ const decodeEnvelope = Effect.fnUntraced(function* (row: {
|
|
|
213
204
|
),
|
|
214
205
|
);
|
|
215
206
|
|
|
216
|
-
const threadId =
|
|
217
|
-
row.thread_id,
|
|
218
|
-
).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
|
|
207
|
+
const { thread_id: threadId, batch_id: batchId } = row;
|
|
219
208
|
|
|
220
|
-
const offset =
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
row.batch_id,
|
|
224
|
-
).pipe(Effect.mapError((error) => schemaStoreError("decode batch identity", error)));
|
|
209
|
+
const offset = ObservationOffset.make(
|
|
210
|
+
`${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${row.sequence}`,
|
|
211
|
+
);
|
|
225
212
|
|
|
226
213
|
const envelope = CanonicalRecordEnvelope.make(
|
|
227
214
|
{ threadId, batchId, sequence: row.sequence, offset, record },
|
|
@@ -317,9 +304,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
317
304
|
const materialize: ThreadStore["Service"]["materialize"] = Effect.fnUntraced(function* (
|
|
318
305
|
request: ThreadMaterialization,
|
|
319
306
|
) {
|
|
320
|
-
const validated = yield*
|
|
321
|
-
|
|
322
|
-
)
|
|
307
|
+
const validated = yield* decodeThreadMaterializationType(request).pipe(
|
|
308
|
+
Effect.mapError((error) => schemaStoreError("validate materialization", error)),
|
|
309
|
+
);
|
|
323
310
|
|
|
324
311
|
const now = yield* Clock.currentTimeMillis;
|
|
325
312
|
|
|
@@ -362,11 +349,6 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
362
349
|
|
|
363
350
|
return storeError("append canonical batch", error);
|
|
364
351
|
}),
|
|
365
|
-
Effect.flatMap((result) =>
|
|
366
|
-
Schema.decodeEffect(AppendResult)(result).pipe(
|
|
367
|
-
Effect.mapError((error) => schemaStoreError("decode append result", error)),
|
|
368
|
-
),
|
|
369
|
-
),
|
|
370
352
|
);
|
|
371
353
|
|
|
372
354
|
yield* hitFailpoint("append:after");
|
|
@@ -391,7 +373,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
391
373
|
});
|
|
392
374
|
|
|
393
375
|
const readEffect = Effect.fnUntraced(function* (request: ThreadReadRequest) {
|
|
394
|
-
const validated = yield*
|
|
376
|
+
const validated = yield* decodeThreadReadRequestType(request).pipe(
|
|
395
377
|
Effect.mapError((error) => schemaStoreError("validate thread read", error)),
|
|
396
378
|
);
|
|
397
379
|
|
|
@@ -503,7 +485,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
503
485
|
const inspectTail: ThreadStore["Service"]["inspectTail"] = Effect.fnUntraced(function* (
|
|
504
486
|
request: ThreadTailRequest,
|
|
505
487
|
) {
|
|
506
|
-
const validated = yield*
|
|
488
|
+
const validated = yield* decodeThreadTailRequestType(request).pipe(
|
|
507
489
|
Effect.mapError((error) => schemaStoreError("validate tail inspection", error)),
|
|
508
490
|
);
|
|
509
491
|
|
|
@@ -602,15 +584,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
602
584
|
snapshot: journal.state.read,
|
|
603
585
|
tail: (threadId) =>
|
|
604
586
|
journal.getThread(threadId).pipe(
|
|
605
|
-
Effect.
|
|
606
|
-
Schema.decodeEffect(
|
|
607
|
-
Schema.UndefinedOr(
|
|
608
|
-
Schema.Struct({
|
|
609
|
-
tail_sequence: CanonicalSequence,
|
|
610
|
-
}),
|
|
611
|
-
),
|
|
612
|
-
)(rows[0]),
|
|
613
|
-
),
|
|
587
|
+
Effect.map((rows) => rows[0]),
|
|
614
588
|
Effect.mapError((error) => storeError("native thread tail", error)),
|
|
615
589
|
),
|
|
616
590
|
}),
|
|
@@ -659,6 +633,13 @@ export const threadStoreLayer: Layer.Layer<
|
|
|
659
633
|
DoStorageConfig | DoStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto
|
|
660
634
|
> = ThreadReader.layer().pipe(Layer.provideMerge(Layer.effectContext(makeServices())));
|
|
661
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Share one initialized journal between local storage ports in one Object build. Provide
|
|
638
|
+
* this beneath both ports and above their common SQL, owner, configuration, failpoint,
|
|
639
|
+
* progress and lifecycle providers. Standalone ports initialize their own journal.
|
|
640
|
+
*/
|
|
641
|
+
export { initializedDoJournalLayer as journalLayer } from "./internal/do-journal.ts";
|
|
642
|
+
|
|
662
643
|
/**
|
|
663
644
|
* Validated Durable Object storage configuration Layer with the documented defaults applied.
|
|
664
645
|
* Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults
|
|
@@ -668,7 +649,7 @@ export const storageConfigLayer = (
|
|
|
668
649
|
options: DoStorageOptions,
|
|
669
650
|
): Layer.Layer<DoStorageConfig, DoStorageError> =>
|
|
670
651
|
Layer.effect(DoStorageConfig)(
|
|
671
|
-
|
|
652
|
+
decodeStorageConfig({
|
|
672
653
|
observationPollInterval: options.observationPollInterval ?? 25,
|
|
673
654
|
maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,
|
|
674
655
|
verifyOnOpen: options.verifyOnOpen ?? false,
|
package/src/PortRouting.ts
CHANGED
|
@@ -236,35 +236,36 @@ const LOCAL: RouteTarget = { _tag: "local" };
|
|
|
236
236
|
* Identities beyond the ledger's 1,024-character row bound fail typed: the minting side
|
|
237
237
|
* refused them at admission, so they cannot name any stored row anywhere.
|
|
238
238
|
*/
|
|
239
|
-
const routableSubmissionTarget =
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
Effect.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
239
|
+
const routableSubmissionTarget =
|
|
240
|
+
(
|
|
241
|
+
ownsThread: RoutedPortOptions["ownsThread"],
|
|
242
|
+
): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>
|
|
243
|
+
(operation, submissionId) =>
|
|
244
|
+
Effect.suspend(() => {
|
|
245
|
+
if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {
|
|
246
|
+
return Effect.fail(
|
|
247
|
+
LedgerError.make({
|
|
248
|
+
operation,
|
|
249
|
+
message:
|
|
250
|
+
`A Submission identity of ${submissionId.length} characters exceeds the ` +
|
|
251
|
+
`${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +
|
|
252
|
+
"refuses such identities, so it cannot name any stored row.",
|
|
253
|
+
}),
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
const separator = submissionId.indexOf(":");
|
|
257
|
+
|
|
258
|
+
if (separator === -1 || !UUID_HEAD_PATTERN.test(submissionId.slice(0, separator)))
|
|
259
|
+
return Effect.succeed(LOCAL);
|
|
260
|
+
|
|
261
|
+
return decodeThreadId(submissionId.slice(separator + 1)).pipe(
|
|
262
|
+
Effect.match({
|
|
263
|
+
onFailure: () => LOCAL,
|
|
264
|
+
onSuccess: (threadId): RouteTarget =>
|
|
265
|
+
ownsThread(threadId) ? LOCAL : { _tag: "foreign", threadId },
|
|
266
|
+
}),
|
|
267
|
+
);
|
|
268
|
+
});
|
|
268
269
|
|
|
269
270
|
/**
|
|
270
271
|
* Read a Submission only from this physical owner. Encoded foreign identities fail before
|
|
@@ -570,9 +571,9 @@ const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPor
|
|
|
570
571
|
const routed = SubmissionLedger.of({
|
|
571
572
|
capabilities: local.capabilities,
|
|
572
573
|
|
|
573
|
-
admit: (request) =>
|
|
574
|
+
admit: (request, admissionOptions) =>
|
|
574
575
|
options.ownsThread(request.threadId)
|
|
575
|
-
? local.admit(request)
|
|
576
|
+
? local.admit(request, admissionOptions)
|
|
576
577
|
: foreignLedgerCall(
|
|
577
578
|
"ledger admit",
|
|
578
579
|
request.threadId,
|
|
@@ -730,6 +731,23 @@ const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPor
|
|
|
730
731
|
? local.claimJoining(request)
|
|
731
732
|
: Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
|
|
732
733
|
|
|
734
|
+
...(local.appendInput === undefined
|
|
735
|
+
? {}
|
|
736
|
+
: {
|
|
737
|
+
appendInput: (
|
|
738
|
+
submissionId: SubmissionSnapshot["submissionId"],
|
|
739
|
+
request: Parameters<NonNullable<SubmissionLedger["Service"]["appendInput"]>>[1],
|
|
740
|
+
) =>
|
|
741
|
+
options.ownsThread(request.threadId)
|
|
742
|
+
? local.appendInput!(submissionId, request)
|
|
743
|
+
: Effect.fail(
|
|
744
|
+
ThreadStoreError.make({
|
|
745
|
+
operation: "append original input",
|
|
746
|
+
message: "Original input publication is lane-local",
|
|
747
|
+
}),
|
|
748
|
+
),
|
|
749
|
+
}),
|
|
750
|
+
|
|
733
751
|
markInputApplied: (request) =>
|
|
734
752
|
submissionTarget("ledger mark input applied", request.submissionId).pipe(
|
|
735
753
|
Effect.flatMap((target) =>
|
|
@@ -824,6 +842,7 @@ const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPor
|
|
|
824
842
|
|
|
825
843
|
// The local scan IS the whole worklist: one Thread per Object (durability §5).
|
|
826
844
|
scanNonterminal: local.scanNonterminal,
|
|
845
|
+
...(local.listNonterminal === undefined ? {} : { listNonterminal: local.listNonterminal }),
|
|
827
846
|
|
|
828
847
|
readAbortIntent: (request) =>
|
|
829
848
|
submissionTarget("ledger read abort intent", request.submissionId).pipe(
|
|
@@ -1046,6 +1065,13 @@ const makeRoutedStoreServices = Effect.fnUntraced(function* (options: RoutedPort
|
|
|
1046
1065
|
).pipe(Effect.map((reply) => reply.range)),
|
|
1047
1066
|
},
|
|
1048
1067
|
work: {
|
|
1068
|
+
isOnlyFreshAdmission: (request) => {
|
|
1069
|
+
const prove = local.work?.isOnlyFreshAdmission;
|
|
1070
|
+
|
|
1071
|
+
return prove !== undefined && options.ownsThread(request.threadId)
|
|
1072
|
+
? prove(request)
|
|
1073
|
+
: Effect.succeed(false);
|
|
1074
|
+
},
|
|
1049
1075
|
threads: (request) =>
|
|
1050
1076
|
Effect.flatMap(CurrentNativeSource, (nativeSource) =>
|
|
1051
1077
|
nativeSource && local.work !== undefined
|