@orpc/experimental-effect 2.0.0-beta.23 → 2.0.0-beta.25

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 CHANGED
@@ -44,6 +44,7 @@ You can read the documentation [here](https://orpc.dev).
44
44
 
45
45
  - [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
46
46
  - [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
47
+ - [@orpc/hibernation](https://www.npmjs.com/package/@orpc/hibernation): Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api).
47
48
  - [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
48
49
 
49
50
  **Framework & ecosystem integrations**
@@ -114,6 +115,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
114
115
  </tr>
115
116
  <tr>
116
117
  <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
118
+ <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
117
119
  </tr>
118
120
  </table>
119
121
 
@@ -139,8 +141,9 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
139
141
  <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
140
142
  </tr>
141
143
  <tr>
144
+ <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&amp;v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
142
145
  <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4" width="119" alt="Alex"/><br />Alex</a></td>
143
- <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=29e91400dbd4a9c217048a8f59562c4f740498e6&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
146
+ <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
144
147
  </tr>
145
148
  </table>
146
149
 
@@ -1,7 +1,7 @@
1
1
  import { ErrorMap, InferSchemaOutput, InitialInputSchema, Schema, AnySchema, InferSchemaInput } from '@orpc/contract';
2
2
  import { Context, ORPCErrorConstructorMap, DecoratedProcedure, AnyORPCError, MergedContext, ImplementedProcedure } from '@orpc/server';
3
3
  import { Effect } from 'effect';
4
- import { W as WithEffectContext, H as HandlerGen, I as InferYieldError } from '../shared/experimental-effect.Cw48Xdc-.mjs';
4
+ import { W as WithEffectContext, H as HandlerGen, I as InferYieldError } from '../shared/experimental-effect.BupPDCRJ.mjs';
5
5
 
6
6
  declare module '@orpc/server' {
7
7
  interface Builder<TInitialContext extends Context, TErrorMap extends ErrorMap> {
@@ -1,7 +1,7 @@
1
1
  import { ErrorMap, InferSchemaOutput, InitialInputSchema, Schema, AnySchema, InferSchemaInput } from '@orpc/contract';
2
2
  import { Context, ORPCErrorConstructorMap, DecoratedProcedure, AnyORPCError, MergedContext, ImplementedProcedure } from '@orpc/server';
3
3
  import { Effect } from 'effect';
4
- import { W as WithEffectContext, H as HandlerGen, I as InferYieldError } from '../shared/experimental-effect.Cw48Xdc-.js';
4
+ import { W as WithEffectContext, H as HandlerGen, I as InferYieldError } from '../shared/experimental-effect.BupPDCRJ.js';
5
5
 
6
6
  declare module '@orpc/server' {
7
7
  interface Builder<TInitialContext extends Context, TErrorMap extends ErrorMap> {
package/dist/index.d.mts CHANGED
@@ -1,15 +1,121 @@
1
- export { H as HandlerGen, I as InferYieldError, W as WithEffectContext, h as handlerGen } from './shared/experimental-effect.Cw48Xdc-.mjs';
1
+ export { H as HandlerGen, I as InferYieldError, W as WithEffectContext, h as handlerGen } from './shared/experimental-effect.BupPDCRJ.mjs';
2
2
  import { AnySchema, Schema as Schema$1 } from '@orpc/contract';
3
3
  import { JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchema } from '@orpc/json-schema';
4
+ import { AnyORPCError, ORPCError, ORPCErrorCode } from '@orpc/server';
4
5
  import { Effect, Schema } from 'effect';
5
- import '@orpc/server';
6
6
 
7
+ /**
8
+ * A JSON Schema converter for Effect Schema, built on top of
9
+ * [Effect Schema to JSON Schema](https://effect.website/docs/schema/json-schema/).
10
+ * Useful with tools such as the OpenAPI Generator.
11
+ *
12
+ * @see {@link https://orpc.dev/docs/integrations/effect#json-schema-converter | Effect Integration - JSON Schema Converter}
13
+ */
7
14
  declare class EffectSchemaToJsonSchemaConverter implements JsonSchemaConverter {
8
15
  private readonly converter;
9
16
  condition(schema: AnySchema | undefined, _direction: JsonSchemaConverterDirection): boolean;
10
17
  convert(schema: AnySchema | undefined, direction: JsonSchemaConverterDirection): [jsonSchema: JsonSchema, optional: boolean];
11
18
  }
12
19
 
20
+ /**
21
+ * Recovers from `ORPCError` failures in the error channel of an effect.
22
+ * Other failures re-fail with their original cause.
23
+ *
24
+ * Supports both data-first `catchORPCError(effect, handler)` and data-last
25
+ * `effect.pipe(catchORPCError(handler))` styles.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * declare const program: Effect.Effect<string, ORPCError<'NOT_FOUND', undefined> | TypeError>
30
+ *
31
+ * const recovered = program.pipe(
32
+ * catchORPCError(error => Effect.succeed(`caught ${error.code}`)),
33
+ * )
34
+ * ```
35
+ *
36
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
37
+ */
38
+ declare const catchORPCError: {
39
+ <E, A2, E2, R2>(f: (error: Extract<E, AnyORPCError>) => Effect.Effect<A2, E2, R2>): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, E2 | Exclude<E, AnyORPCError>, R | R2>;
40
+ <A, E, R, A2, E2, R2>(self: Effect.Effect<A, E, R>, f: (error: Extract<E, AnyORPCError>) => Effect.Effect<A2, E2, R2>): Effect.Effect<A | A2, E2 | Exclude<E, AnyORPCError>, R | R2>;
41
+ };
42
+ /**
43
+ * Recovers from `ORPCError` failures with a matching code in the error channel of an effect.
44
+ * Other failures re-fail with their original cause. The `code` argument is
45
+ * suggested and restricted to the codes present in the error channel.
46
+ *
47
+ * Supports both data-first `catchORPCErrorCode(effect, code, handler)` and
48
+ * data-last `effect.pipe(catchORPCErrorCode(code, handler))` styles.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * declare const program: Effect.Effect<
53
+ * string,
54
+ * ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', undefined> | TypeError
55
+ * >
56
+ *
57
+ * const recovered = program.pipe(
58
+ * catchORPCErrorCode('NOT_FOUND', error => Effect.succeed(error.data.id)),
59
+ * )
60
+ * ```
61
+ *
62
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
63
+ */
64
+ declare const catchORPCErrorCode: {
65
+ <const TCode extends E extends ORPCError<infer TCode, any> ? TCode : never, E, A2, E2, R2>(code: TCode, f: (error: Extract<E, ORPCError<TCode, any>>) => Effect.Effect<A2, E2, R2>): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, E2 | Exclude<E, ORPCError<TCode, any>>, R | R2>;
66
+ <A, E, R, const TCode extends E extends ORPCError<infer TCode, any> ? TCode : never, A2, E2, R2>(self: Effect.Effect<A, E, R>, code: TCode, f: (error: Extract<E, ORPCError<TCode, any>>) => Effect.Effect<A2, E2, R2>): Effect.Effect<A | A2, E2 | Exclude<E, ORPCError<TCode, any>>, R | R2>;
67
+ };
68
+ /**
69
+ * Recovers from `ORPCError` failures using a map of codes to handlers in the
70
+ * error channel of an effect. Other failures re-fail with their original
71
+ * cause. The keys are suggested and restricted to the codes present in the
72
+ * error channel.
73
+ *
74
+ * Supports both data-first `catchORPCErrorCodes(effect, cases)` and data-last
75
+ * `effect.pipe(catchORPCErrorCodes(cases))` styles.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * declare const program: Effect.Effect<
80
+ * string,
81
+ * ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', undefined> | TypeError
82
+ * >
83
+ *
84
+ * const recovered = program.pipe(
85
+ * catchORPCErrorCodes({
86
+ * NOT_FOUND: error => Effect.succeed(error.data.id),
87
+ * CONFLICT: error => Effect.succeed(error.message),
88
+ * }),
89
+ * )
90
+ * ```
91
+ *
92
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
93
+ */
94
+ declare const catchORPCErrorCodes: {
95
+ <E, Cases extends {
96
+ [K in Extract<E, AnyORPCError>['code']]?: (error: Extract<E, ORPCError<K, any>>) => Effect.Effect<any, any, any>;
97
+ } & (unknown extends E ? object : {
98
+ [K in Exclude<keyof Cases, Extract<E, AnyORPCError>['code']>]: never;
99
+ })>(cases: Cases): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | {
100
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<infer A2, any, any> ? A2 : never;
101
+ }[keyof Cases], Exclude<E, ORPCError<keyof Cases & ORPCErrorCode, any>> | {
102
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, infer E2, any> ? E2 : never;
103
+ }[keyof Cases], R | {
104
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, any, infer R2> ? R2 : never;
105
+ }[keyof Cases]>;
106
+ <A, E, R, Cases extends {
107
+ [K in Extract<E, AnyORPCError>['code']]?: (error: Extract<E, ORPCError<K, any>>) => Effect.Effect<any, any, any>;
108
+ } & (unknown extends E ? object : {
109
+ [K in Exclude<keyof Cases, Extract<E, AnyORPCError>['code']>]: never;
110
+ })>(self: Effect.Effect<A, E, R>, cases: Cases): Effect.Effect<A | {
111
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<infer A2, any, any> ? A2 : never;
112
+ }[keyof Cases], Exclude<E, ORPCError<keyof Cases & ORPCErrorCode, any>> | {
113
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, infer E2, any> ? E2 : never;
114
+ }[keyof Cases], R | {
115
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, any, infer R2> ? R2 : never;
116
+ }[keyof Cases]>;
117
+ };
118
+
13
119
  interface RunPromiseOptions {
14
120
  signal?: undefined | AbortSignal;
15
121
  }
@@ -20,5 +126,5 @@ declare function runPromise<T>(effect: Effect.Effect<T, unknown>, options?: RunP
20
126
 
21
127
  declare function toStandardSchema<S extends Schema.ConstraintDecoder<any>>(schema: S): Schema$1<S['Encoded'], S['Type']> & S;
22
128
 
23
- export { EffectSchemaToJsonSchemaConverter, runPromise, toStandardSchema };
129
+ export { EffectSchemaToJsonSchemaConverter, catchORPCError, catchORPCErrorCode, catchORPCErrorCodes, runPromise, toStandardSchema };
24
130
  export type { RunPromiseOptions };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,121 @@
1
- export { H as HandlerGen, I as InferYieldError, W as WithEffectContext, h as handlerGen } from './shared/experimental-effect.Cw48Xdc-.js';
1
+ export { H as HandlerGen, I as InferYieldError, W as WithEffectContext, h as handlerGen } from './shared/experimental-effect.BupPDCRJ.js';
2
2
  import { AnySchema, Schema as Schema$1 } from '@orpc/contract';
3
3
  import { JsonSchemaConverter, JsonSchemaConverterDirection, JsonSchema } from '@orpc/json-schema';
4
+ import { AnyORPCError, ORPCError, ORPCErrorCode } from '@orpc/server';
4
5
  import { Effect, Schema } from 'effect';
5
- import '@orpc/server';
6
6
 
7
+ /**
8
+ * A JSON Schema converter for Effect Schema, built on top of
9
+ * [Effect Schema to JSON Schema](https://effect.website/docs/schema/json-schema/).
10
+ * Useful with tools such as the OpenAPI Generator.
11
+ *
12
+ * @see {@link https://orpc.dev/docs/integrations/effect#json-schema-converter | Effect Integration - JSON Schema Converter}
13
+ */
7
14
  declare class EffectSchemaToJsonSchemaConverter implements JsonSchemaConverter {
8
15
  private readonly converter;
9
16
  condition(schema: AnySchema | undefined, _direction: JsonSchemaConverterDirection): boolean;
10
17
  convert(schema: AnySchema | undefined, direction: JsonSchemaConverterDirection): [jsonSchema: JsonSchema, optional: boolean];
11
18
  }
12
19
 
20
+ /**
21
+ * Recovers from `ORPCError` failures in the error channel of an effect.
22
+ * Other failures re-fail with their original cause.
23
+ *
24
+ * Supports both data-first `catchORPCError(effect, handler)` and data-last
25
+ * `effect.pipe(catchORPCError(handler))` styles.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * declare const program: Effect.Effect<string, ORPCError<'NOT_FOUND', undefined> | TypeError>
30
+ *
31
+ * const recovered = program.pipe(
32
+ * catchORPCError(error => Effect.succeed(`caught ${error.code}`)),
33
+ * )
34
+ * ```
35
+ *
36
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
37
+ */
38
+ declare const catchORPCError: {
39
+ <E, A2, E2, R2>(f: (error: Extract<E, AnyORPCError>) => Effect.Effect<A2, E2, R2>): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, E2 | Exclude<E, AnyORPCError>, R | R2>;
40
+ <A, E, R, A2, E2, R2>(self: Effect.Effect<A, E, R>, f: (error: Extract<E, AnyORPCError>) => Effect.Effect<A2, E2, R2>): Effect.Effect<A | A2, E2 | Exclude<E, AnyORPCError>, R | R2>;
41
+ };
42
+ /**
43
+ * Recovers from `ORPCError` failures with a matching code in the error channel of an effect.
44
+ * Other failures re-fail with their original cause. The `code` argument is
45
+ * suggested and restricted to the codes present in the error channel.
46
+ *
47
+ * Supports both data-first `catchORPCErrorCode(effect, code, handler)` and
48
+ * data-last `effect.pipe(catchORPCErrorCode(code, handler))` styles.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * declare const program: Effect.Effect<
53
+ * string,
54
+ * ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', undefined> | TypeError
55
+ * >
56
+ *
57
+ * const recovered = program.pipe(
58
+ * catchORPCErrorCode('NOT_FOUND', error => Effect.succeed(error.data.id)),
59
+ * )
60
+ * ```
61
+ *
62
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
63
+ */
64
+ declare const catchORPCErrorCode: {
65
+ <const TCode extends E extends ORPCError<infer TCode, any> ? TCode : never, E, A2, E2, R2>(code: TCode, f: (error: Extract<E, ORPCError<TCode, any>>) => Effect.Effect<A2, E2, R2>): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, E2 | Exclude<E, ORPCError<TCode, any>>, R | R2>;
66
+ <A, E, R, const TCode extends E extends ORPCError<infer TCode, any> ? TCode : never, A2, E2, R2>(self: Effect.Effect<A, E, R>, code: TCode, f: (error: Extract<E, ORPCError<TCode, any>>) => Effect.Effect<A2, E2, R2>): Effect.Effect<A | A2, E2 | Exclude<E, ORPCError<TCode, any>>, R | R2>;
67
+ };
68
+ /**
69
+ * Recovers from `ORPCError` failures using a map of codes to handlers in the
70
+ * error channel of an effect. Other failures re-fail with their original
71
+ * cause. The keys are suggested and restricted to the codes present in the
72
+ * error channel.
73
+ *
74
+ * Supports both data-first `catchORPCErrorCodes(effect, cases)` and data-last
75
+ * `effect.pipe(catchORPCErrorCodes(cases))` styles.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * declare const program: Effect.Effect<
80
+ * string,
81
+ * ORPCError<'NOT_FOUND', { id: string }> | ORPCError<'CONFLICT', undefined> | TypeError
82
+ * >
83
+ *
84
+ * const recovered = program.pipe(
85
+ * catchORPCErrorCodes({
86
+ * NOT_FOUND: error => Effect.succeed(error.data.id),
87
+ * CONFLICT: error => Effect.succeed(error.message),
88
+ * }),
89
+ * )
90
+ * ```
91
+ *
92
+ * @see {@link https://orpc.dev/docs/integrations/effect#catching-orpcerrors | Effect Integration - Catching ORPCErrors}
93
+ */
94
+ declare const catchORPCErrorCodes: {
95
+ <E, Cases extends {
96
+ [K in Extract<E, AnyORPCError>['code']]?: (error: Extract<E, ORPCError<K, any>>) => Effect.Effect<any, any, any>;
97
+ } & (unknown extends E ? object : {
98
+ [K in Exclude<keyof Cases, Extract<E, AnyORPCError>['code']>]: never;
99
+ })>(cases: Cases): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | {
100
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<infer A2, any, any> ? A2 : never;
101
+ }[keyof Cases], Exclude<E, ORPCError<keyof Cases & ORPCErrorCode, any>> | {
102
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, infer E2, any> ? E2 : never;
103
+ }[keyof Cases], R | {
104
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, any, infer R2> ? R2 : never;
105
+ }[keyof Cases]>;
106
+ <A, E, R, Cases extends {
107
+ [K in Extract<E, AnyORPCError>['code']]?: (error: Extract<E, ORPCError<K, any>>) => Effect.Effect<any, any, any>;
108
+ } & (unknown extends E ? object : {
109
+ [K in Exclude<keyof Cases, Extract<E, AnyORPCError>['code']>]: never;
110
+ })>(self: Effect.Effect<A, E, R>, cases: Cases): Effect.Effect<A | {
111
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<infer A2, any, any> ? A2 : never;
112
+ }[keyof Cases], Exclude<E, ORPCError<keyof Cases & ORPCErrorCode, any>> | {
113
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, infer E2, any> ? E2 : never;
114
+ }[keyof Cases], R | {
115
+ [K in keyof Cases]: Cases[K] extends (...args: any[]) => Effect.Effect<any, any, infer R2> ? R2 : never;
116
+ }[keyof Cases]>;
117
+ };
118
+
13
119
  interface RunPromiseOptions {
14
120
  signal?: undefined | AbortSignal;
15
121
  }
@@ -20,5 +126,5 @@ declare function runPromise<T>(effect: Effect.Effect<T, unknown>, options?: RunP
20
126
 
21
127
  declare function toStandardSchema<S extends Schema.ConstraintDecoder<any>>(schema: S): Schema$1<S['Encoded'], S['Type']> & S;
22
128
 
23
- export { EffectSchemaToJsonSchemaConverter, runPromise, toStandardSchema };
129
+ export { EffectSchemaToJsonSchemaConverter, catchORPCError, catchORPCErrorCode, catchORPCErrorCodes, runPromise, toStandardSchema };
24
130
  export type { RunPromiseOptions };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { StandardJsonSchemaConverter } from '@orpc/json-schema';
2
- import { Schema } from 'effect';
2
+ import { Schema, Function, Effect } from 'effect';
3
+ import { ORPCError } from '@orpc/server';
3
4
  export { h as handlerGen, r as runPromise } from './shared/experimental-effect.C9oJcd5q.mjs';
4
5
  export { t as toStandardSchema } from './shared/experimental-effect.YQKompVf.mjs';
5
- import '@orpc/server';
6
6
  import '@orpc/shared';
7
7
  import '@orpc/contract';
8
8
 
@@ -18,4 +18,26 @@ class EffectSchemaToJsonSchemaConverter {
18
18
  }
19
19
  }
20
20
 
21
- export { EffectSchemaToJsonSchemaConverter };
21
+ const catchORPCError = Function.dual(
22
+ 2,
23
+ (self, f) => self.pipe(
24
+ Effect.catchIf((error) => error instanceof ORPCError, f)
25
+ )
26
+ );
27
+ const catchORPCErrorCode = Function.dual(
28
+ 3,
29
+ (self, code, f) => self.pipe(
30
+ Effect.catchIf((error) => error instanceof ORPCError && error.code === code, f)
31
+ )
32
+ );
33
+ const catchORPCErrorCodes = Function.dual(
34
+ 2,
35
+ (self, cases) => self.pipe(
36
+ Effect.catchIf(
37
+ (error) => error instanceof ORPCError && typeof cases[error.code] === "function",
38
+ (error) => cases[error.code](error)
39
+ )
40
+ )
41
+ );
42
+
43
+ export { EffectSchemaToJsonSchemaConverter, catchORPCError, catchORPCErrorCode, catchORPCErrorCodes };
@@ -1,6 +1,12 @@
1
1
  import { AnyProcedure, Context as Context$1, ORPCErrorConstructorMap, ProcedureHandlerOptions, ProcedureHandler, AnyORPCError } from '@orpc/server';
2
2
  import { Context, Effect } from 'effect';
3
3
 
4
+ /**
5
+ * A context shape that provides Effect services to effectful handlers
6
+ * through the oRPC context in a typesafe way.
7
+ *
8
+ * @see {@link https://orpc.dev/docs/integrations/effect#effect-services | Effect Integration - Effect Services}
9
+ */
4
10
  interface WithEffectContext<Services> {
5
11
  /**
6
12
  * A pre-built Effect context providing the services available within this oRPC context.
@@ -52,6 +58,13 @@ type InferYieldError<Eff> = [Eff] extends [never] ? never : [Eff] extends [Effec
52
58
  interface HandlerGen<TCurrentContext extends Context$1, TInput, TYield extends Effect.Effect<any, any, TCurrentContext extends WithEffectContext<infer S> ? S : never>, TReturn, TErrorConstructorMap extends ORPCErrorConstructorMap<any>> {
53
59
  (opts: ProcedureHandlerOptions<TCurrentContext, TInput, TErrorConstructorMap>, input: TInput): Generator<TYield, TReturn, never>;
54
60
  }
61
+ /**
62
+ * Creates a procedure handler from an Effect generator function.
63
+ * Inside the generator you can yield Effect operations, and `handlerGen`
64
+ * handles the execution and error handling for you.
65
+ *
66
+ * @see {@link https://orpc.dev/docs/integrations/effect#effectful-handlers | Effect Integration - Effectful Handlers}
67
+ */
55
68
  declare function handlerGen<TCurrentContext extends Context$1, TInput, TErrorConstructorMap extends ORPCErrorConstructorMap<any>, TYield extends Effect.Effect<any, any, TCurrentContext extends WithEffectContext<infer S> ? S : never>, TReturn>(handler: HandlerGen<TCurrentContext, TInput, TYield, TReturn, TErrorConstructorMap>): ProcedureHandler<TCurrentContext, TInput, TReturn | Extract<InferYieldError<TYield>, AnyORPCError>, TErrorConstructorMap>;
56
69
 
57
70
  export { handlerGen as h };
@@ -1,6 +1,12 @@
1
1
  import { AnyProcedure, Context as Context$1, ORPCErrorConstructorMap, ProcedureHandlerOptions, ProcedureHandler, AnyORPCError } from '@orpc/server';
2
2
  import { Context, Effect } from 'effect';
3
3
 
4
+ /**
5
+ * A context shape that provides Effect services to effectful handlers
6
+ * through the oRPC context in a typesafe way.
7
+ *
8
+ * @see {@link https://orpc.dev/docs/integrations/effect#effect-services | Effect Integration - Effect Services}
9
+ */
4
10
  interface WithEffectContext<Services> {
5
11
  /**
6
12
  * A pre-built Effect context providing the services available within this oRPC context.
@@ -52,6 +58,13 @@ type InferYieldError<Eff> = [Eff] extends [never] ? never : [Eff] extends [Effec
52
58
  interface HandlerGen<TCurrentContext extends Context$1, TInput, TYield extends Effect.Effect<any, any, TCurrentContext extends WithEffectContext<infer S> ? S : never>, TReturn, TErrorConstructorMap extends ORPCErrorConstructorMap<any>> {
53
59
  (opts: ProcedureHandlerOptions<TCurrentContext, TInput, TErrorConstructorMap>, input: TInput): Generator<TYield, TReturn, never>;
54
60
  }
61
+ /**
62
+ * Creates a procedure handler from an Effect generator function.
63
+ * Inside the generator you can yield Effect operations, and `handlerGen`
64
+ * handles the execution and error handling for you.
65
+ *
66
+ * @see {@link https://orpc.dev/docs/integrations/effect#effectful-handlers | Effect Integration - Effectful Handlers}
67
+ */
55
68
  declare function handlerGen<TCurrentContext extends Context$1, TInput, TErrorConstructorMap extends ORPCErrorConstructorMap<any>, TYield extends Effect.Effect<any, any, TCurrentContext extends WithEffectContext<infer S> ? S : never>, TReturn>(handler: HandlerGen<TCurrentContext, TInput, TYield, TReturn, TErrorConstructorMap>): ProcedureHandler<TCurrentContext, TInput, TReturn | Extract<InferYieldError<TYield>, AnyORPCError>, TErrorConstructorMap>;
56
69
 
57
70
  export { handlerGen as h };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/experimental-effect",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.23",
4
+ "version": "2.0.0-beta.25",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.dev",
7
7
  "repository": {
@@ -42,10 +42,10 @@
42
42
  "effect": ">=4.0.0-beta.90"
43
43
  },
44
44
  "dependencies": {
45
- "@orpc/contract": "2.0.0-beta.23",
46
- "@orpc/json-schema": "2.0.0-beta.23",
47
- "@orpc/server": "2.0.0-beta.23",
48
- "@orpc/shared": "2.0.0-beta.23"
45
+ "@orpc/server": "2.0.0-beta.25",
46
+ "@orpc/contract": "2.0.0-beta.25",
47
+ "@orpc/shared": "2.0.0-beta.25",
48
+ "@orpc/json-schema": "2.0.0-beta.25"
49
49
  },
50
50
  "devDependencies": {
51
51
  "effect": "4.0.0-beta.101"