@effect-agent/storage-cloudflare 0.1.0-beta.42 → 0.1.0-beta.45

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.
@@ -140,10 +140,13 @@ const parseOffset = Effect.fn(function* (
140
140
  offset: ObservationOffset | undefined,
141
141
  ): Effect.fn.Return<CanonicalSequence, ThreadStoreError> {
142
142
  if (offset === undefined) return ZERO_CANONICAL_SEQUENCE;
143
+
143
144
  const text = yield* Schema.decodeUnknownEffect(OffsetText)(offset).pipe(
144
145
  Effect.mapError((error) => schemaStoreError("decode observation offset", error)),
145
146
  );
147
+
146
148
  const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;
149
+
147
150
  if (!text.startsWith(threadPrefix)) {
148
151
  return yield* ThreadStoreError.make({
149
152
  operation: "decode observation offset",
@@ -151,12 +154,14 @@ const parseOffset = Effect.fn(function* (
151
154
  });
152
155
  }
153
156
  const sequenceText = text.slice(threadPrefix.length);
157
+
154
158
  if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) {
155
159
  return yield* ThreadStoreError.make({
156
160
  operation: "decode observation offset",
157
161
  message: "The observation offset is malformed.",
158
162
  });
159
163
  }
164
+
160
165
  return yield* Schema.decodeUnknownEffect(CanonicalSequence)(Number(sequenceText)).pipe(
161
166
  Effect.mapError((error) => schemaStoreError("decode observation offset", error)),
162
167
  );
@@ -209,13 +214,17 @@ const decodeEnvelope = Effect.fn(function* (row: {
209
214
  }),
210
215
  ),
211
216
  );
217
+
212
218
  const threadId = yield* Schema.decodeUnknownEffect(CanonicalRecordEnvelope.fields.threadId)(
213
219
  row.thread_id,
214
220
  ).pipe(Effect.mapError((error) => schemaStoreError("decode thread identity", error)));
221
+
215
222
  const offset = yield* makeOffset(threadId, row.sequence);
223
+
216
224
  const batchId = yield* Schema.decodeUnknownEffect(CanonicalRecordEnvelope.fields.batchId)(
217
225
  row.batch_id,
218
226
  ).pipe(Effect.mapError((error) => schemaStoreError("decode batch identity", error)));
227
+
219
228
  return CanonicalRecordEnvelope.make({
220
229
  threadId,
221
230
  batchId,
@@ -240,9 +249,11 @@ const requireThread = Effect.fn("DoThreadStore.requireThread")(function* (
240
249
  const rows = yield* journal
241
250
  .getThread(threadId)
242
251
  .pipe(Effect.mapError((error) => storeError("read thread", error)));
252
+
243
253
  if (rows.length === 0) {
244
254
  return yield* ThreadNotMaterialized.make({ threadId });
245
255
  }
256
+
246
257
  return rows[0];
247
258
  });
248
259
 
@@ -252,15 +263,18 @@ const tailDigestAt = Effect.fn("DoThreadStore.tailDigestAt")(function* (
252
263
  sequence: CanonicalSequence,
253
264
  ) {
254
265
  if (sequence === 0) return EMPTY_TAIL_DIGEST;
266
+
255
267
  const digests = yield* journal
256
268
  .getTailDigestAt(threadId, sequence)
257
269
  .pipe(Effect.mapError((error) => storeError("read checkpoint digest", error)));
270
+
258
271
  if (digests.length !== 1) {
259
272
  return yield* CheckpointRejected.make({
260
273
  threadId,
261
274
  reason: "digest-mismatch",
262
275
  });
263
276
  }
277
+
264
278
  return yield* Schema.decodeUnknownEffect(Digest)(digests[0]).pipe(
265
279
  Effect.mapError((error) => schemaStoreError("decode checkpoint digest", error)),
266
280
  );
@@ -271,14 +285,17 @@ const groupByKey = <A>(
271
285
  key: (row: A) => string,
272
286
  ): ReadonlyMap<string, ReadonlyArray<A>> => {
273
287
  const grouped = new Map<string, Array<A>>();
288
+
274
289
  for (const row of rows) {
275
290
  const existing = grouped.get(key(row));
291
+
276
292
  if (existing === undefined) {
277
293
  grouped.set(key(row), [row]);
278
294
  } else {
279
295
  existing.push(row);
280
296
  }
281
297
  }
298
+
282
299
  return grouped;
283
300
  };
284
301
 
@@ -292,6 +309,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
292
309
  crypto: Crypto.Crypto,
293
310
  ) {
294
311
  const stored = yield* journal.scanStoredPayloads();
312
+
295
313
  const batches = yield* Effect.forEach(stored.batches, (batch) =>
296
314
  Schema.decodeEffect(Schema.fromJsonString(CanonicalBatch))(batch.batch_json).pipe(
297
315
  Effect.map((decoded) => ({ decoded, row: batch })),
@@ -304,6 +322,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
304
322
  ),
305
323
  ),
306
324
  );
325
+
307
326
  const records = yield* Effect.forEach(stored.records, (record) =>
308
327
  Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(record.record_json).pipe(
309
328
  Effect.map((decoded) => ({ decoded, row: record })),
@@ -316,6 +335,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
316
335
  ),
317
336
  ),
318
337
  );
338
+
319
339
  const checkpoints = yield* Effect.forEach(stored.checkpoints, (checkpoint) =>
320
340
  Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpoint.checkpoint_json).pipe(
321
341
  Effect.map((decoded) => ({ decoded, row: checkpoint })),
@@ -345,6 +365,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
345
365
 
346
366
  for (const { decoded: canonicalBatch, row: batchRow } of threadBatches) {
347
367
  const key = `${batchRow.thread_id}/${batchRow.batch_id}`;
368
+
348
369
  if (
349
370
  canonicalBatch.batchId !== batchRow.batch_id ||
350
371
  batchRow.first_sequence !== expectedSequence ||
@@ -367,6 +388,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
367
388
  }),
368
389
  ),
369
390
  );
391
+
370
392
  if (batchRow.batch_digest !== digest || batchRow.tail_digest !== digest) {
371
393
  return yield* DoStorageCorruptionError.make({
372
394
  table: "effect_agent_canonical_batches",
@@ -376,6 +398,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
376
398
  }
377
399
 
378
400
  const batchRecords = recordsByBatch.get(batchRow.batch_id) ?? [];
401
+
379
402
  if (batchRecords.length !== canonicalBatch.records.length) {
380
403
  return yield* DoStorageCorruptionError.make({
381
404
  table: "effect_agent_canonical_records",
@@ -386,6 +409,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
386
409
  for (let index = 0; index < canonicalBatch.records.length; index++) {
387
410
  const expectedRecord = canonicalBatch.records[index];
388
411
  const storedRecord = batchRecords[index];
412
+
389
413
  const expectedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(
390
414
  expectedRecord,
391
415
  ).pipe(
@@ -397,6 +421,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
397
421
  }),
398
422
  ),
399
423
  );
424
+
400
425
  const storedJson = yield* Schema.encodeEffect(Schema.fromJsonString(CanonicalRecord))(
401
426
  storedRecord.decoded,
402
427
  ).pipe(
@@ -408,6 +433,7 @@ const decodeStartupPayloads = Effect.fn("DoThreadStore.decodeStartupPayloads")(f
408
433
  }),
409
434
  ),
410
435
  );
436
+
411
437
  if (
412
438
  storedRecord.row.sequence !== batchRow.first_sequence + index ||
413
439
  storedRecord.row.record_id !== expectedRecord.recordId ||
@@ -473,12 +499,14 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
473
499
  const sql = yield* SqlClientService.SqlClient;
474
500
  const crypto = yield* Crypto.Crypto;
475
501
  const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);
502
+
476
503
  if (config.verifyOnOpen) {
477
504
  yield* decodeStartupPayloads(journal, crypto);
478
505
  }
479
506
 
480
507
  const provideCrypto = <A, E>(effect: Effect.Effect<A, E, Crypto.Crypto>) =>
481
508
  Effect.provideService(effect, Crypto.Crypto, crypto);
509
+
482
510
  const hitFailpoint = Effect.fn(
483
511
  (location: DoStorageFailpointLocation): Effect.Effect<void, ThreadStoreError> =>
484
512
  failpoint
@@ -491,7 +519,9 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
491
519
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadMaterialization))(
492
520
  request,
493
521
  ).pipe(Effect.mapError((error) => schemaStoreError("validate materialization", error)));
522
+
494
523
  const now = yield* Clock.currentTimeMillis;
524
+
495
525
  yield* hitFailpoint("materialize:before");
496
526
  yield* journal
497
527
  .materialize(
@@ -517,11 +547,15 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
517
547
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(FencedAppendRequest))(
518
548
  request,
519
549
  ).pipe(Effect.mapError((error) => schemaStoreError("validate canonical append", error)));
550
+
520
551
  yield* requireThread(journal, validated.threadId);
552
+
521
553
  const tailDigest = yield* provideCrypto(
522
554
  digestCanonicalBatch(validated.expectedTailDigest, validated.batch),
523
555
  ).pipe(Effect.mapError((error) => storeError("digest canonical append", error)));
556
+
524
557
  const batchJson = yield* encodeCanonicalBatch(validated.batch);
558
+
525
559
  const rawRecords = yield* Effect.forEach(validated.batch.records, (record) =>
526
560
  encodeCanonicalRecord(record).pipe(
527
561
  Effect.map((recordJson) => ({
@@ -530,6 +564,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
530
564
  })),
531
565
  ),
532
566
  );
567
+
533
568
  const rawRequest = yield* Schema.decodeUnknownEffect(RawAppendRequest)({
534
569
  threadId: validated.threadId,
535
570
  batchId: validated.batch.batchId,
@@ -541,7 +576,9 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
541
576
  records: rawRecords,
542
577
  tailDigest,
543
578
  }).pipe(Effect.mapError((error) => schemaStoreError("encode canonical append", error)));
579
+
544
580
  yield* hitFailpoint("append:before");
581
+
545
582
  const result = yield* journal.append(rawRequest).pipe(
546
583
  Effect.mapError((error) => {
547
584
  if (isDoFenceRejected(error)) {
@@ -562,6 +599,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
562
599
  reason: error.reason,
563
600
  });
564
601
  }
602
+
565
603
  return storeError("append canonical batch", error);
566
604
  }),
567
605
  Effect.flatMap((result) =>
@@ -570,7 +608,9 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
570
608
  ),
571
609
  ),
572
610
  );
