@yielded/agent-storage-cloudflare 0.1.0-beta.173 → 0.1.0-beta.175

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.
Files changed (44) hide show
  1. package/dist/DoMemoryStore.mjs +1 -1
  2. package/dist/DoMessageDeliveryStore.mjs +1 -1
  3. package/dist/DoStorageFailpoint.d.mts +3 -1
  4. package/dist/DoStorageFailpoint.mjs +7 -2
  5. package/dist/DoStorageFailpoint.mjs.map +1 -1
  6. package/dist/DoStorageFailpointTesting.mjs +1 -4
  7. package/dist/DoStorageFailpointTesting.mjs.map +1 -1
  8. package/dist/{DoStorageVersion-NKnQU3eR.d.mts → DoStorageVersion-Mc7CXMdN.d.mts} +2 -2
  9. package/dist/DoStorageVersion.d.mts +1 -1
  10. package/dist/DoStorageVersion.mjs +2 -2
  11. package/dist/DoSubmissionLedger.mjs +121 -67
  12. package/dist/DoSubmissionLedger.mjs.map +1 -1
  13. package/dist/DoSubscriptionStore.mjs.map +1 -1
  14. package/dist/{DoThreadStore-CtyahRTW.mjs → DoThreadStore-CgIZQUNR.mjs} +30 -25
  15. package/dist/DoThreadStore-CgIZQUNR.mjs.map +1 -0
  16. package/dist/DoThreadStore.mjs +1 -1
  17. package/dist/PortProtocol.d.mts +12 -0
  18. package/dist/PortRouting.mjs +6 -1
  19. package/dist/PortRouting.mjs.map +1 -1
  20. package/dist/{do-journal-_MdLGTd3.mjs → do-journal-7P3DUBz0.mjs} +140 -65
  21. package/dist/do-journal-7P3DUBz0.mjs.map +1 -0
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.mjs +1 -1
  24. package/dist/{migrations-C3N9GN6A.mjs → migrations-CAO_akhD.mjs} +45 -22
  25. package/dist/migrations-CAO_akhD.mjs.map +1 -0
  26. package/dist/{owned-state-BHzUi0eb.mjs → owned-state-B4QhezMp.mjs} +8 -6
  27. package/dist/owned-state-B4QhezMp.mjs.map +1 -0
  28. package/package.json +1 -1
  29. package/src/DoStorageFailpoint.ts +4 -0
  30. package/src/DoStorageFailpointTesting.ts +9 -7
  31. package/src/DoSubmissionLedger.ts +271 -150
  32. package/src/DoSubscriptionStore.ts +1 -0
  33. package/src/DoThreadStore.ts +27 -50
  34. package/src/PortRouting.ts +10 -2
  35. package/src/internal/canonical-append.ts +1 -1
  36. package/src/internal/do-journal.ts +987 -800
  37. package/src/internal/migrations.ts +53 -10
  38. package/src/internal/owned-state.ts +18 -7
  39. package/src/internal/prompt-checkpoint.ts +19 -13
  40. package/src/internal/storage-span.ts +22 -13
  41. package/dist/DoThreadStore-CtyahRTW.mjs.map +0 -1
  42. package/dist/do-journal-_MdLGTd3.mjs.map +0 -1
  43. package/dist/migrations-C3N9GN6A.mjs.map +0 -1
  44. package/dist/owned-state-BHzUi0eb.mjs.map +0 -1
