Skip to content

feat(hub): buildHub accpets already-mounted context - #349

Merged
antfu merged 6 commits into
mainfrom
feat/hub-bake-static
Sep 4, 2026
Merged

feat(hub): buildHub accpets already-mounted context#349
antfu merged 6 commits into
mainfrom
feat/hub-bake-static

Conversation

@antfubot

@antfubot antfubot commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Closes #347.

Lets buildHub reuse its baking pipeline for a context a host assembled and mounted itself (Vite DevTools' kit-augmented context, devframes mounted from Vite plugins), so downstreams stop shadowing the baker and inherit format/behaviour fixes for free.

Rather than introduce a new bakeHubStatic verb/concept, this mirrors initHub's existing context option.

What

  • buildHub({ context }) — pass an already-mounted DevframeHubContext instead of devframes; buildHub bakes it, reading ctx.frames and ctx.views.buildStaticDirs for what to emit. Mutually exclusive with devframes (throws DF8002, same as initHub). configure/ui.setup still run against it.
  • ctx.frames (HubMountedFrame[], exported from @devframes/hub/node) is populated in prepareDevframe, so ctx.install, initHub, and buildHub all record frames uniformly and the baker can emit __index.json + per-frame metas for a context it did not mount itself.
  • Statics copied from ctx.views.buildStaticDirs (local dir cp, remote source materialize), so a caller-mounted context whose host copied nothing live still gets its assets in. Page scripts route through views.hostStatic so they land there too.
  • clean?: boolean (default true) — set false to bake beside an app's own build output.

The public surface stays just buildHub; the baking helpers are module-private in build.ts.

Notes

The downstream deletion of vitejs/devtools' hand-rolled packages/core/src/node/build-static.ts lives in that separate repo; this is the upstream half that unblocks it. The change is confined to @devframes/hub (+ docs). Existing buildHub/initHub behaviour is unchanged; added tests cover baking a context, the clean: false flag, and ctx.frames.

This PR was created with the help of an agent.

Extract buildHub's post-mount baker into a public bakeHubStatic(ctx, opts)
so a host that assembles and mounts its own hub context (Vite DevTools'
kit-augmented context, devframes mounted from Vite plugins) reuses the
exact baker instead of reimplementing it and drifting out of sync.

- bakeHubStatic bakes an already-mounted DevframeHubContext; buildHub is now
  createHubContext + mountDevframes + bakeHubStatic.
- Enumerate mounted frames via ctx.frames (HubMountedFrame), populated in
  prepareDevframe, so an externally-mounted context can emit __index.json
  and per-frame __connection.json.
- Materialize statics from ctx.views.buildStaticDirs (each entry now carries
  its resolveFrom); route page scripts through views.hostStatic so they land
  there too.
- Add a clean opt-out so the baker can write beside an app's own build output.
@coldtea-pr-lens

coldtea-pr-lens Bot commented Sep 3, 2026

Copy link
Copy Markdown

◈ PR Lens

🟢 +0 new · 🟠 ~3 changed · 🔴 -0 removed · 1 flow · 11 files · commit ae096b1


Architecture

Architecture diagram for devframes/devframe at ae096b1

3 components touched across 5 lanes.

Open full size


Inside the changed components — 2 views

Component view — Hub static builder

Static build pipeline in buildHub that consumes pre-mounted contexts, copies registered static asset directories, and emits static discovery artifacts.

Architecture view of Component view — Hub static builder in devframes/devframe

Component view — Hub context & frame registration

Hub context creation and frame mounting lifecycle that tracks installed devframes in ctx.frames and records static asset directories on the view host.

Architecture view of Component view — Hub context & frame registration in devframes/devframe

Data flow

Data flow diagram for devframes/devframe at ae096b1

Static hub build from pre-mounted context

Open full size


Drill down
Hub Orchestration — 2 components
🟡 CHANGED Hub Static Builder

Bakes static hub bundles from a pre-mounted context or declarative devframe list, copying recorded static asset directories, writing discovery manifests (__index.json, __connection.json), and outputting static RPC dumps.

🟡 CHANGED Hub Core & Lifecycle

Manages the hub execution lifecycle, context creation, and mounted devframe tracking via ctx.frames, routing page scripts to view static hosting and enforcing mutual exclusivity between devframes and context (DF8002).

Devframe Core Engine — 1 component
🟡 CHANGED Single-Tool Instance Shell

Core runtime context and view host that tracks static asset mounts and preserves resolveFrom paths in buildStaticDirs for offline build asset materialization.


View

  • Architecture lens
  • Data flow lens
  • Expand every detail
  • Show unchanged neighbours

Tip

Would you rather run it from CI on a key of your own? Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and a model key in your repository secrets, say GEMINI_API_KEY. The Action asks Gemini by default, or OpenAI and any endpoint speaking /chat/completions through its provider input.

🪧 More tips
  • Run PR Lens on your own machine: npx skills add coldteadotai/pr-lens installs the agent skill. Then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Draw a diff before it is even a pull request: npx @coldtea/pr-lens-cli analyze --base origin/main reads the diff with your own model key, and npx @coldtea/pr-lens-cli render .pr-lens/graph.json draws the same lenses on your machine.
  • The boxes under View are live. Tick Architecture lens or Data flow lens to choose which diagrams appear, or Expand every detail to open every drill-down at once. The comment redraws in place a few seconds later.
  • Show unchanged neighbours lists the components this change did not touch alongside the ones it did, so the drill-down shows what the changed code sits next to.
  • GitHub will not let you zoom an image in a comment. The link under each diagram opens it full size on a page of its own, where you can.
  • The CLI's render picks up .github/pr-lens.yml automatically and applies your corrections (renames, exclusions, lane pins) at draw time.
  • PR Lens is free for open source. A star on the repository is what keeps it going.
  • Push a new commit and the whole comment re-renders for the new head. An older run never overwrites a newer one, so a slow render cannot put a stale diagram back.
  • The diagrams follow your GitHub theme, so dark mode gets the dark render and light mode the light one, and the moving dots show this pull request's data in motion.

◈ Rendered by PR Lens · crafted with ❤️ by the Coldtea team · Come say hi on Discord

@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
devframe Ready Ready Preview Sep 4, 2026 2:12am UTC

Ablation of the previous commit dropped two deltas that no tested or
in-repo path depends on:

- Removed the `resolveFrom` field added to devframe's core `buildStaticDirs`
  (types/views + host-views). No devframe in the repo declares RemoteAssets
  client assets, and string dist dirs ignore resolveFrom, so re-resolving in
  bakeHubStatic without it is equivalent. Confines the change to @devframes/hub.
- Removed `HubMountedFrame.hasClientAssets` (and serveDevframeAssets' boolean
  return): whether a frame served its own SPA is derivable from
  ctx.views.buildStaticDirs, so bakeHubStatic derives the per-frame meta
  targets instead of carrying an extra field on the public type.
… concept

Rather than introduce a new "bake" verb/function, mirror initHub's existing
`context` option: buildHub now accepts an already-mounted DevframeHubContext
and bakes it (reading ctx.frames + ctx.views.buildStaticDirs), throwing DF8002
if both `context` and `devframes` are passed. The baking helpers fold back into
build.ts as module-private functions; the public surface stays just buildHub.
@antfubot antfubot changed the title feat(hub): expose bakeHubStatic to bake an already-mounted context feat(hub): let buildHub bake an already-mounted context Sep 4, 2026
@antfu antfu changed the title feat(hub): let buildHub bake an already-mounted context feat(hub): buildHub accpets already-mounted context Sep 4, 2026
buildHub copies statics from ctx.views.buildStaticDirs, which for a plugin's
RemoteAssets client bundle (e.g. @devframes/plugin-a11y--assets) must re-resolve
with the plugin's importMetaUrl as resolveFrom to hit the locally-installed
copy; without it resolution fell back to a stale CDN back-proxy cache, baking an
outdated SPA (surfaced by the a11y summary sticky e2e). Record resolveFrom on
each buildStaticDirs entry and pass it through when baking.
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.

feat(hub): let buildHub bake an already-assembled context (reuse in Vite DevTools)

2 participants