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.
@@ -18,11 +18,16 @@ 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 { Effect, ManagedRuntime } from "effect";
26
+ import type { MaybeOptionalOptions } from "@orpc/shared";
27
+ import type { Context as EffectContext, Effect, Layer, Option } from "effect";
24
28
  import type { YieldWrap } from "effect/Utils";
25
29
 
30
+ import type { EffectRuntimeRunner } from "../runtime-source";
26
31
  import type {
27
32
  EffectErrorConstructorMap,
28
33
  EffectErrorMap,
@@ -44,7 +49,7 @@ type EffectBuilderDefBase<
44
49
  >;
45
50
 
46
51
  /**
47
- * Extended builder definition that includes the Effect ManagedRuntime.
52
+ * Extended builder definition that includes Effect execution state.
48
53
  */
49
54
  export interface EffectBuilderDef<
50
55
  TInputSchema extends AnySchema,
@@ -59,7 +64,7 @@ export interface EffectBuilderDef<
59
64
  TEffectErrorMap,
60
65
  TMeta
61
66
  > {
62
- runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;
67
+ runner: EffectRuntimeRunner<TRequirementsProvided, TRuntimeError>;
63
68
  /**
64
69
  * Optional span configuration for Effect tracing.
65
70
  */
@@ -68,10 +73,12 @@ export interface EffectBuilderDef<
68
73
  * Effect-extended error map that supports both traditional errors and tagged errors.
69
74
  */
70
75
  effectErrorMap: TEffectErrorMap;
76
+ effectSteps?: readonly EffectPipelineStep[];
77
+ effectHandler?: EffectProcedureHandlerConfig;
71
78
  }
72
79
 
73
80
  /**
74
- * Extended procedure definition that includes the Effect ManagedRuntime.
81
+ * Extended procedure definition that includes Effect execution state.
75
82
  */
76
83
  export interface EffectProcedureDef<
77
84
  TInitialContext extends Context,
@@ -90,8 +97,10 @@ export interface EffectProcedureDef<
90
97
  EffectErrorMapToErrorMap<TEffectErrorMap>,
91
98
  TMeta
92
99
  > {
93
- runtime: ManagedRuntime.ManagedRuntime<TRequirementsProvided, TRuntimeError>;
100
+ runner: EffectRuntimeRunner<TRequirementsProvided, TRuntimeError>;
94
101
  effectErrorMap: TEffectErrorMap;
102
+ effectSteps?: readonly EffectPipelineStep[];
103
+ effectHandler?: EffectProcedureHandlerConfig;
95
104
  }
96
105
 
97
106
  /**
@@ -139,6 +148,283 @@ export type EffectProcedureHandler<
139
148
  never
140
149
  >;
141
150
 
151
+ export interface EffectProcedureHandlerConfig {
152
+ readonly effectFn: EffectProcedureHandler<any, any, any, any, any, any>;
153
+ readonly defaultCaptureStackTrace: () => string | undefined;
154
+ readonly spanConfig?: EffectSpanConfig;
155
+ }
156
+
157
+ type EffectTagService<T extends EffectContext.Tag<any, any>> =
158
+ T extends EffectContext.Tag<any, infer S> ? S : never;
159
+
160
+ export type EffectProvider<
161
+ TCurrentContext extends Context,
162
+ TInput,
163
+ TEffectErrorMap extends EffectErrorMap,
164
+ TRequirementsProvided,
165
+ TMeta extends Meta,
166
+ TTag extends EffectContext.Tag<any, any>,
167
+ > = (
168
+ opt: ProcedureHandlerOptions<
169
+ TCurrentContext,
170
+ TInput,
171
+ EffectErrorConstructorMap<TEffectErrorMap>,
172
+ TMeta
173
+ >,
174
+ ) => Effect.Effect<
175
+ EffectTagService<TTag>,
176
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
177
+ TRequirementsProvided
178
+ >;
179
+
180
+ export type EffectOptionalProvider<
181
+ TCurrentContext extends Context,
182
+ TInput,
183
+ TEffectErrorMap extends EffectErrorMap,
184
+ TRequirementsProvided,
185
+ TMeta extends Meta,
186
+ TTag extends EffectContext.Tag<any, any>,
187
+ > = (
188
+ opt: ProcedureHandlerOptions<
189
+ TCurrentContext,
190
+ TInput,
191
+ EffectErrorConstructorMap<TEffectErrorMap>,
192
+ TMeta
193
+ >,
194
+ ) => Effect.Effect<
195
+ Option.Option<EffectTagService<TTag>>,
196
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
197
+ TRequirementsProvided
198
+ >;
199
+
200
+ interface EffectMiddlewareNext<
201
+ TOutput,
202
+ TEffectErrorMap extends EffectErrorMap,
203
+ TRequirementsProvided,
204
+ > {
205
+ <UOutContext extends Context = Record<never, never>>(
206
+ ...rest: MaybeOptionalOptions<MiddlewareNextFnOptions<UOutContext>>
207
+ ): Effect.Effect<
208
+ EffectMiddlewareResult<UOutContext, TOutput>,
209
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
210
+ TRequirementsProvided
211
+ >;
212
+ }
213
+
214
+ export type EffectMiddlewareResult<TOutContext extends Context, TOutput> = {
215
+ readonly output: TOutput;
216
+ readonly context: TOutContext;
217
+ };
218
+
219
+ export interface EffectMiddlewareOutput<
220
+ TOutput,
221
+ TEffectErrorMap extends EffectErrorMap,
222
+ TRequirementsProvided,
223
+ > {
224
+ (
225
+ output: TOutput,
226
+ ): Effect.Effect<
227
+ EffectMiddlewareResult<Record<never, never>, TOutput>,
228
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
229
+ TRequirementsProvided
230
+ >;
231
+ }
232
+
233
+ /**
234
+ * Contextual typing bridge for `.use(...)` overloads.
235
+ *
236
+ * At runtime `next()` is either Effect-native or oRPC-native depending on
237
+ * whether the middleware is a generator function. At type-check time we need
238
+ * inline middleware to support both `return next()` and `yield* next()` without
239
+ * an explicit annotation. The return type is intentionally an intersection:
240
+ * assignable to `PromiseLike<A>` for native middleware, and yieldable as an
241
+ * `Effect<A, E, R>` for Effect middleware.
242
+ */
243
+ type EffectAndPromiseLike<A, E, R> = Effect.Effect<A, E, R> & PromiseLike<A>;
244
+
245
+ /** A `next` function that can be consumed by native oRPC or Effect middleware. */
246
+ interface EffectOrORPCMiddlewareNext<
247
+ TOutput,
248
+ TEffectErrorMap extends EffectErrorMap,
249
+ TRequirementsProvided,
250
+ > {
251
+ <UOutContext extends Context = Record<never, never>>(
252
+ ...rest: MaybeOptionalOptions<MiddlewareNextFnOptions<UOutContext>>
253
+ ): EffectAndPromiseLike<
254
+ EffectMiddlewareResult<UOutContext, TOutput>,
255
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
256
+ TRequirementsProvided
257
+ >;
258
+ }
259
+
260
+ /** An `output` helper that can be consumed by native oRPC or Effect middleware. */
261
+ interface EffectOrORPCMiddlewareOutput<
262
+ TOutput,
263
+ TEffectErrorMap extends EffectErrorMap,
264
+ TRequirementsProvided,
265
+ > {
266
+ (
267
+ output: TOutput,
268
+ ): EffectAndPromiseLike<
269
+ EffectMiddlewareResult<Record<never, never>, TOutput>,
270
+ EffectErrorMapToUnion<TEffectErrorMap> | ORPCError<ORPCErrorCode, unknown>,
271
+ TRequirementsProvided
272
+ >;
273
+ }
274
+
275
+ /** Middleware options with the dual-shape `next` used for `.use(...)` inference. */
276
+ type EffectOrORPCMiddlewareOptions<
277
+ TCurrentContext extends Context,
278
+ TOutput,
279
+ TEffectErrorMap extends EffectErrorMap,
280
+ TRequirementsProvided,
281
+ TMeta extends Meta,
282
+ > = Omit<
283
+ MiddlewareOptions<
284
+ TCurrentContext,
285
+ TOutput,
286
+ EffectErrorConstructorMap<TEffectErrorMap>,
287
+ TMeta
288
+ >,
289
+ "next"
290
+ > & {
291
+ readonly next: EffectOrORPCMiddlewareNext<
292
+ TOutput,
293
+ TEffectErrorMap,
294
+ TRequirementsProvided
295
+ >;
296
+ };
297
+
298
+ /**
299
+ * Public `.use(...)` middleware shape.
300
+ *
301
+ * Accepts native oRPC middleware returns (`result` / `PromiseLike<result>`) and
302
+ * Effect generator middleware returns. Runtime dispatch still uses
303
+ * `isEffectMiddleware(...)`; this type only makes the inline callback ergonomic.
304
+ */
305
+ export type EffectOrORPCMiddleware<
306
+ TCurrentContext extends Context,
307
+ TOutContext extends Context,
308
+ TInput,
309
+ TOutput,
310
+ TEffectErrorMap extends EffectErrorMap,
311
+ TRequirementsProvided,
312
+ TMeta extends Meta,
313
+ > = (
314
+ opt: EffectOrORPCMiddlewareOptions<
315
+ TCurrentContext,
316
+ TOutput,
317
+ TEffectErrorMap,
318
+ TRequirementsProvided,
319
+ TMeta
320
+ >,
321
+ input: TInput,
322
+ output: EffectOrORPCMiddlewareOutput<
323
+ TOutput,
324
+ TEffectErrorMap,
325
+ TRequirementsProvided
326
+ >,
327
+ ) =>
328
+ | MiddlewareResult<TOutContext, TOutput>
329
+ | PromiseLike<MiddlewareResult<TOutContext, TOutput>>
330
+ | Generator<
331
+ YieldWrap<
332
+ Effect.Effect<
333
+ unknown,
334
+ | EffectErrorMapToUnion<TEffectErrorMap>
335
+ | ORPCError<ORPCErrorCode, unknown>,
336
+ TRequirementsProvided
337
+ >
338
+ >,
339
+ EffectMiddlewareResult<TOutContext, TOutput> | void,
340
+ never
341
+ >;
342
+
343
+ export type EffectMiddlewareOptions<
344
+ TCurrentContext extends Context,
345
+ TOutput,
346
+ TEffectErrorMap extends EffectErrorMap,
347
+ TRequirementsProvided,
348
+ TMeta extends Meta,
349
+ > = Omit<
350
+ MiddlewareOptions<
351
+ TCurrentContext,
352
+ TOutput,
353
+ EffectErrorConstructorMap<TEffectErrorMap>,
354
+ TMeta
355
+ >,
356
+ "next"
357
+ > & {
358
+ readonly next: EffectMiddlewareNext<
359
+ TOutput,
360
+ TEffectErrorMap,
361
+ TRequirementsProvided
362
+ >;
363
+ };
364
+
365
+ export type EffectMiddleware<
366
+ TCurrentContext extends Context,
367
+ TOutContext extends Context,
368
+ TInput,
369
+ TOutput,
370
+ TEffectErrorMap extends EffectErrorMap,
371
+ TRequirementsProvided,
372
+ TMeta extends Meta,
373
+ > = (
374
+ opt: EffectMiddlewareOptions<
375
+ TCurrentContext,
376
+ TOutput,
377
+ TEffectErrorMap,
378
+ TRequirementsProvided,
379
+ TMeta
380
+ >,
381
+ input: TInput,
382
+ output: EffectMiddlewareOutput<
383
+ TOutput,
384
+ TEffectErrorMap,
385
+ TRequirementsProvided
386
+ >,
387
+ ) => Generator<
388
+ YieldWrap<
389
+ Effect.Effect<
390
+ unknown,
391
+ | EffectErrorMapToUnion<TEffectErrorMap>
392
+ | ORPCError<ORPCErrorCode, unknown>,
393
+ TRequirementsProvided
394
+ >
395
+ >,
396
+ EffectMiddlewareResult<TOutContext, TOutput> | void,
397
+ never
398
+ >;
399
+
400
+ type EffectProvideStep = {
401
+ readonly _tag: "provide";
402
+ readonly tag: EffectContext.Tag<any, any>;
403
+ readonly provider: EffectProvider<any, any, any, any, any, any>;
404
+ };
405
+
406
+ type EffectProvideOptionalStep = {
407
+ readonly _tag: "provideOptional";
408
+ readonly tag: EffectContext.Tag<any, any>;
409
+ readonly provider: EffectOptionalProvider<any, any, any, any, any, any>;
410
+ };
411
+
412
+ type EffectProvideLayerStep = {
413
+ readonly _tag: "provideLayer";
414
+ readonly layer: Layer.Layer<any, any, any>;
415
+ };
416
+
417
+ type EffectMiddlewareStep = {
418
+ readonly _tag: "middleware";
419
+ readonly middleware: EffectMiddleware<any, any, any, any, any, any, any>;
420
+ };
421
+
422
+ export type EffectPipelineStep =
423
+ | EffectProvideStep
424
+ | EffectProvideOptionalStep
425
+ | EffectProvideLayerStep
426
+ | EffectMiddlewareStep;
427
+
142
428
  export type EffectErrorMapToErrorMap<T extends EffectErrorMap> = {
143
429
  [K in keyof T as T[K] extends ErrorMapItem<AnySchema>
144
430
  ? K extends ORPCErrorCode