Skip to content

Commit

Permalink
fix(solid-query): Fix reconciliation strategy for createBaseQuery (#7277
Browse files Browse the repository at this point in the history
)
  • Loading branch information
ardeora committed Apr 14, 2024
1 parent 4ce5509 commit 6c1af4e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
Expand Up @@ -557,7 +557,7 @@ describe('PersistQueryClientProvider', () => {
expect(queryFn2).toHaveBeenCalledTimes(1)
expect(onSuccess).toHaveBeenCalledTimes(1)

expect(states).toHaveLength(4)
expect(states).toHaveLength(3)

expect(states[0]).toMatchObject({
status: 'pending',
Expand All @@ -566,18 +566,12 @@ describe('PersistQueryClientProvider', () => {
})

expect(states[1]).toMatchObject({
status: 'pending',
fetchStatus: 'idle',
data: undefined,
})

expect(states[2]).toMatchObject({
status: 'success',
fetchStatus: 'fetching',
data: 'hydrated',
})

expect(states[3]).toMatchObject({
expect(states[2]).toMatchObject({
status: 'success',
fetchStatus: 'idle',
data: 'queryFn2',
Expand Down
4 changes: 3 additions & 1 deletion packages/solid-query/src/__tests__/createQuery.test.tsx
Expand Up @@ -1051,7 +1051,9 @@ describe('createQuery', () => {
count++
return count === 1 ? result1 : result2
},
reconcile: 'id',
reconcile: (oldData, newData) => {
return reconcile(newData)(oldData)
},
}))

createRenderEffect(() => {
Expand Down
29 changes: 24 additions & 5 deletions packages/solid-query/src/createBaseQuery.ts
Expand Up @@ -34,13 +34,31 @@ function reconcileFn<TData, TError>(
| string
| false
| ((oldData: TData | undefined, newData: TData) => TData),
queryHash?: string,
): QueryObserverResult<TData, TError> {
if (reconcileOption === false) return result
if (typeof reconcileOption === 'function') {
const newData = reconcileOption(store.data, result.data as TData)
return { ...result, data: newData } as typeof result
}
const newData = reconcile(result.data, { key: reconcileOption })(store.data)
let data = result.data
if (store.data === undefined) {
try {
data = structuredClone(data)
} catch (error) {
if (process.env.NODE_ENV !== 'production') {
if (error instanceof Error) {
console.warn(
`Unable to correctly reconcile data for query key: ${queryHash}. ` +
`Possibly because the query data contains data structures that aren't supported ` +
`by the 'structuredClone' algorithm. Consider using a callback function instead ` +
`to manage the reconciliation manually.\n\n Error Received: ${error.name} - ${error.message}`,
)
}
}
}
}
const newData = reconcile(data, { key: reconcileOption })(store.data)
return { ...result, data: newData } as typeof result
}

Expand Down Expand Up @@ -186,14 +204,16 @@ export function createBaseQuery<
}

function setStateWithReconciliation(res: typeof observerResult) {
const opts = observer().options
// @ts-expect-error - Reconcile option is not correctly typed internally
const reconcileOptions = observer().options.reconcile
const reconcileOptions = opts.reconcile

setState((store) => {
return reconcileFn(
store,
res,
reconcileOptions === undefined ? false : reconcileOptions,
opts.queryHash,
)
})
}
Expand Down Expand Up @@ -290,7 +310,7 @@ export function createBaseQuery<
// Setting the options as an immutable object to prevent
// wonky behavior with observer subscriptions
observer().setOptions(newOptions)
setState(observer().getOptimisticResult(newOptions))
setStateWithReconciliation(observer().getOptimisticResult(newOptions))
unsubscribe = createClientSubscriber()
},
},
Expand Down Expand Up @@ -353,8 +373,7 @@ export function createBaseQuery<
prop: keyof QueryObserverResult<TData, TError>,
): any {
if (prop === 'data') {
const opts = observer().options
if (opts.placeholderData) {
if (state.data !== undefined) {
return queryResource.latest?.data
}
return queryResource()?.data
Expand Down

0 comments on commit 6c1af4e

Please sign in to comment.