{
  "version": 3,
  "sources": ["../../../src/plugins/persistence/index.ts"],
  "sourcesContent": ["/**\n * External dependencies\n */\n// @ts-expect-error -- is-plain-object types don't resolve with package.json \"exports\".\nimport { isPlainObject } from 'is-plain-object';\nimport deepmerge from 'deepmerge';\n\n/**\n * Internal dependencies\n */\nimport defaultStorage from './storage/default';\nimport { combineReducers } from '../../';\nimport type {\n\tDataRegistry,\n\tReduxStoreConfig,\n\tStorageInterface,\n} from '../../types';\n\ninterface PersistencePluginOptions {\n\t/**\n\t * Persistent storage implementation. This must\n\t * at least implement `getItem` and `setItem` of\n\t * the Web Storage API.\n\t */\n\tstorage?: StorageInterface;\n\t/**\n\t * Key on which to set in persistent storage.\n\t */\n\tstorageKey?: string;\n}\n\ninterface PersistenceInterface {\n\tget: () => Record< string, unknown >;\n\tset: ( key: string, value: unknown ) => void;\n}\n\n/**\n * Default plugin storage.\n */\nconst DEFAULT_STORAGE = defaultStorage;\n\n/**\n * Default plugin storage key.\n */\nconst DEFAULT_STORAGE_KEY = 'WP_DATA';\n\n/**\n * Higher-order reducer which invokes the original reducer only if state is\n * inequal from that of the action's `nextState` property, otherwise returning\n * the original state reference.\n *\n * @param reducer Original reducer.\n *\n * @return Enhanced reducer.\n */\nexport const withLazySameState =\n\t( reducer: ( state: any, action: any ) => any ) =>\n\t( state: unknown, action: { nextState: unknown } ) => {\n\t\tif ( action.nextState === state ) {\n\t\t\treturn state;\n\t\t}\n\n\t\treturn reducer( state, action );\n\t};\n\n/**\n * Creates a persistence interface, exposing getter and setter methods (`get`\n * and `set` respectively).\n *\n * @param options Plugin options.\n *\n * @return Persistence interface.\n */\nexport function createPersistenceInterface(\n\toptions: PersistencePluginOptions\n): PersistenceInterface {\n\tconst { storage = DEFAULT_STORAGE, storageKey = DEFAULT_STORAGE_KEY } =\n\t\toptions;\n\n\tlet data: Record< string, unknown > | undefined;\n\n\t/**\n\t * Returns the persisted data as an object, defaulting to an empty object.\n\t *\n\t * @return Persisted data.\n\t */\n\tfunction getData(): Record< string, unknown > {\n\t\tif ( data === undefined ) {\n\t\t\t// If unset, getItem is expected to return null. Fall back to\n\t\t\t// empty object.\n\t\t\tconst persisted = storage.getItem( storageKey );\n\t\t\tif ( persisted === null ) {\n\t\t\t\tdata = {};\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse( persisted );\n\t\t\t\t} catch {\n\t\t\t\t\t// Similarly, should any error be thrown during parse of\n\t\t\t\t\t// the string (malformed JSON), fall back to empty object.\n\t\t\t\t\tdata = {};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn data!;\n\t}\n\n\t/**\n\t * Merges an updated reducer state into the persisted data.\n\t *\n\t * @param key   Key to update.\n\t * @param value Updated value.\n\t */\n\tfunction setData( key: string, value: unknown ): void {\n\t\tdata = { ...data, [ key ]: value };\n\t\tstorage.setItem( storageKey, JSON.stringify( data ) );\n\t}\n\n\treturn {\n\t\tget: getData,\n\t\tset: setData,\n\t};\n}\n\n/**\n * Data plugin to persist store state into a single storage key.\n *\n * @param registry      Data registry.\n * @param pluginOptions Plugin options.\n *\n * @return Data plugin.\n */\nfunction persistencePlugin(\n\tregistry: DataRegistry,\n\tpluginOptions: PersistencePluginOptions\n): Partial< DataRegistry > {\n\tconst persistence = createPersistenceInterface( pluginOptions );\n\n\t/**\n\t * Creates an enhanced store dispatch function, triggering the state of the\n\t * given store name to be persisted when changed.\n\t *\n\t * @param getState  Function which returns current state.\n\t * @param storeName Store name.\n\t * @param keys      Optional subset of keys to save.\n\t *\n\t * @return Enhanced dispatch function.\n\t */\n\tfunction createPersistOnChange(\n\t\tgetState: () => unknown,\n\t\tstoreName: string,\n\t\tkeys: boolean | string[]\n\t): () => void {\n\t\tlet getPersistedState: ( state: any, action: any ) => any;\n\t\tif ( Array.isArray( keys ) ) {\n\t\t\t// Given keys, the persisted state should by produced as an object\n\t\t\t// of the subset of keys. This implementation uses combineReducers\n\t\t\t// to leverage its behavior of returning the same object when none\n\t\t\t// of the property values changes. This allows a strict reference\n\t\t\t// equality to bypass a persistence set on an unchanging state.\n\t\t\tconst reducers = keys.reduce(\n\t\t\t\t(\n\t\t\t\t\taccumulator: Record<\n\t\t\t\t\t\tstring,\n\t\t\t\t\t\t( state: any, action: any ) => any\n\t\t\t\t\t>,\n\t\t\t\t\tkey: string\n\t\t\t\t) =>\n\t\t\t\t\tObject.assign( accumulator, {\n\t\t\t\t\t\t[ key ]: (\n\t\t\t\t\t\t\tstate: unknown,\n\t\t\t\t\t\t\taction: { nextState: Record< string, unknown > }\n\t\t\t\t\t\t) => action.nextState[ key ],\n\t\t\t\t\t} ),\n\t\t\t\t{}\n\t\t\t);\n\n\t\t\tgetPersistedState = withLazySameState(\n\t\t\t\tcombineReducers( reducers )\n\t\t\t);\n\t\t} else {\n\t\t\tgetPersistedState = (\n\t\t\t\t_state: unknown,\n\t\t\t\taction: { nextState: unknown }\n\t\t\t) => action.nextState;\n\t\t}\n\n\t\tlet lastState = getPersistedState( undefined, {\n\t\t\tnextState: getState(),\n\t\t} );\n\n\t\treturn () => {\n\t\t\tconst state = getPersistedState( lastState, {\n\t\t\t\tnextState: getState(),\n\t\t\t} );\n\t\t\tif ( state !== lastState ) {\n\t\t\t\tpersistence.set( storeName, state );\n\t\t\t\tlastState = state;\n\t\t\t}\n\t\t};\n\t}\n\n\treturn {\n\t\tregisterStore(\n\t\t\tstoreName: string,\n\t\t\toptions: ReduxStoreConfig< any, any, any > & {\n\t\t\t\tpersist?: boolean | string[];\n\t\t\t}\n\t\t) {\n\t\t\tif ( ! options.persist ) {\n\t\t\t\treturn registry.registerStore( storeName, options );\n\t\t\t}\n\n\t\t\t// Load from persistence to use as initial state.\n\t\t\tconst persistedState = persistence.get()[ storeName ];\n\t\t\tif ( persistedState !== undefined ) {\n\t\t\t\tlet initialState = options.reducer( options.initialState, {\n\t\t\t\t\ttype: '@@WP/PERSISTENCE_RESTORE',\n\t\t\t\t} );\n\n\t\t\t\tif (\n\t\t\t\t\tisPlainObject( initialState ) &&\n\t\t\t\t\tisPlainObject( persistedState )\n\t\t\t\t) {\n\t\t\t\t\t// If state is an object, ensure that:\n\t\t\t\t\t// - Other keys are left intact when persisting only a\n\t\t\t\t\t//   subset of keys.\n\t\t\t\t\t// - New keys in what would otherwise be used as initial\n\t\t\t\t\t//   state are deeply merged as base for persisted value.\n\t\t\t\t\tinitialState = deepmerge(\n\t\t\t\t\t\tinitialState as Record< string, unknown >,\n\t\t\t\t\t\tpersistedState as Record< string, unknown >,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisMergeableObject: isPlainObject,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// If there is a mismatch in object-likeness of default\n\t\t\t\t\t// initial or persisted state, defer to persisted value.\n\t\t\t\t\tinitialState = persistedState;\n\t\t\t\t}\n\n\t\t\t\toptions = {\n\t\t\t\t\t...options,\n\t\t\t\t\tinitialState,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst store = registry.registerStore( storeName, options );\n\n\t\t\tstore.subscribe(\n\t\t\t\tcreatePersistOnChange(\n\t\t\t\t\tstore.getState,\n\t\t\t\t\tstoreName,\n\t\t\t\t\toptions.persist!\n\t\t\t\t)\n\t\t\t);\n\n\t\t\treturn store;\n\t\t},\n\t};\n}\n\nexport default Object.assign( persistencePlugin, {\n\t__unstableMigrate: () => {},\n} );\n"],
  "mappings": "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",
  "names": []
}
