@duckdb/react-duckdb 1.13.1-dev266.0 → 1.13.1-dev267.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckdb/react-duckdb",
3
- "version": "1.13.1-dev266.0",
3
+ "version": "1.13.1-dev267.0",
4
4
  "description": "React components for DuckDB-Wasm",
5
5
  "license": "MPL-2.0",
6
6
  "repository": {
@@ -18,18 +18,11 @@ type DuckDBProps = {
18
18
 
19
19
  export const DuckDBProvider: React.FC<DuckDBProps> = (props: DuckDBProps) => {
20
20
  const logger = useDuckDBLogger();
21
- const bundle = useDuckDBBundle();
22
21
  const resolveBundle = useDuckDBBundleResolver();
23
22
  const [setup, updateSetup] = React.useState<Resolvable<duckdb.AsyncDuckDB, duckdb.InstantiationProgress>>(
24
23
  new Resolvable<duckdb.AsyncDuckDB, duckdb.InstantiationProgress>(),
25
24
  );
26
25
 
27
- React.useEffect(() => {
28
- if (!bundle.resolving()) {
29
- resolveBundle();
30
- }
31
- }, [bundle]);
32
-
33
26
  const worker = React.useRef<Worker | null>(null);
34
27
  React.useEffect(
35
28
  () => () => {
@@ -41,51 +34,50 @@ export const DuckDBProvider: React.FC<DuckDBProps> = (props: DuckDBProps) => {
41
34
  [],
42
35
  );
43
36
 
44
- const lock = React.useRef<boolean>(false);
37
+ const inFlight = React.useRef<Promise<duckdb.AsyncDuckDB | null> | null>(null);
45
38
  const resolver = React.useCallback(async () => {
46
- // Invalid input?
47
- if (!logger || !bundle || bundle.value == null) return null;
48
- // Is updating?
49
- if (lock.current) return null;
50
- lock.current = true;
39
+ // Run only once
40
+ if (inFlight.current) return await inFlight.current;
41
+ inFlight.current = (async () => {
42
+ // Resolve bundle
43
+ const bundle = await resolveBundle();
44
+ if (bundle == null) {
45
+ updateSetup(s => s.failWith('invalid bundle'));
46
+ return null;
47
+ }
51
48
 
52
- // Create worker and next database
53
- let worker: Worker;
54
- let next: duckdb.AsyncDuckDB;
55
- try {
56
- worker = new Worker(bundle.value.mainWorker!);
57
- next = new duckdb.AsyncDuckDB(logger, worker);
58
- } catch (e: any) {
59
- lock.current = false;
60
- updateSetup(s => s.failWith(e));
61
- return null;
62
- }
49
+ // Create worker and next database
50
+ let worker: Worker;
51
+ let next: duckdb.AsyncDuckDB;
52
+ try {
53
+ worker = new Worker(bundle.mainWorker!);
54
+ next = new duckdb.AsyncDuckDB(logger, worker);
55
+ } catch (e: any) {
56
+ updateSetup(s => s.failWith(e));
57
+ return null;
58
+ }
63
59
 
64
- // Instantiate the database asynchronously
65
- try {
66
- await next.instantiate(
67
- bundle.value.mainModule,
68
- bundle.value.pthreadWorker,
69
- (p: duckdb.InstantiationProgress) => {
60
+ // Instantiate the database asynchronously
61
+ try {
62
+ await next.instantiate(bundle.mainModule, bundle.pthreadWorker, (p: duckdb.InstantiationProgress) => {
70
63
  try {
71
64
  updateSetup(s => s.updateRunning(p));
72
65
  } catch (e: any) {
73
66
  console.warn(`progress handler failed with error: ${e.toString()}`);
74
67
  }
75
- },
76
- );
77
- if (props.config !== undefined) {
78
- await next.open(props.config!);
68
+ });
69
+ if (props.config !== undefined) {
70
+ await next.open(props.config!);
71
+ }
72
+ } catch (e: any) {
73
+ updateSetup(s => s.failWith(e));
74
+ return null;
79
75
  }
80
- } catch (e: any) {
81
- lock.current = false;
82
- updateSetup(s => s.failWith(e));
83
- return null;
84
- }
85
- lock.current = false;
86
- updateSetup(s => s.completeWith(next));
87
- return next;
88
- }, [logger, bundle]);
76
+ updateSetup(s => s.completeWith(next));
77
+ return next;
78
+ })();
79
+ return await inFlight.current;
80
+ }, [logger]);
89
81
 
90
82
  return (
91
83
  <resolverCtx.Provider value={resolver}>
@@ -18,22 +18,26 @@ export const useDuckDBBundleResolver = (): Resolver<duckdb.DuckDBBundle> => Reac
18
18
  export const DuckDBPlatform: React.FC<PlatformProps> = (props: PlatformProps) => {
19
19
  const [bundle, setBundle] = React.useState<Resolvable<duckdb.DuckDBBundle>>(new Resolvable());
20
20
 
21
- const lock = React.useRef<boolean>(false);
21
+ const inFlight = React.useRef<Promise<duckdb.DuckDBBundle | null> | null>(null);
22
22
  const resolver = React.useCallback(async () => {
23
- if (lock.current) return null;
24
- lock.current = true;
25
- try {
26
- setBundle(b => b.updateRunning());
27
- const next = await duckdb.selectBundle(props.bundles);
28
- lock.current = false;
29
- setBundle(b => b.completeWith(next));
30
- return next;
31
- } catch (e: any) {
32
- lock.current = false;
33
- console.error(e);
34
- setBundle(b => b.failWith(e));
35
- return null;
36
- }
23
+ if (bundle.error) return null;
24
+ if (bundle.value) return bundle.value;
25
+ if (inFlight.current) return await inFlight.current;
26
+ inFlight.current = (async () => {
27
+ try {
28
+ setBundle(b => b.updateRunning());
29
+ const next = await duckdb.selectBundle(props.bundles);
30
+ inFlight.current = null;
31
+ setBundle(b => b.completeWith(next));
32
+ return next;
33
+ } catch (e: any) {
34
+ inFlight.current = null;
35
+ console.error(e);
36
+ setBundle(b => b.failWith(e));
37
+ return null;
38
+ }
39
+ })();
40
+ return await inFlight.current;
37
41
  }, [props.bundles]);
38
42
 
39
43
  return (