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

satcheljs

v4.3.1

Published

Store implementation for functional reactive flux.

Downloads

829

Readme

Satchel

Satchel is a dataflow framework based on the Flux architecture. It is characterized by exposing an observable state that makes view updates painless and efficient.

npm Build Status License: MIT

Influences

Satchel is an attempt to synthesize the best of several dataflow patterns typically used to drive a React-based UI. In particular:

  • Flux is not a library itself, but is a dataflow pattern conceived for use with React. In Flux, dataflow is unidirectional, and the only way to modify state is by dispatching actions through a central dispatcher.
  • Redux is an implementation of Flux that consolidates stores into a single state tree and attempts to simplify state changes by making all mutations via pure functions called reducers. Ultimately, however, we found reducers and immutable state cumbersome to deal with, particularly in a large, interconnected app.
  • MobX provides a seamless way to make state observable, and allows React to listen to state changes and rerender in a very performant way. Satchel uses MobX under the covers to allow React components to observe the data they depend on.

Advantages

There are a number of advantages to using Satchel to maintain your application state:

  • Satchel enables a very performant UI, only rerendering the minimal amount necessary. MobX makes UI updates very efficient by automatically detecting specifically what components need to rerender for a given state change.
  • Satchel's datastore allows for isomorphic JavaScript by making it feasible to render on the server and then serialize and pass the application state down to the client.
  • Satchel supports middleware that can act on each action that is dispatched. (For example, for tracing or performance instrumentation.)
  • Satchel is type-safe out of the box, without any extra effort on the consumer's part.

Installation

Install via NPM:

npm install satcheljs --save

In order to use Satchel with React, you'll also need MobX and the MobX React bindings:

npm install mobx --save

npm install mobx-react --save

Usage

The following examples assume you're developing in Typescript.

Create a store with some initial state

import { createStore } from 'satcheljs';

let getStore = createStore(
    'todoStore',
    { todos: [] }
);

Create a component that consumes your state

Notice the @observer decorator on the component—this is what tells MobX to rerender the component whenever the data it relies on changes.

import { observer } from 'mobx-react';

@observer
class TodoListComponent extends React.Component<any, any> {
    render() {
        return (
            <div>
                {getStore().todos.map(todo => <div>{todo.text}</div>)}
            </div>
        );
    }
}

Implement an action creator

Note that, as a convenience, Satchel action creators created with the action API both create and dispatch the action. This is typically how you want to use action creators. If you want to create and dispatch the actions separately you can use the actionCreator and dispatch APIs.

import { action } from 'satcheljs';

let addTodo = action(
    'ADD_TODO',
    (text: string) => ({ text: text })
);

// This creates and dispatches an ADD_TODO action
addTodo('Take out trash');

Implement a mutator

You specify what action a mutator subscribes to by providing the corresponding action creator. If you're using TypeScript, the type of actionMessage is automatically inferred.

import { mutator } from 'satcheljs';

mutator(addTodo, (actionMessage) => {
    getStore().todos.push({
        id: Math.random(),
        text: actionMessage.text
    });
};

Orchestrators

Orchestrators are like mutators—they subscribe to actions—but they serve a different purpose. While mutators modify the store, orchestrators are responsible for side effects. Side effects might include making a server call or even dispatching further actions.

The following example shows how an orchestrator can persist a value to a server before updating the store.

import { action, orchestrator } from 'satcheljs';

let requestAddTodo = action(
    'REQUEST_ADD_TODO',
    (text: string) => ({ text: text })
);

orchestrator(requestAddTodo, async (actionMessage) => {
    await addTodoOnServer(actionMessage.text);
    addTodo(actionMessage.text);
});

mutatorAction

In many cases a given action only needs to be handled by one mutator. Satchel provides this utility API which encapsulates action creation, dispatch, and handling in one simple function call.

The addTodo mutator above could be implemented as follows:

let addTodo = mutatorAction(
    'ADD_TODO',
    function addTodo(text: string) {
        getStore().todos.push({
            id: Math.random(),
            text: actionMessage.text
        });
    });

This is a succinct and easy way to write mutators, but it comes with a restriction: the action creator is not exposed, so no other mutators or orchestrators can subscribe to it. If an action needs multiple handlers then it must use the full pattern with action creators and handlers implemented separately.

License - MIT