Line data Source code
1 : import * as React from 'react';
2 : import * as core from '@ankoh/dashql-core';
3 :
4 : // The layout module is an asset of the core package, loaded when the dataflow canvas opens
5 : // eslint-disable-next-line import/no-unresolved -- resolved by bundler
6 : import dataflowWasmUrl from '@ankoh/dashql-core/dataflow-wasm?url';
7 1 : const DATAFLOW_WASM_URL = typeof dataflowWasmUrl === 'string' ? dataflowWasmUrl : new URL(dataflowWasmUrl as string, import.meta.url).href;
8 :
9 1 : let loading: Promise<core.DashQLDataflow> | null = null;
10 :
11 : /// Load the layout module of the dataflow canvas once, a failed load is tried again by the next call
12 1 : export function loadDataflowModule(): Promise<core.DashQLDataflow> {
13 1 : loading ??= (async () => {
14 1 : const response = await fetch(DATAFLOW_WASM_URL);
15 1 : if (!response.ok) throw new Error(`Failed to fetch the layout wasm: ${response.status} ${response.statusText}`);
16 1 : return core.DashQLDataflow.create({ wasmBinary: new Uint8Array(await response.arrayBuffer()) });
17 1 : })();
18 1 : loading.catch(() => {
19 0 : loading = null;
20 1 : });
21 1 : return loading;
22 1 : }
23 :
24 : /// The layout module of the dataflow canvas, null while it loads
25 : export interface DataflowModule {
26 : layout: core.DashQLDataflow | null;
27 : error: Error | null;
28 : }
29 :
30 : /// Load the layout module of the dataflow canvas when a canvas mounts
31 1 : export function useDataflowModule(): DataflowModule {
32 1 : const [state, setState] = React.useState<DataflowModule>({ layout: null, error: null });
33 1 : React.useEffect(() => {
34 1 : let cancelled = false;
35 1 : loadDataflowModule().then(
36 1 : layout => { if (!cancelled) setState({ layout, error: null }); },
37 0 : error => { if (!cancelled) setState({ layout: null, error: error instanceof Error ? error : new Error(String(error)) }); },
38 1 : );
39 1 : return () => { cancelled = true; };
40 1 : }, []);
41 1 : return state;
42 1 : }
|