ts-raii-scope
Version:
TypeScript RAII proof of concept
80 lines (79 loc) • 2.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const disposableResource_1 = require("./disposableResource");
const utils_1 = require("./utils");
class RaiiScope {
constructor(...args) {
this._stack = [];
this._isDisposed = false;
for (const arg of args) {
this.push(arg);
}
}
// noinspection JSUnusedGlobalSymbols
static doInside(resources, action) {
const scope = new RaiiScope(...resources);
try {
return action(...resources);
}
finally {
scope.dispose();
}
}
// noinspection JSUnusedGlobalSymbols
static async doInsideAsync(resources, action) {
const scope = new RaiiScope(...resources);
return action(...resources).then(async (result) => {
await scope.dispose();
return result;
}, async (reason) => {
await scope.dispose();
throw reason;
});
}
push(resource, disposeCallback) {
if (utils_1.isDisposable(resource)) {
if (disposeCallback) {
throw new Error('Disposable resource passed with extra disposeCallback');
}
return this.pushUnique(resource);
}
if (disposeCallback) {
this.pushUnique(new disposableResource_1.DisposableResource(resource, disposeCallback));
return resource;
}
throw new Error('Passed not disposable resource without disposeCallback');
}
dispose() {
if (this._isDisposed === false) {
const disposeResult = this.disposeImpl();
if (utils_1.isPromise(disposeResult)) {
return disposeResult.then(() => {
this._isDisposed = true;
});
}
this._isDisposed = true;
}
}
disposeImpl() {
const resource = this._stack.pop();
if (resource) {
const disposing = utils_1.safeDisposeResource(resource);
return utils_1.isPromise(disposing) ? disposing.then(() => this.disposeImpl()) : this.disposeImpl();
}
}
pushUnique(resource) {
if (this._isDisposed === true) {
throw new Error('Already disposed');
}
if (this._isDisposed === undefined) {
throw new Error('Disposing in progress');
}
if (this._stack.indexOf(resource) !== -1) {
throw new Error('Resource already pushed');
}
this._stack.push(resource);
return resource;
}
}
exports.RaiiScope = RaiiScope;