Package detail

@bigcommerce/data-store

bigcommerce12.7kMIT1.0.3

A JavaScript library for managing application state

readme

@bigcommerce/data-store

Build Status

A JavaScript library for managing application state.

It helps you to enforce unidirectional data flow in your application, by allowing you to:

  • Subscribe to changes to the application state
  • Update the state in a serial and immutable fashion

Install

You can install this library using npm.

npm install --save @bigcommerce/data-store

Requirements

This library requires Promise polyfill if you need to support older browsers, such as IE11.

You may need to create Observables when using this library (please refer to the usage section). We recommend you to use rxjs until the time comes when you can create them natively.

Usage

Create a store

import { createDataStore } from '@bigcommerce/data-store';

const reducer = (state, action) => {
    switch (action.type) {
    case 'INCREMENT':
        return { ...state, count: state.count + 1 };

    case 'UPDATE_COUNT':
        return { ...state, count: action.payload };

    default:
        return state;
    }
};

const initialState = { count: 0 };
const store = createDataStore(reducer, initialState);

To update the current state

import { createAction } from '@bigcommerce/data-store';

store.dispatch(createAction('INCREMENT'));
store.dispatch(createAction('UPDATE_COUNT', 10)));

To update the state asynchronously, you need to create an observable that emits actions:

import { Observable } from 'rxjs';

const action$ = Observable
    .ajax({ url: '/count' })
    .map(({ response }) => createAction('UPDATE_COUNT', response.count))

store.dispatch(action$);

To avoid race condition, actions get dispatched in a series unless you specify a different dispatch queue, i.e.:

store.dispatch(action$);
store.dispatch(action$);

// The following call does not wait for the previous calls
store.dispatch(action$, { queueId: 'foobar' });

Wrap the observable in a closure if you want to access the store elsewhere but don't have direct access to it (i.e.: inside an action creator):

// In an action creator
function updateAction() {
    return (store) => Observable
        .ajax({ url: '/count' })
        .map(({ response }) => {
            const { count } = store.getState();

            return createAction('UPDATE_COUNT', count + response.count);
        });
}
// In a component
store.dispatch(updateAction());

To do something after an asynchronous dispatch:

const { state } = await store.dispatch(action$);

console.log(state);

To subscribe to changes

To changes and render the latest data:

store.subscribe((state) => {
    console.log(state);
});

The subscriber will get triggered once when it is first subscribed. And it won't get triggered unless there's a data change.

To filter out irrelevant changes:

// Only trigger the subscriber if `count` changes
store.subscribe(
    (state) => { console.log(state); },
    (state) => state.count
);

To transform states and actions

To transform the return value of getState or parameter value of subscribe:

const stateTransformer = (state) => ({ ...state, transformed: true });
const store = createDataStore(reducer, initialState, { stateTransformer });

console.log(store.getState()); // { count: 0, transformed: true }

To transform dispatched actions:

const actionTransformer = (action) => ({ ...action, transformed: true });
const store = createDataStore(reducer, initialState, { actionTransformer });

console.log(store.dispatch(createAction('INCREMENT'))); // { type: 'INCREMENT', transformed: true }

Contribution

To release:

npm run release

To see other available commands:

npm run

License

MIT

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

1.0.3 (2025-09-05)

Bug Fixes

  • core: CHECKOUT-9450 Fix issue with ES6 as functions with default arguments no longer return length (9845617)

1.0.2 (2024-01-23)

1.0.1 (2019-08-07)

Bug Fixes

  • core: CHECKOUT-4272 Only create new frozen objects if they are different from previous frozen objects (1911834)

1.0.0 (2019-08-05)

Features

  • core: CHECKOUT-4272 Add ability to pass custom equality check function (d574f1a)

Performance Improvements

  • core: CHECKOUT-4272 Switch to do shallow comparison by default (953ee15)

BREAKING CHANGES

  • core: This commit changes the way we detect changes between the previous and the new state. Previously, we do a deep equality check between the two by default. With this change, we do a shallow equality check instead. This means that subscribers will get notified if any of the immediate members of the previous state is different to the new. This behaviour can be changed by configuring equalityCheck option when creating the DataStore instance.

0.2.7 (2019-05-23)

Bug Fixes

  • core: CHECKOUT-4137 Catch error if unable to freeze or perform check (a4d9ea6)

0.2.6 (2019-01-08)

Bug Fixes

  • core: CHECKOUT-3790 Allow composeReducers function to accept reducers of different type (d66d0f4)
  • core: CHECKOUT-3790 Ensure reducers have the expected signature before composing them (8b7f3a9)

0.2.5 (2018-12-03)

Bug Fixes

  • core: CHECKOUT-3135 Upgrade Rx to version 6 to bring in various performance improvements and features (6849133)

0.2.4 (2018-11-15)

Bug Fixes

  • core: CHECKOUT-3462 Execute thunk actions sequentially (5224e69)

0.2.3 (2018-09-21)

Bug Fixes

  • core: CHECKOUT-3475 Export missing interfaces (56ca1a3)

0.2.2 (2018-08-23)

Bug Fixes

  • common: CHECKOUT-3462 Remove Node engine field (3c034ce)

0.2.1 (2018-08-07)

0.2.0 (2018-08-07)

Bug Fixes

  • core: CHECKOUT-3011 Don't trigger subscribers if only transformed state changes (f99d186)

Features

  • core: CHECKOUT-3011 Skip initial subscriber notification (2869178)

0.1.8 (2018-05-27)

Bug Fixes

  • common: CHECKOUT-3191 Fix sourcemaps by enabling inlineSources (3b85d78)

0.1.7 (2018-05-14)

0.1.6 (2018-05-14)

Bug Fixes

  • core: CHECKOUT-3053 Fix issue related to error action not able to dispatch (443c300)
  • core: CHECKOUT-3053 More permissive default action type (7b8e2ad)

0.1.5 (2018-05-10)

0.1.4 (2018-05-07)

Bug Fixes

  • core: CHECKOUT-3053 Export Reducer and ReducerMap interfaces (d33d91c)
  • core: CHECKOUT-3053 Fix type definition for actionTransformer option. Use Subscribable interface instead. (53fc40e)

0.1.3 (2018-03-26)

Bug Fixes

  • core: CHECKOUT-3027 Fix thunk actions not getting dispatched in separate queues (8a0f758)

0.1.2 (2018-03-20)

Bug Fixes

  • core: CHECKOUT-3007 Change ThunkAction return type to SubscribableOrPromise instead of concrete Observable type (fa090e9)
  • core: CHECKOUT-3007 Set default type for ThunkAction (cbd7bdc)

0.1.1 (2018-03-13)

Bug Fixes

  • core: CHECKOUT-2450 Fix Reducer and Action type definition (07f9baf)
  • core: CHECKOUT-2992 combineReducers and composeReducers should only return new instance if different in value (c4e416b)

0.1.0 (2018-03-01)

Bug Fixes

  • core: CHECKOUT-2450 Create new observable from observable-like action (07aaed5)
  • core: CHECKOUT-2450 Mark options as optional (cbe8631)

Features

  • core: CHECKOUT-2450 Add DataStore module (4fabb82)