vulpix
Version:
CSP-like channels library
67 lines (66 loc) • 2.13 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.waitGroup = exports.WaitGroup = void 0;
const deferred_promise_1 = require("../async/deferred-promise");
class DoneSignal {
constructor(onDone) {
this.onDone = onDone;
this.isDone = false;
}
done() {
if (this.isDone) {
throw new Error('WaitGroup.DoneSignal.done has already been called for this instance');
}
this.isDone = true;
this.onDone();
}
}
class WaitGroup {
constructor(size, onCompletion) {
if (!(Number.isInteger(size) && size > 0)) {
throw new RangeError(`WaitGroup size must be a positive integer. Got: ${size}`);
}
this.size = size;
this.doneCount = 0;
this.emittedSignals = 0;
this.onCompletion = onCompletion;
this.completionPromise = new deferred_promise_1.DeferredPromise();
}
wait() {
return this.completionPromise;
}
add(n) {
if (!(Number.isInteger(n) && n > 0)) {
throw new RangeError(`WaitGroup.add argument must be a positive integer. Got: ${n}`);
}
if (this.isComplete()) {
throw new Error("Can't call WaitGroup.add when WaitGroup has already completed");
}
this.size += n;
}
isComplete() {
return this.doneCount === this.size;
}
get signal() {
if (this.isComplete()) {
throw new Error("Can't get a signal from a WaitGroup that has already completed");
}
if (this.emittedSignals === this.size) {
throw new Error('WaitGroup has no remaining signals');
}
this.emittedSignals++;
return new DoneSignal(() => {
var _a;
this.doneCount++;
if (this.isComplete()) {
this.completionPromise.resolve();
(_a = this.onCompletion) === null || _a === void 0 ? void 0 : _a.call(this);
}
});
}
}
exports.WaitGroup = WaitGroup;
function waitGroup(size) {
return new WaitGroup(size);
}
exports.waitGroup = waitGroup;
;