wardens 0.6.0-rc.3 → 0.6.0-rc.4-2024-07-28.92dafd2

Sign up to get free protection for your applications and to get access to all the features.
package/dist/wardens.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var R=Object.defineProperty;var B=(e,t,r)=>t in e?R(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var f=(e,t,r)=>(B(e,typeof t!="symbol"?t+"":t,r),r),j=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var s=(e,t,r)=>(j(e,t,"read from private field"),r?r.call(e):t.get(e)),d=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},h=(e,t,r,o)=>(j(e,t,"write to private field"),o?o.call(e,r):t.set(e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function M(e){const t=new WeakMap;return new Proxy(e,{get(r,o){const n=Reflect.get(r,o,r);if(typeof n=="function"){if(t.has(n)===!1){const a=n.bind(r);Object.defineProperties(a,Object.getOwnPropertyDescriptors(n)),t.set(n,a)}return t.get(n)}return n},set(r,o,n){return Reflect.set(r,o,n,r)}})}const g=new WeakMap,k=new WeakSet,E=new WeakSet;function A(e){return Proxy.revocable(e,{})}var C,w;class x{constructor(t){d(this,C,Symbol("Context ID"));d(this,w,void 0);h(this,w,t)}static getId(t){return s(t,C)}static getDefaultValue(t){var r;return s(r=t,w).call(r)}}C=new WeakMap,w=new WeakMap;const T=e=>new x(e);var y,l,p,i;class V{constructor(t,r,o){d(this,y,new WeakSet);d(this,l,void 0);d(this,p,void 0);d(this,i,void 0);f(this,"create",async(t,...r)=>{if(s(this,p).enforced)throw new Error("Cannot create new resources after teardown.");const o=Object.create(s(this,i)),n=await P(o,t,...r);return s(this,l).add(n),n});f(this,"destroy",async t=>{if(s(this,y).has(t))throw new Error("Resource already destroyed.");if(!s(this,l).has(t))throw new Error("You do not own this resource.");s(this,l).delete(t),s(this,y).add(t),await m(t)});f(this,"setContext",(t,r)=>(s(this,i)[x.getId(t)]=r,r));f(this,"getContext",t=>{const r=x.getId(t);return r in s(this,i)?s(this,i)[r]:x.getDefaultValue(t)});h(this,i,t),h(this,l,r),h(this,p,o)}}y=new WeakMap,l=new WeakMap,p=new WeakMap,i=new WeakMap;const P=async(e,t,...r)=>{const o={enforced:!1},n=new Set,a=new V(e,n,o);let c;try{c=await t(a,...r)}catch(S){const O=Array.from(n).reverse(),v=(await Promise.allSettled(O.map(u=>a.destroy(u)))).filter(u=>u.status==="rejected");throw v.length?D(v.map(u=>u.reason),{cause:S}):S}const W=c.value,{proxy:b,revoke:I}=A(W);return k.add(b),g.set(b,{curfew:o,resource:c,children:n,revoke:I}),b},m=async e=>{if(!k.has(e))throw new Error("Cannot destroy object. It is not a resource.");const t=g.get(e);if(t){g.delete(e),t.revoke();let r={status:"fulfilled",value:void 0};if(t.resource.destroy)try{await t.resource.destroy()}catch(c){r={status:"rejected",reason:c}}t.curfew.enforced=!0;const o=Array.from(t.children).reverse().map(m),n=await Promise.allSettled(o),a=[r].concat(n).filter(c=>c.status==="rejected");if(a.length)throw D(a.map(c=>c.reason))}},D=(e,t)=>e.length===1?e[0]:new H(e,t);class H extends Error{constructor(t,r){super("Some resources could not be destroyed. See the `failures` property for details.",r),this.failures=t}}const U=async(e,...t)=>{const o=await P(Object.create(null),e,...t);return E.add(o),o},Y=async e=>{if(g.has(e)&&!E.has(e))throw new Error("Cannot destroy child resource. It is owned by another scope.");return m(e)};exports.bindContext=M;exports.create=U;exports.createContext=T;exports.destroy=Y;
1
+ "use strict";var B=Object.defineProperty;var j=e=>{throw TypeError(e)};var M=(e,t,r)=>t in e?B(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var f=(e,t,r)=>M(e,typeof t!="symbol"?t+"":t,r),k=(e,t,r)=>t.has(e)||j("Cannot "+r);var s=(e,t,r)=>(k(e,t,"read from private field"),r?r.call(e):t.get(e)),d=(e,t,r)=>t.has(e)?j("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),h=(e,t,r,o)=>(k(e,t,"write to private field"),o?o.call(e,r):t.set(e,r),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function A(e){const t=new WeakMap;return new Proxy(e,{get(r,o){const n=Reflect.get(r,o,r);if(typeof n=="function"){if(t.has(n)===!1){const a=n.bind(r);Object.defineProperties(a,Object.getOwnPropertyDescriptors(n)),t.set(n,a)}return t.get(n)}return n},set(r,o,n){return Reflect.set(r,o,n,r)}})}const g=new WeakMap,E=new WeakSet,P=new WeakSet;function T(e){return Proxy.revocable(e,{})}var C,w;class x{constructor(t){d(this,C,Symbol("Context ID"));d(this,w);h(this,w,t)}static getId(t){return s(t,C)}static getDefaultValue(t){var r;return s(r=t,w).call(r)}}C=new WeakMap,w=new WeakMap;const V=e=>new x(e);var y,l,p,i;class H{constructor(t,r,o){d(this,y,new WeakSet);d(this,l);d(this,p);d(this,i);f(this,"create",async(t,...r)=>{if(s(this,p).enforced)throw new Error("Cannot create new resources after teardown.");const o=Object.create(s(this,i)),n=await D(o,t,...r);return s(this,l).add(n),n});f(this,"destroy",async t=>{if(s(this,y).has(t))throw new Error("Resource already destroyed.");if(!s(this,l).has(t))throw new Error("You do not own this resource.");s(this,l).delete(t),s(this,y).add(t),await m(t)});f(this,"setContext",(t,r)=>(s(this,i)[x.getId(t)]=r,r));f(this,"getContext",t=>{const r=x.getId(t);return r in s(this,i)?s(this,i)[r]:x.getDefaultValue(t)});h(this,i,t),h(this,l,r),h(this,p,o)}}y=new WeakMap,l=new WeakMap,p=new WeakMap,i=new WeakMap;const D=async(e,t,...r)=>{const o={enforced:!1},n=new Set,a=new H(e,n,o);let c;try{c=await t(a,...r)}catch(S){const R=Array.from(n).reverse(),v=(await Promise.allSettled(R.map(u=>a.destroy(u)))).filter(u=>u.status==="rejected");throw v.length?W(v.map(u=>u.reason),{cause:S}):S}const I=c.value,{proxy:b,revoke:O}=T(I);return E.add(b),g.set(b,{curfew:o,resource:c,children:n,revoke:O}),b},m=async e=>{if(!E.has(e))throw new Error("Cannot destroy object. It is not a resource.");const t=g.get(e);if(t){g.delete(e),t.revoke();let r={status:"fulfilled",value:void 0};if(t.resource.destroy)try{await t.resource.destroy()}catch(c){r={status:"rejected",reason:c}}t.curfew.enforced=!0;const o=Array.from(t.children).reverse().map(m),n=await Promise.allSettled(o),a=[r].concat(n).filter(c=>c.status==="rejected");if(a.length)throw W(a.map(c=>c.reason))}},W=(e,t)=>e.length===1?e[0]:new U(e,t);class U extends Error{constructor(t,r){super("Some resources could not be destroyed. See the `failures` property for details.",r),this.failures=t}}const Y=async(e,...t)=>{const o=await D(Object.create(null),e,...t);return P.add(o),o},q=async e=>{if(g.has(e)&&!P.has(e))throw new Error("Cannot destroy child resource. It is owned by another scope.");return m(e)};exports.bindContext=A;exports.create=Y;exports.createContext=V;exports.destroy=q;
package/dist/wardens.js CHANGED
@@ -1,15 +1,11 @@
1
- var O = Object.defineProperty;
2
- var B = (e, t, r) => t in e ? O(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
- var h = (e, t, r) => (B(e, typeof t != "symbol" ? t + "" : t, r), r), j = (e, t, r) => {
4
- if (!t.has(e))
5
- throw TypeError("Cannot " + r);
1
+ var B = Object.defineProperty;
2
+ var j = (e) => {
3
+ throw TypeError(e);
6
4
  };
7
- var n = (e, t, r) => (j(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => {
8
- if (t.has(e))
9
- throw TypeError("Cannot add the same private member more than once");
10
- t instanceof WeakSet ? t.add(e) : t.set(e, r);
11
- }, f = (e, t, r, o) => (j(e, t, "write to private field"), o ? o.call(e, r) : t.set(e, r), r);
12
- function U(e) {
5
+ var A = (e, t, r) => t in e ? B(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
6
+ var h = (e, t, r) => A(e, typeof t != "symbol" ? t + "" : t, r), k = (e, t, r) => t.has(e) || j("Cannot " + r);
7
+ var n = (e, t, r) => (k(e, t, "read from private field"), r ? r.call(e) : t.get(e)), d = (e, t, r) => t.has(e) ? j("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(e) : t.set(e, r), f = (e, t, r, o) => (k(e, t, "write to private field"), o ? o.call(e, r) : t.set(e, r), r);
8
+ function Y(e) {
13
9
  const t = /* @__PURE__ */ new WeakMap();
14
10
  return new Proxy(e, {
15
11
  get(r, o) {
@@ -31,15 +27,15 @@ function U(e) {
31
27
  }
32
28
  });
33
29
  }
34
- const g = /* @__PURE__ */ new WeakMap(), k = /* @__PURE__ */ new WeakSet(), E = /* @__PURE__ */ new WeakSet();
35
- function A(e) {
30
+ const g = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakSet(), D = /* @__PURE__ */ new WeakSet();
31
+ function M(e) {
36
32
  return Proxy.revocable(e, {});
37
33
  }
38
34
  var m, w;
39
35
  class x {
40
36
  constructor(t) {
41
37
  d(this, m, Symbol("Context ID"));
42
- d(this, w, void 0);
38
+ d(this, w);
43
39
  f(this, w, t);
44
40
  }
45
41
  static getId(t) {
@@ -51,19 +47,19 @@ class x {
51
47
  }
52
48
  }
53
49
  m = new WeakMap(), w = new WeakMap();
54
- const Y = (e) => new x(e);
50
+ const q = (e) => new x(e);
55
51
  var y, l, p, i;
56
- class M {
52
+ class V {
57
53
  constructor(t, r, o) {
58
54
  d(this, y, /* @__PURE__ */ new WeakSet());
59
- d(this, l, void 0);
60
- d(this, p, void 0);
61
- d(this, i, void 0);
55
+ d(this, l);
56
+ d(this, p);
57
+ d(this, i);
62
58
  /** Provision an owned resource and make sure it doesn't outlive us. */
63
59
  h(this, "create", async (t, ...r) => {
64
60
  if (n(this, p).enforced)
65
61
  throw new Error("Cannot create new resources after teardown.");
66
- const o = Object.create(n(this, i)), s = await D(o, t, ...r);
62
+ const o = Object.create(n(this, i)), s = await P(o, t, ...r);
67
63
  return n(this, l).add(s), s;
68
64
  });
69
65
  /**
@@ -88,31 +84,31 @@ class M {
88
84
  }
89
85
  }
90
86
  y = new WeakMap(), l = new WeakMap(), p = new WeakMap(), i = new WeakMap();
91
- const D = async (e, t, ...r) => {
92
- const o = { enforced: !1 }, s = /* @__PURE__ */ new Set(), a = new M(e, s, o);
87
+ const P = async (e, t, ...r) => {
88
+ const o = { enforced: !1 }, s = /* @__PURE__ */ new Set(), a = new V(e, s, o);
93
89
  let c;
94
90
  try {
95
91
  c = await t(a, ...r);
96
92
  } catch (S) {
97
- const R = Array.from(s).reverse(), v = (await Promise.allSettled(
98
- R.map((u) => a.destroy(u))
93
+ const O = Array.from(s).reverse(), v = (await Promise.allSettled(
94
+ O.map((u) => a.destroy(u))
99
95
  )).filter(
100
96
  (u) => u.status === "rejected"
101
97
  );
102
- throw v.length ? P(
98
+ throw v.length ? W(
103
99
  v.map((u) => u.reason),
104
100
  { cause: S }
105
101
  ) : S;
106
102
  }
107
- const W = c.value, { proxy: C, revoke: I } = A(W);
108
- return k.add(C), g.set(C, {
103
+ const I = c.value, { proxy: C, revoke: R } = M(I);
104
+ return E.add(C), g.set(C, {
109
105
  curfew: o,
110
106
  resource: c,
111
107
  children: s,
112
- revoke: I
108
+ revoke: R
113
109
  }), C;
114
110
  }, b = async (e) => {
115
- if (!k.has(e))
111
+ if (!E.has(e))
116
112
  throw new Error("Cannot destroy object. It is not a resource.");
117
113
  const t = g.get(e);
118
114
  if (t) {
@@ -132,10 +128,10 @@ const D = async (e, t, ...r) => {
132
128
  (c) => c.status === "rejected"
133
129
  );
134
130
  if (a.length)
135
- throw P(a.map((c) => c.reason));
131
+ throw W(a.map((c) => c.reason));
136
132
  }
137
- }, P = (e, t) => e.length === 1 ? e[0] : new V(e, t);
138
- class V extends Error {
133
+ }, W = (e, t) => e.length === 1 ? e[0] : new H(e, t);
134
+ class H extends Error {
139
135
  constructor(t, r) {
140
136
  super(
141
137
  "Some resources could not be destroyed. See the `failures` property for details.",
@@ -143,19 +139,19 @@ class V extends Error {
143
139
  ), this.failures = t;
144
140
  }
145
141
  }
146
- const q = async (e, ...t) => {
147
- const o = await D(/* @__PURE__ */ Object.create(null), e, ...t);
148
- return E.add(o), o;
149
- }, z = async (e) => {
150
- if (g.has(e) && !E.has(e))
142
+ const z = async (e, ...t) => {
143
+ const o = await P(/* @__PURE__ */ Object.create(null), e, ...t);
144
+ return D.add(o), o;
145
+ }, F = async (e) => {
146
+ if (g.has(e) && !D.has(e))
151
147
  throw new Error(
152
148
  "Cannot destroy child resource. It is owned by another scope."
153
149
  );
154
150
  return b(e);
155
151
  };
156
152
  export {
157
- U as bindContext,
158
- q as create,
159
- Y as createContext,
160
- z as destroy
153
+ Y as bindContext,
154
+ z as create,
155
+ q as createContext,
156
+ F as destroy
161
157
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wardens",
3
- "version": "0.6.0-rc.3",
3
+ "version": "0.6.0-rc.4-2024-07-28.92dafd2",
4
4
  "description": "A framework for resource management",
5
5
  "type": "module",
6
6
  "main": "./dist/wardens.cjs",
@@ -31,12 +31,13 @@
31
31
  ],
32
32
  "scripts": {
33
33
  "prepack": "tsc && vite build",
34
- "test": "./bin/run-tests",
34
+ "test": "./scripts/run-tests",
35
35
  "test:lint": "eslint src --color",
36
- "test:unit": "vitest --color",
37
- "test:types": "vitest typecheck --color",
36
+ "test:unit": "vitest --color --typecheck",
38
37
  "test:fmt": "prettier --check src --color",
39
- "dev": "vite build --watch"
38
+ "print-pkg-version": "echo ${npm_package_version}",
39
+ "release:candidate": "./scripts/publish-rc",
40
+ "release:stable": "./scripts/publish-stable"
40
41
  },
41
42
  "husky": {
42
43
  "hooks": {
@@ -53,41 +54,17 @@
53
54
  "singleQuote": true,
54
55
  "trailingComma": "all"
55
56
  },
56
- "eslintConfig": {
57
- "parser": "@typescript-eslint/parser",
58
- "parserOptions": {
59
- "sourceType": "module"
60
- },
61
- "overrides": [
62
- {
63
- "files": [
64
- "./**/__tests__/*.ts{x,}"
65
- ],
66
- "rules": {
67
- "@typescript-eslint/no-explicit-any": "off"
68
- }
69
- }
70
- ],
71
- "extends": [
72
- "eslint:recommended",
73
- "plugin:@typescript-eslint/recommended"
74
- ],
75
- "rules": {
76
- "@typescript-eslint/explicit-module-boundary-types": "off",
77
- "@typescript-eslint/no-non-null-assertion": "off",
78
- "@typescript-eslint/no-unused-vars": "error",
79
- "no-prototype-builtins": "off"
80
- }
81
- },
82
57
  "devDependencies": {
83
- "@typescript-eslint/eslint-plugin": "6.4.1",
84
- "@typescript-eslint/parser": "6.4.1",
85
- "eslint": "8.48.0",
86
- "husky": "8.0.3",
87
- "lint-staged": "14.0.1",
88
- "prettier": "2.8.8",
89
- "typescript": "5.2.2",
90
- "vite": "4.4.9",
91
- "vitest": "^0.34.0"
58
+ "@eslint/js": "^9.7.0",
59
+ "@types/eslint__js": "^8.42.3",
60
+ "@types/node": "^22.0.0",
61
+ "eslint": "^9.7.0",
62
+ "husky": "^9.1.3",
63
+ "lint-staged": "^15.2.7",
64
+ "prettier": "^3.3.3",
65
+ "typescript": "^5.5.4",
66
+ "typescript-eslint": "^8.0.0-alpha.54",
67
+ "vite": "^5.3.5",
68
+ "vitest": "^2.0.0"
92
69
  }
93
70
  }
@@ -58,7 +58,7 @@ describe('roots', () => {
58
58
 
59
59
  describe('destroy', () => {
60
60
  it('deallocates the resource', async () => {
61
- const spy = vi.fn<[], void>();
61
+ const spy = vi.fn<() => void>();
62
62
  const Test = async () => ({
63
63
  value: {},
64
64
  destroy: spy,
@@ -58,7 +58,7 @@ describe('roots', () => {
58
58
 
59
59
  describe('destroy', () => {
60
60
  it('deallocates the resource', async () => {
61
- const spy = vi.fn<[], void>();
61
+ const spy = vi.fn<() => void>();
62
62
  const Test = async () => ({
63
63
  value: {},
64
64
  destroy: spy,
@@ -1,4 +1,10 @@
1
- import { create, ResourceScope, ResourceHandle } from '../';
1
+ import {
2
+ create,
3
+ ResourceScope,
4
+ ResourceHandle,
5
+ createContext,
6
+ ContextType,
7
+ } from '../';
2
8
 
3
9
  describe('Utility types', () => {
4
10
  describe('ResourceHandle', () => {
@@ -29,4 +35,22 @@ describe('Utility types', () => {
29
35
  });
30
36
  });
31
37
  });
38
+
39
+ describe('ContextType', () => {
40
+ it('returns the type contained in context', async () => {
41
+ const Context = createContext(() => ({
42
+ hello: 'world',
43
+ }));
44
+
45
+ async function Test({ getContext }: ResourceScope) {
46
+ return { value: getContext(Context) };
47
+ }
48
+
49
+ const value = await create(Test);
50
+
51
+ expectTypeOf(value).toEqualTypeOf<ContextType<typeof Context>>({
52
+ hello: 'any string, really',
53
+ });
54
+ });
55
+ });
32
56
  });
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { default as bindContext } from './bind-context';
2
2
  export { createRoot as create, destroyRoot as destroy } from './root-lifecycle';
3
3
  export { createContext } from './inherited-context';
4
- export type { Resource, ResourceHandle } from './utility-types';
4
+ export type { Resource, ResourceHandle, ContextType } from './utility-types';
5
5
  export type { default as ResourceScope } from './resource-scope';
@@ -119,7 +119,10 @@ const reduceToSingleError = (errors: Array<Error>, options?: ErrorOptions) => {
119
119
 
120
120
  /** Happens when 2 or more child resources cannot be destroyed. */
121
121
  class BulkDestroyError extends Error {
122
- constructor(public failures: Array<unknown>, options?: ErrorOptions) {
122
+ constructor(
123
+ public failures: Array<unknown>,
124
+ options?: ErrorOptions,
125
+ ) {
123
126
  super(
124
127
  'Some resources could not be destroyed. See the `failures` property for details.',
125
128
  options,
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import type { ContextHandle } from './inherited-context';
2
3
  import type ResourceScope from './resource-scope';
3
4
 
4
5
  /**
@@ -29,3 +30,7 @@ export interface Resource<Value extends object> {
29
30
  export type ResourceHandle<
30
31
  Factory extends ParametrizedResourceFactory<object, Array<any>>,
31
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,103 +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
- ### Added
10
-
11
- - New context API carries state down the tree without plumbing through arguments.
12
-
13
- ### Changed
14
-
15
- - Renamed public type `ResourceContext` to `ResourceScope`.
16
- - `destroy(...)` is no longer allowed to destroy child resources, only roots.
17
- - Added tree-shaking metadata. This is useful for bundle analysis tools.
18
-
19
- ## [0.5.1] - 2023-08-12
20
-
21
- ### Fixed
22
-
23
- - Added support for parametrized resources in `ResourceHandle<T>`.
24
-
25
- ## [0.5.0] - 2023-08-12
26
-
27
- ### Changed
28
-
29
- - Wardens is now published with ESM (`type=module`). It should be backwards compatible.
30
- - Now `destroy(...)` throws if you pass an object that wasn't constructed with `create(...)`.
31
-
32
- ### Fixed
33
-
34
- - If a resource fails while initializing, now all intermediate child resources are destroyed as well.
35
- - If a resource fails while being destroyed, now its child resources are destroyed as well.
36
- - Resources can no longer provision child resources after teardown. This closes a loophole where resources could escape destruction.
37
-
38
- ### Added
39
-
40
- - New `ResourceHandle<T>` utility type represents the value returned when creating a resource.
41
-
42
- ## [0.4.1] - 2023-01-14
43
-
44
- ### Fixed
45
-
46
- - Newer versions of TypeScript complained about signatures in `bindContext(...)`.
47
-
48
- ## [0.4.0] - 2022-06-19
49
-
50
- ### Added
51
-
52
- - Support for provisioning resources through async functions instead of `Resource` subclasses. This offers better type safety around null conditions.
53
- - A new `Resource` utility type is exported. The new functional API expects you to return this interface.
54
-
55
- ### Removed
56
-
57
- - The `Resource` abstract class was removed. Use async functions instead.
58
- - The `Controls<...>` utility type was removed. Import the type you need from the module instead.
59
-
60
- ## [0.3.0] - 2022-06-04
61
-
62
- ### Changed
63
-
64
- - Prevent use of `allocate(...)`/`deallocate(...)` outside a resource subclass.
65
- - Renamed `enter()` and `leave()` to `create()` and `destroy()`.
66
- - Renamed `mount()` and `unmount()` to `create()` and `destroy()`.
67
-
68
- ### Removed
69
-
70
- - Second type parameter to `Resource` is gone. Arguments to `enter(...)` are now inferred.
71
- - No more default implementations for `enter(...)`/`leave(...)` on resources.
72
-
73
- ## [0.2.0] - 2022-05-24
74
-
75
- ### Fixed
76
-
77
- - `mount(...)` and `allocate(...)` no longer require a config argument if the resource doesn't explicitly define one.
78
-
79
- ### Added
80
-
81
- - `enter(...)` now supports variable arguments.
82
-
83
- ### Changed
84
-
85
- - The second generic parameter of `Resource` was a config parameter, but now it's an argument tuple.
86
- - The `ExternalControls` utility type was renamed to `Controls`.
87
-
88
- ## [0.1.0] - 2022-05-22
89
-
90
- ### Added
91
-
92
- - Resource class for modeling asynchronously provisioned resources
93
- - `mount`/`unmount` hooks to provision resources
94
- - `allocate`/`deallocate` for creating hierarchies of resources
95
-
96
- [Unreleased]: https://github.com/PsychoLlama/wardens/compare/v0.5.1...HEAD
97
- [0.5.1]: https://github.com/PsychoLlama/wardens/compare/v0.5.0...v0.5.1
98
- [0.5.0]: https://github.com/PsychoLlama/wardens/compare/v0.4.1...v0.5.0
99
- [0.4.1]: https://github.com/PsychoLlama/wardens/compare/v0.4.0...v0.4.1
100
- [0.4.0]: https://github.com/PsychoLlama/wardens/compare/v0.3.0...v0.4.0
101
- [0.3.0]: https://github.com/PsychoLlama/wardens/compare/v0.2.0...v0.3.0
102
- [0.2.0]: https://github.com/PsychoLlama/wardens/compare/v0.1.0...v0.2.0
103
- [0.1.0]: https://github.com/PsychoLlama/wardens/releases/tag/v0.1.0