99 lines
2.4 KiB
TypeScript
99 lines
2.4 KiB
TypeScript
import Observable, { ObserverCallback } from "./observable";
|
|
|
|
export default class AwaitStore<T = any> {
|
|
private observable = new Observable<T>();
|
|
constructor(private _value: T) {
|
|
this.subscribe = this.subscribe.bind(this);
|
|
this.unsubscribe = this.unsubscribe.bind(this);
|
|
}
|
|
|
|
/**
|
|
* Get the current value
|
|
*/
|
|
get value() {
|
|
return this._value;
|
|
}
|
|
|
|
/**
|
|
* Set a new value and notify subscribers
|
|
* @param value Value to be set
|
|
*/
|
|
send(value: T) {
|
|
this._value = value;
|
|
this.observable.send(value);
|
|
}
|
|
|
|
/**
|
|
* Get the current value as well as all changes
|
|
* @param handler Handler called on change
|
|
*/
|
|
subscribe(handler: ObserverCallback<T>) {
|
|
handler(this._value);
|
|
return this.observable.subscribe(handler);
|
|
}
|
|
|
|
/**
|
|
* Unsubscribe from changes
|
|
* @param handler The handler to unsubscribe
|
|
*/
|
|
unsubscribe(handler: ObserverCallback<T>) {
|
|
this.observable.unsubscribe(handler);
|
|
}
|
|
|
|
/**
|
|
* Await a specific value and return.
|
|
*
|
|
* For example if val = true then this function would block until the value
|
|
* is actually true. If it is true, then the promise will resolve immediatly
|
|
*
|
|
* @param val Value to await
|
|
*/
|
|
awaitValue(
|
|
val: T
|
|
): PromiseLike<void> & {
|
|
catch: (cb: (err: any) => PromiseLike<void>) => PromiseLike<void>;
|
|
ignore: () => void;
|
|
} {
|
|
let ignore: () => void = () => undefined;
|
|
|
|
let prms = new Promise<void>((yes) => {
|
|
const cb = () => {
|
|
if (this._value === val) {
|
|
yes();
|
|
this.unsubscribe(cb);
|
|
}
|
|
};
|
|
|
|
this.subscribe(cb);
|
|
});
|
|
|
|
return {
|
|
then: prms.then.bind(prms),
|
|
catch: prms.catch.bind(prms),
|
|
ignore: () => ignore(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates Public API with subscribe and unsubscribe
|
|
*
|
|
* @returns {object}
|
|
*/
|
|
getPublicApi() {
|
|
if (this.observable.closed) throw new Error("Observable is closed!");
|
|
return {
|
|
subscribe: (callback: ObserverCallback<T>) => this.subscribe(callback),
|
|
unsubscribe: (callback: ObserverCallback<T>) =>
|
|
this.unsubscribe(callback),
|
|
awaitValue: (value: T) => this.awaitValue(value),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Close this store. All subscribers will be unsubscribed and any further operations will fail
|
|
*/
|
|
close() {
|
|
this.observable.close();
|
|
}
|
|
}
|