Skip to content

Commit f061ee7

Browse files
committed
fix(query): pagination + cache-and-fetch + gc was incorrectly gcing items from previous pages
1 parent ec7c7d1 commit f061ee7

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

packages/vue/src/query.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,12 @@ export function createQuery<
467467
}).then(async (backgroundResult) => {
468468
const { valid } = await setPageResult(page, savedPageRequestId, backgroundResult)
469469
if (valid && queryTracking && newQueryTracking2) {
470-
queryTracking.handleQueryTracking(page.id, newQueryTracking2, undefined, finalOptions.include)
470+
queryTracking.handleQueryTracking(page.id, newQueryTracking2, undefined, finalOptions.include, page.main)
471471
}
472472
})
473+
474+
// We don't use the builtin 'cache-and-fetch' of `find*' methods to have better control over query tracking handling
475+
finalOptions.fetchPolicy = 'cache-only'
473476
}
474477

475478
// On refresh force fetch

packages/vue/src/tracking.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function useQueryTracking<TResult>(options: UseQueryTrackingOptions<TResu
3434
return res
3535
})
3636

37-
function handleQueryTracking(id: string, newQueryTracking: HookMetaQueryTracking, result?: TResult, include: FindOptionsInclude<Collection, CollectionDefaults, StoreSchema> = {}, markPreviousItemsAsDirty: boolean = true) {
37+
function handleQueryTracking(id: string, newQueryTracking: HookMetaQueryTracking, result: TResult | undefined, include: FindOptionsInclude<Collection, CollectionDefaults, StoreSchema> | undefined, markPreviousItemsAsDirty: boolean) {
3838
if (newQueryTracking.skipped) {
3939
return
4040
}
@@ -47,6 +47,8 @@ export function useQueryTracking<TResult>(options: UseQueryTrackingOptions<TResu
4747

4848
// Init the query tracking object if the result is not empty and there is no previous tracking
4949
if (!isResultEmpty && !queryTracking) {
50+
include ??= {}
51+
5052
const keys = Object.keys(newQueryTracking.items)
5153
const isNewQueryTrackingEmpty = keys.length === 0 || keys.every(k => newQueryTracking.items[k]!.size === 0)
5254

packages/vue/test/query.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,5 +599,44 @@ describe('query', () => {
599599
expect(query.pages.value[1]?.data[0]?.text).toBe('Message 3')
600600
expect(query.pages.value[1]?.data[1]?.text).toBe('New Message')
601601
})
602+
603+
it('should load pages with cache-and-fetch and gc', async () => {
604+
const fetchMessages = (pageIndex?: number) => {
605+
return [
606+
{ id: `message${pageIndex! * 2 + 1}`, text: `Message ${pageIndex! * 2 + 1}` },
607+
{ id: `message${pageIndex! * 2 + 2}`, text: `Message ${pageIndex! * 2 + 2}` },
608+
]
609+
}
610+
const store = await createStore({
611+
schema: [
612+
{
613+
name: 'messages',
614+
hooks: {
615+
fetchMany: ({ pageIndex }) => fetchMessages(pageIndex),
616+
},
617+
},
618+
],
619+
plugins: [],
620+
})
621+
622+
const query = await store.messages.query(q => q.many({
623+
pageIndex: 0,
624+
pageSize: 2,
625+
fetchPolicy: 'cache-and-fetch',
626+
experimentalGarbageCollection: true,
627+
}))
628+
629+
expect(query.data.value?.length).toBe(2)
630+
631+
await query.fetchMore({
632+
pageIndex: 1,
633+
})
634+
635+
expect(query.data.value?.length).toBe(4)
636+
expect(query.data.value?.[0]?.text).toBe('Message 1')
637+
expect(query.data.value?.[1]?.text).toBe('Message 2')
638+
expect(query.data.value?.[2]?.text).toBe('Message 3')
639+
expect(query.data.value?.[3]?.text).toBe('Message 4')
640+
})
602641
})
603642
})

0 commit comments

Comments
 (0)