@@ -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: string;
183
- readonly thread_id: string;
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,17 +204,13 @@ const decodeEnvelope = Effect.fnUntraced(function* (row: {
213
204
  ),
214
205
  );
215
206
 
216
- const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.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 = yield* makeOffset(threadId, row.sequence);
221
-
222
- const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(
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
- const envelope = new CanonicalRecordEnvelope(
213
+ const envelope = CanonicalRecordEnvelope.make(
227
214
  { threadId, batchId, sequence: row.sequence, offset, record },
228
215
  { disableChecks: true },
229
216
  );
@@ -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* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(
321
- request,
322
- ).pipe(Effect.mapError((error) => schemaStoreError("validate materialization", error)));
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* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(
376
+ const validated = yield* decodeThreadReadRequestType(request).pipe(
395
377
  Effect.mapError((error) => schemaStoreError("validate thread read", error)),
396
378
  );
397
379
 
@@ -473,17 +455,20 @@ const makeServices = Effect.fnUntraced(function* () {
473
455
  offsetPrefix: DO_OFFSET_PREFIX,
474
456
  maxValueBytes: config.maxStoredValueBytes,
475
457
  // Import establishes a new sequence space; discard derivatives in this same transaction.
476
- afterImport: ({ result }) =>
477
- Effect.gen(function* () {
458
+ afterImport: Effect.fnUntraced(
459
+ function* ({ result }) {
478
460
  const prefix = promptCheckpointPrefix(result.threadId);
479
461
 
480
462
  yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + "~"}`;
481
463
  // Closed imported history must not emit historical lifecycle notifications again.
482
464
  if (journal.lifecycle !== undefined)
483
465
  yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence) VALUES (${result.threadId}, ${result.tailSequence})`;
484
- }).pipe(
485
- Effect.catchTag("SqlError", (cause) => storeError("rebuild imported derivatives", cause)),
486
- ),
466
+ },
467
+ (effect) =>
468
+ effect.pipe(
469
+ Effect.catchTag("SqlError", (cause) => storeError("rebuild imported derivatives", cause)),
470
+ ),
471
+ ),
487
472
  afterThreadRead: hitFailpoint("export:after-thread-read"),
488
473
  read: (body) =>
489
474
  journal.owner.transaction(body).pipe(
@@ -500,7 +485,7 @@ const makeServices = Effect.fnUntraced(function* () {
500
485
  const inspectTail: ThreadStore["Service"]["inspectTail"] = Effect.fnUntraced(function* (
501
486
  request: ThreadTailRequest,
502
487
  ) {
503
- const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(
488
+ const validated = yield* decodeThreadTailRequestType(request).pipe(
504
489
  Effect.mapError((error) => schemaStoreError("validate tail inspection", error)),
505
490
  );
506
491
 
@@ -599,15 +584,7 @@ const makeServices = Effect.fnUntraced(function* () {
599
584
  snapshot: journal.state.read,
600
585
  tail: (threadId) =>
601
586
  journal.getThread(threadId).pipe(
602
- Effect.flatMap((rows) =>
603
- Schema.decodeEffect(
604
- Schema.UndefinedOr(
605
- Schema.Struct({
606
- tail_sequence: CanonicalSequence,
607
- }),
608
- ),
609
- )(rows[0]),
610
- ),
587
+ Effect.map((rows) => rows[0]),
611
588
  Effect.mapError((error) => storeError("native thread tail", error)),
612
589
  ),
613
590
  }),
@@ -665,7 +642,7 @@ export const storageConfigLayer = (
665
642
  options: DoStorageOptions,
666
643
  ): Layer.Layer<DoStorageConfig, DoStorageError> =>
667
644
  Layer.effect(DoStorageConfig)(
668
- Schema.decodeEffect(DoStorageConfigValue)({
645
+ decodeStorageConfig({
669
646
  observationPollInterval: options.observationPollInterval ?? 25,
670
647
  maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,
671
648
  verifyOnOpen: options.verifyOnOpen ?? false,
@@ -570,9 +570,9 @@ const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPor
570
570
  const routed = SubmissionLedger.of({
571
571
  capabilities: local.capabilities,
572
572
 
573
- admit: (request) =>
573
+ admit: (request, admissionOptions) =>
574
574
  options.ownsThread(request.threadId)
575
- ? local.admit(request)
575
+ ? local.admit(request, admissionOptions)
576
576
  : foreignLedgerCall(
577
577
  "ledger admit",
578
578
  request.threadId,
@@ -824,6 +824,7 @@ const makeRoutedLedgerServices = Effect.fnUntraced(function* (options: RoutedPor
824
824
 
825
825
  // The local scan IS the whole worklist: one Thread per Object (durability §5).
826
826
  scanNonterminal: local.scanNonterminal,
827
+ ...(local.listNonterminal === undefined ? {} : { listNonterminal: local.listNonterminal }),
827
828
 
828
829
  readAbortIntent: (request) =>
829
830
  submissionTarget("ledger read abort intent", request.submissionId).pipe(
@@ -1046,6 +1047,13 @@ const makeRoutedStoreServices = Effect.fnUntraced(function* (options: RoutedPort
1046
1047
  ).pipe(Effect.map((reply) => reply.range)),
1047
1048
  },
1048
1049
  work: {
1050
+ isOnlyFreshAdmission: (request) => {
1051
+ const prove = local.work?.isOnlyFreshAdmission;
1052
+
1053
+ return prove !== undefined && options.ownsThread(request.threadId)
1054
+ ? prove(request)
1055
+ : Effect.succeed(false);
1056
+ },
1049
1057
  threads: (request) =>
1050
1058
  Effect.flatMap(CurrentNativeSource, (nativeSource) =>
1051
1059
  nativeSource && local.work !== undefined
@@ -7,7 +7,7 @@ export const DO_OFFSET_PREFIX = "effect-agent-do@1:";
7
7
 
8
8
  /** Prepare the publisher's privately captured canonical request before the writer. */
9
9
  export const prepareCanonicalAppend = Effect.fnUntraced(function* (input: AppendRequest) {
10
- const request = yield* PreparedAppend.capture(input);
10
+ const request: PreparedAppend = yield* PreparedAppend.capture(input);
11
11
 
12
12
  const raw = yield* prepareSqlAppend(request, DO_OFFSET_PREFIX);
13
13