@furystack/utils 7.0.1 → 8.0.0

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 (104) hide show
  1. package/CHANGELOG.md +2 -36
  2. package/README.md +9 -9
  3. package/esm/debounce.d.ts.map +1 -1
  4. package/esm/deep-merge.d.ts.map +1 -1
  5. package/esm/deep-merge.spec.js +1 -1
  6. package/esm/deep-merge.spec.js.map +1 -1
  7. package/esm/event-hub.d.ts +1 -2
  8. package/esm/event-hub.d.ts.map +1 -1
  9. package/esm/event-hub.js +2 -2
  10. package/esm/event-hub.js.map +1 -1
  11. package/esm/event-hub.spec.js +4 -4
  12. package/esm/event-hub.spec.js.map +1 -1
  13. package/esm/index.d.ts +6 -4
  14. package/esm/index.d.ts.map +1 -1
  15. package/esm/index.js +6 -4
  16. package/esm/index.js.map +1 -1
  17. package/esm/is-async-disposable.d.ts +7 -0
  18. package/esm/is-async-disposable.d.ts.map +1 -0
  19. package/esm/is-async-disposable.js +9 -0
  20. package/esm/is-async-disposable.js.map +1 -0
  21. package/esm/is-async-disposable.spec.d.ts +2 -0
  22. package/esm/is-async-disposable.spec.d.ts.map +1 -0
  23. package/esm/is-async-disposable.spec.js +21 -0
  24. package/esm/is-async-disposable.spec.js.map +1 -0
  25. package/esm/is-disposable.d.ts +7 -0
  26. package/esm/is-disposable.d.ts.map +1 -0
  27. package/esm/is-disposable.js +9 -0
  28. package/esm/is-disposable.js.map +1 -0
  29. package/esm/is-disposable.spec.d.ts +2 -0
  30. package/esm/is-disposable.spec.d.ts.map +1 -0
  31. package/esm/is-disposable.spec.js +21 -0
  32. package/esm/is-disposable.spec.js.map +1 -0
  33. package/esm/observable-value.d.ts +4 -5
  34. package/esm/observable-value.d.ts.map +1 -1
  35. package/esm/observable-value.js +3 -3
  36. package/esm/observable-value.js.map +1 -1
  37. package/esm/observable-value.spec.d.ts.map +1 -1
  38. package/esm/observable-value.spec.js +10 -9
  39. package/esm/observable-value.spec.js.map +1 -1
  40. package/esm/path-helper.js +1 -1
  41. package/esm/path-helper.js.map +1 -1
  42. package/esm/path-helper.spec.d.ts.map +1 -1
  43. package/esm/path-helper.spec.js +9 -1
  44. package/esm/path-helper.spec.js.map +1 -1
  45. package/esm/sort-by.d.ts +1 -1
  46. package/esm/sort-by.d.ts.map +1 -1
  47. package/esm/tuple.d.ts.map +1 -1
  48. package/esm/using-async.d.ts +8 -0
  49. package/esm/using-async.d.ts.map +1 -0
  50. package/esm/using-async.js +22 -0
  51. package/esm/using-async.js.map +1 -0
  52. package/esm/using-async.spec.d.ts +17 -0
  53. package/esm/using-async.spec.d.ts.map +1 -0
  54. package/esm/using-async.spec.js +84 -0
  55. package/esm/using-async.spec.js.map +1 -0
  56. package/esm/using.d.ts +8 -0
  57. package/esm/using.d.ts.map +1 -0
  58. package/esm/using.js +15 -0
  59. package/esm/using.js.map +1 -0
  60. package/esm/{disposable.spec.d.ts → using.spec.d.ts} +2 -7
  61. package/esm/using.spec.d.ts.map +1 -0
  62. package/esm/using.spec.js +62 -0
  63. package/esm/using.spec.js.map +1 -0
  64. package/esm/value-observer.d.ts +3 -4
  65. package/esm/value-observer.d.ts.map +1 -1
  66. package/esm/value-observer.js +3 -3
  67. package/esm/value-observer.js.map +1 -1
  68. package/package.json +3 -3
  69. package/src/deep-merge.spec.ts +2 -2
  70. package/src/event-hub.spec.ts +4 -4
  71. package/src/event-hub.ts +2 -4
  72. package/src/index.ts +6 -4
  73. package/src/is-async-disposable.spec.ts +23 -0
  74. package/src/is-async-disposable.ts +8 -0
  75. package/src/is-disposable.spec.ts +23 -0
  76. package/src/is-disposable.ts +8 -0
  77. package/src/observable-value.spec.ts +11 -9
  78. package/src/observable-value.ts +3 -4
  79. package/src/path-helper.spec.ts +10 -1
  80. package/src/path-helper.ts +1 -1
  81. package/src/using-async.spec.ts +93 -0
  82. package/src/using-async.ts +24 -0
  83. package/src/using.spec.ts +67 -0
  84. package/src/using.ts +13 -0
  85. package/src/value-observer.ts +3 -4
  86. package/esm/disposable.d.ts +0 -49
  87. package/esm/disposable.d.ts.map +0 -1
  88. package/esm/disposable.js +0 -56
  89. package/esm/disposable.js.map +0 -1
  90. package/esm/disposable.spec.d.ts.map +0 -1
  91. package/esm/disposable.spec.js +0 -118
  92. package/esm/disposable.spec.js.map +0 -1
  93. package/esm/trace.d.ts +0 -119
  94. package/esm/trace.d.ts.map +0 -1
  95. package/esm/trace.js +0 -139
  96. package/esm/trace.js.map +0 -1
  97. package/esm/trace.spec.d.ts +0 -2
  98. package/esm/trace.spec.d.ts.map +0 -1
  99. package/esm/trace.spec.js +0 -184
  100. package/esm/trace.spec.js.map +0 -1
  101. package/src/disposable.spec.ts +0 -130
  102. package/src/disposable.ts +0 -69
  103. package/src/trace.spec.ts +0 -200
  104. package/src/trace.ts +0 -265
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, vi } from 'vitest'
1
+ import { describe, expect, it, vi } from 'vitest'
2
2
  import { ObservableValue } from './observable-value.js'