611
+
573
612
  yield* hitFailpoint("append:after");
613
+
574
614
  return result;
575
615
  });
576
616
 
@@ -578,6 +618,7 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
578
618
  const rows = yield* journal
579
619
  .read(request)
580
620
  .pipe(Effect.mapError((error) => storeError("read canonical records", error)));
621
+
581
622
  return yield* Effect.forEach(rows, decodeEnvelope);
582
623
  });
583
624
 
@@ -585,7 +626,9 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
585
626
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadRead))(request).pipe(
586
627
  Effect.mapError((error) => schemaStoreError("validate thread read", error)),
587
628
  );
629
+
588
630
  yield* requireThread(journal, validated.threadId);
631
+
589
632
  const records = yield* loadRecords(
590
633
  RawReadRequest.make({
591
634
  threadId: validated.threadId,
@@ -593,19 +636,24 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
593
636
  limit: validated.limit,
594
637
  }),
595
638
  );
639
+
596
640
  return Stream.fromIterable(records);
597
641
  });
642
+
598
643
  const read: ThreadStore["Service"]["read"] = (request) => Stream.unwrap(readEffect(request));
599
644
 
600
645
  const observeEffect = Effect.fn("DoThreadStore.observe")(function* (request: ThreadObservation) {
601
646
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadObservation))(
602
647
  request,
603
648
  ).pipe(Effect.mapError((error) => schemaStoreError("validate thread observation", error)));
