@effect-agent/platform-cloudflare 0.1.0-beta.42 → 0.1.0-beta.44

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 (42) hide show
  1. package/dist/browser-quick-action.mjs.map +1 -1
  2. package/dist/browser-rest-capture.mjs.map +1 -1
  3. package/dist/browser-rest-crawl.mjs.map +1 -1
  4. package/dist/browser-session-lifecycle-DqntvG-Y.d.mts +21 -0
  5. package/dist/browser-session-lifecycle-ZGgb3pnK.mjs +84 -0
  6. package/dist/browser-session-lifecycle-ZGgb3pnK.mjs.map +1 -0
  7. package/dist/index.d.mts +69 -56
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/interactive-browser.d.mts +1 -18
  10. package/dist/interactive-browser.mjs +2 -81
  11. package/dist/interactive-browser.mjs.map +1 -1
  12. package/dist/prepared-admission-BKp_Upw2.mjs.map +1 -1
  13. package/dist/protected-browser.d.mts +62 -0
  14. package/dist/protected-browser.mjs +714 -0
  15. package/dist/protected-browser.mjs.map +1 -0
  16. package/dist/scheduling.mjs.map +1 -1
  17. package/dist/subscriptions.mjs.map +1 -1
  18. package/package.json +1 -81
  19. package/src/alarm.ts +41 -0
  20. package/src/bindings.ts +5 -0
  21. package/src/boundary.ts +4 -0
  22. package/src/browser-quick-action.ts +52 -0
  23. package/src/browser-rest-capture.ts +30 -0
  24. package/src/browser-rest-crawl.ts +43 -0
  25. package/src/browser-session-lifecycle.ts +18 -0
  26. package/src/client.ts +40 -0
  27. package/src/code-mode-executor.ts +50 -0
  28. package/src/interactive-browser.ts +176 -0
  29. package/src/layers.ts +10 -0
  30. package/src/memory.ts +42 -3
  31. package/src/prepared-admission.ts +1 -0
  32. package/src/progress-wait.ts +14 -0
  33. package/src/protected-browser/binding.ts +185 -0
  34. package/src/protected-browser/inspect-frame.ts +82 -0
  35. package/src/protected-browser/native.ts +384 -0
  36. package/src/protected-browser/policy.ts +594 -0
  37. package/src/protected-browser.ts +2 -0
  38. package/src/scheduling.ts +34 -0
  39. package/src/subscriptions.ts +50 -0
  40. package/src/thread-object.ts +55 -1
  41. package/src/transport.ts +1 -0
  42. package/src/wake-scheduler.ts +1 -0
package/src/scheduling.ts CHANGED
@@ -119,6 +119,7 @@ const ScheduleOwnerRequest = Schema.Union([
119
119
  ScheduleListRequest,
120
120
  ScheduleControlRequest,
121
121
  ]);
122
+
122
123
  type ScheduleOwnerRequest = typeof ScheduleOwnerRequest.Type;
123
124
 
124
125
  const ScheduleOwnerFailure = Schema.Union([
@@ -131,6 +132,7 @@ const ScheduleOwnerFailure = Schema.Union([
131
132
  ScheduleFailpointError,
132
133
  ScheduleOwnerProtocolError,
133
134
  ]);
135
+
134
136
  type ScheduleOwnerFailure = typeof ScheduleOwnerFailure.Type;
135
137
 
136
138
  const ScheduleOwnerResponse = Schema.Union([
@@ -138,6 +140,7 @@ const ScheduleOwnerResponse = Schema.Union([
138
140
  Schema.TaggedStruct("Page", { value: ScheduleSnapshotPageSchema }),
139
141
  Schema.TaggedStruct("Failed", { failure: ScheduleOwnerFailure }),
140
142
  ]);
143
+
141
144
  type ScheduleOwnerResponse = typeof ScheduleOwnerResponse.Type;
142
145
 
143
146
  const decodeScheduleOwnerRequest = Schema.decodeUnknownEffect(ScheduleOwnerRequest);
@@ -181,6 +184,7 @@ export class CloudflareSchedulingClient {
181
184
  ScheduleStorageError.make({ operation: "Schedule Owner protocol", reason: "corrupt" }),
182
185
  ),
183
186
  );
187
+
184
188
  const raw = yield* Effect.tryPromise({
185
189
  try: () => namespace.get(namespace.idFromName(scheduleOwnerKey(owner))).schedule(encoded),
186
190
  catch: () =>
@@ -189,12 +193,15 @@ export class CloudflareSchedulingClient {
189
193
  reason: "unavailable",
190
194
  }),
191
195
  });
196
+
192
197
  const response = yield* decodeScheduleOwnerResponse(raw).pipe(
193
198
  Effect.mapError(() =>
194
199
  ScheduleStorageError.make({ operation: "Schedule Owner protocol", reason: "corrupt" }),
195
200
  ),
196
201
  );
202
+
197
203
  if (response._tag !== "Failed") return response;
204
+
198
205
  return yield* response.failure._tag === "ScheduleOwnerProtocolError"
199
206
  ? ScheduleStorageError.make({ operation: "Schedule Owner protocol", reason: "corrupt" })
200
207
  : response.failure;
@@ -213,6 +220,7 @@ export class CloudflareSchedulingClient {
213
220
  }),
214
221
  ),
