Noteworthy Placebo Mongers

    @seracio/plugnplay

    5.0.9 • Public • Published

    plugnplay

    A tiny module to use a dictionary of Observables as a Store for React

    Disclaimer

    The purpose here is not to provide an async middleware to a redux store with Observables, as redux-cycle-middleware and redux-observable do but to replace redux and its different slices (async middlewares, reducers and derived data) with Behavior Subjects. As this, we can express each variable of the store as a function of other variables, in a clean and async way.

    This library only exposes a component Playground (a store Provider) and a render props component Plug.

    Install

    npm i react@16.7 react-dom@16.7 rxjs@6 @seracio/plugnplay

    Basic usage

    import { Plug, Playground } from '@seracio/plugnplay';
    import React from 'react';
    import { of, interval } from 'rxjs';
    import { shareReplay, delay } from 'rxjs/operators';
    
    // expose a dictionary of Observables (Behavior Subjects)
    const store = {
        hello$: of('hello').pipe(delay(250), shareReplay(1)),
        count$: interval(1000).pipe(shareReplay(1))
    };
    
    render(
        <Playground store={store}>
            <h1>My app</h1>
            <Plug combinator={(store) => store.hello$}>
                {(val) => (!!val ? <div>{val}</div> : <div>waiting...</div>)}
            </Plug>
            <p>Here is a counter:</p>
            <Plug combinator={(store) => store.count$}>
                {(val) => (!!val ? <div>{val}</div> : <div>waiting...</div>)}
            </Plug>
        </Playground>
    );

    API

    Playground

    The Playground component is the equivalent of a redux Provider.

    type PlaygroundProps = {
        store: { [key: string]: Observable };
        children: JSX.Elements;
    };

    Plug

    type PlugProps = {
        combinator: (store) => Observable;
        defaultValue?: any;
    };

    The combinator props is a function that takes the dictionary store as param and returns the unique Observable we want to listen to.
    This Observable can be:

    • an Observable defined in the store
    • a combination of multiple Obserables from the store (thanks to RX operators)
    • a brand new Observble, unlinked to the store

    The value of this Observable will be emitted through a render props function. Typically, you want them to be formated like props, but nothing mandatory here:

    <Plug
        combinator={(store) =>
            combineLatest(store.count$, store.val$).pipe(
                map(([count, val]) => ({ count, val }))
            )
        }
    >
        {(props) => (!!props ? <MyComp {...props} /> : <Waiting />)}
    </Plug>

    As Observables are asynchronous by nature, you must provide a defaultValue if you want a synchronous rendering:

    <Plug combinator={(store) => store.props$} defaultValue={{ count: 0, val: '' }}>
        {(props) => <MyComp {...props} />}
    </Plug>

    Or you can use a Waiting component, as defaultValue is defined as null by default:

    <Plug combinator={(store) => store.props$}>
        {(props) => (!!props ? <MyComp {...props} /> : <Waiting />)}
    </Plug>

    Development

    yarn test --watch
    

    Publish

    Due to the namespace

    npm publish --access=public
    

    Keywords

    Install

    npm i @seracio/plugnplay

    DownloadsWeekly Downloads

    3

    Version

    5.0.9

    License

    MIT

    Unpacked Size

    13.6 kB

    Total Files

    13

    Last publish

    Collaborators

    • seracio