effect-cf 0.6.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/CHANGELOG.md +8 -0
- package/README.md +30 -29
- package/dist/index.d.mts +837 -1027
- package/dist/index.mjs +328 -407
- package/package.json +1 -1
- package/src/Binding.ts +17 -10
- package/src/DurableObject.ts +117 -23
- package/src/DurableObjectDefinition.ts +251 -72
- package/src/DurableObjectNamespace.ts +239 -287
- package/src/Kv.ts +173 -199
- package/src/Queue.ts +18 -4
- package/src/QueueBinding.ts +45 -97
- package/src/QueueDefinition.ts +87 -41
- package/src/ServiceBinding.ts +260 -116
- package/src/Worker.ts +114 -20
- package/src/WorkerDefinition.ts +187 -63
- package/src/Workflow.ts +23 -4
- package/src/WorkflowBinding.ts +100 -109
- package/src/WorkflowDefinition.ts +116 -51
package/package.json
CHANGED
package/src/Binding.ts
CHANGED
|
@@ -59,6 +59,21 @@ export interface BindingService<Self, Id extends string, Service> extends Contex
|
|
|
59
59
|
>;
|
|
60
60
|
}
|
|
61
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
|
+
|
|
62
77
|
export const Service =
|
|
63
78
|
<Self>() =>
|
|
64
79
|
<Id extends string, Resource, Service = Resource>(
|
|
@@ -68,19 +83,11 @@ export const Service =
|
|
|
68
83
|
wrap?: (resource: Resource) => Service,
|
|
69
84
|
): BindingService<Self, Id, Service> => {
|
|
70
85
|
const tag = Context.Service<Self, Service>()(id);
|
|
71
|
-
|
|
72
|
-
const layer = Layer.effect(
|
|
73
|
-
tag,
|
|
74
|
-
Effect.gen(function* () {
|
|
75
|
-
const env = yield* WorkerEnvironment;
|
|
76
|
-
const resource = yield* getBinding(env, binding, isResource);
|
|
77
|
-
return wrap === undefined ? (resource as unknown as Service) : wrap(resource);
|
|
78
|
-
}),
|
|
79
|
-
);
|
|
86
|
+
const serviceLayer = layer(tag, binding, isResource, wrap);
|
|
80
87
|
|
|
81
88
|
return Object.assign(tag, {
|
|
82
89
|
[TypeId]: TypeId,
|
|
83
90
|
binding,
|
|
84
|
-
layer,
|
|
91
|
+
layer: serviceLayer,
|
|
85
92
|
}) as BindingService<Self, Id, Service>;
|
|
86
93
|
};
|
package/src/DurableObject.ts
CHANGED
|
@@ -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
|
|
215
|
+
export type ServiceFreeSchema = S.Codec<any, any, never, never>;
|
|
212
216
|
|
|
213
|
-
export
|
|
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
|
|
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
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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 =
|
|
255
|
+
export type Any = Definition<string, Methods>;
|
|
225
256
|
}
|
|
226
257
|
|
|
227
|
-
export type
|
|
228
|
-
DurableObjectDefinition.ServerApi<Self>;
|
|
258
|
+
export type LayerOptions = DurableObjectDefinition.LayerOptions;
|
|
229
259
|
|
|
230
|
-
export type
|
|
231
|
-
|
|
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
|
|
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
|
|
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
|
|
241
|
-
>
|
|
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
|
|
339
|
+
Self extends Definition.Any,
|
|
246
340
|
Key extends keyof Self["methods"],
|
|
247
|
-
> =
|
|
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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 =
|
|
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> =
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
Self
|
|
47
|
-
|
|
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
|
-
|
|
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:
|
|
68
|
-
) => DurableObjectHandler<ROut,
|
|
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,
|
|
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
|
|
189
|
+
const makeDefinition = <Id extends string, const MethodsShape extends Methods>(
|
|
106
190
|
id: Id,
|
|
107
|
-
methods: MethodsShape &
|
|
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 =
|
|
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
|
-
<
|
|
159
|
-
<Id extends string, const MethodsShape extends
|
|
219
|
+
<Self>() =>
|
|
220
|
+
<Id extends string, const MethodsShape extends Methods>(
|
|
160
221
|
id: Id,
|
|
161
|
-
methods: MethodsShape &
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
|
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,
|
|
393
|
+
> = DurableObjectHandler<ROut, Method.Success<Self["methods"][Key]>>;
|