A universal and lightweight state management library with a clean, stateless API.
# Universal npm install @neabyte/stateless-js # Angular (Automatic Reactivity) npm install @neabyte/stateless-js @angular/core # React (Automatic Re-renders) npm install @neabyte/stateless-js react # Svelte (Automatic Reactivity) npm install @neabyte/stateless-js svelte # Vue (Automatic Reactivity) npm install @neabyte/stateless-js vue
// CommonJS const { createStateless, useStateless } = require('@neabyte/stateless-js') // ESM (ES Modules) import { createStateless, useStateless } from '@neabyte/stateless-js' // Angular (Automatic Reactivity) import { StatelessService, useAngularStateless } from '@neabyte/stateless-js/angular' // React (Automatic Re-renders) import { useReactStateless } from '@neabyte/stateless-js/react' // Svelte (Automatic Reactivity) import { useSvelteStateless } from '@neabyte/stateless-js/svelte' // Vue (Automatic Reactivity) import { useVueStateless } from '@neabyte/stateless-js/vue' // TypeScript types import type { StateSetter, StateValue } from '@neabyte/stateless-js'
// CDN <script src="https://unpkg.com/@neabyte/stateless-js/dist/index.mjs"></script> // jsDelivr ESM <script type="module"> import { createStateless, useStateless } from 'https://cdn.jsdelivr.net/npm/@neabyte/stateless-js/dist/index.mjs' </script>
import { createStateless, useStateless } from '@neabyte/stateless-js' // Create a new state const [setCount, count] = createStateless('counter', 0) console.log(count.value) // 0 // Update state setCount(current => current + 1) console.log(count.value) // 1
import { StatelessService, useAngularStateless } from '@neabyte/stateless-js/angular' // Using the service approach @Injectable({ providedIn: 'root' }) export class MyService { constructor(private stateless: StatelessService) {} counterState = this.stateless.useAngularStateless('counter', 0) count = this.counterState[1] setCount = this.counterState[0] } // Using the standalone function approach export class MyComponent { counterState = useAngularStateless('counter', 0) count = this.counterState[1] setCount = this.counterState[0] increment = () => this.setCount(current => current + 1) }
// In your Angular component @Component({ template: ` <div> <p>Count: {{ count() }}</p> <button (click)="increment()">Increment</button> </div> ` }) export class CounterComponent { counterState = useAngularStateless('counter', 0) count = this.counterState[1] setCount = this.counterState[0] increment = () => this.setCount(current => current + 1) }
import { useReactStateless } from '@neabyte/stateless-js/react' function Counter() { const [setCount, count] = useReactStateless('counter', 0) return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(c => c + 1)}> Increment </button> </div> ) }
import { useSvelteStateless } from '@neabyte/stateless-js/svelte' // In your Svelte component const [setCount, count] = useSvelteStateless('counter', 0) const increment = () => setCount(current => current + 1)
<!-- In your .svelte file --> <script> import { useSvelteStateless } from '@neabyte/stateless-js/svelte' const [setCount, count] = useSvelteStateless('counter', 0) const increment = () => setCount(current => current + 1) </script> <div> <p>Count: {$count}</p> <button on:click={increment}>Increment</button> </div>
import { useVueStateless } from '@neabyte/stateless-js/vue' export default { name: 'Counter', setup() { const [setCount, countValue] = useVueStateless('counter', 0) const count = computed(() => countValue.value) const increment = () => { setCount(current => current + 1) } return { count, increment } } }
// Universal const [setUser, user] = createStateless('user', { name: 'John', age: 25 }) const [setUser2, user2] = useStateless('user', { name: 'Default', age: 0 }) console.log(user.value === user2.value) // true - same state // React - Multiple components share the same state function UserProfile() { const [setUser, user] = useReactStateless('user', { name: 'John', age: 25 }) return <div>Name: {user.name}, Age: {user.age}</div> } function UserEditor() { const [setUser, user] = useReactStateless('user', { name: 'Default', age: 0 }) return <button onClick={() => setUser(u => ({ ...u, age: u.age + 1 }))}> Increase Age </button> } // Vue - Multiple components share the same state export default { name: 'UserProfile', setup() { const [setUser, userValue] = useVueStateless('user', { name: 'John', age: 25 }) const user = computed(() => userValue.value) return { user } } } export default { name: 'UserEditor', setup() { const [setUser, userValue] = useVueStateless('user', { name: 'Default', age: 0 }) const user = computed(() => userValue.value) const increaseAge = () => { setUser(u => ({ ...u, age: u.age + 1 })) } return { user, increaseAge } } }
// Numbers const [setNum, num] = createStateless('number', 42) // Strings const [setStr, str] = createStateless('string', 'hello') // Objects const [setObj, obj] = createStateless('object', { count: 0, items: [] }) // Arrays const [setArr, arr] = createStateless('array', [1, 2, 3]) // Special values const [setNaN, nan] = createStateless('nan', NaN) const [setInf, inf] = createStateless('infinity', Infinity) const [setSymbol, sym] = createStateless('symbol', Symbol('test')) const [setBigInt, big] = createStateless('bigint', BigInt(123))
// Universal const [setData, data] = createStateless('data', { count: 0, items: [] }) // React const [setData, data] = useReactStateless('react-data', { count: 0, items: [] }) // Vue const [setData, dataRef] = useVueStateless('vue-data', { count: 0, items: [] }) const data = computed(() => dataRef.value) // Immutable updates work the same way setData(current => ({ ...current, count: current.count + 1 })) setData(current => ({ ...current, items: [...current.items, 'new item'] }))
const [setTemp, temp] = createStateless('temporary', 'data') // Use the state... console.log(temp.value) // Clean up when done temp.dispose() // Accessing disposed state throws error try { console.log(temp.value) // Error: State has been disposed } catch (error) { console.log(error.message) }
Creates a new state with the given ID and initial value.
id: Unique identifier (string or number)initialState: Initial value for the state- Returns: Tuple
[StateSetter<T>, StateValue<T>]
Uses existing state if it exists, otherwise creates a new one.
id: Unique identifier (string or number)fallbackState: Value to use if state doesn't exist- Returns: Tuple
[StateSetter<T>, StateValue<T>]
Angular service method that provides automatic reactivity using Angular signals.
id: Unique identifier (string or number)initialValue: Initial value for the state- Returns: Tuple
[StateSetter<T>, Signal<T>](Angular signal for reactivity)
Standalone Angular function that provides automatic reactivity using Angular signals.
id: Unique identifier (string or number)initialValue: Initial value for the state- Returns: Tuple
[StateSetter<T>, Signal<T>](Angular signal for reactivity)
React hook that provides automatic re-renders when state changes.
id: Unique identifier (string or number)initialValue: Initial value for the state- Returns: Tuple
[StateSetter<T>, T](direct value, not StateValue object)
Svelte function that provides automatic reactivity using Svelte stores.
id: Unique identifier (string or number)initialValue: Initial value for the state- Returns: Tuple
[StateSetter<T>, Writable<T>](Svelte writable store for reactivity)
Vue composable that provides automatic reactivity when state changes.
id: Unique identifier (string or number)initialValue: Initial value for the state- Returns: Tuple
[StateSetter<T>, Ref<T>](reactive ref for Vue reactivity)
Function to update state: (updater: StateUpdater<T>) => void
Object with:
value: Current state value (readonly)dispose(): Method to clean up the state
This project is licensed under the MIT license. See the LICENSE file for more info.