Skip to content

feat: runtime engines (mount prebuilt engine releases without a console rebuild) - #99

Draft
roncodes wants to merge 1 commit into
release/v0.4.0from
feat/runtime-engines
Draft

roncodes wants to merge 1 commit into
release/v0.4.0from
feat/runtime-engines

Conversation

@roncodes

Copy link
Copy Markdown
Member

Extensions Registry, Phase 3 Workstream H follow-up (decision D3, Outcome A with a version pin).

A console that was built without an engine can now mount a prebuilt release of it at boot. The design, the release layout and the API contract are in docs/runtime-engines.md.

Runtime (addon/utils/runtime-engines.js)

  • prepareRuntimeEngines(application) runs before boot. It:
    • fetches GET ~registry/v1/engines/runtime (an empty list if the endpoint is missing)
    • skips engines the console is built with
    • refuses releases whose required host modules are missing
    • appends <name>/config/environment
    • loads routes.js and host-app.js with script elements
    • fetches translations.json
    • mounts by wrapping the generated router map's DSL callback, never with a second Router.map
  • registerRuntimeEngines(appInstance) runs after load-asset-manifest. It pushes the bundles, adds translations to ember-intl, and registers extension loaders that the extension manager falls back to.
  • loadInstalledExtensions(core, runtimeEngines) lists runtime engines after the build-time list. The localStorage extensions cache is keyed on the runtime list's signature, so an install or update invalidates it.

Tooling (bin/, lib/, Node, no new dependencies)

  • fleetbase-build-engine-release --console <dir> --engine <pkg> --out <dir> [--dist <dir>] writes <out>/<pkg>/ with:
    • routes.js, host-app.js, a standalone extension.js and translations.json
    • manifest.json: versions built against, the runtime entry, required host modules and alias list, sha256 per file
  • fleetbase-check-engine-compat --manifest … --host <dist|host-modules.json> [--policy minor|exact|modules] exits 1 when a required module is missing or ember-ui/ember-core are on a different minor.
  • fleetbase-host-modules --dist … --console … writes a console build's host-modules.json.

Verified locally against the spike's builds (no new builds)

  • Extracting from the spike's control dist gives the same routes.js, the same 490 host-app.js modules and the same translations as the hand-captured package.
  • The compat check passes Pallet against the matching host. Against the ember-ui 0.4.4 host it refuses Pallet and lists exactly the modules that broke at runtime in the spike.
  • node-tests/runtime-engines-mount.test.js booted the spike's console dist built without Pallet (with this branch's sources injected) in headless Chrome:
    • 456 console.pallet.* routes were mounted and /pallet resolved to console.pallet.home.
    • The config meta, the asset-manifest bundle, the translations and the extension setup were all in place, and loadEngine() booted Pallet.
    • The bundle was not fetched at boot, so the engine stays lazy.
    • A release requiring a missing module was refused and not mounted.

Not run locally

The QUnit suite and the lints. CI here is the first run.

Merge order

This PR first, then a release, then the console PR (fleetbase/fleetbase, feat/runtime-engines), which adds the two initializers and bumps @fleetbase/ember-core.

…ole rebuild

Workstream H follow-up (D3, Outcome A). A console build does seven things in
the host for every engine it compiles in; a prebuilt release now ships the
output of each and utils/runtime-engines replays them at boot:

- prepareRuntimeEngines (before boot): fetch GET ~registry/v1/engines/runtime,
  skip engines the console is built with, refuse engines whose required host
  modules are missing, append the config meta, load routes.js and host-app.js
  with script elements, fetch translations.json, and add the mounts by
  wrapping the generated router map (never a second Router.map).
- registerRuntimeEngines (instance boot): push the bundles into the asset
  loader, add translations to ember-intl, register extension loaders that the
  extension manager falls back to. A standalone extension.js keeps the engine
  bundle lazy; without one the bundle loads before requiring <name>/extension.
- loadInstalledExtensions accepts the runtime list; the extensions cache is
  keyed on the runtime list's signature so installs invalidate it.

Tooling (Node, no new dependencies):
- bin/build-engine-release.js: build (or reuse) a console dist with the engine
  and extract <out>/<name>/ with routes.js, host-app.js, extension.js,
  translations.json and manifest.json (versions built against, runtime entry,
  required host modules, alias list, sha256 per file).
- bin/check-engine-compat.js + bin/host-modules.js: diff a release's required
  modules against a console build's module list and gate on the ember-ui /
  ember-core minor.
- node-tests/: unit tests for the scanner, extractor and checks (run in CI),
  and an end-to-end test that boots a console dist built without Pallet in
  headless Chrome and mounts the captured Pallet release (needs two builds,
  skipped in CI).

Design note: docs/runtime-engines.md.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant