@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.
- package/LICENSE +21 -0
- package/package.json +32 -6
- package/packages/resources/resources.entry-point.d.ts +18 -0
- package/packages/resources/resources.entry-point.d.ts.map +1 -0
- package/packages/resources/resources.entry-point.js +25 -0
- package/packages/resources/resources.entry-point.js.map +1 -0
- package/readme.md +127 -5
- package/resources/resource-definition-shape.d.ts +53 -0
- package/resources/resource-definition-shape.d.ts.map +1 -0
- package/resources/resource-graph.d.ts +23 -0
- package/resources/resource-graph.d.ts.map +1 -0
- package/resources/resource-graph.js +151 -0
- package/resources/resource-graph.js.map +1 -0
- package/resources/resource-lifecycle-error.d.ts +19 -0
- package/resources/resource-lifecycle-error.d.ts.map +1 -0
- package/resources/resource-lifecycle-error.js +32 -0
- package/resources/resource-lifecycle-error.js.map +1 -0
- package/resources/resource-session.d.ts +28 -0
- package/resources/resource-session.d.ts.map +1 -0
- package/resources/resource-session.js +182 -0
- package/resources/resource-session.js.map +1 -0
- package/resources/resources.d.ts +149 -0
- package/resources/resources.d.ts.map +1 -0
- package/resources/resources.js +99 -0
- package/resources/resources.js.map +1 -0
- package/resources/runtime-definition.d.ts +23 -0
- package/resources/runtime-definition.d.ts.map +1 -0
- package/resources/runtime-definition.js +19 -0
- package/resources/runtime-definition.js.map +1 -0
- package/resources/runtime-lifecycle.d.ts +14 -0
- package/resources/runtime-lifecycle.d.ts.map +1 -0
- package/resources/runtime-lifecycle.js +83 -0
- package/resources/runtime-lifecycle.js.map +1 -0
- package/resources/runtime-matrix-definition.d.ts +53 -0
- package/resources/runtime-matrix-definition.d.ts.map +1 -0
- package/resources/runtime-matrix-definition.js +159 -0
- package/resources/runtime-matrix-definition.js.map +1 -0
- 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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
#
|
|
1
|
+
# `@overkill-dev/resources`
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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":"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"}
|
|
@@ -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"}
|