[
  {
    "path": ".babelrc.js",
    "content": "/**\n * Babel Configuration\n */\n module.exports = {\n  presets: [\n    [\n      \"@babel/preset-env\"\n    ],\n  ],\n}\n"
  },
  {
    "path": ".eslintrc.yml",
    "content": "---\n\nparser: '@typescript-eslint/parser'\n\nglobals:\n  it: true\n  expect: true\n  describe: true\n  test: true\n  jest: true\n\nplugins:\n- '@typescript-eslint'\n\nextends:\n- eslint:recommended\n- plugin:@typescript-eslint/recommended\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: redux-persist ci\non: [push, pull_request]\n\njobs:\n  # Label of the container job\n  container-job:\n    # Containers must run in Linux based operating systems\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version: [14.x, 16.x]\n    \n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v1\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: npm install\n        run: |\n          npm install\n      - name: run test\n        run: |\n          npm run test\n"
  },
  {
    "path": ".gitignore",
    "content": "es\nlib\ndist\ntypes\n.watchmanconfig\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\n\n# Dependency directories\nnode_modules\n\n# Optional npm cache directory\n.npm\n\n# Optional REPL history\n.node_repl_history\n\n.DS_Store\n"
  },
  {
    "path": ".prettierrc",
    "content": "parser: \"typescript\"\nsemi: false\ntrailingComma: es5\nsingleQuote: true\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\nAll notable changes to this project (after v6.1.0) should be documented in this file.\n\nThe format is (mostly) based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n\n## [6.1.0] - 2021-10-17\nThanks to [@smellman](https://github.com/smellman) for the TypeScript updates.\n\n### Added\n- TypeScript support\n- GitHub Actions\n\n### Changed\n- Move from Flow to TypeScript\n- Move from TravisCI to GitHub Actions ([.github/workflows/ci.yml](.github/workflows/ci.yml))\n- Version updates for some dependencies\n\n### Removed\n- Flow\n- TravisCI\n"
  },
  {
    "path": "LIBSIZE.md",
    "content": "### Redux Persist Size Estimate\nThe following is a history of size estimates in bytes. This is calculated as a rollup minified production build, excluding the size of redux which is an assumed peer dependency. YMMV.\n\n**v5.6.7**: 4724 Bytes  \n**v5.6.8**: 4724 Bytes  \n**v5.6.9**: 4724 Bytes  \n**v5.6.10**: 4724 Bytes  \n**v5.6.11**: 4724 Bytes  \n**v5.6.12**: 4724 Bytes  \n**v5.7.0**: 4893 Bytes  \n**v5.7.1**: 4894 Bytes  \n**v5.7.2**: 4894 Bytes  \n**v5.8.0**: 4894 Bytes  \n**v5.9.0**: 4894 Bytes  \n**v5.9.1**: 4894 Bytes  \n**v5.10.0**: 4356 Bytes  \n**v6.0.0-pre1**: 17783 Bytes  \n**v6.0.0-pre2**: 11878 Bytes  \n**v6.0.0-pre2.0**: 11934 Bytes  \n**v6.0.0-pre2.1**: 5525 Bytes  \n**v6.0.0**: 12167 Bytes  \n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Zack Story\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Redux Persist\nPersist and rehydrate a redux store.\n\n[![build status](https://img.shields.io/travis/rt2zz/redux-persist/master.svg?style=flat-square)](https://travis-ci.org/rt2zz/redux-persist) [![npm version](https://img.shields.io/npm/v/redux-persist.svg?style=flat-square)](https://www.npmjs.com/package/redux-persist) [![npm downloads](https://img.shields.io/npm/dm/redux-persist.svg?style=flat-square)](https://www.npmjs.com/package/redux-persist)\n\n## October 15th, 2021 - Move to TypeScript (Thanks [@smellman](https://github.com/smellman))\n\nAs part of the work to upgrade the infrastructure used to build redux-persist, we're moving from Flow to TypeScript.\n\n- Move from Flow to TypeScript\n- Move from TravisCI to GitHub Actions ([.github/workflows/ci.yml](.github/workflows/ci.yml))\n- Version updates for some dependencies\n\n## September 22nd, 2021 - Under New Management\n\nRedux Persist is a staple project for Redux developers, both on mobile and on the web. If you're here, it's likely because you need it now or have used it before and need to debug something, and like me have possibly struggled with making it work (especially with newer versions of things) and making it work with _your_ code because the examples you'll find around the internet are inconsistent.\n\nI ([@ckalika](https://github.com/ckalika)) spoke with [@rt2zz](https://github.com/rt2zz) about taking over maintenance of the project, and we agreed to give it a shot and see how we go. My priorities are as follows:\n\n1. Go through and triage the existing issues\n    - Separate them into bugs, feature requests, basic questions/requests for code samples, and issues that are either not project-specific or don't fall within the remit of the project (specific definitions and criteria will be posted in the future)\n    - Determine the severity/urgency of each bug or feature request\n    - Guestimate the size of them\n    - Determine which are actionable immediately or in the short term\n    - Establish some semblance of test criteria for each\n\n\n2. Upgrade dependencies (where possible) so that we've got something building with modern versions\n    * Note:  Right now, it's about modernising the project infrastructure and build process without making breaking API changes\n\n\n3. Go through the existing pull requests\n    - Merge the ones that deal with documentation, code samples, etc.\n    - Review and merge the ones that deal with open issues\n    - Review and merge the ones that will require breaking changes and consult authors about `redux-persist@v7` (feature set and requirements to be defined)\n\n\n4. Update the documentation\n    - Split it out for both web and mobile\n    - Providing code samples and test coverage for how to use the library\n    - Provide or link to working examples that integrate with additional libraries (e.g. [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)).\n\n\n5. Improve testing and automation\n    - [x] Move to GitHub Actions\n    - [ ] Move from Ava to Jest\n\nThere's a lot to do here, so I'll ask your patience and understanding as I work through it. If you have ideas for how to improve the library, the documentation, or the community, I'd love to hear them, and if you're submitting pull requests (or have submitted some previously), please reach out and help me understand what you're aiming to do with it.\n\nI'll try to get some discussions up to pull together ideas, so we can properly work out what the next version is likely to look like.\n\n\n## v6 upgrade\n**Web**: no breaking changes\n**React Native**: Users must now explicitly pass their storage engine in. e.g.\n```js\nimport AsyncStorage from '@react-native-async-storage/async-storage';\n\nconst persistConfig = {\n  //...\n  storage: AsyncStorage\n}\n```\n\n## Quickstart\n`npm install redux-persist`\n\nUsage Examples:\n1. [Basic Usage](#basic-usage)\n2. [Nested Persists](#nested-persists)\n3. [Hot Module Replacement](./docs/hot-module-replacement.md)\n4. Code Splitting [coming soon]\n\n#### Basic Usage\nBasic usage involves adding `persistReducer` and `persistStore` to your setup. **IMPORTANT** Every app needs to decide how many levels of state they want to \"merge\". The default is 1 level. Please read through the [state reconciler docs](#state-reconciler) for more information.\n\n```js\n// configureStore.js\n\nimport { createStore } from 'redux'\nimport { persistStore, persistReducer } from 'redux-persist'\nimport storage from 'redux-persist/lib/storage' // defaults to localStorage for web\n\nimport rootReducer from './reducers'\n\nconst persistConfig = {\n  key: 'root',\n  storage,\n}\n\nconst persistedReducer = persistReducer(persistConfig, rootReducer)\n\nexport default () => {\n  let store = createStore(persistedReducer)\n  let persistor = persistStore(store)\n  return { store, persistor }\n}\n```\n\nIf you are using react, wrap your root component with [PersistGate](./docs/PersistGate.md). This delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux. **NOTE** the `PersistGate` loading prop can be null, or any react instance, e.g. `loading={<Loading />}`\n\n```js\nimport { PersistGate } from 'redux-persist/integration/react'\n\n// ... normal setup, create store and persistor, import components etc.\n\nconst App = () => {\n  return (\n    <Provider store={store}>\n      <PersistGate loading={null} persistor={persistor}>\n        <RootComponent />\n      </PersistGate>\n    </Provider>\n  );\n};\n```\n\n## API\n[Full API](./docs/api.md)\n\n#### `persistReducer(config, reducer)`\n  - arguments\n    - [**config**](https://github.com/rt2zz/redux-persist/blob/master/src/types.js#L13-L27) *object*\n      - required config: `key, storage`\n      - notable other config: `whitelist, blacklist, version, stateReconciler, debug`\n    - **reducer** *function*\n      - any reducer will work, typically this would be the top level reducer returned by `combineReducers`\n  - returns an enhanced reducer\n\n#### `persistStore(store, [config, callback])`\n  - arguments\n    - **store** *redux store* The store to be persisted.\n    - **config** *object* (typically null)\n      - If you want to avoid that the persistence starts immediately after calling `persistStore`, set the option manualPersist. Example: `{ manualPersist: true }` Persistence can then be started at any point with `persistor.persist()`. You usually want to do this if your storage is not ready when the `persistStore` call is made.\n    - **callback** *function* will be called after rehydration is finished.\n  - returns **persistor** object\n\n#### `persistor object`\n  - the persistor object is returned by persistStore with the following methods:\n    - `.purge()`\n      - purges state from disk and returns a promise\n    - `.flush()`\n      - immediately writes all pending state to disk and returns a promise\n    - `.pause()`\n      - pauses persistence\n    - `.persist()`\n      - resumes persistence\n\n## State Reconciler\nState reconcilers define how incoming state is merged in with initial state. It is critical to choose the right state reconciler for your state. There are three options that ship out of the box, let's look at how each operates:\n\n1. **hardSet** (`import hardSet from 'redux-persist/lib/stateReconciler/hardSet'`)\nThis will hard set incoming state. This can be desirable in some cases where persistReducer is nested deeper in your reducer tree, or if you do not rely on initialState in your reducer.\n   - **incoming state**: `{ foo: incomingFoo }`\n   - **initial state**: `{ foo: initialFoo, bar: initialBar }`\n   - **reconciled state**: `{ foo: incomingFoo }` // note bar has been dropped\n2. **autoMergeLevel1** (default)\nThis will auto merge one level deep. Auto merge means if the some piece of substate was modified by your reducer during the REHYDRATE action, it will skip this piece of state. Level 1 means it will shallow merge 1 level deep.\n   - **incoming state**: `{ foo: incomingFoo }`\n   - **initial state**: `{ foo: initialFoo, bar: initialBar }`\n   - **reconciled state**: `{ foo: incomingFoo, bar: initialBar }` // note incomingFoo overwrites initialFoo\n3. **autoMergeLevel2** (`import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2'`)\nThis acts just like autoMergeLevel1, except it shallow merges two levels\n   - **incoming state**: `{ foo: incomingFoo }`\n   - **initial state**: `{ foo: initialFoo, bar: initialBar }`\n   - **reconciled state**: `{ foo: mergedFoo, bar: initialBar }` // note: initialFoo and incomingFoo are shallow merged\n\n#### Example\n```js\nimport hardSet from 'redux-persist/lib/stateReconciler/hardSet'\n\nconst persistConfig = {\n  key: 'root',\n  storage,\n  stateReconciler: hardSet,\n}\n```\n\n## React Integration\nRedux persist ships with react integration as a convenience. The `PersistGate` component is the recommended way to delay rendering until persistence is complete. It works in one of two modes:\n1. `loading` prop: The provided loading value will be rendered until persistence is complete at which point children will be rendered.\n2. function children: The function will be invoked with a single `bootstrapped` argument. When bootstrapped is true, persistence is complete and it is safe to render the full app. This can be useful for adding transition animations.\n\n## Blacklist & Whitelist\nBy Example:\n```js\n// BLACKLIST\nconst persistConfig = {\n  key: 'root',\n  storage: storage,\n  blacklist: ['navigation'] // navigation will not be persisted\n};\n\n// WHITELIST\nconst persistConfig = {\n  key: 'root',\n  storage: storage,\n  whitelist: ['navigation'] // only navigation will be persisted\n};\n```\n\n## Nested Persists\nNested persist can be useful for including different storage adapters, code splitting, or deep filtering. For example while blacklist and whitelist only work one level deep, but we can use a nested persist to blacklist a deeper value:\n```js\nimport { combineReducers } from 'redux'\nimport { persistReducer } from 'redux-persist'\nimport storage from 'redux-persist/lib/storage'\n\nimport { authReducer, otherReducer } from './reducers'\n\nconst rootPersistConfig = {\n  key: 'root',\n  storage: storage,\n  blacklist: ['auth']\n}\n\nconst authPersistConfig = {\n  key: 'auth',\n  storage: storage,\n  blacklist: ['somethingTemporary']\n}\n\nconst rootReducer = combineReducers({\n  auth: persistReducer(authPersistConfig, authReducer),\n  other: otherReducer,\n})\n\nexport default persistReducer(rootPersistConfig, rootReducer)\n```\n\n## Migrations\n`persistReducer` has a general purpose \"migrate\" config which will be called after getting stored state but before actually reconciling with the reducer. It can be any function which takes state as an argument and returns a promise to return a new state object.\n\nRedux Persist ships with `createMigrate`, which helps create a synchronous migration for moving from any version of stored state to the current state version. [[Additional information]](./docs/migrations.md)\n\n## Transforms\nTransforms allow you to customize the state object that gets persisted and rehydrated.\n\nThere are several libraries that tackle some common implementations for transforms.\n- [immutable](https://github.com/rt2zz/redux-persist-transform-immutable) - support immutable reducers\n- [seamless-immutable](https://github.com/hilkeheremans/redux-persist-seamless-immutable) - support seamless-immutable reducers\n- [compress](https://github.com/rt2zz/redux-persist-transform-compress) - compress your serialized state with lz-string\n- [encrypt](https://github.com/maxdeviant/redux-persist-transform-encrypt) - encrypt your serialized state with AES\n- [filter](https://github.com/edy/redux-persist-transform-filter) - store or load a subset of your state\n- [filter-immutable](https://github.com/actra-development/redux-persist-transform-filter-immutable) - store or load a subset of your state with support for immutablejs\n- [expire](https://github.com/gabceb/redux-persist-transform-expire) - expire a specific subset of your state based on a property\n- [expire-reducer](https://github.com/kamranahmedse/redux-persist-expire) - more flexible alternative to expire transformer above with more options\n\nWhen the state object gets persisted, it first gets serialized with `JSON.stringify()`. If parts of your state object are not mappable to JSON objects, the serialization process may transform these parts of your state in unexpected ways. For example, the javascript [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) type does not exist in JSON. When you try to serialize a Set via `JSON.stringify()`, it gets converted to an empty object. Probably not what you want.\n\nBelow is a Transform that successfully persists a Set property, which simply converts it to an array and back. In this way, the Set gets converted to an Array, which is a recognized data structure in JSON. When pulled out of the persisted store, the array gets converted back to a Set before being saved to the redux store.\n\n```js\nimport { createTransform } from 'redux-persist';\n\nconst SetTransform = createTransform(\n  // transform state on its way to being serialized and persisted.\n  (inboundState, key) => {\n    // convert mySet to an Array.\n    return { ...inboundState, mySet: [...inboundState.mySet] };\n  },\n  // transform state being rehydrated\n  (outboundState, key) => {\n    // convert mySet back to a Set.\n    return { ...outboundState, mySet: new Set(outboundState.mySet) };\n  },\n  // define which reducers this transform gets called for.\n  { whitelist: ['someReducer'] }\n);\n\nexport default SetTransform;\n```\n\nThe `createTransform` function takes three parameters.\n1. An \"inbound\" function that gets called right before state is persisted (optional).\n2. An \"outbound\" function that gets called right before state is rehydrated (optional).\n3. A config object that determines which keys in your state will be transformed (by default no keys are transformed).\n\nIn order to take effect transforms need to be added to a `PersistReducer`’s config object.\n\n```\nimport storage from 'redux-persist/lib/storage';\nimport { SetTransform } from './transforms';\n\nconst persistConfig = {\n  key: 'root',\n  storage: storage,\n  transforms: [SetTransform]\n};\n```\n\n## Storage Engines\n- **localStorage** `import storage from 'redux-persist/lib/storage'`\n- **sessionStorage** `import storageSession from 'redux-persist/lib/storage/session'`\n- **[electron storage](https://github.com/psperber/redux-persist-electron-storage)** Electron support via [electron store](https://github.com/sindresorhus/electron-store)\n- **[redux-persist-cookie-storage](https://github.com/abersager/redux-persist-cookie-storage)** Cookie storage engine, works in browser and Node.js, for universal / isomorphic apps\n- **[redux-persist-expo-filesystem](https://github.com/t73liu/redux-persist-expo-filesystem)** react-native, similar to redux-persist-filesystem-storage but does not require linking or ejecting CRNA/Expo app. Only available if using Expo SDK (Expo, create-react-native-app, standalone).\n- **[redux-persist-expo-securestore](https://github.com/Cretezy/redux-persist-expo-securestore)** react-native, for sensitive information using Expo's SecureStore. Only available if using Expo SDK (Expo, create-react-native-app, standalone).\n- **[redux-persist-fs-storage](https://github.com/leethree/redux-persist-fs-storage)** react-native-fs engine\n- **[redux-persist-filesystem-storage](https://github.com/robwalkerco/redux-persist-filesystem-storage)** react-native, to mitigate storage size limitations in android ([#199](https://github.com/rt2zz/redux-persist/issues/199), [#284](https://github.com/rt2zz/redux-persist/issues/284))\n  **[redux-persist-indexeddb-storage](https://github.com/machester4/redux-persist-indexeddb-storage)** recommended for web via [localForage](https://github.com/localForage/localForage)\n- **[redux-persist-node-storage](https://github.com/pellejacobs/redux-persist-node-storage)** for use in nodejs environments.\n- **[redux-persist-pouchdb](https://github.com/yanick/redux-persist-pouchdb)** Storage engine for PouchDB.\n- **[redux-persist-sensitive-storage](https://github.com/CodingZeal/redux-persist-sensitive-storage)** react-native, for sensitive information (uses [react-native-sensitive-info](https://github.com/mCodex/react-native-sensitive-info)).\n- **[redux-persist-weapp-storage](https://github.com/cuijiemmx/redux-casa/tree/master/packages/redux-persist-weapp-storage)** Storage engine for wechat mini program, also compatible with wepy\n- **[redux-persist-webextension-storage](https://github.com/ssorallen/redux-persist-webextension-storage)** Storage engine for browser (Chrome, Firefox) web extension storage\n- **[@bankify/redux-persist-realm](https://github.com/bankifyio/redux-persist-realm)** Storage engine for Realm database, you will need to install Realm first\n- **custom** any conforming storage api implementing the following methods: `setItem` `getItem` `removeItem`. (**NB**: These methods must support promises)\n\n## Community & Contributing\n\nI will be updating this section shortly. If you have a pull request that you've got outstanding, please reach out and I will try to review it and get it integrated. As we've shifted to TypeScript, that may necessitate some changes, but I'm happy to help in that regard, wherever I can.\n"
  },
  {
    "path": "docs/MigrationGuide-v5.md",
    "content": "## v5 Breaking Changes\nThere are three important breaking changes.\n1. api has changed as described in the [migration](#migration-from-v4-to-v5) section below.\n2. state with cycles is no longer serialized using `json-stringify-safe`, and will instead noop.\n3. state methods can no longer be overridden which means all top level state needs to be plain objects. `redux-persist-transform-immutable` will continue to operate as before as it works on substate, not top level state.\n\nAdditionally v5 does not yet have typescript bindings.\n\n## Migration from v4 to v5\n**WARNING** v4 stored state is not compatible with v5. If you upgrade a v4 application, your users will lose their stored state upon upgrade. You can try the (highly) experimental [v4 -> v5 state migration](#experimental-v4-to-v5-state-migration) if you please. Feedback appreciated.\n\nStandard Usage:\n- remove **autoRehydrate**\n- changes to **persistStore**:\n  - 1. remove config argument (or replace with an null if you are using a callback)\n  - 2. remove all arguments from the callback. If you need state you can call `store.getState()`\n  - 3. all constants (ex: `REHYDRATE`, `PURGE`) has moved from `redux-persist/constants` to the root module.\n- replace `combineReducers` with **persistCombineReducers**\n  - e.g. `let reducer = persistCombineReducers(config, reducers)`\n- changes to **config**:\n  - `key` is now required. Can be set to anything, e.g. 'primary'\n  - `storage` is now required. For default storage: `import storage from 'redux-persist/lib/storage'`\n\n```diff\n-import { REHYDRATE, PURGE } from 'redux-persist/constants'\n-import { combineReducers } from 'redux'\n+import { REHYDRATE, PURGE, persistCombineReducers } from 'redux-persist'\n+import storage from 'redux-persist/lib/storage' // or whatever storage you are using\n\n const config = {\n+  key: 'primary',\n+  storage\n }\n\n-let reducer = combineReducers(reducers)\n+let reducer = persistCombineReducers(config, reducers)\n\n const store = createStore(\n   reducer,\n   undefined,\n   compose(\n     applyMiddleware(...),\n-    autoRehydrate()\n   )\n )\n\n const callback = ()\n\n persistStore(\n   store,\n-  config,\n+  null,\n   (\n-     err, restoredState\n   ) => {\n+     store.getState() // if you want to get restoredState\n   }\n )\n```\n\nRecommended Additions\n- use new **PersistGate** to delay rendering until rehydration is complete\n  - `import { PersistGate } from 'redux-persist/lib/integration/react'`\n- set `config.debug = true` to get useful logging\n\nIf your implementation uses getStoredState + createPersistor see [alternate migration](./v5-migration-alternate.md)\n\n## Why v5\nLong story short, the changes are required in order to support new use cases\n- code splitting reducers\n- easier to ship persist support inside of other libs (e.g. redux-offline)\n- ability to colocate persistence rules with the reducer it pertains to\n- first class migration support\n- enable PersistGate react component which blocks rendering until persistence is complete (and enables similar patterns for integration)\n- possible to nest persistence\n- guarantee consistent state atoms\n- better debugability and extensibility\n\n## Experimental v4 to v5 State Migration\n- **warning: this method is completely untested**\n- v5 getStoredState is not compatible with v4, so by default v5 will cause all of the persisted state from v4 to disappear on first run\n- v5 ships with an experimental v4 -> v5 migration that works by overriding the default getStoredState implementation\n**Warning** this is completely untested, please try and report back with any issues.\n```js\nimport getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigrateV4'\n// ...\npersistReducer({\n  // ...\n  getStoredState: getStoredStateMigrateV4(yourOldV4Config)\n}, baseReducer)\n```\n"
  },
  {
    "path": "docs/PersistGate.md",
    "content": "`PersistGate` delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux.\n\n**NOTE**: the `loading` prop can be `null` or any react instance to show during loading (e.g. a splash screen), for example `loading={<Loading />}`.\n\nExample usage:\n\n```js\nimport { PersistGate } from 'redux-persist/es/integration/react'\n\nimport configureStore from './store/configureStore'\n\nconst { persistor, store } = configureStore()\n\nconst onBeforeLift = () => {\n  // take some action before the gate lifts\n}\n\nexport default () => (\n  <Provider store={store}>\n    <PersistGate \n      loading={<Loading />}\n      onBeforeLift={onBeforeLift}\n      persistor={persistor}>\n      <App />\n    </PersistGate>\n  </Provider>\n)\n```\n"
  },
  {
    "path": "docs/api.md",
    "content": "# Redux Persist API\n---\n## Standard API\n- [persistReducer](#persistreducerconfig-reducer)([config](#type-persistconfig), reducer)\n- [persistStore](#persiststorestore-config-callback)(store)\n- [createMigrate](#createmigratemigrations-config)([migrations](#type-migrationmanifest))\n### `persistReducer(config, reducer)`\n\n```js\npersistReducer(\n  config: PersistConfig,\n  reducer: Reducer,\n): Reducer\n```\n\nWhere Reducer is any reducer `(state, action) => state` and PersistConfig is [defined below](#type-persistconfig)\n\n### `persistStore(store, config, callback)`\n```js\npersistStore(\n  store: Store,\n  config?: { enhancer?: Function },\n  callback?: () => {}\n): Persistor\n```\n\nWhere Persistor is [defined below](#type-persistor)\n\n### `createMigrate(migrations, config)`\n```js\ncreateMigrate(\n  migrations: MigrationManifest,\n  config?: { debug: boolean }\n)\n```\n\n### `type Persistor`\n```js\n{\n  purge: () => Promise<void>,\n  flush: () => Promise<void>,\n}\n```\n\nThe Persistor is a redux store unto itself, plus\n1. the `purge()` method for clearing out stored state.\n2. the `flush()` method for flushing all pending state serialization and immediately write to disk\n\n`purge()` method only clear the content of the storage, leaving the internal data of `redux` untouched. To clean it instead, you can use the [redux-reset](https://github.com/wwayne/redux-reset) module.\n\n### `type PersistConfig`\n```js\n{\n  key: string, // the key for the persist\n  storage: Object, // the storage adapter, following the AsyncStorage api\n  version?: number, // the state version as an integer (defaults to -1)\n  blacklist?: Array<string>, // do not persist these keys\n  whitelist?: Array<string>, // only persist these keys\n  migrate?: (Object, number) => Promise<Object>,\n  transforms?: Array<Transform>,\n  throttle?: number, // ms to throttle state writes\n  keyPrefix?: string, // will be prefixed to the storage key\n  debug?: boolean, // true -> verbose logs\n  stateReconciler?: false | StateReconciler, // false -> do not automatically reconcile state\n  serialize?: boolean, // false -> do not call JSON.parse & stringify when setting & getting from storage\n  writeFailHandler?: Function, // will be called if the storage engine fails during setItem()\n}\n```\n\nPersisting state involves calling setItem() on the storage engine. By default, this will fail silently if the storage/quota is exhausted.  \nProvide a writeFailHandler(error) function to be notified if this occurs.\n\n### `type MigrationManifest`\n```js\n{\n  [number]: (State) => State\n}\n```\nWhere the keys are state version numbers and the values are migration functions to modify state.\n\n---\n## Expanded API\nThe following methods are used internally by the standard api. They can be accessed directly if more control is needed.\n### `getStoredState(config)`\n```js\ngetStoredState(\n  config: PersistConfig\n): Promise<State>\n```\n\nReturns a promise (if Promise global is defined) of restored state.\n\n### `createPersistoid(config)`\n```js\ncreatePersistoid(\n  config\n): Persistoid\n```\nWhere Persistoid is [defined below](#type-persistoid).\n\n### `type Persistoid`\n```js\n{\n  update: (State) => void\n}\n```\n\n### `type PersistorConfig`\n```js\n{\n  enhancer: Function\n}\n```\nWhere enhancer will be sent verbatim to the redux createStore call used to create the persistor store. This can be useful for example to enable redux devtools on the persistor store.\n\n### `type StateReconciler`\n```js\n(\n  inboundState: State,\n  originalState: State,\n  reducedState: State,\n) => State\n```\nA function which reconciles:\n- **inboundState**: the state being rehydrated from storage\n- **originalState**: the state before the REHYDRATE action\n- **reducedState**: the store state *after* the REHYDRATE action but *before* the reconcilliation\ninto final \"rehydrated\" state.\n"
  },
  {
    "path": "docs/hot-module-replacement.md",
    "content": "## Hot Module Replacement\n\nHot Module Replacement (HMR) is a wonderful feature that is really useful in development environment. This allows you to update the code of your application without reloading the app and resetting the redux state.\n\nThe key modification for using HMR with redux-persist, is the incoming hot reducer needs to be re-persisted via `persistReducer`.\n\n**configureStore.js**\n```js\nimport { persistReducer } from 'redux-persist'\nimport rootReducer from './path/to/reducer'\n\nexport default () => {\n  // create store and persistor per normal...\n\n  if (module.hot) {\n    module.hot.accept('./path/to/reducer', () => {\n      // This fetch the new state of the above reducers.\n      const nextRootReducer = require('./path/to/reducer').default\n      store.replaceReducer(\n        persistReducer(persistConfig, nextRootReducer)\n      )\n    })\n  }\n\n  return { store, persistor }\n}\n```\n"
  },
  {
    "path": "docs/migrations.md",
    "content": "# Redux Persist Migration Example\n\n### Example with createMigrate\n```js\nimport { createMigrate, persistReducer, persistStore } from 'redux-persist'\nimport storage from 'redux-persist/es/storage'\n\nconst migrations = {\n  0: (state) => {\n    // migration clear out device state\n    return {\n      ...state,\n      device: undefined   \n    }\n  },\n  1: (state) => {\n    // migration to keep only device state\n    return {\n      device: state.device\n    }\n  }\n}\n\nconst persistConfig = {\n  key: 'primary',\n  version: 1,\n  storage,\n  migrate: createMigrate(migrations, { debug: false }),\n}\n\nconst finalReducer = persistReducer(persistConfig, reducer)\n\nexport default function configureStore() {\n  let store = createStore(finalReducer)\n  let persistor = persistStore(store)\n  return { store, persistor }\n}\n```\n\n### Alternative\nThe migrate method can be any function with which returns a promise of new state. \n```js\nconst persistConfig = {\n  key: 'primary',\n  version: 1,\n  storage,\n  migrate: (state) => {\n    console.log('Migration Running!')\n    return Promise.resolve(state)\n  }\n}\n"
  },
  {
    "path": "docs/v5-migration-alternate.md",
    "content": "## Alternate Migration\nIf in redux-persist you used getStoredState + createPersistor, the v5 usage is similar with some small modifications. Note: because no `persistor` is created the react integration helper `PersistGate` cannot be used.\n\n1. replace `createPersistor` with `createPersistoid`\n2. update persistoid whenever state changes\n\n```js\nimport { getStoredState } from 'redux-persist/es/getStoredState'\nimport { createPersistoid } from 'redux-persist/es/createPersistoid'\nimport storage from 'redux-persist/es/storages/local'\n\n// ...\n\nconst config = { key: 'root', version: 1, storage }\n\nfunction configureStore () {\n  const initState = await getStoredState(config)\n  // createPersistoid instead of createPersistor\n  let persistoid = createPersistoid(config)\n\n  const store = createStore(reducer, initState)\n \n  // need to hook up the subscription (this used to be done automatically by createPersistor)\n  store.subscribe(() => {\n    persistoid.update(store.getState())\n  })\n}\n```"
  },
  {
    "path": "integration/README.md",
    "content": "Proxy package to enable\n```js\nimport { PersistGate } from 'redux-persist/integration/react'\n```"
  },
  {
    "path": "integration/react/package.json",
    "content": "{\n    \"name\": \"redux-persist/integration/react\",\n    \"private\": true,\n    \"main\": \"../../lib/integration/react\",\n    \"module\": \"../../es/integration/react\",\n    \"jsnext:main\": \"../../es/integration/react\"\n  }\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"redux-persist\",\n  \"version\": \"6.1.0\",\n  \"description\": \"persist and rehydrate redux stores\",\n  \"main\": \"lib/index.js\",\n  \"module\": \"es/index.js\",\n  \"types\": \"lib/index.d.ts\",\n  \"repository\": \"rt2zz/redux-persist\",\n  \"files\": [\n    \"src\",\n    \"es\",\n    \"lib\",\n    \"dist\",\n    \"integration\",\n    \"README.md\"\n  ],\n  \"scripts\": {\n    \"ava\": \"ava\",\n    \"build\": \"npm run build:commonjs && npm run build:es && npm run build:umd\",\n    \"build:commonjs\": \"tsc --module commonjs --outDir lib\",\n    \"build:es\": \"tsc --module es2015 --outDir es\",\n    \"build:umd\": \"rollup -c\",\n    \"clean\": \"rimraf dist && rimraf es && rimraf lib\",\n    \"prepare\": \"npm run build\",\n    \"precommit\": \"lint-staged\",\n    \"stats:size\": \"node ./scripts/size-estimator.js\",\n    \"test\": \"ava\",\n    \"version\": \"npm run clean && npm run build && npm run stats:size | tail -1 >> LIBSIZE.md && git add LIBSIZE.md\"\n  },\n  \"lint-staged\": {\n    \"src/**/*.ts\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/rt2zz/redux-persist#readme\",\n  \"ava\": {\n    \"files\": [\n      \"tests/**/*.spec.ts\"\n    ],\n    \"extensions\": [\n      \"ts\"\n    ],\n    \"require\": [\n      \"ts-node/register\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.15.0\",\n    \"@babel/preset-env\": \"^7.15.0\",\n    \"@rollup/plugin-babel\": \"^5.3.0\",\n    \"@rollup/plugin-commonjs\": \"^20.0.0\",\n    \"@rollup/plugin-node-resolve\": \"^13.0.4\",\n    \"@rollup/plugin-typescript\": \"^8.2.5\",\n    \"@types/react\": \"^17.0.16\",\n    \"@types/redux-mock-store\": \"^1.0.3\",\n    \"@types/sinon\": \"^10.0.2\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.29.0\",\n    \"@typescript-eslint/parser\": \"^4.29.0\",\n    \"ava\": \"^3.15.0\",\n    \"eslint\": \"^7.32.0\",\n    \"eslint-plugin-import\": \"^2.23.4\",\n    \"husky\": \"^7.0.1\",\n    \"lint-staged\": \"^11.1.2\",\n    \"prettier\": \"^2.3.2\",\n    \"redux\": \"^4.1.1\",\n    \"redux-mock-store\": \"^1.5.4\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^2.56.0\",\n    \"rollup-plugin-terser\": \"^7.0.2\",\n    \"sinon\": \"^11.1.2\",\n    \"ts-node\": \"^10.1.0\",\n    \"typescript\": \"^4.3.5\"\n  },\n  \"peerDependencies\": {\n    \"redux\": \">4.0.0\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import pluginNodeResolve from \"@rollup/plugin-node-resolve\"\nimport pluginCommonjs from \"@rollup/plugin-commonjs\"\nimport pluginTypescript from \"@rollup/plugin-typescript\"\nimport { babel as pluginBabel } from \"@rollup/plugin-babel\"\nimport { terser as pluginTerser } from \"rollup-plugin-terser\"\n\nconst moduleName = 'ReduxPersist'\n\nimport * as path from 'path'\n\nimport pkg from \"./package.json\"\n\nconst banner = `/*!\n  ${moduleName}.js v${pkg.version}\n  ${pkg.homepage}\n  Released under the ${pkg.license} License.\n*/`;\n\nconst filePath = 'dist/redux-persist.js'\n\nconst config = [\n  // browser\n  {\n    // entry point\n    input: 'src/index.ts',\n    output: [\n      // no minify\n      {\n        name: moduleName,\n        file: filePath,\n        format: 'umd',\n        sourcemap: true,\n        // copyright\n        banner,\n      },\n      // minify\n      {\n        name: moduleName,\n        file: filePath.replace('.js', '.min.js'),\n        format: 'umd',\n        sourcemap: true,\n        banner,\n        plugins: [\n          pluginTerser(),\n        ],\n      }\n    ],\n    plugins: [\n      pluginTypescript({\n        module: \"esnext\"\n      }),\n      pluginCommonjs({\n        extensions: [\".js\", \".ts\"]\n      }),\n      pluginBabel({\n        babelHelpers: \"bundled\",\n        configFile: path.resolve(__dirname, \".babelrc.js\")\n      }),\n      pluginNodeResolve({\n        browser: true,\n      }),\n    ]\n  },\n];\n\nexport default config\n\n"
  },
  {
    "path": "scripts/size-estimator.js",
    "content": "const { execSync }  = require('child_process')\nconst packageJson = require('../package.json')\n\nlet packageVersion = packageJson.version\n// we estimate redux size based on the content length of the minified umd build hosted by unpkg. This script is brittle but works.\nlet reduxSize = execSync(\"curl -sIL https://unpkg.com/redux/dist/redux.min.js | grep -i Content-Length | tail -1 | awk '{print $2}'\").toString()\n// we need to substract redux size from our umd build to get an estimate of our first party code size\nlet persistSize = execSync(\"wc -c < dist/redux-persist.min.js\") - reduxSize\n\n// note: markdown formatted for conveinence when appending to LIBSIZE.md\nconsole.log(`**v${packageVersion}**: ${persistSize} Bytes  `)\n"
  },
  {
    "path": "src/constants.ts",
    "content": "export const KEY_PREFIX = 'persist:'\nexport const FLUSH = 'persist/FLUSH'\nexport const REHYDRATE = 'persist/REHYDRATE'\nexport const PAUSE = 'persist/PAUSE'\nexport const PERSIST = 'persist/PERSIST'\nexport const PURGE = 'persist/PURGE'\nexport const REGISTER = 'persist/REGISTER'\nexport const DEFAULT_VERSION = -1\n"
  },
  {
    "path": "src/createMigrate.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DEFAULT_VERSION } from './constants'\n\nimport type { PersistedState, MigrationManifest } from './types'\n\nexport default function createMigrate(\n  migrations: MigrationManifest,\n  config?: { debug: boolean }\n): (state: PersistedState, currentVersion: number) => Promise<PersistedState> {\n  const { debug } = config || {}\n  return function(\n    state: PersistedState,\n    currentVersion: number\n  ): Promise<PersistedState> {\n    if (!state) {\n      if (process.env.NODE_ENV !== 'production' && debug)\n        console.log('redux-persist: no inbound state, skipping migration')\n      return Promise.resolve(undefined)\n    }\n\n    const inboundVersion: number =\n      state._persist && state._persist.version !== undefined\n        ? state._persist.version\n        : DEFAULT_VERSION\n    if (inboundVersion === currentVersion) {\n      if (process.env.NODE_ENV !== 'production' && debug)\n        console.log('redux-persist: versions match, noop migration')\n      return Promise.resolve(state)\n    }\n    if (inboundVersion > currentVersion) {\n      if (process.env.NODE_ENV !== 'production')\n        console.error('redux-persist: downgrading version is not supported')\n      return Promise.resolve(state)\n    }\n\n    const migrationKeys = Object.keys(migrations)\n      .map(ver => parseInt(ver))\n      .filter(key => currentVersion >= key && key > inboundVersion)\n      .sort((a, b) => a - b)\n\n    if (process.env.NODE_ENV !== 'production' && debug)\n      console.log('redux-persist: migrationKeys', migrationKeys)\n    try {\n      const migratedState: any = migrationKeys.reduce((state: any, versionKey) => {\n        if (process.env.NODE_ENV !== 'production' && debug)\n          console.log(\n            'redux-persist: running migration for versionKey',\n            versionKey\n          )\n        return migrations[versionKey](state)\n      }, state)\n      return Promise.resolve(migratedState)\n    } catch (err) {\n      return Promise.reject(err)\n    }\n  }\n}\n"
  },
  {
    "path": "src/createPersistoid.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { KEY_PREFIX } from './constants'\n\nimport type { Persistoid, PersistConfig } from './types'\nimport { KeyAccessState } from './types'\n\nexport default function createPersistoid(config: PersistConfig<any>): Persistoid {\n  // defaults\n  const blacklist: string[] | null = config.blacklist || null\n  const whitelist: string[] | null = config.whitelist || null\n  const transforms = config.transforms || []\n  const throttle = config.throttle || 0\n  const storageKey = `${\n    config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX\n  }${config.key}`\n  const storage = config.storage\n  let serialize: (x: any) => any\n  if (config.serialize === false) {\n    serialize = (x: any) => x\n  } else if (typeof config.serialize === 'function') {\n    serialize = config.serialize\n  } else {\n    serialize = defaultSerialize\n  }\n  const writeFailHandler = config.writeFailHandler || null\n\n  // initialize stateful values\n  let lastState: KeyAccessState = {}\n  const stagedState: KeyAccessState = {}\n  const keysToProcess: string[] = []\n  let timeIterator: any = null\n  let writePromise: Promise<any> | null = null\n\n  const update = (state: KeyAccessState) => {\n    // add any changed keys to the queue\n    Object.keys(state).forEach(key => {\n      if (!passWhitelistBlacklist(key)) return // is keyspace ignored? noop\n      if (lastState[key] === state[key]) return // value unchanged? noop\n      if (keysToProcess.indexOf(key) !== -1) return // is key already queued? noop\n      keysToProcess.push(key) // add key to queue\n    })\n\n    //if any key is missing in the new state which was present in the lastState,\n    //add it for processing too\n    Object.keys(lastState).forEach(key => {\n      if (\n        state[key] === undefined &&\n        passWhitelistBlacklist(key) &&\n        keysToProcess.indexOf(key) === -1 &&\n        lastState[key] !== undefined\n      ) {\n        keysToProcess.push(key)\n      }\n    })\n\n    // start the time iterator if not running (read: throttle)\n    if (timeIterator === null) {\n      timeIterator = setInterval(processNextKey, throttle)\n    }\n\n    lastState = state\n  }\n\n  function processNextKey() {\n    if (keysToProcess.length === 0) {\n      if (timeIterator) clearInterval(timeIterator)\n      timeIterator = null\n      return\n    }\n\n    const key: any = keysToProcess.shift()\n    if (key === undefined) {\n      return\n    }\n    const endState = transforms.reduce((subState, transformer) => {\n      return transformer.in(subState, key, lastState)\n    }, lastState[key])\n\n    if (endState !== undefined) {\n      try {\n        stagedState[key] = serialize(endState)\n      } catch (err) {\n        console.error(\n          'redux-persist/createPersistoid: error serializing state',\n          err\n        )\n      }\n    } else {\n      //if the endState is undefined, no need to persist the existing serialized content\n      delete stagedState[key]\n    }\n\n    if (keysToProcess.length === 0) {\n      writeStagedState()\n    }\n  }\n\n  function writeStagedState() {\n    // cleanup any removed keys just before write.\n    Object.keys(stagedState).forEach(key => {\n      if (lastState[key] === undefined) {\n        delete stagedState[key]\n      }\n    })\n\n    writePromise = storage\n      .setItem(storageKey, serialize(stagedState))\n      .catch(onWriteFail)\n  }\n\n  function passWhitelistBlacklist(key: string) {\n    if (whitelist && whitelist.indexOf(key) === -1 && key !== '_persist')\n      return false\n    if (blacklist && blacklist.indexOf(key) !== -1) return false\n    return true\n  }\n\n  function onWriteFail(err: any) {\n    // @TODO add fail handlers (typically storage full)\n    if (writeFailHandler) writeFailHandler(err)\n    if (err && process.env.NODE_ENV !== 'production') {\n      console.error('Error storing data', err)\n    }\n  }\n\n  const flush = () => {\n    while (keysToProcess.length !== 0) {\n      processNextKey()\n    }\n    return writePromise || Promise.resolve()\n  }\n\n  // return `persistoid`\n  return {\n    update,\n    flush,\n  }\n}\n\n// @NOTE in the future this may be exposed via config\nfunction defaultSerialize(data: any) {\n  return JSON.stringify(data)\n}\n"
  },
  {
    "path": "src/createTransform.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\ntype TransformConfig = {\n  whitelist?: Array<string>,\n  blacklist?: Array<string>,\n}\n\nexport default function createTransform(\n  // @NOTE inbound: transform state coming from redux on its way to being serialized and stored\n  // eslint-disable-next-line @typescript-eslint/ban-types\n  inbound: Function,\n  // @NOTE outbound: transform state coming from storage, on its way to be rehydrated into redux\n  // eslint-disable-next-line @typescript-eslint/ban-types\n  outbound: Function,\n  config: TransformConfig = {}\n): any {\n  const whitelist = config.whitelist || null\n  const blacklist = config.blacklist || null\n\n  function whitelistBlacklistCheck(key: string) {\n    if (whitelist && whitelist.indexOf(key) === -1) return true\n    if (blacklist && blacklist.indexOf(key) !== -1) return true\n    return false\n  }\n\n  return {\n    in: (state: Record<string, unknown>, key: string, fullState: Record<string, unknown>) =>\n      !whitelistBlacklistCheck(key) && inbound\n        ? inbound(state, key, fullState)\n        : state,\n    out: (state: Record<string, unknown>, key: string, fullState: Record<string, unknown>) =>\n      !whitelistBlacklistCheck(key) && outbound\n        ? outbound(state, key, fullState)\n        : state,\n  }\n}\n"
  },
  {
    "path": "src/getStoredState.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { KeyAccessState, PersistConfig } from './types'\n\nimport { KEY_PREFIX } from './constants'\n\nexport default function getStoredState(\n  config: PersistConfig<any>\n): Promise<any | void> {\n  const transforms = config.transforms || []\n  const storageKey = `${\n    config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX\n  }${config.key}`\n  const storage = config.storage\n  const debug = config.debug\n  let deserialize: (x: any) => any\n  if (config.deserialize === false) {\n    deserialize = (x: any) => x\n  } else if (typeof config.deserialize === 'function') {\n    deserialize = config.deserialize\n  } else {\n    deserialize = defaultDeserialize\n  }\n  return storage.getItem(storageKey).then((serialized: any) => {\n    if (!serialized) return undefined\n    else {\n      try {\n        const state: KeyAccessState = {}\n        const rawState = deserialize(serialized)\n        Object.keys(rawState).forEach(key => {\n          state[key] = transforms.reduceRight((subState, transformer) => {\n            return transformer.out(subState, key, rawState)\n          }, deserialize(rawState[key]))\n        })\n        return state\n      } catch (err) {\n        if (process.env.NODE_ENV !== 'production' && debug)\n          console.log(\n            `redux-persist/getStoredState: Error restoring data ${serialized}`,\n            err\n          )\n        throw err\n      }\n    }\n  })\n}\n\nfunction defaultDeserialize(serial: string) {\n  return JSON.parse(serial)\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "export { default as persistReducer } from './persistReducer'\nexport { default as persistCombineReducers } from './persistCombineReducers'\nexport { default as persistStore } from './persistStore'\nexport { default as createMigrate } from './createMigrate'\nexport { default as createTransform } from './createTransform'\nexport { default as getStoredState } from './getStoredState'\nexport { default as createPersistoid } from './createPersistoid'\nexport { default as purgeStoredState } from './purgeStoredState'\n\nexport * from './constants'\n"
  },
  {
    "path": "src/integration/getStoredStateMigrateV4.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport getStoredStateV5 from '../getStoredState'\n\nimport type { KeyAccessState, PersistConfig, Storage, Transform } from '../types'\n\ntype V4Config = {\n  storage?: Storage,\n  serialize: boolean,\n  keyPrefix?: string,\n  transforms?: Array<Transform<any, any>>,\n  blacklist?: Array<string>,\n  whitelist?: Array<string>,\n}\n\nexport default function getStoredState(v4Config: V4Config) {\n  return function(v5Config: PersistConfig<any>): any {\n    return getStoredStateV5(v5Config).then(state => {\n      if (state) return state\n      else return getStoredStateV4(v4Config)\n    })\n  }\n}\n\nconst KEY_PREFIX = 'reduxPersist:'\n\nfunction hasLocalStorage() {\n  if (typeof self !== 'object' || !('localStorage' in self)) {\n    return false\n  }\n\n  try {\n    const storage = self.localStorage\n    const testKey = `redux-persist localStorage test`\n    storage.setItem(testKey, 'test')\n    storage.getItem(testKey)\n    storage.removeItem(testKey)\n  } catch (e) {\n    if (process.env.NODE_ENV !== 'production')\n      console.warn(\n        `redux-persist localStorage test failed, persistence will be disabled.`\n      )\n    return false\n  }\n  return true\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst noop = (...args: any) => {\n  /* noop */ return null\n}\nconst noStorage = {\n  getItem: noop,\n  setItem: noop,\n  removeItem: noop,\n  getAllKeys: noop,\n  keys: []\n}\nconst createAsyncLocalStorage = () => {\n  if (!hasLocalStorage()) return noStorage\n  const localStorage = self.localStorage\n  return {\n    getAllKeys: function(cb: any) {\n      try {\n        const keys = []\n        for (let i = 0; i < localStorage.length; i++) {\n          keys.push(localStorage.key(i))\n        }\n        cb(null, keys)\n      } catch (e) {\n        cb(e)\n      }\n    },\n    getItem(key: string, cb: any) {\n      try {\n        const s = localStorage.getItem(key)\n        cb(null, s)\n      } catch (e) {\n        cb(e)\n      }\n    },\n    setItem(key: string, string: string, cb: any) {\n      try {\n        localStorage.setItem(key, string)\n        cb(null)\n      } catch (e) {\n        cb(e)\n      }\n    },\n    removeItem(key: string, cb: any) {\n      try {\n        localStorage.removeItem(key)\n        cb && cb(null)\n      } catch (e) {\n        cb(e)\n      }\n    },\n    keys: localStorage.keys\n  }\n}\n\nfunction getStoredStateV4(v4Config: V4Config) {\n  return new Promise((resolve, reject) => {\n    let storage = v4Config.storage || createAsyncLocalStorage()\n    const deserializer =\n      v4Config.serialize === false\n        ? (data: any) => data\n        : (serial: string) => JSON.parse(serial)\n    const blacklist = v4Config.blacklist || []\n    const whitelist = v4Config.whitelist || false\n    const transforms = v4Config.transforms || []\n    const keyPrefix =\n      v4Config.keyPrefix !== undefined ? v4Config.keyPrefix : KEY_PREFIX\n\n    // fallback getAllKeys to `keys` if present (LocalForage compatability)\n    if (storage.keys && !storage.getAllKeys)\n      storage = { ...storage, getAllKeys: storage.keys }\n\n    const restoredState: KeyAccessState = {}\n    let completionCount = 0\n\n    storage.getAllKeys((err: any, allKeys:string[] = []) => {\n      if (err) {\n        if (process.env.NODE_ENV !== 'production')\n          console.warn(\n            'redux-persist/getStoredState: Error in storage.getAllKeys'\n          )\n        return reject(err)\n      }\n\n      const persistKeys = allKeys\n        .filter(key => key.indexOf(keyPrefix) === 0)\n        .map(key => key.slice(keyPrefix.length))\n      const keysToRestore = persistKeys.filter(passWhitelistBlacklist)\n\n      const restoreCount = keysToRestore.length\n      if (restoreCount === 0) resolve(undefined)\n      keysToRestore.forEach(key => {\n        storage.getItem(createStorageKey(key), (err: any, serialized: string) => {\n          if (err && process.env.NODE_ENV !== 'production')\n            console.warn(\n              'redux-persist/getStoredState: Error restoring data for key:',\n              key,\n              err\n            )\n          else restoredState[key] = rehydrate(key, serialized)\n          completionCount += 1\n          if (completionCount === restoreCount) resolve(restoredState)\n        })\n      })\n    })\n\n    function rehydrate(key: string, serialized: string) {\n      let state = null\n\n      try {\n        const data = serialized ? deserializer(serialized) : undefined\n        state = transforms.reduceRight((subState, transformer) => {\n          return transformer.out(subState, key, {})\n        }, data)\n      } catch (err) {\n        if (process.env.NODE_ENV !== 'production')\n          console.warn(\n            'redux-persist/getStoredState: Error restoring data for key:',\n            key,\n            err\n          )\n      }\n\n      return state\n    }\n\n    function passWhitelistBlacklist(key: string) {\n      if (whitelist && whitelist.indexOf(key) === -1) return false\n      if (blacklist.indexOf(key) !== -1) return false\n      return true\n    }\n\n    function createStorageKey(key: string) {\n      return `${keyPrefix}${key}`\n    }\n  })\n}\n"
  },
  {
    "path": "src/integration/react.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport React, { PureComponent, ReactNode } from 'react'\nimport type { Persistor } from '../types'\n\ntype Props = {\n  onBeforeLift?: () => void,\n  children: ReactNode | ((state: boolean) => ReactNode),\n  loading: ReactNode,\n  persistor: Persistor,\n}\n\ntype State = {\n  bootstrapped: boolean,\n}\n\nexport class PersistGate extends PureComponent<Props, State> {\n  static defaultProps = {\n    children: null,\n    loading: null,\n  }\n\n  state = {\n    bootstrapped: false,\n  }\n  _unsubscribe?: () => void\n\n  componentDidMount(): void {\n    this._unsubscribe = this.props.persistor.subscribe(\n      this.handlePersistorState\n    )\n    this.handlePersistorState()\n  }\n\n  handlePersistorState = (): void => {\n    const { persistor } = this.props\n    const { bootstrapped } = persistor.getState()\n    if (bootstrapped) {\n      if (this.props.onBeforeLift) {\n        Promise.resolve(this.props.onBeforeLift())\n          .finally(() => this.setState({ bootstrapped: true }))\n      } else {\n        this.setState({ bootstrapped: true })\n      }\n      this._unsubscribe && this._unsubscribe()\n    }\n  }\n\n  componentWillUnmount(): void {\n    this._unsubscribe && this._unsubscribe()\n  }\n\n  render(): ReactNode {\n    if (process.env.NODE_ENV !== 'production') {\n      if (typeof this.props.children === 'function' && this.props.loading)\n        console.error(\n          'redux-persist: PersistGate expects either a function child or loading prop, but not both. The loading prop will be ignored.'\n        )\n    }\n    if (typeof this.props.children === 'function') {\n      return this.props.children(this.state.bootstrapped)\n    }\n\n    return this.state.bootstrapped ? this.props.children : this.props.loading\n  }\n}\n"
  },
  {
    "path": "src/persistCombineReducers.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Action, AnyAction, CombinedState, combineReducers, Reducer, ReducersMapObject } from 'redux'\nimport persistReducer from './persistReducer'\nimport autoMergeLevel2 from './stateReconciler/autoMergeLevel2'\n\nimport type { \n  PersistConfig\n} from './types'\n\n// combineReducers + persistReducer with stateReconciler defaulted to autoMergeLevel2\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport default function persistCombineReducers<S, A extends Action>(\n  config: PersistConfig<any>,\n  reducers: ReducersMapObject<CombinedState<S>, Action<any>>\n): Reducer<any, AnyAction> {\n  config.stateReconciler =\n    config.stateReconciler === undefined\n      ? autoMergeLevel2\n      : config.stateReconciler\n  return persistReducer(config, combineReducers(reducers))\n}\n"
  },
  {
    "path": "src/persistReducer.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n  Action, AnyAction, Reducer\n} from 'redux'\n\nimport {\n  FLUSH,\n  PAUSE,\n  PERSIST,\n  PURGE,\n  REHYDRATE,\n  DEFAULT_VERSION,\n} from './constants'\n\nimport type {\n  PersistConfig,\n  PersistState,\n  Persistoid,\n} from './types'\n\nimport autoMergeLevel1 from './stateReconciler/autoMergeLevel1'\nimport createPersistoid from './createPersistoid'\nimport defaultGetStoredState from './getStoredState'\nimport purgeStoredState from './purgeStoredState'\n\ntype PersistPartial = { _persist: PersistState } | any;\nconst DEFAULT_TIMEOUT = 5000\n/*\n  @TODO add validation / handling for:\n  - persisting a reducer which has nested _persist\n  - handling actions that fire before reydrate is called\n*/\nexport default function persistReducer<S, A extends Action>(\n  config: PersistConfig<S>,\n  baseReducer: Reducer<S, A>\n): Reducer<S & PersistPartial, AnyAction> {\n  if (process.env.NODE_ENV !== 'production') {\n    if (!config) throw new Error('config is required for persistReducer')\n    if (!config.key) throw new Error('key is required in persistor config')\n    if (!config.storage)\n      throw new Error(\n        \"redux-persist: config.storage is required. Try using one of the provided storage engines `import storage from 'redux-persist/lib/storage'`\"\n      )\n  }\n\n  const version =\n    config.version !== undefined ? config.version : DEFAULT_VERSION\n  const stateReconciler =\n    config.stateReconciler === undefined\n      ? autoMergeLevel1\n      : config.stateReconciler\n  const getStoredState = config.getStoredState || defaultGetStoredState\n  const timeout =\n    config.timeout !== undefined ? config.timeout : DEFAULT_TIMEOUT\n  let _persistoid: Persistoid | null = null\n  let _purge = false\n  let _paused = true\n  const conditionalUpdate = (state: any) => {\n    // update the persistoid only if we are rehydrated and not paused\n    state._persist.rehydrated &&\n      _persistoid &&\n      !_paused &&\n      _persistoid.update(state)\n    return state\n  }\n\n  return (state: any, action: any) => {\n    const { _persist, ...rest } = state || {}\n    const restState: S = rest\n\n    if (action.type === PERSIST) {\n      let _sealed = false\n      const _rehydrate = (payload: any, err?: Error) => {\n        // dev warning if we are already sealed\n        if (process.env.NODE_ENV !== 'production' && _sealed)\n          console.error(\n            `redux-persist: rehydrate for \"${\n              config.key\n            }\" called after timeout.`,\n            payload,\n            err\n          )\n\n        // only rehydrate if we are not already sealed\n        if (!_sealed) {\n          action.rehydrate(config.key, payload, err)\n          _sealed = true\n        }\n      }\n      timeout &&\n        setTimeout(() => {\n          !_sealed &&\n            _rehydrate(\n              undefined,\n              new Error(\n                `redux-persist: persist timed out for persist key \"${\n                  config.key\n                }\"`\n              )\n            )\n        }, timeout)\n\n      // @NOTE PERSIST resumes if paused.\n      _paused = false\n\n      // @NOTE only ever create persistoid once, ensure we call it at least once, even if _persist has already been set\n      if (!_persistoid) _persistoid = createPersistoid(config)\n\n      // @NOTE PERSIST can be called multiple times, noop after the first\n      if (_persist) {\n        // We still need to call the base reducer because there might be nested\n        // uses of persistReducer which need to be aware of the PERSIST action\n        return {\n          ...baseReducer(restState, action),\n          _persist,\n        };\n      }\n\n      if (\n        typeof action.rehydrate !== 'function' ||\n        typeof action.register !== 'function'\n      )\n        throw new Error(\n          'redux-persist: either rehydrate or register is not a function on the PERSIST action. This can happen if the action is being replayed. This is an unexplored use case, please open an issue and we will figure out a resolution.'\n        )\n\n      action.register(config.key)\n\n      getStoredState(config).then(\n        restoredState => {\n          if (restoredState) {\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n            const migrate = config.migrate || ((s, _) => Promise.resolve(s))\n            migrate(restoredState as any, version).then(\n              migratedState => {\n                _rehydrate(migratedState)\n              },\n              migrateErr => {\n                if (process.env.NODE_ENV !== 'production' && migrateErr)\n                  console.error('redux-persist: migration error', migrateErr)\n                _rehydrate(undefined, migrateErr)\n              }\n            )\n          }\n        },\n        err => {\n          _rehydrate(undefined, err)\n        }\n      )\n\n      return {\n        ...baseReducer(restState, action),\n        _persist: { version, rehydrated: false },\n      }\n    } else if (action.type === PURGE) {\n      _purge = true\n      action.result(purgeStoredState(config))\n      return {\n        ...baseReducer(restState, action),\n        _persist,\n      }\n    } else if (action.type === FLUSH) {\n      action.result(_persistoid && _persistoid.flush())\n      return {\n        ...baseReducer(restState, action),\n        _persist,\n      }\n    } else if (action.type === PAUSE) {\n      _paused = true\n    } else if (action.type === REHYDRATE) {\n      // noop on restState if purging\n      if (_purge)\n        return {\n          ...restState,\n          _persist: { ..._persist, rehydrated: true },\n        }\n\n      // @NOTE if key does not match, will continue to default else below\n      if (action.key === config.key) {\n        const reducedState = baseReducer(restState, action)\n        const inboundState = action.payload\n        // only reconcile state if stateReconciler and inboundState are both defined\n        const reconciledRest: S =\n          stateReconciler !== false && inboundState !== undefined\n            ? stateReconciler(inboundState, state, reducedState, config)\n            : reducedState\n\n        const newState = {\n          ...reconciledRest,\n          _persist: { ..._persist, rehydrated: true },\n        }\n        return conditionalUpdate(newState)\n      }\n    }\n\n    // if we have not already handled PERSIST, straight passthrough\n    if (!_persist) return baseReducer(state, action)\n\n    // run base reducer:\n    // is state modified ? return original : return updated\n    const newState = baseReducer(restState, action)\n    if (newState === restState) return state\n    return conditionalUpdate({ ...newState, _persist })\n  }\n}\n"
  },
  {
    "path": "src/persistStore.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n  Persistor,\n  PersistorOptions,\n  PersistorState,\n} from './types'\n\nimport { AnyAction, createStore, Store } from 'redux'\nimport { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE } from './constants'\n\ntype BoostrappedCb = () => any;\n\nconst initialState: PersistorState = {\n  registry: [],\n  bootstrapped: false,\n}\n\nconst persistorReducer = (state = initialState, action: AnyAction) => {\n  const firstIndex = state.registry.indexOf(action.key)\n  const registry = [...state.registry]\n  switch (action.type) {\n    case REGISTER:\n      return { ...state, registry: [...state.registry, action.key] }\n    case REHYDRATE:\n      registry.splice(firstIndex, 1)\n      return { ...state, registry, bootstrapped: registry.length === 0 }\n    default:\n      return state\n  }\n}\n\ninterface OptionToTestObject {\n  [key: string]: any;\n}\n\nexport default function persistStore(\n  store: Store,\n  options?: PersistorOptions,\n  cb?: BoostrappedCb\n): Persistor {\n  // help catch incorrect usage of passing PersistConfig in as PersistorOptions\n  if (process.env.NODE_ENV !== 'production') {\n    const optionsToTest: OptionToTestObject = options || {}\n    const bannedKeys = [\n      'blacklist',\n      'whitelist',\n      'transforms',\n      'storage',\n      'keyPrefix',\n      'migrate',\n    ]\n    bannedKeys.forEach(k => {\n      if (optionsToTest[k])\n        console.error(\n          `redux-persist: invalid option passed to persistStore: \"${k}\". You may be incorrectly passing persistConfig into persistStore, whereas it should be passed into persistReducer.`\n        )\n    })\n  }\n  let boostrappedCb = cb || false\n\n  const _pStore = createStore(\n    persistorReducer,\n    initialState,\n    options && options.enhancer ? options.enhancer : undefined\n  )\n  const register = (key: string) => {\n    _pStore.dispatch({\n      type: REGISTER,\n      key,\n    })\n  }\n\n  const rehydrate = (key: string, payload: Record<string, unknown>, err: any) => {\n    const rehydrateAction = {\n      type: REHYDRATE,\n      payload,\n      err,\n      key,\n    }\n    // dispatch to `store` to rehydrate and `persistor` to track result\n    store.dispatch(rehydrateAction)\n    _pStore.dispatch(rehydrateAction)\n    if (typeof boostrappedCb === \"function\" && persistor.getState().bootstrapped) {\n      boostrappedCb()\n      boostrappedCb = false\n    }\n  }\n\n  const persistor: Persistor = {\n    ..._pStore,\n    purge: () => {\n      const results: Array<any> = []\n      store.dispatch({\n        type: PURGE,\n        result: (purgeResult: any) => {\n          results.push(purgeResult)\n        },\n      })\n      return Promise.all(results)\n    },\n    flush: () => {\n      const results: Array<any> = []\n      store.dispatch({\n        type: FLUSH,\n        result: (flushResult: any) => {\n          results.push(flushResult)\n        },\n      })\n      return Promise.all(results)\n    },\n    pause: () => {\n      store.dispatch({\n        type: PAUSE,\n      })\n    },\n    persist: () => {\n      store.dispatch({ type: PERSIST, register, rehydrate })\n    },\n  }\n\n  if (!(options && options.manualPersist)){\n    persistor.persist()\n  }\n\n  return persistor\n}\n"
  },
  {
    "path": "src/purgeStoredState.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { PersistConfig } from './types'\n\nimport { KEY_PREFIX } from './constants'\n\nexport default function purgeStoredState(config: PersistConfig<any>):any {\n  const storage = config.storage\n  const storageKey = `${\n    config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX\n  }${config.key}`\n  return storage.removeItem(storageKey, warnIfRemoveError)\n}\n\nfunction warnIfRemoveError(err: any) {\n  if (err && process.env.NODE_ENV !== 'production') {\n    console.error(\n      'redux-persist/purgeStoredState: Error purging data stored state',\n      err\n    )\n  }\n}\n"
  },
  {
    "path": "src/stateReconciler/autoMergeLevel1.ts",
    "content": "/*\n  autoMergeLevel1: \n    - merges 1 level of substate\n    - skips substate if already modified\n*/\n\nimport type { PersistConfig } from '../types'\nimport { KeyAccessState } from '../types'\n\nexport default function autoMergeLevel1<S extends KeyAccessState>(\n  inboundState: S,\n  originalState: S,\n  reducedState: S,\n  { debug }: PersistConfig<S>\n): S {\n  const newState = { ...reducedState }\n  // only rehydrate if inboundState exists and is an object\n  if (inboundState && typeof inboundState === 'object') {\n    const keys: (keyof S)[] = Object.keys(inboundState)\n    keys.forEach(key => {\n      // ignore _persist data\n      if (key === '_persist') return\n      // if reducer modifies substate, skip auto rehydration\n      if (originalState[key] !== reducedState[key]) {\n        if (process.env.NODE_ENV !== 'production' && debug)\n          console.log(\n            'redux-persist/stateReconciler: sub state for key `%s` modified, skipping.',\n            key\n          )\n        return\n      }\n      // otherwise hard set the new value\n      newState[key] = inboundState[key]\n    })\n  }\n\n  if (\n    process.env.NODE_ENV !== 'production' &&\n    debug &&\n    inboundState &&\n    typeof inboundState === 'object'\n  )\n    console.log(\n      `redux-persist/stateReconciler: rehydrated keys '${Object.keys(\n        inboundState\n      ).join(', ')}'`\n    )\n\n  return newState\n}\n"
  },
  {
    "path": "src/stateReconciler/autoMergeLevel2.ts",
    "content": "/*\n  autoMergeLevel2: \n    - merges 2 level of substate\n    - skips substate if already modified\n    - this is essentially redux-perist v4 behavior\n*/\n\nimport type { PersistConfig } from '../types'\nimport { KeyAccessState } from '../types'\n\nexport default function autoMergeLevel2<S extends KeyAccessState>(\n  inboundState: S,\n  originalState: S,\n  reducedState: S,\n  { debug }: PersistConfig<S>\n): S {\n  const newState = { ...reducedState }\n  // only rehydrate if inboundState exists and is an object\n  if (inboundState && typeof inboundState === 'object') {\n    const keys: (keyof S)[] = Object.keys(inboundState)\n    keys.forEach(key => {\n      // ignore _persist data\n      if (key === '_persist') return\n      // if reducer modifies substate, skip auto rehydration\n      if (originalState[key] !== reducedState[key]) {\n        if (process.env.NODE_ENV !== 'production' && debug)\n          console.log(\n            'redux-persist/stateReconciler: sub state for key `%s` modified, skipping.',\n            key\n          )\n        return\n      }\n      if (isPlainEnoughObject(reducedState[key])) {\n        // if object is plain enough shallow merge the new values (hence \"Level2\")\n        newState[key] = { ...newState[key], ...inboundState[key] }\n        return\n      }\n      // otherwise hard set\n      newState[key] = inboundState[key]\n    })\n  }\n\n  if (\n    process.env.NODE_ENV !== 'production' &&\n    debug &&\n    inboundState &&\n    typeof inboundState === 'object'\n  )\n    console.log(\n      `redux-persist/stateReconciler: rehydrated keys '${Object.keys(\n        inboundState\n      ).join(', ')}'`\n    )\n\n  return newState\n}\n\nfunction isPlainEnoughObject(o: unknown) {\n  return o !== null && !Array.isArray(o) && typeof o === 'object'\n}\n"
  },
  {
    "path": "src/stateReconciler/hardSet.ts",
    "content": "/*\n  hardSet: \n    - hard set incoming state\n*/\n\nexport default function hardSet<S>(inboundState: S): S {\n  return inboundState\n}\n"
  },
  {
    "path": "src/storage/createWebStorage.ts",
    "content": "import getStorage from './getStorage'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default function createWebStorage(type: string): any {\n  const storage = getStorage(type)\n  return {\n    getItem: (key: string): Promise<string> => {\n      return new Promise((resolve) => {\n        resolve(storage.getItem(key))\n      })\n    },\n    setItem: (key: string, item: string): Promise<void> => {\n      return new Promise((resolve) => {\n        resolve(storage.setItem(key, item))\n      })\n    },\n    removeItem: (key: string): Promise<void> => {\n      return new Promise((resolve) => {\n        resolve(storage.removeItem(key))\n      })\n    },\n  }\n}\n"
  },
  {
    "path": "src/storage/getStorage.ts",
    "content": "import type { Storage } from '../types'\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noop() {}\nconst noopStorage = {\n  getItem: noop,\n  setItem: noop,\n  removeItem: noop,\n  keys: [],\n  getAllKeys: noop,\n}\n\nfunction hasStorage(storageType: string) {\n  if (typeof self !== 'object' || !(storageType in self)) {\n    return false\n  }\n\n  try {\n    const storage = (self as unknown as { [key: string]: Storage})[storageType] as unknown as Storage\n    const testKey = `redux-persist ${storageType} test`\n    storage.setItem(testKey, 'test')\n    storage.getItem(testKey)\n    storage.removeItem(testKey)\n  } catch (e) {\n    if (process.env.NODE_ENV !== 'production')\n      console.warn(\n        `redux-persist ${storageType} test failed, persistence will be disabled.`\n      )\n    return false\n  }\n  return true\n}\n\nexport default function getStorage(type: string): Storage {\n  const storageType = `${type}Storage`\n  if (hasStorage(storageType)) return (self as unknown as { [key: string]: Storage })[storageType]\n  else {\n    if (process.env.NODE_ENV !== 'production') {\n      console.error(\n        `redux-persist failed to create sync storage. falling back to noop storage.`\n      )\n    }\n    return noopStorage\n  }\n}\n"
  },
  {
    "path": "src/storage/index.ts",
    "content": "import createWebStorage from './createWebStorage'\n\nexport default createWebStorage('local')\n"
  },
  {
    "path": "src/storage/session.ts",
    "content": "import createWebStorage from './createWebStorage'\n\nexport default createWebStorage('session')\n"
  },
  {
    "path": "src/types.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { REHYDRATE, REGISTER } from './constants'\n\nimport { StoreEnhancer } from \"redux\";\n\nexport interface PersistState {\n  version: number;\n  rehydrated: boolean;\n}\n\nexport type PersistedState = {\n  _persist: PersistState;\n} | undefined;\n\nexport type PersistMigrate =\n  (state: PersistedState, currentVersion: number) => Promise<PersistedState>;\n\nexport type StateReconciler<S> =\n  (inboundState: any, state: S, reducedState: S, config: PersistConfig<S>) => S;\n\nexport interface KeyAccessState {\n  [key: string]: any;\n}\n\n/**\n * @desc\n * `HSS` means HydratedSubState\n * `ESS` means EndSubState\n * `S` means State\n * `RS` means RawState\n */\nexport interface PersistConfig<S, RS = any, HSS = any, ESS = any> {\n  version?: number;\n  storage: Storage;\n  key: string;\n  /**\n   * @deprecated keyPrefix is going to be removed in v6.\n   */\n  keyPrefix?: string;\n  blacklist?: Array<string>;\n  whitelist?: Array<string>;\n  transforms?: Array<Transform<HSS, ESS, S, RS>>;\n  throttle?: number;\n  migrate?: PersistMigrate;\n  stateReconciler?: false | StateReconciler<S>;\n  /**\n   * @desc Used for migrations.\n   */\n  getStoredState?: (config: PersistConfig<S, RS, HSS, ESS>) => Promise<PersistedState>;\n  debug?: boolean;\n  serialize?: boolean;\n  deserialize?: boolean | ((x: any) => any);\n  timeout?: number;\n  writeFailHandler?: (err: Error) => void;\n}\n\nexport interface PersistorOptions {\n  enhancer?: StoreEnhancer<any>;\n  manualPersist?: boolean;\n}\n\nexport interface Storage {\n  getItem(key: string, ...args: Array<any>): any;\n  setItem(key: string, value: any, ...args: Array<any>): any;\n  removeItem(key: string, ...args: Array<any>): any;\n  keys?: Array<string>;\n  getAllKeys(cb?: any): any;\n}\n\nexport interface WebStorage extends Storage {\n  /**\n   * @desc Fetches key and returns item in a promise.\n   */\n  getItem(key: string): Promise<string | null>;\n  /**\n   * @desc Sets value for key and returns item in a promise.\n   */\n  setItem(key: string, item: string): Promise<void>;\n  /**\n   * @desc Removes value for key.\n   */\n  removeItem(key: string): Promise<void>;\n}\n\nexport interface MigrationManifest {\n  [key: string]: (state: PersistedState) => PersistedState;\n}\n\n/**\n * @desc\n * `SS` means SubState\n * `ESS` means EndSubState\n * `S` means State\n */\nexport type TransformInbound<SS, ESS, S = any> =\n  (subState: SS, key: keyof S, state: S) => ESS;\n\n/**\n * @desc\n * `SS` means SubState\n * `HSS` means HydratedSubState\n * `RS` means RawState\n */\nexport type TransformOutbound<SS, HSS, RS = any> =\n  (state: SS, key: keyof RS, rawState: RS) => HSS;\n\nexport interface Transform<HSS, ESS, S = any, RS = any> {\n  in: TransformInbound<HSS, ESS, S>;\n  out: TransformOutbound<ESS, HSS, RS>;\n}\n\nexport type RehydrateErrorType = any;\n\nexport interface RehydrateAction {\n  type: typeof REHYDRATE;\n  key: string;\n  payload?: object | null;\n  err?: RehydrateErrorType | null;\n}\n\nexport interface Persistoid {\n  update(state: object): void;\n  flush(): Promise<any>;\n}\n\nexport interface RegisterAction {\n  type: typeof REGISTER;\n  key: string;\n}\n\nexport type PersistorAction =\n  | RehydrateAction\n  | RegisterAction\n;\n\nexport interface PersistorState {\n  registry: Array<string>;\n  bootstrapped: boolean;\n}\n\nexport type PersistorSubscribeCallback = () => any;\n\n/**\n * A persistor is a redux store unto itself, allowing you to purge stored state, flush all\n * pending state serialization and immediately write to disk\n */\nexport interface Persistor {\n  pause(): void;\n  persist(): void;\n  purge(): Promise<any>;\n  flush(): Promise<any>;\n  dispatch(action: PersistorAction): PersistorAction;\n  getState(): PersistorState;\n  subscribe(callback: PersistorSubscribeCallback): () => any;\n}\n"
  },
  {
    "path": "tests/complete.spec.ts",
    "content": "import test from 'ava'\nimport { combineReducers, createStore } from 'redux'\n\nimport persistReducer from '../src/persistReducer'\nimport persistStore from '../src/persistStore'\nimport createMemoryStorage from './utils/createMemoryStorage'\nimport brokenStorage from './utils/brokenStorage'\n\nconst reducer = () => ({})\nconst config = {\n  key: 'persist-reducer-test',\n  version: 1,\n  storage: createMemoryStorage(),\n  debug: true,\n  timeout: 5,\n}\n\ntest('multiple persistReducers work together', t => {\n  return new Promise((resolve) => {\n    const r1 = persistReducer(config, reducer)\n    const r2 = persistReducer(config, reducer)\n    const rootReducer = combineReducers({ r1, r2 })\n    const store = createStore(rootReducer)\n    const persistor = persistStore(store, {}, () => {\n      t.is(persistor.getState().bootstrapped, true)\n      resolve()      \n    })\n  })\n})\n\ntest('persistStore timeout 0 never bootstraps', t => {\n  return new Promise((resolve, reject) => {\n    const r1 = persistReducer({...config, storage: brokenStorage, timeout: 0}, reducer)\n    const rootReducer = combineReducers({ r1 })\n    const store = createStore(rootReducer)\n    const persistor = persistStore(store, undefined, () => {\n      console.log('resolve')\n      reject()     \n    })\n    setTimeout(() => {\n      t.is(persistor.getState().bootstrapped, false)\n      resolve()\n    }, 10)\n  })\n})\n\n\ntest('persistStore timeout forces bootstrap', t => {\n  return new Promise((resolve, reject) => {\n    const r1 = persistReducer({...config, storage: brokenStorage}, reducer)\n    const rootReducer = combineReducers({ r1 })\n    const store = createStore(rootReducer)\n    const persistor = persistStore(store, undefined, () => {\n      t.is(persistor.getState().bootstrapped, true)\n      resolve()\n    })\n    setTimeout(() => {\n      reject()\n    }, 10)\n  })\n})\n"
  },
  {
    "path": "tests/createPersistor.spec.ts",
    "content": "import test from 'ava'\nimport sinon from 'sinon'\nimport createMemoryStorage from './utils/createMemoryStorage'\nimport createPersistoid from '../src/createPersistoid'\nconst memoryStorage = createMemoryStorage()\n\nconst config = {\n  key: 'persist-reducer-test',\n  version: 1,\n  storage: memoryStorage,\n  debug: true\n}\n\nlet spy: sinon.SinonSpy;\nlet clock: sinon.SinonFakeTimers;\n\ntest.beforeEach(() => {\n    spy = sinon.spy(memoryStorage, 'setItem')\n    clock = sinon.useFakeTimers()\n});\n\ntest.afterEach(() => {\n    spy.restore()\n    clock.restore()\n});\n\n// @NOTE these tests broke when updating sinon\ntest.skip('it updates changed state', t => {\n    const { update } = createPersistoid(config)\n    update({ a: 1 })\n    clock.tick(1);\n    update({ a: 2 })\n    clock.tick(1);\n    t.true(spy.calledTwice);\n    t.true(spy.withArgs('persist:persist-reducer-test', '{\"a\":\"1\"}').calledOnce);\n    t.true(spy.withArgs('persist:persist-reducer-test', '{\"a\":\"2\"}').calledOnce);\n})\n\ntest.skip('it does not update unchanged state', t => {\n    const { update } = createPersistoid(config)\n    update({ a: undefined, b: 1 })\n    clock.tick(1);\n    // This update should not cause a write.\n    update({ a: undefined, b: 1 })\n    clock.tick(1);\n    t.true(spy.calledOnce);\n    t.true(spy.withArgs('persist:persist-reducer-test', '{\"b\":\"1\"}').calledOnce);\n})\n\ntest.skip('it updates removed keys', t => {\n    const { update } = createPersistoid(config)\n    update({ a: undefined, b: 1 })\n    clock.tick(1);\n    update({ a: undefined, b: undefined })\n    clock.tick(1);\n    t.true(spy.calledTwice);\n    t.true(spy.withArgs('persist:persist-reducer-test', '{\"b\":\"1\"}').calledOnce);\n    t.true(spy.withArgs('persist:persist-reducer-test', '{}').calledOnce);\n})\n"
  },
  {
    "path": "tests/flush.spec.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport test from 'ava'\nimport { createStore } from 'redux'\n\nimport getStoredState from '../src/getStoredState'\nimport persistReducer from '../src/persistReducer'\nimport persistStore from '../src/persistStore'\nimport createMemoryStorage from './utils/createMemoryStorage'\n\nconst INCREMENT = 'INCREMENT'\n\ninterface StateObject {\n  [key: string]: any;\n}\nconst initialState: StateObject = { a: 0, b: 10, c: 100}\nconst reducer = (state = initialState, { type }: { type: any }) => {\n  console.log('action', type)\n  if (type === INCREMENT) {\n    const result = state\n    Object.keys(state).forEach((key) => {\n      result[key] = state[key] + 1\n    })\n    return result\n  }\n  return state\n}\n\nconst memoryStorage = createMemoryStorage()\n\nconst config = {\n  key: 'persist-reducer-test',\n  version: 1,\n  storage: memoryStorage,\n  debug: true,\n  throttle: 1000,\n}\n\ntest('state before flush is not updated, after flush is', t => {\n  return new Promise((resolve) => {\n    const rootReducer = persistReducer(config, reducer)\n    const store = createStore(rootReducer)\n    const persistor = persistStore(store, {}, async () => {\n      store.dispatch({ type: INCREMENT })\n      const state = store.getState()\n      const storedPreFlush = await getStoredState(config)\n      t.not(storedPreFlush && storedPreFlush.c, state.c)\n      await persistor.flush()\n      const storedPostFlush = await getStoredState(config)\n      resolve(t.is(storedPostFlush && storedPostFlush.c, state.c))\n    })\n  })\n})\n"
  },
  {
    "path": "tests/persistCombineReducers.spec.ts",
    "content": "import persistCombineReducers from '../src/persistCombineReducers'\nimport createMemoryStorage from './utils/createMemoryStorage'\n\nimport test from 'ava'\n\nconst config = {\n  key: 'TestConfig',\n  storage: createMemoryStorage()\n}\n\ntest('persistCombineReducers returns a function', t => {\n  const reducer = persistCombineReducers(config, {\n    foo: () => ({})\n  })\n\n  t.is(typeof reducer, 'function')\n})\n\n/*\ntest.skip('persistCombineReducers merges two levels deep of state', t => {\n  \n})\n*/\n"
  },
  {
    "path": "tests/persistReducer.spec.ts",
    "content": "import test from 'ava'\nimport sinon from 'sinon'\n\nimport persistReducer from '../src/persistReducer'\nimport createMemoryStorage from './utils/createMemoryStorage'\nimport { PERSIST } from '../src/constants'\nimport sleep from './utils/sleep'\n\nconst reducer = () => ({})\nconst config = {\n  key: 'persist-reducer-test',\n  version: 1,\n  storage: createMemoryStorage()\n}\n\ntest('persistedReducer does not automatically set _persist state', t => {\n  const persistedReducer = persistReducer(config, reducer)\n  const state = persistedReducer({}, {type: \"UNDEFINED\"})\n  console.log('state', state)\n  t.is(undefined, state._persist)\n})\n\ntest('persistedReducer does returns versioned, rehydrate tracked _persist state upon PERSIST', t => {\n  const persistedReducer = persistReducer(config, reducer)\n  const register = sinon.spy()\n  const rehydrate = sinon.spy()\n  const state = persistedReducer({}, { type: PERSIST, register, rehydrate })\n  t.deepEqual({ version: 1, rehydrated: false}, state._persist)\n})\n\ntest('persistedReducer calls register and rehydrate after PERSIST', async (t) => {\n  const persistedReducer = persistReducer(config, reducer)\n  const register = sinon.spy()\n  const rehydrate = sinon.spy()\n  persistedReducer({}, { type: PERSIST, register, rehydrate })\n  await sleep(5000)\n  t.is(register.callCount, 1)\n  t.is(rehydrate.callCount, 1)\n})\n"
  },
  {
    "path": "tests/persistStore.spec.ts",
    "content": "import test from 'ava'\nimport sinon from 'sinon'\n\nimport configureStore from 'redux-mock-store'\n\nimport persistStore from '../src/persistStore'\nimport { PERSIST, REHYDRATE } from '../src/constants'\nimport find from './utils/find'\n\nconst mockStore = configureStore([])\n\ntest('persistStore dispatches PERSIST action', t => {\n  const store = mockStore()\n  persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n  t.truthy(persistAction)\n})\n\ntest('register method adds a key to the registry', t => {\n  const store = mockStore()\n  const persistor = persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n  persistAction.register('canary')\n  t.deepEqual(persistor.getState().registry, ['canary'])\n})\n\ntest('rehydrate method fires with the expected shape', t => {\n  const store = mockStore()\n  persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  const rehydrateAction = find(actions, { type: REHYDRATE })\n  t.deepEqual(rehydrateAction, { type: REHYDRATE, key: 'canary', payload: { foo: 'bar' }, err: null })\n})\n\ntest('rehydrate method removes provided key from registry', t => {\n  const store = mockStore()\n  const persistor = persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n\n  // register canary\n  persistAction.register('canary')\n  t.deepEqual(persistor.getState().registry, ['canary'])\n\n  // rehydrate canary\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.deepEqual(persistor.getState().registry, [])\n})\n\ntest('rehydrate method removes exactly one of provided key from registry', t => {\n  const store = mockStore()\n  const persistor = persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n\n  // register canary twice\n  persistAction.register('canary')\n  persistAction.register('canary')\n  t.deepEqual(persistor.getState().registry, ['canary', 'canary'])\n\n  // rehydrate canary\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.deepEqual(persistor.getState().registry, ['canary'])\n})\n\ntest('once registry is cleared for first time, persistor is flagged as bootstrapped', t => {\n  const store = mockStore()\n  const persistor = persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n\n  persistAction.register('canary')\n  t.false(persistor.getState().bootstrapped)\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.true(persistor.getState().bootstrapped)\n})\n\ntest('once persistor is flagged as bootstrapped, further registry changes do not affect this value', t => {\n  const store = mockStore()\n  const persistor = persistStore(store)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n\n  persistAction.register('canary')\n  t.false(persistor.getState().bootstrapped)\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.true(persistor.getState().bootstrapped)\n\n  // add canary back, registry is updated but bootstrapped remains true\n  persistAction.register('canary')\n  t.deepEqual(persistor.getState().registry, ['canary'])\n  t.true(persistor.getState().bootstrapped)\n})\n\ntest('persistStore calls bootstrapped callback (at most once) if provided', t => {\n  const store = mockStore()\n  const bootstrappedCb = sinon.spy()  \n  persistStore(store, {}, bootstrappedCb)\n  const actions = store.getActions()\n  const persistAction = find(actions, { type: PERSIST })\n  \n  persistAction.register('canary')\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.is(bootstrappedCb.callCount, 1)\n\n  // further rehydrates do not trigger the cb\n  persistAction.register('canary')\n  persistAction.rehydrate('canary', { foo: 'bar' }, null)\n  t.is(bootstrappedCb.callCount, 1)\n})\n"
  },
  {
    "path": "tests/utils/brokenStorage.ts",
    "content": "/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/ban-types */\nexport default {\n  getItem(): Promise<void> {\n    return new Promise((resolve: Function, reject: Function) => {})\n  },\n  setItem(): Promise<void> {\n    return new Promise((resolve: Function, reject: Function) => {})\n  },\n  removeItem(): Promise<void> {\n    return new Promise((resolve: Function, reject: Function) => {})\n  },\n  getAllKeys(): Promise<void> {\n    return new Promise((resolve: Function, reject: Function) => {})\n  },\n  keys: []\n}\n"
  },
  {
    "path": "tests/utils/createMemoryStorage.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Storage } from \"../../src/types\"\n\ninterface StateObj {\n  [key: string]: any;\n}\n\nexport function createMemoryStorage():Storage {\n  const state: StateObj = {}\n  return {\n    getItem(key: string): Promise<string> {\n      return Promise.resolve(state[key])\n    },\n    setItem(key: string, value: any): Promise<void> {\n      state[key] = value\n      return Promise.resolve(value)\n    },\n    removeItem(key: string): Promise<void> {\n      delete state[key]\n      return Promise.resolve()\n    },\n    getAllKeys(): Promise<Array<string>> {\n      return Promise.resolve(Object.keys(state))\n    },\n    keys: Object.keys(state)\n  }\n}\n\nexport default createMemoryStorage\n"
  },
  {
    "path": "tests/utils/find.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nexport default (collection: Array<Record<string, any>>, predicate: Record<string, string>): any => {\n  let result = {}\n  collection.forEach((value: any) => {\n    if (value.type && value.type === predicate.type) {\n      result = value\n    }\n  })\n  return result\n}\n"
  },
  {
    "path": "tests/utils/sleep.ts",
    "content": "export default function (timeout: number): Promise<void> {\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  return new Promise((resolve, _) => {\n    setTimeout(resolve, timeout)\n  })\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n\n    /* Basic Options */\n    // \"incremental\": true,                         /* Enable incremental compilation */\n    \"target\": \"es2015\",                             /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */\n    \"module\": \"commonjs\",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */\n    // \"lib\": [],                                   /* Specify library files to be included in the compilation. */\n    // \"allowJs\": true,                             /* Allow javascript files to be compiled. */\n    // \"checkJs\": true,                             /* Report errors in .js files. */\n    // \"jsx\": \"preserve\",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */\n    \"declaration\": true,                            /* Generates corresponding '.d.ts' file. */\n    // \"declarationMap\": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */\n    // \"sourceMap\": true,                           /* Generates corresponding '.map' file. */\n    // \"outFile\": \"./\",                             /* Concatenate and emit output to single file. */\n    \"outDir\": \"./dist\",                             /* Redirect output structure to the directory. */\n    // \"rootDir\": \"./\",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n    // \"composite\": true,                           /* Enable project compilation */\n    // \"tsBuildInfoFile\": \"./\",                     /* Specify file to store incremental compilation information */\n    // \"removeComments\": true,                      /* Do not emit comments to output. */\n    // \"noEmit\": true,                              /* Do not emit outputs. */\n    // \"importHelpers\": true,                       /* Import emit helpers from 'tslib'. */\n    // \"downlevelIteration\": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n    // \"isolatedModules\": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n\n    /* Strict Type-Checking Options */\n    \"strict\": true,                                 /* Enable all strict type-checking options. */\n    // \"noImplicitAny\": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,                    /* Enable strict null checks. */\n    // \"strictFunctionTypes\": true,                 /* Enable strict checking of function types. */\n    // \"strictBindCallApply\": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */\n    // \"strictPropertyInitialization\": true,        /* Enable strict checking of property initialization in classes. */\n    // \"noImplicitThis\": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */\n    // \"alwaysStrict\": true,                        /* Parse in strict mode and emit \"use strict\" for each source file. */\n\n    /* Additional Checks */\n    // \"noUnusedLocals\": true,                      /* Report errors on unused locals. */\n    // \"noUnusedParameters\": true,                  /* Report errors on unused parameters. */\n    // \"noImplicitReturns\": true,                   /* Report error when not all code paths in function return a value. */\n    // \"noFallthroughCasesInSwitch\": true,          /* Report errors for fallthrough cases in switch statement. */\n    // \"noUncheckedIndexedAccess\": true,            /* Include 'undefined' in index signature results */\n    // \"noImplicitOverride\": true,                  /* Ensure overriding members in derived classes are marked with an 'override' modifier. */\n    // \"noPropertyAccessFromIndexSignature\": true,  /* Require undeclared properties from index signatures to use element accesses. */\n\n    /* Module Resolution Options */\n    \"moduleResolution\": \"node\",                     /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */\n    // \"baseUrl\": \"./\",                             /* Base directory to resolve non-absolute module names. */\n    // \"paths\": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n    // \"rootDirs\": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */\n    // \"typeRoots\": [],                             /* List of folders to include type definitions from. */\n    // \"types\": [],                                 /* Type declaration files to be included in compilation. */\n    // \"allowSyntheticDefaultImports\": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n    \"esModuleInterop\": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */\n    // \"preserveSymlinks\": true,                    /* Do not resolve the real path of symlinks. */\n    // \"allowUmdGlobalAccess\": true,                /* Allow accessing UMD globals from modules. */\n\n    /* Source Map Options */\n    // \"sourceRoot\": \"\",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */\n    // \"mapRoot\": \"\",                               /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSourceMap\": true,                     /* Emit a single file with source maps instead of having a separate file. */\n    // \"inlineSources\": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */\n\n    /* Experimental Options */\n    // \"experimentalDecorators\": true,              /* Enables experimental support for ES7 decorators. */\n    // \"emitDecoratorMetadata\": true,               /* Enables experimental support for emitting type metadata for decorators. */\n\n    /* Advanced Options */\n    \"skipLibCheck\": true,                           /* Skip type checking of declaration files. */\n    \"forceConsistentCasingInFileNames\": true        /* Disallow inconsistently-cased references to the same file. */\n  },\n  \"include\": [\n    \"src/**/*\"\n  ],\n  \"exclude\": [\n    \"node_modules\"\n  ]\n}\n"
  }
]