effect-cf 0.33.0 → 0.35.0

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 (74) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +31 -1079
  3. package/dist/{Artifacts-DnHQA-Ax.d.mts → Artifacts-B3r3RuTB.d.mts} +1 -48
  4. package/dist/{Artifacts-CSIk1Oml.mjs → Artifacts-CBxWGeZB.mjs} +2 -7
  5. package/dist/{Binding-pfilNJmP.mjs → Binding-C82jRhdr.mjs} +1 -2
  6. package/dist/{Binding-xJJJPmiD.d.mts → Binding-DKcLrQCM.d.mts} +0 -45
  7. package/dist/ComputerArtifacts.d.mts +1 -3
  8. package/dist/ComputerArtifacts.mjs +1 -2
  9. package/dist/ComputerWorkspace.d.mts +11 -12
  10. package/dist/ComputerWorkspace.mjs +31 -10
  11. package/dist/ComputerWorkspaceHost.d.mts +1 -9
  12. package/dist/{ContainerNamespace-CFjiLw8b.d.mts → ContainerNamespace-DbLaeFhN.d.mts} +1 -14
  13. package/dist/{DurableObjectState-CVLLse69.mjs → DurableObjectState-DcqElJ4e.mjs} +82 -89
  14. package/dist/{DurableObjectState-BpRjz6-q.d.mts → DurableObjectState-DpYdNZgT.d.mts} +102 -266
  15. package/dist/{ErrorMessage-BM0K-Nik.mjs → ErrorMessage-Byx2OgNd.mjs} +0 -1
  16. package/dist/{Hyperdrive-z-9fFz15.d.mts → Hyperdrive-HrwFlZ6x.d.mts} +1 -4
  17. package/dist/HyperdrivePg.d.mts +2 -11
  18. package/dist/HyperdrivePg.mjs +0 -8
  19. package/dist/Sandbox.d.mts +2 -32
  20. package/dist/Sandbox.mjs +2 -11
  21. package/dist/Vitest.d.mts +3 -31
  22. package/dist/Vitest.mjs +8 -26
  23. package/dist/{WorkflowBinding-lBR4_-op.d.mts → WorkflowBinding-Cn3AuUyP.d.mts} +2 -5
  24. package/dist/index.d.mts +42 -480
  25. package/dist/index.mjs +267 -380
  26. package/package.json +1 -1
  27. package/src/AiGateway.ts +0 -6
  28. package/src/AnalyticsEngine.ts +8 -10
  29. package/src/Artifacts.ts +0 -47
  30. package/src/Binding.ts +0 -8
  31. package/src/BrowserRendering.ts +0 -4
  32. package/src/Cache.ts +0 -19
  33. package/src/CloudflareOtlp.ts +6 -39
  34. package/src/ComputerArtifacts.ts +0 -2
  35. package/src/ComputerWorkspace.ts +53 -35
  36. package/src/ComputerWorkspaceHost.ts +0 -8
  37. package/src/ContainerNamespace.ts +0 -13
  38. package/src/D1.ts +0 -22
  39. package/src/DurableObject.ts +51 -32
  40. package/src/DurableObjectAlarm.ts +6 -210
  41. package/src/DurableObjectDefinition.ts +8 -20
  42. package/src/DurableObjectNamespace.ts +88 -115
  43. package/src/DurableObjectRpcWebSocket.ts +5 -46
  44. package/src/DurableObjectSqlite.ts +0 -12
  45. package/src/DurableObjectState.ts +18 -38
  46. package/src/DurableObjectStorage.ts +55 -70
  47. package/src/DurableObjectWebSocket.ts +23 -72
  48. package/src/Email.ts +0 -12
  49. package/src/Environment.ts +0 -37
  50. package/src/Hyperdrive.ts +0 -3
  51. package/src/HyperdrivePg.ts +0 -9
  52. package/src/Images.ts +0 -5
  53. package/src/Kv.ts +0 -15
  54. package/src/QueueBinding.ts +0 -2
  55. package/src/R2.ts +0 -5
  56. package/src/RpcDefinition.ts +5 -17
  57. package/src/RpcTracing.ts +133 -0
  58. package/src/Sandbox.ts +0 -30
  59. package/src/ServiceBinding.ts +83 -128
  60. package/src/Vectorize.ts +0 -5
  61. package/src/Vitest.ts +18 -43
  62. package/src/WebTransport.ts +0 -15
  63. package/src/Worker.ts +140 -108
  64. package/src/WorkerDefinition.ts +5 -14
  65. package/src/WorkersAi.ts +21 -18
  66. package/src/Workflow.ts +45 -54
  67. package/src/WorkflowBinding.ts +0 -3
  68. package/src/index.ts +1 -0
  69. package/src/internal/Entrypoint.ts +23 -4
  70. package/src/internal/ErrorMessage.ts +0 -1
  71. package/src/internal/NativeCallback.ts +55 -0
  72. package/src/internal/RpcInvocation.ts +18 -1
  73. package/src/internal/Runtime.ts +12 -7
  74. package/src/internal/WorkerContext.ts +5 -14
