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-cofx

v2.4.1

Published

redux middleware; sagas as thunks

Downloads

23

Readme

redux-cofx Build Status

Redux middleware: Sagas as thunks; redux-saga meets redux-thunk

Middleware for redux that allows developers to dispatch actions which trigger generator functions. On top of that, these generator functions have an API for describing side-effect as opposed to activating them. Let redux-cofx handle the side-effects, all you need to worry about is describing how the side-effects should work.

Features

  • Action creators spawning side-effects
  • Want to describe side-effects as data
  • Testing is incredibly simple
  • Similar API as redux-saga (select, put, take, call, fork, spawn, all, delay)
  • Typescript support
  • Upgradability from react-cofx and to redux-saga

Install

yarn add redux-cofx

Usage

import cofxMiddleware, { createEffect, call, select, put } from "redux-cofx";
import { applyMiddleware, createStore } from "redux";

const reducer = (state) => state;
const store = createStore(reducer, applyMiddleware(cofxMiddleware));

// action creators
const todosSuccess = payload => ({
  type: "TODO_SUCCESS",
  payload
});
const uploadTodos = todos => createEffect(effect, todos);

// selector
const getApiToken = state => state.token;

// effect
function* effect(todos) {
  const token = yield select(getApiToken);

  const result = yield call(fetch, "/todos", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`
    },
    body: JSON.stringify(todos)
  });
  const json = yield call([result, "json"]);

  yield put(todosSuccess(json));
}

const todos = ["drop kids off at the pool", "make dinner"];
// trigger effect
store.dispatch(uploadTodos(todos));

Using enableBatching we also provide the ability to batch multiple actions while only triggering one state change. See the API section for more info.

Testing

See cofx for instructions on how to test an effect function.

API

For cofx specific effects (e.g. call, fork, spawn, delay, all), see cofx docs

select

Accepts a function with state as the parameter

const getToken = (state) => {
  return state.token;
}

function* effect() {
  const token = yield select(getToken);
}

put

alias for store.dispatch

const setToken = (payload) => {
  return {
    type: 'SET_TOKEN',
    payload,
  }
};

function* effect() {
  yield put(setToken('1234'));
}

batch (requires enableBatching, added v2.0)

dispatch multiple actions with only a single state update. This effect takes an array of actions and dispatches them all within a single state update. This is useful if there are multiple actions being dispatched in sequence and you don't want to re-render the view all of those times.

import { batch } from 'redux-cofx';

const setToken = (payload) => {
  return {
    type: 'SET_TOKEN',
    payload,
  }
};
const login = () => {
  return {
    type: 'LOGIN',
  };
}

function* effect() {
  yield batch([
    setToken('1234'),
    login(),
  ]); // this will only trigger one state update and only one re-render of react!
}

take

Waits for the action to be dispatched

function* effect() {
  const action = yield take('SOMETHING');
  console.log(action.payload);
}

console.log('output ->');
store.dispatch({ type: 'SOMETHING', payload: 'nice!' });

// output ->
// 'nice!'

enableBatching (optional, added v2.0)

This is a higher order reducer that enables the use of batch which allows multiple actions to be dispatched with a single re-render.

import cofxMiddleware, { enabledBatching } from "redux-cofx";
import { applyMiddleware, createStore } from "redux";

const reducer = (state) => state;
const rootReducer = enableBatching(reducer);
const store = createStore(rootReducer, applyMiddleware(cofxMiddleware));

batchActions (optional, added v2.3)

This is a simply action creator, when dispatched outside of an effect, will dispatch all actions simultaneously updating redux store.

import cofxMiddleware, { enabledBatching, batchActions } from "redux-cofx";
import { applyMiddleware, createStore } from "redux";

const reducer = (state) => state;
const rootReducer = enableBatching(reducer);
const store = createStore(rootReducer, applyMiddleware(cofxMiddleware));

store.dispatch(
  batchActions([
    { type: 'SOMETHING', payload: 'great' },
    { type: 'DO_I', payload: 'exist?' },
  ])
);

createEffect

This function creates an effect action that you would dispatch with redux.

import { put, createEffect } from 'redux-cofx';

function* effOne(payload: any) {
  // payload === 'ok'
  yield put({ type: 'AWESOME', payload });
}

const one = (payload: any) => createEffect(effOne, payload);
store.dispatch(one('ok'));

cancel an effect (added v2.0)

We also provide the ability to cancel an effect. The cancel must be a promise. When the cancel promise is resolved then it will cancel the effect.

import { put, createEffect } from 'redux-cofx';

function* effOne(payload: any) {
  yield delay(1000); // delay for 1 second
  yield put({ type: 'AWESOME', payload }); // payload === 'ok'
}

const cancel = () => new Promise((resolve) => {
  setTimeout(() => {
    resolve();
  }, 500);
});
const one = (payload: any) => createEffect({
  fn: effOne,
  args: [payload],
  cancel,
});
store.dispatch(one('ok'));
// the effect will be cancelled before the action can be dispatched!

createEffects

This is a helper function to create effects based on a map of effect names to effect function. The created effects will accept a payload and send it as a parameter to the effect function.

import { put, createEffects } from 'redux-cofx';

function* effOne(payload: any) {
  // payload === 'ok'
  yield put({ type: 'AWESOME', payload });
}

function* effTwo(payload: any) {
  // payload === 'nice'
  yield put({ type: 'WOW', payload });
}

const effects = createEffects({
  one: effOne,
  two: effTwo,
});

store.dispatch(effects.one('ok'));
store.dispatch(effects.two('nice'));