vulpix
Version:
CSP-like channels library
84 lines (83 loc) • 2.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatefulPromise = void 0;
const extensible_promise_1 = require("../extensible-promise");
var PromiseState;
(function (PromiseState) {
PromiseState[PromiseState["PENDING"] = 0] = "PENDING";
PromiseState[PromiseState["RESOLVED"] = 1] = "RESOLVED";
PromiseState[PromiseState["REJECTED"] = 2] = "REJECTED";
})(PromiseState || (PromiseState = {}));
class BufferedEventEmitter {
constructor() {
this.buffer = new Set();
this.listeners = new Map();
}
on(eventName, listener) {
if (this.buffer.has(eventName)) {
listener();
this.buffer.delete(eventName);
return;
}
this.listeners.set(eventName, listener);
}
removeListener(eventName) {
this.listeners.delete(eventName);
}
once(eventName, listener) {
this.on(eventName, () => {
listener();
this.removeListener(eventName);
});
}
emit(eventName) {
const listener = this.listeners.get(eventName);
if (!listener) {
this.buffer.add(eventName);
return;
}
listener();
}
removeAllListeners() {
this.listeners.clear();
}
}
class StatefulPromise extends extensible_promise_1.ExtensiblePromise {
constructor(executor) {
const emitter = new BufferedEventEmitter();
super(new Promise((resolve, reject) => {
const decoratedResolve = (value) => {
emitter.emit('resolved');
resolve(value);
};
const decoratedReject = (reason) => {
emitter.emit('rejected');
reject(reason);
};
executor(decoratedResolve, decoratedReject);
}));
this.state = PromiseState.PENDING;
this.eventEmitter = emitter;
this.eventEmitter.once('resolved', () => {
this.state = PromiseState.RESOLVED;
this.eventEmitter.removeAllListeners();
});
this.eventEmitter.once('rejected', () => {
this.state = PromiseState.REJECTED;
this.eventEmitter.removeAllListeners();
});
}
get isPending() {
return this.state === PromiseState.PENDING;
}
get isResolved() {
return this.state === PromiseState.RESOLVED;
}
get isRejected() {
return this.state === PromiseState.REJECTED;
}
get isFulfilled() {
return !this.isPending;
}
}
exports.StatefulPromise = StatefulPromise;