Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guide/migration-0.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ const view = createJsonRenderView(ctx, {
})
```

`@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.
`@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.

See [JSON-Render](./json-render) for the full integration reference.
4 changes: 2 additions & 2 deletions packages/hub/src/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export function defineDockEntry<
* @deprecated json-render moved out of the hub into the opt-in
* `@devframes/json-render` integration in 0.7. This identity helper is kept
* so existing imports keep compiling — pass your spec directly to
* `createJsonRenderView` (from `@devframes/json-render/node`) instead. Will
* be removed in a future major release.
* `createJsonRenderView` (from `@devframes/json-render/node`) instead.
* Removed in 0.8.
*/
export function defineJsonRenderSpec(spec: JsonRenderSpec): JsonRenderSpec {
return spec
Expand Down
32 changes: 32 additions & 0 deletions packages/hub/src/node/__tests__/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,38 @@ describe('createHubContext dock activation', () => {
})
})

describe('createHubContext createJsonRenderer (deprecated 0.7 compatibility factory)', () => {
it('seeds shared state with the initial spec and applies updateSpec/updateState', async () => {
const context = await createHubContext({
cwd: process.cwd(),
mode: 'build',
host: createHost(),
})

const renderer = context.createJsonRenderer({ root: 'panel', elements: {} })
const state = await context.rpc.sharedState.get<any>(renderer._stateKey)
expect(state.value()).toEqual({ root: 'panel', elements: {} })

await renderer.updateSpec({ root: 'panel', elements: {}, state: { count: 1 } })
expect(state.value()).toEqual({ root: 'panel', elements: {}, state: { count: 1 } })

await renderer.updateState({ count: 2, label: 'hi' })
expect(state.value()).toEqual({ root: 'panel', elements: {}, state: { count: 2, label: 'hi' } })
})

it('gives each renderer its own stable, distinct state key', async () => {
const context = await createHubContext({
cwd: process.cwd(),
mode: 'build',
host: createHost(),
})

const first = context.createJsonRenderer({ root: 'a', elements: {} })
const second = context.createJsonRenderer({ root: 'b', elements: {} })
expect(first._stateKey).not.toEqual(second._stateKey)
})
})

describe('startHttpAndWs remote endpoint metadata', () => {
it('sets and clears the internal websocket endpoint', async () => {
const context = await createHostContext({
Expand Down
52 changes: 48 additions & 4 deletions packages/hub/src/node/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { CreateHostContextOptions } from 'devframe/node'
import type { DevframeHost, DevframeNodeContext } from 'devframe/types'
import type { DevframeCommandsHost } from '../types/commands'
import type { DevframeDockActivation, DevframeDocksActiveState, DevframeDocksHost } from '../types/docks'
import type { JsonRenderer, JsonRenderSpec } from '../types/json-render'
import type { DevframeMessageEntry, DevframeMessageEntryInput, DevframeMessagesHost } from '../types/messages'
import type { DevframeTerminalsHost } from '../types/terminals'
import { createHostContext } from 'devframe/node'
Expand Down Expand Up @@ -84,21 +85,34 @@ declare module 'devframe/types' {
/**
* Hub-augmented node context — extends devframe's framework-neutral
* `DevframeNodeContext` with the hub-level subsystems (`docks`,
* `terminals`, `messages`, `commands`).
* `terminals`, `messages`, `commands`) and the deprecated
* `createJsonRenderer` compatibility factory.
*
* Framework kits further extend this with their own slots (e.g.
* `viteConfig`, `viteServer`). Host-specific capabilities (editor open,
* filesystem reveal, etc.) ship as kit-registered RPC functions rather
* than as part of this surface. JSON-render is not part of the hub: it is
* an opt-in integration (`@devframes/json-render`) that augments any
* devframe context and contributes its own dock type.
* than as part of this surface. JSON-render itself is not part of the hub:
* it is an opt-in integration (`@devframes/json-render`) that augments any
* devframe context and contributes its own dock type — prefer
* `createJsonRenderView` from `@devframes/json-render/node` over the
* deprecated factory below.
*/
export interface DevframeHubContext extends DevframeNodeContext {
readonly host: DevframeHost
docks: DevframeDocksHost
terminals: DevframeTerminalsHost
messages: DevframeMessagesHost
commands: DevframeCommandsHost
/**
* Create a `JsonRenderer` handle for building json-render powered UIs.
*
* @deprecated json-render moved out of the hub into the opt-in
* `@devframes/json-render` integration in 0.7. This factory is kept
* working (not just type-compatible) for the 0.7 series so existing call
* sites don't break — use `createJsonRenderView(ctx, { id, spec })` from
* `@devframes/json-render/node` instead. Will be removed in 0.8.
*/
createJsonRenderer: (spec: JsonRenderSpec) => JsonRenderer
}

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

await docks.init()

// Deprecated pre-0.7 compatibility factory — restored as a working (not
// merely type-compatible) shim so 0.7 only *deprecates* it rather than
// breaking it outright; see the `createJsonRenderer` JSDoc above. Kept
// self-contained against `context.rpc.sharedState` (as it was pre-0.7)
// rather than delegating to `@devframes/json-render`'s
// `createJsonRenderView`, so the hub still carries no dependency — direct
// or peer — on that opt-in package. Removed in 0.8: migrate call sites to
// `createJsonRenderView` before then.
let jsonRenderCounter = 0
context.createJsonRenderer = (initialSpec: JsonRenderSpec): JsonRenderer => {
const stateKey = `devframe:json-render:${jsonRenderCounter++}`
const statePromise = context.rpc.sharedState.get(stateKey as any, {
initialValue: initialSpec as any,
})

return {
_stateKey: stateKey,
async updateSpec(spec) {
const state = await statePromise
state.mutate(() => spec as any)
},
async updateState(newState) {
const state = await statePromise
state.mutate((draft: any) => {
draft.state = { ...draft.state, ...newState }
})
},
}
}

const debounceMs = options.mode === 'build' ? 0 : 10

const docksSharedState = await context.rpc.sharedState.get('devframe:docks', { initialValue: [] })
Expand Down
3 changes: 2 additions & 1 deletion packages/hub/src/types/docks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,11 @@ export interface DevframeViewBuiltin extends DevframeDockEntryBase {
* `JsonRenderer` handle) to {@link DevframeDockEntryRegistry} via declaration
* merging. This type is kept for compatibility but is no longer a member of
* {@link DevframeDockUserEntry} — use `@devframes/json-render/hub` instead.
* Removed in 0.8.
*/
export interface DevframeViewJsonRender extends DevframeDockEntryBase {
type: 'json-render'
/** JsonRenderer handle created by ctx.createJsonRenderer() */
/** JsonRenderer handle created by the deprecated ctx.createJsonRenderer() */
ui: JsonRenderer
}

Expand Down
10 changes: 5 additions & 5 deletions packages/hub/src/types/json-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// 0.7 moved json-render out of the hub into the opt-in `@devframes/json-render`
// integration — use its `DevframeJsonRenderSpec` (from `@devframes/json-render`)
// and `createJsonRenderView` (from `@devframes/json-render/node`) instead. These
// types are kept so existing imports keep compiling; they will be removed in a
// future major release.
// types are kept so existing imports keep compiling through the 0.7 series;
// they are removed in 0.8.

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

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

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