Disposiq is a utility collection of Dispose pattern
npm install @tioniq/disposiqsh
npm install @tioniq/disposiq
`
$3
`typescript
import { DisposableAction } from '@tioniq/disposiq'
// The action will be executed only once when the disposable is disposed
const disposable = new DisposableAction(() => {
console.log('Resource cleaned up')
})
disposable.dispose() // Output: Resource cleaned up
disposable.dispose() // No output
`
$3
`typescript
import { DisposableStore, DisposableAction } from '@tioniq/disposiq'
const store = new DisposableStore()
const disposable1 = new DisposableAction(() => {
console.log('Resource cleaned up 1')
})
// DisposableStore accepts functions as disposables
const disposable2 = () => {
console.log('Resource cleaned up 2')
}
store.add(disposable1)
store.add(disposable2)
store.dispose() // Output: Resource cleaned up 1, Resource cleaned up 2
const disposable3 = () => {
console.log('Resource cleaned up 3')
}
// After disposing of the store, all disposables added to the store will be disposed of immediately
store.add(disposable3) // Output: Resource cleaned up 3
`
$3
`typescript
import { DisposableStore, DisposableAction } from '@tioniq/disposiq'
const store = new DisposableStore()
const disposable1 = new DisposableAction(() => {
console.log('Resource cleaned up 1')
})
const disposable2 = new DisposableAction(() => {
console.log('Resource cleaned up 2')
})
// You can add multiple disposables at once
store.add(disposable1, disposable2)
// Dispose of the current disposables in the store without disposing of the store itself
store.disposeCurrent() // Output: Resource cleaned up 1, Resource cleaned up 2
// The store is still active, but all contained disposables are disposed of and removed from the store
// You can now add new disposables to the store
store.add(() => {
console.log('Resource cleaned up 3')
}) // No output
// Dispose the store completely
store.dispose() // Output: Resource cleaned up 3
`
$3
`typescript
import { DisposableStore, DisposableAction } from '@tioniq/disposiq'
// When using the new 'using' keyword, the disposable will be disposed of automatically when it goes out of scope
{
using disposable = new DisposableAction(() => {
console.log('Resource cleaned up')
})
}
// Output: Resource cleaned up
// It also works with other disposable objects from the library. For example, DisposableStore:
{
using store = new DisposableStore()
store.add(new DisposableAction(() => {
console.log('Resource cleaned up')
}))
} // Output: Resource cleaned up
`
$3
There is a way to achieve the same result without use of the 'using' keyword. You can use the 'using' function instead.
`typescript
import { Disposable, using } from '@tioniq/disposiq'
using(new Client(), async (client) => {
await client.makeRequest() // Output: Request made
}) // Output: Resource cleaned up
class Client extends Disposable {
constructor() {
super()
this.addDisposable(() => {
console.log('Resource cleaned up')
})
}
async makeRequest() {
console.log('Request made')
}
}
`
You can find a simple example here.
Also, check out another project built with Disposiq: Eventiq.
It's an implementation of the Observer pattern using Disposiq. It's an interesting project worth exploring!
Extensions
The library is flexible and can be extended to custom functionality. All classes in the library extend the Disposiq
class, so you can add custom methods to the class.
For example, you can add a custom method to the Disposiq class:
`typescript
import { Disposiq, DisposableAction, IDisposable } from '@tioniq/disposiq'
declare module '@tioniq/disposiq' {
interface Disposiq {
togetherWith(other: IDisposable): Disposiq
}
}
Disposiq.prototype.togetherWith = function (this: Disposiq, other: IDisposable): Disposiq {
return new DisposableAction(() => {
this.dispose()
other.dispose()
})
}
`
Inspiration
This library is inspired by the
- Dispose pattern and its principles
- The usage of disposables in Monaco Editor and
VSCode
- The usage of disposables
in RxJava
and ReactiveX
- The C# IDisposable interface
- The core concept used by major projects like Angular, React, Vue, etc., which utilize a return function or component
method to clean up resources
Documentation
$3
| Interface | Short Description |
|------------------------------|-------------------------------------------------------------------|
| IDisposable | Base interface for disposables |
| IAsyncDisposable | Base interface for asynchronous disposables |
| DisposeFunc | A function with no parameters |
| DisposableLike | A function or disposable object |
| AsyncDisposableLike | A function that returns a Promise or an async disposable object |
| AsyncDisposeFunc | An asynchronous function with no parameters |
| IDisposablesContainer | A container for a collection of disposables |
| DisposableAware | Represents a disposable that is aware of its state |
| DisposableCompat | Represents a disposable compatible with the 'using' keyword |
| DisposableAwareCompat | Combines DisposableAware and DisposableCompat |
| AsyncDisposableAware | An asynchronous disposable that is aware of its state |
| AsyncDisposableCompat | An asynchronous disposable compatible with the 'using' keyword |
| AsyncDisposableAwareCompat | Combines AsyncDisposableAware and AsyncDisposableCompat |
$3
| Class | Short Description | Aliases |
|-----------------------------|---------------------------------------------------------------------------|-----------------------------|
| Disposiq | Base class for all library disposables | - BaseDisposable |
| AsyncDisposiq | Base class for all library asynchronous disposables | - BaseAsyncDisposable |
| DisposableAction | A container for a function to be called on dispose | - |
| AsyncDisposableAction | A container for an asynchronous function to be called on dispose | - |
| DisposableStore | A container for disposables | CompositeDisposable |
| AsyncDisposableStore | A container for async disposables | CompositeAsyncDisposable |
| DisposableMapStore | A container for disposables stored by a key | DisposableDictionary |
| DisposableContainer | A container for a disposable object | SerialDisposable |
| BoolDisposable | A object that aware of its disposed state | BooleanDisposable |
| SafeActionDisposable | A container for a function that is safely called on dispose | ActionSafeDisposable |
| SafeAsyncActionDisposable | A container for an asynchronous function that is safely called on dispose | AsyncActionSafeDisposable |
| AbortDisposable | A wrapper for AbortController to make it disposable | - |
| ObjectDisposedException | An exception thrown when an object is already disposed | - |
$3
| Class | Short Description | Aliases |
|---------------------------|----------------------------------------------------------------------------------------------------------------------|--------------------|
| disposeAll | Dispose of all disposables in the array safely, allowing array modification during disposal | disposeAllSafe |
| disposeAllUnsafe | Dispose of all disposables in the array unsafely, array modification during disposal is dangerous | - |
| disposeAllSafely | Dispose of all disposables in the array safely, with error callback, array modification during disposal is dangerous | - |
| createDisposable | Create a disposable object from a given parameter | toDisposable |
| createDisposableCompat | Create a disposable object from a given parameter compatible with the 'using' keyword | toDisposableCompat |
| disposableFromEvent | Create a disposable object from an event listener | on |
| disposableFromEventOnce | Create a disposable object from an event listener that disposes after the first call | once |
| isDisposable | Check if the object is a disposable object | - |
| isDisposableLike | Check if the object is a disposable-like | - |
| isDisposableCompat | Check if the object is a disposable object that is compatible with the 'using' keyword | - |
| isAsyncDisposableCompat | Check if the object is an asynchronous disposable object that is compatible with the 'using' keyword | - |
| isSystemDisposable | Check if the object is compatible with the system 'using' keyword | - |
| isSystemAsyncDisposable | Check if the object is compatible with the system 'await using' keyword | - |
| addEventListener` | Add an event listener to the target object and return a disposable object. Useful for DOM events | - |