import { WatchedQuery } from '@powersync/common'; import React from 'react'; import { createSuspendingPromise, useTemporaryHold } from './suspense-utils.js'; /** * A hook to access and subscribe to the results of an existing {@link WatchedQuery}. * @example * export const ContentComponent = () => { * const { data: lists } = useWatchedQuerySuspenseSubscription(listsQuery); * * return * {lists.map((l) => ( * {JSON.stringify(l)} * ))} * ; * } * * export const DisplayComponent = () => { * return ( * Loading content...}> * * * ); * } */ export const useWatchedQuerySuspenseSubscription = < ResultType = unknown, Query extends WatchedQuery = WatchedQuery >( query: Query ): Query['state'] => { useTemporaryHold(query); // Force update state function const [, setUpdateCounter] = React.useState(0); React.useEffect(() => { // This runs when the component came out of suspense // This add a permanent hold since a listener has been added to the query const dispose = query.registerListener({ onStateChange() { // Trigger rerender setUpdateCounter((prev) => prev + 1); } }); return dispose; }, []); if (query.state.error != null) { // Report errors - this is caught by an error boundary throw query.state.error; } else if (!query.state.isLoading) { // Happy path data return return query.state; } else { // Notify suspense is required throw createSuspendingPromise(query); } };