├── .gitignore ├── .babelrc ├── package.json ├── README.md └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib/ 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"] 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-persist-migrate", 3 | "version": "5.0.0", 4 | "description": "migrate your redux state", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "standard", 8 | "build": "babel src --out-dir lib", 9 | "build:watch": "npm run build ./src -- -watch", 10 | "clean": "rimraf lib dist", 11 | "prepublish": "npm run clean && npm run build" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/wildlifela/redux-persist-migrate.git" 16 | }, 17 | "homepage": "https://github.com/wildlifela/redux-persist-migrate", 18 | "author": "rt2zz ", 19 | "license": "MIT", 20 | "dependencies": {}, 21 | "keywords": [ 22 | "redux", 23 | "redux-persist", 24 | "redux-persist-migrate", 25 | "redux-migrate" 26 | ], 27 | "peerDependencies": { 28 | "redux-persist": ">=3.0.0" 29 | }, 30 | "devDependencies": { 31 | "babel-cli": "^6.7.7", 32 | "babel-eslint": "^6.0.4", 33 | "babel-preset-es2015": "^6.6.0", 34 | "babel-preset-stage-2": "^6.5.0", 35 | "babel-register": "^6.7.2", 36 | "rimraf": "^2.5.2", 37 | "standard": "^6.0.8" 38 | }, 39 | "files": [ 40 | "lib", 41 | "src" 42 | ], 43 | "standard": { 44 | "parser": "babel-eslint", 45 | "ignore": [ 46 | "/lib" 47 | ] 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## DEPRECATED - This library has been moved 2 | This library has been moved into [redux-persist](https://github.com/rt2zz/redux-persist#migrations) 3 | 4 | --- 5 | 6 | ## Redux Persist Migrate 7 | 8 | Migrate redux state between versions with redux-persist. 9 | 10 | #### Usage 11 | ```js 12 | import { compose, createStore, combineReducers } from 'redux' 13 | import { persistStore, autoRehydrate } from 'redux-persist' 14 | import createMigration from 'redux-persist-migrate' 15 | 16 | // VERSION_REDUCER_KEY is the key of the reducer you want to store the state version in. 17 | // You _must_ create this reducer, redux-persist-migrate will not create it for you. 18 | // In this example after migrations run, `state.app.version` will equal `2` 19 | const VERSION_REDUCER_KEY = 'app' 20 | 21 | // This is a list of changes to make to the state being rehydrated. 22 | // The keys must be integers, and migrations will be performed in ascending key order. 23 | // Note: blacklisted reducers will not be present in this state. 24 | const manifest = { 25 | 1: (state) => ({...state, staleReducer: undefined}) 26 | 2: (state) => ({...state, app: {...state.app, staleKey: undefined}}) 27 | } 28 | 29 | const migration = createMigration(manifest, VERSION_REDUCER_KEY) 30 | const enhancer = compose(migration, autoRehydrate()) 31 | 32 | const reducer = combineReducers({ 33 | [VERSION_REDUCER_KEY]: (state = {}) => state, // This reducer will be used to store the version 34 | otherReducer1, 35 | otherReducer2, 36 | // ... 37 | }) 38 | 39 | const store = createStore(reducer, null, enhancer) 40 | persistStore(store) 41 | ``` 42 | 43 | In the above example `migration = createMigration(manifest, VERSION_REDUCER_KEY)` is equivalent to the more generalized syntax: 44 | ```js 45 | // alternatively with version selector & setter 46 | const migration = createMigration( 47 | manifest, 48 | (state) => state.app.version, 49 | (state, version) => { 50 | return { ...state, app: { ...state.app, version: version } } 51 | } 52 | ) 53 | ``` 54 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { REHYDRATE } from 'redux-persist/constants' 2 | 3 | const processKey = (key) => { 4 | let int = parseInt(key) 5 | if (isNaN(int)) throw new Error('redux-persist-migrate: migrations must be keyed with integer values') 6 | return int 7 | } 8 | 9 | export default function createMigration (manifest, versionSelector, versionSetter) { 10 | if (typeof versionSelector === 'string') { 11 | let reducerKey = versionSelector 12 | versionSelector = (state) => state && state[reducerKey] && state[reducerKey].version 13 | versionSetter = (state, version) => { 14 | if (['undefined', 'object'].indexOf(typeof state[reducerKey]) === -1) { 15 | console.error('redux-persist-migrate: state for versionSetter key must be an object or undefined') 16 | return state 17 | } 18 | state[reducerKey] = state[reducerKey] || {} 19 | state[reducerKey].version = version 20 | return state 21 | } 22 | } 23 | 24 | const versionKeys = Object.keys(manifest).map(processKey).sort((a, b) => a - b) 25 | let currentVersion = versionKeys[versionKeys.length - 1] 26 | if (!currentVersion && currentVersion !== 0) currentVersion = -1 27 | 28 | const migrationDispatch = (next) => (action) => { 29 | if (action.type === REHYDRATE) { 30 | const incomingState = action.payload 31 | let incomingVersion = parseInt(versionSelector(incomingState)) 32 | if (isNaN(incomingVersion)) incomingVersion = null 33 | 34 | if (incomingVersion !== currentVersion) { 35 | const migratedState = migrate(incomingState, incomingVersion) 36 | action.payload = migratedState 37 | } 38 | } 39 | return next(action) 40 | } 41 | 42 | const migrate = (state, version) => { 43 | versionKeys 44 | .filter((v) => v > version || version === null) 45 | .forEach((v) => { state = manifest[v](state) }) 46 | 47 | state = versionSetter(state, currentVersion) 48 | return state 49 | } 50 | 51 | return (next) => (reducer, initialState, enhancer) => { 52 | var store = next(reducer, initialState, enhancer) 53 | return { 54 | ...store, 55 | dispatch: migrationDispatch(store.dispatch) 56 | } 57 | } 58 | } 59 | --------------------------------------------------------------------------------