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

redux-observable-sans

v1.1.2

Published

Use redux without any boilerplate

Downloads

15

Readme

redux-observable-sans-boilerplate

Redux is awesome. But, boilerplate is a code smell. This library allows you to use redux with zero boilerplate:

  • ZERO constant definitions
  • ZERO action definitions
  • ONLY 1 dispatch definition (per http API targeted)

(and similar for websockets). Instead of boilerplate, you should just be coding business logic.

install

npm i --save redux-observable-sans-boilerplate

use

See example directory for a simple example of how to use library

http (json)

import { httpEpic, httpAction } from 'redux-observable-sans-boilerplate'

Setting up the middleware as per https://redux-observboilerplateable.js.org/docs/basics/SettingUpTheMiddleware.html

For our example we will be doing http request to two different backends.

const optionsGH = {
    url: 'https://api.github.com', // site that will be 
    id = 'GH', // optional value used to differentiate http action types
}

const optionsCustom = {
    url: 'https://mysite.url',
    // optionally use setHeaders to do authentication
    setHeaders: (state$, deps) => ({  Authorization: `Bearer ${action$.value.me.token}` }),
}

const rootEpic = combineReducers(httpEpic(optionsGH),httpEpic(optionsCustom))

The action creators have the signature httpAction(dispatch, id)(type, url, method = 'GET', settings = {})(body) where:

  • dispatch as provided by reaca-redux
  • id is optional and should be the same value as used to create the httpEpic
  • type is the front part of the type of action you will be dispatching, eg, 'GET_USERS':
    • httpEpic will turn the dispacted action into GET_USERS_REQUEST, GET_USERS_SUCCESS and GET_USERS_FAILURE type actions
    • the _FAILURE will be followed by either a HTTP_ERROR or HTTP_UNAUTHORIZED type action
      • if id is defined, eg, GH, then the following types would be changed to HTTP_GH_ERROR or HTTP_GH_UNAUTHORIZED
    • a GET_USERS_CANCELLED type action can be used to cancel the ongoing request
  • url is the latter part of the url path; it will be appended to front piece defined in the corresponding httpEpic
  • method can be GET, POST, PATCH, etc.
  • settings is the standard options that can be passed to fetch
  • body is optional; it is the JSON object, eg, from you form

To use you all you need to do is use connect(mapStateToProps, mapDispatchToProps) from react-redux where

const mapDispatchToProps = dispatch => ({
    http: httpAction(dispatch, id), // same id as in corresponding httpEpic
})

which you can call from anywhere in you app, eg,

const mapDispatchToProps = (dispatch, ownProps) => ({
    onSubmit: ownProps.http('GET_USERS', 'users'),
})

where your data is then passed into onSubmit(data).

websocket: command and query (and "event")

I created a command and query for websockets for convention sake, but it works perfectly fine if you just use command.

import { socketEpics, commandAction, toAction } from 'redux-observable-sans-boilerplate'

Setting up the middleware as per https://redux-observboilerplateable.js.org/docs/basics/SettingUpTheMiddleware.html

You need to have defined a socket object

const auth = (state$, deps) =>
    ({ token: state$.value.me.token, userId: state$.value.me.userId })

const rootEpic = combineReducers(...socketEpics(socket))

Note: The auth function is completely optional.

To use you all you need to do is use connect(mapStateToProps, mapDispatchToProps) from react-redux where

const mapDispatchToProps = dispatch => ({
    command: commandAction(dispatch),
})

which you can call from anywhere in you app, eg,

const mapDispatchToProps = (dispatch, ownProps) => ({
    onSubmit: ownProps.command('updateUser'),
})

where your data is then passed into onSubmit(data).

Bonus: to handle events from backend you can use

socket.on(`event`, toAction(dispatch))

it expects the data object received to include a type which will then be converted constant-case, and then dispatched as an action.

If a CommandRejected or QueryRejected type is received a further action of _FAILURE type will also be emitted (based on the constant-case of the payload.type -- idealy that would be the type of the corresponding command or query).