npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@veams/status-quo

v1.10.0

Published

The manager to rule states in frontend.

Downloads

952

Readme

@veams/status-quo

npm version

The manager to rule your state.

This README summarizes the package API. The full routed documentation lives in VEAMS Documentation.

Table of Contents

  1. Overview
  2. Philosophy
  3. Docs
  4. Quickstart
  5. Handlers
  6. Hooks
  7. Providers
  8. Singletons
  9. Composition
  10. API Guide
  11. Devtools
  12. Cleanup
  13. API Reference
  14. Migration

Overview

StatusQuo is a small, framework-agnostic state layer that focuses on explicit lifecycle, clear action APIs, and a minimal subscription surface. It ships three handler implementations with the same public interface: Native (zero-dependency), RxJS-backed (observables), and Signals-backed (stores).

When using the NativeStateHandler, the library is completely zero-dependency.

Philosophy

  • Swap the engine, keep the API. Your UI code stays the same when you switch from RxJS to Signals.
  • Separate view and state. Handlers own transitions and expose actions; views subscribe to snapshots.
  • Framework-agnostic core. Business logic lives outside the UI library; hooks provide the glue.

Docs

Live docs:

https://veams.github.io/status-quo/packages/status-quo/getting-started

Quickstart

Install:

# Minimal installation (Native only)
npm install @veams/status-quo

# Optional engines
npm install rxjs @preact/signals-core

Create a store and use it in a component:

import { NativeStateHandler } from '@veams/status-quo';
import { useStateFactory } from '@veams/status-quo/react';

type CounterState = { count: number };

type CounterActions = {
  increase: () => void;
  decrease: () => void;
};

class CounterStore extends NativeStateHandler<CounterState, CounterActions> {
  constructor() {
    super({ initialState: { count: 0 } });
  }

  getActions(): CounterActions {
    return {
      increase: () => this.setState({ count: this.getState().count + 1 }),
      decrease: () => this.setState({ count: this.getState().count - 1 }),
    };
  }
}

const [state, actions] = useStateFactory(() => new CounterStore(), []);

Optional global setup for shared defaults such as distinct behavior and Redux DevTools:

import equal from 'fast-deep-equal';
import { setupStatusQuo } from '@veams/status-quo';

setupStatusQuo({
  devTools: {
    enabled: true,
  },
  distinct: {
    comparator: equal,
  },
});

Handlers

StatusQuo provides three handler implementations with the same public interface:

  • NativeStateHandler (Zero dependency, plain JS)
  • ObservableStateHandler (RxJS-backed)
  • SignalStateHandler (Signals-backed)

All are built on BaseStateHandler, which provides the shared lifecycle and devtools support.

Hooks

The React layer lives under @veams/status-quo/react.

Use useStateHandler + useStateActions + useStateSubscription as the base composition. useStateFactory and useStateSingleton are shortcut APIs over that composition. For full signatures and practical examples, see API Guide.

  • useStateHandler(factory, params)
    • Creates and memoizes one handler instance per component.
  • StateProvider({ instance })
    • Shares one handler instance with a subtree through React context.
  • useProvidedStateHandler()
    • Reads the nearest provider-scoped handler instance.
  • useProvidedStateActions()
    • Returns provider-scoped actions without subscribing to state.
  • useProvidedStateSubscription(selector?, isEqual?)
    • Subscribes to provider-scoped state and returns [state, actions].
  • useStateActions(handler)
    • Returns actions without subscribing to state.
  • useStateSubscription(handlerOrSingleton, selector?, isEqual?)
    • Subscribes to full state or a selected slice and returns [state, actions].
    • For local state, pass the same handler instance returned by useStateHandler() that you would also pass to useStateActions().
  • useStateFactory(factory, selector?, isEqual?, params?)
    • Shortcut for useStateHandler + useStateSubscription.
  • useStateSingleton(singleton, selector?, isEqual?)
    • Shortcut for useStateSubscription(singleton, selector?, isEqual?).

Recommended composition:

import {
  useStateActions,
  useStateHandler,
  useStateSubscription,
} from '@veams/status-quo/react';

