wardens 0.5.0 → 0.5.1-2024-07-29.a37451d
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 +1 -1
- package/dist/wardens.cjs +1 -1
- package/dist/wardens.js +106 -74
- package/package.json +18 -40
- package/src/__tests__/resource-scope.test.ts +198 -0
- package/src/__tests__/root-lifecycle.test.ts +249 -0
- package/src/__tests__/{allocation.test.ts → roots.test.ts} +15 -15
- package/src/__tests__/utility-types.test-d.ts +56 -0
- package/src/{state.ts → global-weakrefs.ts} +17 -11
- package/src/index.ts +4 -3
- package/src/inherited-context.ts +32 -0
- package/src/{allocation.ts → resource-lifecycle.ts} +16 -11
- package/src/{resource-context.ts → resource-scope.ts} +33 -8
- package/src/root-lifecycle.ts +36 -0
- package/src/{types.ts → utility-types.ts} +12 -6
- package/CHANGELOG.md +0 -86
- package/src/__tests__/resource-context.test.ts +0 -75
- package/src/__tests__/types.test-d.ts +0 -19
- /package/src/{proxy.ts → wrap-with-proxy.ts} +0 -0
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
+
import type { ContextHandle } from './inherited-context';
|
3
|
+
import type ResourceScope from './resource-scope';
|
2
4
|
|
3
5
|
/**
|
4
6
|
* Represents an arbitrary stateful resource that is asynchronously provisioned
|
@@ -6,14 +8,14 @@ import type ResourceContext from './resource-context';
|
|
6
8
|
* first tears down the children.
|
7
9
|
*/
|
8
10
|
export interface ResourceFactory<Value extends object> {
|
9
|
-
(resource:
|
11
|
+
(resource: ResourceScope): Promise<Resource<Value>>;
|
10
12
|
}
|
11
13
|
|
12
14
|
export interface ParametrizedResourceFactory<
|
13
15
|
Value extends object,
|
14
16
|
Args extends Array<unknown>,
|
15
17
|
> {
|
16
|
-
(resource:
|
18
|
+
(resource: ResourceScope, ...args: Args): Promise<Resource<Value>>;
|
17
19
|
}
|
18
20
|
|
19
21
|
export interface Resource<Value extends object> {
|
@@ -25,6 +27,10 @@ export interface Resource<Value extends object> {
|
|
25
27
|
}
|
26
28
|
|
27
29
|
/** The `value` type returned when creating a resource. */
|
28
|
-
export type ResourceHandle<
|
29
|
-
|
30
|
-
>['value'];
|
30
|
+
export type ResourceHandle<
|
31
|
+
Factory extends ParametrizedResourceFactory<object, Array<any>>,
|
32
|
+
> = Awaited<ReturnType<Factory>>['value'];
|
33
|
+
|
34
|
+
/** The type returned when you call `getContext`. */
|
35
|
+
export type ContextType<Handle extends ContextHandle<unknown>> =
|
36
|
+
Handle extends ContextHandle<infer Value> ? Value : never;
|
package/CHANGELOG.md
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
# Changelog
|
2
|
-
|
3
|
-
All notable changes to this project will be documented in this file.
|
4
|
-
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
-
|
7
|
-
## [Unreleased]
|
8
|
-
|
9
|
-
## [0.5.0]
|
10
|
-
|
11
|
-
### Changed
|
12
|
-
|
13
|
-
- Wardens is now published with ESM (`type=module`). It should be backwards compatible.
|
14
|
-
- Now `destroy(...)` throws if you pass an object that wasn't constructed with `create(...)`.
|
15
|
-
|
16
|
-
### Fixed
|
17
|
-
|
18
|
-
- If a resource fails while initializing, now all intermediate child resources are destroyed as well.
|
19
|
-
- If a resource fails while being destroyed, now its child resources are destroyed as well.
|
20
|
-
- Resources can no longer provision child resources after teardown. This closes a loophole where resources could escape destruction.
|
21
|
-
|
22
|
-
### Added
|
23
|
-
|
24
|
-
- New `ResourceHandle<T>` utility type represents the value returned when creating a resource.
|
25
|
-
|
26
|
-
## [0.4.1] - 2023-01-14
|
27
|
-
|
28
|
-
### Fixed
|
29
|
-
|
30
|
-
- Newer versions of TypeScript complained about signatures in `bindContext(...)`.
|
31
|
-
|
32
|
-
## [0.4.0] - 2022-06-19
|
33
|
-
|
34
|
-
### Added
|
35
|
-
|
36
|
-
- Support for provisioning resources through async functions instead of `Resource` subclasses. This offers better type safety around null conditions.
|
37
|
-
- A new `Resource` utility type is exported. The new functional API expects you to return this interface.
|
38
|
-
|
39
|
-
### Removed
|
40
|
-
|
41
|
-
- The `Resource` abstract class was removed. Use async functions instead.
|
42
|
-
- The `Controls<...>` utility type was removed. Import the type you need from the module instead.
|
43
|
-
|
44
|
-
## [0.3.0] - 2022-06-04
|
45
|
-
|
46
|
-
### Changed
|
47
|
-
|
48
|
-
- Prevent use of `allocate(...)`/`deallocate(...)` outside a resource subclass.
|
49
|
-
- Renamed `enter()` and `leave()` to `create()` and `destroy()`.
|
50
|
-
- Renamed `mount()` and `unmount()` to `create()` and `destroy()`.
|
51
|
-
|
52
|
-
### Removed
|
53
|
-
|
54
|
-
- Second type parameter to `Resource` is gone. Arguments to `enter(...)` are now inferred.
|
55
|
-
- No more default implementations for `enter(...)`/`leave(...)` on resources.
|
56
|
-
|
57
|
-
## [0.2.0] - 2022-05-24
|
58
|
-
|
59
|
-
### Fixed
|
60
|
-
|
61
|
-
- `mount(...)` and `allocate(...)` no longer require a config argument if the resource doesn't explicitly define one.
|
62
|
-
|
63
|
-
### Added
|
64
|
-
|
65
|
-
- `enter(...)` now supports variable arguments.
|
66
|
-
|
67
|
-
### Changed
|
68
|
-
|
69
|
-
- The second generic parameter of `Resource` was a config parameter, but now it's an argument tuple.
|
70
|
-
- The `ExternalControls` utility type was renamed to `Controls`.
|
71
|
-
|
72
|
-
## [0.1.0] - 2022-05-22
|
73
|
-
|
74
|
-
### Added
|
75
|
-
|
76
|
-
- Resource class for modeling asynchronously provisioned resources
|
77
|
-
- `mount`/`unmount` hooks to provision resources
|
78
|
-
- `allocate`/`deallocate` for creating hierarchies of resources
|
79
|
-
|
80
|
-
[Unreleased]: https://github.com/PsychoLlama/wardens/compare/v0.5.0...HEAD
|
81
|
-
[0.5.0]: https://github.com/PsychoLlama/wardens/compare/v0.4.1...v0.5.0
|
82
|
-
[0.4.1]: https://github.com/PsychoLlama/wardens/compare/v0.4.0...v0.4.1
|
83
|
-
[0.4.0]: https://github.com/PsychoLlama/wardens/compare/v0.3.0...v0.4.0
|
84
|
-
[0.3.0]: https://github.com/PsychoLlama/wardens/compare/v0.2.0...v0.3.0
|
85
|
-
[0.2.0]: https://github.com/PsychoLlama/wardens/compare/v0.1.0...v0.2.0
|
86
|
-
[0.1.0]: https://github.com/PsychoLlama/wardens/releases/tag/v0.1.0
|
@@ -1,75 +0,0 @@
|
|
1
|
-
import ResourceContext from '../resource-context';
|
2
|
-
import { create } from '../allocation';
|
3
|
-
|
4
|
-
describe('ResourceContext', () => {
|
5
|
-
async function Test() {
|
6
|
-
return { value: {} };
|
7
|
-
}
|
8
|
-
|
9
|
-
it('can spawn children of its own', async () => {
|
10
|
-
const Child = async () => ({
|
11
|
-
value: { child: true },
|
12
|
-
});
|
13
|
-
|
14
|
-
const Parent = async (resource: ResourceContext) => {
|
15
|
-
return { value: await resource.create(Child) };
|
16
|
-
};
|
17
|
-
|
18
|
-
await expect(create(Parent)).resolves.toEqual({ child: true });
|
19
|
-
});
|
20
|
-
|
21
|
-
it('can deallocate child resources on demand', async () => {
|
22
|
-
const spy = vi.fn();
|
23
|
-
|
24
|
-
const Child = async () => ({
|
25
|
-
value: { child: true },
|
26
|
-
destroy: spy,
|
27
|
-
});
|
28
|
-
|
29
|
-
const Parent = async (resource: ResourceContext) => {
|
30
|
-
const child = await resource.create(Child);
|
31
|
-
await resource.destroy(child);
|
32
|
-
|
33
|
-
return {
|
34
|
-
value: { parent: true },
|
35
|
-
};
|
36
|
-
};
|
37
|
-
|
38
|
-
await expect(create(Parent)).resolves.toEqual({ parent: true });
|
39
|
-
expect(spy).toHaveBeenCalled();
|
40
|
-
});
|
41
|
-
|
42
|
-
it('fails to destroy resources owned by someone else', async () => {
|
43
|
-
const test = await create(Test);
|
44
|
-
|
45
|
-
const Sneaky = async (resource: ResourceContext) => {
|
46
|
-
await resource.destroy(test);
|
47
|
-
return { value: {} };
|
48
|
-
};
|
49
|
-
|
50
|
-
await expect(create(Sneaky)).rejects.toThrow(/do not own/i);
|
51
|
-
});
|
52
|
-
|
53
|
-
it('binds create/destroy handlers to the class instance', async () => {
|
54
|
-
async function Allocator({ create, destroy }: ResourceContext) {
|
55
|
-
const test = await create(Test);
|
56
|
-
await destroy(test);
|
57
|
-
|
58
|
-
return { value: [] };
|
59
|
-
}
|
60
|
-
|
61
|
-
await expect(create(Allocator)).resolves.not.toThrow();
|
62
|
-
});
|
63
|
-
|
64
|
-
it('indicates if a resource was already destroyed', async () => {
|
65
|
-
async function Allocator(resource: ResourceContext) {
|
66
|
-
const test = await resource.create(Test);
|
67
|
-
await resource.destroy(test);
|
68
|
-
await resource.destroy(test);
|
69
|
-
|
70
|
-
return { value: [] };
|
71
|
-
}
|
72
|
-
|
73
|
-
await expect(create(Allocator)).rejects.toThrow(/already destroyed/i);
|
74
|
-
});
|
75
|
-
});
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import { create, ResourceHandle } from '../';
|
2
|
-
|
3
|
-
describe('Utility types', () => {
|
4
|
-
describe('ResourceHandle', () => {
|
5
|
-
it('infers the correct type', async () => {
|
6
|
-
async function Test() {
|
7
|
-
return {
|
8
|
-
value: { hello: 'world' },
|
9
|
-
};
|
10
|
-
}
|
11
|
-
|
12
|
-
const test = await create(Test);
|
13
|
-
|
14
|
-
expectTypeOf(test).toEqualTypeOf<ResourceHandle<typeof Test>>({
|
15
|
-
hello: 'world',
|
16
|
-
});
|
17
|
-
});
|
18
|
-
});
|
19
|
-
});
|
File without changes
|