autoMergeLevel2.js.flow 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // @flow
  2. /*
  3. autoMergeLevel2:
  4. - merges 2 level of substate
  5. - skips substate if already modified
  6. - this is essentially redux-perist v4 behavior
  7. */
  8. import type { PersistConfig } from '../types'
  9. export default function autoMergeLevel2<State: Object>(
  10. inboundState: State,
  11. originalState: State,
  12. reducedState: State,
  13. { debug }: PersistConfig
  14. ): State {
  15. let newState = { ...reducedState }
  16. // only rehydrate if inboundState exists and is an object
  17. if (inboundState && typeof inboundState === 'object') {
  18. Object.keys(inboundState).forEach(key => {
  19. // ignore _persist data
  20. if (key === '_persist') return
  21. // if reducer modifies substate, skip auto rehydration
  22. if (originalState[key] !== reducedState[key]) {
  23. if (process.env.NODE_ENV !== 'production' && debug)
  24. console.log(
  25. 'redux-persist/stateReconciler: sub state for key `%s` modified, skipping.',
  26. key
  27. )
  28. return
  29. }
  30. if (isPlainEnoughObject(reducedState[key])) {
  31. // if object is plain enough shallow merge the new values (hence "Level2")
  32. newState[key] = { ...newState[key], ...inboundState[key] }
  33. return
  34. }
  35. // otherwise hard set
  36. newState[key] = inboundState[key]
  37. })
  38. }
  39. if (
  40. process.env.NODE_ENV !== 'production' &&
  41. debug &&
  42. inboundState &&
  43. typeof inboundState === 'object'
  44. )
  45. console.log(
  46. `redux-persist/stateReconciler: rehydrated keys '${Object.keys(
  47. inboundState
  48. ).join(', ')}'`
  49. )
  50. return newState
  51. }
  52. function isPlainEnoughObject(o) {
  53. return o !== null && !Array.isArray(o) && typeof o === 'object'
  54. }