Skip to content

feat: JSON-render packages (@devframes/json-render + @devframes/json-render-ui)#116

Merged
antfu merged 14 commits into
mainfrom
feat/json-render-packages
Jul 22, 2026
Merged

feat: JSON-render packages (@devframes/json-render + @devframes/json-render-ui)#116
antfu merged 14 commits into
mainfrom
feat/json-render-packages

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Implements plans/json-render/plan.md: makes JSON-render an opt-in capability a devframe app adds, never a cost the hub or a plain app pays.

What's here

@devframes/json-render — framework-neutral protocol layer (peer-deps devframe, depends on @json-render/core + zod, no Vue/DOM):

  • . — base catalog + fourteen Devframes-authored Zod prop schemas, serializable JsonRenderViewRef, re-exported protocol types.
  • ./core — curated named re-exports of @json-render/core (builders + types only; no export *).
  • ./nodecreateJsonRenderView: scoped stable ids (devframe:json-render:<scope>:<id>), patch-enabled shared state, JSON-Pointer patchState, ingress prop + JSON-serializability validation, dispose.
  • ./hub — contributes the json-render dock type to the hub's open dock union without the hub depending on json-render.
  • Diagnostics DF0038DF0041.

@devframes/json-render-ui — official Vue reference frontend on @antfu/design (peer-deps @devframes/json-render + vue):

  • Fourteen ported components (as ComponentFns), fully-dynamic sanitized Icon, typed events via bound state.
  • Base registry, createRenderer shell with reset-on-identity/version semantics, unrestricted action bridge (per-action loading + surfaced errors), render-time prop isolation, createJsonRenderDockRenderer, and Storybook.

Hub decoupling — the dock union is now an augmentable DevframeDockEntryRegistry; removed the closed DevframeViewJsonRender variant, createJsonRenderer, defineJsonRenderSpec, and the hand-written json-render types. Added registerRenderer routing (with dispose-on-deactivation) to the client host. The hub acquires no Vue and no json-render dependency.

devframe core — added RpcSharedStateHost.delete, load immer patches for patch-enabled shared state, removed stale createJsonRenderer doc comments.

Verification

pnpm lint && pnpm test && pnpm typecheck && pnpm build all pass (788 tests). tsnapi API snapshots and tests/exports.test.ts subpaths updated for both new packages and the changed hub. Docs error pages DF0038DF0041 added.

Deferred (plan §8–9, separable follow-up slices)

Wiring the devframe dev/build adapters to auto-serve a frontend lib's SPA (with the static-snapshot affordance) and the throwaway end-to-end prototype. The hub-mounted render path is complete and tested; the standalone renderer shell and static interactive: false affordance exist, but adapter auto-serving is left as its own slice.

This PR was created with the help of an agent.

Introduce JSON-render as an opt-in capability a devframe app adds, rather
than a cost the hub or a plain app pays.

- @devframes/json-render: framework-neutral protocol layer — base catalog +
  per-component Zod prop schemas, serializable JsonRenderViewRef, curated
  ./core re-exports of @json-render/core, and a ./node createJsonRenderView
  runtime factory (scoped stable ids, patch-enabled shared state, JSON-Pointer
  state patches, ingress prop + serializability validation, disposal). A
  ./hub subpath contributes the json-render dock type to the hub's open dock
  union without making the hub depend on json-render.
- @devframes/json-render-ui: official Vue reference frontend on @antfu/design —
  the fourteen base components, base registry, renderer shell with reset
  semantics, an unrestricted action bridge that tracks per-action loading and
  surfaces failures, render-time prop isolation, a hub dock renderer, and
  Storybook coverage.
- Hub: open the dock union via an augmentable registry and drop the closed
  json-render variant, createJsonRenderer, and the hand-written json-render
  types; add registerRenderer routing (with dispose-on-deactivation) to the
  client host.
- devframe core: add RpcSharedStateHost.delete, load immer patches for
  patch-enabled shared state, and remove stale createJsonRenderer references.
- Docs: error pages DF0038-DF0041. tsnapi snapshots + exports tests updated.

Created with the help of an agent.
@netlify

netlify Bot commented Jul 21, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit 4f341f3
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a603e76936b3100089e8d49
😎 Deploy Preview https://deploy-preview-116--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.

- examples/minimal-json-render: a standalone Vue + Vite devframe that authors a
  JSON-render view server-side (createJsonRenderView), ticks live state, bridges
  a Button action to RPC, and renders it with @devframes/json-render-ui.
- docs/guide/json-render.md: authoring, base catalog, actions/state, standalone
  and hub rendering, and swapping the frontend; linked from the guide index.
- docs/examples/minimal-json-render.md + examples index/sidebar entry.
- hub + client-context guides updated for the open dock union and the client
  host renderer registry (no more hub createJsonRenderer).

Created with the help of an agent.
@antfubot

Copy link
Copy Markdown
Collaborator Author