const handler = useStateHandler(createUserStore, []);
const actions = useStateActions(handler);
const [name] = useStateSubscription(handler, (state) => state.user.name);

const [singletonName] = useStateSubscription(UserSingleton, (state) => state.user.name);

Providers

Use provider scope when a parent should own one local handler instance and several descendants need access to that same instance.

import {
  StateProvider,
  useProvidedStateActions,
  useProvidedStateSubscription,
  useStateHandler,
} from '@veams/status-quo/react';

function CounterScope() {
  const handler = useStateHandler(createCounterStore, []);

  return (
    <StateProvider instance={handler}>
      <CounterValue />
      <CounterButtons />
    </StateProvider>
  );
}

function CounterValue() {
  const [count] = useProvidedStateSubscription((state: CounterState) => state.count);

  return <strong>{count}</strong>;
}

function CounterButtons() {
  const actions = useProvidedStateActions<CounterState, CounterActions>();

  return <button onClick={actions.increase}>Increase</button>;
}

This is the scoped-sharing option between a local handler and a singleton:

  • parent owns lifecycle once
  • children choose whether they need state, actions, or the raw handler
  • action-only components stay out of rerender fanout
  • no prop drilling just to move a handler through the tree

Singletons

Use singletons for shared state across multiple components.

import { makeStateSingleton } from '@veams/status-quo';
import { useStateSingleton } from '@veams/status-quo/react';

// Default behavior: singleton stays alive across unmounts.
const CounterSingleton = makeStateSingleton(() => new CounterStore());

const [state, actions] = useStateSingleton(CounterSingleton);

Destroy a singleton instance when the last consumer unmounts:

const RouteScopedCounterSingleton = makeStateSingleton(() => new CounterStore(), {
  destroyOnNoConsumers: true,
});

Keep the default for app-level shared state that should survive route/component unmounts. Use destroyOnNoConsumers: true when the shared handler should behave more like a mounted resource.

Composition

Use only the slice you need. RxJS makes multi-source composition powerful and declarative with operators like combineLatest, switchMap, or debounceTime. Signals can derive values with computed and wire them into a parent store via bindSubscribable.

import { combineLatest } from 'rxjs';

// RxJS: combine handler streams (RxJS shines here)
class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
  private counter$ = CounterObservableStore.getInstance().getObservable();
  private card$ = new CardObservableHandler();

  constructor() {
    super({ initialState: { counter: 0, cardTitle: '' }});

    this.subscriptions.push(
      combineLatest([
        this.counter$,
        this.card$,
      ]).subscribe(([counterState, cardState]) => {
        this.setState({
          counter: counterState,
          cardTitle: cardState.title,
        }, 'sync-combined');
      })
    )
  }

}

// Signals: combine derived values via computed + bindSubscribable
import { computed } from '@preact/signals-core';

class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
  private counter = CounterSignalHandler.getInstance();
  private card = new CardSignalHandler();
  private combined$ = computed(() => ({
    counter: this.counter.getSignal().value,
    cardTitle: this.card.getSignal().value.title,
  }));

  constructor() {
    super({ initialState: { counter: 0, cardTitle: '' }});

    this.bindSubscribable(
      { subscribe: this.combined.subscribe.bind(this.combined), getSnapshot: () => this.combined.value },
      (nextState) => this.setState(nextState, 'sync-combined')
    );
  }
}

Comparator defaults

Status Quo has two comparison layers, and they solve different problems.

  • Handler-level distinct comparison decides whether a state update should propagate at all.
  • Hook-level isEqual decides whether one selected value should trigger a rerender.
  • The handler is the primary place to define comparison behavior. Hook-level equality is possible, but it should stay focused on UI-specific selection boundaries.

Default behavior:

  • setupStatusQuo({ distinct }) and per-handler options.distinct use a comparator with an Object.is fast path and a JSON-based structural fallback that serializes Map and Set values through a custom replacer.
  • useStateSubscription(), useProvidedStateSubscription(), useStateFactory(), and useStateSingleton() default isEqual to Object.is.
  • If a selector returns a fresh object on each run, Object.is will treat that as changed unless you provide a custom equality function.

