@elementspanel/panel 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/app.js +3940 -180
  2. package/app.js.map +1 -1
  3. package/package.json +18 -18
  4. package/public/assets/{AppDialog.vue_vue_type_style_index_0_lang-8b56f871.js → AppDialog.vue_vue_type_style_index_0_lang-e6e38e8b.js} +2 -2
  5. package/public/assets/AppDialog.vue_vue_type_style_index_0_lang-e6e38e8b.js.map +1 -0
  6. package/public/assets/CardPanel-59b7da2e.js +2 -0
  7. package/public/assets/CardPanel-59b7da2e.js.map +1 -0
  8. package/public/assets/{DesktopDialog-081410ca.js → DesktopDialog-e4041e4e.js} +2 -2
  9. package/public/assets/DesktopDialog-e4041e4e.js.map +1 -0
  10. package/public/assets/{Loading.vue_vue_type_script_setup_true_lang-9e79de95.js → Loading.vue_vue_type_script_setup_true_lang-1b74dd54.js} +2 -2
  11. package/public/assets/Loading.vue_vue_type_script_setup_true_lang-1b74dd54.js.map +1 -0
  12. package/public/assets/{PageToolbar-5ca1a069.js → PageToolbar-7130e13d.js} +2 -2
  13. package/public/assets/PageToolbar-7130e13d.js.map +1 -0
  14. package/public/assets/{_elements-sdk_pinia-fc8ba898.js → _elements-sdk_pinia-2c56d2c1.js} +3 -3
  15. package/public/assets/{_elements-sdk_pinia-fc8ba898.js.map → _elements-sdk_pinia-2c56d2c1.js.map} +1 -1
  16. package/public/assets/{_elements-sdk_vue-b86b0db6.js → _elements-sdk_vue-80f42d87.js} +2 -2
  17. package/public/assets/_elements-sdk_vue-80f42d87.js.map +1 -0
  18. package/public/assets/{_elements-sdk_vue-i18n-64f8e172.js → _elements-sdk_vue-i18n-4b8a106a.js} +2 -2
  19. package/public/assets/_elements-sdk_vue-i18n-4b8a106a.js.map +1 -0
  20. package/public/assets/{_elements-sdk_vue-router-a62f518d.js → _elements-sdk_vue-router-a171591a.js} +2 -2
  21. package/public/assets/_elements-sdk_vue-router-a171591a.js.map +1 -0
  22. package/public/assets/{const-cfe7ddfe.js → const-93b324c0.js} +2 -2
  23. package/public/assets/const-93b324c0.js.map +1 -0
  24. package/public/assets/{const-01673e6b.js → const-ea30795c.js} +2 -2
  25. package/public/assets/const-ea30795c.js.map +1 -0
  26. package/public/assets/{context-b16af9cc.js → context-cc90576e.js} +2 -2
  27. package/public/assets/{context-b16af9cc.js.map → context-cc90576e.js.map} +1 -1
  28. package/public/assets/{copy-4d64fc1f.js → copy-b106bb10.js} +2 -2
  29. package/public/assets/copy-b106bb10.js.map +1 -0
  30. package/public/assets/{core-b6992169.js → core-d3bfdede.js} +2 -2
  31. package/public/assets/core-d3bfdede.js.map +1 -0
  32. package/public/assets/{desktopNotice-2c886f6b.js → desktopNotice-5ca3448c.js} +2 -2
  33. package/public/assets/desktopNotice-5ca3448c.js.map +1 -0
  34. package/public/assets/dom-ff483262.js.map +1 -1
  35. package/public/assets/{i18n-fe0f1ee7.js → i18n-e810b9fa.js} +2 -2
  36. package/public/assets/i18n-e810b9fa.js.map +1 -0
  37. package/public/assets/{index-76b0df52.js → index-6e8d74f8.js} +2 -2
  38. package/public/assets/{index-76b0df52.js.map → index-6e8d74f8.js.map} +1 -1
  39. package/public/assets/index-e3f35709.js.map +1 -1
  40. package/public/assets/{instance-26cca4c8.js → instance-cc59e210.js} +2 -2
  41. package/public/assets/instance-cc59e210.js.map +1 -0
  42. package/public/assets/lodash-001e4f93.js.map +1 -1
  43. package/public/assets/{nodes-402cdcbd.js → nodes-a56b1b35.js} +2 -2
  44. package/public/assets/nodes-a56b1b35.js.map +1 -0
  45. package/public/assets/protocol-97f7bab7.js.map +1 -1
  46. package/public/assets/randId-56f93901.js +2 -0
  47. package/public/assets/randId-56f93901.js.map +1 -0
  48. package/public/assets/{router-0f7d4714.js → router-eff205cc.js} +2 -2
  49. package/public/assets/router-eff205cc.js.map +1 -0
  50. package/public/assets/safe-87846d89.js.map +1 -1
  51. package/public/assets/{sdk-01dda668.js → sdk-3f2277ab.js} +2 -2
  52. package/public/assets/sdk-3f2277ab.js.map +1 -0
  53. package/public/assets/{shared-f2e37690.js → shared-597ef52b.js} +2 -2
  54. package/public/assets/shared-597ef52b.js.map +1 -0
  55. package/public/assets/{useAppConfigStore-289073ec.js → useAppConfigStore-352fe033.js} +2 -2
  56. package/public/assets/useAppConfigStore-352fe033.js.map +1 -0
  57. package/public/assets/useAppRouters-747b627a.js +2 -0
  58. package/public/assets/useAppRouters-747b627a.js.map +1 -0
  59. package/public/assets/{useAppStateStore-a644582a.js → useAppStateStore-a438b9a6.js} +2 -2
  60. package/public/assets/useAppStateStore-a438b9a6.js.map +1 -0
  61. package/public/assets/{useAppToolsStore-3a911226.js → useAppToolsStore-288c4fe8.js} +2 -2
  62. package/public/assets/useAppToolsStore-288c4fe8.js.map +1 -0
  63. package/public/assets/{useDefineApi-ead2616e.js → useDefineApi-b726db1e.js} +2 -2
  64. package/public/assets/useDefineApi-b726db1e.js.map +1 -0
  65. package/public/assets/{useInstanceActionAvailability-dec16c10.js → useInstanceActionAvailability-16de3001.js} +2 -2
  66. package/public/assets/useInstanceActionAvailability-16de3001.js.map +1 -0
  67. package/public/assets/{useKeyboardEvents-dba9d5ca.js → useKeyboardEvents-6f7f845c.js} +2 -2
  68. package/public/assets/useKeyboardEvents-6f7f845c.js.map +1 -0
  69. package/public/assets/{useMountComponent-dd1fcfea.js → useMountComponent-4043cb4c.js} +2 -2
  70. package/public/assets/useMountComponent-4043cb4c.js.map +1 -0
  71. package/public/assets/{useOverviewChart-119bda3b.js → useOverviewChart-7d758bc4.js} +2 -2
  72. package/public/assets/useOverviewChart-7d758bc4.js.map +1 -0
  73. package/public/assets/{useOverviewInfo-a149d634.js → useOverviewInfo-9ca25ab9.js} +2 -2
  74. package/public/assets/useOverviewInfo-9ca25ab9.js.map +1 -0
  75. package/public/assets/{usePolling-f2f09d27.js → usePolling-1bc2009b.js} +2 -2
  76. package/public/assets/usePolling-1bc2009b.js.map +1 -0
  77. package/public/assets/{useScreen-e3715e1f.js → useScreen-fad29b7c.js} +2 -2
  78. package/public/assets/useScreen-fad29b7c.js.map +1 -0
  79. package/public/assets/{useSocketIo-bc0a62c2.js → useSocketIo-ea3c9a61.js} +2 -2
  80. package/public/assets/useSocketIo-ea3c9a61.js.map +1 -0
  81. package/public/assets/{useThemeSwitch-6ff90248.js → useThemeSwitch-dc70883c.js} +2 -2
  82. package/public/assets/useThemeSwitch-dc70883c.js.map +1 -0
  83. package/public/assets/{vue-2433bd89.js → vue-6b52a630.js} +2 -2
  84. package/public/assets/{vue-2433bd89.js.map → vue-6b52a630.js.map} +1 -1
  85. package/public/assets/{vuetifyModal-49cb95ba.js → vuetifyModal-8382b175.js} +2 -2
  86. package/public/assets/vuetifyModal-8382b175.js.map +1 -0
  87. package/public/index.html +4 -4
  88. package/public/stats.html +2 -2
  89. package/runtime/npm-plugins.cjs +42 -11
  90. package/runtime/plugin-resolution.cjs +27 -9
  91. package/public/assets/AppDialog.vue_vue_type_style_index_0_lang-8b56f871.js.map +0 -1
  92. package/public/assets/CardPanel-a704f146.js +0 -2
  93. package/public/assets/CardPanel-a704f146.js.map +0 -1
  94. package/public/assets/DesktopDialog-081410ca.js.map +0 -1
  95. package/public/assets/Loading.vue_vue_type_script_setup_true_lang-9e79de95.js.map +0 -1
  96. package/public/assets/PageToolbar-5ca1a069.js.map +0 -1
  97. package/public/assets/_elements-sdk_vue-b86b0db6.js.map +0 -1
  98. package/public/assets/_elements-sdk_vue-i18n-64f8e172.js.map +0 -1
  99. package/public/assets/_elements-sdk_vue-router-a62f518d.js.map +0 -1
  100. package/public/assets/const-01673e6b.js.map +0 -1
  101. package/public/assets/const-cfe7ddfe.js.map +0 -1
  102. package/public/assets/copy-4d64fc1f.js.map +0 -1
  103. package/public/assets/core-b6992169.js.map +0 -1
  104. package/public/assets/desktopNotice-2c886f6b.js.map +0 -1
  105. package/public/assets/i18n-fe0f1ee7.js.map +0 -1
  106. package/public/assets/instance-26cca4c8.js.map +0 -1
  107. package/public/assets/nodes-402cdcbd.js.map +0 -1
  108. package/public/assets/randId-ed0b95b7.js +0 -2
  109. package/public/assets/randId-ed0b95b7.js.map +0 -1
  110. package/public/assets/router-0f7d4714.js.map +0 -1
  111. package/public/assets/sdk-01dda668.js.map +0 -1
  112. package/public/assets/shared-f2e37690.js.map +0 -1
  113. package/public/assets/useAppConfigStore-289073ec.js.map +0 -1
  114. package/public/assets/useAppRouters-5f58db32.js +0 -2
  115. package/public/assets/useAppRouters-5f58db32.js.map +0 -1
  116. package/public/assets/useAppStateStore-a644582a.js.map +0 -1
  117. package/public/assets/useAppToolsStore-3a911226.js.map +0 -1
  118. package/public/assets/useDefineApi-ead2616e.js.map +0 -1
  119. package/public/assets/useInstanceActionAvailability-dec16c10.js.map +0 -1
  120. package/public/assets/useKeyboardEvents-dba9d5ca.js.map +0 -1
  121. package/public/assets/useMountComponent-dd1fcfea.js.map +0 -1
  122. package/public/assets/useOverviewChart-119bda3b.js.map +0 -1
  123. package/public/assets/useOverviewInfo-a149d634.js.map +0 -1
  124. package/public/assets/usePolling-f2f09d27.js.map +0 -1
  125. package/public/assets/useScreen-e3715e1f.js.map +0 -1
  126. package/public/assets/useSocketIo-bc0a62c2.js.map +0 -1
  127. package/public/assets/useThemeSwitch-6ff90248.js.map +0 -1
  128. package/public/assets/vuetifyModal-49cb95ba.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["trackPluginDisposal","ctx","pending","failures","tracked","scopes","observe","scope","reset","dispose","wrapper","args","result","error","task","key","errors","FOUNDATION_SERVICES","ESSENTIAL_PLUGIN_IDS","change","createPluginQueue","settle","plugins","shallowReactive","sources","compareSources","a","b","requiredServices","module","value","name","scopeState","refreshPluginState","plugin","pluginError","_a","_b","notifyPluginDiagnostics","candidate","normalizeMetadata","id","toModule","loadStyles","source","links","href","resolve","reject","link","removePluginStyles","style","normalizedHref","fetchProductionSources","manifestUrl","response","body","manifest","toUrl","item","metadata","entry","entryUrl","cacheKey","url","__vitePreload","discoverSources","discovered","unique","resolveSourceGraph","resolvePluginDependencyOrder","preloadPluginAssets","validatePluginCompatibility","preparePlugin","removeStyles","styles","recordGraphFailure","existing","install","configOverride","prepared","unavailableDependencies","resources","applied","thrown","_c","isCurrentRoute","vue","routes","record","unloadPluginInternal","index","loadPluginInternal","refreshPluginsInternal","reloadPluginInternal","next","graph","issue","current","changed","bootstrapPanelFrontendPlugins","removePreloads","getLoadedPlugins","getPluginDiagnostics","auditFrontendPlugins","unloadPlugin","loadPlugin","reloadPlugin","refreshPlugins","watchPluginChanges","events","revision","stopped","retry","synchronize","event","setupPanelFrontendPlugins","startup","host"],"sources":["../../../common/src/plugin_lifecycle.ts","../../src/plugin/loader.ts","../../src/plugin/install.ts","../../src/main.ts"],"sourcesContent":["/** Cordis 3 starts async disposers without awaiting them. Track them per host. */\nexport function trackPluginDisposal(ctx: any) {\n const pending = new Set<Promise<unknown>>();\n const failures: unknown[] = [];\n const tracked = new WeakSet<Function>();\n const scopes = new WeakSet<object>();\n const observe = (scope: any) => {\n if (scopes.has(scope)) return;\n scopes.add(scope);\n const reset = scope.reset;\n scope.reset = function () {\n this.disposables = this.disposables.map((dispose: Function) => {\n if (tracked.has(dispose)) return dispose;\n const wrapper = (...args: unknown[]) => {\n let result: unknown;\n try {\n result = dispose(...args);\n } catch (error) {\n failures.push(error);\n throw error;\n }\n if (result && typeof (result as Promise<unknown>).then === \"function\") {\n const task = Promise.resolve(result)\n .catch((error) => {\n failures.push(error);\n })\n .finally(() => pending.delete(task));\n pending.add(task);\n }\n return result;\n };\n // Cordis marks persistent disposers with a symbol; preserve its semantics.\n for (const key of Object.getOwnPropertySymbols(dispose))\n Object.defineProperty(wrapper, key, Object.getOwnPropertyDescriptor(dispose, key)!);\n tracked.add(wrapper);\n return wrapper;\n });\n return reset.call(this);\n };\n };\n ctx.on(\"internal/runtime\", observe);\n ctx.on(\"internal/fork\", observe);\n return async () => {\n do {\n await ctx.events.flush();\n await Promise.all([...pending]);\n } while (pending.size);\n if (failures.length) {\n const errors = failures.splice(0);\n throw new Error(`Plugin cleanup failed: ${errors.map(String).join(\"; \")}`);\n }\n };\n}\n","import {\n createPluginQueue,\n resolvePluginDependencyOrder,\n type PluginState,\n validatePluginCompatibility\n} from \"../../../common/src/plugin_contract\";\nimport { trackPluginDisposal } from \"../../../common/src/plugin_lifecycle\";\nimport { shallowReactive } from \"vue\";\nimport type { EffectScope, ForkScope } from \"cordis\";\nimport {\n ctx,\n type PanelFrontendPluginContext,\n type PanelFrontendPluginDiagnostic\n} from \"./context\";\nimport { panelPluginModules } from \"virtual:panel-plugins\";\n\nconst FOUNDATION_SERVICES: Record<string, string> = {\n runtime: \"startup\",\n i18n: \"i18n\",\n console: \"console\"\n};\nconst ESSENTIAL_PLUGIN_IDS = new Set(Object.keys(FOUNDATION_SERVICES));\nconst change = createPluginQueue();\nconst settle = trackPluginDisposal(ctx);\n\n/**\n * Fetches plugin code and hands it to cordis.\n *\n * Discovery is unchanged: in development the Vite plugin supplies a virtual\n * module of static imports; in production the browser fetches\n * `plugins/manifest.json` and imports each entry by URL. What that feeds is now\n * `ctx.plugin()`, and unloading is `fork.dispose()` — every route, card, menu,\n * action and translation the plugin registered is an effect of its scope.\n */\n\nexport interface PanelFrontendPluginMetadata {\n id: string;\n version?: string;\n description?: string;\n enabled?: boolean;\n priority?: number;\n frontend?: string;\n ui?: string;\n frontendInject?: string[];\n frontendImmediate?: boolean;\n frontendRequired?: boolean;\n config?: unknown;\n restartRequired?: boolean;\n [key: string]: unknown;\n}\n\n/** A frontend plugin module, as its entry exports it. */\nexport interface PanelFrontendPluginModule {\n inject?: string[] | Record<string, { required: boolean }>;\n apply(ctx: PanelFrontendPluginContext, config?: unknown): void | Promise<void>;\n}\n\ninterface PluginSource {\n metadata: PanelFrontendPluginMetadata;\n directory: string;\n assetDirectory: string;\n entry?: string;\n revision?: string;\n styles?: string[];\n load: (cacheKey?: string) => Promise<Record<string, unknown>>;\n}\n\ntype PreparedPlugin =\n | { module: PanelFrontendPluginModule; removeStyles?: () => void }\n | { error: Error };\n\nexport interface LoadedPanelFrontendPlugin {\n metadata: PanelFrontendPluginMetadata;\n directory: string;\n state: PluginState;\n requiredServices: readonly string[];\n missingServices: readonly string[];\n revision?: string;\n fork?: ForkScope;\n error?: Error;\n restartRequired?: boolean;\n reloadRequired?: boolean;\n}\n\ninterface InternalPlugin extends LoadedPanelFrontendPlugin {\n source: PluginSource;\n /** Only the stylesheet links, which are not cordis effects. */\n removeStyles?: () => void;\n}\n\nconst plugins = shallowReactive<InternalPlugin[]>([]);\nconst sources = new Map<string, PluginSource>();\n\nfunction compareSources(a: PluginSource, b: PluginSource) {\n return (\n (Number(a.metadata.priority) || 0) - (Number(b.metadata.priority) || 0) ||\n a.metadata.id.localeCompare(b.metadata.id)\n );\n}\n\nfunction requiredServices(module: PanelFrontendPluginModule) {\n if (Array.isArray(module.inject)) return [...new Set(module.inject)];\n if (!module.inject) return [];\n return Object.entries(module.inject)\n .filter(([, value]) => value?.required)\n .map(([name]) => name);\n}\n\nfunction scopeState(scope?: ForkScope): PluginState {\n if (!scope) return \"failed\";\n if (scope.error || scope.runtime.error) return \"failed\";\n switch (scope.status) {\n case 0: // ScopeStatus.PENDING\n return \"pending\";\n case 1: // ScopeStatus.LOADING\n return \"loading\";\n case 2: // ScopeStatus.ACTIVE\n return \"active\";\n case 3: // ScopeStatus.FAILED\n case 4: // ScopeStatus.DISPOSED\n return \"failed\";\n default:\n return \"pending\";\n }\n}\n\nfunction refreshPluginState(plugin: InternalPlugin) {\n plugin.missingServices = plugin.requiredServices.filter((name) => !ctx.get(name as never));\n plugin.state =\n plugin.restartRequired || plugin.reloadRequired\n ? \"restart-required\"\n : plugin.error\n ? \"failed\"\n : scopeState(plugin.fork);\n}\n\nfunction pluginError(plugin: InternalPlugin): Error | undefined {\n const error = plugin.error || plugin.fork?.error || plugin.fork?.runtime.error;\n if (error === undefined || error === null) return undefined;\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction notifyPluginDiagnostics() {\n for (const plugin of plugins) refreshPluginState(plugin);\n}\n\nctx.on(\"internal/status\", (scope: EffectScope) => {\n const plugin = plugins.find((candidate) => candidate.fork === scope);\n if (plugin) notifyPluginDiagnostics();\n});\n\nfunction normalizeMetadata(value: Record<string, unknown>): PanelFrontendPluginMetadata | null {\n const id = typeof value.id === \"string\" ? value.id.trim() : \"\";\n if (!id) return null;\n return { ...value, id } as PanelFrontendPluginMetadata;\n}\n\n/**\n * The plugin object a module exports, whether as named exports or as `default`.\n *\n * Only an object counts: every function has `Function.prototype.apply`, so a\n * module whose default export is a function would otherwise be mistaken for a\n * plugin and then called with the context as `this`.\n */\nfunction toModule(value: any, id: string): PanelFrontendPluginModule | undefined {\n for (const candidate of [value, value?.default]) {\n if (typeof candidate !== \"object\" || candidate === null) continue;\n if (typeof candidate.apply === \"function\") return candidate;\n }\n ctx.logger(\"plugin\").warn(`Panel frontend plugin \"${id}\" must export an apply() function.`);\n return undefined;\n}\n\nasync function loadStyles(source: PluginSource) {\n const links: HTMLLinkElement[] = [];\n try {\n await Promise.all(\n (source.styles || []).map(\n (href) =>\n new Promise<void>((resolve, reject) => {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.dataset.panelPlugin = source.metadata.id;\n link.addEventListener(\"load\", () => resolve(), { once: true });\n link.addEventListener(\n \"error\",\n () => reject(new Error(`Failed to load panel plugin stylesheet: ${href}`)),\n { once: true }\n );\n document.head.appendChild(link);\n links.push(link);\n })\n )\n );\n } catch (error) {\n links.forEach((link) => link.remove());\n throw error;\n }\n return () => links.forEach((link) => link.remove());\n}\n\n/**\n * Removes stylesheets the plugin injected itself, which the core cannot track:\n * `<style>` elements it tagged, and any `<link>` matching one of its hrefs.\n */\nfunction removePluginStyles(source: PluginSource) {\n document\n .querySelectorAll<HTMLStyleElement>(\n `style[data-panel-plugin=${JSON.stringify(source.metadata.id)}]`\n )\n .forEach((style) => style.remove());\n for (const href of source.styles || []) {\n const normalizedHref = new URL(href, document.baseURI).href;\n document.querySelectorAll<HTMLLinkElement>(\"link[rel='stylesheet']\").forEach((link) => {\n try {\n if (new URL(link.href, document.baseURI).href === normalizedHref) link.remove();\n } catch {\n // Ignore malformed third-party stylesheet URLs.\n }\n });\n }\n}\n\nasync function fetchProductionSources(): Promise<PluginSource[]> {\n const manifestUrl = new URL(\"plugins/manifest.json\", document.baseURI);\n const response = await fetch(manifestUrl.href, { cache: \"no-store\" });\n if (!response.ok) {\n if (response.status === 404) return [];\n throw new Error(`Failed to load panel plugin manifest: HTTP ${response.status}`);\n }\n const body = await response.json();\n // Older panel builds may still pass the manifest through the standard API\n // envelope. Accept both the raw array and `{ data: [...] }` forms.\n const manifest = Array.isArray(body) ? body : body?.data;\n if (!Array.isArray(manifest)) throw new Error(\"Invalid panel plugin manifest.\");\n\n const toUrl = (value: string) => new URL(value, manifestUrl).href;\n const result: PluginSource[] = [];\n for (const item of manifest) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const metadata = normalizeMetadata((item as any).metadata || item);\n const entry = typeof (item as any).entry === \"string\" ? (item as any).entry : \"\";\n if (!metadata || metadata.enabled === false || !entry) continue;\n const entryUrl = toUrl(entry);\n result.push({\n metadata,\n directory:\n typeof (item as any).directory === \"string\" ? (item as any).directory : metadata.id,\n assetDirectory:\n typeof (item as any).assetDirectory === \"string\"\n ? (item as any).assetDirectory\n : metadata.id,\n entry: entryUrl,\n revision: typeof item.revision === \"string\" ? item.revision : String(metadata.version || \"\"),\n styles: Array.isArray((item as any).styles)\n ? (item as any).styles\n .filter((style: unknown): style is string => typeof style === \"string\")\n .map(toUrl)\n : [],\n load: async (cacheKey) => {\n const url = new URL(entryUrl);\n if (cacheKey) url.searchParams.set(\"panel_plugin_reload\", cacheKey);\n return import(/* @vite-ignore */ url.href) as Promise<Record<string, unknown>>;\n }\n });\n }\n return result;\n}\n\nasync function discoverSources() {\n const discovered = import.meta.env.DEV\n ? (panelPluginModules as PluginSource[])\n : await fetchProductionSources();\n const unique = new Map<string, PluginSource>();\n for (const source of discovered) {\n const metadata = normalizeMetadata(source.metadata);\n if (!metadata || metadata.enabled === false || unique.has(metadata.id)) continue;\n unique.set(metadata.id, { ...source, metadata });\n }\n return [...unique.values()].sort(compareSources);\n}\n\nfunction resolveSourceGraph(discovered: readonly PluginSource[]) {\n return resolvePluginDependencyOrder(discovered, {\n id: (source) => source.metadata.id,\n dependencies: (source) => source.metadata.frontendInject,\n compare: compareSources\n });\n}\n\n/** Fetch production assets during foundation startup without evaluating plugin code. */\nfunction preloadPluginAssets(discovered: readonly PluginSource[]) {\n const links: HTMLLinkElement[] = [];\n if (!import.meta.env.DEV) {\n for (const source of resolveSourceGraph(discovered).ordered) {\n try {\n validatePluginCompatibility(source.metadata.elements);\n } catch {\n continue;\n }\n if (source.metadata.restartRequired || !source.entry) continue;\n const module = document.createElement(\"link\");\n module.rel = \"modulepreload\";\n module.href = source.entry;\n module.crossOrigin = \"anonymous\";\n document.head.appendChild(module);\n links.push(module);\n for (const href of source.styles || []) {\n const style = document.createElement(\"link\");\n style.rel = \"preload\";\n style.setAttribute(\"as\", \"style\");\n style.href = href;\n document.head.appendChild(style);\n links.push(style);\n }\n }\n }\n return () => links.forEach((link) => link.remove());\n}\n\n/** Preparation never rejects, so an optional download failure cannot abort the batch. */\nasync function preparePlugin(source: PluginSource, cacheKey?: string): Promise<PreparedPlugin> {\n let removeStyles: (() => void) | undefined;\n try {\n validatePluginCompatibility(source.metadata.elements);\n if (source.metadata.restartRequired)\n throw new Error(\"The plugin backend requires a restart before this version can load.\");\n const [styles, entry] = await Promise.allSettled([\n import.meta.env.DEV ? Promise.resolve(undefined) : loadStyles(source),\n Promise.resolve().then(() => source.load(cacheKey))\n ]);\n if (styles.status === \"rejected\") throw styles.reason;\n removeStyles = styles.value;\n if (entry.status === \"rejected\") throw entry.reason;\n const module = toModule(entry.value, source.metadata.id);\n if (!module)\n throw new Error(`Panel frontend plugin has no apply() export: ${source.metadata.id}`);\n return { module, removeStyles };\n } catch (error) {\n removeStyles?.();\n return { error: error instanceof Error ? error : new Error(String(error)) };\n }\n}\n\nfunction recordGraphFailure(source: PluginSource, error: Error) {\n const existing = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (existing) {\n existing.error = error;\n existing.state = \"failed\";\n notifyPluginDiagnostics();\n return existing;\n }\n const plugin = shallowReactive<InternalPlugin>({\n source,\n metadata: source.metadata,\n directory: source.directory,\n revision: source.revision,\n state: \"failed\",\n requiredServices: [],\n missingServices: [],\n error\n });\n plugins.push(plugin);\n notifyPluginDiagnostics();\n return plugin;\n}\n\nasync function install(\n source: PluginSource,\n cacheKey?: string,\n configOverride?: unknown,\n prepared?: PreparedPlugin\n) {\n const existing = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (existing) return existing;\n\n const unavailableDependencies = (source.metadata.frontendInject || []).filter(\n (id) => plugins.find((plugin) => plugin.metadata.id === id)?.state !== \"active\"\n );\n if (unavailableDependencies.length) {\n if (prepared && \"module\" in prepared) prepared.removeStyles?.();\n return recordGraphFailure(\n source,\n new Error(\n `Frontend plugin dependencies are not active: ${unavailableDependencies.join(\", \")}`\n )\n );\n }\n\n const plugin = shallowReactive<InternalPlugin>({\n source,\n metadata: source.metadata,\n directory: source.directory,\n revision: source.revision,\n state: \"loading\",\n requiredServices: [],\n missingServices: []\n });\n plugins.push(plugin);\n notifyPluginDiagnostics();\n try {\n const resources = prepared ?? (await preparePlugin(source, cacheKey));\n if (\"error\" in resources) throw resources.error;\n plugin.removeStyles = resources.removeStyles;\n const { module } = resources;\n plugin.requiredServices = requiredServices(module);\n {\n // An `async apply()` is awaited here, so a plugin is fully applied before\n // the next one activates and before the app is mounted. Resource loading\n // happens in parallel before this dependency-ordered activation phase.\n //\n // cordis catches a synchronous throw from `apply()` and cancels the scope\n // itself, so the wrapper keeps a copy of it: without that, a plugin that\n // failed on its first line would still be reported as loaded.\n let applied: unknown;\n let thrown: unknown;\n // The manifest id is the plugin's name, so `ctx.name` — which is what\n // appears in its log lines — always matches `plugin.json`.\n plugin.fork = ctx.plugin(\n {\n ...module,\n name: source.metadata.id,\n apply: (...args) => {\n try {\n return (applied = module.apply(...args));\n } catch (error) {\n thrown = error;\n throw error;\n }\n }\n },\n configOverride === undefined\n ? (source.metadata as { config?: unknown }).config\n : configOverride\n );\n if (thrown) throw thrown;\n await applied;\n ctx.logger(\"plugin\").info(`Panel frontend plugin loaded: ${source.metadata.id}`);\n }\n } catch (error: any) {\n // Failure is atomic: whatever the plugin managed to register before it threw\n // goes with its scope, so a half-loaded plugin never stays behind.\n plugin.error = error instanceof Error ? error : new Error(String(error));\n plugin.fork?.dispose();\n plugin.fork = undefined;\n plugin.removeStyles?.();\n ctx\n .logger(\"plugin\")\n .error(`Panel frontend plugin failed to load: ${source.metadata.id}`, error);\n }\n notifyPluginDiagnostics();\n return plugin;\n}\n\nfunction isCurrentRoute(plugin: InternalPlugin) {\n const vue = ctx.get(\"vue\");\n const routes = ctx.get(\"routes\");\n if (!vue || !routes) return false;\n return vue.router.currentRoute.value.matched.some(\n (record) => routes.ownerOf(record.path) === plugin.metadata.id\n );\n}\n\nasync function unloadPluginInternal(id: string) {\n if (ESSENTIAL_PLUGIN_IDS.has(id)) {\n throw new Error(`The essential frontend plugin \"${id}\" cannot be unloaded.`);\n }\n const plugin = plugins.find((candidate) => candidate.metadata.id === id);\n if (!plugin) return false;\n plugin.state = \"unloading\";\n notifyPluginDiagnostics();\n // Leave the plugin's page before its routes go, or the router lands on\n // nothing.\n const vue = ctx.get(\"vue\");\n if (vue && isCurrentRoute(plugin)) await vue.router.replace(\"/404\");\n plugin.fork?.dispose();\n try {\n await settle();\n } catch (error) {\n plugin.error = error instanceof Error ? error : new Error(String(error));\n throw error;\n }\n plugin.removeStyles?.();\n removePluginStyles(plugin.source);\n const index = plugins.indexOf(plugin);\n if (index >= 0) plugins.splice(index, 1);\n notifyPluginDiagnostics();\n ctx.logger(\"plugin\").info(`Panel frontend plugin unloaded: ${id}`);\n return true;\n}\n\nasync function loadPluginInternal(id: string) {\n let source = sources.get(id);\n if (!source && !import.meta.env.DEV) {\n await refreshPluginsInternal();\n source = sources.get(id);\n }\n if (!source) throw new Error(`Panel frontend plugin not found: ${id}`);\n return install(source);\n}\n\nasync function reloadPluginInternal(id: string) {\n if (ESSENTIAL_PLUGIN_IDS.has(id)) {\n throw new Error(`The essential frontend plugin \"${id}\" cannot be reloaded.`);\n }\n await unloadPluginInternal(id);\n if (!import.meta.env.DEV) {\n const discovered = await discoverSources();\n sources.clear();\n discovered.forEach((source) => sources.set(source.metadata.id, source));\n }\n const source = sources.get(id);\n if (!source) throw new Error(`Panel frontend plugin not found: ${id}`);\n // The server revision is the cache identity. Reloading unchanged code still\n // retries activation without manufacturing an unbounded timestamp URL.\n return install(source, source.revision || String(source.metadata.version || \"reload\"));\n}\n\n/** Re-reads what is installed and loads or unloads to match. */\nasync function refreshPluginsInternal(discovered?: PluginSource[]) {\n discovered ??= await discoverSources();\n const next = new Map(discovered.map((source) => [source.metadata.id, source]));\n sources.clear();\n next.forEach((source, id) => sources.set(id, source));\n for (const plugin of [...plugins].reverse()) {\n if (ESSENTIAL_PLUGIN_IDS.has(plugin.metadata.id)) continue;\n if (!next.has(plugin.metadata.id)) await unloadPluginInternal(plugin.metadata.id);\n }\n const graph = resolveSourceGraph(discovered);\n for (const [id, issue] of graph.issues) {\n const source = next.get(id);\n if (!source) continue;\n const current = plugins.find((plugin) => plugin.metadata.id === id);\n if (current && !ESSENTIAL_PLUGIN_IDS.has(id)) await unloadPluginInternal(id);\n recordGraphFailure(source, new Error(issue.message));\n }\n const pending: PluginSource[] = [];\n for (const source of graph.ordered) {\n const current = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (current) current.restartRequired = Boolean(source.metadata.restartRequired);\n const changed =\n current &&\n (source.revision !== current.source.revision ||\n JSON.stringify(source.metadata) !== JSON.stringify(current.metadata) ||\n Boolean(source.metadata.restartRequired) !==\n Boolean(current.source.metadata.restartRequired));\n if (current && (changed || source.metadata.restartRequired)) {\n if (ESSENTIAL_PLUGIN_IDS.has(source.metadata.id) || source.metadata.restartRequired) {\n current.restartRequired = Boolean(source.metadata.restartRequired);\n current.reloadRequired = Boolean(changed && ESSENTIAL_PLUGIN_IDS.has(source.metadata.id));\n continue;\n }\n await unloadPluginInternal(source.metadata.id);\n }\n if (!plugins.some((plugin) => plugin.metadata.id === source.metadata.id)) pending.push(source);\n }\n const prepared = await Promise.all(pending.map((source) => preparePlugin(source)));\n for (const [index, source] of pending.entries()) {\n await install(source, undefined, undefined, prepared[index]);\n }\n await settle();\n notifyPluginDiagnostics();\n return discovered.map((source) => source.metadata) as readonly PanelFrontendPluginMetadata[];\n}\n\n/** Discover once, prefetch assets, then activate foundations before the remaining batch. */\nexport async function bootstrapPanelFrontendPlugins() {\n const discovered = await discoverSources();\n sources.clear();\n discovered.forEach((source) => sources.set(source.metadata.id, source));\n const removePreloads = preloadPluginAssets(discovered);\n try {\n for (const id of ESSENTIAL_PLUGIN_IDS) {\n const source = sources.get(id);\n if (!source) throw new Error(`Panel frontend foundation plugin not found: ${id}`);\n const plugin = await install(source);\n if (plugin.error) throw plugin.error;\n if (!plugin.fork || !ctx.get(FOUNDATION_SERVICES[id])) {\n throw new Error(`Panel frontend foundation plugin failed to initialize: ${id}`);\n }\n }\n await refreshPluginsInternal(discovered);\n window.dispatchEvent(new CustomEvent(\"elementspanel:plugins-changed\"));\n } finally {\n removePreloads();\n }\n}\n\nexport function getLoadedPlugins(): readonly LoadedPanelFrontendPlugin[] {\n return plugins;\n}\n\nexport function getPluginDiagnostics(): readonly PanelFrontendPluginDiagnostic[] {\n return plugins.map((plugin) => {\n const error = pluginError(plugin);\n return {\n id: plugin.metadata.id,\n state: plugin.state,\n required: Boolean(plugin.metadata.frontendRequired),\n revision: plugin.revision,\n requiredServices: [...plugin.requiredServices],\n missingServices: [...plugin.missingServices],\n ...(error ? { error: error.message } : {})\n };\n });\n}\n\nexport function auditFrontendPlugins() {\n notifyPluginDiagnostics();\n const failures = getPluginDiagnostics().filter(\n (plugin) => plugin.required && plugin.state !== \"active\"\n );\n if (!failures.length) return;\n throw new Error(\n `Required frontend plugins are not active: ${failures\n .map((plugin) => `${plugin.id} (${plugin.state}${plugin.error ? `: ${plugin.error}` : \"\"})`)\n .join(\", \")}`\n );\n}\n\n/** Serialize UI actions and server notifications against the same browser state. */\nexport const unloadPlugin = (id: string) => change(() => unloadPluginInternal(id));\nexport const loadPlugin = (id: string) => change(() => loadPluginInternal(id));\nexport const reloadPlugin = (id: string) => change(() => reloadPluginInternal(id));\nexport const refreshPlugins = () =>\n change(async () => {\n const result = await refreshPluginsInternal();\n window.dispatchEvent(new CustomEvent(\"elementspanel:plugins-changed\"));\n return result;\n });\n\n/** Reconnect receives the complete current generation; no event history is needed. */\nexport function watchPluginChanges(): () => void {\n if (import.meta.env.DEV || typeof EventSource === \"undefined\") return () => {};\n const events = new EventSource(new URL(\"plugins/events\", document.baseURI).href);\n let revision = \"\";\n let stopped = false;\n let retry: ReturnType<typeof setTimeout> | undefined;\n const synchronize = () => {\n if (stopped) return;\n void refreshPlugins().catch((error) => {\n ctx.logger(\"plugin\").error(\"Failed to synchronize plugins\", error);\n retry = setTimeout(synchronize, 2000);\n });\n };\n events.onmessage = (event) => {\n let next: string;\n try {\n next = JSON.parse(event.data).revision;\n } catch {\n return;\n }\n if (typeof next !== \"string\" || next === revision || stopped) return;\n revision = next;\n if (retry) clearTimeout(retry);\n synchronize();\n };\n return () => {\n stopped = true;\n if (retry) clearTimeout(retry);\n events.close();\n };\n}\n","import { ctx } from \"./context\";\nimport {\n bootstrapPanelFrontendPlugins,\n auditFrontendPlugins,\n getPluginDiagnostics,\n getLoadedPlugins,\n loadPlugin,\n refreshPlugins,\n reloadPlugin,\n unloadPlugin,\n watchPluginChanges\n} from \"./loader\";\n\ndeclare global {\n interface Window {\n ElementsPanelPlugins?: {\n load: typeof loadPlugin;\n unload: typeof unloadPlugin;\n reload: typeof reloadPlugin;\n refresh: typeof refreshPlugins;\n loaded: typeof getLoadedPlugins;\n diagnostics: typeof getPluginDiagnostics;\n audit: typeof auditFrontendPlugins;\n };\n }\n}\n\nexport async function setupPanelFrontendPlugins() {\n ctx.provide(\"plugins\", undefined, true);\n ctx.set(\"plugins\", {\n get loaded() {\n return getLoadedPlugins();\n },\n get diagnostics() {\n return getPluginDiagnostics();\n },\n load: loadPlugin,\n unload: unloadPlugin,\n reload: reloadPlugin,\n refresh: refreshPlugins,\n audit: auditFrontendPlugins\n });\n\n await bootstrapPanelFrontendPlugins();\n auditFrontendPlugins();\n\n window.ElementsPanelPlugins = {\n load: loadPlugin,\n unload: unloadPlugin,\n reload: reloadPlugin,\n refresh: refreshPlugins,\n loaded: getLoadedPlugins,\n diagnostics: getPluginDiagnostics,\n audit: auditFrontendPlugins\n };\n await ctx.parallel(\"plugins/loaded\");\n await ctx.start();\n ctx.effect(watchPluginChanges);\n}\n","import { ctx } from \"./plugin/context\";\nimport { setupPanelFrontendPlugins } from \"./plugin/install\";\n\nsetupPanelFrontendPlugins().catch(async (error) => {\n console.error(\"Plugin startup failed:\", error);\n const startup = ctx.get(\"startup\");\n if (startup) startup.showError(error);\n else {\n const host = window as Window & { setAppLoadingError?: (message: string) => void };\n host.setAppLoadingError?.(error instanceof Error ? error.message : String(error));\n }\n await ctx.stop();\n});\n"],"file":"assets/index-76b0df52.js"}
