Await cached component module imports

Ensure x-component loading awaits cached dynamic import promises before appending deferred markup, matching first-load behavior and preventing Alpine bindings from running before imported stores register.

Document the loader contract in the WebUI JS DOX notes.
This commit is contained in:
Alessandro 2026-07-08 20:53:56 +02:00
parent 4f80ded531
commit a7255d9773
2 changed files with 3 additions and 2 deletions

View file

@ -37,6 +37,7 @@
- Keep extension loader cache keys and extension point names stable for plugins.
- HTML extension loading turns discovered HTML files into `<x-component>` tags; JavaScript extensions must export a default function.
- `<x-component>` loading must process component `style`, `script`, and stylesheet-link assets only once, even when a component keeps its scoped `<style>` inside `<body>`.
- Every `<x-component>` instance must await cached module-load promises before markup is appended so Alpine bindings only run after imported stores exist.
- Frontend extension hooks such as `confirm_dialog_after_render` and `get_tool_message_handler` must preserve their mutable context contracts.
- Sanitize or safely render user/model-provided HTML and markdown.
- Do not expose secrets in localStorage, console logs, URLs, or WebSocket payloads.

View file

@ -79,8 +79,8 @@ export async function importComponent(path, targetElement) {
if (!componentCache[resolvedUrl]) {
const modulePromise = import(resolvedUrl);
componentCache[resolvedUrl] = modulePromise;
loadPromises.push(modulePromise);
}
loadPromises.push(componentCache[resolvedUrl]);
} else {
const virtualUrl = `${componentUrl.replaceAll(
"/",
@ -122,8 +122,8 @@ export async function importComponent(path, targetElement) {
.finally(() => URL.revokeObjectURL(blobUrl));
componentCache[virtualUrl] = modulePromise;
loadPromises.push(modulePromise);
}
loadPromises.push(componentCache[virtualUrl]);
}
} else {
// Non-module script