@shivaedev/effect-trpc 0.2.0 → 0.3.1

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 (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +19 -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/procedure.d.ts +10 -3
  26. package/dist/procedure.d.ts.map +1 -1
  27. package/dist/procedure.js +16 -3
  28. package/dist/procedure.js.map +1 -1
  29. package/dist/request-signal.d.ts +4 -0
  30. package/dist/request-signal.d.ts.map +1 -0
  31. package/dist/request-signal.js +4 -0
  32. package/dist/request-signal.js.map +1 -0
  33. package/dist/types.d.ts +3 -2
  34. package/dist/types.d.ts.map +1 -1
  35. package/package.json +5 -5
  36. package/src/adapter.ts +29 -4
  37. package/src/index.ts +3 -0
  38. package/src/internal/context-bridge.ts +14 -1
  39. package/src/internal/procedure-types.ts +9 -1
  40. package/src/internal/runtime.ts +72 -38
  41. package/src/internal/subscription-handler.ts +61 -0
  42. package/src/procedure.ts +58 -0
  43. package/src/request-signal.ts +7 -0
  44. package/src/types.ts +7 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.3.1 - 2026-08-12
6
+
7
+ ### Changed
8
+
9
+ - Require Effect 4.0.0-beta.107, so applications can depend on packages such as
10
+ `@effect/platform-node` that are only published against the current beta line.
11
+
12
+ ## 0.3.0 - 2026-08-03
13
+
14
+ ### Added
15
+
16
+ - Add Effect Stream subscriptions with request-scoped Layers, transport
17
+ cancellation, finalizers, tracing, and stream instrumentation.
18
+ - Accept a shared application runtime so tRPC calls and other promise-based
19
+ adapters use the same ambient Effect services.
20
+
5
21
  ## 0.2.0 - 2026-08-03
6
22
 
7
23
  ### Added
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@shivaedev/effect-trpc`
2
2
 
3
- Effect-native query and mutation procedures for tRPC, with an optional Vitest
3
+ Effect-native query, mutation, and subscription procedures for tRPC, with an optional Vitest
4
4
  harness for calling routers as Effects.
5
5
 
6
6
  This package currently targets exact early-access versions of Effect v4 and
@@ -55,9 +55,21 @@ uses the schema's encoded type at the caller and decoded type in the generator;
55
55
  output uses the schema's encoded type in the generator and decoded type at the
56
56
  caller.
57
57
 
58
- Build middleware, metadata, and other tRPC configuration on the ordinary tRPC
59
- procedure builder before passing it to `adapter.procedure`. This release wraps
60
- queries and mutations; subscriptions are not yet supported.
58
+ Subscriptions return an Effect Stream. The request Layer remains open for the
59
+ stream's lifetime, transport cancellation interrupts the stream, and scoped
60
+ finalizers run when it ends:
61
+
62
+ ```ts
63
+ const updates = procedure.subscription(function* () {
64
+ const movies = yield* Movies
65
+ return movies.updates
66
+ })
67
+ ```
68
+
69
+ `RequestSignal` exposes tRPC's transport signal when application code needs to
70
+ combine it with another disconnect signal. Build middleware, metadata, and
71
+ other tRPC configuration on the ordinary tRPC procedure builder before passing
72
+ it to `adapter.procedure`.
61
73
 
62
74
  ## Request services
63
75
 
@@ -96,9 +108,9 @@ const adapter = makeEffectTRPC({
96
108
  })
97
109
  ```
98
110
 
99
- Each procedure runs in a span named after its tRPC path. `instrument` can add
100
- application-specific Effect logging, metrics, or tracing without changing
101
- procedure definitions.
111
+ Each procedure runs in a span named after its tRPC path. `instrument` and
112
+ `instrumentStream` can add application-specific Effect logging, metrics, or
113
+ tracing without changing procedure definitions.
102
114
 
103
115
  ## Vitest
104
116
 
package/dist/adapter.d.ts CHANGED
@@ -1,12 +1,24 @@
1
1
  import type { inferProcedureBuilderResolverOptions, TRPCProcedureBuilder } from "@trpc/server";
2
- import type { Context, ManagedRuntime } from "effect";
2
+ import type { Context, Effect, Exit } from "effect";
3
3
  import { EffectProcedureBuilder } from "./procedure.js";
4
4
  import type { EffectProcedureRequestServices } from "./request-services.js";
5
- import type { EffectTRPCErrorMapper, EffectTRPCInstrument } from "./types.js";
5
+ import type { EffectTRPCErrorMapper, EffectTRPCInstrument, EffectTRPCStreamInstrument } from "./types.js";
6
6
  export interface MakeEffectTRPCOptions<Requirements, RuntimeError> {
7
7
  readonly instrument?: EffectTRPCInstrument;
8
+ readonly instrumentStream?: EffectTRPCStreamInstrument;
8
9
  readonly mapError?: EffectTRPCErrorMapper;
9
- readonly runtime: ManagedRuntime.ManagedRuntime<Requirements, RuntimeError>;
10
+ readonly runtime: EffectTRPCRuntime<Requirements, RuntimeError>;
11
+ }
12
+ export interface EffectTRPCRuntime<Requirements, RuntimeError> {
13
+ readonly contextEffect: Effect.Effect<Context.Context<Requirements>, RuntimeError>;
14
+ readonly currentServices?: () => Context.Context<never> | undefined;
15
+ readonly runPromise: <Value, Error>(effect: Effect.Effect<Value, Error, Requirements>, options?: {
16
+ readonly signal?: AbortSignal;
17
+ }) => Promise<Value>;
18
+ readonly runPromiseExit: <Value, Error>(effect: Effect.Effect<Value, Error, Requirements>, options?: {
19
+ readonly signal?: AbortSignal;
20
+ }) => Promise<Exit.Exit<Value, Error | RuntimeError>>;
21
+ readonly runWithServices?: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
10
22
  }
11
23
  export interface EffectTRPCAdapter<Requirements> {
12
24
  readonly procedure: <Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError>(builder: TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>, requestServices: EffectProcedureRequestServices<inferProcedureBuilderResolverOptions<TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>>["ctx"], ProvidedServices, LayerError>) => EffectProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError, Requirements>;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oCAAoC,EACpC,oBAAoB,EACpB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,WAAW,qBAAqB,CAAC,YAAY,EAAE,YAAY;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,iBAAiB,CAAC,YAAY;IAC9C,QAAQ,CAAC,SAAS,EAAE,CACnB,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,UAAU,EAEV,OAAO,EAAE,oBAAoB,CAC5B,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,CACL,EACD,eAAe,EAAE,8BAA8B,CAC9C,oCAAoC,CACnC,oBAAoB,CACnB,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,CACL,CACD,CAAC,KAAK,CAAC,EACR,gBAAgB,EAChB,UAAU,CACV,KACG,sBAAsB,CAC1B,OAAO,EACP,IAAI,EACJ,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,YAAY,CACZ,CAAC;IACF,QAAQ,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,KAAK,EACzC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EACnC,QAAQ,EAAE,MAAM,KAAK,KACjB,KAAK,CAAC;CACX;AAED,eAAO,MAAM,cAAc,GAAI,YAAY,EAAE,YAAY,GAAG,KAAK,EAChE,SAAS,qBAAqB,CAAC,YAAY,EAAE,YAAY,CAAC,KACxD,iBAAiB,CAAC,YAAY,CAShC,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
package/dist/adapter.js CHANGED
@@ -2,7 +2,7 @@ import { makeContextBridge } from "./internal/context-bridge.js";
2
2
  import { makeRuntimeBridge } from "./internal/runtime.js";
3
3
  import { EffectProcedureBuilder } from "./procedure.js";
4
4
  export const makeEffectTRPC = (options) => {
5
- const contextBridge = makeContextBridge();
5
+ const contextBridge = makeContextBridge(options.runtime);
6
6
  const runtime = makeRuntimeBridge(options.runtime, contextBridge, options);
7
7
  return {
8
8
  procedure: (builder, requestServices) => new EffectProcedureBuilder(builder, requestServices, runtime),
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAkExD,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,OAA0D,EACxB,EAAE;IACpC,MAAM,aAAa,GAAG,iBAAiB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAE3E,OAAO;QACN,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,CACvC,IAAI,sBAAsB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAU;QACvE,eAAe,EAAE,aAAa,CAAC,GAAG;KAClC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AA2FxD,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,OAA0D,EACxB,EAAE;IACpC,MAAM,aAAa,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAE3E,OAAO;QACN,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,CACvC,IAAI,sBAAsB,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,CAAU;QACvE,eAAe,EAAE,aAAa,CAAC,GAAG;KAClC,CAAC;AACH,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- export { type EffectTRPCAdapter, type MakeEffectTRPCOptions, makeEffectTRPC, } from "./adapter.js";
1
+ export { type EffectTRPCAdapter, type EffectTRPCRuntime, type MakeEffectTRPCOptions, makeEffectTRPC, } from "./adapter.js";
2
2
  export { badRequest, conflict, fail, forbidden, internalServerError, notFound, preconditionFailed, unauthorized, } from "./errors.js";
3
3
  export type { EffectProcedureBuilder } from "./procedure.js";
4
4
  export { type EffectProcedureRequestServices, extendRequestServices, makeRequestServices, } from "./request-services.js";
5
- export type { EffectTRPCErrorContext, EffectTRPCErrorMapper, EffectTRPCInstrument, ProcedureInfo, ProcedureKind, } from "./types.js";
5
+ export { RequestSignal } from "./request-signal.js";
6
+ export type { EffectTRPCErrorContext, EffectTRPCErrorMapper, EffectTRPCInstrument, EffectTRPCStreamInstrument, ProcedureInfo, ProcedureKind, } from "./types.js";
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,cAAc,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACN,KAAK,8BAA8B,EACnC,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACX,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,cAAc,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACN,KAAK,8BAA8B,EACnC,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACX,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { makeEffectTRPC, } from "./adapter.js";
2
2
  export { badRequest, conflict, fail, forbidden, internalServerError, notFound, preconditionFailed, unauthorized, } from "./errors.js";
3
3
  export { extendRequestServices, makeRequestServices, } from "./request-services.js";
4
+ export { RequestSignal } from "./request-signal.js";
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,cAAc,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,YAAY,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAEN,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,cAAc,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,UAAU,EACV,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,YAAY,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAEN,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -3,5 +3,8 @@ export interface ContextBridge {
3
3
  readonly current: () => Context.Context<never> | undefined;
4
4
  readonly run: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
5
5
  }
6
- export declare const makeContextBridge: () => ContextBridge;
6
+ export declare const makeContextBridge: (shared?: {
7
+ readonly currentServices?: ContextBridge["current"];
8
+ readonly runWithServices?: ContextBridge["run"];
9
+ }) => ContextBridge;
7
10
  //# sourceMappingURL=context-bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/internal/context-bridge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,EAC7B,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EACnC,QAAQ,EAAE,MAAM,KAAK,KACjB,KAAK,CAAC;CACX;AAED,eAAO,MAAM,iBAAiB,QAAO,aAQpC,CAAC"}
1
+ {"version":3,"file":"context-bridge.d.ts","sourceRoot":"","sources":["../../src/internal/context-bridge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IAC3D,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,EAC7B,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EACnC,QAAQ,EAAE,MAAM,KAAK,KACjB,KAAK,CAAC;CACX;AAED,eAAO,MAAM,iBAAiB,GAAI,SAAS;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACpD,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAChD,KAAG,aAkBH,CAAC"}
@@ -1,5 +1,12 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
- export const makeContextBridge = () => {
2
+ export const makeContextBridge = (shared) => {
3
+ if (shared?.currentServices !== undefined &&
4
+ shared.runWithServices !== undefined) {
5
+ return {
6
+ current: shared.currentServices,
7
+ run: shared.runWithServices,
8
+ };
9
+ }
3
10
  const storage = new AsyncLocalStorage();
4
11
  return {
5
12
  current: () => storage.getStore(),
@@ -1 +1 @@
1
- {"version":3,"file":"context-bridge.js","sourceRoot":"","sources":["../../src/internal/context-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAWrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAkB,EAAE;IACpD,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAA0B,CAAC;IAEhE,OAAO;QACN,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;QACjC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAC3B,OAAO,CAAC,GAAG,CAAC,QAAkC,EAAE,QAAQ,CAAC;KAC1D,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"context-bridge.js","sourceRoot":"","sources":["../../src/internal/context-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAWrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAGjC,EAAiB,EAAE;IACnB,IACC,MAAM,EAAE,eAAe,KAAK,SAAS;QACrC,MAAM,CAAC,eAAe,KAAK,SAAS,EACnC,CAAC;QACF,OAAO;YACN,OAAO,EAAE,MAAM,CAAC,eAAe;YAC/B,GAAG,EAAE,MAAM,CAAC,eAAe;SAC3B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAA0B,CAAC;IAEhE,OAAO;QACN,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;QACjC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAC3B,OAAO,CAAC,GAAG,CAAC,QAAkC,EAAE,QAAQ,CAAC;KAC1D,CAAC;AACH,CAAC,CAAC"}
@@ -1,9 +1,10 @@
1
1
  import type { inferProcedureBuilderResolverOptions, TRPCProcedureBuilder, TRPCUnsetMarker } from "@trpc/server";
2
- import type { Effect } from "effect";
2
+ import type { Effect, Stream } from "effect";
3
3
  export type AnyProcedureBuilder = TRPCProcedureBuilder<any, any, any, any, any, any, any, false>;
4
4
  export type DefaultValue<Value, Fallback> = Value extends TRPCUnsetMarker ? Fallback : Value;
5
5
  export type IntersectIfDefined<Value, With> = Value extends TRPCUnsetMarker ? With : With extends TRPCUnsetMarker ? Value : Value & With;
6
6
  export type ResolverContext<Builder extends AnyProcedureBuilder> = inferProcedureBuilderResolverOptions<Builder>["ctx"];
7
7
  export type ProcedureEffect<Requirements> = Effect.Effect<any, any, Requirements>;
8
8
  export type EffectProcedureResolver<Input, Requirements, Output> = (input: Input) => Generator<ProcedureEffect<Requirements>, Output, never>;
9
+ export type EffectSubscriptionResolver<Input, Requirements, Output> = (input: Input) => Generator<ProcedureEffect<Requirements>, Stream.Stream<Output, unknown, Requirements>, never>;
9
10
  //# sourceMappingURL=procedure-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"procedure-types.d.ts","sourceRoot":"","sources":["../../src/internal/procedure-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oCAAoC,EACpC,oBAAoB,EACpB,eAAe,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAErD,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EACH,KAAK,CACL,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,QAAQ,IAAI,KAAK,SAAS,eAAe,GACtE,QAAQ,GACR,KAAK,CAAC;AAET,MAAM,MAAM,kBAAkB,CAAC,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,eAAe,GACxE,IAAI,GACJ,IAAI,SAAS,eAAe,GAC3B,KAAK,GACL,KAAK,GAAG,IAAI,CAAC;AAEjB,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,mBAAmB,IAC9D,oCAAoC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;AAEtD,MAAM,MAAM,eAAe,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,CAExD,GAAG,EAEH,GAAG,EACH,YAAY,CACZ,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAClE,KAAK,EAAE,KAAK,KACR,SAAS,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"procedure-types.d.ts","sourceRoot":"","sources":["../../src/internal/procedure-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oCAAoC,EACpC,oBAAoB,EACpB,eAAe,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAErD,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EAEH,GAAG,EACH,KAAK,CACL,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,QAAQ,IAAI,KAAK,SAAS,eAAe,GACtE,QAAQ,GACR,KAAK,CAAC;AAET,MAAM,MAAM,kBAAkB,CAAC,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,eAAe,GACxE,IAAI,GACJ,IAAI,SAAS,eAAe,GAC3B,KAAK,GACL,KAAK,GAAG,IAAI,CAAC;AAEjB,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,mBAAmB,IAC9D,oCAAoC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;AAEtD,MAAM,MAAM,eAAe,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,CAExD,GAAG,EAEH,GAAG,EACH,YAAY,CACZ,CAAC;AAEF,MAAM,MAAM,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAClE,KAAK,EAAE,KAAK,KACR,SAAS,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE7D,MAAM,MAAM,0BAA0B,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CACrE,KAAK,EAAE,KAAK,KACR,SAAS,CACb,eAAe,CAAC,YAAY,CAAC,EAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,EAC5C,KAAK,CACL,CAAC"}
@@ -1,4 +1,5 @@
1
- import { Effect, type ManagedRuntime } from "effect";
1
+ import { Effect, Stream } from "effect";
2
+ import type { EffectTRPCRuntime } from "../adapter.js";
2
3
  import type { EffectTRPCErrorMapper, EffectTRPCInstrument, ProcedureInfo } from "../types.js";
3
4
  import type { ContextBridge } from "./context-bridge.js";
4
5
  interface RunEffectOptions {
@@ -8,9 +9,11 @@ interface RunEffectOptions {
8
9
  export interface RuntimeBridge<Requirements> {
9
10
  readonly instrument: EffectTRPCInstrument;
10
11
  readonly runEffect: <Value>(effect: Effect.Effect<Value, unknown, Requirements>, options: RunEffectOptions) => Promise<Value>;
12
+ readonly runStream: <Value>(stream: Stream.Stream<Value, unknown, Requirements>, options: RunEffectOptions) => Promise<AsyncIterable<Value>>;
11
13
  }
12
- export declare const makeRuntimeBridge: <Requirements, RuntimeError>(runtime: ManagedRuntime.ManagedRuntime<Requirements, RuntimeError>, contextBridge: ContextBridge, options: {
14
+ export declare const makeRuntimeBridge: <Requirements, RuntimeError>(runtime: EffectTRPCRuntime<Requirements, RuntimeError>, contextBridge: ContextBridge, options: {
13
15
  readonly instrument?: EffectTRPCInstrument;
16
+ readonly instrumentStream?: import("../types.js").EffectTRPCStreamInstrument;
14
17
  readonly mapError?: EffectTRPCErrorMapper;
15
18
  }) => RuntimeBridge<Requirements>;
16
19
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/internal/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAGN,MAAM,EAEN,KAAK,cAAc,EAGnB,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,UAAU,gBAAgB;IACzB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa,CAAC,YAAY;IAC1C,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EACnD,OAAO,EAAE,gBAAgB,KACrB,OAAO,CAAC,KAAK,CAAC,CAAC;CACpB;AA4BD,eAAO,MAAM,iBAAiB,GAAI,YAAY,EAAE,YAAY,EAC3D,SAAS,cAAc,CAAC,cAAc,CAAC,YAAY,EAAE,YAAY,CAAC,EAClE,eAAe,aAAa,EAC5B,SAAS;IACR,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAC1C,KACC,aAAa,CAAC,YAAY,CAqE3B,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/internal/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAwB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,UAAU,gBAAgB;IACzB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa,CAAC,YAAY;IAC1C,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EACnD,OAAO,EAAE,gBAAgB,KACrB,OAAO,CAAC,KAAK,CAAC,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EACnD,OAAO,EAAE,gBAAgB,KACrB,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;CACnC;AAkED,eAAO,MAAM,iBAAiB,GAAI,YAAY,EAAE,YAAY,EAC3D,SAAS,iBAAiB,CAAC,YAAY,EAAE,YAAY,CAAC,EACtD,eAAe,aAAa,EAC5B,SAAS;IACR,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,aAAa,EAAE,0BAA0B,CAAC;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAC1C,KACC,aAAa,CAAC,YAAY,CAmE3B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { TRPCError } from "@trpc/server";
2
- import { Cause, Context, Effect, Exit, Option, Result, } from "effect";
2
+ import { Cause, Context, Effect, Exit, Option, Result, Stream } from "effect";
3
3
  const internalError = (cause) => new TRPCError({
4
4
  cause,
5
5
  code: "INTERNAL_SERVER_ERROR",
@@ -16,10 +16,56 @@ const mapError = (error, origin, procedure, consumerMapper) => {
16
16
  return internalError(mapperDefect);
17
17
  }
18
18
  };
19
+ const mapCause = (cause, procedure, consumerMapper) => {
20
+ if (Cause.hasInterruptsOnly(cause)) {
21
+ return new TRPCError({
22
+ code: "CLIENT_CLOSED_REQUEST",
23
+ message: "Request cancelled",
24
+ });
25
+ }
26
+ const failure = Cause.findErrorOption(cause);
27
+ if (Option.isSome(failure)) {
28
+ return mapError(failure.value, "failure", procedure, consumerMapper);
29
+ }
30
+ const defect = Cause.findDefect(cause);
31
+ if (Result.isSuccess(defect)) {
32
+ return mapError(defect.success, "defect", procedure, consumerMapper);
33
+ }
34
+ return internalError();
35
+ };
36
+ const interruptOn = (signal) => {
37
+ if (signal === undefined)
38
+ return Effect.never;
39
+ return Effect.callback((resume) => {
40
+ if (signal.aborted) {
41
+ resume(Effect.void);
42
+ return;
43
+ }
44
+ const abort = () => resume(Effect.void);
45
+ signal.addEventListener("abort", abort, { once: true });
46
+ return Effect.sync(() => signal.removeEventListener("abort", abort));
47
+ });
48
+ };
19
49
  export const makeRuntimeBridge = (runtime, contextBridge, options) => ({
20
50
  instrument: (effect, procedure) => Effect.suspend(() => options.instrument === undefined
21
51
  ? effect
22
52
  : options.instrument(effect, procedure)),
53
+ runStream: async (stream, runOptions) => {
54
+ const instrumented = Stream.suspend(() => options.instrumentStream === undefined
55
+ ? stream
56
+ : options.instrumentStream(stream, runOptions.procedure)).pipe(Stream.withSpan(runOptions.procedure.path, {
57
+ attributes: {
58
+ "rpc.method": runOptions.procedure.path,
59
+ "rpc.system": "trpc",
60
+ "trpc.type": runOptions.procedure.type,
61
+ },
62
+ captureStackTrace: runOptions.procedure.captureStackTrace,
63
+ }), Stream.interruptWhen(interruptOn(runOptions.signal)), Stream.catchCause((cause) => Stream.fail(mapCause(cause, runOptions.procedure, options.mapError))));
64
+ const context = await runtime.runPromise(Effect.context());
65
+ const ambient = contextBridge.current();
66
+ const provided = ambient === undefined ? context : Context.merge(context, ambient);
67
+ return Stream.toAsyncIterableWith(instrumented, provided);
68
+ },
23
69
  runEffect: async (effect, runOptions) => {
24
70
  const traced = effect.pipe(Effect.withSpan(runOptions.procedure.path, {
25
71
  attributes: {
@@ -40,21 +86,7 @@ export const makeRuntimeBridge = (runtime, contextBridge, options) => ({
40
86
  if (Exit.isSuccess(exit)) {
41
87
  return exit.value;
42
88
  }
43
- if (Cause.hasInterruptsOnly(exit.cause)) {
44
- throw new TRPCError({
45
- code: "CLIENT_CLOSED_REQUEST",
46
- message: "Request cancelled",
47
- });
48
- }
49
- const failure = Cause.findErrorOption(exit.cause);
50
- if (Option.isSome(failure)) {
51
- throw mapError(failure.value, "failure", runOptions.procedure, options.mapError);
52
- }
53
- const defect = Cause.findDefect(exit.cause);
54
- if (Result.isSuccess(defect)) {
55
- throw mapError(defect.success, "defect", runOptions.procedure, options.mapError);
56
- }
57
- throw internalError();
89
+ throw mapCause(exit.cause, runOptions.procedure, options.mapError);
58
90
  },
59
91
  });
60
92
  //# sourceMappingURL=runtime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/internal/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/internal/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Schema } from "effect";
2
+ import type { EffectProcedureRequestServices } from "../request-services.js";
3
+ import type { ProcedureInfo } from "../types.js";
4
+ import type { EffectSubscriptionResolver } from "./procedure-types.js";
5
+ import type { RuntimeBridge } from "./runtime.js";
6
+ interface SubscriptionInvocation<Context, Input> {
7
+ readonly ctx: Context;
8
+ readonly input: Input;
9
+ readonly path: string;
10
+ readonly signal?: AbortSignal;
11
+ }
12
+ export declare const makeSubscriptionHandler: <RuntimeRequirements, Context, Input, ProvidedServices, LayerError, Output>(runtime: RuntimeBridge<RuntimeRequirements>, resolver: EffectSubscriptionResolver<Input, ProvidedServices | NoInfer<RuntimeRequirements>, Output>, requestServices: EffectProcedureRequestServices<Context, ProvidedServices, LayerError>, procedure: Omit<ProcedureInfo, "path">, outputSchema?: Schema.ConstraintDecoder<unknown>) => (invocation: SubscriptionInvocation<Context, Input>) => Promise<AsyncIterable<Output>>;
13
+ export {};
14
+ //# sourceMappingURL=subscription-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-handler.d.ts","sourceRoot":"","sources":["../../src/internal/subscription-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAU,MAAM,QAAQ,CAAC;AACvD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,UAAU,sBAAsB,CAAC,OAAO,EAAE,KAAK;IAC9C,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,eAAO,MAAM,uBAAuB,GACnC,mBAAmB,EACnB,OAAO,EACP,KAAK,EACL,gBAAgB,EAChB,UAAU,EACV,MAAM,EAEN,SAAS,aAAa,CAAC,mBAAmB,CAAC,EAC3C,UAAU,0BAA0B,CACnC,KAAK,EACL,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC,EAC/C,MAAM,CACN,EACD,iBAAiB,8BAA8B,CAC9C,OAAO,EACP,gBAAgB,EAChB,UAAU,CACV,EACD,WAAW,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EACtC,eAAe,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAIlC,YAAY,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC,mCAsBhE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Effect, Layer, Schema, Stream } from "effect";
2
+ import { RequestSignal } from "../request-signal.js";
3
+ export const makeSubscriptionHandler = (runtime, resolver, requestServices, procedure, outputSchema) => {
4
+ const tracedResolver = Effect.fnUntraced(resolver);
5
+ return async (invocation) => {
6
+ const info = { ...procedure, path: invocation.path };
7
+ const requestLayer = Layer.merge(requestServices.layer(invocation.ctx), Layer.succeed(RequestSignal, invocation.signal));
8
+ let stream = Stream.unwrap(Effect.suspend(() => runtime.instrument(tracedResolver(invocation.input), info))).pipe(Stream.provide(requestLayer));
9
+ if (outputSchema !== undefined) {
10
+ stream = Stream.mapEffect(stream, (value) => Schema.decodeUnknownEffect(outputSchema)(value));
11
+ }
12
+ return await runtime.runStream(stream, {
13
+ procedure: info,
14
+ ...(invocation.signal === undefined ? {} : { signal: invocation.signal }),
15
+ });
16
+ };
17
+ };
18
+ //# sourceMappingURL=subscription-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-handler.js","sourceRoot":"","sources":["../../src/internal/subscription-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAYrD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAQtC,OAA2C,EAC3C,QAIC,EACD,eAIC,EACD,SAAsC,EACtC,YAAgD,EAC/C,EAAE;IACH,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEnD,OAAO,KAAK,EAAE,UAAkD,EAAE,EAAE;QACnE,MAAM,IAAI,GAAG,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAC/B,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EACrC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,MAAM,CAAC,CAC/C,CAAC;QACF,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,CACzB,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CACnB,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAC1D,CACD,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QACrC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAC3C,MAAM,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAC9B,CAAC;QACpB,CAAC;QAED,OAAO,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE;YACtC,SAAS,EAAE,IAAI;YACf,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;SACzE,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
- import type { TRPCMutationProcedure, TRPCProcedureBuilder, TRPCQueryProcedure } from "@trpc/server";
1
+ import type { TRPCMutationProcedure, TRPCProcedureBuilder, TRPCQueryProcedure, TRPCSubscriptionProcedure } from "@trpc/server";
2
2
  import { Schema } from "effect";
3
- import type { DefaultValue, EffectProcedureResolver, IntersectIfDefined, ResolverContext } from "./internal/procedure-types.js";
3
+ import type { DefaultValue, EffectProcedureResolver, EffectSubscriptionResolver, IntersectIfDefined, ResolverContext } from "./internal/procedure-types.js";
4
4
  import type { RuntimeBridge } from "./internal/runtime.js";
5
5
  import type { EffectProcedureRequestServices } from "./request-services.js";
6
6
  type Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut> = TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>;
@@ -8,7 +8,9 @@ export declare class EffectProcedureBuilder<Context, Meta, ContextOverrides, Inp
8
8
  private readonly builder;
9
9
  private readonly requestServices;
10
10
  private readonly runtime;
11
- constructor(builder: Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>, requestServices: EffectProcedureRequestServices<ResolverContext<Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>>, ProvidedServices, LayerError>, runtime: RuntimeBridge<RuntimeRequirements>);
11
+ private readonly subscriptionBuilder;
12
+ private readonly subscriptionOutput?;
13
+ constructor(builder: Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>, requestServices: EffectProcedureRequestServices<ResolverContext<Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>>, ProvidedServices, LayerError>, runtime: RuntimeBridge<RuntimeRequirements>, subscriptionBuilder?: Builder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>, subscriptionOutput?: Schema.ConstraintDecoder<unknown> | undefined);
12
14
  input<SchemaValue extends Schema.ConstraintDecoder<unknown>>(schema: SchemaValue): EffectProcedureBuilder<Context, Meta, ContextOverrides, IntersectIfDefined<InputIn, SchemaValue["Encoded"]>, IntersectIfDefined<InputOut, SchemaValue["Type"]>, OutputIn, OutputOut, ProvidedServices, LayerError, RuntimeRequirements>;
13
15
  output<SchemaValue extends Schema.ConstraintDecoder<unknown>>(schema: SchemaValue): EffectProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, IntersectIfDefined<OutputIn, SchemaValue["Encoded"]>, IntersectIfDefined<OutputOut, SchemaValue["Type"]>, ProvidedServices, LayerError, RuntimeRequirements>;
14
16
  query<Output>(resolver: EffectProcedureResolver<DefaultValue<InputOut, undefined>, ProvidedServices | NoInfer<RuntimeRequirements>, DefaultValue<OutputIn, Output>>): TRPCQueryProcedure<{
@@ -21,6 +23,11 @@ export declare class EffectProcedureBuilder<Context, Meta, ContextOverrides, Inp
21
23
  output: DefaultValue<OutputOut, Output>;
22
24
  meta: Meta;
23
25
  }>;
26
+ subscription<Output>(resolver: EffectSubscriptionResolver<DefaultValue<InputOut, undefined>, ProvidedServices | NoInfer<RuntimeRequirements>, DefaultValue<OutputIn, Output>>): TRPCSubscriptionProcedure<{
27
+ input: DefaultValue<InputIn, void>;
28
+ output: AsyncIterable<DefaultValue<OutputOut, Output>, void, unknown>;
29
+ meta: Meta;
30
+ }>;
24
31
  private dispatch;
25
32
  }
26
33
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"procedure.d.ts","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"procedure.d.ts","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"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"}
package/dist/procedure.js CHANGED
@@ -1,22 +1,28 @@
1
1
  import { Schema } from "effect";
2
2
  import { makeProcedureHandler } from "./internal/procedure-handler.js";
3
3
  import { captureStackTrace } from "./internal/stack-trace.js";
4
+ import { makeSubscriptionHandler } from "./internal/subscription-handler.js";
4
5
  export class EffectProcedureBuilder {
5
6
  builder;
6
7
  requestServices;
7
8
  runtime;
8
- constructor(builder, requestServices, runtime) {
9
+ subscriptionBuilder;
10
+ subscriptionOutput;
11
+ constructor(builder, requestServices, runtime, subscriptionBuilder = builder, subscriptionOutput) {
9
12
  this.builder = builder;
10
13
  this.requestServices = requestServices;
11
14
  this.runtime = runtime;
15
+ this.subscriptionBuilder = subscriptionBuilder;
16
+ this.subscriptionOutput = subscriptionOutput;
12
17
  }
13
18
  input(schema) {
14
19
  const next = this.builder.input(Schema.toStandardSchemaV1(schema));
15
- return new EffectProcedureBuilder(next, this.requestServices, this.runtime);
20
+ const subscriptionNext = this.subscriptionBuilder.input(Schema.toStandardSchemaV1(schema));
21
+ return new EffectProcedureBuilder(next, this.requestServices, this.runtime, subscriptionNext, this.subscriptionOutput);
16
22
  }
17
23
  output(schema) {
18
24
  const next = this.builder.output(Schema.toStandardSchemaV1(schema));
19
- return new EffectProcedureBuilder(next, this.requestServices, this.runtime);
25
+ return new EffectProcedureBuilder(next, this.requestServices, this.runtime, this.subscriptionBuilder, schema);
20
26
  }
21
27
  query(resolver) {
22
28
  return this.dispatch("query", resolver);
@@ -24,6 +30,13 @@ export class EffectProcedureBuilder {
24
30
  mutation(resolver) {
25
31
  return this.dispatch("mutation", resolver);
26
32
  }
33
+ subscription(resolver) {
34
+ const handler = makeSubscriptionHandler(this.runtime, resolver, this.requestServices, {
35
+ captureStackTrace: captureStackTrace(),
36
+ type: "subscription",
37
+ }, this.subscriptionOutput);
38
+ return this.subscriptionBuilder.subscription(handler);
39
+ }
27
40
  dispatch(type, resolver) {
28
41
  const handler = makeProcedureHandler(this.runtime, resolver, this.requestServices, { captureStackTrace: captureStackTrace(), type });
29
42
  return type === "query"
@@ -1 +1 @@
1
- {"version":3,"file":"procedure.js","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAQvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAsB9D,MAAM,OAAO,sBAAsB;IAahB;IASA;IAeA;IAzBlB,YACkB,OAQhB,EACgB,eAchB,EACgB,OAA2C;QAxB3C,YAAO,GAAP,OAAO,CAQvB;QACgB,oBAAe,GAAf,eAAe,CAc/B;QACgB,YAAO,GAAP,OAAO,CAAoC;IAC1D,CAAC;IAEJ,KAAK,CACJ,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAU,CAAC,CAAC;QAC5E,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,CACZ,CAAC;IACH,CAAC;IAED,MAAM,CACL,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,CACZ,CAAC;IACH,CAAC;IAED,KAAK,CACJ,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAIpC,CAAC;IACJ,CAAC;IAED,QAAQ,CACP,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAIvC,CAAC;IACJ,CAAC;IAEO,QAAQ,CACf,IAA0B,EAC1B,QAIC;QAED,MAAM,OAAO,GAAG,oBAAoB,CACnC,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,CACvC,CAAC;QACX,OAAO,IAAI,KAAK,OAAO;YACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACD"}
1
+ {"version":3,"file":"procedure.js","sourceRoot":"","sources":["../src/procedure.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AASvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAsB7E,MAAM,OAAO,sBAAsB;IAahB;IASA;IAeA;IACA;IACA;IA3BlB,YACkB,OAQhB,EACgB,eAchB,EACgB,OAA2C,EAC3C,sBAAsB,OAAO,EAC7B,kBAAsD;QA1BtD,YAAO,GAAP,OAAO,CAQvB;QACgB,oBAAe,GAAf,eAAe,CAc/B;QACgB,YAAO,GAAP,OAAO,CAAoC;QAC3C,wBAAmB,GAAnB,mBAAmB,CAAU;QAC7B,uBAAkB,GAAlB,kBAAkB,CAAoC;IACrE,CAAC;IAEJ,KAAK,CACJ,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAU,CAAC,CAAC;QAC5E,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CACtD,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAU,CAC1C,CAAC;QACF,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,EACZ,gBAQC,EACD,IAAI,CAAC,kBAAkB,CACvB,CAAC;IACH,CAAC;IAED,MAAM,CACL,MAAmB;QAanB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,OAAO,IAAI,sBAAsB,CAChC,IAQC,EACD,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,mBAQJ,EACD,MAAM,CACN,CAAC;IACH,CAAC;IAED,KAAK,CACJ,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAIpC,CAAC;IACJ,CAAC;IAED,QAAQ,CACP,QAIC;QAMD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAIvC,CAAC;IACJ,CAAC;IAED,YAAY,CACX,QAIC;QAMD,MAAM,OAAO,GAAG,uBAAuB,CACtC,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB;YACC,iBAAiB,EAAE,iBAAiB,EAAE;YACtC,IAAI,EAAE,cAAc;SACpB,EACD,IAAI,CAAC,kBAAkB,CACd,CAAC;QACX,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAC3C,OAAO,CAKN,CAAC;IACJ,CAAC;IAEO,QAAQ,CACf,IAA0B,EAC1B,QAIC;QAED,MAAM,OAAO,GAAG,oBAAoB,CACnC,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,CACvC,CAAC;QACX,OAAO,IAAI,KAAK,OAAO;YACtB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACD"}
@@ -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"}
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.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Effect-native procedures and testing for tRPC",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,9 +43,9 @@
43
43
  "provenance": true
44
44
  },
45
45
  "peerDependencies": {
46
- "@effect/vitest": "4.0.0-beta.102",
46
+ "@effect/vitest": "4.0.0-beta.107",
47
47
  "@trpc/server": "11.18.0",
48
- "effect": "4.0.0-beta.102"
48
+ "effect": "4.0.0-beta.107"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "@effect/vitest": {
@@ -53,11 +53,11 @@
53
53
  }
54
54
  },
55
55
  "devDependencies": {
56
- "@effect/vitest": "4.0.0-beta.102",
56
+ "@effect/vitest": "4.0.0-beta.107",
57
57
  "@trpc/server": "11.18.0",
58
58
  "@types/node": "24.10.1",
59
59
  "@typescript/native": "npm:typescript@7.0.2",
60
- "effect": "4.0.0-beta.102",
60
+ "effect": "4.0.0-beta.107",
61
61
  "typescript": "npm:@typescript/typescript6@6.0.2",
62
62
  "vitest": "4.1.9"
63
63
  },
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
+ };
package/src/procedure.ts CHANGED
@@ -2,17 +2,20 @@ import type {
2
2
  TRPCMutationProcedure,
3
3
  TRPCProcedureBuilder,
4
4
  TRPCQueryProcedure,
5
+ TRPCSubscriptionProcedure,
5
6
  } from "@trpc/server";
6
7
  import { Schema } from "effect";
7
8
  import { makeProcedureHandler } from "./internal/procedure-handler.js";
8
9
  import type {
9
10
  DefaultValue,
10
11
  EffectProcedureResolver,
12
+ EffectSubscriptionResolver,
11
13
  IntersectIfDefined,
12
14
  ResolverContext,
13
15
  } from "./internal/procedure-types.js";
14
16
  import type { RuntimeBridge } from "./internal/runtime.js";
15
17
  import { captureStackTrace } from "./internal/stack-trace.js";
18
+ import { makeSubscriptionHandler } from "./internal/subscription-handler.js";
16
19
  import type { EffectProcedureRequestServices } from "./request-services.js";
17
20
 
18
21
  type Builder<
@@ -72,6 +75,8 @@ export class EffectProcedureBuilder<
72
75
  LayerError
73
76
  >,
74
77
  private readonly runtime: RuntimeBridge<RuntimeRequirements>,
78
+ private readonly subscriptionBuilder = builder,
79
+ private readonly subscriptionOutput?: Schema.ConstraintDecoder<unknown>,
75
80
  ) {}
76
81
 
77
82
  input<SchemaValue extends Schema.ConstraintDecoder<unknown>>(
@@ -89,6 +94,9 @@ export class EffectProcedureBuilder<
89
94
  RuntimeRequirements
90
95
  > {
91
96
  const next = this.builder.input(Schema.toStandardSchemaV1(schema) as never);
97
+ const subscriptionNext = this.subscriptionBuilder.input(
98
+ Schema.toStandardSchemaV1(schema) as never,
99
+ );
92
100
  return new EffectProcedureBuilder(
93
101
  next as unknown as Builder<
94
102
  Context,
@@ -101,6 +109,16 @@ export class EffectProcedureBuilder<
101
109
  >,
102
110
  this.requestServices,
103
111
  this.runtime,
112
+ subscriptionNext as unknown as Builder<
113
+ Context,
114
+ Meta,
115
+ ContextOverrides,
116
+ IntersectIfDefined<InputIn, SchemaValue["Encoded"]>,
117
+ IntersectIfDefined<InputOut, SchemaValue["Type"]>,
118
+ OutputIn,
119
+ OutputOut
120
+ >,
121
+ this.subscriptionOutput,
104
122
  );
105
123
  }
106
124
 
@@ -131,6 +149,16 @@ export class EffectProcedureBuilder<
131
149
  >,
132
150
  this.requestServices,
133
151
  this.runtime,
152
+ this.subscriptionBuilder as unknown as Builder<
153
+ Context,
154
+ Meta,
155
+ ContextOverrides,
156
+ InputIn,
157
+ InputOut,
158
+ IntersectIfDefined<OutputIn, SchemaValue["Encoded"]>,
159
+ IntersectIfDefined<OutputOut, SchemaValue["Type"]>
160
+ >,
161
+ schema,
134
162
  );
135
163
  }
136
164
 
@@ -170,6 +198,36 @@ export class EffectProcedureBuilder<
170
198
  }>;
171
199
  }
172
200
 
201
+ subscription<Output>(
202
+ resolver: EffectSubscriptionResolver<
203
+ DefaultValue<InputOut, undefined>,
204
+ ProvidedServices | NoInfer<RuntimeRequirements>,
205
+ DefaultValue<OutputIn, Output>
206
+ >,
207
+ ): TRPCSubscriptionProcedure<{
208
+ input: DefaultValue<InputIn, void>;
209
+ output: AsyncIterable<DefaultValue<OutputOut, Output>, void, unknown>;
210
+ meta: Meta;
211
+ }> {
212
+ const handler = makeSubscriptionHandler(
213
+ this.runtime,
214
+ resolver,
215
+ this.requestServices,
216
+ {
217
+ captureStackTrace: captureStackTrace(),
218
+ type: "subscription",
219
+ },
220
+ this.subscriptionOutput,
221
+ ) as never;
222
+ return this.subscriptionBuilder.subscription(
223
+ handler,
224
+ ) as TRPCSubscriptionProcedure<{
225
+ input: DefaultValue<InputIn, void>;
226
+ output: AsyncIterable<DefaultValue<OutputOut, Output>, void, unknown>;
227
+ meta: Meta;
228
+ }>;
229
+ }
230
+
173
231
  private dispatch<Output>(
174
232
  type: "mutation" | "query",
175
233
  resolver: EffectProcedureResolver<
@@ -0,0 +1,7 @@
1
+ import { Context } from "effect";
2
+
3
+ /** The transport cancellation signal for the current tRPC procedure. */
4
+ export const RequestSignal = Context.Reference<AbortSignal | undefined>(
5
+ "@shivaedev/effect-trpc/RequestSignal",
6
+ { defaultValue: () => undefined },
7
+ );
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { TRPCError } from "@trpc/server";
2
- import type { Effect } from "effect";
2
+ import type { Effect, Stream } from "effect";
3
3
 
4
- export type ProcedureKind = "mutation" | "query";
4
+ export type ProcedureKind = "mutation" | "query" | "subscription";
5
5
 
6
6
  export interface ProcedureInfo {
7
7
  readonly captureStackTrace: () => string | undefined;
@@ -22,3 +22,8 @@ export type EffectTRPCInstrument = <A, E, R>(
22
22
  effect: Effect.Effect<A, E, R>,
23
23
  procedure: ProcedureInfo,
24
24
  ) => Effect.Effect<A, E, R>;
25
+
26
+ export type EffectTRPCStreamInstrument = <A, E, R>(
27
+ stream: Stream.Stream<A, E, R>,
28
+ procedure: ProcedureInfo,
29
+ ) => Stream.Stream<A, E, R>;