Skip to content

Commit ffbda00

Browse files
authored
fix(hub): restore ctx.createJsonRenderer as a working 0.7 deprecation, remove in 0.8 (#125)
1 parent fd23f6b commit ffbda00

6 files changed

Lines changed: 90 additions & 13 deletions

File tree

docs/guide/migration-0.7.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ const view = createJsonRenderView(ctx, {
7272
})
7373
```
7474

75-
`@devframes/hub` still exports `defineJsonRenderSpec` as a deprecated identity function (same for the `JsonRenderSpec` / `JsonRenderElement` / `JsonRenderer` types), so existing imports keep compiling — but it no longer registers anything with the hub on its own. Move call sites over to `createJsonRenderView` now rather than waiting for the alias's removal in a future major release.
75+
`@devframes/hub` still exports `defineJsonRenderSpec` as a deprecated identity function (same for the `JsonRenderSpec` / `JsonRenderElement` / `JsonRenderer` types) and still runs `ctx.createJsonRenderer` (against its own pre-0.7 shared-state implementation, not `@devframes/json-render`), so existing call sites keep working through 0.7 unmodified — but it no longer registers anything with the hub's dock union on its own, and won't gain the new dock projection or `registerRenderer()` support that `createJsonRenderView` gets. Move call sites over to `createJsonRenderView` now; `ctx.createJsonRenderer` and the other aliases above are removed in 0.8.
7676

7777
See [JSON-Render](./json-render) for the full integration reference.

packages/hub/src/define.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export function defineDockEntry<
2626
* @deprecated json-render moved out of the hub into the opt-in
2727
* `@devframes/json-render` integration in 0.7. This identity helper is kept
2828
* so existing imports keep compiling — pass your spec directly to
29-
* `createJsonRenderView` (from `@devframes/json-render/node`) instead. Will
30-
* be removed in a future major release.
29+
* `createJsonRenderView` (from `@devframes/json-render/node`) instead.
30+
* Removed in 0.8.
3131
*/
3232
export function defineJsonRenderSpec(spec: JsonRenderSpec): JsonRenderSpec {
3333
return spec

packages/hub/src/node/__tests__/context.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,38 @@ describe('createHubContext dock activation', () => {
5959
})
6060
})
6161

62+
describe('createHubContext createJsonRenderer (deprecated 0.7 compatibility factory)', () => {
63+
it('seeds shared state with the initial spec and applies updateSpec/updateState', async () => {
64+
const context = await createHubContext({
65+
cwd: process.cwd(),
66+
mode: 'build',
67+
host: createHost(),
68+
})
69+
70+
const renderer = context.createJsonRenderer({ root: 'panel', elements: {} })
71+
const state = await context.rpc.sharedState.get<any>(renderer._stateKey)
72+
expect(state.value()).toEqual({ root: 'panel', elements: {} })
73+
74+
await renderer.updateSpec({ root: 'panel', elements: {}, state: { count: 1 } })
75+
expect(state.value()).toEqual({ root: 'panel', elements: {}, state: { count: 1 } })
76+
77+
await renderer.updateState({ count: 2, label: 'hi' })
78+
expect(state.value()).toEqual({ root: 'panel', elements: {}, state: { count: 2, label: 'hi' } })
79+
})
80+
81+
it('gives each renderer its own stable, distinct state key', async () => {
82+
const context = await createHubContext({
83+
cwd: process.cwd(),
84+
mode: 'build',
85+
host: createHost(),
86+
})
87+
88+
const first = context.createJsonRenderer({ root: 'a', elements: {} })
89+
const second = context.createJsonRenderer({ root: 'b', elements: {} })
90+
expect(first._stateKey).not.toEqual(second._stateKey)
91+
})
92+
})
93+
6294
describe('startHttpAndWs remote endpoint metadata', () => {
6395
it('sets and clears the internal websocket endpoint', async () => {
6496
const context = await createHostContext({

packages/hub/src/node/context.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { CreateHostContextOptions } from 'devframe/node'
22
import type { DevframeHost, DevframeNodeContext } from 'devframe/types'
33
import type { DevframeCommandsHost } from '../types/commands'
44
import type { DevframeDockActivation, DevframeDocksActiveState, DevframeDocksHost } from '../types/docks'
5+
import type { JsonRenderer, JsonRenderSpec } from '../types/json-render'
56
import type { DevframeMessageEntry, DevframeMessageEntryInput, DevframeMessagesHost } from '../types/messages'
67
import type { DevframeTerminalsHost } from '../types/terminals'
78
import { createHostContext } from 'devframe/node'
@@ -84,21 +85,34 @@ declare module 'devframe/types' {
8485
/**
8586
* Hub-augmented node context — extends devframe's framework-neutral
8687
* `DevframeNodeContext` with the hub-level subsystems (`docks`,
87-
* `terminals`, `messages`, `commands`).
88+
* `terminals`, `messages`, `commands`) and the deprecated
89+
* `createJsonRenderer` compatibility factory.
8890
*
8991
* Framework kits further extend this with their own slots (e.g.
9092
* `viteConfig`, `viteServer`). Host-specific capabilities (editor open,
9193
* filesystem reveal, etc.) ship as kit-registered RPC functions rather
92-
* than as part of this surface. JSON-render is not part of the hub: it is
93-
* an opt-in integration (`@devframes/json-render`) that augments any
94-
* devframe context and contributes its own dock type.
94+
* than as part of this surface. JSON-render itself is not part of the hub:
95+
* it is an opt-in integration (`@devframes/json-render`) that augments any
96+
* devframe context and contributes its own dock type — prefer
97+
* `createJsonRenderView` from `@devframes/json-render/node` over the
98+
* deprecated factory below.
9599
*/
96100
export interface DevframeHubContext extends DevframeNodeContext {
97101
readonly host: DevframeHost
98102
docks: DevframeDocksHost
99103
terminals: DevframeTerminalsHost
100104
messages: DevframeMessagesHost
101105
commands: DevframeCommandsHost
106+
/**
107+
* Create a `JsonRenderer` handle for building json-render powered UIs.
108+
*
109+
* @deprecated json-render moved out of the hub into the opt-in
110+
* `@devframes/json-render` integration in 0.7. This factory is kept
111+
* working (not just type-compatible) for the 0.7 series so existing call
112+
* sites don't break — use `createJsonRenderView(ctx, { id, spec })` from
113+
* `@devframes/json-render/node` instead. Will be removed in 0.8.
114+
*/
115+
createJsonRenderer: (spec: JsonRenderSpec) => JsonRenderer
102116
}
103117

104118
/**
@@ -136,6 +150,36 @@ export async function createHubContext(options: CreateHubContextOptions): Promis
136150

137151
await docks.init()
138152

153+
// Deprecated pre-0.7 compatibility factory — restored as a working (not
154+
// merely type-compatible) shim so 0.7 only *deprecates* it rather than
155+
// breaking it outright; see the `createJsonRenderer` JSDoc above. Kept
156+
// self-contained against `context.rpc.sharedState` (as it was pre-0.7)
157+
// rather than delegating to `@devframes/json-render`'s
158+
// `createJsonRenderView`, so the hub still carries no dependency — direct
159+
// or peer — on that opt-in package. Removed in 0.8: migrate call sites to
160+
// `createJsonRenderView` before then.
161+
let jsonRenderCounter = 0
162+
context.createJsonRenderer = (initialSpec: JsonRenderSpec): JsonRenderer => {
163+
const stateKey = `devframe:json-render:${jsonRenderCounter++}`
164+
const statePromise = context.rpc.sharedState.get(stateKey as any, {
165+
initialValue: initialSpec as any,
166+
})
167+
168+
return {
169+
_stateKey: stateKey,
170+
async updateSpec(spec) {
171+
const state = await statePromise
172+
state.mutate(() => spec as any)
173+
},
174+
async updateState(newState) {
175+
const state = await statePromise
176+
state.mutate((draft: any) => {
177+
draft.state = { ...draft.state, ...newState }
178+
})
179+
},
180+
}
181+
}
182+
139183
const debounceMs = options.mode === 'build' ? 0 : 10
140184

141185
const docksSharedState = await context.rpc.sharedState.get('devframe:docks', { initialValue: [] })

packages/hub/src/types/docks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,11 @@ export interface DevframeViewBuiltin extends DevframeDockEntryBase {
259259
* `JsonRenderer` handle) to {@link DevframeDockEntryRegistry} via declaration
260260
* merging. This type is kept for compatibility but is no longer a member of
261261
* {@link DevframeDockUserEntry} — use `@devframes/json-render/hub` instead.
262+
* Removed in 0.8.
262263
*/
263264
export interface DevframeViewJsonRender extends DevframeDockEntryBase {
264265
type: 'json-render'
265-
/** JsonRenderer handle created by ctx.createJsonRenderer() */
266+
/** JsonRenderer handle created by the deprecated ctx.createJsonRenderer() */
266267
ui: JsonRenderer
267268
}
268269

packages/hub/src/types/json-render.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
// 0.7 moved json-render out of the hub into the opt-in `@devframes/json-render`
44
// integration — use its `DevframeJsonRenderSpec` (from `@devframes/json-render`)
55
// and `createJsonRenderView` (from `@devframes/json-render/node`) instead. These
6-
// types are kept so existing imports keep compiling; they will be removed in a
7-
// future major release.
6+
// types are kept so existing imports keep compiling through the 0.7 series;
7+
// they are removed in 0.8.
88

9-
/** @deprecated Use `DevframeJsonRenderSpec`'s element shape from `@devframes/json-render` instead. */
9+
/** @deprecated Use `DevframeJsonRenderSpec`'s element shape from `@devframes/json-render` instead. Removed in 0.8. */
1010
export interface JsonRenderElement {
1111
type: string
1212
props?: Record<string, unknown>
@@ -21,15 +21,15 @@ export interface JsonRenderElement {
2121
[key: string]: unknown
2222
}
2323

24-
/** @deprecated Use `DevframeJsonRenderSpec` from `@devframes/json-render` instead. */
24+
/** @deprecated Use `DevframeJsonRenderSpec` from `@devframes/json-render` instead. Removed in 0.8. */
2525
export interface JsonRenderSpec {
2626
root: string
2727
elements: Record<string, JsonRenderElement>
2828
/** Initial client-side state model for $state/$bindState expressions */
2929
state?: Record<string, unknown>
3030
}
3131

32-
/** @deprecated Use `JsonRenderView` from `@devframes/json-render` instead. */
32+
/** @deprecated Use `JsonRenderView` from `@devframes/json-render` instead. Removed in 0.8. */
3333
export interface JsonRenderer {
3434
/** Replace the entire spec */
3535
updateSpec: (spec: JsonRenderSpec) => void | Promise<void>

0 commit comments

Comments
 (0)