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 🙏

© 2025 – Pkg Stats / Ryan Hefner

object-state-storage

v3.3.1

Published

Local state storage for javascript apps

Readme

Object State Storage is a tiny state container written in es6.

Install with npm install --save object-state-storage or yarn add object-state-storage. Note that no compiled version is provided. So if you are using webpack and babel, you might want to explicitly include object-state-storage in babel-loader rule.

API

  • const store = new ObjectStateStorage([initialState: Object]) - create new storage with optional initial state.
  • const unsubscribe = store.subscribe(listener: (currentState, prevState, label) => {}) - subscribe to state changes, returns unsubscribe function. label might be useful for debugging.
  • store.setState(modifier: Object or ([currentState]) => Object, [label]) - recursively merges current state and modifier object. If modifier is a function, it might take currentState as an argument and return an Object, that is going to be merged into current state. Merge function can be reused: import { merge } from 'object-state-storage'. If modification results in null or undefined, nothing happens and subscribers are not called.
  • store.resetState(newState: Object or ([currentState]) => Object, [label]) - replaces current state with provided newState Object. If newState is a function, it might take currentState as an argument and return an Object, that is going to replace current state. If modification results in null or undefined, nothing happens and subscribers are not called.
  • store.state - returns cloned state. Clone function is available via import { clone } from 'object-state-storage'

Example

import ObjectStateStorage from 'object-state-storage';
import { merge, clone } from 'object-state-storage';

// create a storage unit with initial value { foo: 'bar' }
const store = new ObjectStateStorage({ foo: 'bar' });

// subscribe to store updates
const unsubscribe = store.subscribe((curState, prevState) => {
  // log previous state and current state
  console.log(curState, prevState);
  // unsubscribe
  unsubscribe();
});

// update the state (merges current state and provided object)
// expect to see in console { foo: 'bar' } and { foo: 'bar', bar: 'foo' }
store.setState({ bar: 'foo' });

// log current state after store was updated
// expect the following object to be in console.log
// {
//   foo: 'bar',
//   bar: 'foo',
// }
console.log(store.state);

// resets the state (replaces current state and provided object)
store.resetState({ foobar: 'foobar' });

// expect to see { foobar: 'foobar' } in console
console.log(store.state);

// immutable merge, used in setState:
const mergeExample = { foo: 'bar' };
const mergeResult = merge(mergeExample, { bar: 'foo' });

// expect { foo: 'bar' }
console.log(mergeExample);
// expect { foo: 'bar', bar: 'foo' }
console.log(mergeResult);

// clone:
const cloneExample = { foo: 'bar' };
const cloneResult = clone(cloneExample);
cloneExample.bar = 'foo';

// expect { foo: 'bar', bar: 'foo' }
console.log(cloneExample);
// expect { foo: 'bar' }
console.log(cloneResult);

Note

I've previously written, that this state container is based on Redux, but without reducers and other related things. After reading comments to this publication on hacker news I decided that it might be a bit misleading.

This library is not a replacement for Redux, but can be a good alternative if you can live without benefits of message-passing system and you don't want to repeat everything three times, an action type constant, the action type creator function, and the reducer (reference tweet).

More links on understanding Redux:

When using object-state-storage with React it's better to put business logic into separate functions (actions) and only modify store state there (to inject those in components, you might want to use something like components-di). Actions combine reducers and action creators (redux) into a single function. I guess testing actions might be treated as integration tests, as they are not pure functions and have side-effects.