@logux/state
Version:
A tiny (152 bytes) state manager for React/Preact/Vue/Svelte with many atomic tree-shakable stores
86 lines (78 loc) • 2.02 kB
TypeScript
type ReadonlyIfObject<Value> = Value extends object ? Readonly<Value> : Value
export type StoreValue<SomeStore> = SomeStore extends Store<infer Value>
? Value
: any
/**
* Store object.
*/
export type Store<Value = any> = {
/**
* `true` if store has any listeners.
*/
active: true | undefined
/**
* Low-level access to store’s value. Can be empty without listeners.
* It is better to always use {@link getValue}.
*/
value: Value | undefined
/**
* Subscribe to store changes and call listener immediately.
*
* ```
* import { router } from '../store'
*
* router.subscribe(page => {
* console.log(page)
* })
* ```
*
* @param listener Callback with store value.
* @returns Function to remove listener.
*/
subscribe(listener: (value: ReadonlyIfObject<Value>) => void): () => void
/**
* Subscribe to store changes.
*
* In contrast with {@link Store#subscribe} it do not call listener
* immediately.
*
* @param listener Callback with store value.
* @returns Function to remove listener.
*/
listen(listener: (value: ReadonlyIfObject<Value>) => void): () => void
/**
* Change store value.
*
* ```js
* router.set({ path: location.pathname, page: parse(location.pathname) })
* ```
*
* @param newValue New store value.
*/
set(newValue: Value): void
}
/**
* Define simple (singleton) store.
*
* ```js
* import { createStore } from '@logux/state'
*
* function parse () {
* router.set({ path: location.pathname, page: parse(location.pathname) })
* }
*
* export const router = createStore(() => {
* parse()
* window.addEventListener('popstate', parse)
* return () => {
* window.removeEventListener('popstate', parse)
* }
* })
* ```
*
* @param init Initialize store and return store destructor.
* @returns The store object with methods to subscribe.
*/
export function createStore<Value, StoreExt = {}>(
init?: () => void | (() => void)
): Store<Value> & StoreExt