effect-cf 0.5.0 → 0.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-cf",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Effect-native primitives for Cloudflare Workers and bindings.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/Binding.ts CHANGED
@@ -45,26 +45,49 @@ const getBinding = <Resource>(
45
45
  /**
46
46
  * Creates a Context tag + layer for reading and validating a Cloudflare binding.
47
47
  */
48
+ export interface BindingService<Self, Id extends string, Service> extends Context.ServiceClass<
49
+ Self,
50
+ Id,
51
+ Service
52
+ > {
53
+ readonly [TypeId]: typeof TypeId;
54
+ readonly binding: string;
55
+ readonly layer: Layer.Layer<
56
+ Self,
57
+ BindingNotFoundError | BindingValidationError,
58
+ WorkerEnvironment
59
+ >;
60
+ }
61
+
62
+ export const layer = <Self, Resource, Service = Resource>(
63
+ tag: Context.Service<Self, Service>,
64
+ binding: string,
65
+ isResource: (value: unknown) => value is Resource,
66
+ wrap?: (resource: Resource) => Service,
67
+ ): Layer.Layer<Self, BindingNotFoundError | BindingValidationError, WorkerEnvironment> =>
68
+ Layer.effect(
69
+ tag,
70
+ Effect.gen(function* () {
71
+ const env = yield* WorkerEnvironment;
72
+ const resource = yield* getBinding(env, binding, isResource);
73
+ return wrap === undefined ? (resource as unknown as Service) : wrap(resource);
74
+ }),
75
+ );
76
+
48
77
  export const Service =
49
78
  <Self>() =>
50
- <Id extends string, Resource>(
79
+ <Id extends string, Resource, Service = Resource>(
51
80
  id: Id,
52
81
  binding: string,
53
82
  isResource: (value: unknown) => value is Resource,
54
- ) => {
55
- const tag = Context.Service<Self, Resource>()(id);
56
-
57
- const layer = Layer.effect(
58
- tag,
59
- Effect.gen(function* () {
60
- const env = yield* WorkerEnvironment;
61
- return yield* getBinding(env, binding, isResource);
62
- }),
63
- );
83
+ wrap?: (resource: Resource) => Service,
84
+ ): BindingService<Self, Id, Service> => {
85
+ const tag = Context.Service<Self, Service>()(id);
86
+ const serviceLayer = layer(tag, binding, isResource, wrap);
64
87
 
65
88
  return Object.assign(tag, {
66
89
  [TypeId]: TypeId,
67
90
  binding,
68
- layer,
69
- });
91
+ layer: serviceLayer,
92
+ }) as BindingService<Self, Id, Service>;
70
93
  };
@@ -1,11 +1,15 @@
1
1
  import { DurableObject as CloudflareDurableObject } from "cloudflare:workers";
2
- import { Effect, Layer, ManagedRuntime, type Scope } from "effect";
2
+ import { Effect, Layer, ManagedRuntime, type Context, type Scope } from "effect";
3
+ import type { Schema as S } from "effect";
3
4
 
4
5
  import { NativeRequest } from "./Worker";
5
6
  import { WorkerEnvironment, type WorkerEnv } from "./Environment";
6
7
  import { DurableObjectState, fromDurableObjectState } from "./DurableObjectState";
7
8
  import { fromWebSocket, type DurableWebSocket } from "./DurableObjectWebSocket";
9
+ import type * as Binding from "./Binding";
8
10
  import * as DurableObjectDefinition from "./DurableObjectDefinition";
11
+ import type * as DurableObjectNamespace from "./DurableObjectNamespace";
12
+ import type * as Rpc from "./Rpc";
9
13
  import * as Entrypoint from "./internal/Entrypoint";
10
14
 
