@devframes/json-render 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hub.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as JsonRenderViewRef, n as JsonRenderView } from "./types-CC2-FD2H.mjs";
1
+ import { a as JsonRenderViewRef, r as JsonRenderView } from "./types-P1hZJnNo.mjs";
2
2
  import { DockRenderer, DockRendererMountOptions } from "@devframes/hub/client";
3
3
  import { DevframeDockEntryBase } from "@devframes/hub/types";
4
4
  //#region src/hub.d.ts
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Catalog, InferComponentProps, Spec, StateModel, StateStore, UIElement } from "./core.mjs";
2
- import { a as JsonRenderViewStateRef, i as JsonRenderViewRef, n as JsonRenderView, r as JsonRenderViewInlineRef, t as DevframeJsonRenderSpec } from "./types-CC2-FD2H.mjs";
2
+ import { a as JsonRenderViewRef, i as JsonRenderViewInlineRef, n as DevframeJsonRenderSpec, o as JsonRenderViewStateRef, r as JsonRenderView, t as CatalogUIElement } from "./types-P1hZJnNo.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/prop-schemas.d.ts
5
5
  declare const StackPropsSchema: z.ZodObject<{
@@ -447,4 +447,4 @@ interface JsonRenderIndexEntry {
447
447
  /** The shape of the view-index shared state: entries keyed by `stateKey`. */
448
448
  type JsonRenderIndex = Record<string, JsonRenderIndexEntry>;
449
449
  //#endregion
450
- export { BadgePropsSchema, type BaseComponentName, ButtonPropsSchema, CardPropsSchema, type Catalog, CodeBlockPropsSchema, DataTablePropsSchema, type DevframeJsonRenderSpec, DividerPropsSchema, IconPropsSchema, type InferComponentProps, JSON_RENDER_INDEX_KEY, type JsonRenderIndex, type JsonRenderIndexEntry, type JsonRenderView, type JsonRenderViewInlineRef, type JsonRenderViewRef, type JsonRenderViewStateRef, KeyValueTablePropsSchema, LinkPropsSchema, ProgressPropsSchema, SelectPropsSchema, type Spec, StackPropsSchema, type StateModel, type StateStore, SwitchPropsSchema, TabsPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, type UIElement, baseCatalog, baseComponentNames, basePropSchemas, baseSchema };
450
+ export { BadgePropsSchema, type BaseComponentName, ButtonPropsSchema, CardPropsSchema, type Catalog, type CatalogUIElement, CodeBlockPropsSchema, DataTablePropsSchema, type DevframeJsonRenderSpec, DividerPropsSchema, IconPropsSchema, type InferComponentProps, JSON_RENDER_INDEX_KEY, type JsonRenderIndex, type JsonRenderIndexEntry, type JsonRenderView, type JsonRenderViewInlineRef, type JsonRenderViewRef, type JsonRenderViewStateRef, KeyValueTablePropsSchema, LinkPropsSchema, ProgressPropsSchema, SelectPropsSchema, type Spec, StackPropsSchema, type StateModel, type StateStore, SwitchPropsSchema, TabsPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, type UIElement, baseCatalog, baseComponentNames, basePropSchemas, baseSchema };
@@ -1,8 +1,9 @@
1
- import { n as JsonRenderView, t as DevframeJsonRenderSpec } from "../types-CC2-FD2H.mjs";
1
+ import { n as DevframeJsonRenderSpec, r as JsonRenderView } from "../types-P1hZJnNo.mjs";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
3
  import { DevframeNodeContext, DevframeScopedNodeContext } from "devframe";
3
4
  //#region src/node/create-view.d.ts
4
5
  /** Options for {@link createJsonRenderView}. */
5
- interface CreateJsonRenderViewOptions {
6
+ interface CreateJsonRenderViewOptions<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> {
6
7
  /**
7
8
  * Stable, author-supplied id, unique within the view's scope. Forms the
8
9
  * shared-state key `devframe:json-render:<scope>:<id>` and never changes
@@ -10,7 +11,9 @@ interface CreateJsonRenderViewOptions {
10
11
  */
11
12
  id: string;
12
13
  /** The initial spec. */
13
- spec: DevframeJsonRenderSpec;
14
+ spec: SpecType;
15
+ /** A replacement Standard Schema validator, or `false` to disable validation. */
16
+ schema?: StandardSchemaV1 | false;
14
17
  /**
15
18
  * Override the scope segment of the view's stable id. Defaults to the
16
19
  * context's namespace when created from a scoped context, otherwise
@@ -40,7 +43,7 @@ type AnyContext = DevframeNodeContext | DevframeScopedNodeContext<string>;
40
43
  * view.dispose()
41
44
  * ```
42
45
  */
43
- declare function createJsonRenderView(ctx: AnyContext, options: CreateJsonRenderViewOptions): JsonRenderView;
46
+ declare function createJsonRenderView<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec>(ctx: AnyContext, options: CreateJsonRenderViewOptions<SpecType>): JsonRenderView<SpecType>;
44
47
  //#endregion
45
48
  //#region ../../node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/diagnostic-wduO7saY.d.mts
46
49
  //#region src/utils.d.ts
@@ -300,6 +303,19 @@ declare const diagnostics: Diagnostics<{
300
303
  }) => string;
301
304
  readonly fix: "Specs and state travel as strict JSON — remove functions, symbols, class instances, Map/Set, or circular references.";
302
305
  };
306
+ readonly DF0073: {
307
+ readonly why: (p: {
308
+ id: string;
309
+ issues: string;
310
+ }) => string;
311
+ readonly fix: "Match the authored spec to the Standard Schema passed to `createJsonRenderView`.";
312
+ };
313
+ readonly DF0074: {
314
+ readonly why: (p: {
315
+ id: string;
316
+ }) => string;
317
+ readonly fix: "Use a synchronous Standard Schema so initial creation and updates remain synchronous.";
318
+ };
303
319
  }, readonly [(d: Diagnostic, { method }?: {
304
320
  method?: "log" | "warn" | "error";
305
321
  }) => void]>;
@@ -20,6 +20,14 @@ const diagnostics = defineDiagnostics({
20
20
  DF0041: {
21
21
  why: (p) => `JSON-render view "${p.id}" spec is not JSON-serializable: ${p.reason}`,
22
22
  fix: "Specs and state travel as strict JSON — remove functions, symbols, class instances, Map/Set, or circular references."
23
+ },
24
+ DF0073: {
25
+ why: (p) => `JSON-render view "${p.id}" does not match its configured schema: ${p.issues}`,
26
+ fix: "Match the authored spec to the Standard Schema passed to `createJsonRenderView`."
27
+ },
28
+ DF0074: {
29
+ why: (p) => `JSON-render view "${p.id}" uses an asynchronous Standard Schema.`,
30
+ fix: "Use a synchronous Standard Schema so initial creation and updates remain synchronous."
23
31
  }
24
32
  }
25
33
  });
