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

warix-state

v1.0.22

Published

Warix immutable state

Downloads

31

Readme

Warix State

Warix State is an immutable state manager that follows lossely the flux pattern, although very similar in concept with Redux, WarixState prefers common actions with specific payloads instead of specific actions with common payloads.

Warix State uses RxJs at its core to dispatch, modify and monitor the data, with ImmutabeJS for data handling and ensure immutability.

Usage

The contructor for a warix state takes an optional Map<string, any> or {} as it initial state, if none is specified, the state is initialized with an empty Immutable map

const state = new WarixState({ foo: { bar: 1 } });

Dispatching actions can be done by either the dispatch method

state.dispatch('actionType', actionPayload);
state.dispatch({ type: '', payload: null });

Or by one of the shortcut methods:

  • set
  • setIn
  • apply
  • patch
  • listPush
  • listPop
  • listShift
  • listUnshift
  • listSplice
  • listInsert
  • listRemoveAt
  • listRemoveFind
  • listSort
  • listFilter

Paths

Paths to properties are specified either by an string array or by a dot delimeted pathing

state.setIn([ 'foo', 'bar' ], 0);
state.setIn('foo.bar', 0);

Path resolution is possible witht the following operands

  • ~ Moves the current path to the root
  • .. Moves the path up one level
  • . Keeps the path in the current level

Path resolution can only be performed when the path is specified as an array

Custom Actions

Actions in WarixState are considered of 3 types

PreProcessors

Transform dispatched actions into another actions, useful when creating specific actions that execute common actions. If the purpose is to increase a property current value by 1, one way of achieving this is by dispatching an apply action that performs the operation:

state.apply('foo.bar', (currentValue: number) => currentValue + 1);

Another approach is to register a PreProcessor action increase that transforms the action into the apply operation:

const increasePreHandler = state.registerPreProcessor('increase', (state, action) => {
    return WarixStateActions.apply(action.payload.path, (currentValue: number) => currentValue + action.payload.value);
});

Afterwards the increase action can be called directly

state.dispatch('increase', { path: 'foo.bar', value: 1 });

Processors

In charge of reducing the dispatched actions into actual state modifications, theay are executed after all PreProcessors have been applied to the dispatched actions

const actionHandler = state.registerProcessor('action', (state, action) => {
    return state.setIn(action.payload.path, action.payload.value);
});

AsyncProcessors

Async processors are not executed immediatley, instead they are excuted when a provided observable emits one of its lifecycle values.

  • START Executed when the processor is first subscribed to the observable
  • NEXT Executed when the observable emits a next value
  • ERROR Executed when the observable throws an error
  • COMPLETE Executed when the observable is completed

Due to the nature of observables, async processors are allways subscribed with the take(1) RxJs operator

Async processors registrations dispatch actions modified by the state the subscription is currently at. Consider an async preprocessor load, its emitted action type would be as follows :

{ type: 'load::START', payload: null }
{ type: 'load::NEXT', payload: emittedValue }
{ type: 'load::ERROR', payload: error }
{ type: 'load::COMPLETE', payload: null }

PreProcessors and Processors must be registered taking into account the actionType modifiers

const asyncLoadHandler = state.registerAsync('load', (state, action) => someObservable$);

Processor Handlers

All processors registration return a handler to it that allows for control over it, allowing it to pause / resume or remove the processor. See Interfaces for specifics

SubStates

Since almost all actions on WarixState depends on specific paths, a subHandler or proxy can be created that transforms all actions executed on it to be localized to a given path

const proxy = state.subHandler('some.really.deep.path.in.the.state');

Proxys provide the same functionality as WarixState but removing the need of specifing full paths for actions, since all actions are created based on the path of the proxy

proxy.setIn('prop', value);
// is equivalent to
state.setIn('some.really.deep.path.in.the.state.prop', value);

Use path resolution in the proxy if properties of the upper levels are required

proxy.select([ '~', 'some', 'really'])

Path resolution can only be performed when the path is specified as an array

Processor registrations on a proxy (PreProcessor, Processor or AsyncProcessor) although registered globally, will be removed once the complete method is called in the Proxy

Monitoring (Reactivity)

To monitor specific properties of the state use one of the selection methods

  • select: Obtains an observable to the underlying value of a key in the state that will dispatch whenever the value changes
  • selectMap: Obtains an observable to the underlying value of a key in the state that will dispatch whenever the value changes. If the value is a Map or a List, the value is flattened with its toJS method. Flattening a immutable object can be an expensive operation, use with caution.
  • on: Obtains an observable that will emit whenever the specifed action type is dispatched in the state

Reading

When reading a value from the state sync, use one of the peek methods

  • peek: Obtains the underlying value of the state
  • peekKey: Obtains the underlying value of a key in the state

Decorators

Decorators provide an easier selection of properties to the state

  • @Select : Selects an observable to the provided path from the owning object WarixState

  • @SelectFlatten: Selects an observable to the provided path from the owning object WarixState, if the object is an immutable List or Map, the object is flatten with the toJS method of the immutable object. Flattening an immutable object can be an expensive operation if the value changes constantly, use with caution

  • @FromState: Creates a get/set accesor to the provided path from the owning object WarixState or WarixStateProxy

@FromState('user.name') public userName: string;
@Select('user') public userData$: Observable<Map<string, any>>;
@SelectFlatten('user') public userDataFlat: Observable<any>;

As well as the select and selectFlatten methods of WarixState, @Select and @SelectFlatten decorators can provide a second argument of type IWarixSelectSettings to fine tune the resulting observable