effect-cf 0.27.0 → 0.28.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 +10 -0
- package/dist/{Artifacts-DcoXcRP5.d.mts → Artifacts-DnHQA-Ax.d.mts} +42 -25
- package/dist/{Artifacts-BhWrdyqX.mjs → Artifacts-rq3hUKQE.mjs} +46 -30
- package/dist/{Binding-COCtoJXa.d.mts → Binding-xJJJPmiD.d.mts} +6 -5
- package/dist/ComputerArtifacts.d.mts +1 -1
- package/dist/ComputerArtifacts.mjs +9 -9
- package/dist/ComputerWorkspace.d.mts +5 -5
- package/dist/ComputerWorkspace.mjs +107 -75
- package/dist/ComputerWorkspaceHost.d.mts +1 -1
- package/dist/ComputerWorkspaceHost.mjs +18 -16
- package/dist/{DurableObjectState-biHrHwrh.d.mts → DurableObjectState-B3uFY1eM.d.mts} +85 -62
- package/dist/{DurableObjectState-Dux8KfjG.mjs → DurableObjectState-BjkK2kwH.mjs} +3 -3
- package/dist/{ErrorMessage-_lg53p3W.mjs → ErrorMessage-BM0K-Nik.mjs} +1 -4
- package/dist/{Hyperdrive-6p59yyVk.d.mts → Hyperdrive-z-9fFz15.d.mts} +2 -2
- package/dist/HyperdrivePg.d.mts +2 -2
- package/dist/Vitest.d.mts +6 -5
- package/dist/Vitest.mjs +2 -2
- package/dist/{WorkflowBinding-zlRPCXVf.d.mts → WorkflowBinding-wZ-yGHow.d.mts} +5 -10
- package/dist/index.d.mts +82 -60
- package/dist/index.mjs +268 -170
- package/package.json +1 -1
- package/src/AiGateway.ts +62 -7
- package/src/AnalyticsEngine.ts +17 -13
- package/src/Artifacts.ts +111 -47
- package/src/Binding.ts +34 -23
- package/src/BrowserRendering.ts +72 -33
- package/src/CloudflareOtlp.ts +8 -5
- package/src/ComputerArtifacts.ts +17 -9
- package/src/ComputerWorkspace.ts +202 -98
- package/src/ComputerWorkspaceHost.ts +55 -27
- package/src/ContainerNamespace.ts +8 -9
- package/src/D1.ts +8 -14
- package/src/DurableObject.ts +27 -11
- package/src/DurableObjectAlarm.ts +17 -5
- package/src/DurableObjectDefinition.ts +89 -72
- package/src/DurableObjectNamespace.ts +26 -12
- package/src/DurableObjectRpcWebSocket.ts +9 -10
- package/src/DurableObjectState.ts +1 -0
- package/src/DurableObjectStorage.ts +5 -2
- package/src/DurableObjectWebSocket.ts +4 -1
- package/src/Email.ts +26 -25
- package/src/Hyperdrive.ts +4 -10
- package/src/Images.ts +12 -14
- package/src/Kv.ts +15 -17
- package/src/Queue.ts +2 -1
- package/src/QueueBinding.ts +7 -12
- package/src/QueueDefinition.ts +7 -2
- package/src/R2.ts +33 -24
- package/src/Rpc.ts +15 -21
- package/src/RpcDefinition.ts +33 -38
- package/src/ServiceBinding.ts +26 -8
- package/src/Vectorize.ts +45 -18
- package/src/Vitest.ts +9 -3
- package/src/WebTransport.ts +11 -5
- package/src/Worker.ts +91 -21
- package/src/WorkerDefinition.ts +143 -63
- package/src/WorkersAi.ts +50 -28
- package/src/Workflow.ts +66 -13
- package/src/WorkflowBinding.ts +18 -25
- package/src/WorkflowDefinition.ts +4 -2
- package/src/internal/Entrypoint.ts +29 -13
- package/src/internal/ErrorMessage.ts +7 -6
- package/src/internal/RpcInvocation.ts +34 -11
- package/src/internal/Runtime.ts +33 -22
- package/src/internal/WorkerContext.ts +3 -3
package/src/Worker.ts
CHANGED
|
@@ -118,10 +118,6 @@ type WorkerFetchContext<ROut> =
|
|
|
118
118
|
type WorkerRpcContext<ROut> = WorkerBaseContext<ROut> | Scope.Scope;
|
|
119
119
|
|
|
120
120
|
type RuntimeContext<ROut> = WorkerBaseContext<ROut>;
|
|
121
|
-
type RunOptions = {
|
|
122
|
-
readonly eventLayer?: boolean;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
121
|
const RunSymbol = Symbol.for("effect-cf/Worker/run");
|
|
126
122
|
const FetchSymbol = Symbol.for("effect-cf/Worker/fetch");
|
|
127
123
|
|
|
@@ -151,7 +147,7 @@ export type WorkerRpcHandler<ROut, A = unknown> = Effect.Effect<A, unknown, Work
|
|
|
151
147
|
*/
|
|
152
148
|
export type WorkerRpc<ROut> = Record<string, (...args: Array<any>) => WorkerRpcHandler<ROut>>;
|
|
153
149
|
|
|
154
|
-
export type
|
|
150
|
+
export type WorkerRpcContract<Rpc extends WorkerRpc<ROut>, ROut> = {
|
|
155
151
|
readonly [Key in keyof Rpc]: Rpc[Key] extends (
|
|
156
152
|
...args: infer Args
|
|
157
153
|
) => Effect.Effect<infer A, unknown, WorkerRpcContext<ROut>>
|
|
@@ -167,7 +163,7 @@ export type RpcHandlers<ROut, Api> = {
|
|
|
167
163
|
? never
|
|
168
164
|
: [Api[Key]] extends [never]
|
|
169
165
|
? never
|
|
170
|
-
: Api[Key] extends (...args: Array<any>) => Promise<
|
|
166
|
+
: Api[Key] extends (...args: Array<any>) => Promise<any>
|
|
171
167
|
? Key
|
|
172
168
|
: never
|
|
173
169
|
: never]: Api[Key] extends (...args: infer Args) => Promise<infer A>
|
|
@@ -209,6 +205,15 @@ export interface WorkerOptions<
|
|
|
209
205
|
readonly rpc?: Rpc;
|
|
210
206
|
}
|
|
211
207
|
|
|
208
|
+
type WorkerOptionsWithEventLayer<
|
|
209
|
+
RRuntime,
|
|
210
|
+
REvent,
|
|
211
|
+
EventLayerError,
|
|
212
|
+
Rpc extends WorkerRpc<RRuntime | REvent> = Record<never, never>,
|
|
213
|
+
> = Omit<WorkerOptions<RRuntime, REvent, EventLayerError, Rpc>, "eventLayer"> & {
|
|
214
|
+
readonly eventLayer: Layer.Layer<REvent, EventLayerError, WorkerBaseContext<RRuntime>>;
|
|
215
|
+
};
|
|
216
|
+
|
|
212
217
|
export type FetchWorkerOptions<RRuntime, REvent = never, EventLayerError = never> = Omit<
|
|
213
218
|
WorkerOptions<RRuntime, REvent, EventLayerError, Record<never, never>>,
|
|
214
219
|
"rpc"
|
|
@@ -216,6 +221,13 @@ export type FetchWorkerOptions<RRuntime, REvent = never, EventLayerError = never
|
|
|
216
221
|
readonly rpc?: never;
|
|
217
222
|
};
|
|
218
223
|
|
|
224
|
+
type FetchWorkerOptionsWithEventLayer<RRuntime, REvent, EventLayerError> = Omit<
|
|
225
|
+
FetchWorkerOptions<RRuntime, REvent, EventLayerError>,
|
|
226
|
+
"eventLayer"
|
|
227
|
+
> & {
|
|
228
|
+
readonly eventLayer: Layer.Layer<REvent, EventLayerError, WorkerBaseContext<RRuntime>>;
|
|
229
|
+
};
|
|
230
|
+
|
|
219
231
|
/**
|
|
220
232
|
* Cloudflare `WorkerEntrypoint` constructor produced by {@link make}.
|
|
221
233
|
*/
|
|
@@ -225,7 +237,8 @@ export type WorkerClass<Rpc extends WorkerRpc<ROut>, ROut> = new (
|
|
|
225
237
|
) => CloudflareWorkerEntrypoint<WorkerEnv> & {
|
|
226
238
|
fetch(request: Request): Promise<Response>;
|
|
227
239
|
queue(batch: globalThis.MessageBatch): Promise<void>;
|
|
228
|
-
|
|
240
|
+
[FetchSymbol](request: Request, requestContext: globalThis.ExecutionContext): Promise<Response>;
|
|
241
|
+
} & WorkerRpcContract<Rpc, ROut>;
|
|
229
242
|
|
|
230
243
|
/**
|
|
231
244
|
* `ExportedHandler`-compatible fetch object produced by {@link makeFetchHandler}.
|
|
@@ -316,7 +329,17 @@ export function make<ROut, LayerError>(
|
|
|
316
329
|
export function make<
|
|
317
330
|
ROut,
|
|
318
331
|
LayerError,
|
|
319
|
-
REvent
|
|
332
|
+
REvent,
|
|
333
|
+
EventLayerError = never,
|
|
334
|
+
const Rpc extends WorkerRpc<ROut | REvent> = Record<never, never>,
|
|
335
|
+
>(
|
|
336
|
+
layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>,
|
|
337
|
+
options: WorkerOptionsWithEventLayer<ROut, REvent, EventLayerError, Rpc>,
|
|
338
|
+
): WorkerClass<Rpc, ROut | REvent>;
|
|
339
|
+
export function make<
|
|
340
|
+
ROut,
|
|
341
|
+
LayerError,
|
|
342
|
+
REvent extends never = never,
|
|
320
343
|
EventLayerError = never,
|
|
321
344
|
const Rpc extends WorkerRpc<ROut | REvent> = Record<never, never>,
|
|
322
345
|
>(
|
|
@@ -333,9 +356,9 @@ export function make<
|
|
|
333
356
|
layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>,
|
|
334
357
|
optionsOrFetch: WorkerOptions<ROut, REvent, EventLayerError, Rpc> | WorkerHandler<ROut>,
|
|
335
358
|
): WorkerClass<Rpc, ROut | REvent> {
|
|
336
|
-
const options = isWorkerOptions(optionsOrFetch)
|
|
359
|
+
const options: WorkerOptions<ROut, REvent, EventLayerError, Rpc> = isWorkerOptions(optionsOrFetch)
|
|
337
360
|
? optionsOrFetch
|
|
338
|
-
:
|
|
361
|
+
: { fetch: optionsOrFetch };
|
|
339
362
|
|
|
340
363
|
class EffectWorker extends CloudflareWorkerEntrypoint<WorkerEnv> {
|
|
341
364
|
readonly runtime: ManagedRuntime.ManagedRuntime<RuntimeContext<ROut>, LayerError>;
|
|
@@ -359,13 +382,25 @@ export function make<
|
|
|
359
382
|
|
|
360
383
|
[RunSymbol]<A, E>(
|
|
361
384
|
effect: Effect.Effect<A, E, RuntimeContext<ROut> | REvent | Scope.Scope>,
|
|
362
|
-
runOptions: RunOptions = {},
|
|
363
385
|
): Promise<A> {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
386
|
+
const eventLayer = options.eventLayer;
|
|
387
|
+
|
|
388
|
+
if (eventLayer === undefined) {
|
|
389
|
+
// SAFETY: the public make overloads permit an absent event layer only when REvent is never.
|
|
390
|
+
return Runtime.runEventPromise(
|
|
391
|
+
this.runtime,
|
|
392
|
+
effect as Effect.Effect<A, E, RuntimeContext<ROut> | Scope.Scope>,
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return Runtime.runEventPromise<
|
|
397
|
+
A,
|
|
398
|
+
E,
|
|
399
|
+
RuntimeContext<ROut>,
|
|
400
|
+
REvent,
|
|
401
|
+
EventLayerError,
|
|
402
|
+
LayerError
|
|
403
|
+
>(this.runtime, effect, eventLayer);
|
|
369
404
|
}
|
|
370
405
|
|
|
371
406
|
fetch(request: Request): Promise<Response> {
|
|
@@ -390,6 +425,7 @@ export function make<
|
|
|
390
425
|
Layer.succeed(WorkerContext, fromExecutionContext(ctx)),
|
|
391
426
|
);
|
|
392
427
|
|
|
428
|
+
// SAFETY: requestServices provides the HTTP/request contexts introduced by renderFetchSuccess.
|
|
393
429
|
return this[RunSymbol](
|
|
394
430
|
renderFetchSuccess(fetchHandler).pipe(
|
|
395
431
|
Effect.tap(() => scheduleTelemetryFlush),
|
|
@@ -438,7 +474,27 @@ interface FetchCapableInstance {
|
|
|
438
474
|
* isolate is evicted; Cloudflare provides no shutdown hook. Use `eventLayer`
|
|
439
475
|
* for resources that must be finalized per event.
|
|
440
476
|
*/
|
|
441
|
-
export
|
|
477
|
+
export function makeFetchHandler<
|
|
478
|
+
ROut,
|
|
479
|
+
LayerError,
|
|
480
|
+
REvent,
|
|
481
|
+
EventLayerError = never,
|
|
482
|
+
Env extends WorkerEnv = WorkerEnv,
|
|
483
|
+
>(
|
|
484
|
+
layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>,
|
|
485
|
+
options: FetchWorkerOptionsWithEventLayer<ROut, REvent, EventLayerError>,
|
|
486
|
+
): FetchHandler<Env>;
|
|
487
|
+
export function makeFetchHandler<
|
|
488
|
+
ROut,
|
|
489
|
+
LayerError,
|
|
490
|
+
REvent extends never = never,
|
|
491
|
+
EventLayerError = never,
|
|
492
|
+
Env extends WorkerEnv = WorkerEnv,
|
|
493
|
+
>(
|
|
494
|
+
layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>,
|
|
495
|
+
options: FetchWorkerOptions<ROut, REvent, EventLayerError>,
|
|
496
|
+
): FetchHandler<Env>;
|
|
497
|
+
export function makeFetchHandler<
|
|
442
498
|
ROut,
|
|
443
499
|
LayerError,
|
|
444
500
|
REvent = never,
|
|
@@ -447,8 +503,19 @@ export const makeFetchHandler = <
|
|
|
447
503
|
>(
|
|
448
504
|
layer: Layer.Layer<ROut, LayerError, ExecutionContext | WorkerContext | WorkerEnvironment>,
|
|
449
505
|
options: FetchWorkerOptions<ROut, REvent, EventLayerError>,
|
|
450
|
-
): FetchHandler<Env>
|
|
451
|
-
const WorkerClass =
|
|
506
|
+
): FetchHandler<Env> {
|
|
507
|
+
const WorkerClass =
|
|
508
|
+
options.eventLayer === undefined
|
|
509
|
+
? make(
|
|
510
|
+
layer,
|
|
511
|
+
// SAFETY: the no-event public overload is the only one that permits an absent eventLayer.
|
|
512
|
+
options as FetchWorkerOptions<ROut, never, EventLayerError>,
|
|
513
|
+
)
|
|
514
|
+
: make(
|
|
515
|
+
layer,
|
|
516
|
+
// SAFETY: this branch has the eventLayer required by the event-dependent public overload.
|
|
517
|
+
options as FetchWorkerOptionsWithEventLayer<ROut, REvent, EventLayerError>,
|
|
518
|
+
);
|
|
452
519
|
const instances = new WeakMap<WorkerEnv, FetchCapableInstance>();
|
|
453
520
|
|
|
454
521
|
return {
|
|
@@ -456,14 +523,14 @@ export const makeFetchHandler = <
|
|
|
456
523
|
let instance = instances.get(env);
|
|
457
524
|
|
|
458
525
|
if (instance === undefined) {
|
|
459
|
-
instance = new WorkerClass(ctx, env)
|
|
526
|
+
instance = new WorkerClass(ctx, env);
|
|
460
527
|
instances.set(env, instance);
|
|
461
528
|
}
|
|
462
529
|
|
|
463
530
|
return instance[FetchSymbol](request, ctx);
|
|
464
531
|
},
|
|
465
532
|
};
|
|
466
|
-
}
|
|
533
|
+
}
|
|
467
534
|
|
|
468
535
|
export type {
|
|
469
536
|
Api,
|
|
@@ -481,3 +548,6 @@ export type {
|
|
|
481
548
|
} from "./WorkerDefinition";
|
|
482
549
|
|
|
483
550
|
export { implement, method, Tag } from "./WorkerDefinition";
|
|
551
|
+
|
|
552
|
+
/** @deprecated Use {@link WorkerRpcContract}. */
|
|
553
|
+
export { type WorkerRpcContract as "WorkerRpcShape" };
|
package/src/WorkerDefinition.ts
CHANGED
|
@@ -48,7 +48,7 @@ export namespace Method {
|
|
|
48
48
|
|
|
49
49
|
export type Success<Self extends Any> = S.Schema.Type<Self["success"]>;
|
|
50
50
|
|
|
51
|
-
export type EncodedSuccess<
|
|
51
|
+
export type EncodedSuccess<_Self extends Any> = S.Json;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
export type Methods = Record<string, Method.Any>;
|
|
@@ -59,9 +59,12 @@ export type Methods = Record<string, Method.Any>;
|
|
|
59
59
|
* Create with {@link make} and reuse to type both worker implementations and
|
|
60
60
|
* service bindings in other workers.
|
|
61
61
|
*/
|
|
62
|
-
export interface Definition<
|
|
62
|
+
export interface Definition<
|
|
63
|
+
Id extends string = string,
|
|
64
|
+
MethodDefinitions extends Methods = Methods,
|
|
65
|
+
> {
|
|
63
66
|
readonly id: Id;
|
|
64
|
-
readonly methods:
|
|
67
|
+
readonly methods: MethodDefinitions;
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
export namespace Definition {
|
|
@@ -70,8 +73,8 @@ export namespace Definition {
|
|
|
70
73
|
|
|
71
74
|
export type ReservedMethodName = WorkerEntrypoint.ReservedMethodName;
|
|
72
75
|
|
|
73
|
-
export type NoReservedMethods<
|
|
74
|
-
Extract<keyof
|
|
76
|
+
export type NoReservedMethods<MethodDefinitions extends Methods> =
|
|
77
|
+
Extract<keyof MethodDefinitions, ReservedMethodName> extends never ? MethodDefinitions : never;
|
|
75
78
|
|
|
76
79
|
const reservedMethodNames = new Set<string>([
|
|
77
80
|
"constructor",
|
|
@@ -116,51 +119,89 @@ type BoundaryHandlers<ROut, Self extends Definition.Any> = {
|
|
|
116
119
|
) => WorkerRpcHandler<ROut, Method.EncodedSuccess<Self["methods"][Key]>>;
|
|
117
120
|
};
|
|
118
121
|
|
|
122
|
+
type MutableBoundaryHandlers<ROut, Self extends Definition.Any> = {
|
|
123
|
+
-readonly [Key in keyof Self["methods"]]: (
|
|
124
|
+
...args: Array<unknown>
|
|
125
|
+
) => WorkerRpcHandler<ROut, Method.EncodedSuccess<Self["methods"][Key]>>;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
type BaseOptions<ROut, Self extends Definition.Any, REvent, EventLayerError> = Omit<
|
|
129
|
+
WorkerEntrypoint.WorkerOptions<ROut, REvent, EventLayerError, Handlers<ROut | REvent, Self>>,
|
|
130
|
+
"eventLayer" | "rpc"
|
|
131
|
+
> & {
|
|
132
|
+
readonly rpc: Handlers<ROut | REvent, Self>;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type EventLayerOptions<ROut, REvent, EventLayerError> = [REvent] extends [never]
|
|
136
|
+
? Pick<WorkerEntrypoint.WorkerOptions<ROut, never, EventLayerError>, "eventLayer">
|
|
137
|
+
: {
|
|
138
|
+
readonly eventLayer: NonNullable<
|
|
139
|
+
WorkerEntrypoint.WorkerOptions<ROut, REvent, EventLayerError>["eventLayer"]
|
|
140
|
+
>;
|
|
141
|
+
};
|
|
142
|
+
|
|
119
143
|
/**
|
|
120
144
|
* Worker constructor options for a specific RPC definition.
|
|
121
145
|
*/
|
|
122
|
-
export
|
|
146
|
+
export type Options<
|
|
123
147
|
ROut,
|
|
124
148
|
Self extends Definition.Any,
|
|
125
149
|
REvent = never,
|
|
126
150
|
EventLayerError = never,
|
|
127
|
-
>
|
|
128
|
-
|
|
129
|
-
"rpc"
|
|
130
|
-
> {
|
|
131
|
-
readonly rpc: Handlers<ROut | REvent, Self>;
|
|
132
|
-
}
|
|
151
|
+
> = BaseOptions<ROut, Self, REvent, EventLayerError> &
|
|
152
|
+
EventLayerOptions<ROut, REvent, EventLayerError>;
|
|
133
153
|
|
|
134
154
|
export type LayerOptions = {
|
|
135
155
|
readonly binding: string;
|
|
136
156
|
};
|
|
137
157
|
|
|
138
|
-
export type TagClass<
|
|
158
|
+
export type TagClass<
|
|
159
|
+
Self,
|
|
160
|
+
Id extends string,
|
|
161
|
+
MethodDefinitions extends Methods,
|
|
162
|
+
> = Context.ServiceClass<
|
|
139
163
|
Self,
|
|
140
164
|
Id,
|
|
141
165
|
ServiceBinding.ServiceBindingEffectClient<
|
|
142
|
-
Api<Definition<Id,
|
|
143
|
-
Definition<Id,
|
|
166
|
+
Api<Definition<Id, MethodDefinitions>>,
|
|
167
|
+
Definition<Id, MethodDefinitions>
|
|
144
168
|
>
|
|
145
169
|
> &
|
|
146
170
|
ServiceBinding.ServiceBindingStaticClient<
|
|
147
171
|
Self,
|
|
148
|
-
Api<Definition<Id,
|
|
149
|
-
Definition<Id,
|
|
172
|
+
Api<Definition<Id, MethodDefinitions>>,
|
|
173
|
+
Definition<Id, MethodDefinitions>
|
|
150
174
|
> & {
|
|
151
175
|
readonly id: Id;
|
|
152
|
-
readonly methods:
|
|
153
|
-
readonly make:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
176
|
+
readonly methods: MethodDefinitions;
|
|
177
|
+
readonly make: {
|
|
178
|
+
<ROut, LayerError, REvent, EventLayerError = never>(
|
|
179
|
+
layer: Layer.Layer<
|
|
180
|
+
ROut,
|
|
181
|
+
LayerError,
|
|
182
|
+
WorkerEntrypoint.ExecutionContext | WorkerEntrypoint.WorkerContext | WorkerEnvironment
|
|
183
|
+
>,
|
|
184
|
+
options: Options<ROut, Definition<Id, MethodDefinitions>, REvent, EventLayerError> & {
|
|
185
|
+
readonly eventLayer: NonNullable<
|
|
186
|
+
WorkerEntrypoint.WorkerOptions<ROut, REvent, EventLayerError>["eventLayer"]
|
|
187
|
+
>;
|
|
188
|
+
},
|
|
189
|
+
): WorkerEntrypoint.WorkerClass<
|
|
190
|
+
Handlers<ROut | REvent, Definition<Id, MethodDefinitions>>,
|
|
191
|
+
ROut | REvent
|
|
192
|
+
>;
|
|
193
|
+
<ROut, LayerError, REvent extends never = never, EventLayerError = never>(
|
|
194
|
+
layer: Layer.Layer<
|
|
195
|
+
ROut,
|
|
196
|
+
LayerError,
|
|
197
|
+
WorkerEntrypoint.ExecutionContext | WorkerEntrypoint.WorkerContext | WorkerEnvironment
|
|
198
|
+
>,
|
|
199
|
+
options: Options<ROut, Definition<Id, MethodDefinitions>, REvent, EventLayerError>,
|
|
200
|
+
): WorkerEntrypoint.WorkerClass<
|
|
201
|
+
Handlers<ROut | REvent, Definition<Id, MethodDefinitions>>,
|
|
202
|
+
ROut | REvent
|
|
203
|
+
>;
|
|
204
|
+
};
|
|
164
205
|
readonly layer: (
|
|
165
206
|
options: LayerOptions,
|
|
166
207
|
) => Layer.Layer<
|
|
@@ -170,10 +211,19 @@ export type TagClass<Self, Id extends string, MethodsShape extends Methods> = Co
|
|
|
170
211
|
>;
|
|
171
212
|
};
|
|
172
213
|
|
|
214
|
+
type TagClassValue = S.Schema.Type<typeof S.Unknown>;
|
|
215
|
+
|
|
216
|
+
const assumeTagClass = <Self, Id extends string, MethodDefinitions extends Methods>(
|
|
217
|
+
value: TagClassValue,
|
|
218
|
+
): TagClass<Self, Id, MethodDefinitions> => {
|
|
219
|
+
// SAFETY: callers supply a Context service tag with every definition-derived static member attached.
|
|
220
|
+
return value as TagClass<Self, Id, MethodDefinitions>;
|
|
221
|
+
};
|
|
222
|
+
|
|
173
223
|
/**
|
|
174
224
|
* Defines a single RPC method schema in a worker definition.
|
|
175
225
|
*/
|
|
176
|
-
export const method
|
|
226
|
+
export const method: {
|
|
177
227
|
<Success extends ServiceFreeSchema>(definition: {
|
|
178
228
|
readonly success: Success;
|
|
179
229
|
}): Method<readonly [], Success>;
|
|
@@ -184,7 +234,7 @@ export const method = RpcDefinition.method as {
|
|
|
184
234
|
readonly args: Args;
|
|
185
235
|
readonly success: Success;
|
|
186
236
|
}): Method<Args, Success>;
|
|
187
|
-
};
|
|
237
|
+
} = RpcDefinition.method;
|
|
188
238
|
|
|
189
239
|
/**
|
|
190
240
|
* Creates a typed worker RPC definition plus helpers for implementation and bindings.
|
|
@@ -199,11 +249,11 @@ export const method = RpcDefinition.method as {
|
|
|
199
249
|
* });
|
|
200
250
|
* ```
|
|
201
251
|
*/
|
|
202
|
-
const makeDefinition = <Id extends string, const
|
|
252
|
+
const makeDefinition = <Id extends string, const MethodDefinitions extends Methods>(
|
|
203
253
|
id: Id,
|
|
204
|
-
methods:
|
|
254
|
+
methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>,
|
|
205
255
|
) => {
|
|
206
|
-
type SelfDefinition = Definition<Id,
|
|
256
|
+
type SelfDefinition = Definition<Id, MethodDefinitions>;
|
|
207
257
|
RpcDefinition.assertNoReservedMethods("Worker", methods, reservedMethodNames);
|
|
208
258
|
const definition: SelfDefinition = RpcDefinition.make(id, methods);
|
|
209
259
|
|
|
@@ -215,32 +265,55 @@ const makeDefinition = <Id extends string, const MethodsShape extends Methods>(
|
|
|
215
265
|
WorkerEntrypoint.ExecutionContext | WorkerEntrypoint.WorkerContext | WorkerEnvironment
|
|
216
266
|
>,
|
|
217
267
|
options: Options<ROut, SelfDefinition, REvent, EventLayerError>,
|
|
218
|
-
) =>
|
|
219
|
-
|
|
268
|
+
) => {
|
|
269
|
+
type WrappedRpc = BoundaryHandlers<ROut | REvent, SelfDefinition>;
|
|
270
|
+
type WrappedOptions = WorkerEntrypoint.WorkerOptions<
|
|
271
|
+
ROut,
|
|
272
|
+
REvent,
|
|
273
|
+
EventLayerError,
|
|
274
|
+
WrappedRpc
|
|
275
|
+
>;
|
|
276
|
+
type WrappedOptionsWithEventLayer = Omit<WrappedOptions, "eventLayer"> & {
|
|
277
|
+
readonly eventLayer: NonNullable<WrappedOptions["eventLayer"]>;
|
|
278
|
+
};
|
|
279
|
+
const workerOptions = {
|
|
220
280
|
...options,
|
|
221
281
|
rpc: wrapHandlers(definition, options.rpc),
|
|
222
|
-
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
if (workerOptions.eventLayer === undefined) {
|
|
285
|
+
// SAFETY: Options permits an absent eventLayer only when REvent is never.
|
|
286
|
+
return WorkerEntrypoint.make(
|
|
287
|
+
layer,
|
|
288
|
+
workerOptions as WorkerEntrypoint.WorkerOptions<
|
|
289
|
+
ROut,
|
|
290
|
+
never,
|
|
291
|
+
EventLayerError,
|
|
292
|
+
BoundaryHandlers<ROut, SelfDefinition>
|
|
293
|
+
>,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// SAFETY: this branch has the eventLayer required by WorkerEntrypoint.make's event overload.
|
|
298
|
+
return WorkerEntrypoint.make(layer, workerOptions as WrappedOptionsWithEventLayer);
|
|
299
|
+
},
|
|
223
300
|
});
|
|
224
301
|
};
|
|
225
302
|
|
|
226
|
-
export const make = <Id extends string, const
|
|
303
|
+
export const make = <Id extends string, const MethodDefinitions extends Methods>(
|
|
227
304
|
id: Id,
|
|
228
|
-
methods:
|
|
229
|
-
) =>
|
|
230
|
-
Tag<Definition<Id, MethodsShape>>()<Id, MethodsShape>(
|
|
231
|
-
id,
|
|
232
|
-
methods as MethodsShape & NoReservedMethods<MethodsShape>,
|
|
233
|
-
);
|
|
305
|
+
methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>,
|
|
306
|
+
) => Tag<Definition<Id, MethodDefinitions>>()<Id, MethodDefinitions>(id, methods);
|
|
234
307
|
|
|
235
308
|
export const Tag =
|
|
236
309
|
<Self>() =>
|
|
237
|
-
<Id extends string, const
|
|
310
|
+
<Id extends string, const MethodDefinitions extends Methods>(
|
|
238
311
|
id: Id,
|
|
239
|
-
methods:
|
|
312
|
+
methods: MethodDefinitions & NoReservedMethods<MethodDefinitions>,
|
|
240
313
|
) => {
|
|
241
|
-
const definition = makeDefinition<Id,
|
|
314
|
+
const definition = makeDefinition<Id, MethodDefinitions>(id, methods);
|
|
242
315
|
|
|
243
|
-
type SelfDefinition = Definition<Id,
|
|
316
|
+
type SelfDefinition = Definition<Id, MethodDefinitions>;
|
|
244
317
|
type ClientApi = Api<SelfDefinition>;
|
|
245
318
|
const tag = Context.Service<
|
|
246
319
|
Self,
|
|
@@ -264,11 +337,12 @@ export const Tag =
|
|
|
264
337
|
|
|
265
338
|
const rpc = <Method extends keyof ClientApi>(
|
|
266
339
|
method: Method,
|
|
267
|
-
...args: ClientApi[Method] extends (...args: infer Args) =>
|
|
340
|
+
...args: ClientApi[Method] extends (...args: infer Args) => any ? Args : never
|
|
268
341
|
) =>
|
|
269
342
|
Effect.gen(function* () {
|
|
270
343
|
const service = yield* tag;
|
|
271
344
|
|
|
345
|
+
// SAFETY: the public signature above restores the selected ClientApi tuple and result types.
|
|
272
346
|
return yield* (service.rpc as UnsafeInvoke<ServiceBinding.ServiceBindingRpcError>)(
|
|
273
347
|
method,
|
|
274
348
|
...args,
|
|
@@ -277,11 +351,12 @@ export const Tag =
|
|
|
277
351
|
|
|
278
352
|
const call = <Method extends keyof ClientApi>(
|
|
279
353
|
method: Method,
|
|
280
|
-
...args: ClientApi[Method] extends (...args: infer Args) =>
|
|
354
|
+
...args: ClientApi[Method] extends (...args: infer Args) => any ? Args : never
|
|
281
355
|
) =>
|
|
282
356
|
Effect.gen(function* () {
|
|
283
357
|
const service = yield* tag;
|
|
284
358
|
|
|
359
|
+
// SAFETY: the public signature above restores the selected ClientApi tuple and result types.
|
|
285
360
|
return yield* (service.call as UnsafeInvoke<ServiceBinding.ServiceBindingRpcError>)(
|
|
286
361
|
method,
|
|
287
362
|
...args,
|
|
@@ -290,11 +365,12 @@ export const Tag =
|
|
|
290
365
|
|
|
291
366
|
const scopedCall = <Method extends keyof ClientApi>(
|
|
292
367
|
method: Method,
|
|
293
|
-
...args: ClientApi[Method] extends (...args: infer Args) =>
|
|
368
|
+
...args: ClientApi[Method] extends (...args: infer Args) => any ? Args : never
|
|
294
369
|
) =>
|
|
295
370
|
Effect.gen(function* () {
|
|
296
371
|
const service = yield* tag;
|
|
297
372
|
|
|
373
|
+
// SAFETY: the public signature above restores the selected ClientApi tuple and result types.
|
|
298
374
|
return yield* (service.scopedCall as UnsafeInvoke<ServiceBinding.ServiceBindingRpcError>)(
|
|
299
375
|
method,
|
|
300
376
|
...args,
|
|
@@ -303,19 +379,22 @@ export const Tag =
|
|
|
303
379
|
|
|
304
380
|
const directMethods = ServiceBinding.makeDirectMethods<Self, ClientApi, SelfDefinition>(
|
|
305
381
|
definition,
|
|
382
|
+
// SAFETY: call's public generic signature is derived from this same ClientApi definition.
|
|
306
383
|
call as never,
|
|
307
384
|
);
|
|
308
385
|
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
386
|
+
return assumeTagClass<Self, Id, MethodDefinitions>(
|
|
387
|
+
Object.assign(tag, directMethods, {
|
|
388
|
+
id: definition.id,
|
|
389
|
+
methods: definition.methods,
|
|
390
|
+
make: definition.make,
|
|
391
|
+
layer,
|
|
392
|
+
fetch,
|
|
393
|
+
rpc,
|
|
394
|
+
call,
|
|
395
|
+
scopedCall,
|
|
396
|
+
}),
|
|
397
|
+
);
|
|
319
398
|
};
|
|
320
399
|
|
|
321
400
|
export const Worker = Tag;
|
|
@@ -324,8 +403,9 @@ const wrapHandlers = <ROut, const Self extends Definition.Any>(
|
|
|
324
403
|
definition: Self,
|
|
325
404
|
handlers: Handlers<ROut, Self>,
|
|
326
405
|
): BoundaryHandlers<ROut, Self> => {
|
|
327
|
-
const wrapped
|
|
406
|
+
const wrapped: MutableBoundaryHandlers<ROut, Self> = Object.create(null);
|
|
328
407
|
|
|
408
|
+
// SAFETY: definition.methods is the owner of the method-name union used to index both mappings.
|
|
329
409
|
for (const key of Object.keys(definition.methods) as Array<
|
|
330
410
|
RpcDefinition.Definition.MethodNames<Self>
|
|
331
411
|
>) {
|
|
@@ -340,7 +420,7 @@ const wrapHandlers = <ROut, const Self extends Definition.Any>(
|
|
|
340
420
|
});
|
|
341
421
|
}
|
|
342
422
|
|
|
343
|
-
return wrapped
|
|
423
|
+
return wrapped;
|
|
344
424
|
};
|
|
345
425
|
|
|
346
426
|
/**
|