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

rxcomp-store

v1.0.0-beta.18

Published

Reactive StoreModule for RxComp component library

Downloads

6

Readme

💎 RxComp StoreModule

Licence

RxComp Store is a small Javascript module for RxComp, developed with Immer and RxJs as a simple alternative to Redux.

The store can however be used with any framework or VanillaJS.

lib & dependancy | size :--------------------|:----------------------------------------------------------------------------------------------| rxcomp-store.min.js | rxcomp-store.min.js | rxcomp.min.js | rxcomp.min.js | rxjs.min.js | rxjs.min.js | immer.min.js | immer.min.js |

RxComp Store Demo
RxComp Store Api
RxComp Sotre Codesandbox


Installation and Usage

ES6 via npm

This library depend on RxComp Immer and RxJs
install via npm or include via script

npm install rxjs immer rxcomp rxcomp-store --save

CDN

For CDN, you can use unpkg

<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/rxjs.umd.min.js" crossorigin="anonymous" SameSite="none Secure"></script>
<script src="https://unpkg.com/[email protected]/dist/immer.umd.production.min.js" crossorigin="anonymous" SameSite="none Secure"></script>
<script src="https://unpkg.com/[email protected]/dist/umd/rxcomp.min.js" crossorigin="anonymous" SameSite="none Secure"></script>  
<script src="https://unpkg.com/[email protected]/dist/umd/rxcomp-store.min.js" crossorigin="anonymous" SameSite="none Secure"></script>  

The global namespace for RxComp is rxcomp

import { CoreModule, Module } from 'rxcomp';

The global namespace for RxComp StoreModule is rxcomp.store

import { StoreModule } from 'rxcomp-store';

The store

With the useStore factory we create the immutable store with a default value.
The store will be consumed by a singleton service, and honoring the single-responsibility principle only a specific portion of the app data will be stored.

import { useStore } from 'rxcomp-store';

const { state$ } = useStore({ todolist: [] });

Subscribing to the state$ observable you always get the last immutable copy of the state draft.

state$.subscribe(state => this.todolist = state.todolist);

Reducing the store state

The reducer operator accept a reducer callback with the observable$ payload and a mutable draft of the state as parameter.
When reducer returns, an immutable copy of the state will be pushed to the state$ observable through Immer.

const { reducer } = useStore({ todolist: [] });

observable$.pipe(
  reducer((todolist, state) => state.todolist = todolist)
);

Retry state

The retryState operator will retry N times before throwing the error.

const { retryState } = useStore({ todolist: [] });

observable$.pipe(
  retryState(3),
);

Catching errors into the state

The catchState operator is used to catch the error and store it in the immutable state.

const { catchState } = useStore({ todolist: [] });

observable$.pipe(
  catchState(console.log),
);

You can then observe the state for errors.

state$.subscribe(state => this.error = state.error);

Canceling

The cancel method will interrupt all the currently running streams in the store.
This method will not abort the fetch requests.

const { cancel } = useStore({ todolist: [] });

// stop currently running streams
cancel();

Setting the busy state

The busy$ observable will store the busy flag in the immutable state and lock future calls until the observable completes.

const { busy$ } = useStore({ todolist: [] });

busy$().pipe(
  switchMap(() => observable$),
);

You can then observe the busy state.

state$.subscribe(state => this.busy = state.busy);

Loading state from Web Api Storage or Cookie

While reloading the page, you may want to reload the previous state of the app.
First we have to initialize the store with a different StoreType (the default is StoreType.Memory) and give it a unique store name.

import { StoreType, useStore } from 'rxcomp-store';

const { cached$ } = useStore({ todolist: [] }, 
  StoreType.Session, 'todolist'
);

With the cached$ observable we can retrieve the last saved state from sessionStorage or localStorage or cookie.

cached$((state) => state.todolist)

All together

  1. busy$ mark state as busy
  2. cached$ load data from cache
  3. reducer reduce the state to the new state
  4. retryState repeat the request N times then throw error.
  5. catchState catch the error and reduce the state to the errored state.
import { StoreType, useStore } from 'rxcomp-store';

const { busy$, cached$, reducer, retryState, catchState } = useStore(
  { todolist: [] },
  StoreType.Session, 'todolist'
);

busy$().pipe(
  switchMap(() => 
    merge(cached$((state) => state.todolist), fromApi$).pipe(
      reducer((todolist, state) => state.todolist = todolist),
	  retryState(),
	  catchState(console.log),
    )
  )
);

Querying the store state

The select$ observable accept a reducer callback with an immutable copy of the state as parameter and returns an immutable copy of a portion of the state as observable.

const { select$ } = useStore({ todolist: [] });

const todolist$ = select$((state) => state.todolist);

Querying with select

The select method works like the select$ observable but doesn't return an observable.

const { select } = useStore({ todolist: [] });

const todolist = select((state) => state.todolist);

Other methods

Setting the store state

The next method accept a reducer callback with a mutable draft of the state as parameter.
When reducer returns, an immutable copy of the state will be pushed to the state$ observable through Immer.
It works like the reduce operator but doesn't return an observable.

const { next } = useStore({ todolist: [] });

next((state) => state.todolist = todolist))

Setting the store error

The nextError method will store the error parameter in the immutable state. It works like the catchState operator but is intended to use in conjunction of classic catchError operator.

const { nextError } = useStore({ todolist: [] });

catchError(error => nextError(error))

Bootstrapping Module

import { Browser, CoreModule, Module } from 'rxcomp';
import { StoreModule } from 'rxcomp-store';
import AppComponent from './app.component';

export default class AppModule extends Module {}

AppModule.meta = {
    imports: [
        CoreModule,
        StoreModule
    ],
    declarations: [],
    bootstrap: AppComponent,
};

Browser.bootstrap(AppModule);

Browser Compatibility

RxComp supports all browsers that are ES5-compliant (IE8 and below are not supported).


Contributing

Pull requests are welcome and please submit bugs 🐞


Install packages

npm install

Build, Serve & Watch

gulp

Build Dist

gulp build --target dist

Thank you for taking the time to provide feedback and review. This feedback is appreciated and very helpful 🌈

GitHub forks GitHub stars GitHub followers

If you find it helpful, feel free to contribute in keeping this library up to date via PayPal

PayPal


Contact

Twitter Follow


Release Notes

Changelog here.