UNPKG

@uistate/core

Version:

Lightweight event-driven state management with path-based subscriptions, wildcards, and async support

152 lines (106 loc) 4.96 kB
# @uistate/core Path-based state management with wildcard subscriptions and async support. [![npm version](https://img.shields.io/npm/v/@uistate/core.svg)](https://www.npmjs.com/package/@uistate/core) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE) ## Install ```bash npm install @uistate/core ``` ## Quick Start ```javascript import { createEventState } from '@uistate/core'; const store = createEventState({ user: { name: 'Alice' }, count: 0 }); // Exact path store.subscribe('count', (value) => console.log('Count:', value)); // Wildcard — fires on any child of 'user' store.subscribe('user.*', ({ path, value }) => console.log(path, value)); // Global — fires on every change store.subscribe('*', ({ path, value }) => console.log(path, value)); store.set('user.name', 'Bob'); store.set('count', 1); ``` ## API ### `createEventState(initialState)` Returns a store with `get`, `set`, `batch`, `setMany`, `subscribe`, `setAsync`, `cancel`, `destroy`. ### `store.get(path?)` ```javascript store.get('user.name'); // 'Alice' store.get('user'); // { name: 'Alice' } store.get(); // entire state ``` ### `store.set(path, value)` Sets a value and notifies subscribers. Creates intermediate objects if needed. ```javascript store.set('user.email', 'alice@example.com'); // state.user.email now exists even if it didn't before ``` ### `store.subscribe(path, handler)` Returns an unsubscribe function. Exact subscribers get `(value, detail)`. Wildcard/global subscribers get `(detail)` where detail is `{ path, value, oldValue }`. ```javascript const unsub = store.subscribe('count', (value, { oldValue }) => { console.log(`${oldValue} → ${value}`); }); unsub(); // cleanup ``` ### `store.batch(fn)` Batch multiple `set()` calls. Subscribers fire once per unique path after the batch completes, not during. Supports nesting. ```javascript store.batch(() => { store.set('ui.route.view', 'user'); store.set('ui.route.path', '/users/42'); store.set('ui.route.params', { id: '42' }); }); // Subscribers fire here, once per path, all state consistent ``` ### `store.setMany(entries)` Set multiple paths atomically. Shorthand for `batch` + a loop of `set` calls. Accepts a plain object, an array of `[path, value]` pairs, or a `Map`. ```javascript store.setMany({ 'ui.route.view': 'user', 'ui.route.path': '/users/42', 'ui.route.params': { id: '42' }, }); ``` ### `store.setAsync(path, fetcher)` Manages async state at `${path}.status`, `${path}.data`, `${path}.error`. Supports abort on re-call. ```javascript await store.setAsync('users', async (signal) => { const res = await fetch('/api/users', { signal }); return res.json(); }); // store.get('users.data') → [...] // store.get('users.status') → 'success' ``` ### `store.cancel(path)` / `store.destroy()` Cancel an in-flight async operation, or tear down the entire store. ## Query Client Convenience wrapper around `setAsync` for data-fetching patterns. ```javascript import { createQueryClient } from '@uistate/core/query'; const qc = createQueryClient(store); await qc.query('users', (signal) => fetch('/api/users', { signal }).then(r => r.json())); qc.getData('users'); qc.getStatus('users'); qc.cancel('users'); qc.invalidate('users'); ``` ## Ecosystem | Package | Description | License | |---|---|---| | [@uistate/core](https://www.npmjs.com/package/@uistate/core) | Path-based state management with wildcard subscriptions and async support | MIT | | [@uistate/view](https://www.npmjs.com/package/@uistate/view) | State-driven view: DOMless resolve + surgical DOM projector. View tree as first-class state | MIT | | [@uistate/react](https://www.npmjs.com/package/@uistate/react) | React adapter — `usePath`, `useIntent`, `useAsync` hooks and `EventStateProvider` | MIT | | [@uistate/css](https://www.npmjs.com/package/@uistate/css) | Reactive CSSOM engine — design tokens, typed validation, WCAG enforcement, all via path-based state | MIT | | [@uistate/event-test](https://www.npmjs.com/package/@uistate/event-test) | Event-sequence testing for UIstate stores | Proprietary | | [@uistate/examples](https://www.npmjs.com/package/@uistate/examples) | Example applications and patterns | MIT | | [@uistate/renderer](https://www.npmjs.com/package/@uistate/renderer) | Direct-binding reactive renderer: `bind-*`, `set`, `each` attributes. Zero build step | Proprietary | | [@uistate/aliases](https://www.npmjs.com/package/@uistate/aliases) | Ergonomic single-character and short-name DOM aliases for vanilla JS | MIT | 📖 **Documentation:** [uistate.com](https://uistate.com) ## License MIT — see [LICENSE](./LICENSE). Copyright © 20252026 Ajdin Imsirovic ## Links - [Documentation](https://uistate.com) - [GitHub](https://github.com/ImsirovicAjdin/uistate) - [npm](https://www.npmjs.com/package/@uistate/core) - [Issues](https://github.com/ImsirovicAjdin/uistate/issues)