effect-cf 0.41.0 → 0.42.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 (67) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +28 -0
  3. package/dist/AiGateway.d.mts +2 -2
  4. package/dist/AnalyticsEngine.d.mts +2 -2
  5. package/dist/Artifacts.d.mts +2 -2
  6. package/dist/BrowserRendering.d.mts +2 -2
  7. package/dist/ContainerNamespace.d.mts +2 -2
  8. package/dist/ContainerNamespace.mjs +23 -20
  9. package/dist/D1.d.mts +9 -12
  10. package/dist/DurableObject.d.mts +5 -3
  11. package/dist/DurableObject.mjs +4 -3
  12. package/dist/DurableObjectDefinition.d.mts +15 -12
  13. package/dist/DurableObjectDefinition.mjs +5 -3
  14. package/dist/DurableObjectNamespace.d.mts +10 -8
  15. package/dist/DurableObjectNamespace.mjs +1 -1
  16. package/dist/Email.d.mts +2 -2
  17. package/dist/Hyperdrive.d.mts +2 -2
  18. package/dist/Images.d.mts +2 -2
  19. package/dist/Kv.d.mts +2 -2
  20. package/dist/Queue.d.mts +5 -4
  21. package/dist/QueueDefinition.d.mts +4 -4
  22. package/dist/R2.d.mts +2 -2
  23. package/dist/RpcDefinition.d.mts +26 -12
  24. package/dist/RpcDefinition.mjs +22 -5
  25. package/dist/RpcTargets.mjs +1 -2
  26. package/dist/Sandbox.d.mts +1 -1
  27. package/dist/Sandbox.mjs +87 -65
  28. package/dist/ServiceBinding.d.mts +17 -18
  29. package/dist/Vectorize.d.mts +2 -2
  30. package/dist/Worker.d.mts +5 -3
  31. package/dist/Worker.mjs +5 -4
  32. package/dist/WorkerDefinition.d.mts +15 -11
  33. package/dist/WorkerDefinition.mjs +5 -3
  34. package/dist/WorkersAi.d.mts +2 -2
  35. package/dist/Workflow.d.mts +5 -4
  36. package/dist/WorkflowDefinition.d.mts +4 -4
  37. package/dist/index.d.mts +2 -2
  38. package/dist/index.mjs +1 -1
  39. package/dist/internal/RpcTargets.mjs +5 -0
  40. package/package.json +1 -1
  41. package/src/AiGateway.ts +2 -0
  42. package/src/AnalyticsEngine.ts +2 -0
  43. package/src/Artifacts.ts +2 -0
  44. package/src/BrowserRendering.ts +2 -0
  45. package/src/ContainerNamespace.ts +34 -39
  46. package/src/D1.ts +16 -8
  47. package/src/DurableObject.ts +14 -1
  48. package/src/DurableObjectDefinition.ts +33 -17
  49. package/src/DurableObjectNamespace.ts +19 -35
  50. package/src/Email.ts +2 -0
  51. package/src/Hyperdrive.ts +2 -0
  52. package/src/Images.ts +2 -0
  53. package/src/Kv.ts +2 -0
  54. package/src/Queue.ts +4 -7
  55. package/src/QueueDefinition.ts +7 -4
  56. package/src/R2.ts +2 -0
  57. package/src/RpcDefinition.ts +64 -25
  58. package/src/RpcTargets.ts +2 -8
  59. package/src/Sandbox.ts +133 -146
  60. package/src/ServiceBinding.ts +39 -34
  61. package/src/Vectorize.ts +2 -0
  62. package/src/Worker.ts +12 -1
  63. package/src/WorkerDefinition.ts +28 -17
  64. package/src/WorkersAi.ts +2 -0
  65. package/src/Workflow.ts +9 -8
  66. package/src/WorkflowDefinition.ts +12 -4
  67. package/src/internal/RpcTargets.ts +10 -0
package/src/Hyperdrive.ts CHANGED
@@ -6,6 +6,8 @@ import type { Layer } from "effect";
6
6
  import * as Binding from "./Binding";
7
7
  import type { WorkerEnvironment } from "./Environment";
8
8
 
9
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
10
+
9
11
  const expectedHyperdrive = "Hyperdrive binding with connectionString";
10
12
 
11
13
  export interface HyperdriveDefinition {
package/src/Images.ts CHANGED
@@ -33,6 +33,8 @@ import * as Binding from "./Binding";
33
33
  import type { WorkerEnvironment } from "./Environment";
34
34
  import * as ErrorMessage from "./internal/ErrorMessage";
35
35
 
36
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
37
+
36
38
  const TypeId = "~effect-cf/Images/Steps" as const;
37
39
 
38
40
  export type TypeId = typeof TypeId;
package/src/Kv.ts CHANGED
@@ -14,6 +14,8 @@ import * as Binding from "./Binding";
14
14
  import type { WorkerEnvironment } from "./Environment";
15
15
  import * as ErrorMessage from "./internal/ErrorMessage";
16
16
 
17
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
18
+
17
19
  const expectedKvNamespace =
18
20
  "KV namespace binding with get(), put(), delete(), getWithMetadata(), and list()";
19
21
 
package/src/Queue.ts CHANGED
@@ -7,6 +7,9 @@ import type { WorkerEnvironment } from "./Environment";
7
7
  import type * as QueueDefinition from "./QueueDefinition";
8
8
  import * as ErrorMessage from "./internal/ErrorMessage";
9
9
 
10
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
11
+ export type { QueueOperationError, QueueProducer } from "./QueueBinding";
12
+
10
13
  export interface QueueMessage<Body> {
11
14
  readonly raw: globalThis.Message<unknown>;
12
15
  readonly id: string;
@@ -111,13 +114,7 @@ export namespace Definition {
111
114
 
112
115
  export type LayerOptions = QueueDefinition.LayerOptions;
113
116
 
114
- export type TagClass<
115
- Self,
116
- Id extends string,
117
- Message extends QueueDefinition.Definition.Any["message"],
118
- > = QueueDefinition.TagClass<Self, Id, Message>;
119
-
120
- export { implement, Tag } from "./QueueDefinition";
117
+ export { implement, Tag, type TagClass } from "./QueueDefinition";
121
118
 
122
119
  export type Handler<ROut, Self extends QueueDefinition.Definition.Any> = QueueDefinition.Handler<
123
120
  ROut,
@@ -11,6 +11,9 @@ import type { ExecutionContext, WorkerContext } from "./Worker";
11
11
  import * as WorkerEntrypoint from "./Worker";
12
12
  import type * as RpcDefinition from "./RpcDefinition";
13
13
 
14
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
15
+ export type { QueueOperationError, QueueProducer } from "./QueueBinding";
16
+
14
17
  export interface Definition<
15
18
  Id extends string = string,
16
19
  Message extends RpcDefinition.ServiceFreeSchema = RpcDefinition.ServiceFreeSchema,
@@ -43,15 +46,15 @@ export type LayerOptions = {
43
46
  readonly binding: string;
44
47
  };
45
48
 
46
- export interface TagClass<
49
+ export type TagClass<
47
50
  Self,
48
51
  Id extends string,
49
52
  Message extends RpcDefinition.ServiceFreeSchema,
50
- > extends Context.ServiceClass<
53
+ > = Context.ServiceClass<
51
54
  Self,
52
55
  `effect-cf/Queue/${Id}`,
53
56
  QueueBinding.QueueBindingClient<Message>
54
- > {
57
+ > & {
55
58
  readonly id: Id;
56
59
  readonly message: Message;
57
60
  readonly make: <ROut, LayerError>(
@@ -83,7 +86,7 @@ export interface TagClass<
83
86
  never,
84
87
  Self
85
88
  >;
86
- }
89
+ };
87
90
 
88
91
  const makeDefinition = <Id extends string, Message extends RpcDefinition.ServiceFreeSchema>(
89
92
  id: Id,
package/src/R2.ts CHANGED
@@ -24,6 +24,8 @@ import * as Binding from "./Binding";
24
24
  import type { WorkerEnvironment } from "./Environment";
25
25
  import * as ErrorMessage from "./internal/ErrorMessage";
26
26
 
27
+ export type { BindingNotFoundError, BindingValidationError } from "./Binding";
28
+
27
29
  const expectedR2Bucket =
28
30
  "R2 bucket binding with head(), get(), put(), createMultipartUpload(), resumeMultipartUpload(), delete(), and list()";
29
31
 
@@ -148,45 +148,86 @@ export type ReservedMethodName = (typeof reservedMethodNameValues)[number];
148
148
 
149
149
  export type ServiceFreeSchema = S.Codec<any, any, never, never>;
150
150
 
151
+ export const NativeSchemaTypeId: unique symbol = Symbol.for("effect-cf/RpcDefinition/NativeSchema");
152
+
153
+ /** A schema whose encoded value is passed directly to Workers RPC. */
154
+ export interface NativeSchema<Schema extends ServiceFreeSchema = ServiceFreeSchema> {
155
+ readonly [NativeSchemaTypeId]: typeof NativeSchemaTypeId;
156
+ readonly schema: Schema;
157
+ }
158
+
159
+ export type RpcSchema = ServiceFreeSchema | NativeSchema;
160
+
161
+ export type SchemaType<Schema extends RpcSchema> =
162
+ Schema extends NativeSchema<infer Native extends ServiceFreeSchema>
163
+ ? S.Schema.Type<Native>
164
+ : Schema extends ServiceFreeSchema
165
+ ? S.Schema.Type<Schema>
166
+ : never;
167
+
168
+ export type WireEncoded<Schema extends RpcSchema> =
169
+ Schema extends NativeSchema<infer Native extends ServiceFreeSchema>
170
+ ? S.Codec.Encoded<Native>
171
+ : S.Json;
172
+
173
+ /**
174
+ * Marks a schema to use its declared encoded form directly at the Workers RPC
175
+ * boundary instead of lowering it to canonical JSON.
176
+ */
177
+ export const native = <Schema extends ServiceFreeSchema>(schema: Schema): NativeSchema<Schema> => {
178
+ const nativeSchema: NativeSchema<Schema> = {
179
+ [NativeSchemaTypeId]: NativeSchemaTypeId,
180
+ schema,
181
+ };
182
+
183
+ return Object.freeze(nativeSchema);
184
+ };
185
+
186
+ const isNativeSchema = (schema: RpcSchema): schema is NativeSchema =>
187
+ Predicate.hasProperty(schema, NativeSchemaTypeId) &&
188
+ schema[NativeSchemaTypeId] === NativeSchemaTypeId;
189
+
151
190
  /**
152
191
  * Workers RPC structured-clones every value that crosses an isolate boundary
153
192
  * and rejects class instances. Declaration schemas such as `Schema.Result`
154
193
  * keep their container instance in their `Encoded` form, so the declared
155
- * schemas are lowered to their canonical JSON codec before touching the wire.
194
+ * schemas are lowered to their canonical JSON codec before touching the wire,
195
+ * unless explicitly wrapped with `native`.
156
196
  */
157
- const wireCodec = <Schema extends S.Constraint>(schema: Schema) => S.toCodecJson(schema);
197
+ const wireCodec = (schema: RpcSchema): ServiceFreeSchema =>
198
+ isNativeSchema(schema) ? schema.schema : S.toCodecJson(schema);
158
199
 
159
200
  export interface Method<
160
- Args extends ReadonlyArray<ServiceFreeSchema> = ReadonlyArray<ServiceFreeSchema>,
161
- Success extends ServiceFreeSchema = ServiceFreeSchema,
201
+ Args extends ReadonlyArray<RpcSchema> = ReadonlyArray<RpcSchema>,
202
+ Success extends RpcSchema = RpcSchema,
162
203
  > {
163
204
  readonly args: Args;
164
205
  readonly success: Success;
165
206
  }
166
207
 
167
208
  export namespace Method {
168
- export type Any = Method<ReadonlyArray<ServiceFreeSchema>, ServiceFreeSchema>;
209
+ export type Any = Method<ReadonlyArray<RpcSchema>, RpcSchema>;
169
210
 
170
- type ArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = Args extends readonly []
211
+ type ArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = Args extends readonly []
171
212
  ? []
172
213
  : Args extends readonly [
173
- infer Head extends ServiceFreeSchema,
174
- ...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
214
+ infer Head extends RpcSchema,
215
+ ...infer Tail extends ReadonlyArray<RpcSchema>,
175
216
  ]
176
- ? [S.Schema.Type<Head>, ...ArgsFromSchemas<Tail>]
177
- : Array<S.Schema.Type<Args[number]>>;
217
+ ? [SchemaType<Head>, ...ArgsFromSchemas<Tail>]
218
+ : Array<SchemaType<Args[number]>>;
178
219
 
179
- type EncodedArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = {
180
- [Index in keyof Args]: S.Json;
220
+ type EncodedArgsFromSchemas<Args extends ReadonlyArray<RpcSchema>> = {
221
+ [Index in keyof Args]: WireEncoded<Args[Index]>;
181
222
  };
182
223
 
183
224
  export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
184
225
 
185
226
  export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
186
227
 
187
- export type Success<Self extends Any> = S.Schema.Type<Self["success"]>;
228
+ export type Success<Self extends Any> = SchemaType<Self["success"]>;
188
229
 
189
- export type EncodedSuccess<_Self extends Any> = S.Json;
230
+ export type EncodedSuccess<Self extends Any> = WireEncoded<Self["success"]>;
190
231
  }
191
232
 
192
233
  export type Methods = Record<string, Method.Any>;
@@ -237,16 +278,16 @@ export const assertNoReservedMethods = <
237
278
  }
238
279
  };
239
280
 
240
- export function method<Success extends ServiceFreeSchema>(definition: {
281
+ export function method<Success extends RpcSchema>(definition: {
241
282
  readonly success: Success;
242
283
  }): Method<readonly [], Success>;
243
284
  export function method<
244
- const Args extends ReadonlyArray<ServiceFreeSchema>,
245
- Success extends ServiceFreeSchema,
285
+ const Args extends ReadonlyArray<RpcSchema>,
286
+ Success extends RpcSchema,
246
287
  >(definition: { readonly args: Args; readonly success: Success }): Method<Args, Success>;
247
288
  export function method(definition: {
248
- readonly args?: ReadonlyArray<ServiceFreeSchema>;
249
- readonly success: ServiceFreeSchema;
289
+ readonly args?: ReadonlyArray<RpcSchema>;
290
+ readonly success: RpcSchema;
250
291
  }) {
251
292
  return {
252
293
  args: definition.args ?? [],
@@ -276,9 +317,8 @@ export const decodeArgs = Effect.fnUntraced(function* <
276
317
  });
277
318
  }
278
319
 
279
- const decoded = yield* S.decodeUnknownEffect(wireCodec(S.Tuple(methodDefinition.args)))(
280
- args,
281
- ).pipe(
320
+ const codecs = methodDefinition.args.map((schema) => wireCodec(schema));
321
+ const decoded = yield* S.decodeUnknownEffect(S.Tuple(codecs))(args).pipe(
282
322
  Effect.mapError(
283
323
  (cause) =>
284
324
  new RpcArgumentDecodeError({
@@ -315,9 +355,8 @@ export const encodeArgs = Effect.fnUntraced(function* <
315
355
  });
316
356
  }
317
357
 
318
- const encoded = yield* S.encodeUnknownEffect(wireCodec(S.Tuple(methodDefinition.args)))(
319
- args,
320
- ).pipe(
358
+ const codecs = methodDefinition.args.map((schema) => wireCodec(schema));
359
+ const encoded = yield* S.encodeUnknownEffect(S.Tuple(codecs))(args).pipe(
321
360
  Effect.mapError(
322
361
  (cause) =>
323
362
  new RpcArgumentEncodeError({
package/src/RpcTargets.ts CHANGED
@@ -1,21 +1,15 @@
1
- import * as Context from "effect/Context";
2
1
  import * as Effect from "effect/Effect";
3
2
  import * as Data from "effect/Data";
4
3
  import type * as Scope from "effect/Scope";
5
4
  import * as Option from "effect/Option";
6
5
 
6
+ import { CurrentTargets, type Targets } from "./internal/RpcTargets";
7
+
7
8
  /** A native RPC target could not be constructed. */
8
9
  export class RpcTargetError extends Data.TaggedError("RpcTargetError")<{
9
10
  readonly cause: unknown;
10
11
  }> {}
11
12
 
12
- interface Targets {
13
- get<A extends object, Owner extends object>(owner: Owner, address: string, create: () => A): A;
14
- invalidate<Target extends object>(target: Target): void;
15
- }
16
-
17
- class CurrentTargets extends Context.Service<CurrentTargets, Targets>()("effect-cf/RpcTargets") {}
18
-
19
13
  /**
20
14
  * Reuse a native RPC target within the current invocation. Native Durable Object
21
15
  * stubs capture the calling request's channel when created. Recreating a stub