Line data Source code
1 : import * as React from 'react';
2 :
3 : import type { EmbeddedComputeDatabase } from '../../platform/database/embedded_database.js';
4 : import { useEmbeddedDatabaseSetup } from '../../platform/database/embedded_database_provider.js';
5 : import type { HyperDBSourceDatabase } from '../../platform/hyperdb/hyperdb_incremental_extract.js';
6 : import { stringifyError } from '../../platform/logger/logger.js';
7 : import { useLogger } from '../../platform/logger/logger_provider.js';
8 :
9 1 : const LOG_CTX = 'demos';
10 :
11 : /// The data source of a demo, the HyperDB WASM of the page
12 : export interface DemoDataSource {
13 : /// The Hyper that the queries of the demo read
14 : database: HyperDBSourceDatabase;
15 : /// The HyperDB WASM of the page, the demo fills it itself
16 : embedded: EmbeddedComputeDatabase;
17 : /// The version of the Hyper
18 : version: string | null;
19 : }
20 :
21 : /// The state of the setup of a data source
22 : export interface DemoDataSourceState {
23 : /// The connected source, null while it is set up or after it failed
24 : source: DemoDataSource | null;
25 : /// The error of the setup
26 : error: string | null;
27 : }
28 :
29 : /// Set up the data source of a demo
30 1 : export function useDemoDataSource(): DemoDataSourceState {
31 1 : const logger = useLogger();
32 1 : const setupEmbedded = useEmbeddedDatabaseSetup();
33 1 : const [state, setState] = React.useState<DemoDataSourceState>({ source: null, error: null });
34 :
35 1 : React.useEffect(() => {
36 1 : setState({ source: null, error: null });
37 1 : let cancelled = false;
38 1 : const setup = async (): Promise<DemoDataSource> => {
39 1 : const embedded = await setupEmbedded('demos');
40 : // The tables of the demo live in the user database of the page, a fresh one per page load
41 : const database: HyperDBSourceDatabase = {
42 1 : connect: options => embedded.connect({ ...options, defaultDatabase: 'hyper' }),
43 : };
44 1 : return { database, embedded, version: await embedded.getVersion() };
45 1 : };
46 1 : setup().then(
47 1 : source => { if (!cancelled) setState({ source, error: null }); },
48 0 : error => {
49 0 : logger.error('Setting up the data source of the demo failed', { error: stringifyError(error) }, LOG_CTX);
50 0 : if (!cancelled) setState({ source: null, error: error instanceof Error ? error.message : String(error) });
51 0 : },
52 1 : );
53 1 : return () => { cancelled = true; };
54 1 : }, [setupEmbedded, logger]);
55 :
56 1 : return state;
57 1 : }
|