@shivaedev/effect-trpc 0.1.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +24 -7
  3. package/dist/adapter.d.ts +15 -3
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/adapter.js +1 -1
  6. package/dist/adapter.js.map +1 -1
  7. package/dist/index.d.ts +3 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal/context-bridge.d.ts +4 -1
  12. package/dist/internal/context-bridge.d.ts.map +1 -1
  13. package/dist/internal/context-bridge.js +8 -1
  14. package/dist/internal/context-bridge.js.map +1 -1
  15. package/dist/internal/procedure-types.d.ts +2 -1
  16. package/dist/internal/procedure-types.d.ts.map +1 -1
  17. package/dist/internal/runtime.d.ts +5 -2
  18. package/dist/internal/runtime.d.ts.map +1 -1
  19. package/dist/internal/runtime.js +48 -16
  20. package/dist/internal/runtime.js.map +1 -1
  21. package/dist/internal/subscription-handler.d.ts +14 -0
  22. package/dist/internal/subscription-handler.d.ts.map +1 -0
  23. package/dist/internal/subscription-handler.js +18 -0
  24. package/dist/internal/subscription-handler.js.map +1 -0
  25. package/dist/internal/vitest-trpc.d.ts +2 -1
  26. package/dist/internal/vitest-trpc.d.ts.map +1 -1
  27. package/dist/internal/vitest-trpc.js +8 -3
  28. package/dist/internal/vitest-trpc.js.map +1 -1
  29. package/dist/procedure.d.ts +10 -3
  30. package/dist/procedure.d.ts.map +1 -1
  31. package/dist/procedure.js +16 -3
  32. package/dist/procedure.js.map +1 -1
  33. package/dist/request-signal.d.ts +4 -0
  34. package/dist/request-signal.d.ts.map +1 -0
  35. package/dist/request-signal.js +4 -0
  36. package/dist/request-signal.js.map +1 -0
  37. package/dist/testing/types.d.ts +19 -9
  38. package/dist/testing/types.d.ts.map +1 -1
  39. package/dist/testing/vitest.d.ts +2 -1
  40. package/dist/testing/vitest.d.ts.map +1 -1
  41. package/dist/testing/vitest.js +29 -22
  42. package/dist/testing/vitest.js.map +1 -1
  43. package/dist/testing.d.ts +2 -2
  44. package/dist/testing.d.ts.map +1 -1
  45. package/dist/testing.js +1 -1
  46. package/dist/testing.js.map +1 -1
  47. package/dist/types.d.ts +3 -2
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +1 -1
  50. package/src/adapter.ts +29 -4
  51. package/src/index.ts +3 -0
  52. package/src/internal/context-bridge.ts +14 -1
  53. package/src/internal/procedure-types.ts +9 -1
  54. package/src/internal/runtime.ts +72 -38
  55. package/src/internal/subscription-handler.ts +61 -0
  56. package/src/internal/vitest-trpc.ts +34 -17
  57. package/src/procedure.ts +58 -0
  58. package/src/request-signal.ts +7 -0
  59. package/src/testing/types.ts +61 -14
  60. package/src/testing/vitest.ts +72 -26
  61. package/src/testing.ts +7 -1
  62. package/src/types.ts +7 -2
@@ -0,0 +1,4 @@
1
+ import { Context } from "effect";
2
+ /** The transport cancellation signal for the current tRPC procedure. */
3
+ export declare const RequestSignal: Context.Reference<AbortSignal | undefined>;
4
+ //# sourceMappingURL=request-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-signal.d.ts","sourceRoot":"","sources":["../src/request-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,wEAAwE;AACxE,eAAO,MAAM,aAAa,4CAGzB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Context } from "effect";
2
+ /** The transport cancellation signal for the current tRPC procedure. */
3
+ export const RequestSignal = Context.Reference("@shivaedev/effect-trpc/RequestSignal", { defaultValue: () => undefined });
4
+ //# sourceMappingURL=request-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-signal.js","sourceRoot":"","sources":["../src/request-signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,wEAAwE;AACxE,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAC7C,sCAAsC,EACtC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CACjC,CAAC"}
@@ -2,30 +2,40 @@ import type { TestContext, TestOptions, Vitest } from "@effect/vitest";
2
2
  import type { Effect, Layer } from "effect";
