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

insula

v2.0.3

Published

Insula is an event-driven state management library for JavaScript applications.

Downloads

4

Readme

Insula is an event-driven state management library for JavaScript applications.

build status npm version

Usage

Installation

npm

npm install --save insula

yarn

yarn add insula

Creating a state store

To create a new store initialize a new Store object by passing in the initial state.

import Store from 'insula';

const initialState = {foo: 'bar'};
const store = new Store(initialState);

State management

Accessing store values

There are two ways to access values from the store. getState returns the entire state value, and getPartialState returns a portion of the state described by the passed selector.

const store = new Store({
    nested: {
        object: 'value'
    }
});

store.getState(); // {nested: {object: "value"}}
store.getPartialState(['nested']); // {object: "value"}
store.getPartialState(['nested', 'object']); // "value"

Note that accessing any non-existant part of state will return a null value.

const store = new Store({});
store.getPartialState(['some', 'nonexistant', 'object']); // null

Updating store values

A Store has two ways to update its values. setState replaces the entire store value with a new object while setPartialState updates only a portion of state specified by a selector.

const store = new Store({foo: 'bar'});

store.setState({fiz: 'biz'});
store.getState(); // {fiz: 'biz'}

store.setPartialState(['foo'], 'bar');
store.getState(); // {fix: 'biz', foo: 'bar'}

Note that setting a part of state whose object chain does not exist will create the necessary objects inside state.

const store = new Store({});
store.setPartialState(['nested', 'object'], 'value');
store.getState(); // {nested: {object: "value"}}

Subscribing to state changes

A Store allows subscriber functions to be added for all or part of state. By using selectors to explcitly declare what part of state to subscribe to, these functions are only called when relevant pieces of state are changed.

The subscribeToState method takes two arguments, the first is an array of selectors and the second is the subscriber function. When called, the subscriber is passed an array of values in response to the selectors.

const store = new Store({
    nested: {object: 'value'},
    foo: 'bar'
});

const selectors = [
    ['nested', 'object'],
    ['foo']
];

function subscriber(values) {
    // values is an array with the state values contained in `nested.object` and `foo`
    const [nestedObject, foo] = values;
};

store.subscribeToState(selectors, subscriber);

store.setPartialState(['foo'], 'baz');
// subscriber will be called with "value" and "baz" as the two values

A subscriber will be called if any part of its selector overlaps with a state change. Take a look at this example to understand what changes will affect a subscriber.

store.subscribeToState([['nested', 'object']], ([nestedObject]) => {});

// these updates will trigger the subscriber
store.setState({}); // changing the entire state will affect any subscriber
store.setPartialState(['nested'], {}); // the new value for `nested` could change `nested.object`
store.setPartialState(['nested', 'object'], {}); // this matches the subscriber
store.setPartialState(['nested', 'object', 'subobject'], {}); // a piece of state contained by the selector changed

// these will not trigger the subscriber
store.setPartialState(['somewhere-else'], {}); // `somewhere-else` doesn't match the selector at all
store.setPartialState(['nested', 'someOtherObject'], {}); // `nested.object` doesn't care about `nested.someOtherObject`

Unsubscribing

The subscribeToState method returns a function that will remove the subscription.

const store = new Store({});

// add a subscription
const unsubscribe = store.subscribeToState([['foo']], () => {});

// remove the subscription
unsubscribe();

Event system

Insula encourages state updates to be driven by events. The Store provides on and off methods to add and remove event listeners as well as a dispatch method to send events and payloads. Event listeners are called with the event payload and an object with additional functions for interacting with the state. These listeners can optionally dispatch other events, retrieve state values, or update state values.

const store = new Store({});

store.on(
    'MY_EVENT',
    (payload, {dispatch, getState, getPartialState, setState, setPartialState}) => {
        // ...
    }
);

store.dispatch('MY_EVENT', {the: 'payload'});

Selectors

A selector is an array of string values describing how to access a part of state. To set or get a state value the array values are used to traverse the state object. Using selectors allows Insula to understand which state subscription functions are affected by a state update.

Using arrays to describe the selectors allows Insula to support any kind of data structure, including when object keys include the . character. There is a middleware if you'd rather use strings such as nested.object for your selectors.

Performance

Performance is a major goal for Insula and is achieved primarily through two mechanisms. Selectors allow Insula to understand the scope of a change and call only those functions which have subscribed to an affected part of state.

The second key element to Insula's performance is subscriber batching. While calls to setState and setPartialState are synchronous (you can get call getState/getPartialState right away and retrieve the new state values), any affected subscribers will not be called until the next event loop cycle.

const store = new Store({});

const subscriber = () => console.log('subscriber called'); // called only once in this example

store.subscribeToState([[]], subscriber); // empty selector subscribes to all state changes

store.setState({});
store.setPartialState(['nested'], {});
store.setPartialState(['foo'], 'bar');
store.setPartialState(['foo'], 'baz');
store.setState({something: 'else'});