11
15
  const reservedMethodNames = new Set<string>([
@@ -208,40 +212,130 @@ export const make = <
208
212
  return Entrypoint.assumeEntrypointClass<DurableObjectClass<Rpc, ROut>>(EffectDurableObject);
209
213
  };
210
214
 
211
- export const Tag = DurableObjectDefinition.Tag;
215
+ export type ServiceFreeSchema = S.Codec<any, any, never, never>;
212
216
 
213
- export const method = DurableObjectDefinition.method;
217
+ export interface Method<
218
+ Args extends ReadonlyArray<ServiceFreeSchema> = ReadonlyArray<ServiceFreeSchema>,
219
+ Success extends ServiceFreeSchema = ServiceFreeSchema,
220
+ > {
221
+ readonly args: Args;
222
+ readonly success: Success;
223
+ }
224
+
225
+ export namespace Method {
226
+ export type Any = Method<ReadonlyArray<ServiceFreeSchema>, ServiceFreeSchema>;
227
+
228
+ type ArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = Args extends readonly []
229
+ ? []
230
+ : Args extends readonly [
231
+ infer Head extends ServiceFreeSchema,
232
+ ...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
233
+ ]
234
+ ? [S.Schema.Type<Head>, ...ArgsFromSchemas<Tail>]
235
+ : Array<S.Schema.Type<Args[number]>>;
214
236
 
215
- export const implement = DurableObjectDefinition.implement;
237
+ export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
238
+
239
+ export type Success<Self extends Any> = S.Schema.Type<Self["success"]>;
240
+ }
216
241
 
217
- export type Definition<
218
- Id extends string = string,
219
- Methods extends DurableObjectDefinition.Definition.Any["methods"] =
220
- DurableObjectDefinition.Definition.Any["methods"],
221
- > = DurableObjectDefinition.Definition<Id, Methods>;
242
+ export type Methods = Record<string, Method.Any>;
243
+
244
+ export type ReservedMethodName = DurableObjectDefinition.ReservedMethodName;
245
+
246
+ export type NoReservedMethods<MethodsShape extends Methods> =
247
+ Extract<keyof MethodsShape, ReservedMethodName> extends never ? MethodsShape : never;
248
+
249
+ export interface Definition<Id extends string = string, MethodsShape extends Methods = Methods> {
250
+ readonly id: Id;
251
+ readonly methods: MethodsShape;
252
+ }
222
253
 
223
254
  export namespace Definition {
224
- export type Any = DurableObjectDefinition.Definition.Any;
255
+ export type Any = Definition<string, Methods>;
225
256
  }
226
257
 
227
- export type ServerApi<Self extends DurableObjectDefinition.Definition.Any> =
228
- DurableObjectDefinition.ServerApi<Self>;
258
+ export type LayerOptions = DurableObjectDefinition.LayerOptions;
229
259
 
230
- export type Api<Self extends DurableObjectDefinition.Definition.Any> =
231
- DurableObjectDefinition.Api<Self>;
260
+ export type ServerApi<Self extends Definition.Any> = {
261
+ readonly [Key in keyof Self["methods"]]: (
262
+ ...args: Method.Args<Self["methods"][Key]>
263
+ ) => Promise<Method.Success<Self["methods"][Key]>>;
264
+ };
232
265
 
233
- export type Handlers<
234
- ROut,
235
- Self extends DurableObjectDefinition.Definition.Any,
236
- > = DurableObjectDefinition.Handlers<ROut, Self>;
266
+ export type Api<Self extends Definition.Any> = Rpc.Provider<ServerApi<Self>, ReservedMethodName>;
237
267
 
238
- export type Options<
268
+ export type Handlers<ROut, Self extends Definition.Any> = {
269
+ readonly [Key in keyof Self["methods"]]: (
270
+ ...args: Method.Args<Self["methods"][Key]>
271
+ ) => DurableObjectHandler<ROut, Method.Success<Self["methods"][Key]>>;
272
+ };
273
+
274
+ export interface Options<ROut, Self extends Definition.Any> extends Omit<
275
+ DurableObjectOptions<ROut, Handlers<ROut, Self>>,
276
+ "rpc"
277
+ > {
278
+ readonly rpc: Handlers<ROut, Self>;
279
+ }
280
+
281
+ export type TagClass<Self, Id extends string, MethodsShape extends Methods> = Context.ServiceClass<
282
+ Self,
283
+ Id,
284
+ DurableObjectNamespace.DurableObjectNamespaceEffectClient<
285
+ Api<Definition<Id, MethodsShape>>,
286
+ Definition<Id, MethodsShape>
287
+ >
288
+ > &
289
+ DurableObjectNamespace.DurableObjectNamespaceStaticClient<
290
+ Self,
291
+ Api<Definition<Id, MethodsShape>>,
292
+ Definition<Id, MethodsShape>
293
+ > & {
294
+ readonly id: Id;
295
+ readonly methods: MethodsShape;
296
+ readonly make: <ROut, LayerError>(
297
+ layer: Layer.Layer<ROut, LayerError, DurableObjectState | WorkerEnvironment>,
298
+ options: Options<ROut, Definition<Id, MethodsShape>>,
299
+ ) => DurableObjectClass<Handlers<ROut, Definition<Id, MethodsShape>>, ROut>;
300
+ readonly layer: (
301
+ options: LayerOptions,
302
+ ) => Layer.Layer<
303
+ Self,
304
+ Binding.BindingNotFoundError | Binding.BindingValidationError,
305
+ WorkerEnvironment
306
+ >;
307
+ };
308
+
309
+ export type TagFactory = <Self>() => <Id extends string, const MethodsShape extends Methods>(
310
+ id: Id,
311
+ methods: MethodsShape & NoReservedMethods<MethodsShape>,
312
+ ) => TagClass<Self, Id, MethodsShape>;
313
+
314
+ export const Tag = DurableObjectDefinition.Tag as unknown as TagFactory;
315
+
316
+ export const method = DurableObjectDefinition.method as {
317
+ <Success extends ServiceFreeSchema>(definition: {
318
+ readonly success: Success;
319
+ }): Method<readonly [], Success>;
320
+ <
321
+ const Args extends ReadonlyArray<ServiceFreeSchema>,
322
+ Success extends ServiceFreeSchema,
323
+ >(definition: {
324
+ readonly args: Args;
325
+ readonly success: Success;
326
+ }): Method<Args, Success>;
327
+ };
328
+
329
+ export const implement = DurableObjectDefinition.implement as unknown as <
239
330
  ROut,
240
- Self extends DurableObjectDefinition.Definition.Any,
241
- > = DurableObjectDefinition.Options<ROut, Self>;
331
+ const Self extends Definition.Any,
332
+ >(
333
+ _definition: Self,
334
+ handlers: Handlers<ROut, Self>,
335
+ ) => Handlers<ROut, Self>;
242
336
 
243
337
  export type HandlerEffect<
244
338
  ROut,
245
- Self extends DurableObjectDefinition.Definition.Any,
339
+ Self extends Definition.Any,
246
340
  Key extends keyof Self["methods"],
247
- > = DurableObjectDefinition.HandlerEffect<ROut, Self, Key>;
341
+ > = DurableObjectHandler<ROut, Method.Success<Self["methods"][Key]>>;
@@ -1,22 +1,68 @@
1
- import { Effect, type Layer } from "effect";
1
+ import { Context, Effect, type Layer } from "effect";
2
+ import type { Schema as S } from "effect";
2
3
 
4
+ import * as Binding from "./Binding";
3
5
  import * as DurableObjectEntrypoint from "./DurableObject";
4
6
  import type { DurableObjectHandler } from "./DurableObject";
5
7
  import * as DurableObjectNamespace from "./DurableObjectNamespace";
6
8
  import type { DurableObjectState } from "./DurableObjectState";
9
+ import type * as Rpc from "./Rpc";
7
10
  import * as RpcDefinition from "./RpcDefinition";
8
11
  import type { WorkerEnvironment } from "./Environment";
9
12
 
13
+ export type ServiceFreeSchema = S.Codec<any, any, never, never>;
14
+
15
+ export interface Method<
16
+ Args extends ReadonlyArray<ServiceFreeSchema> = ReadonlyArray<ServiceFreeSchema>,
17
+ Success extends ServiceFreeSchema = ServiceFreeSchema,
18
+ > {
19
+ readonly args: Args;
20
+ readonly success: Success;
21
+ }
22
+
23
+ export namespace Method {
24
+ export type Any = Method<ReadonlyArray<ServiceFreeSchema>, ServiceFreeSchema>;
25
+
26
+ type ArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> = Args extends readonly []
27
+ ? []
28
+ : Args extends readonly [
29
+ infer Head extends ServiceFreeSchema,
30
+ ...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
31
+ ]
32
+ ? [S.Schema.Type<Head>, ...ArgsFromSchemas<Tail>]
33
+ : Array<S.Schema.Type<Args[number]>>;
34
+
35
+ type EncodedArgsFromSchemas<Args extends ReadonlyArray<ServiceFreeSchema>> =
36
+ Args extends readonly []
37
+ ? []
38
+ : Args extends readonly [
39
+ infer Head extends ServiceFreeSchema,
40
+ ...infer Tail extends ReadonlyArray<ServiceFreeSchema>,
41
+ ]
42
+ ? [S.Codec.Encoded<Head>, ...EncodedArgsFromSchemas<Tail>]
43
+ : Array<S.Codec.Encoded<Args[number]>>;
44
+
45
+ export type Args<Self extends Any> = ArgsFromSchemas<Self["args"]>;
46
+
47
+ export type EncodedArgs<Self extends Any> = EncodedArgsFromSchemas<Self["args"]>;
48
+
49
+ export type Success<Self extends Any> = S.Schema.Type<Self["success"]>;
50
+
51
+ export type EncodedSuccess<Self extends Any> = S.Codec.Encoded<Self["success"]>;
52
+ }
53
+
54
+ export type Methods = Record<string, Method.Any>;
55
+
10
56
  /**
11
57
  * RPC contract for a Durable Object class.
12
58
  */
13
- export type Definition<
14
- Id extends string = string,
15
- Methods extends RpcDefinition.Methods = RpcDefinition.Methods,
16
- > = RpcDefinition.Definition<Id, Methods>;
59
+ export interface Definition<Id extends string = string, MethodsShape extends Methods = Methods> {
60
+ readonly id: Id;
61
+ readonly methods: MethodsShape;
62
+ }
17
63
 
18
64
  export namespace Definition {
19
- export type Any = RpcDefinition.Definition.Any;
65
+ export type Any = Definition<string, Methods>;
20
66
  }
21
67
 
22
68
  export type ReservedMethodName =
@@ -27,6 +73,9 @@ export type ReservedMethodName =
27
73
  | "webSocketClose"
28
74
  | "webSocketError";
29
75
 
76
+ export type NoReservedMethods<MethodsShape extends Methods> =
77
+ Extract<keyof MethodsShape, ReservedMethodName> extends never ? MethodsShape : never;
78
+
30
79
  const reservedMethodNames = new Set<string>([
31
80
  "constructor",
32
81
  "dup",
@@ -40,38 +89,27 @@ const reservedMethodNames = new Set<string>([
40
89
  /**
41
90
  * Promise-based client API derived from a Durable Object definition.
42
91
  */
43
- export type ServerApi<Self extends Definition.Any> = RpcDefinition.Definition.ServerApi<Self>;
44
-
45
- export type Api<Self extends Definition.Any> = RpcDefinition.Definition.Api<
46
- Self,
47
- ReservedMethodName
48
- >;
92
+ export type ServerApi<Self extends Definition.Any> = {
93
+ readonly [Key in keyof Self["methods"]]: (
94
+ ...args: Method.Args<Self["methods"][Key]>
95
+ ) => Promise<Method.Success<Self["methods"][Key]>>;
96
+ };
49
97
 
50
- declare const NamespaceServiceTypeId: unique symbol;
51
-
52
- /**
53
- * Nominal service marker for a Durable Object namespace binding.
54
- */
55
- export interface NamespaceService<Id extends string, Self extends Definition.Any> {
56
- readonly [NamespaceServiceTypeId]: {
57
- readonly id: Id;
58
- readonly definition: Self;
59
- };
60
- }
98
+ export type Api<Self extends Definition.Any> = Rpc.Provider<ServerApi<Self>, ReservedMethodName>;
61
99
 
62
100
  /**
63
101
  * Effect handlers for each RPC method in a Durable Object definition.
64
102
  */
65
103
  export type Handlers<ROut, Self extends Definition.Any> = {
66
104
  readonly [Key in keyof Self["methods"]]: (
67
- ...args: RpcDefinition.Method.Args<Self["methods"][Key]>
68
- ) => DurableObjectHandler<ROut, RpcDefinition.Method.Success<Self["methods"][Key]>>;
105
+ ...args: Method.Args<Self["methods"][Key]>
106
+ ) => DurableObjectHandler<ROut, Method.Success<Self["methods"][Key]>>;
69
107
  };
70
108
 
71
109
  type BoundaryHandlers<ROut, Self extends Definition.Any> = {
72
110
  readonly [Key in keyof Self["methods"]]: (
73
111
  ...args: Array<unknown>
74
- ) => DurableObjectHandler<ROut, RpcDefinition.Method.EncodedSuccess<Self["methods"][Key]>>;
112
+ ) => DurableObjectHandler<ROut, Method.EncodedSuccess<Self["methods"][Key]>>;
75
113
  };
76
114
 
77
115
  /**
@@ -84,10 +122,56 @@ export interface Options<ROut, Self extends Definition.Any> extends Omit<
84
122
  readonly rpc: Handlers<ROut, Self>;
85
123
  }
86
124
 
125
+ export type LayerOptions = {
126
+ readonly binding: string;
127
+ };
128
+
129
+ export type TagClass<Self, Id extends string, MethodsShape extends Methods> = Context.ServiceClass<
130
+ Self,
131
+ Id,
132
+ DurableObjectNamespace.DurableObjectNamespaceEffectClient<
133
+ Api<Definition<Id, MethodsShape>>,
134
+ Definition<Id, MethodsShape>
135
+ >
136
+ > &
137
+ DurableObjectNamespace.DurableObjectNamespaceStaticClient<
138
+ Self,
139
+ Api<Definition<Id, MethodsShape>>,
140
+ Definition<Id, MethodsShape>
141
+ > & {
142
+ readonly id: Id;
143
+ readonly methods: MethodsShape;
144
+ readonly make: <ROut, LayerError>(
145
+ layer: Layer.Layer<ROut, LayerError, DurableObjectState | WorkerEnvironment>,
146
+ options: Options<ROut, Definition<Id, MethodsShape>>,
147
+ ) => DurableObjectEntrypoint.DurableObjectClass<
148
+ Handlers<ROut, Definition<Id, MethodsShape>>,
149
+ ROut
150
+ >;
151
+ readonly layer: (
152
+ options: LayerOptions,
153
+ ) => Layer.Layer<
154
+ Self,
155
+ Binding.BindingNotFoundError | Binding.BindingValidationError,
156
+ WorkerEnvironment
157
+ >;
158
+ };
159
+
87
160
  /**
88
161
  * Defines a single RPC method schema in a Durable Object definition.
89
162
  */
90
- export const method = RpcDefinition.method;
163
+ export const method = RpcDefinition.method as {
164
+ <Success extends ServiceFreeSchema>(definition: {
165
+ readonly success: Success;
166
+ }): Method<readonly [], Success>;
167
+ <
168
+ const Args extends ReadonlyArray<ServiceFreeSchema>,
169
+ Success extends ServiceFreeSchema,
170
+ >(definition: {
171
+ readonly args: Args;
172
+ readonly success: Success;
173
+ }): Method<Args, Success>;
174
+ };
91
175
 
92
176
  /**
93
177
  * Creates a Durable Object RPC definition plus implementation/binding helpers.
@@ -102,9 +186,9 @@ export const method = RpcDefinition.method;
102
186
  * });
103
187
  * ```
104
188
  */
105
- const makeDefinition = <Id extends string, const MethodsShape extends RpcDefinition.Methods>(
189
+ const makeDefinition = <Id extends string, const MethodsShape extends Methods>(
106
190
  id: Id,
107
- methods: MethodsShape & RpcDefinition.NoReservedMethods<MethodsShape, ReservedMethodName>,
191
+ methods: MethodsShape & NoReservedMethods<MethodsShape>,
108
192
  ) => {
109
193
  type SelfDefinition = Definition<Id, MethodsShape>;
110
194
  RpcDefinition.assertNoReservedMethods("Durable Object", methods, reservedMethodNames);
@@ -119,58 +203,153 @@ const makeDefinition = <Id extends string, const MethodsShape extends RpcDefinit
119
203
  ...options,
120
204
  rpc: wrapHandlers(definition, options.rpc),
121
205
  }),
122
- Namespace:
123
- <Self>() =>
124
- <BindingId extends string>(
125
- bindingId: BindingId,
126
- binding: Omit<
127
- DurableObjectNamespace.DurableObjectNamespaceBindingDefinition<SelfDefinition>,
128
- "definition"
129
- >,
130
- ) =>
131
- DurableObjectNamespace.Service<Self, Api<SelfDefinition>>()<BindingId, SelfDefinition>(
132
- bindingId,
133
- {
134
- ...binding,
135
- definition,
136
- },
137
- ),
138
- namespace: <BindingId extends string>(
139
- bindingId: BindingId,
140
- binding: Omit<
141
- DurableObjectNamespace.DurableObjectNamespaceBindingDefinition<SelfDefinition>,
142
- "definition"
143
- >,
144
- ) =>
145
- DurableObjectNamespace.Service<
146
- NamespaceService<BindingId, SelfDefinition>,
147
- Api<SelfDefinition>
148
- >()<BindingId, SelfDefinition>(bindingId, {
149
- ...binding,
150
- definition,
151
- }),
152
206
  });
153
207
  };