Set the distinct comparator globally:

import { setupStatusQuo } from '@veams/status-quo';

setupStatusQuo({
  distinct: {
    comparator: (previous, next) => previous.version === next.version,
  },
});

Or set it per handler:

import { NativeStateHandler } from '@veams/status-quo';

class SearchHandler extends NativeStateHandler<
  { version: number; resultIds: string[] },
  { replace: (version: number, resultIds: string[]) => void }
> {
  constructor() {
    super({
      initialState: {
        version: 0,
        resultIds: [],
      },
      options: {
        distinct: {
          comparator: (previous, next) => previous.version === next.version,
        },
      },
    });
  }

  getActions() {
    return {
      replace: (version: number, resultIds: string[]) => {
        this.setState({ version, resultIds }, 'replace');
      },
    };
  }
}

Practical rule:

  • If several consumers need the same comparison rule, move it into the handler.
  • Use hook-level isEqual only when one component is projecting a temporary view model or other UI-specific slice.
  • Avoid making the component layer the primary home of state semantics when the handler can own that rule once.

API Guide

This section documents the primary public API with behavior notes and usage examples.

setupStatusQuo(config?)

Sets global runtime defaults for distinct update behavior and Redux DevTools enablement. Per-handler options still override the global setup.

type StatusQuoConfig = {
  devTools?: {
    enabled?: boolean; // default: false
  };
  distinct?: {
    enabled?: boolean; // default: true
    comparator?: (previous: unknown, next: unknown) => boolean; // default: Object.is fast path + JSON structural fallback with Map/Set support
  };
};
import equal from 'fast-deep-equal';
import { setupStatusQuo } from '@veams/status-quo';

setupStatusQuo({
  devTools: {
    enabled: true,
  },
  distinct: {
    comparator: equal,
  },
});

useStateHandler(factory, params?)

Creates one handler instance per component mount and returns it.

  • factory: function returning a StateSubscriptionHandler
  • params: optional factory params tuple
  • lifecycle note: params are applied when the handler instance is created for that mount
import { useStateHandler } from '@veams/status-quo/react';

const handler = useStateHandler(createUserStore, []);

StateProvider

Shares one existing handler instance with a subtree through React context. Use this when a parent owns lifecycle and descendants should consume the same local instance without prop drilling.

import { StateProvider, useStateHandler } from '@veams/status-quo/react';

const handler = useStateHandler(createUserStore, []);

return <StateProvider instance={handler}>{children}</StateProvider>;

useProvidedStateHandler()

Reads the nearest provider-scoped handler instance. Use this as the low-level entry point when a descendant needs the raw handler for manual composition.

import { useProvidedStateHandler } from '@veams/status-quo/react';

const handler = useProvidedStateHandler<UserState, UserActions>();

useStateActions(handler)

Returns actions from a handler without subscribing to state changes. Use this in action-only components to avoid rerenders from state updates.

import { useStateActions, useStateHandler } from '@veams/status-quo/react';

const handler = useStateHandler(createUserStore, []);
const actions = useStateActions(handler);

useProvidedStateActions()

Returns actions from the nearest StateProvider without subscribing to state. Use this for command-only components inside a provider scope.

import { useProvidedStateActions } from '@veams/status-quo/react';

const actions = useProvidedStateActions<UserState, UserActions>();

useStateSubscription(source, selector?, isEqual?)

Subscribes to either a handler instance or a singleton and returns [selectedState, actions].

  • source: StateSubscriptionHandler or StateSingleton
    • When you use local state, source is the handler instance returned by useStateHandler().
    • That means it is the same object you would pass to useStateActions(handler).
  • selector: optional projection function; defaults to identity
  • isEqual: optional equality function; defaults to Object.is

Full snapshot subscription:

import { useStateHandler, useStateSubscription } from '@veams/status-quo/react';

const handler = useStateHandler(createUserStore, []);
const [state, actions] = useStateSubscription(handler);

Selector subscription:

import { useStateSubscription } from '@veams/status-quo/react';

const [name, actions] = useStateSubscription(
  handler,
  (state) => state.user.name
);

