Skip to content

Commit

Permalink
feat(persistQueryClient): add optional functions to serialize and des…
Browse files Browse the repository at this point in the history
…erialize from Storage Persistors (#2864)
  • Loading branch information
bengry committed Oct 31, 2021
1 parent 69a5d79 commit 8013d4a
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
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

1 comment on commit 8013d4a

@vercel
Copy link

@vercel vercel bot commented on 8013d4a Oct 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.