simple-store

    4.0.0 • Public • Published

    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

    Keywords

    none

    Install

    npm i simple-store

    DownloadsWeekly Downloads

    6

    Version

    4.0.0

    License

    MIT

    Unpacked Size

    312 kB

    Total Files

    6

    Last publish

    Collaborators

    • bigab