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
|
@@ -12,12 +12,21 @@ import {
|
|
|
12
12
|
outputSchema,
|
|
13
13
|
} from "./shared";
|
|
14
14
|
|
|
15
|
+
const authMiddleware: Middleware<
|
|
16
|
+
InitialContext,
|
|
17
|
+
{ auth: boolean },
|
|
18
|
+
{ input: string },
|
|
19
|
+
unknown,
|
|
20
|
+
any,
|
|
21
|
+
BaseMeta
|
|
22
|
+
> = ({ next }) => next({ context: { auth: true as boolean } });
|
|
23
|
+
|
|
15
24
|
const procedure = makeEffectORPC(runtime)
|
|
16
25
|
.$context<InitialContext>()
|
|
17
26
|
.$meta({ mode: "dev" } as BaseMeta)
|
|
18
27
|
.$input(inputSchema)
|
|
19
28
|
.errors(baseErrorMap)
|
|
20
|
-
.use(
|
|
29
|
+
.use(authMiddleware)
|
|
21
30
|
.output(outputSchema)
|
|
22
31
|
.effect(function* () {
|
|
23
32
|
return { output: 456 };
|
|
@@ -61,13 +70,20 @@ describe("parity: @orpc/server procedure-decorated.test-d.ts", () => {
|
|
|
61
70
|
|
|
62
71
|
describe(".use", () => {
|
|
63
72
|
it("without map input", () => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
const middleware: Middleware<
|
|
74
|
+
CurrentContext,
|
|
75
|
+
{ extra: boolean },
|
|
76
|
+
{ input: string },
|
|
77
|
+
{ output: number },
|
|
78
|
+
any,
|
|
79
|
+
BaseMeta
|
|
80
|
+
> = ({ next }, input, output) => {
|
|
81
|
+
expectTypeOf(input).toEqualTypeOf<{ input: string }>();
|
|
82
|
+
expectTypeOf(output).toBeFunction();
|
|
83
|
+
return next({ context: { extra: true } });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
expectTypeOf(procedure.use(middleware)).toBeObject();
|
|
71
87
|
|
|
72
88
|
procedure.use(
|
|
73
89
|
// @ts-expect-error - invalid TInContext
|
package/src/tests/shared.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Meta, Schema } from "@orpc/contract";
|
|
2
|
-
import { ContractProcedure
|
|
2
|
+
import { ContractProcedure } from "@orpc/contract";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
|
|
5
5
|
export const inputSchema = z.object({
|
|
@@ -53,28 +53,4 @@ export const pong = new ContractProcedure<
|
|
|
53
53
|
route: {},
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
export const router = {
|
|
57
|
-
ping,
|
|
58
|
-
pong,
|
|
59
|
-
nested: {
|
|
60
|
-
ping,
|
|
61
|
-
pong,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const streamedOutputSchema = eventIterator(outputSchema);
|
|
66
|
-
|
|
67
|
-
export const streamed = new ContractProcedure<
|
|
68
|
-
typeof inputSchema,
|
|
69
|
-
typeof streamedOutputSchema,
|
|
70
|
-
typeof baseErrorMap,
|
|
71
|
-
Meta
|
|
72
|
-
>({
|
|
73
|
-
errorMap: baseErrorMap,
|
|
74
|
-
meta: {},
|
|
75
|
-
route: {},
|
|
76
|
-
inputSchema,
|
|
77
|
-
outputSchema: streamedOutputSchema,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
56
|
export type AssertExtends<_TActual extends TExpected, TExpected> = true;
|
|
@@ -20,13 +20,17 @@ import type {
|
|
|
20
20
|
Router,
|
|
21
21
|
} from "@orpc/server";
|
|
22
22
|
import type { IntersectPick } from "@orpc/shared";
|
|
23
|
+
import type { Context as EffectContext, Layer } from "effect";
|
|
23
24
|
|
|
24
25
|
import type {
|
|
25
26
|
EffectBuilderDef,
|
|
26
27
|
EffectErrorMapToErrorMap,
|
|
28
|
+
EffectOrORPCMiddleware,
|
|
29
|
+
EffectOptionalProvider,
|
|
27
30
|
EffectProcedureBuilderWithInput,
|
|
28
31
|
EffectProcedureBuilderWithOutput,
|
|
29
32
|
EffectProcedureHandler,
|
|
33
|
+
EffectProvider,
|
|
30
34
|
EffectRouterBuilder,
|
|
31
35
|
EnhancedEffectRouter,
|
|
32
36
|
} from ".";
|
|
@@ -37,6 +41,9 @@ import type {
|
|
|
37
41
|
MergedEffectErrorMap,
|
|
38
42
|
} from "../tagged-error";
|
|
39
43
|
|
|
44
|
+
type EffectTagIdentifier<T extends EffectContext.Tag<any, any>> =
|
|
45
|
+
T extends EffectContext.Tag<infer I, any> ? I : never;
|
|
46
|
+
|
|
40
47
|
export interface EffectBuilderSurface<
|
|
41
48
|
TInitialContext extends Context,
|
|
42
49
|
TCurrentContext extends Context,
|
|
@@ -158,6 +165,28 @@ export interface EffectBuilderSurface<
|
|
|
158
165
|
*
|
|
159
166
|
* @see {@link https://orpc.dev/docs/middleware Middleware Docs}
|
|
160
167
|
*/
|
|
168
|
+
middleware<
|
|
169
|
+
UOutContext extends IntersectPick<TCurrentContext, UOutContext>,
|
|
170
|
+
TInput,
|
|
171
|
+
TOutput = any,
|
|
172
|
+
>(
|
|
173
|
+
middleware: EffectOrORPCMiddleware<
|
|
174
|
+
TInitialContext,
|
|
175
|
+
UOutContext,
|
|
176
|
+
TInput,
|
|
177
|
+
TOutput,
|
|
178
|
+
TEffectErrorMap,
|
|
179
|
+
TRequirementsProvided,
|
|
180
|
+
TMeta
|
|
181
|
+
>,
|
|
182
|
+
): DecoratedMiddleware<
|
|
183
|
+
TInitialContext,
|
|
184
|
+
UOutContext,
|
|
185
|
+
TInput,
|
|
186
|
+
TOutput,
|
|
187
|
+
any,
|
|
188
|
+
TMeta
|
|
189
|
+
>;
|
|
161
190
|
middleware<
|
|
162
191
|
UOutContext extends IntersectPick<TCurrentContext, UOutContext>,
|
|
163
192
|
TInput,
|
|
@@ -212,6 +241,32 @@ export interface EffectBuilderSurface<
|
|
|
212
241
|
TRequirementsProvided,
|
|
213
242
|
TRuntimeError
|
|
214
243
|
>;
|
|
244
|
+
/**
|
|
245
|
+
* Uses an Effect middleware or native oRPC middleware to modify the context, throw early, or modify the response.
|
|
246
|
+
*/
|
|
247
|
+
use<
|
|
248
|
+
UOutContext extends IntersectPick<TCurrentContext, UOutContext>,
|
|
249
|
+
UInContext extends Context = TCurrentContext,
|
|
250
|
+
>(
|
|
251
|
+
middleware: EffectOrORPCMiddleware<
|
|
252
|
+
UInContext | TCurrentContext,
|
|
253
|
+
UOutContext,
|
|
254
|
+
InferSchemaOutput<TInputSchema>,
|
|
255
|
+
unknown,
|
|
256
|
+
TEffectErrorMap,
|
|
257
|
+
TRequirementsProvided,
|
|
258
|
+
TMeta
|
|
259
|
+
>,
|
|
260
|
+
): EffectBuilderSurface<
|
|
261
|
+
MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,
|
|
262
|
+
MergedCurrentContext<TCurrentContext, UOutContext>,
|
|
263
|
+
TInputSchema,
|
|
264
|
+
TOutputSchema,
|
|
265
|
+
TEffectErrorMap,
|
|
266
|
+
TMeta,
|
|
267
|
+
TRequirementsProvided,
|
|
268
|
+
TRuntimeError
|
|
269
|
+
>;
|
|
215
270
|
/**
|
|
216
271
|
* Uses a middleware to modify the context or improve the pipeline.
|
|
217
272
|
*
|
|
@@ -241,6 +296,67 @@ export interface EffectBuilderSurface<
|
|
|
241
296
|
TRequirementsProvided,
|
|
242
297
|
TRuntimeError
|
|
243
298
|
>;
|
|
299
|
+
/**
|
|
300
|
+
* Provides an Effect layer to downstream procedures.
|
|
301
|
+
*/
|
|
302
|
+
provide<TLayerOut, TLayerError, TLayerIn extends TRequirementsProvided>(
|
|
303
|
+
layer: Layer.Layer<TLayerOut, TLayerError, TLayerIn>,
|
|
304
|
+
): EffectBuilderSurface<
|
|
305
|
+
TInitialContext,
|
|
306
|
+
TCurrentContext,
|
|
307
|
+
TInputSchema,
|
|
308
|
+
TOutputSchema,
|
|
309
|
+
TEffectErrorMap,
|
|
310
|
+
TMeta,
|
|
311
|
+
TRequirementsProvided | TLayerOut,
|
|
312
|
+
TRuntimeError | TLayerError
|
|
313
|
+
>;
|
|
314
|
+
/**
|
|
315
|
+
* Provides a request-scoped Effect service to downstream procedures.
|
|
316
|
+
*/
|
|
317
|
+
provide<TTag extends EffectContext.Tag<any, any>>(
|
|
318
|
+
tag: TTag,
|
|
319
|
+
provider: EffectProvider<
|
|
320
|
+
TCurrentContext,
|
|
321
|
+
InferSchemaOutput<TInputSchema>,
|
|
322
|
+
TEffectErrorMap,
|
|
323
|
+
TRequirementsProvided,
|
|
324
|
+
TMeta,
|
|
325
|
+
TTag
|
|
326
|
+
>,
|
|
327
|
+
): EffectBuilderSurface<
|
|
328
|
+
TInitialContext,
|
|
329
|
+
TCurrentContext,
|
|
330
|
+
TInputSchema,
|
|
331
|
+
TOutputSchema,
|
|
332
|
+
TEffectErrorMap,
|
|
333
|
+
TMeta,
|
|
334
|
+
TRequirementsProvided | EffectTagIdentifier<TTag>,
|
|
335
|
+
TRuntimeError
|
|
336
|
+
>;
|
|
337
|
+
/**
|
|
338
|
+
* Optionally provides a request-scoped Effect service to downstream procedures.
|
|
339
|
+
*/
|
|
340
|
+
provideOptional<TTag extends EffectContext.Tag<any, any>>(
|
|
341
|
+
tag: TTag,
|
|
342
|
+
provider: EffectOptionalProvider<
|
|
343
|
+
TCurrentContext,
|
|
344
|
+
InferSchemaOutput<TInputSchema>,
|
|
345
|
+
TEffectErrorMap,
|
|
346
|
+
TRequirementsProvided,
|
|
347
|
+
TMeta,
|
|
348
|
+
TTag
|
|
349
|
+
>,
|
|
350
|
+
): EffectBuilderSurface<
|
|
351
|
+
TInitialContext,
|
|
352
|
+
TCurrentContext,
|
|
353
|
+
TInputSchema,
|
|
354
|
+
TOutputSchema,
|
|
355
|
+
TEffectErrorMap,
|
|
356
|
+
TMeta,
|
|
357
|
+
TRequirementsProvided,
|
|
358
|
+
TRuntimeError
|
|
359
|
+
>;
|
|
244
360
|
/**
|
|
245
361
|
* Sets or updates the metadata.
|
|
246
362
|
* The provided metadata is spared-merged with any existing metadata.
|
|
@@ -18,8 +18,15 @@ import type {
|
|
|
18
18
|
ProcedureDef,
|
|
19
19
|
} from "@orpc/server";
|
|
20
20
|
import type { IntersectPick, MaybeOptionalOptions } from "@orpc/shared";
|
|
21
|
+
import type { Context as EffectContext, Layer } from "effect";
|
|
21
22
|
|
|
22
|
-
import type {
|
|
23
|
+
import type {
|
|
24
|
+
EffectErrorMapToErrorMap,
|
|
25
|
+
EffectOrORPCMiddleware,
|
|
26
|
+
EffectOptionalProvider,
|
|
27
|
+
EffectProcedureDef,
|
|
28
|
+
EffectProvider,
|
|
29
|
+
} from ".";
|
|
23
30
|
import type { EffectDecoratedProcedure } from "../effect-procedure";
|
|
24
31
|
import type {
|
|
25
32
|
EffectErrorConstructorMap,
|
|
@@ -27,6 +34,9 @@ import type {
|
|
|
27
34
|
MergedEffectErrorMap,
|
|
28
35
|
} from "../tagged-error";
|
|
29
36
|
|
|
37
|
+
type EffectTagIdentifier<T extends EffectContext.Tag<any, any>> =
|
|
38
|
+
T extends EffectContext.Tag<infer I, any> ? I : never;
|
|
39
|
+
|
|
30
40
|
export interface EffectDecoratedProcedureSurface<
|
|
31
41
|
TInitialContext extends Context,
|
|
32
42
|
TCurrentContext extends Context,
|
|
@@ -117,6 +127,93 @@ export interface EffectDecoratedProcedureSurface<
|
|
|
117
127
|
TRequirementsProvided,
|
|
118
128
|
TRuntimeError
|
|
119
129
|
>;
|
|
130
|
+
/**
|
|
131
|
+
* Provides an Effect layer to downstream procedures.
|
|
132
|
+
*/
|
|
133
|
+
provide<TLayerOut, TLayerError, TLayerIn extends TRequirementsProvided>(
|
|
134
|
+
layer: Layer.Layer<TLayerOut, TLayerError, TLayerIn>,
|
|
135
|
+
): EffectDecoratedProcedure<
|
|
136
|
+
TInitialContext,
|
|
137
|
+
TCurrentContext,
|
|
138
|
+
TInputSchema,
|
|
139
|
+
TOutputSchema,
|
|
140
|
+
TEffectErrorMap,
|
|
141
|
+
TMeta,
|
|
142
|
+
TRequirementsProvided | TLayerOut,
|
|
143
|
+
TRuntimeError | TLayerError
|
|
144
|
+
>;
|
|
145
|
+
/**
|
|
146
|
+
* Provides a request-scoped Effect service to downstream procedures.
|
|
147
|
+
*/
|
|
148
|
+
provide<TTag extends EffectContext.Tag<any, any>>(
|
|
149
|
+
tag: TTag,
|
|
150
|
+
provider: EffectProvider<
|
|
151
|
+
TCurrentContext,
|
|
152
|
+
InferSchemaOutput<TInputSchema>,
|
|
153
|
+
TEffectErrorMap,
|
|
154
|
+
TRequirementsProvided,
|
|
155
|
+
TMeta,
|
|
156
|
+
TTag
|
|
157
|
+
>,
|
|
158
|
+
): EffectDecoratedProcedure<
|
|
159
|
+
TInitialContext,
|
|
160
|
+
TCurrentContext,
|
|
161
|
+
TInputSchema,
|
|
162
|
+
TOutputSchema,
|
|
163
|
+
TEffectErrorMap,
|
|
164
|
+
TMeta,
|
|
165
|
+
TRequirementsProvided | EffectTagIdentifier<TTag>,
|
|
166
|
+
TRuntimeError
|
|
167
|
+
>;
|
|
168
|
+
/**
|
|
169
|
+
* Optionally provides a request-scoped Effect service to downstream procedures.
|
|
170
|
+
*/
|
|
171
|
+
provideOptional<TTag extends EffectContext.Tag<any, any>>(
|
|
172
|
+
tag: TTag,
|
|
173
|
+
provider: EffectOptionalProvider<
|
|
174
|
+
TCurrentContext,
|
|
175
|
+
InferSchemaOutput<TInputSchema>,
|
|
176
|
+
TEffectErrorMap,
|
|
177
|
+
TRequirementsProvided,
|
|
178
|
+
TMeta,
|
|
179
|
+
TTag
|
|
180
|
+
>,
|
|
181
|
+
): EffectDecoratedProcedure<
|
|
182
|
+
TInitialContext,
|
|
183
|
+
TCurrentContext,
|
|
184
|
+
TInputSchema,
|
|
185
|
+
TOutputSchema,
|
|
186
|
+
TEffectErrorMap,
|
|
187
|
+
TMeta,
|
|
188
|
+
TRequirementsProvided,
|
|
189
|
+
TRuntimeError
|
|
190
|
+
>;
|
|
191
|
+
/**
|
|
192
|
+
* Uses an Effect middleware or native oRPC middleware to modify the context, throw early, or modify the response.
|
|
193
|
+
*/
|
|
194
|
+
use<
|
|
195
|
+
UOutContext extends IntersectPick<TCurrentContext, UOutContext>,
|
|
196
|
+
UInContext extends Context = TCurrentContext,
|
|
197
|
+
>(
|
|
198
|
+
middleware: EffectOrORPCMiddleware<
|
|
199
|
+
UInContext | TCurrentContext,
|
|
200
|
+
UOutContext,
|
|
201
|
+
InferSchemaOutput<TInputSchema>,
|
|
202
|
+
InferSchemaInput<TOutputSchema>,
|
|
203
|
+
TEffectErrorMap,
|
|
204
|
+
TRequirementsProvided,
|
|
205
|
+
TMeta
|
|
206
|
+
>,
|
|
207
|
+
): EffectDecoratedProcedure<
|
|
208
|
+
MergedInitialContext<TInitialContext, UInContext, TCurrentContext>,
|
|
209
|
+
MergedCurrentContext<TCurrentContext, UOutContext>,
|
|
210
|
+
TInputSchema,
|
|
211
|
+
TOutputSchema,
|
|
212
|
+
TEffectErrorMap,
|
|
213
|
+
TMeta,
|
|
214
|
+
TRequirementsProvided,
|
|
215
|
+
TRuntimeError
|
|
216
|
+
>;
|
|
120
217
|
/**
|
|
121
218
|
* Uses a middleware to modify the context or improve the pipeline.
|
|
122
219
|
*
|
package/src/types/index.ts
CHANGED
|
@@ -18,9 +18,19 @@ import type {
|
|
|
18
18
|
ProcedureBuilderWithOutput,
|
|
19
19
|
ProcedureDef,
|
|
20
20
|
ProcedureHandlerOptions,
|
|
21
|
+
MiddlewareNextFnOptions,
|
|
22
|
+
MiddlewareOptions,
|
|
23
|
+
MiddlewareResult,
|
|
21
24
|
RouterBuilder,
|
|
22
25
|
} from "@orpc/server";
|
|
23
|
-
import type {
|
|
26
|
+
import type { MaybeOptionalOptions } from "@orpc/shared";
|
|
27
|
+
import type {
|
|
28
|
+
Context as EffectContext,
|
|
29
|
+
Effect,
|
|
30
|
+
Layer,
|
|
31
|
+
ManagedRuntime,
|
|
32
|
+
Option,
|
|
33
|
+
} from "effect";
|
|
24
34
|
import type { YieldWrap } from "effect/Utils";
|
|
25
35
|
|
|
26
36
|
import type {
|
|
@@ -68,6 +78,8 @@ export interface EffectBuilderDef<
|
|
|
68
78
|
* Effect-extended error map that supports both traditional errors and tagged errors.
|
|
69
79
|
*/
|
|
70
80
|
effectErrorMap: TEffectErrorMap;
|
|
81
|
+
effectSteps?: readonly EffectPipelineStep[];
|
|
82
|
+
effectHandler?: EffectProcedureHandlerConfig;
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
/**
|
|
@@ -92,6 +104,8 @@ export interface EffectProcedureDef<
|
|
|
92
104
|
> {
|
|
93
105
|
runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;
|
|
94
106
|
effectErrorMap: TEffectErrorMap;
|
|
107
|
+
effectSteps?: readonly EffectPipelineStep[];
|
|
108
|
+
effectHandler?: EffectProcedureHandlerConfig;
|
|
95
109
|
}
|
|
96
110
|
|
|
97
111
|
/**
|
|
@@ -139,6 +153,283 @@ export type EffectProcedureHandler<
|
|
|
139
153
|
never
|
|
140
154
|
>;
|
|
141
155
|
|
|
156
|
+
export interface EffectProcedureHandlerConfig {
|
|
157
|
+
readonly effectFn: EffectProcedureHandler<any, any, any, any, any, any>;
|
|
158
|
+
readonly defaultCaptureStackTrace: () => string | undefined;
|
|
159
|
+
readonly spanConfig?: EffectSpanConfig;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type EffectTagService<T extends EffectContext.Tag<any, any>> =
|
|
163
|
+
T extends EffectContext.Tag<any, infer S> ? S : never;
|
|
164
|
+
|
|
165
|
+
export type EffectProvider<
|
|
166
|
+
TCurrentContext extends Context,
|
|
167
|
+
TInput,
|
|
168
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
169
|
+
TRequirementsProvided,
|
|
170
|
+
TMeta extends Meta,
|
|
171
|
+
TTag extends EffectContext.Tag<any, any>,
|
|
172
|
+
> = (
|
|
173
|
+
opt: ProcedureHandlerOptions<
|
|
174
|
+
TCurrentContext,
|
|
175
|
+
TInput,
|
|
176
|
+
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
177
|
+
TMeta
|
|
178
|
+
>,
|
|
179
|
+
) => Effect.Effect<
|
|
180
|
+
EffectTagService<TTag>,
|
|
181
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
182
|
+
TRequirementsProvided
|
|
183
|
+
>;
|
|
184
|
+
|
|
185
|
+
export type EffectOptionalProvider<
|
|
186
|
+
TCurrentContext extends Context,
|
|
187
|
+
TInput,
|
|
188
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
189
|
+
TRequirementsProvided,
|
|
190
|
+
TMeta extends Meta,
|
|
191
|
+
TTag extends EffectContext.Tag<any, any>,
|
|
192
|
+
> = (
|
|
193
|
+
opt: ProcedureHandlerOptions<
|
|
194
|
+
TCurrentContext,
|
|
195
|
+
TInput,
|
|
196
|
+
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
197
|
+
TMeta
|
|
198
|
+
>,
|
|
199
|
+
) => Effect.Effect<
|
|
200
|
+
Option.Option<EffectTagService<TTag>>,
|
|
201
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
202
|
+
TRequirementsProvided
|
|
203
|
+
>;
|
|
204
|
+
|
|
205
|
+
interface EffectMiddlewareNext<
|
|
206
|
+
TOutput,
|
|
207
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
208
|
+
TRequirementsProvided,
|
|
209
|
+
> {
|
|
210
|
+
<UOutContext extends Context = Record<never, never>>(
|
|
211
|
+
...rest: MaybeOptionalOptions<MiddlewareNextFnOptions<UOutContext>>
|
|
212
|
+
): Effect.Effect<
|
|
213
|
+
EffectMiddlewareResult<UOutContext, TOutput>,
|
|
214
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
215
|
+
TRequirementsProvided
|
|
216
|
+
>;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export type EffectMiddlewareResult<TOutContext extends Context, TOutput> = {
|
|
220
|
+
readonly output: TOutput;
|
|
221
|
+
readonly context: TOutContext;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export interface EffectMiddlewareOutput<
|
|
225
|
+
TOutput,
|
|
226
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
227
|
+
TRequirementsProvided,
|
|
228
|
+
> {
|
|
229
|
+
(
|
|
230
|
+
output: TOutput,
|
|
231
|
+
): Effect.Effect<
|
|
232
|
+
EffectMiddlewareResult<Record<never, never>, TOutput>,
|
|
233
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
234
|
+
TRequirementsProvided
|
|
235
|
+
>;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Contextual typing bridge for `.use(...)` overloads.
|
|
240
|
+
*
|
|
241
|
+
* At runtime `next()` is either Effect-native or oRPC-native depending on
|
|
242
|
+
* whether the middleware is a generator function. At type-check time we need
|
|
243
|
+
* inline middleware to support both `return next()` and `yield* next()` without
|
|
244
|
+
* an explicit annotation. The return type is intentionally an intersection:
|
|
245
|
+
* assignable to `PromiseLike<A>` for native middleware, and yieldable as an
|
|
246
|
+
* `Effect<A, E, R>` for Effect middleware.
|
|
247
|
+
*/
|
|
248
|
+
type EffectAndPromiseLike<A, E, R> = Effect.Effect<A, E, R> & PromiseLike<A>;
|
|
249
|
+
|
|
250
|
+
/** A `next` function that can be consumed by native oRPC or Effect middleware. */
|
|
251
|
+
interface EffectOrORPCMiddlewareNext<
|
|
252
|
+
TOutput,
|
|
253
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
254
|
+
TRequirementsProvided,
|
|
255
|
+
> {
|
|
256
|
+
<UOutContext extends Context = Record<never, never>>(
|
|
257
|
+
...rest: MaybeOptionalOptions<MiddlewareNextFnOptions<UOutContext>>
|
|
258
|
+
): EffectAndPromiseLike<
|
|
259
|
+
EffectMiddlewareResult<UOutContext, TOutput>,
|
|
260
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
261
|
+
TRequirementsProvided
|
|
262
|
+
>;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** An `output` helper that can be consumed by native oRPC or Effect middleware. */
|
|
266
|
+
interface EffectOrORPCMiddlewareOutput<
|
|
267
|
+
TOutput,
|
|
268
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
269
|
+
TRequirementsProvided,
|
|
270
|
+
> {
|
|
271
|
+
(
|
|
272
|
+
output: TOutput,
|
|
273
|
+
): EffectAndPromiseLike<
|
|
274
|
+
EffectMiddlewareResult<Record<never, never>, TOutput>,
|
|
275
|
+
EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
|
|
276
|
+
TRequirementsProvided
|
|
277
|
+
>;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Middleware options with the dual-shape `next` used for `.use(...)` inference. */
|
|
281
|
+
type EffectOrORPCMiddlewareOptions<
|
|
282
|
+
TCurrentContext extends Context,
|
|
283
|
+
TOutput,
|
|
284
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
285
|
+
TRequirementsProvided,
|
|
286
|
+
TMeta extends Meta,
|
|
287
|
+
> = Omit<
|
|
288
|
+
MiddlewareOptions<
|
|
289
|
+
TCurrentContext,
|
|
290
|
+
TOutput,
|
|
291
|
+
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
292
|
+
TMeta
|
|
293
|
+
>,
|
|
294
|
+
"next"
|
|
295
|
+
> & {
|
|
296
|
+
readonly next: EffectOrORPCMiddlewareNext<
|
|
297
|
+
TOutput,
|
|
298
|
+
TEffectErrorMap,
|
|
299
|
+
TRequirementsProvided
|
|
300
|
+
>;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Public `.use(...)` middleware shape.
|
|
305
|
+
*
|
|
306
|
+
* Accepts native oRPC middleware returns (`result` / `PromiseLike<result>`) and
|
|
307
|
+
* Effect generator middleware returns. Runtime dispatch still uses
|
|
308
|
+
* `isEffectMiddleware(...)`; this type only makes the inline callback ergonomic.
|
|
309
|
+
*/
|
|
310
|
+
export type EffectOrORPCMiddleware<
|
|
311
|
+
TCurrentContext extends Context,
|
|
312
|
+
TOutContext extends Context,
|
|
313
|
+
TInput,
|
|
314
|
+
TOutput,
|
|
315
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
316
|
+
TRequirementsProvided,
|
|
317
|
+
TMeta extends Meta,
|
|
318
|
+
> = (
|
|
319
|
+
opt: EffectOrORPCMiddlewareOptions<
|
|
320
|
+
TCurrentContext,
|
|
321
|
+
TOutput,
|
|
322
|
+
TEffectErrorMap,
|
|
323
|
+
TRequirementsProvided,
|
|
324
|
+
TMeta
|
|
325
|
+
>,
|
|
326
|
+
input: TInput,
|
|
327
|
+
output: EffectOrORPCMiddlewareOutput<
|
|
328
|
+
TOutput,
|
|
329
|
+
TEffectErrorMap,
|
|
330
|
+
TRequirementsProvided
|
|
331
|
+
>,
|
|
332
|
+
) =>
|
|
333
|
+
| MiddlewareResult<TOutContext, TOutput>
|
|
334
|
+
| PromiseLike<MiddlewareResult<TOutContext, TOutput>>
|
|
335
|
+
| Generator<
|
|
336
|
+
YieldWrap<
|
|
337
|
+
Effect.Effect<
|
|
338
|
+
unknown,
|
|
339
|
+
| EffectErrorMapToUnion<TEffectErrorMap>
|
|
340
|
+
| ORPCError<ORPCErrorCode, unknown>,
|
|
341
|
+
TRequirementsProvided
|
|
342
|
+
>
|
|
343
|
+
>,
|
|
344
|
+
EffectMiddlewareResult<TOutContext, TOutput> | void,
|
|
345
|
+
never
|
|
346
|
+
>;
|
|
347
|
+
|
|
348
|
+
export type EffectMiddlewareOptions<
|
|
349
|
+
TCurrentContext extends Context,
|
|
350
|
+
TOutput,
|
|
351
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
352
|
+
TRequirementsProvided,
|
|
353
|
+
TMeta extends Meta,
|
|
354
|
+
> = Omit<
|
|
355
|
+
MiddlewareOptions<
|
|
356
|
+
TCurrentContext,
|
|
357
|
+
TOutput,
|
|
358
|
+
EffectErrorConstructorMap<TEffectErrorMap>,
|
|
359
|
+
TMeta
|
|
360
|
+
>,
|
|
361
|
+
"next"
|
|
362
|
+
> & {
|
|
363
|
+
readonly next: EffectMiddlewareNext<
|
|
364
|
+
TOutput,
|
|
365
|
+
TEffectErrorMap,
|
|
366
|
+
TRequirementsProvided
|
|
367
|
+
>;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export type EffectMiddleware<
|
|
371
|
+
TCurrentContext extends Context,
|
|
372
|
+
TOutContext extends Context,
|
|
373
|
+
TInput,
|
|
374
|
+
TOutput,
|
|
375
|
+
TEffectErrorMap extends EffectErrorMap,
|
|
376
|
+
TRequirementsProvided,
|
|
377
|
+
TMeta extends Meta,
|
|
378
|
+
> = (
|
|
379
|
+
opt: EffectMiddlewareOptions<
|
|
380
|
+
TCurrentContext,
|
|
381
|
+
TOutput,
|
|
382
|
+
TEffectErrorMap,
|
|
383
|
+
TRequirementsProvided,
|
|
384
|
+
TMeta
|
|
385
|
+
>,
|
|
386
|
+
input: TInput,
|
|
387
|
+
output: EffectMiddlewareOutput<
|
|
388
|
+
TOutput,
|
|
389
|
+
TEffectErrorMap,
|
|
390
|
+
TRequirementsProvided
|
|
391
|
+
>,
|
|
392
|
+
) => Generator<
|
|
393
|
+
YieldWrap<
|
|
394
|
+
Effect.Effect<
|
|
395
|
+
unknown,
|
|
396
|
+
| EffectErrorMapToUnion<TEffectErrorMap>
|
|
397
|
+
| ORPCError<ORPCErrorCode, unknown>,
|
|
398
|
+
TRequirementsProvided
|
|
399
|
+
>
|
|
400
|
+
>,
|
|
401
|
+
EffectMiddlewareResult<TOutContext, TOutput> | void,
|
|
402
|
+
never
|
|
403
|
+
>;
|
|
404
|
+
|
|
405
|
+
type EffectProvideStep = {
|
|
406
|
+
readonly _tag: "provide";
|
|
407
|
+
readonly tag: EffectContext.Tag<any, any>;
|
|
408
|
+
readonly provider: EffectProvider<any, any, any, any, any, any>;
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
type EffectProvideOptionalStep = {
|
|
412
|
+
readonly _tag: "provideOptional";
|
|
413
|
+
readonly tag: EffectContext.Tag<any, any>;
|
|
414
|
+
readonly provider: EffectOptionalProvider<any, any, any, any, any, any>;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
type EffectProvideLayerStep = {
|
|
418
|
+
readonly _tag: "provideLayer";
|
|
419
|
+
readonly layer: Layer.Layer<any, any, any>;
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
type EffectMiddlewareStep = {
|
|
423
|
+
readonly _tag: "middleware";
|
|
424
|
+
readonly middleware: EffectMiddleware<any, any, any, any, any, any, any>;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export type EffectPipelineStep =
|
|
428
|
+
| EffectProvideStep
|
|
429
|
+
| EffectProvideOptionalStep
|
|
430
|
+
| EffectProvideLayerStep
|
|
431
|
+
| EffectMiddlewareStep;
|
|
432
|
+
|
|
142
433
|
export type EffectErrorMapToErrorMap<T extends EffectErrorMap> = {
|
|
143
434
|
[K in keyof T as T[K] extends ErrorMapItem<AnySchema>
|
|
144
435
|
? K extends ORPCErrorCode
|