3
3
 
4
4
  /**
@@ -74,8 +74,10 @@ export const observableTests = describe('Observable', () => {
74
74
  v.subscribe(callback1)
75
75
  v.subscribe(callback2)
76
76
  expect(v.getObservers().length).toBe(2)
77
- v.dispose()
77
+ v[Symbol.dispose]()
78
78
  expect(v.getObservers().length).toBe(0)
79
+
80
+ expect(v.isDisposed).toBe(true)
79
81
  })
80
82
 
81
83
  it('should remove the subscription on Observer dispose', () => {
@@ -85,25 +87,25 @@ export const observableTests = describe('Observable', () => {
85
87
  const v = new ObservableValue(1)
86
88
  const observer = v.subscribe(callback1)
87
89
  expect(v.getObservers().length).toBe(1)
88
- observer.dispose()
90
+ observer[Symbol.dispose]()
89
91
  expect(v.getObservers().length).toBe(0)
90
92
  })
91
93
 
92
94
  it('should throw an error for setValue() when the observer has been disposed', () => {
93
95
  const v = new ObservableValue(1)
94
- v.dispose()
96
+ v[Symbol.dispose]()
95
97
  expect(() => v.setValue(3)).toThrowError('Observable already disposed')
96
98
  })
97
99
 
98
100
  it('should throw an error for getValue() when the observer has been disposed', () => {
99
101
  const v = new ObservableValue(1)
100
- v.dispose()
102
+ v[Symbol.dispose]()
101
103
  expect(() => v.getValue()).toThrowError('Observable already disposed')
102
104
  })
103
105
 
104
106
  it('should throw an error for subscribe() when the observer has been disposed', () => {
105
107
  const v = new ObservableValue(1)
106
- v.dispose()
108
+ v[Symbol.dispose]()
107
109
  expect(() =>
108
110
  v.subscribe(() => {
109
111
  /** */
