@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.
- package/CHANGELOG.md +16 -0
- package/README.md +24 -7
- package/dist/adapter.d.ts +15 -3
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/context-bridge.d.ts +4 -1
- package/dist/internal/context-bridge.d.ts.map +1 -1
- package/dist/internal/context-bridge.js +8 -1
- package/dist/internal/context-bridge.js.map +1 -1
- package/dist/internal/procedure-types.d.ts +2 -1
- package/dist/internal/procedure-types.d.ts.map +1 -1
- package/dist/internal/runtime.d.ts +5 -2
- package/dist/internal/runtime.d.ts.map +1 -1
- package/dist/internal/runtime.js +48 -16
- package/dist/internal/runtime.js.map +1 -1
- package/dist/internal/subscription-handler.d.ts +14 -0
- package/dist/internal/subscription-handler.d.ts.map +1 -0
- package/dist/internal/subscription-handler.js +18 -0
- package/dist/internal/subscription-handler.js.map +1 -0
- package/dist/internal/vitest-trpc.d.ts +2 -1
- package/dist/internal/vitest-trpc.d.ts.map +1 -1
- package/dist/internal/vitest-trpc.js +8 -3
- package/dist/internal/vitest-trpc.js.map +1 -1
- package/dist/procedure.d.ts +10 -3
- package/dist/procedure.d.ts.map +1 -1
- package/dist/procedure.js +16 -3
- package/dist/procedure.js.map +1 -1
- package/dist/request-signal.d.ts +4 -0
- package/dist/request-signal.d.ts.map +1 -0
- package/dist/request-signal.js +4 -0
- package/dist/request-signal.js.map +1 -0
- package/dist/testing/types.d.ts +19 -9
- package/dist/testing/types.d.ts.map +1 -1
- package/dist/testing/vitest.d.ts +2 -1
- package/dist/testing/vitest.d.ts.map +1 -1
- package/dist/testing/vitest.js +29 -22
- package/dist/testing/vitest.js.map +1 -1
- package/dist/testing.d.ts +2 -2
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapter.ts +29 -4
- package/src/index.ts +3 -0
- package/src/internal/context-bridge.ts +14 -1
- package/src/internal/procedure-types.ts +9 -1
- package/src/internal/runtime.ts +72 -38
- package/src/internal/subscription-handler.ts +61 -0
- package/src/internal/vitest-trpc.ts +34 -17
- package/src/procedure.ts +58 -0
- package/src/request-signal.ts +7 -0
- package/src/testing/types.ts +61 -14
- package/src/testing/vitest.ts +72 -26
- package/src/testing.ts +7 -1
- package/src/types.ts +7 -2
|
@@ -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/testing/types.d.ts
CHANGED
|
@@ -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
|
|
6
|
-
export interface
|
|
7
|
-
readonly skip:
|
|
8
|
-
readonly skipIf: (condition: unknown) =>
|
|
9
|
-
readonly runIf: (condition: unknown) =>
|
|
10
|
-
readonly only:
|
|
11
|
-
readonly each: <Item>(cases: ReadonlyArray<Item>) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(name: string, body: (item: Item,
|
|
12
|
-
readonly fails:
|
|
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
|
|
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":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"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"}
|
package/dist/testing/vitest.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/testing/vitest.js
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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,
|
|
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
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -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
package/dist/testing.js.map
CHANGED
|
@@ -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;
|
|
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
|
package/dist/types.d.ts.map
CHANGED
|
@@ -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;
|
|
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
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,
|
|
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 {
|
|
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:
|
|
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 = (
|
|
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
|
+
>;
|
package/src/internal/runtime.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { TRPCError } from "@trpc/server";
|
|
2
|
-
import {
|
|
3
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
+
};
|