better-effect 0.13.0 → 0.14.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/README.md +337 -88
- package/dist/adapters/iti.d.mts +2 -3
- package/dist/adapters/iti.d.mts.map +1 -1
- package/dist/adapters/iti.mjs +2 -2
- package/dist/bun.d.mts +75 -23
- package/dist/bun.d.mts.map +1 -1
- package/dist/bun.mjs +170 -33
- package/dist/bun.mjs.map +1 -1
- package/dist/{context-BphfFUMO.mjs → context-DSGSqcJj.mjs} +12 -3
- package/dist/context-DSGSqcJj.mjs.map +1 -0
- package/dist/{current-request-DDKNyymv.mjs → current-request-Bc1YHL0w.mjs} +3 -2
- package/dist/{current-request-DDKNyymv.mjs.map → current-request-Bc1YHL0w.mjs.map} +1 -1
- package/dist/{current-request-CIU7AHhF.d.mts → current-request-Dm-QQ3Xr.d.mts} +4 -4
- package/dist/current-request-Dm-QQ3Xr.d.mts.map +1 -0
- package/dist/{effect-CPdV7Yv8.mjs → effect-W0IQXY8P.mjs} +21 -2
- package/dist/effect-W0IQXY8P.mjs.map +1 -0
- package/dist/{errors-BKcsQ0ip.d.mts → errors-CpHMzPiP.d.mts} +6 -2
- package/dist/errors-CpHMzPiP.d.mts.map +1 -0
- package/dist/hono.d.mts +63 -27
- package/dist/hono.d.mts.map +1 -1
- package/dist/hono.mjs +111 -45
- package/dist/hono.mjs.map +1 -1
- package/dist/{index-CCi07kUw.d.mts → index-3Bkl-sxS.d.mts} +7 -2
- package/dist/{index-CCi07kUw.d.mts.map → index-3Bkl-sxS.d.mts.map} +1 -1
- package/dist/{index-cXgyMa0v.d.mts → index-C2ed9Ilq.d.mts} +32 -7
- package/dist/index-C2ed9Ilq.d.mts.map +1 -0
- package/dist/{index-BodMy6rO.d.mts → index-ClNndn2-.d.mts} +93 -63
- package/dist/index-ClNndn2-.d.mts.map +1 -0
- package/dist/{index-DAKn0qHk.d.mts → index-Cy1VsU-u.d.mts} +2 -4
- package/dist/index-Cy1VsU-u.d.mts.map +1 -0
- package/dist/index.d.mts +6 -8
- package/dist/index.mjs +8 -9
- package/dist/index.mjs.map +1 -1
- package/dist/{internal-identity-CbXoZIfw.mjs → internal-identity-BuHBtP0k.mjs} +2 -2
- package/dist/{internal-identity-CbXoZIfw.mjs.map → internal-identity-BuHBtP0k.mjs.map} +1 -1
- package/dist/layer-2kjHVv4N.mjs +343 -0
- package/dist/layer-2kjHVv4N.mjs.map +1 -0
- package/dist/layer-C2OaqTmB.d.mts +987 -0
- package/dist/layer-C2OaqTmB.d.mts.map +1 -0
- package/dist/next.d.mts +102 -26
- package/dist/next.d.mts.map +1 -1
- package/dist/next.mjs +157 -40
- package/dist/next.mjs.map +1 -1
- package/dist/{node-context-DczjAcrX.d.mts → node-context-1YEjrU9g.d.mts} +2 -2
- package/dist/{node-context-DczjAcrX.d.mts.map → node-context-1YEjrU9g.d.mts.map} +1 -1
- package/dist/{node-context-Ca18oNSg.mjs → node-context-g3bCcY9t.mjs} +2 -2
- package/dist/{node-context-Ca18oNSg.mjs.map → node-context-g3bCcY9t.mjs.map} +1 -1
- package/dist/node.d.mts +11 -6
- package/dist/node.d.mts.map +1 -1
- package/dist/node.mjs +156 -10
- package/dist/node.mjs.map +1 -1
- package/dist/opentelemetry.d.mts +20 -2
- package/dist/opentelemetry.d.mts.map +1 -1
- package/dist/opentelemetry.mjs +423 -5
- package/dist/opentelemetry.mjs.map +1 -1
- package/dist/{registration-drnZk0SY.mjs → registration-Bwe2GbVu.mjs} +8 -2
- package/dist/registration-Bwe2GbVu.mjs.map +1 -0
- package/dist/runtime/explicit.d.mts +2 -2
- package/dist/runtime/explicit.mjs +1 -1
- package/dist/runtime/node.d.mts +3 -3
- package/dist/runtime/node.mjs +2 -2
- package/dist/runtime-qpcVwaz_.mjs +1680 -0
- package/dist/runtime-qpcVwaz_.mjs.map +1 -0
- package/dist/service-CO9VJQYa.mjs +74 -0
- package/dist/service-CO9VJQYa.mjs.map +1 -0
- package/dist/{signal-nfgFyNCk.mjs → signal-5Rg9bUUe.mjs} +2 -2
- package/dist/{signal-nfgFyNCk.mjs.map → signal-5Rg9bUUe.mjs.map} +1 -1
- package/dist/{standard-services-vnGIafkS.mjs → standard-services-B-iMM_W7.mjs} +38 -4
- package/dist/standard-services-B-iMM_W7.mjs.map +1 -0
- package/dist/standard-services.d.mts +4 -4
- package/dist/standard-services.mjs +3 -3
- package/dist/testing.d.mts +25 -7
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.mjs +51 -7
- package/dist/testing.mjs.map +1 -1
- package/dist/{types-oihI-ESv.d.mts → types-BFTqCCcw.d.mts} +32 -5
- package/dist/types-BFTqCCcw.d.mts.map +1 -0
- package/dist/web-effect-B9hp9jIe.mjs +380 -0
- package/dist/web-effect-B9hp9jIe.mjs.map +1 -0
- package/dist/web.d.mts +22 -13
- package/dist/web.d.mts.map +1 -1
- package/dist/web.mjs +1 -1
- package/package.json +10 -16
- package/dist/context-BphfFUMO.mjs.map +0 -1
- package/dist/current-request-CIU7AHhF.d.mts.map +0 -1
- package/dist/disposable-CP-Q2H3l.mjs +0 -57
- package/dist/disposable-CP-Q2H3l.mjs.map +0 -1
- package/dist/effect-CPdV7Yv8.mjs.map +0 -1
- package/dist/errors-BKcsQ0ip.d.mts.map +0 -1
- package/dist/index-AiKM71-u.d.mts +0 -376
- package/dist/index-AiKM71-u.d.mts.map +0 -1
- package/dist/index-BodMy6rO.d.mts.map +0 -1
- package/dist/index-DAKn0qHk.d.mts.map +0 -1
- package/dist/index-cXgyMa0v.d.mts.map +0 -1
- package/dist/layer-D16GKxuX.mjs +0 -269
- package/dist/layer-D16GKxuX.mjs.map +0 -1
- package/dist/observer-9nhbL7Pr.d.mts +0 -68
- package/dist/observer-9nhbL7Pr.d.mts.map +0 -1
- package/dist/outcome-DI8LPIQ4.d.mts +0 -387
- package/dist/outcome-DI8LPIQ4.d.mts.map +0 -1
- package/dist/program-metadata-BxjGkT17.mjs +0 -260
- package/dist/program-metadata-BxjGkT17.mjs.map +0 -1
- package/dist/registration-drnZk0SY.mjs.map +0 -1
- package/dist/runtime-C_55ofnL.mjs +0 -791
- package/dist/runtime-C_55ofnL.mjs.map +0 -1
- package/dist/standard-services-vnGIafkS.mjs.map +0 -1
- package/dist/types-oihI-ESv.d.mts.map +0 -1
- package/dist/web-Bq3MfMrj.mjs +0 -147
- package/dist/web-Bq3MfMrj.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-context-
|
|
1
|
+
{"version":3,"file":"node-context-g3bCcY9t.mjs","names":[],"sources":["../src/runtime/node-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { RuntimeContextNotConfiguredError } from './errors'\n\nimport {\n currentRuntimeContextFrame,\n setRuntimeContextFrameCarrier,\n withActiveRuntimeContextStorage\n} from './context'\n\nimport type {\n ActiveRuntimeContextFrame,\n RuntimeContext,\n RuntimeContextFrameCarrier,\n RuntimeContextStorage\n} from './context'\n\nconst asyncLocalStorage = new AsyncLocalStorage<ActiveRuntimeContextFrame>()\n\nconst frameCarrier: RuntimeContextFrameCarrier = {\n run: (frame, program) => asyncLocalStorage.run(frame, program),\n current: () => asyncLocalStorage.getStore()\n}\n\nsetRuntimeContextFrameCarrier(frameCarrier)\n\n/** RuntimeContextStorage backed by Node/Bun async context propagation. */\nexport class NodeRuntimeContextStorage implements RuntimeContextStorage {\n run<A>(context: RuntimeContext, program: () => A): A {\n return withActiveRuntimeContextStorage(this, context, program)\n }\n\n current(): RuntimeContext {\n const frame = currentRuntimeContextFrame()\n\n if (!frame || frame.storage !== this) {\n throw new RuntimeContextNotConfiguredError()\n }\n\n return frame.context\n }\n}\n\n/** Shared Node/Bun storage used by the compatibility APIs and default Runtime. */\nexport const nodeRuntimeContextStorage = new NodeRuntimeContextStorage()\n\nexport { RuntimeContextNotConfiguredError } from './errors'\n\nexport type { RuntimeContext, RuntimeContextStorage } from './context'\n"],"mappings":";;;AAiBA,MAAM,oBAAoB,IAAI,kBAA6C;AAO3E,8BAA8B;CAJ5B,MAAM,OAAO,YAAY,kBAAkB,IAAI,OAAO,OAAO;CAC7D,eAAe,kBAAkB,SAAS;AAGH,CAAC;;AAG1C,IAAa,4BAAb,MAAwE;CACtE,IAAO,SAAyB,SAAqB;EACnD,OAAO,gCAAgC,MAAM,SAAS,OAAO;CAC/D;CAEA,UAA0B;EACxB,MAAM,QAAQ,2BAA2B;EAEzC,IAAI,CAAC,SAAS,MAAM,YAAY,MAC9B,MAAM,IAAI,iCAAiC;EAG7C,OAAO,MAAM;CACf;AACF;;AAGA,MAAa,4BAA4B,IAAI,0BAA0B"}
|
package/dist/node.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { t as RuntimeContextNotConfiguredError } from "./errors-
|
|
4
|
-
import "./
|
|
5
|
-
import { n as nodeRuntimeContextStorage, t as NodeRuntimeContextStorage } from "./node-context-DczjAcrX.mjs";
|
|
1
|
+
import { $ as CompleteInput, Ot as EffectError, V as LayerBackend, Z as CompleteExecution, c as RuntimeContext, g as RuntimeOptions, h as RuntimeDisposeOptions, jt as EffectSuccess, l as RuntimeContextStorage, ot as ProvidedEnvironment, tt as LayerInput } from "./layer-C2OaqTmB.mjs";
|
|
2
|
+
import "./index-3Bkl-sxS.mjs";
|
|
3
|
+
import { t as RuntimeContextNotConfiguredError } from "./errors-CpHMzPiP.mjs";
|
|
4
|
+
import { n as nodeRuntimeContextStorage, t as NodeRuntimeContextStorage } from "./node-context-1YEjrU9g.mjs";
|
|
6
5
|
import { Result } from "better-result";
|
|
7
6
|
//#region src/runtime/node-runtime.d.ts
|
|
8
7
|
/** Process signals supported by the Node.js/Bun process boundary. */
|
|
@@ -23,7 +22,11 @@ type NodeRuntimeOptions<Success = unknown, Failure = unknown> = RuntimeOptions &
|
|
|
23
22
|
readonly onFailure?: NodeRuntimeFailureHandler<Failure>;
|
|
24
23
|
/** Observe a defect. Defects are rethrown after the handler runs. */
|
|
25
24
|
readonly onDefect?: NodeRuntimeDefectHandler;
|
|
25
|
+
/** Runtime shutdown policy used after a signal or main-program settlement. */
|
|
26
|
+
readonly shutdown?: RuntimeDisposeOptions;
|
|
26
27
|
};
|
|
28
|
+
/** Options for the Layer-first `NodeRuntime.launch` entrypoint. */
|
|
29
|
+
type NodeRuntimeLaunchOptions = Omit<NodeRuntimeOptions<never, never>, 'onSuccess' | 'onFailure'>;
|
|
27
30
|
type NonResultMainSuccess<Value> = Value extends Result<any, any> ? never : Value;
|
|
28
31
|
type PlainMainSuccess<Value> = NonResultMainSuccess<Awaited<Value>>;
|
|
29
32
|
type MainSuccess<Value> = EffectSuccess<Value> | PlainMainSuccess<Value>;
|
|
@@ -38,6 +41,8 @@ declare class NodeRuntime {
|
|
|
38
41
|
static runMain<A, L extends LayerInput>(layer: L & CompleteInput<L>, backend: LayerBackend, program: CompleteExecution<ProvidedEnvironment<L>, A>, options?: MainOptions<A>): Promise<Awaited<A>>;
|
|
39
42
|
static runMain<A, L extends LayerInput>(layer: L & CompleteInput<L>, program: CompleteExecution<ProvidedEnvironment<L>, A>, options?: MainOptions<A>): Promise<Awaited<A>>;
|
|
40
43
|
static runMain<A, L extends LayerInput>(layer: L & CompleteInput<L>, options: MainOptions<A>, program: CompleteExecution<ProvidedEnvironment<L>, A>): Promise<Awaited<A>>;
|
|
44
|
+
/** Start a Layer-owned application until a process or caller signal shuts it down. */
|
|
45
|
+
static launch<L extends LayerInput>(layer: L & CompleteInput<L>, options?: NodeRuntimeLaunchOptions): Promise<void>;
|
|
41
46
|
}
|
|
42
47
|
/** Type-level aliases for the Node.js/Bun process boundary. */
|
|
43
48
|
declare namespace NodeRuntime {
|
|
@@ -47,5 +52,5 @@ declare namespace NodeRuntime {
|
|
|
47
52
|
type Signal = NodeRuntimeSignal;
|
|
48
53
|
}
|
|
49
54
|
//#endregion
|
|
50
|
-
export { NodeRuntime, NodeRuntimeContextStorage, type NodeRuntimeDefectHandler, type NodeRuntimeFailureHandler, type NodeRuntimeOptions, type NodeRuntimeSignal, type NodeRuntimeSuccessHandler, type RuntimeContext, RuntimeContextNotConfiguredError, type RuntimeContextStorage, nodeRuntimeContextStorage };
|
|
55
|
+
export { NodeRuntime, NodeRuntimeContextStorage, type NodeRuntimeDefectHandler, type NodeRuntimeFailureHandler, type NodeRuntimeLaunchOptions, type NodeRuntimeOptions, type NodeRuntimeSignal, type NodeRuntimeSuccessHandler, type RuntimeContext, RuntimeContextNotConfiguredError, type RuntimeContextStorage, nodeRuntimeContextStorage };
|
|
51
56
|
//# sourceMappingURL=node.d.mts.map
|
package/dist/node.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.mts","names":[],"sources":["../src/runtime/node-runtime.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.d.mts","names":[],"sources":["../src/runtime/node-runtime.ts"],"mappings":";;;;;;;KAoBY;;KAGA,0BAA0B,YAAY,OAAO;;KAG7C,0BAA0B,YAAY,OAAO;;KAG7C,4BAA4B;;KAG5B,mBAAmB,mBAAmB,qBAAqB;;WAE5D,mBAAmB;;WAEnB,YAAY,0BAA0B;;WAEtC,YAAY,0BAA0B;;WAEtC,WAAW;;WAEX,WAAW;;;KAIV,2BAA2B,KACrC;KAIG,qBAAqB,SAAS,cAAc,2BAA+B;KAE3E,iBAAiB,SAAS,qBAAqB,QAAQ;KAEvD,YAAY,SAAS,cAAc,SAAS,iBAAiB;KAE7D,YAAY,SAAS,YAAY;KAEjC,YAAY,SAAS,mBAAmB,YAAY,QAAQ,YAAY;;cA4PhE;;;;;SAKJ,QAAQ,GAAG,UAAU,YAC1B,OAAO,IAAI,cAAc,IACzB,SAAS,cACT,SAAS,kBAAkB,oBAAoB,IAAI,IACnD,UAAU,YAAY,KACrB,QAAQ,QAAQ;SAEZ,QAAQ,GAAG,UAAU,YAC1B,OAAO,IAAI,cAAc,IACzB,SAAS,kBAAkB,oBAAoB,IAAI,IACnD,UAAU,YAAY,KACrB,QAAQ,QAAQ;SAEZ,QAAQ,GAAG,UAAU,YAC1B,OAAO,IAAI,cAAc,IACzB,SAAS,YAAY,IACrB,SAAS,kBAAkB,oBAAoB,IAAI,KAClD,QAAQ,QAAQ;;SA6PN,OAAO,UAAU,YAC5B,OAAO,IAAI,cAAc,IACzB,UAAS,2BACR;;;kBAqHoB;;OAEX,QAAQ,mBAAmB,qBAAqB,mBAAmB,SAAS;;OAG5E,SAAS"}
|
package/dist/node.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { h as RuntimeContextNotConfiguredError } from "./context-
|
|
2
|
-
import { n as nodeRuntimeContextStorage, t as NodeRuntimeContextStorage } from "./node-context-
|
|
3
|
-
import { t as Runtime } from "./runtime-
|
|
4
|
-
import { n as linkAbortSignals } from "./signal-
|
|
1
|
+
import { h as RuntimeContextNotConfiguredError } from "./context-DSGSqcJj.mjs";
|
|
2
|
+
import { n as nodeRuntimeContextStorage, t as NodeRuntimeContextStorage } from "./node-context-g3bCcY9t.mjs";
|
|
3
|
+
import { t as Runtime } from "./runtime-qpcVwaz_.mjs";
|
|
4
|
+
import { n as linkAbortSignals } from "./signal-5Rg9bUUe.mjs";
|
|
5
5
|
import { Err, Ok } from "better-result";
|
|
6
6
|
//#region src/runtime/node-runtime.ts
|
|
7
7
|
const DEFAULT_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
@@ -21,6 +21,11 @@ const validateExitCode = (code) => {
|
|
|
21
21
|
return code;
|
|
22
22
|
};
|
|
23
23
|
const ensureFailureExitCode = (code) => code === 0 ? 1 : code;
|
|
24
|
+
const makeShutdownReason = (kind, cause) => {
|
|
25
|
+
const reason = { kind };
|
|
26
|
+
if (cause !== void 0) Object.assign(reason, { cause });
|
|
27
|
+
return reason;
|
|
28
|
+
};
|
|
24
29
|
const validateSignals = (signals) => {
|
|
25
30
|
if (signals !== void 0 && !Array.isArray(signals)) throw new TypeError("NodeRuntime signals must be an array of supported signal names");
|
|
26
31
|
for (const signal of signals ?? DEFAULT_SIGNALS) if (typeof signal !== "string" || signal !== "SIGINT" && signal !== "SIGTERM") throw new RangeError(`NodeRuntime signal "${String(signal)}" is not supported`);
|
|
@@ -28,6 +33,11 @@ const validateSignals = (signals) => {
|
|
|
28
33
|
const validateRuntimeOptions = (options) => {
|
|
29
34
|
if (options.signal !== void 0 && !isAbortSignal(options.signal)) throw new TypeError("NodeRuntime signal must be an AbortSignal");
|
|
30
35
|
};
|
|
36
|
+
const validateShutdownOptions = (shutdown) => {
|
|
37
|
+
if (shutdown === void 0) return;
|
|
38
|
+
if (shutdown.gracePeriod !== void 0 && (!Number.isFinite(shutdown.gracePeriod) || shutdown.gracePeriod < 0)) throw new RangeError("NodeRuntime shutdown gracePeriod must be a finite non-negative number");
|
|
39
|
+
if (shutdown.abortAfterGracePeriod !== void 0 && typeof shutdown.abortAfterGracePeriod !== "boolean") throw new TypeError("NodeRuntime shutdown abortAfterGracePeriod must be a boolean");
|
|
40
|
+
};
|
|
31
41
|
const validateCallbacks = (options) => {
|
|
32
42
|
if (options.onSuccess !== void 0 && typeof options.onSuccess !== "function") throw new TypeError("NodeRuntime onSuccess must be a function");
|
|
33
43
|
if (options.onFailure !== void 0 && typeof options.onFailure !== "function") throw new TypeError("NodeRuntime onFailure must be a function");
|
|
@@ -38,6 +48,7 @@ const validateOptions = (options) => {
|
|
|
38
48
|
validateSignals(options.signals);
|
|
39
49
|
validateRuntimeOptions(options);
|
|
40
50
|
validateCallbacks(options);
|
|
51
|
+
validateShutdownOptions(options.shutdown);
|
|
41
52
|
if (options.observers !== void 0 && !Array.isArray(options.observers)) throw new TypeError("NodeRuntime observers must be an array");
|
|
42
53
|
};
|
|
43
54
|
const normalizeSignals = (signals) => {
|
|
@@ -55,6 +66,15 @@ const removeSignalListeners = (listeners) => {
|
|
|
55
66
|
listeners.length = 0;
|
|
56
67
|
return failures;
|
|
57
68
|
};
|
|
69
|
+
const removeAbortListener = (listener) => {
|
|
70
|
+
if (listener === void 0) return [];
|
|
71
|
+
try {
|
|
72
|
+
listener.signal.removeEventListener("abort", listener.listener);
|
|
73
|
+
return [];
|
|
74
|
+
} catch (cause) {
|
|
75
|
+
return [cause];
|
|
76
|
+
}
|
|
77
|
+
};
|
|
58
78
|
const combineFailures = (failures) => {
|
|
59
79
|
if (failures.length === 0) return [];
|
|
60
80
|
if (failures.length === 1) return [failures[0]];
|
|
@@ -105,12 +125,13 @@ var NodeRuntime = class {
|
|
|
105
125
|
validateOptions(normalizedOptions);
|
|
106
126
|
const shutdownController = new AbortController();
|
|
107
127
|
const configuredSignals = normalizeSignals(normalizedOptions.signals);
|
|
108
|
-
const { onSuccess, onFailure, onDefect, signal: callerSignal, ...runtimeOptions } = normalizedOptions;
|
|
128
|
+
const { onSuccess, onFailure, onDefect, signal: callerSignal, shutdown: shutdownOptions, ...runtimeOptions } = normalizedOptions;
|
|
109
129
|
const signalLink = linkAbortSignals(callerSignal, shutdownController.signal);
|
|
110
130
|
const listeners = [];
|
|
111
131
|
const cleanupFailures = [];
|
|
112
132
|
let runtime;
|
|
113
133
|
let disposalPromise;
|
|
134
|
+
let pendingDisposalReason;
|
|
114
135
|
let disposalObserved = false;
|
|
115
136
|
let firstSignal;
|
|
116
137
|
let setupFailed = false;
|
|
@@ -121,10 +142,18 @@ var NodeRuntime = class {
|
|
|
121
142
|
let executionOutcome;
|
|
122
143
|
let programSettled = false;
|
|
123
144
|
let programValue;
|
|
124
|
-
|
|
145
|
+
let externalAbortListener;
|
|
146
|
+
const requestDispose = (reason) => {
|
|
125
147
|
if (disposalPromise) return disposalPromise;
|
|
148
|
+
if (runtime === void 0) {
|
|
149
|
+
pendingDisposalReason ??= reason;
|
|
150
|
+
return Promise.resolve();
|
|
151
|
+
}
|
|
126
152
|
try {
|
|
127
|
-
disposalPromise = runtime.dispose(
|
|
153
|
+
disposalPromise = runtime.dispose({
|
|
154
|
+
...shutdownOptions,
|
|
155
|
+
reason
|
|
156
|
+
});
|
|
128
157
|
} catch (cause) {
|
|
129
158
|
disposalPromise = Promise.reject(cause);
|
|
130
159
|
}
|
|
@@ -134,7 +163,7 @@ var NodeRuntime = class {
|
|
|
134
163
|
if (!runtime || disposalObserved) return;
|
|
135
164
|
disposalObserved = true;
|
|
136
165
|
try {
|
|
137
|
-
await requestDispose();
|
|
166
|
+
await requestDispose(makeShutdownReason("main-settled", programFailure));
|
|
138
167
|
} catch (cause) {
|
|
139
168
|
cleanupFailures.push(cause);
|
|
140
169
|
}
|
|
@@ -145,10 +174,31 @@ var NodeRuntime = class {
|
|
|
145
174
|
try {
|
|
146
175
|
shutdownController.abort(signal);
|
|
147
176
|
} finally {
|
|
148
|
-
requestDispose(
|
|
177
|
+
requestDispose({
|
|
178
|
+
kind: "signal",
|
|
179
|
+
signal
|
|
180
|
+
}).catch(() => {});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const onExternalAbort = () => {
|
|
184
|
+
const cause = callerSignal?.reason;
|
|
185
|
+
try {
|
|
186
|
+
shutdownController.abort(cause);
|
|
187
|
+
} finally {
|
|
188
|
+
requestDispose(makeShutdownReason("external-abort", cause)).catch(() => {});
|
|
149
189
|
}
|
|
150
190
|
};
|
|
151
191
|
try {
|
|
192
|
+
installSignalListeners(configuredSignals, listeners, onSignal);
|
|
193
|
+
if (callerSignal !== void 0) {
|
|
194
|
+
const listener = onExternalAbort;
|
|
195
|
+
externalAbortListener = {
|
|
196
|
+
signal: callerSignal,
|
|
197
|
+
listener
|
|
198
|
+
};
|
|
199
|
+
callerSignal.addEventListener("abort", listener, { once: true });
|
|
200
|
+
if (callerSignal.aborted) onExternalAbort();
|
|
201
|
+
}
|
|
152
202
|
const executionObserver = { onExecutionEnd: ({ outcome }) => {
|
|
153
203
|
executionOutcome = outcome;
|
|
154
204
|
} };
|
|
@@ -158,7 +208,7 @@ var NodeRuntime = class {
|
|
|
158
208
|
signal: signalLink.signal
|
|
159
209
|
};
|
|
160
210
|
runtime = backend ? await Runtime.make(layer, backend, runtimeOptionsWithSignal) : await Runtime.make(layer, runtimeOptionsWithSignal);
|
|
161
|
-
|
|
211
|
+
if (pendingDisposalReason !== void 0) requestDispose(pendingDisposalReason).catch(() => {});
|
|
162
212
|
try {
|
|
163
213
|
programValue = await runtime.run(program);
|
|
164
214
|
programSettled = true;
|
|
@@ -174,6 +224,7 @@ var NodeRuntime = class {
|
|
|
174
224
|
} finally {
|
|
175
225
|
await observeDisposal();
|
|
176
226
|
cleanupFailures.push(...removeSignalListeners(listeners));
|
|
227
|
+
cleanupFailures.push(...removeAbortListener(externalAbortListener));
|
|
177
228
|
try {
|
|
178
229
|
signalLink.dispose();
|
|
179
230
|
} catch (cause) {
|
|
@@ -226,6 +277,101 @@ var NodeRuntime = class {
|
|
|
226
277
|
if (hasCleanupFailure) throw cleanupFailure;
|
|
227
278
|
return programValue;
|
|
228
279
|
}
|
|
280
|
+
/** Start a Layer-owned application until a process or caller signal shuts it down. */
|
|
281
|
+
static async launch(layer, options = {}) {
|
|
282
|
+
if (!isOptionsObject(options)) throw new TypeError("NodeRuntime options must be a non-array object");
|
|
283
|
+
validateOptions(options);
|
|
284
|
+
const configuredSignals = normalizeSignals(options.signals);
|
|
285
|
+
const callerSignal = options.signal;
|
|
286
|
+
const shutdownOptions = options.shutdown;
|
|
287
|
+
const runtimeOptions = { ...options };
|
|
288
|
+
const listeners = [];
|
|
289
|
+
const cleanupFailures = [];
|
|
290
|
+
let runtime;
|
|
291
|
+
let disposalPromise;
|
|
292
|
+
let pendingShutdownReason;
|
|
293
|
+
let resolveShutdown;
|
|
294
|
+
let rejectShutdown;
|
|
295
|
+
const shutdown = new Promise((resolve, reject) => {
|
|
296
|
+
resolveShutdown = resolve;
|
|
297
|
+
rejectShutdown = reject;
|
|
298
|
+
});
|
|
299
|
+
let firstSignal;
|
|
300
|
+
let callerAbortListener;
|
|
301
|
+
const requestShutdown = (reason) => {
|
|
302
|
+
if (disposalPromise !== void 0) return;
|
|
303
|
+
if (runtime === void 0) {
|
|
304
|
+
pendingShutdownReason ??= reason;
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
disposalPromise = runtime.dispose({
|
|
309
|
+
...shutdownOptions,
|
|
310
|
+
reason
|
|
311
|
+
});
|
|
312
|
+
disposalPromise.then(resolveShutdown, rejectShutdown);
|
|
313
|
+
} catch (cause) {
|
|
314
|
+
disposalPromise = Promise.reject(cause);
|
|
315
|
+
disposalPromise.then(resolveShutdown, rejectShutdown);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
const onSignal = (signal) => {
|
|
319
|
+
if (firstSignal !== void 0) return;
|
|
320
|
+
firstSignal = signal;
|
|
321
|
+
requestShutdown({
|
|
322
|
+
kind: "signal",
|
|
323
|
+
signal
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
const onCallerAbort = () => {
|
|
327
|
+
const cause = callerSignal?.reason;
|
|
328
|
+
requestShutdown(makeShutdownReason("external-abort", cause));
|
|
329
|
+
};
|
|
330
|
+
let launchFailed = false;
|
|
331
|
+
let failure;
|
|
332
|
+
try {
|
|
333
|
+
installSignalListeners(configuredSignals, listeners, onSignal);
|
|
334
|
+
if (callerSignal !== void 0) {
|
|
335
|
+
callerAbortListener = {
|
|
336
|
+
signal: callerSignal,
|
|
337
|
+
listener: onCallerAbort
|
|
338
|
+
};
|
|
339
|
+
callerSignal.addEventListener("abort", onCallerAbort, { once: true });
|
|
340
|
+
if (callerSignal.aborted) onCallerAbort();
|
|
341
|
+
}
|
|
342
|
+
runtime = await Runtime.make(layer, runtimeOptions);
|
|
343
|
+
if (pendingShutdownReason !== void 0) requestShutdown(pendingShutdownReason);
|
|
344
|
+
process.stdin.resume();
|
|
345
|
+
await shutdown;
|
|
346
|
+
} catch (cause) {
|
|
347
|
+
launchFailed = true;
|
|
348
|
+
failure = cause;
|
|
349
|
+
if (runtime !== void 0 && disposalPromise === void 0) try {
|
|
350
|
+
await runtime.dispose({
|
|
351
|
+
...shutdownOptions,
|
|
352
|
+
reason: {
|
|
353
|
+
kind: "main-settled",
|
|
354
|
+
cause
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
} catch (cleanupCause) {
|
|
358
|
+
failure = cleanupCause;
|
|
359
|
+
}
|
|
360
|
+
} finally {
|
|
361
|
+
cleanupFailures.push(...removeSignalListeners(listeners));
|
|
362
|
+
cleanupFailures.push(...removeAbortListener(callerAbortListener));
|
|
363
|
+
process.stdin.pause();
|
|
364
|
+
}
|
|
365
|
+
if (launchFailed) {
|
|
366
|
+
reportDefect(failure, options.onDefect);
|
|
367
|
+
throw failure;
|
|
368
|
+
}
|
|
369
|
+
if (cleanupFailures.length > 0) {
|
|
370
|
+
const cleanupFailure = combineFailures(cleanupFailures)[0];
|
|
371
|
+
reportDefect(cleanupFailure, options.onDefect);
|
|
372
|
+
throw cleanupFailure;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
229
375
|
};
|
|
230
376
|
//#endregion
|
|
231
377
|
export { NodeRuntime, NodeRuntimeContextStorage, RuntimeContextNotConfiguredError, nodeRuntimeContextStorage };
|
package/dist/node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","names":[],"sources":["../src/runtime/node-runtime.ts"],"sourcesContent":["import { Err, Ok } from 'better-result'\n\nimport type { Result as ResultType } from 'better-result'\n\nimport type { EffectError, EffectSuccess } from '../effect'\nimport type { LayerBackend } from '../layer/backend'\nimport type {\n CompleteExecution,\n CompleteInput,\n LayerInput,\n ProvidedEnvironment\n} from '../layer/inference'\nimport { Runtime } from './runtime'\nimport { linkAbortSignals } from './signal'\n\nimport type { RuntimeOptions } from './outcome'\nimport type { RuntimeExecutionEndEvent, RuntimeObserver } from './observer'\nimport type { ScopeOutcome } from '../scope'\n\n/** Process signals supported by the Node.js/Bun process boundary. */\nexport type NodeRuntimeSignal = 'SIGINT' | 'SIGTERM'\n\n/** Translate a successful main result to a process exit code. */\nexport type NodeRuntimeSuccessHandler<Success> = (value: Success) => number\n\n/** Translate a typed main failure to a process exit code. */\nexport type NodeRuntimeFailureHandler<Failure> = (error: Failure) => number\n\n/** Observe a thrown or rejected main defect while it remains a rejected Promise. */\nexport type NodeRuntimeDefectHandler = (cause: unknown) => number | void\n\n/** Options for the Node.js/Bun process boundary. */\nexport type NodeRuntimeOptions<Success = unknown, Failure = unknown> = RuntimeOptions & {\n /** Process signals that request cooperative shutdown. Defaults to SIGINT and SIGTERM. */\n readonly signals?: readonly NodeRuntimeSignal[]\n /** Map a nominal Result.ok value, or a plain successful value, to an exit code. */\n readonly onSuccess?: NodeRuntimeSuccessHandler<Success>\n /** Map a nominal Result.err error to an exit code. */\n readonly onFailure?: NodeRuntimeFailureHandler<Failure>\n /** Observe a defect. Defects are rethrown after the handler runs. */\n readonly onDefect?: NodeRuntimeDefectHandler\n}\n\ntype NonResultMainSuccess<Value> = Value extends ResultType<any, any> ? never : Value\n\ntype PlainMainSuccess<Value> = NonResultMainSuccess<Awaited<Value>>\n\ntype MainSuccess<Value> = EffectSuccess<Value> | PlainMainSuccess<Value>\n\ntype MainFailure<Value> = EffectError<Value>\n\ntype MainOptions<Value> = NodeRuntimeOptions<MainSuccess<Value>, MainFailure<Value>>\n\nconst DEFAULT_SIGNALS = ['SIGINT', 'SIGTERM'] as const satisfies readonly NodeRuntimeSignal[]\n\ntype InstalledSignalListener = {\n readonly signal: NodeRuntimeSignal\n readonly listener: () => void\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- backend overload dispatch validates an opaque runtime value.\nconst isLayerBackend = (value: unknown): value is LayerBackend => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- runtime overload dispatch must inspect the backend shape.\n if (value === null || typeof value !== 'object') {\n return false\n }\n\n return (\n 'register' in value &&\n 'resolve' in value &&\n 'disposeAll' in value &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.register === 'function' &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.resolve === 'function' &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.disposeAll === 'function'\n )\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- AbortSignal validation receives an opaque public option.\nconst isAbortSignal = (value: unknown): value is AbortSignal => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n if (value === null || typeof value !== 'object') {\n return false\n }\n\n return (\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).aborted === 'boolean' &&\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).addEventListener === 'function' &&\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).removeEventListener === 'function'\n )\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- options are validated at the public boundary.\nconst isOptionsObject = (value: unknown): value is object => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the public options boundary before installing listeners.\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst validateExitCode = (code: number): number => {\n if (!Number.isSafeInteger(code) || code < 0) {\n throw new RangeError('NodeRuntime exit codes must be non-negative safe integers')\n }\n\n return code\n}\n\nconst ensureFailureExitCode = (code: number): number => (code === 0 ? 1 : code)\n\nconst validateSignals = <Success, Failure>(\n signals: NodeRuntimeOptions<Success, Failure>['signals']\n): void => {\n if (signals !== undefined && !Array.isArray(signals)) {\n throw new TypeError('NodeRuntime signals must be an array of supported signal names')\n }\n\n for (const signal of signals ?? DEFAULT_SIGNALS) {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before process.on receives them.\n if (typeof signal !== 'string' || (signal !== 'SIGINT' && signal !== 'SIGTERM')) {\n throw new RangeError(`NodeRuntime signal \"${String(signal)}\" is not supported`)\n }\n }\n}\n\nconst validateRuntimeOptions = <Success, Failure>(\n options: NodeRuntimeOptions<Success, Failure>\n): void => {\n if (options.signal !== undefined && !isAbortSignal(options.signal)) {\n throw new TypeError('NodeRuntime signal must be an AbortSignal')\n }\n}\n\nconst validateCallbacks = <Success, Failure>(\n options: NodeRuntimeOptions<Success, Failure>\n): void => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onSuccess !== undefined && typeof options.onSuccess !== 'function') {\n throw new TypeError('NodeRuntime onSuccess must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onFailure !== undefined && typeof options.onFailure !== 'function') {\n throw new TypeError('NodeRuntime onFailure must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onDefect !== undefined && typeof options.onDefect !== 'function') {\n throw new TypeError('NodeRuntime onDefect must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before Runtime invokes the observer.\n if (options.onCleanupFailure !== undefined && typeof options.onCleanupFailure !== 'function') {\n throw new TypeError('NodeRuntime onCleanupFailure must be a function')\n }\n}\n\nconst validateOptions = <Success, Failure>(options: NodeRuntimeOptions<Success, Failure>): void => {\n validateSignals(options.signals)\n validateRuntimeOptions(options)\n validateCallbacks(options)\n\n if (options.observers !== undefined && !Array.isArray(options.observers)) {\n throw new TypeError('NodeRuntime observers must be an array')\n }\n}\n\nconst normalizeSignals = (\n signals: readonly NodeRuntimeSignal[] | undefined\n): readonly NodeRuntimeSignal[] => {\n const unique = new Set<NodeRuntimeSignal>()\n\n for (const signal of signals ?? DEFAULT_SIGNALS) {\n unique.add(signal)\n }\n\n return [...unique]\n}\n\nconst removeSignalListeners = (listeners: InstalledSignalListener[]): readonly unknown[] => {\n const failures: unknown[] = []\n\n for (const { signal, listener } of listeners) {\n try {\n process.removeListener(signal, listener)\n } catch (cause) {\n failures.push(cause)\n }\n }\n\n listeners.length = 0\n\n return failures\n}\n\nconst combineFailures = (failures: readonly unknown[]): readonly unknown[] => {\n if (failures.length === 0) {\n return []\n }\n\n if (failures.length === 1) {\n return [failures[0]]\n }\n\n return [new AggregateError(failures, 'NodeRuntime cleanup failed')]\n}\n\nconst setExitCode = (code: number): void => {\n process.exitCode = validateExitCode(code)\n}\n\nconst reportDefect = (cause: unknown, handler: NodeRuntimeDefectHandler | undefined): void => {\n let exitCode = 1\n\n if (handler) {\n try {\n const requestedExitCode = handler(cause)\n\n if (requestedExitCode !== undefined) {\n exitCode = validateExitCode(requestedExitCode)\n }\n } catch {\n exitCode = 1\n }\n }\n\n setExitCode(ensureFailureExitCode(exitCode))\n}\n\nconst installSignalListeners = (\n signals: readonly NodeRuntimeSignal[],\n listeners: InstalledSignalListener[],\n onSignal: (signal: NodeRuntimeSignal) => void\n): void => {\n for (const signal of signals) {\n const listener = (): void => onSignal(signal)\n process.on(signal, listener)\n listeners.push({ signal, listener })\n }\n}\n\n/** Node.js/Bun process lifecycle helpers. */\nexport class NodeRuntime {\n /**\n * Run a typed main Program, translate its final result to `process.exitCode`,\n * and dispose the Runtime when the program or a configured process signal settles.\n */\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n backend: LayerBackend,\n program: CompleteExecution<ProvidedEnvironment<L>, A>,\n options?: MainOptions<A>\n ): Promise<Awaited<A>>\n\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n program: CompleteExecution<ProvidedEnvironment<L>, A>,\n options?: MainOptions<A>\n ): Promise<Awaited<A>>\n\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n options: MainOptions<A>,\n program: CompleteExecution<ProvidedEnvironment<L>, A>\n ): Promise<Awaited<A>>\n\n static async runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n backendOrProgramOrOptions:\n | LayerBackend\n | MainOptions<A>\n | CompleteExecution<ProvidedEnvironment<L>, A>,\n programOrOptions?: CompleteExecution<ProvidedEnvironment<L>, A> | MainOptions<A>,\n legacyOptions?: MainOptions<A>\n ): Promise<Awaited<A>> {\n let backend: LayerBackend | undefined\n let program!: CompleteExecution<ProvidedEnvironment<L>, A>\n let options: MainOptions<A> | undefined\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- overload dispatch distinguishes the Program callback from configuration.\n if (typeof backendOrProgramOrOptions === 'function') {\n program = backendOrProgramOrOptions\n // SAFETY: this branch is selected by the Program overload, so the optional value is its options object.\n options = programOrOptions as MainOptions<A> | undefined\n } else if (isLayerBackend(backendOrProgramOrOptions)) {\n backend = backendOrProgramOrOptions\n // SAFETY: the backend overload requires a Program in the third argument.\n program = programOrOptions as CompleteExecution<ProvidedEnvironment<L>, A>\n options = legacyOptions\n } else {\n options = backendOrProgramOrOptions\n // SAFETY: the options overload requires a Program in the third argument.\n program = programOrOptions as CompleteExecution<ProvidedEnvironment<L>, A>\n }\n\n if (options !== undefined && !isOptionsObject(options)) {\n throw new TypeError('NodeRuntime options must be a non-array object')\n }\n\n // SAFETY: validation above establishes an object; the empty object is the omitted-options case.\n const normalizedOptions = (options ?? {}) as MainOptions<A>\n validateOptions(normalizedOptions)\n\n const shutdownController = new AbortController()\n const configuredSignals = normalizeSignals(normalizedOptions.signals)\n const {\n onSuccess,\n onFailure,\n onDefect,\n signal: callerSignal,\n ...runtimeOptions\n } = normalizedOptions\n const signalLink = linkAbortSignals(callerSignal, shutdownController.signal)\n const listeners: InstalledSignalListener[] = []\n const cleanupFailures: unknown[] = []\n\n let runtime: Runtime<ProvidedEnvironment<L>> | undefined\n let disposalPromise: Promise<void> | undefined\n let disposalObserved = false\n let firstSignal: NodeRuntimeSignal | undefined\n let setupFailed = false\n let setupFailure: unknown\n let programFailed = false\n let programFailure: unknown\n let executionCleanupFailed = false\n let executionOutcome: ScopeOutcome | undefined\n let programSettled = false\n let programValue!: Awaited<A>\n\n const requestDispose = (): Promise<void> => {\n if (disposalPromise) {\n return disposalPromise\n }\n\n try {\n disposalPromise = runtime!.dispose()\n } catch (cause) {\n disposalPromise = Promise.reject(cause)\n }\n\n return disposalPromise\n }\n\n const observeDisposal = async (): Promise<void> => {\n if (!runtime || disposalObserved) {\n return\n }\n\n disposalObserved = true\n\n try {\n await requestDispose()\n } catch (cause) {\n cleanupFailures.push(cause)\n }\n }\n\n const onSignal = (signal: NodeRuntimeSignal): void => {\n if (firstSignal !== undefined) {\n return\n }\n\n firstSignal = signal\n\n try {\n shutdownController.abort(signal)\n } finally {\n void requestDispose().catch(() => {})\n }\n }\n\n try {\n const executionObserver: RuntimeObserver = {\n onExecutionEnd: ({ outcome }: RuntimeExecutionEndEvent): void => {\n executionOutcome = outcome\n }\n }\n const runtimeOptionsWithSignal: RuntimeOptions = {\n ...runtimeOptions,\n observers: [executionObserver, ...(runtimeOptions.observers ?? [])],\n signal: signalLink.signal\n }\n\n runtime = backend\n ? await Runtime.make(layer, backend, runtimeOptionsWithSignal)\n : await Runtime.make(layer, runtimeOptionsWithSignal)\n\n installSignalListeners(configuredSignals, listeners, onSignal)\n\n try {\n programValue = await runtime.run(program)\n programSettled = true\n } catch (cause) {\n if (executionOutcome?.status === 'success') {\n executionCleanupFailed = true\n } else {\n programFailed = true\n }\n programFailure = cause\n }\n\n await observeDisposal()\n } catch (cause) {\n setupFailed = true\n setupFailure = cause\n } finally {\n await observeDisposal()\n cleanupFailures.push(...removeSignalListeners(listeners))\n\n try {\n signalLink.dispose()\n } catch (cause) {\n cleanupFailures.push(cause)\n }\n }\n\n const cleanupFailureValues = combineFailures(cleanupFailures)\n const hasCleanupFailure = cleanupFailureValues.length > 0\n const cleanupFailure = cleanupFailureValues[0]\n\n if (setupFailed) {\n reportDefect(setupFailure, onDefect)\n throw setupFailure\n }\n\n if (programFailed) {\n reportDefect(programFailure, onDefect)\n throw programFailure\n }\n\n if (executionCleanupFailed) {\n setExitCode(1)\n throw programFailure\n }\n\n if (!programSettled) {\n const failure = new Error('NodeRuntime main program did not settle')\n reportDefect(failure, onDefect)\n throw failure\n }\n\n if (programValue instanceof Err) {\n let exitCode = 1\n\n try {\n if (onFailure) {\n // SAFETY: Err carries the failure channel represented by MainFailure<A>.\n exitCode = validateExitCode(onFailure(programValue.error as MainFailure<A>))\n }\n } catch (cause) {\n reportDefect(cause, onDefect)\n throw cause\n }\n\n setExitCode(exitCode)\n return programValue\n }\n\n let exitCode = 0\n\n try {\n if (onSuccess) {\n const successValue = programValue instanceof Ok ? programValue.value : programValue\n // SAFETY: Ok is unwrapped above; plain successful values retain the MainSuccess<A> channel.\n exitCode = validateExitCode(onSuccess(successValue as MainSuccess<A>))\n }\n } catch (cause) {\n reportDefect(cause, onDefect)\n throw cause\n }\n\n if (hasCleanupFailure) {\n exitCode = ensureFailureExitCode(exitCode)\n }\n\n setExitCode(exitCode)\n\n if (hasCleanupFailure) {\n throw cleanupFailure\n }\n\n return programValue\n }\n}\n\n/** Type-level aliases for the Node.js/Bun process boundary. */\nexport declare namespace NodeRuntime {\n /** Options for `NodeRuntime.runMain`. */\n export type Options<Success = unknown, Failure = unknown> = NodeRuntimeOptions<Success, Failure>\n\n /** A process signal accepted by `NodeRuntime.runMain`. */\n export type Signal = NodeRuntimeSignal\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node.mjs","names":[],"sources":["../src/runtime/node-runtime.ts"],"sourcesContent":["import { Err, Ok } from 'better-result'\n\nimport type { Result as ResultType } from 'better-result'\n\nimport type { EffectError, EffectSuccess } from '../effect'\nimport type { LayerBackend } from '../layer/backend'\nimport type {\n CompleteExecution,\n CompleteInput,\n LayerInput,\n ProvidedEnvironment\n} from '../layer/inference'\nimport { Runtime } from './runtime'\nimport { linkAbortSignals } from './signal'\n\nimport type { RuntimeDisposeOptions, RuntimeOptions, RuntimeShutdownReason } from './outcome'\nimport type { RuntimeExecutionEndEvent, RuntimeObserver } from './observer'\nimport type { ScopeOutcome } from '../scope'\n\n/** Process signals supported by the Node.js/Bun process boundary. */\nexport type NodeRuntimeSignal = 'SIGINT' | 'SIGTERM'\n\n/** Translate a successful main result to a process exit code. */\nexport type NodeRuntimeSuccessHandler<Success> = (value: Success) => number\n\n/** Translate a typed main failure to a process exit code. */\nexport type NodeRuntimeFailureHandler<Failure> = (error: Failure) => number\n\n/** Observe a thrown or rejected main defect while it remains a rejected Promise. */\nexport type NodeRuntimeDefectHandler = (cause: unknown) => number | void\n\n/** Options for the Node.js/Bun process boundary. */\nexport type NodeRuntimeOptions<Success = unknown, Failure = unknown> = RuntimeOptions & {\n /** Process signals that request cooperative shutdown. Defaults to SIGINT and SIGTERM. */\n readonly signals?: readonly NodeRuntimeSignal[]\n /** Map a nominal Result.ok value, or a plain successful value, to an exit code. */\n readonly onSuccess?: NodeRuntimeSuccessHandler<Success>\n /** Map a nominal Result.err error to an exit code. */\n readonly onFailure?: NodeRuntimeFailureHandler<Failure>\n /** Observe a defect. Defects are rethrown after the handler runs. */\n readonly onDefect?: NodeRuntimeDefectHandler\n /** Runtime shutdown policy used after a signal or main-program settlement. */\n readonly shutdown?: RuntimeDisposeOptions\n}\n\n/** Options for the Layer-first `NodeRuntime.launch` entrypoint. */\nexport type NodeRuntimeLaunchOptions = Omit<\n NodeRuntimeOptions<never, never>,\n 'onSuccess' | 'onFailure'\n>\n\ntype NonResultMainSuccess<Value> = Value extends ResultType<any, any> ? never : Value\n\ntype PlainMainSuccess<Value> = NonResultMainSuccess<Awaited<Value>>\n\ntype MainSuccess<Value> = EffectSuccess<Value> | PlainMainSuccess<Value>\n\ntype MainFailure<Value> = EffectError<Value>\n\ntype MainOptions<Value> = NodeRuntimeOptions<MainSuccess<Value>, MainFailure<Value>>\n\nconst DEFAULT_SIGNALS = ['SIGINT', 'SIGTERM'] as const satisfies readonly NodeRuntimeSignal[]\n\ntype InstalledSignalListener = {\n readonly signal: NodeRuntimeSignal\n readonly listener: () => void\n}\n\ntype InstalledAbortListener = {\n readonly signal: AbortSignal\n readonly listener: () => void\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- backend overload dispatch validates an opaque runtime value.\nconst isLayerBackend = (value: unknown): value is LayerBackend => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- runtime overload dispatch must inspect the backend shape.\n if (value === null || typeof value !== 'object') {\n return false\n }\n\n return (\n 'register' in value &&\n 'resolve' in value &&\n 'disposeAll' in value &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.register === 'function' &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.resolve === 'function' &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- the backend contract is validated at this runtime boundary.\n typeof value.disposeAll === 'function'\n )\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- AbortSignal validation receives an opaque public option.\nconst isAbortSignal = (value: unknown): value is AbortSignal => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n if (value === null || typeof value !== 'object') {\n return false\n }\n\n return (\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).aborted === 'boolean' &&\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).addEventListener === 'function' &&\n // SAFETY: the preceding guard establishes that the opaque value is an object; these are the required AbortSignal members.\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the structural host signal contract.\n typeof (value as AbortSignal).removeEventListener === 'function'\n )\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters -- options are validated at the public boundary.\nconst isOptionsObject = (value: unknown): value is object => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate the public options boundary before installing listeners.\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nconst validateExitCode = (code: number): number => {\n if (!Number.isSafeInteger(code) || code < 0) {\n throw new RangeError('NodeRuntime exit codes must be non-negative safe integers')\n }\n\n return code\n}\n\nconst ensureFailureExitCode = (code: number): number => (code === 0 ? 1 : code)\n\nconst makeShutdownReason = (\n kind: RuntimeShutdownReason['kind'],\n cause?: unknown\n): RuntimeShutdownReason => {\n const reason: RuntimeShutdownReason = { kind }\n\n if (cause !== undefined) {\n Object.assign(reason, { cause })\n }\n\n return reason\n}\n\nconst validateSignals = <Success, Failure>(\n signals: NodeRuntimeOptions<Success, Failure>['signals']\n): void => {\n if (signals !== undefined && !Array.isArray(signals)) {\n throw new TypeError('NodeRuntime signals must be an array of supported signal names')\n }\n\n for (const signal of signals ?? DEFAULT_SIGNALS) {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before process.on receives them.\n if (typeof signal !== 'string' || (signal !== 'SIGINT' && signal !== 'SIGTERM')) {\n throw new RangeError(`NodeRuntime signal \"${String(signal)}\" is not supported`)\n }\n }\n}\n\nconst validateRuntimeOptions = <Success, Failure>(\n options: NodeRuntimeOptions<Success, Failure>\n): void => {\n if (options.signal !== undefined && !isAbortSignal(options.signal)) {\n throw new TypeError('NodeRuntime signal must be an AbortSignal')\n }\n}\n\nconst validateShutdownOptions = <Success, Failure>(\n shutdown: NodeRuntimeOptions<Success, Failure>['shutdown']\n): void => {\n if (shutdown === undefined) {\n return\n }\n\n if (\n shutdown.gracePeriod !== undefined &&\n (!Number.isFinite(shutdown.gracePeriod) || shutdown.gracePeriod < 0)\n ) {\n throw new RangeError('NodeRuntime shutdown gracePeriod must be a finite non-negative number')\n }\n\n if (\n shutdown.abortAfterGracePeriod !== undefined &&\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped public options at the process boundary.\n typeof shutdown.abortAfterGracePeriod !== 'boolean'\n ) {\n throw new TypeError('NodeRuntime shutdown abortAfterGracePeriod must be a boolean')\n }\n}\n\nconst validateCallbacks = <Success, Failure>(\n options: NodeRuntimeOptions<Success, Failure>\n): void => {\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onSuccess !== undefined && typeof options.onSuccess !== 'function') {\n throw new TypeError('NodeRuntime onSuccess must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onFailure !== undefined && typeof options.onFailure !== 'function') {\n throw new TypeError('NodeRuntime onFailure must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before invoking the callback.\n if (options.onDefect !== undefined && typeof options.onDefect !== 'function') {\n throw new TypeError('NodeRuntime onDefect must be a function')\n }\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- validate untyped options before Runtime invokes the observer.\n if (options.onCleanupFailure !== undefined && typeof options.onCleanupFailure !== 'function') {\n throw new TypeError('NodeRuntime onCleanupFailure must be a function')\n }\n}\n\nconst validateOptions = <Success, Failure>(options: NodeRuntimeOptions<Success, Failure>): void => {\n validateSignals(options.signals)\n validateRuntimeOptions(options)\n validateCallbacks(options)\n validateShutdownOptions(options.shutdown)\n\n if (options.observers !== undefined && !Array.isArray(options.observers)) {\n throw new TypeError('NodeRuntime observers must be an array')\n }\n}\n\nconst normalizeSignals = (\n signals: readonly NodeRuntimeSignal[] | undefined\n): readonly NodeRuntimeSignal[] => {\n const unique = new Set<NodeRuntimeSignal>()\n\n for (const signal of signals ?? DEFAULT_SIGNALS) {\n unique.add(signal)\n }\n\n return [...unique]\n}\n\nconst removeSignalListeners = (listeners: InstalledSignalListener[]): readonly unknown[] => {\n const failures: unknown[] = []\n\n for (const { signal, listener } of listeners) {\n try {\n process.removeListener(signal, listener)\n } catch (cause) {\n failures.push(cause)\n }\n }\n\n listeners.length = 0\n\n return failures\n}\n\nconst removeAbortListener = (listener: InstalledAbortListener | undefined): readonly unknown[] => {\n if (listener === undefined) {\n return []\n }\n\n try {\n listener.signal.removeEventListener('abort', listener.listener)\n return []\n } catch (cause) {\n return [cause]\n }\n}\n\nconst combineFailures = (failures: readonly unknown[]): readonly unknown[] => {\n if (failures.length === 0) {\n return []\n }\n\n if (failures.length === 1) {\n return [failures[0]]\n }\n\n return [new AggregateError(failures, 'NodeRuntime cleanup failed')]\n}\n\nconst setExitCode = (code: number): void => {\n process.exitCode = validateExitCode(code)\n}\n\nconst reportDefect = (cause: unknown, handler: NodeRuntimeDefectHandler | undefined): void => {\n let exitCode = 1\n\n if (handler) {\n try {\n const requestedExitCode = handler(cause)\n\n if (requestedExitCode !== undefined) {\n exitCode = validateExitCode(requestedExitCode)\n }\n } catch {\n exitCode = 1\n }\n }\n\n setExitCode(ensureFailureExitCode(exitCode))\n}\n\nconst installSignalListeners = (\n signals: readonly NodeRuntimeSignal[],\n listeners: InstalledSignalListener[],\n onSignal: (signal: NodeRuntimeSignal) => void\n): void => {\n for (const signal of signals) {\n const listener = (): void => onSignal(signal)\n process.on(signal, listener)\n listeners.push({ signal, listener })\n }\n}\n\n/** Node.js/Bun process lifecycle helpers. */\nexport class NodeRuntime {\n /**\n * Run a typed main Program, translate its final result to `process.exitCode`,\n * and dispose the Runtime when the program or a configured process signal settles.\n */\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n backend: LayerBackend,\n program: CompleteExecution<ProvidedEnvironment<L>, A>,\n options?: MainOptions<A>\n ): Promise<Awaited<A>>\n\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n program: CompleteExecution<ProvidedEnvironment<L>, A>,\n options?: MainOptions<A>\n ): Promise<Awaited<A>>\n\n static runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n options: MainOptions<A>,\n program: CompleteExecution<ProvidedEnvironment<L>, A>\n ): Promise<Awaited<A>>\n\n static async runMain<A, L extends LayerInput>(\n layer: L & CompleteInput<L>,\n backendOrProgramOrOptions:\n | LayerBackend\n | MainOptions<A>\n | CompleteExecution<ProvidedEnvironment<L>, A>,\n programOrOptions?: CompleteExecution<ProvidedEnvironment<L>, A> | MainOptions<A>,\n legacyOptions?: MainOptions<A>\n ): Promise<Awaited<A>> {\n let backend: LayerBackend | undefined\n let program!: CompleteExecution<ProvidedEnvironment<L>, A>\n let options: MainOptions<A> | undefined\n\n // oxlint-disable-next-line anti-slop/no-runtime-typeof -- overload dispatch distinguishes the Program callback from configuration.\n if (typeof backendOrProgramOrOptions === 'function') {\n program = backendOrProgramOrOptions\n // SAFETY: this branch is selected by the Program overload, so the optional value is its options object.\n options = programOrOptions as MainOptions<A> | undefined\n } else if (isLayerBackend(backendOrProgramOrOptions)) {\n backend = backendOrProgramOrOptions\n // SAFETY: the backend overload requires a Program in the third argument.\n program = programOrOptions as CompleteExecution<ProvidedEnvironment<L>, A>\n options = legacyOptions\n } else {\n options = backendOrProgramOrOptions\n // SAFETY: the options overload requires a Program in the third argument.\n program = programOrOptions as CompleteExecution<ProvidedEnvironment<L>, A>\n }\n\n if (options !== undefined && !isOptionsObject(options)) {\n throw new TypeError('NodeRuntime options must be a non-array object')\n }\n\n // SAFETY: validation above establishes an object; the empty object is the omitted-options case.\n const normalizedOptions = (options ?? {}) as MainOptions<A>\n validateOptions(normalizedOptions)\n\n const shutdownController = new AbortController()\n const configuredSignals = normalizeSignals(normalizedOptions.signals)\n const {\n onSuccess,\n onFailure,\n onDefect,\n signal: callerSignal,\n shutdown: shutdownOptions,\n ...runtimeOptions\n } = normalizedOptions\n const signalLink = linkAbortSignals(callerSignal, shutdownController.signal)\n const listeners: InstalledSignalListener[] = []\n const cleanupFailures: unknown[] = []\n\n let runtime: Runtime<ProvidedEnvironment<L>> | undefined\n let disposalPromise: Promise<void> | undefined\n let pendingDisposalReason: RuntimeShutdownReason | undefined\n let disposalObserved = false\n let firstSignal: NodeRuntimeSignal | undefined\n let setupFailed = false\n let setupFailure: unknown\n let programFailed = false\n let programFailure: unknown\n let executionCleanupFailed = false\n let executionOutcome: ScopeOutcome | undefined\n let programSettled = false\n let programValue!: Awaited<A>\n let externalAbortListener: InstalledAbortListener | undefined\n\n const requestDispose = (reason: RuntimeShutdownReason): Promise<void> => {\n if (disposalPromise) {\n return disposalPromise\n }\n\n if (runtime === undefined) {\n pendingDisposalReason ??= reason\n return Promise.resolve()\n }\n\n try {\n disposalPromise = runtime!.dispose({ ...shutdownOptions, reason })\n } catch (cause) {\n disposalPromise = Promise.reject(cause)\n }\n\n return disposalPromise\n }\n\n const observeDisposal = async (): Promise<void> => {\n if (!runtime || disposalObserved) {\n return\n }\n\n disposalObserved = true\n\n try {\n await requestDispose(makeShutdownReason('main-settled', programFailure))\n } catch (cause) {\n cleanupFailures.push(cause)\n }\n }\n\n const onSignal = (signal: NodeRuntimeSignal): void => {\n if (firstSignal !== undefined) {\n return\n }\n\n firstSignal = signal\n\n try {\n shutdownController.abort(signal)\n } finally {\n void requestDispose({ kind: 'signal', signal }).catch(() => {})\n }\n }\n\n const onExternalAbort = (): void => {\n const cause = callerSignal?.reason\n\n try {\n shutdownController.abort(cause)\n } finally {\n void requestDispose(makeShutdownReason('external-abort', cause)).catch(() => {})\n }\n }\n\n try {\n installSignalListeners(configuredSignals, listeners, onSignal)\n if (callerSignal !== undefined) {\n const listener = onExternalAbort\n externalAbortListener = { signal: callerSignal, listener }\n callerSignal.addEventListener('abort', listener, { once: true })\n\n if (callerSignal.aborted) {\n onExternalAbort()\n }\n }\n\n const executionObserver: RuntimeObserver = {\n onExecutionEnd: ({ outcome }: RuntimeExecutionEndEvent): void => {\n executionOutcome = outcome\n }\n }\n const runtimeOptionsWithSignal: RuntimeOptions = {\n ...runtimeOptions,\n observers: [executionObserver, ...(runtimeOptions.observers ?? [])],\n signal: signalLink.signal\n }\n\n runtime = backend\n ? await Runtime.make(layer, backend, runtimeOptionsWithSignal)\n : await Runtime.make(layer, runtimeOptionsWithSignal)\n\n if (pendingDisposalReason !== undefined) {\n void requestDispose(pendingDisposalReason).catch(() => {})\n }\n\n try {\n programValue = await runtime.run(program)\n programSettled = true\n } catch (cause) {\n if (executionOutcome?.status === 'success') {\n executionCleanupFailed = true\n } else {\n programFailed = true\n }\n programFailure = cause\n }\n\n await observeDisposal()\n } catch (cause) {\n setupFailed = true\n setupFailure = cause\n } finally {\n await observeDisposal()\n cleanupFailures.push(...removeSignalListeners(listeners))\n cleanupFailures.push(...removeAbortListener(externalAbortListener))\n\n try {\n signalLink.dispose()\n } catch (cause) {\n cleanupFailures.push(cause)\n }\n }\n\n const cleanupFailureValues = combineFailures(cleanupFailures)\n const hasCleanupFailure = cleanupFailureValues.length > 0\n const cleanupFailure = cleanupFailureValues[0]\n\n if (setupFailed) {\n reportDefect(setupFailure, onDefect)\n throw setupFailure\n }\n\n if (programFailed) {\n reportDefect(programFailure, onDefect)\n throw programFailure\n }\n\n if (executionCleanupFailed) {\n setExitCode(1)\n throw programFailure\n }\n\n if (!programSettled) {\n const failure = new Error('NodeRuntime main program did not settle')\n reportDefect(failure, onDefect)\n throw failure\n }\n\n if (programValue instanceof Err) {\n let exitCode = 1\n\n try {\n if (onFailure) {\n // SAFETY: Err carries the failure channel represented by MainFailure<A>.\n exitCode = validateExitCode(onFailure(programValue.error as MainFailure<A>))\n }\n } catch (cause) {\n reportDefect(cause, onDefect)\n throw cause\n }\n\n setExitCode(exitCode)\n return programValue\n }\n\n let exitCode = 0\n\n try {\n if (onSuccess) {\n const successValue = programValue instanceof Ok ? programValue.value : programValue\n // SAFETY: Ok is unwrapped above; plain successful values retain the MainSuccess<A> channel.\n exitCode = validateExitCode(onSuccess(successValue as MainSuccess<A>))\n }\n } catch (cause) {\n reportDefect(cause, onDefect)\n throw cause\n }\n\n if (hasCleanupFailure) {\n exitCode = ensureFailureExitCode(exitCode)\n }\n\n setExitCode(exitCode)\n\n if (hasCleanupFailure) {\n throw cleanupFailure\n }\n\n return programValue\n }\n\n /** Start a Layer-owned application until a process or caller signal shuts it down. */\n static async launch<L extends LayerInput>(\n layer: L & CompleteInput<L>,\n options: NodeRuntimeLaunchOptions = {}\n ): Promise<void> {\n if (!isOptionsObject(options)) {\n throw new TypeError('NodeRuntime options must be a non-array object')\n }\n\n validateOptions(options)\n\n const configuredSignals = normalizeSignals(options.signals)\n const callerSignal = options.signal\n const shutdownOptions = options.shutdown\n const runtimeOptions = { ...options }\n const listeners: InstalledSignalListener[] = []\n const cleanupFailures: unknown[] = []\n let runtime: Runtime<ProvidedEnvironment<L>> | undefined\n let disposalPromise: Promise<void> | undefined\n let pendingShutdownReason: RuntimeShutdownReason | undefined\n let resolveShutdown!: () => void\n let rejectShutdown!: (cause: unknown) => void\n const shutdown = new Promise<void>((resolve, reject) => {\n resolveShutdown = resolve\n rejectShutdown = reject\n })\n let firstSignal: NodeRuntimeSignal | undefined\n let callerAbortListener: InstalledAbortListener | undefined\n\n const requestShutdown = (reason: RuntimeShutdownReason): void => {\n if (disposalPromise !== undefined) {\n return\n }\n\n if (runtime === undefined) {\n pendingShutdownReason ??= reason\n return\n }\n\n try {\n disposalPromise = runtime!.dispose({ ...shutdownOptions, reason })\n void disposalPromise.then(resolveShutdown, rejectShutdown)\n } catch (cause) {\n disposalPromise = Promise.reject(cause)\n void disposalPromise.then(resolveShutdown, rejectShutdown)\n }\n }\n\n const onSignal = (signal: NodeRuntimeSignal): void => {\n if (firstSignal !== undefined) {\n return\n }\n\n firstSignal = signal\n requestShutdown({ kind: 'signal', signal })\n }\n\n const onCallerAbort = (): void => {\n const cause = callerSignal?.reason\n requestShutdown(makeShutdownReason('external-abort', cause))\n }\n\n let launchFailed = false\n let failure: unknown\n\n try {\n installSignalListeners(configuredSignals, listeners, onSignal)\n\n if (callerSignal !== undefined) {\n callerAbortListener = { signal: callerSignal, listener: onCallerAbort }\n callerSignal.addEventListener('abort', onCallerAbort, { once: true })\n\n if (callerSignal.aborted) {\n onCallerAbort()\n }\n }\n\n runtime = await Runtime.make(layer, runtimeOptions)\n\n if (pendingShutdownReason !== undefined) {\n requestShutdown(pendingShutdownReason)\n }\n\n // A pending Promise alone does not keep a Node.js process alive. stdin is\n // the host-native wait handle; no polling timer is needed.\n process.stdin.resume()\n await shutdown\n } catch (cause) {\n launchFailed = true\n failure = cause\n\n if (runtime !== undefined && disposalPromise === undefined) {\n try {\n await runtime.dispose({\n ...shutdownOptions,\n reason: { kind: 'main-settled', cause }\n })\n } catch (cleanupCause) {\n failure = cleanupCause\n }\n }\n } finally {\n cleanupFailures.push(...removeSignalListeners(listeners))\n cleanupFailures.push(...removeAbortListener(callerAbortListener))\n process.stdin.pause()\n }\n\n if (launchFailed) {\n reportDefect(failure, options.onDefect)\n throw failure\n }\n\n if (cleanupFailures.length > 0) {\n const cleanupFailure = combineFailures(cleanupFailures)[0]\n reportDefect(cleanupFailure, options.onDefect)\n throw cleanupFailure\n }\n }\n}\n\n/** Type-level aliases for the Node.js/Bun process boundary. */\nexport declare namespace NodeRuntime {\n /** Options for `NodeRuntime.runMain`. */\n export type Options<Success = unknown, Failure = unknown> = NodeRuntimeOptions<Success, Failure>\n\n /** A process signal accepted by `NodeRuntime.runMain`. */\n export type Signal = NodeRuntimeSignal\n}\n"],"mappings":"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"}
|
package/dist/opentelemetry.d.mts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as RuntimeServiceAcquireEvent, C as RuntimeExecutionStartEvent, D as RuntimeLifecycleStartEvent, E as RuntimeLifecycleReleaseEvent, M as RuntimeShutdownEvent, O as RuntimeObserver, b as RuntimeExecutionAttributes, j as RuntimeServiceResolveEvent, k as RuntimeResourceReleaseEvent, w as RuntimeLifecycleEndEvent, x as RuntimeExecutionEndEvent } from "./layer-C2OaqTmB.mjs";
|
|
2
2
|
import { AttributeValue, Tracer, TracerProvider } from "@opentelemetry/api";
|
|
3
|
+
//#region src/opentelemetry/lifecycle.d.ts
|
|
4
|
+
/** Controls how lifecycle-only Layer entries are represented in telemetry. */
|
|
5
|
+
type LifecycleTelemetryMode = 'off' | 'events' | 'spans';
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/opentelemetry/shutdown.d.ts
|
|
8
|
+
/** Controls how Runtime shutdown phases are represented in telemetry. */
|
|
9
|
+
type ShutdownTelemetryMode = 'off' | 'events' | 'spans';
|
|
10
|
+
//#endregion
|
|
3
11
|
//#region src/opentelemetry/index.d.ts
|
|
4
12
|
/** Controls how Service lifecycle events are represented in telemetry. */
|
|
5
13
|
type ServiceTelemetryMode = 'off' | 'events' | 'spans';
|
|
@@ -25,6 +33,10 @@ type OpenTelemetryRuntimeObserverBaseOptions = {
|
|
|
25
33
|
readonly tracerVersion?: string;
|
|
26
34
|
/** Service resolution policy. Defaults to `off`. */
|
|
27
35
|
readonly serviceResolution?: ServiceTelemetryMode;
|
|
36
|
+
/** Lifecycle-only Layer entry policy. Defaults to `off`. */
|
|
37
|
+
readonly lifecycle?: LifecycleTelemetryMode;
|
|
38
|
+
/** Runtime shutdown policy. Defaults to `off`. */
|
|
39
|
+
readonly shutdown?: ShutdownTelemetryMode;
|
|
28
40
|
/** Record explicitly sanitized failure details in addition to setting status. */
|
|
29
41
|
readonly recordFailures?: boolean;
|
|
30
42
|
/** Explicitly sanitize arbitrary execution attributes. */
|
|
@@ -60,6 +72,8 @@ declare class OpenTelemetryRuntimeObserver implements RuntimeObserver {
|
|
|
60
72
|
private readonly limits;
|
|
61
73
|
private readonly executionSpans;
|
|
62
74
|
private readonly serviceResolution;
|
|
75
|
+
private readonly lifecycleTelemetry;
|
|
76
|
+
private readonly shutdownTelemetry;
|
|
63
77
|
private readonly recordFailures;
|
|
64
78
|
private disposed;
|
|
65
79
|
constructor(options: OpenTelemetryRuntimeObserverOptions);
|
|
@@ -69,6 +83,10 @@ declare class OpenTelemetryRuntimeObserver implements RuntimeObserver {
|
|
|
69
83
|
readonly onServiceResolve: (event: RuntimeServiceResolveEvent) => void;
|
|
70
84
|
readonly onServiceAcquire: (event: RuntimeServiceAcquireEvent) => void;
|
|
71
85
|
readonly onResourceRelease: (event: RuntimeResourceReleaseEvent) => void;
|
|
86
|
+
readonly onLifecycleStart: (event: RuntimeLifecycleStartEvent) => void;
|
|
87
|
+
readonly onLifecycleEnd: (event: RuntimeLifecycleEndEvent) => void;
|
|
88
|
+
readonly onLifecycleRelease: (event: RuntimeLifecycleReleaseEvent) => void;
|
|
89
|
+
readonly onShutdown: (event: RuntimeShutdownEvent) => void;
|
|
72
90
|
/** End any spans whose malformed or missing end event left them pending. */
|
|
73
91
|
dispose(): void;
|
|
74
92
|
[Symbol.dispose](): void;
|
|
@@ -90,5 +108,5 @@ declare class OpenTelemetryRuntimeObserver implements RuntimeObserver {
|
|
|
90
108
|
private finishServiceSpan;
|
|
91
109
|
}
|
|
92
110
|
//#endregion
|
|
93
|
-
export { OpenTelemetryAttributes, OpenTelemetryExecutionAttributesSanitizer, OpenTelemetryFailure, OpenTelemetryFailureSanitizer, OpenTelemetryRuntimeObserver, OpenTelemetryRuntimeObserverOptions, ServiceTelemetryMode };
|
|
111
|
+
export { type LifecycleTelemetryMode, OpenTelemetryAttributes, OpenTelemetryExecutionAttributesSanitizer, OpenTelemetryFailure, OpenTelemetryFailureSanitizer, OpenTelemetryRuntimeObserver, OpenTelemetryRuntimeObserverOptions, ServiceTelemetryMode, type ShutdownTelemetryMode };
|
|
94
112
|
//# sourceMappingURL=opentelemetry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opentelemetry.d.mts","names":[],"sources":["../src/opentelemetry/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"opentelemetry.d.mts","names":[],"sources":["../src/opentelemetry/lifecycle.ts","../src/opentelemetry/shutdown.ts","../src/opentelemetry/index.ts"],"mappings":";;;;KAUY;;;;KCEA;;;;KCsBA;;KAGA,0BAA0B,SAAS,eAAe;;KAGlD;WAGG;WACA,aAAa;;;KAIhB,6CACV,YAAY,+BACT;;KAGO,iCAAiC,mBAAmB;KAE3D;;WAEM,SAAS;;WAET,WAAW;;WAEX;;WAEA;;WAEA,oBAAoB;;WAEpB,YAAY;;WAEZ,WAAW;;WAEX;;WAEA,8BAA8B;;WAE9B;;WAEA,kBAAkB;;WAElB;;WAEA;;WAEA;;;KAIC,uCACP;WACU,QAAQ;WACR;MAEV;WACU,UAAU;WACV;;;;;;;;cAgsBF,wCAAwC;mBAClC;mBAEA;mBAEA;mBAEA;mBAEA;mBAEA;mBAEA;mBAEA;UAET;EAER,YAAY,SAAS;SA6Cd,KAAK,SAAS,sCAAsC;WAIlD,mBAAgB,OAAW;WAI3B,iBAAc,OAAW;WAIzB,mBAAgB,OAAW;WAI3B,mBAAgB,OAAW;WAI3B,oBAAiB,OAAW;WAI5B,mBAAgB,OAAW;WAI3B,iBAAc,OAAW;WAIzB,qBAAkB,OAAW;WAI7B,aAAU,OAAW;;EAK9B;GAuBC,OAAO;GAID,OAAO,iBAAiB;UAIvB;UAYA;UAsBA;UAIA;UASA;UAMA;UAMA;UAyDA;UAiBA;UAgCA;UASA;UAiCA;UAIA;UA0BA;UAuBA"}
|