docs(readme): ship UI via typedserver + bundled ts module
Rework the implementation-notes section of readme.ui.md so the UI delivery story matches ModelGrid's deno-compile single-binary shape. Adopt the @stack.gallery/registry pattern: a build step bundles ts_web/ into a generated ts_bundled/bundle.ts exporting a path->bytes map that typedserver serves at runtime. Add a dev-vs-prod asset-source switch so UI edits stay hot-reloadable during development while release builds embed the whole console in the binary.
This commit is contained in:
+29
-7
@@ -355,17 +355,39 @@ marked with a `restart required` badge, and the UI surfaces a single
|
|||||||
component-per-view under `ts_web/elements/<area>/`, a tiny
|
component-per-view under `ts_web/elements/<area>/`, a tiny
|
||||||
SmartRouter-style client router (`ts_web/router.ts`), and a single
|
SmartRouter-style client router (`ts_web/router.ts`), and a single
|
||||||
`appstate.ts` as the store.
|
`appstate.ts` as the store.
|
||||||
|
- **Bundled into the binary via `ts_bundled/bundle.ts`.** ModelGrid is a
|
||||||
|
Deno project that ships as a `deno compile` single binary, so the UI
|
||||||
|
follows the `@stack.gallery/registry` pattern: a build step bundles
|
||||||
|
the `ts_web/` sources (HTML, JS, CSS, fonts, icons) into a single
|
||||||
|
generated `ts_bundled/bundle.ts` module that exports a
|
||||||
|
`{ path → bytes | string }` map. The daemon dynamically imports that
|
||||||
|
module at startup and hands the map to **typedserver**, which serves
|
||||||
|
it on the UI port. Result: no external asset directory, no runtime
|
||||||
|
filesystem dependency, one binary still ships the entire console.
|
||||||
|
- **Dev vs prod asset source.** In `deno task dev`, typedserver is
|
||||||
|
pointed at `ts_web/` on disk so UI edits are hot-reloadable without
|
||||||
|
re-running the bundler. In `deno task compile` / prod, the bundler
|
||||||
|
regenerates `ts_bundled/bundle.ts` first and the compiled binary
|
||||||
|
serves exclusively from the embedded map. A single flag
|
||||||
|
(`UI_ASSET_SOURCE=disk|bundle`, default `bundle`) picks the strategy
|
||||||
|
at runtime.
|
||||||
|
- **Bundler placement.** Mirrors `@stack.gallery/registry`: keep the
|
||||||
|
bundler in `scripts/bundle-ui.ts`, invoke it from a `deno task
|
||||||
|
bundle:ui` that the `compile:all` task depends on, and `.gitignore`
|
||||||
|
the generated `ts_bundled/bundle.ts` so it is only produced during
|
||||||
|
release builds (or regenerated on demand for local prod testing).
|
||||||
- **Packaging.** Follow dcrouter's module split: `@modelgrid.com/modelgrid`
|
- **Packaging.** Follow dcrouter's module split: `@modelgrid.com/modelgrid`
|
||||||
ships the daemon and the UI bundle; a future
|
ships the daemon and the embedded UI bundle; a future
|
||||||
`@modelgrid.com/modelgrid-web` can carve out the web boundary if the
|
`@modelgrid.com/modelgrid-web` can carve out the web sources as their
|
||||||
bundle grows large.
|
own publishable boundary if the bundle grows large or the UI needs to
|
||||||
|
be consumed independently.
|
||||||
- **Dark theme default** (black background, high-contrast foreground) to
|
- **Dark theme default** (black background, high-contrast foreground) to
|
||||||
match dcrouter and the expected server-ops environment. Light theme
|
match dcrouter and the expected server-ops environment. Light theme
|
||||||
is a later toggle.
|
is a later toggle.
|
||||||
- **No server-side rendering.** The UI is a static SPA served by the
|
- **No server-side rendering.** The UI is a static SPA; typedserver
|
||||||
daemon; all data is fetched through the API. This keeps the runtime
|
returns the asset map's `index.html` for the app shell and the rest
|
||||||
surface small and makes the UI-less `curl` story identical to the UI
|
of the state comes from the API. This keeps the runtime surface
|
||||||
story.
|
small and makes the UI-less `curl` story identical to the UI story.
|
||||||
|
|
||||||
## ❓ Open Questions
|
## ❓ Open Questions
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user