649
+
604
650
  yield* requireThread(journal, validated.threadId);
605
651
  const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);
606
652
  const cursor = yield* Ref.make(initialSequence);
653
+
607
654
  const poll = Effect.fn("DoThreadStore.observePoll")(function* () {
608
655
  const fromSequenceExclusive = yield* Ref.get(cursor);
656
+
609
657
  const records = yield* loadRecords(
610
658
  RawReadRequest.make({
611
659
  threadId: validated.threadId,
@@ -613,15 +661,20 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
613
661
  limit: 1_024,
614
662
  }),
615
663
  );
664
+
616
665
  if (records.length === 0) {
617
666
  yield* Effect.sleep(config.observationPollInterval);
667
+
618
668
  return [];
619
669
  }
620
670
  yield* Ref.set(cursor, records[records.length - 1].sequence);
671
+
621
672
  return records;
622
673
  });
674
+
623
675
  return Stream.fromIterableEffectRepeat(poll());
624
676
  });
677
+
625
678
  const observe: ThreadStore["Service"]["observe"] = (request) =>
626
679
  Stream.unwrap(observeEffect(request));
627
680
 
@@ -630,20 +683,26 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
630
683
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadExportRequest))(
631
684
  request,
632
685
  ).pipe(Effect.mapError((error) => schemaStoreError("validate thread export", error)));
