@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
|
@@ -3,27 +3,26 @@ import type { EffectProcedureRequestServices } from "#request-services.ts";
|
|
|
3
3
|
import { RequestSignal } from "#request-signal.ts";
|
|
4
4
|
import type { ProcedureInfo } from "#types.ts";
|
|
5
5
|
import { acceptParsedInput } from "./loose.ts";
|
|
6
|
-
import type { EffectSubscriptionResolver, ProcedureInvocation } from "./
|
|
6
|
+
import type { EffectSubscriptionResolver, ProcedureInvocation } from "./procedureTypes.ts";
|
|
7
7
|
import type { RuntimeBridge } from "./runtime.ts";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
requestServices: EffectProcedureRequestServices<Context, ProvidedServices, LayerError>,
|
|
8
|
+
export function makeSubscriptionHandler<TRuntimeRequirements, TContext, TProvidedServices, TLayerError>(
|
|
9
|
+
runtime: RuntimeBridge<TRuntimeRequirements>,
|
|
10
|
+
resolver: EffectSubscriptionResolver<never, TProvidedServices | NoInfer<TRuntimeRequirements>, unknown>,
|
|
11
|
+
requestServices: EffectProcedureRequestServices<TContext, TProvidedServices, TLayerError>,
|
|
13
12
|
procedure: Omit<ProcedureInfo, "path">,
|
|
14
13
|
outputSchema?: Schema.ConstraintDecoder<unknown>,
|
|
15
|
-
)
|
|
14
|
+
) {
|
|
16
15
|
const tracedResolver = Effect.fnUntraced(acceptParsedInput(resolver));
|
|
17
|
-
|
|
18
|
-
return async (invocation: ProcedureInvocation<Context>) => {
|
|
16
|
+
return async (invocation: ProcedureInvocation<TContext>) => {
|
|
19
17
|
const info = { ...procedure, path: invocation.path };
|
|
20
|
-
const
|
|
21
|
-
|
|
18
|
+
const stream = Stream.suspend(() => {
|
|
19
|
+
const requestLayer = Layer.merge(requestServices.layer(invocation.ctx), Layer.succeed(RequestSignal, invocation.signal));
|
|
20
|
+
return Stream.unwrap(Effect.suspend(() => runtime.instrument(tracedResolver(invocation.input), info))).pipe(Stream.provide(requestLayer));
|
|
21
|
+
});
|
|
22
22
|
const decoded = outputSchema === undefined ? stream : Stream.mapEffect(stream, (value) => Schema.decodeUnknownEffect(outputSchema)(value));
|
|
23
|
-
|
|
24
23
|
return await runtime.runStream(decoded, {
|
|
25
24
|
procedure: info,
|
|
26
25
|
...(invocation.signal === undefined ? {} : { signal: invocation.signal }),
|
|
27
26
|
});
|
|
28
27
|
};
|
|
29
|
-
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { inferProcedureBuilderResolverOptions, TRPCProcedureBuilder, TRPCUnsetMarker } from "@trpc/server";
|
|
2
|
+
import type { Effect, StandardSchema, Stream } from "effect";
|
|
3
|
+
export type ProcedureBuilderOf<TContext, TMeta, TContextOverrides, TInputIn, TInputOut, TOutputIn, TOutputOut> = TRPCProcedureBuilder<
|
|
4
|
+
TContext,
|
|
5
|
+
TMeta,
|
|
6
|
+
TContextOverrides,
|
|
7
|
+
TInputIn,
|
|
8
|
+
TInputOut,
|
|
9
|
+
TOutputIn,
|
|
10
|
+
TOutputOut,
|
|
11
|
+
false
|
|
12
|
+
>;
|
|
13
|
+
export type DefaultValue<TValue, TFallback> = TValue extends TRPCUnsetMarker ? TFallback : TValue;
|
|
14
|
+
export type IntersectIfDefined<TValue, TWith> = TValue extends TRPCUnsetMarker ? TWith : TWith extends TRPCUnsetMarker ? TValue : TValue & TWith;
|
|
15
|
+
export type ResolverContext<TContext, TMeta, TContextOverrides> = inferProcedureBuilderResolverOptions<
|
|
16
|
+
ProcedureBuilderOf<TContext, TMeta, TContextOverrides, TRPCUnsetMarker, TRPCUnsetMarker, TRPCUnsetMarker, TRPCUnsetMarker>
|
|
17
|
+
>["ctx"];
|
|
18
|
+
export type ProcedureEffect<TRequirements> = Effect.Effect<unknown, unknown, TRequirements>;
|
|
19
|
+
export type EffectProcedureResolver<TInput, TRequirements, TOutput> = (input: TInput) => Generator<ProcedureEffect<TRequirements>, TOutput, never>;
|
|
20
|
+
export type EffectSubscriptionResolver<TInput, TRequirements, TOutput> = (
|
|
21
|
+
input: TInput,
|
|
22
|
+
) => Generator<ProcedureEffect<TRequirements>, Stream.Stream<TOutput, unknown, TRequirements>, never>;
|
|
23
|
+
export interface ProcedureInvocation<TContext> {
|
|
24
|
+
readonly ctx: TContext;
|
|
25
|
+
readonly input: unknown;
|
|
26
|
+
readonly path: string;
|
|
27
|
+
readonly signal: AbortSignal | undefined;
|
|
28
|
+
}
|
|
29
|
+
export interface ProcedureBuilderSurface<TContext> {
|
|
30
|
+
input: (schema: StandardSchema.StandardSchemaV1) => ProcedureBuilderSurface<TContext>;
|
|
31
|
+
mutation: (resolver: (invocation: ProcedureInvocation<TContext>) => Promise<unknown>) => unknown;
|
|
32
|
+
output: (schema: StandardSchema.StandardSchemaV1) => ProcedureBuilderSurface<TContext>;
|
|
33
|
+
query: (resolver: (invocation: ProcedureInvocation<TContext>) => Promise<unknown>) => unknown;
|
|
34
|
+
subscription: (resolver: (invocation: ProcedureInvocation<TContext>) => Promise<AsyncIterable<unknown, void, unknown>>) => unknown;
|
|
35
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
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 "./contextBridge.ts";
|
|
6
|
+
|
|
7
|
+
interface RunEffectOptions {
|
|
8
|
+
readonly procedure: ProcedureInfo;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
export interface RuntimeBridge<TRequirements> {
|
|
12
|
+
readonly instrument: EffectTRPCInstrument;
|
|
13
|
+
readonly runEffect: <TValue>(effect: Effect.Effect<TValue, unknown, TRequirements>, options: RunEffectOptions) => Promise<TValue>;
|
|
14
|
+
readonly runStream: <TValue>(stream: Stream.Stream<TValue, unknown, TRequirements>, options: RunEffectOptions) => Promise<AsyncIterable<TValue>>;
|
|
15
|
+
}
|
|
16
|
+
function internalError(cause?: unknown): TRPCError {
|
|
17
|
+
return new TRPCError({
|
|
18
|
+
cause,
|
|
19
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
20
|
+
message: "Internal server error",
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function mapError(
|
|
24
|
+
error: unknown,
|
|
25
|
+
origin: "defect" | "failure",
|
|
26
|
+
procedure: ProcedureInfo,
|
|
27
|
+
consumerMapper: EffectTRPCErrorMapper | undefined,
|
|
28
|
+
): TRPCError {
|
|
29
|
+
if (error instanceof TRPCError) {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
return consumerMapper?.(error, { ...procedure, origin }) ?? internalError(error);
|
|
34
|
+
} catch (mapperDefect) {
|
|
35
|
+
return internalError(mapperDefect);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function mapCause(cause: Cause.Cause<unknown>, procedure: ProcedureInfo, consumerMapper: EffectTRPCErrorMapper | undefined): TRPCError {
|
|
39
|
+
if (Cause.hasInterruptsOnly(cause)) {
|
|
40
|
+
return new TRPCError({
|
|
41
|
+
code: "CLIENT_CLOSED_REQUEST",
|
|
42
|
+
message: "Request cancelled",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const failure = Cause.findErrorOption(cause);
|
|
46
|
+
if (Option.isSome(failure)) {
|
|
47
|
+
return mapError(failure.value, "failure", procedure, consumerMapper);
|
|
48
|
+
}
|
|
49
|
+
const defect = Cause.findDefect(cause);
|
|
50
|
+
if (Result.isSuccess(defect)) {
|
|
51
|
+
return mapError(defect.success, "defect", procedure, consumerMapper);
|
|
52
|
+
}
|
|
53
|
+
return internalError();
|
|
54
|
+
}
|
|
55
|
+
function interruptOn(signal: AbortSignal | undefined): Effect.Effect<void> {
|
|
56
|
+
if (signal === undefined) {
|
|
57
|
+
return Effect.never;
|
|
58
|
+
}
|
|
59
|
+
return Effect.callback<void>((resume) => {
|
|
60
|
+
if (signal.aborted) {
|
|
61
|
+
resume(Effect.void);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
function abort() {
|
|
65
|
+
return resume(Effect.void);
|
|
66
|
+
}
|
|
67
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
68
|
+
return Effect.sync(() => signal.removeEventListener("abort", abort));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function makeRuntimeBridge<TRequirements, TRuntimeError>(
|
|
72
|
+
runtime: EffectTRPCRuntime<TRequirements, TRuntimeError>,
|
|
73
|
+
contextBridge: ContextBridge,
|
|
74
|
+
options: {
|
|
75
|
+
readonly instrument?: EffectTRPCInstrument;
|
|
76
|
+
readonly instrumentStream?: import("#types.ts").EffectTRPCStreamInstrument;
|
|
77
|
+
readonly mapError?: EffectTRPCErrorMapper;
|
|
78
|
+
},
|
|
79
|
+
): RuntimeBridge<TRequirements> {
|
|
80
|
+
return {
|
|
81
|
+
instrument: (effect, procedure) => Effect.suspend(() => (options.instrument === undefined ? effect : options.instrument(effect, procedure))),
|
|
82
|
+
runEffect: async (effect, runOptions) => {
|
|
83
|
+
const traced = effect.pipe(
|
|
84
|
+
Effect.withSpan(
|
|
85
|
+
runOptions.procedure.path,
|
|
86
|
+
{
|
|
87
|
+
attributes: {
|
|
88
|
+
"rpc.method": runOptions.procedure.path,
|
|
89
|
+
"rpc.system": "trpc",
|
|
90
|
+
"trpc.type": runOptions.procedure.type,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
captureStackTrace: runOptions.procedure.captureStackTrace,
|
|
95
|
+
},
|
|
96
|
+
),
|
|
97
|
+
);
|
|
98
|
+
const ambient = contextBridge.current();
|
|
99
|
+
const runnable =
|
|
100
|
+
ambient === undefined ? traced : Effect.flatMap(runtime.contextEffect, (base) => Effect.provideContext(traced, Context.merge(base, ambient)));
|
|
101
|
+
const exit = await runtime.runPromiseExit(runnable, runOptions.signal === undefined ? undefined : { signal: runOptions.signal });
|
|
102
|
+
if (Exit.isSuccess(exit)) {
|
|
103
|
+
return exit.value;
|
|
104
|
+
}
|
|
105
|
+
throw mapCause(exit.cause, runOptions.procedure, options.mapError);
|
|
106
|
+
},
|
|
107
|
+
runStream: async (stream, runOptions) => {
|
|
108
|
+
const instrumented = Stream.suspend(() =>
|
|
109
|
+
options.instrumentStream === undefined ? stream : options.instrumentStream(stream, runOptions.procedure),
|
|
110
|
+
).pipe(
|
|
111
|
+
Stream.withSpan(runOptions.procedure.path, {
|
|
112
|
+
attributes: {
|
|
113
|
+
"rpc.method": runOptions.procedure.path,
|
|
114
|
+
"rpc.system": "trpc",
|
|
115
|
+
"trpc.type": runOptions.procedure.type,
|
|
116
|
+
},
|
|
117
|
+
captureStackTrace: runOptions.procedure.captureStackTrace,
|
|
118
|
+
}),
|
|
119
|
+
Stream.interruptWhen(interruptOn(runOptions.signal)),
|
|
120
|
+
Stream.catchCause((cause) => Stream.fail(mapCause(cause, runOptions.procedure, options.mapError))),
|
|
121
|
+
);
|
|
122
|
+
const exit = await runtime.runPromiseExit(Effect.context<TRequirements>());
|
|
123
|
+
if (Exit.isFailure(exit)) {
|
|
124
|
+
throw mapCause(exit.cause, runOptions.procedure, options.mapError);
|
|
125
|
+
}
|
|
126
|
+
const ambient = contextBridge.current();
|
|
127
|
+
const provided = ambient === undefined ? exit.value : Context.merge(exit.value, ambient);
|
|
128
|
+
return Stream.toAsyncIterableWith(instrumented, provided);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -9,46 +9,49 @@ const TAXONOMY_CODES = new Map<string, TRPC_ERROR_CODE_KEY>([
|
|
|
9
9
|
["PreconditionFailed", "PRECONDITION_FAILED"],
|
|
10
10
|
["TooManyRequests", "TOO_MANY_REQUESTS"],
|
|
11
11
|
["AuthUnavailable", "SERVICE_UNAVAILABLE"],
|
|
12
|
+
["ServiceUnavailable", "SERVICE_UNAVAILABLE"],
|
|
13
|
+
["InternalServerError", "INTERNAL_SERVER_ERROR"],
|
|
12
14
|
]);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
export function rejectionCode(tag: string): TRPC_ERROR_CODE_KEY {
|
|
16
|
+
return TAXONOMY_CODES.get(tag) ?? "BAD_REQUEST";
|
|
17
|
+
}
|
|
16
18
|
const DeclaredRejection = Schema.StructWithRest(Schema.Struct({ _tag: Schema.String }), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
17
|
-
|
|
18
19
|
export type DeclaredRejection = typeof DeclaredRejection.Type;
|
|
19
|
-
|
|
20
20
|
interface InvalidInputIsReserved {
|
|
21
21
|
readonly "invalidInput is reserved for the mark on input that did not parse": never;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
23
|
interface DeclaredEncoding {
|
|
25
24
|
readonly _tag: string;
|
|
26
25
|
readonly invalidInput?: InvalidInputIsReserved;
|
|
27
26
|
}
|
|
28
|
-
|
|
29
27
|
export class RejectionError extends TRPCError {
|
|
30
28
|
readonly rejection: DeclaredRejection;
|
|
31
|
-
|
|
32
29
|
constructor(rejection: DeclaredRejection, code: TRPC_ERROR_CODE_KEY = rejectionCode(rejection._tag)) {
|
|
33
30
|
super({ code, message: typeof rejection.message === "string" ? rejection.message : rejection._tag });
|
|
34
31
|
this.rejection = rejection;
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
readonly code?: (tag: Tag) => TRPC_ERROR_CODE_KEY;
|
|
34
|
+
export interface RejectWithOptions<TTag extends string> {
|
|
35
|
+
readonly code?: (tag: TTag) => TRPC_ERROR_CODE_KEY;
|
|
40
36
|
}
|
|
41
|
-
|
|
42
|
-
const encodeRejection = (schema: Schema.Constraint) => {
|
|
37
|
+
function encodeRejection(schema: Schema.Constraint) {
|
|
43
38
|
const encode = Schema.encodeUnknownEffect(schema);
|
|
44
39
|
const tagged = Schema.decodeUnknownEffect(DeclaredRejection);
|
|
45
40
|
return (rejection: unknown) => Effect.orDie(Effect.flatMap(encode(rejection), tagged));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
}
|
|
42
|
+
export function rejectWith<
|
|
43
|
+
TSession extends Schema.ConstraintCodec<
|
|
44
|
+
{
|
|
45
|
+
readonly _tag: string;
|
|
46
|
+
},
|
|
47
|
+
DeclaredEncoding,
|
|
48
|
+
unknown,
|
|
49
|
+
unknown
|
|
50
|
+
>,
|
|
51
|
+
>(
|
|
52
|
+
schema: TSession,
|
|
53
|
+
options?: RejectWithOptions<TSession["Type"]["_tag"]>,
|
|
54
|
+
): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, Exclude<E, TSession["Type"]> | RejectionError, R | TSession["EncodingServices"]>;
|
|
52
55
|
export function rejectWith(schema: Schema.Constraint, options?: RejectWithOptions<string>) {
|
|
53
56
|
const is = Schema.is(schema);
|
|
54
57
|
const encode = encodeRejection(schema);
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { StandardSchemaV1Error, type TRPCDefaultErrorShape, type TRPCError } from "@trpc/server";
|
|
2
|
-
import type { EncodedRejection } from "#
|
|
2
|
+
import type { EncodedRejection } from "#rejectionDecoding.ts";
|
|
3
3
|
import { type DeclaredRejection, RejectionError } from "./rejection.ts";
|
|
4
|
-
|
|
5
4
|
export interface RejectionData {
|
|
6
5
|
readonly rejection?: EncodedRejection;
|
|
7
6
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
export type RejectionErrorShape = TRPCDefaultErrorShape & {
|
|
8
|
+
readonly data: RejectionData;
|
|
9
|
+
};
|
|
10
|
+
function inputRejection({ issues: [issue] }: StandardSchemaV1Error): EncodedRejection | undefined {
|
|
12
11
|
if (issue === undefined) {
|
|
13
12
|
return undefined;
|
|
14
13
|
}
|
|
@@ -16,11 +15,11 @@ const inputRejection = ({ issues: [issue] }: StandardSchemaV1Error): EncodedReje
|
|
|
16
15
|
return field === ""
|
|
17
16
|
? { _tag: "BadRequest", invalidInput: true, message: issue.message }
|
|
18
17
|
: { _tag: "BadRequest", field, invalidInput: true, message: issue.message };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
}
|
|
19
|
+
function declared({ invalidInput: _reserved, ...rejection }: DeclaredRejection): EncodedRejection {
|
|
20
|
+
return rejection;
|
|
21
|
+
}
|
|
22
|
+
function rejectionFrom(error: TRPCError): EncodedRejection | undefined {
|
|
24
23
|
if (error instanceof RejectionError) {
|
|
25
24
|
return declared(error.rejection);
|
|
26
25
|
}
|
|
@@ -28,12 +27,20 @@ const rejectionFrom = (error: TRPCError): EncodedRejection | undefined => {
|
|
|
28
27
|
return inputRejection(error.cause);
|
|
29
28
|
}
|
|
30
29
|
return undefined;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
}
|
|
31
|
+
export function withRejection<
|
|
32
|
+
TShape extends {
|
|
33
|
+
readonly data: object;
|
|
34
|
+
},
|
|
35
|
+
>(
|
|
36
|
+
shape: TShape,
|
|
37
|
+
error: TRPCError,
|
|
38
|
+
): TShape & {
|
|
39
|
+
readonly data: RejectionData;
|
|
40
|
+
} {
|
|
34
41
|
const rejection = rejectionFrom(error);
|
|
35
42
|
return rejection === undefined ? shape : { ...shape, data: { ...shape.data, rejection } };
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
}
|
|
44
|
+
export function rejectionFormatter({ shape, error }: { readonly shape: TRPCDefaultErrorShape; readonly error: TRPCError }): RejectionErrorShape {
|
|
45
|
+
return withRejection(shape, error);
|
|
46
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Layer as EffectLayer, Layer } from "effect";
|
|
2
|
+
export interface EffectProcedureRequestServices<TContext, TRequirements, TError = never> {
|
|
3
|
+
readonly layer: (context: TContext) => EffectLayer.Layer<TRequirements, TError>;
|
|
4
|
+
}
|
|
5
|
+
export function makeRequestServices<TContext, TRequirements, TError = never>(
|
|
6
|
+
layer: (context: TContext) => EffectLayer.Layer<TRequirements, TError>,
|
|
7
|
+
): EffectProcedureRequestServices<TContext, TRequirements, TError> {
|
|
8
|
+
return { layer };
|
|
9
|
+
}
|
|
10
|
+
export function extendRequestServices<
|
|
11
|
+
TBaseContext,
|
|
12
|
+
TContext extends TBaseContext,
|
|
13
|
+
TBaseRequirements,
|
|
14
|
+
TBaseError,
|
|
15
|
+
TAdditionalRequirements,
|
|
16
|
+
TAdditionalError,
|
|
17
|
+
TAdditionalDependencies extends TBaseRequirements = TBaseRequirements,
|
|
18
|
+
>(
|
|
19
|
+
base: EffectProcedureRequestServices<TBaseContext, TBaseRequirements, TBaseError>,
|
|
20
|
+
additional: (context: TContext) => EffectLayer.Layer<TAdditionalRequirements, TAdditionalError, TAdditionalDependencies>,
|
|
21
|
+
): EffectProcedureRequestServices<TContext, TBaseRequirements | TAdditionalRequirements, TBaseError | TAdditionalError> {
|
|
22
|
+
return makeRequestServices((context: TContext) => Layer.provideMerge(additional(context), base.layer(context)));
|
|
23
|
+
}
|
|
@@ -1,39 +1,34 @@
|
|
|
1
1
|
import { getTRPCErrorFromUnknown, type TRPCError } from "@trpc/server";
|
|
2
2
|
import { type Context, Effect } from "effect";
|
|
3
3
|
import type { EffectTRPCAdapter } from "#adapter.ts";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
: Caller[Key];
|
|
4
|
+
export type EffectCaller<TCaller> = {
|
|
5
|
+
readonly [TKey in keyof TCaller]: TCaller[TKey] extends (...arguments_: infer TArguments) => Promise<infer TResult>
|
|
6
|
+
? (...arguments_: TArguments) => Effect.Effect<TResult, TRPCError>
|
|
7
|
+
: TCaller[TKey] extends (...arguments_: infer TArguments) => infer TResult
|
|
8
|
+
? (...arguments_: TArguments) => TResult
|
|
9
|
+
: TCaller[TKey] extends Record<string, unknown>
|
|
10
|
+
? EffectCaller<TCaller[TKey]>
|
|
11
|
+
: TCaller[TKey];
|
|
13
12
|
};
|
|
14
|
-
|
|
15
|
-
export type EffectCallerFactory<Options, Caller> = EffectCaller<Caller> & ((options?: Options) => EffectCaller<Caller>);
|
|
16
|
-
|
|
13
|
+
export type EffectCallerFactory<TOptions, TCaller> = EffectCaller<TCaller> & ((options?: TOptions) => EffectCaller<TCaller>);
|
|
17
14
|
type Adapter = Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const invoke = (promiseCaller: object, path: readonly string[], argumentsList: readonly unknown[]): Promise<unknown> => {
|
|
15
|
+
function member(node: unknown, segment: string): unknown {
|
|
16
|
+
return (typeof node === "object" && node !== null) || typeof node === "function" ? Reflect.get(node, segment) : undefined;
|
|
17
|
+
}
|
|
18
|
+
function invoke(promiseCaller: object, path: readonly string[], argumentsList: readonly unknown[]): Promise<unknown> {
|
|
23
19
|
const leaf = path.reduce<unknown>(member, promiseCaller);
|
|
24
20
|
return typeof leaf === "function"
|
|
25
21
|
? Promise.resolve(Reflect.apply(leaf, undefined, argumentsList))
|
|
26
22
|
: Promise.reject(new TypeError(`${path.join(".")} is not a procedure`));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function makeEffectCaller<Caller extends object, Services>(
|
|
23
|
+
}
|
|
24
|
+
export function makeEffectCaller<TCaller extends object, TServices>(
|
|
30
25
|
adapter: Adapter,
|
|
31
|
-
promiseCaller:
|
|
32
|
-
services: Context.Context<
|
|
33
|
-
): EffectCaller<
|
|
26
|
+
promiseCaller: TCaller,
|
|
27
|
+
services: Context.Context<TServices>,
|
|
28
|
+
): EffectCaller<TCaller>;
|
|
34
29
|
export function makeEffectCaller(adapter: Adapter, promiseCaller: object, services: Context.Context<never>): unknown {
|
|
35
|
-
|
|
36
|
-
new Proxy(
|
|
30
|
+
function build(path: readonly string[]): unknown {
|
|
31
|
+
return new Proxy(
|
|
37
32
|
Object.assign(() => undefined, { path }),
|
|
38
33
|
{
|
|
39
34
|
apply(_target, _this, argumentsList) {
|
|
@@ -50,19 +45,19 @@ export function makeEffectCaller(adapter: Adapter, promiseCaller: object, servic
|
|
|
50
45
|
},
|
|
51
46
|
},
|
|
52
47
|
);
|
|
53
|
-
|
|
48
|
+
}
|
|
54
49
|
return build([]);
|
|
55
50
|
}
|
|
56
|
-
|
|
57
|
-
export function makeEffectCallerFactory<Options, Caller extends object, Services>(
|
|
51
|
+
export function makeEffectCallerFactory<TOptions, TCaller extends object, TServices>(
|
|
58
52
|
adapter: Adapter,
|
|
59
|
-
createCaller: (options?:
|
|
60
|
-
services: Context.Context<
|
|
61
|
-
): EffectCallerFactory<
|
|
53
|
+
createCaller: (options?: TOptions) => TCaller,
|
|
54
|
+
services: Context.Context<TServices>,
|
|
55
|
+
): EffectCallerFactory<TOptions, TCaller>;
|
|
62
56
|
export function makeEffectCallerFactory(adapter: Adapter, createCaller: (options?: unknown) => object, services: Context.Context<never>): unknown {
|
|
63
57
|
const defaultCaller = makeEffectCaller(adapter, createCaller(), services);
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
function target(options?: unknown) {
|
|
59
|
+
return makeEffectCaller(adapter, createCaller(options), services);
|
|
60
|
+
}
|
|
66
61
|
return new Proxy(target, {
|
|
67
62
|
get(_target, property, receiver) {
|
|
68
63
|
if (property === "then") {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { TestContext, Vitest } from "@effect/vitest";
|
|
2
|
+
import type { Effect, Layer, Scope } 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 "./AnyTestLayer.ts";
|
|
6
|
+
import type { EffectCallerFactory } from "./caller.ts";
|
|
7
|
+
export type TrpcHarnessTest<THarness, TProvided> = <A, TEff extends Effect.Effect<unknown, unknown, TProvided>>(
|
|
8
|
+
name: string,
|
|
9
|
+
body: (harness: THarness, context: TestContext) => Generator<TEff, A, never>,
|
|
10
|
+
options?: number | EffectTestOptions,
|
|
11
|
+
) => void;
|
|
12
|
+
export interface TrpcHarnessTester<THarness, TProvided> extends TrpcHarnessTest<THarness, TProvided> {
|
|
13
|
+
readonly each: <TItem>(
|
|
14
|
+
cases: readonly TItem[],
|
|
15
|
+
) => <A, TEff extends Effect.Effect<unknown, unknown, TProvided>>(
|
|
16
|
+
name: string,
|
|
17
|
+
body: (item: TItem, harness: THarness, context: TestContext) => Generator<TEff, A, never>,
|
|
18
|
+
options?: number | EffectTestOptions,
|
|
19
|
+
) => void;
|
|
20
|
+
readonly fails: TrpcHarnessTest<THarness, TProvided>;
|
|
21
|
+
readonly only: TrpcHarnessTest<THarness, TProvided>;
|
|
22
|
+
readonly runIf: (condition: unknown) => TrpcHarnessTest<THarness, TProvided>;
|
|
23
|
+
readonly skip: TrpcHarnessTest<THarness, TProvided>;
|
|
24
|
+
readonly skipIf: (condition: unknown) => TrpcHarnessTest<THarness, TProvided>;
|
|
25
|
+
}
|
|
26
|
+
export type TrpcTest<TOptions, TCaller, TProvided> = TrpcHarnessTest<EffectCallerFactory<TOptions, TCaller>, TProvided>;
|
|
27
|
+
export type TrpcTester<TOptions, TCaller, TProvided> = TrpcHarnessTester<EffectCallerFactory<TOptions, TCaller>, TProvided>;
|
|
28
|
+
export type TrpcIt<TOptions, TCaller, TProvided> = Vitest.Methods & {
|
|
29
|
+
readonly "effectTRPC": TrpcTester<TOptions, TCaller, TProvided>;
|
|
30
|
+
};
|
|
31
|
+
export type TrpcHarnessIt<THarness, TProvided> = Vitest.Methods & {
|
|
32
|
+
readonly "effectTRPC": TrpcHarnessTester<THarness, TProvided>;
|
|
33
|
+
};
|
|
34
|
+
export interface MakeTrpcItOptions<TCreateCaller extends (...arguments_: never[]) => object, TTestLayer extends AnyTestLayer> {
|
|
35
|
+
readonly adapter: Pick<EffectTRPCAdapter<never>, "runWithServices">;
|
|
36
|
+
readonly around?: <A, E>(
|
|
37
|
+
effect: Effect.Effect<A, E, Layer.Success<TTestLayer> | Scope.Scope>,
|
|
38
|
+
) => Effect.Effect<A, unknown, Layer.Success<TTestLayer> | Scope.Scope>;
|
|
39
|
+
readonly clock?: EffectClock;
|
|
40
|
+
readonly createCaller: TCreateCaller;
|
|
41
|
+
readonly layer: TTestLayer;
|
|
42
|
+
}
|
|
43
|
+
export interface MakeTrpcHarnessItOptions<TCreateCaller extends (...arguments_: never[]) => object, TTestLayer extends AnyTestLayer, THarness>
|
|
44
|
+
extends MakeTrpcItOptions<TCreateCaller, TTestLayer> {
|
|
45
|
+
readonly makeHarness: (
|
|
46
|
+
trpc: EffectCallerFactory<CallerOptions<TCreateCaller>, CallerResult<TCreateCaller>>,
|
|
47
|
+
context: TestContext,
|
|
48
|
+
) => Effect.Effect<THarness, unknown, Layer.Success<TTestLayer>>;
|
|
49
|
+
}
|
|
50
|
+
export type CallerOptions<TCreateCaller> = TCreateCaller extends (...arguments_: infer TArguments) => object ? TArguments[0] : never;
|
|
51
|
+
export type CallerResult<TCreateCaller> = TCreateCaller extends (...arguments_: infer _TArguments) => infer TCaller
|
|
52
|
+
? TCaller extends object
|
|
53
|
+
? TCaller
|
|
54
|
+
: never
|
|
55
|
+
: never;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { it as effectIt, type Vitest } from "@effect/vitest";
|
|
2
2
|
import { Effect, type Layer } from "effect";
|
|
3
3
|
import { makeEffectIt } from "@shivaedev/effect-test/vitest.ts";
|
|
4
|
-
import type { AnyTestLayer } from "./
|
|
4
|
+
import type { AnyTestLayer } from "./AnyTestLayer.ts";
|
|
5
5
|
import { makeEffectCallerFactory } from "./caller.ts";
|
|
6
6
|
import type { CallerOptions, CallerResult, MakeTrpcHarnessItOptions, MakeTrpcItOptions, TrpcHarnessIt, TrpcIt } from "./types.ts";
|
|
7
7
|
|
|
8
|
-
function
|
|
9
|
-
|
|
8
|
+
function withEffectTrpc<TTester>(tester: TTester): Vitest.Methods & {
|
|
9
|
+
readonly "effectTRPC": TTester;
|
|
10
|
+
};
|
|
11
|
+
function withEffectTrpc(tester: unknown): unknown {
|
|
10
12
|
return new Proxy(effectIt, {
|
|
11
13
|
get(target, property, receiver) {
|
|
12
14
|
if (property === "effectTRPC") {
|
|
@@ -16,12 +18,11 @@ function withEffectTRPC(tester: unknown): unknown {
|
|
|
16
18
|
},
|
|
17
19
|
});
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
options: MakeTrpcHarnessItOptions<(options?: unknown) => object, TestLayer, Harness>,
|
|
21
|
+
export function makeTrpcHarnessIt<TCreateCaller extends (...arguments_: never[]) => object, TTestLayer extends AnyTestLayer, THarness>(
|
|
22
|
+
options: MakeTrpcHarnessItOptions<TCreateCaller, TTestLayer, THarness>,
|
|
23
|
+
): TrpcHarnessIt<THarness, Layer.Success<TTestLayer>>;
|
|
24
|
+
export function makeTrpcHarnessIt<TTestLayer extends AnyTestLayer, THarness>(
|
|
25
|
+
options: MakeTrpcHarnessItOptions<(options?: unknown) => object, TTestLayer, THarness>,
|
|
25
26
|
): unknown {
|
|
26
27
|
const { effectApp } = makeEffectIt({
|
|
27
28
|
around: options.around,
|
|
@@ -29,19 +30,18 @@ export function makeTrpcHarnessIt<TestLayer extends AnyTestLayer, Harness>(
|
|
|
29
30
|
layer: options.layer,
|
|
30
31
|
makeHarness: (context) =>
|
|
31
32
|
Effect.gen(function* () {
|
|
32
|
-
const services = yield* Effect.context<Layer.Success<
|
|
33
|
+
const services = yield* Effect.context<Layer.Success<TTestLayer>>();
|
|
33
34
|
const trpc = makeEffectCallerFactory(options.adapter, options.createCaller, services);
|
|
34
35
|
return yield* options.makeHarness(trpc, context);
|
|
35
36
|
}),
|
|
36
37
|
});
|
|
37
|
-
|
|
38
|
-
return withEffectTRPC(effectApp);
|
|
38
|
+
return withEffectTrpc(effectApp);
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
makeTrpcHarnessIt({
|
|
40
|
+
export function makeTrpcIt<TCreateCaller extends (...arguments_: never[]) => object, TTestLayer extends AnyTestLayer>(
|
|
41
|
+
options: MakeTrpcItOptions<TCreateCaller, TTestLayer>,
|
|
42
|
+
): TrpcIt<CallerOptions<TCreateCaller>, CallerResult<TCreateCaller>, Layer.Success<TTestLayer>> {
|
|
43
|
+
return makeTrpcHarnessIt({
|
|
45
44
|
...options,
|
|
46
45
|
makeHarness: (trpc) => Effect.succeed(trpc),
|
|
47
46
|
});
|
|
47
|
+
}
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import type { TRPCError } from "@trpc/server";
|
|
2
2
|
import type { Effect, Stream } from "effect";
|
|
3
|
-
|
|
4
3
|
export type ProcedureKind = "mutation" | "query" | "subscription";
|
|
5
|
-
|
|
6
4
|
export interface ProcedureInfo {
|
|
7
5
|
readonly captureStackTrace: () => string | undefined;
|
|
8
6
|
readonly path: string;
|
|
9
7
|
readonly type: ProcedureKind;
|
|
10
8
|
}
|
|
11
|
-
|
|
12
9
|
export interface EffectTRPCErrorContext extends ProcedureInfo {
|
|
13
10
|
readonly origin: "defect" | "failure";
|
|
14
11
|
}
|
|
15
|
-
|
|
16
12
|
export type EffectTRPCErrorMapper = (error: unknown, context: EffectTRPCErrorContext) => TRPCError | undefined;
|
|
17
|
-
|
|
18
13
|
export type EffectTRPCInstrument = <A, E, R>(effect: Effect.Effect<A, E, R>, procedure: ProcedureInfo) => Effect.Effect<A, E, R>;
|
|
19
|
-
|
|
20
14
|
export type EffectTRPCStreamInstrument = <A, E, R>(stream: Stream.Stream<A, E, R>, procedure: ProcedureInfo) => Stream.Stream<A, E, R>;
|
package/dist/adapter.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { TRPCProcedureBuilder } from "@trpc/server";
|
|
2
|
-
import type { Context, Effect, Exit } from "effect";
|
|
3
|
-
import type { ResolverContext } from "#internal/procedure-types.ts";
|
|
4
|
-
import { EffectProcedureBuilder } from "./procedure.ts";
|
|
5
|
-
import type { EffectProcedureRequestServices } from "./request-services.ts";
|
|
6
|
-
import type { EffectTRPCErrorMapper, EffectTRPCInstrument, EffectTRPCStreamInstrument } from "./types.ts";
|
|
7
|
-
export interface MakeEffectTRPCOptions<Requirements, RuntimeError> {
|
|
8
|
-
readonly instrument?: EffectTRPCInstrument;
|
|
9
|
-
readonly instrumentStream?: EffectTRPCStreamInstrument;
|
|
10
|
-
readonly mapError?: EffectTRPCErrorMapper;
|
|
11
|
-
readonly runtime: EffectTRPCRuntime<Requirements, RuntimeError>;
|
|
12
|
-
}
|
|
13
|
-
export interface EffectTRPCRuntime<Requirements, RuntimeError> {
|
|
14
|
-
readonly contextEffect: Effect.Effect<Context.Context<Requirements>, RuntimeError>;
|
|
15
|
-
readonly currentServices?: () => Context.Context<never> | undefined;
|
|
16
|
-
readonly runPromise: <Value, Error>(effect: Effect.Effect<Value, Error, Requirements>, options?: {
|
|
17
|
-
readonly signal?: AbortSignal;
|
|
18
|
-
}) => Promise<Value>;
|
|
19
|
-
readonly runPromiseExit: <Value, Error>(effect: Effect.Effect<Value, Error, Requirements>, options?: {
|
|
20
|
-
readonly signal?: AbortSignal;
|
|
21
|
-
}) => Promise<Exit.Exit<Value, Error | RuntimeError>>;
|
|
22
|
-
readonly runWithServices?: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
|
|
23
|
-
}
|
|
24
|
-
export interface EffectTRPCAdapter<Requirements> {
|
|
25
|
-
readonly procedure: <Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError>(builder: TRPCProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, false>, requestServices: EffectProcedureRequestServices<ResolverContext<Context, Meta, ContextOverrides>, ProvidedServices, LayerError>) => EffectProcedureBuilder<Context, Meta, ContextOverrides, InputIn, InputOut, OutputIn, OutputOut, ProvidedServices, LayerError, Requirements>;
|
|
26
|
-
readonly runWithServices: <Services, Value>(services: Context.Context<Services>, evaluate: () => Value) => Value;
|
|
27
|
-
}
|
|
28
|
-
export declare const makeEffectTRPC: <Requirements, RuntimeError = never>(options: MakeEffectTRPCOptions<Requirements, RuntimeError>) => EffectTRPCAdapter<Requirements>;
|
|
29
|
-
//# sourceMappingURL=adapter.d.ts.map
|
package/dist/adapter.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAiCxD,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,CACV,OAA6G,EAC7G,eAA+H,EAC9H,EAAE;YACH,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACpC,OAAO,IAAI,sBAAsB,CAW/B;gBACD,OAAO,EAAE,KAAK;gBACd,eAAe;gBACf,OAAO;gBACP,mBAAmB,EAAE,KAAK;aAC1B,CAAC,CAAC;QACJ,CAAC;QACD,eAAe,EAAE,aAAa,CAAC,GAAG;KAClC,CAAC;AACH,CAAC,CAAC"}
|