35 lines
836 B
TypeScript
35 lines
836 B
TypeScript
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)
|
|
},
|
|
}
|
|
}
|