Coder Social home page Coder Social logo

insula's Introduction

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'});

insula's People

Contributors

chandlerprall avatar hartzis avatar michaelmerrilltest avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.