215
222
  );
223
+
216
224
  return yield* Schema.decodeUnknownEffect(PersistedJson)(encoded).pipe(
217
225
  Effect.mapError(() =>
218
226
  ScheduleValidationError.make({
@@ -225,6 +233,7 @@ export class CloudflareSchedulingClient {
225
233
  const create: Scheduling["Service"]["create"] = (agent, input, options) =>
226
234
  Effect.gen(function* () {
227
235
  const payload = yield* encodeInput(agent, input);
236
+
228
237
  const response = yield* call(options.scope.owner, {
229
238
  _tag: "Create",
230
239
  schemaVersion: 1,
@@ -232,6 +241,7 @@ export class CloudflareSchedulingClient {
232
241
  input: payload,
233
242
  ...options,
234
243
  });
244
+
235
245
  return response._tag === "Snapshot"
236
246
  ? response.value
237
247
  : yield* ScheduleStorageError.make({
@@ -243,6 +253,7 @@ export class CloudflareSchedulingClient {
243
253
  const update: Scheduling["Service"]["update"] = (agent, input, options) =>
244
254
  Effect.gen(function* () {
245
255
  const payload = yield* encodeInput(agent, input);
256
+
246
257
  const response = yield* call(options.scope.owner, {
247
258
  _tag: "Update",
248
259
  schemaVersion: 1,
@@ -250,6 +261,7 @@ export class CloudflareSchedulingClient {
250
261
  input: payload,
251
262
  ...options,
252
263
  });
264
+
253
265
  return response._tag === "Snapshot"
254
266
  ? response.value
255
267
  : yield* ScheduleStorageError.make({
@@ -266,6 +278,7 @@ export class CloudflareSchedulingClient {
266
278
  scope,
267
279
  scheduleId,
268
280
  });
281
+
269
282
  return response._tag === "Snapshot"
270
283
  ? response.value
271
284
  : yield* ScheduleStorageError.make({
@@ -283,6 +296,7 @@ export class CloudflareSchedulingClient {
283
296
  ...(options.after === undefined ? {} : { after: options.after }),
284
297
  ...(options.limit === undefined ? {} : { limit: options.limit }),
285
298
  });
299
+
286
300
  return response._tag === "Page"
287
301
  ? response.value
288
302
  : yield* ScheduleStorageError.make({
@@ -306,6 +320,7 @@ export class CloudflareSchedulingClient {
306
320
  scheduleId,
307
321
  expectedRevision,
308
322
  });
323
+
309
324
  return response._tag === "Snapshot"
310
325
  ? response.value
311
326
  : yield* ScheduleStorageError.make({
@@ -340,6 +355,7 @@ const decodeOwnerName = Effect.fn("decodeScheduleOwnerName")(function* (
340
355
  message: "Schedule Owner objects require an idFromName identity",
341
356
  });
342
357
  }
358
+
343
359
  const tuple = yield* Schema.decodeUnknownEffect(
344
360
  Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String])),
345
361
  )(name).pipe(
@@ -347,6 +363,7 @@ const decodeOwnerName = Effect.fn("decodeScheduleOwnerName")(function* (
347
363
  ScheduleOwnerProtocolError.make({ message: "Schedule Owner object name is malformed" }),
348
364
  ),
349
365
  );
366
+
350
367
  return yield* Schema.decodeUnknownEffect(ScheduleOwner)({
351
368
  tenantId: tuple[0],
352
369
  ownerId: tuple[1],
@@ -371,10 +388,12 @@ const transactionLayer: Layer.Layer<
371
388
  DoScheduleTransaction,
372
389
  Effect.gen(function* () {
373
390
  const alarms = yield* DurableObjectAlarm.DurableObjectAlarm;
391
+
374
392
  return DoScheduleTransaction.of({
375
393
  run: (body) =>
376
394
  Effect.gen(function* () {
377
395
  const nowMillis = yield* Clock.currentTimeMillis;
396
+
378
397
  return yield* alarms
379
398
  .transaction((transaction) =>
380
399
  body((replacement) =>
@@ -434,6 +453,7 @@ const ensureOwner = (
434
453
  request: ScheduleOwnerRequest,
435
454
  ): Effect.Effect<void, ScheduleOwnerProtocolError> => {
436
455
  const observed = requestOwner(request);
456
+
437
457
  return observed.tenantId === expected.tenantId && observed.ownerId === expected.ownerId
438
458
  ? Effect.void
439
459
  : Effect.fail(
@@ -447,6 +467,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
447
467
  encoded: unknown,
448
468
  ): Effect.fn.Return<unknown, never, Scheduling | ScheduleOwnerIdentity> {
449
469
  const decoded = yield* decodeScheduleOwnerRequest(encoded).pipe(Effect.result);
470
+
450
471
  if (decoded._tag === "Failure") {
451
472
  return yield* encodeScheduleOwnerResponse(
452
473
  scheduleProtocolFailure("The Schedule request could not be decoded"),
@@ -455,6 +476,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
455
476
  const request = decoded.success;
456
477
  const { owner } = yield* ScheduleOwnerIdentity;
457
478
  const scheduling = yield* Scheduling;
479
+
458
480
  const response = yield* Effect.gen(function* () {
459
481
  yield* ensureOwner(owner, request);
460
482
  switch (request._tag) {
@@ -467,6 +489,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
467
489
  deliveryPrincipal: request.deliveryPrincipal,
468
490
  definitions: request.definitions,
469
491
  });
492
+
470
493
  return { _tag: "Snapshot" as const, value };
471
494
  }
472
495
  case "Update": {
@@ -479,6 +502,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
479
502
  definitions: request.definitions,
480
503
  expectedRevision: request.expectedRevision,
481
504
  });
505
+
482
506
  return { _tag: "Snapshot" as const, value };
483
507
  }
484
508
  case "Get":
@@ -509,6 +533,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
509
533
  request.scheduleId,
510
534
  request.expectedRevision,
511
535
  );
536
+
512
537
  return { _tag: "Snapshot" as const, value };
513
538
  }
514
539
  }
@@ -522,6 +547,7 @@ const handleScheduleRequest = Effect.fn("ScheduleOwner.handleRequest")(function*
522
547
  ),
523
548
  ),
524
549
  );
550
+
525
551
  return yield* encodeScheduleOwnerResponse(response).pipe(Effect.orDie);
526
552
  });
527
553
 
@@ -545,8 +571,10 @@ const scheduleAlarmHandler = (limits: SchedulingLimits) =>
545
571
  const alarmControl = yield* DoScheduleAlarmControl;
546
572
  const { owner } = yield* ScheduleOwnerIdentity;
547
573
  const nowMillis = yield* Clock.currentTimeMillis;
574
+
548
575
  yield* alarmControl.prearm(nowMillis + limits.recoveryPollMillis);
549
576
  const pass = yield* scheduling.runDue(owner);
577
+
550
578
  if (pass.failed > 0) {
551
579
  yield* alarmControl.prearm((yield* Clock.currentTimeMillis) + limits.recoveryPollMillis);
552
580
  } else {
@@ -585,14 +613,17 @@ export const makeScheduleOwnerObjectClass = <E>(
585
613
  ScheduleOwnerIdentity,
586
614
  Effect.gen(function* () {
587
615
  const state = yield* EffectCfDurableObjectState.DurableObjectState;
616
+
588
617
  return ScheduleOwnerIdentity.of({ owner: yield* decodeOwnerName(state.raw.id.name) });
589
618
  }),
590
619
  );
620
+
591
621
  const sqlLayer = Layer.unwrap(
592
622
  Effect.map(EffectCfDurableObjectState.DurableObjectState, (state) =>
593
623
  SqliteClient.layer({ storage: state.raw.storage }),
594
624
  ),
595
625
  );
626
+
596
627
  const application = Layer.merge(Scheduling.layer(limits), ScheduleDriver.layer(limits)).pipe(
597
628
  Layer.provideMerge(
598
629
  scheduleStoreLayer.pipe(Layer.provide(transactionLayer), Layer.provide(sqlLayer)),
@@ -609,6 +640,7 @@ export const makeScheduleOwnerObjectClass = <E>(
609
640
  Layer.provide(host),
610
641
  Layer.provideMerge(ownerLayer),
611
642
  );
643
+
612
644
  const runtime: Layer.Layer<
613
645
  ScheduleRuntimeServices,
614
646
  E | ScheduleStorageError | ScheduleOwnerProtocolError | ScheduleValidationError,
@@ -617,6 +649,7 @@ export const makeScheduleOwnerObjectClass = <E>(
617
649
  Effect.gen(function* () {
618
650
  const state = yield* EffectCfDurableObjectState.DurableObjectState;
619
651
  const scope = yield* Effect.scope;
652
+
620
653
  return yield* state.blockConcurrencyWhile(Layer.buildWithScope(application, scope));
621
654
  }),
622
655
  );
@@ -636,5 +669,6 @@ export const makeScheduleOwnerObjectClass = <E>(
636
669
  return super.alarm?.(alarmInfo);
637
670
  }
638
671
  }
672
+
639
673
  return ScheduleOwnerObject;
640
674
  };
@@ -70,6 +70,7 @@ export const validateCloudflareSubscriptionLimits = (
70
70
  ): Effect.Effect<void, CloudflareSubscriptionConfigError> => {
71
71
  const worstCaseMillis =
72
72
  4 * Math.ceil(limits.batchSize / limits.concurrency) * limits.operationTimeoutMillis;
73
+
73
74
  return worstCaseMillis <= MAX_ALARM_WALL_MILLIS
74
75
  ? Effect.void
75
76
  : Effect.fail(
@@ -146,16 +147,19 @@ const SubscriptionPartitionRequest = Schema.Union([
146
147
  AcceptRequest,
147
148
  StatusRequest,
148
149
  ]);
150
+
149
151
  type SubscriptionPartitionRequest = typeof SubscriptionPartitionRequest.Type;
150
152
 
151
153
  const SubscriptionPage = Schema.Struct({
152
154
  items: Schema.Array(SubscriptionSnapshot),
153
155
  next: Schema.NullOr(Schema.Natural),
154
156
  });
157
+
155
158
  const DeliveryPage = Schema.Struct({
156
159
  items: Schema.Array(SubscriptionDeliverySnapshot),
157
160
  next: Schema.NullOr(Schema.String),
158
161
  });
162
+
159
163
  const IntakeStatus = Schema.Struct({
160
164
  ...EventAcknowledgement.fields,
161
165
  routingComplete: Schema.Boolean,
@@ -169,6 +173,7 @@ const SubscriptionPartitionFailure = Schema.Union([
169
173
  SubscriptionFailpointError,
170
174
  SubscriptionPartitionProtocolError,
171
175
  ]);
176
+
172
177
  type SubscriptionPartitionFailure = typeof SubscriptionPartitionFailure.Type;
173
178
 
174
179
  const SubscriptionPartitionResponse = Schema.Union([
@@ -179,6 +184,7 @@ const SubscriptionPartitionResponse = Schema.Union([
179
184
  Schema.TaggedStruct("Status", { value: IntakeStatus }),
180
185
  Schema.TaggedStruct("Failed", { failure: SubscriptionPartitionFailure }),
181
186
  ]);
187
+
182
188
  type SubscriptionPartitionResponse = typeof SubscriptionPartitionResponse.Type;
183
189
 
184
190
  const decodeRequest = Schema.decodeUnknownEffect(SubscriptionPartitionRequest);
@@ -205,6 +211,7 @@ export class SubscriptionPartitionNamespace extends Context.Service<
205
211
 
206
212
  const storageFailure = (code: string): SubscriptionError =>
207
213
  SubscriptionError.make({ reason: "storage", code });
214
+
208
215
  const corruptFailure = (code: string): SubscriptionError =>
209
216
  SubscriptionError.make({ reason: "corrupt", code });
210
217
 
@@ -224,9 +231,11 @@ export class CloudflareSubscriptionsClient {
224
231
  if (!samePartition(partition, addressedPartition)) {
225
232
  return yield* SubscriptionError.make({ reason: "unauthorized", code: "partition" });
226
233
  }
234
+
227
235
  const encoded = yield* encodeRequest(request).pipe(
228
236
  Effect.mapError(() => corruptFailure("subscription-partition-protocol")),
229
237
  );
238
+
230
239
  const raw = yield* Effect.tryPromise({
231
240
  try: () =>
232
241
  namespace
@@ -234,6 +243,7 @@ export class CloudflareSubscriptionsClient {
234
243
  .subscription(encoded),
235
244
  catch: () => storageFailure("call-subscription-partition"),
236
245
  });
246
+
237
247
  return yield* decodeResponse(raw).pipe(
238
248
  Effect.mapError(() => corruptFailure("subscription-partition-protocol")),
239
249
  );
@@ -245,6 +255,7 @@ export class CloudflareSubscriptionsClient {
245
255
  : SubscriptionPartitionProtocolError.make({
246
256
  message: "Unexpected subscription response",
247
257
  });
258
+
248
259
  const asProtocolError = (): SubscriptionError =>
249
260
  corruptFailure("subscription-partition-protocol");
250
261
 
@@ -257,14 +268,17 @@ export class CloudflareSubscriptionsClient {
257
268
  scope,
258
269
  options,
259
270
  });
271
+
260
272
  if (response._tag === "Snapshot") return response.value;
261
273
  const failure = failed(response);
274
+
262
275
  if (
263
276
  failure._tag === "SubscriptionError" ||
264
277
  failure._tag === "SubscriptionSourceError" ||
265
278
  failure._tag === "SubscriptionFailpointError"
266
279
  )
267
280
  return yield* failure;
281
+
268
282
  return yield* asProtocolError();
269
283
  }),
270
284
  listSubscriptions: (scope, after, limit) =>
@@ -276,8 +290,10 @@ export class CloudflareSubscriptionsClient {
276
290
  ...(after === undefined ? {} : { after }),
277
291
  ...(limit === undefined ? {} : { limit }),
278
292
  });
293
+
279
294
  if (response._tag === "SubscriptionPage") return response.value;
280
295
  const failure = failed(response);
296
+
281
297
  return yield* failure._tag === "SubscriptionError" ? failure : asProtocolError();
282
298
  }),
283
299
  cancelSubscription: (scope, key) =>
@@ -288,13 +304,16 @@ export class CloudflareSubscriptionsClient {
288
304
  scope,
289
305
  key,
290
306
  });
307
+
291
308
  if (response._tag === "Snapshot") return response.value;
292
309
  const failure = failed(response);
310
+
293
311
  if (
294
312
  failure._tag === "SubscriptionError" ||
295
313
  failure._tag === "SubscriptionFailpointError"
296
314
  )
297
315
  return yield* failure;
316
+
298
317
  return yield* asProtocolError();
299
318
  }),
300
319
  listDeliveries: (scope, key, after, limit) =>
@@ -307,8 +326,10 @@ export class CloudflareSubscriptionsClient {
307
326
  ...(after === undefined ? {} : { after }),
308
327
  ...(limit === undefined ? {} : { limit }),
309
328
  });
329
+
310
330
  if (response._tag === "DeliveryPage") return response.value;
311
331
  const failure = failed(response);
332
+
312
333
  return yield* failure._tag === "SubscriptionError" ? failure : asProtocolError();
313
334
  }),
314
335
  });
@@ -328,15 +349,19 @@ export class CloudflareSubscriptionsClient {
328
349
  SubscriptionError.make({ reason: "validation", code: "event-payload" }),
329
350
  ),
330
351
  );
352
+
331
353
  const response = yield* call(request.partition, request);
354
+
332
355
  if (response._tag === "Acknowledgement") return response.value;
333
356
  const failure = failed(response);
357
+
334
358
  if (
335
359
  failure._tag === "SubscriptionError" ||
336
360
  failure._tag === "SubscriptionSourceError" ||
337
361
  failure._tag === "SubscriptionFailpointError"
338
362
  )
339
363
  return yield* failure;
364
+
340
365
  return yield* asProtocolError();
341
366
  }),
342
367
  status: (principal, source, eventId) =>
@@ -349,8 +374,10 @@ export class CloudflareSubscriptionsClient {
349
374
  source,
350
375
  eventId,
351
376
  });
377
+
352
378
  if (response._tag === "Status") return response.value;
353
379
  const failure = failed(response);
380
+
354
381
  return yield* failure._tag === "SubscriptionError" ? failure : asProtocolError();
355
382
  }),
356
383
  });
@@ -376,6 +403,7 @@ const decodePartitionName = Effect.fn("decodeSubscriptionPartitionName")(functio
376
403
  message: "Subscription Partition objects require an idFromName identity",
377
404
  });
378
405
  }
406
+
379
407
  const tuple = yield* Schema.decodeUnknownEffect(
380
408
  Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String])),
381
409
  )(name).pipe(
@@ -385,6 +413,7 @@ const decodePartitionName = Effect.fn("decodeSubscriptionPartitionName")(functio
385
413
  }),
386
414
  ),
387
415
  );
416
+
388
417
  return yield* Schema.decodeUnknownEffect(SourcePartition)({
389
418
  tenantId: tuple[0],
390
419
  address: tuple[1],
@@ -398,6 +427,7 @@ const decodePartitionName = Effect.fn("decodeSubscriptionPartitionName")(functio
398
427
  });
399
428
 
400
429
  const samePartition = Schema.toEquivalence(SourcePartition);
430
+
401
431
  const requestPartition = (request: SubscriptionPartitionRequest): SourcePartition =>
402
432
  request._tag === "Accept" || request._tag === "Status"
403
433
  ? request.partition
@@ -407,6 +437,7 @@ const handleRequest = Effect.fn("SubscriptionPartition.handleRequest")(function*
407
437
  encoded: unknown,
408
438
  ) {
409
439
  const decoded = yield* decodeRequest(encoded).pipe(Effect.result);
440
+
410
441
  if (decoded._tag === "Failure") {
411
442
  return yield* encodeResponse(
412
443
  protocolFailure("The subscription request could not be decoded"),
@@ -414,6 +445,7 @@ const handleRequest = Effect.fn("SubscriptionPartition.handleRequest")(function*
414
445
  }
415
446
  const request = decoded.success;
416
447
  const { partition } = yield* SubscriptionPartitionIdentity;
448
+
417
449
  if (!samePartition(partition, requestPartition(request))) {
418
450
  return yield* encodeResponse(
419
451
  protocolFailure("The request partition does not match the addressed object"),
@@ -421,6 +453,7 @@ const handleRequest = Effect.fn("SubscriptionPartition.handleRequest")(function*
421
453
  }
422
454
  const subscriptions = yield* Subscriptions;
423
455
  const intake = yield* SubscriptionIntake;
456
+
424
457
  const response = yield* Effect.gen(function* (): Effect.fn.Return<
425
458
  SubscriptionPartitionResponse,
426
459
  SubscriptionPartitionFailure
@@ -473,6 +506,7 @@ const handleRequest = Effect.fn("SubscriptionPartition.handleRequest")(function*
473
506
  : Effect.succeed(protocolFailure("The subscription operation failed outside its contract")),
474
507
  ),
475
508
  );
509
+
476
510
  return yield* encodeResponse(response).pipe(Effect.orDie);
477
511
  });
478
512
 
@@ -486,10 +520,12 @@ const transactionLayer: Layer.Layer<
486
520
  DoSubscriptionTransaction,
487
521
  Effect.gen(function* () {
488
522
  const alarms = yield* DurableObjectAlarm.DurableObjectAlarm;
523
+
489
524
  return DoSubscriptionTransaction.of({
490
525
  run: (body) =>
491
526
  Effect.gen(function* () {
492
527
  const nowMillis = yield* Clock.currentTimeMillis;
528
+
493
529
  return yield* alarms
494
530
  .transaction((transaction) =>
495
531
  body((replacement) =>
@@ -542,7 +578,9 @@ const alarmHandler = (limits: SubscriptionLimits) =>
542
578
  );
543
579
  const driver = yield* SubscriptionDriver;
544
580
  const alarmControl = yield* DoSubscriptionAlarmControl;
581
+
545
582
  yield* alarmControl.prearm((yield* Clock.currentTimeMillis) + limits.retryMillis);
583
+
546
584
  const pass = yield* driver.runDue.pipe(
547
585
  Effect.catchCause((cause) =>
548
586
  Cause.hasInterrupts(cause)
@@ -553,6 +591,7 @@ const alarmHandler = (limits: SubscriptionLimits) =>
553
591
  ),
554
592
  ),
555
593
  );
594
+
556
595
  if (pass.failed > 0) {
557
596
  yield* alarmControl.prearm((yield* Clock.currentTimeMillis) + limits.retryMillis);
558
597
  } else {
@@ -596,20 +635,24 @@ export const makeSubscriptionPartitionObjectClass = <E>(
596
635
  limits: SubscriptionLimits = defaultSubscriptionLimits,
597
636
  ): SubscriptionPartitionObjectClass => {
598
637
  const cloudflareLimitsLayer = Layer.effectDiscard(validateCloudflareSubscriptionLimits(limits));
638
+
599
639
  const identityLayer = Layer.effect(
600
640
  SubscriptionPartitionIdentity,
601
641
  Effect.gen(function* () {
602
642
  const state = yield* EffectCfDurableObjectState.DurableObjectState;
643
+
603
644
  return SubscriptionPartitionIdentity.of({
604
645
  partition: yield* decodePartitionName(state.raw.id.name),
605
646
  });
606
647
  }),
607
648
  );
649
+
608
650
  const sqlLayer = Layer.unwrap(
609
651
  Effect.map(EffectCfDurableObjectState.DurableObjectState, (state) =>
610
652
  SqliteClient.layer({ storage: state.raw.storage }),
611
653
  ),
612
654
  );
655
+
613
656
  const partitionStore = Layer.unwrap(
614
657
  Effect.map(SubscriptionPartitionIdentity, ({ partition }) =>
615
658
  doSubscriptionStoreLayer(partition).pipe(
@@ -618,6 +661,7 @@ export const makeSubscriptionPartitionObjectClass = <E>(
618
661
  ),
619
662
  ),
620
663
  );
664
+
621
665
  const application = Layer.mergeAll(
622
666
  Subscriptions.layer(limits),
623
667
  SubscriptionIntake.layer(limits),
@@ -633,6 +677,7 @@ export const makeSubscriptionPartitionObjectClass = <E>(
633
677
  Layer.provide(host),
634
678
  Layer.provideMerge(identityLayer),
635
679
  );
680
+
636
681
  const runtime: Layer.Layer<
637
682
  SubscriptionRuntimeServices,
638
683
  E | SubscriptionError | SubscriptionPartitionProtocolError | CloudflareSubscriptionConfigError,
@@ -641,21 +686,26 @@ export const makeSubscriptionPartitionObjectClass = <E>(
641
686
  Effect.gen(function* () {
642
687
  const state = yield* EffectCfDurableObjectState.DurableObjectState;
643
688
  const scope = yield* Effect.scope;
689
+
644
690
  return yield* state.blockConcurrencyWhile(Layer.buildWithScope(application, scope));
645
691
  }),
646
692
  );
693
+
647
694
  const rpc = {
648
695
  subscription: (encoded: unknown) => handleRequest(encoded),
649
696
  } satisfies EffectCfDurableObject.DurableObjectRpc<SubscriptionRuntimeServices>;
697
+
650
698
  const Base = EffectCfDurableObject.make(runtime, {
651
699
  initialize: Effect.void,
652
700
  rpc,
653
701
  alarms: alarmHandler(limits),
654
702
  });
703
+
655
704
  class SubscriptionPartitionObject extends Base {
656
705
  override alarm(alarmInfo?: AlarmInvocationInfo): Promise<void> | void {
657
706
  return super.alarm?.(alarmInfo);
658
707
  }
659
708
  }
709
+
660
710
  return SubscriptionPartitionObject;
661
711
  };