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,4 +1,4 @@
|
|
|
1
|
-
import { Data, Effect, type Scope } from "effect";
|
|
1
|
+
import { Context, Data, Effect, type Scope } from "effect";
|
|
2
2
|
|
|
3
3
|
import * as Binding from "./Binding";
|
|
4
4
|
import * as CloudflareRpc from "./Rpc";
|
|
@@ -6,8 +6,6 @@ import type * as DurableObjectDefinition from "./DurableObjectDefinition";
|
|
|
6
6
|
import * as RpcDefinition from "./RpcDefinition";
|
|
7
7
|
import * as RpcInvocation from "./internal/RpcInvocation";
|
|
8
8
|
|
|
9
|
-
const TypeId = "effect-cf/DurableObjectNamespace" as const;
|
|
10
|
-
|
|
11
9
|
interface DurableObjectFetcher {
|
|
12
10
|
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
13
11
|
}
|
|
@@ -66,14 +64,6 @@ export interface DurableObjectNamespaceDefinition {
|
|
|
66
64
|
readonly binding: string;
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
type ApiFromDefinition<Definition> = Definition extends DurableObjectDefinition.Definition.Any
|
|
70
|
-
? DurableObjectDefinition.ServerApi<Definition>
|
|
71
|
-
: never;
|
|
72
|
-
|
|
73
|
-
type ApiOrDefinition<Api extends object, Definition> = [Api] extends [never]
|
|
74
|
-
? ApiFromDefinition<Definition>
|
|
75
|
-
: Api;
|
|
76
|
-
|
|
77
67
|
/**
|
|
78
68
|
* Namespace binding metadata with optional RPC schema.
|
|
79
69
|
*/
|
|
@@ -109,6 +99,10 @@ type StubMethodSuccess<Api, Method extends keyof Api> = RpcInvocation.AsyncMetho
|
|
|
109
99
|
Api,
|
|
110
100
|
Method
|
|
111
101
|
>;
|
|
102
|
+
type StubMethodCloudflareReturn<
|
|
103
|
+
Api,
|
|
104
|
+
Method extends keyof Api,
|
|
105
|
+
> = RpcInvocation.AsyncMethodCloudflareReturn<Api, Method>;
|
|
112
106
|
|
|
113
107
|
type StubCall<R, Api extends object> = <Method extends StubMethodKey<Api>>(
|
|
114
108
|
stub: DurableObjectStubClient<Api>,
|
|
@@ -128,6 +122,7 @@ type DurableObjectDirectClient<R, Api extends object> = {
|
|
|
128
122
|
};
|
|
129
123
|
|
|
130
124
|
type DefinitionNamespaceDirectMethods<
|
|
125
|
+
R,
|
|
131
126
|
Api extends object,
|
|
132
127
|
Definition extends DurableObjectDefinition.Definition.Any,
|
|
133
128
|
> = {
|
|
@@ -136,7 +131,8 @@ type DefinitionNamespaceDirectMethods<
|
|
|
136
131
|
...args: RpcDefinition.Method.Args<Definition["methods"][Method]>
|
|
137
132
|
) => Effect.Effect<
|
|
138
133
|
RpcDefinition.Method.Success<Definition["methods"][Method]>,
|
|
139
|
-
DurableObjectRpcError
|
|
134
|
+
DurableObjectRpcError,
|
|
135
|
+
R
|
|
140
136
|
>;
|
|
141
137
|
};
|
|
142
138
|
|
|
@@ -177,7 +173,7 @@ type DirectMethods<
|
|
|
177
173
|
Api extends object,
|
|
178
174
|
Definition,
|
|
179
175
|
> = Definition extends DurableObjectDefinition.Definition.Any
|
|
180
|
-
? DefinitionNamespaceDirectMethods<Api, Definition> &
|
|
176
|
+
? DefinitionNamespaceDirectMethods<R, Api, Definition> &
|
|
181
177
|
DefinitionNamespaceDirectClientMethods<R, Definition>
|
|
182
178
|
: {};
|
|
183
179
|
|
|
@@ -185,280 +181,231 @@ export type DurableObjectNamespaceEffectClient<
|
|
|
185
181
|
Api extends object,
|
|
186
182
|
Definition extends DurableObjectDefinition.Definition.Any | undefined = undefined,
|
|
187
183
|
> = DirectMethods<never, Api, Definition> & {
|
|
184
|
+
/** Creates a globally unique Durable Object id. */
|
|
188
185
|
readonly newUniqueId: (
|
|
189
186
|
options?: globalThis.DurableObjectNamespaceNewUniqueIdOptions,
|
|
190
187
|
) => Effect.Effect<globalThis.DurableObjectId>;
|
|
188
|
+
/** Deterministically maps a name to a Durable Object id. */
|
|
191
189
|
readonly idFromName: (name: string) => Effect.Effect<globalThis.DurableObjectId>;
|
|
190
|
+
/** Rehydrates a Durable Object id from its string form. */
|
|
192
191
|
readonly idFromString: (id: string) => Effect.Effect<globalThis.DurableObjectId>;
|
|
192
|
+
/** Returns a stub for an existing Durable Object id. */
|
|
193
193
|
readonly get: (
|
|
194
194
|
id: globalThis.DurableObjectId,
|
|
195
195
|
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
196
196
|
) => Effect.Effect<DurableObjectStubClient<Api>>;
|
|
197
|
+
/** Returns a stub by deterministic name. */
|
|
197
198
|
readonly getByName: (
|
|
198
199
|
name: string,
|
|
199
200
|
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
200
201
|
) => Effect.Effect<DurableObjectStubClient<Api>>;
|
|
202
|
+
/** Selects a namespace pinned to a specific jurisdiction. */
|
|
201
203
|
readonly jurisdiction: (
|
|
202
204
|
jurisdiction: globalThis.DurableObjectJurisdiction,
|
|
203
205
|
) => Effect.Effect<DurableObjectNamespaceClient<Api>>;
|
|
206
|
+
/**
|
|
207
|
+
* Forwards an HTTP request to a Durable Object stub.
|
|
208
|
+
*
|
|
209
|
+
* Use this for fetch-based Durable Object APIs, including WebSocket upgrade
|
|
210
|
+
* forwarding where the native response must be preserved.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* import { Effect } from "effect";
|
|
215
|
+
*
|
|
216
|
+
* const program = Effect.gen(function* () {
|
|
217
|
+
* const rooms = yield* ChatRooms;
|
|
218
|
+
* const room = yield* rooms.getByName("general");
|
|
219
|
+
*
|
|
220
|
+
* return yield* rooms.fetch(room, new Request("https://worker.example/room"));
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
204
224
|
readonly fetch: (
|
|
205
225
|
stub: DurableObjectStubClient<Api>,
|
|
206
226
|
input: RequestInfo | URL,
|
|
207
227
|
init?: RequestInit,
|
|
208
228
|
) => Effect.Effect<globalThis.Response, DurableObjectFetchError>;
|
|
229
|
+
/**
|
|
230
|
+
* Invokes a Durable Object RPC method and returns Cloudflare's raw RPC result.
|
|
231
|
+
*
|
|
232
|
+
* This preserves Cloudflare RPC behavior such as promise-like pipelining and
|
|
233
|
+
* transferable / disposable result objects. It does not resolve the returned
|
|
234
|
+
* promise-like value and it does not decode definition-backed success schemas.
|
|
235
|
+
*
|
|
236
|
+
* Most application code should use {@link call} instead.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* import { Effect } from "effect";
|
|
241
|
+
*
|
|
242
|
+
* const program = Effect.gen(function* () {
|
|
243
|
+
* const counters = yield* Counters;
|
|
244
|
+
* const counter = yield* counters.getByName("main");
|
|
245
|
+
*
|
|
246
|
+
* const result = yield* counters.rpc(counter, "get");
|
|
247
|
+
* const value = yield* Effect.promise(() => result);
|
|
248
|
+
*
|
|
249
|
+
* return value;
|
|
250
|
+
* });
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
209
253
|
readonly rpc: <Method extends StubMethodKey<Api>>(
|
|
210
254
|
stub: DurableObjectStubClient<Api>,
|
|
211
255
|
method: Method,
|
|
212
256
|
...args: StubMethodArgs<Api, Method>
|
|
213
|
-
) => Effect.Effect<
|
|
257
|
+
) => Effect.Effect<StubMethodCloudflareReturn<Api, Method>, DurableObjectRpcError>;
|
|
258
|
+
/**
|
|
259
|
+
* Invokes a Durable Object RPC method, resolves Cloudflare's RPC result, and
|
|
260
|
+
* decodes the success value when the namespace was created from a definition.
|
|
261
|
+
*
|
|
262
|
+
* This is the normal choice when application code wants the final typed value.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { Effect } from "effect";
|
|
267
|
+
*
|
|
268
|
+
* const program = Effect.gen(function* () {
|
|
269
|
+
* const counters = yield* Counters;
|
|
270
|
+
* const counter = yield* counters.getByName("main");
|
|
271
|
+
*
|
|
272
|
+
* return yield* counters.call(counter, "increment", 1);
|
|
273
|
+
* });
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
214
276
|
readonly call: <Method extends StubMethodKey<Api>>(
|
|
215
277
|
stub: DurableObjectStubClient<Api>,
|
|
216
278
|
method: Method,
|
|
217
279
|
...args: StubMethodArgs<Api, Method>
|
|
218
280
|
) => Effect.Effect<StubMethodSuccess<Api, Method>, DurableObjectRpcError>;
|
|
281
|
+
/**
|
|
282
|
+
* Invokes a Durable Object RPC method in the current `Scope`, resolves
|
|
283
|
+
* Cloudflare's RPC result, decodes definition-backed success values, and
|
|
284
|
+
* disposes the resolved result when the scope closes if it implements
|
|
285
|
+
* `Symbol.dispose`.
|
|
286
|
+
*
|
|
287
|
+
* Use this for RPC methods that return Cloudflare RPC resources or other
|
|
288
|
+
* disposable objects whose lifetime should be tied to an Effect scope.
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* import { Effect } from "effect";
|
|
293
|
+
*
|
|
294
|
+
* const program = Effect.scoped(
|
|
295
|
+
* Effect.gen(function* () {
|
|
296
|
+
* const rooms = yield* ChatRooms;
|
|
297
|
+
* const room = yield* rooms.getByName("general");
|
|
298
|
+
* const handle = yield* rooms.scopedCall(room, "openStream");
|
|
299
|
+
*
|
|
300
|
+
* return yield* handle.read();
|
|
301
|
+
* }),
|
|
302
|
+
* );
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
219
305
|
readonly scopedCall: <Method extends StubMethodKey<Api>>(
|
|
220
306
|
stub: DurableObjectStubClient<Api>,
|
|
221
307
|
method: Method,
|
|
222
308
|
...args: StubMethodArgs<Api, Method>
|
|
223
309
|
) => Effect.Effect<Awaited<StubMethodSuccess<Api, Method>>, unknown, Scope.Scope>;
|
|
310
|
+
/**
|
|
311
|
+
* Exposes the underlying native Durable Object namespace binding.
|
|
312
|
+
*
|
|
313
|
+
* Prefer the typed helpers above unless Cloudflare exposes a platform feature
|
|
314
|
+
* that is not wrapped by effect-cf yet.
|
|
315
|
+
*/
|
|
224
316
|
readonly unsafeRaw: Effect.Effect<DurableObjectNamespaceClient<Api>>;
|
|
225
317
|
};
|
|
226
318
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
<
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
hasFunction(value, "get") &&
|
|
271
|
-
hasFunction(value, "idFromName") &&
|
|
272
|
-
hasFunction(value, "idFromString") &&
|
|
273
|
-
hasFunction(value, "newUniqueId") &&
|
|
274
|
-
hasFunction(value, "jurisdiction");
|
|
319
|
+
export type DurableObjectNamespaceStaticClient<
|
|
320
|
+
R,
|
|
321
|
+
Api extends object,
|
|
322
|
+
Definition extends DurableObjectDefinition.Definition.Any | undefined = undefined,
|
|
323
|
+
> = DirectMethods<R, Api, Definition> & {
|
|
324
|
+
readonly newUniqueId: (
|
|
325
|
+
options?: globalThis.DurableObjectNamespaceNewUniqueIdOptions,
|
|
326
|
+
) => Effect.Effect<globalThis.DurableObjectId, never, R>;
|
|
327
|
+
readonly idFromName: (name: string) => Effect.Effect<globalThis.DurableObjectId, never, R>;
|
|
328
|
+
readonly idFromString: (id: string) => Effect.Effect<globalThis.DurableObjectId, never, R>;
|
|
329
|
+
readonly get: (
|
|
330
|
+
id: globalThis.DurableObjectId,
|
|
331
|
+
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
332
|
+
) => Effect.Effect<DurableObjectStubClient<Api>, never, R>;
|
|
333
|
+
readonly getByName: (
|
|
334
|
+
name: string,
|
|
335
|
+
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
336
|
+
) => Effect.Effect<DurableObjectStubClient<Api>, never, R>;
|
|
337
|
+
readonly jurisdiction: (
|
|
338
|
+
jurisdiction: globalThis.DurableObjectJurisdiction,
|
|
339
|
+
) => Effect.Effect<DurableObjectNamespaceClient<Api>, never, R>;
|
|
340
|
+
readonly fetch: (
|
|
341
|
+
stub: DurableObjectStubClient<Api>,
|
|
342
|
+
input: RequestInfo | URL,
|
|
343
|
+
init?: RequestInit,
|
|
344
|
+
) => Effect.Effect<globalThis.Response, DurableObjectFetchError, R>;
|
|
345
|
+
readonly rpc: <Method extends StubMethodKey<Api>>(
|
|
346
|
+
stub: DurableObjectStubClient<Api>,
|
|
347
|
+
method: Method,
|
|
348
|
+
...args: StubMethodArgs<Api, Method>
|
|
349
|
+
) => Effect.Effect<StubMethodCloudflareReturn<Api, Method>, DurableObjectRpcError, R>;
|
|
350
|
+
readonly call: <Method extends StubMethodKey<Api>>(
|
|
351
|
+
stub: DurableObjectStubClient<Api>,
|
|
352
|
+
method: Method,
|
|
353
|
+
...args: StubMethodArgs<Api, Method>
|
|
354
|
+
) => Effect.Effect<StubMethodSuccess<Api, Method>, DurableObjectRpcError, R>;
|
|
355
|
+
readonly scopedCall: <Method extends StubMethodKey<Api>>(
|
|
356
|
+
stub: DurableObjectStubClient<Api>,
|
|
357
|
+
method: Method,
|
|
358
|
+
...args: StubMethodArgs<Api, Method>
|
|
359
|
+
) => Effect.Effect<Awaited<StubMethodSuccess<Api, Method>>, unknown, Scope.Scope | R>;
|
|
360
|
+
readonly unsafeRaw: () => Effect.Effect<DurableObjectNamespaceClient<Api>, never, R>;
|
|
361
|
+
};
|
|
275
362
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
try: () => stub.fetch(input, init),
|
|
302
|
-
catch: (cause) => new DurableObjectFetchError({ binding: definition.binding, cause }),
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
const rpc = <Method extends StubMethodKey<NamespaceApi>>(
|
|
306
|
-
stub: StubClient,
|
|
307
|
-
method: Method,
|
|
308
|
-
...args: StubMethodArgs<NamespaceApi, Method>
|
|
309
|
-
) =>
|
|
310
|
-
Effect.gen(function* () {
|
|
311
|
-
const methodName = String(method);
|
|
312
|
-
const encodedArgs =
|
|
313
|
-
definition.definition === undefined
|
|
314
|
-
? args
|
|
315
|
-
: yield* RpcDefinition.encodeArgs(
|
|
316
|
-
definition.definition,
|
|
317
|
-
methodName as RpcDefinition.Definition.MethodNames<NonNullable<Definition>>,
|
|
318
|
-
args as never,
|
|
319
|
-
).pipe(
|
|
320
|
-
Effect.mapError(
|
|
321
|
-
(cause) =>
|
|
322
|
-
new DurableObjectRpcError({
|
|
323
|
-
binding: definition.binding,
|
|
324
|
-
method: methodName,
|
|
325
|
-
cause,
|
|
326
|
-
}),
|
|
327
|
-
),
|
|
328
|
-
);
|
|
329
|
-
|
|
330
|
-
return yield* RpcInvocation.invokeRpcMethod(
|
|
331
|
-
stub,
|
|
332
|
-
method,
|
|
333
|
-
encodedArgs as StubMethodArgs<NamespaceApi, Method>,
|
|
334
|
-
(cause) =>
|
|
335
|
-
new DurableObjectRpcError({
|
|
336
|
-
binding: definition.binding,
|
|
337
|
-
method: methodName,
|
|
338
|
-
cause,
|
|
339
|
-
}),
|
|
340
|
-
);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
const call = <Method extends StubMethodKey<NamespaceApi>>(
|
|
344
|
-
stub: StubClient,
|
|
345
|
-
method: Method,
|
|
346
|
-
...args: StubMethodArgs<NamespaceApi, Method>
|
|
347
|
-
) =>
|
|
348
|
-
Effect.gen(function* () {
|
|
349
|
-
const methodName = String(method);
|
|
350
|
-
const value = yield* CloudflareRpc.resolve(yield* rpc(stub, method, ...args)).pipe(
|
|
351
|
-
Effect.mapError(
|
|
352
|
-
(cause) =>
|
|
353
|
-
new DurableObjectRpcError({
|
|
354
|
-
binding: definition.binding,
|
|
355
|
-
method: methodName,
|
|
356
|
-
cause,
|
|
357
|
-
}),
|
|
358
|
-
),
|
|
359
|
-
);
|
|
360
|
-
|
|
361
|
-
if (definition.definition === undefined) {
|
|
362
|
-
return value as StubMethodSuccess<NamespaceApi, Method>;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const decoded = yield* RpcDefinition.decodeSuccess(
|
|
366
|
-
definition.definition,
|
|
367
|
-
methodName as RpcDefinition.Definition.MethodNames<NonNullable<Definition>>,
|
|
368
|
-
value,
|
|
369
|
-
).pipe(
|
|
370
|
-
Effect.mapError(
|
|
371
|
-
(cause) =>
|
|
372
|
-
new DurableObjectRpcError({
|
|
373
|
-
binding: definition.binding,
|
|
374
|
-
method: methodName,
|
|
375
|
-
cause,
|
|
376
|
-
}),
|
|
377
|
-
),
|
|
378
|
-
);
|
|
379
|
-
|
|
380
|
-
return decoded as StubMethodSuccess<NamespaceApi, Method>;
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
const scopedCall = <Method extends StubMethodKey<NamespaceApi>>(
|
|
384
|
-
stub: StubClient,
|
|
385
|
-
method: Method,
|
|
386
|
-
...args: StubMethodArgs<NamespaceApi, Method>
|
|
387
|
-
) =>
|
|
388
|
-
Effect.gen(function* () {
|
|
389
|
-
const result = yield* rpc(stub, method, ...args);
|
|
390
|
-
return yield* CloudflareRpc.scoped(result);
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
const directMethods = makeDirectMethods<never, NamespaceApi, Definition>(
|
|
394
|
-
definition.definition,
|
|
395
|
-
{
|
|
396
|
-
call,
|
|
397
|
-
fetch,
|
|
398
|
-
get,
|
|
399
|
-
getByName,
|
|
400
|
-
},
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
return Object.assign(directMethods, {
|
|
404
|
-
newUniqueId,
|
|
405
|
-
idFromName,
|
|
406
|
-
idFromString,
|
|
407
|
-
get,
|
|
408
|
-
getByName,
|
|
409
|
-
jurisdiction,
|
|
410
|
-
fetch,
|
|
411
|
-
rpc,
|
|
412
|
-
call,
|
|
413
|
-
scopedCall,
|
|
414
|
-
unsafeRaw: Effect.succeed(namespace),
|
|
415
|
-
}) as DurableObjectNamespaceEffectClient<NamespaceApi, Definition>;
|
|
416
|
-
};
|
|
363
|
+
const hasFunction = (value: object, key: string): boolean =>
|
|
364
|
+
typeof Reflect.get(value, key) === "function";
|
|
365
|
+
|
|
366
|
+
export const isDurableObjectNamespaceClient = <Api extends object>(
|
|
367
|
+
value: unknown,
|
|
368
|
+
): value is DurableObjectNamespaceClient<Api> =>
|
|
369
|
+
typeof value === "object" &&
|
|
370
|
+
value !== null &&
|
|
371
|
+
hasFunction(value, "getByName") &&
|
|
372
|
+
hasFunction(value, "get") &&
|
|
373
|
+
hasFunction(value, "idFromName") &&
|
|
374
|
+
hasFunction(value, "idFromString") &&
|
|
375
|
+
hasFunction(value, "newUniqueId") &&
|
|
376
|
+
hasFunction(value, "jurisdiction");
|
|
377
|
+
|
|
378
|
+
export const makeClient = <
|
|
379
|
+
Api extends object,
|
|
380
|
+
const Definition extends DurableObjectDefinition.Definition.Any | undefined = undefined,
|
|
381
|
+
>(
|
|
382
|
+
definition: DurableObjectNamespaceBindingDefinition<Definition>,
|
|
383
|
+
): ((
|
|
384
|
+
namespace: DurableObjectNamespaceClient<Api>,
|
|
385
|
+
) => DurableObjectNamespaceEffectClient<Api, Definition>) => {
|
|
386
|
+
type NamespaceClient = DurableObjectNamespaceClient<Api>;
|
|
387
|
+
type StubClient = DurableObjectStubClient<Api>;
|
|
417
388
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
(value): value is NamespaceClient => isDurableObjectNamespaceClient(value),
|
|
422
|
-
makeClient,
|
|
423
|
-
);
|
|
424
|
-
|
|
425
|
-
const newUniqueId = Effect.fnUntraced(function* (
|
|
426
|
-
options?: globalThis.DurableObjectNamespaceNewUniqueIdOptions,
|
|
427
|
-
) {
|
|
428
|
-
const namespace = yield* tag;
|
|
429
|
-
return yield* namespace.newUniqueId(options);
|
|
430
|
-
});
|
|
389
|
+
return (namespace: NamespaceClient) => {
|
|
390
|
+
const newUniqueId = (options?: globalThis.DurableObjectNamespaceNewUniqueIdOptions) =>
|
|
391
|
+
Effect.sync(() => namespace.newUniqueId(options));
|
|
431
392
|
|
|
432
|
-
const idFromName = Effect.
|
|
433
|
-
const namespace = yield* tag;
|
|
434
|
-
return yield* namespace.idFromName(name);
|
|
435
|
-
});
|
|
393
|
+
const idFromName = (name: string) => Effect.sync(() => namespace.idFromName(name));
|
|
436
394
|
|
|
437
|
-
const idFromString = Effect.
|
|
438
|
-
const namespace = yield* tag;
|
|
439
|
-
return yield* namespace.idFromString(id);
|
|
440
|
-
});
|
|
395
|
+
const idFromString = (id: string) => Effect.sync(() => namespace.idFromString(id));
|
|
441
396
|
|
|
442
|
-
const get =
|
|
397
|
+
const get = (
|
|
443
398
|
id: globalThis.DurableObjectId,
|
|
444
399
|
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
445
|
-
)
|
|
446
|
-
const namespace = yield* tag;
|
|
447
|
-
return yield* namespace.get(id, options);
|
|
448
|
-
});
|
|
400
|
+
) => Effect.sync(() => namespace.get(id, options));
|
|
449
401
|
|
|
450
|
-
const getByName =
|
|
402
|
+
const getByName = (
|
|
451
403
|
name: string,
|
|
452
404
|
options?: globalThis.DurableObjectNamespaceGetDurableObjectOptions,
|
|
453
|
-
)
|
|
454
|
-
const namespace = yield* tag;
|
|
455
|
-
return yield* namespace.getByName(name, options);
|
|
456
|
-
});
|
|
405
|
+
) => Effect.sync(() => namespace.getByName(name, options));
|
|
457
406
|
|
|
458
|
-
const jurisdiction =
|
|
459
|
-
|
|
460
|
-
return yield* namespace.jurisdiction(value);
|
|
461
|
-
});
|
|
407
|
+
const jurisdiction = (value: globalThis.DurableObjectJurisdiction) =>
|
|
408
|
+
Effect.sync(() => namespace.jurisdiction(value));
|
|
462
409
|
|
|
463
410
|
const fetch = (stub: StubClient, input: RequestInfo | URL, init?: RequestInit) =>
|
|
464
411
|
Effect.tryPromise({
|
|
@@ -466,10 +413,10 @@ export const Service =
|
|
|
466
413
|
catch: (cause) => new DurableObjectFetchError({ binding: definition.binding, cause }),
|
|
467
414
|
});
|
|
468
415
|
|
|
469
|
-
const rpc = <Method extends StubMethodKey<
|
|
416
|
+
const rpc = <Method extends StubMethodKey<Api>>(
|
|
470
417
|
stub: StubClient,
|
|
471
418
|
method: Method,
|
|
472
|
-
...args: StubMethodArgs<
|
|
419
|
+
...args: StubMethodArgs<Api, Method>
|
|
473
420
|
) =>
|
|
474
421
|
Effect.gen(function* () {
|
|
475
422
|
const methodName = String(method);
|
|
@@ -494,7 +441,7 @@ export const Service =
|
|
|
494
441
|
return yield* RpcInvocation.invokeRpcMethod(
|
|
495
442
|
stub,
|
|
496
443
|
method,
|
|
497
|
-
encodedArgs as StubMethodArgs<
|
|
444
|
+
encodedArgs as StubMethodArgs<Api, Method>,
|
|
498
445
|
(cause) =>
|
|
499
446
|
new DurableObjectRpcError({
|
|
500
447
|
binding: definition.binding,
|
|
@@ -504,14 +451,20 @@ export const Service =
|
|
|
504
451
|
);
|
|
505
452
|
});
|
|
506
453
|
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
...args: StubMethodArgs<NamespaceApi, Method>
|
|
454
|
+
const decodeSuccess = <Method extends StubMethodKey<Api>>(
|
|
455
|
+
methodName: string,
|
|
456
|
+
value: Awaited<StubMethodCloudflareReturn<Api, Method>>,
|
|
511
457
|
) =>
|
|
512
458
|
Effect.gen(function* () {
|
|
513
|
-
|
|
514
|
-
|
|
459
|
+
if (definition.definition === undefined) {
|
|
460
|
+
return value as StubMethodSuccess<Api, Method>;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const decoded = yield* RpcDefinition.decodeSuccess(
|
|
464
|
+
definition.definition,
|
|
465
|
+
methodName as RpcDefinition.Definition.MethodNames<NonNullable<Definition>>,
|
|
466
|
+
value,
|
|
467
|
+
).pipe(
|
|
515
468
|
Effect.mapError(
|
|
516
469
|
(cause) =>
|
|
517
470
|
new DurableObjectRpcError({
|
|
@@ -522,15 +475,17 @@ export const Service =
|
|
|
522
475
|
),
|
|
523
476
|
);
|
|
524
477
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
}
|
|
478
|
+
return decoded as StubMethodSuccess<Api, Method>;
|
|
479
|
+
});
|
|
528
480
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
481
|
+
const call = <Method extends StubMethodKey<Api>>(
|
|
482
|
+
stub: StubClient,
|
|
483
|
+
method: Method,
|
|
484
|
+
...args: StubMethodArgs<Api, Method>
|
|
485
|
+
) =>
|
|
486
|
+
Effect.gen(function* () {
|
|
487
|
+
const methodName = String(method);
|
|
488
|
+
const value = yield* CloudflareRpc.resolve(yield* rpc(stub, method, ...args)).pipe(
|
|
534
489
|
Effect.mapError(
|
|
535
490
|
(cause) =>
|
|
536
491
|
new DurableObjectRpcError({
|
|
@@ -541,34 +496,29 @@ export const Service =
|
|
|
541
496
|
),
|
|
542
497
|
);
|
|
543
498
|
|
|
544
|
-
return
|
|
499
|
+
return yield* decodeSuccess<Method>(methodName, value);
|
|
545
500
|
});
|
|
546
501
|
|
|
547
|
-
const scopedCall = <Method extends StubMethodKey<
|
|
502
|
+
const scopedCall = <Method extends StubMethodKey<Api>>(
|
|
548
503
|
stub: StubClient,
|
|
549
504
|
method: Method,
|
|
550
|
-
...args: StubMethodArgs<
|
|
505
|
+
...args: StubMethodArgs<Api, Method>
|
|
551
506
|
) =>
|
|
552
507
|
Effect.gen(function* () {
|
|
508
|
+
const methodName = String(method);
|
|
553
509
|
const result = yield* rpc(stub, method, ...args);
|
|
554
|
-
|
|
510
|
+
const value = yield* CloudflareRpc.scoped(result);
|
|
511
|
+
return yield* decodeSuccess<Method>(methodName, value);
|
|
555
512
|
});
|
|
556
513
|
|
|
557
|
-
const
|
|
558
|
-
const namespace = yield* tag;
|
|
559
|
-
return yield* namespace.unsafeRaw;
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
const directMethods = makeDirectMethods<Self, NamespaceApi, Definition>(definition.definition, {
|
|
514
|
+
const directMethods = makeDirectMethods<never, Api, Definition>(definition.definition, {
|
|
563
515
|
call,
|
|
564
516
|
fetch,
|
|
565
517
|
get,
|
|
566
518
|
getByName,
|
|
567
519
|
});
|
|
568
520
|
|
|
569
|
-
return Object.assign(
|
|
570
|
-
[TypeId]: TypeId,
|
|
571
|
-
definition,
|
|
521
|
+
return Object.assign(directMethods, {
|
|
572
522
|
newUniqueId,
|
|
573
523
|
idFromName,
|
|
574
524
|
idFromString,
|
|
@@ -579,26 +529,28 @@ export const Service =
|
|
|
579
529
|
rpc,
|
|
580
530
|
call,
|
|
581
531
|
scopedCall,
|
|
582
|
-
unsafeRaw,
|
|
583
|
-
}) as
|
|
584
|
-
DirectMethods<Self, NamespaceApi, Definition> & {
|
|
585
|
-
readonly [TypeId]: typeof TypeId;
|
|
586
|
-
readonly definition: DurableObjectNamespaceBindingDefinition<Definition>;
|
|
587
|
-
readonly newUniqueId: typeof newUniqueId;
|
|
588
|
-
readonly idFromName: typeof idFromName;
|
|
589
|
-
readonly idFromString: typeof idFromString;
|
|
590
|
-
readonly get: typeof get;
|
|
591
|
-
readonly getByName: typeof getByName;
|
|
592
|
-
readonly jurisdiction: typeof jurisdiction;
|
|
593
|
-
readonly fetch: typeof fetch;
|
|
594
|
-
readonly rpc: typeof rpc;
|
|
595
|
-
readonly call: typeof call;
|
|
596
|
-
readonly scopedCall: typeof scopedCall;
|
|
597
|
-
readonly unsafeRaw: typeof unsafeRaw;
|
|
598
|
-
};
|
|
532
|
+
unsafeRaw: Effect.succeed(namespace),
|
|
533
|
+
}) as DurableObjectNamespaceEffectClient<Api, Definition>;
|
|
599
534
|
};
|
|
535
|
+
};
|
|
600
536
|
|
|
601
|
-
const
|
|
537
|
+
export const layer = <
|
|
538
|
+
Self,
|
|
539
|
+
Api extends object,
|
|
540
|
+
const Definition extends DurableObjectDefinition.Definition.Any | undefined = undefined,
|
|
541
|
+
>(
|
|
542
|
+
tag: Context.Service<Self, DurableObjectNamespaceEffectClient<Api, Definition>>,
|
|
543
|
+
definition: DurableObjectNamespaceBindingDefinition<Definition>,
|
|
544
|
+
) =>
|
|
545
|
+
Binding.layer(
|
|
546
|
+
tag,
|
|
547
|
+
definition.binding,
|
|
548
|
+
(value): value is DurableObjectNamespaceClient<Api> =>
|
|
549
|
+
isDurableObjectNamespaceClient<Api>(value),
|
|
550
|
+
makeClient<Api, Definition>(definition),
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
export const makeDirectMethods = <
|
|
602
554
|
R,
|
|
603
555
|
Api extends object,
|
|
604
556
|
Definition extends DurableObjectDefinition.Definition.Any | undefined,
|
|
@@ -655,7 +607,7 @@ const makeDirectMethods = <
|
|
|
655
607
|
stub: DurableObjectStubClient<Api>,
|
|
656
608
|
method: string,
|
|
657
609
|
...args: Array<unknown>
|
|
658
|
-
) => Effect.Effect<unknown, DurableObjectRpcError>
|
|
610
|
+
) => Effect.Effect<unknown, DurableObjectRpcError, R>
|
|
659
611
|
)(stub, methodName, ...args);
|
|
660
612
|
});
|
|
661
613
|
}
|