package/src/Kv.ts CHANGED
@@ -11,10 +11,8 @@ import * as ErrorMessage from "./internal/ErrorMessage";
11
11
  const expectedKvNamespace =
12
12
  "KV namespace binding with get(), put(), delete(), getWithMetadata(), and list()";
13
13
 
14
- /** KV operation represented by {@link KvOperationError}. */
15
14
  export type KvOperation = "put" | "get" | "getWithMetadata" | "list" | "delete";
16
15
 
17
- /** Error raised when a KV operation fails. */
18
16
  export class KvOperationError extends Data.TaggedError("KvOperationError")<{
19
17
  readonly binding: string;
20
18
  readonly operation: KvOperation;
@@ -25,28 +23,23 @@ export class KvOperationError extends Data.TaggedError("KvOperationError")<{
25
23
  }
26
24
  }
27
25
 
28
- /** `KVNamespace.put` options. */
29
26
  export type KvPutOptions = CloudflareKVNamespacePutOptions;
30
- /** `KVNamespace.list` options with optional metadata decoding schema. */
31
27
  export type KvListOptions<Metadata = unknown> = CloudflareKVNamespaceListOptions & {
32
28
  readonly metadataSchema?: S.Codec<Metadata, unknown>;
33
29
  };
34
30
 
35
- /** Successful value returned by `getWithMetadata`. */
36
31
  export interface KvWithMetadata<Value, Metadata> {
37
32
  readonly value: Value;
38
33
  readonly metadata: Option.Option<Metadata>;
39
34
  readonly cacheStatus: Option.Option<string>;
40
35
  }
41
36
 
42
- /** Decoded key entry returned by `list`. */
43
37
  export interface KvListKey<Key, Metadata = unknown> {
44
38
  readonly name: Key;
45
39
  readonly expiration: Option.Option<number>;
46
40
  readonly metadata: Option.Option<Metadata>;
47
41
  }
48
42
 
