| 1 | import { useEffect, useState } from "react"; |
| 2 | import { app, onRuntimeRebuilt } from "./bridge"; |
| 3 | import { runtimeStateStore } from "./runtimeStateStore"; |
| 4 | import type { ModelSettingsResult } from "./modelSettingsTypes"; |
| 5 | |
| 6 | // Lifecycle events request a coalesced read of backend-owned state. |
| 7 | export function useModelApplicationStatus(tabId?: string) { |
| 8 | const [target,setTarget]=useState<ModelSettingsResult["targets"][number]>(); |
| 9 | useEffect(()=>{ |
| 10 | setTarget(undefined); |
| 11 | if(!tabId || !app.GetModelSettingsApplication) return; |
| 12 | let active=true, reading=false, pending=false; |
| 13 | const refresh=async()=>{ |
| 14 | if(reading){pending=true;return;} |
| 15 | reading=true; |
| 16 | do { |
| 17 | pending=false; |
| 18 | try { |
| 19 | const result=await app.GetModelSettingsApplication(); |
| 20 | if(active) setTarget(result.targets.find(item=>item.tabId===tabId)); |
| 21 | } catch { /* Keep confirmed status on transport failure. */ } |
| 22 | } while(active && pending); |
| 23 | reading=false; |
| 24 | }; |
| 25 | const notify=()=>{void refresh();}; |
| 26 | const rebuilt=onRuntimeRebuilt(id=>{if(!id || id===tabId) notify();}); |
| 27 | const runtime=runtimeStateStore.subscribe(notify); |
| 28 | window.addEventListener("reasonix:model-catalog-changed",notify); |
| 29 | window.addEventListener("focus",notify); |
| 30 | notify(); |
| 31 | return ()=>{active=false;rebuilt();runtime();window.removeEventListener("reasonix:model-catalog-changed",notify);window.removeEventListener("focus",notify);}; |
| 32 | },[tabId]); |
| 33 | return target; |
| 34 | } |
| 35 |