wardens 0.5.0-rc.0 → 0.5.1-2024-07-28.65ce2a7

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.
@@ -1,4 +1,6 @@
1
- import type ResourceContext from './resource-context';
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: ResourceContext): Promise<Resource<Value>>;
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: ResourceContext, ...args: Args): Promise<Resource<Value>>;
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<Factory extends ResourceFactory<object>> = Awaited<
29
- ReturnType<Factory>
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,83 +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
- ### Changed
10
-
11
- - Wardens is now published with ESM (`type=module`). It should be backwards compatible.
12
- - Now `destroy(...)` throws if you pass an object that wasn't constructed with `create(...)`.
13
-
14
- ### Fixed
15
-
16
- - If a resource fails while initializing, now all intermediate child resources are destroyed as well.
17
- - If a resource fails while being destroyed, now its child resources are destroyed as well.
18
- - Resources can no longer provision child resources after teardown. This closes a loophole where resources could escape destruction.
19
-
20
- ### Added
21
-
22
- - New `ResourceHandle<T>` utility type represents the value returned when creating a resource.
23
-
24
- ## [0.4.1] - 2023-01-14
25
-
26
- ### Fixed
27
-
28
- - Newer versions of TypeScript complained about signatures in `bindContext(...)`.
29
-
30
- ## [0.4.0] - 2022-06-19
31
-
32
- ### Added
33
-
34
- - Support for provisioning resources through async functions instead of `Resource` subclasses. This offers better type safety around null conditions.
35
- - A new `Resource` utility type is exported. The new functional API expects you to return this interface.
36
-
37
- ### Removed
38
-
39
- - The `Resource` abstract class was removed. Use async functions instead.
40
- - The `Controls<...>` utility type was removed. Import the type you need from the module instead.
41
-
42
- ## [0.3.0] - 2022-06-04
43
-
44
- ### Changed
45
-
46
- - Prevent use of `allocate(...)`/`deallocate(...)` outside a resource subclass.
47
- - Renamed `enter()` and `leave()` to `create()` and `destroy()`.
48
- - Renamed `mount()` and `unmount()` to `create()` and `destroy()`.
49
-
50
- ### Removed
51
-
52
- - Second type parameter to `Resource` is gone. Arguments to `enter(...)` are now inferred.
53
- - No more default implementations for `enter(...)`/`leave(...)` on resources.
54
-
55
- ## [0.2.0] - 2022-05-24
56
-
57
- ### Fixed
58
-
59
- - `mount(...)` and `allocate(...)` no longer require a config argument if the resource doesn't explicitly define one.
60
-
61
- ### Added
62
-
63
- - `enter(...)` now supports variable arguments.
64
-
65
- ### Changed
66
-
67
- - The second generic parameter of `Resource` was a config parameter, but now it's an argument tuple.
68
- - The `ExternalControls` utility type was renamed to `Controls`.
69
-
70
- ## [0.1.0] - 2022-05-22
71
-
72
- ### Added
73
-
74
- - Resource class for modeling asynchronously provisioned resources
75
- - `mount`/`unmount` hooks to provision resources
76
- - `allocate`/`deallocate` for creating hierarchies of resources
77
-
78
- [Unreleased]: https://github.com/PsychoLlama/wardens/compare/v0.4.1...HEAD
79
- [0.4.1]: https://github.com/PsychoLlama/wardens/compare/v0.4.0...v0.4.1
80
- [0.4.0]: https://github.com/PsychoLlama/wardens/compare/v0.3.0...v0.4.0
81
- [0.3.0]: https://github.com/PsychoLlama/wardens/compare/v0.2.0...v0.3.0
82
- [0.2.0]: https://github.com/PsychoLlama/wardens/compare/v0.1.0...v0.2.0
83
- [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