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

storable-state

v2.1.0

Published

State management library that integrates with localStorage

Downloads

5

Readme

Storable State

There are lot's of state management libraries. This one takes inspiration from the state management system that comes with svelte. It is simple, intuitive and powerful at the same time.

Stores

The library is comprised of 4 store types. These 4 types are writable, readable, storable and derived. Writable can be written to, readable can be read only, storable uses the localStorage api to preserve data between site refresh and derived depends on one or more stores to calculate it's value. All stores can be subscribed to.

Documentation

Writable

A writable store can be created with an initial value and optionally passed a callback function that will be invoked when the first subscriber for that store is register. The return value is another function that will be invoked when the last subscriber is lost.

import { writable } from 'storable-state';

const store = writable(0, () => {

    console.log("Got my first subscriber");

    return () => console.log("Lost my last subscriber");
});

set is a method that will update the store with a new value.

store.set(10);

update is a method that takes a callback function. It passes the current value to the callback. The return value of the callback is the new store value.

store.update(value => value +1);

subscribe is a method that accepts a callback that will be called with the new value every time the store value changes. The return of this method is a function you can invoke to unsubscribe.

const unsubscribe = store.subscribe(value => console.log(value));

unsubscribe(); // <-- Call to unsubscribe

Readable

A readable store does the exact same as a writable store, exept that you cannot use the set or update method. The parameter for the readable store are exactly the same as writable, except that the second parameter is now required. This is the only way to update the store value.

To update the store value you can use the set method provided to the callback. An async method works great here.

import { readable } from 'storable-state';

const store = readable(0, async (set) => {
    const count = await fetch('https://api.somewhere.com/count');

    set(count);

    return () => cleanup();
});

NB: the set method is also passed to the writable store if you want to use async there as well.

Storable

The storable store is essentially the writable store with and extra 2 methods and integration with the localStorage api to preserve state between page refershes. To get this to work you need to provide a key to the storable store. This key will be used to save and retrieve the stored state from localStorage. Storable only supports values that can be parsed with JSON.stringify() and JSON.parse(). If you are looking to serialize other javascript apis, you can use the serializable store.

import { storable } from 'storable-state';

                         ||
                         \/
const store = storable('count', 0);

NB: Also here you can add the setup/teardown callback as the third parameter.

detach is a method that takes no arguments. It's purpose is to remove the value from local storage so that it won't be preserved on refres. When detach is invoked, the store essentially behaves like a writable store.

store.detach();

attach is a method that does the opposite of detach. It saves the store value back to local storage.

store.attach();

Serializable

The serializable store does the exact same thing as the storable store, except that it also serializes more complex javascript apis like Map or Function. It uses yahoo's serialize-javascript. Check out their repo to see a full list of supported apis.

import { serializable } from 'storable-state';

const personRegister = new Map();
person.set(1, 'John Doe');
person.set(2, 'Jane Doe');

const store = serializable('personRegister', personRegister);

Derived

The derived store takes one store OR an array of stores as first parameter and a callback that will be called with all the respective store values every time one of them changes. The return of this callback will be the new state of the store.

import { derived, writable } from 'storable-state';

const dividend = writable(10);
const divisor = writable(2);

const store = derived(
    [dividend, divisor],
    (dividend, divisor) => {
        return dividend / divisor;
    }
)

Custom Stores

You can extend the stores with your own buildt in methods if you would like. The basic idea is to destructure any of the stores into their methods and use them in other configurations. Here is an example of how you could achieve this:

import { storable } from 'storable';

const createCountStore = (key = 'count') => {
    const { subscribe, set, update, detach, attach } = storable(key, 0);

    return {
        increase:   () => update((value) => value + 1),
        decrease:   () => update((value) => value - 1),
        reset:      () => set(0),
        subscribe,
        detach,
        attach
    }
}

export const store = createCountStore('count');