@rc312/tss-effect-serverfn 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +126 -2
- package/dist/bootstrap.server.d.ts +12 -0
- package/dist/bootstrap.server.d.ts.map +1 -0
- package/dist/bootstrap.server.js +17 -0
- package/dist/bootstrap.server.js.map +1 -0
- package/dist/boundary.server.d.ts +26 -0
- package/dist/boundary.server.d.ts.map +1 -0
- package/dist/boundary.server.js +117 -0
- package/dist/boundary.server.js.map +1 -0
- package/dist/compiler-runtime.d.ts +40 -0
- package/dist/compiler-runtime.d.ts.map +1 -0
- package/dist/compiler-runtime.js +54 -0
- package/dist/compiler-runtime.js.map +1 -0
- package/dist/create-effect-server-fn.d.ts +84 -0
- package/dist/create-effect-server-fn.d.ts.map +1 -0
- package/dist/create-effect-server-fn.js +27 -0
- package/dist/create-effect-server-fn.js.map +1 -0
- package/dist/effect-middleware.d.ts +116 -0
- package/dist/effect-middleware.d.ts.map +1 -0
- package/dist/effect-middleware.js +46 -0
- package/dist/effect-middleware.js.map +1 -0
- package/dist/execution.d.ts +35 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +7 -0
- package/dist/execution.js.map +1 -0
- package/dist/failure.server.d.ts +44 -0
- package/dist/failure.server.d.ts.map +1 -0
- package/dist/failure.server.js +161 -0
- package/dist/failure.server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/provenance.server.d.ts +54 -0
- package/dist/provenance.server.d.ts.map +1 -0
- package/dist/provenance.server.js +87 -0
- package/dist/provenance.server.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +3 -0
- package/dist/server.js.map +1 -0
- package/dist/vite.d.ts +24 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +296 -0
- package/dist/vite.js.map +1 -0
- package/docs/composition.md +188 -0
- package/docs/usage.md +223 -0
- package/package.json +67 -4
- package/src/bootstrap.server.ts +22 -0
- package/src/boundary.server.ts +198 -0
- package/src/compiler-runtime.ts +75 -0
- package/src/create-effect-server-fn.ts +197 -0
- package/src/effect-middleware.ts +171 -0
- package/src/execution.ts +39 -0
- package/src/failure.server.ts +257 -0
- package/src/index.ts +12 -0
- package/src/provenance.server.ts +125 -0
- package/src/server.ts +7 -0
- package/src/vite.ts +462 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { ServerFnMeta } from "@tanstack/react-start";
|
|
2
|
+
import type { ValidateSerializableInput } from "@tanstack/router-core";
|
|
3
|
+
import type { Cause, Duration, Effect, Exit, Schema } from "effect";
|
|
4
|
+
import type { HttpServerRequest } from "effect/http";
|
|
5
|
+
import type { ExecutionCapability } from "./execution.ts";
|
|
6
|
+
/**
|
|
7
|
+
* Server-local diagnostics passed to a configured failure reporter after request
|
|
8
|
+
* cleanup. Causes can contain private input and application details; only the
|
|
9
|
+
* projected rejection is eligible for transport to the client.
|
|
10
|
+
*/
|
|
11
|
+
export interface FailureReport {
|
|
12
|
+
/** Original operation Cause, including any request-scope finalizer failures. */
|
|
13
|
+
readonly cause: Cause.Cause<unknown>;
|
|
14
|
+
/** The phase active when the operation failed. */
|
|
15
|
+
readonly phase: "input" | "execution";
|
|
16
|
+
/** Proposed client rejection: the approved encoded error or trusted fallback. */
|
|
17
|
+
readonly failure: unknown;
|
|
18
|
+
/** An additional fault from inspecting or encoding the original failure. */
|
|
19
|
+
readonly processingCause?: Cause.Cause<unknown> | undefined;
|
|
20
|
+
/** TanStack's identity and source metadata for the current server function. */
|
|
21
|
+
readonly serverFnMeta: ServerFnMeta;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Application-owned execution and failure policy resolved for a handler call.
|
|
25
|
+
*
|
|
26
|
+
* The adapter owns the request Scope; the application owns the runtime and its
|
|
27
|
+
* disposal. Encoding and reporting run after request cleanup, with application
|
|
28
|
+
* services and HTTP request metadata still available.
|
|
29
|
+
*
|
|
30
|
+
* @template R - Services supplied by the application's runner.
|
|
31
|
+
* @template RuntimeError - Failures from acquiring the application's runtime.
|
|
32
|
+
* @template P - Public rejection record produced by the error encoder.
|
|
33
|
+
*/
|
|
34
|
+
export interface EffectConfiguration<R, RuntimeError, P extends object> {
|
|
35
|
+
/**
|
|
36
|
+
* Execute in the application environment and return the complete Exit.
|
|
37
|
+
* Use `Effect.runPromiseExit` for service-free work or a shared
|
|
38
|
+
* `ManagedRuntime`'s `runPromiseExit`. Custom runners must honor the supplied
|
|
39
|
+
* abort signal and await finalization before settling.
|
|
40
|
+
*/
|
|
41
|
+
readonly runPromiseExit: <A, E>(program: Effect.Effect<A, E, R>, options?: Effect.RunOptions) => Promise<Exit.Exit<A, E | RuntimeError>>;
|
|
42
|
+
/**
|
|
43
|
+
* Approve and encode a single typed business failure for the client.
|
|
44
|
+
* Undeclared properties are stripped. Unapproved failures, defects, mixed
|
|
45
|
+
* Causes, and encoding failures use `fallbackFailure` instead.
|
|
46
|
+
*/
|
|
47
|
+
readonly publicError?: Schema.ConstraintEncoder<ValidateSerializableInput<unknown, P>, NoInfer<R> | HttpServerRequest.HttpServerRequest>;
|
|
48
|
+
/**
|
|
49
|
+
* Replace native `ErrorReporter.report` with an awaited Effect.
|
|
50
|
+
* Control flow, ordinary invalid input, and pure interruption skip reporting.
|
|
51
|
+
* Faults or timeouts in this callback leave the business rejection intact and
|
|
52
|
+
* allow outer framework reporting. Compose native reporting here if desired.
|
|
53
|
+
*/
|
|
54
|
+
readonly reportFailure?: (report: FailureReport) => Effect.Effect<void, unknown, NoInfer<R> | HttpServerRequest.HttpServerRequest>;
|
|
55
|
+
/**
|
|
56
|
+
* Timeout for the `reportFailure` override only.
|
|
57
|
+
*
|
|
58
|
+
* @default "5 seconds"
|
|
59
|
+
*/
|
|
60
|
+
readonly reportTimeout?: Duration.Input;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Configure the eager safe fallback and lazy application execution policy.
|
|
64
|
+
*
|
|
65
|
+
* @template R - Services supplied by the resolved runner.
|
|
66
|
+
* @template RuntimeError - Failures from acquiring the application's runtime.
|
|
67
|
+
* @template P - Public rejection record produced by the error encoder.
|
|
68
|
+
* @template F - Trusted fallback record available before application loading.
|
|
69
|
+
*/
|
|
70
|
+
export interface EffectMiddlewareOptions<R, RuntimeError, P extends object, F extends object> {
|
|
71
|
+
/**
|
|
72
|
+
* Trusted, serializable rejection for failures that cannot be exposed.
|
|
73
|
+
* Keep it independent of lazy application loading and free of private details.
|
|
74
|
+
* A fresh copy receives server-local diagnostics for each rejection.
|
|
75
|
+
*/
|
|
76
|
+
readonly fallbackFailure: F & ValidateSerializableInput<unknown, F>;
|
|
77
|
+
/**
|
|
78
|
+
* Resolve configuration when the generated handler requests execution.
|
|
79
|
+
* Native middleware that rejects or replaces the handler does not invoke this
|
|
80
|
+
* callback. Reuse an application runtime rather than creating one per request.
|
|
81
|
+
*/
|
|
82
|
+
readonly resolve: () => EffectConfiguration<R, RuntimeError, P> | PromiseLike<EffectConfiguration<R, RuntimeError, P>>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create native Start middleware that supplies Effect execution to server functions.
|
|
86
|
+
*
|
|
87
|
+
* Install one owner before authorization and validation middleware. The Vite
|
|
88
|
+
* plugin's generated handler uses it to decode input and execute business work
|
|
89
|
+
* in one request Scope, with cancellation tied to the actual HTTP request.
|
|
90
|
+
* Cleanup completes before native post-handler middleware resumes.
|
|
91
|
+
*
|
|
92
|
+
* @param options - Trusted fallback and lazy application configuration.
|
|
93
|
+
* @returns Function middleware for a configured `createEffectServerFn` builder
|
|
94
|
+
* or Start's global function-middleware registration.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { createServerOnlyFn } from "@tanstack/react-start";
|
|
99
|
+
* import { Effect } from "effect";
|
|
100
|
+
* import {
|
|
101
|
+
* createEffectMiddleware,
|
|
102
|
+
* createEffectServerFn as base,
|
|
103
|
+
* } from "@rc312/tss-effect-serverfn";
|
|
104
|
+
*
|
|
105
|
+
* export const createEffectServerFn = base().middleware([
|
|
106
|
+
* createEffectMiddleware({
|
|
107
|
+
* fallbackFailure: { code: "INTERNAL", message: "Something went wrong" },
|
|
108
|
+
* resolve: createServerOnlyFn(() => ({
|
|
109
|
+
* runPromiseExit: Effect.runPromiseExit,
|
|
110
|
+
* })),
|
|
111
|
+
* }),
|
|
112
|
+
* ]);
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare const createEffectMiddleware: <R, RuntimeError, P extends object, F extends object>(options: EffectMiddlewareOptions<R, RuntimeError, P, F>) => import("@tanstack/react-start").FunctionMiddlewareAfterServer<{}, unknown, undefined, ExecutionCapability<R>, undefined, undefined, undefined>;
|
|
116
|
+
//# sourceMappingURL=effect-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-middleware.d.ts","sourceRoot":"","sources":["../src/effect-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC;IACtC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAC5D,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,SAAS,MAAM;IACpE;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,EAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,UAAU,KACxB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAE7C,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,EACrC,OAAO,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,iBAAiB,CACjD,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,MAAM,EAAE,aAAa,KAClB,MAAM,CAAC,MAAM,CAChB,IAAI,EACJ,OAAO,EACP,OAAO,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,iBAAiB,CACjD,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB,CACtC,CAAC,EACD,YAAY,EACZ,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,CAAC,GAAG,yBAAyB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MACd,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,GACvC,WAAW,CAAC,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;CAC1D;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,sBAAsB,GACjC,CAAC,EACD,YAAY,EACZ,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,WAEP,uBAAuB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC,mJAmBtD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createMiddleware, createServerOnlyFn } from "@tanstack/react-start";
|
|
2
|
+
import { bootstrapFailure } from "./bootstrap.server.js";
|
|
3
|
+
const loadBoundary = createServerOnlyFn(() => import("./boundary.server.js"));
|
|
4
|
+
const makeBootstrapFailure = createServerOnlyFn(bootstrapFailure);
|
|
5
|
+
/**
|
|
6
|
+
* Create native Start middleware that supplies Effect execution to server functions.
|
|
7
|
+
*
|
|
8
|
+
* Install one owner before authorization and validation middleware. The Vite
|
|
9
|
+
* plugin's generated handler uses it to decode input and execute business work
|
|
10
|
+
* in one request Scope, with cancellation tied to the actual HTTP request.
|
|
11
|
+
* Cleanup completes before native post-handler middleware resumes.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Trusted fallback and lazy application configuration.
|
|
14
|
+
* @returns Function middleware for a configured `createEffectServerFn` builder
|
|
15
|
+
* or Start's global function-middleware registration.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { createServerOnlyFn } from "@tanstack/react-start";
|
|
20
|
+
* import { Effect } from "effect";
|
|
21
|
+
* import {
|
|
22
|
+
* createEffectMiddleware,
|
|
23
|
+
* createEffectServerFn as base,
|
|
24
|
+
* } from "@rc312/tss-effect-serverfn";
|
|
25
|
+
*
|
|
26
|
+
* export const createEffectServerFn = base().middleware([
|
|
27
|
+
* createEffectMiddleware({
|
|
28
|
+
* fallbackFailure: { code: "INTERNAL", message: "Something went wrong" },
|
|
29
|
+
* resolve: createServerOnlyFn(() => ({
|
|
30
|
+
* runPromiseExit: Effect.runPromiseExit,
|
|
31
|
+
* })),
|
|
32
|
+
* }),
|
|
33
|
+
* ]);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const createEffectMiddleware = (options) => createMiddleware({ type: "function" }).server(async ({ next, context, method, serverFnMeta }) => {
|
|
37
|
+
let boundary;
|
|
38
|
+
try {
|
|
39
|
+
boundary = await loadBoundary();
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw makeBootstrapFailure(options.fallbackFailure, error);
|
|
43
|
+
}
|
|
44
|
+
return boundary.execute(options, { method, serverFnMeta }, context, (execution) => next({ context: execution }));
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=effect-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-middleware.js","sourceRoot":"","sources":["../src/effect-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAwGzD,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;AAE9E,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAMpC,OAAuD,EACvD,EAAE,CACF,gBAAgB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,CAC3C,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;IAChD,IAAI,QAAkD,CAAC;IAEvD,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,oBAAoB,CAAI,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,CACrB,OAAO,EACP,EAAE,MAAM,EAAE,YAAY,EAAE,EACxB,OAAO,EACP,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAC5C,CAAC;AACJ,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Effect, Scope } from "effect";
|
|
2
|
+
import type { HttpServerRequest } from "effect/http";
|
|
3
|
+
/**
|
|
4
|
+
* Native middleware-context key shared by the compiler bridge and runtime owner.
|
|
5
|
+
* This server-local capability must never be forwarded through `sendContext`.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare const executionKey = "@rc312/tss-effect-serverfn/execution";
|
|
9
|
+
/**
|
|
10
|
+
* Services supplied by the adapter in addition to the application's services.
|
|
11
|
+
* The Scope covers decoding and business work. The HTTP request provides
|
|
12
|
+
* metadata; Start has already consumed the RPC body.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export type RequestServices = Scope.Scope | HttpServerRequest.HttpServerRequest;
|
|
16
|
+
/**
|
|
17
|
+
* Request-local execution contract used by generated handlers.
|
|
18
|
+
*
|
|
19
|
+
* Phase notifications occur inside the running Effect immediately before each
|
|
20
|
+
* stage. Calls to `run` are rejected after the enclosing native middleware ends.
|
|
21
|
+
*
|
|
22
|
+
* @template R - Services supplied by the application runtime.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export interface ExecutionCapability<R> {
|
|
26
|
+
readonly [executionKey]: {
|
|
27
|
+
/** Run scoped work and await cleanup before resolving or rejecting the Promise. */
|
|
28
|
+
readonly run: <A, E>(program: Effect.Effect<A, E, R | RequestServices>) => Promise<A>;
|
|
29
|
+
/** Classify subsequent failures as input-decoding failures. */
|
|
30
|
+
readonly beginInput: () => void;
|
|
31
|
+
/** Classify subsequent failures as handler-execution failures. */
|
|
32
|
+
readonly beginExecution: () => void;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,YAAY,yCAAyC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,GAAG,iBAAiB,CAAC,iBAAiB,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;QACvB,mFAAmF;QACnF,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,KAC9C,OAAO,CAAC,CAAC,CAAC,CAAC;QAChB,+DAA+D;QAC/D,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;QAChC,kEAAkE;QAClE,QAAQ,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC;KACrC,CAAC;CACH"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native middleware-context key shared by the compiler bridge and runtime owner.
|
|
3
|
+
* This server-local capability must never be forwarded through `sendContext`.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export const executionKey = "@rc312/tss-effect-serverfn/execution";
|
|
7
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,sCAAsC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Cause, Effect } from "effect";
|
|
2
|
+
import type { HttpServerRequest } from "effect/http";
|
|
3
|
+
import type { EffectConfiguration } from "./effect-middleware.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Reject a configuration or runtime failure without invoking application policy.
|
|
6
|
+
* Runtime faults are never approved by the business-error schema, even when
|
|
7
|
+
* they resemble a public error or native redirect.
|
|
8
|
+
*
|
|
9
|
+
* @param fallback - Trusted rejection record to copy for an unexpected failure.
|
|
10
|
+
* @param cause - Original failure retained in the server-local registry.
|
|
11
|
+
* @throws {unknown} The squashed interruption, or a fresh fallback with native reporting ownership.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare const rejectRuntimeFailure: <F extends object, E>(fallback: F, cause: Cause.Cause<E>) => never;
|
|
15
|
+
/**
|
|
16
|
+
* Handle a rejection escaping the native middleware chain.
|
|
17
|
+
* Recognized control flow and already-owned rejections retain their identity.
|
|
18
|
+
* Other values, including objects whose inspection throws, receive the trusted
|
|
19
|
+
* fallback without loading the application runtime.
|
|
20
|
+
*
|
|
21
|
+
* @param fallback - Trusted rejection record for unrecognized failures.
|
|
22
|
+
* @param error - Value thrown by native middleware or the generated handler.
|
|
23
|
+
* @throws {unknown} The recognized rejection or a registered fallback record.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare const rejectMiddlewareFailure: <F extends object>(fallback: F, error: unknown) => never;
|
|
27
|
+
/**
|
|
28
|
+
* Project a completed operation's Cause into a client rejection and report it.
|
|
29
|
+
*
|
|
30
|
+
* Pure interruption and native control flow pass through without reporting.
|
|
31
|
+
* Ordinary decoder failures become `INVALID_INPUT` with HTTP 400. Only a single
|
|
32
|
+
* execution failure can be approved by the public-error encoder; other failures
|
|
33
|
+
* use the trusted fallback. Diagnostics stay attached by server-local identity.
|
|
34
|
+
*
|
|
35
|
+
* The caller must close the operation Scope before running this Effect and
|
|
36
|
+
* contain any defect in projection itself. Encoder/reporter services come from
|
|
37
|
+
* the application runtime and HTTP request, not the closed operation Scope.
|
|
38
|
+
*
|
|
39
|
+
* @returns An Effect yielding the rejection value for the Promise boundary to
|
|
40
|
+
* throw. The original Cause is preserved separately from the client payload.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export declare const projectFailure: <R, RuntimeError, P extends object, F extends object>(cause: Cause.Cause<unknown>, phase: "execution" | "input", configuration: EffectConfiguration<R, RuntimeError, P>, fallback: F, serverFnMeta: import("@tanstack/react-start").ServerFnMeta) => Effect.Effect<unknown, never, R | HttpServerRequest.HttpServerRequest>;
|
|
44
|
+
//# sourceMappingURL=failure.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.server.d.ts","sourceRoot":"","sources":["../src/failure.server.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,EACL,MAAM,EAMP,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,wBAAwB,CAAC;AAiChC;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,YAC5C,CAAC,SACJ,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KACpB,KAMF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,MAAM,YAC5C,CAAC,SACJ,OAAO,KACb,KAcF,CAAC;AAiDF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,GACzB,CAAC,EACD,YAAY,EACZ,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,uQAwFhB,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/* oxlint-disable anti-slop/no-unknown-parameters -- This boundary classifies arbitrary thrown values; parsing them first would lose native control flow and error identity. */
|
|
2
|
+
import { setResponseStatus } from "@tanstack/react-start/server";
|
|
3
|
+
import { isNotFound, isRedirect } from "@tanstack/router-core";
|
|
4
|
+
import { Cause, Effect, ErrorReporter, Exit, Option, Predicate, Schema, } from "effect";
|
|
5
|
+
import { getServerFnFailureDisposition, ownFailure, } from "./provenance.server.js";
|
|
6
|
+
const isControlFlow = (value) => value instanceof Response || isRedirect(value) || isNotFound(value);
|
|
7
|
+
/**
|
|
8
|
+
* Extract a typed failure only when it is the Cause's sole reason.
|
|
9
|
+
* Mixed Causes, defects, and interruption cannot qualify as a public business
|
|
10
|
+
* error. `Some(undefined)` still represents a real typed failure.
|
|
11
|
+
*/
|
|
12
|
+
const getSingleFailure = (cause) => {
|
|
13
|
+
const reason = cause.reasons.length === 1 ? cause.reasons[0] : undefined;
|
|
14
|
+
return reason && Cause.isFailReason(reason)
|
|
15
|
+
? Option.some(reason.error)
|
|
16
|
+
: Option.none();
|
|
17
|
+
};
|
|
18
|
+
const isOwnedFailure = (value) => getServerFnFailureDisposition(value) !== undefined;
|
|
19
|
+
const suppressInterruption = (cause) => {
|
|
20
|
+
const rejection = Cause.squash(cause);
|
|
21
|
+
return Predicate.isObject(rejection)
|
|
22
|
+
? ownFailure(rejection, "suppress", cause)
|
|
23
|
+
: rejection;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Reject a configuration or runtime failure without invoking application policy.
|
|
27
|
+
* Runtime faults are never approved by the business-error schema, even when
|
|
28
|
+
* they resemble a public error or native redirect.
|
|
29
|
+
*
|
|
30
|
+
* @param fallback - Trusted rejection record to copy for an unexpected failure.
|
|
31
|
+
* @param cause - Original failure retained in the server-local registry.
|
|
32
|
+
* @throws {unknown} The squashed interruption, or a fresh fallback with native reporting ownership.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export const rejectRuntimeFailure = (fallback, cause) => {
|
|
36
|
+
if (Cause.hasInterruptsOnly(cause)) {
|
|
37
|
+
throw suppressInterruption(cause);
|
|
38
|
+
}
|
|
39
|
+
throw ownFailure({ ...fallback }, "native", cause);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Handle a rejection escaping the native middleware chain.
|
|
43
|
+
* Recognized control flow and already-owned rejections retain their identity.
|
|
44
|
+
* Other values, including objects whose inspection throws, receive the trusted
|
|
45
|
+
* fallback without loading the application runtime.
|
|
46
|
+
*
|
|
47
|
+
* @param fallback - Trusted rejection record for unrecognized failures.
|
|
48
|
+
* @param error - Value thrown by native middleware or the generated handler.
|
|
49
|
+
* @throws {unknown} The recognized rejection or a registered fallback record.
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
export const rejectMiddlewareFailure = (fallback, error) => {
|
|
53
|
+
let passthrough = false;
|
|
54
|
+
try {
|
|
55
|
+
passthrough = isControlFlow(error) || isOwnedFailure(error);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Inspection faults remain private.
|
|
59
|
+
}
|
|
60
|
+
if (passthrough) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
return rejectRuntimeFailure(fallback, Cause.fail(error));
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Await the selected reporter and determine who owns further reporting.
|
|
67
|
+
* An explicit override replaces native reporting and its ignore policy. The
|
|
68
|
+
* override is interruptible and timeout-bounded even during masked rejection
|
|
69
|
+
* processing. Reporter failures leave ownership with the outer framework.
|
|
70
|
+
*
|
|
71
|
+
* @returns An Effect yielding `boundary` after handling, `suppress` for a native
|
|
72
|
+
* ignore annotation, or `native` when outer framework reporting is still needed.
|
|
73
|
+
*/
|
|
74
|
+
const reportFailure = Effect.fnUntraced(function* reportFailure(report, configuration, ignoredByNativeReporter) {
|
|
75
|
+
const { reportFailure: override, reportTimeout } = configuration;
|
|
76
|
+
if (override) {
|
|
77
|
+
const reportingExit = yield* Effect.exit(Effect.suspend(() => override(report)).pipe(Effect.interruptible, Effect.timeout(reportTimeout ?? "5 seconds")));
|
|
78
|
+
return Exit.isSuccess(reportingExit) ? "boundary" : "native";
|
|
79
|
+
}
|
|
80
|
+
const reporters = yield* ErrorReporter.CurrentErrorReporters;
|
|
81
|
+
const reportingExit = yield* Effect.exit(ErrorReporter.report(report.cause));
|
|
82
|
+
if (ignoredByNativeReporter) {
|
|
83
|
+
return "suppress";
|
|
84
|
+
}
|
|
85
|
+
return Exit.isSuccess(reportingExit) && reporters.size > 0
|
|
86
|
+
? "boundary"
|
|
87
|
+
: "native";
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Project a completed operation's Cause into a client rejection and report it.
|
|
91
|
+
*
|
|
92
|
+
* Pure interruption and native control flow pass through without reporting.
|
|
93
|
+
* Ordinary decoder failures become `INVALID_INPUT` with HTTP 400. Only a single
|
|
94
|
+
* execution failure can be approved by the public-error encoder; other failures
|
|
95
|
+
* use the trusted fallback. Diagnostics stay attached by server-local identity.
|
|
96
|
+
*
|
|
97
|
+
* The caller must close the operation Scope before running this Effect and
|
|
98
|
+
* contain any defect in projection itself. Encoder/reporter services come from
|
|
99
|
+
* the application runtime and HTTP request, not the closed operation Scope.
|
|
100
|
+
*
|
|
101
|
+
* @returns An Effect yielding the rejection value for the Promise boundary to
|
|
102
|
+
* throw. The original Cause is preserved separately from the client payload.
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
105
|
+
export const projectFailure = Effect.fnUntraced(function* projectFailure(cause, phase, configuration, fallback, serverFnMeta) {
|
|
106
|
+
if (Cause.hasInterruptsOnly(cause)) {
|
|
107
|
+
return suppressInterruption(cause);
|
|
108
|
+
}
|
|
109
|
+
let failure = { ...fallback };
|
|
110
|
+
let processingCause;
|
|
111
|
+
const inspectionExit = yield* Effect.exit(Effect.sync(() => {
|
|
112
|
+
const single = getSingleFailure(cause);
|
|
113
|
+
return Option.isSome(single)
|
|
114
|
+
? {
|
|
115
|
+
ignored: ErrorReporter.isIgnored(single.value),
|
|
116
|
+
invalidInput: phase === "input" && Schema.isSchemaError(single.value),
|
|
117
|
+
passthrough: isControlFlow(single.value) || isOwnedFailure(single.value),
|
|
118
|
+
value: single.value,
|
|
119
|
+
}
|
|
120
|
+
: undefined;
|
|
121
|
+
}));
|
|
122
|
+
if (Exit.isFailure(inspectionExit)) {
|
|
123
|
+
processingCause = inspectionExit.cause;
|
|
124
|
+
}
|
|
125
|
+
else if (inspectionExit.value) {
|
|
126
|
+
const single = inspectionExit.value;
|
|
127
|
+
if (single.passthrough) {
|
|
128
|
+
return single.value;
|
|
129
|
+
}
|
|
130
|
+
if (single.invalidInput) {
|
|
131
|
+
yield* Effect.sync(() => setResponseStatus(400));
|
|
132
|
+
return ownFailure({ code: "INVALID_INPUT", message: "Invalid input" }, "suppress", cause);
|
|
133
|
+
}
|
|
134
|
+
const { publicError } = configuration;
|
|
135
|
+
if (phase === "execution" && publicError) {
|
|
136
|
+
const encodingExit = yield* Effect.exit(Effect.suspend(() => Schema.encodeUnknownEffect(publicError, {
|
|
137
|
+
onExcessProperty: "ignore",
|
|
138
|
+
})(single.value)));
|
|
139
|
+
if (Exit.isSuccess(encodingExit)) {
|
|
140
|
+
failure = encodingExit.value;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
processingCause = encodingExit.cause;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const report = {
|
|
148
|
+
cause,
|
|
149
|
+
failure,
|
|
150
|
+
phase,
|
|
151
|
+
processingCause,
|
|
152
|
+
serverFnMeta,
|
|
153
|
+
};
|
|
154
|
+
const ignored = Exit.isSuccess(inspectionExit) && inspectionExit.value?.ignored === true;
|
|
155
|
+
const disposition = yield* reportFailure(report, configuration, ignored);
|
|
156
|
+
if (Predicate.isObject(failure)) {
|
|
157
|
+
return ownFailure({ ...failure }, disposition, cause);
|
|
158
|
+
}
|
|
159
|
+
return ownFailure({ ...fallback }, "native", cause);
|
|
160
|
+
});
|
|
161
|
+
//# sourceMappingURL=failure.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.server.js","sourceRoot":"","sources":["../src/failure.server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { type CreateEffectServerFn, createEffectServerFn, type EffectServerFnBuilder, } from "./create-effect-server-fn.ts";
|
|
2
|
+
export { type EffectConfiguration, type EffectMiddlewareOptions, createEffectMiddleware, type FailureReport, } from "./effect-middleware.ts";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,qBAAqB,GAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,sBAAsB,EACtB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,oBAAoB,GAErB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAGL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Cause } from "effect";
|
|
2
|
+
/**
|
|
3
|
+
* Reporting ownership for one rejection identity: suppress all capture, mark
|
|
4
|
+
* boundary handling, or leave reporting to the native framework.
|
|
5
|
+
*/
|
|
6
|
+
type Disposition = "suppress" | "boundary" | "native";
|
|
7
|
+
/**
|
|
8
|
+
* Register diagnostics and reporting ownership without mutating a rejection.
|
|
9
|
+
* Registration resets event acceptance for this identity. Boundary-created
|
|
10
|
+
* rejections use fresh records so separate requests are deduplicated separately.
|
|
11
|
+
*
|
|
12
|
+
* @param failure - Object used as the actual rejection identity.
|
|
13
|
+
* @param disposition - Whether reporting is suppressed, handled, or delegated.
|
|
14
|
+
* @param cause - Original diagnostic Cause; never added to the wire payload.
|
|
15
|
+
* @returns The same object, suitable for returning or throwing.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const ownFailure: <P extends object>(failure: P, disposition: Disposition, cause?: Cause.Cause<unknown>) => P;
|
|
19
|
+
/**
|
|
20
|
+
* Read the reporting policy for a rejection recognized by this server process.
|
|
21
|
+
*
|
|
22
|
+
* `capture` indicates whether an error event is allowed. `handled` indicates
|
|
23
|
+
* that the boundary handled or suppressed reporting, so outer middleware should
|
|
24
|
+
* not initiate another capture. This lookup does not consume event acceptance.
|
|
25
|
+
*
|
|
26
|
+
* @param error - The original rejection object, not a deserialized copy.
|
|
27
|
+
* @returns A policy snapshot, or `undefined` for an unrecognized value.
|
|
28
|
+
*/
|
|
29
|
+
export declare const getServerFnFailureDisposition: <E>(error: E) => {
|
|
30
|
+
capture: boolean;
|
|
31
|
+
handled: boolean;
|
|
32
|
+
} | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve the original diagnostic Cause associated with a rejection.
|
|
35
|
+
* Includes bootstrap and runtime failures as well as business/cleanup failures.
|
|
36
|
+
* The Cause can contain private data and must remain server-local.
|
|
37
|
+
*
|
|
38
|
+
* @param error - The original rejection identity observed on the server.
|
|
39
|
+
* @returns Its registered Cause, or `undefined` when none is available.
|
|
40
|
+
*/
|
|
41
|
+
export declare const getServerFnFailureCause: <E>(error: E) => Cause.Cause<unknown> | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Accept at most one error-delivery event for a registered rejection identity.
|
|
44
|
+
* Use in a reporter's `beforeSend`-style hook, including events initiated by the
|
|
45
|
+
* boundary itself. Unlike the disposition lookup, this call consumes acceptance.
|
|
46
|
+
* Unrelated errors retain native reporting behavior.
|
|
47
|
+
*
|
|
48
|
+
* @param error - The original exception associated with the delivery event.
|
|
49
|
+
* @returns `false` for suppressed or already-accepted registered failures;
|
|
50
|
+
* `true` for the first allowed event or any unrecognized value.
|
|
51
|
+
*/
|
|
52
|
+
export declare const acceptServerFnErrorEvent: <E>(error: E) => boolean;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=provenance.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.server.d.ts","sourceRoot":"","sources":["../src/provenance.server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;GAGG;AACH,KAAK,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AA+BtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,WAChC,CAAC,eACG,WAAW,UAChB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAC3B,CAYF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAI,CAAC,SAAS,CAAC;;;aASxD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAChC,CAAC,KACP,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,SAA0C,CAAC;AAErE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,CAAC,YAcnD,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Predicate } from "effect";
|
|
2
|
+
const makeRegistry = () => ({
|
|
3
|
+
failures: new WeakMap(),
|
|
4
|
+
});
|
|
5
|
+
/**
|
|
6
|
+
* Identity-based diagnostics shared by adapters and reporting hooks.
|
|
7
|
+
* Weak keys avoid retaining completed failures; Vite's HMR data keeps in-flight
|
|
8
|
+
* rejections recognizable when this module is replaced.
|
|
9
|
+
*/
|
|
10
|
+
const registry = (() => {
|
|
11
|
+
if (import.meta.hot) {
|
|
12
|
+
import.meta.hot.data.effectServerFnProvenance ??= makeRegistry();
|
|
13
|
+
return import.meta.hot.data.effectServerFnProvenance;
|
|
14
|
+
}
|
|
15
|
+
return makeRegistry();
|
|
16
|
+
})();
|
|
17
|
+
// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Lookup accepts arbitrary rejection values and narrows before touching the identity registry.
|
|
18
|
+
const getFailureState = (error) => Predicate.isObject(error) ? registry.failures.get(error) : undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Register diagnostics and reporting ownership without mutating a rejection.
|
|
21
|
+
* Registration resets event acceptance for this identity. Boundary-created
|
|
22
|
+
* rejections use fresh records so separate requests are deduplicated separately.
|
|
23
|
+
*
|
|
24
|
+
* @param failure - Object used as the actual rejection identity.
|
|
25
|
+
* @param disposition - Whether reporting is suppressed, handled, or delegated.
|
|
26
|
+
* @param cause - Original diagnostic Cause; never added to the wire payload.
|
|
27
|
+
* @returns The same object, suitable for returning or throwing.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export const ownFailure = (failure, disposition, cause) => {
|
|
31
|
+
const state = {
|
|
32
|
+
accepted: false,
|
|
33
|
+
disposition,
|
|
34
|
+
};
|
|
35
|
+
registry.failures.set(failure, cause === undefined ? state : { ...state, cause });
|
|
36
|
+
return failure;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Read the reporting policy for a rejection recognized by this server process.
|
|
40
|
+
*
|
|
41
|
+
* `capture` indicates whether an error event is allowed. `handled` indicates
|
|
42
|
+
* that the boundary handled or suppressed reporting, so outer middleware should
|
|
43
|
+
* not initiate another capture. This lookup does not consume event acceptance.
|
|
44
|
+
*
|
|
45
|
+
* @param error - The original rejection object, not a deserialized copy.
|
|
46
|
+
* @returns A policy snapshot, or `undefined` for an unrecognized value.
|
|
47
|
+
*/
|
|
48
|
+
export const getServerFnFailureDisposition = (error) => {
|
|
49
|
+
const state = getFailureState(error);
|
|
50
|
+
return state
|
|
51
|
+
? {
|
|
52
|
+
capture: state.disposition !== "suppress",
|
|
53
|
+
handled: state.disposition !== "native",
|
|
54
|
+
}
|
|
55
|
+
: undefined;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Retrieve the original diagnostic Cause associated with a rejection.
|
|
59
|
+
* Includes bootstrap and runtime failures as well as business/cleanup failures.
|
|
60
|
+
* The Cause can contain private data and must remain server-local.
|
|
61
|
+
*
|
|
62
|
+
* @param error - The original rejection identity observed on the server.
|
|
63
|
+
* @returns Its registered Cause, or `undefined` when none is available.
|
|
64
|
+
*/
|
|
65
|
+
export const getServerFnFailureCause = (error) => getFailureState(error)?.cause;
|
|
66
|
+
/**
|
|
67
|
+
* Accept at most one error-delivery event for a registered rejection identity.
|
|
68
|
+
* Use in a reporter's `beforeSend`-style hook, including events initiated by the
|
|
69
|
+
* boundary itself. Unlike the disposition lookup, this call consumes acceptance.
|
|
70
|
+
* Unrelated errors retain native reporting behavior.
|
|
71
|
+
*
|
|
72
|
+
* @param error - The original exception associated with the delivery event.
|
|
73
|
+
* @returns `false` for suppressed or already-accepted registered failures;
|
|
74
|
+
* `true` for the first allowed event or any unrecognized value.
|
|
75
|
+
*/
|
|
76
|
+
export const acceptServerFnErrorEvent = (error) => {
|
|
77
|
+
const state = getFailureState(error);
|
|
78
|
+
if (!state) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (state.disposition === "suppress" || state.accepted) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
state.accepted = true;
|
|
85
|
+
return true;
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=provenance.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.server.js","sourceRoot":"","sources":["../src/provenance.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAenC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1B,QAAQ,EAAE,IAAI,OAAO,EAAwB;CAC9C,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,QAAQ,GAAoC,CAAC,GAAG,EAAE;IACtD,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,KAAK,YAAY,EAAE,CAAC;QAEjE,OAAO,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC;IACvD,CAAC;IAED,OAAO,YAAY,EAAE,CAAC;AACxB,CAAC,CAAC,EAAE,CAAC;AAEL,2JAA2J;AAC3J,MAAM,eAAe,GAAG,CAAC,KAAc,EAAE,EAAE,CACzC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAU,EACV,WAAwB,EACxB,KAA4B,EACzB,EAAE;IACL,MAAM,KAAK,GAAG;QACZ,QAAQ,EAAE,KAAK;QACf,WAAW;KACZ,CAAC;IAEF,QAAQ,CAAC,QAAQ,CAAC,GAAG,CACnB,OAAO,EACP,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAClD,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAI,KAAQ,EAAE,EAAE;IAC3D,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO,KAAK;QACV,CAAC,CAAC;YACE,OAAO,EAAE,KAAK,CAAC,WAAW,KAAK,UAAU;YACzC,OAAO,EAAE,KAAK,CAAC,WAAW,KAAK,QAAQ;SACxC;QACH,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,KAAQ,EAC0B,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAI,KAAQ,EAAE,EAAE;IACtD,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAErC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;IAEtB,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC"}
|