1
+ {"version":3,"mappings":"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","names":["trackPluginDisposal","ctx","pending","failures","tracked","scopes","observe","scope","reset","dispose","wrapper","args","result","error","task","key","errors","FOUNDATION_SERVICES","ESSENTIAL_PLUGIN_IDS","change","createPluginQueue","settle","plugins","shallowReactive","sources","compareSources","a","b","requiredServices","module","value","name","scopeState","refreshPluginState","plugin","pluginError","_a","_b","notifyPluginDiagnostics","candidate","normalizeMetadata","id","toModule","loadStyles","source","links","href","resolve","reject","link","removePluginStyles","style","normalizedHref","fetchProductionSources","manifestUrl","response","body","manifest","toUrl","item","metadata","entry","entryUrl","cacheKey","url","__vitePreload","discoverSources","discovered","unique","resolveSourceGraph","resolvePluginDependencyOrder","preloadPluginAssets","validatePluginCompatibility","preparePlugin","removeStyles","styles","recordGraphFailure","existing","install","configOverride","prepared","unavailableDependencies","resources","applied","thrown","_c","isCurrentRoute","vue","routes","record","unloadPluginInternal","index","loadPluginInternal","refreshPluginsInternal","reloadPluginInternal","next","graph","issue","current","changed","bootstrapPanelFrontendPlugins","removePreloads","getLoadedPlugins","getPluginDiagnostics","auditFrontendPlugins","unloadPlugin","loadPlugin","reloadPlugin","refreshPlugins","watchPluginChanges","events","revision","stopped","retry","synchronize","event","setupPanelFrontendPlugins","startup","host"],"sources":["../../../common/src/plugin_lifecycle.ts","../../src/plugin/loader.ts","../../src/plugin/install.ts","../../src/main.ts"],"sourcesContent":["/** Cordis 3 starts async disposers without awaiting them. Track them per host. */\nexport function trackPluginDisposal(ctx: any) {\n const pending = new Set<Promise<unknown>>();\n const failures: unknown[] = [];\n const tracked = new WeakSet<Function>();\n const scopes = new WeakSet<object>();\n const observe = (scope: any) => {\n if (scopes.has(scope)) return;\n scopes.add(scope);\n const reset = scope.reset;\n scope.reset = function () {\n this.disposables = this.disposables.map((dispose: Function) => {\n if (tracked.has(dispose)) return dispose;\n const wrapper = (...args: unknown[]) => {\n let result: unknown;\n try {\n result = dispose(...args);\n } catch (error) {\n failures.push(error);\n throw error;\n }\n if (result && typeof (result as Promise<unknown>).then === \"function\") {\n const task = Promise.resolve(result)\n .catch((error) => {\n failures.push(error);\n })\n .finally(() => pending.delete(task));\n pending.add(task);\n }\n return result;\n };\n // Cordis marks persistent disposers with a symbol; preserve its semantics.\n for (const key of Object.getOwnPropertySymbols(dispose))\n Object.defineProperty(wrapper, key, Object.getOwnPropertyDescriptor(dispose, key)!);\n tracked.add(wrapper);\n return wrapper;\n });\n return reset.call(this);\n };\n };\n ctx.on(\"internal/runtime\", observe);\n ctx.on(\"internal/fork\", observe);\n return async () => {\n do {\n await ctx.events.flush();\n await Promise.all([...pending]);\n } while (pending.size);\n if (failures.length) {\n const errors = failures.splice(0);\n throw new Error(`Plugin cleanup failed: ${errors.map(String).join(\"; \")}`);\n }\n };\n}\n","import {\n createPluginQueue,\n resolvePluginDependencyOrder,\n type PluginState,\n validatePluginCompatibility\n} from \"../../../common/src/plugin_contract\";\nimport { trackPluginDisposal } from \"../../../common/src/plugin_lifecycle\";\nimport { shallowReactive } from \"vue\";\nimport type { EffectScope, ForkScope } from \"cordis\";\nimport {\n ctx,\n type PanelFrontendPluginContext,\n type PanelFrontendPluginDiagnostic\n} from \"./context\";\nimport { panelPluginModules } from \"virtual:panel-plugins\";\n\nconst FOUNDATION_SERVICES: Record<string, string> = {\n runtime: \"startup\",\n i18n: \"i18n\",\n console: \"console\"\n};\nconst ESSENTIAL_PLUGIN_IDS = new Set(Object.keys(FOUNDATION_SERVICES));\nconst change = createPluginQueue();\nconst settle = trackPluginDisposal(ctx);\n\n/**\n * Fetches plugin code and hands it to cordis.\n *\n * Discovery is unchanged: in development the Vite plugin supplies a virtual\n * module of static imports; in production the browser fetches\n * `plugins/manifest.json` and imports each entry by URL. What that feeds is now\n * `ctx.plugin()`, and unloading is `fork.dispose()` — every route, card, menu,\n * action and translation the plugin registered is an effect of its scope.\n */\n\nexport interface PanelFrontendPluginMetadata {\n id: string;\n version?: string;\n description?: string;\n enabled?: boolean;\n priority?: number;\n frontend?: string;\n ui?: string;\n frontendInject?: string[];\n frontendImmediate?: boolean;\n frontendRequired?: boolean;\n config?: unknown;\n restartRequired?: boolean;\n [key: string]: unknown;\n}\n\n/** A frontend plugin module, as its entry exports it. */\nexport interface PanelFrontendPluginModule {\n inject?: string[] | Record<string, { required: boolean }>;\n apply(ctx: PanelFrontendPluginContext, config?: unknown): void | Promise<void>;\n}\n\ninterface PluginSource {\n metadata: PanelFrontendPluginMetadata;\n directory: string;\n assetDirectory: string;\n entry?: string;\n revision?: string;\n styles?: string[];\n load: (cacheKey?: string) => Promise<Record<string, unknown>>;\n}\n\ntype PreparedPlugin =\n | { module: PanelFrontendPluginModule; removeStyles?: () => void }\n | { error: Error };\n\nexport interface LoadedPanelFrontendPlugin {\n metadata: PanelFrontendPluginMetadata;\n directory: string;\n state: PluginState;\n requiredServices: readonly string[];\n missingServices: readonly string[];\n revision?: string;\n fork?: ForkScope;\n error?: Error;\n restartRequired?: boolean;\n reloadRequired?: boolean;\n}\n\ninterface InternalPlugin extends LoadedPanelFrontendPlugin {\n source: PluginSource;\n /** Only the stylesheet links, which are not cordis effects. */\n removeStyles?: () => void;\n}\n\nconst plugins = shallowReactive<InternalPlugin[]>([]);\nconst sources = new Map<string, PluginSource>();\n\nfunction compareSources(a: PluginSource, b: PluginSource) {\n return (\n (Number(a.metadata.priority) || 0) - (Number(b.metadata.priority) || 0) ||\n a.metadata.id.localeCompare(b.metadata.id)\n );\n}\n\nfunction requiredServices(module: PanelFrontendPluginModule) {\n if (Array.isArray(module.inject)) return [...new Set(module.inject)];\n if (!module.inject) return [];\n return Object.entries(module.inject)\n .filter(([, value]) => value?.required)\n .map(([name]) => name);\n}\n\nfunction scopeState(scope?: ForkScope): PluginState {\n if (!scope) return \"failed\";\n if (scope.error || scope.runtime.error) return \"failed\";\n switch (scope.status) {\n case 0: // ScopeStatus.PENDING\n return \"pending\";\n case 1: // ScopeStatus.LOADING\n return \"loading\";\n case 2: // ScopeStatus.ACTIVE\n return \"active\";\n case 3: // ScopeStatus.FAILED\n case 4: // ScopeStatus.DISPOSED\n return \"failed\";\n default:\n return \"pending\";\n }\n}\n\nfunction refreshPluginState(plugin: InternalPlugin) {\n plugin.missingServices = plugin.requiredServices.filter((name) => !ctx.get(name as never));\n plugin.state =\n plugin.restartRequired || plugin.reloadRequired\n ? \"restart-required\"\n : plugin.error\n ? \"failed\"\n : scopeState(plugin.fork);\n}\n\nfunction pluginError(plugin: InternalPlugin): Error | undefined {\n const error = plugin.error || plugin.fork?.error || plugin.fork?.runtime.error;\n if (error === undefined || error === null) return undefined;\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction notifyPluginDiagnostics() {\n for (const plugin of plugins) refreshPluginState(plugin);\n}\n\nctx.on(\"internal/status\", (scope: EffectScope) => {\n const plugin = plugins.find((candidate) => candidate.fork === scope);\n if (plugin) notifyPluginDiagnostics();\n});\n\nfunction normalizeMetadata(value: Record<string, unknown>): PanelFrontendPluginMetadata | null {\n const id = typeof value.id === \"string\" ? value.id.trim() : \"\";\n if (!id) return null;\n return { ...value, id } as PanelFrontendPluginMetadata;\n}\n\n/**\n * The plugin object a module exports, whether as named exports or as `default`.\n *\n * Only an object counts: every function has `Function.prototype.apply`, so a\n * module whose default export is a function would otherwise be mistaken for a\n * plugin and then called with the context as `this`.\n */\nfunction toModule(value: any, id: string): PanelFrontendPluginModule | undefined {\n for (const candidate of [value, value?.default]) {\n if (typeof candidate !== \"object\" || candidate === null) continue;\n if (typeof candidate.apply === \"function\") return candidate;\n }\n ctx.logger(\"plugin\").warn(`Panel frontend plugin \"${id}\" must export an apply() function.`);\n return undefined;\n}\n\nasync function loadStyles(source: PluginSource) {\n const links: HTMLLinkElement[] = [];\n try {\n await Promise.all(\n (source.styles || []).map(\n (href) =>\n new Promise<void>((resolve, reject) => {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = href;\n link.dataset.panelPlugin = source.metadata.id;\n link.addEventListener(\"load\", () => resolve(), { once: true });\n link.addEventListener(\n \"error\",\n () => reject(new Error(`Failed to load panel plugin stylesheet: ${href}`)),\n { once: true }\n );\n document.head.appendChild(link);\n links.push(link);\n })\n )\n );\n } catch (error) {\n links.forEach((link) => link.remove());\n throw error;\n }\n return () => links.forEach((link) => link.remove());\n}\n\n/**\n * Removes stylesheets the plugin injected itself, which the core cannot track:\n * `<style>` elements it tagged, and any `<link>` matching one of its hrefs.\n */\nfunction removePluginStyles(source: PluginSource) {\n document\n .querySelectorAll<HTMLStyleElement>(\n `style[data-panel-plugin=${JSON.stringify(source.metadata.id)}]`\n )\n .forEach((style) => style.remove());\n for (const href of source.styles || []) {\n const normalizedHref = new URL(href, document.baseURI).href;\n document.querySelectorAll<HTMLLinkElement>(\"link[rel='stylesheet']\").forEach((link) => {\n try {\n if (new URL(link.href, document.baseURI).href === normalizedHref) link.remove();\n } catch {\n // Ignore malformed third-party stylesheet URLs.\n }\n });\n }\n}\n\nasync function fetchProductionSources(): Promise<PluginSource[]> {\n const manifestUrl = new URL(\"plugins/manifest.json\", document.baseURI);\n const response = await fetch(manifestUrl.href, { cache: \"no-store\" });\n if (!response.ok) {\n if (response.status === 404) return [];\n throw new Error(`Failed to load panel plugin manifest: HTTP ${response.status}`);\n }\n const body = await response.json();\n // Older panel builds may still pass the manifest through the standard API\n // envelope. Accept both the raw array and `{ data: [...] }` forms.\n const manifest = Array.isArray(body) ? body : body?.data;\n if (!Array.isArray(manifest)) throw new Error(\"Invalid panel plugin manifest.\");\n\n const toUrl = (value: string) => new URL(value, manifestUrl).href;\n const result: PluginSource[] = [];\n for (const item of manifest) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const metadata = normalizeMetadata((item as any).metadata || item);\n const entry = typeof (item as any).entry === \"string\" ? (item as any).entry : \"\";\n if (!metadata || metadata.enabled === false || !entry) continue;\n const entryUrl = toUrl(entry);\n result.push({\n metadata,\n directory:\n typeof (item as any).directory === \"string\" ? (item as any).directory : metadata.id,\n assetDirectory:\n typeof (item as any).assetDirectory === \"string\"\n ? (item as any).assetDirectory\n : metadata.id,\n entry: entryUrl,\n revision: typeof item.revision === \"string\" ? item.revision : String(metadata.version || \"\"),\n styles: Array.isArray((item as any).styles)\n ? (item as any).styles\n .filter((style: unknown): style is string => typeof style === \"string\")\n .map(toUrl)\n : [],\n load: async (cacheKey) => {\n const url = new URL(entryUrl);\n if (cacheKey) url.searchParams.set(\"panel_plugin_reload\", cacheKey);\n return import(/* @vite-ignore */ url.href) as Promise<Record<string, unknown>>;\n }\n });\n }\n return result;\n}\n\nasync function discoverSources() {\n const discovered = import.meta.env.DEV\n ? (panelPluginModules as PluginSource[])\n : await fetchProductionSources();\n const unique = new Map<string, PluginSource>();\n for (const source of discovered) {\n const metadata = normalizeMetadata(source.metadata);\n if (!metadata || metadata.enabled === false || unique.has(metadata.id)) continue;\n unique.set(metadata.id, { ...source, metadata });\n }\n return [...unique.values()].sort(compareSources);\n}\n\nfunction resolveSourceGraph(discovered: readonly PluginSource[]) {\n return resolvePluginDependencyOrder(discovered, {\n id: (source) => source.metadata.id,\n dependencies: (source) => source.metadata.frontendInject,\n compare: compareSources\n });\n}\n\n/** Fetch production assets during foundation startup without evaluating plugin code. */\nfunction preloadPluginAssets(discovered: readonly PluginSource[]) {\n const links: HTMLLinkElement[] = [];\n if (!import.meta.env.DEV) {\n for (const source of resolveSourceGraph(discovered).ordered) {\n try {\n validatePluginCompatibility(source.metadata.elements);\n } catch {\n continue;\n }\n if (source.metadata.restartRequired || !source.entry) continue;\n const module = document.createElement(\"link\");\n module.rel = \"modulepreload\";\n module.href = source.entry;\n module.crossOrigin = \"anonymous\";\n document.head.appendChild(module);\n links.push(module);\n for (const href of source.styles || []) {\n const style = document.createElement(\"link\");\n style.rel = \"preload\";\n style.setAttribute(\"as\", \"style\");\n style.href = href;\n document.head.appendChild(style);\n links.push(style);\n }\n }\n }\n return () => links.forEach((link) => link.remove());\n}\n\n/** Preparation never rejects, so an optional download failure cannot abort the batch. */\nasync function preparePlugin(source: PluginSource, cacheKey?: string): Promise<PreparedPlugin> {\n let removeStyles: (() => void) | undefined;\n try {\n validatePluginCompatibility(source.metadata.elements);\n if (source.metadata.restartRequired)\n throw new Error(\"The plugin backend requires a restart before this version can load.\");\n const [styles, entry] = await Promise.allSettled([\n import.meta.env.DEV ? Promise.resolve(undefined) : loadStyles(source),\n Promise.resolve().then(() => source.load(cacheKey))\n ]);\n if (styles.status === \"rejected\") throw styles.reason;\n removeStyles = styles.value;\n if (entry.status === \"rejected\") throw entry.reason;\n const module = toModule(entry.value, source.metadata.id);\n if (!module)\n throw new Error(`Panel frontend plugin has no apply() export: ${source.metadata.id}`);\n return { module, removeStyles };\n } catch (error) {\n removeStyles?.();\n return { error: error instanceof Error ? error : new Error(String(error)) };\n }\n}\n\nfunction recordGraphFailure(source: PluginSource, error: Error) {\n const existing = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (existing) {\n existing.error = error;\n existing.state = \"failed\";\n notifyPluginDiagnostics();\n return existing;\n }\n const plugin = shallowReactive<InternalPlugin>({\n source,\n metadata: source.metadata,\n directory: source.directory,\n revision: source.revision,\n state: \"failed\",\n requiredServices: [],\n missingServices: [],\n error\n });\n plugins.push(plugin);\n notifyPluginDiagnostics();\n return plugin;\n}\n\nasync function install(\n source: PluginSource,\n cacheKey?: string,\n configOverride?: unknown,\n prepared?: PreparedPlugin\n) {\n const existing = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (existing) return existing;\n\n const unavailableDependencies = (source.metadata.frontendInject || []).filter(\n (id) => plugins.find((plugin) => plugin.metadata.id === id)?.state !== \"active\"\n );\n if (unavailableDependencies.length) {\n if (prepared && \"module\" in prepared) prepared.removeStyles?.();\n return recordGraphFailure(\n source,\n new Error(\n `Frontend plugin dependencies are not active: ${unavailableDependencies.join(\", \")}`\n )\n );\n }\n\n const plugin = shallowReactive<InternalPlugin>({\n source,\n metadata: source.metadata,\n directory: source.directory,\n revision: source.revision,\n state: \"loading\",\n requiredServices: [],\n missingServices: []\n });\n plugins.push(plugin);\n notifyPluginDiagnostics();\n try {\n const resources = prepared ?? (await preparePlugin(source, cacheKey));\n if (\"error\" in resources) throw resources.error;\n plugin.removeStyles = resources.removeStyles;\n const { module } = resources;\n plugin.requiredServices = requiredServices(module);\n {\n // An `async apply()` is awaited here, so a plugin is fully applied before\n // the next one activates and before the app is mounted. Resource loading\n // happens in parallel before this dependency-ordered activation phase.\n //\n // cordis catches a synchronous throw from `apply()` and cancels the scope\n // itself, so the wrapper keeps a copy of it: without that, a plugin that\n // failed on its first line would still be reported as loaded.\n let applied: unknown;\n let thrown: unknown;\n // The manifest id is the plugin's name, so `ctx.name` — which is what\n // appears in its log lines — always matches the package metadata.\n plugin.fork = ctx.plugin(\n {\n ...module,\n name: source.metadata.id,\n apply: (...args) => {\n try {\n return (applied = module.apply(...args));\n } catch (error) {\n thrown = error;\n throw error;\n }\n }\n },\n configOverride === undefined\n ? (source.metadata as { config?: unknown }).config\n : configOverride\n );\n if (thrown) throw thrown;\n await applied;\n ctx.logger(\"plugin\").info(`Panel frontend plugin loaded: ${source.metadata.id}`);\n }\n } catch (error: any) {\n // Failure is atomic: whatever the plugin managed to register before it threw\n // goes with its scope, so a half-loaded plugin never stays behind.\n plugin.error = error instanceof Error ? error : new Error(String(error));\n plugin.fork?.dispose();\n plugin.fork = undefined;\n plugin.removeStyles?.();\n ctx\n .logger(\"plugin\")\n .error(`Panel frontend plugin failed to load: ${source.metadata.id}`, error);\n }\n notifyPluginDiagnostics();\n return plugin;\n}\n\nfunction isCurrentRoute(plugin: InternalPlugin) {\n const vue = ctx.get(\"vue\");\n const routes = ctx.get(\"routes\");\n if (!vue || !routes) return false;\n return vue.router.currentRoute.value.matched.some(\n (record) => routes.ownerOf(record.path) === plugin.metadata.id\n );\n}\n\nasync function unloadPluginInternal(id: string) {\n if (ESSENTIAL_PLUGIN_IDS.has(id)) {\n throw new Error(`The essential frontend plugin \"${id}\" cannot be unloaded.`);\n }\n const plugin = plugins.find((candidate) => candidate.metadata.id === id);\n if (!plugin) return false;\n plugin.state = \"unloading\";\n notifyPluginDiagnostics();\n // Leave the plugin's page before its routes go, or the router lands on\n // nothing.\n const vue = ctx.get(\"vue\");\n if (vue && isCurrentRoute(plugin)) await vue.router.replace(\"/404\");\n plugin.fork?.dispose();\n try {\n await settle();\n } catch (error) {\n plugin.error = error instanceof Error ? error : new Error(String(error));\n throw error;\n }\n plugin.removeStyles?.();\n removePluginStyles(plugin.source);\n const index = plugins.indexOf(plugin);\n if (index >= 0) plugins.splice(index, 1);\n notifyPluginDiagnostics();\n ctx.logger(\"plugin\").info(`Panel frontend plugin unloaded: ${id}`);\n return true;\n}\n\nasync function loadPluginInternal(id: string) {\n let source = sources.get(id);\n if (!source && !import.meta.env.DEV) {\n await refreshPluginsInternal();\n source = sources.get(id);\n }\n if (!source) throw new Error(`Panel frontend plugin not found: ${id}`);\n return install(source);\n}\n\nasync function reloadPluginInternal(id: string) {\n if (ESSENTIAL_PLUGIN_IDS.has(id)) {\n throw new Error(`The essential frontend plugin \"${id}\" cannot be reloaded.`);\n }\n await unloadPluginInternal(id);\n if (!import.meta.env.DEV) {\n const discovered = await discoverSources();\n sources.clear();\n discovered.forEach((source) => sources.set(source.metadata.id, source));\n }\n const source = sources.get(id);\n if (!source) throw new Error(`Panel frontend plugin not found: ${id}`);\n // The server revision is the cache identity. Reloading unchanged code still\n // retries activation without manufacturing an unbounded timestamp URL.\n return install(source, source.revision || String(source.metadata.version || \"reload\"));\n}\n\n/** Re-reads what is installed and loads or unloads to match. */\nasync function refreshPluginsInternal(discovered?: PluginSource[]) {\n discovered ??= await discoverSources();\n const next = new Map(discovered.map((source) => [source.metadata.id, source]));\n sources.clear();\n next.forEach((source, id) => sources.set(id, source));\n for (const plugin of [...plugins].reverse()) {\n if (ESSENTIAL_PLUGIN_IDS.has(plugin.metadata.id)) continue;\n if (!next.has(plugin.metadata.id)) await unloadPluginInternal(plugin.metadata.id);\n }\n const graph = resolveSourceGraph(discovered);\n for (const [id, issue] of graph.issues) {\n const source = next.get(id);\n if (!source) continue;\n const current = plugins.find((plugin) => plugin.metadata.id === id);\n if (current && !ESSENTIAL_PLUGIN_IDS.has(id)) await unloadPluginInternal(id);\n recordGraphFailure(source, new Error(issue.message));\n }\n const pending: PluginSource[] = [];\n for (const source of graph.ordered) {\n const current = plugins.find((plugin) => plugin.metadata.id === source.metadata.id);\n if (current) current.restartRequired = Boolean(source.metadata.restartRequired);\n const changed =\n current &&\n (source.revision !== current.source.revision ||\n JSON.stringify(source.metadata) !== JSON.stringify(current.metadata) ||\n Boolean(source.metadata.restartRequired) !==\n Boolean(current.source.metadata.restartRequired));\n if (current && (changed || source.metadata.restartRequired)) {\n if (ESSENTIAL_PLUGIN_IDS.has(source.metadata.id) || source.metadata.restartRequired) {\n current.restartRequired = Boolean(source.metadata.restartRequired);\n current.reloadRequired = Boolean(changed && ESSENTIAL_PLUGIN_IDS.has(source.metadata.id));\n continue;\n }\n await unloadPluginInternal(source.metadata.id);\n }\n if (!plugins.some((plugin) => plugin.metadata.id === source.metadata.id)) pending.push(source);\n }\n const prepared = await Promise.all(pending.map((source) => preparePlugin(source)));\n for (const [index, source] of pending.entries()) {\n await install(source, undefined, undefined, prepared[index]);\n }\n await settle();\n notifyPluginDiagnostics();\n return discovered.map((source) => source.metadata) as readonly PanelFrontendPluginMetadata[];\n}\n\n/** Discover once, prefetch assets, then activate foundations before the remaining batch. */\nexport async function bootstrapPanelFrontendPlugins() {\n const discovered = await discoverSources();\n sources.clear();\n discovered.forEach((source) => sources.set(source.metadata.id, source));\n const removePreloads = preloadPluginAssets(discovered);\n try {\n for (const id of ESSENTIAL_PLUGIN_IDS) {\n const source = sources.get(id);\n if (!source) throw new Error(`Panel frontend foundation plugin not found: ${id}`);\n const plugin = await install(source);\n if (plugin.error) throw plugin.error;\n if (!plugin.fork || !ctx.get(FOUNDATION_SERVICES[id])) {\n throw new Error(`Panel frontend foundation plugin failed to initialize: ${id}`);\n }\n }\n await refreshPluginsInternal(discovered);\n window.dispatchEvent(new CustomEvent(\"elementspanel:plugins-changed\"));\n } finally {\n removePreloads();\n }\n}\n\nexport function getLoadedPlugins(): readonly LoadedPanelFrontendPlugin[] {\n return plugins;\n}\n\nexport function getPluginDiagnostics(): readonly PanelFrontendPluginDiagnostic[] {\n return plugins.map((plugin) => {\n const error = pluginError(plugin);\n return {\n id: plugin.metadata.id,\n state: plugin.state,\n required: Boolean(plugin.metadata.frontendRequired),\n revision: plugin.revision,\n requiredServices: [...plugin.requiredServices],\n missingServices: [...plugin.missingServices],\n ...(error ? { error: error.message } : {})\n };\n });\n}\n\nexport function auditFrontendPlugins() {\n notifyPluginDiagnostics();\n const failures = getPluginDiagnostics().filter(\n (plugin) => plugin.required && plugin.state !== \"active\"\n );\n if (!failures.length) return;\n throw new Error(\n `Required frontend plugins are not active: ${failures\n .map((plugin) => `${plugin.id} (${plugin.state}${plugin.error ? `: ${plugin.error}` : \"\"})`)\n .join(\", \")}`\n );\n}\n\n/** Serialize UI actions and server notifications against the same browser state. */\nexport const unloadPlugin = (id: string) => change(() => unloadPluginInternal(id));\nexport const loadPlugin = (id: string) => change(() => loadPluginInternal(id));\nexport const reloadPlugin = (id: string) => change(() => reloadPluginInternal(id));\nexport const refreshPlugins = () =>\n change(async () => {\n const result = await refreshPluginsInternal();\n window.dispatchEvent(new CustomEvent(\"elementspanel:plugins-changed\"));\n return result;\n });\n\n/** Reconnect receives the complete current generation; no event history is needed. */\nexport function watchPluginChanges(): () => void {\n if (import.meta.env.DEV || typeof EventSource === \"undefined\") return () => {};\n const events = new EventSource(new URL(\"plugins/events\", document.baseURI).href);\n let revision = \"\";\n let stopped = false;\n let retry: ReturnType<typeof setTimeout> | undefined;\n const synchronize = () => {\n if (stopped) return;\n void refreshPlugins().catch((error) => {\n ctx.logger(\"plugin\").error(\"Failed to synchronize plugins\", error);\n retry = setTimeout(synchronize, 2000);\n });\n };\n events.onmessage = (event) => {\n let next: string;\n try {\n next = JSON.parse(event.data).revision;\n } catch {\n return;\n }\n if (typeof next !== \"string\" || next === revision || stopped) return;\n revision = next;\n if (retry) clearTimeout(retry);\n synchronize();\n };\n return () => {\n stopped = true;\n if (retry) clearTimeout(retry);\n events.close();\n };\n}\n","import { ctx } from \"./context\";\nimport {\n bootstrapPanelFrontendPlugins,\n auditFrontendPlugins,\n getPluginDiagnostics,\n getLoadedPlugins,\n loadPlugin,\n refreshPlugins,\n reloadPlugin,\n unloadPlugin,\n watchPluginChanges\n} from \"./loader\";\n\ndeclare global {\n interface Window {\n ElementsPanelPlugins?: {\n load: typeof loadPlugin;\n unload: typeof unloadPlugin;\n reload: typeof reloadPlugin;\n refresh: typeof refreshPlugins;\n loaded: typeof getLoadedPlugins;\n diagnostics: typeof getPluginDiagnostics;\n audit: typeof auditFrontendPlugins;\n };\n }\n}\n\nexport async function setupPanelFrontendPlugins() {\n ctx.provide(\"plugins\", undefined, true);\n ctx.set(\"plugins\", {\n get loaded() {\n return getLoadedPlugins();\n },\n get diagnostics() {\n return getPluginDiagnostics();\n },\n load: loadPlugin,\n unload: unloadPlugin,\n reload: reloadPlugin,\n refresh: refreshPlugins,\n audit: auditFrontendPlugins\n });\n\n await bootstrapPanelFrontendPlugins();\n auditFrontendPlugins();\n\n window.ElementsPanelPlugins = {\n load: loadPlugin,\n unload: unloadPlugin,\n reload: reloadPlugin,\n refresh: refreshPlugins,\n loaded: getLoadedPlugins,\n diagnostics: getPluginDiagnostics,\n audit: auditFrontendPlugins\n };\n await ctx.parallel(\"plugins/loaded\");\n await ctx.start();\n ctx.effect(watchPluginChanges);\n}\n","import { ctx } from \"./plugin/context\";\nimport { setupPanelFrontendPlugins } from \"./plugin/install\";\n\nsetupPanelFrontendPlugins().catch(async (error) => {\n console.error(\"Plugin startup failed:\", error);\n const startup = ctx.get(\"startup\");\n if (startup) startup.showError(error);\n else {\n const host = window as Window & { setAppLoadingError?: (message: string) => void };\n host.setAppLoadingError?.(error instanceof Error ? error.message : String(error));\n }\n await ctx.stop();\n});\n"],"file":"assets/index-6e8d74f8.js"}