diff --git a/README.md b/README.md index 80d0652..98b0ddd 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,8 @@ import { recoilPersist } from 'recoil-persist' const { persistAtom } = recoilPersist({ key: 'recoil-persist', // this key is using to store data in local storage storage: localStorage, // configurate which stroage will be used to store the data + stringify: JSON.stringify, + parser: JSON.parse, }) ``` @@ -133,6 +135,23 @@ type config.storage = Storage Set `config.storage` with `sessionStorage` or other `Storage` implementation to change storage target. Otherwise `localStorage` is used (default). + +```js +type config.stringify = Function +``` + +Set `config.stringify` with any method implementation to +change the saved data. Otherwise `JSON.stringify` is used (default). + + +```js +type config.parser = Function +``` + +Set `config.parser` with any method implementation to +change/transfer return data. Otherwise `JSON.parse` is used (default). + + ## Migration from version 1.x.x to 2.x.x The API changed from version 1.x.x. @@ -154,7 +173,7 @@ const { - ['count'], // no need for specifying atoms keys { key: 'recoil-persist', // configuration stay the same too - storage: localStorage + storage: localStorage, } ) diff --git a/src/index.ts b/src/index.ts index 45d1871..89737e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,8 @@ export interface PersistStorage { export interface PersistConfiguration { key?: string storage?: PersistStorage + stringify?: (value: any) => any + parser?: (value: any) => any } /** @@ -27,27 +29,34 @@ export const recoilPersist = ( } } - const { key = 'recoil-persist', storage = localStorage } = config - + const { + key = 'recoil-persist', + storage = localStorage, + stringify = JSON.stringify, + parser = JSON.parse, + } = config const persistAtom: AtomEffect = ({ onSet, node, trigger, setSelf }) => { if (trigger === 'get') { const state = getState() if (typeof state.then === 'function') { - state.then((s) => { - if (s.hasOwnProperty(node.key)) { + state.then((s: any) => { + if (s && s.hasOwnProperty(node.key)) { setSelf(s[node.key]) } }) } + if (state.hasOwnProperty(node.key)) { setSelf(state[node.key]) } } - onSet(async (newValue, _, isReset) => { + onSet((newValue, _, isReset) => { const state = getState() if (typeof state.then === 'function') { - state.then((s: any) => updateState(newValue, s, node.key, isReset)) + state.then((s: any) => + updateState(newValue, s ?? {}, node.key, isReset), + ) } else { updateState(newValue, state, node.key, isReset) } @@ -89,7 +98,7 @@ export const recoilPersist = ( return {} } try { - return JSON.parse(state) + return parser(state) } catch (e) { console.error(e) return {} @@ -99,9 +108,9 @@ export const recoilPersist = ( const setState = (state: any): void => { try { if (typeof storage.mergeItem === 'function') { - storage.mergeItem(key, JSON.stringify(state)) + storage.mergeItem(key, stringify(state)) } else { - storage.setItem(key, JSON.stringify(state)) + storage.setItem(key, stringify(state)) } } catch (e) { console.error(e)