@overkill-dev/resources 0.0.1 → 0.0.2

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.
Files changed (38) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +32 -6
  3. package/packages/resources/resources.entry-point.d.ts +18 -0
  4. package/packages/resources/resources.entry-point.d.ts.map +1 -0
  5. package/packages/resources/resources.entry-point.js +25 -0
  6. package/packages/resources/resources.entry-point.js.map +1 -0
  7. package/readme.md +127 -5
  8. package/resources/resource-definition-shape.d.ts +53 -0
  9. package/resources/resource-definition-shape.d.ts.map +1 -0
  10. package/resources/resource-graph.d.ts +23 -0
  11. package/resources/resource-graph.d.ts.map +1 -0
  12. package/resources/resource-graph.js +151 -0
  13. package/resources/resource-graph.js.map +1 -0
  14. package/resources/resource-lifecycle-error.d.ts +19 -0
  15. package/resources/resource-lifecycle-error.d.ts.map +1 -0
  16. package/resources/resource-lifecycle-error.js +32 -0
  17. package/resources/resource-lifecycle-error.js.map +1 -0
  18. package/resources/resource-session.d.ts +28 -0
  19. package/resources/resource-session.d.ts.map +1 -0
  20. package/resources/resource-session.js +182 -0
  21. package/resources/resource-session.js.map +1 -0
  22. package/resources/resources.d.ts +149 -0
  23. package/resources/resources.d.ts.map +1 -0
  24. package/resources/resources.js +99 -0
  25. package/resources/resources.js.map +1 -0
  26. package/resources/runtime-definition.d.ts +23 -0
  27. package/resources/runtime-definition.d.ts.map +1 -0
  28. package/resources/runtime-definition.js +19 -0
  29. package/resources/runtime-definition.js.map +1 -0
  30. package/resources/runtime-lifecycle.d.ts +14 -0
  31. package/resources/runtime-lifecycle.d.ts.map +1 -0
  32. package/resources/runtime-lifecycle.js +83 -0
  33. package/resources/runtime-lifecycle.js.map +1 -0
  34. package/resources/runtime-matrix-definition.d.ts +53 -0
  35. package/resources/runtime-matrix-definition.d.ts.map +1 -0
  36. package/resources/runtime-matrix-definition.js +159 -0
  37. package/resources/runtime-matrix-definition.js.map +1 -0
  38. package/sbom.cdx.json +30 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Overkill contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,7 +1,33 @@
