@river-build/sdk
Version:
For more details, visit the following resources:
57 lines • 1.79 kB
JavaScript
export class Observable {
_nextId = 0;
subscribers = [];
_value;
constructor(value) {
this._value = value;
}
get value() {
return this._value;
}
setValue(newValue) {
this._value = newValue;
this.notify();
}
subscribe(subscriber, opts = {}) {
const sub = {
id: this._nextId++,
fn: subscriber,
once: opts?.once ?? false,
condition: opts?.condition ?? (() => true),
};
this.subscribers.push(sub);
if (opts.fireImediately) {
this._notify(sub, this.value);
}
return () => this.unsubscribe(subscriber);
}
when(condition, opts = { timeoutMs: 5000 }) {
const logId = opts.description ? ` ${opts.description}` : '';
const timeoutError = new Error(`Timeout waiting for condition${logId}`);
return new Promise((resolve, reject) => {
const timeoutHandle = setTimeout(() => {
reject(timeoutError);
}, opts.timeoutMs);
this.subscribe((value) => {
clearTimeout(timeoutHandle);
resolve(value);
}, { fireImediately: true, condition: condition, once: true });
});
}
unsubscribe(subscriber) {
this.subscribers = this.subscribers.filter((sub) => sub.fn !== subscriber);
}
notify() {
const subscriptions = this.subscribers;
subscriptions.forEach((sub) => this._notify(sub, this.value));
}
_notify(sub, value) {
if (sub.condition(value)) {
sub.fn(value);
if (sub.once) {
this.subscribers = this.subscribers.filter((s) => s !== sub);
}
}
}
}
//# sourceMappingURL=observable.js.map