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

enviante

v4.2.1

Published

Class registry and intent dispatch

Downloads

26

Readme

npm install enviante

Decoupled, predictable application state. Subscribe anywhere, dispatch anywhere.

import createStore from 'enviante';
const connect = createStore({count: 0});

connect(({subscribe}) => {
	document.getElementById('counter').innerHTML = subscribe('count');
});

connect(({dispatch}) => {
	document.getElementById('increment').addEventListener('click', () => {		
		dispatch('count', count => count + 1);
	});
});

connect = createStore(state)

Create a new store with an initial state. Returns a function to connect to the store.

connect(receiver: ({subscribe, dispatch, unsubscribe, meta}) => {})

Sets up a connection from the store via the receiver. The function is called an object containing keys subscribe, dispatch, unsubscribe, and meta. Call subscribe to register a subscription to part of the state: when the state changes, the receiver is called again. Call dispatch to change part of the state and notify subscribers. Call unsubscribe to remove subscriptions. meta is information passed along with a dispatch, see below.

The receiver is called once, immediately. It will only be called again if you subscribe to any state. If you don't call subscribe, it's safe to register event handlers etc. in here.

subscribe(['state', 'path'], defaultValue)

Returns the nested state value at the path, falling back to a default value. Future dispatches to this path (or a sub-path) will call the receiver again.

dispatch(['state', 'path'], updater, meta)

Modifies the nested state value at the path with an updater function. The updater is called with the previous value, and its return value replaces the state at the path. If the updater returns undefined, the previous value is used. If the value is an object, mutations will be kept.

Any previous subscriptions at this path (or a sub-path) will call the receiver again. The last argument, meta, is passed along to receivers, which is useful for things like ignoring updates from certain sources.

unsubscribe(['state', 'path'])

Removes any previous subscription to the path. Future subscriptions will still cause reruns.

Inspiration

Redux and Meteor's react-meteor-data.

I love Redux. I find it hard to build my state and components in the top-down way it seems to favour, and mutating state can be nicer than deep immutable updates. I also love Meteor, but Tracker is far too magic.

Enviante lets you imbue any part of your application with an arbitrary chunk of state. If your dispatches are pure, your state is predicable. Since each dispatch only sees a small part of the state, it's also safe to mutate in-place.

History

Versions 1 and 2: Highland streams. "Receivers" that receive "Intents" and return a stream of Intents. Hard to reason about laziness, need to manually drain everything.

Version 3: Bacon streams. Concept of nested state appears. All receivers are passed in as a tree on init. Still a bunch of internal mystery meat, still weird laziness constraints.

Licence

MIT