@json-render/svelte 0.17.0 → 0.18.0

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.
@@ -5,8 +5,11 @@
5
5
  resolveBindings,
6
6
  resolveActionParam,
7
7
  evaluateVisibility,
8
+ isDevtoolsActive,
9
+ subscribeDevtoolsActive,
8
10
  type PropResolutionContext,
9
11
  } from "@json-render/core";
12
+ import { onDestroy } from "svelte";
10
13
  import type { ComponentRegistry, ComponentRenderer } from "./renderer.js";
11
14
  import type { EventHandle } from "./catalog-types.js";
12
15
  import { getStateContext } from "./contexts/StateProvider.svelte";
@@ -18,13 +21,29 @@
18
21
 
19
22
  interface Props {
20
23
  element: UIElement;
24
+ /** Spec key for this element. Used by the devtools picker. */
25
+ elementKey?: string;
21
26
  spec: Spec;
22
27
  registry: ComponentRegistry;
23
28
  loading?: boolean;
24
29
  fallback?: ComponentRenderer;
25
30
  }
26
31
 
27
- let { element, spec, registry, loading = false, fallback }: Props = $props();
32
+ let {
33
+ element,
34
+ elementKey,
35
+ spec,
36
+ registry,
37
+ loading = false,
38
+ fallback,
39
+ }: Props = $props();
40
+
41
+ // Reactive mirror of the devtools-active flag (for picker support).
42
+ let devtoolsActive = $state(isDevtoolsActive());
43
+ const unsubDevtools = subscribeDevtoolsActive(() => {
44
+ devtoolsActive = isDevtoolsActive();
45
+ });
46
+ onDestroy(unsubDevtools);
28
47
 
29
48
  const stateCtx = getStateContext();
30
49
  const actionCtx = getActionContext();
@@ -110,36 +129,73 @@
110
129
  error,
111
130
  );
112
131
  }}>
