@@ -91,16 +91,12 @@ export function experimental_createPersister<TStorageValue = string>({
91
91
prefix = PERSISTER_KEY_PREFIX ,
92
92
filters,
93
93
} : StoragePersisterOptions < TStorageValue > ) {
94
- return async function persisterFn < T , TQueryKey extends QueryKey > (
95
- queryFn : ( context : QueryFunctionContext < TQueryKey > ) => T | Promise < T > ,
96
- context : QueryFunctionContext < TQueryKey > ,
97
- query : Query ,
94
+ async function restoreQuery < T > (
95
+ queryHash : string ,
96
+ afterRestoreMacroTask ?: ( persistedQuery : PersistedQuery ) => void ,
98
97
) {
99
- const storageKey = `${ prefix } -${ query . queryHash } `
100
- const matchesFilter = filters ? matchQuery ( filters , query ) : true
101
-
102
- // Try to restore only if we do not have any data in the cache and we have persister defined
103
- if ( matchesFilter && query . state . data === undefined && storage != null ) {
98
+ if ( storage != null ) {
99
+ const storageKey = `${ prefix } -${ queryHash } `
104
100
try {
105
101
const storedData = await storage . getItem ( storageKey )
106
102
if ( storedData ) {
@@ -113,20 +109,12 @@ export function experimental_createPersister<TStorageValue = string>({
113
109
if ( expired || busted ) {
114
110
await storage . removeItem ( storageKey )
115
111
} else {
116
- // Just after restoring we want to get fresh data from the server if it's stale
117
- setTimeout ( ( ) => {
118
- // Set proper updatedAt, since resolving in the first pass overrides those values
119
- query . setState ( {
120
- dataUpdatedAt : persistedQuery . state . dataUpdatedAt ,
121
- errorUpdatedAt : persistedQuery . state . errorUpdatedAt ,
122
- } )
123
-
124
- if ( query . isStale ( ) ) {
125
- query . fetch ( )
126
- }
127
- } , 0 )
112
+ if ( afterRestoreMacroTask ) {
113
+ // Just after restoring we want to get fresh data from the server if it's stale
114
+ setTimeout ( ( ) => afterRestoreMacroTask ( persistedQuery ) , 0 )
115
+ }
128
116
// We must resolve the promise here, as otherwise we will have `loading` state in the app until `queryFn` resolves
129
- return Promise . resolve ( persistedQuery . state . data as T )
117
+ return persistedQuery . state . data as T
130
118
}
131
119
} else {
132
120
await storage . removeItem ( storageKey )
@@ -143,24 +131,69 @@ export function experimental_createPersister<TStorageValue = string>({
143
131
}
144
132
}
145
133
134
+ return
135
+ }
136
+
137
+ async function persistQuery ( query : Query ) {
138
+ if ( storage != null ) {
139
+ const storageKey = `${ prefix } -${ query . queryHash } `
140
+ storage . setItem (
141
+ storageKey ,
142
+ await serialize ( {
143
+ state : query . state ,
144
+ queryKey : query . queryKey ,
145
+ queryHash : query . queryHash ,
146
+ buster : buster ,
147
+ } ) ,
148
+ )
149
+ }
150
+ }
151
+
152
+ async function persisterFn < T , TQueryKey extends QueryKey > (
153
+ queryFn : ( context : QueryFunctionContext < TQueryKey > ) => T | Promise < T > ,
154
+ ctx : QueryFunctionContext < TQueryKey > ,
155
+ query : Query ,
156
+ ) {
157
+ const matchesFilter = filters ? matchQuery ( filters , query ) : true
158
+
159
+ // Try to restore only if we do not have any data in the cache and we have persister defined
160
+ if ( matchesFilter && query . state . data === undefined && storage != null ) {
161
+ const restoredData = await restoreQuery (
162
+ query . queryHash ,
163
+ ( persistedQuery : PersistedQuery ) => {
164
+ // Set proper updatedAt, since resolving in the first pass overrides those values
165
+ query . setState ( {
166
+ dataUpdatedAt : persistedQuery . state . dataUpdatedAt ,
167
+ errorUpdatedAt : persistedQuery . state . errorUpdatedAt ,
168
+ } )
169
+
170
+ if ( query . isStale ( ) ) {
171
+ query . fetch ( )
172
+ }
173
+ } ,
174
+ )
175
+
176
+ if ( restoredData != null ) {
177
+ return Promise . resolve ( restoredData as T )
178
+ }
179
+ }
180
+
146
181
// If we did not restore, or restoration failed - fetch
147
- const queryFnResult = await queryFn ( context )
182
+ const queryFnResult = await queryFn ( ctx )
148
183
149
184
if ( matchesFilter && storage != null ) {
150
185
// Persist if we have storage defined, we use timeout to get proper state to be persisted
151
- setTimeout ( async ( ) => {
152
- storage . setItem (
153
- storageKey ,
154
- await serialize ( {
155
- state : query . state ,
156
- queryKey : query . queryKey ,
157
- queryHash : query . queryHash ,
158
- buster : buster ,
159
- } ) ,
160
- )
186
+ setTimeout ( ( ) => {
187
+ persistQuery ( query )
161
188
} , 0 )
162
189
}
163
190
164
191
return Promise . resolve ( queryFnResult )
165
192
}
193
+
194
+ return {
195
+ persisterFn,
196
+ persistQuery,
197
+ restoreQuery,
198
+ }
166
199
}
0 commit comments