import * as React from 'react' import { TSR_DEFERRED_PROMISE, defer } from '@tanstack/router-core' import { reactUse } from './utils' export type AwaitOptions = { promise: Promise } /** Suspend until a deferred promise resolves or rejects and return its data. */ export function useAwaited({ promise: _promise }: AwaitOptions): T { if (reactUse) { const data = reactUse(_promise) return data } const promise = defer(_promise) if (promise[TSR_DEFERRED_PROMISE].status === 'pending') { throw promise } if (promise[TSR_DEFERRED_PROMISE].status === 'error') { throw promise[TSR_DEFERRED_PROMISE].error } return promise[TSR_DEFERRED_PROMISE].data } /** * Component that suspends on a deferred promise and renders its child with * the resolved value. Optionally provides a Suspense fallback. */ export function Await( props: AwaitOptions & { fallback?: React.ReactNode children: (result: T) => React.ReactNode }, ) { const inner = if (props.fallback) { return {inner} } return inner } function AwaitInner( props: AwaitOptions & { fallback?: React.ReactNode children: (result: T) => React.ReactNode }, ): React.JSX.Element { const data = useAwaited(props) return props.children(data) as React.JSX.Element }