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

transmuter-store

v0.3.0

Published

Transmuter.js - simple state container store, fires events when property changes

Downloads

6

Readme

TransmuterStore

A store container that reacts to transmutations of properties of the store itself by emitting events.

Getting started

First, install transmuter-store via:

NPM

npm install transmuter-store

Yarn

yarn add transmuter-store

Basic concept

A TransmuterStore consists of 3 things:

  • The name of the store;
  • The store itself, which could be an object with pre-existing properties as an initial state;
  • The context on which to fire the events on.

By default, a TransmuterStore will fire events on a context element when a property of the store changes. This event is namespaced with the name of the store and the name of the property that changed. For example: if the store is named 'shed' and the property that changed is called items, then the event fired will be shed:items.

How does this work, you ask? The magic of transmuter-store lies in wrapping the store object in a Proxy with a set handler. The set handler is called each time a property of the store is being added or changed. This handler then fires an event on the context element, specifying which property has changed.

transmuter-store provides you with 2 things: the store container that fires the events, and a listener helper function (listen) that eases the setting up of store listeners.

How to use

In its simplest form, you can use transmuter-store like this:

import { TransmuterStore, listen } from 'transmuter-store';

// Set up an initial state for the store
const initialState = {
  items: [1, 2, 3],
  isMenuOpen: false
};

// Create a new store and apply the initial state object. Returns a store with name, context and state properties.
const store = new TransmuterStore('app', initialState);

console.log(store.name); // 'app'
console.log(store.context); // window
console.log(store.state); // State object Proxy, this is where the ✨ magic ✨ happens

// Listener function. This is called when a property changes with the name of the prop, the new value and the old value.
function logger(prop, value, oldValue, state) {
  console.log('property:', prop);
  console.log('new value:', value);
  console.log('old value:', oldValue);
  console.log('new state:', state);
}

// Add a store listener that listens to both the items and isMenuOpen properties and calls the above logger() function`
const listener = listen(store, ['items', 'isMenuOpen'], logger);

// Now when you change a property of the store, the change is logged using the listener function.
store.state.isMenuOpen = true;

// Add new items to array.
// ℹ️ See 'Limitations' below
store.state.items = [...store.state.items, 4];

Limitations

As a set handler of a Proxy only watches direct properties of the object it wraps, changes to nested objects or items in arrays won't propagate to the set handler. Use array/object destructuring for this and assigning the new result directly to the store, or use something like Immutable.js.

Plain JS, does not trigger event:

// This does *not* trigger a TransmuterStore event unfortunately
store.state.items.push(4); // ❌

Plain JS, does trigger event:

// This *does* trigger a TransmuterStore event
store.state.items = [...store.state.items, 4]; // ✅

Using Immutable.js

import { TransmuterStore } from 'transmuter-store';
import { List } from 'immutable';

// Set up state
const initialState = {
  items: List([1, 2, 3]) // Use an Immutable List
};

// Set up store
const store = new TransmuterStore('store', initialState);

// Returns a new List containing the added item and assign it to the store.
store.state.items = store.state.items.push(4); // ✅

Roadmap

  • [ ] Watching nested objects, if possible.
  • [ ] Watching items in arrays, if possible.
  • [ ] Handle store property deletions

Thanks

Heydon Pickering, for inspiring me with Mutilator.js to research and develop this library.

License

TransmuterStore is MIT-licensed.