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 🙏

© 2024 – Pkg Stats / Ryan Hefner

watch-redux

v1.0.1

Published

Watch Redux for granular changes

Downloads

4

Readme

watch-redux

This is...

A library that makes observing changes in a Redux store using selectors very easy, and efficient. It provides watching for changes with full granularity.

Disclaimer: This library is still in its early stages and may still undergo some development, polish and see new APIs.

Installation

npm install watch-redux --save

Details

watch-redux is smart enough to avoid invoking your watcher callbacks when values didn't really change. The only requirement is that you don't assign to your old state objects (a general Redux rule, and best enforced with a library such as deep-freeze), but instead use the built-in APIs to create new objects and arrays when mutations occur.

In essence, we replace the Object.assign-pattern followed by a diffing algorithm by a single assign() function, which immediately registers the change.

Usage

Bootstrapping

var createStore = require('redux').createStore;
var watchRedux = require('watch-redux');

var store = createStore(/* how you normally set up your Redux store */);
watchRedux.setup(store);

Reducers

For the system to know what changed, you need to use specialized API that helps with the assignment of properties to your objects. That means you cannot depend on functions like Object.assign. Doing a diff after reducing is rather heavy, and we want to avoid this by design.

Assigning values to an object

When assigning a value using assign(state, changes), all changes will be registered and cause relevant watchers to be notified.

Example:

var assign = require('watch-redux/reduce/assign');

function reduce(state, action) {
	// eg: state is { age: 30 }

	if (action.type === 'AGE_INC') {
		state = assign(state, {
			age: state.age + action.inc
		});
	}

	return state;
}

store.dispatch({ type: 'AGE_INC', inc: 1 });

Reducing a collection of objects

The following example shows how to run a single reducer on each property of an object, or each entry of an array. This will call assign for you on those entries.

var assign = require('watch-redux/reduce/assign');
var reduceAll = require('watch-redux/reduce/reduceAll');

function reduceUser(state, action) {
	if (action.type === 'AGE_INC' && action.id === state.id) {
		state = assign(state, {
			age: state.age + action.inc
		});
	}
}

function reduce(state, action) {
	// eg: state is { abc: { id: 'abc', age: 30 }, def: { id: 'def', age: 40 } }

	return reduceAll(state, action, reduceUser);
}

store.dispatch({ type: 'AGE_INC', id: 'def', inc: 1 });

Watchers

To watch for changes, you must register a selector. Selectors in watch-redux are objects with 2 methods:

  • watch(state) receives the global state and must return a key/value object. Its values will be observed, and its keys serve as labels for the transform method.
  • transform(states) receives the result of the call to watch. Every time any of the objects being watched changes, the transform method will be invoked again. It may return anything you want, and it will be the value passed to the callback you register.

The moment you register your watcher, its callback will be immediately invoked with the current value. We found that this is very useful when you are linking your state to your UI.

Example:

var userNameSelector = {
	watch: function (state) {
		// states is { users: { id: { name: 'Bob' }, ... } }
		return {
			user: state.users[state.myUserId]
		};
	},
	transform: function (states) {
		return states.user.name;
	}
};

var watcher = watchRedux.watch(userNameSelector, function (name) {
	console.log('My name is now:', name);
});

watcher.destroy();

Once you have no longer need to watch the selector, you may call .destroy() on the watcher object returned by watchRedux.watch(...). Your watcher callback will never be invoked again.

License

MIT