686
+
633
687
  yield* requireThread(journal, validated.threadId);
688
+
634
689
  const exported = yield* journal
635
690
  .exportThread(validated.threadId)
636
691
  .pipe(Effect.mapError((error) => storeError("export thread", error)));
692
+
637
693
  const records = yield* Effect.forEach(exported.records, decodeEnvelope);
694
+
638
695
  if (records.length > 65_536) {
639
696
  return yield* ThreadStoreError.make({
640
697
  operation: "decode thread export",
641
698
  message: "The thread exceeds the current export record limit.",
642
699
  });
643
700
  }
701
+
644
702
  const tailDigest = yield* Schema.decodeUnknownEffect(Digest)(
645
703
  exported.thread.tail_digest,
646
704
  ).pipe(Effect.mapError((error) => schemaStoreError("decode export tail digest", error)));
705
+
647
706
  return ThreadExport.make({
648
707
  format: "effect-agent/thread@1",
649
708
  threadId: validated.threadId,
@@ -659,10 +718,13 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
659
718
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ThreadTailRequest))(
660
719
  request,
661
720
  ).pipe(Effect.mapError((error) => schemaStoreError("validate tail inspection", error)));
721
+
662
722
  const thread = yield* requireThread(journal, validated.threadId);
723
+
663
724
  const tailDigest = yield* Schema.decodeUnknownEffect(Digest)(thread.tail_digest).pipe(
664
725
  Effect.mapError((error) => schemaStoreError("decode tail digest", error)),
665
726
  );
727
+
666
728
  return ThreadTail.make({
667
729
  threadId: validated.threadId,
668
730
  tailSequence: thread.tail_sequence,
@@ -677,18 +739,22 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
677
739
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SaveCheckpointRequest))(
678
740
  request,
679
741
  ).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint", error)));
742
+
680
743
  const thread = yield* requireThread(journal, validated.checkpoint.threadId);
744
+
681
745
  if (validated.checkpoint.throughSequence > thread.tail_sequence) {
682
746
  return yield* CheckpointRejected.make({
683
747
  threadId: validated.checkpoint.threadId,
684
748
  reason: "ahead-of-tail",
685
749
  });
686
750
  }
751
+
687
752
  const canonicalDigest = yield* tailDigestAt(
688
753
  journal,
689
754
  validated.checkpoint.threadId,
690
755
  validated.checkpoint.throughSequence,
691
756
  );
757
+
692
758
  if (canonicalDigest !== validated.checkpoint.tailDigest) {
693
759
  return yield* CheckpointRejected.make({
694
760
  threadId: validated.checkpoint.threadId,
@@ -696,12 +762,14 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
696
762
  });
697
763
  }
698
764
  const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);
765
+
699
766
  const raw = RawCheckpoint.make({
700
767
  threadId: validated.checkpoint.threadId,
701
768
  throughSequence: validated.checkpoint.throughSequence,
702
769
  tailDigest: validated.checkpoint.tailDigest,
703
770
  checkpointJson,
704
771
  });
772
+
705
773
  yield* hitFailpoint("save-checkpoint:before");
