Line data Source code
1 : import * as React from 'react';
2 :
3 : import { useSaveBeforeConnect } from './connection_persistence.js';
4 : import { cancelConnectionSetup, registerConnectionSetup } from './connection_setup_cancellation.js';
5 :
6 : /// The setup of a connection from its settings
7 : export interface ConnectionSetup {
8 : /// Run a setup with the saved settings, unsaved edits are saved first.
9 : /// The setup receives the signal that cancels it.
10 : run: (setup: (signal: AbortSignal) => Promise<void>) => Promise<void>;
11 : /// Cancel the running setup
12 : cancel: () => void;
13 : }
14 :
15 1 : export function useConnectionSetup(connectionId: string | null): ConnectionSetup {
16 1 : const saveBeforeConnect = useSaveBeforeConnect(connectionId);
17 1 : const controllerRef = React.useRef<AbortController | null>(null);
18 :
19 1 : const run = React.useCallback(async (setup: (signal: AbortSignal) => Promise<void>) => {
20 : // Connections are set up with saved settings, unsaved edits are saved first
21 1 : if (!await saveBeforeConnect()) return;
22 1 : const controller = new AbortController();
23 : // The startup and the settings share one cancellation owner per connection
24 1 : const unregister = connectionId == null ? () => { } : registerConnectionSetup(connectionId, controller);
25 1 : controllerRef.current = controller;
26 1 : try {
27 1 : await setup(controller.signal);
28 1 : } finally {
29 1 : unregister();
30 1 : if (controllerRef.current === controller) controllerRef.current = null;
31 1 : }
32 1 : }, [connectionId, saveBeforeConnect]);
33 :
34 1 : const cancel = React.useCallback(() => {
35 1 : if (connectionId != null) cancelConnectionSetup(connectionId);
36 1 : controllerRef.current?.abort(new DOMException('Connection setup cancelled', 'AbortError'));
37 1 : controllerRef.current = null;
38 1 : }, [connectionId]);
39 :
40 1 : return React.useMemo(() => ({ run, cancel }), [run, cancel]);
41 1 : }
|