redux-state-sync
Advanced tools
Comparing version 1.0.4 to 1.1.0
@@ -10,5 +10,3 @@ | ||
store[key] = value.toString(); | ||
Event.prototype.newValue = JSON.stringify({ | ||
stampedAction: JSON.parse(value).stampedAction, | ||
}); | ||
Event.prototype.newValue = value; | ||
window.dispatchEvent(new Event('storage')); | ||
@@ -15,0 +13,0 @@ }, |
/* global jest window localStorage describe it test expect */ | ||
import { actionStorageMiddleware, createStorageListener, timestampAction } from '../syncStorage'; | ||
import { actionStorageMiddleware, createStorageListener, generateUuidForAction } from '../dist/syncStorage'; | ||
@@ -15,5 +15,5 @@ const LAST_ACTION = 'LAST_ACTION'; | ||
createStorageListener(store); | ||
it('action should have $time added', () => { | ||
it('action should have $uuid added', () => { | ||
const action = { type: 'Test', payload: 'Test' }; | ||
expect(timestampAction(action).stampedAction.$time).toBeDefined(); | ||
expect(generateUuidForAction(action).$uuid).toBeDefined(); | ||
}); | ||
@@ -23,3 +23,4 @@ | ||
const action = { type: 'Test', payload: 'Test' }; | ||
actionStorageMiddleware()(next => next)(action); | ||
const getState = () => {}; | ||
actionStorageMiddleware({ getState })(next => next)(action); | ||
stampedAction = action; | ||
@@ -29,7 +30,7 @@ expect(localStorage.getItem(LAST_ACTION)).toBeDefined(); | ||
it('same action should be triggered', () => { | ||
expect(triggeredAction.type).toBe(stampedAction.type); | ||
expect(triggeredAction.payload).toBe(stampedAction.payload); | ||
expect(triggeredAction.$time).toBe(stampedAction.$time); | ||
it('same action should not be triggered, because the timestamp is the same as the latest timestamp', () => { | ||
expect(triggeredAction.type).toBe(undefined); | ||
expect(triggeredAction.payload).toBe(undefined); | ||
expect(triggeredAction.$uuid).toBe(undefined); | ||
}); | ||
}); |
{ | ||
"name": "redux-state-sync", | ||
"version": "1.0.4", | ||
"description": "A middleware for redux to sync localstorage state in different tabs", | ||
"main": "syncStorage.js", | ||
"version": "1.1.0", | ||
"description": "A middleware for redux to sync state in different tabs", | ||
"main": "dist/syncStorage.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "jest --clearCache", | ||
"commit": "git-cz", | ||
"prebuild": "rimraf dist", | ||
"build": "npm-run-all --parallel build:*", | ||
"build:main": "babel --copy-files --out-dir dist --ignore *.test.js src", | ||
"build:umd": "webpack --output-filename syncStorage.umd.js", | ||
"build:umd.min": "webpack --output-filename syncStorage.umd.min.js -p", | ||
"semantic-release": "semantic-release pre && npm publish && semantic-release post" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/AOHUA/redux-state-sync.git" | ||
"url": "https://github.com/AOHUA/redux-state-sync.git" | ||
}, | ||
@@ -31,4 +38,8 @@ "keywords": [ | ||
"babel-jest": "^16.0.0", | ||
"babel-loader": "^7.0.0", | ||
"babel-polyfill": "^6.16.0", | ||
"babel-preset-es2015": "^6.18.0", | ||
"babel-register": "^6.18.0", | ||
"commitizen": "^2.8.6", | ||
"cz-conventional-changelog": "^1.2.0", | ||
"eslint": "^3.8.1", | ||
@@ -39,7 +50,9 @@ "eslint-config-airbnb": "^12.0.0", | ||
"eslint-plugin-react": "^6.4.1", | ||
"jest": "^16.0.2" | ||
"jest": "^16.0.2", | ||
"npm-run-all": "^4.0.2", | ||
"rimraf": "^2.5.4", | ||
"semantic-release": "^6.3.2", | ||
"webpack": "^2.4.1" | ||
}, | ||
"dependencies": { | ||
"lodash": "^4.16.4" | ||
}, | ||
"dependencies": {}, | ||
"jest": { | ||
@@ -50,3 +63,6 @@ "setupFiles": [ | ||
"verbose": true | ||
}, | ||
"czConfig": { | ||
"path": "node_modules/cz-conventional-changelog" | ||
} | ||
} |
# Redux-State-Sync | ||
A very light weight middleware to sync your redux state across browser tabs. | ||
A lightweight middleware to sync your redux state across browser tabs. It will listen to the window storage event and dispatch exactly the same actions dispatched in other tabs to keep the redux state in sync. Furthermore, you can also pass a list of actions to ignore, so that they wouldn't be dispatched in other tabs (e.g. API requests). | ||
### Installing | ||
[![travis build](https://img.shields.io/travis/AOHUA/redux-state-sync.svg)](https://travis-ci.org/AOHUA/redux-state-sync) | ||
[![downloads](https://img.shields.io/npm/dm/redux-state-sync.svg)](https://www.npmjs.com/package/redux-state-sync) | ||
### How to install | ||
Simply install it with npm. | ||
@@ -11,7 +14,16 @@ | ||
npm install --save redux-state-sync | ||
or | ||
yarn add redux-state-sync | ||
``` | ||
### How to use | ||
import `actionStorageMiddleware` and `createStorageListener`. | ||
Add actionStorageMiddleware to the list of middlewares during store creation. | ||
Call `createStorageListener` to subscribe for storage events and dispatch actions to change store state. | ||
Follow the example below: | ||
``` | ||
@@ -41,3 +53,3 @@ import { actionStorageMiddleware, createStorageListener } from 'redux-state-sync'; | ||
You may not want to trigger the Actions which triggers a api request. So you can simply pass in the Action type to ignore it. Like below: | ||
You may not want to dispatch actions which trigger API requests. To prevent those actions from being dispatched, pass in a list of action types as strings: | ||
@@ -51,3 +63,3 @@ ``` | ||
/* | ||
* To still make your state sync. You need to trigger other actions with the data from the api request. | ||
* To still make your state sync. You need to trigger other actions with the data from the api request. | ||
* The example is using redux-saga to handle the side effects. | ||
@@ -59,2 +71,3 @@ */ | ||
const repo = yield call(api.fetchRepo, action.url); | ||
/* Triggers a REPO_SUCCESS and this action should be triggered in other tabs also */ | ||
yield put({ type: 'REPO_SUCCESS', repo }); | ||
@@ -74,1 +87,37 @@ } catch (e) { | ||
``` | ||
Thanks to [Olebedev](https://github.com/olebedev), there's another way to ignore actions which you don't want to be dispatched. You can simply provide a predicate function in the config object: | ||
``` | ||
const config = { | ||
predicate: actionType => actionType !== 'GET_REPO', | ||
}; | ||
``` | ||
GET_REPO action will not be triggered in other tabs in this case. | ||
### Experimental feature | ||
How to init new tab with current tab's state | ||
By default this feature is disabled, you can enable it as below: | ||
``` | ||
const config = { | ||
initiateWithState: true, | ||
}; | ||
``` | ||
You also need to wrap your root reducer with 'withReduxStateSync' function. | ||
``` | ||
import { withReduxStateSync } from 'redux-state-sync' | ||
const rootReducer = combineReducers({ | ||
todos, | ||
visibilityFilter | ||
}) | ||
export default withReduxStateSync(rootReducer) | ||
``` | ||
This feature is totally experimental, you shall use it at your own risk. ;-) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
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
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
492809
0
39
947
0
119
18
3
- Removedlodash@^4.16.4
- Removedlodash@4.17.21(transitive)