Created
September 13, 2023 05:22
-
-
Save tzkmx/a0161c195b3485c6835569422c269f45 to your computer and use it in GitHub Desktop.
Polyfill to use DisposableStack in Node16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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