154
208
 
155
- export const make = makeDefinition;
209
+ export const make = <Id extends string, const MethodsShape extends Methods>(
210
+ id: Id,
211
+ methods: MethodsShape & NoReservedMethods<MethodsShape>,
212
+ ) =>
213
+ Tag<Definition<Id, MethodsShape>>()<Id, MethodsShape>(
214
+ id,
215
+ methods as MethodsShape & NoReservedMethods<MethodsShape>,
216
+ );
156
217
 
157
218
  export const Tag =
158
- <_Self>() =>
159
- <Id extends string, const MethodsShape extends RpcDefinition.Methods>(
219
+ <Self>() =>
220
+ <Id extends string, const MethodsShape extends Methods>(
160
221
  id: Id,
161
- methods: MethodsShape & RpcDefinition.NoReservedMethods<MethodsShape, ReservedMethodName>,
222
+ methods: MethodsShape & NoReservedMethods<MethodsShape>,
162
223
  ) => {
163
224
  const definition = makeDefinition<Id, MethodsShape>(id, methods);
225
+ type SelfDefinition = Definition<Id, MethodsShape>;
226
+ type ClientApi = Api<SelfDefinition>;
227
+ const tag = Context.Service<
228
+ Self,
229
+ DurableObjectNamespace.DurableObjectNamespaceEffectClient<ClientApi, SelfDefinition>
230
+ >()(id);
231
+
232
+ const bindingDefinition = (binding: LayerOptions) => ({
233
+ ...binding,
234
+ definition,
235
+ });
236
+
237
+ const layer = (binding: LayerOptions) =>
238
+ DurableObjectNamespace.layer<Self, ClientApi, SelfDefinition>(
239
+ tag,
240
+ bindingDefinition(binding),
241
+ );
242
+
243
+ const newUniqueId = Effect.fnUntraced(function* (
244
+ options?: globalThis.DurableObjectNamespaceNewUniqueIdOptions,
245
+ ) {
246
+ const namespace = yield* tag;
247
+ return yield* namespace.newUniqueId(options);
248
+ });
249
+
250
+ const idFromName = Effect.fnUntraced(function* (name: string) {
251
+ const namespace = yield* tag;
252
+ return yield* namespace.idFromName(name);
253
+ });
254
+
255
+ const idFromString = Effect.fnUntraced(function* (value: string) {
256
+ const namespace = yield* tag;
257
+ return yield* namespace.idFromString(value);
258
+ });
259
+
260
+ const get = Effect.fnUntraced(function* (
261
+ objectId: globalThis.DurableObjectId,
262
+ options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
263
+ ) {
264
+ const namespace = yield* tag;
265
+ return yield* namespace.get(objectId, options);
266
+ });
267
+
268
+ const getByName = Effect.fnUntraced(function* (
269
+ name: string,
270
+ options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
271
+ ) {
272
+ const namespace = yield* tag;
273
+ return yield* namespace.getByName(name, options);
274
+ });
275
+
276
+ const jurisdiction = Effect.fnUntraced(function* (value: globalThis.DurableObjectJurisdiction) {
277
+ const namespace = yield* tag;
278
+ return yield* namespace.jurisdiction(value);
279
+ });
280
+
281
+ const fetch = (
282
+ stub: DurableObjectNamespace.DurableObjectStubClient<ClientApi>,
283
+ input: RequestInfo | URL,
284
+ init?: RequestInit,
285
+ ) =>
286
+ Effect.gen(function* () {
287
+ const namespace = yield* tag;
288
+ return yield* namespace.fetch(stub, input, init);
289
+ });
290
+
291
+ const rpc = <Method extends keyof ClientApi>(
292
+ stub: DurableObjectNamespace.DurableObjectStubClient<ClientApi>,
293
+ method: Method,
294
+ ...args: ClientApi[Method] extends (...args: infer Args) => unknown ? Args : never
295
+ ) =>
296
+ Effect.gen(function* () {
297
+ const namespace = yield* tag;
298
+ return yield* namespace.rpc(stub, method as never, ...(args as never));
299
+ });
300
+
301
+ const call = <Method extends keyof ClientApi>(
302
+ stub: DurableObjectNamespace.DurableObjectStubClient<ClientApi>,
303
+ method: Method,
304
+ ...args: ClientApi[Method] extends (...args: infer Args) => unknown ? Args : never
305
+ ) =>
306
+ Effect.gen(function* () {
307
+ const namespace = yield* tag;
308
+ return yield* namespace.call(stub, method as never, ...(args as never));
309
+ });
310
+
311
+ const scopedCall = <Method extends keyof ClientApi>(
312
+ stub: DurableObjectNamespace.DurableObjectStubClient<ClientApi>,
313
+ method: Method,
314
+ ...args: ClientApi[Method] extends (...args: infer Args) => unknown ? Args : never
315
+ ) =>
316
+ Effect.gen(function* () {
317
+ const namespace = yield* tag;
318
+ return yield* namespace.scopedCall(stub, method as never, ...(args as never));
319
+ });
320
+
321
+ const unsafeRaw = Effect.fnUntraced(function* () {
322
+ const namespace = yield* tag;
323
+ return yield* namespace.unsafeRaw;
324
+ });
164
325
 
165
- abstract class DurableObjectDefinitionClass {
166
- static readonly id = definition.id;
167
- static readonly methods = definition.methods;
168
- static readonly make = definition.make;
169
- static readonly Namespace = definition.Namespace;
170
- static readonly namespace = definition.namespace;
171
- }
326
+ const directMethods = DurableObjectNamespace.makeDirectMethods<Self, ClientApi, SelfDefinition>(
327
+ definition,
328
+ {
329
+ call: call as never,
330
+ fetch,
331
+ get,
332
+ getByName,
333
+ },
334
+ );
172
335
 
173
- return DurableObjectDefinitionClass as (abstract new () => object) & typeof definition;
336
+ return Object.assign(tag, directMethods, {
337
+ id: definition.id,
338
+ methods: definition.methods,
339
+ make: definition.make,
340
+ layer,
341
+ newUniqueId,
342
+ idFromName,
343
+ idFromString,
344
+ get,
345
+ getByName,
346
+ jurisdiction,
347
+ fetch,
348
+ rpc,
349
+ call,
350
+ scopedCall,
351
+ unsafeRaw,
352
+ }) as unknown as TagClass<Self, Id, MethodsShape>;
174
353
  };
175
354
 
176
355
  export const DurableObject = Tag;
@@ -211,4 +390,4 @@ export type HandlerEffect<
211
390
  ROut,
212
391
  Self extends Definition.Any,
213
392
  Key extends keyof Self["methods"],
214
- > = DurableObjectHandler<ROut, RpcDefinition.Method.Success<Self["methods"][Key]>>;
393
+ > = DurableObjectHandler<ROut, Method.Success<Self["methods"][Key]>>;