From ae17e3002e731c34e6abfbf9ceb14b84b780a329 Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 1 Dec 2023 11:43:32 +0100 Subject: [PATCH 1/6] feat: add prefetch --- .changeset/fresh-spoons-dream.md | 7 ++ .../postgrest-core/__tests__/index.spec.ts | 2 +- .../src/offset-pagination-fetcher.ts | 97 ++++++++++++--- .../query/use-query.integration.spec.tsx | 27 ++++- .../postgrest-react-query/src/query/index.ts | 1 + .../src/query/prefetch.ts | 62 ++++++++++ ...offset-infinite-query.integration.spec.tsx | 28 +++-- ...infinite-scroll-query.integration.spec.tsx | 36 +++--- .../use-pagination-query.integration.spec.tsx | 35 +++--- .../query/use-query.integration.spec.tsx | 58 +++++---- .../src/lib/create-key-getter.ts | 1 - packages/postgrest-swr/src/query/index.ts | 1 + packages/postgrest-swr/src/query/prefetch.ts | 112 ++++++++++++++++++ .../src/query/use-offset-infinite-query.ts | 2 + .../query/use-offset-infinite-scroll-query.ts | 2 + 15 files changed, 388 insertions(+), 83 deletions(-) create mode 100644 .changeset/fresh-spoons-dream.md create mode 100644 packages/postgrest-react-query/src/query/prefetch.ts create mode 100644 packages/postgrest-swr/src/query/prefetch.ts diff --git a/.changeset/fresh-spoons-dream.md b/.changeset/fresh-spoons-dream.md new file mode 100644 index 00000000..d693d0f5 --- /dev/null +++ b/.changeset/fresh-spoons-dream.md @@ -0,0 +1,7 @@ +--- +"@supabase-cache-helpers/postgrest-react-query": minor +"@supabase-cache-helpers/postgrest-core": minor +"@supabase-cache-helpers/postgrest-swr": minor +--- + +feat: add prefetch diff --git a/packages/postgrest-core/__tests__/index.spec.ts b/packages/postgrest-core/__tests__/index.spec.ts index 31febb70..b0f4cc65 100644 --- a/packages/postgrest-core/__tests__/index.spec.ts +++ b/packages/postgrest-core/__tests__/index.spec.ts @@ -2,6 +2,6 @@ import * as Import from '../src'; describe('index exports', () => { it('should export', () => { - expect(Object.keys(Import)).toHaveLength(36); + expect(Object.keys(Import)).toHaveLength(38); }); }); diff --git a/packages/postgrest-core/src/offset-pagination-fetcher.ts b/packages/postgrest-core/src/offset-pagination-fetcher.ts index 6b86eb42..77e3970b 100644 --- a/packages/postgrest-core/src/offset-pagination-fetcher.ts +++ b/packages/postgrest-core/src/offset-pagination-fetcher.ts @@ -20,6 +20,7 @@ export const createOffsetPaginationFetcher = < Row extends Record, Result, Args, + RelationName = unknown, Relationships = unknown, >( query: PostgrestTransformBuilder | null, @@ -34,19 +35,52 @@ export const createOffsetPaginationFetcher = < const decodedKey = decode(args); const limit = (decodedKey.limit ? decodedKey.limit - 1 : pageSize) - 1; const offset = decodedKey.offset ?? 0; - const { data } = await query.range(offset, offset + limit).throwOnError(); - // cannot be null because of .throwOnError() - return data as Result[]; + return await offsetPaginationFetcher< + Schema, + Row, + Result, + RelationName, + Relationships + >(query, { limit, offset }); }; }; +export const offsetPaginationFetcher = async < + Schema extends GenericSchema, + Row extends Record, + Result, + RelationName = unknown, + Relationships = unknown, +>( + query: PostgrestTransformBuilder< + Schema, + Row, + Result[], + RelationName, + Relationships + >, + { limit, offset }: { limit: number; offset: number }, +) => { + const { data } = await query.range(offset, offset + limit).throwOnError(); + // cannot be null because of .throwOnError() + return data as Result[]; +}; + export const createOffsetPaginationHasMoreFetcher = < Schema extends GenericSchema, Row extends Record, Result, Args, + RelationName = unknown, + Relationships = unknown, >( - query: PostgrestTransformBuilder | null, + query: PostgrestTransformBuilder< + Schema, + Row, + Result[], + RelationName, + Relationships + > | null, decode: PostgrestOffsetPaginationKeyDecoder, pageSize: number, ): PostgrestOffsetPaginationFetcher< @@ -58,16 +92,49 @@ export const createOffsetPaginationHasMoreFetcher = < const decodedKey = decode(args); const limit = decodedKey.limit ? decodedKey.limit - 1 : pageSize; const offset = decodedKey.offset ?? 0; - const { data } = await query.range(offset, offset + limit).throwOnError(); - let hasMore = false; - if (data && data.length === pageSize + 1) { - hasMore = true; - data.pop(); - } - return { - // cannot be null because of .throwOnError() - data: data as Result[], - hasMore, - }; + return await offsetPaginationHasMoreFetcher< + Schema, + Row, + Result, + RelationName, + Relationships + >(query, { + limit, + offset, + pageSize, + }); + }; +}; + +export const offsetPaginationHasMoreFetcher = async < + Schema extends GenericSchema, + Row extends Record, + Result, + RelationName = unknown, + Relationships = unknown, +>( + query: PostgrestTransformBuilder< + Schema, + Row, + Result[], + RelationName, + Relationships + >, + { + limit, + offset, + pageSize, + }: { limit: number; offset: number; pageSize: number }, +) => { + const { data } = await query.range(offset, offset + limit).throwOnError(); + let hasMore = false; + if (data && data.length === pageSize + 1) { + hasMore = true; + data.pop(); + } + return { + // cannot be null because of .throwOnError() + data: data as Result[], + hasMore, }; }; diff --git a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx index 244b8b35..a0cbc062 100644 --- a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx @@ -3,7 +3,7 @@ import { QueryClient } from '@tanstack/react-query'; import { fireEvent, screen } from '@testing-library/react'; import React, { useState } from 'react'; -import { useQuery } from '../../src'; +import { prefetchQuery, useQuery } from '../../src'; import { encode } from '../../src/lib/key'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -173,4 +173,29 @@ describe('useQuery', () => { fireEvent.click(screen.getByTestId('mutate')); await screen.findByText('refetched: true', {}, { timeout: 10000 }); }); + + it('prefetch should work', async () => { + const queryClient = new QueryClient(); + const query = client + .from('contact') + .select('id,username') + .eq('username', contacts[0].username ?? '') + .single(); + await prefetchQuery(queryClient, query); + let hasBeenFalse = false; + function Page() { + const { data } = useQuery(query); + if (!data) hasBeenFalse = true; + + return ( +
+
{data?.username ?? 'undefined'}
+
+ ); + } + + renderWithConfig(, queryClient); + expect(hasBeenFalse).toBe(false); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); + }); }); diff --git a/packages/postgrest-react-query/src/query/index.ts b/packages/postgrest-react-query/src/query/index.ts index 1a179f58..07f005ea 100644 --- a/packages/postgrest-react-query/src/query/index.ts +++ b/packages/postgrest-react-query/src/query/index.ts @@ -1 +1,2 @@ +export * from './prefetch'; export * from './use-query'; diff --git a/packages/postgrest-react-query/src/query/prefetch.ts b/packages/postgrest-react-query/src/query/prefetch.ts new file mode 100644 index 00000000..3796c754 --- /dev/null +++ b/packages/postgrest-react-query/src/query/prefetch.ts @@ -0,0 +1,62 @@ +import { + PostgrestError, + PostgrestMaybeSingleResponse, + PostgrestResponse, + PostgrestSingleResponse, +} from '@supabase/postgrest-js'; +import { + AnyPostgrestResponse, + isPostgrestBuilder, +} from '@supabase-cache-helpers/postgrest-core'; +import { FetchQueryOptions, QueryClient } from '@tanstack/react-query'; + +import { encode } from '../lib'; + +function prefetchQuery( + queryClient: QueryClient, + query: PromiseLike>, + config?: Omit< + FetchQueryOptions, PostgrestError>, + 'queryKey' | 'queryFn' + >, +): Promise; +function prefetchQuery( + queryClient: QueryClient, + query: PromiseLike>, + config?: Omit< + FetchQueryOptions, PostgrestError>, + 'queryKey' | 'queryFn' + >, +): Promise; +function prefetchQuery( + queryClient: QueryClient, + query: PromiseLike>, + config?: Omit< + FetchQueryOptions, PostgrestError>, + 'queryKey' | 'queryFn' + >, +): Promise; + +async function prefetchQuery( + queryClient: QueryClient, + query: PromiseLike>, + config?: Omit< + FetchQueryOptions, PostgrestError>, + 'queryKey' | 'queryFn' + >, +) { + await queryClient.prefetchQuery, PostgrestError>( + { + queryKey: encode(query, false), + queryFn: async () => { + if (isPostgrestBuilder(query)) { + query = query.throwOnError(); + } + return await query; + }, + ...config, + }, + ); +} + +export { prefetchQuery }; diff --git a/packages/postgrest-swr/__tests__/query/use-offset-infinite-query.integration.spec.tsx b/packages/postgrest-swr/__tests__/query/use-offset-infinite-query.integration.spec.tsx index 6a587968..5641b48e 100644 --- a/packages/postgrest-swr/__tests__/query/use-offset-infinite-query.integration.spec.tsx +++ b/packages/postgrest-swr/__tests__/query/use-offset-infinite-query.integration.spec.tsx @@ -2,7 +2,10 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { fireEvent, screen } from '@testing-library/react'; import React, { useState } from 'react'; -import { useOffsetInfiniteQuery } from '../../src'; +import { + fetchOffsetPaginationFallbackData, + useOffsetInfiniteQuery, +} from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -98,18 +101,17 @@ describe('useOffsetInfiniteQuery', () => { }); it('should work with fallbackData', async () => { + const query = client + .from('contact') + .select('id,username') + .ilike('username', `${testRunPrefix}%`) + .order('username', { ascending: true }); + const [_, fallbackData] = await fetchOffsetPaginationFallbackData(query, 1); function Page() { - const { data, size } = useOffsetInfiniteQuery( - client - .from('contact') - .select('id,username') - .ilike('username', `${testRunPrefix}%`) - .order('username', { ascending: true }), - { - pageSize: 1, - fallbackData: [[{ id: 'test', username: 'fallback' }]], - }, - ); + const { data, size } = useOffsetInfiniteQuery(null, { + pageSize: 1, + fallbackData, + }); return (
@@ -124,6 +126,6 @@ describe('useOffsetInfiniteQuery', () => { renderWithConfig(, { provider: () => provider }); - await screen.findByText(`fallback`, {}, { timeout: 10000 }); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); }); }); diff --git a/packages/postgrest-swr/__tests__/query/use-offset-infinite-scroll-query.integration.spec.tsx b/packages/postgrest-swr/__tests__/query/use-offset-infinite-scroll-query.integration.spec.tsx index 4e8cf774..c1af4268 100644 --- a/packages/postgrest-swr/__tests__/query/use-offset-infinite-scroll-query.integration.spec.tsx +++ b/packages/postgrest-swr/__tests__/query/use-offset-infinite-scroll-query.integration.spec.tsx @@ -1,8 +1,12 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { fireEvent, screen } from '@testing-library/react'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { useSWRConfig } from 'swr'; -import { useOffsetInfiniteScrollQuery } from '../../src'; +import { + fetchOffsetPaginationHasMoreFallbackData, + useOffsetInfiniteScrollQuery, +} from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -128,20 +132,20 @@ describe('useOffsetInfiniteScrollQuery', () => { }); it('should work with fallback data', async () => { + const query = client + .from('contact') + .select('id,username') + .ilike('username', `${testRunPrefix}%`) + .order('username', { ascending: true }); + const [_, fallbackData] = await fetchOffsetPaginationHasMoreFallbackData( + query, + 1, + ); function Page() { - const { data } = useOffsetInfiniteScrollQuery( - client - .from('contact') - .select('id,username') - .ilike('username', `${testRunPrefix}%`) - .order('username', { ascending: true }), - { - pageSize: 1, - fallbackData: [ - { data: [{ username: 'fallback', id: 'test' }], hasMore: false }, - ], - }, - ); + const { data } = useOffsetInfiniteScrollQuery(null, { + pageSize: 1, + fallbackData, + }); return (
@@ -152,6 +156,6 @@ describe('useOffsetInfiniteScrollQuery', () => { } renderWithConfig(, { provider: () => provider }); - await screen.findByText('fallback', {}, { timeout: 10000 }); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); }); }); diff --git a/packages/postgrest-swr/__tests__/query/use-pagination-query.integration.spec.tsx b/packages/postgrest-swr/__tests__/query/use-pagination-query.integration.spec.tsx index 90cd6b71..7bb63178 100644 --- a/packages/postgrest-swr/__tests__/query/use-pagination-query.integration.spec.tsx +++ b/packages/postgrest-swr/__tests__/query/use-pagination-query.integration.spec.tsx @@ -2,7 +2,10 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { fireEvent, screen } from '@testing-library/react'; import React, { useState } from 'react'; -import { useInfiniteOffsetPaginationQuery } from '../../src'; +import { + useInfiniteOffsetPaginationQuery, + fetchOffsetPaginationHasMoreFallbackData, +} from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -188,22 +191,22 @@ describe('useInfiniteOffsetPaginationQuery', () => { }); it('fallbackData should work', async () => { + const q = client + .from('contact') + .select('id,username') + .ilike('username', `${testRunPrefix}%`) + .order('username', { ascending: true }); + const [_, fallbackData] = await fetchOffsetPaginationHasMoreFallbackData( + q, + 1, + ); function Page() { const { currentPage, isLoading, setPage } = - useInfiniteOffsetPaginationQuery( - client - .from('contact') - .select('id,username') - .ilike('username', `${testRunPrefix}%`) - .order('username', { ascending: true }), - { - pageSize: 1, - revalidateOnReconnect: true, - fallbackData: [ - { data: [{ id: 'test', username: 'fallback' }], hasMore: true }, - ], - }, - ); + useInfiniteOffsetPaginationQuery(null, { + pageSize: 1, + revalidateOnReconnect: true, + fallbackData, + }); return (
setPage(3)} /> @@ -216,6 +219,6 @@ describe('useInfiniteOffsetPaginationQuery', () => { } renderWithConfig(, { provider: () => provider }); - await screen.findByText('fallback', {}, { timeout: 10000 }); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); }); }); diff --git a/packages/postgrest-swr/__tests__/query/use-query.integration.spec.tsx b/packages/postgrest-swr/__tests__/query/use-query.integration.spec.tsx index 546c4ba6..59ddd472 100755 --- a/packages/postgrest-swr/__tests__/query/use-query.integration.spec.tsx +++ b/packages/postgrest-swr/__tests__/query/use-query.integration.spec.tsx @@ -2,7 +2,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { fireEvent, screen } from '@testing-library/react'; import React, { useState } from 'react'; -import { useQuery } from '../../src'; +import { fetchQueryFallbackData, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -191,31 +191,49 @@ describe('useQuery', () => { }); it('should work with fallbackData', async () => { + const q = client + .from('contact') + .select('id,username') + .eq('username', contacts[0].username!) + .single(); + const [_, fallbackData] = await fetchQueryFallbackData(q); function Page() { - const { data } = useQuery( - !contacts[0].username - ? null - : client - .from('contact') - .select('id,username') - .eq('username', contacts[0].username) - .single(), - { - revalidateOnFocus: false, - fallbackData: { - data: { username: 'fallback', id: 'id' }, - status: 200, - error: null, - count: 0, - statusText: 'OK', - }, - }, - ); + const { data } = useQuery(null, { + revalidateOnFocus: false, + fallbackData, + }); return
{data?.username}
; } renderWithConfig(, { provider: () => provider }); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); + }); + + it('should work with global fallbackData', async () => { + const q = client + .from('contact') + .select('id,username') + .eq('username', contacts[0].username!) + .single(); + const [key, fallbackData] = await fetchQueryFallbackData(q); + function Page() { + const { data } = useQuery(q, { + revalidateOnFocus: true, + }); + + return
{data?.username}
; + } + + renderWithConfig(, { + provider: () => provider, + fallback: { + [key]: { + ...fallbackData, + data: { ...fallbackData.data, username: 'fallback' }, + }, + }, + }); await screen.findByText('fallback', {}, { timeout: 10000 }); }); }); diff --git a/packages/postgrest-swr/src/lib/create-key-getter.ts b/packages/postgrest-swr/src/lib/create-key-getter.ts index 2e87379d..db656d4e 100644 --- a/packages/postgrest-swr/src/lib/create-key-getter.ts +++ b/packages/postgrest-swr/src/lib/create-key-getter.ts @@ -3,7 +3,6 @@ import { GenericSchema } from '@supabase/postgrest-js/dist/module/types'; import { setFilterValue, get, - OrderDefinition, isPostgrestHasMorePaginationResponse, isPostgrestPaginationResponse, PostgrestHasMorePaginationResponse, diff --git a/packages/postgrest-swr/src/query/index.ts b/packages/postgrest-swr/src/query/index.ts index 1417c86e..57a1dec4 100644 --- a/packages/postgrest-swr/src/query/index.ts +++ b/packages/postgrest-swr/src/query/index.ts @@ -1,3 +1,4 @@ +export * from './prefetch'; export * from './use-cursor-infinite-scroll-query'; export * from './use-offset-infinite-query'; export * from './use-offset-infinite-scroll-query'; diff --git a/packages/postgrest-swr/src/query/prefetch.ts b/packages/postgrest-swr/src/query/prefetch.ts new file mode 100644 index 00000000..c5f8f140 --- /dev/null +++ b/packages/postgrest-swr/src/query/prefetch.ts @@ -0,0 +1,112 @@ +import { + PostgrestResponse, + PostgrestSingleResponse, + PostgrestMaybeSingleResponse, + PostgrestTransformBuilder, +} from '@supabase/postgrest-js'; +import { GenericSchema } from '@supabase/postgrest-js/dist/module/types'; +import { + AnyPostgrestResponse, + PostgrestParser, + isPostgrestBuilder, + offsetPaginationFetcher, + offsetPaginationHasMoreFetcher, +} from '@supabase-cache-helpers/postgrest-core'; + +import { encode } from '../lib'; + +function fetchQueryFallbackData( + query: PromiseLike>, +): Promise<[string, PostgrestSingleResponse]>; + +function fetchQueryFallbackData( + query: PromiseLike>, +): Promise<[string, PostgrestMaybeSingleResponse]>; + +function fetchQueryFallbackData( + query: PromiseLike>, +): Promise<[string, PostgrestResponse]>; + +async function fetchQueryFallbackData( + query: PromiseLike>, +): Promise<[string, AnyPostgrestResponse]> { + if (!isPostgrestBuilder(query)) { + throw new Error('Query is not a PostgrestBuilder'); + } + + return [ + encode(new PostgrestParser(query), false), + await query.throwOnError(), + ]; +} + +async function fetchOffsetPaginationHasMoreFallbackData< + Schema extends GenericSchema, + Table extends Record, + Result extends Record, + RelationName = unknown, + Relationships = unknown, +>( + query: PostgrestTransformBuilder< + Schema, + Table, + Result[], + RelationName, + Relationships + >, + pageSize: number, +): Promise< + [ + string, + [ + { + data: Result[]; + hasMore: boolean; + }, + ], + ] +> { + return [ + encode(new PostgrestParser(query.range(0, pageSize)), true), + [ + await offsetPaginationHasMoreFetcher(query, { + offset: 0, + limit: pageSize, + pageSize, + }), + ], + ]; +} + +const fetchOffsetPaginationFallbackData = async < + Schema extends GenericSchema, + Table extends Record, + Result extends Record, + RelationName = unknown, + Relationships = unknown, +>( + query: PostgrestTransformBuilder< + Schema, + Table, + Result[], + RelationName, + Relationships + >, + pageSize: number, +): Promise<[string, [Result[]]]> => { + return [ + encode(new PostgrestParser(query.range(0, pageSize)), true), + [ + await offsetPaginationFetcher(query, { + offset: 0, + limit: pageSize, + }), + ], + ]; +}; + +export { + fetchQueryFallbackData, + fetchOffsetPaginationHasMoreFallbackData, + fetchOffsetPaginationFallbackData, +}; diff --git a/packages/postgrest-swr/src/query/use-offset-infinite-query.ts b/packages/postgrest-swr/src/query/use-offset-infinite-query.ts index ad298b68..bb84e077 100644 --- a/packages/postgrest-swr/src/query/use-offset-infinite-query.ts +++ b/packages/postgrest-swr/src/query/use-offset-infinite-query.ts @@ -39,12 +39,14 @@ function useOffsetInfiniteQuery< Schema extends GenericSchema, Table extends Record, Result extends Record, + RelationName = unknown, Relationships = unknown, >( query: PostgrestTransformBuilder< Schema, Table, Result[], + RelationName, Relationships > | null, config?: SWRInfiniteConfiguration< diff --git a/packages/postgrest-swr/src/query/use-offset-infinite-scroll-query.ts b/packages/postgrest-swr/src/query/use-offset-infinite-scroll-query.ts index e6253b5b..e058912b 100644 --- a/packages/postgrest-swr/src/query/use-offset-infinite-scroll-query.ts +++ b/packages/postgrest-swr/src/query/use-offset-infinite-scroll-query.ts @@ -68,12 +68,14 @@ function useOffsetInfiniteScrollQuery< Schema extends GenericSchema, Table extends Record, Result extends Record, + RelationName, Relationships = unknown, >( query: PostgrestTransformBuilder< Schema, Table, Result[], + RelationName, Relationships > | null, config?: SWRInfiniteConfiguration< From 7396ad7704d8c1af68c0d23f82cd8203ae4f191b Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 1 Dec 2023 18:03:58 +0100 Subject: [PATCH 2/6] feat: add tests --- .../__tests__/cache/use-mutate-item.spec.tsx | 2 +- .../use-delete-mutation.integration.spec.tsx | 2 +- .../use-insert-mutation.integration.spec.tsx | 2 +- .../use-update-mutation.integration.spec.tsx | 2 +- .../use-upsert-mutation.integration.spec.tsx | 2 +- .../query/prefetch.integration.spec.ts | 45 +++++++++++++++++++ .../query/use-query.integration.spec.tsx | 2 +- ...se-subscription-query-integration.spec.tsx | 2 +- .../use-subscription.integration.spec.tsx | 2 +- .../src/query/prefetch.ts | 7 +-- .../query/prefetch.integration.spec.ts | 43 ++++++++++++++++++ 11 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts create mode 100644 packages/postgrest-swr/__tests__/query/prefetch.integration.spec.ts diff --git a/packages/postgrest-react-query/__tests__/cache/use-mutate-item.spec.tsx b/packages/postgrest-react-query/__tests__/cache/use-mutate-item.spec.tsx index b4bb9d04..d40d49d1 100644 --- a/packages/postgrest-react-query/__tests__/cache/use-mutate-item.spec.tsx +++ b/packages/postgrest-react-query/__tests__/cache/use-mutate-item.spec.tsx @@ -7,7 +7,7 @@ import { useMutateItem, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-mutate-item'; +const TEST_PREFIX = 'postgrest-react-query-mutate-item'; describe('useMutateItem', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/mutate/use-delete-mutation.integration.spec.tsx b/packages/postgrest-react-query/__tests__/mutate/use-delete-mutation.integration.spec.tsx index 04935bef..60e5115d 100644 --- a/packages/postgrest-react-query/__tests__/mutate/use-delete-mutation.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/mutate/use-delete-mutation.integration.spec.tsx @@ -7,7 +7,7 @@ import { useDeleteMutation, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-delete'; +const TEST_PREFIX = 'postgrest-react-query-delete'; describe('useDeleteMutation', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/mutate/use-insert-mutation.integration.spec.tsx b/packages/postgrest-react-query/__tests__/mutate/use-insert-mutation.integration.spec.tsx index c8467d6c..e13f47c5 100644 --- a/packages/postgrest-react-query/__tests__/mutate/use-insert-mutation.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/mutate/use-insert-mutation.integration.spec.tsx @@ -7,7 +7,7 @@ import { useInsertMutation, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-insert'; +const TEST_PREFIX = 'postgrest-react-query-insert'; describe('useInsertMutation', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/mutate/use-update-mutation.integration.spec.tsx b/packages/postgrest-react-query/__tests__/mutate/use-update-mutation.integration.spec.tsx index 2a9a1f08..da01a5f9 100644 --- a/packages/postgrest-react-query/__tests__/mutate/use-update-mutation.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/mutate/use-update-mutation.integration.spec.tsx @@ -7,7 +7,7 @@ import { useInsertMutation, useQuery, useUpdateMutation } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-update'; +const TEST_PREFIX = 'postgrest-react-query-update'; describe('useUpdateMutation', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/mutate/use-upsert-mutation.integration.spec.tsx b/packages/postgrest-react-query/__tests__/mutate/use-upsert-mutation.integration.spec.tsx index 097687f6..1c4ef019 100644 --- a/packages/postgrest-react-query/__tests__/mutate/use-upsert-mutation.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/mutate/use-upsert-mutation.integration.spec.tsx @@ -7,7 +7,7 @@ import { useQuery, useUpsertMutation } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-upsert'; +const TEST_PREFIX = 'postgrest-react-query-upsert'; describe('useUpsertMutation', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts b/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts new file mode 100644 index 00000000..6f3bc16b --- /dev/null +++ b/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts @@ -0,0 +1,45 @@ +import { createClient, SupabaseClient } from '@supabase/supabase-js'; +import { QueryClient } from '@tanstack/react-query'; + +import { prefetchQuery } from '../../src'; +import type { Database } from '../database.types'; +import '../utils'; + +const TEST_PREFIX = 'postgrest-react-query-prefetch'; + +describe('prefetch', () => { + let client: SupabaseClient; + let testRunPrefix: string; + let contacts: Database['public']['Tables']['contact']['Row'][]; + + beforeAll(async () => { + testRunPrefix = `${TEST_PREFIX}-${Math.floor(Math.random() * 100)}`; + client = createClient( + process.env.SUPABASE_URL as string, + process.env.SUPABASE_ANON_KEY as string, + ); + await client.from('contact').delete().ilike('username', `${TEST_PREFIX}%`); + + const { data } = await client + .from('contact') + .insert([ + { username: `${testRunPrefix}-username-1` }, + { username: `${testRunPrefix}-username-2` }, + { username: `${testRunPrefix}-username-3` }, + { username: `${testRunPrefix}-username-4` }, + ]) + .select('*') + .throwOnError(); + contacts = data ?? []; + expect(contacts).toHaveLength(4); + }); + + it('should throw if query is not a PostgrestBuilder', async () => { + const queryClient = new QueryClient(); + try { + await prefetchQuery(queryClient, Promise.resolve({} as any)); + } catch (error) { + expect(error).toEqual(new Error('Key is not a PostgrestBuilder')); + } + }); +}); diff --git a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx index a0cbc062..b32ec61b 100644 --- a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx @@ -8,7 +8,7 @@ import { encode } from '../../src/lib/key'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-query'; +const TEST_PREFIX = 'postgrest-react-query-query'; describe('useQuery', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/subscribe/use-subscription-query-integration.spec.tsx b/packages/postgrest-react-query/__tests__/subscribe/use-subscription-query-integration.spec.tsx index 3343bf4a..a5fde1c1 100644 --- a/packages/postgrest-react-query/__tests__/subscribe/use-subscription-query-integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/subscribe/use-subscription-query-integration.spec.tsx @@ -7,7 +7,7 @@ import { useSubscriptionQuery, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-subscription-query'; +const TEST_PREFIX = 'postgrest-react-query-subscription-query'; describe('useSubscriptionQuery', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/__tests__/subscribe/use-subscription.integration.spec.tsx b/packages/postgrest-react-query/__tests__/subscribe/use-subscription.integration.spec.tsx index e288ffc0..5e1b5709 100644 --- a/packages/postgrest-react-query/__tests__/subscribe/use-subscription.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/subscribe/use-subscription.integration.spec.tsx @@ -7,7 +7,7 @@ import { useSubscription, useQuery } from '../../src'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; -const TEST_PREFIX = 'postgrest-swr-subscription-plain'; +const TEST_PREFIX = 'postgrest-react-query-subscription-plain'; describe('useSubscription', () => { let client: SupabaseClient; diff --git a/packages/postgrest-react-query/src/query/prefetch.ts b/packages/postgrest-react-query/src/query/prefetch.ts index 3796c754..97615e60 100644 --- a/packages/postgrest-react-query/src/query/prefetch.ts +++ b/packages/postgrest-react-query/src/query/prefetch.ts @@ -49,10 +49,11 @@ async function prefetchQuery( { queryKey: encode(query, false), queryFn: async () => { - if (isPostgrestBuilder(query)) { - query = query.throwOnError(); + if (!isPostgrestBuilder(query)) { + throw new Error('Query is not a PostgrestBuilder'); } - return await query; + + return await query.throwOnError(); }, ...config, }, diff --git a/packages/postgrest-swr/__tests__/query/prefetch.integration.spec.ts b/packages/postgrest-swr/__tests__/query/prefetch.integration.spec.ts new file mode 100644 index 00000000..a162d63d --- /dev/null +++ b/packages/postgrest-swr/__tests__/query/prefetch.integration.spec.ts @@ -0,0 +1,43 @@ +import { createClient, SupabaseClient } from '@supabase/supabase-js'; + +import { fetchQueryFallbackData } from '../../src'; +import type { Database } from '../database.types'; +import '../utils'; + +const TEST_PREFIX = 'postgrest-swr-prefetch'; + +describe('prefetch', () => { + let client: SupabaseClient; + let testRunPrefix: string; + let contacts: Database['public']['Tables']['contact']['Row'][]; + + beforeAll(async () => { + testRunPrefix = `${TEST_PREFIX}-${Math.floor(Math.random() * 100)}`; + client = createClient( + process.env.SUPABASE_URL as string, + process.env.SUPABASE_ANON_KEY as string, + ); + await client.from('contact').delete().ilike('username', `${TEST_PREFIX}%`); + + const { data } = await client + .from('contact') + .insert([ + { username: `${testRunPrefix}-username-1` }, + { username: `${testRunPrefix}-username-2` }, + { username: `${testRunPrefix}-username-3` }, + { username: `${testRunPrefix}-username-4` }, + ]) + .select('*') + .throwOnError(); + contacts = data ?? []; + expect(contacts).toHaveLength(4); + }); + + it('should throw if not a postgrest builder', async () => { + try { + await fetchQueryFallbackData('' as any); + } catch (error) { + expect(error).toEqual(new Error('Query is not a PostgrestBuilder')); + } + }); +}); From 9e48c814027b13ee9060d677699363d8ca9cc471 Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 8 Dec 2023 11:43:51 +0100 Subject: [PATCH 3/6] docs: ssr with swr --- docs/pages/postgrest/_meta.json | 3 +- docs/pages/postgrest/ssr/_meta.json | 4 + docs/pages/postgrest/ssr/react-query.mdx | 0 docs/pages/postgrest/ssr/swr.mdx | 210 +++++++++++++++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 docs/pages/postgrest/ssr/_meta.json create mode 100644 docs/pages/postgrest/ssr/react-query.mdx create mode 100644 docs/pages/postgrest/ssr/swr.mdx diff --git a/docs/pages/postgrest/_meta.json b/docs/pages/postgrest/_meta.json index 0ef72c8e..8b85a42e 100644 --- a/docs/pages/postgrest/_meta.json +++ b/docs/pages/postgrest/_meta.json @@ -3,5 +3,6 @@ "queries": "Queries", "mutations": "Mutations", "subscriptions": "Subscriptions", - "custom-cache-updates": "Custom Cache Updates" + "custom-cache-updates": "Custom Cache Updates", + "ssr": "Server Side Rendering" } diff --git a/docs/pages/postgrest/ssr/_meta.json b/docs/pages/postgrest/ssr/_meta.json new file mode 100644 index 00000000..7d1ed804 --- /dev/null +++ b/docs/pages/postgrest/ssr/_meta.json @@ -0,0 +1,4 @@ +{ + "swr": "SWR", + "react-query": "React Query" +} diff --git a/docs/pages/postgrest/ssr/react-query.mdx b/docs/pages/postgrest/ssr/react-query.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/pages/postgrest/ssr/swr.mdx b/docs/pages/postgrest/ssr/swr.mdx new file mode 100644 index 00000000..fd996275 --- /dev/null +++ b/docs/pages/postgrest/ssr/swr.mdx @@ -0,0 +1,210 @@ +import { Callout, Tabs, Tab } from "nextra-theme-docs"; + +# Server Side Rendering with SWR + +SWR allows a user to [pre-render with default data](https://swr.vercel.app/docs/with-nextjs). Specifically, you can either pass `fallbackData` directly to `useSWR`, + +```tsx +const { data } = useSWR("/api/article", fetcher, { fallbackData }); +``` + +or define it globally in `SWRConfig` + +```tsx + +
+ +``` + +Supabase Cache Helpers exports helper to simplify it for every query type. + +### `useQuery` + +Fetch fallback data for `useQuery` using `fetchQueryFallbackData`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, fallbackData] = await fetchQueryFallbackData( + buildQuery(supabase), + ); + return { + props: { + fallback: fallbackData, + }, + }; +} + +export default function Articles({ fallback }) { + const supabase = useSupabaseClient(); + + const { data } = useQuery(buildQuery(supabase), { fallbackData: fallback }); + ... + +} +``` + +The data can also be passed globally using `key`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, fallbackData] = await fetchQueryFallbackData( + buildQuery(supabase), + ); + return { + props: { + fallback { + [key]: fallbackData, + }, + }; +} + +export default function App({ fallback }) { + return ( + +
+ + ) +} +``` + +### `useOffsetInfiniteQuery` + +To fetch fallback data for `useOffsetInfiniteQuery`, use `fetchOffsetPaginationFallbackData`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, fallbackData] = await fetchOffsetPaginationFallbackData( + buildQuery(supabase), 1 + ); + return { + props: { + fallback: fallbackData, + }, + }; +} + +export default function Articles({ fallback }) { + const supabase = useSupabaseClient(); + + const { data } = useOffsetInfiniteQuery(buildQuery(supabase), { + pageSize: 1, + fallbackData, + }); + ... + +} +``` + + + Unfortunately, passing it globally to `SWRConfig` does not work. There seems + to be an issue with `fallbackData` in `useSWRInfinite` that I could not figure + out yet. + + +### `useOffsetInfiniteScrollQuery` + +To fetch fallback data for `useOffsetInfiniteScrollQuery`, use `fetchOffsetPaginationHasMoreFallbackData`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, fallbackData] = await fetchOffsetPaginationHasMoreFallbackData( + buildQuery(supabase), 1 + ); + return { + props: { + fallback: fallbackData, + }, + }; +} + +export default function Articles({ fallback }) { + const supabase = useSupabaseClient(); + + const { data } = useOffsetInfiniteScrollQuery(buildQuery(supabase), { + pageSize: 1, + fallbackData, + }); + ... + +} +``` + + + Unfortunately, passing it globally to `SWRConfig` does not work. There seems + to be an issue with `fallbackData` in `useSWRInfinite` that I could not figure + out yet. + + +### `useInfiniteOffsetPaginationQuery` + +To fetch fallback data for `useInfiniteOffsetPaginationQuery`, use `fetchOffsetPaginationHasMoreFallbackData`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, fallbackData] = await fetchOffsetPaginationHasMoreFallbackData( + buildQuery(supabase), 1 + ); + return { + props: { + fallback: fallbackData, + }, + }; +} + +export default function Articles({ fallback }) { + const supabase = useSupabaseClient(); + + const { data } = useInfiniteOffsetPaginationQuery(buildQuery(supabase), { + pageSize: 1, + fallbackData, + }); + ... + +} +``` + + + Unfortunately, passing it globally to `SWRConfig` does not work. There seems + to be an issue with `fallbackData` in `useSWRInfinite` that I could not figure + out yet. + From 3e6d1a5d71c16de776f160af4d34811ee8ab328d Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 8 Dec 2023 12:11:58 +0100 Subject: [PATCH 4/6] feat: initial data for react-query --- .../query/use-query.integration.spec.tsx | 27 ++++++++++++++++++- .../src/query/prefetch.ts | 24 ++++++++++++++++- .../src/query/use-query.ts | 8 +++--- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx index b32ec61b..1b38cbe9 100644 --- a/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx +++ b/packages/postgrest-react-query/__tests__/query/use-query.integration.spec.tsx @@ -3,7 +3,7 @@ import { QueryClient } from '@tanstack/react-query'; import { fireEvent, screen } from '@testing-library/react'; import React, { useState } from 'react'; -import { prefetchQuery, useQuery } from '../../src'; +import { fetchQueryInitialData, prefetchQuery, useQuery } from '../../src'; import { encode } from '../../src/lib/key'; import type { Database } from '../database.types'; import { renderWithConfig } from '../utils'; @@ -198,4 +198,29 @@ describe('useQuery', () => { expect(hasBeenFalse).toBe(false); await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); }); + + it('initalData should work', async () => { + const queryClient = new QueryClient(); + const query = client + .from('contact') + .select('id,username') + .eq('username', contacts[0].username ?? '') + .single(); + const [key, initial] = await fetchQueryInitialData(query); + let hasBeenFalse = false; + function Page() { + const { data } = useQuery(query, { initialData: initial }); + if (!data) hasBeenFalse = true; + + return ( +
+
{data?.username ?? 'undefined'}
+
+ ); + } + + renderWithConfig(, queryClient); + expect(hasBeenFalse).toBe(false); + await screen.findByText(contacts[0].username!, {}, { timeout: 10000 }); + }); }); diff --git a/packages/postgrest-react-query/src/query/prefetch.ts b/packages/postgrest-react-query/src/query/prefetch.ts index 97615e60..7b3f5296 100644 --- a/packages/postgrest-react-query/src/query/prefetch.ts +++ b/packages/postgrest-react-query/src/query/prefetch.ts @@ -60,4 +60,26 @@ async function prefetchQuery( ); } -export { prefetchQuery }; +function fetchQueryInitialData( + query: PromiseLike>, +): Promise<[string[], PostgrestSingleResponse]>; + +function fetchQueryInitialData( + query: PromiseLike>, +): Promise<[string[], PostgrestMaybeSingleResponse]>; + +function fetchQueryInitialData( + query: PromiseLike>, +): Promise<[string[], PostgrestResponse]>; + +async function fetchQueryInitialData( + query: PromiseLike>, +): Promise<[string[], AnyPostgrestResponse]> { + if (!isPostgrestBuilder(query)) { + throw new Error('Query is not a PostgrestBuilder'); + } + + return [encode(query, false), await query.throwOnError()]; +} + +export { prefetchQuery, fetchQueryInitialData }; diff --git a/packages/postgrest-react-query/src/query/use-query.ts b/packages/postgrest-react-query/src/query/use-query.ts index b4d4509b..bbe83f12 100644 --- a/packages/postgrest-react-query/src/query/use-query.ts +++ b/packages/postgrest-react-query/src/query/use-query.ts @@ -86,7 +86,7 @@ function useQuery( query: PromiseLike>, config?: Omit< UseReactQueryOptions, PostgrestError>, - 'queryKey' | 'queryFn' | 'initialData' + 'queryKey' | 'queryFn' >, ): UseQuerySingleReturn; /** @@ -100,7 +100,7 @@ function useQuery( query: PromiseLike>, config?: Omit< UseReactQueryOptions, PostgrestError>, - 'queryKey' | 'queryFn' | 'initialData' + 'queryKey' | 'queryFn' >, ): UseQueryMaybeSingleReturn; /** @@ -115,7 +115,7 @@ function useQuery( query: PromiseLike>, config?: Omit< UseReactQueryOptions, PostgrestError>, - 'queryKey' | 'queryFn' | 'initialData' + 'queryKey' | 'queryFn' >, ): UseQueryReturn; /** @@ -130,7 +130,7 @@ function useQuery( query: PromiseLike>, config?: Omit< UseReactQueryOptions, PostgrestError>, - 'queryKey' | 'queryFn' | 'intialData' + 'queryKey' | 'queryFn' >, ): UseQueryAnyReturn { const { data, ...rest } = useReactQuery< From 4deea427659c00b4accad82744a3ec90cc6a7dcf Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 8 Dec 2023 20:15:19 +0100 Subject: [PATCH 5/6] chore: docs for react query --- docs/pages/postgrest/ssr/react-query.mdx | 79 ++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/docs/pages/postgrest/ssr/react-query.mdx b/docs/pages/postgrest/ssr/react-query.mdx index e69de29b..e11eb2f8 100644 --- a/docs/pages/postgrest/ssr/react-query.mdx +++ b/docs/pages/postgrest/ssr/react-query.mdx @@ -0,0 +1,79 @@ +import { Callout, Tabs, Tab } from "nextra-theme-docs"; + +# Server Side Rendering with React Query + +React Query offers two APIs to supply initial data for a query to the cache before you need it: Declaratively using [`initialData`](https://tanstack.com/query/v4/docs/react/guides/initial-query-data), and imperatively using [`prefetchQuery`](https://tanstack.com/query/v5/docs/react/guides/advanced-ssr). + +Supabase Cache Helpers exports utilities for both. + +## Declaratively providing `initialData` + +Fetch initial data for `useQuery` using `fetchQueryInitialData`. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + const [key, initialData] = await fetchQueryInitialData( + buildQuery(supabase), + ); + return { + props: { + initialData + }, + }; +} + +export default function Articles({ initialData }) { + const supabase = useSupabaseClient(); + + const { data } = useQuery(buildQuery(supabase), { initialData }); + ... + +} +``` + +## Imperatively prefetch query data + +You can also use leverage `prefetchQuery` to prefetch data for `useQuery` imperatively and pass it to the client using the hydration APIs. + +```tsx +const buildQuery = (supabase: SupabaseClient) => { + return supabase.from('article').select('id,title'); +}; + +export async function getStaticProps() { + const queryClient = new QueryClient() + const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, + ); + await prefetchQuery(queryClient, buildQuery(supabase)); + return { + props: { + dehydratedState: dehydrate(queryClient), + }, + }; +} + +function Articles() { + const supabase = useSupabaseClient(); + + const { data } = useQuery(buildQuery(supabase)); + ... +} + +export default ArticlesRoute({ dehydratedState }) { + return ( + + + + ) +} +``` From dbd0fd12fbb83a8c32222f63d1324f63867e0b35 Mon Sep 17 00:00:00 2001 From: psteinroe Date: Fri, 8 Dec 2023 21:31:09 +0100 Subject: [PATCH 6/6] fix: missing test --- .../__tests__/query/prefetch.integration.spec.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts b/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts index 6f3bc16b..feaef48b 100644 --- a/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts +++ b/packages/postgrest-react-query/__tests__/query/prefetch.integration.spec.ts @@ -1,7 +1,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { QueryClient } from '@tanstack/react-query'; -import { prefetchQuery } from '../../src'; +import { fetchQueryInitialData, prefetchQuery } from '../../src'; import type { Database } from '../database.types'; import '../utils'; @@ -34,7 +34,7 @@ describe('prefetch', () => { expect(contacts).toHaveLength(4); }); - it('should throw if query is not a PostgrestBuilder', async () => { + it('prefetchQuery should throw if query is not a PostgrestBuilder', async () => { const queryClient = new QueryClient(); try { await prefetchQuery(queryClient, Promise.resolve({} as any)); @@ -42,4 +42,12 @@ describe('prefetch', () => { expect(error).toEqual(new Error('Key is not a PostgrestBuilder')); } }); + + it('fetchQueryInitialData should throw if query is not a PostgrestBuilder', async () => { + try { + await fetchQueryInitialData(Promise.resolve({} as any)); + } catch (error) { + expect(error).toEqual(new Error('Query is not a PostgrestBuilder')); + } + }); });