Skip to content

feat(hub): support functional/boolean when on dock entries#87

Closed
antfubot wants to merge 1 commit into
mainfrom
feat/dynamic-dock-when
Closed

feat(hub): support functional/boolean when on dock entries#87
antfubot wants to merge 1 commit into
mainfrom
feat/dynamic-dock-when

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

What

Widens the dock-entry when field (DevframeDockEntryBase.when, shared by every dock entry type) from string to:

type DevframeWhen = string | boolean | (() => string | boolean | undefined)

Adds a resolveWhen() helper (packages/hub/src/node/when.ts, re-exported from @devframes/hub/node) that resolves any of those forms down to the existing wire contract — string | undefined — and wires it into DevframeDocksHost's projectView(), the single place a registered entry is turned into its serializable form for values(). The resolution happens on a shallow copy, so the stored entry (and any when function on it) is left untouched for the next serialization pass.

defineDockEntry's when type is widened the same way, and mountDevframe's dock option doc comment now calls out the function form.

Why

when on a dock entry is a string expression evaluated client-side. The built-in ~terminals/~messages docks get dynamic visibility today via an object-literal getter (get when() { … }) on the entry returned fresh from values() every call. That trick doesn't work for a dock registered via docks.register(...) or mounted via mountDevframe(ctx, def, { dock }): the entry is stored once, and mountDevframe's ...options.dock spread would evaluate a getter a single time and freeze it. A function value, by contrast, survives an object spread by reference, so allowing when to be a function gives mounted/registered docks the same dynamic behavior the built-ins have, without any client-side changes.

The wire contract is unchanged — clients and whenexpr keep interpreting when exactly as before. The function/boolean form is purely a server-side authoring convenience resolved during serialization:

  • false'false' (unconditionally hidden)
  • true / null / undefinedundefined (unconditionally visible)
  • a string is passed through unchanged (still client-evaluated)

Testing

  • Unit tests added in host-docks.test.ts (function when re-resolves per values() call reflecting current state, boolean resolution, string passthrough, no mutation of the stored entry) and mount-devframe.test.ts (a function when flows through the ...options.dock spread and re-resolves per call).
  • pnpm lint && pnpm test && pnpm typecheck && pnpm build all pass, including the Next.js Turbopack example (had to move the new resolveWhen helper into its own node/when.ts module rather than the existing node/utils.ts, since the latter transitively pulls in mlly's toDataURL, which broke that example's build once host-docks.ts imported from it).
  • Docs updated in docs/guide/when-clauses.md.

Created with the help of an agent.

Widen dock-entry `when` to `string | boolean | (() => string | boolean | undefined)`,
resolved to the existing `string | undefined` wire contract once per
`DevframeDocksHost.values()`/`projectView` serialization pass.

This lets a host give a dock registered via `docks.register(...)` or
mounted via `mountDevframe(ctx, def, { dock })` the same dynamic
visibility the built-in `~terminals`/`~messages` entries get from an
object-literal getter — a function survives `mountDevframe`'s
`...options.dock` spread by reference, where a getter would only run
once. Clients and `whenexpr` are unaffected; the resolved value is
still a plain string expression or `undefined`.
@netlify

netlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit aa7d2b6
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a507bc0f1aea500081a1217
😎 Deploy Preview https://deploy-preview-87--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@antfu antfu closed this Jul 10, 2026
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.

2 participants