Line data Source code
1 : import * as React from 'react';
2 :
3 : import type { ConnectionState } from '../connections/connection_state.js';
4 : import { useConnectionReferences, useConnectionRegistryStore } from '../connections/connection_registry.js';
5 : import { connectionLabelParts, connectionOrdinals, type ConnectionLabelParts } from '../connections/connection_label.js';
6 : import { useSessionScriptsRegistry } from './scripts/session_scripts_registry.js';
7 :
8 1 : const subscribeNever = () => () => {};
9 :
10 : /// The ordinals that tell connections of the same connector apart, see `connectionOrdinals`.
11 : /// The map keeps its identity while the ordinals are unchanged.
12 1 : export function useConnectionOrdinals(): ReadonlyMap<string, number> {
13 : // Re-number when the sessions use other connections
14 1 : const [scripts] = useSessionScriptsRegistry();
15 1 : const references = useConnectionReferences();
16 : // The registry changes with every query, the selector returns a string to compare by value
17 1 : const selectKey = React.useCallback(
18 1 : (registry: Parameters<typeof connectionOrdinals>[0]) => [...connectionOrdinals(registry, references)]
19 1 : .map(([connectionId, ordinal]) => `${connectionId}=${ordinal}`)
20 1 : .join(','),
21 1 : [references, scripts],
22 1 : );
23 : // Views outside of a connection registry (e.g. in tests) number no connections
24 1 : const store = useConnectionRegistryStore();
25 1 : const key = React.useSyncExternalStore(store?.subscribe ?? subscribeNever, () => store == null ? '' : selectKey(store.current));
26 1 : return React.useMemo(() => new Map(key.length === 0 ? [] : key.split(',').map(entry => {
27 0 : const [connectionId, ordinal] = entry.split('=');
28 0 : return [connectionId, Number(ordinal)] as const;
29 1 : })), [key]);
30 1 : }
31 :
32 : /// Label connections after their connectors and their ordinals
33 1 : export function useConnectionLabeler(): (database: ConnectionState) => ConnectionLabelParts {
34 1 : const ordinals = useConnectionOrdinals();
35 1 : return React.useCallback(
36 1 : (database: ConnectionState) => connectionLabelParts(database, ordinals.get(database.connectionId) ?? null),
37 1 : [ordinals],
38 1 : );
39 1 : }
|