keycloakify
Version:
Framework to create custom Keycloak UIs
58 lines (48 loc) • 1.38 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
}
);
}