| type Listener = () => void | |
| type OnChange<T> = (args: { newState: T; oldState: T }) => void | |
| export type Store<T> = { | |
| getState: () => T | |
| setState: (updater: (prev: T) => T) => void | |
| subscribe: (listener: Listener) => () => void | |
| } | |
| export function createStore<T>( | |
| initialState: T, | |
| onChange?: OnChange<T>, | |
| ): Store<T> { | |
| let state = initialState | |
| const listeners = new Set<Listener>() | |
| return { | |
| getState: () => state, | |
| setState: (updater: (prev: T) => T) => { | |
| const prev = state | |
| const next = updater(prev) | |
| if (Object.is(next, prev)) return | |
| state = next | |
| onChange?.({ newState: next, oldState: prev }) | |
| for (const listener of listeners) listener() | |
| }, | |
| subscribe: (listener: Listener) => { | |
| listeners.add(listener) | |
| return () => listeners.delete(listener) | |
| }, | |
| } | |
| } | |