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

simple-store

v4.0.0

Published

A library for creating simple flux stores to be used in front-end web applications

Downloads

35

Readme

Simple-Store

Sometimes, you just need a simple store.

Just a function

This library let's you create a flux-like store out of just a function, and use that store in your React or Svelte apps.

Build Status

Code Example

Create a store

import { createSimpleStoreHook } from 'simple-store';

const store = createSimpleStoreHook(async (state, action, deps, resolve) => {
  // if the store is being subscribed to, or the action is 'reset'
  if ((!state && !action) || action.type === 'reset') {
    // early sync resolve so you can show a spinner or something
    resolve({ loading: true });

    // then fetch the data for your store
    const response = await deps.fetch('https://example.com/api/things');
    const { data: things } = await resonse.json();

    // then return to set new state again
    return { things, loading: false }; // turn off spinner and show data
  }

  // if a filter action is dipatched fetch only things for that category
  if (action.type === 'filter') {
    const category = action.payload.category.id;

    // still show the current items, along with the spinner
    resolve({ ...state, loading: true });

    // until the filter request resolves
    const response = await deps.fetch(
      `https://example.com/api/things/${category}`
    );
    const { data: things } = await resonse.json();

    return { things, loading: false, category };
  }

  // by default, just return the same state and nothing happens
  return state;
});

Create a store hook for React

import { createSimpleStoreHook } from 'simple-store/react';

// this could likely be in another file
// thingsStoreFn is the storeFn from example above
const useThings = createSimpleStoreHook(thingsStoreFn);

const ThingList = ({ category }) => {
  // hook returns [state, dispatch] tuple, just like useReducer
  const [{ things, loading }, dispatch] = useThings();

  if (loading) {
    return <Spinner />;
  }
  return (
    <>
      {things.map(thing => (
        <Thing
          key={thing.id}
          thing={thing}
          onSelectCategory={() => {
            dispatch({ type: 'filter', payload: { category } });
          }}
        />
      ))}
    </>
  );
};

Use your store in a Svelte component

// example coming soon, but just swap out a Svelte store

Installation

simple-store requires rxjs as a peer dependency.

npm install simple-store rxjs
yarn add simple-store rxjs

Also, if you are importing from simple-store/react you will require a peer dependency of react. And of course if you are importing from simple-store/svelte you will require a peer dependency of svelte.

Features

  • create a flux store from a simple function
  • async by default
  • framework agnostic

API Reference

createSimpleStore(storeFn, deps) => store

createSimpleStore is the most basic way to create an observable flux store. You pass in a function (storeFn) which defines how state is derived any dispatched actions (or when instatiated).

You can optionally also pass in any dependencies (deps) the function may require, as an object, so that you may swap those dependencies out, for testing or any other reason you need, to change the beahviour of the store. Deps helps decouple your store from certain aspects, for example: your data retrieval and storage, as well as many other useful things.

storeFn: (state[, action, deps, resolve]) => newState

This storeFn function, essentially becomes the store, deriving state from any actions that are dispatched into it. When called initially, it will have undefined for both state and action, and from then on, any calls to store.dispatch() will re-invoke this storeFn with the current state, the action dispatched, any deps provided to the store initially or by DI, and an optional resolve function, used to set state synchronously while you wait for async state to return.

storeFn is async by default, so using async/await is perfectly okay and encouraged, as is returning a promise, or even an RxJS observable.

React

To line up with the React way of doing things, SimpleStore exports function called createSimpleStoreHook which will create a hook/provider pair, which internally use a SimpleStore instance.

createSimpleStoreHook(storeFn[, options = { deps }]) => useStoreHook

To create the hook, the arguments are the storeFn (just like creating a store instance), and an optional options object. The options will have a property { deps }, which can be used to provide deps to the underlying store, with the added benefit of being able to swap out deps in your React apps using the context API.

createSimpleStoreHook returns a useStoreHook which is described below.

useStoreHook(stateSelector[, deps = []]) => [state, dispatch]

The useStoreHook is to be used in React function components, providing the stores current state and dispatch method to the component, similar to useReducer.

It also accepts a stateSelector function, which is basically a mapping of the store state to the components local state, so that component updates and re-renders can be limited to the particular slice of state this component is subscribing to.

The deps array offers a way to change the stateSelector, just like the deps params in useEffect(), useMemo(), useCallback() and useImperativeHandle() and useLayoutEffect(), but defaults to an empty array [] rather than undefined.

Tests

If you are curious about the requirements or test coverage, you can pull down the repo and run:

npm test

...to get an idea of what is being tested and the general idea of code coverage.

Built with

Contribute

Let people know how they can contribute into your project. A contributing guideline will be a big plus.

License

MIT © Adam L Barrett