@@ -120,10 +122,10 @@ export const observableTests = describe('Observable', () => {
120
122
  }
121
123
  }
122
124
  const v = new ObservableValue(1)
123
- const observer = v.subscribe(new Alma().Callback)
124
- v.subscribe(new Alma().Callback)
125
+ const observer = v.subscribe(() => new Alma().Callback())
126
+ v.subscribe(() => new Alma().Callback())
125
127
  expect(v.getObservers().length).toBe(2)
126
- observer.dispose()
128
+ observer[Symbol.dispose]()
127
129
  expect(v.getObservers().length).toBe(1)
128
130
  v.setValue(3)
129
131
 
@@ -1,4 +1,3 @@
1
- import type { Disposable } from './disposable.js'
2
1
  import type { ValueObserverOptions } from './value-observer.js'
3
2
  import { ValueObserver } from './value-observer.js'
4
3
 
@@ -42,9 +41,9 @@ const defaultComparer = <T>(a: T, b: T) => a !== b
42
41
  * // To update the value
43
42
  * observableValue.setValue(Math.random());
44
43
  * // if you want to dispose a single observer
45
- * observer.dispose();
44
+ * observer[Symbol.dispose]();
46
45
  * // if you want to dispose the whole observableValue with all of its observers:
47
- * observableValue.dispose();
46
+ * observableValue[Symbol.dispose]();
48
47
  * ```
49
48
  * @param T Generic argument to indicate the value type
50
49
  */
@@ -58,7 +57,7 @@ export class ObservableValue<T> implements Disposable {
58
57
  /**
59
58
  * Disposes the ObservableValue object, removes all observers
60
59
  */
61
- public dispose() {
60
+ public [Symbol.dispose]() {
62
61
  this.observers.clear()
63
62
  this._isDisposed = true
64
63
  // @ts-expect-error getting currentValue after disposing is not allowed
@@ -1,4 +1,4 @@
1
- import { describe, it, expect } from 'vitest'
1
+ import { describe, expect, it } from 'vitest'
2
2
  import { PathHelper } from './path-helper.js'
3
3
 
4
4
  /**
@@ -69,4 +69,13 @@ export const pathHelperTests = describe('PathHelper', () => {
69
69
  expect(PathHelper.getParentPath('Root')).toBe('Root')
70
70
  })
71
71
  })
72
+
73
+ describe('#normalize()', () => {
74
+ it('Should normalize the path', () => {
75
+ expect(PathHelper.normalize('Root/Example/Content')).toBe('Root/Example/Content')
76
+ expect(PathHelper.normalize('/Root/Example/Content')).toBe('Root/Example/Content')
77
+ expect(PathHelper.normalize('Root/Example/Content/')).toBe('Root/Example/Content')
78
+ expect(PathHelper.normalize('/Root/Example/Content/')).toBe('Root/Example/Content')
79
+ })
80
+ })
72
81
  })
@@ -35,7 +35,7 @@ export class PathHelper {
35
35
  * @returns the joined path string
36
36
  */
37
37
  public static joinPaths(...args: string[]) {
38
- return args.map(this.trimSlashes).join('/')
38
+ return args.map((path) => this.trimSlashes(path)).join('/')
39
39
  }
40
40
 
41
41
  /**
@@ -0,0 +1,93 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { usingAsync } from './using-async.js'
3
+ import { MockDisposable } from './using.spec.js'
4
+
5
+ export class MockAsyncDisposable implements AsyncDisposable {
6
+ private disposed = false
7
+ public isDisposed = () => this.disposed
8
+ /**
9
+ * Disposes the MockDisposable instance, calls the dispose callback
10
+ */
11
+ public async [Symbol.asyncDispose]() {
12
+ this.disposed = true
13
+ this.disposeCallback && this.disposeCallback()
14
+ }
15
+
16
+ /**
17
+ * Mock to throw an error
18
+ */
19
+ public whooops() {
20
+ throw Error('Whooops')
21
+ }
22
+
23
+ /**
24
+ * Defines the callback that will be called on dispose
25
+ */
26
+ public disposeCallback!: () => void
27
+ }
28
+
29
+ /**
30
+ * Unit tests for disposables
31
+ */
32
+ describe('usingAsync()', () => {
33
+ it('dispose should be called with usingAsync()', async () => {
34
+ const callbackMethod = vi.fn()
35
+ await usingAsync(new MockAsyncDisposable(), async (d) => {
36
+ d.disposeCallback = () => {
37
+ callbackMethod()
38
+ }
39
+ return new Promise((resolve) => {
40
+ setTimeout(resolve, 1)
41
+ })
42
+ })
43
+ expect(callbackMethod).toBeCalled()
44
+ })
45
+
46
+ it('dispose should be called when async fails', async () => {
47
+ const callbackMethod = vi.fn()
48
+ try {
49
+ await usingAsync(new MockAsyncDisposable(), async (d) => {
50
+ d.disposeCallback = () => {
51
+ callbackMethod()
52
+ }
53
+ return new Promise((_resolve, reject) => {
54
+ setTimeout(reject, 1)
55
+ })
56
+ })
57
+ } catch (error) {
58
+ /** ignore */
59
+ }
60
+ expect(callbackMethod).toBeCalled()
61
+ })
62
+
63
+ it('should await dispose for asyncs with usingAsync()', async () => {
64
+ class AsyncDispose implements AsyncDisposable {
65
+ /** flag */
66
+ public isDisposed = false
67
+ /** set isDisposed with a timeout */
68
+ public async [Symbol.asyncDispose]() {
69
+ await new Promise<void>((resolve) =>
70
+ setTimeout(() => {
71
+ this.isDisposed = true
72
+ resolve()
73
+ }, 10),
74
+ )
75
+ }
76
+ }
77
+
78
+ const asyncDispose = new AsyncDispose()
79
+ await usingAsync(asyncDispose, async () => {
80
+ /** */
81
+ })
82
+ expect(asyncDispose.isDisposed).toBe(true)
83
+ })
84
+
85
+ it('Should dispose a non-async disposable object as well', async () => {
86
+ const createdResource = await usingAsync(new MockDisposable(), async (mock) => {
87
+ expect(mock).toBeInstanceOf(MockDisposable)
88
+ return mock
89
+ })
90
+
91
+ expect(createdResource.isDisposed()).toBe(true)
92
+ })
93
+ })
@@ -0,0 +1,24 @@
1
+ import { isAsyncDisposable } from './is-async-disposable.js'
2
+ import { isDisposable } from './is-disposable.js'
3
+
4
+ /**
5
+ * Method that accepts an IDisposable resource that will be disposed after the callback
6
+ * @param resource The resource that is used in the callback and will be disposed afterwards
7
+ * @param callback The callback that will be executed asynchrounously before the resource will be disposed
8
+ * @returns A promise that will be resolved with a return value after the resource is disposed
9
+ */
10
+ export const usingAsync = async <T extends Disposable | AsyncDisposable, TReturns>(
11
+ resource: T,
12
+ callback: (r: T) => Promise<TReturns>,
13
+ ) => {
14
+ try {
15
+ return await callback(resource)
16
+ } finally {
17
+ if (isAsyncDisposable(resource)) {
18
+ await resource[Symbol.asyncDispose]()
19
+ }
20
+ if (isDisposable(resource)) {
21
+ resource[Symbol.dispose]()
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,67 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { using } from './using.js'
3
+
4
+ export class MockDisposable implements Disposable {
5
+ private disposed = false
6
+ public isDisposed = () => this.disposed
7
+ /**
8
+ * Disposes the MockDisposable instance, calls the dispose callback
9
+ */
10
+ public [Symbol.dispose]() {
11
+ this.disposed = true
12
+ this.disposeCallback && this.disposeCallback()
13
+ }
14
+
15
+ /**
16
+ * Mock to throw an error
17
+ */
18
+ public whooops() {
19
+ throw Error('Whooops')
20
+ }
21
+
22
+ /**
23
+ * Defines the callback that will be called on dispose
24
+ */
25
+ public disposeCallback!: () => void
26
+ }
27
+
28
+ describe('Using', () => {
29
+ it('Can be constructed', () => {
30
+ using(new MockDisposable(), (d) => {
31
+ expect(d).toBeInstanceOf(MockDisposable)
32
+ })
33
+ })
34
+
35
+ it('Should return a value from a callback', () => {
36
+ const returned = using(new MockDisposable(), () => {
37
+ return 1
38
+ })
39
+ expect(returned).toBe(1)
40
+ })
41
+
42
+ describe('isDisposed', () => {
43
+ it('should return a correct value before and after disposition', () => {
44
+ const d = new MockDisposable()
45
+ expect(d.isDisposed()).toBe(false)
46
+ d[Symbol.dispose]()
47
+ expect(d.isDisposed()).toBe(true)
48
+ })
49
+ })
50
+
51
+ describe('dispose()', () => {
52
+ it('should be called on error', () => {
53
+ const callbackMethod = vi.fn()
54
+ try {
55
+ using(new MockDisposable(), (d) => {
56
+ d.disposeCallback = () => {
57
+ callbackMethod()
58
+ }
59
+ d.whooops()
60
+ })
61
+ } catch {
62
+ /** ignore */
63
+ }
64
+ expect(callbackMethod).toBeCalled()
65
+ })
66
+ })
67
+ })
package/src/using.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Method that accepts an IDisposable resource that will be disposed after the callback
3
+ * @param resource The resource that is used in the callback and will be disposed afterwards
4
+ * @param callback The callback that will be executed synchrounously before the resource will be disposed
5
+ * @returns the value that will be returned by the callback method
6
+ */
7
+ export const using = <T extends Disposable, TReturns>(resource: T, callback: (r: T) => TReturns) => {
8
+ try {
9
+ return callback(resource)
10
+ } finally {
11
+ resource[Symbol.dispose]()
12
+ }
13
+ }
@@ -1,4 +1,3 @@
1
- import type { Disposable } from './disposable.js'
2
1
  import type { ObservableValue, ValueChangeCallback } from './observable-value.js'
3
2
 
4
3
  export type ValueObserverOptions<T> = {
@@ -21,9 +20,9 @@ export type ValueObserverOptions<T> = {
21
20
  * // To update the value
22
21
  * observableValue.setValue(Math.random());
23
22
  * // if you want to dispose a single observer
24
- * observer.dispose();
23
+ * observer[Symbol.dispose]();
25
24
  * // if you want to dispose the whole observableValue with all of its observers:
26
- * observableValue.dispose();
25
+ * observableValue[Symbol.dispose]();
27
26
  * ```
