Skip to content

Conversation

Chriztiaan
Copy link
Contributor

@Chriztiaan Chriztiaan commented Oct 3, 2024

Overview

This introduces a @powersync/tanstack-react-query package - it contains Tanstack React Query (FKA React Query) wrapper hooks for Tanstack's useQuery and useSuspenseQuery. Piggybacking off the existing hooks for stable support for query caching and suspense.

It matches the existing hooks API signature almost identically, except that query and parameters options have been introduced to overwrite the existing queryFn option. Note that queryFn is still supported, but is ignored if the new query option is specified in the query options.

Example

The Readme covers setup and usage.

Here is example usage:

  const { data: todoLists, isLoading, isFetching, error } = useQuery({
    queryKey: ['todoLists'],
    query: 'SELECT * FROM lists WHERE id = ?', // use `query` instead of `queryFn` to define a SQL query
    parameters: ['id-1'], // supply query parameters for the SQL query
  });

Typing

The return type of the data can be defined by useQuery<T> and useQuerySuspense<T> which means that each row returned will be of type T.

Alternatively, compilable query support is included (with Kysely as an example):

const { data: todoLists, isLoading, error } = useQuery({
    queryKey: ['todoLists'],
    query: kyselyDb.selectFrom('lists').selectAll(), // The type of the rows in `data` are inferred from the Kysely query
  });

Alternative API considered

Adding query and parameters makes usage easier, especially if you consider it allows the hooks to handle compilable queries internally. An alternative would be to drop the two new options in favour of having the internals of the package simpler, and pass on deriving the queryFn with the SQL query and parameters (or compilable query) to somewhere else.

The problem being that if we do that, there is no clear mechanism for resolving the query's dependent tables (which we need for the watch).

For example:

  import { useQuery, useDerivedQuery } from `@powersync/tanstack-react-query`;
  
  const { queryFn: derivedQueryFn, tables } = useDerivedQuery<{name: string}>('SELECT * FROM lists WHERE id = ?', parameters: ['id-1']);

  const { data: todoLists, isLoading, isFetching, error } = useQuery(
  {
    queryKey: ['todoLists'],
    queryFn: derivedQueryFn
  }, null, // don't overwrite query client
    options: { tables }
  );

Copy link

changeset-bot bot commented Oct 3, 2024

🦋 Changeset detected

Latest commit: 12c8abd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@powersync/tanstack-react-query Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@guillempuche
Copy link
Contributor

Nice!! Having integrations with top frontend libraries will attract people from other ecosystems.

Let's TanStack team know about PowerSync to list you in some places!

@Chriztiaan Chriztiaan marked this pull request as ready for review October 4, 2024 08:44
stevensJourney
stevensJourney previously approved these changes Oct 4, 2024
Copy link
Collaborator

@stevensJourney stevensJourney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. I'm happy with this for an alpha release. Tanstack query has a very powerful and established API, this is awesome.

Ensuring that queryFn is called if custom query option is not specified.
@Chriztiaan
Copy link
Contributor Author

Chriztiaan commented Oct 4, 2024

Note: there's an issue with the base queryFn not working correctly.
Edit: Resolved in latest commit.

Chriztiaan and others added 3 commits October 8, 2024 09:02
stevensJourney
stevensJourney previously approved these changes Oct 9, 2024
@Chriztiaan Chriztiaan requested a review from rkistner October 9, 2024 08:25
Copy link
Contributor

@rkistner rkistner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from queryKey, the useQuery hook here looks practically the same as the normal PowerSync's useQuery hook. What is the practical difference between the two, or where would the TanStack hook be preferred?

@Chriztiaan
Copy link
Contributor Author

Apart from queryKey, the useQuery hook here looks practically the same as the normal PowerSync's useQuery hook. What is the practical difference between the two, or where would the TanStack hook be preferred?

Briefly, the Tanstack version of useQuery allows you to use the other features included in Tanstack like caching, placeholder or initial data, their loading states, retry on error (not that useful for local first), simplified pagination (potentially not much easier than with the existing hook), enabling/disabling a query.

So this would be valuable in cases where a project already uses Tanstack and wants to stay consistent with their APIs. Otherwise when you want to depend on some of the other query options - the caching is quite powerful.

rkistner
rkistner previously approved these changes Oct 9, 2024
# Conflicts:
#	pnpm-lock.yaml
@Chriztiaan Chriztiaan dismissed stale reviews from rkistner and stevensJourney via 12c8abd October 10, 2024 12:40
@Chriztiaan Chriztiaan merged commit c4e183a into main Oct 10, 2024
5 checks passed
@Chriztiaan Chriztiaan deleted the tanstack/react branch October 10, 2024 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants