import React from 'react'; import * as duckdb from '@duckdb/duckdb-wasm'; import { Resolvable, Resolver } from './resolvable'; type PlatformProps = { children: React.ReactElement | React.ReactElement[]; logger: duckdb.Logger; bundles: duckdb.DuckDBBundles; }; const loggerCtx = React.createContext(null); const bundleCtx = React.createContext | null>(null); const resolverCtx = React.createContext | null>(null); export const useDuckDBLogger = (): duckdb.Logger => React.useContext(loggerCtx)!; export const useDuckDBBundle = (): Resolvable => React.useContext(bundleCtx)!; export const useDuckDBBundleResolver = (): Resolver => React.useContext(resolverCtx)!; export const DuckDBPlatform: React.FC = (props: PlatformProps) => { const [bundle, setBundle] = React.useState>(new Resolvable()); const inFlight = React.useRef | null>(null); const resolver = React.useCallback(async () => { if (bundle.error) return null; if (bundle.value) return bundle.value; if (inFlight.current) return await inFlight.current; inFlight.current = (async () => { try { const params = new URLSearchParams(window.location.search); const bundleName = params.get('bundle') as keyof duckdb.DuckDBBundles | null; setBundle(b => b.updateRunning()); const bundle = bundleName !== null ? props.bundles[bundleName] : null; const next = (bundle || (await duckdb.selectBundle(props.bundles))) as duckdb.DuckDBBundle; inFlight.current = null; setBundle(b => b.completeWith(next)); return next; } catch (e: any) { inFlight.current = null; console.error(e); setBundle(b => b.failWith(e)); return null; } })(); return await inFlight.current; }, [props.bundles]); return ( {props.children} ); };