better-effect 0.11.0 → 0.13.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 +544 -10
- package/dist/adapters/iti.d.mts +3 -2
- package/dist/adapters/iti.d.mts.map +1 -1
- package/dist/adapters/iti.mjs +11 -10
- package/dist/adapters/iti.mjs.map +1 -1
- package/dist/bun.d.mts +43 -0
- package/dist/bun.d.mts.map +1 -0
- package/dist/bun.mjs +40 -0
- package/dist/bun.mjs.map +1 -0
- package/dist/{context-BUEf1qjL.mjs → context-BphfFUMO.mjs} +4 -2
- package/dist/context-BphfFUMO.mjs.map +1 -0
- package/dist/current-request-CIU7AHhF.d.mts +22 -0
- package/dist/current-request-CIU7AHhF.d.mts.map +1 -0
- package/dist/current-request-DDKNyymv.mjs +20 -0
- package/dist/current-request-DDKNyymv.mjs.map +1 -0
- package/dist/disposable-CP-Q2H3l.mjs +57 -0
- package/dist/disposable-CP-Q2H3l.mjs.map +1 -0
- package/dist/{effect-2ZcGZI8A.mjs → effect-CPdV7Yv8.mjs} +56 -10
- package/dist/effect-CPdV7Yv8.mjs.map +1 -0
- package/dist/hono.d.mts +7 -5
- package/dist/hono.d.mts.map +1 -1
- package/dist/hono.mjs +88 -30
- package/dist/hono.mjs.map +1 -1
- package/dist/{index-heuaRmXR.d.mts → index-AiKM71-u.d.mts} +3 -1
- package/dist/{index-heuaRmXR.d.mts.map → index-AiKM71-u.d.mts.map} +1 -1
- package/dist/index-BodMy6rO.d.mts +180 -0
- package/dist/index-BodMy6rO.d.mts.map +1 -0
- package/dist/{index-C7Qild0_.d.mts → index-CCi07kUw.d.mts} +15 -151
- package/dist/index-CCi07kUw.d.mts.map +1 -0
- package/dist/index-DAKn0qHk.d.mts +19 -0
- package/dist/index-DAKn0qHk.d.mts.map +1 -0
- package/dist/{index-DStz0JMN.d.mts → index-cXgyMa0v.d.mts} +75 -22
- package/dist/index-cXgyMa0v.d.mts.map +1 -0
- package/dist/index.d.mts +7 -4
- package/dist/index.mjs +8 -6
- 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-B97cs85Z.mjs → layer-D16GKxuX.mjs} +31 -112
- package/dist/layer-D16GKxuX.mjs.map +1 -0
- package/dist/next.d.mts +116 -0
- package/dist/next.d.mts.map +1 -0
- package/dist/next.mjs +68 -0
- package/dist/next.mjs.map +1 -0
- package/dist/node-context-Ca18oNSg.mjs +25 -0
- package/dist/node-context-Ca18oNSg.mjs.map +1 -0
- package/dist/node-context-DczjAcrX.d.mts +12 -0
- package/dist/node-context-DczjAcrX.d.mts.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/observer-9nhbL7Pr.d.mts +68 -0
- package/dist/observer-9nhbL7Pr.d.mts.map +1 -0
- package/dist/opentelemetry.d.mts +94 -0
- package/dist/opentelemetry.d.mts.map +1 -0
- package/dist/opentelemetry.mjs +453 -0
- package/dist/opentelemetry.mjs.map +1 -0
- package/dist/{index-rQhZk3Nt.d.mts → outcome-DI8LPIQ4.d.mts} +27 -72
- package/dist/outcome-DI8LPIQ4.d.mts.map +1 -0
- package/dist/{scope-GGnmTQck.mjs → program-metadata-BxjGkT17.mjs} +19 -4
- package/dist/program-metadata-BxjGkT17.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/explicit.mjs +1 -1
- package/dist/runtime/node.d.mts +3 -12
- package/dist/runtime/node.mjs +2 -24
- package/dist/{runtime-DnMn0X0X.mjs → runtime-C_55ofnL.mjs} +245 -67
- package/dist/runtime-C_55ofnL.mjs.map +1 -0
- package/dist/signal-nfgFyNCk.mjs +52 -0
- package/dist/signal-nfgFyNCk.mjs.map +1 -0
- package/dist/{standard-services-BFBq-4lo.mjs → standard-services-vnGIafkS.mjs} +200 -30
- package/dist/standard-services-vnGIafkS.mjs.map +1 -0
- package/dist/standard-services.d.mts +4 -3
- package/dist/standard-services.mjs +4 -3
- package/dist/testing.d.mts +67 -7
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.mjs +192 -9
- package/dist/testing.mjs.map +1 -1
- package/dist/types-oihI-ESv.d.mts +54 -0
- package/dist/types-oihI-ESv.d.mts.map +1 -0
- package/dist/web-Bq3MfMrj.mjs +147 -0
- package/dist/web-Bq3MfMrj.mjs.map +1 -0
- package/dist/web.d.mts +47 -0
- package/dist/web.d.mts.map +1 -0
- package/dist/web.mjs +2 -0
- package/package.json +39 -3
- package/dist/context-BUEf1qjL.mjs.map +0 -1
- package/dist/effect-2ZcGZI8A.mjs.map +0 -1
- package/dist/errors-Dnjhzbt0.mjs +0 -99
- package/dist/errors-Dnjhzbt0.mjs.map +0 -1
- package/dist/index-C7Qild0_.d.mts.map +0 -1
- package/dist/index-DStz0JMN.d.mts.map +0 -1
- package/dist/index-rQhZk3Nt.d.mts.map +0 -1
- package/dist/internal-identity-DmUpBeeL.mjs.map +0 -1
- package/dist/runtime/node.d.mts.map +0 -1
- package/dist/runtime/node.mjs.map +0 -1
- package/dist/runtime-DnMn0X0X.mjs.map +0 -1
- package/dist/scope-GGnmTQck.mjs.map +0 -1
- package/dist/signal-B97cs85Z.mjs.map +0 -1
- package/dist/standard-services-BFBq-4lo.mjs.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { t as CurrentAbortSignal } from "./signal-
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { t as CurrentAbortSignal } from "./signal-nfgFyNCk.mjs";
|
|
2
|
+
import { n as CurrentRequestLayer, t as CurrentRequest } from "./current-request-DDKNyymv.mjs";
|
|
3
|
+
import { S as ConfigValidationError, _ as IdGeneratorTestLayer, a as Logger, b as ConfigLive, c as LoggerTestLayer, d as RandomSeeded, f as RandomSeededLayer, g as IdGeneratorTest, h as IdGeneratorLive, i as ClockTestLayer, l as Random, m as IdGeneratorExhaustedError, n as ClockLive, o as LoggerLive, p as IdGenerator, r as ClockTest, s as LoggerTest, t as Clock, u as RandomLive, v as IdGeneratorUnavailableError, x as ConfigSourceError, y as Config } from "./standard-services-vnGIafkS.mjs";
|
|
4
|
+
export { Clock, ClockLive, ClockTest, ClockTestLayer, Config, ConfigLive, ConfigSourceError, ConfigValidationError, CurrentAbortSignal, CurrentRequest, CurrentRequestLayer, IdGenerator, IdGeneratorExhaustedError, IdGeneratorLive, IdGeneratorTest, IdGeneratorTestLayer, IdGeneratorUnavailableError, Logger, LoggerLive, LoggerTest, LoggerTestLayer, Random, RandomLive, RandomSeeded, RandomSeededLayer };
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { M as AnyService, c as RuntimeContextStorage } from "./index-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { M as AnyService, c as RuntimeContextStorage } from "./index-AiKM71-u.mjs";
|
|
2
|
+
import { C as OverrideLayerResult, E as ValidateLayerInput, O as ValidateOverrides, T as RequiredEnvironment, b as LayerInputState, d as LayerBackend, g as CompleteExecutionLayer, h as CompleteExecution, i as RuntimeRunOptions, j as MissingDependencies, k as ValidateOverridesWitness, n as RuntimeDisposeOptions, r as RuntimeOptions, w as ProvidedEnvironment, y as LayerInput } from "./outcome-DI8LPIQ4.mjs";
|
|
3
|
+
import { a as RuntimeObserver, c as RuntimeServiceResolveEvent, i as RuntimeExecutionStartEvent, n as RuntimeExecutionEndEvent, o as RuntimeResourceReleaseEvent, s as RuntimeServiceAcquireEvent } from "./observer-9nhbL7Pr.mjs";
|
|
4
|
+
import { t as MapLayerBackend } from "./index-DAKn0qHk.mjs";
|
|
5
|
+
import { l as Runtime } from "./index-BodMy6rO.mjs";
|
|
6
|
+
import { f as LoggerTest, g as RandomSeeded, i as ClockTest, x as IdGeneratorTest } from "./index-cXgyMa0v.mjs";
|
|
5
7
|
//#region src/testing/contracts.d.ts
|
|
6
8
|
/** One runner-neutral conformance scenario. */
|
|
7
9
|
interface ContractScenario {
|
|
@@ -95,6 +97,59 @@ declare class RecordedRuntimeObserver implements RuntimeObserver {
|
|
|
95
97
|
private record;
|
|
96
98
|
}
|
|
97
99
|
//#endregion
|
|
100
|
+
//#region src/testing/runtime-graph-observer.d.ts
|
|
101
|
+
/** One logical Service node in a Runtime graph snapshot. */
|
|
102
|
+
type RuntimeGraphNode = {
|
|
103
|
+
readonly tag: string;
|
|
104
|
+
readonly resolutions: number;
|
|
105
|
+
readonly acquisitions: number;
|
|
106
|
+
readonly failures: number;
|
|
107
|
+
};
|
|
108
|
+
/** One observed parent-to-child Service edge in a Runtime graph snapshot. */
|
|
109
|
+
type RuntimeGraphEdge = {
|
|
110
|
+
readonly from: string;
|
|
111
|
+
readonly to: string;
|
|
112
|
+
readonly resolutions: number;
|
|
113
|
+
};
|
|
114
|
+
/** Detached, sorted and immutable Runtime graph data. */
|
|
115
|
+
type RuntimeGraphSnapshot = {
|
|
116
|
+
readonly nodes: readonly RuntimeGraphNode[];
|
|
117
|
+
readonly edges: readonly RuntimeGraphEdge[];
|
|
118
|
+
};
|
|
119
|
+
/** Options for a diagnostic Runtime graph observer. */
|
|
120
|
+
type RuntimeGraphObserverOptions = {
|
|
121
|
+
/** Count failed resolution and acquisition events in each node's failures field. */
|
|
122
|
+
readonly includeFailures?: boolean;
|
|
123
|
+
/** Add this label as a synthetic root in Mermaid output for top-level resolutions. */
|
|
124
|
+
readonly rootLabel?: string;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Observe the public Runtime resolution and acquisition events as a diagnostic graph.
|
|
128
|
+
*
|
|
129
|
+
* The graph is deliberately an observation of paths emitted by Runtime. It does
|
|
130
|
+
* not inspect Layer provenance, retain Service instances, or plan dependencies.
|
|
131
|
+
*/
|
|
132
|
+
declare class RuntimeGraphObserver implements RuntimeObserver {
|
|
133
|
+
private readonly includeFailures;
|
|
134
|
+
private readonly rootLabel;
|
|
135
|
+
private readonly nodes;
|
|
136
|
+
private readonly edges;
|
|
137
|
+
private readonly rootEdges;
|
|
138
|
+
private constructor();
|
|
139
|
+
/** Create an empty Runtime graph observer. */
|
|
140
|
+
static make(options?: RuntimeGraphObserverOptions): RuntimeGraphObserver;
|
|
141
|
+
readonly onServiceResolve: (event: RuntimeServiceResolveEvent) => void;
|
|
142
|
+
readonly onServiceAcquire: (event: RuntimeServiceAcquireEvent) => void;
|
|
143
|
+
/** Return a fresh, deeply detached and sorted graph snapshot. */
|
|
144
|
+
toJSON(): RuntimeGraphSnapshot;
|
|
145
|
+
/** Render the current graph as deterministic Mermaid flowchart source. */
|
|
146
|
+
toMermaid(): string;
|
|
147
|
+
/** Discard all observed graph data while keeping this observer reusable. */
|
|
148
|
+
clear(): void;
|
|
149
|
+
private ensureNode;
|
|
150
|
+
private ensurePath;
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
98
153
|
//#region src/testing/test-runtime.d.ts
|
|
99
154
|
declare const TestRuntimeOptionsOverridesTypeId: unique symbol;
|
|
100
155
|
type ValidatedTestServiceOption<Base extends LayerInput, Overrides extends readonly LayerInput[], Replacement extends LayerInput, Value> = Value & ValidateOverridesWitness<Base, readonly [...Overrides, Replacement]>;
|
|
@@ -110,6 +165,8 @@ type TestRuntimeOptions<Base extends LayerInput = LayerInput, Overrides extends
|
|
|
110
165
|
readonly logger?: ValidatedTestServiceOption<Base, Overrides, LoggerTestLayer, LoggerTest>;
|
|
111
166
|
/** Seeded Random provider to install for this TestRuntime. */
|
|
112
167
|
readonly random?: ValidatedTestServiceOption<Base, Overrides, RandomSeededLayer, RandomSeeded>;
|
|
168
|
+
/** Deterministic IdGenerator provider to install for this TestRuntime. */
|
|
169
|
+
readonly idGenerator?: ValidatedTestServiceOption<Base, Overrides, IdGeneratorTestLayer, IdGeneratorTest>;
|
|
113
170
|
/** Additional best-effort observers after the default recorder. */
|
|
114
171
|
readonly observers?: readonly RuntimeObserver[];
|
|
115
172
|
} & {
|
|
@@ -118,20 +175,22 @@ type TestRuntimeOptions<Base extends LayerInput = LayerInput, Overrides extends
|
|
|
118
175
|
type ClockTestLayer = ReturnType<typeof ClockTest.layer>;
|
|
119
176
|
type LoggerTestLayer = ReturnType<typeof LoggerTest.layer>;
|
|
120
177
|
type RandomSeededLayer = ReturnType<typeof RandomSeeded.layer>;
|
|
178
|
+
type IdGeneratorTestLayer = ReturnType<typeof IdGeneratorTest.layer>;
|
|
121
179
|
type TestRuntimeOptionsInput = Omit<RuntimeOptions, 'backend' | 'observers'> & {
|
|
122
180
|
readonly overrides?: readonly LayerInput[];
|
|
123
181
|
readonly backend?: LayerBackend;
|
|
124
182
|
readonly clock?: ClockTest;
|
|
125
183
|
readonly logger?: LoggerTest;
|
|
126
184
|
readonly random?: RandomSeeded;
|
|
185
|
+
readonly idGenerator?: IdGeneratorTest;
|
|
127
186
|
readonly observers?: readonly RuntimeObserver[];
|
|
128
187
|
};
|
|
129
188
|
type ExplicitOverrides<Options extends TestRuntimeOptionsInput> = typeof TestRuntimeOptionsOverridesTypeId extends keyof Options ? Exclude<Options[typeof TestRuntimeOptionsOverridesTypeId], undefined> extends (infer Overrides extends readonly LayerInput[]) ? Overrides : readonly [] : Exclude<Options['overrides'], undefined> extends (infer Overrides extends readonly LayerInput[]) ? Overrides : readonly [];
|
|
130
189
|
type HasDefinedOption<Options, Key extends PropertyKey> = true extends (Options extends unknown ? Key extends keyof Options ? {} extends Pick<Options, Key> ? false : undefined extends Options[Key] ? false : true : false : never) ? true : false;
|
|
131
190
|
type HasPotentialOption<Options, Key extends PropertyKey> = true extends (Options extends unknown ? Key extends keyof Options ? [Exclude<Options[Key], undefined>] extends [never] ? false : true : false : never) ? true : false;
|
|
132
191
|
type HasGuaranteedOption<Options, Key extends PropertyKey> = [Options] extends [never] ? false : false extends (Options extends unknown ? HasDefinedOption<Options, Key> : never) ? false : true;
|
|
133
|
-
type TestRuntimeOptionLayers<Options extends TestRuntimeOptionsInput> = [...ExplicitOverrides<Options>, ...(HasGuaranteedOption<Options, 'clock'> extends true ? [ClockTestLayer] : []), ...(HasGuaranteedOption<Options, 'logger'> extends true ? [LoggerTestLayer] : []), ...(HasGuaranteedOption<Options, 'random'> extends true ? [RandomSeededLayer] : [])];
|
|
134
|
-
type TestRuntimeValidationLayers<Options extends TestRuntimeOptionsInput> = [...ExplicitOverrides<Options>, ...(HasPotentialOption<Options, 'clock'> extends true ? [ClockTestLayer] : []), ...(HasPotentialOption<Options, 'logger'> extends true ? [LoggerTestLayer] : []), ...(HasPotentialOption<Options, 'random'> extends true ? [RandomSeededLayer] : [])];
|
|
192
|
+
type TestRuntimeOptionLayers<Options extends TestRuntimeOptionsInput> = [...ExplicitOverrides<Options>, ...(HasGuaranteedOption<Options, 'clock'> extends true ? [ClockTestLayer] : []), ...(HasGuaranteedOption<Options, 'logger'> extends true ? [LoggerTestLayer] : []), ...(HasGuaranteedOption<Options, 'random'> extends true ? [RandomSeededLayer] : []), ...(HasGuaranteedOption<Options, 'idGenerator'> extends true ? [IdGeneratorTestLayer] : [])];
|
|
193
|
+
type TestRuntimeValidationLayers<Options extends TestRuntimeOptionsInput> = [...ExplicitOverrides<Options>, ...(HasPotentialOption<Options, 'clock'> extends true ? [ClockTestLayer] : []), ...(HasPotentialOption<Options, 'logger'> extends true ? [LoggerTestLayer] : []), ...(HasPotentialOption<Options, 'random'> extends true ? [RandomSeededLayer] : []), ...(HasPotentialOption<Options, 'idGenerator'> extends true ? [IdGeneratorTestLayer] : [])];
|
|
135
194
|
type TestRuntimeLayer<Base extends LayerInput, Options extends TestRuntimeOptionsInput> = OverrideLayerResult<Base, TestRuntimeOptionLayers<Options>>;
|
|
136
195
|
type TestRuntimeOptionsValidation<Base extends LayerInput, Options extends TestRuntimeOptionsInput> = (Options extends {
|
|
137
196
|
readonly overrides?: infer Overrides extends readonly LayerInput[];
|
|
@@ -162,6 +221,7 @@ declare class TestRuntime<Provided extends AnyService = any, Options extends obj
|
|
|
162
221
|
readonly clock: ConfiguredService<Options, 'clock', ClockTest>;
|
|
163
222
|
readonly logger: ConfiguredService<Options, 'logger', LoggerTest>;
|
|
164
223
|
readonly random: ConfiguredService<Options, 'random', RandomSeeded>;
|
|
224
|
+
readonly idGenerator: ConfiguredService<Options, 'idGenerator', IdGeneratorTest>;
|
|
165
225
|
private disposalPromise;
|
|
166
226
|
private constructor();
|
|
167
227
|
/** Create a TestRuntime with a fresh backend and default lifecycle recorder. */
|
|
@@ -194,5 +254,5 @@ declare namespace TestRuntime {
|
|
|
194
254
|
type DisposeOptions = RuntimeDisposeOptions;
|
|
195
255
|
}
|
|
196
256
|
//#endregion
|
|
197
|
-
export { ClockTest, ConformanceError, type ContextConcurrency, type ContractScenario, type LayerBackendAcquisitionFailure, type LayerBackendContractOptions, LoggerTest, MapLayerBackend as MemoryLayerBackend, RandomSeeded, RecordedRuntimeObserver, type RecordedRuntimeObserverSnapshot, type RuntimeContextStorageContractOptions, RuntimeObserver, type RuntimeObserverEvent, TestRuntime, TestRuntimeObserverError, type TestRuntimeOptions, layerBackendContract, runtimeContextStorageContract };
|
|
257
|
+
export { ClockTest, ConformanceError, type ContextConcurrency, type ContractScenario, IdGeneratorTest, type LayerBackendAcquisitionFailure, type LayerBackendContractOptions, LoggerTest, MapLayerBackend as MemoryLayerBackend, RandomSeeded, RecordedRuntimeObserver, type RecordedRuntimeObserverSnapshot, type RuntimeContextStorageContractOptions, type RuntimeGraphEdge, type RuntimeGraphNode, RuntimeGraphObserver, type RuntimeGraphObserverOptions, type RuntimeGraphSnapshot, RuntimeObserver, type RuntimeObserverEvent, TestRuntime, TestRuntimeObserverError, type TestRuntimeOptions, layerBackendContract, runtimeContextStorageContract };
|
|
198
258
|
//# sourceMappingURL=testing.d.mts.map
|
package/dist/testing.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.mts","names":[],"sources":["../src/testing/contracts.ts","../src/testing/recorded-runtime-observer.ts","../src/testing/test-runtime.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"testing.d.mts","names":[],"sources":["../src/testing/contracts.ts","../src/testing/recorded-runtime-observer.ts","../src/testing/runtime-graph-observer.ts","../src/testing/test-runtime.ts"],"mappings":"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"}
|
package/dist/testing.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as RuntimeContextOverlapError, h as RuntimeContextNotConfiguredError } from "./context-
|
|
1
|
+
import { i as LayerDisposeError, r as DuplicateServiceError, s as ServiceTagCollisionError, u as ServiceNotFoundError } from "./registration-drnZk0SY.mjs";
|
|
2
|
+
import { g as RuntimeContextOverlapError, h as RuntimeContextNotConfiguredError } from "./context-BphfFUMO.mjs";
|
|
3
3
|
import { t as isPromiseLike } from "./runtime-CDcCF5cb.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { r as
|
|
6
|
-
import { i as
|
|
7
|
-
import {
|
|
4
|
+
import { a as ScopeClosedError, i as ScopeCloseError } from "./disposable-CP-Q2H3l.mjs";
|
|
5
|
+
import { n as Service, r as ServiceRuntime, t as Layer } from "./layer-D16GKxuX.mjs";
|
|
6
|
+
import { i as Scope, o as ScopeRuntime } from "./program-metadata-BxjGkT17.mjs";
|
|
7
|
+
import { i as MapLayerBackend, n as RuntimeObserver, r as classifyRuntimeOutcome, t as Runtime } from "./runtime-C_55ofnL.mjs";
|
|
8
|
+
import { a as Logger, d as RandomSeeded, g as IdGeneratorTest, l as Random, p as IdGenerator, r as ClockTest, s as LoggerTest, t as Clock } from "./standard-services-vnGIafkS.mjs";
|
|
8
9
|
//#region src/testing/contracts.ts
|
|
9
10
|
/** Thrown by a conformance scenario when an adapter violates its contract. */
|
|
10
11
|
var ConformanceError = class extends Error {
|
|
@@ -809,6 +810,185 @@ var RecordedRuntimeObserver = class RecordedRuntimeObserver {
|
|
|
809
810
|
}
|
|
810
811
|
};
|
|
811
812
|
//#endregion
|
|
813
|
+
//#region src/testing/runtime-graph-observer.ts
|
|
814
|
+
const compareStrings = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
815
|
+
const compareEdges = (left, right) => compareStrings(left.from, right.from) || compareStrings(left.to, right.to);
|
|
816
|
+
const freezeNode = (node) => Object.freeze({ ...node });
|
|
817
|
+
const freezeEdge = (edge) => Object.freeze({ ...edge });
|
|
818
|
+
const serviceTags = (path, targetTag) => {
|
|
819
|
+
const tags = path.map((service) => service.serviceTag);
|
|
820
|
+
if (tags[tags.length - 1] !== targetTag) tags.push(targetTag);
|
|
821
|
+
return tags;
|
|
822
|
+
};
|
|
823
|
+
const mermaidLabelPunctuation = /* @__PURE__ */ new Set([
|
|
824
|
+
"&",
|
|
825
|
+
"\"",
|
|
826
|
+
"'",
|
|
827
|
+
"\\",
|
|
828
|
+
"[",
|
|
829
|
+
"]",
|
|
830
|
+
"(",
|
|
831
|
+
")",
|
|
832
|
+
"{",
|
|
833
|
+
"}",
|
|
834
|
+
"|",
|
|
835
|
+
"#",
|
|
836
|
+
";",
|
|
837
|
+
":",
|
|
838
|
+
"<",
|
|
839
|
+
">",
|
|
840
|
+
"=",
|
|
841
|
+
"`",
|
|
842
|
+
"*",
|
|
843
|
+
"_",
|
|
844
|
+
"~",
|
|
845
|
+
"!",
|
|
846
|
+
"^",
|
|
847
|
+
"$"
|
|
848
|
+
]);
|
|
849
|
+
const isMermaidLabelControl = (character, codePoint) => codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint >= 55296 && codePoint <= 57343 || /\s/u.test(character) && character !== " " || /\p{Cf}/u.test(character);
|
|
850
|
+
/**
|
|
851
|
+
* Escape Mermaid syntax while keeping the decoded label readable.
|
|
852
|
+
*
|
|
853
|
+
* Mermaid's documented `#number;` form is a syntax-level escape. Encoding the
|
|
854
|
+
* entity introducers themselves prevents label text from creating a second
|
|
855
|
+
* entity, while encoding Markdown and HTML punctuation keeps it out of the
|
|
856
|
+
* renderer's interpretation paths.
|
|
857
|
+
*/
|
|
858
|
+
const escapeMermaidLabel = (label) => {
|
|
859
|
+
let escaped = "";
|
|
860
|
+
for (const character of label) {
|
|
861
|
+
const codePoint = character.codePointAt(0);
|
|
862
|
+
if (codePoint === void 0) continue;
|
|
863
|
+
if (isMermaidLabelControl(character, codePoint) || mermaidLabelPunctuation.has(character)) escaped += `#${codePoint};`;
|
|
864
|
+
else escaped += character;
|
|
865
|
+
}
|
|
866
|
+
return escaped;
|
|
867
|
+
};
|
|
868
|
+
/** Encode a string as a Mermaid-safe, injective and registration-order-independent ID. */
|
|
869
|
+
const mermaidId = (prefix, value) => {
|
|
870
|
+
const codeUnits = [];
|
|
871
|
+
for (let index = 0; index < value.length; index += 1) codeUnits.push(value.charCodeAt(index).toString(16).padStart(4, "0"));
|
|
872
|
+
return `${prefix}${codeUnits.join("_") || "empty"}`;
|
|
873
|
+
};
|
|
874
|
+
/**
|
|
875
|
+
* Observe the public Runtime resolution and acquisition events as a diagnostic graph.
|
|
876
|
+
*
|
|
877
|
+
* The graph is deliberately an observation of paths emitted by Runtime. It does
|
|
878
|
+
* not inspect Layer provenance, retain Service instances, or plan dependencies.
|
|
879
|
+
*/
|
|
880
|
+
var RuntimeGraphObserver = class RuntimeGraphObserver {
|
|
881
|
+
includeFailures;
|
|
882
|
+
rootLabel;
|
|
883
|
+
nodes = /* @__PURE__ */ new Map();
|
|
884
|
+
edges = /* @__PURE__ */ new Map();
|
|
885
|
+
rootEdges = /* @__PURE__ */ new Map();
|
|
886
|
+
constructor(includeFailures, rootLabel) {
|
|
887
|
+
this.includeFailures = includeFailures;
|
|
888
|
+
this.rootLabel = rootLabel;
|
|
889
|
+
}
|
|
890
|
+
/** Create an empty Runtime graph observer. */
|
|
891
|
+
static make(options = {}) {
|
|
892
|
+
if (typeof options !== "object" || options === null) throw new TypeError("RuntimeGraphObserver options must be an object");
|
|
893
|
+
if (options.includeFailures !== void 0 && typeof options.includeFailures !== "boolean") throw new TypeError("RuntimeGraphObserver includeFailures must be a boolean");
|
|
894
|
+
if (options.rootLabel !== void 0 && typeof options.rootLabel !== "string") throw new TypeError("RuntimeGraphObserver rootLabel must be a string");
|
|
895
|
+
return new RuntimeGraphObserver(options.includeFailures ?? true, options.rootLabel);
|
|
896
|
+
}
|
|
897
|
+
onServiceResolve = (event) => {
|
|
898
|
+
const targetTag = event.service.serviceTag;
|
|
899
|
+
const path = serviceTags(event.resolutionPath, targetTag);
|
|
900
|
+
const node = this.ensureNode(targetTag);
|
|
901
|
+
this.ensurePath(path);
|
|
902
|
+
node.resolutions += 1;
|
|
903
|
+
if (event.outcome.status === "failure" && this.includeFailures) node.failures += 1;
|
|
904
|
+
const parentTag = path[path.length - 2];
|
|
905
|
+
if (parentTag === void 0) {
|
|
906
|
+
if (this.rootLabel !== void 0) this.rootEdges.set(targetTag, (this.rootEdges.get(targetTag) ?? 0) + 1);
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
const targets = this.edges.get(parentTag) ?? /* @__PURE__ */ new Map();
|
|
910
|
+
const edge = targets.get(targetTag) ?? (() => {
|
|
911
|
+
const created = {
|
|
912
|
+
from: parentTag,
|
|
913
|
+
to: targetTag,
|
|
914
|
+
resolutions: 0
|
|
915
|
+
};
|
|
916
|
+
targets.set(targetTag, created);
|
|
917
|
+
return created;
|
|
918
|
+
})();
|
|
919
|
+
edge.resolutions += 1;
|
|
920
|
+
this.edges.set(parentTag, targets);
|
|
921
|
+
};
|
|
922
|
+
onServiceAcquire = (event) => {
|
|
923
|
+
const targetTag = event.service.serviceTag;
|
|
924
|
+
const path = serviceTags(event.resolutionPath, targetTag);
|
|
925
|
+
const node = this.ensureNode(targetTag);
|
|
926
|
+
this.ensurePath(path);
|
|
927
|
+
node.acquisitions += 1;
|
|
928
|
+
if (event.outcome.status === "failure" && this.includeFailures) node.failures += 1;
|
|
929
|
+
};
|
|
930
|
+
/** Return a fresh, deeply detached and sorted graph snapshot. */
|
|
931
|
+
toJSON() {
|
|
932
|
+
const nodes = Object.freeze([...this.nodes.entries()].sort(([left], [right]) => compareStrings(left, right)).map(([tag, counters]) => freezeNode({
|
|
933
|
+
tag,
|
|
934
|
+
resolutions: counters.resolutions,
|
|
935
|
+
acquisitions: counters.acquisitions,
|
|
936
|
+
failures: counters.failures
|
|
937
|
+
})));
|
|
938
|
+
const edges = Object.freeze([...this.edges.values()].flatMap((targets) => [...targets.values()]).map((edge) => freezeEdge({ ...edge })).sort(compareEdges));
|
|
939
|
+
return Object.freeze({
|
|
940
|
+
nodes,
|
|
941
|
+
edges
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
/** Render the current graph as deterministic Mermaid flowchart source. */
|
|
945
|
+
toMermaid() {
|
|
946
|
+
const snapshot = this.toJSON();
|
|
947
|
+
const serviceIds = new Map(snapshot.nodes.map((node) => [node.tag, mermaidId("service_", node.tag)]));
|
|
948
|
+
const lines = ["flowchart TD"];
|
|
949
|
+
const rootTargets = [...this.rootEdges.entries()].sort(([left], [right]) => compareStrings(left, right));
|
|
950
|
+
const root = this.rootLabel !== void 0 && rootTargets.length > 0 ? {
|
|
951
|
+
id: mermaidId("root_", this.rootLabel),
|
|
952
|
+
label: this.rootLabel
|
|
953
|
+
} : void 0;
|
|
954
|
+
if (root !== void 0) lines.push(` ${root.id}["${escapeMermaidLabel(root.label)}"]`);
|
|
955
|
+
for (const node of snapshot.nodes) {
|
|
956
|
+
const id = serviceIds.get(node.tag);
|
|
957
|
+
if (id !== void 0) lines.push(` ${id}["${escapeMermaidLabel(node.tag)}"]`);
|
|
958
|
+
}
|
|
959
|
+
if (root !== void 0) for (const [targetTag, resolutions] of rootTargets) {
|
|
960
|
+
const targetId = serviceIds.get(targetTag);
|
|
961
|
+
if (targetId !== void 0) lines.push(` ${root.id} -->|${resolutions}| ${targetId}`);
|
|
962
|
+
}
|
|
963
|
+
for (const edge of snapshot.edges) {
|
|
964
|
+
const fromId = serviceIds.get(edge.from);
|
|
965
|
+
const toId = serviceIds.get(edge.to);
|
|
966
|
+
if (fromId !== void 0 && toId !== void 0) lines.push(` ${fromId} -->|${edge.resolutions}| ${toId}`);
|
|
967
|
+
}
|
|
968
|
+
return lines.join("\n");
|
|
969
|
+
}
|
|
970
|
+
/** Discard all observed graph data while keeping this observer reusable. */
|
|
971
|
+
clear() {
|
|
972
|
+
this.nodes.clear();
|
|
973
|
+
this.edges.clear();
|
|
974
|
+
this.rootEdges.clear();
|
|
975
|
+
}
|
|
976
|
+
ensureNode(tag) {
|
|
977
|
+
const existing = this.nodes.get(tag);
|
|
978
|
+
if (existing !== void 0) return existing;
|
|
979
|
+
const node = {
|
|
980
|
+
resolutions: 0,
|
|
981
|
+
acquisitions: 0,
|
|
982
|
+
failures: 0
|
|
983
|
+
};
|
|
984
|
+
this.nodes.set(tag, node);
|
|
985
|
+
return node;
|
|
986
|
+
}
|
|
987
|
+
ensurePath(path) {
|
|
988
|
+
for (const tag of path) this.ensureNode(tag);
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
//#endregion
|
|
812
992
|
//#region src/testing/test-runtime.ts
|
|
813
993
|
/**
|
|
814
994
|
* Thrown when the TestRuntime recorder contains an execution start or end
|
|
@@ -836,13 +1016,15 @@ var TestRuntime = class TestRuntime {
|
|
|
836
1016
|
clock;
|
|
837
1017
|
logger;
|
|
838
1018
|
random;
|
|
1019
|
+
idGenerator;
|
|
839
1020
|
disposalPromise;
|
|
840
|
-
constructor(runtime, observer, clock, logger, random) {
|
|
1021
|
+
constructor(runtime, observer, clock, logger, random, idGenerator) {
|
|
841
1022
|
this.runtime = runtime;
|
|
842
1023
|
this.observer = observer;
|
|
843
1024
|
this.clock = clock;
|
|
844
1025
|
this.logger = logger;
|
|
845
1026
|
this.random = random;
|
|
1027
|
+
this.idGenerator = idGenerator;
|
|
846
1028
|
}
|
|
847
1029
|
static async make(layer, options) {
|
|
848
1030
|
const resolvedOptions = options === void 0 ? {} : options;
|
|
@@ -858,7 +1040,7 @@ var TestRuntime = class TestRuntime {
|
|
|
858
1040
|
};
|
|
859
1041
|
const typedLayer = composedLayer;
|
|
860
1042
|
const runtime = await Runtime.make(typedLayer, runtimeOptions);
|
|
861
|
-
return new TestRuntime(runtime, observer, options.clock, options.logger, options.random);
|
|
1043
|
+
return new TestRuntime(runtime, observer, options.clock, options.logger, options.random, options.idGenerator);
|
|
862
1044
|
}
|
|
863
1045
|
/** Run a fully typechecked program in the underlying Runtime. */
|
|
864
1046
|
run(program, options) {
|
|
@@ -941,6 +1123,7 @@ const composeTestLayer = (layer, options) => {
|
|
|
941
1123
|
if (options.clock !== void 0) overrides.push(Layer.succeed(Clock, options.clock));
|
|
942
1124
|
if (options.logger !== void 0) overrides.push(Layer.succeed(Logger, options.logger));
|
|
943
1125
|
if (options.random !== void 0) overrides.push(Layer.succeed(Random, options.random));
|
|
1126
|
+
if (options.idGenerator !== void 0) overrides.push(Layer.succeed(IdGenerator, options.idGenerator));
|
|
944
1127
|
const typedLayer = layer;
|
|
945
1128
|
const typedOverrides = overrides;
|
|
946
1129
|
return Layer.override(typedLayer, ...typedOverrides);
|
|
@@ -971,6 +1154,6 @@ const countExecutionScopes = (events) => {
|
|
|
971
1154
|
return counts;
|
|
972
1155
|
};
|
|
973
1156
|
//#endregion
|
|
974
|
-
export { ClockTest, ConformanceError, LoggerTest, MapLayerBackend as MemoryLayerBackend, RandomSeeded, RecordedRuntimeObserver, RuntimeObserver, TestRuntime, TestRuntimeObserverError, layerBackendContract, runtimeContextStorageContract };
|
|
1157
|
+
export { ClockTest, ConformanceError, IdGeneratorTest, LoggerTest, MapLayerBackend as MemoryLayerBackend, RandomSeeded, RecordedRuntimeObserver, RuntimeGraphObserver, RuntimeObserver, TestRuntime, TestRuntimeObserverError, layerBackendContract, runtimeContextStorageContract };
|
|
975
1158
|
|
|
976
1159
|
//# sourceMappingURL=testing.mjs.map
|