Skip to content

feat: add optional functions to serialize and deserialize from Storage Persistors #2864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/src/pages/plugins/createAsyncStoragePersistor.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ interface CreateAsyncStoragePersistorOptions {
/** To avoid localstorage spamming,
* pass a time in ms to throttle saving the cache to disk */
throttleTime?: number
/** How to serialize the data to storage */
serialize?: (client: PersistedClient) => string
/** How to deserialize the data from storage */
deserialize?: (cachedString: string) => PersistedClient
}

interface AsyncStorage {
Expand All @@ -75,5 +79,7 @@ The default options are:
{
key = `REACT_QUERY_OFFLINE_CACHE`,
throttleTime = 1000,
serialize = JSON.stringify,
deserialize = JSON.parse,
}
```
6 changes: 6 additions & 0 deletions docs/src/pages/plugins/createWebStoragePersistor.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ interface CreateWebStoragePersistorOptions {
/** To avoid spamming,
* pass a time in ms to throttle saving the cache to disk */
throttleTime?: number
/** How to serialize the data to storage */
serialize?: (client: PersistedClient) => string
/** How to deserialize the data from storage */
deserialize?: (cachedString: string) => PersistedClient
}
```

Expand All @@ -66,5 +70,7 @@ The default options are:
{
key = `REACT_QUERY_OFFLINE_CACHE`,
throttleTime = 1000,
serialize = JSON.stringify,
deserialize = JSON.parse,
}
```
24 changes: 18 additions & 6 deletions src/createAsyncStoragePersistor-experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,28 @@ interface CreateAsyncStoragePersistorOptions {
/** To avoid spamming,
* pass a time in ms to throttle saving the cache to disk */
throttleTime?: number
/**
* How to serialize the data to storage.
* @default `JSON.stringify`
*/
serialize?: (client: PersistedClient) => string
/**
* How to deserialize the data from storage.
* @default `JSON.parse`
*/
deserialize?: (cachedString: string) => PersistedClient
}

export const createAsyncStoragePersistor = ({
storage,
key = `REACT_QUERY_OFFLINE_CACHE`,
throttleTime = 1000,
serialize = JSON.stringify,
deserialize = JSON.parse,
}: CreateAsyncStoragePersistorOptions): Persistor => {
return {
persistClient: asyncThrottle(
persistedClient => storage.setItem(key, JSON.stringify(persistedClient)),
persistedClient => storage.setItem(key, serialize(persistedClient)),
{ interval: throttleTime }
),
restoreClient: async () => {
Expand All @@ -33,22 +45,22 @@ export const createAsyncStoragePersistor = ({
return
}

return JSON.parse(cacheString) as PersistedClient
return deserialize(cacheString) as PersistedClient
},
removeClient: () => storage.removeItem(key),
}
}

function asyncThrottle<T>(
func: (...args: ReadonlyArray<unknown>) => Promise<T>,
function asyncThrottle<Args extends readonly unknown[], Result>(
func: (...args: Args) => Promise<Result>,
{ interval = 1000, limit = 1 }: { interval?: number; limit?: number } = {}
) {
if (typeof func !== 'function') throw new Error('argument is not function.')
const running = { current: false }
let lastTime = 0
let timeout: number
const queue: Array<any[]> = []
return (...args: any) =>
const queue: Array<Args> = []
return (...args: Args) =>
(async () => {
if (running.current) {
lastTime = Date.now()
Expand Down
16 changes: 14 additions & 2 deletions src/createWebStoragePersistor-experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,29 @@ interface CreateWebStoragePersistorOptions {
/** To avoid spamming,
* pass a time in ms to throttle saving the cache to disk */
throttleTime?: number
/**
* How to serialize the data to storage.
* @default `JSON.stringify`
*/
serialize?: (client: PersistedClient) => string
/**
* How to deserialize the data from storage.
* @default `JSON.parse`
*/
deserialize?: (cachedString: string) => PersistedClient
}

export function createWebStoragePersistor({
storage,
key = `REACT_QUERY_OFFLINE_CACHE`,
throttleTime = 1000,
serialize = JSON.stringify,
deserialize = JSON.parse,
}: CreateWebStoragePersistorOptions): Persistor {
if (typeof storage !== 'undefined') {
return {
persistClient: throttle(persistedClient => {
storage.setItem(key, JSON.stringify(persistedClient))
storage.setItem(key, serialize(persistedClient))
}, throttleTime),
restoreClient: () => {
const cacheString = storage.getItem(key)
Expand All @@ -28,7 +40,7 @@ export function createWebStoragePersistor({
return
}

return JSON.parse(cacheString) as PersistedClient
return deserialize(cacheString) as PersistedClient
},
removeClient: () => {
storage.removeItem(key)
Expand Down