40 lines
1.0 KiB
TypeScript
40 lines
1.0 KiB
TypeScript
import type { CommandDispatcher } from "@commands/dispatcher";
|
|
import { createCommandDispatcher } from "@commands/dispatcher";
|
|
import type { CommandRegistry } from "@commands/registry";
|
|
import type { AppState } from "./state";
|
|
|
|
export type StateListener = (state: AppState) => void;
|
|
|
|
export type AppStore = {
|
|
getState(): AppState;
|
|
subscribe(listener: StateListener): () => void;
|
|
dispatch: CommandDispatcher["dispatch"];
|
|
};
|
|
|
|
export function createAppStore(initialState: AppState, registry: CommandRegistry): AppStore {
|
|
let state = initialState;
|
|
const listeners = new Set<StateListener>();
|
|
|
|
const emit = () => {
|
|
for (const listener of listeners) listener(state);
|
|
};
|
|
|
|
const dispatcher = createCommandDispatcher({
|
|
registry,
|
|
getState: () => state,
|
|
setState: (nextState) => {
|
|
state = nextState;
|
|
emit();
|
|
},
|
|
});
|
|
|
|
return {
|
|
getState: () => state,
|
|
subscribe(listener) {
|
|
listeners.add(listener);
|
|
return () => listeners.delete(listener);
|
|
},
|
|
dispatch: dispatcher.dispatch,
|
|
};
|
|
}
|