Add WASM module registry and admin panel extensibility#265
Conversation
…st` and opaque I/O. WIT hasn't yet evolved to the point where it can be extended that makes it easily versionable. Specifically adding a new exported guest function (optional is not yet supported) or changing records/enums instantly makes newer versions of TB incompatible with existing components requiring a rebuild. That's why at least for now we're switching to a single monolithic function with opaque I/O (which is JSON as defined by the `InitManifest`).
Made loaded WASM modules visible to administrators Allowed modules to present a branded identity in the dashboard Enabled modules to surface their own configuration UI in admin Equipped module authors with built-in admin access control Turn WASM into a first-class extension model for the admin Remove the need for a separate admin interface per extension Spare module authors from re-implementing admin access control
Introduced tb-html-fragment custom element that attaches a shadow root and injects fragment HTML inside it, replacing direct innerHTML assignment into a light-DOM container. Prevents WASM component settings pages from leaking styles/markup into or colliding with the admin app's own DOM and CSS, enforcing isolation at the injection point rather than relying on convention.
Rendered inline-SVG manifest icons through an <img data:> URL, which isolates the SVG and breaks currentColor inheritance from the parent. Render inline SVGs directly via innerHTML instead, keep <img> only for data: URL icons. Provides consistent theme-aware icon coloring for any WASM module manifest that relies on currentColor, matching the built-in fallback icon's behavior across light and dark admin themes.
|
I started to look at this, in the beginning there were some ~150 files flagged as changed by the GitHub review UI, which was partly due to the selected base-path, staleness of the manifest branch, ... I didn't really find a good way to filter out the noise, so I rebased |
|
Sorry, wrong base — I opened this against main instead of manifest, which is why manifest's commits are showing up in the diff. Glad you still managed to get a clean starting point out of it. |
|
One option worth trying: closing and reopening the PR sometimes forces GitHub to recompute the diff against the new base. I don't have that available on my end, but figured it's worth mentioning in case you want to give it a shot. |
Closes #252.
What this adds:
GET /_/admin/wasm-modules— new API endpoint listing all loaded modules with their metadata/wasm-modules— shows each module with icon, display name, and descriptionget-manifest— module metadata (display_name,icon,description,config_path) is read through the guest'sget-manifestexport, following the manifest-based init approach. Partial manifests are supported — missing fields fall back to sane defaults/wasm-modules/:name— when a module declares aconfig_path, the admin fetches the fragment and wraps it in a custom element with Shadow DOM, rather than injecting it viainnerHTMLis_admincheck added towasm-runtime-guest— since this feature opens the door to admin-panel extensions, module endpoints that serve management UI must be able to guard access. The project didn't previously need this in the guest crate, but shipping admin-facing modules without a built-in auth check would push that burden onto every extension author individuallyStyle isolation:
The settings fragment is wrapped in a Web Component with Shadow DOM on the admin side, isolating styles in both directions.
Real-world example:
To verify the manifest-based init end-to-end, wcauth-tb-component can be used as a test module — it implements
get-manifestand exposes a settings page. Build it from source, place the resulting binary as wcauth.wasm in traildepot, and it should appear in the WASM Modules page with its manifest applied.