diff --git a/packages/pglite-react/src/hooks.ts b/packages/pglite-react/src/hooks.ts index 5bf90d313..765fedeb3 100644 --- a/packages/pglite-react/src/hooks.ts +++ b/packages/pglite-react/src/hooks.ts @@ -44,6 +44,7 @@ function useLiveQueryImpl( /* eslint-disable @eslint-react/hooks-extra/no-direct-set-state-in-use-effect */ useEffect(() => { + if (!db) return // no PGliteProvider mounted — skip subscription let cancelled = false const cb = (results: LiveQueryResults) => { if (cancelled) return diff --git a/packages/pglite-react/src/provider.tsx b/packages/pglite-react/src/provider.tsx index f1b5f70e2..ffc865fcf 100644 --- a/packages/pglite-react/src/provider.tsx +++ b/packages/pglite-react/src/provider.tsx @@ -9,7 +9,7 @@ interface Props { type PGliteProvider = ( props: Props, ) => React.JSX.Element -type UsePGlite = (db?: T) => T +type UsePGlite = (db?: T) => T | null interface PGliteProviderSet { PGliteProvider: PGliteProvider @@ -28,12 +28,9 @@ function makePGliteProvider(): PGliteProviderSet { // allow providing a db explicitly if (db !== undefined) return db - if (!dbProvided) - throw new Error( - 'No PGlite instance found, use PGliteProvider to provide one', - ) - - return dbProvided + // Return null instead of throwing when no provider is mounted. + // Callers can guard with `if (!db) return` for lazy / conditional rendering. + return dbProvided ?? null }) as UsePGlite, PGliteProvider: ({ children, db }: Props) => { return {children} diff --git a/packages/pglite-react/test/provider.test.tsx b/packages/pglite-react/test/provider.test.tsx index 651052e60..dd5661d94 100644 --- a/packages/pglite-react/test/provider.test.tsx +++ b/packages/pglite-react/test/provider.test.tsx @@ -41,3 +41,20 @@ describe('provider', () => { await waitFor(() => expect(result.current).toBe(db)) }) }) + +describe('usePGlite outside provider', () => { + it('returns null when no PGliteProvider is mounted', () => { + const { result } = renderHook(() => usePGlite()) + expect(result.current).toBeNull() + }) + + it('does not throw when no PGliteProvider is mounted', () => { + expect(() => renderHook(() => usePGlite())).not.toThrow() + }) + + it('returns the db when provided directly as argument', async () => { + const db = await PGlite.create({ extensions: { live } }) + const { result } = renderHook(() => usePGlite(db as PGliteWithLive)) + expect(result.current).toBe(db) + }) +})