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

singulum

v1.0.1

Published

State management sanity with minimal effort

Downloads

6

Readme

singulum

singulum is a state container and manager for your JavaScript application with a tiny footprint (3.2KB minified and gzipped), attempting to have an explicit and straightforward API while maintaining the best aspects of both Flux and Redux.

If you are unfamiliar with the Flux principles there are countless articles and blog posts out there, and if you are unfamiliar with Redux then there are some spectacular videos made by it's founder, Dan Abramov. Knowing Flux or Redux is not required for using singulum, however having a basic understanding of both provide a good foundation.

Getting started

singulum acts as a singleton object, which has a small API for building your application's state tree. To install:

npm i singulum --save

Then to create your first branch:

import singulum from 'singulum';

const actions = {
    todos: {
        addTodo(todos = [], value) {
            return [
                ...todos,
                {
                    id: todos.length.
                    value
                }
            ];
        },
        removeTodo(todos = [], id) {
            const todoToRemove = todos.findIndex((todo) => {
                return todo.id === id;
            });
        
            return [
                ...todos.slice(0, todoToRemove),
                ...todos.slice(todoToRemove + 1, todos.length)
            ];
        }
    }
};

const initialValues = {
    todos: []
};

export default singulum.branch(actions, initialValues, 'todosBranch');

Actions are automatically bound to the branch's store, and whatever value is returned from those functions is then applied to the state. You can scope the actions to specific properties on the branch's store as well; in this case, our actions are specific to todos, so they are mapped automatically to the todos property on our store when the branch is created (no switch statement or merging of full state needed). Now, if you wanted to add a todo:

import todosBranch from './todosBranch.js';

const todosActions = todosBranch.actions;

console.log(todosBranch.store); // {todos: []}

todosActions.addTodo('Do a little dance');
todosActions.addTodo('Make a little love');
todosActions.addTodo('Get down tonight');

console.log(todosBranch.store);
/*
    {
        [
            {id: 0, value: 'Do a little dance'},
            {id: 1, value: 'Make a little love'},
            {id: 2, value: 'Get down tonight'}
        ]
    }
*/

todosActions.removeTodo(1);

console.log(todosBranch.store);
/*
    {
        [
            {id: 0, value: 'Do a little dance'},
            {id: 2, value: 'Get down tonight'}
        ]
    }
*/

Boom, you're on your way.

This is a rudimentary example obviously, but there is much more to see over in the API section, including how to use reducers for your entire store, as well as how to easily bind it to the component lifecycle if you are using React.

Why create singulum?

Flux was a giant leap in the right direction for managing the data flow within applications. That said, the clear separation of actions and stores (and then manuall binding actions to their store property) creates a lot of boilerplate code. Also, the concept of a single dispatcher has good intentions, but is largely unnecessary with appropriate data flow.

Redux helped with both of these concepts, as it removed Flux dispatchers in favor of pure functions, which also allowed for a greater focus on immutability. Consequently, the wall between declaring actions and stores came down, as your store is governed by many functions (reducers) which operates as the action itself, and you can combine the reducers to create a single store.

That's great, so what's different about singulum?

singulum attempts to blend the two concepts into a more digestable solution. While Flux's separate declaration of actions and stores that need to be later bound creates boilerplate, the logical separation of actions and stores makes sense as a cause-effect relationship. While Redux set the stage for a more pure state manager, it can be difficult to understand the hierarchy of data in your state tree due to the "build many pebbles and combine them into a foundation" nature of combineReducers. Plus (subjectively) switch statements don't feel like an extensible paradigm.

singulum allows for simple, unified declaration of actions and stores, but creates a logical separation of them when in use, and doesn't require any boilerplate binding code. Additionally, singulum allows for great control over granularity of your actions (either for the entire store or a specific property), with the relationship being very declarative and explicit.

Browser support

There are no external dependencies of singulum, so all modern browsers are supported. If you want to support IE9-11 then the es6-promise polyfill (or equivalent) will need to be provided, as Promises are not supported natively in IE. Due to the lack of ES5 support for certain features (namely Object.defineProperty), IE8 and below are not supported.