feat: JSON-render packages (@devframes/json-render + @devframes/json-render-ui)#116
Merged
Conversation
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.
✅ Deploy Preview for devfra ready!
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.
Collaborator
Author
|
Added an example and docs:
|
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.
…feat/json-render-packages
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).
…feat/json-render-packages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-depsdevframe, depends on@json-render/core+zod, no Vue/DOM):.— base catalog + fourteen Devframes-authored Zod prop schemas, serializableJsonRenderViewRef, re-exported protocol types../core— curated named re-exports of@json-render/core(builders + types only; noexport *)../node—createJsonRenderView: scoped stable ids (devframe:json-render:<scope>:<id>), patch-enabled shared state, JSON-PointerpatchState, ingress prop + JSON-serializability validation,dispose../hub— contributes thejson-renderdock type to the hub's open dock union without the hub depending on json-render.DF0038–DF0041.@devframes/json-render-ui— official Vue reference frontend on@antfu/design(peer-deps@devframes/json-render+vue):ComponentFns), fully-dynamic sanitizedIcon, typed events via bound state.createRenderershell 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 closedDevframeViewJsonRendervariant,createJsonRenderer,defineJsonRenderSpec, and the hand-written json-render types. AddedregisterRendererrouting (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 stalecreateJsonRendererdoc comments.Verification
pnpm lint && pnpm test && pnpm typecheck && pnpm buildall pass (788 tests). tsnapi API snapshots andtests/exports.test.tssubpaths updated for both new packages and the changed hub. Docs error pagesDF0038–DF0041added.Deferred (plan §8–9, separable follow-up slices)
Wiring the devframe
dev/buildadapters 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 staticinteractive: falseaffordance exist, but adapter auto-serving is left as its own slice.This PR was created with the help of an agent.