redux-detector
Advanced tools
Comparing version
@@ -1,3 +0,2 @@ | ||
import { Action } from 'redux'; | ||
import { Detector } from './Detector'; | ||
export declare function combineDetectors<S, A extends Action>(...detectors: Detector<S>[]): Detector<S>; | ||
export declare function combineDetectors<S>(...detectors: Detector<S>[]): Detector<S>; |
import { StoreEnhancer, Reducer } from 'redux'; | ||
import { Detector } from './Detector'; | ||
import { DetectableStore } from './DetectableStore'; | ||
export declare function createDetectableStore<S>(reducer: Reducer<S>, detector: Detector<S>, preloadedState: S, enhancer?: StoreEnhancer<S>): DetectableStore<S>; | ||
export declare function createDetectableStore<S>(reducer: Reducer<S>, detector: Detector<S>, preloadedState?: S, enhancer?: StoreEnhancer<S>): DetectableStore<S>; |
import { StoreEnhancerStoreCreator, Reducer } from 'redux'; | ||
import { Detector } from './Detector'; | ||
import { DetectableStore } from './DetectableStore'; | ||
export declare const ActionTypes: { | ||
INIT: string; | ||
}; | ||
export declare type StoreDetectableEnhancer<S> = (next: StoreEnhancerStoreCreator<S>) => StoreEnhancerStoreDetectableCreator<S>; | ||
export declare type StoreEnhancerStoreDetectableCreator<S> = (reducer: Reducer<S>, preloadedState: S) => DetectableStore<S>; | ||
export declare function createDetectorEnhancer<S>(detector: Detector<S>): StoreDetectableEnhancer<S>; |
@@ -1,2 +0,2 @@ | ||
import { Action } from 'redux'; | ||
export declare type Detector<S> = <A extends Action>(prevState: S | undefined, nextState: S) => A[] | void; | ||
import { ActionLike } from './ActionLike'; | ||
export declare type Detector<S> = (prevState: S | undefined, nextState: S) => ActionLike | ActionLike[] | void; |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("Redux")):"function"==typeof define&&define.amd?define(["Redux"],e):"object"==typeof exports?exports.ReduxDetector=e(require("Redux")):t.ReduxDetector=e(t.Redux)}(this,function(t){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var r={};return e.m=t,e.c=r,e.i=function(t){return t},e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=5)}([function(t,e,r){"use strict";function n(t){return function(e){return function(r,n){var u=e(r,n),i=n,a=t,f=o({},u,{replaceDetector:function(t){if("function"!=typeof t)throw Error("Expected the nextDetector to be a function.");a=t,u.dispatch({type:c.INIT})}});return f.subscribe(function(){var t=f.getState(),e=a(i,t);i=t,e&&Array===e.constructor&&e.forEach(function(t){return f.dispatch(t)})}),f}}}var o=this&&this.__assign||Object.assign||function(t){for(var e,r=1,n=arguments.length;n>r;r++){e=arguments[r];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t},c={INIT:"@@detector/INIT"};e.createDetectorEnhancer=n},function(t,e,r){"use strict";function n(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e];var r=t.map(function(t,e){return t instanceof Function?-1:e}).filter(function(t){return t!==-1});if(r.length)throw Error("Detected invalid arguments: "+r.join(", ")+" in combineDetectors call.\nDetectors should be a 'function' type, "+("'"+r.map(function(e){return typeof t[e]}).join("', '")+"' types passed."));return function(e,r){return t.map(function(t){return t(e,r)||[]}).reduce(function(t,e){return t.concat(e)},[])}}e.combineDetectors=n},function(t,e,r){"use strict";function n(t,e,r,n){return n=n?o.compose(c.createDetectorEnhancer(e),n):c.createDetectorEnhancer(e),o.createStore(t,r,n)}var o=r(4),c=r(0);e.createDetectableStore=n},function(t,e,r){"use strict";function n(t,e){return function(r,n){return e(t(r),t(n))}}e.mountDetector=n},function(e,r){e.exports=t},function(t,e,r){"use strict";var n=r(1);e.combineDetectors=n.combineDetectors;var o=r(0);e.createDetectorEnhancer=o.createDetectorEnhancer;var c=r(2);e.createDetectableStore=c.createDetectableStore;var u=r(3);e.mountDetector=u.mountDetector}])}); | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("Redux")):"function"==typeof define&&define.amd?define(["Redux"],e):"object"==typeof exports?exports.ReduxDetector=e(require("Redux")):t.ReduxDetector=e(t.Redux)}(this,function(t){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var r={};return e.m=t,e.c=r,e.i=function(t){return t},e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=5)}([function(t,e,r){"use strict";function n(t){if("function"!=typeof t)throw Error("Expected the detector to be a function.");return function(r){return function(n,c){var u=r(n,c),i=c,a=t,f=o({},u,{replaceDetector:function(t){if("function"!=typeof t)throw Error("Expected the nextDetector to be a function.");a=t,u.dispatch({type:e.ActionTypes.INIT})}});return f.subscribe(function(){var t=f.getState(),e=a(i,t)||[];i=t,Array===e.constructor?e.forEach(function(t){return f.dispatch(t)}):f.dispatch(e)}),f}}}var o=this&&this.__assign||Object.assign||function(t){for(var e,r=1,n=arguments.length;n>r;r++){e=arguments[r];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o])}return t};e.ActionTypes={INIT:"@@detector/INIT"},e.createDetectorEnhancer=n},function(t,e,r){"use strict";function n(){for(var t=[],e=0;arguments.length>e;e++)t[e]=arguments[e];var r=t.map(function(t,e){return t instanceof Function?-1:e}).filter(function(t){return t!==-1});if(r.length)throw Error("Invalid arguments: "+r.join(", ")+" in combineDetectors call.\nDetectors should be a 'function' type, "+("'"+r.map(function(e){return typeof t[e]}).join("', '")+"' types passed."));return function(e,r){return t.map(function(t){return t(e,r)||[]}).reduce(function(t,e){return t.concat(e)},[])}}e.combineDetectors=n},function(t,e,r){"use strict";function n(t,e,r,n){return n=n?o.compose(c.createDetectorEnhancer(e),n):c.createDetectorEnhancer(e),o.createStore(t,r,n)}var o=r(4),c=r(0);e.createDetectableStore=n},function(t,e,r){"use strict";function n(t,e){return function(r,n){return e(t(r),t(n))}}e.mountDetector=n},function(e,r){e.exports=t},function(t,e,r){"use strict";var n=r(1);e.combineDetectors=n.combineDetectors;var o=r(0);e.createDetectorEnhancer=o.createDetectorEnhancer;var c=r(2);e.createDetectableStore=c.createDetectableStore;var u=r(3);e.mountDetector=u.mountDetector}])}); | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,2 @@ | ||
import { Action } from 'redux'; | ||
import { Detector } from './Detector'; | ||
export declare function mountDetector<S1, S2, A extends Action>(selector: (state: S1) => S2, detector: Detector<S2>): Detector<S1>; | ||
export declare function mountDetector<S1, S2>(selector: (state: S1) => S2, detector: Detector<S2>): Detector<S1>; |
{ | ||
"name": "redux-detector", | ||
"version": "0.5.1", | ||
"description": "Redux extension allows to detect state changes and then dispatch actions using pure functions.", | ||
"version": "0.5.2", | ||
"description": "Redux enhancer for pure detection of state changes.", | ||
"main": "lib/index.js", | ||
@@ -6,0 +6,0 @@ "types": "lib/index.d.ts", |
@@ -6,3 +6,3 @@ # Redux Detector | ||
Redux [enhancer](http://redux.js.org/docs/api/createStore.html) for pure state changes detection. | ||
Redux [enhancer](http://redux.js.org/docs/api/createStore.html) for pure detection of state changes. | ||
@@ -47,6 +47,6 @@ **Warning: API is not stable yet, will be from version 1.0** | ||
Redux Detector [enhancer](http://redux.js.org/docs/api/createStore.html) allows you to use state changes detectors with redux. | ||
Detector is a simple and pure function which compares two states and returns list of actions for some states configurations. | ||
Detector is a simple and pure function which compares two states and returns action or list of actions for some states configurations. | ||
It can be used for reacting on particular state transitions. | ||
```typescript | ||
type Detector<S> = <A extends Action>(prevState: S | undefined, nextState: S) => A[] | void | ||
type Detector<S> = <A extends Action>(prevState: S | undefined, nextState: S) => A | A[] | void | ||
``` | ||
@@ -58,6 +58,7 @@ | ||
if (prevState.rows.length <= 100 && nextState.rows.length > 100) { | ||
return [{ type: ROWS_LIMIT_EXCEEDED }]; | ||
return { type: ROWS_LIMIT_EXCEEDED }; | ||
} | ||
} | ||
``` | ||
You can also return array of actions to dispatch them. | ||
@@ -81,7 +82,7 @@ Thanks to detectors purity they are predictable and easy to test. There is no problem with features like time-travel, etc. | ||
```js | ||
// ./detectors/limitExceedDetector | ||
export default function createLimitExceedDetector(limit, action) { | ||
// ./detectors/limitExceedDetector.js | ||
export function createLimitExceedDetector(limit, action) { | ||
return function limitExceedDetector(prevState, nextState) { | ||
if (prevState <= limit && nextState > limit) { | ||
return [action]; | ||
return action; | ||
} | ||
@@ -91,3 +92,3 @@ } | ||
// ./detectors/rowsLimitExceedDetector | ||
// ./detectors/rowsLimitExceedDetector.js | ||
import { mountDetector } from 'redux-detector'; | ||
@@ -104,3 +105,10 @@ import { createLimitExceeedDetector } from './limitExceedDetector'; | ||
## Code Splitting ## | ||
Redux Detector provides `replaceDetector` method on `DetectableStore` interface (store created by Redux Detector). It's similar to | ||
`replaceReducer` - it changes detector and dispatches `{ type: '@@detector/INIT' }`. | ||
## Typings ## | ||
If you are using [TypeScript](https://www.typescriptlang.org/), you don't have to install typings - they are provided in npm package. | ||
## License ## | ||
MIT |
@@ -1,6 +0,6 @@ | ||
import { Action } from 'redux'; | ||
import { Detector } from './Detector'; | ||
import { ActionLike } from './ActionLike'; | ||
export function combineDetectors<S, A extends Action>(...detectors: Detector<S>[]): Detector<S> { | ||
// check detectors types in runtime | ||
export function combineDetectors<S>(...detectors: Detector<S>[]): Detector<S> { | ||
// check detectors type in runtime | ||
const invalidDetectorsIndexes: number[] = detectors | ||
@@ -12,3 +12,3 @@ .map((detector, index) => detector instanceof Function ? -1 : index) | ||
throw new Error( | ||
`Detected invalid arguments: ${invalidDetectorsIndexes.join(', ')} in combineDetectors call.\n` + | ||
`Invalid arguments: ${invalidDetectorsIndexes.join(', ')} in combineDetectors call.\n` + | ||
`Detectors should be a 'function' type, ` + | ||
@@ -19,7 +19,7 @@ `'${invalidDetectorsIndexes.map(index => typeof detectors[index]).join(`', '`)}' types passed.` | ||
return function combinedDetector(prevState: S, nextState: S): A[] { | ||
return function combinedDetector(prevState: S, nextState: S): ActionLike[] { | ||
return detectors | ||
.map(detector => detector(prevState, nextState) || []) | ||
.reduce<A[]>((actions: A[], nextActions: A[]) => actions.concat(nextActions), []); | ||
.reduce<ActionLike[]>((actions: ActionLike[], nextActions: ActionLike | ActionLike[]) => actions.concat(nextActions), []); | ||
}; | ||
} |
@@ -9,3 +9,3 @@ import { StoreEnhancer, Reducer, compose, createStore } from 'redux'; | ||
detector: Detector<S>, | ||
preloadedState: S, | ||
preloadedState?: S, | ||
enhancer?: StoreEnhancer<S> | ||
@@ -12,0 +12,0 @@ ): DetectableStore<S> { |
@@ -1,6 +0,7 @@ | ||
import { StoreEnhancerStoreCreator, Store, Reducer, Action } from 'redux'; | ||
import { StoreEnhancerStoreCreator, Store, Reducer } from 'redux'; | ||
import { Detector } from './Detector'; | ||
import { ActionLike } from './ActionLike'; | ||
import { DetectableStore } from './DetectableStore'; | ||
const ActionTypes: { INIT: string } = { | ||
export const ActionTypes: { INIT: string } = { | ||
INIT: '@@detector/INIT' | ||
@@ -13,2 +14,6 @@ }; | ||
export function createDetectorEnhancer<S>(detector: Detector<S>): StoreDetectableEnhancer<S> { | ||
if (typeof detector !== 'function') { | ||
throw new Error('Expected the detector to be a function.'); | ||
} | ||
return function detectorEnhancer(next: StoreEnhancerStoreCreator<S>): StoreEnhancerStoreDetectableCreator<S> { | ||
@@ -41,3 +46,3 @@ return function detectableStoreCreator(reducer: Reducer<S>, preloadedState?: S): DetectableStore<S> { | ||
// detect actions by comparing prev and next state | ||
const detectedActions: Action[] | void = currentDetector(prevState, nextState); | ||
const detectedActions: ActionLike | ActionLike[] = currentDetector(prevState, nextState) || []; | ||
@@ -48,4 +53,6 @@ // store current state as previous for next subscribe call | ||
// dispatch all actions returned from detector | ||
if (detectedActions && Array === detectedActions.constructor) { | ||
detectedActions.forEach(detectedAction => detectableStore.dispatch(detectedAction)); | ||
if (Array === detectedActions.constructor) { | ||
(detectedActions as ActionLike[]).forEach(detectedAction => detectableStore.dispatch(detectedAction)); | ||
} else { | ||
detectableStore.dispatch(detectedActions as ActionLike); | ||
} | ||
@@ -52,0 +59,0 @@ }); |
@@ -1,3 +0,5 @@ | ||
import { Action } from 'redux'; | ||
import { ActionLike } from './ActionLike'; | ||
export type Detector<S> = <A extends Action>(prevState: S | undefined, nextState: S) => A[] | void; | ||
// we use ActionLike instead of <A extends Action>, because second form doesn't check type on definition, only on call expression. | ||
// we could use also Detector<S, A>, but it's not practical - all we need to know is that ActionLike object has 'type': string field. | ||
export type Detector<S> = (prevState: S | undefined, nextState: S) => ActionLike | ActionLike[] | void; |
@@ -1,8 +0,8 @@ | ||
import { Action } from 'redux'; | ||
import { Detector } from './Detector'; | ||
import { ActionLike } from './ActionLike'; | ||
export function mountDetector<S1, S2, A extends Action>(selector: (state: S1) => S2, detector: Detector<S2>): Detector<S1> { | ||
return function mountedDetector(prevState: S1, nextState: S1): A[] | void { | ||
return detector<A>(selector(prevState), selector(nextState)); | ||
export function mountDetector<S1, S2>(selector: (state: S1) => S2, detector: Detector<S2>): Detector<S1> { | ||
return function mountedDetector(prevState: S1, nextState: S1): ActionLike | ActionLike[] | void { | ||
return detector(selector(prevState), selector(nextState)); | ||
}; | ||
} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
38442
5.07%22
10%158
12.06%109
7.92%0
-100%