Selector with custom equality:

import { useStateSubscription } from '@veams/status-quo/react';

const [profile] = useStateSubscription(
  handler,
  (state) => state.user.profile,
  (current, next) => current.id === next.id && current.role === next.role
);

Singleton source:

import { useStateSubscription } from '@veams/status-quo/react';

const [session, actions] = useStateSubscription(SessionSingleton);

Lifecycle note for singleton sources:

  • Consumers are ref-counted.
  • The singleton instance is only destroyed when the last consumer unmounts and destroyOnNoConsumers === true.

useProvidedStateSubscription(selector?, isEqual?)

Subscribes to the nearest StateProvider instead of taking a source argument. It supports full snapshots, selectors, and custom equality the same way useStateSubscription does.

import { useProvidedStateSubscription } from '@veams/status-quo/react';

const [state, actions] = useProvidedStateSubscription<UserState, UserActions>();
const [name] = useProvidedStateSubscription((state: UserState) => state.user.name);

useStateFactory(factory, selector?, isEqual?, params?)

Shortcut API for useStateHandler + useStateSubscription.

  • useStateFactory(factory, params)
  • useStateFactory(factory, selector, params)
  • useStateFactory(factory, selector, isEqual, params)
import { useStateFactory } from '@veams/status-quo/react';

const [state, actions] = useStateFactory(createUserStore, []);
const [name] = useStateFactory(createUserStore, (state) => state.user.name, []);
const [profile] = useStateFactory(
  createUserStore,
  (state) => state.user.profile,
  (current, next) => current.id === next.id,
  []
);

makeStateSingleton(factory, options?)

Creates a shared singleton provider for a handler instance.

import { makeStateSingleton } from '@veams/status-quo';

const UserSingleton = makeStateSingleton(() => new UserStore());

Options:

type StateSingletonOptions = {
  destroyOnNoConsumers?: boolean; // default: false
};
  • false (default): keep instance alive across periods with zero consumers
  • true: destroy instance after last consumer unmounts
import { makeStateSingleton } from '@veams/status-quo';

const RouteScopedUserSingleton = makeStateSingleton(() => new UserStore(), {
  destroyOnNoConsumers: true,
});

useStateSingleton(singleton, selector?, isEqual?)

Shortcut API for useStateSubscription(singleton, selector?, isEqual?).

import { useStateSingleton } from '@veams/status-quo/react';

const [state, actions] = useStateSingleton(UserSingleton);
const [name] = useStateSingleton(UserSingleton, (state) => state.user.name);

Devtools

Status Quo supports the Redux DevTools browser extension on NativeStateHandler, ObservableStateHandler, and SignalStateHandler.

Turn it on globally:

import { setupStatusQuo } from '@veams/status-quo';

setupStatusQuo({
  devTools: {
    enabled: true,
  },
});

Override it per handler when needed:

class CounterStore extends ObservableStateHandler<CounterState, CounterActions> {
  constructor() {
    super({
      initialState: { count: 0 },
      options: { devTools: { namespace: 'Counter' } },
    });
  }
}

Notes:

  • setupStatusQuo({ devTools: { enabled: true } }) enables Redux DevTools by default for handlers.
  • options.devTools still overrides the global default per handler.
  • namespace is optional. When omitted, Status Quo uses the handler class name.
  • setState(nextState, actionName) sends the actionName to the Redux DevTools timeline.
  • The current integration supports reset, commit, jump to state, and jump to action from the extension UI.
  • If the extension is not installed, Status Quo logs that and continues without a devtools connection.

Cleanup

Handlers expose subscribe, getSnapshot, and destroy for custom integrations:

const unsubscribe = store.subscribe(() => {
  console.log(store.getSnapshot());
});

unsubscribe();
store.destroy();

API Reference

StateSubscriptionHandler<V, A>

Required interface implemented by all handlers.

interface StateSubscriptionHandler<V, A> {
  subscribe(listener: () => void): () => void;
  subscribe(listener: (value: V) => void): () => void;
  getSnapshot: () => V;
  destroy: () => void;
  getInitialState: () => V;
  getActions: () => A;
}

