ngrx-store-localstorage
Advanced tools
Comparing version 0.2.4 to 0.3.0
export declare const dateReviver: (key: string, value: any) => any; | ||
export declare const rehydrateApplicationState: (keys: any[], storage: Storage, storageKeySerializer: (key: string) => string) => any; | ||
export declare const rehydrateApplicationState: (keys: any[], storage: Storage, storageKeySerializer: (key: string) => string, restoreDates: boolean) => any; | ||
export declare const syncStateUpdate: (state: any, keys: any[], storage: Storage, storageKeySerializer: (key: string) => string, removeOnUndefined: boolean) => void; | ||
@@ -11,3 +11,4 @@ export declare const localStorageSync: (config: LocalStorageConfig) => (reducer: any) => (state: any, action: any) => any; | ||
removeOnUndefined?: boolean; | ||
restoreDates?: boolean; | ||
storageKeySerializer?: (key: string) => string; | ||
} |
@@ -8,3 +8,3 @@ "use strict"; | ||
exports.dateReviver = function (key, value) { | ||
if (typeof value === 'string' && (detectDate.test(value))) { | ||
if (typeof value === 'string' && detectDate.test(value)) { | ||
return new Date(value); | ||
@@ -14,2 +14,3 @@ } | ||
}; | ||
var dummyReviver = function (key, value) { return value; }; | ||
var validateStateKeys = function (keys) { | ||
@@ -21,5 +22,5 @@ return keys.map(function (key) { | ||
} | ||
if (typeof (attr) !== 'string') { | ||
throw new TypeError("localStorageSync Unknown Parameter Type: " | ||
+ ("Expected type of string, got " + typeof attr)); | ||
if (typeof attr !== 'string') { | ||
throw new TypeError("localStorageSync Unknown Parameter Type: " + | ||
("Expected type of string, got " + typeof attr)); | ||
} | ||
@@ -29,6 +30,6 @@ return key; | ||
}; | ||
exports.rehydrateApplicationState = function (keys, storage, storageKeySerializer) { | ||
exports.rehydrateApplicationState = function (keys, storage, storageKeySerializer, restoreDates) { | ||
return keys.reduce(function (acc, curr) { | ||
var key = curr; | ||
var reviver = exports.dateReviver; | ||
var reviver = restoreDates ? exports.dateReviver : dummyReviver; | ||
var deserialize = undefined; | ||
@@ -54,3 +55,4 @@ var decrypt = undefined; | ||
if (curr[key].encrypt && curr[key].decrypt) { | ||
if (typeof (curr[key].encrypt) === 'function' && typeof (curr[key].decrypt) === 'function') { | ||
if (typeof curr[key].encrypt === 'function' && | ||
typeof curr[key].decrypt === 'function') { | ||
decrypt = curr[key].decrypt; | ||
@@ -73,3 +75,3 @@ } | ||
} | ||
var isObjectRegex = new RegExp('\{|\\['); | ||
var isObjectRegex = new RegExp('{|\\['); | ||
var raw = stateSlice; | ||
@@ -79,3 +81,5 @@ if (isObjectRegex.test(stateSlice.charAt(0))) { | ||
} | ||
return Object.assign({}, acc, (_a = {}, _a[key] = deserialize ? deserialize(raw) : raw, _a)); | ||
return Object.assign({}, acc, (_a = {}, | ||
_a[key] = deserialize ? deserialize(raw) : raw, | ||
_a)); | ||
} | ||
@@ -95,3 +99,3 @@ return acc; | ||
stateSlice = state[name_1]; | ||
if (typeof (stateSlice) !== 'undefined' && key[name_1]) { | ||
if (typeof stateSlice !== 'undefined' && key[name_1]) { | ||
// use serialize function if specified. | ||
@@ -102,2 +106,3 @@ if (key[name_1].serialize) { | ||
else { | ||
// if serialize function is not specified filter on fields if an array has been provided. | ||
var filter = undefined; | ||
@@ -118,3 +123,3 @@ if (key[name_1].reduce) { | ||
if (key[name_1].encrypt && key[name_1].decrypt) { | ||
if (typeof (key[name_1].encrypt) === 'function') { | ||
if (typeof key[name_1].encrypt === 'function') { | ||
encrypt = key[name_1].encrypt; | ||
@@ -129,5 +134,5 @@ } | ||
/* | ||
Replacer and space arguments to pass to JSON.stringify. | ||
If these fields don't exist, undefined will be passed. | ||
*/ | ||
Replacer and space arguments to pass to JSON.stringify. | ||
If these fields don't exist, undefined will be passed. | ||
*/ | ||
replacer = key[name_1].replacer; | ||
@@ -138,9 +143,13 @@ space = key[name_1].space; | ||
} | ||
if (typeof (stateSlice) !== 'undefined') { | ||
if (typeof stateSlice !== 'undefined') { | ||
try { | ||
if (encrypt) { | ||
// ensure that a string message is passed | ||
stateSlice = encrypt(typeof stateSlice === 'string' ? stateSlice : JSON.stringify(stateSlice, replacer, space)); | ||
stateSlice = encrypt(typeof stateSlice === 'string' | ||
? stateSlice | ||
: JSON.stringify(stateSlice, replacer, space)); | ||
} | ||
storage.setItem(storageKeySerializer(key), typeof stateSlice === 'string' ? stateSlice : JSON.stringify(stateSlice, replacer, space)); | ||
storage.setItem(storageKeySerializer(key), typeof stateSlice === 'string' | ||
? stateSlice | ||
: JSON.stringify(stateSlice, replacer, space)); | ||
} | ||
@@ -151,3 +160,3 @@ catch (e) { | ||
} | ||
else if (typeof (stateSlice) === 'undefined' && removeOnUndefined) { | ||
else if (typeof stateSlice === 'undefined' && removeOnUndefined) { | ||
try { | ||
@@ -169,10 +178,15 @@ storage.removeItem(storageKeySerializer(key)); | ||
} | ||
if (config.restoreDates === undefined) { | ||
config.restoreDates = true; | ||
} | ||
var stateKeys = validateStateKeys(config.keys); | ||
var rehydratedState = config.rehydrate ? exports.rehydrateApplicationState(stateKeys, config.storage, config.storageKeySerializer) : undefined; | ||
var rehydratedState = config.rehydrate | ||
? exports.rehydrateApplicationState(stateKeys, config.storage, config.storageKeySerializer, config.restoreDates) | ||
: undefined; | ||
return function (state, action) { | ||
if (state === void 0) { state = rehydratedState; } | ||
/* | ||
Handle case where state is rehydrated AND initial state is supplied. | ||
Any additional state supplied will override rehydrated state for the given key. | ||
*/ | ||
Handle case where state is rehydrated AND initial state is supplied. | ||
Any additional state supplied will override rehydrated state for the given key. | ||
*/ | ||
if (action.type === INIT_ACTION && rehydratedState) { | ||
@@ -179,0 +193,0 @@ state = Object.assign({}, state, rehydratedState); |
{ | ||
"name": "ngrx-store-localstorage", | ||
"version": "0.2.4", | ||
"version": "0.3.0", | ||
"description": "State and local storage syncing for @ngrx/store", | ||
@@ -21,9 +21,3 @@ "main": "./dist/index.js", | ||
}, | ||
"keywords": [ | ||
"redux", | ||
"ngrx", | ||
"store", | ||
"localstorage", | ||
"rxjs" | ||
], | ||
"keywords": ["redux", "ngrx", "store", "localstorage", "rxjs"], | ||
"author": "Brian Troncone", | ||
@@ -30,0 +24,0 @@ "license": "MIT", |
@@ -72,8 +72,9 @@ # ngrx-store-localstorage | ||
* filter: An array of properties which should be synced (same format as the stand-along array specified above). | ||
* filter: An array of properties which should be synced (same format as the stand-alone array specified above). | ||
* `rehydrate` (optional) `boolean`: Pull initial state from local storage on startup, this will default to `false`. | ||
* `storage` (optional) `Storage`: Specify an object that conforms to the Storage interface to use, this will default to `localStorage`. | ||
* `storage` (optional) `Storage`: Specify an object that conforms to the [Storage interface](https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L9708) to use, this will default to `localStorage`. | ||
* `removeOnUndefined` (optional) `boolean`: Specify if the state is removed from the storage when the new value is undefined, this will default to `false`. | ||
* `storageKeySerializer` (optional) `(key: string) => string`: Сustom serialize function for storage keys, used to avoid Storage conflicts. | ||
* `restoreDates` \(*boolean? = true*): Restore serialized date objects. If you work directly with ISO date strings, set this option to `false`. | ||
Usage: `localStorageSync({keys: ['todos', 'visibilityFilter'], storageKeySerializer: (key) => 'cool_' + key, ... })`. In this example `Storage` will use keys `cool_todos` and `cool_visibilityFilter` keys to store `todos` and `visibilityFilter` slices of state). The key itself is used by default - `(key) => key`. | ||
@@ -80,0 +81,0 @@ |
@@ -86,3 +86,3 @@ declare var beforeEachProviders, it, describe, expect, inject; | ||
3.14159, | ||
new Date('1968-11-16T12:30:00'), | ||
new Date('1968-11-16T12:30:00Z'), | ||
new TypeB('Nested Class')); | ||
@@ -126,3 +126,3 @@ | ||
let finalState: any = rehydrateApplicationState(['state'], s, skr); | ||
let finalState: any = rehydrateApplicationState(['state'], s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(initialStateJson); | ||
@@ -143,3 +143,3 @@ | ||
const finalState: any = rehydrateApplicationState(['state'], s, skr); | ||
const finalState: any = rehydrateApplicationState(['state'], s, skr, true); | ||
expect(finalState.state).toEqual(primitiveStr); | ||
@@ -164,3 +164,3 @@ }); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(JSON.stringify({ state: t1Filtered })); | ||
@@ -182,3 +182,3 @@ | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(JSON.stringify(initialState)); | ||
@@ -199,3 +199,3 @@ expect(finalState.state instanceof TypeA).toBeTruthy(); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(JSON.stringify(initialState)); | ||
@@ -220,3 +220,3 @@ expect(finalState.state instanceof TypeA).toBeTruthy(); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(JSON.stringify({ filtered: t1Filtered })); | ||
@@ -240,3 +240,3 @@ | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(JSON.stringify({ replacer: t1Filtered })); | ||
@@ -265,3 +265,3 @@ | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
@@ -284,3 +284,3 @@ expect(JSON.stringify(finalState)).toEqual('{"replacer":{"astring":"Testing","adate":"1968-11-16T12:30:00.000Z","anumber":3.14159}}'); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr); | ||
let finalState: any = rehydrateApplicationState(keys, s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(initialStateJson); | ||
@@ -323,2 +323,15 @@ expect(finalState.state instanceof TypeA).toBeTruthy(); | ||
it('not restoreDates', () => { | ||
// Tests that dates are not revived when the flag is set to false | ||
let s = new MockStorage(); | ||
let skr = mockStorageKeySerializer; | ||
const initalState = {state: t1Simple}; | ||
syncStateUpdate(initalState, ['state'], s, skr, false); | ||
let finalState: any = rehydrateApplicationState(['state'], s, skr, false); | ||
expect(finalState).toEqual(initalState, 'rehydrated state should equal initial state'); | ||
}); | ||
it('encrypt-decrypt', () => { | ||
@@ -336,3 +349,3 @@ let s = new MockStorage(); | ||
// Retrieve the stored state with the rehydrateApplicationState function and | ||
let storedState = rehydrateApplicationState(keys, s, skr); | ||
let storedState = rehydrateApplicationState(keys, s, skr, true); | ||
expect(initialStateJson).toEqual(JSON.stringify(storedState)); | ||
@@ -370,3 +383,3 @@ }); | ||
let finalState: any = rehydrateApplicationState(['state'], s, skr); | ||
let finalState: any = rehydrateApplicationState(['state'], s, skr, true); | ||
expect(JSON.stringify(finalState)).toEqual(initialStateJson); | ||
@@ -373,0 +386,0 @@ |
380
src/index.ts
@@ -6,183 +6,239 @@ const INIT_ACTION = '@ngrx/store/init'; | ||
export const dateReviver = (key: string, value: any) => { | ||
if (typeof value === 'string' && (detectDate.test(value))) { | ||
return new Date(value); | ||
} | ||
return value; | ||
if (typeof value === 'string' && detectDate.test(value)) { | ||
return new Date(value); | ||
} | ||
return value; | ||
}; | ||
const dummyReviver = (key: string, value: any) => value; | ||
const validateStateKeys = (keys: any[]) => { | ||
return keys.map(key => { | ||
let attr = key; | ||
return keys.map(key => { | ||
let attr = key; | ||
if (typeof key === 'object') { | ||
attr = Object.keys(key)[0]; | ||
} | ||
if (typeof key === 'object') { | ||
attr = Object.keys(key)[0]; | ||
} | ||
if (typeof (attr) !== 'string') { | ||
throw new TypeError( | ||
`localStorageSync Unknown Parameter Type: ` | ||
+ `Expected type of string, got ${typeof attr}` | ||
); | ||
} | ||
return key; | ||
}); | ||
if (typeof attr !== 'string') { | ||
throw new TypeError( | ||
`localStorageSync Unknown Parameter Type: ` + | ||
`Expected type of string, got ${typeof attr}` | ||
); | ||
} | ||
return key; | ||
}); | ||
}; | ||
export const rehydrateApplicationState = (keys: any[], storage: Storage, storageKeySerializer: (key: string) => string) => { | ||
return keys.reduce((acc, curr) => { | ||
let key = curr; | ||
let reviver = dateReviver; | ||
let deserialize = undefined; | ||
let decrypt = undefined; | ||
export const rehydrateApplicationState = ( | ||
keys: any[], | ||
storage: Storage, | ||
storageKeySerializer: (key: string) => string, | ||
restoreDates: boolean | ||
) => { | ||
return keys.reduce((acc, curr) => { | ||
let key = curr; | ||
let reviver = restoreDates ? dateReviver : dummyReviver; | ||
let deserialize = undefined; | ||
let decrypt = undefined; | ||
if (typeof key === 'object') { | ||
key = Object.keys(key)[0]; | ||
// use the custom reviver function | ||
if (typeof curr[key] === 'function') { | ||
reviver = curr[key]; | ||
} | ||
else { | ||
// use custom reviver function if available | ||
if (curr[key].reviver) { | ||
reviver = curr[key].reviver; | ||
} | ||
// use custom serialize function if available | ||
if (curr[key].deserialize) { | ||
deserialize = curr[key].deserialize; | ||
} | ||
} | ||
if (typeof key === 'object') { | ||
key = Object.keys(key)[0]; | ||
// use the custom reviver function | ||
if (typeof curr[key] === 'function') { | ||
reviver = curr[key]; | ||
} else { | ||
// use custom reviver function if available | ||
if (curr[key].reviver) { | ||
reviver = curr[key].reviver; | ||
} | ||
// use custom serialize function if available | ||
if (curr[key].deserialize) { | ||
deserialize = curr[key].deserialize; | ||
} | ||
} | ||
// Ensure that encrypt and decrypt functions are both presents | ||
if (curr[key].encrypt && curr[key].decrypt) { | ||
if (typeof (curr[key].encrypt) === 'function' && typeof (curr[key].decrypt) === 'function') { | ||
decrypt = curr[key].decrypt; | ||
} else { | ||
console.error(`Either encrypt or decrypt is not a function on '${curr[key]}' key object.`); | ||
} | ||
} else if (curr[key].encrypt || curr[key].decrypt) { | ||
// Let know that one of the encryption functions is not provided | ||
console.error(`Either encrypt or decrypt function is not present on '${curr[key]}' key object.`); | ||
} | ||
// Ensure that encrypt and decrypt functions are both presents | ||
if (curr[key].encrypt && curr[key].decrypt) { | ||
if ( | ||
typeof curr[key].encrypt === 'function' && | ||
typeof curr[key].decrypt === 'function' | ||
) { | ||
decrypt = curr[key].decrypt; | ||
} else { | ||
console.error( | ||
`Either encrypt or decrypt is not a function on '${ | ||
curr[key] | ||
}' key object.` | ||
); | ||
} | ||
} else if (curr[key].encrypt || curr[key].decrypt) { | ||
// Let know that one of the encryption functions is not provided | ||
console.error( | ||
`Either encrypt or decrypt function is not present on '${ | ||
curr[key] | ||
}' key object.` | ||
); | ||
} | ||
} | ||
let stateSlice = storage.getItem(storageKeySerializer(key)); | ||
if (stateSlice) { | ||
// Use provided decrypt function | ||
if (decrypt) { | ||
stateSlice = decrypt(stateSlice); | ||
} | ||
let stateSlice = storage.getItem(storageKeySerializer(key)); | ||
if (stateSlice) { | ||
// Use provided decrypt function | ||
if (decrypt) { | ||
stateSlice = decrypt(stateSlice); | ||
} | ||
const isObjectRegex = new RegExp('\{|\\['); | ||
let raw = stateSlice; | ||
const isObjectRegex = new RegExp('{|\\['); | ||
let raw = stateSlice; | ||
if (isObjectRegex.test(stateSlice.charAt(0))) { | ||
raw = JSON.parse(stateSlice, reviver); | ||
} | ||
if (isObjectRegex.test(stateSlice.charAt(0))) { | ||
raw = JSON.parse(stateSlice, reviver); | ||
} | ||
return Object.assign({}, acc, { [key]: deserialize ? deserialize(raw) : raw }); | ||
} | ||
return acc; | ||
}, {}); | ||
return Object.assign({}, acc, { | ||
[key]: deserialize ? deserialize(raw) : raw | ||
}); | ||
} | ||
return acc; | ||
}, {}); | ||
}; | ||
export const syncStateUpdate = (state: any, keys: any[], storage: Storage, storageKeySerializer: (key: string) => string, removeOnUndefined: boolean) => { | ||
keys.forEach(key => { | ||
export const syncStateUpdate = ( | ||
state: any, | ||
keys: any[], | ||
storage: Storage, | ||
storageKeySerializer: (key: string) => string, | ||
removeOnUndefined: boolean | ||
) => { | ||
keys.forEach(key => { | ||
let stateSlice = state[key]; | ||
let replacer = undefined; | ||
let space = undefined; | ||
let encrypt = undefined; | ||
let stateSlice = state[key]; | ||
let replacer = undefined; | ||
let space = undefined; | ||
let encrypt = undefined; | ||
if (typeof key === 'object') { | ||
let name = Object.keys(key)[0]; | ||
stateSlice = state[name]; | ||
if (typeof key === 'object') { | ||
let name = Object.keys(key)[0]; | ||
stateSlice = state[name]; | ||
if (typeof stateSlice !== 'undefined' && key[name]) { | ||
// use serialize function if specified. | ||
if (key[name].serialize) { | ||
stateSlice = key[name].serialize(stateSlice); | ||
} else { | ||
// if serialize function is not specified filter on fields if an array has been provided. | ||
let filter = undefined; | ||
if (key[name].reduce) { | ||
filter = key[name]; | ||
} else if (key[name].filter) { | ||
filter = key[name].filter; | ||
} | ||
if (filter) { | ||
stateSlice = filter.reduce((memo, attr) => { | ||
memo[attr] = stateSlice[attr]; | ||
return memo; | ||
}, {}); | ||
} | ||
if (typeof (stateSlice) !== 'undefined' && key[name]) { | ||
// use serialize function if specified. | ||
if (key[name].serialize) { | ||
stateSlice = key[name].serialize(stateSlice); | ||
} | ||
// if serialize function is not specified filter on fields if an array has been provided. | ||
else { | ||
let filter = undefined; | ||
if (key[name].reduce) { | ||
filter = key[name]; | ||
} | ||
else if (key[name].filter) { | ||
filter = key[name].filter; | ||
} | ||
if (filter) { | ||
stateSlice = filter.reduce((memo, attr) => { | ||
memo[attr] = stateSlice[attr]; | ||
return memo; | ||
}, {}); | ||
} | ||
// Check if encrypt and decrypt are present, also checked at this#rehydrateApplicationState() | ||
if (key[name].encrypt && key[name].decrypt) { | ||
if (typeof key[name].encrypt === 'function') { | ||
encrypt = key[name].encrypt; | ||
} | ||
} else if (key[name].encrypt || key[name].decrypt) { | ||
// If one of those is not present, then let know that one is missing | ||
console.error( | ||
`Either encrypt or decrypt function is not present on '${ | ||
key[name] | ||
}' key object.` | ||
); | ||
} | ||
} | ||
// Check if encrypt and decrypt are present, also checked at this#rehydrateApplicationState() | ||
if (key[name].encrypt && key[name].decrypt) { | ||
if (typeof (key[name].encrypt) === 'function') { | ||
encrypt = key[name].encrypt; | ||
} | ||
} else if (key[name].encrypt || key[name].decrypt) { | ||
// If one of those is not present, then let know that one is missing | ||
console.error(`Either encrypt or decrypt function is not present on '${key[name]}' key object.`); | ||
} | ||
} | ||
/* | ||
/* | ||
Replacer and space arguments to pass to JSON.stringify. | ||
If these fields don't exist, undefined will be passed. | ||
*/ | ||
replacer = key[name].replacer; | ||
space = key[name].space; | ||
} | ||
replacer = key[name].replacer; | ||
space = key[name].space; | ||
} | ||
key = name; | ||
} | ||
key = name; | ||
} | ||
if (typeof (stateSlice) !== 'undefined') { | ||
try { | ||
if (encrypt) { | ||
// ensure that a string message is passed | ||
stateSlice = encrypt(typeof stateSlice === 'string' ? stateSlice : JSON.stringify(stateSlice, replacer, space)); | ||
} | ||
storage.setItem(storageKeySerializer(key), typeof stateSlice === 'string' ? stateSlice : JSON.stringify(stateSlice, replacer, space)); | ||
} catch (e) { | ||
console.warn('Unable to save state to localStorage:', e); | ||
} | ||
} else if (typeof (stateSlice) === 'undefined' && removeOnUndefined) { | ||
try { | ||
storage.removeItem(storageKeySerializer(key)); | ||
} catch (e) { | ||
console.warn(`Exception on removing/cleaning undefined '${key}' state`, e); | ||
} | ||
if (typeof stateSlice !== 'undefined') { | ||
try { | ||
if (encrypt) { | ||
// ensure that a string message is passed | ||
stateSlice = encrypt( | ||
typeof stateSlice === 'string' | ||
? stateSlice | ||
: JSON.stringify(stateSlice, replacer, space) | ||
); | ||
} | ||
}); | ||
storage.setItem( | ||
storageKeySerializer(key), | ||
typeof stateSlice === 'string' | ||
? stateSlice | ||
: JSON.stringify(stateSlice, replacer, space) | ||
); | ||
} catch (e) { | ||
console.warn('Unable to save state to localStorage:', e); | ||
} | ||
} else if (typeof stateSlice === 'undefined' && removeOnUndefined) { | ||
try { | ||
storage.removeItem(storageKeySerializer(key)); | ||
} catch (e) { | ||
console.warn( | ||
`Exception on removing/cleaning undefined '${key}' state`, | ||
e | ||
); | ||
} | ||
} | ||
}); | ||
}; | ||
export const localStorageSync = (config: LocalStorageConfig) => (reducer: any) => { | ||
export const localStorageSync = (config: LocalStorageConfig) => ( | ||
reducer: any | ||
) => { | ||
if (config.storage === undefined) { | ||
config.storage = localStorage || window.localStorage; | ||
} | ||
if (config.storage === undefined) { | ||
config.storage = localStorage || window.localStorage; | ||
} | ||
if (config.storageKeySerializer === undefined) { | ||
config.storageKeySerializer = key => key; | ||
} | ||
if (config.storageKeySerializer === undefined) { | ||
config.storageKeySerializer = (key) => key; | ||
} | ||
if (config.restoreDates === undefined) { | ||
config.restoreDates = true; | ||
} | ||
const stateKeys = validateStateKeys(config.keys); | ||
const rehydratedState = config.rehydrate ? rehydrateApplicationState(stateKeys, config.storage, config.storageKeySerializer) : undefined; | ||
const stateKeys = validateStateKeys(config.keys); | ||
const rehydratedState = config.rehydrate | ||
? rehydrateApplicationState( | ||
stateKeys, | ||
config.storage, | ||
config.storageKeySerializer, | ||
config.restoreDates | ||
) | ||
: undefined; | ||
return function (state = rehydratedState, action: any) { | ||
/* | ||
return function(state = rehydratedState, action: any) { | ||
/* | ||
Handle case where state is rehydrated AND initial state is supplied. | ||
Any additional state supplied will override rehydrated state for the given key. | ||
*/ | ||
if (action.type === INIT_ACTION && rehydratedState) { | ||
state = Object.assign({}, state, rehydratedState); | ||
} | ||
const nextState = reducer(state, action); | ||
syncStateUpdate(nextState, stateKeys, config.storage, config.storageKeySerializer, config.removeOnUndefined); | ||
return nextState; | ||
}; | ||
if (action.type === INIT_ACTION && rehydratedState) { | ||
state = Object.assign({}, state, rehydratedState); | ||
} | ||
const nextState = reducer(state, action); | ||
syncStateUpdate( | ||
nextState, | ||
stateKeys, | ||
config.storage, | ||
config.storageKeySerializer, | ||
config.removeOnUndefined | ||
); | ||
return nextState; | ||
}; | ||
}; | ||
@@ -197,20 +253,24 @@ | ||
*/ | ||
export const localStorageSyncAndClean = (keys: any[], rehydrate: boolean = false, removeOnUndefined: boolean = false) => (reducer: any) => { | ||
export const localStorageSyncAndClean = ( | ||
keys: any[], | ||
rehydrate: boolean = false, | ||
removeOnUndefined: boolean = false | ||
) => (reducer: any) => { | ||
let config: LocalStorageConfig = { | ||
keys: keys, | ||
rehydrate: rehydrate, | ||
storage: localStorage, | ||
removeOnUndefined: removeOnUndefined | ||
}; | ||
let config: LocalStorageConfig = { | ||
keys: keys, | ||
rehydrate: rehydrate, | ||
storage: localStorage, | ||
removeOnUndefined: removeOnUndefined | ||
}; | ||
return this.localStorageSync(config); | ||
return this.localStorageSync(config); | ||
}; | ||
export interface LocalStorageConfig { | ||
keys: any[]; | ||
rehydrate?: boolean; | ||
storage?: Storage; | ||
removeOnUndefined?: boolean; | ||
storageKeySerializer?: (key: string) => string; | ||
keys: any[]; | ||
rehydrate?: boolean; | ||
storage?: Storage; | ||
removeOnUndefined?: boolean; | ||
restoreDates?: boolean; | ||
storageKeySerializer?: (key: string) => string; | ||
} |
Sorry, the diff of this file is not supported yet
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
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
53217
861
113