Skip to content

AegisJSProject/state

Repository files navigation

@aegisjsproject/state

A lightweight state management library that persists state across navigation within the same session. It leverages history.state for easy integration into web applications and synchronizes state across tabs or windows within the same origin using BroadcastChannel.

CodeQL Node CI Lint Code Base

GitHub license GitHub last commit GitHub release GitHub Sponsors

npm node-current npm bundle size gzipped npm

GitHub followers GitHub forks GitHub stars Twitter Follow

Donate using Liberapay


Features

  • Session persistence: State persists across navigation, staying in sync with the browser's session history.
  • Multi-tab synchronization: Keeps state in sync across multiple tabs or windows on the same origin using BroadcastChannel.
  • Efficient state updates: Only updates when necessary, ensuring minimal performance overhead.
  • Flexible API: Includes utilities for observing state changes, managing key-specific states, and clearing state.

Installation

npm install @aegisjsproject/state

CDN and importmap

You do not even need to npm install this or use any build process. You may either import it directly from a CDN or use an importmap.

<script type="importmap">
{
  "imports": {
    "@aegisjsproject/state": "https://unpkg.com/@aegisjsproject/state[@version]/state.js"
  }
}
</script>

Example

import { setState, getState, observeStateChanges, manageState, watchState } from '@aegisjsproject/state';

// Enables syncing of state across tabs/windows
watchState();

// Set state
setState('key', 'value');

// Get state
const value = getState('key');

// Observe state changes
observeStateChanges(({ diff, state }) => {
  console.log('State changed:', diff, state);
});

// Observe state changes to only specific state keys
observeStateChanges(({ state }) => {
  console.log('State changed:', {
    foo: state.foo,
    bar: state.bar,
  });
}, 'foo', 'bar');

// Manage state with reactive pattern
const [state, setStateValue] = manageState('key', 'defaultValue');
console.log(state.valueOf());  // Logs the state value from the wrapper object
setStateValue('newValue');     // Updates the state

Important

This is NOT to be confused with eg useState() in React or anything like that. There is no transpilation step involved. Although manageState() does return a tuple of [value, setValue], it takes a key and an initial value, and the value is an object which wraps the current value. You can use the value via things like setValue(value + 1) thanks to [Symbol.toPrimitive], however.