From 6468a884fbd288c0947e0f6dfb7f2d5f3d376d96 Mon Sep 17 00:00:00 2001 From: Kim Ode Date: Tue, 1 Oct 2024 15:56:41 +0200 Subject: [PATCH] Add initialDataUpdatedAt --- packages/mst-query/src/MstQueryHandler.ts | 20 ++++++++---- packages/mst-query/src/hooks.ts | 5 +-- packages/mst-query/tests/mstQuery.test.tsx | 36 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/packages/mst-query/src/MstQueryHandler.ts b/packages/mst-query/src/MstQueryHandler.ts index e85de6b..7f3c416 100644 --- a/packages/mst-query/src/MstQueryHandler.ts +++ b/packages/mst-query/src/MstQueryHandler.ts @@ -80,8 +80,11 @@ export class QueryObserver { this.query.setData(null); } - if (!this.isMounted && !this.query.__MstQueryHandler.isFetched && options.initialData) { - this.query.__MstQueryHandler.hydrate(options); + if (!this.isMounted && options.initialData) { + const initialDataUpdatedAt = options.initialDataUpdatedAt ?? new Date(); + if (!isDataStale(initialDataUpdatedAt, options.staleTime)) { + this.query.__MstQueryHandler.hydrate(options); + } } this.query.__MstQueryHandler.queryWhenChanged(options); @@ -517,10 +520,11 @@ export class MstQueryHandler { } isStale(options: any) { - const now = new Date(); - const cachedAt = this.cachedAt?.getTime() ?? now.getTime(); - const isStale = now.getTime() - cachedAt >= (options.staleTime ?? 0); - return this.markedAsStale || isStale; + if (!this.cachedAt) { + return false; + } + + return this.markedAsStale || isDataStale(this.cachedAt.getTime(), options.staleTime); } onAfterCreate() { @@ -533,3 +537,7 @@ export class MstQueryHandler { this.abort(); } } + +function isDataStale(cachedAt: number, staleTime: number = 0) { + return Date.now() - cachedAt >= staleTime; +} diff --git a/packages/mst-query/src/hooks.ts b/packages/mst-query/src/hooks.ts index 5c59633..2594a97 100644 --- a/packages/mst-query/src/hooks.ts +++ b/packages/mst-query/src/hooks.ts @@ -23,6 +23,7 @@ type QueryOptions> = { staleTime?: number; enabled?: boolean; initialData?: any; + initialDataUpdatedAt?: number; meta?: { [key: string]: any }; }; @@ -66,11 +67,12 @@ export function useQuery>( observer.unsubscribe(); }; }, [options]); - + const data = isRequestEqual ? query.data : null; return { data: data as typeof query['data'], + dataUpdatedAt: query.__MstQueryHandler.cachedAt?.getTime(), error: query.error, isFetched: query.isFetched, isLoading: query.isLoading, @@ -78,7 +80,6 @@ export function useQuery>( isFetchingMore: query.isFetchingMore, query: query, refetch: query.refetch, - cachedAt: query.__MstQueryHandler.cachedAt, isStale: query.__MstQueryHandler.isStale(options), }; } diff --git a/packages/mst-query/tests/mstQuery.test.tsx b/packages/mst-query/tests/mstQuery.test.tsx index 7f2959e..83a3060 100644 --- a/packages/mst-query/tests/mstQuery.test.tsx +++ b/packages/mst-query/tests/mstQuery.test.tsx @@ -879,6 +879,42 @@ test('useQuery should not run when initialData is passed and staleTime is larger configureMobx({ enforceActions: 'observed' }); }); +test('useQuery should run when initialData is passed and initialDataUpdatedAt is older than staleTime', async () => { + const { render, q } = setup(); + + configureMobx({ enforceActions: 'never' }); + + let id = observable.box('test'); + const initialData = await api.getItem({ request: { id: id.get() } }); + const initialDataUpdatedAt = Date.now() - 1000; + + const loadingStates: boolean[] = []; + const Comp = observer(() => { + const { query, isLoading } = useQuery(q.itemQuery, { + initialData, + initialDataUpdatedAt, + request: { id: id.get() }, + staleTime: 500, + }); + loadingStates.push(isLoading); + return
; + }); + render(); + + await wait(0); + + expect(loadingStates).toEqual([false, true, false]); + expect(q.itemQuery.data?.id).toBe('test'); + + id.set('different-test'); + await wait(0); + expect(q.itemQuery.data?.id).toBe('different-test'); + expect(q.itemQuery.variables.request?.id).toBe('different-test'); + + configureMobx({ enforceActions: 'observed' }); +}); + + test('refetchOnMount & refetchOnRequestChanged', async () => { const { render, q } = setup();