better-effect 0.10.0 → 0.12.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 +464 -11
- package/dist/adapters/iti.d.mts +4 -4
- package/dist/adapters/iti.d.mts.map +1 -1
- package/dist/adapters/iti.mjs +20 -14
- package/dist/adapters/iti.mjs.map +1 -1
- package/dist/effect-CK4YZaX0.mjs +559 -0
- package/dist/effect-CK4YZaX0.mjs.map +1 -0
- package/dist/hono.d.mts +18 -13
- package/dist/hono.d.mts.map +1 -1
- package/dist/hono.mjs +9 -5
- package/dist/hono.mjs.map +1 -1
- package/dist/{index-DklNCz7w.d.mts → index-B1nH4luq.d.mts} +74 -7
- package/dist/index-B1nH4luq.d.mts.map +1 -0
- package/dist/index-BMdU_Z72.d.mts +18 -0
- package/dist/index-BMdU_Z72.d.mts.map +1 -0
- package/dist/{index-BafDna0B.d.mts → index-CX6iAoCB.d.mts} +168 -174
- package/dist/index-CX6iAoCB.d.mts.map +1 -0
- package/dist/index-GYJ4qm9K.d.mts +179 -0
- package/dist/index-GYJ4qm9K.d.mts.map +1 -0
- package/dist/{index-CULgSzUw.d.mts → index-heuaRmXR.d.mts} +5 -5
- package/dist/{index-CULgSzUw.d.mts.map → index-heuaRmXR.d.mts.map} +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +9 -539
- package/dist/index.mjs.map +1 -1
- package/dist/{internal-identity-DmUpBeeL.mjs → internal-identity-CbXoZIfw.mjs} +3 -3
- package/dist/internal-identity-CbXoZIfw.mjs.map +1 -0
- package/dist/{signal-C1bagvrO.mjs → layer-D56fRdLt.mjs} +62 -64
- package/dist/layer-D56fRdLt.mjs.map +1 -0
- package/dist/node-context-DWsCUBRa.d.mts +12 -0
- package/dist/node-context-DWsCUBRa.d.mts.map +1 -0
- package/dist/node-context-lggRF4bR.mjs +25 -0
- package/dist/node-context-lggRF4bR.mjs.map +1 -0
- package/dist/node.d.mts +51 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +233 -0
- package/dist/node.mjs.map +1 -0
- package/dist/{index-C7KX5rAP.d.mts → outcome-CB43bnFW.d.mts} +140 -27
- package/dist/outcome-CB43bnFW.d.mts.map +1 -0
- package/dist/program-metadata-DhQCCirO.mjs +260 -0
- package/dist/program-metadata-DhQCCirO.mjs.map +1 -0
- package/dist/registration-drnZk0SY.mjs +182 -0
- package/dist/registration-drnZk0SY.mjs.map +1 -0
- package/dist/runtime/explicit.d.mts +1 -1
- package/dist/runtime/node.d.mts +3 -12
- package/dist/runtime/node.mjs +2 -24
- package/dist/runtime-CBMrX8Wl.mjs +776 -0
- package/dist/runtime-CBMrX8Wl.mjs.map +1 -0
- package/dist/signal-D2UTcaaG.mjs +105 -0
- package/dist/signal-D2UTcaaG.mjs.map +1 -0
- package/dist/{standard-services-DW-i4UuA.mjs → standard-services-GBZ32tll.mjs} +200 -16
- package/dist/standard-services-GBZ32tll.mjs.map +1 -0
- package/dist/standard-services.d.mts +3 -3
- package/dist/standard-services.mjs +3 -3
- package/dist/testing.d.mts +257 -2
- package/dist/testing.d.mts.map +1 -0
- package/dist/testing.mjs +1159 -2
- package/dist/testing.mjs.map +1 -0
- package/package.json +8 -3
- package/dist/effect-DAMqvegy.mjs +0 -544
- package/dist/effect-DAMqvegy.mjs.map +0 -1
- package/dist/errors-Dnjhzbt0.mjs +0 -99
- package/dist/errors-Dnjhzbt0.mjs.map +0 -1
- package/dist/index-BafDna0B.d.mts.map +0 -1
- package/dist/index-C7KX5rAP.d.mts.map +0 -1
- package/dist/index-DklNCz7w.d.mts.map +0 -1
- package/dist/internal-identity-DmUpBeeL.mjs.map +0 -1
- package/dist/map-layer-backend-gal-mcRv.mjs +0 -53
- package/dist/map-layer-backend-gal-mcRv.mjs.map +0 -1
- package/dist/map-layer-backend-rNwfH0Bz.d.mts +0 -42
- package/dist/map-layer-backend-rNwfH0Bz.d.mts.map +0 -1
- package/dist/runtime/node.d.mts.map +0 -1
- package/dist/runtime/node.mjs.map +0 -1
- package/dist/signal-C1bagvrO.mjs.map +0 -1
- package/dist/standard-services-DW-i4UuA.mjs.map +0 -1
package/dist/node.mjs
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { h as RuntimeContextNotConfiguredError } from "./context-BUEf1qjL.mjs";
|
|
2
|
+
import { n as nodeRuntimeContextStorage, t as NodeRuntimeContextStorage } from "./node-context-lggRF4bR.mjs";
|
|
3
|
+
import { n as linkAbortSignals } from "./signal-D2UTcaaG.mjs";
|
|
4
|
+
import { t as Runtime } from "./runtime-CBMrX8Wl.mjs";
|
|
5
|
+
import { Err, Ok } from "better-result";
|
|
6
|
+
//#region src/runtime/node-runtime.ts
|
|
7
|
+
const DEFAULT_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
8
|
+
const isLayerBackend = (value) => {
|
|
9
|
+
if (value === null || typeof value !== "object") return false;
|
|
10
|
+
return "register" in value && "resolve" in value && "disposeAll" in value && typeof value.register === "function" && typeof value.resolve === "function" && typeof value.disposeAll === "function";
|
|
11
|
+
};
|
|
12
|
+
const isAbortSignal = (value) => {
|
|
13
|
+
if (value === null || typeof value !== "object") return false;
|
|
14
|
+
return typeof value.aborted === "boolean" && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function";
|
|
15
|
+
};
|
|
16
|
+
const isOptionsObject = (value) => {
|
|
17
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
18
|
+
};
|
|
19
|
+
const validateExitCode = (code) => {
|
|
20
|
+
if (!Number.isSafeInteger(code) || code < 0) throw new RangeError("NodeRuntime exit codes must be non-negative safe integers");
|
|
21
|
+
return code;
|
|
22
|
+
};
|
|
23
|
+
const ensureFailureExitCode = (code) => code === 0 ? 1 : code;
|
|
24
|
+
const validateSignals = (signals) => {
|
|
25
|
+
if (signals !== void 0 && !Array.isArray(signals)) throw new TypeError("NodeRuntime signals must be an array of supported signal names");
|
|
26
|
+
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`);
|
|
27
|
+
};
|
|
28
|
+
const validateRuntimeOptions = (options) => {
|
|
29
|
+
if (options.signal !== void 0 && !isAbortSignal(options.signal)) throw new TypeError("NodeRuntime signal must be an AbortSignal");
|
|
30
|
+
};
|
|
31
|
+
const validateCallbacks = (options) => {
|
|
32
|
+
if (options.onSuccess !== void 0 && typeof options.onSuccess !== "function") throw new TypeError("NodeRuntime onSuccess must be a function");
|
|
33
|
+
if (options.onFailure !== void 0 && typeof options.onFailure !== "function") throw new TypeError("NodeRuntime onFailure must be a function");
|
|
34
|
+
if (options.onDefect !== void 0 && typeof options.onDefect !== "function") throw new TypeError("NodeRuntime onDefect must be a function");
|
|
35
|
+
if (options.onCleanupFailure !== void 0 && typeof options.onCleanupFailure !== "function") throw new TypeError("NodeRuntime onCleanupFailure must be a function");
|
|
36
|
+
};
|
|
37
|
+
const validateOptions = (options) => {
|
|
38
|
+
validateSignals(options.signals);
|
|
39
|
+
validateRuntimeOptions(options);
|
|
40
|
+
validateCallbacks(options);
|
|
41
|
+
if (options.observers !== void 0 && !Array.isArray(options.observers)) throw new TypeError("NodeRuntime observers must be an array");
|
|
42
|
+
};
|
|
43
|
+
const normalizeSignals = (signals) => {
|
|
44
|
+
const unique = /* @__PURE__ */ new Set();
|
|
45
|
+
for (const signal of signals ?? DEFAULT_SIGNALS) unique.add(signal);
|
|
46
|
+
return [...unique];
|
|
47
|
+
};
|
|
48
|
+
const removeSignalListeners = (listeners) => {
|
|
49
|
+
const failures = [];
|
|
50
|
+
for (const { signal, listener } of listeners) try {
|
|
51
|
+
process.removeListener(signal, listener);
|
|
52
|
+
} catch (cause) {
|
|
53
|
+
failures.push(cause);
|
|
54
|
+
}
|
|
55
|
+
listeners.length = 0;
|
|
56
|
+
return failures;
|
|
57
|
+
};
|
|
58
|
+
const combineFailures = (failures) => {
|
|
59
|
+
if (failures.length === 0) return [];
|
|
60
|
+
if (failures.length === 1) return [failures[0]];
|
|
61
|
+
return [new AggregateError(failures, "NodeRuntime cleanup failed")];
|
|
62
|
+
};
|
|
63
|
+
const setExitCode = (code) => {
|
|
64
|
+
process.exitCode = validateExitCode(code);
|
|
65
|
+
};
|
|
66
|
+
const reportDefect = (cause, handler) => {
|
|
67
|
+
let exitCode = 1;
|
|
68
|
+
if (handler) try {
|
|
69
|
+
const requestedExitCode = handler(cause);
|
|
70
|
+
if (requestedExitCode !== void 0) exitCode = validateExitCode(requestedExitCode);
|
|
71
|
+
} catch {
|
|
72
|
+
exitCode = 1;
|
|
73
|
+
}
|
|
74
|
+
setExitCode(ensureFailureExitCode(exitCode));
|
|
75
|
+
};
|
|
76
|
+
const installSignalListeners = (signals, listeners, onSignal) => {
|
|
77
|
+
for (const signal of signals) {
|
|
78
|
+
const listener = () => onSignal(signal);
|
|
79
|
+
process.on(signal, listener);
|
|
80
|
+
listeners.push({
|
|
81
|
+
signal,
|
|
82
|
+
listener
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/** Node.js/Bun process lifecycle helpers. */
|
|
87
|
+
var NodeRuntime = class {
|
|
88
|
+
static async runMain(layer, backendOrProgramOrOptions, programOrOptions, legacyOptions) {
|
|
89
|
+
let backend;
|
|
90
|
+
let program;
|
|
91
|
+
let options;
|
|
92
|
+
if (typeof backendOrProgramOrOptions === "function") {
|
|
93
|
+
program = backendOrProgramOrOptions;
|
|
94
|
+
options = programOrOptions;
|
|
95
|
+
} else if (isLayerBackend(backendOrProgramOrOptions)) {
|
|
96
|
+
backend = backendOrProgramOrOptions;
|
|
97
|
+
program = programOrOptions;
|
|
98
|
+
options = legacyOptions;
|
|
99
|
+
} else {
|
|
100
|
+
options = backendOrProgramOrOptions;
|
|
101
|
+
program = programOrOptions;
|
|
102
|
+
}
|
|
103
|
+
if (options !== void 0 && !isOptionsObject(options)) throw new TypeError("NodeRuntime options must be a non-array object");
|
|
104
|
+
const normalizedOptions = options ?? {};
|
|
105
|
+
validateOptions(normalizedOptions);
|
|
106
|
+
const shutdownController = new AbortController();
|
|
107
|
+
const configuredSignals = normalizeSignals(normalizedOptions.signals);
|
|
108
|
+
const { onSuccess, onFailure, onDefect, signal: callerSignal, ...runtimeOptions } = normalizedOptions;
|
|
109
|
+
const signalLink = linkAbortSignals(callerSignal, shutdownController.signal);
|
|
110
|
+
const listeners = [];
|
|
111
|
+
const cleanupFailures = [];
|
|
112
|
+
let runtime;
|
|
113
|
+
let disposalPromise;
|
|
114
|
+
let disposalObserved = false;
|
|
115
|
+
let firstSignal;
|
|
116
|
+
let setupFailed = false;
|
|
117
|
+
let setupFailure;
|
|
118
|
+
let programFailed = false;
|
|
119
|
+
let programFailure;
|
|
120
|
+
let executionCleanupFailed = false;
|
|
121
|
+
let executionOutcome;
|
|
122
|
+
let programSettled = false;
|
|
123
|
+
let programValue;
|
|
124
|
+
const requestDispose = () => {
|
|
125
|
+
if (disposalPromise) return disposalPromise;
|
|
126
|
+
try {
|
|
127
|
+
disposalPromise = runtime.dispose();
|
|
128
|
+
} catch (cause) {
|
|
129
|
+
disposalPromise = Promise.reject(cause);
|
|
130
|
+
}
|
|
131
|
+
return disposalPromise;
|
|
132
|
+
};
|
|
133
|
+
const observeDisposal = async () => {
|
|
134
|
+
if (!runtime || disposalObserved) return;
|
|
135
|
+
disposalObserved = true;
|
|
136
|
+
try {
|
|
137
|
+
await requestDispose();
|
|
138
|
+
} catch (cause) {
|
|
139
|
+
cleanupFailures.push(cause);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const onSignal = (signal) => {
|
|
143
|
+
if (firstSignal !== void 0) return;
|
|
144
|
+
firstSignal = signal;
|
|
145
|
+
try {
|
|
146
|
+
shutdownController.abort(signal);
|
|
147
|
+
} finally {
|
|
148
|
+
requestDispose().catch(() => {});
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
try {
|
|
152
|
+
const executionObserver = { onExecutionEnd: ({ outcome }) => {
|
|
153
|
+
executionOutcome = outcome;
|
|
154
|
+
} };
|
|
155
|
+
const runtimeOptionsWithSignal = {
|
|
156
|
+
...runtimeOptions,
|
|
157
|
+
observers: [executionObserver, ...runtimeOptions.observers ?? []],
|
|
158
|
+
signal: signalLink.signal
|
|
159
|
+
};
|
|
160
|
+
runtime = backend ? await Runtime.make(layer, backend, runtimeOptionsWithSignal) : await Runtime.make(layer, runtimeOptionsWithSignal);
|
|
161
|
+
installSignalListeners(configuredSignals, listeners, onSignal);
|
|
162
|
+
try {
|
|
163
|
+
programValue = await runtime.run(program);
|
|
164
|
+
programSettled = true;
|
|
165
|
+
} catch (cause) {
|
|
166
|
+
if (executionOutcome?.status === "success") executionCleanupFailed = true;
|
|
167
|
+
else programFailed = true;
|
|
168
|
+
programFailure = cause;
|
|
169
|
+
}
|
|
170
|
+
await observeDisposal();
|
|
171
|
+
} catch (cause) {
|
|
172
|
+
setupFailed = true;
|
|
173
|
+
setupFailure = cause;
|
|
174
|
+
} finally {
|
|
175
|
+
await observeDisposal();
|
|
176
|
+
cleanupFailures.push(...removeSignalListeners(listeners));
|
|
177
|
+
try {
|
|
178
|
+
signalLink.dispose();
|
|
179
|
+
} catch (cause) {
|
|
180
|
+
cleanupFailures.push(cause);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const cleanupFailureValues = combineFailures(cleanupFailures);
|
|
184
|
+
const hasCleanupFailure = cleanupFailureValues.length > 0;
|
|
185
|
+
const cleanupFailure = cleanupFailureValues[0];
|
|
186
|
+
if (setupFailed) {
|
|
187
|
+
reportDefect(setupFailure, onDefect);
|
|
188
|
+
throw setupFailure;
|
|
189
|
+
}
|
|
190
|
+
if (programFailed) {
|
|
191
|
+
reportDefect(programFailure, onDefect);
|
|
192
|
+
throw programFailure;
|
|
193
|
+
}
|
|
194
|
+
if (executionCleanupFailed) {
|
|
195
|
+
setExitCode(1);
|
|
196
|
+
throw programFailure;
|
|
197
|
+
}
|
|
198
|
+
if (!programSettled) {
|
|
199
|
+
const failure = /* @__PURE__ */ new Error("NodeRuntime main program did not settle");
|
|
200
|
+
reportDefect(failure, onDefect);
|
|
201
|
+
throw failure;
|
|
202
|
+
}
|
|
203
|
+
if (programValue instanceof Err) {
|
|
204
|
+
let exitCode = 1;
|
|
205
|
+
try {
|
|
206
|
+
if (onFailure) exitCode = validateExitCode(onFailure(programValue.error));
|
|
207
|
+
} catch (cause) {
|
|
208
|
+
reportDefect(cause, onDefect);
|
|
209
|
+
throw cause;
|
|
210
|
+
}
|
|
211
|
+
setExitCode(exitCode);
|
|
212
|
+
return programValue;
|
|
213
|
+
}
|
|
214
|
+
let exitCode = 0;
|
|
215
|
+
try {
|
|
216
|
+
if (onSuccess) {
|
|
217
|
+
const successValue = programValue instanceof Ok ? programValue.value : programValue;
|
|
218
|
+
exitCode = validateExitCode(onSuccess(successValue));
|
|
219
|
+
}
|
|
220
|
+
} catch (cause) {
|
|
221
|
+
reportDefect(cause, onDefect);
|
|
222
|
+
throw cause;
|
|
223
|
+
}
|
|
224
|
+
if (hasCleanupFailure) exitCode = ensureFailureExitCode(exitCode);
|
|
225
|
+
setExitCode(exitCode);
|
|
226
|
+
if (hasCleanupFailure) throw cleanupFailure;
|
|
227
|
+
return programValue;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
//#endregion
|
|
231
|
+
export { NodeRuntime, NodeRuntimeContextStorage, RuntimeContextNotConfiguredError, nodeRuntimeContextStorage };
|
|
232
|
+
|
|
233
|
+
//# sourceMappingURL=node.mjs.map
|
|
@@ -0,0 +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,11 +1,13 @@
|
|
|
1
|
-
import { F as ServiceContract, H as ServiceToken, L as ServiceIdentityTypeId, M as AnyService, N as AnyServiceToken, P as ServiceClass, T as EffectRequirements, U as ServiceTokenOf, V as ServiceTagOf, c as RuntimeContextStorage, d as CleanupFailureDiagnostic, h as ScopeOutcome, j as ServiceRequirement, p as MaybePromise, u as Scope, z as ServiceRequirements } from "./index-
|
|
2
|
-
import { a as LayerRegistration, i as LayerGeneratorRequirements, n as LayerBackend, o as MaybePromise$1, r as LayerGenerator } from "./map-layer-backend-rNwfH0Bz.mjs";
|
|
1
|
+
import { F as ServiceContract, H as ServiceToken, L as ServiceIdentityTypeId, M as AnyService, N as AnyServiceToken, O as InferYieldRequirements, P as ServiceClass, T as EffectRequirements, U as ServiceTokenOf, V as ServiceTagOf, a as ServiceResolver, c as RuntimeContextStorage, d as CleanupFailureDiagnostic, f as DisposableResource, h as ScopeOutcome, j as ServiceRequirement, m as ScopeFinalizer, p as MaybePromise$1, u as Scope, z as ServiceRequirements } from "./index-heuaRmXR.mjs";
|
|
3
2
|
//#region src/internal/variance.d.ts
|
|
4
3
|
/** Type-level marker for a value produced by `A`. */
|
|
5
4
|
type Covariant<A> = () => A;
|
|
6
5
|
/** Type-level marker that both consumes and produces `A`. */
|
|
7
6
|
type Invariant<A> = (value: A) => A;
|
|
8
7
|
//#endregion
|
|
8
|
+
//#region src/utils/types.d.ts
|
|
9
|
+
type MaybePromise<T> = T | PromiseLike<T>;
|
|
10
|
+
//#endregion
|
|
9
11
|
//#region src/internal/missing-dependencies.d.ts
|
|
10
12
|
type MissingDependencies<Missing extends AnyService> = {
|
|
11
13
|
/** Names the Services that must be supplied before execution. */
|
|
@@ -33,7 +35,7 @@ interface LayerProvenance<out Entries extends ProviderEntry<AnyService, AnyServi
|
|
|
33
35
|
//#region src/layer/inference.d.ts
|
|
34
36
|
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
35
37
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
36
|
-
type IsUnion<T, Candidate = T> = T extends unknown ? [Candidate] extends [T] ? false : true : never;
|
|
38
|
+
type IsUnion$1<T, Candidate = T> = T extends unknown ? [Candidate] extends [T] ? false : true : never;
|
|
37
39
|
/** Any Layer shape accepted by type-level inference helpers. */
|
|
38
40
|
type LayerInput = Layer<any, any> | Layer<never, any>;
|
|
39
41
|
/** Extract the public Service environment channels from a Layer. */
|
|
@@ -65,21 +67,22 @@ type PreciseEntries<L extends LayerInput> = L extends LayerProvenance<infer Entr
|
|
|
65
67
|
* explicitly annotated Layer.
|
|
66
68
|
*/
|
|
67
69
|
type ErasedEntries<L extends LayerInput> = L extends LayerProvenance<any, infer Erased> ? Erased : [ProvidedEnvironment<L> | RequiredEnvironment<L>] extends [never] ? never : ErasedProvenance<ProvidedEnvironment<L>, RequiredEnvironment<L>>;
|
|
70
|
+
type PossibleProvidedEnvironment<L extends LayerInput> = EntryProvided<PreciseEntries<L>> | ErasedProvided<ErasedEntries<L>>;
|
|
68
71
|
type LayerMetadata<Entries extends AnyProviderEntry, Erased extends AnyErasedProvenance> = [Entries | Erased] extends [never] ? unknown : LayerProvenance<Entries, Erased>;
|
|
69
72
|
/** Opaque internal result type used by Layer constructors and combinators. */
|
|
70
|
-
type LayerResult<Entries extends AnyProviderEntry, Erased extends AnyErasedProvenance = never
|
|
73
|
+
type LayerResult<Entries extends AnyProviderEntry, Erased extends AnyErasedProvenance = never, VisibleProvided extends AnyService = EntryProvided<Entries> | ErasedProvided<Erased>> = Layer<VisibleProvided, LayerExternalRequirements<EntryRequired<Entries> | ErasedRequired<Erased>, VisibleProvided>> & LayerMetadata<Entries, Erased>;
|
|
71
74
|
type LayerChannelPair<L> = L extends Layer<infer Provided, infer Required> ? [Provided, Required] : never;
|
|
72
75
|
type ExactUncheckedArm<L> = LayerChannelPair<L> extends [infer Provided extends AnyService, infer Required extends AnyService] ? IsAny<Provided> extends true ? IsAny<Required> extends true ? true : false : IsNever<Provided> extends true ? IsAny<Required> extends true ? true : false : false : false;
|
|
73
76
|
type HasUncheckedProvidedArm<L> = L extends unknown ? LayerChannelPair<L> extends [infer Provided, infer Required] ? IsAny<Provided> extends true ? IsAny<Required> extends true ? true : false : false : false : never;
|
|
74
77
|
type HasUncheckedEmptyArm<L> = L extends unknown ? LayerChannelPair<L> extends [infer Provided, infer Required] ? IsNever<Provided> extends true ? IsAny<Required> extends true ? true : false : false : false : never;
|
|
75
78
|
type HasNonUncheckedArm<L> = L extends unknown ? ExactUncheckedArm<L> extends true ? false : true : never;
|
|
76
79
|
/** Recognize only the documented exact unchecked Layer sentinels. */
|
|
77
|
-
type IsExactUncheckedLayer<L> = IsUnion<L> extends false ? ExactUncheckedArm<L> : true extends HasNonUncheckedArm<L> ? false : true extends HasUncheckedProvidedArm<L> ? true extends HasUncheckedEmptyArm<L> ? true : false : false;
|
|
80
|
+
type IsExactUncheckedLayer<L> = IsUnion$1<L> extends false ? ExactUncheckedArm<L> : true extends HasNonUncheckedArm<L> ? false : true extends HasUncheckedProvidedArm<L> ? true extends HasUncheckedEmptyArm<L> ? true : false : false;
|
|
78
81
|
type PartialAnyArm<L> = LayerChannelPair<L> extends [infer Provided extends AnyService, infer Required extends AnyService] ? IsAny<Provided> extends true ? IsAny<Required> extends true ? false : true : IsAny<Required> extends true ? IsNever<Provided> extends true ? false : true : false : false;
|
|
79
82
|
/** Detect any Layer constituent with only one erased generic channel. */
|
|
80
83
|
type HasPartialAnyChannel<L> = true extends (L extends unknown ? PartialAnyArm<L> : never) ? true : false;
|
|
81
84
|
/** Detect a concrete union of Layer values, preserving the original shape. */
|
|
82
|
-
type IsConcreteUnion<L> = IsAny<L> extends true ? false : IsUnion<L> extends true ? IsExactUncheckedLayer<L> extends true ? false : true : false;
|
|
85
|
+
type IsConcreteUnion<L> = IsAny<L> extends true ? false : IsUnion$1<L> extends true ? IsExactUncheckedLayer<L> extends true ? false : true : false;
|
|
83
86
|
type LayerInputState<L> = IsExactUncheckedLayer<L> extends true ? 'unchecked' : HasPartialAnyChannel<L> extends true ? 'invalid-partial-any' : IsConcreteUnion<L> extends true ? 'invalid-union' : 'typed';
|
|
84
87
|
type InvalidLayerErasure = {
|
|
85
88
|
readonly __betterEffectInvalidLayerErasure: unique symbol;
|
|
@@ -100,11 +103,16 @@ type ReplacePreciseOne<Entries extends AnyProviderEntry, Replacement extends Lay
|
|
|
100
103
|
type ReplaceErasedOne<Erased extends AnyErasedProvenance, Replacement extends LayerInput> = Erased extends ErasedProvenance<infer Provided, infer StickyRequired> ? ErasedProvenance<RemoveCompatibleServices<Provided, Extract<ProvidedEnvironment<Replacement>, AnyService>>, StickyRequired> : never;
|
|
101
104
|
type ApplyPreciseOverrides<Entries extends AnyProviderEntry, Overrides extends readonly LayerInput[]> = Overrides extends readonly [infer Head extends LayerInput, ...infer Tail extends readonly LayerInput[]] ? ApplyPreciseOverrides<ReplacePreciseOne<Entries, Head>, Tail> : Entries;
|
|
102
105
|
type ApplyErasedOverrides<Erased extends AnyErasedProvenance, Overrides extends readonly LayerInput[]> = Overrides extends readonly [infer Head extends LayerInput, ...infer Tail extends readonly LayerInput[]] ? ApplyErasedOverrides<ReplaceErasedOne<Erased, Head> | Extract<ErasedEntries<Head>, AnyErasedProvenance>, Tail> : Erased;
|
|
103
|
-
type
|
|
106
|
+
type HasMatchingService<Candidate extends AnyService, Available extends AnyService> = true extends (Available extends AnyService ? SameService<Candidate, Available> : never) ? true : false;
|
|
107
|
+
type GuaranteedServiceCandidates<Candidates extends AnyService, Branches extends LayerInput> = Candidates extends AnyService ? false extends (Branches extends LayerInput ? HasMatchingService<Candidates, Extract<ProvidedEnvironment<Branches>, AnyService>> : never) ? never : Candidates : never;
|
|
108
|
+
type GuaranteedProvided<Branch extends LayerInput, Branches extends LayerInput = Branch> = Branch extends LayerInput ? GuaranteedServiceCandidates<Extract<ProvidedEnvironment<Branch>, AnyService>, Branches> : never;
|
|
109
|
+
type HasUncheckedLayerInTuple<Layers extends readonly LayerInput[]> = true extends { [Index in keyof Layers]: IsExactUncheckedLayer<Layers[Index]>; }[number] ? true : false;
|
|
104
110
|
type MergeLayerResult<Layers extends readonly LayerInput[]> = HasUncheckedLayerInTuple<Layers> extends true ? Layer<any, any> : LayerResult<PreciseEntries<Layers[number]>, ErasedEntries<Layers[number]>>;
|
|
105
111
|
/** Internal result type for Layer.merge. */
|
|
106
112
|
type MergeResult<Layers extends readonly LayerInput[]> = MergeLayerResult<Layers>;
|
|
107
|
-
type
|
|
113
|
+
type ApplyVisibleOverrides<CurrentProvided extends AnyService, Overrides extends readonly LayerInput[]> = Overrides extends readonly [infer Head extends LayerInput, ...infer Tail extends readonly LayerInput[]] ? ApplyVisibleOverrides<RemoveCompatibleServices<CurrentProvided, Extract<ProvidedEnvironment<Head>, AnyService>> | Extract<ProvidedEnvironment<Head>, AnyService>, Tail> : CurrentProvided;
|
|
114
|
+
type OverrideLayerBranches<Base extends LayerInput, Overrides extends readonly LayerInput[]> = Overrides extends readonly LayerInput[] ? Layer<ApplyVisibleOverrides<Extract<ProvidedEnvironment<Base>, AnyService>, Overrides>, never> : never;
|
|
115
|
+
type OverrideLayerResultUnchecked<Base extends LayerInput, Overrides extends readonly LayerInput[]> = HasUncheckedLayerInTuple<[Base, ...Overrides]> extends true ? Layer<any, any> : LayerResult<ApplyPreciseOverrides<PreciseEntries<Base>, Overrides>, ApplyErasedOverrides<ErasedEntries<Base>, Overrides>, Extract<GuaranteedProvided<OverrideLayerBranches<Base, Overrides>>, AnyService>>;
|
|
108
116
|
/** Internal result type for an ordered override tuple. */
|
|
109
117
|
type OverrideLayerResult<Base extends LayerInput, Overrides extends readonly LayerInput[]> = OverrideLayerResultUnchecked<Base, Overrides>;
|
|
110
118
|
type IncompatibleOverridePair<Current extends AnyService, Replacement extends AnyService> = SameServiceTag<Current, Replacement> extends true ? SameServiceContract<Current, Replacement> extends true ? never : ServiceTokenOf<Replacement> : never;
|
|
@@ -117,7 +125,10 @@ type InvalidWidenedProvidedEnvironment = {
|
|
|
117
125
|
readonly __betterEffectWidenedProvidedEnvironment: unique symbol;
|
|
118
126
|
};
|
|
119
127
|
type ValidateOverrideLayerInput<L extends LayerInput> = IsExactUncheckedLayer<L> extends true ? unknown : ValidateLayerInput<L> & (true extends HasWidenedTag<Extract<ProvidedEnvironment<L>, AnyService>> ? InvalidWidenedProvidedEnvironment : unknown);
|
|
128
|
+
type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends ((value: infer Intersection) => void) ? Intersection : never;
|
|
129
|
+
type ValidationFailuresToConstraint<Failures> = [Failures] extends [never] ? unknown : UnionToIntersection<Failures>;
|
|
120
130
|
type ValidateOverrideTuple<Overrides extends readonly LayerInput[]> = { [Index in keyof Overrides]: ValidateOverrideLayerInput<Overrides[Index]>; };
|
|
131
|
+
type ValidateOverrideTupleFailures<Overrides extends readonly LayerInput[]> = ValidationFailuresToConstraint<Overrides extends readonly LayerInput[] ? ValidationFailureWitness<{ [Index in keyof Overrides]: ValidateOverrideLayerInput<Overrides[Index]>; }> : never>;
|
|
121
132
|
type ServiceAtTag<Services, Tag extends string> = Tag extends keyof Services ? Extract<Services[Tag], AnyService> : never;
|
|
122
133
|
type ServiceTagMap<Services extends AnyService> = { [Tag in ServiceTagOf<Services>]: Extract<Services, {
|
|
123
134
|
readonly [ServiceIdentityTypeId]: Tag;
|
|
@@ -133,11 +144,32 @@ type ValidateOverridePair<CurrentProvided extends AnyService, ReplacementProvide
|
|
|
133
144
|
* Rebuilding the full Layer provenance for every step is quadratic and can
|
|
134
145
|
* exhaust TypeScript's instantiation depth on otherwise simple override lists.
|
|
135
146
|
*/
|
|
136
|
-
type
|
|
147
|
+
type ValidateOverridesFromStateForArm<Overrides extends readonly LayerInput[], BaseMap, CurrentProvided extends AnyService, CurrentChanged extends boolean, CurrentUnchecked extends boolean> = Overrides extends readonly [infer Head extends LayerInput, ...infer Tail extends readonly LayerInput[]] ? CurrentUnchecked extends true ? ValidateOverridesFromStateForArm<Tail, BaseMap, AnyService, true, true> : IsExactUncheckedLayer<Head> extends true ? ValidateOverridesFromStateForArm<Tail, BaseMap, AnyService, true, true> : CurrentChanged extends false ? CanSkipBaseOverride<BaseMap, Extract<ProvidedEnvironment<Head>, AnyService>> extends true ? ValidateOverridesFromStateForArm<Tail, BaseMap, CurrentProvided, false, false> : ValidateOverridePair<CurrentProvided, Extract<ProvidedEnvironment<Head>, AnyService>> & ValidateOverridesFromStateForArm<Tail, BaseMap, ApplyValidationOverride<CurrentProvided, Extract<ProvidedEnvironment<Head>, AnyService>>, true, false> : ValidateOverridePair<CurrentProvided, Extract<ProvidedEnvironment<Head>, AnyService>> & ValidateOverridesFromStateForArm<Tail, BaseMap, ApplyValidationOverride<CurrentProvided, Extract<ProvidedEnvironment<Head>, AnyService>>, true, false> : unknown;
|
|
148
|
+
/** Validate every possible override tuple arm instead of accepting one valid arm. */
|
|
149
|
+
type ValidateOverridesFromState<Overrides extends readonly LayerInput[], BaseMap, CurrentProvided extends AnyService, CurrentChanged extends boolean, CurrentUnchecked extends boolean> = ValidationFailuresToConstraint<Overrides extends readonly LayerInput[] ? ValidationFailureWitness<ValidateOverridesFromStateForArm<Overrides, BaseMap, CurrentProvided, CurrentChanged, CurrentUnchecked>> : never>;
|
|
137
150
|
/** Validate one override against the currently accumulated Layer state. */
|
|
138
|
-
type ValidateOneOverride<Current extends LayerInput, Replacement extends LayerInput> = ValidateOverrideLayerInput<Current> & ValidateOverrideLayerInput<Replacement> & (IsExactUncheckedLayer<Current> extends true ? unknown : IsExactUncheckedLayer<Replacement> extends true ? unknown : [IncompatibleOverridePairs<Extract<
|
|
151
|
+
type ValidateOneOverride<Current extends LayerInput, Replacement extends LayerInput> = ValidateOverrideLayerInput<Current> & ValidateOverrideLayerInput<Replacement> & (IsExactUncheckedLayer<Current> extends true ? unknown : IsExactUncheckedLayer<Replacement> extends true ? unknown : [IncompatibleOverridePairs<Extract<PossibleProvidedEnvironment<Current>, AnyService>, Extract<PossibleProvidedEnvironment<Replacement>, AnyService>>] extends [never] ? unknown : IncompatibleLayerOverride<IncompatibleOverridePairs<Extract<PossibleProvidedEnvironment<Current>, AnyService>, Extract<PossibleProvidedEnvironment<Replacement>, AnyService>>>);
|
|
152
|
+
type IsTuple<Values extends readonly unknown[]> = number extends Values['length'] ? false : true;
|
|
153
|
+
type InvalidWidenedOverrideList = {
|
|
154
|
+
readonly __betterEffectWidenedOverrideList: unique symbol;
|
|
155
|
+
};
|
|
139
156
|
/** Validate ordered overrides against the state produced by earlier overrides. */
|
|
140
|
-
type ValidateOverrides<Base extends LayerInput, Overrides extends readonly LayerInput[]> = Overrides extends
|
|
157
|
+
type ValidateOverrides<Base extends LayerInput, Overrides extends readonly LayerInput[]> = [Overrides] extends [never] ? unknown : IsTuple<Overrides> extends false ? IsExactUncheckedLayer<Base> extends true ? unknown : InvalidWidenedOverrideList : ValidateOverrideLayerInput<Base> & ValidateOverrideTuple<Overrides> & ValidationFailuresToConstraint<Overrides extends readonly LayerInput[] ? [Overrides] extends [readonly []] ? never : ValidationFailureWitness<ValidateOverrideTuple<Overrides> & ValidateOverrideTupleFailures<Overrides> & ValidateOverridesFromState<Overrides, ServiceTagMap<Extract<PossibleProvidedEnvironment<Base>, AnyService>>, Extract<PossibleProvidedEnvironment<Base>, AnyService>, false, IsExactUncheckedLayer<Base>>> : never>;
|
|
158
|
+
type ValidationFailureWitness<Value> = Value extends {
|
|
159
|
+
readonly __betterEffectIncompatibleLayerOverride: infer Tokens;
|
|
160
|
+
} ? {
|
|
161
|
+
readonly __betterEffectIncompatibleLayerOverride: Tokens;
|
|
162
|
+
} : Value extends {
|
|
163
|
+
readonly __betterEffectInvalidLayerErasure: unique symbol;
|
|
164
|
+
} ? Value : Value extends {
|
|
165
|
+
readonly __betterEffectAmbiguousLayerUnion: unique symbol;
|
|
166
|
+
} ? Value : Value extends {
|
|
167
|
+
readonly __betterEffectWidenedProvidedEnvironment: unique symbol;
|
|
168
|
+
} ? Value : Value extends {
|
|
169
|
+
readonly __betterEffectWidenedOverrideList: unique symbol;
|
|
170
|
+
} ? Value : Value extends readonly (infer Element)[] ? ValidationFailureWitness<Element> : never;
|
|
171
|
+
/** Reduce Layer override validation to a usable call-site diagnostic witness. */
|
|
172
|
+
type ValidateOverridesWitness<Base extends LayerInput, Overrides extends readonly LayerInput[]> = ValidationFailureWitness<ValidateOverrides<Base, Overrides>> extends (infer Failure) ? [Failure] extends [never] ? unknown : Failure : never;
|
|
141
173
|
/** A Layer accepted by Runtime boundaries after completeness validation. */
|
|
142
174
|
type CompleteInput<L extends LayerInput> = ValidateLayerInput<L> & (LayerInputState<L> extends 'unchecked' ? L : LayerInputState<L> extends 'typed' ? [RequiredEnvironment<L>] extends [never] ? L : L & MissingDependencies<Extract<RequiredEnvironment<L>, AnyService>> : L);
|
|
143
175
|
type ExecutionRequirementsMissing<RootProvided extends AnyService, Request extends LayerInput> = MissingServices<Extract<RequiredEnvironment<Request>, AnyService>, Extract<RootProvided, AnyService>>;
|
|
@@ -150,18 +182,58 @@ type CompleteExecutionWithRequirements<Provided extends AnyService, A, Required
|
|
|
150
182
|
/** Keep execution callbacks unchanged when their Effect requirements are met. */
|
|
151
183
|
type CompleteExecution<Provided extends AnyService, A> = CompleteExecutionWithRequirements<Provided, A, EffectRequirements<A>>;
|
|
152
184
|
//#endregion
|
|
185
|
+
//#region src/layer/types.d.ts
|
|
186
|
+
/** Runtime-facing provider registration supplied by a Layer backend. */
|
|
187
|
+
interface LayerRegistration {
|
|
188
|
+
/** The class-backed Service token provided by this registration. */
|
|
189
|
+
readonly service: ServiceClass<any, any>;
|
|
190
|
+
/**
|
|
191
|
+
* The canonical tag captured when the provider was created.
|
|
192
|
+
*
|
|
193
|
+
* This remains optional for direct backend registrations created against the
|
|
194
|
+
* pre-inspection API; backends capture the token tag synchronously when it is
|
|
195
|
+
* omitted.
|
|
196
|
+
*/
|
|
197
|
+
readonly serviceTag?: string;
|
|
198
|
+
/** Lazily acquire the Service instance; concrete types are erased at this backend boundary. */
|
|
199
|
+
readonly acquire: () => MaybePromise<unknown>;
|
|
200
|
+
}
|
|
201
|
+
/** Generator shape used by `Layer.gen` and `Layer.scopedGen`. */
|
|
202
|
+
type LayerGenerator<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown> = ServiceRequirement<unknown>> = () => AsyncGenerator<Yield, ServiceContract<InstanceType<S>>, unknown>;
|
|
203
|
+
/** Service requirements inferred from a provider's methods and generator. */
|
|
204
|
+
type LayerGeneratorRequirements<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>> = ServiceRequirements<InstanceType<S>> | InferYieldRequirements<Yield>;
|
|
205
|
+
//#endregion
|
|
153
206
|
//#region src/layer/layer.d.ts
|
|
154
207
|
declare const LayerTypeId: unique symbol;
|
|
155
208
|
interface LayerVariance<in out Provided, out Required> {
|
|
156
209
|
readonly _Provided: Invariant<Provided>;
|
|
157
210
|
readonly _Required: Covariant<Required>;
|
|
158
211
|
}
|
|
212
|
+
type CapturedLayerAcquisition = {
|
|
213
|
+
readonly instance: unknown;
|
|
214
|
+
readonly release: ScopeFinalizer;
|
|
215
|
+
};
|
|
159
216
|
interface LayerProvider extends LayerRegistration {
|
|
217
|
+
/** The tag captured before this provider can cross an asynchronous boundary. */
|
|
218
|
+
readonly serviceTag: string;
|
|
160
219
|
/** Provider storage deliberately erases the concrete instance type. */
|
|
161
|
-
readonly release?: (instance: unknown, outcome: ScopeOutcome) => MaybePromise
|
|
220
|
+
readonly release?: (instance: unknown, outcome: ScopeOutcome) => MaybePromise<void>;
|
|
221
|
+
/** Capture acquisition-local cleanup without retaining the acquired instance. */
|
|
222
|
+
readonly acquireWithRelease?: () => MaybePromise<CapturedLayerAcquisition>;
|
|
162
223
|
}
|
|
163
224
|
/** A Service class whose constructor can be called without arguments. */
|
|
164
225
|
type DefaultConstructibleServiceClass<Tag extends string = string, Instance extends AnyService = AnyService> = ServiceClass<Tag, Instance> & (new () => Instance);
|
|
226
|
+
type IsUnion<Type, Candidate = Type> = Type extends unknown ? [Candidate] extends [Type] ? false : true : never;
|
|
227
|
+
type InvalidUnionAliasToken = {
|
|
228
|
+
readonly __betterEffectUnionLayerAliasToken: unique symbol;
|
|
229
|
+
};
|
|
230
|
+
type RejectUnionAliasToken<Token> = IsUnion<Token> extends true ? InvalidUnionAliasToken : unknown;
|
|
231
|
+
type LayerAliasOptions<From extends ServiceClass<any, any>, To extends ServiceClass<any, any>> = {
|
|
232
|
+
readonly from: From;
|
|
233
|
+
readonly to: To;
|
|
234
|
+
} & RejectUnionAliasToken<From> & RejectUnionAliasToken<To> & ([ServiceContract<InstanceType<From>>] extends [ServiceContract<InstanceType<To>>] ? unknown : {
|
|
235
|
+
readonly __betterEffectIncompatibleLayerAlias: unique symbol;
|
|
236
|
+
});
|
|
165
237
|
/**
|
|
166
238
|
* Declarative collection of Service providers.
|
|
167
239
|
*
|
|
@@ -184,15 +256,21 @@ declare class Layer<in out Provided extends AnyService = AnyService, out Require
|
|
|
184
256
|
/** The provider registrations retained by this Layer. */
|
|
185
257
|
readonly providers: readonly LayerProvider[];
|
|
186
258
|
private constructor();
|
|
259
|
+
/** A stable provider-free Layer for composition roots with no Services. */
|
|
260
|
+
static readonly empty: Layer<never, never>;
|
|
187
261
|
/** Create a Layer that lazily acquires a Service instance. */
|
|
188
262
|
static make<S extends DefaultConstructibleServiceClass<any, any>>(service: S): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
|
|
189
|
-
static make<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise
|
|
263
|
+
static make<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
|
|
190
264
|
/** Create a Layer from an already-constructed Service instance. */
|
|
191
265
|
static succeed<S extends ServiceClass<any, any>>(service: S, instance: ServiceContract<InstanceType<S>>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
|
|
266
|
+
/** Alias a source Service under a compatible target contract. */
|
|
267
|
+
static alias<From extends ServiceClass<any, any>, To extends ServiceClass<any, any>>(options: LayerAliasOptions<From, To>): LayerResult<ProviderEntry<InstanceType<To>, InstanceType<From> | ServiceRequirements<InstanceType<To>>>>;
|
|
192
268
|
/** Define a provider with Runtime-root cleanup. */
|
|
193
|
-
static scoped<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise
|
|
269
|
+
static scoped<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise<ServiceContract<InstanceType<S>>>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise<void>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
|
|
270
|
+
/** Define a provider with Runtime-root cleanup through its disposal protocol. */
|
|
271
|
+
static scopedDisposable<S extends ServiceClass<any, any>>(service: S, acquire: () => MaybePromise<ServiceContract<InstanceType<S>> & DisposableResource>): LayerResult<ProviderEntry<InstanceType<S>, ServiceRequirements<InstanceType<S>>>>;
|
|
194
272
|
/** Define a provider whose acquisition can yield contextual Services. */
|
|
195
|
-
static scopedGen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise
|
|
273
|
+
static scopedGen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>, release: (instance: InstanceType<S>, outcome: ScopeOutcome) => MaybePromise<void>): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>;
|
|
196
274
|
/** Define a provider whose acquisition can yield contextual Services. */
|
|
197
275
|
static gen<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>>(service: S, factory: LayerGenerator<S, Yield>): LayerResult<ProviderEntry<InstanceType<S>, LayerGeneratorRequirements<S, Yield>>>;
|
|
198
276
|
/** Compose Layers without replacing providers. */
|
|
@@ -202,7 +280,7 @@ declare class Layer<in out Provided extends AnyService = AnyService, out Require
|
|
|
202
280
|
/** Replace providers in a base Layer, using tag identity and compatible contracts. */
|
|
203
281
|
static override<Base extends LayerInput>(base: Base & ValidateLayerInput<Base>): OverrideLayerResult<Base, readonly []>;
|
|
204
282
|
static override<Base extends LayerInput, const Overrides extends readonly [LayerInput, ...LayerInput[]]>(base: Base & ValidateLayerInput<Base>, ...overrides: Overrides & ValidateOverrides<Base, Overrides>): OverrideLayerResult<Base, Overrides>;
|
|
205
|
-
static override<Base extends LayerInput, const Overrides extends readonly LayerInput[]>(base: Base & ValidateLayerInput<Base>, ...overrides: Overrides
|
|
283
|
+
static override<Base extends LayerInput, const Overrides extends readonly LayerInput[]>(base: Base & ValidateLayerInput<Base>, ...overrides: Overrides & ValidateOverrides<Base, Overrides>): OverrideLayerResult<Base, Overrides>;
|
|
206
284
|
}
|
|
207
285
|
/** Type-level aliases for inspecting Layer environments and completeness. */
|
|
208
286
|
declare namespace Layer {
|
|
@@ -218,6 +296,23 @@ declare namespace Layer {
|
|
|
218
296
|
type Complete<L extends LayerInput> = CompleteInput<L>;
|
|
219
297
|
}
|
|
220
298
|
//#endregion
|
|
299
|
+
//#region src/layer/backend.d.ts
|
|
300
|
+
/** Observation hook invoked for acquisitions that disposal will await. */
|
|
301
|
+
type LayerBackendDisposeOptions = {
|
|
302
|
+
/**
|
|
303
|
+
* Receives the in-flight acquisition Promises when disposal begins. The callback
|
|
304
|
+
* is invoked synchronously and awaited before the backend clears its state.
|
|
305
|
+
*/
|
|
306
|
+
readonly onPendingAcquisitions?: (acquisitions: readonly Promise<unknown>[]) => void | PromiseLike<void>;
|
|
307
|
+
};
|
|
308
|
+
/** Runtime adapter responsible for registering, resolving, and disposing Layer providers. */
|
|
309
|
+
interface LayerBackend extends ServiceResolver {
|
|
310
|
+
/** Register one Service provider with the backend. */
|
|
311
|
+
register(registration: LayerRegistration): MaybePromise<void>;
|
|
312
|
+
/** Dispose all backend-owned instances and provider registrations. */
|
|
313
|
+
disposeAll(options?: LayerBackendDisposeOptions): MaybePromise<void>;
|
|
314
|
+
}
|
|
315
|
+
//#endregion
|
|
221
316
|
//#region src/layer/errors.d.ts
|
|
222
317
|
type LayerCause = Extract<ScopeOutcome, {
|
|
223
318
|
readonly status: 'failure';
|
|
@@ -264,14 +359,26 @@ type RuntimeServiceAcquireEvent = {
|
|
|
264
359
|
readonly resolutionPath: readonly AnyServiceToken[];
|
|
265
360
|
readonly outcome: ScopeOutcome;
|
|
266
361
|
};
|
|
362
|
+
/** Values supplied to one Runtime execution for diagnostic correlation. */
|
|
363
|
+
type RuntimeExecutionAttributes = Readonly<Record<string, unknown>>;
|
|
364
|
+
/** Metadata shared by the start and end events for one execution. */
|
|
365
|
+
type RuntimeExecutionMetadata = {
|
|
366
|
+
readonly executionId: string;
|
|
367
|
+
readonly name?: string;
|
|
368
|
+
readonly attributes?: RuntimeExecutionAttributes;
|
|
369
|
+
/** Monotonic host timestamp captured immediately before the Program starts. */
|
|
370
|
+
readonly startedAt: number;
|
|
371
|
+
};
|
|
267
372
|
/** Event emitted immediately before a program starts in an execution Scope. */
|
|
268
|
-
type RuntimeExecutionStartEvent = {
|
|
373
|
+
type RuntimeExecutionStartEvent = RuntimeExecutionMetadata & {
|
|
269
374
|
readonly scope: Scope;
|
|
270
375
|
};
|
|
271
376
|
/** Event emitted after a program and its execution Scope settle. */
|
|
272
|
-
type RuntimeExecutionEndEvent = {
|
|
377
|
+
type RuntimeExecutionEndEvent = RuntimeExecutionMetadata & {
|
|
273
378
|
readonly scope: Scope;
|
|
274
379
|
readonly outcome: ScopeOutcome;
|
|
380
|
+
/** Monotonic elapsed time for the Program and its execution cleanup. */
|
|
381
|
+
readonly durationMs: number;
|
|
275
382
|
};
|
|
276
383
|
/** Event emitted after a Layer provider release callback settles. */
|
|
277
384
|
type RuntimeResourceReleaseEvent = {
|
|
@@ -281,11 +388,15 @@ type RuntimeResourceReleaseEvent = {
|
|
|
281
388
|
};
|
|
282
389
|
/** Optional best-effort hooks for Runtime lifecycle and resolution events. */
|
|
283
390
|
type RuntimeObserver = {
|
|
284
|
-
readonly onServiceResolve?: (event: RuntimeServiceResolveEvent) => MaybePromise
|
|
285
|
-
readonly onServiceAcquire?: (event: RuntimeServiceAcquireEvent) => MaybePromise
|
|
286
|
-
readonly onExecutionStart?: (event: RuntimeExecutionStartEvent) => MaybePromise
|
|
287
|
-
readonly onExecutionEnd?: (event: RuntimeExecutionEndEvent) => MaybePromise
|
|
288
|
-
readonly onResourceRelease?: (event: RuntimeResourceReleaseEvent) => MaybePromise
|
|
391
|
+
readonly onServiceResolve?: (event: RuntimeServiceResolveEvent) => MaybePromise<void>;
|
|
392
|
+
readonly onServiceAcquire?: (event: RuntimeServiceAcquireEvent) => MaybePromise<void>;
|
|
393
|
+
readonly onExecutionStart?: (event: RuntimeExecutionStartEvent) => MaybePromise<void>;
|
|
394
|
+
readonly onExecutionEnd?: (event: RuntimeExecutionEndEvent) => MaybePromise<void>;
|
|
395
|
+
readonly onResourceRelease?: (event: RuntimeResourceReleaseEvent) => MaybePromise<void>;
|
|
396
|
+
};
|
|
397
|
+
/** Compose best-effort Runtime observers into one observer. */
|
|
398
|
+
declare const RuntimeObserver: {
|
|
399
|
+
compose: (...observers: readonly RuntimeObserver[]) => RuntimeObserver;
|
|
289
400
|
};
|
|
290
401
|
//#endregion
|
|
291
402
|
//#region src/runtime/outcome.d.ts
|
|
@@ -297,7 +408,7 @@ type RuntimeShutdownDiagnostic = {
|
|
|
297
408
|
readonly error: LayerDisposeError;
|
|
298
409
|
};
|
|
299
410
|
/** Observer notified about cleanup failures without changing primary results. */
|
|
300
|
-
type CleanupFailureObserver = (diagnostic: CleanupFailureDiagnostic | RuntimeShutdownDiagnostic) => MaybePromise<void>;
|
|
411
|
+
type CleanupFailureObserver = (diagnostic: CleanupFailureDiagnostic | RuntimeShutdownDiagnostic) => MaybePromise$1<void>;
|
|
301
412
|
/** Optional Runtime configuration for cleanup diagnostics. */
|
|
302
413
|
type RuntimeOptions = {
|
|
303
414
|
/** Backend used to register and resolve the Layer. Defaults to MapLayerBackend. */
|
|
@@ -313,9 +424,11 @@ type RuntimeOptions = {
|
|
|
313
424
|
/** Optional signal exposed through the RuntimeContext. */
|
|
314
425
|
readonly signal?: AbortSignal;
|
|
315
426
|
};
|
|
316
|
-
/** Optional signal supplied to one
|
|
427
|
+
/** Optional signal and diagnostic attributes supplied to one Runtime execution. */
|
|
317
428
|
type RuntimeRunOptions = {
|
|
318
429
|
readonly signal?: AbortSignal;
|
|
430
|
+
/** Copied once and exposed as a readonly event view. */
|
|
431
|
+
readonly attributes?: RuntimeExecutionAttributes;
|
|
319
432
|
};
|
|
320
433
|
/** Cooperative shutdown policy for a managed Runtime. */
|
|
321
434
|
type RuntimeDisposeOptions = {
|
|
@@ -325,5 +438,5 @@ type RuntimeDisposeOptions = {
|
|
|
325
438
|
readonly abortAfterGracePeriod?: boolean;
|
|
326
439
|
};
|
|
327
440
|
//#endregion
|
|
328
|
-
export {
|
|
329
|
-
//# sourceMappingURL=
|
|
441
|
+
export { MissingServices as A, CompleteExecution as C, LayerInput as D, ExecutionMissing as E, ValidateOneOverride as F, ValidateOverrides as I, ValidateOverridesWitness as L, ProvidedEnvironment as M, RequiredEnvironment as N, LayerInputState as O, ValidateLayerInput as P, ProviderEntry as R, LayerRegistration as S, CompleteInput as T, LayerRegistrationError as _, RuntimeShutdownDiagnostic as a, LayerBackendDisposeOptions as b, RuntimeExecutionMetadata as c, RuntimeResourceReleaseEvent as d, RuntimeServiceAcquireEvent as f, LayerGeneratorYieldError as g, LayerDisposeError as h, RuntimeRunOptions as i, OverrideLayerResult as j, LayerResult as k, RuntimeExecutionStartEvent as l, DuplicateServiceError as m, RuntimeDisposeOptions as n, RuntimeExecutionAttributes as o, RuntimeServiceResolveEvent as p, RuntimeOptions as r, RuntimeExecutionEndEvent as s, CleanupFailureObserver as t, RuntimeObserver as u, ServiceTagCollisionError as v, CompleteExecutionLayer as w, Layer as x, LayerBackend as y, MissingDependencies as z };
|
|
442
|
+
//# sourceMappingURL=outcome-CB43bnFW.d.mts.map
|