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

aio-store

v2.5.2

Published

A javascript app state management

Downloads

35

Readme

publish version dependencies size MIT License

AIO-STORE

State management for any javascript application. It's tiny, fast, stable, contains no boilerplate, has no side effects, doesn't need a context provider and compatible with SSR. It comes with zero dependencies and lets you dispatch actions from anywhere. Typescript user or Javascript user, it doesn't matter. It is all for you.

Installation

  npm install aio-store

Usage

Let's import createStore

// All users, No hook
import { createStore } from "aio-store";

// React user with hook
import { createStore } from "aio-store/react";

Create a store

Just create your store, No actions is needed

export const useExpStore = createStore({
  exp: 10,
});

Use the store

  • Anywhere in your app
const store = myStore.get()
  • Inside a React component
import { useExpStore } from "./store";

const MyComponent = () => {

  // Realtime update for React users
  const { exp } = useExpStore();

  // ❗ this is just a snapshot, No realtime changes
  const { exp } = useExpStore.get();

  // ❗ this is just a snapshot, No realtime changes
  const exp = useExpStore.get("exp");

  // Realtime update available for React users
  const { exp } = useExpStore("*");

  // Deep data with realtime update
  const deepValue = useExpStore("data.depp.moreDeep");

  return <span>{exp}</span>;
};
  • With selector

Get your store and return whatever you want in any format

import { useExpStore } from "./store";

const MyComponent = () => {
  
  const { exp } = useExpStore(store => ({exp: store.exp}));
  
  const [exp,other] = useExpStore(store => [store.exp,store.other]);
  
  const exp = useExpStore(store => store.exp);

  // Deep data with realtime update
  const deepValue = useExpStore(store => store.data.depp.moreDeep);

  // ❗ Just a snapshot, No realtime changes
  const exp = useExpStore.get(store => store.exp);

  return <span>{exp}</span>;
};
  • With listener

You can listen to your store changes anywhere in your app and update something stateless. Very useful when you want to eliminate unnecessary rendering.

const myStore = createStore(...);

// Listen to all changes
myStore.listen('*', (data) => {
  // while listening, you can get a snapshot to do some control
  // React user or vanilla users
  const snap = myStore.get()
  
  // vanilla users
  const snap = myStore()
  
  const someValue = myStore.get("someValue")
  // do what ever you want with your data,
})

// Listen to specific changes
myStore.listen('data.content.value', (data) => {
  // while listening, you can get a snapshot
  const snap = myStore.get()
  const someValue = myStore.get("someValue")
  // do what ever you want with your data,
})

The listen method returns an unsubscribe function

const unsubscribe = myStore.listen('data', (data) => {})

unsubscribe()

Limit render

By default aio-store use strict equality to prevent unnecessary render. For more control, you can use any data equality function as long as it returns a boolean.

// String selector
const data = myStore("data",(oldValue, newValue) => sameOrNot)

// Function selector
const data = myStore(store => store.data, (oldValue, newValue) => sameOrNot)

// Listener selector
const data = myStore("data",callback, (oldValue, newValue) => sameOrNot)

Mutation

Your store is immutable, you will always get a fresh store. When you mutate your store, Please be aware that, storeRef or whatever the name you call it, point to a reference of your store. So do not override the reference.

Mutate Object

const myStore = createStore({
  myValue: 10,
})
myStore.set(storeRef => {
  // ❌ Bad, Don't do this.
  storeRef = {
    myValue: 11
  }
})

Instead, do like following lines

const myStore = createStore({
  myValue: 10,
})

myStore.set(storeRef => {
  storeRef.MyValue = 11
  // ✅ Good,
  storeRef.MyValue = {
    // ...whatever you want
  }
  // ✅ Good, you can add new Props
  storeRef.newProp = {
    // ...whatever you want
  }
  // ✅ Good,
  storeRef.props.data = {
    someData: someValue
    // ...whatever you want
  }
  // ✅ Good, if props.data already exists
  storeRef.props.data.someData += someValue
})

Mutate Array

const myStore = createStore({
  arr: [{name: "default"}],
})

myStore.set(storeRef => {
  // Mutation inside the array
  storeRef.arr[0].name = "New name";
  storeRef.arr.push("new item")
// Mutation with new array or clean the array
  storeRef.arr.length = 0
  // Or 
  storeRef.arr = []
})

Mutate Map / Set

const myStore = createStore({
  map: new Map(),
  set: new Set(),
  setContainsMap: new Set().add(new Map()),
  mapContainsSet: new Map().set("mySet",new Set()),
})
// Mutation inside the array
myStore.set(storeRef => {
  // Mutation inside a map
  storeRef.map.set("new Key", "new value")
  // Mutation inside a set
  storeRef.set.add("new value")
  // Mutation inside setContainsMap
  storeRef.setContainsMap.forEach(s => {
    // S is a Map
    s.set("new Key", "new value")
  })
  // Mutation inside mapContainsSet
  storeRef.mapContainsSet.get("mySet").add("new Value")
  // Cleaning
  storeRef.mapContainsSet.clear()
  storeRef.setContainsMap.clear()
})

Transferring the ref

When you do not want to repeat yourself, It is useful to save a reference of the updated part and use it multiple times. But always take care of not destroying that reference

const myStore = createStore({
  data: {
    deep: {
      moreDeep: {}
    }
  }
})

myStore.set(storeRef => {
  const moreDeep = storeRef.data.deep.moreDeep;
  
  // Use moreDeep ✅
  moreDeep.newProp1 = "new value 1"
  moreDeep.newProp2 = "new value 2"

  let deep = storeRef.data.deep;

  // Use moreDeep ✅
  deep.moreDeep = {
    newProp1: "new value 1",
    newProp2: "new value 2"
  }

  let moreDeep = storeRef.data.deep.moreDeep;
  
  // ❌ you are destroying the reference.
  // ❌ moreDeep is not pointing anymore the real moreDeep.
  // ❌ It has a new reference
  moreDeep = {
    newProp1: "new value 1",
    newProp2: "new value 2"
  }
  // But This is fine ✅
  // Because the storeRef is in charge
  storeRef.data.deep.moreDeep = {
    newProp1: "new value 1",
    newProp2: "new value 2"
  }
})

Available tools and options

  • createStore Let you create a store
  • set A property attached to your store that lets you dispatch actions from any file.
  • get A Function attached to your store that lets you get a snapshot of your store at any time.
  • listen A Function attached to your store that lets you listen to changes in all or specific part of your store.
  • * A key that can be passed to your store in order to get everything or to listen to all changes in your store.

License

MIT