@codegouvfr/react-dsfr
Version:
French State Design System React integration library
55 lines (45 loc) • 1.36 kB
text/typescript
import { assert, is } from "tsafe/assert";
export type StatefulObservable<T> = {
current: T;
subscribe: (next: (data: T) => void) => Subscription;
};
export type Subscription = {
unsubscribe(): void;
};
export function createStatefulObservable<T>(getInitialValue: () => T): StatefulObservable<T> {
const nextFunctions: ((data: T) => void)[] = [];
const { get, set } = (() => {
let wrappedState: [T] | undefined = undefined;
function set(data: T) {
wrappedState = [data];
nextFunctions.forEach(next => next(data));
}
return {
"get": () => {
if (wrappedState === undefined) {
set(getInitialValue());
assert(!is<undefined>(wrappedState));
}
return wrappedState[0];
},
set
};
})();
return Object.defineProperty(
{
"current": null as any as T,
"subscribe": (next: (data: T) => void) => {
nextFunctions.push(next);
return {
"unsubscribe": () => nextFunctions.splice(nextFunctions.indexOf(next), 1)
};
}
},
"current",
{
"enumerable": true,
get,
set
}
);
}