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

statehubjs

v0.2.0

Published

StateHub is a centralized state management solution which provides reactivity and seamless intercommunication between application components, as well as ease of use for application authors.

Downloads

6

Readme

About

StateHub is a centralized state management solution which provides reactivity and seamless intercommunication between application components, as well as ease of use for application authors.

Benefits:

  • Supports components of any type (React, Angular, Vue, Web Component, raw DOM nodes, etc.)
  • Components subscribed/connected to the StateHub receive changes to the centralized state as they occur.
  • Allows components to communicate with and affect each other irrespective of hierarchy.
  • Separating state management logic from component view logic makes component code leaner.
  • Aims to be easier to use than other contemporary state management solutions.

Installation

Via NPM:

$ npm i statehubjs

OR

By cloning this Git repository. Note that this repository contains Git submodules, so please use appropriate command line flags or use the following command:

$ git clone --recurse-submodules https://github.com/zeemeng/statehub.git

Example and concepts

First import the module:

/* FILE hub.js */

import StateHub from "statehubjs"; // In a Node environment

// OR

import StateHub from "./statehub/index.js"; // Import from index.js in non-Node environments

Then, instantiate and export a hub:

import { actions } from "./actions.js";

const hub = new StateHub(actions, optionalInitialState);

export default hub;

Notice that the StateHub constructor takes 2 arguments. The second argument is optional. If supplied, it is assigned as the initial state value maintained by the hub. If not supplied, the initial state value of the hub will be an empty Object. The state can be of any data type, but using an Object might be good choice if the state that need to be maintained is complex and structured.

The first argument to the StateHub constructor is a dictionary of "actions" which are simply functions which describe how the state can be mutated. Thus, the first argument is in effect an Object containing key-value pairs, where the keys represent "action types" and must be unique strings, and where the values are "action" functions.

Here is an example of such a dictionary of "actions" defined in a separate file:

/* FILE actions.js */

export const actionTypes = {
  removeSection: "removeSection",
  setActiveSection: "setActiveSection",
  toggleNavDropdown: "toggleNavDropdown",
  hideNavDropdown: "hideNavDropdown"
};

export const actions = {
  removeSection: (state, payload) => ({
    ...state,
    sections: state.sections.filter(section => section.id !== payload)
  }),
  setActiveSection: (state, payload) => ({ ...state, activeSection: payload }),
  toggleNavDropdown: state => ({ ...state, showNavDropdown: !state.showNavDropdown }),
  hideNavDropdown: state => ({ ...state, showNavDropdown: false })
};

Here we see more clearly the signature of an "action" function. It is a function which takes 1 or 2 arguments and returns a value, which will became the new state value of the hub once the action is triggered and executed.

The first argument is always the value of the state before the mutation occurs and the second argument is an optional value supplied by the component which triggers the action. More on that later.

We see that the return value of all the "action" functions in the example is a newly created Objet where some properties are copied from the old state value and some other are assigned new values. In contrast to directly assigning the new property values to the old state object, this provides multiple benefits, such as some guarantee of synchronicity to components that are subscribed to the hub and that might handle/use multiple "versions" of the state.

In the above example, there is also an exported actionType Object/dictionary which properties are associated with each key present in the actions Object. This is not required, but comes in handy later on in component code which need to trigger/dispatch action as we will see.

With the hub set up, it's time to use it in various components.

import hub from "./hub.js"

/* In a component life-cycle method or when the component gets initialized */
...
  hub.subscribe((updatedStateValue) => {
    // Do something with the state value. For example, save it to a local state or use it to render some view.
    setLocalState(updatedStateValue);
  })
...

Now, everytime that the state of the hub updates, the callback provided to the subscribe method will be invoked with the new state value.

To trigger an action on the hub:

import hub from "./hub.js";
import { actionTypes } from "./actions.js";

const someEventHandler = event => {
  const payload = event.target.id;
  hub.dispatch(actionType.removeSection, payload);
};

When the event handler get invoked, the hub state will be mutated according to the defined action and the supplied payload. Then, all subscribed components will be notified with the new state value.

Notes

  • This package is fully annotated and supports IntelliSense.
  • Suggestions and contributions are welcome.