113
- <Component
114
- element={resolvedElement}
115
- bindings={elementBindings}
116
- {loading}
117
- {on}
118
- {emit}>
119
- {#if resolvedElement.repeat}
120
- <RepeatChildren
132
+ {#if devtoolsActive && elementKey}
133
+ <span data-jr-key={elementKey} style="display:contents">
134
+ <Component
121
135
  element={resolvedElement}
122
- {spec}
123
- {registry}
136
+ bindings={elementBindings}
124
137
  {loading}
125
- {fallback} />
126
- {:else if resolvedElement.children}
127
- {#each resolvedElement.children as childKey (childKey)}
128
- {#if spec.elements[childKey]}
129
- <Self
130
- element={spec.elements[childKey]}
138
+ {on}
139
+ {emit}>
140
+ {#if resolvedElement.repeat}
141
+ <RepeatChildren
142
+ element={resolvedElement}
131
143
  {spec}
132
144
  {registry}
133
145
  {loading}
134
146
  {fallback} />
135
- {:else if !loading}
136
- {console.warn(
137
- `[json-render] Missing element "${childKey}" referenced as child of "${resolvedElement.type}". This element will not render.`,
138
- )}
147
+ {:else if resolvedElement.children}
148
+ {#each resolvedElement.children as childKey (childKey)}
149
+ {#if spec.elements[childKey]}
150
+ <Self
151
+ element={spec.elements[childKey]}
152
+ elementKey={childKey}
153
+ {spec}
154
+ {registry}
155
+ {loading}
156
+ {fallback} />
157
+ {:else if !loading}
158
+ {console.warn(
159
+ `[json-render] Missing element "${childKey}" referenced as child of "${resolvedElement.type}". This element will not render.`,
160
+ )}
161
+ {/if}
162
+ {/each}
139
163
  {/if}
140
- {/each}
141
- {/if}
142
- </Component>
164
+ </Component>
165
+ </span>
166
+ {:else}
167
+ <Component
168
+ element={resolvedElement}
169
+ bindings={elementBindings}
170
+ {loading}
171
+ {on}
172
+ {emit}>
173
+ {#if resolvedElement.repeat}
174
+ <RepeatChildren
175
+ element={resolvedElement}
176
+ {spec}
177
+ {registry}
178
+ {loading}
179
+ {fallback} />
180
+ {:else if resolvedElement.children}
181
+ {#each resolvedElement.children as childKey (childKey)}
182
+ {#if spec.elements[childKey]}
183
+ <Self
184
+ element={spec.elements[childKey]}
185
+ elementKey={childKey}
186
+ {spec}
187
+ {registry}
188
+ {loading}
189
+ {fallback} />
190
+ {:else if !loading}
191
+ {console.warn(
192
+ `[json-render] Missing element "${childKey}" referenced as child of "${resolvedElement.type}". This element will not render.`,
193
+ )}
194
+ {/if}
195
+ {/each}
196
+ {/if}
197
+ </Component>
198
+ {/if}
143
199
  {#snippet failed()}
144
200
  <!-- render nothing -->
145
201
  {/snippet}
@@ -2,6 +2,8 @@ import type { Spec, UIElement } from "@json-render/core";
2
2
  import type { ComponentRegistry, ComponentRenderer } from "./renderer.js";
3
3
  interface Props {
4
4
  element: UIElement;
5
+ /** Spec key for this element. Used by the devtools picker. */
6
+ elementKey?: string;
5
7
  spec: Spec;
6
8
  registry: ComponentRegistry;
7
9
  loading?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"ElementRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ElementRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAQzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAUxE,UAAU,KAAK;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAyHH,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ElementRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ElementRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAWzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAUxE,UAAU,KAAK;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AA4JH,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -27,6 +27,7 @@
27
27
  {#if spec && rootElement}
28
28
  <ElementRenderer
29
29
  element={rootElement}
30
+ elementKey={spec.root}
30
31
  {spec}
31
32
  {registry}
32
33
  {loading}
@@ -35,6 +35,7 @@
35
35
  {#if spec.elements[childKey]}
36
36
  <ElementRenderer
37
37
  element={spec.elements[childKey]}
38
+ elementKey={childKey}
38
39
  {spec}
39
40
  {registry}
40
41
  {loading}
@@ -140,6 +140,9 @@
140
140
  import {
141
141
  resolveAction,
142
142
  executeAction,
143
+ nextActionDispatchId,
144
+ notifyActionDispatch,
145
+ notifyActionSettle,
143
146
  type ActionBinding as CoreActionBinding,
144
147
  type ActionHandler as CoreActionHandler,
145
148
  } from "@json-render/core";
@@ -165,6 +168,19 @@
165
168
  const execute = async (binding: CoreActionBinding): Promise<void> => {
166
169
  const resolved = resolveAction(binding, stateCtx.getSnapshot());
167
170
 
171
+ // --- devtools / observer hooks ---
172
+ const dispatchId = nextActionDispatchId();
173
+ const dispatchedAt = Date.now();
174
+ notifyActionDispatch({
175
+ id: dispatchId,
176
+ name: resolved.action,
177
+ params: resolved.params,
178
+ at: dispatchedAt,
179
+ });
180
+ let __ok = true;
181
+ let __error: unknown = undefined;
182
+
183
+ try {
168
184
  if (resolved.action === "setState" && resolved.params) {
169
185
  const statePath = resolved.params.statePath as string;
170
186
  const value = resolved.params.value;
@@ -314,6 +330,21 @@
314
330
  } finally {
315
331
  loadingActions.delete(resolved.action);
316
332
  }
333
+ } catch (err) {
334
+ __ok = false;
335
+ __error = err;
336
+ throw err;
337
+ } finally {
338
+ const now = Date.now();
339
+ notifyActionSettle({
340
+ id: dispatchId,
341
+ name: resolved.action,
342
+ ok: __ok,
343
+ at: now,
344
+ durationMs: now - dispatchedAt,
345
+ error: __error,
346
+ });
347
+ }
317
348
  };
318
349
 
319
350
  const ctx: ActionContext = {
@@ -1 +1 @@
1
- {"version":3,"file":"ActionProvider.svelte.d.ts","sourceRoot":"","sources":["../../src/contexts/ActionProvider.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,qCAAqC;IACrC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,kCAAkC;IAClC,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,gCAAgC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iCAAiC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,aAAa,GAAG,SAAS,CAAC,CAOzC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuDH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAIH,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,mBAAmB,CAAC;AAM3B,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2MH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"ActionProvider.svelte.d.ts","sourceRoot":"","sources":["../../src/contexts/ActionProvider.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,qCAAqC;IACrC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,kCAAkC;IAClC,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,gCAAgC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iCAAiC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,aAAa,GAAG,SAAS,CAAC,CAOzC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuDH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAOH,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,mBAAmB,CAAC;AAM3B,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuOH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-render/svelte",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Svelte 5 renderer for @json-render/core. JSON becomes Svelte components.",
6
6
  "keywords": [
@@ -49,7 +49,7 @@
49
49
  "dist"
50
50
  ],
51
51
  "dependencies": {
52
- "@json-render/core": "0.17.0"
52
+ "@json-render/core": "0.18.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@sveltejs/package": "^2.3.0",