effect-cf 0.6.0 → 0.8.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 +16 -0
- package/README.md +121 -29
- package/dist/Hyperdrive-By6DrSS_.d.mts +140 -0
- package/dist/Hyperdrive-LuQaVhXU.mjs +86 -0
- package/dist/HyperdrivePg.d.mts +14 -0
- package/dist/HyperdrivePg.mjs +13 -0
- package/dist/index.d.mts +1029 -1162
- package/dist/index.mjs +497 -515
- package/package.json +13 -1
- package/src/Binding.ts +17 -10
- package/src/D1.ts +3 -59
- package/src/DurableObject.ts +117 -23
- package/src/DurableObjectDefinition.ts +251 -72
- package/src/DurableObjectNamespace.ts +239 -287
- package/src/Hyperdrive.ts +82 -0
- package/src/HyperdrivePg.ts +27 -0
- package/src/Images.ts +332 -0
- package/src/Kv.ts +152 -240
- package/src/Queue.ts +18 -4
- package/src/QueueBinding.ts +45 -97
- package/src/QueueDefinition.ts +87 -41
- package/src/R2.ts +230 -0
- 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/src/index.ts +3 -0
|
@@ -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]>>;
|