@yielded/agent-platform-cloudflare 0.0.0-stage → 0.1.0-beta.166

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/dist/Alarm-B0ODr1NE.mjs +1738 -0
  3. package/dist/Alarm-B0ODr1NE.mjs.map +1 -0
  4. package/dist/Alarm.d.mts +267 -0
  5. package/dist/Alarm.mjs +2 -0
  6. package/dist/BrowserCredentials.d.mts +91 -0
  7. package/dist/BrowserCredentials.mjs +120 -0
  8. package/dist/BrowserCredentials.mjs.map +1 -0
  9. package/dist/BrowserRestCapture.d.mts +34 -0
  10. package/dist/BrowserRestCapture.mjs +238 -0
  11. package/dist/BrowserRestCapture.mjs.map +1 -0
  12. package/dist/BrowserRestCrawl.d.mts +16 -0
  13. package/dist/BrowserRestCrawl.mjs +244 -0
  14. package/dist/BrowserRestCrawl.mjs.map +1 -0
  15. package/dist/BrowserSession-B969Xg-2.d.mts +132 -0
  16. package/dist/BrowserSession-RfIzxGCH.mjs +515 -0
  17. package/dist/BrowserSession-RfIzxGCH.mjs.map +1 -0
  18. package/dist/BrowserSession.d.mts +3 -0
  19. package/dist/BrowserSession.mjs +4 -0
  20. package/dist/CloudflareAiGateway.d.mts +64 -0
  21. package/dist/CloudflareAiGateway.mjs +70 -0
  22. package/dist/CloudflareAiGateway.mjs.map +1 -0
  23. package/dist/CloudflareBindings.d.mts +115 -0
  24. package/dist/CloudflareBindings.mjs +113 -0
  25. package/dist/CloudflareBindings.mjs.map +1 -0
  26. package/dist/CloudflareBrowser-5an6m-Qb.mjs +495 -0
  27. package/dist/CloudflareBrowser-5an6m-Qb.mjs.map +1 -0
  28. package/dist/CloudflareBrowser-gu7gma0Y.d.mts +80 -0
  29. package/dist/CloudflareBrowser.d.mts +2 -0
  30. package/dist/CloudflareBrowser.mjs +2 -0
  31. package/dist/CloudflareCodeMode.d.mts +44 -0
  32. package/dist/CloudflareCodeMode.mjs +616 -0
  33. package/dist/CloudflareCodeMode.mjs.map +1 -0
  34. package/dist/CloudflareConfig-qDrRLofL.d.mts +100 -0
  35. package/dist/CloudflareConfig.d.mts +2 -0
  36. package/dist/CloudflareConfig.mjs +122 -0
  37. package/dist/CloudflareConfig.mjs.map +1 -0
  38. package/dist/CloudflareMemory.d.mts +142 -0
  39. package/dist/CloudflareMemory.mjs +202 -0
  40. package/dist/CloudflareMemory.mjs.map +1 -0
  41. package/dist/CloudflareScheduling.d.mts +52 -0
  42. package/dist/CloudflareScheduling.mjs +396 -0
  43. package/dist/CloudflareScheduling.mjs.map +1 -0
  44. package/dist/CloudflareSubscriptions.d.mts +87 -0
  45. package/dist/CloudflareSubscriptions.mjs +529 -0
  46. package/dist/CloudflareSubscriptions.mjs.map +1 -0
  47. package/dist/CloudflareThreadClient.d.mts +1796 -0
  48. package/dist/CloudflareThreadClient.mjs +382 -0
  49. package/dist/CloudflareThreadClient.mjs.map +1 -0
  50. package/dist/InteractiveBrowser-BbG3kGA9.mjs +1934 -0
  51. package/dist/InteractiveBrowser-BbG3kGA9.mjs.map +1 -0
  52. package/dist/InteractiveBrowser-wV2Bti5e.d.mts +228 -0
  53. package/dist/InteractiveBrowser.d.mts +2 -0
  54. package/dist/InteractiveBrowser.mjs +2 -0
  55. package/dist/ThreadObject-BcfXbzSO.d.mts +867 -0
  56. package/dist/ThreadObject-DHjrnlX4.mjs +937 -0
  57. package/dist/ThreadObject-DHjrnlX4.mjs.map +1 -0
  58. package/dist/ThreadObject.d.mts +2 -0
  59. package/dist/ThreadObject.mjs +3 -0
  60. package/dist/WakeScheduler.d.mts +23 -0
  61. package/dist/WakeScheduler.mjs +57 -0
  62. package/dist/WakeScheduler.mjs.map +1 -0
  63. package/dist/boundary-BguazVkh.mjs +42 -0
  64. package/dist/boundary-BguazVkh.mjs.map +1 -0
  65. package/dist/index.d.mts +15 -0
  66. package/dist/index.mjs +15 -0
  67. package/dist/prepared-admission-DMX5p9dC.mjs +73 -0
  68. package/dist/prepared-admission-DMX5p9dC.mjs.map +1 -0
  69. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  70. package/package.json +1 -6
  71. package/src/Alarm.ts +2961 -0
  72. package/src/BrowserCredentials.ts +146 -0
  73. package/src/BrowserRestCapture.ts +477 -0
  74. package/src/BrowserRestCrawl.ts +540 -0
  75. package/src/BrowserSession.ts +667 -0
  76. package/src/CloudflareAiGateway.ts +170 -0
  77. package/src/CloudflareBindings.ts +199 -0
  78. package/src/CloudflareBrowser.ts +15 -0
  79. package/src/CloudflareCodeMode.ts +878 -0
  80. package/src/CloudflareConfig.ts +138 -0
  81. package/src/CloudflareMemory.ts +420 -0
  82. package/src/CloudflareScheduling.ts +745 -0
  83. package/src/CloudflareSubscriptions.ts +1044 -0
  84. package/src/CloudflareThreadClient.ts +809 -0
  85. package/src/InteractiveBrowser.ts +3275 -0
  86. package/src/ThreadObject.ts +1198 -0
  87. package/src/WakeScheduler.ts +91 -0
  88. package/src/index.ts +14 -0
  89. package/src/internal/boundary.ts +55 -0
  90. package/src/internal/browser-binding.ts +322 -0
  91. package/src/internal/browser-credentials.ts +362 -0
  92. package/src/internal/browser-failure.ts +92 -0
  93. package/src/internal/browser-file-selection.ts +126 -0
  94. package/src/internal/browser-quick-action.ts +857 -0
  95. package/src/internal/browser-readonly-live-view.ts +111 -0
  96. package/src/internal/browser-session-lifecycle.ts +193 -0
  97. package/src/internal/due-queue.ts +493 -0
  98. package/src/internal/layers.ts +1068 -0
  99. package/src/internal/message-delivery.ts +120 -0
  100. package/src/internal/prepared-admission.ts +116 -0
  101. package/src/internal/progress-wait.ts +121 -0
  102. package/src/internal/transport.ts +56 -0
  103. package/README.md +0 -3
