@xylabs/threads
Version:
Web workers & worker threads as simple as a function call
132 lines • 3.5 kB
JavaScript
// src/observable-promise.ts
import { Observable } from "observable-fns";
var doNothing = () => {
};
var returnInput = (input) => input;
var runDeferred = (fn) => Promise.resolve().then(fn);
function fail(error) {
throw error;
}
function isThenable(thing) {
return thing && typeof thing.then === "function";
}
var ObservablePromise = class _ObservablePromise extends Observable {
[Symbol.toStringTag] = "[object ObservablePromise]";
initHasRun = false;
fulfillmentCallbacks = [];
rejectionCallbacks = [];
firstValue;
firstValueSet = false;
rejection;
state = "pending";
constructor(init) {
super((originalObserver) => {
const self = this;
const observer = {
...originalObserver,
complete() {
originalObserver.complete();
self.onCompletion();
},
error(error) {
originalObserver.error(error);
self.onError(error);
},
next(value) {
originalObserver.next(value);
self.onNext(value);
}
};
try {
this.initHasRun = true;
return init(observer);
} catch (error) {
observer.error(error);
}
});
}
onNext(value) {
if (!this.firstValueSet) {
this.firstValue = value;
this.firstValueSet = true;
}
}
onError(error) {
this.state = "rejected";
this.rejection = error;
for (const onRejected of this.rejectionCallbacks) {
runDeferred(() => onRejected(error));
}
}
onCompletion() {
this.state = "fulfilled";
for (const onFulfilled of this.fulfillmentCallbacks) {
runDeferred(() => onFulfilled(this.firstValue));
}
}
then(onFulfilledRaw, onRejectedRaw) {
const onFulfilled = onFulfilledRaw || returnInput;
const onRejected = onRejectedRaw || fail;
let onRejectedCalled = false;
return new Promise((resolve, reject) => {
const rejectionCallback = (error) => {
if (onRejectedCalled) return;
onRejectedCalled = true;
try {
resolve(onRejected(error));
} catch (anotherError) {
reject(anotherError);
}
};
const fulfillmentCallback = (value) => {
try {
resolve(onFulfilled(value));
} catch (ex) {
const error = ex;
rejectionCallback(error);
}
};
if (!this.initHasRun) {
this.subscribe({ error: rejectionCallback });
}
if (this.state === "fulfilled") {
return resolve(onFulfilled(this.firstValue));
}
if (this.state === "rejected") {
onRejectedCalled = true;
return resolve(onRejected(this.rejection));
}
this.fulfillmentCallbacks.push(fulfillmentCallback);
this.rejectionCallbacks.push(rejectionCallback);
});
}
catch(onRejected) {
return this.then(void 0, onRejected);
}
finally(onCompleted) {
const handler = onCompleted || doNothing;
return this.then(
(value) => {
handler();
return value;
},
() => handler()
);
}
static from(thing) {
return isThenable(thing) ? new _ObservablePromise((observer) => {
const onFulfilled = (value) => {
observer.next(value);
observer.complete();
};
const onRejected = (error) => {
observer.error(error);
};
thing.then(onFulfilled, onRejected);
}) : super.from(thing);
}
};
export {
ObservablePromise
};
//# sourceMappingURL=observable-promise.mjs.map