feat: multi-account system
This commit is contained in:
41
packages/app/src/ExternalStore.ts
Normal file
41
packages/app/src/ExternalStore.ts
Normal file
@ -0,0 +1,41 @@
|
||||
type HookFn = () => void;
|
||||
|
||||
interface HookFilter {
|
||||
fn: HookFn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple React hookable store with manual change notifications
|
||||
*/
|
||||
export default abstract class ExternalStore<TSnapshot> {
|
||||
#hooks: Array<HookFilter> = [];
|
||||
#snapshot: Readonly<TSnapshot> = {} as Readonly<TSnapshot>;
|
||||
#changed = true;
|
||||
|
||||
hook(fn: HookFn) {
|
||||
this.#hooks.push({
|
||||
fn,
|
||||
});
|
||||
return () => {
|
||||
const idx = this.#hooks.findIndex(a => a.fn === fn);
|
||||
if (idx >= 0) {
|
||||
this.#hooks.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
snapshot() {
|
||||
if (this.#changed) {
|
||||
this.#snapshot = this.takeSnapshot();
|
||||
this.#changed = false;
|
||||
}
|
||||
return this.#snapshot;
|
||||
}
|
||||
|
||||
protected notifyChange() {
|
||||
this.#changed = true;
|
||||
this.#hooks.forEach(h => h.fn());
|
||||
}
|
||||
|
||||
abstract takeSnapshot(): TSnapshot;
|
||||
}
|
Reference in New Issue
Block a user