Skip to content

Commit 340c942

Browse files
committed
fix(json-render): declare renderer peer and document view ownership
1 parent fdc268c commit 340c942

11 files changed

Lines changed: 87 additions & 28 deletions

File tree

‎docs/content/1.guide/8.json-render.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ and the [`json-render` example](https://github.com/devframes/devframe/tree/main/
170170

171171
## Rendering with a custom RPC channel
172172

173-
A host page can import the reference browser bundle directly. It includes its renderer and styles:
173+
A host page can import the reference browser bundle directly. It includes its renderer and styles. TypeScript consumers also install the `@devframes/json-render`, `@devframes/hub` and `devframe` peers for the renderer declarations:
174174

175175
```ts
176176
import renderer from '@devframes/json-render-ui/renderer'
@@ -187,4 +187,14 @@ mounted.dispose?.()
187187

188188
`call` and `sharedState` are native RPC members. An optional `connectionMeta.backend` marks static output. The reference implementation accepts this smaller `JsonRenderRpcContext`; a full hub client context also satisfies it. Custom `JsonRenderDockRenderer` implementations retain the full client context by default and can declare their own context type through its generic parameter.
189189

190-
For view publication in a worker, import `createJsonRenderView` from `@devframes/json-render/view` and pass `{ rpc: { sharedState } }`. Its native publishing state must support `get(key, { sharedState })`. The node-side import and scoped node contexts continue to use the same implementation.
190+
For view publication in a worker, import `createJsonRenderView` from `@devframes/json-render/view`. Its native publishing state must support `get(key, { sharedState })`. Reuse one context object for all views on that state instance. View discovery and duplicate detection belong to this context:
191+
192+
```ts
193+
import { createJsonRenderView } from '@devframes/json-render/view'
194+
195+
const context = { rpc: { sharedState } }
196+
const metrics = createJsonRenderView(context, { id: 'metrics', spec: metricsSpec })
197+
const details = createJsonRenderView(context, { id: 'details', spec: detailsSpec })
198+
```
199+
200+
The node-side import and scoped node contexts use the same implementation.

‎packages/json-render-ui/package.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@
4343
},
4444
"peerDependencies": {
4545
"@devframes/hub": "workspace:*",
46+
"@devframes/json-render": "workspace:*",
4647
"devframe": "workspace:*"
4748
},
4849
"peerDependenciesMeta": {
4950
"@devframes/hub": {
5051
"optional": true
5152
},
53+
"@devframes/json-render": {
54+
"optional": true
55+
},
5256
"devframe": {
5357
"optional": true
5458
}

‎packages/json-render/src/view.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export interface CreateJsonRenderViewOptions<SpecType extends DevframeJsonRender
3434
title?: string
3535
}
3636

37-
/** Native shared-state publication required by a JSON view. */
37+
/** Reuse one context per native shared-state instance for view discovery and duplicate detection. */
3838
export interface JsonRenderViewContext {
3939
rpc: { sharedState: RpcSharedStateHost }
4040
}

‎packages/json-render/test/create-view.test.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,20 @@ describe('createJsonRenderView identity', () => {
5959

6060
describe('createJsonRenderView state', () => {
6161
it('publishes and disposes through a shared-state-only context', async () => {
62-
expect.assertions(3)
62+
expect.assertions(5)
6363
const context = { rpc: { sharedState: ctx.rpc.sharedState } }
6464
const view = createPortableView(context, { id: 'portable', spec })
6565
const state = await context.rpc.sharedState.get(view.ref.stateKey)
6666
expect(state.value()).toEqual(spec)
67+
const secondView = createPortableView(context, { id: 'second', spec })
68+
const index = await context.rpc.sharedState.get(JSON_RENDER_INDEX_KEY)
69+
expect(Object.keys(index.value())).toEqual([view.ref.stateKey, secondView.ref.stateKey])
70+
expect(() => createPortableView(context, { id: 'portable', spec })).toThrow()
6771
view.patchState([{ op: 'replace', path: '/count', value: 2 }])
6872
expect(state.value().state).toEqual({ count: 2 })
6973
view.dispose()
7074
expect(context.rpc.sharedState.keys()).not.toContain(view.ref.stateKey)
75+
secondView.dispose()
7176
})
7277

7378
it('registers a shared state carrying the spec', async () => {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Generated by tsnapi — public API snapshot of `@devframes/json-render-ui/renderer`
3+
*/
4+
// #region Default Export
5+
declare const _default: JsonRenderDockRenderer<JsonRenderRpcContext>;
6+
export default _default
7+
// #endregion
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Generated by tsnapi — public API snapshot of `@devframes/json-render-ui/renderer`
3+
*/
4+
// #region Default Export
5+
var _default
6+
export default _default
7+
// #endregion

‎tests/__snapshots__/tsnapi/@devframes/json-render/hub.snapshot.d.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ export interface DevframeJsonRenderDockEntry extends DevframeDockEntryBase {
66
type: 'json-render';
77
view: JsonRenderViewRef;
88
}
9+
export interface JsonRenderRpcContext {
10+
rpc: Pick<DevframeRpcClient, 'call' | 'sharedState'> & {
11+
connectionMeta?: Pick<ConnectionMeta, 'backend'>;
12+
};
13+
}
914
// #endregion
1015

1116
// #region Types
12-
export type JsonRenderDockMountOptions = DockRendererMountOptions<DevframeJsonRenderDockEntry>;
13-
export type JsonRenderDockRenderer = DockRenderer<DevframeJsonRenderDockEntry>;
17+
export type JsonRenderDockMountOptions<Context = DevframeClientContext> = Omit<DockRendererMountOptions<DevframeJsonRenderDockEntry>, 'context'> & {
18+
context: Context;
19+
};
20+
export type JsonRenderDockRenderer<Context = DevframeClientContext> = (_: JsonRenderDockMountOptions<Context>) => DockRendererInstance | Promise<DockRendererInstance>;
1421
// #endregion
1522

1623
// #region Functions
Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
11
/**
22
* Generated by tsnapi — public API snapshot of `@devframes/json-render/node`
33
*/
4-
// #region Interfaces
5-
export interface CreateJsonRenderViewOptions<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> {
6-
id: string;
7-
spec: SpecType;
8-
schema?: StandardSchemaV1 | false;
9-
scope?: string;
10-
title?: string;
11-
}
12-
// #endregion
13-
14-
// #region Functions
15-
export declare function createJsonRenderView<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec>(_: AnyContext, _: CreateJsonRenderViewOptions<SpecType>): JsonRenderView<SpecType>;
16-
// #endregion
17-
184
// #region Variables
195
export declare const jsonRenderDiagnostics: DevframeDiagnostics<typeof codes>;
206
// #endregion
217

22-
// #region Referenced (internal)
23-
type AnyContext = DevframeNodeContext | DevframeScopedNodeContext<string>;
8+
// #region Other
9+
export { createJsonRenderView }
10+
export { CreateJsonRenderViewOptions }
2411
// #endregion
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
/**
22
* Generated by tsnapi — public API snapshot of `@devframes/json-render/node`
33
*/
4-
// #region Functions
5-
export function createJsonRenderView(_, _) {}
6-
// #endregion
7-
8-
// #region Variables
9-
export var jsonRenderDiagnostics /* const */
4+
// #region Other
5+
export { createJsonRenderView }
6+
export { diagnostics as jsonRenderDiagnostics }
107
// #endregion
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Generated by tsnapi — public API snapshot of `@devframes/json-render/view`
3+
*/
4+
// #region Interfaces
5+
export interface CreateJsonRenderViewOptions<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> {
6+
id: string;
7+
spec: SpecType;
8+
schema?: StandardSchemaV1 | false;
9+
scope?: string;
10+
title?: string;
11+
}
12+
export interface JsonRenderScopedViewContext {
13+
base: JsonRenderViewContext;
14+
namespace: string;
15+
}
16+
export interface JsonRenderViewContext {
17+
rpc: {
18+
sharedState: RpcSharedStateHost;
19+
};
20+
}
21+
// #endregion
22+
23+
// #region Functions
24+
export declare function createJsonRenderView<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec>(_: AnyContext, _: CreateJsonRenderViewOptions<SpecType>): JsonRenderView<SpecType>;
25+
// #endregion
26+
27+
// #region Referenced (internal)
28+
type AnyContext = JsonRenderViewContext | JsonRenderScopedViewContext;
29+
// #endregion

0 commit comments

Comments
 (0)