706
774
  yield* journal.saveCheckpoint(raw).pipe(
707
775
  Effect.mapError((error) =>
@@ -722,10 +790,13 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
722
790
  const validated = yield* Schema.decodeUnknownEffect(Schema.toType(LoadCheckpointRequest))(
723
791
  request,
724
792
  ).pipe(Effect.mapError((error) => schemaStoreError("validate checkpoint lookup", error)));
793
+
725
794
  const thread = yield* requireThread(journal, validated.threadId);
795
+
726
796
  const rows = yield* journal
727
797
  .loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence)
728
798
  .pipe(Effect.mapError((error) => storeError("load checkpoint", error)));
799
+
729
800
  if (rows.length === 0) return Option.none();
730
801
  if (rows.length !== 1) {
731
802
  return yield* ThreadStoreError.make({
@@ -734,17 +805,20 @@ const makeServices = Effect.fn("DoThreadStore.makeServices")(function* () {
734
805
  });
735
806
  }
736
807
  const checkpoint = yield* decodeCheckpoint(rows[0].checkpoint_json);
808
+
737
809
  const canonicalDigest = yield* tailDigestAt(
738
810
  journal,
739
811
  checkpoint.threadId,
740
812
  checkpoint.throughSequence,
741
813
  );
814
+
742
815
  if (canonicalDigest !== checkpoint.tailDigest) {
743
816
  return yield* CheckpointRejected.make({
744
817
  threadId: checkpoint.threadId,
745
818
  reason: "digest-mismatch",
746
819
  });
747
820
  }
821
+
748
822
  return Option.some(checkpoint);
749
823
  },
750
824
  );
package/src/errors.ts CHANGED
@@ -155,6 +155,7 @@ export const DoStorageFailpointLocation = Schema.Literals([
155
155
  "ledger:child-settled:before",
156
156
  "ledger:child-settled:after",
157
157
  ]);
158
+
158
159
  export type DoStorageFailpointLocation = typeof DoStorageFailpointLocation.Type;
159
160
 
160
161
  /** Deterministic test-only fault or pause injected at a Durable Object storage boundary. */
@@ -60,7 +60,9 @@ const RevalidateRequest = Schema.TaggedStruct("Revalidate", {
60
60
  lookup: MemoryLookup,
61
61
  limits: MemoryRecallLimits,
62
62
  });
63
+
63
64
  const ChangeRequest = Schema.TaggedStruct("Change", { ...RequestFields, write: MemoryWrite.Wire });
65
+
64
66
  const SemanticRequest: Schema.TaggedStruct<
65
67
  "RevalidateSemantic",
66
68
  typeof RequestFields & {
@@ -74,9 +76,11 @@ const SemanticRequest: Schema.TaggedStruct<
74
76
  profile: SemanticMemoryProfile,
75
77
  limits: SemanticCandidateLimits,
76
78
  });
79
+
77
80
  export const MemoryOwnerRequest: Schema.Union<
78
81
  [typeof RevalidateRequest, typeof ChangeRequest, typeof SemanticRequest]
79
82
  > = Schema.Union([RevalidateRequest, ChangeRequest, SemanticRequest]);
83
+
80
84
  export type MemoryOwnerRequest = typeof MemoryOwnerRequest.Type;
81
85
 