BaseStateHandler<S, A>

Shared base class for all handlers.

Constructor:

protected constructor(initialState: S)

Public methods:

  • getInitialState(): S
  • getState(): S
  • getSnapshot(): S
  • setState(next: Partial<S>, actionName = 'change'): void
  • subscribe(listener: () => void): () => void (abstract)
  • subscribe(listener: (value: S) => void): () => void (abstract)
  • destroy(): void
  • getActions(): A (abstract)

Tracked subscription state:

  • subscriptions: Array<{ unsubscribe: () => void }>
  • namedSubscriptions: Map<string, { unsubscribe: () => void }>
    • Use this.namedSubscriptions inside the handler when you need to inspect which named bindings are currently registered.

Protected helpers:

  • getStateValue(): S (abstract)
  • setStateValue(next: S): void (abstract)
  • initDevTools(options?: { enabled?: boolean; namespace?: string }): void
  • bindSubscribable<T>(subscriptionName: string, service: { subscribe: (listener: (value: T) => void) => () => void; getSnapshot?: () => T }, onChange: (value: T) => void, selector?: (value: T) => T, isEqual?: (current: T, next: T) => boolean): void
  • bindSubscribable<T, Sel>(subscriptionName: string, service: { subscribe: (listener: (value: T) => void) => () => void; getSnapshot?: () => T }, onChange: (value: Sel) => void, selector: (value: T) => Sel, isEqual?: (current: Sel, next: Sel) => boolean): void
  • bindSubscribable<T>(service: { subscribe: (listener: (value: T) => void) => () => void; getSnapshot?: () => T }, onChange: (value: T) => void, selector?: (value: T) => T, isEqual?: (current: T, next: T) => boolean): void
  • bindSubscribable<T, Sel>(service: { subscribe: (listener: (value: T) => void) => () => void; getSnapshot?: () => T }, onChange: (value: Sel) => void, selector: (value: T) => Sel, isEqual?: (current: Sel, next: Sel) => boolean): void
    • Named subscriptions are tracked on this.namedSubscriptions. Rebinding the same subscriptionName unsubscribes the previous binding before replacing it.
    • Unnamed subscriptions are tracked on this.subscriptions.
    • Both named and unnamed subscriptions invoke onChange with the current snapshot when available.
    • If selector is omitted, identity selection is used.
    • onChange is only called when selected value changes according to isEqual (default Object.is).

NativeStateHandler<S, A>

Zero-dependency, plain JS handler. Extends BaseStateHandler.

Constructor:

protected constructor({
  initialState,
  options
}: {
  initialState: S;
  options?: {
    devTools?: { enabled?: boolean; namespace?: string };
    distinct?: {
      enabled?: boolean;
      comparator?: (previous: S, next: S) => boolean;
    };
    useDistinctUntilChanged?: boolean;
  };
})

Public methods:

  • subscribe(listener: () => void): () => void
  • subscribe(listener: (value: S) => void): () => void

Notes:

  • The handler uses plain JS and a Set for listener management.
  • Zero external dependencies.
  • Distinct behavior defaults to enabled.
  • Configure it globally via setupStatusQuo or per handler via options.distinct.
  • Devtools can be enabled globally via setupStatusQuo({ devTools: { enabled: true } }) or overridden per handler via options.devTools.
  • subscribe fires immediately with the current snapshot and then on subsequent changes.
  • Subscribers receive the next state snapshot as a callback argument.

ObservableStateHandler<S, A>

RxJS-backed handler. Extends BaseStateHandler.

Constructor:

protected constructor({
  initialState,
  options
}: {
  initialState: S;
  options?: {
    devTools?: { enabled?: boolean; namespace?: string };
    distinct?: {
      enabled?: boolean;
      comparator?: (previous: S, next: S) => boolean;
    };
    useDistinctUntilChanged?: boolean; // optional override
  };
})

Public methods:

  • getObservable(options?: { useDistinctUntilChanged?: boolean }): Observable<S>
  • getObservableItem(key: keyof S): Observable<S[keyof S]>
  • subscribe(listener: () => void): () => void
  • subscribe(listener: (value: S) => void): () => void