1
1
  {
2
- "name": "@overkill-dev/resources",
3
- "version": "0.0.1",
4
- "description": "Placeholder claiming the npm package name \"@overkill-dev/resources\" so a trusted publisher can be configured. See https://github.com/npm/cli/issues/8544.",
5
- "license": "MIT",
6
- "deprecated": "Placeholder published as a workaround so a Trusted Publisher could be configured. See https://github.com/npm/cli/issues/8544."
7
- }
2
+ "author": "Christian Rackerseder <git@echooff.de>",
3
+ "bugs": {
4
+ "url": "https://github.com/enormora/overkill/issues"
5
+ },
6
+ "description": "Typed Overkill resource and runtime descriptors.",
7
+ "engines": {
8
+ "node": "^26.9.0"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "import": "./packages/resources/resources.entry-point.js",
13
+ "types": "./packages/resources/resources.entry-point.d.ts"
14
+ }
15
+ },
16
+ "homepage": "https://github.com/enormora/overkill#readme",
17
+ "keywords": [
18
+ "tdd",
19
+ "test",
20
+ "tests"
21
+ ],
22
+ "license": "MIT",
23
+ "name": "@overkill-dev/resources",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/enormora/overkill.git"
27
+ },
28
+ "sideEffects": [
29
+ "./packages/resources/resources.entry-point.js"
30
+ ],
31
+ "type": "module",
32
+ "version": "0.0.2"
33
+ }
@@ -0,0 +1,18 @@
1
+ import { type ResourcesModule } from '../../resources/resources.ts';
2
+ export declare const composeRuntimeContext: ResourcesModule['composeRuntimeContext'];
3
+ export declare const composeRuntimes: ResourcesModule['composeRuntimes'];
4
+ export declare const createTemporaryDirectoryResource: ResourcesModule['createTemporaryDirectoryResource'];
5
+ export declare const defineResource: ResourcesModule['defineResource'];
6
+ export declare const defineRuntime: ResourcesModule['defineRuntime'];
7
+ export declare const defineRuntimeMatrix: ResourcesModule['defineRuntimeMatrix'];
8
+ export { isDefinedResource, isDefinedRuntime, isDefinedRuntimeGraph, isDefinedRuntimeMatrix, runtimeGraphLeaves } from '../../resources/resources.ts';
9
+ export { assertPerCaseResourceGraph, assertResourceDependencyScopes } from '../../resources/resource-graph.ts';
10
+ export { startResources } from '../../resources/resource-session.ts';
11
+ export { ResourceLifecycleError } from '../../resources/resource-lifecycle-error.ts';
12
+ export { startRuntime } from '../../resources/runtime-lifecycle.ts';
13
+ export type { AnyResourceDefinition, ComposedRuntimeGraph, ExecutionRequirement, ResourceContext, ResourceCreationContext, ResourceDependencies, ResourceDefinition, ResourceDefinitionInput, ResourceDisposalContext, ResourceHandle, ResourceProjectionContext, ResourceProjectionPayload, ResourceScope, RuntimeContext, RuntimeContextComposition, RuntimeDefinition, RuntimeDefinitionInput, RuntimeDimensions, RuntimeGraph, RuntimeGraphLeaf, RuntimeGraphContext, RuntimeId, RuntimeMatrixDefinition, RuntimeMatrixDefinitionInput, RuntimeMatrixVariant, RuntimeMatrixVariantMap, RuntimeResourceMap, RuntimeScopeContext, SharedRuntimeMatrixDefinitionInput, TemporaryDirectoryHandle } from '../../resources/resources.ts';
14
+ export type { RuntimeDefinition as Runtime, RuntimeResourceMap as ResourceMap } from '../../resources/resources.ts';
15
+ export type { ResourceLifecycleFailure, ResourceLifecyclePhase } from '../../resources/resource-lifecycle-error.ts';
16
+ export type { ResourceSession, ResourceSessionDisposalContext, StartResourcesRequest } from '../../resources/resource-session.ts';
17
+ export type { RuntimeSession, RuntimeSessionDisposalContext, StartRuntimeRequest } from '../../resources/runtime-lifecycle.ts';
18
+ //# sourceMappingURL=resources.entry-point.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.entry-point.d.ts","sourceRoot":"","sources":["../../../../../source/packages/resources/resources.entry-point.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAY3F,eAAO,MAAM,qBAAqB,EAAE,eAAe,CAAC,uBAAuB,CAAyC,CAAC;AACrH,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,iBAAiB,CAAmC,CAAC;AACnG,eAAO,MAAM,gCAAgC,EAAE,eAAe,CAAC,kCAAkC,CAC7C,CAAC;AACrD,eAAO,MAAM,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAkC,CAAC;AAChG,eAAO,MAAM,aAAa,EAAE,eAAe,CAAC,eAAe,CAAiC,CAAC;AAC7F,eAAO,MAAM,mBAAmB,EAAE,eAAe,CAAC,qBAAqB,CAAuC,CAAC;AAE/G,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,0BAA0B,EAC1B,8BAA8B,EACjC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACH,cAAc,EACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACH,sBAAsB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACH,YAAY,EACf,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EACR,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,cAAc,EACd,yBAAyB,EACzB,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,kCAAkC,EAClC,wBAAwB,EAC3B,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACR,iBAAiB,IAAI,OAAO,EAC5B,kBAAkB,IAAI,WAAW,EACpC,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACR,wBAAwB,EACxB,sBAAsB,EACzB,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACR,eAAe,EACf,8BAA8B,EAC9B,qBAAqB,EACxB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACR,cAAc,EACd,6BAA6B,EAC7B,mBAAmB,EACtB,MAAM,sCAAsC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { mkdtemp, rm } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { createResourcesModule } from "../../resources/resources.js";
5
+ const resourcesModule = createResourcesModule({
6
+ temporaryDirectoryPathPrefix: join(tmpdir(), 'overkill-temporary-directory-'),
7
+ async createTemporaryDirectory(pathPrefix) {
8
+ return await mkdtemp(pathPrefix);
9
+ },
10
+ async removeDirectory(path) {
11
+ await rm(path, { force: true, recursive: true });
12
+ }
13
+ });
14
+ export const composeRuntimeContext = resourcesModule.composeRuntimeContext;
15
+ export const composeRuntimes = resourcesModule.composeRuntimes;
16
+ export const createTemporaryDirectoryResource = resourcesModule.createTemporaryDirectoryResource;
17
+ export const defineResource = resourcesModule.defineResource;
18
+ export const defineRuntime = resourcesModule.defineRuntime;
19
+ export const defineRuntimeMatrix = resourcesModule.defineRuntimeMatrix;
20
+ export { isDefinedResource, isDefinedRuntime, isDefinedRuntimeGraph, isDefinedRuntimeMatrix, runtimeGraphLeaves } from "../../resources/resources.js";
21
+ export { assertPerCaseResourceGraph, assertResourceDependencyScopes } from "../../resources/resource-graph.js";
22
+ export { startResources } from "../../resources/resource-session.js";
23
+ export { ResourceLifecycleError } from "../../resources/resource-lifecycle-error.js";
24
+ export { startRuntime } from "../../resources/runtime-lifecycle.js";
25
+ //# sourceMappingURL=resources.entry-point.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.entry-point.js","sourceRoot":"","sources":["../../../../../source/packages/resources/resources.entry-point.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAwB,MAAM,8BAA8B,CAAC;AAE3F,MAAM,eAAe,GAAG,qBAAqB,CAAC;IAC1C,4BAA4B,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,+BAA+B,CAAC;IAC7E,KAAK,CAAC,wBAAwB,CAAC,UAAU;QACrC,OAAO,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,IAAI;QACtB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAA6C,eAAe,CAAC,qBAAqB,CAAC;AACrH,MAAM,CAAC,MAAM,eAAe,GAAuC,eAAe,CAAC,eAAe,CAAC;AACnG,MAAM,CAAC,MAAM,gCAAgC,GACzC,eAAe,CAAC,gCAAgC,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAsC,eAAe,CAAC,cAAc,CAAC;AAChG,MAAM,CAAC,MAAM,aAAa,GAAqC,eAAe,CAAC,aAAa,CAAC;AAC7F,MAAM,CAAC,MAAM,mBAAmB,GAA2C,eAAe,CAAC,mBAAmB,CAAC;AAE/G,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EACrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,0BAA0B,EAC1B,8BAA8B,EACjC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACH,cAAc,EACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACH,sBAAsB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACH,YAAY,EACf,MAAM,sCAAsC,CAAC"}
package/readme.md CHANGED
@@ -1,7 +1,129 @@
1
- # @overkill-dev/resources
1
+ # `@overkill-dev/resources`
2
2
 
