effect-orpc 0.3.0 → 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 +63 -64
- package/dist/index.js +78 -60
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/contract.ts +15 -12
- package/src/effect-builder.ts +28 -19
- package/src/effect-enhance-router.ts +3 -3
- package/src/effect-procedure.ts +7 -7
- package/src/effect-runtime.ts +27 -37
- package/src/extension/state.ts +3 -5
- package/src/index.ts +1 -0
- package/src/runtime-source.ts +70 -12
- package/src/tagged-error.ts +1 -1
- package/src/tests/contract.test.ts +5 -8
- package/src/tests/effect-builder.proxy.test.ts +4 -4
- package/src/tests/effect-builder.test.ts +56 -22
- package/src/tests/effect-error-map.test.ts +10 -10
- package/src/tests/effect-procedure.test.ts +9 -6
- package/src/types/effect-builder-surface.ts +1 -1
- package/src/types/index.ts +6 -11
- package/src/types/variants.ts +5 -5
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Runnable demos live in the repository's `examples/` directory.
|
|
|
30
30
|
```ts
|
|
31
31
|
import { os } from "@orpc/server";
|
|
32
32
|
import { Effect, ManagedRuntime } from "effect";
|
|
33
|
-
import { makeEffectORPC, ORPCTaggedError } from "effect-orpc";
|
|
33
|
+
import { eos, makeEffectORPC, ORPCTaggedError } from "effect-orpc";
|
|
34
34
|
|
|
35
35
|
interface User {
|
|
36
36
|
id: number;
|
|
@@ -43,15 +43,6 @@ let users: User[] = [
|
|
|
43
43
|
{ id: 3, name: "James Dane" },
|
|
44
44
|
];
|
|
45
45
|
|
|
46
|
-
// Authenticated os with initial context & errors set
|
|
47
|
-
const authedOs = os
|
|
48
|
-
.errors({ UNAUTHORIZED: { status: 401 } })
|
|
49
|
-
.$context<{ userId?: number }>()
|
|
50
|
-
.use(({ context, errors, next }) => {
|
|
51
|
-
if (context.userId === undefined) throw errors.UNAUTHORIZED();
|
|
52
|
-
return next({ context: { ...context, userId: context.userId } });
|
|
53
|
-
});
|
|
54
|
-
|
|
55
46
|
// Define your services
|
|
56
47
|
class UsersRepo extends Effect.Service<UsersRepo>()("UsersRepo", {
|
|
57
48
|
accessors: true,
|
|
@@ -65,26 +56,27 @@ class UserNotFoundError extends ORPCTaggedError("UserNotFoundError", {
|
|
|
65
56
|
status: 404,
|
|
66
57
|
}) {}
|
|
67
58
|
|
|
68
|
-
// Create an Effect-aware oRPC builder with your service layer,
|
|
69
|
-
//
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
})
|
|
59
|
+
// Create an Effect-aware oRPC builder with your service layer, context, errors,
|
|
60
|
+
// and middleware.
|
|
61
|
+
const effectProcedure = eos
|
|
62
|
+
.provide(UsersRepo.Default)
|
|
63
|
+
.errors({ UNAUTHORIZED: { status: 401 }, UserNotFoundError })
|
|
64
|
+
.$context<{ userId?: number }>()
|
|
65
|
+
.use(({ context, errors, next }) => {
|
|
66
|
+
if (context.userId === undefined) throw errors.UNAUTHORIZED();
|
|
67
|
+
return next({ context: { ...context, userId: context.userId } });
|
|
68
|
+
});
|
|
73
69
|
|
|
74
|
-
//
|
|
70
|
+
// Use ManagedRuntime only when scoped resources should be acquired once and
|
|
71
|
+
// released on shutdown, for example a shared cache, database pool, or telemetry SDK:
|
|
75
72
|
// const runtime = ManagedRuntime.make(UsersRepo.Default);
|
|
76
|
-
// const
|
|
77
|
-
|
|
78
|
-
// Or start with only the builder and provide the layer later:
|
|
79
|
-
// const effectOs = makeEffectORPC(authedOs)
|
|
80
|
-
// .provide(UsersRepo.Default)
|
|
81
|
-
// .errors({ UserNotFoundError });
|
|
73
|
+
// const effectProcedure = makeEffectORPC(runtime).errors({ UserNotFoundError });
|
|
82
74
|
|
|
83
75
|
// Create the router with mixed procedures
|
|
84
76
|
export const router = {
|
|
85
77
|
health: os.handler(() => "ok"),
|
|
86
78
|
users: {
|
|
87
|
-
me:
|
|
79
|
+
me: effectProcedure.effect(function* ({ context: { userId } }) {
|
|
88
80
|
const user = yield* UsersRepo.get(userId);
|
|
89
81
|
if (!user) {
|
|
90
82
|
return yield* new UserNotFoundError();
|
|
@@ -103,7 +95,7 @@ The wrapper enforces that Effect procedures only use services provided by `.prov
|
|
|
103
95
|
|
|
104
96
|
```ts
|
|
105
97
|
import { Context, Effect, Layer } from "effect";
|
|
106
|
-
import {
|
|
98
|
+
import { eos } from "effect-orpc";
|
|
107
99
|
|
|
108
100
|
class ProvidedService extends Context.Tag("ProvidedService")<
|
|
109
101
|
ProvidedService,
|
|
@@ -119,16 +111,16 @@ const AppLive = Layer.succeed(ProvidedService, {
|
|
|
119
111
|
doSomething: () => Effect.succeed("ok"),
|
|
120
112
|
});
|
|
121
113
|
|
|
122
|
-
const
|
|
114
|
+
const effectProcedure = eos.provide(AppLive);
|
|
123
115
|
|
|
124
116
|
// ✅ This compiles - ProvidedService is provided by AppLive
|
|
125
|
-
const works =
|
|
117
|
+
const works = effectProcedure.effect(function* () {
|
|
126
118
|
const service = yield* ProvidedService;
|
|
127
119
|
return yield* service.doSomething();
|
|
128
120
|
});
|
|
129
121
|
|
|
130
122
|
// ❌ This fails to compile - MissingService is not provided
|
|
131
|
-
const fails =
|
|
123
|
+
const fails = effectProcedure.effect(function* () {
|
|
132
124
|
const service = yield* MissingService; // Type error!
|
|
133
125
|
return yield* service.doSomething();
|
|
134
126
|
});
|
|
@@ -145,7 +137,7 @@ const fails = effectOs.effect(function* () {
|
|
|
145
137
|
Make sure the tagged error class is passed to the effect `.errors()` to be able to yield the error class directly and make the client recognize it as defined.
|
|
146
138
|
|
|
147
139
|
```ts
|
|
148
|
-
const getUser =
|
|
140
|
+
const getUser = effectProcedure
|
|
149
141
|
// Mixed error maps
|
|
150
142
|
.errors({
|
|
151
143
|
// Regular oRPC error
|
|
@@ -214,19 +206,19 @@ All Effect procedures are automatically traced with `Effect.withSpan`. By defaul
|
|
|
214
206
|
const router = {
|
|
215
207
|
users: {
|
|
216
208
|
// Span name: "users.get"
|
|
217
|
-
get:
|
|
209
|
+
get: effectProcedure.input(z.object({ id: z.string() })).effect(function* ({
|
|
218
210
|
input,
|
|
219
211
|
}) {
|
|
220
212
|
const userService = yield* UserService;
|
|
221
213
|
return yield* userService.findById(input.id);
|
|
222
214
|
}),
|
|
223
215
|
// Span name: "users.create"
|
|
224
|
-
create:
|
|
225
|
-
input
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
216
|
+
create: effectProcedure
|
|
217
|
+
.input(z.object({ name: z.string() }))
|
|
218
|
+
.effect(function* ({ input }) {
|
|
219
|
+
const userService = yield* UserService;
|
|
220
|
+
return yield* userService.create(input.name);
|
|
221
|
+
}),
|
|
230
222
|
},
|
|
231
223
|
};
|
|
232
224
|
```
|
|
@@ -234,7 +226,7 @@ const router = {
|
|
|
234
226
|
Use `.traced()` to override the default span name:
|
|
235
227
|
|
|
236
228
|
```ts
|
|
237
|
-
const getUser =
|
|
229
|
+
const getUser = effectProcedure
|
|
238
230
|
.input(z.object({ id: z.string() }))
|
|
239
231
|
.traced("custom.span.name") // Override the default path-based name
|
|
240
232
|
.effect(function* ({ input }) {
|
|
@@ -261,7 +253,7 @@ const TracingLive = NodeSdk.layer(
|
|
|
261
253
|
|
|
262
254
|
const AppLive = Layer.mergeAll(UserServiceLive, TracingLive);
|
|
263
255
|
|
|
264
|
-
const
|
|
256
|
+
const effectProcedure = eos.provide(AppLive);
|
|
265
257
|
```
|
|
266
258
|
|
|
267
259
|
### Error Stack Traces
|
|
@@ -283,7 +275,7 @@ middleware. Two patterns are supported:
|
|
|
283
275
|
automatically (no need to call `next`):
|
|
284
276
|
|
|
285
277
|
```ts
|
|
286
|
-
|
|
278
|
+
effectProcedure.use(function* () {
|
|
287
279
|
const user = yield* CurrentUser;
|
|
288
280
|
yield* requireActiveUser(user);
|
|
289
281
|
});
|
|
@@ -293,7 +285,7 @@ effectOs.use(function* () {
|
|
|
293
285
|
middleware that uses `return next(...)`, use `return yield* next(...)`:
|
|
294
286
|
|
|
295
287
|
```ts
|
|
296
|
-
|
|
288
|
+
effectProcedure.use(function* ({ next }) {
|
|
297
289
|
const user = yield* CurrentUser;
|
|
298
290
|
yield* requireActiveUser(user);
|
|
299
291
|
|
|
@@ -306,7 +298,7 @@ effectOs.use(function* ({ next }) {
|
|
|
306
298
|
To transform the downstream output, capture `next()` and pass through `output`:
|
|
307
299
|
|
|
308
300
|
```ts
|
|
309
|
-
|
|
301
|
+
effectProcedure.use(function* ({ next }, _input, output) {
|
|
310
302
|
const result = yield* next();
|
|
311
303
|
return yield* output(`${result.output}-wrapped`);
|
|
312
304
|
});
|
|
@@ -323,7 +315,8 @@ Effect-native steps are `.provide(...)`, `.provideOptional(...)`, generator
|
|
|
323
315
|
`.use(function* ...)`, and `.effect(function* ...)`.
|
|
324
316
|
|
|
325
317
|
```ts
|
|
326
|
-
|
|
318
|
+
eos
|
|
319
|
+
.provide(AppLive)
|
|
327
320
|
.provide(CurrentUser, ({ context }) => Effect.succeed(context.user))
|
|
328
321
|
.use(function* ({ next }) {
|
|
329
322
|
const user = yield* CurrentUser;
|
|
@@ -336,13 +329,14 @@ makeEffectORPC(AppLive)
|
|
|
336
329
|
```
|
|
337
330
|
|
|
338
331
|
The example above runs the provider, middleware, and handler inside a single
|
|
339
|
-
|
|
332
|
+
Effect execution boundary.
|
|
340
333
|
|
|
341
334
|
A native oRPC middleware breaks the contiguous Effect pipeline. Pending Effect
|
|
342
335
|
steps are flushed into one generated oRPC middleware before the native middleware:
|
|
343
336
|
|
|
344
337
|
```ts
|
|
345
|
-
|
|
338
|
+
eos
|
|
339
|
+
.provide(AppLive)
|
|
346
340
|
.provide(CurrentUser, getCurrentUser) // Effect group #1
|
|
347
341
|
.use(function* ({ next }) {
|
|
348
342
|
return yield* next();
|
|
@@ -370,10 +364,11 @@ Effect group #2.
|
|
|
370
364
|
|
|
371
365
|
Procedure-level `.provide*` after a native `.handler(...)` has no Effect handler
|
|
372
366
|
boundary to attach to, so it is installed as an oRPC middleware that runs its
|
|
373
|
-
provider Effect through the runtime:
|
|
367
|
+
provider Effect through the configured runtime source:
|
|
374
368
|
|
|
375
369
|
```ts
|
|
376
|
-
|
|
370
|
+
eos
|
|
371
|
+
.provide(AppLive)
|
|
377
372
|
.handler(() => "ok") // native oRPC handler
|
|
378
373
|
.provide(CurrentUser, getCurrentUser); // fallback provider middleware
|
|
379
374
|
```
|
|
@@ -397,10 +392,10 @@ oRPC pipeline and should be visible inside handlers:
|
|
|
397
392
|
```ts
|
|
398
393
|
import { Hono } from "hono";
|
|
399
394
|
import { Effect } from "effect";
|
|
400
|
-
import {
|
|
395
|
+
import { eos } from "effect-orpc";
|
|
401
396
|
import { withFiberContext } from "effect-orpc/node";
|
|
402
397
|
|
|
403
|
-
const
|
|
398
|
+
const effectProcedure = eos.provide(AppLive);
|
|
404
399
|
const app = new Hono();
|
|
405
400
|
|
|
406
401
|
app.use("*", async (c, next) => {
|
|
@@ -432,8 +427,8 @@ relies on `AsyncLocalStorage` from `node:async_hooks`.
|
|
|
432
427
|
|
|
433
428
|
Use `implementEffect(contract, layerOrRuntime)` when you already have an oRPC
|
|
434
429
|
contract and want to keep contract-first enforcement while adding Effect-native
|
|
435
|
-
handlers. Use `
|
|
436
|
-
|
|
430
|
+
handlers. Use `eos.provide(layer)` when you want to build procedures directly
|
|
431
|
+
from the default Effect-aware builder.
|
|
437
432
|
|
|
438
433
|
```ts
|
|
439
434
|
import { Effect } from "effect";
|
|
@@ -478,29 +473,33 @@ directly from the `ORPCTaggedError` class.
|
|
|
478
473
|
|
|
479
474
|
## API Reference
|
|
480
475
|
|
|
481
|
-
### `
|
|
476
|
+
### `eos`
|
|
482
477
|
|
|
483
|
-
|
|
484
|
-
|
|
478
|
+
The default Effect-aware procedure builder. Provide your application services
|
|
479
|
+
with `.provide(layer)`:
|
|
485
480
|
|
|
486
|
-
|
|
481
|
+
```ts
|
|
482
|
+
const effectProcedure = eos.provide(AppLive);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Use `makeEffectORPC(runtime)` when a scoped `Layer` should be acquired once and
|
|
486
|
+
released by your application shutdown path, such as a shared cache, database
|
|
487
|
+
pool, HTTP client, or telemetry SDK:
|
|
487
488
|
|
|
488
489
|
```ts
|
|
489
|
-
|
|
490
|
-
|
|
490
|
+
const runtime = ManagedRuntime.make(AppLive);
|
|
491
|
+
|
|
492
|
+
const effectProcedure = makeEffectORPC(runtime);
|
|
491
493
|
|
|
492
|
-
//
|
|
493
|
-
|
|
494
|
+
// later, during app shutdown
|
|
495
|
+
await runtime.dispose();
|
|
494
496
|
```
|
|
495
497
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
+
`makeEffectORPC(builder)` is also available when you need to wrap an existing
|
|
499
|
+
oRPC builder:
|
|
498
500
|
|
|
499
501
|
```ts
|
|
500
|
-
const
|
|
501
|
-
const effectAuthedOsWithProvidedLayer =
|
|
502
|
-
makeEffectORPC(authedBuilder).provide(AppLive);
|
|
503
|
-
const effectOsFromRuntime = makeEffectORPC(runtime);
|
|
502
|
+
const effectAuthedOs = makeEffectORPC(authedBuilder).provide(AppLive);
|
|
504
503
|
```
|
|
505
504
|
|
|
506
505
|
### `implementEffect(contract, layerOrRuntime)`
|
|
@@ -508,7 +507,7 @@ const effectOsFromRuntime = makeEffectORPC(runtime);
|
|
|
508
507
|
Creates an Effect-aware contract implementer.
|
|
509
508
|
|
|
510
509
|
- `contract` - An oRPC contract router built with `oc`
|
|
511
|
-
- `layerOrRuntime` - A `Layer<R, E, never>` or `ManagedRuntime<R, E>`
|
|
510
|
+
- `layerOrRuntime` - A `Layer<R, E, never>` provided per call, or a user-owned `ManagedRuntime<R, E>` when the application should control acquisition and release (for example, a shared cache, database pool, or telemetry SDK)
|
|
512
511
|
|
|
513
512
|
Returns a contract-shaped implementer tree whose leaves support `.effect(...)`.
|
|
514
513
|
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ import { Layer } from "effect";
|
|
|
39
39
|
|
|
40
40
|
// src/effect-runtime.ts
|
|
41
41
|
import { ORPCError as ORPCError2 } from "@orpc/contract";
|
|
42
|
-
import { Cause as Cause2, Effect, Exit,
|
|
42
|
+
import { Cause as Cause2, Effect, Exit, Option } from "effect";
|
|
43
43
|
|
|
44
44
|
// src/tagged-error.ts
|
|
45
45
|
import {
|
|
@@ -211,7 +211,7 @@ function toORPCErrorFromCause(cause) {
|
|
|
211
211
|
}
|
|
212
212
|
function createEffectProcedureHandler(options) {
|
|
213
213
|
const {
|
|
214
|
-
|
|
214
|
+
runner,
|
|
215
215
|
effectErrorMap,
|
|
216
216
|
effectFn,
|
|
217
217
|
effectSteps = [],
|
|
@@ -246,10 +246,9 @@ function createEffectProcedureHandler(options) {
|
|
|
246
246
|
spanName,
|
|
247
247
|
{ captureStackTrace }
|
|
248
248
|
);
|
|
249
|
-
const exit = await
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
);
|
|
249
|
+
const exit = await runner.runPromiseExit(tracedEffect, {
|
|
250
|
+
signal: opts.signal
|
|
251
|
+
});
|
|
253
252
|
if (Exit.isFailure(exit)) {
|
|
254
253
|
throw toORPCErrorFromCause(exit.cause);
|
|
255
254
|
}
|
|
@@ -257,7 +256,7 @@ function createEffectProcedureHandler(options) {
|
|
|
257
256
|
};
|
|
258
257
|
}
|
|
259
258
|
function createEffectPipelineMiddleware(options) {
|
|
260
|
-
const {
|
|
259
|
+
const { runner, effectErrorMap, steps } = options;
|
|
261
260
|
return async (opts, input) => {
|
|
262
261
|
const baseOptions = makeEffectOptions(opts, input, effectErrorMap);
|
|
263
262
|
const effect = runEffectPipeline({
|
|
@@ -271,16 +270,15 @@ function createEffectPipelineMiddleware(options) {
|
|
|
271
270
|
input,
|
|
272
271
|
steps
|
|
273
272
|
});
|
|
274
|
-
const exit = await
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
);
|
|
273
|
+
const exit = await runner.runPromiseExit(effect, {
|
|
274
|
+
signal: opts.signal
|
|
275
|
+
});
|
|
278
276
|
if (Exit.isFailure(exit)) throw toORPCErrorFromCause(exit.cause);
|
|
279
277
|
return exit.value;
|
|
280
278
|
};
|
|
281
279
|
}
|
|
282
280
|
function createEffectProviderMiddleware(options) {
|
|
283
|
-
const {
|
|
281
|
+
const { runner, effectErrorMap, tag, provider } = options;
|
|
284
282
|
return async (opts, input) => {
|
|
285
283
|
const effectOpts = makeEffectOptions(opts, input, effectErrorMap);
|
|
286
284
|
const effect = Effect.flatMap(
|
|
@@ -291,7 +289,7 @@ function createEffectProviderMiddleware(options) {
|
|
|
291
289
|
service
|
|
292
290
|
)
|
|
293
291
|
);
|
|
294
|
-
const exit = await
|
|
292
|
+
const exit = await runner.runPromiseExit(effect, {
|
|
295
293
|
signal: opts.signal
|
|
296
294
|
});
|
|
297
295
|
if (Exit.isFailure(exit)) throw toORPCErrorFromCause(exit.cause);
|
|
@@ -299,7 +297,7 @@ function createEffectProviderMiddleware(options) {
|
|
|
299
297
|
};
|
|
300
298
|
}
|
|
301
299
|
function createEffectOptionalProviderMiddleware(options) {
|
|
302
|
-
const {
|
|
300
|
+
const { runner, effectErrorMap, tag, provider } = options;
|
|
303
301
|
return async (opts, input) => {
|
|
304
302
|
const effectOpts = makeEffectOptions(opts, input, effectErrorMap);
|
|
305
303
|
const effect = Effect.flatMap(
|
|
@@ -313,7 +311,7 @@ function createEffectOptionalProviderMiddleware(options) {
|
|
|
313
311
|
)
|
|
314
312
|
})
|
|
315
313
|
);
|
|
316
|
-
const exit = await
|
|
314
|
+
const exit = await runner.runPromiseExit(effect, {
|
|
317
315
|
signal: opts.signal
|
|
318
316
|
});
|
|
319
317
|
if (Exit.isFailure(exit)) throw toORPCErrorFromCause(exit.cause);
|
|
@@ -445,17 +443,6 @@ function withCurrentFiberContext(fn) {
|
|
|
445
443
|
)
|
|
446
444
|
);
|
|
447
445
|
}
|
|
448
|
-
function withParentFiberRefs(effect) {
|
|
449
|
-
const parentFiberRefs = getCurrentFiberRefs();
|
|
450
|
-
return parentFiberRefs ? Effect.fiberIdWith(
|
|
451
|
-
(fiberId) => Effect.flatMap(
|
|
452
|
-
Effect.getFiberRefs,
|
|
453
|
-
(fiberRefs) => Effect.setFiberRefs(
|
|
454
|
-
FiberRefs.joinAs(fiberRefs, fiberId, parentFiberRefs)
|
|
455
|
-
).pipe(Effect.andThen(effect))
|
|
456
|
-
)
|
|
457
|
-
) : effect;
|
|
458
|
-
}
|
|
459
446
|
|
|
460
447
|
// src/extension/compose-surfaces.ts
|
|
461
448
|
function composeSurfaceProxy(surface, target) {
|
|
@@ -668,7 +655,7 @@ function getEffectProcedureDef(context) {
|
|
|
668
655
|
effectSteps: context.state.effectSteps,
|
|
669
656
|
effectHandler: context.state.effectHandler,
|
|
670
657
|
effectErrorMap: context.state.effectErrorMap,
|
|
671
|
-
|
|
658
|
+
runner: context.state.runner
|
|
672
659
|
};
|
|
673
660
|
}
|
|
674
661
|
function makeEffectProcedureHandler(def) {
|
|
@@ -680,7 +667,7 @@ function makeEffectProcedureHandler(def) {
|
|
|
680
667
|
effectErrorMap: def.effectErrorMap,
|
|
681
668
|
effectFn: def.effectHandler.effectFn,
|
|
682
669
|
effectSteps: def.effectSteps,
|
|
683
|
-
|
|
670
|
+
runner: def.runner,
|
|
684
671
|
spanConfig: def.effectHandler.spanConfig
|
|
685
672
|
});
|
|
686
673
|
}
|
|
@@ -702,7 +689,7 @@ function flushEffectSteps(def) {
|
|
|
702
689
|
}
|
|
703
690
|
const middleware = createEffectPipelineMiddleware({
|
|
704
691
|
effectErrorMap: def.effectErrorMap,
|
|
705
|
-
|
|
692
|
+
runner: def.runner,
|
|
706
693
|
steps: def.effectSteps
|
|
707
694
|
});
|
|
708
695
|
return withRebuiltEffectHandler({
|
|
@@ -770,7 +757,7 @@ function createEffectProcedureProxy(target, decorated) {
|
|
|
770
757
|
def.middlewares,
|
|
771
758
|
createEffectPipelineMiddleware({
|
|
772
759
|
effectErrorMap: state.effectErrorMap,
|
|
773
|
-
|
|
760
|
+
runner: state.runner,
|
|
774
761
|
steps: [step]
|
|
775
762
|
})
|
|
776
763
|
)
|
|
@@ -792,7 +779,7 @@ function createEffectProcedureProxy(target, decorated) {
|
|
|
792
779
|
createEffectProviderMiddleware({
|
|
793
780
|
effectErrorMap: state.effectErrorMap,
|
|
794
781
|
provider,
|
|
795
|
-
|
|
782
|
+
runner: state.runner,
|
|
796
783
|
tag: tagOrLayer
|
|
797
784
|
})
|
|
798
785
|
)
|
|
@@ -819,7 +806,7 @@ function createEffectProcedureProxy(target, decorated) {
|
|
|
819
806
|
createEffectOptionalProviderMiddleware({
|
|
820
807
|
effectErrorMap: state.effectErrorMap,
|
|
821
808
|
provider,
|
|
822
|
-
|
|
809
|
+
runner: state.runner,
|
|
823
810
|
tag
|
|
824
811
|
})
|
|
825
812
|
)
|
|
@@ -885,7 +872,7 @@ var EffectProcedure = class _EffectProcedure extends Procedure {
|
|
|
885
872
|
effectSteps,
|
|
886
873
|
effectHandler,
|
|
887
874
|
effectErrorMap: def.effectErrorMap,
|
|
888
|
-
|
|
875
|
+
runner: def.runner
|
|
889
876
|
});
|
|
890
877
|
if (new.target === _EffectProcedure) {
|
|
891
878
|
return createEffectProcedureProxy(this, false);
|
|
@@ -940,7 +927,7 @@ function enhanceEffectRouter(router, options) {
|
|
|
940
927
|
middlewares,
|
|
941
928
|
inputValidationIndex: source["~orpc"].inputValidationIndex + newMiddlewareAdded,
|
|
942
929
|
outputValidationIndex: source["~orpc"].outputValidationIndex + newMiddlewareAdded,
|
|
943
|
-
|
|
930
|
+
runner: options.runner
|
|
944
931
|
});
|
|
945
932
|
}
|
|
946
933
|
const enhanced = {};
|
|
@@ -951,11 +938,42 @@ function enhanceEffectRouter(router, options) {
|
|
|
951
938
|
}
|
|
952
939
|
|
|
953
940
|
// src/runtime-source.ts
|
|
954
|
-
import { ManagedRuntime } from "effect";
|
|
955
|
-
function
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
941
|
+
import { Effect as Effect2, FiberRefs, ManagedRuntime } from "effect";
|
|
942
|
+
function makeEffectRuntimeRunner(source) {
|
|
943
|
+
if (source === void 0) {
|
|
944
|
+
return {
|
|
945
|
+
runPromiseExit: (effect, options) => Effect2.runPromiseExit(withParentFiberRefs(effect), {
|
|
946
|
+
signal: options?.signal
|
|
947
|
+
})
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
if (ManagedRuntime.isManagedRuntime(source)) {
|
|
951
|
+
const runtime = source;
|
|
952
|
+
return {
|
|
953
|
+
runtime,
|
|
954
|
+
runPromiseExit: (effect, options) => runtime.runPromiseExit(withParentFiberRefs(effect), {
|
|
955
|
+
signal: options?.signal
|
|
956
|
+
})
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
const layer = source;
|
|
960
|
+
return {
|
|
961
|
+
runPromiseExit: (effect, options) => Effect2.runPromiseExit(
|
|
962
|
+
withParentFiberRefs(Effect2.provide(effect, layer)),
|
|
963
|
+
{ signal: options?.signal }
|
|
964
|
+
)
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
function withParentFiberRefs(effect) {
|
|
968
|
+
const parentFiberRefs = getCurrentFiberRefs();
|
|
969
|
+
return parentFiberRefs ? Effect2.fiberIdWith(
|
|
970
|
+
(fiberId) => Effect2.flatMap(
|
|
971
|
+
Effect2.getFiberRefs,
|
|
972
|
+
(fiberRefs) => Effect2.setFiberRefs(
|
|
973
|
+
FiberRefs.joinAs(fiberRefs, fiberId, parentFiberRefs)
|
|
974
|
+
).pipe(Effect2.andThen(effect))
|
|
975
|
+
)
|
|
976
|
+
) : effect;
|
|
959
977
|
}
|
|
960
978
|
|
|
961
979
|
// src/effect-builder.ts
|
|
@@ -999,7 +1017,7 @@ function getEffectBuilderDef(context) {
|
|
|
999
1017
|
return {
|
|
1000
1018
|
...context.upstream["~orpc"],
|
|
1001
1019
|
effectErrorMap: context.state.effectErrorMap,
|
|
1002
|
-
|
|
1020
|
+
runner: context.state.runner,
|
|
1003
1021
|
spanConfig: context.state.spanConfig,
|
|
1004
1022
|
effectSteps: context.state.effectSteps,
|
|
1005
1023
|
effectHandler: context.state.effectHandler
|
|
@@ -1010,7 +1028,7 @@ function wrapBuilderLike(builder, state) {
|
|
|
1010
1028
|
{
|
|
1011
1029
|
...builder["~orpc"],
|
|
1012
1030
|
effectErrorMap: state.effectErrorMap,
|
|
1013
|
-
|
|
1031
|
+
runner: state.runner,
|
|
1014
1032
|
spanConfig: state.spanConfig,
|
|
1015
1033
|
effectSteps: state.effectSteps,
|
|
1016
1034
|
effectHandler: state.effectHandler
|
|
@@ -1030,7 +1048,7 @@ function flushEffectSteps2(builder, state) {
|
|
|
1030
1048
|
}
|
|
1031
1049
|
const middleware = createEffectPipelineMiddleware({
|
|
1032
1050
|
effectErrorMap: state.effectErrorMap,
|
|
1033
|
-
|
|
1051
|
+
runner: state.runner,
|
|
1034
1052
|
steps: state.effectSteps
|
|
1035
1053
|
});
|
|
1036
1054
|
return {
|
|
@@ -1088,7 +1106,7 @@ function createEffectBuilderProxy(target) {
|
|
|
1088
1106
|
effectErrorMap: state.effectErrorMap,
|
|
1089
1107
|
effectFn,
|
|
1090
1108
|
effectSteps: state.effectSteps,
|
|
1091
|
-
|
|
1109
|
+
runner: state.runner,
|
|
1092
1110
|
spanConfig: state.spanConfig
|
|
1093
1111
|
})(opts);
|
|
1094
1112
|
}
|
|
@@ -1101,7 +1119,7 @@ function createEffectBuilderProxy(target) {
|
|
|
1101
1119
|
if (isEffectMiddleware(middleware)) {
|
|
1102
1120
|
const effectMiddleware = createEffectPipelineMiddleware({
|
|
1103
1121
|
effectErrorMap: state.effectErrorMap,
|
|
1104
|
-
|
|
1122
|
+
runner: state.runner,
|
|
1105
1123
|
steps: [
|
|
1106
1124
|
...state.effectSteps ?? [],
|
|
1107
1125
|
{ _tag: "middleware", middleware }
|
|
@@ -1227,12 +1245,12 @@ function addSpanStackTrace() {
|
|
|
1227
1245
|
}
|
|
1228
1246
|
var EffectBuilder = class {
|
|
1229
1247
|
constructor(def, builder) {
|
|
1230
|
-
const {
|
|
1248
|
+
const { runner, spanConfig, effectErrorMap, effectSteps, ...orpcDef } = def;
|
|
1231
1249
|
attachEffectState(this, builder ?? new Builder(orpcDef), {
|
|
1232
1250
|
effectSteps,
|
|
1233
1251
|
effectHandler: def.effectHandler,
|
|
1234
1252
|
effectErrorMap,
|
|
1235
|
-
|
|
1253
|
+
runner,
|
|
1236
1254
|
spanConfig
|
|
1237
1255
|
});
|
|
1238
1256
|
return createEffectBuilderProxy(this);
|
|
@@ -1242,15 +1260,13 @@ function makeEffectORPC(source, builder) {
|
|
|
1242
1260
|
const sourceIsBuilder = source !== void 0 && isBuilderLike(source);
|
|
1243
1261
|
const resolvedBuilder = sourceIsBuilder ? source : builder ?? emptyBuilder();
|
|
1244
1262
|
const effectErrorMap = getEffectErrorMap(resolvedBuilder);
|
|
1245
|
-
const
|
|
1246
|
-
sourceIsBuilder || source === void 0 ? Layer3.empty : source
|
|
1247
|
-
);
|
|
1263
|
+
const runner = sourceIsBuilder || source === void 0 ? makeEffectRuntimeRunner() : makeEffectRuntimeRunner(source);
|
|
1248
1264
|
return new EffectBuilder(
|
|
1249
1265
|
{
|
|
1250
1266
|
...resolvedBuilder["~orpc"],
|
|
1251
1267
|
effectErrorMap,
|
|
1252
1268
|
errorMap: effectErrorMapToErrorMap(effectErrorMap),
|
|
1253
|
-
|
|
1269
|
+
runner
|
|
1254
1270
|
},
|
|
1255
1271
|
unwrapEffectUpstream(resolvedBuilder)
|
|
1256
1272
|
);
|
|
@@ -1267,6 +1283,7 @@ function emptyBuilder() {
|
|
|
1267
1283
|
route: {}
|
|
1268
1284
|
});
|
|
1269
1285
|
}
|
|
1286
|
+
var eos = makeEffectORPC();
|
|
1270
1287
|
|
|
1271
1288
|
// src/eoc.ts
|
|
1272
1289
|
import { isContractProcedure, oc } from "@orpc/contract";
|
|
@@ -1405,15 +1422,15 @@ var CONTRACT_HIDDEN_METHODS = /* @__PURE__ */ new Set([
|
|
|
1405
1422
|
"router",
|
|
1406
1423
|
"tag"
|
|
1407
1424
|
]);
|
|
1408
|
-
function makeEnhanceOptions(
|
|
1425
|
+
function makeEnhanceOptions(runner) {
|
|
1409
1426
|
return {
|
|
1410
1427
|
middlewares: [],
|
|
1411
1428
|
errorMap: {},
|
|
1412
1429
|
dedupeLeadingMiddlewares: true,
|
|
1413
|
-
|
|
1430
|
+
runner
|
|
1414
1431
|
};
|
|
1415
1432
|
}
|
|
1416
|
-
function wrapContractNode(contract, target,
|
|
1433
|
+
function wrapContractNode(contract, target, runner) {
|
|
1417
1434
|
const cache = /* @__PURE__ */ new Map();
|
|
1418
1435
|
return new Proxy(target, {
|
|
1419
1436
|
get(currentTarget, prop, receiver) {
|
|
@@ -1428,9 +1445,9 @@ function wrapContractNode(contract, target, runtime) {
|
|
|
1428
1445
|
...currentTarget["~orpc"],
|
|
1429
1446
|
errorMap: effectErrorMapToErrorMap(effectErrorMap),
|
|
1430
1447
|
effectErrorMap,
|
|
1431
|
-
|
|
1448
|
+
runner,
|
|
1432
1449
|
handler: createEffectProcedureHandler({
|
|
1433
|
-
|
|
1450
|
+
runner,
|
|
1434
1451
|
effectErrorMap,
|
|
1435
1452
|
effectFn,
|
|
1436
1453
|
defaultCaptureStackTrace: addSpanStackTrace()
|
|
@@ -1448,7 +1465,7 @@ function wrapContractNode(contract, target, runtime) {
|
|
|
1448
1465
|
currentTarget,
|
|
1449
1466
|
args
|
|
1450
1467
|
),
|
|
1451
|
-
|
|
1468
|
+
runner
|
|
1452
1469
|
);
|
|
1453
1470
|
cache.set(prop, use);
|
|
1454
1471
|
return use;
|
|
@@ -1465,7 +1482,7 @@ function wrapContractNode(contract, target, runtime) {
|
|
|
1465
1482
|
currentTarget,
|
|
1466
1483
|
args
|
|
1467
1484
|
),
|
|
1468
|
-
|
|
1485
|
+
runner
|
|
1469
1486
|
);
|
|
1470
1487
|
cache.set(prop, wrappedMethod);
|
|
1471
1488
|
return wrappedMethod;
|
|
@@ -1477,7 +1494,7 @@ function wrapContractNode(contract, target, runtime) {
|
|
|
1477
1494
|
currentTarget,
|
|
1478
1495
|
args
|
|
1479
1496
|
),
|
|
1480
|
-
makeEnhanceOptions(
|
|
1497
|
+
makeEnhanceOptions(runner)
|
|
1481
1498
|
);
|
|
1482
1499
|
cache.set(prop, wrappedMethod);
|
|
1483
1500
|
return wrappedMethod;
|
|
@@ -1486,7 +1503,7 @@ function wrapContractNode(contract, target, runtime) {
|
|
|
1486
1503
|
const child = wrapContractNode(
|
|
1487
1504
|
contract[prop],
|
|
1488
1505
|
Reflect.get(currentTarget, prop, receiver),
|
|
1489
|
-
|
|
1506
|
+
runner
|
|
1490
1507
|
);
|
|
1491
1508
|
cache.set(prop, child);
|
|
1492
1509
|
return child;
|
|
@@ -1514,7 +1531,7 @@ function implementEffect(contract, source) {
|
|
|
1514
1531
|
return wrapContractNode(
|
|
1515
1532
|
contract,
|
|
1516
1533
|
implement(contract),
|
|
1517
|
-
|
|
1534
|
+
makeEffectRuntimeRunner(source)
|
|
1518
1535
|
);
|
|
1519
1536
|
}
|
|
1520
1537
|
export {
|
|
@@ -1526,6 +1543,7 @@ export {
|
|
|
1526
1543
|
createEffectErrorConstructorMap,
|
|
1527
1544
|
effectErrorMapToErrorMap,
|
|
1528
1545
|
eoc,
|
|
1546
|
+
eos,
|
|
1529
1547
|
implementEffect,
|
|
1530
1548
|
isORPCTaggedError,
|
|
1531
1549
|
isORPCTaggedErrorClass,
|