import { INI_PANEL_ENTRIES, getIniPanelEntryByHref, getIniPanelEntryManifest, } from "./entry-manifest.js"; import { createMachineSessionControlPageController, } from "./control-page-controller.js"; import { renderMachineSessionControlView, } from "./control-view-renderer.js"; import { controlPageStatusText, createControlPageRefreshState, refreshMachineSessionControlPage, } from "./control-page-refresh-workflow.js"; import { createControlPageSessionLoadState, loadMachineSessionForControlPageWorkflow, } from "./control-page-session-workflow.js"; import { createMachineSessionReadonlyStatus, createMachineSessionReadonlyStatusApiManifest, readMachineSessionReadonlyStatus, } from "./readonly-status-api.js"; export { controlPageStatusText, createControlPageRefreshState, refreshMachineSessionControlPage, } from "./control-page-refresh-workflow.js"; export { createControlPageSessionLoadState, loadMachineSessionForControlPageWorkflow, } from "./control-page-session-workflow.js"; export { createMachineSessionReadonlyStatus, createMachineSessionReadonlyStatusApiManifest, readMachineSessionReadonlyStatus, } from "./readonly-status-api.js"; export { INI_PANEL_ENTRIES, getIniPanelEntryByHref, getIniPanelEntryManifest, } from "./entry-manifest.js"; export { createMachineSessionControlPageController, } from "./control-page-controller.js"; export { renderMachineSessionControlView, } from "./control-view-renderer.js"; export function getVisibleIniPanelEntries() { return getIniPanelEntryManifest(); } export function createIniPanelLauncherLinkViewModel(entries = getVisibleIniPanelEntries()) { return entries.map(({ id, href, title }) => ({ entryId: id, href, label: title, })); } export function createIniPanelLaunchApiSchema() { return { apiName: "ini-panel-launch", manifestVersion: 1, fields: [ "apiName", "manifestVersion", "methods", "visibleEntries", "targetPages", "controlPageApiMethods", "persistenceCapabilities", ], }; } export function isSupportedIniPanelLaunchApiManifest(manifest, schema = createIniPanelLaunchApiSchema()) { if (!manifest || typeof manifest !== "object") { return false; } if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) { return false; } return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName)); } export function createControlPageBrowserApiSchema() { return { apiName: "ini-panel-control-page", manifestVersion: 1, fields: [ "apiName", "manifestVersion", "methods", "contract", "readonlyStatusApiManifest", ], }; } export function isSupportedIniPanelControlPageApiManifest( manifest, schema = createControlPageBrowserApiSchema(), ) { if (!manifest || typeof manifest !== "object") { return false; } if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) { return false; } return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName)); } export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntries()) { const schema = createIniPanelLaunchApiSchema(); return { apiName: schema.apiName, manifestVersion: schema.manifestVersion, methods: [ "isSupportedLaunchApiManifest", "getLaunchApiSchema", "getLaunchApiManifest", "getShellIntegrationSchema", "getShellIntegrationManifest", "getLauncherLinks", "getControlPageApiMethods", ], visibleEntries: entries.map(({ id, href, title }) => ({ id, href, title, })), targetPages: entries.map(({ id, href }) => ({ entryId: id, href, })), controlPageApiMethods: createControlPageBrowserApiMethods(), persistenceCapabilities: [ { id: "machine-files", label: "Machine text files", scope: "opfs", }, { id: "session-snapshot", label: "Machine session snapshot", scope: "opfs", }, { id: "readonly-status", label: "Read-only machine session status", scope: "control-page", }, ], }; } export function createIniPanelShellControlPageContract() { const readonlyStatusApiManifest = createMachineSessionReadonlyStatusApiManifest(); return { methodNames: [ "createController", "loadSessionState", "readStatus", "refresh", "renderView", ], readonlyStatusApiManifest, readonlyStatusApiMethodNames: Object.keys(readonlyStatusApiManifest.methods), readonlyStatusApiStatusFields: readonlyStatusApiManifest.statusFields, relatedControlPageMethods: readonlyStatusApiManifest.relatedControlPageMethods, }; } export function createControlPageBrowserApiMethods() { return [ "isSupportedControlPageApiManifest", "getControlPageApiSchema", "getControlPageApiManifest", "getControlPageApiMethods", "getControlPageContract", "getControlView", "getPanelApi", "loadControlPageSessionState", "readControlPageStatus", "refreshControlPage", "renderControlPage", ]; } export function createControlPageBrowserApiManifest() { const schema = createControlPageBrowserApiSchema(); const contract = createIniPanelShellControlPageContract(); return { apiName: schema.apiName, manifestVersion: schema.manifestVersion, methods: createControlPageBrowserApiMethods(), contract, readonlyStatusApiManifest: contract.readonlyStatusApiManifest, }; } export function createIniPanelShellIntegrationSchema() { return { apiName: "ini-panel-shell-integration", manifestVersion: 1, fields: [ "apiName", "manifestVersion", "pages", "launcherLinks", "launchApiSchema", "launchApiManifest", "controlPageApiSchema", "controlPageApiManifest", "compatibility", "persistenceCapabilities", ], }; } export function isSupportedIniPanelShellIntegrationManifest( manifest, schema = createIniPanelShellIntegrationSchema(), ) { if (!manifest || typeof manifest !== "object") { return false; } if (manifest.apiName !== schema.apiName || manifest.manifestVersion !== schema.manifestVersion) { return false; } return schema.fields.every((fieldName) => Object.hasOwn(manifest, fieldName)); } export function createIniPanelShellIntegrationManifest(entries = getVisibleIniPanelEntries()) { const schema = createIniPanelShellIntegrationSchema(); const launchApiSchema = createIniPanelLaunchApiSchema(); const launchApiManifest = createIniPanelLaunchApiManifest(entries); const controlPageApiSchema = createControlPageBrowserApiSchema(); const controlPageApiManifest = createControlPageBrowserApiManifest(); return { apiName: schema.apiName, manifestVersion: schema.manifestVersion, pages: entries.map(({ id, href, title }) => ({ id, href, title, })), launcherLinks: createIniPanelLauncherLinkViewModel(entries), launchApiSchema, launchApiManifest, controlPageApiSchema, controlPageApiManifest, compatibility: { launchApiManifest: isSupportedIniPanelLaunchApiManifest(launchApiManifest, launchApiSchema), controlPageApiManifest: isSupportedIniPanelControlPageApiManifest( controlPageApiManifest, controlPageApiSchema, ), }, persistenceCapabilities: launchApiManifest.persistenceCapabilities, }; } export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { return { pages: entries.map(({ id, href, title }) => ({ id, href, title, })), launcherLinks: createIniPanelLauncherLinkViewModel(entries), shellIntegrationSchema: createIniPanelShellIntegrationSchema(), shellIntegrationManifest: createIniPanelShellIntegrationManifest(entries), launchApiSchema: createIniPanelLaunchApiSchema(), launchApiManifest: createIniPanelLaunchApiManifest(entries), isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), browserApiManifest: createControlPageBrowserApiManifest(), browserApiMethods: createControlPageBrowserApiMethods(), contract: createIniPanelShellControlPageContract(), createController: createMachineSessionControlPageController, isSupportedBrowserApiManifest: isSupportedIniPanelControlPageApiManifest, loadSessionState: loadMachineSessionForControlPageWorkflow, readonlyStatusApiManifest: createMachineSessionReadonlyStatusApiManifest(), readStatus: readMachineSessionReadonlyStatus, refresh: refreshMachineSessionControlPage, renderView: renderMachineSessionControlView, }, }; }