Notes:

  • The observable stream uses distinctUntilChanged by default.
  • Distinct behavior can be configured globally via setupStatusQuo or per handler via options.distinct.
  • Devtools can be enabled globally via setupStatusQuo({ devTools: { enabled: true } }) or overridden per handler via options.devTools.
  • subscribe fires immediately with the current snapshot and then on subsequent changes.
  • Subscribers receive the next state snapshot as a callback argument.

SignalStateHandler<S, A>

Signals-backed handler. Extends BaseStateHandler.

Constructor:

protected constructor({
  initialState,
  options
}: {
  initialState: S;
  options?: {
    devTools?: { enabled?: boolean; namespace?: string };
    distinct?: {
      enabled?: boolean;
      comparator?: (previous: S, next: S) => boolean;
    };
    useDistinctUntilChanged?: boolean;
  };
})

Public methods:

  • getSignal(): Signal<S>
  • subscribe(listener: () => void): () => void
  • subscribe(listener: (value: S) => void): () => void

Notes:

  • Distinct behavior defaults to enabled.
  • Configure it globally via setupStatusQuo or per handler via options.distinct.
  • Devtools can be enabled globally via setupStatusQuo({ devTools: { enabled: true } }) or overridden per handler via options.devTools.
  • useDistinctUntilChanged remains available as a shorthand enable/disable override.

setupStatusQuo

type StatusQuoConfig = {
  devTools?: {
    enabled?: boolean;
  };
  distinct?: {
    enabled?: boolean;
    comparator?: (previous: unknown, next: unknown) => boolean;
  };
};

function setupStatusQuo(config?: StatusQuoConfig): void

makeStateSingleton

type StateSingletonOptions = {
  destroyOnNoConsumers?: boolean; // default: false
};

function makeStateSingleton<S, A>(
  factory: () => StateSubscriptionHandler<S, A>,
  options?: StateSingletonOptions
): {
  getInstance: () => StateSubscriptionHandler<S, A>;
}

Lifecycle behavior:

  • destroyOnNoConsumers: false (default): keep the same singleton instance alive when no component is subscribed.
  • destroyOnNoConsumers: true: destroy and recreate singleton instances with mount lifecycle.

Hooks

  • React entrypoint: @veams/status-quo/react
  • useStateHandler<V, A, P extends unknown[]>(factory: (...args: P) => StateSubscriptionHandler<V, A>, params?: P)
    • Returns StateSubscriptionHandler<V, A>.
  • StateProvider<V, A>({ instance }: { instance: StateSubscriptionHandler<V, A> })
    • Shares a handler instance with a subtree.
  • useProvidedStateHandler<V, A>()
    • Returns StateSubscriptionHandler<V, A>.
  • useProvidedStateActions<V, A>()
    • Returns A.
  • useProvidedStateSubscription<V, A, Sel = V>(selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean)
    • Returns [state, actions].
  • useStateActions<V, A>(handler: StateSubscriptionHandler<V, A>)
    • Returns A.
  • useStateSubscription<V, A, Sel = V>(source: StateSubscriptionHandler<V, A> | StateSingleton<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean)
    • Returns [state, actions].
  • useStateFactory<V, A, P extends unknown[], Sel = V>(factory: (...args: P) => StateSubscriptionHandler<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean, params?: P)
    • Returns [state, actions].
  • useStateSingleton<V, A, Sel = V>(singleton: StateSingleton<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean)
    • Returns [state, actions].

Migration

From pre-1.0 releases:

  1. Rename StateHandler -> ObservableStateHandler.
  2. Implement subscribe() and getSnapshot() on custom handlers.
  3. Replace getStateAsObservable() with getObservable().
  4. Replace getStateItemAsObservable() and keyed getObservable(key) with getObservableItem(key).
  5. Move React hooks and StateProvider imports from @veams/status-quo or @veams/status-quo/hooks to @veams/status-quo/react.
  6. Update devtools config:
    • From: super({ initialState, devTools: { ... } })
    • To: super({ initialState, options: { devTools: { ... } } })