28
27
  * @param T This type parameter is the value type to observe
29
28
  */
@@ -31,7 +30,7 @@ export class ValueObserver<T> implements Disposable {
31
30
  /**
32
31
  * Disposes the ValueObserver instance. Unsubscribes from the observable
33
32
  */
34
- public dispose() {
33
+ public [Symbol.dispose]() {
35
34
  this.observable.unsubscribe(this)
36
35
  }
37
36
 
@@ -1,49 +0,0 @@
1
- /**
2
- *
3
- * You can implement *IDisposable* resources and use them with a *using()* or *usingAsync()* syntax.
4
- *
5
- * Usage example:
6
- *
7
- * ```ts
8
- * class Resource implements IDisposable{
9
- * dispose(){
10
- * // cleanup logics
11
- * }
12
- * }
13
- *
14
- *
15
- * using(new Resource(), (resource)=>{
16
- * // do something with the resource
17
- * })
18
- *
19
- * usingAsync(new Resource(), async (resource)=>{
20
- * // do something with the resource, allows awaiting promises
21
- * })
22
- * ```
23
- */
24
- /** */
25
- /**
26
- * Resources in using an usingAsync should implement this interface
27
- *
28
- */
29
- export interface Disposable {
30
- /**
31
- * Method called when the IDisposable is disposed.
32
- */
33
- dispose: () => void | Promise<void>;
34
- }
35
- /**
36
- * Method that accepts an IDisposable resource that will be disposed after the callback
37
- * @param resource The resource that is used in the callback and will be disposed afterwards
38
- * @param callback The callback that will be executed synchrounously before the resource will be disposed
39
- * @returns the value that will be returned by the callback method
40
- */
41
- export declare const using: <T extends Disposable, TReturns>(resource: T, callback: (r: T) => TReturns) => TReturns;
42
- /**
43
- * Method that accepts an IDisposable resource that will be disposed after the callback
44
- * @param resource The resource that is used in the callback and will be disposed afterwards
45
- * @param callback The callback that will be executed asynchrounously before the resource will be disposed
46
- * @returns A promise that will be resolved with a return value after the resource is disposed
47
- */
48
- export declare const usingAsync: <T extends Disposable, TReturns>(resource: T, callback: (r: T) => Promise<TReturns>) => Promise<TReturns>;
49
- //# sourceMappingURL=disposable.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"disposable.d.ts","sourceRoot":"","sources":["../src/disposable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM;AAEN;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpC;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,6CAA8C,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,KAAK,QAAQ,aAM9F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,6CACX,CAAC,YACD,CAAC,CAAC,EAAE,CAAC,KAAK,QAAQ,QAAQ,CAAC,sBAUtC,CAAA"}
package/esm/disposable.js DELETED
@@ -1,56 +0,0 @@
1
- /**
2
- *
3
- * You can implement *IDisposable* resources and use them with a *using()* or *usingAsync()* syntax.
4
- *
5
- * Usage example:
6
- *
7
- * ```ts
8
- * class Resource implements IDisposable{
9
- * dispose(){
10
- * // cleanup logics
11
- * }
12
- * }
13
- *
14
- *
15
- * using(new Resource(), (resource)=>{
16
- * // do something with the resource
17
- * })
18
- *
19
- * usingAsync(new Resource(), async (resource)=>{
20
- * // do something with the resource, allows awaiting promises
21
- * })
22
- * ```
23
- */
24
- /** */
25
- /**
26
- * Method that accepts an IDisposable resource that will be disposed after the callback
27
- * @param resource The resource that is used in the callback and will be disposed afterwards
28
- * @param callback The callback that will be executed synchrounously before the resource will be disposed
29
- * @returns the value that will be returned by the callback method
30
- */
31
- export const using = (resource, callback) => {
32
- try {
33
- return callback(resource);
34
- }
35
- finally {
36
- resource.dispose();
37
- }
38
- };
39
- /**
40
- * Method that accepts an IDisposable resource that will be disposed after the callback
41
- * @param resource The resource that is used in the callback and will be disposed afterwards
42
- * @param callback The callback that will be executed asynchrounously before the resource will be disposed
43
- * @returns A promise that will be resolved with a return value after the resource is disposed
44
- */
45
- export const usingAsync = async (resource, callback) => {
46
- try {
47
- return await callback(resource);
48
- }
49
- finally {
50
- const disposeResult = resource.dispose();
51
- if (disposeResult instanceof Promise) {
52
- await disposeResult;
53
- }
54
- }
55
- };
56
- //# sourceMappingURL=disposable.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"disposable.js","sourceRoot":"","sources":["../src/disposable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM;AAaN;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAiC,QAAW,EAAE,QAA4B,EAAE,EAAE;IACjG,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC3B,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,OAAO,EAAE,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,QAAW,EACX,QAAqC,EACrC,EAAE;IACF,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACjC,CAAC;YAAS,CAAC;QACT,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAA;QACxC,IAAI,aAAa,YAAY,OAAO,EAAE,CAAC;YACrC,MAAM,aAAa,CAAA;QACrB,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"disposable.spec.d.ts","sourceRoot":"","sources":["../src/disposable.spec.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGjD,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,QAAQ,CAAQ;IACjB,UAAU,gBAAsB;IACvC;;OAEG;IACI,OAAO,aAGb;IAED;;OAEG;IACI,OAAO;IAId;;OAEG;IACI,eAAe,EAAG,MAAM,IAAI,CAAA;CACpC;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,qCAkG1B,CAAA"}
@@ -1,118 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { using, usingAsync } from './disposable.js';
3
- export class MockDisposable {
4
- disposed = false;
5
- isDisposed = () => this.disposed;
6
- /**
7
- * Disposes the MockDisposable instance, calls the dispose callback
8
- */
9
- dispose = () => {
10
- this.disposed = true;
11
- this.disposeCallback && this.disposeCallback();
12
- };
13
- /**
14
- * Mock to throw an error
15
- */
16
- whooops() {
17
- throw Error('Whooops');
18
- }
19
- /**
20
- * Defines the callback that will be called on dispose
21
- */
22
- disposeCallback;
23
- }
24
- /**
25
- * Unit tests for disposables
26
- */
27
- export const disposableTests = describe('Disposable', () => {
28
- it('Can be constructed', () => {
29
- using(new MockDisposable(), (d) => {
30
- expect(d).toBeInstanceOf(MockDisposable);
31
- });
32
- });
33
- it('Should return a value from a callback', () => {
34
- const returned = using(new MockDisposable(), () => {
35
- return 1;
36
- });
37
- expect(returned).toBe(1);
38
- });
39
- it('Should return a value from an async callback', async () => {
40
- const returned = await usingAsync(new MockDisposable(), async () => {
41
- return 2;
42
- });
43
- expect(returned).toBe(2);
44
- });
45
- describe('isDisposed', () => {
46
- it('should return a correct value before and after disposition', () => {
47
- const d = new MockDisposable();
48
- expect(d.isDisposed()).toBe(false);
49
- d.dispose();
50
- expect(d.isDisposed()).toBe(true);
51
- });
52
- });
53
- describe('dispose()', () => {
54
- it('should be called on error', () => {
55
- const callbackMethod = vi.fn();
56
- try {
57
- using(new MockDisposable(), (d) => {
58
- d.disposeCallback = () => {
59
- callbackMethod();
60
- };
61
- d.whooops();
62
- });
63
- }
64
- catch {
65
- /** ignore */
66
- }
67
- expect(callbackMethod).toBeCalled();
68
- });
69
- it('should be called with usingAsync()', async () => {
70
- const callbackMethod = vi.fn();
71
- await usingAsync(new MockDisposable(), async (d) => {
72
- d.disposeCallback = () => {
73
- callbackMethod();
74
- };
75
- return new Promise((resolve) => {
76
- setTimeout(resolve, 1);
77
- });
78
- });
79
- expect(callbackMethod).toBeCalled();
80
- });
81
- it('should be called when async fails', async () => {
82
- const callbackMethod = vi.fn();
83
- try {
84
- await usingAsync(new MockDisposable(), async (d) => {
85
- d.disposeCallback = () => {
86
- callbackMethod();
87
- };
88
- return new Promise((_resolve, reject) => {
89
- setTimeout(reject, 1);
90
- });
91
- });
92
- }
93
- catch (error) {
94
- /** ignore */
95
- }
96
- expect(callbackMethod).toBeCalled();
97
- });
98
- it('should await dispose for asyncs with usingAsync()', async () => {
99
- class AsyncDispose {
100
- /** flag */
101
- isDisposed = false;
102
- /** set isDisposed with a timeout */
103
- async dispose() {
104
- await new Promise((resolve) => setTimeout(() => {
105
- this.isDisposed = true;
106
- resolve();
107
- }, 10));
108
- }
109
- }
110
- const asyncDispose = new AsyncDispose();
111
- await usingAsync(asyncDispose, async () => {
112
- /** */
113
- });
114
- expect(asyncDispose.isDisposed).toBe(true);
115
- });
116
- });
117
- });
118
- //# sourceMappingURL=disposable.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"disposable.spec.js","sourceRoot":"","sources":["../src/disposable.spec.ts"],"names":[],"mappings":"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"}