3
- This version is a placeholder published only to claim the npm name `@overkill-dev/resources` so a Trusted Publisher
4
- can subsequently be configured for it. It contains no real package content and is published already
5
- deprecated.
3
+ Typed resource and runtime lifecycle composition for Overkill.
6
4
 
7
- Workaround context: https://github.com/npm/cli/issues/8544
5
+ This package defines resources as values and can start an explicit runtime
6
+ session from them. A resource declares its stable name, lifecycle scope,
7
+ execution requirements, dependencies, acquisition callback, and disposal
8
+ callback.
9
+
10
+ ```ts
11
+ import {
12
+ composeRuntimeContext,
13
+ composeRuntimes,
14
+ createTemporaryDirectoryResource,
15
+ defineResource,
16
+ defineRuntime,
17
+ startResources,
18
+ startRuntime,
19
+ type ResourceContext,
20
+ type RuntimeContext
21
+ } from '@overkill-dev/resources';
22
+
23
+ const database = defineResource({
24
+ name: 'database',
25
+ scope: 'per-case',
26
+ requirements: [ { kind: 'exclusive-resource', name: 'database' } ],
27
+ dependencies: {},
28
+ async acquire(context) {
29
+ context.signal.throwIfAborted();
30
+
31
+ return await openDatabase();
32
+ },
33
+ async dispose(database, _context) {
34
+ await database.close();
35
+ }
36
+ });
37
+
38
+ const server = defineResource({
39
+ name: 'server',
40
+ scope: 'per-case',
41
+ requirements: [],
42
+ dependencies: { database },
43
+ async acquire(context) {
44
+ return await startServer(context.dependencies.database);
45
+ },
46
+ async dispose(server, context) {
47
+ await server.stop(context.dependencies.database);
48
+ }
49
+ });
50
+
51
+ const scratch = createTemporaryDirectoryResource('scratch');
52
+ const sharedDatabase = defineResource({
53
+ name: 'shared-database',
54
+ scope: 'per-run',
55
+ requirements: [ { kind: 'single-worker' } ],
56
+ async acquire(context) {
57
+ context.signal.throwIfAborted();
58
+
59
+ return await openDatabase();
60
+ },
61
+ deserializeHandle(payload) {
62
+ return { url: payload.url };
63
+ },
64
+ async dispose(database) {
65
+ await database.close();
66
+ },
67
+ serializeHandle(database) {
68
+ return { url: database.url };
69
+ }
70
+ });
71
+ const runtime = defineRuntime({
72
+ name: 'api',
73
+ dimensions: {},
74
+ resources: { database, server, scratch },
75
+ requirements: [ { kind: 'startup-budget-milliseconds', minimumMilliseconds: 1000 } ]
76
+ });
77
+
78
+ type ApiContext = RuntimeContext<typeof runtime>;
79
+ type ScratchContext = ResourceContext<{ readonly scratch: typeof scratch; }>;
80
+
81
+ await using session = await startRuntime({ runtime, signal });
82
+
83
+ const scopeWithRuntime = composeRuntimeContext(testScope, runtime, session.context);
84
+ scopeWithRuntime.runtimes.api.database;
85
+
86
+ await using resources = await startResources({ resources: { scratch }, signal });
87
+ resources.context.scratch.path;
88
+ ```
89
+
90
+ `RuntimeContext` uses the keys from the runtime's `resources` object. Resource
91
+ `name` remains the stable identity used by reporters, artifacts, and future
92
+ scheduling work.
93
+
94
+ `composeRuntimeContext(...)` exposes acquired handles under
95
+ `scope.runtimes.<runtimeName>`, such as `scope.runtimes.api`.
96
+ `composeRuntimes(...)` combines leaf runtimes and runtime matrices into one
97
+ graph while exposing each child under its own public runtime name.
98
+
99
+ Dependency context uses the keys from the resource's `dependencies` object.
100
+ Omitting `dependencies` is accepted for compatibility and produces
101
+ `dependencies: {}` on the returned descriptor.
102
+
103
+ `createTemporaryDirectoryResource(name)` returns a per-case resource descriptor
104
+ whose handle is `{ readonly path: string }`. Each acquisition creates a unique
105
+ directory with an Overkill prefix. Disposal removes that directory recursively.
106
+
107
+ `startRuntime(...)` acquires dependencies before dependents, shares one handle
108
+ per descriptor inside the session, and disposes acquired resources once in
109
+ reverse dependency order. Independent ready resources may acquire concurrently.
110
+
111
+ `startResources(...)` starts a direct resource session without wrapping the
112
+ handles in a runtime name. It uses the keys from the provided resource map and
113
+ the same acquisition, sharing, and disposal behavior as `startRuntime(...)`.
114
+
115
+ The package-level session API starts one explicit session and therefore shares
116
+ one handle per descriptor inside that session. Runner-managed wrappers in
117
+ `@overkill-dev/test/resources` interpret `scope` as `per-run`, `per-file`,
118
+ `per-suite`, `per-case`, or `shared-per-worker` lifetime boundaries.
119
+
120
+ `per-run` resources must define `serializeHandle(...)` and
121
+ `deserializeHandle(...)` so runner-owned resources can be projected into
122
+ consumer execution contexts. `per-file` and `per-suite` resources may also
123
+ define projection hooks when their owner handle is not the same value that
124
+ test code should consume. `per-case` and `shared-per-worker` resources are
125
+ local to their execution owner and do not use projection hooks.
126
+
127
+ Execution requirements describe placement pressure for the runner:
128
+ `serial`, `single-worker`, `exclusive-resource`, `capacity-weight`,
129
+ `affinity-key`, `fault-domain`, and `startup-budget-milliseconds`.
@@ -0,0 +1,53 @@
1
+ export type Awaitable<Value> = Promise<Value> | Value;
2
+ export type ValueOf<Values> = Values[keyof Values];
3
+ type ExclusiveResource = {
4
+ readonly kind: 'exclusive-resource';
5
+ readonly name: string;
6
+ };
7
+ type SerialExecution = {
8
+ readonly kind: 'serial';
9
+ };
10
+ type SingleWorkerExecution = {
11
+ readonly kind: 'single-worker';
12
+ };
13
+ type StartupBudget = {
14
+ readonly kind: 'startup-budget-milliseconds';
15
+ readonly minimumMilliseconds: number;
16
+ };
17
+ type CapacityWeight = {
18
+ readonly kind: 'capacity-weight';
19
+ readonly weight: number;
20
+ };
21
+ type AffinityKey = {
22
+ readonly key: string;
23
+ readonly kind: 'affinity-key';
24
+ };
25
+ type FaultDomain = {
26
+ readonly key: string;
27
+ readonly kind: 'fault-domain';
28
+ };
29
+ type PlacementRequirement = AffinityKey | CapacityWeight | ExclusiveResource | FaultDomain;
30
+ type SchedulingRequirement = SerialExecution | SingleWorkerExecution | StartupBudget;
31
+ export type ExecutionRequirement = PlacementRequirement | SchedulingRequirement;
32
+ export type ResourceScope = 'per-case' | 'per-file' | 'per-run' | 'per-suite' | 'shared-per-worker';
33
+ export type AnyResourceDefinition = {
34
+ readonly acquire: (context: never) => Awaitable<unknown>;
35
+ readonly dependencies: ResourceDependencies;
36
+ readonly deserializeHandle?: (payload: never, context: never) => unknown;
37
+ readonly dispose: ((handle: never, context: never) => Awaitable<void>) | null;
38
+ readonly name: string;
39
+ readonly requirements: readonly ExecutionRequirement[];
40
+ readonly scope: ResourceScope;
41
+ readonly serializeHandle?: (handle: never, context: never) => ResourceProjectionPayload;
42
+ };
43
+ export type RuntimeResourceMap = Readonly<Record<string, AnyResourceDefinition>>;
44
+ export type EmptyResourceDependencies = Readonly<Record<PropertyKey, never>>;
45
+ export type ResourceDependencies = Readonly<Record<string, AnyResourceDefinition>>;
46
+ type ResourceProjectionObject = {
47
+ readonly [key: string]: ResourceProjectionPayload;
48
+ };
49
+ type ResourceProjectionScalar = boolean | number | string | null;
50
+ type ResourceProjectionCollection = ResourceProjectionObject | readonly ResourceProjectionPayload[];
51
+ export type ResourceProjectionPayload = ResourceProjectionCollection | ResourceProjectionScalar;
52
+ export {};
53
+ //# sourceMappingURL=resource-definition-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-definition-shape.d.ts","sourceRoot":"","sources":["../../../../source/resources/resource-definition-shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type AnyResourceDefinition, type Awaitable, type ResourceCreationContext, type ResourceDependencies, type ResourceDisposalContext } from './resources.ts';
2
+ export type ResourceEntry = readonly [string, AnyResourceDefinition];
3
+ export type ResourceNode = {
4
+ readonly dependencies: readonly ResourceNode[];
5
+ readonly descriptor: AnyResourceDefinition;
6
+ };
7
+ export type ResourceGraph = {
8
+ readonly order: readonly ResourceNode[];
9
+ readonly topLevelEntries: readonly ResourceEntry[];
10
+ };
11
+ type DependencyDisposalContext = ResourceDisposalContext<ResourceDependencies>;
12
+ export type ResourceDisposeCallback = (handle: unknown, context: DependencyDisposalContext) => Awaitable<void>;
13
+ export type CallableResourceDefinition = AnyResourceDefinition & {
14
+ readonly acquire: (context: ResourceCreationContext<ResourceDependencies>) => Awaitable<unknown>;
15
+ readonly dispose: ResourceDisposeCallback | null;
16
+ };
17
+ export declare function resourceEntries(resources: ResourceDependencies): readonly ResourceEntry[];
18
+ export declare function callableResourceDefinition(resource: AnyResourceDefinition): CallableResourceDefinition;
19
+ export declare function createResourceGraph(resources: ResourceDependencies): ResourceGraph;
20
+ export declare function assertPerCaseResourceGraph(resources: ResourceDependencies): void;
21
+ export declare function assertResourceDependencyScopes(resources: ResourceDependencies): void;
22
+ export {};
23
+ //# sourceMappingURL=resource-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-graph.d.ts","sourceRoot":"","sources":["../../../../source/resources/resource-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EAEd,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAE/B,MAAM,gBAAgB,CAAC;AAaxB,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AACrE,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,YAAY,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;CAC9C,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;CACtD,CAAC;AACF,KAAK,yBAAyB,GAAG,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;AAC/E,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;AAC/G,MAAM,MAAM,0BAA0B,GAAG,qBAAqB,GAAG;IAC7D,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC;IACjG,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;CACpD,CAAC;AAQF,wBAAgB,eAAe,CAAC,SAAS,EAAE,oBAAoB,GAAG,SAAS,aAAa,EAAE,CAEzF;AA+CD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,0BAA0B,CAQtG;AAiFD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,oBAAoB,GAAG,aAAa,CAElF;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAuBhF;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAwBpF"}
@@ -0,0 +1,151 @@
1
+ import { isDefinedResource } from "./resources.js";
2
+ import { resourceLifecycleError } from "./resource-lifecycle-error.js";
3
+ const perRunScopeRank = 0;
4
+ const perFileScopeRank = 1;
5
+ const perSuiteScopeRank = 2;
6
+ const sharedPerWorkerScopeRank = 3;
7
+ const perCaseScopeRank = 4;
8
+ export function resourceEntries(resources) {
9
+ return Object.entries(resources);
10
+ }
11
+ function scopeDescription(scope) {
12
+ return scope === 'per-case'
13
+ ? 'per-case scope'
14
+ : `${scope} scope, which direct execution wrappers do not support yet`;
15
+ }
16
+ function scopeRank(scope) {
17
+ if (scope === 'per-run') {
18
+ return perRunScopeRank;
19
+ }
20
+ if (scope === 'per-file') {
21
+ return perFileScopeRank;
22
+ }
23
+ if (scope === 'per-suite') {
24
+ return perSuiteScopeRank;
25
+ }
26
+ if (scope === 'shared-per-worker') {
27
+ return sharedPerWorkerScopeRank;
28
+ }
29
+ return perCaseScopeRank;
30
+ }
31
+ function dependencyScopeAllowed(resource, dependency) {
32
+ const resourceScope = resource.scope;
33
+ const dependencyScope = dependency.scope;
34
+ if (dependencyScope === 'shared-per-worker') {
35
+ return resource.scope === 'shared-per-worker' || resource.scope === 'per-case';
36
+ }
37
+ if (resourceScope === 'shared-per-worker') {
38
+ return dependency.scope === 'per-run' || dependency.scope === 'shared-per-worker';
39
+ }
40
+ return scopeRank(dependencyScope) <= scopeRank(resourceScope);
41
+ }
42
+ function hasCallableResourceCallbacks(resource) {
43
+ return isDefinedResource(resource) && typeof resource.acquire === 'function';
44
+ }
45
+ export function callableResourceDefinition(resource) {
46
+ if (hasCallableResourceCallbacks(resource)) {
47
+ return resource;
48
+ }
49
+ throw resourceLifecycleError('Resource descriptor is invalid.', [
50
+ { cause: resource, phase: 'graph', resourceName: 'resource' }
51
+ ], resource);
52
+ }
53
+ function assertUniqueResourceName(descriptorsByName, resource) {
54
+ const descriptorForName = descriptorsByName.get(resource.name);
55
+ if (descriptorForName !== undefined && descriptorForName !== resource) {
56
+ throw resourceLifecycleError(`Resource name "${resource.name}" is used by multiple descriptors.`, [
57
+ { cause: resource, phase: 'graph', resourceName: resource.name }
58
+ ], resource);
59
+ }
60
+ }
61
+ function assertResourceAcyclic(traversal, resource, path) {
62
+ if (traversal.has(resource)) {
63
+ throw resourceLifecycleError(`Resource dependency cycle detected: ${path.join(' -> ')}.`, [
64
+ { cause: resource, phase: 'graph', resourceName: resource.name }
65
+ ], resource);
66
+ }
67
+ }
68
+ function createResourceGraphBuilder() {
69
+ const descriptorsByName = new Map();
70
+ const nodesByDescriptor = new Map();
71
+ const order = [];
72
+ const traversal = new Set();
73
+ const builder = {
74
+ assertAcyclic(resource, path) {
75
+ assertResourceAcyclic(traversal, resource, path);
76
+ },
77
+ assertUniqueName(resource) {
78
+ assertUniqueResourceName(descriptorsByName, resource);
79
+ descriptorsByName.set(resource.name, resource);
80
+ },
81
+ build(resources) {
82
+ const topLevelEntries = resourceEntries(resources);
83
+ for (const [, resource] of topLevelEntries) {
84
+ builder.visit(resource, [resource.name]);
85
+ }
86
+ return { order, topLevelEntries };
87
+ },
88
+ record(resource, path) {
89
+ traversal.add(resource);
90
+ const dependencies = resourceEntries(resource.dependencies).map(function visitDependency([, dependency]) {
91
+ return builder.visit(dependency, [...path, dependency.name]);
92
+ });
93
+ const node = { dependencies, descriptor: resource };
94
+ traversal.delete(resource);
95
+ nodesByDescriptor.set(resource, node);
96
+ order.push(node);
97
+ return node;
98
+ },
99
+ visit(resource, path) {
100
+ const callableResource = callableResourceDefinition(resource);
101
+ const existingNode = nodesByDescriptor.get(callableResource);
102
+ builder.assertUniqueName(callableResource);
103
+ builder.assertAcyclic(callableResource, path);
104
+ if (existingNode !== undefined) {
105
+ return existingNode;
106
+ }
107
+ return builder.record(callableResource, path);
108
+ }
109
+ };
110
+ return builder;
111
+ }
112
+ export function createResourceGraph(resources) {
113
+ return createResourceGraphBuilder().build(resources);
114
+ }
115
+ export function assertPerCaseResourceGraph(resources) {
116
+ const graph = createResourceGraph(resources);
117
+ const nonPerCaseResource = graph.order.find(function hasBroaderScope(node) {
118
+ return node.descriptor.scope !== 'per-case';
119
+ });
120
+ if (nonPerCaseResource === undefined) {
121
+ return;
122
+ }
123
+ throw resourceLifecycleError(`Resource "${nonPerCaseResource.descriptor.name}" uses ${scopeDescription(nonPerCaseResource.descriptor.scope)}.`, [
124
+ {
125
+ cause: nonPerCaseResource.descriptor,
126
+ phase: 'graph',
127
+ resourceName: nonPerCaseResource.descriptor.name
128
+ }
129
+ ], nonPerCaseResource.descriptor);
130
+ }
131
+ export function assertResourceDependencyScopes(resources) {
132
+ const graph = createResourceGraph(resources);
133
+ for (const node of graph.order) {
134
+ for (const dependency of node.dependencies) {
135
+ if (!dependencyScopeAllowed(node.descriptor, dependency.descriptor)) {
136
+ throw resourceLifecycleError([
137
+ `Resource "${node.descriptor.name}" uses ${node.descriptor.scope} scope and cannot depend on`,
138
+ `resource "${dependency.descriptor.name}" with ${dependency.descriptor.scope} scope.`
139
+ ]
140
+ .join(' '), [
141
+ {
142
+ cause: dependency.descriptor,
143
+ phase: 'graph',
144
+ resourceName: node.descriptor.name
145
+ }
146
+ ], dependency.descriptor);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ //# sourceMappingURL=resource-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-graph.js","sourceRoot":"","sources":["../../../../source/resources/resource-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,iBAAiB,EAKpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AA4BvE,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,MAAM,UAAU,eAAe,CAAC,SAA+B;IAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAoB;IAC1C,OAAO,KAAK,KAAK,UAAU;QACvB,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,GAAG,KAAK,4DAA4D,CAAC;AAC/E,CAAC;AAED,SAAS,SAAS,CAAC,KAAoB;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,eAAe,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACvB,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACxB,OAAO,iBAAiB,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,KAAK,mBAAmB,EAAE,CAAC;QAChC,OAAO,wBAAwB,CAAC;IACpC,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC5B,CAAC;AAED,SAAS,sBAAsB,CAAC,QAA+B,EAAE,UAAiC;IAC9F,MAAM,aAAa,GAAkB,QAAQ,CAAC,KAAK,CAAC;IACpD,MAAM,eAAe,GAAkB,UAAU,CAAC,KAAK,CAAC;IAExD,IAAI,eAAe,KAAK,mBAAmB,EAAE,CAAC;QAC1C,OAAO,QAAQ,CAAC,KAAK,KAAK,mBAAmB,IAAI,QAAQ,CAAC,KAAK,KAAK,UAAU,CAAC;IACnF,CAAC;IAED,IAAI,aAAa,KAAK,mBAAmB,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,KAAK,mBAAmB,CAAC;IACtF,CAAC;IAED,OAAO,SAAS,CAAC,eAAe,CAAC,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,4BAA4B,CAAC,QAA+B;IACjE,OAAO,iBAAiB,CAAC,QAAQ,CAAC,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAA+B;IACtE,IAAI,4BAA4B,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,MAAM,sBAAsB,CAAC,iCAAiC,EAAE;QAC5D,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE;KAChE,EAAE,QAAQ,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,wBAAwB,CAC7B,iBAA6D,EAC7D,QAA+B;IAE/B,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE/D,IAAI,iBAAiB,KAAK,SAAS,IAAI,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QACpE,MAAM,sBAAsB,CAAC,kBAAkB,QAAQ,CAAC,IAAI,oCAAoC,EAAE;YAC9F,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE;SACnE,EAAE,QAAQ,CAAC,CAAC;IACjB,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAC1B,SAA6C,EAC7C,QAA+B,EAC/B,IAAuB;IAEvB,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,sBAAsB,CAAC,uCAAuC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;YACtF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE;SACnE,EAAE,QAAQ,CAAC,CAAC;IACjB,CAAC;AACL,CAAC;AAED,SAAS,0BAA0B;IAC/B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAiC,CAAC;IACnE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAuC,CAAC;IACzE,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IACnD,MAAM,OAAO,GAA4B;QACrC,aAAa,CAAC,QAAQ,EAAE,IAAI;YACxB,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,gBAAgB,CAAC,QAAQ;YACrB,wBAAwB,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;YACtD,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnD,CAAC;QACD,KAAK,CAAC,SAAS;YACX,MAAM,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;YAEnD,KAAK,MAAM,CAAE,AAAD,EAAG,QAAQ,CAAE,IAAI,eAAe,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAE,QAAQ,CAAC,IAAI,CAAE,CAAC,CAAC;YAC/C,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;QACtC,CAAC;QACD,MAAM,CAAC,QAAQ,EAAE,IAAI;YACjB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAExB,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,SAAS,eAAe,CAAC,CAAE,AAAD,EAAG,UAAU,CAAE;gBACrG,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAE,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAE,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;YAEpD,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEjB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,QAAQ,EAAE,IAAI;YAChB,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAE7D,OAAO,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YAC3C,OAAO,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YAE9C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,YAAY,CAAC;YACxB,CAAC;YAED,OAAO,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;KACJ,CAAC;IAEF,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAA+B;IAC/D,OAAO,0BAA0B,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,SAA+B;IACtE,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,eAAe,CAAC,IAAI;QACrE,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK,UAAU,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO;IACX,CAAC;IAED,MAAM,sBAAsB,CACxB,aAAa,kBAAkB,CAAC,UAAU,CAAC,IAAI,UAC3C,gBAAgB,CAAC,kBAAkB,CAAC,UAAU,CAAC,KAAK,CACxD,GAAG,EACH;QACI;YACI,KAAK,EAAE,kBAAkB,CAAC,UAAU;YACpC,KAAK,EAAE,OAAO;YACd,YAAY,EAAE,kBAAkB,CAAC,UAAU,CAAC,IAAI;SACnD;KACJ,EACD,kBAAkB,CAAC,UAAU,CAChC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,SAA+B;IAC1E,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7B,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClE,MAAM,sBAAsB,CACxB;oBACI,aAAa,IAAI,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,KAAK,6BAA6B;oBAC7F,aAAa,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,UAAU,CAAC,UAAU,CAAC,KAAK,SAAS;iBACxF;qBACI,IAAI,CAAC,GAAG,CAAC,EACd;oBACI;wBACI,KAAK,EAAE,UAAU,CAAC,UAAU;wBAC5B,KAAK,EAAE,OAAO;wBACd,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;qBACrC;iBACJ,EACD,UAAU,CAAC,UAAU,CACxB,CAAC;YACN,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ export type ResourceLifecyclePhase = 'acquire' | 'dispose' | 'graph';
2
+ export type ResourceLifecycleFailure = {
3
+ readonly cause: unknown;
4
+ readonly phase: ResourceLifecyclePhase;
5
+ readonly resourceName: string;
6
+ };
7
+ type ResourceLifecycleErrorOptions = {
8
+ readonly cause: unknown;
9
+ readonly failures: readonly ResourceLifecycleFailure[];
10
+ };
11
+ export declare class ResourceLifecycleError extends Error {
12
+ private readonly lifecycleFailures;
13
+ constructor(message: string, options: ResourceLifecycleErrorOptions);
14
+ failures(): readonly ResourceLifecycleFailure[];
15
+ }
16
+ export declare function resourceLifecycleError(message: string, failures: readonly ResourceLifecycleFailure[], cause: unknown): ResourceLifecycleError;
17
+ export declare function lifecycleFailures(results: readonly PromiseSettledResult<unknown>[], fallbackResourceName: string): readonly ResourceLifecycleFailure[];
18
+ export {};
19
+ //# sourceMappingURL=resource-lifecycle-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-lifecycle-error.d.ts","sourceRoot":"","sources":["../../../../source/resources/resource-lifecycle-error.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAErE,MAAM,MAAM,wBAAwB,GAAG;IACnC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAC;CAC1D,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,KAAK;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAsC;gBAGpE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,6BAA6B;IAOnC,QAAQ,IAAI,SAAS,wBAAwB,EAAE;CAGzD;AAED,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,SAAS,wBAAwB,EAAE,EAC7C,KAAK,EAAE,OAAO,GACf,sBAAsB,CAExB;AAUD,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,SAAS,oBAAoB,CAAC,OAAO,CAAC,EAAE,EACjD,oBAAoB,EAAE,MAAM,GAC7B,SAAS,wBAAwB,EAAE,CAYrC"}
@@ -0,0 +1,32 @@
1
+ export class ResourceLifecycleError extends Error {
2
+ lifecycleFailures;
3
+ constructor(message, options) {
4
+ super(message, options);
5
+ this.name = 'ResourceLifecycleError';
6
+ this.lifecycleFailures = options.failures;
7
+ }
8
+ failures() {
9
+ return this.lifecycleFailures;
10
+ }
11
+ }
12
+ export function resourceLifecycleError(message, failures, cause) {
13
+ return new ResourceLifecycleError(message, { cause, failures });
14
+ }
15
+ function lifecycleFailuresFrom(reason, fallbackResourceName) {
16
+ if (reason instanceof ResourceLifecycleError) {
17
+ return reason.failures();
18
+ }
19
+ return [{ cause: reason, phase: 'acquire', resourceName: fallbackResourceName }];
20
+ }
21
+ export function lifecycleFailures(results, fallbackResourceName) {
22
+ const failures = new Set();
23
+ for (const result of results) {
24
+ if (result.status === 'rejected') {
25
+ for (const failure of lifecycleFailuresFrom(result.reason, fallbackResourceName)) {
26
+ failures.add(failure);
27
+ }
28
+ }
29
+ }
30
+ return Array.from(failures);
31
+ }
32
+ //# sourceMappingURL=resource-lifecycle-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-lifecycle-error.js","sourceRoot":"","sources":["../../../../source/resources/resource-lifecycle-error.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC5B,iBAAiB,CAAsC;IAExE,YACI,OAAe,EACf,OAAsC;QAEtC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9C,CAAC;IAEM,QAAQ;QACX,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAClC,CAAC;CACJ;AAED,MAAM,UAAU,sBAAsB,CAClC,OAAe,EACf,QAA6C,EAC7C,KAAc;IAEd,OAAO,IAAI,sBAAsB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAe,EAAE,oBAA4B;IACxE,IAAI,MAAM,YAAY,sBAAsB,EAAE,CAAC;QAC3C,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAE,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC7B,OAAiD,EACjD,oBAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC/B,KAAK,MAAM,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAAE,CAAC;gBAC/E,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { AnyResourceDefinition, ResourceContext, ResourceDependencies } from './resources.ts';
2
+ import { type ResourceNode } from './resource-graph.ts';
3
+ import { type ResourceLifecycleFailure } from './resource-lifecycle-error.ts';
4
+ type ResourceAcquisitionContext = {
5
+ readonly acquisitionFailureMessage: string;
6
+ readonly fallbackResourceName: string;
7
+ };
8
+ export type StartResourcesRequest<Resources extends ResourceDependencies> = {
9
+ readonly resources: Resources;
10
+ readonly signal: AbortSignal;
11
+ };
12
+ export type ResourceSessionDisposalContext = {
13
+ readonly signal: AbortSignal;
14
+ };
15
+ export type ResourceSession<Resources extends ResourceDependencies> = AsyncDisposable & {
16
+ readonly context: ResourceContext<Resources>;
17
+ readonly disposeOnce: (context: ResourceSessionDisposalContext) => Promise<void>;
18
+ };
19
+ export declare function disposeResources(order: readonly ResourceNode[], handles: ReadonlyMap<AnyResourceDefinition, unknown>, signal: AbortSignal): Promise<readonly ResourceLifecycleFailure[]>;
20
+ export declare function runtimeAsyncDisposeSymbol(): symbol;
21
+ export declare function acquireResourceGraph<Resources extends ResourceDependencies>(request: StartResourcesRequest<Resources>, context: ResourceAcquisitionContext): Promise<{
22
+ readonly context: ResourceContext<Resources>;
23
+ readonly handles: ReadonlyMap<AnyResourceDefinition, unknown>;
24
+ readonly order: readonly ResourceNode[];
25
+ }>;
26
+ export declare function startResources<Resources extends ResourceDependencies>(request: StartResourcesRequest<Resources>): Promise<ResourceSession<Resources>>;
27
+ export {};
28
+ //# sourceMappingURL=resource-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-session.d.ts","sourceRoot":"","sources":["../../../../source/resources/resource-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,qBAAqB,EAErB,eAAe,EAEf,oBAAoB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAMH,KAAK,YAAY,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGH,KAAK,wBAAwB,EAChC,MAAM,+BAA+B,CAAC;AASvC,KAAK,0BAA0B,GAAG;IAC9B,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACzC,CAAC;AAiBF,MAAM,MAAM,qBAAqB,CAAC,SAAS,SAAS,oBAAoB,IAAI;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,SAAS,SAAS,oBAAoB,IAAI,eAAe,GAAG;IACpF,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,8BAA8B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF,CAAC;AAsDF,wBAAsB,gBAAgB,CAClC,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,OAAO,EAAE,WAAW,CAAC,qBAAqB,EAAE,OAAO,CAAC,EACpD,MAAM,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC,CAY9C;AAuID,wBAAgB,yBAAyB,IAAI,MAAM,CAQlD;AAQD,wBAAsB,oBAAoB,CAAC,SAAS,SAAS,oBAAoB,EAC7E,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,EACzC,OAAO,EAAE,0BAA0B,GACpC,OAAO,CAAC;IACP,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C,CAAC,CASD;AAED,wBAAsB,cAAc,CAAC,SAAS,SAAS,oBAAoB,EACvE,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,GAC1C,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CA4BrC"}