@@ -0,0 +1,120 @@
1
+ import { type ThreadId } from "@yielded/agent/identifiers";
2
+ import {
3
+ MessageDeliveryDriver,
4
+ MessageDeliveryError,
5
+ MessageDeliveryStore,
6
+ } from "@yielded/agent/message-delivery";
7
+ import { WakeScheduler } from "@yielded/agent/wake-scheduler";
8
+ import { Clock, Context, Effect, Layer, Option } from "effect";
9
+
10
+ import { DurableAlarmError, ThreadMessageDelivery, ThreadMutationGate } from "../Alarm.ts";
11
+ import { ThreadObjectPlacement } from "../CloudflareBindings.ts";
12
+ import * as DueQueue from "./due-queue.ts";
13
+
14
+ /** Every write prearms its owner; the delivery due index owns its recovery deadline. */
15
+ export const guardedMessageDeliveryStoreLayer = Layer.effect(
16
+ MessageDeliveryStore,
17
+ Effect.gen(function* () {
18
+ const store = yield* MessageDeliveryStore;
19
+ const mutations = yield* ThreadMutationGate;
20
+ const wakes = yield* WakeScheduler;
21
+ const { ownsThread } = yield* ThreadObjectPlacement;
22
+
23
+ const local = <A, E>(
24
+ owner: ThreadId | undefined,
25
+ body: Effect.Effect<A, E>,
26
+ ): Effect.Effect<A, E | MessageDeliveryError> =>
27
+ owner === undefined || ownsThread(owner)
28
+ ? body
29
+ : Effect.fail(
30
+ MessageDeliveryError.make({ reason: "validation", operation: "message owner" }),
31
+ );
32
+
33
+ const mutate = <A, E>(body: Effect.Effect<A, E>) =>
34
+ mutations
35
+ .withMutation(body, {
36
+ invalidatesRecovery: false,
37
+ lanes: [
38
+ DueQueue.Messages,
39
+ ...(store.lifecyclePublications === undefined ? [] : [DueQueue.Lifecycle]),
40
+ ],
41
+ })
42
+ .pipe(
43
+ Effect.catchTag("DurableAlarmError", (cause) =>
44
+ MessageDeliveryError.make({
45
+ reason: "storage",
46
+ operation: "prearm message delivery",
47
+ cause,
48
+ }),
49
+ ),
50
+ );
51
+
52
+ return MessageDeliveryStore.of({
53
+ limits: store.limits,
54
+ maxStoredValueBytes: store.maxStoredValueBytes,
55
+ insert: (record) =>
56
+ local(
57
+ record.key.ownerThreadId,
58
+ mutate(store.insert(record)).pipe(
59
+ Effect.tap(() => wakes.notify(record.key.ownerThreadId)),
60
+ ),
61
+ ),
62
+ get: (key) => local(key.ownerThreadId, store.get(key)),
63
+ list: (request) => local(request.ownerThreadId, store.list(request)),
64
+ change: (key, change) => local(key.ownerThreadId, mutate(store.change(key, change))),
65
+ // Only the trusted physical-owner selection omits an owner. All returned keys still
66
+ // pass placement validation before the driver may dispatch any of the wave.
67
+ due: (nowMillis, limit, owner) =>
68
+ local(owner, store.due(nowMillis, limit, owner)).pipe(
69
+ Effect.filterOrFail(
70
+ (keys) => keys.every((key) => ownsThread(key.ownerThreadId)),
71
+ () => MessageDeliveryError.make({ reason: "validation", operation: "message owner" }),
72
+ ),
73
+ ),
74
+ nextDeadline: (owner) => local(owner, store.nextDeadline(owner)),
75
+ });
76
+ }),
77
+ );
78
+
79
+ /** Message progress shares the native alarm slot without blocking source runtime work. */
80
+ export const threadMessageDeliveryLayer = Layer.effectContext(
81
+ Effect.gen(function* () {
82
+ const driver = yield* MessageDeliveryDriver;
83
+ const store = yield* MessageDeliveryStore;
84
+
85
+ const failure = (operation: string) => () =>
86
+ DurableAlarmError.make({
87
+ operation,
88
+ message: "Durable message recovery remains pending",
89
+ });
90
+
91
+ const prepare = Effect.gen(function* () {
92
+ const deadline = yield* store.nextDeadline();
93
+
94
+ if (deadline === null || deadline > (yield* Clock.currentTimeMillis))
95
+ return { timeoutMillis: 1, run: Effect.succeed(Option.fromNullishOr(deadline)) };
96
+ // The assembled driver has four permits: a wave is one parallel attempt window.
97
+ const keys = yield* store.due(yield* Clock.currentTimeMillis, 4);
98
+ const records = yield* Effect.forEach(keys, (key) => store.get(key));
99
+
100
+ return {
101
+ timeoutMillis: Math.max(
102
+ 1,
103
+ ...records.map((record) => record?.policy.attemptTimeoutMillis ?? 1),
104
+ ),
105
+ run: Effect.forEach(keys, (key) => driver.process(key), {
106
+ concurrency: 4,
107
+ discard: true,
108
+ }).pipe(
109
+ Effect.andThen(store.nextDeadline()),
110
+ Effect.map(Option.fromNullishOr),
111
+ Effect.mapError(failure("dispatch message delivery")),
112
+ ),
113
+ };
114
+ }).pipe(Effect.mapError(failure("prepare message delivery")));
115
+
116
+ return Context.make(ThreadMessageDelivery, {
117
+ prepare,
118
+ });
119
+ }),
120
+ );
@@ -0,0 +1,116 @@
1
+ import { type DurableSubmitAgent } from "@yielded/agent/durable-agent-runtime";
2
+ import { type AgentId } from "@yielded/agent/identifiers";
3
+ import { PreparedInputAdmission } from "@yielded/agent/prepared-input-admission";
4
+ import { PersistedJson } from "@yielded/agent/records";
5
+ import {
6
+ type ScheduledEnvelope,
7
+ ScheduledInputAdmission,
8
+ ScheduledInputRetryable,
9
+ ScheduledInputRefused,
10
+ ScheduleStorageError,
11
+ } from "@yielded/agent/schedule";
12
+ import { type PreparedInput } from "@yielded/agent/subscription";
13
+ import { Effect, Layer } from "effect";
14
+
15
+ import { CloudflareThreadClient, type ThreadClientError } from "../CloudflareThreadClient.ts";
16
+
17
+ const passthroughAgent = (agentId: AgentId): DurableSubmitAgent<typeof PersistedJson> => ({
18
+ definition: { id: agentId, input: PersistedJson },
19
+ });
20
+
21
+ /** Ordinary prepared admission through one freshly addressed Thread Object call. */
22
+ export const cloudflarePreparedInputAdmissionLayer: Layer.Layer<
23
+ PreparedInputAdmission,
24
+ never,
25
+ CloudflareThreadClient
26
+ > = Layer.effect(
27
+ PreparedInputAdmission,
28
+ Effect.gen(function* () {
29
+ const client = yield* CloudflareThreadClient;
30
+
31
+ return PreparedInputAdmission.of({
32
+ submissionStatus: (receipt) =>
33
+ client
34
+ .submissionStatus(receipt)
35
+ .pipe(Effect.mapError(() => ScheduledInputRetryable.make({ reason: "storage" }))),
36
+ submit: (envelope) =>
37
+ client
38
+ .submit(passthroughAgent(envelope.agentId), envelope.input, {
39
+ threadId: envelope.threadId,
40
+ principal: envelope.deliveryPrincipal,
41
+ idempotencyKey: envelope.admissionKey,
42
+ ...(envelope.admissionGroup === undefined
43
+ ? {}
44
+ : { admissionGroup: envelope.admissionGroup }),
45
+ ...(envelope.admissionFence === undefined
46
+ ? {}
47
+ : { admissionFence: envelope.admissionFence }),
48
+ ...(envelope.workerAdmission === undefined
49
+ ? {}
50
+ : { workerAdmission: envelope.workerAdmission }),
51
+ ...(envelope.messageAdmission === undefined
52
+ ? {}
53
+ : { messageAdmission: envelope.messageAdmission }),
54
+ definitions: envelope.definitions,
55
+ })
56
+ .pipe(
57
+ Effect.catchTags({
58
+ AdmissionConflict: () =>
59
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
60
+ AdmissionLimitExceeded: () => ScheduledInputRetryable.make({ reason: "capacity" }),
61
+ ThreadClientError: (error: ThreadClientError) =>
62
+ ScheduledInputRetryable.make({
63
+ reason: error.overloaded === true ? "capacity" : "transport",
64
+ }),
65
+ HostProtocolError: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
66
+ AdmissionPolicyError: (error) =>
67
+ error.reason === "refused"
68
+ ? ScheduledInputRefused.make({ code: error.code })
69
+ : ScheduledInputRetryable.make({
70
+ reason: error.reason === "occupied" ? "capacity" : "storage",
71
+ }),
72
+ LedgerError: () => ScheduledInputRetryable.make({ reason: "storage" }),
73
+ ThreadStoreError: () => ScheduledInputRetryable.make({ reason: "storage" }),
74
+ DurableAlarmError: () => ScheduledInputRetryable.make({ reason: "storage" }),
75
+ AgentInputError: () =>
76
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
77
+ DigestError: () =>
78
+ ScheduleStorageError.make({ operation: "prepared admission", reason: "corrupt" }),
79
+ ThreadNotMaterialized: () => ScheduledInputRetryable.make({ reason: "storage" }),
80
+ AppendConflict: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
81
+ FenceRejected: () => ScheduledInputRetryable.make({ reason: "ambiguous" }),
82
+ DurableRuntimeFailpointError: () =>
83
+ ScheduledInputRetryable.make({ reason: "ambiguous" }),
84
+ }),
85
+ ),
86
+ });
87
+ }),
88
+ );
89
+
90
+ const preparedFromSchedule = (envelope: ScheduledEnvelope): PreparedInput => ({
91
+ schemaVersion: 1,
92
+ threadId: envelope.threadId,
93
+ deliveryPrincipal: envelope.deliveryPrincipal,
94
+ ...(envelope.admissionGroup === undefined ? {} : { admissionGroup: envelope.admissionGroup }),
95
+ ...(envelope.admissionFence === undefined ? {} : { admissionFence: envelope.admissionFence }),
96
+ agentId: envelope.agentId,
97
+ definitions: envelope.definitions,
98
+ input: envelope.input,
99
+ inputDigest: envelope.inputDigest,
100
+ admissionKey: envelope.admissionKey,
101
+ authorization: envelope.authorization,
102
+ });
103
+
104
+ /** Compatibility adapter retaining Scheduling's public admission port. */
105
+ export const cloudflareScheduledInputAdmissionLayer: Layer.Layer<
106
+ ScheduledInputAdmission,
107
+ never,
108
+ PreparedInputAdmission
109
+ > = Layer.effect(
110
+ ScheduledInputAdmission,
111
+ Effect.map(PreparedInputAdmission, (admission) =>
112
+ ScheduledInputAdmission.of({
113
+ submit: (envelope) => admission.submit(preparedFromSchedule(envelope)),
114
+ }),
115
+ ),
116
+ );
@@ -0,0 +1,121 @@
1
+ import { Context, Deferred, Effect, Layer, Ref, type Scope } from "effect";
2
+
3
+ /** Cancellation tombstones are bounded hints, never durable authority. */
4
+ const MAX_CANCELLATION_TOMBSTONES = 1_024;
5
+
6
+ type ActiveRegistration = ReadonlySet<Deferred.Deferred<void>>;
7
+ type Registration = ActiveRegistration | "cancelled";
8
+ type Registrations = ReadonlyMap<string, Registration>;
9
+
10
+ /**
11
+ * Per-incarnation cancellation registry for long-lived progress RPCs. The public runtime owns
12
+ * the actual wake registration; this host-only registry lets an interrupted Worker Effect ask
13
+ * the Object to interrupt its scoped wait before the Worker execution context itself ends.
14
+ */
15
+ export class ProgressWaitRegistry extends Context.Service<
16
+ ProgressWaitRegistry,
17
+ {
18
+ /** Register a Scope-owned cancellation signal, observing any early cancel tombstone. */
19
+ readonly subscribe: (
20
+ waiterId: string,
21
+ ) => Effect.Effect<Effect.Effect<void>, never, Scope.Scope>;
22
+ /** Cancel every attempt and retain a bounded tombstone for later transport attempts. */
23
+ readonly cancel: (waiterId: string) => Effect.Effect<void>;
24
+ }
25
+ >()("@effect-agent/platform-cloudflare/ProgressWaitRegistry") {
26
+ static readonly layer: Layer.Layer<ProgressWaitRegistry> = Layer.effect(
27
+ ProgressWaitRegistry,
28
+ Effect.gen(function* () {
29
+ const registrations = yield* Ref.make<Registrations>(new Map());
30
+
31
+ const remove = (waiterId: string, deferred: Deferred.Deferred<void>) =>
32
+ Ref.update(registrations, (current) => {
33
+ const existing = current.get(waiterId);
34
+
35
+ if (existing === undefined || existing === "cancelled" || !existing.has(deferred)) {
36
+ return current;
37
+ }
38
+ const next = new Map(current);
39
+ const active = new Set(existing);
40
+
41
+ active.delete(deferred);
42
+ if (active.size === 0) {
43
+ next.delete(waiterId);
44
+ } else {
45
+ next.set(waiterId, active);
46
+ }
47
+
48
+ return next;
49
+ });
50
+
51
+ const subscribe = Effect.fn("ProgressWaitRegistry.subscribe")(
52
+ (waiterId: string): Effect.Effect<Effect.Effect<void>, never, Scope.Scope> =>
53
+ Effect.gen(function* () {
54
+ const deferred = yield* Deferred.make<void>();
55
+
56
+ yield* Effect.addFinalizer(() => remove(waiterId, deferred));
57
+
58
+ const cancelled = yield* Ref.modify(registrations, (current) => {
59
+ const existing = current.get(waiterId);
60
+ const next = new Map(current);
61
+
62
+ if (existing === "cancelled") {
63
+ return [true, current] as const;
64
+ }
65
+ const active = new Set(existing ?? []);
66
+
67
+ active.add(deferred);
68
+ next.set(waiterId, active);
69
+
70
+ return [false, next] as const;
71
+ });
72
+
73
+ return { cancelled, deferred };
74
+ }).pipe(
75
+ Effect.map(({ cancelled, deferred }) =>
76
+ cancelled ? Effect.void : Deferred.await(deferred),
77
+ ),
78
+ ),
79
+ );
80
+
81
+ // Updating the registry and completing captured signals form one nonblocking operation;
82
+ // interruption between them must not strand attempts removed from the active registry.
83
+ const cancel = Effect.fn("ProgressWaitRegistry.cancel")(function* (waiterId: string) {
84
+ const waiters = yield* Ref.modify(
85
+ registrations,
86
+ (current): readonly [ReadonlyArray<Deferred.Deferred<void>>, Registrations] => {
87
+ const existing = current.get(waiterId);
88
+
89
+ if (existing === "cancelled") return [[], current] as const;
90
+ const next = new Map(current);
91
+
92
+ // A retry may arrive after an active attempt was cancelled. Retain the same
93
+ // tombstone used for early cancellation, ordered by cancellation time.
94
+ next.delete(waiterId);
95
+ next.set(waiterId, "cancelled");
96
+ let tombstones = 0;
97
+
98
+ for (const registration of next.values()) {
99
+ if (registration === "cancelled") tombstones += 1;
100
+ }
101
+ if (tombstones > MAX_CANCELLATION_TOMBSTONES) {
102
+ for (const [id, registration] of next) {
103
+ if (registration !== "cancelled") continue;
104
+ next.delete(id);
105
+ break;
106
+ }
107
+ }
108
+
109
+ return [existing === undefined ? [] : [...existing], next] as const;
110
+ },
111
+ );
112
+
113
+ yield* Effect.forEach(waiters, (waiter) => Deferred.succeed(waiter, undefined), {
114
+ discard: true,
115
+ });
116
+ }, Effect.uninterruptible);
117
+
118
+ return ProgressWaitRegistry.of({ subscribe, cancel });
119
+ }),
120
+ );
121
+ }
@@ -0,0 +1,56 @@
1
+ import {
2
+ ThreadPortTransport,
3
+ portTransportFailure,
4
+ } from "@yielded/agent-storage-cloudflare/port-routing";
5
+ import type { ThreadId } from "@yielded/agent/identifiers";
6
+ import { Effect, Layer } from "effect";
7
+ import { RpcTracing } from "effect-cf";
8
+
9
+ import { callThreadObject, ThreadObjectNamespace } from "../CloudflareBindings.ts";
10
+
11
+ /**
12
+ * `ThreadPortTransport` over native Durable Object JS RPC (decision D-P6-3): one
13
+ * `portCall(envelope)` on the stub of the Object that owns the addressed Thread
14
+ * (`namespace.idFromName(threadId)` — the identity rule, plan §1.2). The envelopes are
15
+ * already Schema-encoded JSON, so the RPC boundary carries only structured-cloneable values;
16
+ * the protocol module stays transport-agnostic and fetch-with-JSON remains the documented
17
+ * fallback carrier.
18
+ * The namespace's optional `rpcTracing` setting uses the same transient trailing context
19
+ * as host calls; it never changes the encoded port envelope.
20
+ *
21
+ * Every delivery problem — stub construction, RPC rejection, overload, deploy-in-progress —
22
+ * surfaces as `PortTransportError` (preserving the platform stub's own `retryable` signal
23
+ * when present) and NEVER as a fabricated answer: on `resolveAdmission` the routing layer
24
+ * turns exactly this error into `AdmissionIndeterminate` (SUB-031).
25
+ */
26
+ export const threadPortTransportLayer: Layer.Layer<
27
+ ThreadPortTransport,
28
+ never,
29
+ ThreadObjectNamespace
30
+ > = Layer.effect(ThreadPortTransport)(
31
+ Effect.gen(function* () {
32
+ const namespace = yield* ThreadObjectNamespace;
33
+ const { rpcTracing } = namespace;
34
+
35
+ return ThreadPortTransport.of({
36
+ call: Effect.fn(
37
+ function* (threadId: ThreadId, request: unknown) {
38
+ const traceArgs =
39
+ rpcTracing === undefined ? [] : yield* RpcTracing.withRpcTraceContext([]);
40
+
41
+ return yield* callThreadObject(
42
+ threadId,
43
+ (target) => target.portCall(request, ...traceArgs),
44
+ (cause) => portTransportFailure(threadId, cause),
45
+ ).pipe(Effect.provideService(ThreadObjectNamespace, namespace));
46
+ },
47
+ (effect, threadId) =>
48
+ rpcTracing === undefined
49
+ ? Effect.withSpan(effect, "CloudflarePortTransport.call", {
50
+ attributes: { threadId },
51
+ })
52
+ : RpcTracing.withRpcClientSpan(effect, rpcTracing, "portCall"),
53
+ ),
54
+ });
55
+ }),
56
+ );
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.