Added an example and docs:

  • examples/minimal-json-render — a standalone Vue + Vite devframe that authors a JSON-render view server-side (createJsonRenderView), ticks live uptime state via patchState, bridges a Refresh button action to RPC, and renders it with @devframes/json-render-ui. Verified end to end: SPA vite build, node-side static snapshot (the dumped shared state contains the view spec + state), typecheck, and the full turbo build all pass.
  • docs/guide/json-render.md — authoring, the base catalog, actions/state, standalone + hub rendering, and swapping the frontend; linked from the guide index.
  • docs/examples/minimal-json-render.md + examples index/sidebar entry.
  • Updated the Hub and Client Scripts & Context guides for the open dock union and the client-host renderer registry (no more hub createJsonRenderer).

pnpm lint, pnpm typecheck, pnpm build, pnpm exec vitest run (788 tests) and pnpm docs:build (no dead links) all green.

antfubot and others added 12 commits July 22, 2026 00:30
Resolve pnpm-lock.yaml by regenerating from the merged manifests.
- Rework the example spec into a project dashboard that exercises every
  base-catalog component (Stack, Card, Text, Badge, Button, Icon, Divider,
  TextInput, Switch, KeyValueTable, DataTable, CodeBlock, Progress, Tree),
  with live state, two-way bindings, and three actions (Refresh re-samples the
  Progress bars, Deploy toggles DataTable loading and appends a module, Save
  sends bound form params the server writes back).
- Make Button icons dependency-free: render the runtime-resolved Icon and a CSS
  spinner instead of static `i-ph:*` classes; use a text caret in Card so
  neither component requires an icon font in the consuming app.

Created with the help of an agent.
Build the reference frontend on @antfu/design's Vue components directly instead
of hand-rolled markup, so it tracks the shared design system and stops drifting.

- Icon wraps DisplayIconifyRemoteIcon, which fetches with color=currentColor —
  fixing the reported bug where a button/text icon didn't inherit its color.
- Button→ActionButton, Badge→DisplayBadge, Card→LayoutCard, Divider→
  LayoutSeparator, TextInput→FormTextInput, Switch→FormSwitch,
  Progress→DisplayProgressBar, KeyValueTable→DisplayKeyValue.
- Stack, Text, CodeBlock, the value-tree Tree, and the row-clickable/loadable
  DataTable stay bespoke where @antfu/design has no matching primitive.
- @antfu/design becomes a peer dependency, kept external in the tsdown build
  (its .vue is compiled by the consumer's Vite); a *.vue shim resolves types.
  Consumers exclude it from optimizeDeps and safelist the runtime badge colors.

Docs and the minimal-json-render example updated for the consumer setup.

Created with the help of an agent.
Split the grouped component modules (layout/controls/data/typography/icon) into
one file per catalog component — Stack, Card, Divider, Text, Badge, CodeBlock,
Button, Icon, TextInput, Switch, KeyValueTable, DataTable, Progress, Tree — so
each is individually importable and easy to locate. Shared helpers (JrComponent,
toNumber, formatValue) live in _shared; the internal error placeholder stays in
_error. No behavior change.

Created with the help of an agent.
Verify the JSON-render hub integration end to end in the Vite hub shell:

- Extract a reusable `createDashboardView(ctx)` + `dashboardSpec` from the
  minimal-json-render example (exported as `minimal-json-render/dashboard`),
  used by both the standalone devframe and the hub.
- The Vite hub authors the view on its hub context and projects it onto a
  `json-render` dock (via `@devframes/json-render/hub`), and the client host
  registers `createJsonRenderDockRenderer()` and mounts the dock into a panel.
- Wire the hub's Vite build for the Vue renderer: @vitejs/plugin-vue,
  optimizeDeps exclude, UnoCSS `.vue` scanning + badge-color safelist, and a
  `*.vue` type shim.

Created with the help of an agent.
Verify the JSON-render hub integration in the React/Next shell via registry
replacement (the path a non-Vue host uses, per the plan):

- The Next hub authors the shared minimal-json-render view on its hub context
  and projects it onto a `json-render` dock (via @devframes/json-render/hub).
- A small in-example React registry (built on @json-render/react + the shared
  @antfu/design tokens) is registered as the `json-render` renderer on the
  client host; the page mounts the active dock into a panel via the renderer
  registry. Next.js can't compile Vue SFCs, so the Vue @devframes/json-render-ui
  isn't used here — this is registry replacement.
- UnoCSS scans the new dir + safelists the badge colors.

Docs: note the json-render dock in both hub example pages and the guide.

Created with the help of an agent.
Resolve uno.config conflicts in both hub examples: adopt main's shared
designConfig base (mergeConfigs) while keeping the JSON-render dock's .vue
scanning (Vite hub) and json-render dir glob, plus the badge-color safelist.
The page root uses `h-full`, but `<html>`/`<body>` weren't full-height (unlike
the Vite hub's index.html), so the layout collapsed. Set `h-full` on html/body
(plus `m0 of-hidden` and the base surface).
@antfu
antfu merged commit ef75b1a into main Jul 22, 2026
11 of 12 checks passed
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