effect-orpc 0.2.1 → 0.3.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/README.md +198 -77
- package/dist/{chunk-VOWRLWZZ.js → chunk-IJP6L2XR.js} +6 -2
- package/dist/chunk-IJP6L2XR.js.map +1 -0
- package/dist/index.js +736 -266
- package/dist/index.js.map +1 -1
- package/dist/node.js +4 -3
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/src/contract.ts +34 -2
- package/src/effect-builder.ts +452 -18
- package/src/effect-procedure.ts +247 -9
- package/src/effect-runtime.ts +453 -21
- package/src/extension/create-node-proxy.ts +17 -1
- package/src/extension/state.ts +13 -15
- package/src/fiber-context-bridge.ts +13 -0
- package/src/node.ts +2 -1
- package/src/runtime-source.ts +18 -0
- package/src/tagged-error.ts +0 -9
- package/src/tests/contract.test.ts +24 -0
- package/src/tests/effect-builder.test.ts +506 -3
- package/src/tests/node-side-effect.test.ts +80 -0
- package/src/tests/parity.effect-builder.test.ts +10 -3
- package/src/tests/parity.effect-procedure.test.ts +24 -8
- package/src/tests/shared.ts +1 -25
- package/src/types/effect-builder-surface.ts +116 -0
- package/src/types/effect-procedure-surface.ts +98 -1
- package/src/types/index.ts +292 -1
- package/src/types/variants.ts +346 -13
- package/dist/chunk-VOWRLWZZ.js.map +0 -1
package/src/effect-builder.ts
CHANGED
|
@@ -7,11 +7,15 @@ import type {
|
|
|
7
7
|
} from "@orpc/contract";
|
|
8
8
|
import type { Context, Router } from "@orpc/server";
|
|
9
9
|
import { Builder, fallbackConfig, lazy } from "@orpc/server";
|
|
10
|
-
import
|
|
10
|
+
import { Layer, ManagedRuntime } from "effect";
|
|
11
11
|
|
|
12
12
|
import { enhanceEffectRouter } from "./effect-enhance-router";
|
|
13
13
|
import { EffectDecoratedProcedure } from "./effect-procedure";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
createEffectPipelineMiddleware,
|
|
16
|
+
createEffectProcedureHandler,
|
|
17
|
+
isEffectMiddleware,
|
|
18
|
+
} from "./effect-runtime";
|
|
15
19
|
import {
|
|
16
20
|
createNodeProxy,
|
|
17
21
|
unhandled,
|
|
@@ -23,6 +27,8 @@ import {
|
|
|
23
27
|
unwrapEffectUpstream,
|
|
24
28
|
type EffectProxyTarget,
|
|
25
29
|
} from "./extension/state";
|
|
30
|
+
import type { EffectRuntimeSource } from "./runtime-source";
|
|
31
|
+
import { toManagedRuntime } from "./runtime-source";
|
|
26
32
|
import type { EffectErrorMap, MergedEffectErrorMap } from "./tagged-error";
|
|
27
33
|
import { effectErrorMapToErrorMap } from "./tagged-error";
|
|
28
34
|
import type {
|
|
@@ -43,6 +49,9 @@ const builderVirtualDescriptors = {
|
|
|
43
49
|
errors: { enumerable: false },
|
|
44
50
|
handler: { enumerable: false },
|
|
45
51
|
lazy: { enumerable: false },
|
|
52
|
+
middleware: { enumerable: false },
|
|
53
|
+
provide: { enumerable: false },
|
|
54
|
+
provideOptional: { enumerable: false },
|
|
46
55
|
router: { enumerable: false },
|
|
47
56
|
traced: { enumerable: false },
|
|
48
57
|
} as const;
|
|
@@ -51,6 +60,9 @@ const builderVirtualKeys = [
|
|
|
51
60
|
"~effect",
|
|
52
61
|
"errors",
|
|
53
62
|
"effect",
|
|
63
|
+
"middleware",
|
|
64
|
+
"provide",
|
|
65
|
+
"provideOptional",
|
|
54
66
|
"traced",
|
|
55
67
|
"handler",
|
|
56
68
|
"router",
|
|
@@ -96,6 +108,8 @@ function getEffectBuilderDef(
|
|
|
96
108
|
effectErrorMap: context.state.effectErrorMap,
|
|
97
109
|
runtime: context.state.runtime,
|
|
98
110
|
spanConfig: context.state.spanConfig,
|
|
111
|
+
effectSteps: context.state.effectSteps,
|
|
112
|
+
effectHandler: context.state.effectHandler,
|
|
99
113
|
};
|
|
100
114
|
}
|
|
101
115
|
|
|
@@ -109,11 +123,55 @@ function wrapBuilderLike(
|
|
|
109
123
|
effectErrorMap: state.effectErrorMap,
|
|
110
124
|
runtime: state.runtime,
|
|
111
125
|
spanConfig: state.spanConfig,
|
|
126
|
+
effectSteps: state.effectSteps,
|
|
127
|
+
effectHandler: state.effectHandler,
|
|
112
128
|
},
|
|
113
129
|
unwrapEffectUpstream(builder),
|
|
114
130
|
);
|
|
115
131
|
}
|
|
116
132
|
|
|
133
|
+
function appendEffectStep(
|
|
134
|
+
state: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>["state"],
|
|
135
|
+
step: NonNullable<
|
|
136
|
+
NodeProxyContext<
|
|
137
|
+
EffectBuilderTarget,
|
|
138
|
+
AnyBuilderLike
|
|
139
|
+
>["state"]["effectSteps"]
|
|
140
|
+
>[number],
|
|
141
|
+
): NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>["state"] {
|
|
142
|
+
return {
|
|
143
|
+
...state,
|
|
144
|
+
effectSteps: [...(state.effectSteps ?? []), step],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function flushEffectSteps(
|
|
149
|
+
builder: AnyBuilderLike,
|
|
150
|
+
state: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>["state"],
|
|
151
|
+
): {
|
|
152
|
+
builder: AnyBuilderLike;
|
|
153
|
+
state: NodeProxyContext<EffectBuilderTarget, AnyBuilderLike>["state"];
|
|
154
|
+
} {
|
|
155
|
+
if (!state.effectSteps?.length) {
|
|
156
|
+
return { builder, state };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const middleware = createEffectPipelineMiddleware({
|
|
160
|
+
effectErrorMap: state.effectErrorMap,
|
|
161
|
+
runtime: state.runtime,
|
|
162
|
+
steps: state.effectSteps,
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
builder: Reflect.apply(Reflect.get(builder, "use", builder), builder, [
|
|
166
|
+
middleware,
|
|
167
|
+
]) as AnyBuilderLike,
|
|
168
|
+
state: {
|
|
169
|
+
...state,
|
|
170
|
+
effectSteps: undefined,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
117
175
|
function createEffectBuilderProxy(
|
|
118
176
|
target: EffectBuilderTarget,
|
|
119
177
|
): EffectBuilderTarget {
|
|
@@ -166,13 +224,20 @@ function createEffectBuilderProxy(
|
|
|
166
224
|
>[0],
|
|
167
225
|
) => {
|
|
168
226
|
const defaultCaptureStackTrace = addSpanStackTrace();
|
|
227
|
+
const effectHandler = {
|
|
228
|
+
defaultCaptureStackTrace,
|
|
229
|
+
effectFn,
|
|
230
|
+
spanConfig: state.spanConfig,
|
|
231
|
+
};
|
|
169
232
|
return new EffectDecoratedProcedure({
|
|
170
233
|
...effectDef,
|
|
234
|
+
effectHandler,
|
|
171
235
|
handler: async (opts) => {
|
|
172
236
|
return createEffectProcedureHandler({
|
|
173
237
|
defaultCaptureStackTrace,
|
|
174
238
|
effectErrorMap: state.effectErrorMap,
|
|
175
239
|
effectFn,
|
|
240
|
+
effectSteps: state.effectSteps,
|
|
176
241
|
runtime: state.runtime,
|
|
177
242
|
spanConfig: state.spanConfig,
|
|
178
243
|
})(opts as any);
|
|
@@ -180,6 +245,82 @@ function createEffectBuilderProxy(
|
|
|
180
245
|
});
|
|
181
246
|
};
|
|
182
247
|
});
|
|
248
|
+
case "middleware":
|
|
249
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
250
|
+
return (middleware: any) => {
|
|
251
|
+
if (isEffectMiddleware(middleware)) {
|
|
252
|
+
const effectMiddleware = createEffectPipelineMiddleware({
|
|
253
|
+
effectErrorMap: state.effectErrorMap,
|
|
254
|
+
runtime: state.runtime,
|
|
255
|
+
steps: [
|
|
256
|
+
...(state.effectSteps ?? []),
|
|
257
|
+
{ _tag: "middleware" as const, middleware },
|
|
258
|
+
],
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return Reflect.apply(
|
|
262
|
+
Reflect.get(source, "middleware", source),
|
|
263
|
+
source,
|
|
264
|
+
[effectMiddleware],
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return Reflect.apply(
|
|
269
|
+
Reflect.get(source, "middleware", source),
|
|
270
|
+
source,
|
|
271
|
+
[middleware],
|
|
272
|
+
);
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
case "provide":
|
|
276
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
277
|
+
return (tagOrLayer: any, provider?: any) => {
|
|
278
|
+
return wrapBuilderLike(
|
|
279
|
+
source,
|
|
280
|
+
appendEffectStep(
|
|
281
|
+
state,
|
|
282
|
+
Layer.isLayer(tagOrLayer)
|
|
283
|
+
? { _tag: "provideLayer", layer: tagOrLayer }
|
|
284
|
+
: { _tag: "provide", provider, tag: tagOrLayer },
|
|
285
|
+
),
|
|
286
|
+
);
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
case "provideOptional":
|
|
290
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
291
|
+
return (tag: any, provider: any) => {
|
|
292
|
+
return wrapBuilderLike(
|
|
293
|
+
source,
|
|
294
|
+
appendEffectStep(state, {
|
|
295
|
+
_tag: "provideOptional",
|
|
296
|
+
provider,
|
|
297
|
+
tag,
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
case "use":
|
|
303
|
+
return getOrCreateVirtualMethod(context, prop, () => {
|
|
304
|
+
return (middleware: any, ...rest: unknown[]) => {
|
|
305
|
+
if (isEffectMiddleware(middleware) && rest.length === 0) {
|
|
306
|
+
return wrapBuilderLike(
|
|
307
|
+
source,
|
|
308
|
+
appendEffectStep(state, {
|
|
309
|
+
_tag: "middleware",
|
|
310
|
+
middleware,
|
|
311
|
+
}),
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const flushed = flushEffectSteps(source, state);
|
|
316
|
+
const nextBuilder: AnyBuilderLike = Reflect.apply(
|
|
317
|
+
Reflect.get(flushed.builder, "use", flushed.builder),
|
|
318
|
+
flushed.builder,
|
|
319
|
+
[middleware, ...rest],
|
|
320
|
+
);
|
|
321
|
+
return wrapBuilderLike(nextBuilder, flushed.state);
|
|
322
|
+
};
|
|
323
|
+
});
|
|
183
324
|
case "traced":
|
|
184
325
|
return getOrCreateVirtualMethod(context, prop, () => {
|
|
185
326
|
return (spanName: string) =>
|
|
@@ -292,6 +433,12 @@ export class EffectBuilder<
|
|
|
292
433
|
TRequirementsProvided,
|
|
293
434
|
TRuntimeError
|
|
294
435
|
> {
|
|
436
|
+
/**
|
|
437
|
+
* Sets or overrides the config.
|
|
438
|
+
*
|
|
439
|
+
* @see {@link https://orpc.dev/docs/client/server-side#middlewares-order Middlewares Order Docs}
|
|
440
|
+
* @see {@link https://orpc.dev/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}
|
|
441
|
+
*/
|
|
295
442
|
declare $config: EffectBuilderSurface<
|
|
296
443
|
TInitialContext,
|
|
297
444
|
TCurrentContext,
|
|
@@ -302,6 +449,11 @@ export class EffectBuilder<
|
|
|
302
449
|
TRequirementsProvided,
|
|
303
450
|
TRuntimeError
|
|
304
451
|
>["$config"];
|
|
452
|
+
/**
|
|
453
|
+
* Set or override the initial context.
|
|
454
|
+
*
|
|
455
|
+
* @see {@link https://orpc.dev/docs/context Context Docs}
|
|
456
|
+
*/
|
|
305
457
|
declare $context: EffectBuilderSurface<
|
|
306
458
|
TInitialContext,
|
|
307
459
|
TCurrentContext,
|
|
@@ -312,6 +464,11 @@ export class EffectBuilder<
|
|
|
312
464
|
TRequirementsProvided,
|
|
313
465
|
TRuntimeError
|
|
314
466
|
>["$context"];
|
|
467
|
+
/**
|
|
468
|
+
* Sets or overrides the initial meta.
|
|
469
|
+
*
|
|
470
|
+
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
|
|
471
|
+
*/
|
|
315
472
|
declare $meta: EffectBuilderSurface<
|
|
316
473
|
TInitialContext,
|
|
317
474
|
TCurrentContext,
|
|
@@ -322,6 +479,13 @@ export class EffectBuilder<
|
|
|
322
479
|
TRequirementsProvided,
|
|
323
480
|
TRuntimeError
|
|
324
481
|
>["$meta"];
|
|
482
|
+
/**
|
|
483
|
+
* Sets or overrides the initial route.
|
|
484
|
+
* This option is typically relevant when integrating with OpenAPI.
|
|
485
|
+
*
|
|
486
|
+
* @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
|
|
487
|
+
* @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
488
|
+
*/
|
|
325
489
|
declare $route: EffectBuilderSurface<
|
|
326
490
|
TInitialContext,
|
|
327
491
|
TCurrentContext,
|
|
@@ -332,6 +496,11 @@ export class EffectBuilder<
|
|
|
332
496
|
TRequirementsProvided,
|
|
333
497
|
TRuntimeError
|
|
334
498
|
>["$route"];
|
|
499
|
+
/**
|
|
500
|
+
* Sets or overrides the initial input schema.
|
|
501
|
+
*
|
|
502
|
+
* @see {@link https://orpc.dev/docs/procedure#initial-configuration Initial Procedure Configuration Docs}
|
|
503
|
+
*/
|
|
335
504
|
declare $input: EffectBuilderSurface<
|
|
336
505
|
TInitialContext,
|
|
337
506
|
TCurrentContext,
|
|
@@ -342,6 +511,9 @@ export class EffectBuilder<
|
|
|
342
511
|
TRequirementsProvided,
|
|
343
512
|
TRuntimeError
|
|
344
513
|
>["$input"];
|
|
514
|
+
/**
|
|
515
|
+
* This property holds the defined options and the effect-specific properties.
|
|
516
|
+
*/
|
|
345
517
|
declare "~effect": EffectBuilderDef<
|
|
346
518
|
TInputSchema,
|
|
347
519
|
TOutputSchema,
|
|
@@ -350,6 +522,9 @@ export class EffectBuilder<
|
|
|
350
522
|
TRequirementsProvided,
|
|
351
523
|
TRuntimeError
|
|
352
524
|
>;
|
|
525
|
+
/**
|
|
526
|
+
* This property holds the defined options.
|
|
527
|
+
*/
|
|
353
528
|
declare "~orpc": EffectBuilderSurface<
|
|
354
529
|
TInitialContext,
|
|
355
530
|
TCurrentContext,
|
|
@@ -360,6 +535,11 @@ export class EffectBuilder<
|
|
|
360
535
|
TRequirementsProvided,
|
|
361
536
|
TRuntimeError
|
|
362
537
|
>["~orpc"];
|
|
538
|
+
/**
|
|
539
|
+
* Creates a middleware.
|
|
540
|
+
*
|
|
541
|
+
* @see {@link https://orpc.dev/docs/middleware Middleware Docs}
|
|
542
|
+
*/
|
|
363
543
|
declare middleware: EffectBuilderSurface<
|
|
364
544
|
TInitialContext,
|
|
365
545
|
TCurrentContext,
|
|
@@ -370,6 +550,27 @@ export class EffectBuilder<
|
|
|
370
550
|
TRequirementsProvided,
|
|
371
551
|
TRuntimeError
|
|
372
552
|
>["middleware"];
|
|
553
|
+
/**
|
|
554
|
+
* Adds type-safe custom errors.
|
|
555
|
+
* Supports both traditional oRPC error definitions and ORPCTaggedError classes.
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```ts
|
|
559
|
+
* // Traditional format
|
|
560
|
+
* builder.errors({ BAD_REQUEST: { status: 400, message: 'Bad request' } })
|
|
561
|
+
*
|
|
562
|
+
* // Tagged error class
|
|
563
|
+
* builder.errors({ USER_NOT_FOUND: UserNotFoundError })
|
|
564
|
+
*
|
|
565
|
+
* // Mixed
|
|
566
|
+
* builder.errors({
|
|
567
|
+
* BAD_REQUEST: { status: 400 },
|
|
568
|
+
* USER_NOT_FOUND: UserNotFoundError,
|
|
569
|
+
* })
|
|
570
|
+
* ```
|
|
571
|
+
*
|
|
572
|
+
* @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
|
|
573
|
+
*/
|
|
373
574
|
declare errors: EffectBuilderSurface<
|
|
374
575
|
TInitialContext,
|
|
375
576
|
TCurrentContext,
|
|
@@ -380,6 +581,13 @@ export class EffectBuilder<
|
|
|
380
581
|
TRequirementsProvided,
|
|
381
582
|
TRuntimeError
|
|
382
583
|
>["errors"];
|
|
584
|
+
/**
|
|
585
|
+
* Uses a middleware to modify the context or improve the pipeline.
|
|
586
|
+
*
|
|
587
|
+
* @info Supports both normal middleware and inline middleware implementations.
|
|
588
|
+
* @note The current context must be satisfy middleware dependent-context
|
|
589
|
+
* @see {@link https://orpc.dev/docs/middleware Middleware Docs}
|
|
590
|
+
*/
|
|
383
591
|
declare use: EffectBuilderSurface<
|
|
384
592
|
TInitialContext,
|
|
385
593
|
TCurrentContext,
|
|
@@ -390,6 +598,38 @@ export class EffectBuilder<
|
|
|
390
598
|
TRequirementsProvided,
|
|
391
599
|
TRuntimeError
|
|
392
600
|
>["use"];
|
|
601
|
+
/**
|
|
602
|
+
* Provides a request-scoped Effect service to downstream procedures.
|
|
603
|
+
*/
|
|
604
|
+
declare provide: EffectBuilderSurface<
|
|
605
|
+
TInitialContext,
|
|
606
|
+
TCurrentContext,
|
|
607
|
+
TInputSchema,
|
|
608
|
+
TOutputSchema,
|
|
609
|
+
TEffectErrorMap,
|
|
610
|
+
TMeta,
|
|
611
|
+
TRequirementsProvided,
|
|
612
|
+
TRuntimeError
|
|
613
|
+
>["provide"];
|
|
614
|
+
/**
|
|
615
|
+
* Optionally provides a request-scoped Effect service to downstream procedures.
|
|
616
|
+
*/
|
|
617
|
+
declare provideOptional: EffectBuilderSurface<
|
|
618
|
+
TInitialContext,
|
|
619
|
+
TCurrentContext,
|
|
620
|
+
TInputSchema,
|
|
621
|
+
TOutputSchema,
|
|
622
|
+
TEffectErrorMap,
|
|
623
|
+
TMeta,
|
|
624
|
+
TRequirementsProvided,
|
|
625
|
+
TRuntimeError
|
|
626
|
+
>["provideOptional"];
|
|
627
|
+
/**
|
|
628
|
+
* Sets or updates the metadata.
|
|
629
|
+
* The provided metadata is spared-merged with any existing metadata.
|
|
630
|
+
*
|
|
631
|
+
* @see {@link https://orpc.dev/docs/metadata Metadata Docs}
|
|
632
|
+
*/
|
|
393
633
|
declare meta: EffectBuilderSurface<
|
|
394
634
|
TInitialContext,
|
|
395
635
|
TCurrentContext,
|
|
@@ -400,6 +640,14 @@ export class EffectBuilder<
|
|
|
400
640
|
TRequirementsProvided,
|
|
401
641
|
TRuntimeError
|
|
402
642
|
>["meta"];
|
|
643
|
+
/**
|
|
644
|
+
* Sets or updates the route definition.
|
|
645
|
+
* The provided route is spared-merged with any existing route.
|
|
646
|
+
* This option is typically relevant when integrating with OpenAPI.
|
|
647
|
+
*
|
|
648
|
+
* @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
|
|
649
|
+
* @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
650
|
+
*/
|
|
403
651
|
declare route: EffectBuilderSurface<
|
|
404
652
|
TInitialContext,
|
|
405
653
|
TCurrentContext,
|
|
@@ -410,6 +658,11 @@ export class EffectBuilder<
|
|
|
410
658
|
TRequirementsProvided,
|
|
411
659
|
TRuntimeError
|
|
412
660
|
>["route"];
|
|
661
|
+
/**
|
|
662
|
+
* Defines the input validation schema.
|
|
663
|
+
*
|
|
664
|
+
* @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}
|
|
665
|
+
*/
|
|
413
666
|
declare input: EffectBuilderSurface<
|
|
414
667
|
TInitialContext,
|
|
415
668
|
TCurrentContext,
|
|
@@ -420,6 +673,11 @@ export class EffectBuilder<
|
|
|
420
673
|
TRequirementsProvided,
|
|
421
674
|
TRuntimeError
|
|
422
675
|
>["input"];
|
|
676
|
+
/**
|
|
677
|
+
* Defines the output validation schema.
|
|
678
|
+
*
|
|
679
|
+
* @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}
|
|
680
|
+
*/
|
|
423
681
|
declare output: EffectBuilderSurface<
|
|
424
682
|
TInitialContext,
|
|
425
683
|
TCurrentContext,
|
|
@@ -430,6 +688,25 @@ export class EffectBuilder<
|
|
|
430
688
|
TRequirementsProvided,
|
|
431
689
|
TRuntimeError
|
|
432
690
|
>["output"];
|
|
691
|
+
/**
|
|
692
|
+
* Adds a traceable span to the procedure for telemetry.
|
|
693
|
+
* The span name is used for Effect tracing via `Effect.withSpan`.
|
|
694
|
+
* Stack trace is captured at the call site for better error reporting.
|
|
695
|
+
*
|
|
696
|
+
* @param spanName - The name of the span for telemetry (e.g., 'users.getUser')
|
|
697
|
+
* @returns An EffectBuilder with span tracing configured
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* ```ts
|
|
701
|
+
* const getUser = effectOs
|
|
702
|
+
* .input(z.object({ id: z.string() }))
|
|
703
|
+
* .traced('users.getUser')
|
|
704
|
+
* .effect(function* ({ input }) {
|
|
705
|
+
* const userService = yield* UserService
|
|
706
|
+
* return yield* userService.findById(input.id)
|
|
707
|
+
* })
|
|
708
|
+
* ```
|
|
709
|
+
*/
|
|
433
710
|
declare traced: EffectBuilderSurface<
|
|
434
711
|
TInitialContext,
|
|
435
712
|
TCurrentContext,
|
|
@@ -440,6 +717,11 @@ export class EffectBuilder<
|
|
|
440
717
|
TRequirementsProvided,
|
|
441
718
|
TRuntimeError
|
|
442
719
|
>["traced"];
|
|
720
|
+
/**
|
|
721
|
+
* Defines the handler of the procedure using a standard async/sync function.
|
|
722
|
+
*
|
|
723
|
+
* @see {@link https://orpc.dev/docs/procedure Procedure Docs}
|
|
724
|
+
*/
|
|
443
725
|
declare handler: EffectBuilderSurface<
|
|
444
726
|
TInitialContext,
|
|
445
727
|
TCurrentContext,
|
|
@@ -450,6 +732,13 @@ export class EffectBuilder<
|
|
|
450
732
|
TRequirementsProvided,
|
|
451
733
|
TRuntimeError
|
|
452
734
|
>["handler"];
|
|
735
|
+
/**
|
|
736
|
+
* Defines the handler of the procedure using an Effect.
|
|
737
|
+
* The Effect is executed using the ManagedRuntime provided during builder creation.
|
|
738
|
+
* The effect is automatically wrapped with `Effect.withSpan`.
|
|
739
|
+
*
|
|
740
|
+
* @see {@link https://orpc.dev/docs/procedure Procedure Docs}
|
|
741
|
+
*/
|
|
453
742
|
declare effect: EffectBuilderSurface<
|
|
454
743
|
TInitialContext,
|
|
455
744
|
TCurrentContext,
|
|
@@ -460,6 +749,14 @@ export class EffectBuilder<
|
|
|
460
749
|
TRequirementsProvided,
|
|
461
750
|
TRuntimeError
|
|
462
751
|
>["effect"];
|
|
752
|
+
/**
|
|
753
|
+
* Prefixes all procedures in the router.
|
|
754
|
+
* The provided prefix is post-appended to any existing router prefix.
|
|
755
|
+
*
|
|
756
|
+
* @note This option does not affect procedures that do not define a path in their route definition.
|
|
757
|
+
*
|
|
758
|
+
* @see {@link https://orpc.dev/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}
|
|
759
|
+
*/
|
|
463
760
|
declare prefix: EffectBuilderSurface<
|
|
464
761
|
TInitialContext,
|
|
465
762
|
TCurrentContext,
|
|
@@ -470,6 +767,12 @@ export class EffectBuilder<
|
|
|
470
767
|
TRequirementsProvided,
|
|
471
768
|
TRuntimeError
|
|
472
769
|
>["prefix"];
|
|
770
|
+
/**
|
|
771
|
+
* Adds tags to all procedures in the router.
|
|
772
|
+
* This helpful when you want to group procedures together in the OpenAPI specification.
|
|
773
|
+
*
|
|
774
|
+
* @see {@link https://orpc.dev/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}
|
|
775
|
+
*/
|
|
473
776
|
declare tag: EffectBuilderSurface<
|
|
474
777
|
TInitialContext,
|
|
475
778
|
TCurrentContext,
|
|
@@ -480,6 +783,11 @@ export class EffectBuilder<
|
|
|
480
783
|
TRequirementsProvided,
|
|
481
784
|
TRuntimeError
|
|
482
785
|
>["tag"];
|
|
786
|
+
/**
|
|
787
|
+
* Applies all of the previously defined options to the specified router.
|
|
788
|
+
*
|
|
789
|
+
* @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
|
|
790
|
+
*/
|
|
483
791
|
declare router: EffectBuilderSurface<
|
|
484
792
|
TInitialContext,
|
|
485
793
|
TCurrentContext,
|
|
@@ -490,6 +798,12 @@ export class EffectBuilder<
|
|
|
490
798
|
TRequirementsProvided,
|
|
491
799
|
TRuntimeError
|
|
492
800
|
>["router"];
|
|
801
|
+
/**
|
|
802
|
+
* Create a lazy router
|
|
803
|
+
* And applies all of the previously defined options to the specified router.
|
|
804
|
+
*
|
|
805
|
+
* @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
|
|
806
|
+
*/
|
|
493
807
|
declare lazy: EffectBuilderSurface<
|
|
494
808
|
TInitialContext,
|
|
495
809
|
TCurrentContext,
|
|
@@ -512,9 +826,12 @@ export class EffectBuilder<
|
|
|
512
826
|
>,
|
|
513
827
|
builder?: AnyBuilderLike,
|
|
514
828
|
) {
|
|
515
|
-
const { runtime, spanConfig, effectErrorMap, ...orpcDef } =
|
|
829
|
+
const { runtime, spanConfig, effectErrorMap, effectSteps, ...orpcDef } =
|
|
830
|
+
def;
|
|
516
831
|
|
|
517
832
|
attachEffectState(this, builder ?? new Builder(orpcDef), {
|
|
833
|
+
effectSteps,
|
|
834
|
+
effectHandler: def.effectHandler,
|
|
518
835
|
effectErrorMap,
|
|
519
836
|
runtime,
|
|
520
837
|
spanConfig,
|
|
@@ -524,12 +841,76 @@ export class EffectBuilder<
|
|
|
524
841
|
}
|
|
525
842
|
}
|
|
526
843
|
|
|
844
|
+
/**
|
|
845
|
+
* Creates an Effect-aware procedure builder with the specified Layer.
|
|
846
|
+
* Uses the default builder shape from `@orpc/server`.
|
|
847
|
+
*
|
|
848
|
+
* @param layer - The Layer that provides services for Effect procedures
|
|
849
|
+
* @returns An EffectBuilder instance for creating Effect-native procedures
|
|
850
|
+
*
|
|
851
|
+
* @example
|
|
852
|
+
* ```ts
|
|
853
|
+
* import { makeEffectORPC } from '@orpc/effect'
|
|
854
|
+
* import { Effect, Layer } from 'effect'
|
|
855
|
+
*
|
|
856
|
+
* const effectOs = makeEffectORPC(Layer.empty)
|
|
857
|
+
*
|
|
858
|
+
* const hello = effectOs.effect(() => Effect.succeed('Hello!'))
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
export function makeEffectORPC(): EffectBuilder<
|
|
862
|
+
Context,
|
|
863
|
+
Context,
|
|
864
|
+
Schema<unknown, unknown>,
|
|
865
|
+
Schema<unknown, unknown>,
|
|
866
|
+
Record<never, never>,
|
|
867
|
+
Record<never, never>,
|
|
868
|
+
never,
|
|
869
|
+
never
|
|
870
|
+
>;
|
|
871
|
+
|
|
872
|
+
export function makeEffectORPC<
|
|
873
|
+
TBuilder extends AnyBuilderLike<
|
|
874
|
+
TInputSchema,
|
|
875
|
+
TOutputSchema,
|
|
876
|
+
TErrorMap,
|
|
877
|
+
TMeta
|
|
878
|
+
>,
|
|
879
|
+
TInputSchema extends AnySchema,
|
|
880
|
+
TOutputSchema extends AnySchema,
|
|
881
|
+
TErrorMap extends ErrorMap,
|
|
882
|
+
TMeta extends Meta,
|
|
883
|
+
>(
|
|
884
|
+
builder: TBuilder,
|
|
885
|
+
): EffectBuilder<
|
|
886
|
+
InferBuilderInitialContext<TBuilder>,
|
|
887
|
+
InferBuilderCurrentContext<TBuilder>,
|
|
888
|
+
InferBuilderInputSchema<TBuilder>,
|
|
889
|
+
InferBuilderOutputSchema<TBuilder>,
|
|
890
|
+
InferBuilderErrorMap<TBuilder>,
|
|
891
|
+
InferBuilderMeta<TBuilder>,
|
|
892
|
+
never,
|
|
893
|
+
never
|
|
894
|
+
>;
|
|
895
|
+
|
|
896
|
+
export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
897
|
+
layer: Layer.Layer<TRequirementsProvided, TRuntimeError, never>,
|
|
898
|
+
): EffectBuilder<
|
|
899
|
+
Context,
|
|
900
|
+
Context,
|
|
901
|
+
Schema<unknown, unknown>,
|
|
902
|
+
Schema<unknown, unknown>,
|
|
903
|
+
Record<never, never>,
|
|
904
|
+
Record<never, never>,
|
|
905
|
+
TRequirementsProvided,
|
|
906
|
+
TRuntimeError
|
|
907
|
+
>;
|
|
908
|
+
|
|
527
909
|
/**
|
|
528
910
|
* Creates an Effect-aware procedure builder with the specified ManagedRuntime.
|
|
529
911
|
* Uses the default builder shape from `@orpc/server`.
|
|
530
912
|
*
|
|
531
913
|
* @param runtime - The ManagedRuntime that provides services for Effect procedures
|
|
532
|
-
* @returns An EffectBuilder instance for creating Effect-native procedures
|
|
533
914
|
*/
|
|
534
915
|
export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
535
916
|
runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,
|
|
@@ -546,11 +927,33 @@ export function makeEffectORPC<TRequirementsProvided, TRuntimeError>(
|
|
|
546
927
|
|
|
547
928
|
/**
|
|
548
929
|
* Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder
|
|
549
|
-
* with the specified
|
|
930
|
+
* with the specified Layer.
|
|
550
931
|
*
|
|
551
|
-
* @param
|
|
552
|
-
* @param builder - The oRPC Builder instance to wrap
|
|
932
|
+
* @param layer - The Layer that provides services for Effect procedures
|
|
933
|
+
* @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)
|
|
553
934
|
* @returns An EffectBuilder instance that extends the original builder with Effect support
|
|
935
|
+
*
|
|
936
|
+
* @example
|
|
937
|
+
* ```ts
|
|
938
|
+
* import { makeEffectORPC } from '@orpc/effect'
|
|
939
|
+
* import { os } from '@orpc/server'
|
|
940
|
+
* import { Effect, Layer } from 'effect'
|
|
941
|
+
*
|
|
942
|
+
* // Create a customized builder
|
|
943
|
+
* const authedOs = os.use(authMiddleware)
|
|
944
|
+
*
|
|
945
|
+
* // Wrap it with Effect support
|
|
946
|
+
* const effectOs = makeEffectORPC(UserServiceLive, authedOs)
|
|
947
|
+
*
|
|
948
|
+
* const getUser = effectOs
|
|
949
|
+
* .input(z.object({ id: z.string() }))
|
|
950
|
+
* .effect(
|
|
951
|
+
* Effect.fn(function* ({ input }) {
|
|
952
|
+
* const userService = yield* UserService
|
|
953
|
+
* return yield* userService.findById(input.id)
|
|
954
|
+
* })
|
|
955
|
+
* )
|
|
956
|
+
* ```
|
|
554
957
|
*/
|
|
555
958
|
export function makeEffectORPC<
|
|
556
959
|
TBuilder extends AnyBuilderLike<
|
|
@@ -566,7 +969,7 @@ export function makeEffectORPC<
|
|
|
566
969
|
TRequirementsProvided,
|
|
567
970
|
TRuntimeError,
|
|
568
971
|
>(
|
|
569
|
-
|
|
972
|
+
layer: Layer.Layer<TRequirementsProvided, TRuntimeError, never>,
|
|
570
973
|
builder: TBuilder,
|
|
571
974
|
): EffectBuilder<
|
|
572
975
|
InferBuilderInitialContext<TBuilder>,
|
|
@@ -579,21 +982,52 @@ export function makeEffectORPC<
|
|
|
579
982
|
TRuntimeError
|
|
580
983
|
>;
|
|
581
984
|
|
|
582
|
-
|
|
985
|
+
/**
|
|
986
|
+
* Creates an Effect-aware procedure builder by wrapping an existing oRPC Builder
|
|
987
|
+
* with the specified ManagedRuntime.
|
|
988
|
+
*
|
|
989
|
+
* @param runtime - The ManagedRuntime that provides services for Effect procedures
|
|
990
|
+
* @param builder - The oRPC Builder instance to wrap (e.g., a customized `os`)
|
|
991
|
+
*/
|
|
992
|
+
export function makeEffectORPC<
|
|
993
|
+
TBuilder extends AnyBuilderLike<
|
|
994
|
+
TInputSchema,
|
|
995
|
+
TOutputSchema,
|
|
996
|
+
TErrorMap,
|
|
997
|
+
TMeta
|
|
998
|
+
>,
|
|
999
|
+
TInputSchema extends AnySchema,
|
|
1000
|
+
TOutputSchema extends AnySchema,
|
|
1001
|
+
TErrorMap extends ErrorMap,
|
|
1002
|
+
TMeta extends Meta,
|
|
1003
|
+
TRequirementsProvided,
|
|
1004
|
+
TRuntimeError,
|
|
1005
|
+
>(
|
|
583
1006
|
runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>,
|
|
584
|
-
builder
|
|
1007
|
+
builder: TBuilder,
|
|
585
1008
|
): EffectBuilder<
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
1009
|
+
InferBuilderInitialContext<TBuilder>,
|
|
1010
|
+
InferBuilderCurrentContext<TBuilder>,
|
|
1011
|
+
InferBuilderInputSchema<TBuilder>,
|
|
1012
|
+
InferBuilderOutputSchema<TBuilder>,
|
|
1013
|
+
InferBuilderErrorMap<TBuilder>,
|
|
1014
|
+
InferBuilderMeta<TBuilder>,
|
|
592
1015
|
TRequirementsProvided,
|
|
593
1016
|
TRuntimeError
|
|
594
|
-
|
|
595
|
-
|
|
1017
|
+
>;
|
|
1018
|
+
|
|
1019
|
+
export function makeEffectORPC(
|
|
1020
|
+
source?: EffectRuntimeSource<any, any> | AnyBuilderLike,
|
|
1021
|
+
builder?: AnyBuilderLike,
|
|
1022
|
+
): any {
|
|
1023
|
+
const sourceIsBuilder = source !== undefined && isBuilderLike(source);
|
|
1024
|
+
const resolvedBuilder = sourceIsBuilder
|
|
1025
|
+
? source
|
|
1026
|
+
: (builder ?? emptyBuilder());
|
|
596
1027
|
const effectErrorMap = getEffectErrorMap(resolvedBuilder);
|
|
1028
|
+
const runtime = toManagedRuntime(
|
|
1029
|
+
sourceIsBuilder || source === undefined ? Layer.empty : source,
|
|
1030
|
+
);
|
|
597
1031
|
return new EffectBuilder(
|
|
598
1032
|
{
|
|
599
1033
|
...resolvedBuilder["~orpc"],
|