@@ -77,6 +85,27 @@ function validateElementProps(id, spec) {
77
85
  }
78
86
  }
79
87
  }
88
+ function formatStandardSchemaIssues(issues) {
89
+ return issues.map((issue) => {
90
+ return `${issue.path?.map((segment) => typeof segment === "object" ? String(segment.key) : String(segment)).join(".") || "(root)"}: ${issue.message}`;
91
+ }).join("; ");
92
+ }
93
+ function isPromise(value) {
94
+ return typeof value.then === "function";
95
+ }
96
+ function validateSpec(id, spec, schema) {
97
+ if (schema === false) return;
98
+ if (!schema) {
99
+ validateElementProps(id, spec);
100
+ return;
101
+ }
102
+ const result = schema["~standard"].validate(spec);
103
+ if (isPromise(result)) throw diagnostics.DF0074({ id });
104
+ if (result.issues) throw diagnostics.DF0073({
105
+ id,
106
+ issues: formatStandardSchemaIssues(result.issues)
107
+ });
108
+ }
80
109
  function normalizeSpec(spec) {
81
110
  return spec.state ? spec : {
82
111
  ...spec,
@@ -111,7 +140,7 @@ function createJsonRenderView(ctx, options) {
111
140
  scope
112
141
  });
113
142
  const initial = normalizeSpec(options.spec);
114
- validateElementProps(id, initial);
143
+ validateSpec(id, initial, options.schema);
115
144
  assertJsonSerializable(id, initial);
116
145
  const state = createSharedState({
117
146
  initialValue: initial,
@@ -140,7 +169,7 @@ function createJsonRenderView(ctx, options) {
140
169
  update(spec) {
141
170
  assertLive();
142
171
  const next = normalizeSpec(spec);
143
- validateElementProps(id, next);
172
+ validateSpec(id, next, options.schema);
144
173
  assertJsonSerializable(id, next);
145
174
  state.mutate(() => next);
146
175
  },
@@ -1,4 +1,4 @@
1
- import { Spec } from "@json-render/core";
1
+ import { Catalog, InferCatalogComponents, InferComponentProps, Spec, UIElement } from "@json-render/core";
2
2
  //#region src/view-ref.d.ts
3
3
  /**
4
4
  * A view backed by **live shared state**: the client subscribes to `stateKey`
@@ -17,9 +17,9 @@ interface JsonRenderViewStateRef {
17
17
  * rendered as-is (static: local state and bindings still work, but there is no
18
18
  * server-driven live update stream).
19
19
  */
20
- interface JsonRenderViewInlineRef {
20
+ interface JsonRenderViewInlineRef<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> {
21
21
  /** The full spec, carried in the reference itself. */
22
- spec: DevframeJsonRenderSpec;
22
+ spec: SpecType;
23
23
  }
24
24
  /**
25
25
  * The serializable reference to a JSON-render view that crosses process /
@@ -28,7 +28,7 @@ interface JsonRenderViewInlineRef {
28
28
  * the client subscribes through, or an {@link JsonRenderViewInlineRef.spec
29
29
  * inline spec} rendered directly.
30
30
  */
31
- type JsonRenderViewRef = JsonRenderViewStateRef | JsonRenderViewInlineRef;
31
+ type JsonRenderViewRef<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> = JsonRenderViewStateRef | JsonRenderViewInlineRef<SpecType>;
32
32
  //#endregion
33
33
  //#region src/types.d.ts
34
34
  /**
@@ -36,7 +36,11 @@ type JsonRenderViewRef = JsonRenderViewStateRef | JsonRenderViewInlineRef;
36
36
  * `root` key, an `elements` map, and optional initial `state`. This alias is
37
37
  * the Devframes-facing name; it does not add or remove fields.
38
38
  */
39
- type DevframeJsonRenderSpec = Spec;
39
+ type DevframeJsonRenderSpec<Element extends UIElement = UIElement> = Omit<Spec, 'elements'> & {
40
+ elements: Record<string, Element>;
41
+ };
42
+ /** Derive a discriminated element union from every component in a catalog. */
43
+ type CatalogUIElement<CatalogType extends Catalog> = { [ComponentName in keyof InferCatalogComponents<CatalogType> & string]: UIElement<ComponentName, InferComponentProps<CatalogType, ComponentName>>; }[keyof InferCatalogComponents<CatalogType> & string];
40
44
  /**
41
45
  * A single JSON-Pointer patch to a view's `state` model. `path` is an
42
46
  * RFC 6901 JSON Pointer relative to the state root (e.g. `/count`,
@@ -55,7 +59,7 @@ interface JsonRenderStatePatch {
55
59
  * serializable {@link JsonRenderViewStateRef} that a hub dock (or any client
56
60
  * transport) uses to locate it.
57
61
  */
58
- interface JsonRenderView {
62
+ interface JsonRenderView<SpecType extends DevframeJsonRenderSpec = DevframeJsonRenderSpec> {
59
63
  /** Author-supplied stable id, unique within the view's scope. */
60
64
  readonly id: string;
61
65
  /** Human-facing label published in the view index (defaults to `id`). */
@@ -63,7 +67,7 @@ interface JsonRenderView {
63
67
  /** The serializable reference clients subscribe through. */
64
68
  readonly ref: JsonRenderViewStateRef;
65
69
  /** Replace the entire spec (a structural change replaces the whole spec). */
66
- update: (spec: DevframeJsonRenderSpec) => void;
70
+ update: (spec: SpecType) => void;
67
71
  /**
68
72
  * Apply JSON-Pointer patches to the view's `state`. Travels as a
69
73
  * shared-state patch (not a whole-spec snapshot), so only the changed
@@ -71,9 +75,9 @@ interface JsonRenderView {
71
75
  */
72
76
  patchState: (patches: JsonRenderStatePatch[]) => void;
73
77
  /** Read the current spec (immutable). */
74
- value: () => DevframeJsonRenderSpec;
78
+ value: () => SpecType;
75
79
  /** Unregister the shared state and its listeners. */
76
80
  dispose: () => void;
77
81
  }
78
82
  //#endregion
79
- export { JsonRenderViewStateRef as a, JsonRenderViewRef as i, JsonRenderView as n, JsonRenderViewInlineRef as r, DevframeJsonRenderSpec as t };
83
+ export { JsonRenderViewRef as a, JsonRenderViewInlineRef as i, DevframeJsonRenderSpec as n, JsonRenderViewStateRef as o, JsonRenderView as r, CatalogUIElement as t };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/json-render",
3
3
  "type": "module",
4
- "version": "0.9.3",
4
+ "version": "0.9.5",
5
5
  "description": "Protocol layer for describing devframe views as JSON that any renderer can display.",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -30,8 +30,8 @@
30
30
  "dist"
31
31
  ],
32
32
  "peerDependencies": {
33
- "@devframes/hub": "0.9.3",
34
- "devframe": "0.9.3"
33
+ "@devframes/hub": "0.9.5",
34
+ "devframe": "0.9.5"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@devframes/hub": {
@@ -40,13 +40,14 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@json-render/core": "^0.19.0",
43
+ "@standard-schema/spec": "^1.1.0",
43
44
  "zod": "^4.4.3"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@types/node": "^26.2.0",
47
48
  "tsdown": "^0.22.14",
48
- "@devframes/hub": "0.9.3",
49
- "devframe": "0.9.3"
49
+ "@devframes/hub": "0.9.5",
50
+ "devframe": "0.9.5"
50
51
  },
51
52
  "scripts": {
52
53
  "build": "tsdown",