effect-orpc 0.2.2 → 0.4.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 +225 -105
- package/dist/{chunk-VOWRLWZZ.js → chunk-IJP6L2XR.js} +6 -2
- package/dist/chunk-IJP6L2XR.js.map +1 -0
- package/dist/index.js +770 -282
- 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 +46 -11
- package/src/effect-builder.ts +295 -33
- package/src/effect-enhance-router.ts +3 -3
- package/src/effect-procedure.ts +205 -11
- package/src/effect-runtime.ts +445 -23
- package/src/extension/create-node-proxy.ts +17 -1
- package/src/extension/state.ts +16 -20
- package/src/fiber-context-bridge.ts +13 -0
- package/src/index.ts +1 -0
- package/src/node.ts +2 -1
- package/src/runtime-source.ts +76 -0
- package/src/tagged-error.ts +1 -10
- package/src/tests/contract.test.ts +21 -0
- package/src/tests/effect-builder.proxy.test.ts +4 -4
- package/src/tests/effect-builder.test.ts +544 -7
- package/src/tests/effect-error-map.test.ts +10 -10
- package/src/tests/effect-procedure.test.ts +9 -6
- 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 +117 -1
- package/src/types/effect-procedure-surface.ts +98 -1
- package/src/types/index.ts +291 -5
- package/src/types/variants.ts +351 -18
- package/dist/chunk-VOWRLWZZ.js.map +0 -1
|
@@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
4
4
|
import z from "zod";
|
|
5
5
|
|
|
6
6
|
import { EffectDecoratedProcedure } from "../effect-procedure";
|
|
7
|
+
import { makeEffectRuntimeRunner } from "../runtime-source";
|
|
7
8
|
import {
|
|
8
9
|
baseErrorMap,
|
|
9
10
|
baseMeta,
|
|
@@ -25,6 +26,7 @@ vi.mock("@orpc/server", async (importOriginal) => {
|
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
const runtime = ManagedRuntime.make(Layer.empty);
|
|
29
|
+
const runner = makeEffectRuntimeRunner(runtime);
|
|
28
30
|
|
|
29
31
|
const handler = vi.fn();
|
|
30
32
|
const middleware = vi.fn();
|
|
@@ -40,6 +42,7 @@ const def = {
|
|
|
40
42
|
meta: baseMeta,
|
|
41
43
|
route: baseRoute,
|
|
42
44
|
handler,
|
|
45
|
+
runner,
|
|
43
46
|
runtime,
|
|
44
47
|
};
|
|
45
48
|
|
|
@@ -80,7 +83,7 @@ describe("effectDecoratedProcedure", () => {
|
|
|
80
83
|
});
|
|
81
84
|
|
|
82
85
|
// Preserves runtime
|
|
83
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
86
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
84
87
|
});
|
|
85
88
|
|
|
86
89
|
it(".meta", () => {
|
|
@@ -96,7 +99,7 @@ describe("effectDecoratedProcedure", () => {
|
|
|
96
99
|
});
|
|
97
100
|
|
|
98
101
|
// Preserves runtime
|
|
99
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
102
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
100
103
|
});
|
|
101
104
|
|
|
102
105
|
it(".route", () => {
|
|
@@ -112,7 +115,7 @@ describe("effectDecoratedProcedure", () => {
|
|
|
112
115
|
});
|
|
113
116
|
|
|
114
117
|
// Preserves runtime
|
|
115
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
118
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
116
119
|
});
|
|
117
120
|
|
|
118
121
|
describe(".use", () => {
|
|
@@ -129,7 +132,7 @@ describe("effectDecoratedProcedure", () => {
|
|
|
129
132
|
});
|
|
130
133
|
|
|
131
134
|
// Preserves runtime
|
|
132
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
135
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
133
136
|
});
|
|
134
137
|
|
|
135
138
|
it("with map input", () => {
|
|
@@ -146,7 +149,7 @@ describe("effectDecoratedProcedure", () => {
|
|
|
146
149
|
});
|
|
147
150
|
|
|
148
151
|
// Preserves runtime
|
|
149
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
152
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
150
153
|
});
|
|
151
154
|
});
|
|
152
155
|
|
|
@@ -207,7 +210,7 @@ describe("effectDecoratedProcedure chaining", () => {
|
|
|
207
210
|
.route({ path: "/custom" });
|
|
208
211
|
|
|
209
212
|
expect(applied).toBeInstanceOf(EffectDecoratedProcedure);
|
|
210
|
-
expect(applied["~effect"].runtime).toBe(runtime);
|
|
213
|
+
expect(applied["~effect"].runner.runtime).toBe(runtime);
|
|
211
214
|
expect(applied["~effect"].errorMap).toHaveProperty("CUSTOM");
|
|
212
215
|
});
|
|
213
216
|
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
async function makeSplitProcedure(options: {
|
|
4
|
+
readonly installNodeBridge: boolean;
|
|
5
|
+
}) {
|
|
6
|
+
vi.resetModules();
|
|
7
|
+
|
|
8
|
+
if (options.installNodeBridge) {
|
|
9
|
+
await import("../node");
|
|
10
|
+
} else {
|
|
11
|
+
const { installFiberContextBridge } =
|
|
12
|
+
await import("../fiber-context-bridge");
|
|
13
|
+
installFiberContextBridge(undefined);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const [
|
|
17
|
+
{ call },
|
|
18
|
+
{ Context, Effect, Layer, ManagedRuntime },
|
|
19
|
+
{ makeEffectORPC },
|
|
20
|
+
] = await Promise.all([
|
|
21
|
+
import("@orpc/server"),
|
|
22
|
+
import("effect"),
|
|
23
|
+
import("../effect-builder"),
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
class CurrentUser extends Context.Tag("SideEffectImportCurrentUser")<
|
|
27
|
+
CurrentUser,
|
|
28
|
+
{ readonly id: string }
|
|
29
|
+
>() {}
|
|
30
|
+
|
|
31
|
+
const runtime = ManagedRuntime.make(Layer.empty);
|
|
32
|
+
const runPromiseExit = vi.spyOn(runtime, "runPromiseExit");
|
|
33
|
+
const procedure = makeEffectORPC(runtime)
|
|
34
|
+
.$context<{ readonly user: { readonly id: string } }>()
|
|
35
|
+
.provide(CurrentUser, ({ context }) => Effect.succeed(context.user))
|
|
36
|
+
.use(function* ({ next }) {
|
|
37
|
+
return yield* next();
|
|
38
|
+
})
|
|
39
|
+
.use(({ next }) => next())
|
|
40
|
+
.use(function* ({ next }) {
|
|
41
|
+
const user = yield* CurrentUser;
|
|
42
|
+
return yield* next({ context: { userId: user.id } });
|
|
43
|
+
})
|
|
44
|
+
.effect(function* ({ context }) {
|
|
45
|
+
const user = yield* CurrentUser;
|
|
46
|
+
return `${context.userId}:${user.id}`;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return { call, procedure, runPromiseExit, runtime };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
describe("node side-effect bridge", () => {
|
|
53
|
+
it("propagates FiberRefs across split Effect groups with only the side-effect import", async () => {
|
|
54
|
+
const { call, procedure, runPromiseExit, runtime } =
|
|
55
|
+
await makeSplitProcedure({ installNodeBridge: true });
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await expect(
|
|
59
|
+
call(procedure, undefined, { context: { user: { id: "u-side" } } }),
|
|
60
|
+
).resolves.toBe("u-side:u-side");
|
|
61
|
+
expect(runPromiseExit).toHaveBeenCalledTimes(2);
|
|
62
|
+
} finally {
|
|
63
|
+
await runtime.dispose();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("does not propagate FiberRefs across split Effect groups without the bridge", async () => {
|
|
68
|
+
const { call, procedure, runPromiseExit, runtime } =
|
|
69
|
+
await makeSplitProcedure({ installNodeBridge: false });
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await expect(
|
|
73
|
+
call(procedure, undefined, { context: { user: { id: "u-side" } } }),
|
|
74
|
+
).rejects.toThrow();
|
|
75
|
+
expect(runPromiseExit).toHaveBeenCalledTimes(2);
|
|
76
|
+
} finally {
|
|
77
|
+
await runtime.dispose();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -42,9 +42,16 @@ const rootBuilder = makeEffectORPC(runtime)
|
|
|
42
42
|
.$input(inputSchema)
|
|
43
43
|
.errors(baseErrorMap);
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const authMiddleware: Middleware<
|
|
46
|
+
InitialContext,
|
|
47
|
+
{ auth: boolean },
|
|
48
|
+
{ input: string },
|
|
49
|
+
unknown,
|
|
50
|
+
any,
|
|
51
|
+
BaseMeta
|
|
52
|
+
> = ({ next }) => next({ context: { auth: true as boolean } });
|
|
53
|
+
|
|
54
|
+
const withMiddlewares = rootBuilder.use(authMiddleware);
|
|
48
55
|
|
|
49
56
|
const procedureBuilder = withMiddlewares.meta(baseMeta);
|
|
50
57
|
const withInput = procedureBuilder.input(inputSchema);
|
|
@@ -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.
|
|
@@ -358,7 +474,7 @@ export interface EffectBuilderSurface<
|
|
|
358
474
|
>;
|
|
359
475
|
/**
|
|
360
476
|
* Defines the handler of the procedure using an Effect.
|
|
361
|
-
* The Effect is executed using the
|
|
477
|
+
* The Effect is executed using the configured Effect runtime source.
|
|
362
478
|
* The effect is automatically wrapped with `Effect.withSpan`.
|
|
363
479
|
*
|
|
364
480
|
* @see {@link https://orpc.dev/docs/procedure Procedure Docs}
|
|
@@ -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
|
*
|