49
- /** Decoded result returned by `list`. */
50
43
  export interface KvListResult<Key, Metadata = unknown> {
51
44
  readonly keys: ReadonlyArray<KvListKey<Key, Metadata>>;
52
45
  readonly listComplete: boolean;
@@ -54,15 +47,9 @@ export interface KvListResult<Key, Metadata = unknown> {
54
47
  readonly cacheStatus: Option.Option<string>;
55
48
  }
56
49
 
57
- /**
58
- * Typed KV binding definition.
59
- */
60
50
  export interface KvDefinition<Key, Value, EncodedValue> {
61
- /** Binding name as configured in `wrangler.jsonc`. */
62
51
  readonly binding: string;
63
- /** Codec used to encode/decode keys. */
64
52
  readonly key: S.Codec<Key, string>;
65
- /** Codec used to encode/decode values. */
66
53
  readonly value: S.Codec<Value, EncodedValue>;
67
54
  }
68
55
 
@@ -76,9 +63,7 @@ export interface Definition<
76
63
  EncodedValue = unknown,
77
64
  > {
78
65
  readonly id: Id;
79
- /** Codec used to encode/decode keys. */
80
66
  readonly key: S.Codec<Key, string>;
81
- /** Codec used to encode/decode values. */
82
67
  readonly value: S.Codec<Value, EncodedValue>;
83
68
  }
84
69
 
@@ -27,9 +27,7 @@ const expectedQueueProducer = "Queue producer binding with send(); optional send
27
27
  type QueueCandidate = Parameters<typeof Predicate.isUnknown>[0];
28
28
 
29
29
  export interface QueueBindingDefinition<Message extends RpcDefinition.ServiceFreeSchema> {
30
- /** Binding name as configured in `wrangler.jsonc`. */
31
30
  readonly binding: string;
32
- /** Codec used to encode messages before sending them to Cloudflare Queues. */
33
31
  readonly message: Message;
34
32
  }
35
33
 
package/src/R2.ts CHANGED
@@ -21,7 +21,6 @@ import * as ErrorMessage from "./internal/ErrorMessage";
21
21
  const expectedR2Bucket =
22
22
  "R2 bucket binding with head(), get(), put(), createMultipartUpload(), resumeMultipartUpload(), delete(), and list()";
23
23
 
24
- /** R2 operation represented by {@link R2OperationError}. */
25
24
  export type R2Operation =
26
25
  | "head"
27
26
  | "get"
@@ -39,7 +38,6 @@ export type R2Operation =
39
38
  | "json"
40
39
  | "blob";
41
40
 
42
- /** Error raised when an R2 operation fails. */
43
41
  export class R2OperationError extends Data.TaggedError("R2OperationError")<{
44
42
  readonly binding: string;
45
43
  readonly operation: R2Operation;
@@ -50,9 +48,7 @@ export class R2OperationError extends Data.TaggedError("R2OperationError")<{
50
48
  }
51
49
  }
52
50
 
53
- /** Typed R2 bucket binding definition. */
54
51
  export interface R2Definition {
55
- /** Binding name as configured in `wrangler.jsonc`. */
56
52
  readonly binding: string;
57
53
  }
58
54
 
@@ -133,7 +129,6 @@ export interface R2Client {
133
129
 
134
130
  declare const R2ServiceTypeId: unique symbol;
135
131
 
136
- /** Nominal service marker for R2 services created with {@link make}. */
137
132
  export interface R2Service<Id extends string> {
138
133
  readonly [R2ServiceTypeId]: {
139
134
  readonly id: Id;
@@ -106,7 +106,6 @@ export const encodeWireError = (error: WireValue): WireValue => {
106
106
  }
107
107
  };
108
108
 
109
- /** Restores package RPC errors from the {@link encodeWireError} envelope. */
110
109
  export const decodeWireError = (cause: WireValue): WireValue => {
111
110
  if (!(cause instanceof Error)) {
112
111
  return cause;
@@ -125,7 +124,7 @@ export const decodeWireError = (cause: WireValue): WireValue => {
125
124
  }
126
125
  };
127
126
 
128
- export const reservedMethodNames = new Set([
127
+ const reservedMethodNameValues = [
129
128
  "constructor",
130
129
  "fetch",
131
130
  "connect",
@@ -138,21 +137,11 @@ export const reservedMethodNames = new Set([
138
137
  "dispose",
139
138
  "serialize",
140
139
  "deserialize",
141
- ]);
140
+ ] as const;
141
+
142
+ export const reservedMethodNames = new Set<string>(reservedMethodNameValues);
142
143
 
143
- export type ReservedMethodName =
144
- | "constructor"
145
- | "fetch"
146
- | "connect"
147
- | "alarm"
148
- | "webSocketMessage"
149
- | "webSocketClose"
150
- | "webSocketError"
151
- | "then"
152
- | "dup"
153
- | "dispose"
154
- | "serialize"
155
- | "deserialize";
144
+ export type ReservedMethodName = (typeof reservedMethodNameValues)[number];
156
145
 
157
146
  export type ServiceFreeSchema = S.Codec<any, any, never, never>;
158
147
 
@@ -184,7 +173,6 @@ export namespace Method {
184
173
  ? [S.Schema.Type<Head>, ...ArgsFromSchemas<Tail>]
185
174
  : Array<S.Schema.Type<Args[number]>>;
186
175
 
187
- /** Method schemas cross the wire through their canonical JSON codec. */
188
176
  type EncodedArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = {
189
177
  [Index in keyof Args]: S.Json;
190
178
  };
@@ -0,0 +1,133 @@
1
+ import { Cause, Clock, Context, Effect, Exit, Option, References, Schema, Tracer } from "effect";
2
+
3
+ /**
4
+ * Live native RPC metadata. Opted-in receivers reserve a valid trailing value
5
+ * with this tag for transport context; do not use it as a final domain argument.
6
+ * Never store this in durable messages or envelopes.
7
+ */
8
+ export const RpcTraceContext = Schema.Struct({
9
+ _tag: Schema.Literal("effect-cf/RpcTraceContext/v1"),
10
+ traceId: Schema.String.check(Schema.isPattern(/^(?!0{32}$)[0-9a-f]{32}$/)),
11
+ spanId: Schema.String.check(Schema.isPattern(/^(?!0{16}$)[0-9a-f]{16}$/)),
12
+ sampled: Schema.Boolean,
13
+ });
14
+
15
+ export type RpcTraceContext = typeof RpcTraceContext.Type;
16
+
17
+ export interface ReceiverOptions {
18
+ /** Stable service name, never an instance id or capability URL. */
19
+ readonly service: string;
20
+ }
21
+
22
+ /** Per-invocation metadata passed to Worker and DurableObject RunSymbol overrides. */
23
+ export interface RpcInvocationInfo {
24
+ readonly service: string;
25
+ readonly method: string;
26
+ /** Native arguments with valid, opted-in trace metadata removed. Do not log them. */
27
+ readonly args: ReadonlyArray<unknown>;
28
+ /**
29
+ * Set after a definition-backed receiver decodes its arguments, before its
30
+ * handler runs. Absent before decoding and when decoding fails. Do not log it.
31
+ */
32
+ readonly decodedArgs?: ReadonlyArray<unknown>;
33
+ readonly parent?: RpcTraceContext;
34
+ }
35
+
36
+ const isRpcTraceContext = Schema.is(RpcTraceContext);
37
+
38
+ /**
39
+ * Appends the current live parent only for a receiver that has opted in.
40
+ * Call this inside the CLIENT span, immediately before the native invocation.
41
+ * With no valid propagating parent, the original argument array is returned.
42
+ */
43
+ export const withRpcTraceContext = Effect.fnUntraced(function* (
44
+ args: ReadonlyArray<unknown>,
45
+ ): Effect.fn.Return<ReadonlyArray<unknown>> {
46
+ if (yield* Tracer.DisablePropagation) {
47
+ return args;
48
+ }
49
+
50
+ const parent = yield* Effect.serviceOption(Tracer.ParentSpan);
51
+
52
+ if (Option.isNone(parent) || Context.get(parent.value.annotations, Tracer.DisablePropagation)) {
53
+ return args;
54
+ }
55
+
56
+ const context = {
57
+ _tag: "effect-cf/RpcTraceContext/v1",
58
+ traceId: parent.value.traceId,
59
+ spanId: parent.value.spanId,
60
+ sampled: parent.value.sampled,
61
+ };
62
+
63
+ return isRpcTraceContext(context) ? [...args, context] : args;
64
+ });
65
+
66
+ const attributes = (service: string, method: string) => ({
67
+ "sentry.op": "rpc",
68
+ "rpc.system.name": "cloudflare",
69
+ "rpc.method": `${service}/${method}`,
70
+ "server.address": service,
71
+ });
72
+
73
+ const withRpcSpan = <A, E, R>(
74
+ effect: Effect.Effect<A, E, R>,
75
+ service: string,
76
+ method: string,
77
+ options: Tracer.SpanOptionsNoTrace,
78
+ ): Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>> =>
79
+ Effect.useSpan(
80
+ `${service}/${method}`,
81
+ {
82
+ ...options,
83
+ attributes: attributes(service, method),
84
+ },
85
+ (span) =>
86
+ effect.pipe(
87
+ Effect.withParentSpan(span),
88
+ Effect.onExit((exit) => {
89
+ if (
90
+ Exit.isSuccess(exit) ||
91
+ Cause.hasInterruptsOnly(exit.cause) ||
92
+ span.status._tag === "Ended"
93
+ ) {
94
+ return Effect.void;
95
+ }
96
+
97
+ // OTLP's default cause formatter includes schema inputs and native error
98
+ // messages. End with a safe failure, while returning the original exit.
99
+ return Effect.gen(function* () {
100
+ const timing = yield* References.TracerTimingEnabled;
101
+ const endTime = timing ? yield* Clock.currentTimeNanos : 0n;
102
+
103
+ span.attribute("error.type", "_OTHER");
104
+ span.end(endTime, Exit.fail("RPC failed"));
105
+ });
106
+ }),
107
+ ),
108
+ );
109
+
110
+ /** Wrap the whole call, including native result resolution and success decoding. */
111
+ export const withRpcClientSpan = <A, E, R>(
112
+ effect: Effect.Effect<A, E, R>,
113
+ binding: string,
114
+ method: string,
115
+ ): Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>> =>
116
+ withRpcSpan(effect, binding, method, {
117
+ kind: "client",
118
+ });
119
+
120
+ /**
121
+ * Optional application instrumentation for the entire receiver effect.
122
+ * Use in a RunSymbol override to include argument decode, handler and encode.
123
+ * Records stable service/method attributes and failure status, not argument or
124
+ * error payloads. The original typed failure still propagates to the caller.
125
+ */
126
+ export const withRpcServerSpan = <A, E, R>(
127
+ effect: Effect.Effect<A, E, R>,
128
+ invocation: RpcInvocationInfo,
129
+ ): Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>> =>
130
+ withRpcSpan(effect, invocation.service, invocation.method, {
131
+ kind: "server",
132
+ parent: invocation.parent === undefined ? undefined : Tracer.externalSpan(invocation.parent),
133
+ });
package/src/Sandbox.ts CHANGED
@@ -77,13 +77,10 @@ export type {
77
77
  const expectedSandboxNamespace =
78
78
  "Sandbox Durable Object namespace binding with idFromName() and get()";
79
79
 
80
- /** Sandbox namespace binding metadata. */
81
80
  export interface SandboxDefinition {
82
- /** Binding name as configured in `wrangler.jsonc`. */
83
81
  readonly binding: string;
84
82
  }
85
83
 
86
- /** Failure raised when invoking a sandbox operation. */
87
84
  export class SandboxOperationError extends Data.TaggedError("SandboxOperationError")<{
88
85
  readonly binding: string;
89
86
  readonly instance: string;
@@ -110,55 +107,42 @@ export interface SandboxNamespaceResource {
110
107
  ): globalThis.DurableObjectStub;
111
108
  }
112
109
 
113
- /** Result of `writeFile` as reported by the sandbox client. */
114
110
  export type WriteFileResult = Awaited<ReturnType<ISandbox["writeFile"]>>;
115
111
 
116
- /** Result of `readFile` as reported by the sandbox client. */
117
112
  export type ReadFileResult = Awaited<ReturnType<ISandbox["readFile"]>>;
118
113
 
119
- /** Result of `mkdir` as reported by the sandbox client. */
120
114
  export type MkdirResult = Awaited<ReturnType<ISandbox["mkdir"]>>;
121
115
 
122
- /** Result of `deleteFile` as reported by the sandbox client. */
123
116
  export type DeleteFileResult = Awaited<ReturnType<ISandbox["deleteFile"]>>;
124
117
 
125
- /** Result of `renameFile` as reported by the sandbox client. */
126
118
  export type RenameFileResult = Awaited<ReturnType<ISandbox["renameFile"]>>;
127
119
 
128
- /** Result of `moveFile` as reported by the sandbox client. */
129
120
  export type MoveFileResult = Awaited<ReturnType<ISandbox["moveFile"]>>;
130
121
 
131
- /** Result of `listFiles` as reported by the sandbox client. */
132
122
  export type ListFilesResult = Awaited<ReturnType<ISandbox["listFiles"]>>;
133
123
 
134
- /** Result of `exists` as reported by the sandbox client. */
135
124
  export type FileExistsResult = Awaited<ReturnType<ISandbox["exists"]>>;
136
125
 
137
- /** Text encodings accepted by `readFile`. */
138
126
  export type ReadFileEncoding = "utf-8" | "utf8" | "base64";
139
127
 
140
- /** Options accepted by `exposePort`. */
141
128
  export interface ExposePortOptions {
142
129
  readonly name?: string;
143
130
  readonly hostname: string;
144
131
  readonly token?: string;
145
132
  }
146
133
 
147
- /** Preview URL information returned by `exposePort`. */
148
134
  export interface ExposedPort {
149
135
  readonly url: string;
150
136
  readonly port: number;
151
137
  readonly name?: string;
152
138
  }
153
139
 
154
- /** Currently forwardable preview URL returned by `getExposedPorts`. */
155
140
  export interface ExposedPortStatus {
156
141
  readonly url: string;
157
142
  readonly port: number;
158
143
  readonly status: "active";
159
144
  }
160
145
 
161
- /** Structural tunnel API surface exposed by a sandbox client. */
162
146
  export interface SandboxTunnelsResource {
163
147
  get(port: number, options?: TunnelOptions): Promise<TunnelInfo>;
164
148
  list(): Promise<Array<TunnelInfo>>;
@@ -183,7 +167,6 @@ export interface SandboxClientResource extends ISandbox {
183
167
  readonly tunnels: SandboxTunnelsResource;
184
168
  }
185
169
 
186
- /** Effect-wrapped handle for one process started inside a sandbox. */
187
170
  export interface SandboxProcessHandle {
188
171
  readonly id: string;
189
172
  readonly pid: number;
@@ -213,7 +196,6 @@ export interface SandboxProcessHandle {
213
196
  readonly kill: (signal?: number) => Effect.Effect<void, SandboxOperationError>;
214
197
  }
215
198
 
216
- /** Effect-wrapped handle for one interactive terminal inside a sandbox. */
217
199
  export interface SandboxTerminalHandle {
218
200
  readonly id: string;
219
201
  readonly rawUnsafe: Effect.Effect<Terminal>;
@@ -238,7 +220,6 @@ export interface SandboxTerminalHandle {
238
220
  ) => Effect.Effect<Response, SandboxOperationError>;
239
221
  }
240
222
 
241
- /** Effect-wrapped tunnel operations for one sandbox instance. */
242
223
  export interface SandboxTunnelsClient {
243
224
  readonly get: (
244
225
  port: number,
@@ -248,7 +229,6 @@ export interface SandboxTunnelsClient {
248
229
  readonly destroy: (portOrInfo: number | TunnelInfo) => Effect.Effect<void, SandboxOperationError>;
249
230
  }
250
231
 
251
- /** Effect-wrapped client for one named sandbox instance. */
252
232
  export interface SandboxInstanceClient {
253
233
  readonly rawUnsafe: Effect.Effect<SandboxClientResource>;
254
234
  readonly exec: (
@@ -344,7 +324,6 @@ export interface SandboxInstanceClient {
344
324
  readonly destroy: Effect.Effect<void, SandboxOperationError>;
345
325
  }
346
326
 
347
- /** Effect client for a Sandbox Durable Object namespace binding. */
348
327
  export interface SandboxNamespaceClient<
349
328
  Namespace extends SandboxNamespaceResource = SandboxNamespaceResource,
350
329
  > {
@@ -616,13 +595,6 @@ const makeTerminalHandle = (
616
595
  };
617
596
  };
618
597
 
619
- /**
620
- * Wraps an already-created sandbox client (the value returned by
621
- * `getSandbox()` from `@cloudflare/sandbox`) into an Effect client.
622
- *
623
- * Prefer {@link Tag}/{@link make} with a layer for application code; this
624
- * entry point exists for advanced composition and testing.
625
- */
626
598
  export const fromSandboxClient = (
627
599
  client: SandboxClientResource,
628
600
  definition: SandboxDefinition,
@@ -1029,14 +1001,12 @@ export const make = <Id extends string>(id: Id) => Tag<SandboxNamespaceService<I
1029
1001
 
1030
1002
  declare const SandboxNamespaceServiceTypeId: unique symbol;
1031
1003
 
1032
- /** Nominal service marker for Sandbox namespaces created with {@link make}. */
1033
1004
  export interface SandboxNamespaceService<Id extends string> {
1034
1005
  readonly [SandboxNamespaceServiceTypeId]: {
1035
1006
  readonly id: Id;
1036
1007
  };
1037
1008
  }
1038
1009
 
1039
- /** Creates a typed Effect service for a Cloudflare Sandbox namespace. */
1040
1010
  export const Tag =
1041
1011
  <Self, Namespace extends SandboxNamespaceResource = SandboxNamespaceResource>() =>
1042
1012
  <Id extends string>(id: Id) => {