@reactive-js/disposable
Advanced tools
Comparing version 0.0.24 to 0.0.25
@@ -1,18 +0,20 @@ | ||
export declare type DisposableOrTeardown = DisposableLike | (() => void); | ||
export interface ErrorLike { | ||
readonly cause: unknown; | ||
} | ||
export declare type DisposableOrTeardown = DisposableLike | ((error?: ErrorLike) => void); | ||
export interface DisposableLike { | ||
readonly isDisposed: boolean; | ||
add(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(): boolean; | ||
remove(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(error?: ErrorLike): void; | ||
} | ||
export declare const createDisposable: (onDispose?: (() => void) | undefined) => DisposableLike; | ||
export declare const createDisposable: (onDispose?: ((error?: ErrorLike | undefined) => void) | undefined) => DisposableLike; | ||
export declare const disposed: DisposableLike; | ||
export declare const throwIfDisposed: (disposable: DisposableLike) => void; | ||
export interface DelegatingDisposableLike { | ||
readonly disposable: DisposableLike; | ||
} | ||
export declare const disposableMixin: { | ||
add(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
dispose(this: DelegatingDisposableLike): boolean; | ||
remove(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
add<This extends DisposableLike>(this: { | ||
disposable: DisposableLike; | ||
} & This, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): This; | ||
dispose(this: { | ||
disposable: DisposableLike; | ||
}, error?: ErrorLike | undefined): void; | ||
}; | ||
@@ -19,0 +21,0 @@ export interface SerialDisposableLike extends DisposableLike { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const doDispose = (disposable) => { | ||
const doDispose = (disposable, error) => { | ||
if (disposable instanceof Function) { | ||
try { | ||
disposable(); | ||
disposable(error); | ||
} | ||
@@ -12,3 +12,3 @@ catch (_) { | ||
else { | ||
disposable.dispose(); | ||
disposable.dispose(error); | ||
} | ||
@@ -20,2 +20,3 @@ }; | ||
this.disposables = []; | ||
this.error = undefined; | ||
} | ||
@@ -25,3 +26,3 @@ add(...disposables) { | ||
for (const d of disposables) { | ||
doDispose(d); | ||
doDispose(d, this.error); | ||
} | ||
@@ -43,24 +44,13 @@ } | ||
} | ||
dispose() { | ||
const isDisposed = this.isDisposed; | ||
if (!isDisposed) { | ||
dispose(error) { | ||
if (!this.isDisposed) { | ||
this.isDisposed = true; | ||
this.error = error; | ||
let disposable = this.disposables.shift(); | ||
while (disposable !== undefined) { | ||
doDispose(disposable); | ||
doDispose(disposable, error); | ||
disposable = this.disposables.shift(); | ||
} | ||
} | ||
return !isDisposed; | ||
} | ||
remove(...disposables) { | ||
if (!this.isDisposed) { | ||
for (const d of disposables) { | ||
if (this.doRemove(d)) { | ||
doDispose(d); | ||
} | ||
} | ||
} | ||
return this; | ||
} | ||
doRemove(d) { | ||
@@ -92,8 +82,3 @@ const index = this.disposables.indexOf(d); | ||
isDisposed: true, | ||
dispose() { | ||
return false; | ||
}, | ||
remove(..._) { | ||
return _disposed; | ||
}, | ||
dispose(_) { }, | ||
}; | ||
@@ -111,9 +96,5 @@ exports.disposed = _disposed; | ||
}, | ||
dispose() { | ||
return this.disposable.dispose(); | ||
dispose(error) { | ||
this.disposable.dispose(error); | ||
}, | ||
remove(disposable, ...disposables) { | ||
this.disposable.remove(disposable, ...disposables); | ||
return this; | ||
}, | ||
}; | ||
@@ -123,6 +104,5 @@ class SerialDisposableImpl { | ||
this._inner = exports.disposed; | ||
this.add = exports.disposableMixin.add; | ||
this.disposable = exports.createDisposable(); | ||
this.add = exports.disposableMixin.add; | ||
this.dispose = exports.disposableMixin.dispose; | ||
this.remove = exports.disposableMixin.remove; | ||
} | ||
@@ -140,3 +120,4 @@ get inner() { | ||
if (oldInner !== newInner) { | ||
this.add(newInner).remove(oldInner); | ||
this.add(newInner); | ||
oldInner.dispose(); | ||
} | ||
@@ -143,0 +124,0 @@ } |
@@ -1,18 +0,20 @@ | ||
export declare type DisposableOrTeardown = DisposableLike | (() => void); | ||
export interface ErrorLike { | ||
readonly cause: unknown; | ||
} | ||
export declare type DisposableOrTeardown = DisposableLike | ((error?: ErrorLike) => void); | ||
export interface DisposableLike { | ||
readonly isDisposed: boolean; | ||
add(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(): boolean; | ||
remove(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(error?: ErrorLike): void; | ||
} | ||
export declare const createDisposable: (onDispose?: (() => void) | undefined) => DisposableLike; | ||
export declare const createDisposable: (onDispose?: ((error?: ErrorLike | undefined) => void) | undefined) => DisposableLike; | ||
export declare const disposed: DisposableLike; | ||
export declare const throwIfDisposed: (disposable: DisposableLike) => void; | ||
export interface DelegatingDisposableLike { | ||
readonly disposable: DisposableLike; | ||
} | ||
export declare const disposableMixin: { | ||
add(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
dispose(this: DelegatingDisposableLike): boolean; | ||
remove(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
add<This extends DisposableLike>(this: { | ||
disposable: DisposableLike; | ||
} & This, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): This; | ||
dispose(this: { | ||
disposable: DisposableLike; | ||
}, error?: ErrorLike | undefined): void; | ||
}; | ||
@@ -19,0 +21,0 @@ export interface SerialDisposableLike extends DisposableLike { |
@@ -1,5 +0,5 @@ | ||
const doDispose = (disposable) => { | ||
const doDispose = (disposable, error) => { | ||
if (disposable instanceof Function) { | ||
try { | ||
disposable(); | ||
disposable(error); | ||
} | ||
@@ -10,3 +10,3 @@ catch (_) { | ||
else { | ||
disposable.dispose(); | ||
disposable.dispose(error); | ||
} | ||
@@ -18,2 +18,3 @@ }; | ||
this.disposables = []; | ||
this.error = undefined; | ||
} | ||
@@ -23,3 +24,3 @@ add(...disposables) { | ||
for (const d of disposables) { | ||
doDispose(d); | ||
doDispose(d, this.error); | ||
} | ||
@@ -41,24 +42,13 @@ } | ||
} | ||
dispose() { | ||
const isDisposed = this.isDisposed; | ||
if (!isDisposed) { | ||
dispose(error) { | ||
if (!this.isDisposed) { | ||
this.isDisposed = true; | ||
this.error = error; | ||
let disposable = this.disposables.shift(); | ||
while (disposable !== undefined) { | ||
doDispose(disposable); | ||
doDispose(disposable, error); | ||
disposable = this.disposables.shift(); | ||
} | ||
} | ||
return !isDisposed; | ||
} | ||
remove(...disposables) { | ||
if (!this.isDisposed) { | ||
for (const d of disposables) { | ||
if (this.doRemove(d)) { | ||
doDispose(d); | ||
} | ||
} | ||
} | ||
return this; | ||
} | ||
doRemove(d) { | ||
@@ -90,8 +80,3 @@ const index = this.disposables.indexOf(d); | ||
isDisposed: true, | ||
dispose() { | ||
return false; | ||
}, | ||
remove(..._) { | ||
return _disposed; | ||
}, | ||
dispose(_) { }, | ||
}; | ||
@@ -109,9 +94,5 @@ export const disposed = _disposed; | ||
}, | ||
dispose() { | ||
return this.disposable.dispose(); | ||
dispose(error) { | ||
this.disposable.dispose(error); | ||
}, | ||
remove(disposable, ...disposables) { | ||
this.disposable.remove(disposable, ...disposables); | ||
return this; | ||
}, | ||
}; | ||
@@ -121,6 +102,5 @@ class SerialDisposableImpl { | ||
this._inner = disposed; | ||
this.add = disposableMixin.add; | ||
this.disposable = createDisposable(); | ||
this.add = disposableMixin.add; | ||
this.dispose = disposableMixin.dispose; | ||
this.remove = disposableMixin.remove; | ||
} | ||
@@ -138,3 +118,4 @@ get inner() { | ||
if (oldInner !== newInner) { | ||
this.add(newInner).remove(oldInner); | ||
this.add(newInner); | ||
oldInner.dispose(); | ||
} | ||
@@ -141,0 +122,0 @@ } |
@@ -1,18 +0,20 @@ | ||
export declare type DisposableOrTeardown = DisposableLike | (() => void); | ||
export interface ErrorLike { | ||
readonly cause: unknown; | ||
} | ||
export declare type DisposableOrTeardown = DisposableLike | ((error?: ErrorLike) => void); | ||
export interface DisposableLike { | ||
readonly isDisposed: boolean; | ||
add(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(): boolean; | ||
remove(disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): this; | ||
dispose(error?: ErrorLike): void; | ||
} | ||
export declare const createDisposable: (onDispose?: (() => void) | undefined) => DisposableLike; | ||
export declare const createDisposable: (onDispose?: ((error?: ErrorLike | undefined) => void) | undefined) => DisposableLike; | ||
export declare const disposed: DisposableLike; | ||
export declare const throwIfDisposed: (disposable: DisposableLike) => void; | ||
export interface DelegatingDisposableLike { | ||
readonly disposable: DisposableLike; | ||
} | ||
export declare const disposableMixin: { | ||
add(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
dispose(this: DelegatingDisposableLike): boolean; | ||
remove(this: DelegatingDisposableLike, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): any; | ||
add<This extends DisposableLike>(this: { | ||
disposable: DisposableLike; | ||
} & This, disposable: DisposableOrTeardown, ...disposables: DisposableOrTeardown[]): This; | ||
dispose(this: { | ||
disposable: DisposableLike; | ||
}, error?: ErrorLike | undefined): void; | ||
}; | ||
@@ -19,0 +21,0 @@ export interface SerialDisposableLike extends DisposableLike { |
@@ -22,3 +22,2 @@ | ||
* [dispose](disposablelike.md#dispose) | ||
* [remove](disposablelike.md#remove) | ||
@@ -54,23 +53,12 @@ ## Properties | ||
▸ **dispose**(): *boolean* | ||
▸ **dispose**(`error?`: [ErrorLike](errorlike.md)): *void* | ||
Dispose the resource, the operation should be idempotent. | ||
**Returns:** *boolean* | ||
___ | ||
### remove | ||
▸ **remove**(`disposable`: [DisposableOrTeardown](../README.md#disposableorteardown), ...`disposables`: [DisposableOrTeardown](../README.md#disposableorteardown)[]): *this* | ||
Removes and disposes the given disposables if they are part of this container. | ||
**Parameters:** | ||
Name | Type | Description | | ||
------ | ------ | ------ | | ||
`disposable` | [DisposableOrTeardown](../README.md#disposableorteardown) | - | | ||
`...disposables` | [DisposableOrTeardown](../README.md#disposableorteardown)[] | | | ||
Name | Type | | ||
------ | ------ | | ||
`error?` | [ErrorLike](errorlike.md) | | ||
**Returns:** *this* | ||
**Returns:** *void* |
@@ -8,4 +8,4 @@ | ||
* [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md) | ||
* [DisposableLike](interfaces/disposablelike.md) | ||
* [ErrorLike](interfaces/errorlike.md) | ||
* [SerialDisposableLike](interfaces/serialdisposablelike.md) | ||
@@ -95,4 +95,8 @@ | ||
▸ **add**(`this`: [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md), `disposable`: [DisposableOrTeardown](README.md#disposableorteardown), ...`disposables`: [DisposableOrTeardown](README.md#disposableorteardown)[]): *any* | ||
▸ **add**<**This**>(`this`: object & This, `disposable`: [DisposableOrTeardown](README.md#disposableorteardown), ...`disposables`: [DisposableOrTeardown](README.md#disposableorteardown)[]): *This* | ||
**Type parameters:** | ||
▪ **This**: *[DisposableLike](interfaces/disposablelike.md)* | ||
**Parameters:** | ||
@@ -102,11 +106,11 @@ | ||
------ | ------ | | ||
`this` | [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md) | | ||
`this` | object & This | | ||
`disposable` | [DisposableOrTeardown](README.md#disposableorteardown) | | ||
`...disposables` | [DisposableOrTeardown](README.md#disposableorteardown)[] | | ||
**Returns:** *any* | ||
**Returns:** *This* | ||
### dispose | ||
▸ **dispose**(`this`: [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md)): *boolean* | ||
▸ **dispose**(`this`: object, `error?`: [ErrorLike](interfaces/errorlike.md)): *void* | ||
@@ -117,18 +121,5 @@ **Parameters:** | ||
------ | ------ | | ||
`this` | [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md) | | ||
`this` | object | | ||
`error?` | [ErrorLike](interfaces/errorlike.md) | | ||
**Returns:** *boolean* | ||
### remove | ||
▸ **remove**(`this`: [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md), `disposable`: [DisposableOrTeardown](README.md#disposableorteardown), ...`disposables`: [DisposableOrTeardown](README.md#disposableorteardown)[]): *any* | ||
**Parameters:** | ||
Name | Type | | ||
------ | ------ | | ||
`this` | [DelegatingDisposableLike](interfaces/delegatingdisposablelike.md) | | ||
`disposable` | [DisposableOrTeardown](README.md#disposableorteardown) | | ||
`...disposables` | [DisposableOrTeardown](README.md#disposableorteardown)[] | | ||
**Returns:** *any* | ||
**Returns:** *void* |
{ | ||
"name": "@reactive-js/disposable", | ||
"version": "0.0.24", | ||
"version": "0.0.25", | ||
"main": "dist/cjs/index.js", | ||
@@ -65,3 +65,3 @@ "module": "dist/esm5/index.js", | ||
}, | ||
"gitHead": "19ba0c0276afd9ca23aae5497c04c1f63d2d72a4" | ||
"gitHead": "c23221b85a7fc7f4252783af164069c6397f41de" | ||
} |
@@ -1,3 +0,13 @@ | ||
export type DisposableOrTeardown = DisposableLike | (() => void); | ||
/** | ||
* A wrapper around a caught error to handle wierd corner cases like | ||
* a function which throws undefined or a string. | ||
*/ | ||
export interface ErrorLike { | ||
readonly cause: unknown; | ||
} | ||
export type DisposableOrTeardown = | ||
| DisposableLike | ||
| ((error?: ErrorLike) => void); | ||
/** | ||
@@ -26,20 +36,9 @@ * Represents an unmanaged resource that can be disposed. | ||
*/ | ||
dispose(): boolean; | ||
/** | ||
* Removes and disposes the given disposables if they are part of this container. | ||
* | ||
* @param disposable | ||
* @param disposables | ||
*/ | ||
remove( | ||
disposable: DisposableOrTeardown, | ||
...disposables: DisposableOrTeardown[] | ||
): this; | ||
dispose(error?: ErrorLike): void; | ||
} | ||
const doDispose = (disposable: DisposableOrTeardown) => { | ||
const doDispose = (disposable: DisposableOrTeardown, error?: ErrorLike) => { | ||
if (disposable instanceof Function) { | ||
try { | ||
disposable(); | ||
disposable(error); | ||
} catch (_) { | ||
@@ -51,3 +50,3 @@ /* Proactively catch exceptions thrown in teardown logic. Teardown functions | ||
} else { | ||
disposable.dispose(); | ||
disposable.dispose(error); | ||
} | ||
@@ -59,2 +58,3 @@ }; | ||
private readonly disposables: Array<DisposableOrTeardown> = []; | ||
private error?: ErrorLike = undefined; | ||
@@ -64,3 +64,3 @@ add(...disposables: DisposableOrTeardown[]) { | ||
for (const d of disposables) { | ||
doDispose(d); | ||
doDispose(d, this.error); | ||
} | ||
@@ -84,27 +84,15 @@ } else { | ||
dispose(): boolean { | ||
const isDisposed = this.isDisposed; | ||
if (!isDisposed) { | ||
dispose(error?: ErrorLike) { | ||
if (!this.isDisposed) { | ||
this.isDisposed = true; | ||
this.error = error; | ||
let disposable = this.disposables.shift(); | ||
while (disposable !== undefined) { | ||
doDispose(disposable); | ||
doDispose(disposable, error); | ||
disposable = this.disposables.shift(); | ||
} | ||
} | ||
return !isDisposed; | ||
} | ||
remove(...disposables: DisposableOrTeardown[]) { | ||
if (!this.isDisposed) { | ||
for (const d of disposables) { | ||
if (this.doRemove(d)) { | ||
doDispose(d); | ||
} | ||
} | ||
} | ||
return this; | ||
} | ||
private doRemove(d: DisposableOrTeardown): boolean { | ||
@@ -125,3 +113,5 @@ const index = this.disposables.indexOf(d); | ||
*/ | ||
export const createDisposable = (onDispose?: () => void): DisposableLike => { | ||
export const createDisposable = ( | ||
onDispose?: (error?: ErrorLike) => void, | ||
): DisposableLike => { | ||
const disposable = new DisposableImpl(); | ||
@@ -142,8 +132,3 @@ if (onDispose !== undefined) { | ||
isDisposed: true, | ||
dispose() { | ||
return false; | ||
}, | ||
remove(..._: DisposableOrTeardown[]) { | ||
return _disposed; | ||
}, | ||
dispose(_?: ErrorLike) {}, | ||
}; | ||
@@ -167,26 +152,14 @@ | ||
export interface DelegatingDisposableLike { | ||
readonly disposable: DisposableLike; | ||
} | ||
export const disposableMixin = { | ||
add( | ||
this: DelegatingDisposableLike, | ||
add<This extends DisposableLike>( | ||
this: { disposable: DisposableLike } & This, | ||
disposable: DisposableOrTeardown, | ||
...disposables: DisposableOrTeardown[] | ||
): any { | ||
): This { | ||
this.disposable.add(disposable, ...disposables); | ||
return this; | ||
}, | ||
dispose(this: DelegatingDisposableLike): boolean { | ||
return this.disposable.dispose(); | ||
dispose(this: { disposable: DisposableLike }, error?: ErrorLike) { | ||
this.disposable.dispose(error); | ||
}, | ||
remove( | ||
this: DelegatingDisposableLike, | ||
disposable: DisposableOrTeardown, | ||
...disposables: DisposableOrTeardown[] | ||
): any { | ||
this.disposable.remove(disposable, ...disposables); | ||
return this; | ||
}, | ||
}; | ||
@@ -208,7 +181,6 @@ | ||
_inner: DisposableLike = disposed; | ||
readonly add = disposableMixin.add; | ||
readonly disposable = createDisposable(); | ||
readonly dispose = disposableMixin.dispose; | ||
add = disposableMixin.add; | ||
dispose = disposableMixin.dispose; | ||
remove = disposableMixin.remove; | ||
get inner() { | ||
@@ -226,3 +198,4 @@ return this._inner; | ||
if (oldInner !== newInner) { | ||
this.add(newInner).remove(oldInner); | ||
this.add(newInner); | ||
oldInner.dispose(); | ||
} | ||
@@ -229,0 +202,0 @@ } |
@@ -49,14 +49,11 @@ import { | ||
test("remove", () => { | ||
const disposable = createDisposable(); | ||
test("disposed", () => { | ||
expect(disposed.isDisposed).toBeTruthy(); | ||
const child = createDisposable(); | ||
disposed.add(child); | ||
disposable.add(child).remove(child); | ||
expect(child.isDisposed).toBeTruthy(); | ||
}); | ||
test("disposed", () => { | ||
expect(disposed.isDisposed).toBeTruthy(); | ||
}); | ||
test("dispose when teardown throws an exception", () => { | ||
@@ -68,2 +65,26 @@ const disposable = createDisposable(() => { | ||
}); | ||
test("dispose with error", () => { | ||
const error = { cause: null }; | ||
const childTeardown = jest.fn(); | ||
const child = createDisposable().add(e => childTeardown(e)); | ||
const teardown = jest.fn(); | ||
const disposable = createDisposable() | ||
.add(child) | ||
.add(e => teardown(e)); | ||
disposable.dispose(error); | ||
const teardown2 = jest.fn(); | ||
disposable.add(e => teardown2(e)); | ||
const childTeardown2 = jest.fn(); | ||
const child2 = createDisposable().add(e => childTeardown2(e)); | ||
disposable.add(child2); | ||
expect(childTeardown).toBeCalledWith(error); | ||
expect(teardown).toBeCalledWith(error); | ||
expect(childTeardown2).toBeCalledWith(error); | ||
expect(teardown2).toBeCalledWith(error); | ||
}); | ||
}); | ||
@@ -70,0 +91,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
350478
636