3
3
  import type { EffectTRPCAdapter } from "../adapter.js";
4
4
  import type { EffectCallerFactory } from "./caller.js";
5
- export type TrpcTest<Options, Caller, Provided> = <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (trpc: EffectCallerFactory<Options, Caller>, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
6
- export interface TrpcTester<Options, Caller, Provided> extends TrpcTest<Options, Caller, Provided> {
7
- readonly skip: TrpcTest<Options, Caller, Provided>;
8
- readonly skipIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
9
- readonly runIf: (condition: unknown) => TrpcTest<Options, Caller, Provided>;
10
- readonly only: TrpcTest<Options, Caller, Provided>;
11
- readonly each: <Item>(cases: ReadonlyArray<Item>) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (item: Item, trpc: EffectCallerFactory<Options, Caller>, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
12
- readonly fails: TrpcTest<Options, Caller, Provided>;
5
+ export type TrpcHarnessTest<Harness, Provided> = <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (harness: Harness, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
6
+ export interface TrpcHarnessTester<Harness, Provided> extends TrpcHarnessTest<Harness, Provided> {
7
+ readonly skip: TrpcHarnessTest<Harness, Provided>;
8
+ readonly skipIf: (condition: unknown) => TrpcHarnessTest<Harness, Provided>;
9
+ readonly runIf: (condition: unknown) => TrpcHarnessTest<Harness, Provided>;
10
+ readonly only: TrpcHarnessTest<Harness, Provided>;
11
+ readonly each: <Item>(cases: ReadonlyArray<Item>) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (item: Item, harness: Harness, context: TestContext) => Generator<Eff, A, never>, options?: number | TestOptions) => void;
12
+ readonly fails: TrpcHarnessTest<Harness, Provided>;
13
13
  }
14
+ export type TrpcTest<Options, Caller, Provided> = TrpcHarnessTest<EffectCallerFactory<Options, Caller>, Provided>;
15
+ export type TrpcTester<Options, Caller, Provided> = TrpcHarnessTester<EffectCallerFactory<Options, Caller>, Provided>;
14
16
  export type TrpcIt<Options, Caller, Provided> = Vitest.Methods & {
15
17
  readonly effectTRPC: TrpcTester<Options, Caller, Provided>;
16
18
  };
17
- export interface TrpcTestRuntimeOptions<Options, Caller extends object, Provided, LayerError> {
19
+ export type TrpcHarnessIt<Harness, Provided> = Vitest.Methods & {
20
+ readonly effectTRPC: TrpcHarnessTester<Harness, Provided>;
21
+ };
22
+ export interface TrpcHarnessTestRuntimeOptions<Options, Caller extends object, Harness, Provided, LayerError> {
18
23
  readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
19
24
  readonly around?: <A, E>(effect: Effect.Effect<A, E, Provided>) => Effect.Effect<A, unknown, Provided>;
20
25
  readonly createCaller: (options?: Options) => Caller;
21
26
  readonly layer: Layer.Layer<Provided, LayerError>;
27
+ readonly makeHarness: (trpc: EffectCallerFactory<Options, Caller>, context: TestContext) => Effect.Effect<Harness, unknown, Provided>;
22
28
  }
29
+ export type TrpcTestRuntimeOptions<Options, Caller extends object, Provided, LayerError> = Omit<TrpcHarnessTestRuntimeOptions<Options, Caller, EffectCallerFactory<Options, Caller>, Provided, LayerError>, "makeHarness">;
23
30
  export interface MakeTrpcItOptions<CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>> {
24
31
  readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
25
32
  readonly around?: <A, E>(effect: Effect.Effect<A, E, Layer.Success<TestLayer>>) => Effect.Effect<A, unknown, Layer.Success<TestLayer>>;
26
33
  readonly createCaller: CreateCaller;
27
34
  readonly layer: TestLayer;
28
35
  }
36
+ export interface MakeTrpcHarnessItOptions<CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>, Harness> extends MakeTrpcItOptions<CreateCaller, TestLayer> {
37
+ readonly makeHarness: (trpc: EffectCallerFactory<CallerOptions<CreateCaller>, CallerResult<CreateCaller>>, context: TestContext) => Effect.Effect<Harness, unknown, Layer.Success<TestLayer>>;
38
+ }
29
39
  export type CallerOptions<CreateCaller> = CreateCaller extends (...arguments_: infer Arguments) => object ? Arguments[0] : never;
30
40
  export type CallerResult<CreateCaller> = CreateCaller extends (...arguments_: infer _Arguments) => infer Caller ? Caller extends object ? Caller : never : never;
31
41
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Layer } from "effect";
2
- import type { CallerOptions, CallerResult, MakeTrpcItOptions, TrpcIt } from "./types.js";
2
+ import type { CallerOptions, CallerResult, MakeTrpcHarnessItOptions, MakeTrpcItOptions, TrpcHarnessIt, TrpcIt } from "./types.js";
3
3
  export declare const makeTrpcIt: <CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>>(options: MakeTrpcItOptions<CreateCaller, TestLayer>) => TrpcIt<CallerOptions<CreateCaller>, CallerResult<CreateCaller>, Layer.Success<TestLayer>>;
4
+ export declare const makeTrpcHarnessIt: <CreateCaller extends (...arguments_: never[]) => object, TestLayer extends Layer.Layer<any, any, never>, Harness>(options: MakeTrpcHarnessItOptions<CreateCaller, TestLayer, Harness>) => TrpcHarnessIt<Harness, Layer.Success<TestLayer>>;
4
5
  //# sourceMappingURL=vitest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,EAAS,MAAM,QAAQ,CAAC;AAMpD,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,UAAU,GACtB,YAAY,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,MAAM,EAEvD,SAAS,SAAS,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAE9C,SAAS,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,KACjD,MAAM,CACR,aAAa,CAAC,YAAY,CAAC,EAC3B,YAAY,CAAC,YAAY,CAAC,EAC1B,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAwCxB,CAAC"}
1
+ {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,EAAS,MAAM,QAAQ,CAAC;AAOpD,OAAO,KAAK,EACX,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,MAAM,EACN,MAAM,YAAY,CAAC;AAoCpB,eAAO,MAAM,UAAU,GACtB,YAAY,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,MAAM,EAEvD,SAAS,SAAS,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAE9C,SAAS,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,KACjD,MAAM,CACR,aAAa,CAAC,YAAY,CAAC,EAC3B,YAAY,CAAC,YAAY,CAAC,EAC1B,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAkBxB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC7B,YAAY,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,KAAK,MAAM,EAEvD,SAAS,SAAS,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAC9C,OAAO,EAEP,SAAS,wBAAwB,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,KACjE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAsBjD,CAAC"}
@@ -1,28 +1,35 @@
1
1
  import { it as effectIt } from "@effect/vitest";
2
2
  import { Effect, Exit, Layer, Scope } from "effect";
3
- import { fixtureName, makeTrpcTester, } from "../internal/vitest-trpc.js";
4
- export const makeTrpcIt = (options) => {
5
- const fixtureIt = effectIt.extend(fixtureName, { scope: "worker" },
6
- // biome-ignore lint/correctness/noEmptyPattern: Vitest fixtures require a destructured context parameter.
7
- async ({}, { onCleanup }) => {
8
- const scope = Effect.runSync(Scope.make());
9
- onCleanup(() => Effect.runPromise(Scope.close(scope, Exit.void)));
10
- try {
11
- return await Effect.runPromise(Layer.buildWithScope(options.layer, scope));
12
- }
13
- catch (error) {
14
- await Effect.runPromise(Scope.close(scope, Exit.void));
15
- throw error;
3
+ import { fixtureName, makeTrpcHarnessTester, makeTrpcTester, } from "../internal/vitest-trpc.js";
4
+ const makeFixtureIt = (layer) => effectIt.extend(fixtureName, { scope: "worker" },
5
+ // biome-ignore lint/correctness/noEmptyPattern: Vitest fixtures require a destructured context parameter.
6
+ async ({}, { onCleanup }) => {
7
+ const scope = Effect.runSync(Scope.make());
8
+ onCleanup(() => Effect.runPromise(Scope.close(scope, Exit.void)));
9
+ try {
10
+ return await Effect.runPromise(Layer.buildWithScope(layer, scope));
11
+ }
12
+ catch (error) {
13
+ await Effect.runPromise(Scope.close(scope, Exit.void));
14
+ throw error;
15
+ }
16
+ });
17
+ const withEffectTRPC = (tester) => new Proxy(effectIt, {
18
+ get(target, property, receiver) {
19
+ if (property === "effectTRPC") {
20
+ return tester;
16
21
  }
17
- });
22
+ return Reflect.get(target, property, receiver);
23
+ },
24
+ });
25
+ export const makeTrpcIt = (options) => {
26
+ const fixtureIt = makeFixtureIt(options.layer);
18
27
  const effectTRPC = makeTrpcTester(fixtureIt, options);
19
- return new Proxy(effectIt, {
20
- get(target, property, receiver) {
21
- if (property === "effectTRPC") {
22
- return effectTRPC;
23
- }
24
- return Reflect.get(target, property, receiver);
25
- },
26
- });
28
+ return withEffectTRPC(effectTRPC);
29
+ };
30
+ export const makeTrpcHarnessIt = (options) => {
31
+ const fixtureIt = makeFixtureIt(options.layer);
32
+ const effectTRPC = makeTrpcHarnessTester(fixtureIt, options);
33
+ return withEffectTRPC(effectTRPC);
27
34
  };
28
35
  //# sourceMappingURL=vitest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAEN,WAAW,EACX,cAAc,GACd,MAAM,4BAA4B,CAAC;AAQpC,MAAM,CAAC,MAAM,UAAU,GAAG,CAKzB,OAAmD,EAKlD,EAAE;IAKH,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAChC,WAAW,EACX,EAAE,KAAK,EAAE,QAAQ,EAAE;IACnB,0GAA0G;IAC1G,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElE,IAAI,CAAC;YACJ,OAAO,MAAM,MAAM,CAAC,UAAU,CAC7B,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAC1C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC,CACD,CAAC;IAEF,MAAM,UAAU,GAAG,cAAc,CAChC,SAAgD,EAChD,OAEI,CACJ,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;YAC7B,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC/B,OAAO,UAAU,CAAC;YACnB,CAAC;YACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChD,CAAC;KACD,CAAsC,CAAC;AACzC,CAAC,CAAC"}
1
+ {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/testing/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAe,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAEN,WAAW,EACX,qBAAqB,EACrB,cAAc,GACd,MAAM,4BAA4B,CAAC;AAUpC,MAAM,aAAa,GAAG,CACrB,KAAwC,EACb,EAAE,CAC7B,QAAQ,CAAC,MAAM,CACd,WAAW,EACX,EAAE,KAAK,EAAE,QAAQ,EAAE;AACnB,0GAA0G;AAC1G,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAElE,IAAI,CAAC;QACJ,OAAO,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC,CACsC,CAAC;AAE1C,MAAM,cAAc,GAAG,CACtB,MAAc,EAGb,EAAE,CACH,IAAI,KAAK,CAAC,QAAQ,EAAE;IACnB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;QAC7B,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC;QACf,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;CACD,CAAqD,CAAC;AAExD,MAAM,CAAC,MAAM,UAAU,GAAG,CAKzB,OAAmD,EAKlD,EAAE;IAKH,MAAM,SAAS,GAAG,aAAa,CAC9B,OAAO,CAAC,KAAK,CACb,CAAC;IAEF,MAAM,UAAU,GAAG,cAAc,CAChC,SAAgD,EAChD,OAEI,CACJ,CAAC;IAEF,OAAO,cAAc,CAAC,UAAU,CAAsC,CAAC;AACxE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAMhC,OAAmE,EAChB,EAAE;IAKrD,MAAM,SAAS,GAAG,aAAa,CAC9B,OAAO,CAAC,KAAK,CACb,CAAC;IACF,MAAM,UAAU,GAAG,qBAAqB,CACvC,SAAS,EACT,OAQI,CACJ,CAAC;IAEF,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC,CAAC"}
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { type EffectCaller, type EffectCallerFactory, makeEffectCaller, makeEffectCallerFactory, } from "./testing/caller.js";
2
- export type { MakeTrpcItOptions, TrpcIt, TrpcTest, TrpcTester, } from "./testing/types.js";
3
- export { makeTrpcIt } from "./testing/vitest.js";
2
+ export type { CallerOptions, CallerResult, MakeTrpcHarnessItOptions, MakeTrpcItOptions, TrpcHarnessIt, TrpcHarnessTest, TrpcHarnessTester, TrpcIt, TrpcTest, TrpcTester, } from "./testing/types.js";
3
+ export { makeTrpcHarnessIt, makeTrpcIt } from "./testing/vitest.js";
4
4
  //# sourceMappingURL=testing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,iBAAiB,EACjB,MAAM,EACN,QAAQ,EACR,UAAU,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,MAAM,EACN,QAAQ,EACR,UAAU,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/testing.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { makeEffectCaller, makeEffectCallerFactory, } from "./testing/caller.js";
2
- export { makeTrpcIt } from "./testing/vitest.js";
2
+ export { makeTrpcHarnessIt, makeTrpcIt } from "./testing/vitest.js";
3
3
  //# sourceMappingURL=testing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { TRPCError } from "@trpc/server";
2
- import type { Effect } from "effect";
3
- export type ProcedureKind = "mutation" | "query";
2
+ import type { Effect, Stream } from "effect";
3
+ export type ProcedureKind = "mutation" | "query" | "subscription";
4
4
  export interface ProcedureInfo {
5
5
  readonly captureStackTrace: () => string | undefined;
6
6
  readonly path: string;
@@ -11,4 +11,5 @@ export interface EffectTRPCErrorContext extends ProcedureInfo {
11
11
  }
12
12
  export type EffectTRPCErrorMapper = (error: unknown, context: EffectTRPCErrorContext) => TRPCError | undefined;
13
13
  export type EffectTRPCInstrument = <A, E, R>(effect: Effect.Effect<A, E, R>, procedure: ProcedureInfo) => Effect.Effect<A, E, R>;
14
+ export type EffectTRPCStreamInstrument = <A, E, R>(stream: Stream.Stream<A, E, R>, procedure: ProcedureInfo) => Stream.Stream<A, E, R>;
14
15
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,qBAAqB,GAAG,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,sBAAsB,KAC3B,SAAS,GAAG,SAAS,CAAC;AAE3B,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,SAAS,EAAE,aAAa,KACpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;AAElE,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,qBAAqB,GAAG,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,sBAAsB,KAC3B,SAAS,GAAG,SAAS,CAAC;AAE3B,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,SAAS,EAAE,aAAa,KACpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAE5B,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAChD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,SAAS,EAAE,aAAa,KACpB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/effect-trpc",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Effect-native procedures and testing for tRPC",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/adapter.ts CHANGED
@@ -2,17 +2,42 @@ import type {
2
2
  inferProcedureBuilderResolverOptions,
3
3
  TRPCProcedureBuilder,
4
4
  } from "@trpc/server";
5
- import type { Context, ManagedRuntime } from "effect";
5
+ import type { Context, Effect, Exit } from "effect";
6
6
  import { makeContextBridge } from "./internal/context-bridge.js";
7
7
  import { makeRuntimeBridge } from "./internal/runtime.js";
8
8
  import { EffectProcedureBuilder } from "./procedure.js";
9
9
  import type { EffectProcedureRequestServices } from "./request-services.js";
10
- import type { EffectTRPCErrorMapper, EffectTRPCInstrument } from "./types.js";
10
+ import type {
11
+ EffectTRPCErrorMapper,
12
+ EffectTRPCInstrument,
13
+ EffectTRPCStreamInstrument,
14
+ } from "./types.js";
11
15
 
12
16
  export interface MakeEffectTRPCOptions<Requirements, RuntimeError> {
13
17
  readonly instrument?: EffectTRPCInstrument;
18
+ readonly instrumentStream?: EffectTRPCStreamInstrument;
14
19
  readonly mapError?: EffectTRPCErrorMapper;
15
- readonly runtime: ManagedRuntime.ManagedRuntime<Requirements, RuntimeError>;
20
+ readonly runtime: EffectTRPCRuntime<Requirements, RuntimeError>;
21
+ }
22
+
23
+ export interface EffectTRPCRuntime<Requirements, RuntimeError> {
24
+ readonly contextEffect: Effect.Effect<
25
+ Context.Context<Requirements>,
26
+ RuntimeError
27
+ >;
28
+ readonly currentServices?: () => Context.Context<never> | undefined;
29
+ readonly runPromise: <Value, Error>(
30
+ effect: Effect.Effect<Value, Error, Requirements>,
31
+ options?: { readonly signal?: AbortSignal },
32
+ ) => Promise<Value>;
33
+ readonly runPromiseExit: <Value, Error>(
34
+ effect: Effect.Effect<Value, Error, Requirements>,
35
+ options?: { readonly signal?: AbortSignal },
36
+ ) => Promise<Exit.Exit<Value, Error | RuntimeError>>;
37
+ readonly runWithServices?: <Services, Value>(
38
+ services: Context.Context<Services>,
39
+ evaluate: () => Value,
40
+ ) => Value;
16
41
  }
17
42
 
18
43
  export interface EffectTRPCAdapter<Requirements> {
@@ -74,7 +99,7 @@ export interface EffectTRPCAdapter<Requirements> {
74
99
  export const makeEffectTRPC = <Requirements, RuntimeError = never>(
75
100
  options: MakeEffectTRPCOptions<Requirements, RuntimeError>,
76
101
  ): EffectTRPCAdapter<Requirements> => {
77
- const contextBridge = makeContextBridge();
102
+ const contextBridge = makeContextBridge(options.runtime);
78
103
  const runtime = makeRuntimeBridge(options.runtime, contextBridge, options);
79
104
 
80
105
  return {
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export {
2
2
  type EffectTRPCAdapter,
3
+ type EffectTRPCRuntime,
3
4
  type MakeEffectTRPCOptions,
4
5
  makeEffectTRPC,
5
6
  } from "./adapter.js";
@@ -19,10 +20,12 @@ export {
19
20
  extendRequestServices,
20
21
  makeRequestServices,
21
22
  } from "./request-services.js";
23
+ export { RequestSignal } from "./request-signal.js";
22
24
  export type {
23
25
  EffectTRPCErrorContext,
24
26
  EffectTRPCErrorMapper,
25
27
  EffectTRPCInstrument,
28
+ EffectTRPCStreamInstrument,
26
29
  ProcedureInfo,
27
30
  ProcedureKind,
28
31
  } from "./types.js";
@@ -9,7 +9,20 @@ export interface ContextBridge {
9
9
  ) => Value;
10
10
  }
11
11
 
12
- export const makeContextBridge = (): ContextBridge => {
12
+ export const makeContextBridge = (shared?: {
13
+ readonly currentServices?: ContextBridge["current"];
14
+ readonly runWithServices?: ContextBridge["run"];
15
+ }): ContextBridge => {
16
+ if (
17
+ shared?.currentServices !== undefined &&
18
+ shared.runWithServices !== undefined
19
+ ) {
20
+ return {
21
+ current: shared.currentServices,
22
+ run: shared.runWithServices,
23
+ };
24
+ }
25
+
13
26
  const storage = new AsyncLocalStorage<Context.Context<never>>();
14
27
 
15
28
  return {
@@ -3,7 +3,7 @@ import type {
3
3
  TRPCProcedureBuilder,
4
4
  TRPCUnsetMarker,
5
5
  } from "@trpc/server";
6
- import type { Effect } from "effect";
6
+ import type { Effect, Stream } from "effect";
7
7
 
8
8
  export type AnyProcedureBuilder = TRPCProcedureBuilder<
9
9
  // biome-ignore lint/suspicious/noExplicitAny: tRPC phantom slot extraction
@@ -47,3 +47,11 @@ export type ProcedureEffect<Requirements> = Effect.Effect<
47
47
  export type EffectProcedureResolver<Input, Requirements, Output> = (
48
48
  input: Input,
49
49
  ) => Generator<ProcedureEffect<Requirements>, Output, never>;
50
+
51
+ export type EffectSubscriptionResolver<Input, Requirements, Output> = (
52
+ input: Input,
53
+ ) => Generator<
54
+ ProcedureEffect<Requirements>,
55
+ Stream.Stream<Output, unknown, Requirements>,
56
+ never
57
+ >;
@@ -1,13 +1,6 @@
1
1
  import { TRPCError } from "@trpc/server";
2
- import {
3
- Cause,
4
- Context,
5
- Effect,
6
- Exit,
7
- type ManagedRuntime,
8
- Option,
9
- Result,
10
- } from "effect";
2
+ import { Cause, Context, Effect, Exit, Option, Result, Stream } from "effect";
3
+ import type { EffectTRPCRuntime } from "../adapter.js";
11
4
  import type {
12
5
  EffectTRPCErrorMapper,
13
6
  EffectTRPCInstrument,
@@ -26,6 +19,10 @@ export interface RuntimeBridge<Requirements> {
26
19
  effect: Effect.Effect<Value, unknown, Requirements>,
27
20
  options: RunEffectOptions,
28
21
  ) => Promise<Value>;
22
+ readonly runStream: <Value>(
23
+ stream: Stream.Stream<Value, unknown, Requirements>,
24
+ options: RunEffectOptions,
25
+ ) => Promise<AsyncIterable<Value>>;
29
26
  }
30
27
 
31
28
  const internalError = (cause?: unknown): TRPCError =>
@@ -54,11 +51,50 @@ const mapError = (
54
51
  }
55
52
  };
56
53
 
54
+ const mapCause = (
55
+ cause: Cause.Cause<unknown>,
56
+ procedure: ProcedureInfo,
57
+ consumerMapper: EffectTRPCErrorMapper | undefined,
58
+ ): TRPCError => {
59
+ if (Cause.hasInterruptsOnly(cause)) {
60
+ return new TRPCError({
61
+ code: "CLIENT_CLOSED_REQUEST",
62
+ message: "Request cancelled",
63
+ });
64
+ }
65
+
66
+ const failure = Cause.findErrorOption(cause);
67
+ if (Option.isSome(failure)) {
68
+ return mapError(failure.value, "failure", procedure, consumerMapper);
69
+ }
70
+
71
+ const defect = Cause.findDefect(cause);
72
+ if (Result.isSuccess(defect)) {
73
+ return mapError(defect.success, "defect", procedure, consumerMapper);
74
+ }
75
+
76
+ return internalError();
77
+ };
78
+
79
+ const interruptOn = (signal: AbortSignal | undefined): Effect.Effect<void> => {
80
+ if (signal === undefined) return Effect.never;
81
+ return Effect.callback<void>((resume) => {
82
+ if (signal.aborted) {
83
+ resume(Effect.void);
84
+ return;
85
+ }
86
+ const abort = () => resume(Effect.void);
87
+ signal.addEventListener("abort", abort, { once: true });
88
+ return Effect.sync(() => signal.removeEventListener("abort", abort));
89
+ });
90
+ };
91
+
57
92
  export const makeRuntimeBridge = <Requirements, RuntimeError>(
58
- runtime: ManagedRuntime.ManagedRuntime<Requirements, RuntimeError>,
93
+ runtime: EffectTRPCRuntime<Requirements, RuntimeError>,
59
94
  contextBridge: ContextBridge,
60
95
  options: {
61
96
  readonly instrument?: EffectTRPCInstrument;
97
+ readonly instrumentStream?: import("../types.js").EffectTRPCStreamInstrument;
62
98
  readonly mapError?: EffectTRPCErrorMapper;
63
99
  },
64
100
  ): RuntimeBridge<Requirements> => ({
@@ -68,6 +104,31 @@ export const makeRuntimeBridge = <Requirements, RuntimeError>(
68
104
  ? effect
69
105
  : options.instrument(effect, procedure),
70
106
  ),
107
+ runStream: async (stream, runOptions) => {
108
+ const instrumented = Stream.suspend(() =>
109
+ options.instrumentStream === undefined
110
+ ? stream
111
+ : options.instrumentStream(stream, runOptions.procedure),
112
+ ).pipe(
113
+ Stream.withSpan(runOptions.procedure.path, {
114
+ attributes: {
115
+ "rpc.method": runOptions.procedure.path,
116
+ "rpc.system": "trpc",
117
+ "trpc.type": runOptions.procedure.type,
118
+ },
119
+ captureStackTrace: runOptions.procedure.captureStackTrace,
120
+ }),
121
+ Stream.interruptWhen(interruptOn(runOptions.signal)),
122
+ Stream.catchCause((cause) =>
123
+ Stream.fail(mapCause(cause, runOptions.procedure, options.mapError)),
124
+ ),
125
+ );
126
+ const context = await runtime.runPromise(Effect.context<Requirements>());
127
+ const ambient = contextBridge.current();
128
+ const provided =
129
+ ambient === undefined ? context : Context.merge(context, ambient);
130
+ return Stream.toAsyncIterableWith(instrumented, provided);
131
+ },
71
132
  runEffect: async (effect, runOptions) => {
72
133
  const traced = effect.pipe(
73
134
  Effect.withSpan(
@@ -101,33 +162,6 @@ export const makeRuntimeBridge = <Requirements, RuntimeError>(
101
162
  if (Exit.isSuccess(exit)) {
102
163
  return exit.value;
103
164
  }
104
- if (Cause.hasInterruptsOnly(exit.cause)) {
105
- throw new TRPCError({
106
- code: "CLIENT_CLOSED_REQUEST",
107
- message: "Request cancelled",
108
- });
109
- }
110
-
111
- const failure = Cause.findErrorOption(exit.cause);
112
- if (Option.isSome(failure)) {
113
- throw mapError(
114
- failure.value,
115
- "failure",
116
- runOptions.procedure,
117
- options.mapError,
118
- );
119
- }
120
-
121
- const defect = Cause.findDefect(exit.cause);
122
- if (Result.isSuccess(defect)) {
123
- throw mapError(
124
- defect.success,
125
- "defect",
126
- runOptions.procedure,
127
- options.mapError,
128
- );
129
- }
130
-
131
- throw internalError();
165
+ throw mapCause(exit.cause, runOptions.procedure, options.mapError);
132
166
  },
133
167
  });
@@ -0,0 +1,61 @@
1
+ import { Effect, Layer, Schema, Stream } from "effect";
2
+ import type { EffectProcedureRequestServices } from "../request-services.js";
3
+ import { RequestSignal } from "../request-signal.js";
4
+ import type { ProcedureInfo } from "../types.js";
5
+ import type { EffectSubscriptionResolver } from "./procedure-types.js";
6
+ import type { RuntimeBridge } from "./runtime.js";
7
+
8
+ interface SubscriptionInvocation<Context, Input> {
9
+ readonly ctx: Context;
10
+ readonly input: Input;
11
+ readonly path: string;
12
+ readonly signal?: AbortSignal;
13
+ }
14
+
15
+ export const makeSubscriptionHandler = <
16
+ RuntimeRequirements,
17
+ Context,
18
+ Input,
19
+ ProvidedServices,
20
+ LayerError,
21
+ Output,
22
+ >(
23
+ runtime: RuntimeBridge<RuntimeRequirements>,
24
+ resolver: EffectSubscriptionResolver<
25
+ Input,
26
+ ProvidedServices | NoInfer<RuntimeRequirements>,
27
+ Output
28
+ >,
29
+ requestServices: EffectProcedureRequestServices<
30
+ Context,
31
+ ProvidedServices,
32
+ LayerError
33
+ >,
34
+ procedure: Omit<ProcedureInfo, "path">,
35
+ outputSchema?: Schema.ConstraintDecoder<unknown>,
36
+ ) => {
37
+ const tracedResolver = Effect.fnUntraced(resolver);
38
+
39
+ return async (invocation: SubscriptionInvocation<Context, Input>) => {
40
+ const info = { ...procedure, path: invocation.path };
41
+ const requestLayer = Layer.merge(
42
+ requestServices.layer(invocation.ctx),
43
+ Layer.succeed(RequestSignal, invocation.signal),
44
+ );
45
+ let stream = Stream.unwrap(
46
+ Effect.suspend(() =>
47
+ runtime.instrument(tracedResolver(invocation.input), info),
48
+ ),
49
+ ).pipe(Stream.provide(requestLayer));
50
+ if (outputSchema !== undefined) {
51
+ stream = Stream.mapEffect(stream, (value) =>
52
+ Schema.decodeUnknownEffect(outputSchema)(value),
53
+ ) as typeof stream;
54
+ }
55
+
56
+ return await runtime.runStream(stream, {
57
+ procedure: info,
58
+ ...(invocation.signal === undefined ? {} : { signal: invocation.signal }),
59
+ });
60
+ };
61
+ };