Gathering detailed insights and metrics for redux-symbiote
Gathering detailed insights and metrics for redux-symbiote
npm install redux-symbiote
Typescript
Module System
Node Version
NPM Version
72.8
Supply Chain
98.2
Quality
78.1
Maintenance
50
Vulnerability
100
License
JavaScript (81.21%)
TypeScript (18.79%)
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Total Downloads
85,552
Last Day
96
Last Week
476
Last Month
1,400
Last Year
11,342
MIT License
163 Stars
95 Commits
9 Forks
5 Watchers
2 Branches
8 Contributors
Updated on Aug 01, 2024
Minified
Minified + Gzipped
Latest Version
3.4.0
Package Id
redux-symbiote@3.4.0
Unpacked Size
32.90 kB
Size
8.89 kB
File Count
11
NPM Version
6.9.0
Node Version
10.16.3
Cumulative downloads
Total Downloads
Last Day
152.6%
96
Compared to previous day
Last Week
44.7%
476
Compared to previous week
Last Month
27.6%
1,400
Compared to previous month
Last Year
-26.3%
11,342
Compared to previous year
2
Write your actions and reducers without pain
1import { createSymbiote } from 'redux-symbiote' 2 3 4const initialState = { 5 error: null, 6 accounts: [], 7 loading: false, 8} 9 10const symbiotes = { 11 accounts: { 12 loading: { 13 start: (state) => ({ ...state, loading: true }), 14 failed: (state, error) => ({ ...state, loading: false, error }), 15 finish: (state, accounts) => ({ ...state, loading: false, accounts }), 16 }, 17 }, 18} 19 20export const { actions, reducer } = createSymbiote(initialState, symbiotes)
Also you can use CommonJS:
1const { createSymbiote } = require('redux-symbiote') 2 3// ...
1function createSymbiote(
2 initialState,
3 symbiotes,
4 ?namespace = ''
5)
1createSymbiote(initialState, {
2 actionType: actionReducer,
3 nestedType: {
4 actionType: nestedActionReducer,
5 }
6})
Example:
1const initialState = { value: 1, data: 'another' } 2 3const symbiotes = { 4 increment: (state) => ({ ...state, value: state.value + 1 }), 5 decrement: (state) => ({ ...state, value: state.value - 1 }), 6 setValue: (state, value) => ({ ...state, value }), 7 setData: (state, data) => ({ ...state, data }), 8 concatData: (state, data) => ({ ...state, data: data + state.data }), 9} 10 11export const { actions, reducer } = createSymbiote(initialState, symbiotes) 12 13dispatch(actions.increment()) // { type: 'increment' } 14dispatch(actions.setValue(4)) // { type: 'setValue', payload: [4] } 15dispatch(actions.decrement()) // { type: 'decrement' } 16dispatch(actions.setData('bar')) // { type: 'setData', payload: ['bar'] } 17dispatch(actions.concatData('foo ')) // { type: 'concatData', payload: ['foo '] } 18 19// State here { value: 3, data: 'foo bar' }
When you call actions.setValue
symbiote calls your action handler with previousState and all arguments spreaded after state.
1const initialState = { value: 1, data: 'another' } 2 3const symbiotes = { 4 value: { 5 increment: (state) => ({ ...state, value: state.value + 1 }), 6 decrement: (state) => ({ ...state, value: state.value - 1 }), 7 }, 8 data: { 9 set: (state, data) => ({ ...state, data }), 10 concat: (state, data) => ({ ...state, data: data + state.data }), 11 }, 12} 13 14export const { actions, reducer } = createSymbiote(initialState, symbiotes) 15 16dispatch(actions.value.increment()) // { type: 'value/increment' } 17dispatch(actions.value.decrement()) // { type: 'value/decrement' } 18dispatch(actions.data.set('bar')) // { type: 'data/set', payload: ['bar'] } 19dispatch(actions.data.concat('foo ')) // { type: 'data/concat', payload: ['foo '] }
Third parameter in createSymbiote
is optional string
or object
.
If string
passed, symbiote converts it to { namespace: 'string' }
.
Object has optional properties:
namespace
is string
β set prefix for each action typedefaultReducer
is (previousState, action) -> newState
β called instead of return previous stateseparator
is string
β change separator of nested action types (default /
)You can use action as action type in classic reducer or in handleAction(s)
in redux-actions
1import { handleActions } from 'redux-actions' 2import { createSymbiote } from 'redux-symbiote' 3 4const initialState = { /* ... */ } 5 6const symbiotes = { 7 foo: { 8 bar: { 9 baz: (state, arg1, arg2) => ({ ...state, data: arg1, atad: arg2 }), 10 }, 11 }, 12} 13 14const { actions } = createSymbiote(initialState, symbiotes) 15 16const reducer = handleActions({ 17 [actions.foo.bar.baz]: (state, { payload: [arg1, arg2] }) => ({ 18 ...state, 19 data: arg1, 20 atad: arg2, 21 }), 22}, initialState)
createSymbiote
returns object with actions
and reducer
.
Created reducer already handles created actions. You don't need to handle actions from symbiote.
1// accounts.js 2export const { actions, reducer } = createSymbiote(initialState, symbiotes, options) 3 4// reducer.js 5import { reducer as accounts } from '../accounts/symbiote' 6// another imports 7 8export const reducer = combineReducers({ 9 accounts, 10 // another reducers 11})
Redux recommends creating constants, action creators and reducers separately.
1const ACCOUNTS_LOADING_START = 'ACCOUNTS_LOADING_START' 2const ACCOUNTS_LOADING_FAILED = 'ACCOUNTS_LOADING_FAILED' 3const ACCOUNTS_LOADING_FINISH = 'ACCOUNTS_LOADING_FINISH' 4 5 6export function loadingStart() { 7 return { 8 type: ACCOUNTS_LOADING_START, 9 } 10} 11 12export function loadingFailed(error) { 13 return { 14 type: ACCOUNTS_LOADING_FAILED, 15 payload: { 16 error, 17 }, 18 } 19} 20 21export function loadingFinish(accounts) { 22 return { 23 type: ACCOUNTS_LOADING_FINISH, 24 payload: { 25 accounts, 26 }, 27 } 28} 29 30const initialState = { 31 error: null, 32 accounts: [], 33 loading: false, 34} 35 36export function accountsReducer(state = initialState, action) { 37 switch (action.type) { 38 case ACCOUNTS_LOADING_START: 39 return Object.assign({}, state, { 40 loading: true, 41 }) 42 43 case ACCOUNTS_LOADING_FAILED: 44 return Object.assign({}, state, { 45 loading: false, 46 error: action.payload.error, 47 }) 48 49 case ACCOUNTS_LOADING_FINISH: 50 return Object.assign({}, state, { 51 loading: false, 52 accounts: action.payload.accounts, 53 }) 54 } 55 56 return state 57}
So much boilerplate.
Let's look at redux-actions.
1import { createActions, handleActions, combineActions } from 'redux-actions' 2 3 4export const actions = createActions({ 5 accounts: { 6 loading: { 7 start: () => ({ loading: true }), 8 failed: (error) => ({ loading: false, error }), 9 finish: (accounts) => ({ loading: false, accounts }), 10 }, 11 }, 12}).accounts 13 14const initialState = { 15 error: null, 16 accounts: [], 17 loading: false, 18} 19 20export const accountsReducer = handleActions({ 21 [combineActions(actions.loading.start, actions.loading.failed, actions.loading.finish)]: 22 (state, { payload: { loading } }) => ({ ...state, loading }), 23 24 [actions.loading.failed]: (state, { payload: { error } }) => ({ ...state, error }), 25 26 [actions.loading.finish]: (state, { payload: { accounts } }) => ({ ...state, accounts }), 27}, initialState)
But we have some duplicate in action creators properties and reducer.
Let's rewrite it to redux-symbiote:
1import { createSymbiote } from 'redux-symbiote' 2 3const initialState = { 4 error: null, 5 accounts: [], 6 loading: false, 7} 8 9const symbiotes = { 10 start: (state) => ({ ...state, loading: true }), 11 finish: (state, { accounts }) => ({ ...state, loading: false, accounts }), 12 failed: (state, { error }) => ({ ...state, loading: false, error }), 13} 14 15export const { actions, reducer: accountsReducer } = 16 createSymbiote(initialState, symbiotes, 'accounts/loading')
That's all. accounts/loading
is an optional namespace for actions types.
To reduce noise around loading actions try symbiote-fetching
.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
security policy file detected
Details
Reason
Found 4/16 approved changesets -- score normalized to 2
Reason
project is archived
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
51 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-03-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More