Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
redux-rsync
Advanced tools
Readme
RSync is an alternative to redux-saga to handle async actions without generator. It makes handling complicated async flow easier and offers a great readability.
For a demo, click here.
yarn add redux-rsync
1. Apply rsync middlware
redux/index.js
import rootReducer from './reducer'
import rsync from 'redux-rsync'
import { createStore, applyMiddleware } from 'redux'
export const store = createStore(
rootReducer,
applyMiddleware(rsync)
)
2. Decorate actions with async or flow metadata
redux/action.js
import api from '../api'
...
export function requestGetUser (payload) {
return {
type: 'REQUEST_GET_USER',
payload,
meta: {
async: {
effect: () => api.user.show(),
resolve: { type: 'RESOLVE_REQUEST_GET_USER' },
reject: { type: 'REJECT_REQUEST_GET_USER' },
take: 'latest'
}
}
}
}
...
redux/flow.js
import { requestGetUser, requestGetPosts } from './action'
import { loadInitialDataParams } from './prepare'
...
export function loadInitialData (payload) {
return {
type: 'LOAD_INITIAL_DATA',
payload,
meta: {
flow: {
actions: [
[
{
effect: requestGetUser,
break: ({ response }) => !response.data.args.user
},
{
prepare: loadInitialDataParams.requestGetPosts,
effect: requestGetPosts
}
]
],
resolve: { type: 'RESOLVE_LOAD_INITIAL_DATA' },
reject: { type: 'REJECT_LOAD_INITIAL_DATA' },
take: 'every:serial'
}
}
}
}
...
RSync works by decorating actions with async
and/or flow
metadata
import api from '../api'
...
export function requestGetUser (payload) {
return {
type: 'REQUEST_GET_USER',
payload,
meta: {
async: {
effect: () => api.user.show(),
resolve: { type: 'RESOLVE_REQUEST_GET_USER' },
reject: { type: 'REJECT_REQUEST_GET_USER' },
take: 'latest'
}
}
}
}
...
Property | Type | Value | Description |
---|---|---|---|
effect | function | payload => {} | Async side effect to run |
resolve | object | { type: '<ACTION_NAME>' } | Will be dispatched if the effect execution is successful. Payload and effect result/response will be passed to the reducer automatically |
reject | object | { type: '<ACTION_NAME>' } | Will be dispatched if the effect execution is failed. Payload and error will be passed to the reducer automatically |
take | string | every:parallel (default), latest | latest : if an action effect still running when another action with the same type is dispatched, then the previous action will be cancelledevery:parallel : take all dispatched actions |
// async.js
import api from '../api'
...
export function requestGetUser (payload) {
return {
type: 'REQUEST_GET_USER',
payload,
meta: {
async: {
effect: () => api.user.show(),
resolve: { type: 'RESOLVE_REQUEST_GET_USER' },
reject: { type: 'REJECT_REQUEST_GET_USER' },
take: 'latest'
}
}
}
}
export function requestGetPosts (payload) {
return {
type: 'REQUEST_GET_POSTS',
payload,
meta: {
async: {
effect: () => api.post.index(),
resolve: { type: 'RESOLVE_REQUEST_GET_POSTS' },
reject: { type: 'REJECT_REQUEST_GET_POSTS' },
take: 'latest'
}
}
}
}
...
// flow.js
import { requestGetUser, requestGetPosts } from './action'
import { loadInitialDataParams } from './prepare'
...
export function loadInitialData (payload) {
return {
type: 'LOAD_INITIAL_DATA',
payload,
meta: {
flow: {
actions: [ // will be executed in order
{
effect: requestGetUser,
break: ({ response }) => !response.data.args.user
},
{
prepare: loadInitialDataParams.requestGetPosts,
effect: requestGetPosts
},
[ // to execute multiple async actions in parallel, wrap them inside another array
{
prepare: loadInitialDataParams.doFoo,
effect: doFoo
},
{
prepare: loadInitialDataParams.doBar,
effect: doBar
},
]
],
resolve: { type: 'RESOLVE_LOAD_INITIAL_DATA' },
reject: { type: 'REJECT_LOAD_INITIAL_DATA' },
take: 'every:serial'
}
}
}
}
...
Property | Type | Value | Description |
---|---|---|---|
actions | array[object/array] or | [{ effect: () => {}, ... }, ...}] | Array of actions to run. The action will support these following properties: effect , prepare , break The actions will be executed in order. To run the actions in parallel, Wrapping the actions inside another another array will do it. (see example above) effect : function that will return redux action with meta:async property. (see example above)prepare : function to prepare result/response from previous async action into params for the current actionbreak : function to evaluate the result/response from the action. return true to break the flow or return false to continue |
resolve | object | { type: '<ACTION_NAME>' } | Will be dispatched if the effect execution is successful. Effect result/response will be passed to the reducer automatically. |
reject | object | { type: '<ACTION_NAME>' } | Will be dispatched if the effect execution is failed. Error will be passed to the reducer automatically. |
take | string | first (default), every:serial , every:parallel | first : will not accept any flow actions with the same type with the one that currently running unti it's doneevery:serial : take all dispatched flow actions with the same type , put them in a queue and execute them in serial |
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
FAQs
Redux saga alternative to handle async actions
The npm package redux-rsync receives a total of 1 weekly downloads. As such, redux-rsync popularity was classified as not popular.
We found that redux-rsync demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.