/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * useBimHost — React hook that initializes the SDK and BimHost. * * This hook: * 1. Creates a LocalBackend backed by the Zustand store * 2. Creates a BimContext (the `bim` object) * 3. Starts a BimHost listening on BroadcastChannel 'ifc-lite' * 4. External tools (ifc-scripts, ifc-flow) can connect to control the viewer * * Usage: * function App() { * const bim = useBimHost(); * // bim is available for internal use * // External tools can connect via BroadcastChannel 'ifc-lite' * } */ import { useRef, useEffect, useMemo } from 'react'; import { createBimContext, BimHost, type BimContext } from '@ifc-lite/sdk'; import { useViewerStore } from '../store/index.js'; import { LocalBackend } from './local-backend.js'; const BROADCAST_CHANNEL = 'ifc-lite'; /** * Initialize the SDK with a local backend and start the BimHost. * Returns the BimContext for internal use. */ export function useBimHost(): BimContext { const hostRef = useRef(null); const backendRef = useRef(null); // Create local backend and BimContext once — single shared backend const bim = useMemo(() => { const storeApi = { getState: useViewerStore.getState, subscribe: useViewerStore.subscribe, }; const backend = new LocalBackend(storeApi); backendRef.current = backend; return createBimContext({ backend }); }, []); // Start BimHost for external connections — reuse the same backend useEffect(() => { const backend = backendRef.current; if (!backend) return; const host = new BimHost(backend); try { host.listenBroadcast(BROADCAST_CHANNEL); } catch { // BroadcastChannel not available (e.g., in some test environments) } hostRef.current = host; return () => { host.close(); hostRef.current = null; }; }, []); return bim; }