82
86
  export const MemoryOwnerFailure = Schema.Union([
@@ -90,6 +94,7 @@ export const MemoryOwnerFailure = Schema.Union([
90
94
  MemoryIndexError,
91
95
  SemanticMemoryError,
92
96
  ]);
97
+
93
98
  export type MemoryOwnerFailure = typeof MemoryOwnerFailure.Type;
94
99
 
95
100
  export const MemoryOwnerResponse = Schema.Union([
@@ -98,6 +103,7 @@ export const MemoryOwnerResponse = Schema.Union([
98
103
  Schema.TaggedStruct("Semantic", { access: MemoryAccess.Wire, result: SemanticCandidateResult }),
99
104
  Schema.TaggedStruct("Failed", { failure: MemoryOwnerFailure }),
100
105
  ]);
106
+
101
107
  export type MemoryOwnerResponse = typeof MemoryOwnerResponse.Type;
102
108
 
103
109
  /** Fail-closed application policy. Authorize the namespace, principal, scope, and full command. */
@@ -126,8 +132,10 @@ export const decodeMemoryWire = Effect.fn("decodeMemoryWire")(function* <A, I>(
126
132
  const text = yield* Schema.decodeUnknownEffect(Schema.String)(raw).pipe(
127
133
  Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
128
134
  );
135
+
129
136
  if (text.length > maxBytes || memoryWireBytes(text) > maxBytes)
130
137
  return yield* MemoryRpcError.make({ reason: "budget" });
138
+
131
139
  return yield* Schema.decodeEffect(Schema.fromJsonString(schema))(text).pipe(
132
140
  Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
133
141
  );
@@ -141,8 +149,10 @@ export const encodeMemoryWire = Effect.fn("encodeMemoryWire")(function* <A, I>(
141
149
  const encoded = yield* Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(
142
150
  Effect.mapError(() => MemoryRpcError.make({ reason: "protocol" })),
143
151
  );
152
+
144
153
  if (encoded.length > maxBytes || memoryWireBytes(encoded) > maxBytes)
145
154
  return yield* MemoryRpcError.make({ reason: "budget" });
155
+
146
156
  return encoded;
147
157
  });
148
158
 
@@ -165,6 +175,7 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
165
175
  );
166
176
  const request = yield* decodeMemoryWire(MemoryOwnerRequest, raw, limits.maxRequestBytes);
167
177
  const { namespace } = yield* MemoryOwnerIdentity;
178
+
168
179
  if (
169
180
  !MemoryNamespace.equals(namespace, request.access.namespace) ||
170
181
  (request._tag === "Change" &&
@@ -175,20 +186,25 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
175
186
  ))
176
187
  )
177
188
  return yield* MemoryRpcError.make({ reason: "denied" });
189
+
178
190
  const remaining = Math.min(
179
191
  limits.timeoutMillis,
180
192
  request.deadlineMillis - (yield* Clock.currentTimeMillis),
181
193
  );
194
+
182
195
  if (remaining <= 0) return yield* MemoryRpcError.make({ reason: "timeout" });
196
+
183
197
  return yield* Effect.gen(function* (): Effect.fn.Return<
184
198
  MemoryOwnerResponse,
185
199
  MemoryOwnerFailure,
186
200
  MemoryOwnerAuthorizer | MemoryReader | MemoryWriter
187
201
  > {
188
202
  const authorizer = yield* MemoryOwnerAuthorizer;
203
+
189
204
  yield* authorizer.authorize(request);
190
205
  if (request._tag === "Change") {
191
206
  const writer = yield* MemoryWriter;
207
+
192
208
  return {
193
209
  _tag: "Changed",
194
210
  access: request.access,
@@ -201,6 +217,7 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
201
217
  limits.maxSources
202
218
  )
203
219
  return yield* MemoryRpcError.make({ reason: "budget" });
220
+
204
221
  const result = yield* revalidateSemanticMemoryCandidates(
205
222
  request.found,
206
223
  request.access,
@@ -217,18 +234,23 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
217
234
  ),
218
235
  },
219
236
  );
237
+
220
238
  return { _tag: "Semantic", access: request.access, result };
221
239
  }
240
+
222
241
  const count =
223
242
  request.lookup._tag === "Found"
224
243
  ? new Set(request.lookup.passages.map((passage) => passage.source.id)).size
225
244
  : 0;
245
+
226
246
  if (count > Math.min(limits.maxSources, request.limits.maxSources))
227
247
  return yield* MemoryRpcError.make({ reason: "budget" });
248
+
228
249
  const lookup = yield* revalidateMemoryLookup(request.lookup, request.access, {
229
250
  maxSourceBytes: limits.maxSourceBytes,
230
251
  maxInputBytes: Math.min(limits.maxSourceBytes, request.limits.maxInputBytes ?? 16_777_216),
231
252
  });
253
+
232
254
  return { _tag: "Lookup", access: request.access, lookup };
233
255
  }).pipe(
234
256
  Effect.scoped,
@@ -243,7 +265,9 @@ export const handleMemoryOwnerRequest = Effect.fn("MemoryOwner.handleRequest")(f
243
265
  ),
244
266
  Effect.result,
245
267
  );
268
+
246
269
  if (result._tag === "Success") return result.success;
270
+
247
271
  return yield* encodeMemoryWire(
248
272
  MemoryOwnerResponse,
249
273
  {
@@ -177,6 +177,7 @@ export const PortRequest = Schema.Union([
177
177
  StoreInspectTailCall,
178
178
  StoreExportCall,
179
179
  ]);
180
+
180
181
  export type PortRequest = typeof PortRequest.Type;
181
182
 
182
183
  /** The wire form of one port request (what a transport actually carries). */
@@ -264,6 +265,7 @@ export const PortResult = Schema.Union([
264
265
  StoreInspectTailResult,
265
266
  StoreExportResult,
266
267
  ]);
268
+
267
269
  export type PortResult = typeof PortResult.Type;
268
270
 
269
271
  // ---------------------------------------------------------------------------
@@ -286,6 +288,7 @@ export const PortFailure = Schema.Union([
286
288
  FenceRejected,
287
289
  PortProtocolError,
288
290
  ]);
291
+
289
292
  export type PortFailure = typeof PortFailure.Type;
290
293
 
291
294
  /** The routed operation succeeded on its owning Object. */