export function createMachineSessionControlPageController({ panelFrame, statusNode, viewNode, renderControlView, pollMs = 200, setIntervalFn = globalThis.setInterval, } = {}) { if (!panelFrame) { throw new Error("A panel iframe is required."); } if (!statusNode) { throw new Error("A control page status node is required."); } if (!viewNode) { throw new Error("A control page view node is required."); } if (typeof renderControlView !== "function") { throw new Error("A control view renderer is required."); } let refreshTimer = null; function getPanelWindow() { return panelFrame.contentWindow ?? null; } function getPanelApi() { return getPanelWindow()?.linuxCncIniPanelApi ?? null; } function getControlView() { return getPanelApi()?.getMachineSessionControlView?.() ?? null; } function render() { const view = getControlView(); if (!view) { statusNode.textContent = "waiting for panel"; viewNode.textContent = ""; return null; } statusNode.textContent = [ view.status.lastAction ?? "-", view.status.runStatus ?? "-", view.status.error ?? "-", ].join(" | "); return renderControlView(viewNode, view); } function startPolling() { if (!refreshTimer) { refreshTimer = setIntervalFn(render, pollMs); } return refreshTimer; } function mount({ panelSrc = "./index.html" } = {}) { panelFrame.addEventListener("load", () => { render(); startPolling(); }); panelFrame.src = panelSrc; render(); startPolling(); return controller; } const controller = { getControlView, getPanelApi, getPanelWindow, mount, render, startPolling, }; return controller; }