Skip to content

Instantly share code, notes, and snippets.

@tzkmx
Created September 13, 2023 05:22
Show Gist options
  • Save tzkmx/a0161c195b3485c6835569422c269f45 to your computer and use it in GitHub Desktop.
Save tzkmx/a0161c195b3485c6835569422c269f45 to your computer and use it in GitHub Desktop.
Polyfill to use DisposableStack in Node16
class DisposableStack {
constructor() {
if (!(this instanceof DisposableStack)) {
throw new TypeError('DisposableStack must be constructed with new');
}
this.#state = 'pending';
this.#disposeCapability = newDisposeCapability();
}
get disposed() {
return this.#state === 'disposed';
}
dispose() {
if (this.disposed) {
return;
}
this.#state = 'disposed';
disposeResources(this.#disposeCapability, NormalCompletion())?.['?']();
}
use(value) {
if (this.disposed) {
throw new ReferenceError('A disposed stack cannot use anything new');
}
addDisposableResource(this.#disposeCapability, value, 'sync-dispose');
return value;
}
adopt(value, onDispose) {
if (this.disposed) {
throw new ReferenceError('A disposed stack cannot use anything new');
}
if (typeof onDispose !== 'function') {
throw new TypeError('`onDispose` must be a function');
}
const F = () => {
return onDispose(value);
};
addDisposableResource(this.#disposeCapability, undefined, 'sync-dispose', F);
return value;
}
defer(onDispose) {
if (this.disposed) {
throw new ReferenceError('A disposed stack cannot defer anything new');
}
if (typeof onDispose !== 'function') {
throw new TypeError('`onDispose` must be a function');
}
addDisposableResource(this.#disposeCapability, undefined, 'sync-dispose', onDispose);
}
move() {
if (this.disposed) {
throw new ReferenceError('A disposed stack cannot use anything new');
}
const newDisposableStack = new DisposableStack();
newDisposableStack.#disposeCapability = this.#disposeCapability;
this.#disposeCapability = newDisposeCapability();
this.#state = 'disposed';
return newDisposableStack;
}
}
if (typeof Symbol !== 'undefined' && Symbol.dispose) {
DisposableStack.prototype[Symbol.dispose] = DisposableStack.prototype.dispose;
}
Object.defineProperty(DisposableStack.prototype, Symbol.toStringTag, {
value: 'DisposableStack',
writable: false,
enumerable: false,
configurable: true,
});
// Utility functions
function newDisposeCapability() {
return {};
}
function disposeResources(capability, completion) {
// Implement this function according to your requirements
}
function addDisposableResource(capability, value, type, onDispose) {
// Implement this function according to your requirements
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment