@shivaedev/effect-trpc 0.6.0 → 0.7.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 +23 -0
- package/README.md +309 -186
- package/dist/{client/rejection.d.ts → rejectionDecoding.d.ts} +4 -4
- package/dist/rejectionDecoding.d.ts.map +1 -0
- package/dist/{client/rejection.js → rejectionDecoding.js} +6 -4
- package/dist/rejectionDecoding.js.map +1 -0
- package/dist/server/EffectProcedureBuilder.d.ts +35 -0
- package/dist/server/EffectProcedureBuilder.d.ts.map +1 -0
- package/dist/server/EffectProcedureBuilder.js +38 -0
- package/dist/server/EffectProcedureBuilder.js.map +1 -0
- package/dist/{request-signal.d.ts → server/RequestSignal.d.ts} +1 -1
- package/dist/server/RequestSignal.d.ts.map +1 -0
- package/dist/{request-signal.js → server/RequestSignal.js} +1 -1
- package/dist/server/RequestSignal.js.map +1 -0
- package/dist/server/adapter.d.ts +29 -0
- package/dist/server/adapter.d.ts.map +1 -0
- package/dist/{adapter.js → server/adapter.js} +3 -3
- package/dist/server/adapter.js.map +1 -0
- package/dist/server/errors.d.ts +11 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +27 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/internal/captureStackTrace.d.ts +2 -0
- package/dist/server/internal/captureStackTrace.d.ts.map +1 -0
- package/dist/{internal/stack-trace.js → server/internal/captureStackTrace.js} +4 -4
- package/dist/server/internal/captureStackTrace.js.map +1 -0
- package/dist/{internal/context-bridge.d.ts → server/internal/contextBridge.d.ts} +4 -4
- package/dist/server/internal/contextBridge.d.ts.map +1 -0
- package/dist/{internal/context-bridge.js → server/internal/contextBridge.js} +3 -3
- package/dist/server/internal/contextBridge.js.map +1 -0
- package/dist/server/internal/loose.d.ts +4 -0
- package/dist/server/internal/loose.d.ts.map +1 -0
- package/dist/server/internal/loose.js.map +1 -0
- package/dist/server/internal/makeProcedureHandler.d.ts +6 -0
- package/dist/server/internal/makeProcedureHandler.d.ts.map +1 -0
- package/dist/{internal/procedure-handler.js → server/internal/makeProcedureHandler.js} +3 -3
- package/dist/server/internal/makeProcedureHandler.js.map +1 -0
- package/dist/server/internal/makeSubscriptionHandler.d.ts +7 -0
- package/dist/server/internal/makeSubscriptionHandler.d.ts.map +1 -0
- package/dist/{internal/subscription-handler.js → server/internal/makeSubscriptionHandler.js} +7 -5
- package/dist/server/internal/makeSubscriptionHandler.js.map +1 -0
- package/dist/server/internal/procedureTypes.d.ts +23 -0
- package/dist/server/internal/procedureTypes.d.ts.map +1 -0
- package/dist/server/internal/procedureTypes.js +2 -0
- package/dist/server/internal/procedureTypes.js.map +1 -0
- package/dist/server/internal/runtime.d.ts +20 -0
- package/dist/server/internal/runtime.d.ts.map +1 -0
- package/dist/server/internal/runtime.js +94 -0
- package/dist/server/internal/runtime.js.map +1 -0
- package/dist/{rejection.d.ts → server/rejection.d.ts} +5 -5
- package/dist/server/rejection.d.ts.map +1 -0
- package/dist/{rejection.js → server/rejection.js} +7 -3
- package/dist/server/rejection.js.map +1 -0
- package/dist/{rejection-formatter.d.ts → server/rejectionFormatter.d.ts} +6 -6
- package/dist/server/rejectionFormatter.d.ts.map +1 -0
- package/dist/{rejection-formatter.js → server/rejectionFormatter.js} +13 -9
- package/dist/server/rejectionFormatter.js.map +1 -0
- package/dist/server/requestServices.d.ts +7 -0
- package/dist/server/requestServices.d.ts.map +1 -0
- package/dist/server/requestServices.js +8 -0
- package/dist/server/requestServices.js.map +1 -0
- package/dist/{testing/any-test-layer.d.ts → server/testing/AnyTestLayer.d.ts} +1 -1
- package/dist/server/testing/AnyTestLayer.d.ts.map +1 -0
- package/dist/server/testing/AnyTestLayer.js +2 -0
- package/dist/server/testing/AnyTestLayer.js.map +1 -0
- package/dist/server/testing/caller.d.ts +12 -0
- package/dist/server/testing/caller.d.ts.map +1 -0
- package/dist/server/testing/caller.js +48 -0
- package/dist/server/testing/caller.js.map +1 -0
- package/dist/server/testing/types.d.ts +36 -0
- package/dist/server/testing/types.d.ts.map +1 -0
- package/dist/server/testing/types.js.map +1 -0
- package/dist/server/testing/vitest.d.ts +6 -0
- package/dist/server/testing/vitest.d.ts.map +1 -0
- package/dist/{testing → server/testing}/vitest.js +8 -6
- package/dist/server/testing/vitest.js.map +1 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/{testing → server}/types.js.map +1 -1
- package/docs/north-star.md +48 -0
- package/docs/roadmap.md +33 -0
- package/package.json +198 -22
- package/src/{client/rejection.ts → rejectionDecoding.ts} +7 -5
- package/src/server/EffectProcedureBuilder.ts +134 -0
- package/src/{request-signal.ts → server/RequestSignal.ts} +0 -1
- package/src/server/adapter.ts +83 -0
- package/src/server/errors.ts +26 -0
- package/src/{internal/stack-trace.ts → server/internal/captureStackTrace.ts} +3 -4
- package/src/{internal/context-bridge.ts → server/internal/contextBridge.ts} +4 -8
- package/src/server/internal/loose.ts +12 -0
- package/src/{internal/procedure-handler.ts → server/internal/makeProcedureHandler.ts} +8 -10
- package/src/{internal/subscription-handler.ts → server/internal/makeSubscriptionHandler.ts} +12 -13
- package/src/server/internal/procedureTypes.ts +35 -0
- package/src/server/internal/runtime.ts +131 -0
- package/src/{rejection.ts → server/rejection.ts} +22 -19
- package/src/{rejection-formatter.ts → server/rejectionFormatter.ts} +25 -18
- package/src/server/requestServices.ts +23 -0
- package/src/{testing/any-test-layer.ts → server/testing/AnyTestLayer.ts} +0 -1
- package/src/{testing → server/testing}/caller.ts +28 -33
- package/src/server/testing/types.ts +55 -0
- package/src/{testing → server/testing}/vitest.ts +17 -17
- package/src/{types.ts → server/types.ts} +0 -6
- package/dist/adapter.d.ts +0 -29
- package/dist/adapter.d.ts.map +0 -1
- package/dist/adapter.js.map +0 -1
- package/dist/client/rejection.d.ts.map +0 -1
- package/dist/client/rejection.js.map +0 -1
- package/dist/errors.d.ts +0 -11
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -11
- package/dist/errors.js.map +0 -1
- package/dist/internal/context-bridge.d.ts.map +0 -1
- package/dist/internal/context-bridge.js.map +0 -1
- package/dist/internal/loose.d.ts +0 -4
- package/dist/internal/loose.d.ts.map +0 -1
- package/dist/internal/loose.js.map +0 -1
- package/dist/internal/procedure-handler.d.ts +0 -6
- package/dist/internal/procedure-handler.d.ts.map +0 -1
- package/dist/internal/procedure-handler.js.map +0 -1
- package/dist/internal/procedure-types.d.ts +0 -23
- package/dist/internal/procedure-types.d.ts.map +0 -1
- package/dist/internal/procedure-types.js +0 -2
- package/dist/internal/procedure-types.js.map +0 -1
- package/dist/internal/runtime.d.ts +0 -20
- package/dist/internal/runtime.d.ts.map +0 -1
- package/dist/internal/runtime.js +0 -85
- package/dist/internal/runtime.js.map +0 -1
- package/dist/internal/stack-trace.d.ts +0 -2
- package/dist/internal/stack-trace.d.ts.map +0 -1
- package/dist/internal/stack-trace.js.map +0 -1
- package/dist/internal/subscription-handler.d.ts +0 -7
- package/dist/internal/subscription-handler.d.ts.map +0 -1
- package/dist/internal/subscription-handler.js.map +0 -1
- package/dist/procedure.d.ts +0 -36
- package/dist/procedure.d.ts.map +0 -1
- package/dist/procedure.js +0 -38
- package/dist/procedure.js.map +0 -1
- package/dist/rejection-formatter.d.ts.map +0 -1
- package/dist/rejection-formatter.js.map +0 -1
- package/dist/rejection.d.ts.map +0 -1
- package/dist/rejection.js.map +0 -1
- package/dist/request-services.d.ts +0 -7
- package/dist/request-services.d.ts.map +0 -1
- package/dist/request-services.js +0 -4
- package/dist/request-services.js.map +0 -1
- package/dist/request-signal.d.ts.map +0 -1
- package/dist/request-signal.js.map +0 -1
- package/dist/testing/any-test-layer.d.ts.map +0 -1
- package/dist/testing/any-test-layer.js +0 -2
- package/dist/testing/any-test-layer.js.map +0 -1
- package/dist/testing/caller.d.ts +0 -12
- package/dist/testing/caller.d.ts.map +0 -1
- package/dist/testing/caller.js +0 -42
- package/dist/testing/caller.js.map +0 -1
- package/dist/testing/types.d.ts +0 -36
- package/dist/testing/types.d.ts.map +0 -1
- package/dist/testing/vitest.d.ts +0 -6
- package/dist/testing/vitest.d.ts.map +0 -1
- package/dist/testing/vitest.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/src/adapter.ts +0 -72
- package/src/errors.ts +0 -19
- package/src/internal/loose.ts +0 -14
- package/src/internal/procedure-types.ts +0 -44
- package/src/internal/runtime.ts +0 -134
- package/src/procedure.ts +0 -142
- package/src/request-services.ts +0 -23
- package/src/testing/types.ts +0 -63
- /package/dist/{internal → server/internal}/loose.js +0 -0
- /package/dist/{testing → server/testing}/types.js +0 -0
- /package/dist/{types.d.ts → server/types.d.ts} +0 -0
- /package/dist/{types.js → server/types.js} +0 -0
package/dist/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/src/adapter.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { TRPCProcedureBuilder } from "@trpc/server";
|
|
2
|
-
import type { Context, Effect, Exit } from "effect";
|
|
3
|
-
import { makeContextBridge } from "#internal/context-bridge.ts";
|
|
4
|
-
import { looseBuilder } from "#internal/loose.ts";
|
|
5
|
-
import type { ResolverContext } from "#internal/procedure-types.ts";
|
|
6
|
-
import { makeRuntimeBridge } from "#internal/runtime.ts";
|
|
7
|
-
import { EffectProcedureBuilder } from "./procedure.ts";
|
|
8
|
-
import type { EffectProcedureRequestServices } from "./request-services.ts";
|
|
9
|
-
import type { EffectTRPCErrorMapper, EffectTRPCInstrument, EffectTRPCStreamInstrument } from "./types.ts";
|
|
10
|
-
|
|
11
|
-
export interface MakeEffectTRPCOptions<Requirements, RuntimeError> {
|
|
12
|
-
readonly instrument?: EffectTRPCInstrument;
|
|
13
|
-
readonly instrumentStream?: EffectTRPCStreamInstrument;
|
|
14
|
-
readonly mapError?: EffectTRPCErrorMapper;
|
|
15
|
-
readonly runtime: EffectTRPCRuntime<Requirements, RuntimeError>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface EffectTRPCRuntime<Requirements, RuntimeError> {
|
|
19
|
-
readonly contextEffect: Effect.Effect<Context.Context<Requirements>, RuntimeError>;
|
|
20
|
-
readonly currentServices?: () => Context.Context<never> | undefined;
|
|
21
|
-
readonly runPromise: <Value, Error>(
|
|
22
|
-
effect: Effect.Effect<Value, Error, Requirements>,
|
|
23
|
-
options?: { readonly signal?: AbortSignal },
|
|
24
|
-
) => Promise<Value>;
|
|
25
|
-
readonly runPromiseExit: <Value, Error>(
|
|
26
|
-
effect: Effect.Effect<Value, Error, Requirements>,
|
|
27
|
-
options?: { readonly signal?: AbortSignal },
|
|
28
|
-
) => Promise<Exit.Exit<Value, Error | RuntimeError>>;
|
|
29
|
-
readonly runWithServices?: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface EffectTRPCAdapter<Requirements> {
|
|
33
|
-
readonly procedure: <Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError>(
|
|
34
|
-
builder: TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>,
|
|
35
|
-
requestServices: EffectProcedureRequestServices<ResolverContext<Context, Meta, ContextOverrides>, ProvidedServices, LayerError>,
|
|
36
|
-
) => EffectProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError, Requirements>;
|
|
37
|
-
readonly runWithServices: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const makeEffectTRPC = <Requirements, RuntimeError = never>(
|
|
41
|
-
options: MakeEffectTRPCOptions<Requirements, RuntimeError>,
|
|
42
|
-
): EffectTRPCAdapter<Requirements> => {
|
|
43
|
-
const contextBridge = makeContextBridge(options.runtime);
|
|
44
|
-
const runtime = makeRuntimeBridge(options.runtime, contextBridge, options);
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
procedure: <Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError>(
|
|
48
|
-
builder: TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>,
|
|
49
|
-
requestServices: EffectProcedureRequestServices<ResolverContext<Context, Meta, ContextOverrides>, ProvidedServices, LayerError>,
|
|
50
|
-
) => {
|
|
51
|
-
const loose = looseBuilder(builder);
|
|
52
|
-
return new EffectProcedureBuilder<
|
|
53
|
-
Context,
|
|
54
|
-
Meta,
|
|
55
|
-
ContextOverrides,
|
|
56
|
-
InputIn,
|
|
57
|
-
InputOut,
|
|
58
|
-
OutputIn,
|
|
59
|
-
OutputOut,
|
|
60
|
-
ProvidedServices,
|
|
61
|
-
LayerError,
|
|
62
|
-
Requirements
|
|
63
|
-
>({
|
|
64
|
-
builder: loose,
|
|
65
|
-
requestServices,
|
|
66
|
-
runtime,
|
|
67
|
-
subscriptionBuilder: loose,
|
|
68
|
-
});
|
|
69
|
-
},
|
|
70
|
-
runWithServices: contextBridge.run,
|
|
71
|
-
};
|
|
72
|
-
};
|
package/src/errors.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { TRPCError } from "@trpc/server";
|
|
2
|
-
import { Effect } from "effect";
|
|
3
|
-
|
|
4
|
-
export const fail = (code: TRPCError["code"], message: string, cause?: unknown): Effect.Effect<never, TRPCError> =>
|
|
5
|
-
Effect.fail(new TRPCError({ cause, code, message }));
|
|
6
|
-
|
|
7
|
-
export const badRequest = (message: string, cause?: unknown) => fail("BAD_REQUEST", message, cause);
|
|
8
|
-
|
|
9
|
-
export const unauthorized = (message: string, cause?: unknown) => fail("UNAUTHORIZED", message, cause);
|
|
10
|
-
|
|
11
|
-
export const forbidden = (message: string, cause?: unknown) => fail("FORBIDDEN", message, cause);
|
|
12
|
-
|
|
13
|
-
export const notFound = (message: string, cause?: unknown) => fail("NOT_FOUND", message, cause);
|
|
14
|
-
|
|
15
|
-
export const conflict = (message: string, cause?: unknown) => fail("CONFLICT", message, cause);
|
|
16
|
-
|
|
17
|
-
export const preconditionFailed = (message: string, cause?: unknown) => fail("PRECONDITION_FAILED", message, cause);
|
|
18
|
-
|
|
19
|
-
export const internalServerError = (message: string, cause?: unknown) => fail("INTERNAL_SERVER_ERROR", message, cause);
|
package/src/internal/loose.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ProcedureBuilderOf, ProcedureBuilderSurface, ResolverContext } from "./procedure-types.ts";
|
|
2
|
-
|
|
3
|
-
export function looseBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>(
|
|
4
|
-
builder: ProcedureBuilderOf<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut>,
|
|
5
|
-
): ProcedureBuilderSurface<ResolverContext<Context, Meta, ContextOverrides>>;
|
|
6
|
-
export function looseBuilder(builder: unknown): unknown {
|
|
7
|
-
return builder;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// tRPC runs the procedure's input parsers before the resolver, so the resolver receives the input it declared.
|
|
11
|
-
export function acceptParsedInput<Result>(resolver: (input: never) => Result): (input: unknown) => Result;
|
|
12
|
-
export function acceptParsedInput(resolver: unknown): unknown {
|
|
13
|
-
return resolver;
|
|
14
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { inferProcedureBuilderResolverOptions, TRPCProcedureBuilder, TRPCUnsetMarker } from "@trpc/server";
|
|
2
|
-
import type { Effect, StandardSchema, Stream } from "effect";
|
|
3
|
-
|
|
4
|
-
export type ProcedureBuilderOf<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut> = TRPCProcedureBuilder<
|
|
5
|
-
Context,
|
|
6
|
-
Meta,
|
|
7
|
-
ContextOverrides,
|
|
8
|
-
InputIn,
|
|
9
|
-
InputOut,
|
|
10
|
-
OutputIn,
|
|
11
|
-
OutputOut,
|
|
12
|
-
false
|
|
13
|
-
>;
|
|
14
|
-
|
|
15
|
-
export type DefaultValue<Value, Fallback> = Value extends TRPCUnsetMarker ? Fallback : Value;
|
|
16
|
-
|
|
17
|
-
export type IntersectIfDefined<Value, With> = Value extends TRPCUnsetMarker ? With : With extends TRPCUnsetMarker ? Value : Value & With;
|
|
18
|
-
|
|
19
|
-
export type ResolverContext<Context, Meta, ContextOverrides> = inferProcedureBuilderResolverOptions<
|
|
20
|
-
ProcedureBuilderOf<Context, Meta, ContextOverrides, TRPCUnsetMarker, TRPCUnsetMarker, TRPCUnsetMarker, TRPCUnsetMarker>
|
|
21
|
-
>["ctx"];
|
|
22
|
-
|
|
23
|
-
export type ProcedureEffect<Requirements> = Effect.Effect<unknown, unknown, Requirements>;
|
|
24
|
-
|
|
25
|
-
export type EffectProcedureResolver<Input, Requirements, Output> = (input: Input) => Generator<ProcedureEffect<Requirements>, Output, never>;
|
|
26
|
-
|
|
27
|
-
export type EffectSubscriptionResolver<Input, Requirements, Output> = (
|
|
28
|
-
input: Input,
|
|
29
|
-
) => Generator<ProcedureEffect<Requirements>, Stream.Stream<Output, unknown, Requirements>, never>;
|
|
30
|
-
|
|
31
|
-
export interface ProcedureInvocation<Context> {
|
|
32
|
-
readonly ctx: Context;
|
|
33
|
-
readonly input: unknown;
|
|
34
|
-
readonly path: string;
|
|
35
|
-
readonly signal: AbortSignal | undefined;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface ProcedureBuilderSurface<Context> {
|
|
39
|
-
input: (schema: StandardSchema.StandardSchemaV1) => ProcedureBuilderSurface<Context>;
|
|
40
|
-
mutation: (resolver: (invocation: ProcedureInvocation<Context>) => Promise<unknown>) => unknown;
|
|
41
|
-
output: (schema: StandardSchema.StandardSchemaV1) => ProcedureBuilderSurface<Context>;
|
|
42
|
-
query: (resolver: (invocation: ProcedureInvocation<Context>) => Promise<unknown>) => unknown;
|
|
43
|
-
subscription: (resolver: (invocation: ProcedureInvocation<Context>) => Promise<AsyncIterable<unknown, void, unknown>>) => unknown;
|
|
44
|
-
}
|
package/src/internal/runtime.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { TRPCError } from "@trpc/server";
|
|
2
|
-
import { Cause, Context, Effect, Exit, Option, Result, Stream } from "effect";
|
|
3
|
-
import type { EffectTRPCRuntime } from "#adapter.ts";
|
|
4
|
-
import type { EffectTRPCErrorMapper, EffectTRPCInstrument, ProcedureInfo } from "#types.ts";
|
|
5
|
-
import type { ContextBridge } from "./context-bridge.ts";
|
|
6
|
-
|
|
7
|
-
interface RunEffectOptions {
|
|
8
|
-
readonly procedure: ProcedureInfo;
|
|
9
|
-
readonly signal?: AbortSignal;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RuntimeBridge<Requirements> {
|
|
13
|
-
readonly instrument: EffectTRPCInstrument;
|
|
14
|
-
readonly runEffect: <Value>(effect: Effect.Effect<Value, unknown, Requirements>, options: RunEffectOptions) => Promise<Value>;
|
|
15
|
-
readonly runStream: <Value>(stream: Stream.Stream<Value, unknown, Requirements>, options: RunEffectOptions) => Promise<AsyncIterable<Value>>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const internalError = (cause?: unknown): TRPCError =>
|
|
19
|
-
new TRPCError({
|
|
20
|
-
cause,
|
|
21
|
-
code: "INTERNAL_SERVER_ERROR",
|
|
22
|
-
message: "Internal server error",
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const mapError = (
|
|
26
|
-
error: unknown,
|
|
27
|
-
origin: "defect" | "failure",
|
|
28
|
-
procedure: ProcedureInfo,
|
|
29
|
-
consumerMapper: EffectTRPCErrorMapper | undefined,
|
|
30
|
-
): TRPCError => {
|
|
31
|
-
if (error instanceof TRPCError) {
|
|
32
|
-
return error;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
return consumerMapper?.(error, { ...procedure, origin }) ?? internalError(error);
|
|
37
|
-
} catch (mapperDefect) {
|
|
38
|
-
return internalError(mapperDefect);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const mapCause = (cause: Cause.Cause<unknown>, procedure: ProcedureInfo, consumerMapper: EffectTRPCErrorMapper | undefined): TRPCError => {
|
|
43
|
-
if (Cause.hasInterruptsOnly(cause)) {
|
|
44
|
-
return new TRPCError({
|
|
45
|
-
code: "CLIENT_CLOSED_REQUEST",
|
|
46
|
-
message: "Request cancelled",
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const failure = Cause.findErrorOption(cause);
|
|
51
|
-
if (Option.isSome(failure)) {
|
|
52
|
-
return mapError(failure.value, "failure", procedure, consumerMapper);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const defect = Cause.findDefect(cause);
|
|
56
|
-
if (Result.isSuccess(defect)) {
|
|
57
|
-
return mapError(defect.success, "defect", procedure, consumerMapper);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return internalError();
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const interruptOn = (signal: AbortSignal | undefined): Effect.Effect<void> => {
|
|
64
|
-
if (signal === undefined) {
|
|
65
|
-
return Effect.never;
|
|
66
|
-
}
|
|
67
|
-
return Effect.callback<void>((resume) => {
|
|
68
|
-
if (signal.aborted) {
|
|
69
|
-
resume(Effect.void);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
const abort = () => resume(Effect.void);
|
|
73
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
74
|
-
return Effect.sync(() => signal.removeEventListener("abort", abort));
|
|
75
|
-
});
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const makeRuntimeBridge = <Requirements, RuntimeError>(
|
|
79
|
-
runtime: EffectTRPCRuntime<Requirements, RuntimeError>,
|
|
80
|
-
contextBridge: ContextBridge,
|
|
81
|
-
options: {
|
|
82
|
-
readonly instrument?: EffectTRPCInstrument;
|
|
83
|
-
readonly instrumentStream?: import("#types.ts").EffectTRPCStreamInstrument;
|
|
84
|
-
readonly mapError?: EffectTRPCErrorMapper;
|
|
85
|
-
},
|
|
86
|
-
): RuntimeBridge<Requirements> => ({
|
|
87
|
-
instrument: (effect, procedure) => Effect.suspend(() => (options.instrument === undefined ? effect : options.instrument(effect, procedure))),
|
|
88
|
-
runEffect: async (effect, runOptions) => {
|
|
89
|
-
const traced = effect.pipe(
|
|
90
|
-
Effect.withSpan(
|
|
91
|
-
runOptions.procedure.path,
|
|
92
|
-
{
|
|
93
|
-
attributes: {
|
|
94
|
-
"rpc.method": runOptions.procedure.path,
|
|
95
|
-
"rpc.system": "trpc",
|
|
96
|
-
"trpc.type": runOptions.procedure.type,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
captureStackTrace: runOptions.procedure.captureStackTrace,
|
|
101
|
-
},
|
|
102
|
-
),
|
|
103
|
-
);
|
|
104
|
-
const ambient = contextBridge.current();
|
|
105
|
-
const runnable =
|
|
106
|
-
ambient === undefined ? traced : Effect.flatMap(runtime.contextEffect, (base) => Effect.provideContext(traced, Context.merge(base, ambient)));
|
|
107
|
-
const exit = await runtime.runPromiseExit(runnable, runOptions.signal === undefined ? undefined : { signal: runOptions.signal });
|
|
108
|
-
|
|
109
|
-
if (Exit.isSuccess(exit)) {
|
|
110
|
-
return exit.value;
|
|
111
|
-
}
|
|
112
|
-
throw mapCause(exit.cause, runOptions.procedure, options.mapError);
|
|
113
|
-
},
|
|
114
|
-
runStream: async (stream, runOptions) => {
|
|
115
|
-
const instrumented = Stream.suspend(() =>
|
|
116
|
-
options.instrumentStream === undefined ? stream : options.instrumentStream(stream, runOptions.procedure),
|
|
117
|
-
).pipe(
|
|
118
|
-
Stream.withSpan(runOptions.procedure.path, {
|
|
119
|
-
attributes: {
|
|
120
|
-
"rpc.method": runOptions.procedure.path,
|
|
121
|
-
"rpc.system": "trpc",
|
|
122
|
-
"trpc.type": runOptions.procedure.type,
|
|
123
|
-
},
|
|
124
|
-
captureStackTrace: runOptions.procedure.captureStackTrace,
|
|
125
|
-
}),
|
|
126
|
-
Stream.interruptWhen(interruptOn(runOptions.signal)),
|
|
127
|
-
Stream.catchCause((cause) => Stream.fail(mapCause(cause, runOptions.procedure, options.mapError))),
|
|
128
|
-
);
|
|
129
|
-
const context = await runtime.runPromise(Effect.context<Requirements>());
|
|
130
|
-
const ambient = contextBridge.current();
|
|
131
|
-
const provided = ambient === undefined ? context : Context.merge(context, ambient);
|
|
132
|
-
return Stream.toAsyncIterableWith(instrumented, provided);
|
|
133
|
-
},
|
|
134
|
-
});
|
package/src/procedure.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import type { TRPCMutationProcedure, TRPCQueryProcedure, TRPCSubscriptionProcedure } from "@trpc/server";
|
|
2
|
-
import { Schema } from "effect";
|
|
3
|
-
import { makeProcedureHandler } from "#internal/procedure-handler.ts";
|
|
4
|
-
import type {
|
|
5
|
-
DefaultValue,
|
|
6
|
-
EffectProcedureResolver,
|
|
7
|
-
EffectSubscriptionResolver,
|
|
8
|
-
IntersectIfDefined,
|
|
9
|
-
ProcedureBuilderSurface,
|
|
10
|
-
ResolverContext,
|
|
11
|
-
} from "#internal/procedure-types.ts";
|
|
12
|
-
import type { RuntimeBridge } from "#internal/runtime.ts";
|
|
13
|
-
import { captureStackTrace } from "#internal/stack-trace.ts";
|
|
14
|
-
import { makeSubscriptionHandler } from "#internal/subscription-handler.ts";
|
|
15
|
-
import type { EffectProcedureRequestServices } from "./request-services.ts";
|
|
16
|
-
|
|
17
|
-
interface ProcedureParts<Context, Meta, ContextOverrides, ProvidedServices, LayerError, RuntimeRequirements> {
|
|
18
|
-
readonly builder: ProcedureBuilderSurface<ResolverContext<Context, Meta, ContextOverrides>>;
|
|
19
|
-
readonly requestServices: EffectProcedureRequestServices<ResolverContext<Context, Meta, ContextOverrides>, ProvidedServices, LayerError>;
|
|
20
|
-
readonly runtime: RuntimeBridge<RuntimeRequirements>;
|
|
21
|
-
readonly subscriptionBuilder: ProcedureBuilderSurface<ResolverContext<Context, Meta, ContextOverrides>>;
|
|
22
|
-
readonly subscriptionOutput?: Schema.ConstraintDecoder<unknown> | undefined;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class EffectProcedureBuilder<
|
|
26
|
-
Context,
|
|
27
|
-
Meta,
|
|
28
|
-
ContextOverrides,
|
|
29
|
-
InputIn,
|
|
30
|
-
InputOut,
|
|
31
|
-
OutputIn,
|
|
32
|
-
OutputOut,
|
|
33
|
-
ProvidedServices,
|
|
34
|
-
LayerError,
|
|
35
|
-
RuntimeRequirements,
|
|
36
|
-
> {
|
|
37
|
-
private readonly parts: ProcedureParts<Context, Meta, ContextOverrides, ProvidedServices, LayerError, RuntimeRequirements>;
|
|
38
|
-
|
|
39
|
-
constructor(parts: ProcedureParts<Context, Meta, ContextOverrides, ProvidedServices, LayerError, RuntimeRequirements>) {
|
|
40
|
-
this.parts = parts;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
input<SchemaValue extends Schema.ConstraintDecoder<unknown>>(
|
|
44
|
-
schema: SchemaValue,
|
|
45
|
-
): EffectProcedureBuilder<
|
|
46
|
-
Context,
|
|
47
|
-
Meta,
|
|
48
|
-
ContextOverrides,
|
|
49
|
-
IntersectIfDefined<InputIn, SchemaValue["Encoded"]>,
|
|
50
|
-
IntersectIfDefined<InputOut, SchemaValue["Type"]>,
|
|
51
|
-
OutputIn,
|
|
52
|
-
OutputOut,
|
|
53
|
-
ProvidedServices,
|
|
54
|
-
LayerError,
|
|
55
|
-
RuntimeRequirements
|
|
56
|
-
> {
|
|
57
|
-
const parser = Schema.toStandardSchemaV1(schema);
|
|
58
|
-
return new EffectProcedureBuilder({
|
|
59
|
-
...this.parts,
|
|
60
|
-
builder: this.parts.builder.input(parser),
|
|
61
|
-
subscriptionBuilder: this.parts.subscriptionBuilder.input(parser),
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
output<SchemaValue extends Schema.ConstraintDecoder<unknown>>(
|
|
66
|
-
schema: SchemaValue,
|
|
67
|
-
): EffectProcedureBuilder<
|
|
68
|
-
Context,
|
|
69
|
-
Meta,
|
|
70
|
-
ContextOverrides,
|
|
71
|
-
InputIn,
|
|
72
|
-
InputOut,
|
|
73
|
-
IntersectIfDefined<OutputIn, SchemaValue["Encoded"]>,
|
|
74
|
-
IntersectIfDefined<OutputOut, SchemaValue["Type"]>,
|
|
75
|
-
ProvidedServices,
|
|
76
|
-
LayerError,
|
|
77
|
-
RuntimeRequirements
|
|
78
|
-
> {
|
|
79
|
-
return new EffectProcedureBuilder({
|
|
80
|
-
...this.parts,
|
|
81
|
-
builder: this.parts.builder.output(Schema.toStandardSchemaV1(schema)),
|
|
82
|
-
subscriptionOutput: schema,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
query<Output>(
|
|
87
|
-
resolver: EffectProcedureResolver<
|
|
88
|
-
DefaultValue<InputOut, undefined>,
|
|
89
|
-
ProvidedServices | NoInfer<RuntimeRequirements>,
|
|
90
|
-
DefaultValue<OutputIn, Output>
|
|
91
|
-
>,
|
|
92
|
-
): TRPCQueryProcedure<{
|
|
93
|
-
input: DefaultValue<InputIn, void>;
|
|
94
|
-
output: DefaultValue<OutputOut, Output>;
|
|
95
|
-
meta: Meta;
|
|
96
|
-
}>;
|
|
97
|
-
query(resolver: EffectProcedureResolver<never, ProvidedServices | RuntimeRequirements, unknown>): unknown {
|
|
98
|
-
return this.parts.builder.query(this.handler("query", resolver));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
mutation<Output>(
|
|
102
|
-
resolver: EffectProcedureResolver<
|
|
103
|
-
DefaultValue<InputOut, undefined>,
|
|
104
|
-
ProvidedServices | NoInfer<RuntimeRequirements>,
|
|
105
|
-
DefaultValue<OutputIn, Output>
|
|
106
|
-
>,
|
|
107
|
-
): TRPCMutationProcedure<{
|
|
108
|
-
input: DefaultValue<InputIn, void>;
|
|
109
|
-
output: DefaultValue<OutputOut, Output>;
|
|
110
|
-
meta: Meta;
|
|
111
|
-
}>;
|
|
112
|
-
mutation(resolver: EffectProcedureResolver<never, ProvidedServices | RuntimeRequirements, unknown>): unknown {
|
|
113
|
-
return this.parts.builder.mutation(this.handler("mutation", resolver));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
subscription<Output>(
|
|
117
|
-
resolver: EffectSubscriptionResolver<
|
|
118
|
-
DefaultValue<InputOut, undefined>,
|
|
119
|
-
ProvidedServices | NoInfer<RuntimeRequirements>,
|
|
120
|
-
DefaultValue<OutputIn, Output>
|
|
121
|
-
>,
|
|
122
|
-
): TRPCSubscriptionProcedure<{
|
|
123
|
-
input: DefaultValue<InputIn, void>;
|
|
124
|
-
output: AsyncIterable<DefaultValue<OutputOut, Output>, void, unknown>;
|
|
125
|
-
meta: Meta;
|
|
126
|
-
}>;
|
|
127
|
-
subscription(resolver: EffectSubscriptionResolver<never, ProvidedServices | RuntimeRequirements, unknown>): unknown {
|
|
128
|
-
return this.parts.subscriptionBuilder.subscription(
|
|
129
|
-
makeSubscriptionHandler(
|
|
130
|
-
this.parts.runtime,
|
|
131
|
-
resolver,
|
|
132
|
-
this.parts.requestServices,
|
|
133
|
-
{ captureStackTrace: captureStackTrace(), type: "subscription" },
|
|
134
|
-
this.parts.subscriptionOutput,
|
|
135
|
-
),
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private handler(type: "mutation" | "query", resolver: EffectProcedureResolver<never, ProvidedServices | RuntimeRequirements, unknown>) {
|
|
140
|
-
return makeProcedureHandler(this.parts.runtime, resolver, this.parts.requestServices, { captureStackTrace: captureStackTrace(), type });
|
|
141
|
-
}
|
|
142
|
-
}
|
package/src/request-services.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type Layer as EffectLayer, Layer } from "effect";
|
|
2
|
-
|
|
3
|
-
export interface EffectProcedureRequestServices<Context, Requirements, Error = never> {
|
|
4
|
-
readonly layer: (context: Context) => EffectLayer.Layer<Requirements, Error>;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export const makeRequestServices = <Context, Requirements, Error = never>(
|
|
8
|
-
layer: (context: Context) => EffectLayer.Layer<Requirements, Error>,
|
|
9
|
-
): EffectProcedureRequestServices<Context, Requirements, Error> => ({ layer });
|
|
10
|
-
|
|
11
|
-
export const extendRequestServices = <
|
|
12
|
-
BaseContext,
|
|
13
|
-
Context extends BaseContext,
|
|
14
|
-
BaseRequirements,
|
|
15
|
-
BaseError,
|
|
16
|
-
AdditionalRequirements,
|
|
17
|
-
AdditionalError,
|
|
18
|
-
AdditionalDependencies extends BaseRequirements = BaseRequirements,
|
|
19
|
-
>(
|
|
20
|
-
base: EffectProcedureRequestServices<BaseContext, BaseRequirements, BaseError>,
|
|
21
|
-
additional: (context: Context) => EffectLayer.Layer<AdditionalRequirements, AdditionalError, AdditionalDependencies>,
|
|
22
|
-
): EffectProcedureRequestServices<Context, BaseRequirements | AdditionalRequirements, BaseError | AdditionalError> =>
|
|
23
|
-
makeRequestServices((context: Context) => Layer.provideMerge(additional(context), base.layer(context)));
|
package/src/testing/types.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { TestContext, Vitest } from "@effect/vitest";
|
|
2
|
-
import type { Effect, Layer } from "effect";
|
|
3
|
-
import type { EffectClock, EffectTestOptions } from "@shivaedev/effect-test/types.ts";
|
|
4
|
-
import type { EffectTRPCAdapter } from "#adapter.ts";
|
|
5
|
-
import type { AnyTestLayer } from "./any-test-layer.ts";
|
|
6
|
-
import type { EffectCallerFactory } from "./caller.ts";
|
|
7
|
-
|
|
8
|
-
export type TrpcHarnessTest<Harness, Provided> = <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(
|
|
9
|
-
name: string,
|
|
10
|
-
body: (harness: Harness, context: TestContext) => Generator<Eff, A, never>,
|
|
11
|
-
options?: number | EffectTestOptions,
|
|
12
|
-
) => void;
|
|
13
|
-
|
|
14
|
-
export interface TrpcHarnessTester<Harness, Provided> extends TrpcHarnessTest<Harness, Provided> {
|
|
15
|
-
readonly each: <Item>(
|
|
16
|
-
cases: readonly Item[],
|
|
17
|
-
) => <A, Eff extends Effect.Effect<unknown, unknown, Provided>>(
|
|
18
|
-
name: string,
|
|
19
|
-
body: (item: Item, harness: Harness, context: TestContext) => Generator<Eff, A, never>,
|
|
20
|
-
options?: number | EffectTestOptions,
|
|
21
|
-
) => void;
|
|
22
|
-
readonly fails: TrpcHarnessTest<Harness, Provided>;
|
|
23
|
-
readonly only: TrpcHarnessTest<Harness, Provided>;
|
|
24
|
-
readonly runIf: (condition: unknown) => TrpcHarnessTest<Harness, Provided>;
|
|
25
|
-
readonly skip: TrpcHarnessTest<Harness, Provided>;
|
|
26
|
-
readonly skipIf: (condition: unknown) => TrpcHarnessTest<Harness, Provided>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export type TrpcTest<Options, Caller, Provided> = TrpcHarnessTest<EffectCallerFactory<Options, Caller>, Provided>;
|
|
30
|
-
|
|
31
|
-
export type TrpcTester<Options, Caller, Provided> = TrpcHarnessTester<EffectCallerFactory<Options, Caller>, Provided>;
|
|
32
|
-
|
|
33
|
-
export type TrpcIt<Options, Caller, Provided> = Vitest.Methods & {
|
|
34
|
-
readonly effectTRPC: TrpcTester<Options, Caller, Provided>;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export type TrpcHarnessIt<Harness, Provided> = Vitest.Methods & {
|
|
38
|
-
readonly effectTRPC: TrpcHarnessTester<Harness, Provided>;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export interface MakeTrpcItOptions<CreateCaller extends (...arguments_: never[]) => object, TestLayer extends AnyTestLayer> {
|
|
42
|
-
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
43
|
-
readonly around?: <A, E>(effect: Effect.Effect<A, E, Layer.Success<TestLayer>>) => Effect.Effect<A, unknown, Layer.Success<TestLayer>>;
|
|
44
|
-
readonly clock?: EffectClock;
|
|
45
|
-
readonly createCaller: CreateCaller;
|
|
46
|
-
readonly layer: TestLayer;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface MakeTrpcHarnessItOptions<CreateCaller extends (...arguments_: never[]) => object, TestLayer extends AnyTestLayer, Harness>
|
|
50
|
-
extends MakeTrpcItOptions<CreateCaller, TestLayer> {
|
|
51
|
-
readonly makeHarness: (
|
|
52
|
-
trpc: EffectCallerFactory<CallerOptions<CreateCaller>, CallerResult<CreateCaller>>,
|
|
53
|
-
context: TestContext,
|
|
54
|
-
) => Effect.Effect<Harness, unknown, Layer.Success<TestLayer>>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type CallerOptions<CreateCaller> = CreateCaller extends (...arguments_: infer Arguments) => object ? Arguments[0] : never;
|
|
58
|
-
|
|
59
|
-
export type CallerResult<CreateCaller> = CreateCaller extends (...arguments_: infer _Arguments) => infer Caller
|
|
60
|
-
? Caller extends object
|
|
61
|
-
? Caller
|
|
62
|
-
: never
|
|
63
|
-
: never;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|