@json-render/react-native 0.8.0 → 0.9.1

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/README.md CHANGED
@@ -214,6 +214,26 @@ const systemPrompt = catalog.prompt({
214
214
  });
215
215
  ```
216
216
 
217
+ ## External Store (Controlled Mode)
218
+
219
+ For full control over state, pass a `StateStore` to bypass the internal state and wire json-render to any state management library (Redux, Zustand, XState, etc.):
220
+
221
+ ```tsx
222
+ import { createStateStore, type StateStore } from "@json-render/react-native";
223
+
224
+ // Use the built-in store outside of React
225
+ const store = createStateStore({ count: 0 });
226
+
227
+ <StateProvider store={store}>
228
+ {children}
229
+ </StateProvider>
230
+
231
+ // Mutate from anywhere — React will re-render automatically:
232
+ store.set("/count", 1);
233
+ ```
234
+
235
+ When `store` is provided, `initialState` and `onStateChange` are ignored. The store is the single source of truth. The same `store` prop is available on `createRenderer`, `JSONUIProvider`, and `StateProvider`.
236
+
217
237
  ## Hooks
218
238
 
219
239
  | Hook | Purpose |
@@ -227,3 +247,4 @@ const systemPrompt = catalog.prompt({
227
247
  | `useAction(name)` | Get a single action dispatch function |
228
248
  | `useUIStream(options)` | Stream specs from an API endpoint |
229
249
  | `createStandardActionHandlers(options)` | Create handlers for standard actions |
250
+ | `createStateStore(initialState)` | Create a framework-agnostic in-memory `StateStore` |
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
- export { Spec, StateModel } from '@json-render/core';
3
+ import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
+ export { Spec, StateModel, StateStore, createStateStore } from '@json-render/core';
5
5
  export { ElementTreeSchema, ElementTreeSpec, ReactNativeSchema, ReactNativeSpec, elementTreeSchema, schema } from './schema.mjs';
6
6
  export { ActionDefinition, ComponentDefinition, standardActionDefinitions, standardComponentDefinitions } from './catalog.mjs';
7
7
  import 'zod';
@@ -18,21 +18,40 @@ interface StateContextValue {
18
18
  set: (path: string, value: unknown) => void;
19
19
  /** Update multiple values at once */
20
20
  update: (updates: Record<string, unknown>) => void;
21
+ /** Return the live state snapshot from the underlying store (not the React render snapshot). */
22
+ getSnapshot: () => StateModel;
21
23
  }
22
24
  /**
23
25
  * Props for StateProvider
24
26
  */
25
27
  interface StateProviderProps {
26
- /** Initial state model */
28
+ /**
29
+ * External store that owns the state. When provided, the provider operates
30
+ * in **controlled mode** — `initialState` and `onStateChange` are ignored
31
+ * and the store is the single source of truth.
32
+ */
33
+ store?: StateStore;
34
+ /** Initial state model (used only in uncontrolled mode) */
27
35
  initialState?: StateModel;
28
- /** Callback when state changes */
29
- onStateChange?: (path: string, value: unknown) => void;
36
+ /**
37
+ * Callback when state changes (used only in uncontrolled mode).
38
+ * Called once per `set` or `update` with all changed entries.
39
+ */
40
+ onStateChange?: (changes: Array<{
41
+ path: string;
42
+ value: unknown;
43
+ }>) => void;
30
44
  children: ReactNode;
31
45
  }
32
46
  /**
33
- * Provider for state model context
47
+ * Provider for state model context.
48
+ *
49
+ * Supports two modes:
50
+ * - **Controlled**: pass a `store` prop (e.g. backed by Redux / Zustand).
51
+ * - **Uncontrolled** (default): omit `store` and optionally pass
52
+ * `initialState` / `onStateChange`.
34
53
  */
35
- declare function StateProvider({ initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
54
+ declare function StateProvider({ store: externalStore, initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
36
55
  /**
37
56
  * Hook to access the state context
38
57
  */
@@ -391,7 +410,12 @@ interface JSONUIProviderProps {
391
410
  * Custom components are merged with (and override) standard components.
392
411
  */
393
412
  registry?: ComponentRegistry;
394
- /** Initial state model */
413
+ /**
414
+ * External store (controlled mode). When provided, `initialState` and
415
+ * `onStateChange` are ignored.
416
+ */
417
+ store?: StateStore;
418
+ /** Initial state model (uncontrolled mode) */
395
419
  initialState?: Record<string, unknown>;
396
420
  /** Action handlers */
397
421
  handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
@@ -399,14 +423,17 @@ interface JSONUIProviderProps {
399
423
  navigate?: (path: string) => void;
400
424
  /** Custom validation functions */
401
425
  validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
402
- /** Callback when state changes */
403
- onStateChange?: (path: string, value: unknown) => void;
426
+ /** Callback when state changes (uncontrolled mode) */
427
+ onStateChange?: (changes: Array<{
428
+ path: string;
429
+ value: unknown;
430
+ }>) => void;
404
431
  children: ReactNode;
405
432
  }
406
433
  /**
407
434
  * Combined provider for all JSONUI contexts
408
435
  */
409
- declare function JSONUIProvider({ registry, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
436
+ declare function JSONUIProvider({ registry, store, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
410
437
  /**
411
438
  * Result returned by defineRegistry
412
439
  */
@@ -463,12 +490,20 @@ declare function defineRegistry<C extends Catalog>(_catalog: C, options: {
463
490
  interface CreateRendererProps {
464
491
  /** The spec to render (AI-generated JSON) */
465
492
  spec: Spec | null;
466
- /** State context for dynamic values */
493
+ /**
494
+ * External store (controlled mode). When provided, `state` and
495
+ * `onStateChange` are ignored.
496
+ */
497
+ store?: StateStore;
498
+ /** State context for dynamic values (uncontrolled mode) */
467
499
  state?: Record<string, unknown>;
468
500
  /** Action handler */
469
501
  onAction?: (actionName: string, params?: Record<string, unknown>) => void;
470
- /** Callback when state changes (e.g., from form inputs) */
471
- onStateChange?: (path: string, value: unknown) => void;
502
+ /** Callback when state changes (uncontrolled mode) */
503
+ onStateChange?: (changes: Array<{
504
+ path: string;
505
+ value: unknown;
506
+ }>) => void;
472
507
  /** Whether the spec is currently loading/streaming */
473
508
  loading?: boolean;
474
509
  /** Fallback component for unknown types */
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, ComponentType } from 'react';
3
- import { StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
- export { Spec, StateModel } from '@json-render/core';
3
+ import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, FlatElement } from '@json-render/core';
4
+ export { Spec, StateModel, StateStore, createStateStore } from '@json-render/core';
5
5
  export { ElementTreeSchema, ElementTreeSpec, ReactNativeSchema, ReactNativeSpec, elementTreeSchema, schema } from './schema.js';
6
6
  export { ActionDefinition, ComponentDefinition, standardActionDefinitions, standardComponentDefinitions } from './catalog.js';
7
7
  import 'zod';
@@ -18,21 +18,40 @@ interface StateContextValue {
18
18
  set: (path: string, value: unknown) => void;
19
19
  /** Update multiple values at once */
20
20
  update: (updates: Record<string, unknown>) => void;
21
+ /** Return the live state snapshot from the underlying store (not the React render snapshot). */
22
+ getSnapshot: () => StateModel;
21
23
  }
22
24
  /**
23
25
  * Props for StateProvider
24
26
  */
25
27
  interface StateProviderProps {
26
- /** Initial state model */
28
+ /**
29
+ * External store that owns the state. When provided, the provider operates
30
+ * in **controlled mode** — `initialState` and `onStateChange` are ignored
31
+ * and the store is the single source of truth.
32
+ */
33
+ store?: StateStore;
34
+ /** Initial state model (used only in uncontrolled mode) */
27
35
  initialState?: StateModel;
28
- /** Callback when state changes */
29
- onStateChange?: (path: string, value: unknown) => void;
36
+ /**
37
+ * Callback when state changes (used only in uncontrolled mode).
38
+ * Called once per `set` or `update` with all changed entries.
39
+ */
40
+ onStateChange?: (changes: Array<{
41
+ path: string;
42
+ value: unknown;
43
+ }>) => void;
30
44
  children: ReactNode;
31
45
  }
32
46
  /**
33
- * Provider for state model context
47
+ * Provider for state model context.
48
+ *
49
+ * Supports two modes:
50
+ * - **Controlled**: pass a `store` prop (e.g. backed by Redux / Zustand).
51
+ * - **Uncontrolled** (default): omit `store` and optionally pass
52
+ * `initialState` / `onStateChange`.
34
53
  */
35
- declare function StateProvider({ initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
54
+ declare function StateProvider({ store: externalStore, initialState, onStateChange, children, }: StateProviderProps): react_jsx_runtime.JSX.Element;
36
55
  /**
37
56
  * Hook to access the state context
38
57
  */
@@ -391,7 +410,12 @@ interface JSONUIProviderProps {
391
410
  * Custom components are merged with (and override) standard components.
392
411
  */
393
412
  registry?: ComponentRegistry;
394
- /** Initial state model */
413
+ /**
414
+ * External store (controlled mode). When provided, `initialState` and
415
+ * `onStateChange` are ignored.
416
+ */
417
+ store?: StateStore;
418
+ /** Initial state model (uncontrolled mode) */
395
419
  initialState?: Record<string, unknown>;
396
420
  /** Action handlers */
397
421
  handlers?: Record<string, (params: Record<string, unknown>) => Promise<unknown> | unknown>;
@@ -399,14 +423,17 @@ interface JSONUIProviderProps {
399
423
  navigate?: (path: string) => void;
400
424
  /** Custom validation functions */
401
425
  validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
402
- /** Callback when state changes */
403
- onStateChange?: (path: string, value: unknown) => void;
426
+ /** Callback when state changes (uncontrolled mode) */
427
+ onStateChange?: (changes: Array<{
428
+ path: string;
429
+ value: unknown;
430
+ }>) => void;
404
431
  children: ReactNode;
405
432
  }
406
433
  /**
407
434
  * Combined provider for all JSONUI contexts
408
435
  */
409
- declare function JSONUIProvider({ registry, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
436
+ declare function JSONUIProvider({ registry, store, initialState, handlers, navigate, validationFunctions, onStateChange, children, }: JSONUIProviderProps): react_jsx_runtime.JSX.Element;
410
437
  /**
411
438
  * Result returned by defineRegistry
412
439
  */
@@ -463,12 +490,20 @@ declare function defineRegistry<C extends Catalog>(_catalog: C, options: {
463
490
  interface CreateRendererProps {
464
491
  /** The spec to render (AI-generated JSON) */
465
492
  spec: Spec | null;
466
- /** State context for dynamic values */
493
+ /**
494
+ * External store (controlled mode). When provided, `state` and
495
+ * `onStateChange` are ignored.
496
+ */
497
+ store?: StateStore;
498
+ /** State context for dynamic values (uncontrolled mode) */
467
499
  state?: Record<string, unknown>;
468
500
  /** Action handler */
469
501
  onAction?: (actionName: string, params?: Record<string, unknown>) => void;
470
- /** Callback when state changes (e.g., from form inputs) */
471
- onStateChange?: (path: string, value: unknown) => void;
502
+ /** Callback when state changes (uncontrolled mode) */
503
+ onStateChange?: (changes: Array<{
504
+ path: string;
505
+ value: unknown;
506
+ }>) => void;
472
507
  /** Whether the spec is currently loading/streaming */
473
508
  loading?: boolean;
474
509
  /** Fallback component for unknown types */
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  VisibilityProvider: () => VisibilityProvider,
41
41
  createRenderer: () => createRenderer,
42
42
  createStandardActionHandlers: () => createStandardActionHandlers,
43
+ createStateStore: () => import_core8.createStateStore,
43
44
  defineRegistry: () => defineRegistry,
44
45
  elementTreeSchema: () => elementTreeSchema,
45
46
  flatToTree: () => flatToTree,
@@ -62,68 +63,104 @@ __export(index_exports, {
62
63
  });
63
64
  module.exports = __toCommonJS(index_exports);
64
65
 
65
- // src/contexts/state.tsx
66
+ // ../react-state/dist/index.mjs
66
67
  var import_react = require("react");
67
68
  var import_core = require("@json-render/core");
69
+ var import_store_utils = require("@json-render/core/store-utils");
68
70
  var import_jsx_runtime = require("react/jsx-runtime");
69
71
  var StateContext = (0, import_react.createContext)(null);
72
+ function computeInitialFlat(isControlled, initialState) {
73
+ if (isControlled) return null;
74
+ if (Object.keys(initialState).length === 0) return {};
75
+ return (0, import_store_utils.flattenToPointers)(initialState);
76
+ }
70
77
  function StateProvider({
78
+ store: externalStore,
71
79
  initialState = {},
72
80
  onStateChange,
73
81
  children
74
82
  }) {
75
- const [state, setStateInternal] = (0, import_react.useState)(initialState);
76
- const stateRef = (0, import_react.useRef)(state);
77
- stateRef.current = state;
78
- const initialStateJsonRef = (0, import_react.useRef)(JSON.stringify(initialState));
83
+ const internalStoreRef = (0, import_react.useRef)(void 0);
84
+ if (!externalStore && !internalStoreRef.current) {
85
+ internalStoreRef.current = (0, import_core.createStateStore)(initialState);
86
+ }
87
+ const store = externalStore ?? internalStoreRef.current;
88
+ const storeRef = (0, import_react.useRef)(store);
89
+ storeRef.current = store;
90
+ const isControlledRef = (0, import_react.useRef)(!!externalStore);
91
+ isControlledRef.current = !!externalStore;
92
+ const initialModeRef = (0, import_react.useRef)(externalStore ? "controlled" : "uncontrolled");
93
+ const modeWarnedRef = (0, import_react.useRef)(false);
94
+ if (process.env.NODE_ENV !== "production") {
95
+ const currentMode = externalStore ? "controlled" : "uncontrolled";
96
+ if (currentMode !== initialModeRef.current && !modeWarnedRef.current) {
97
+ modeWarnedRef.current = true;
98
+ console.warn(
99
+ `StateProvider: switching from ${initialModeRef.current} to ${currentMode} mode is not supported.`
100
+ );
101
+ }
102
+ }
103
+ const prevInitialStateRef = (0, import_react.useRef)(initialState);
104
+ const prevFlatRef = (0, import_react.useRef)(
105
+ computeInitialFlat(!!externalStore, initialState)
106
+ );
79
107
  (0, import_react.useEffect)(() => {
80
- const newJson = JSON.stringify(initialState);
81
- if (newJson !== initialStateJsonRef.current) {
82
- initialStateJsonRef.current = newJson;
83
- if (initialState && Object.keys(initialState).length > 0) {
84
- setStateInternal((prev) => ({ ...prev, ...initialState }));
108
+ if (externalStore) return;
109
+ if (initialState === prevInitialStateRef.current) return;
110
+ prevInitialStateRef.current = initialState;
111
+ const nextFlat = initialState && Object.keys(initialState).length > 0 ? (0, import_store_utils.flattenToPointers)(initialState) : {};
112
+ const prevFlat = prevFlatRef.current ?? {};
113
+ const allKeys = /* @__PURE__ */ new Set([
114
+ ...Object.keys(prevFlat),
115
+ ...Object.keys(nextFlat)
116
+ ]);
117
+ const updates = {};
118
+ for (const key of allKeys) {
119
+ if (prevFlat[key] !== nextFlat[key]) {
120
+ updates[key] = key in nextFlat ? nextFlat[key] : void 0;
85
121
  }
86
122
  }
87
- }, [initialState]);
88
- const get = (0, import_react.useCallback)(
89
- (path) => (0, import_core.getByPath)(stateRef.current, path),
90
- []
91
- );
92
- const set = (0, import_react.useCallback)(
93
- (path, value2) => {
94
- setStateInternal((prev) => {
95
- const next = { ...prev };
96
- (0, import_core.setByPath)(next, path, value2);
97
- return next;
98
- });
99
- onStateChange?.(path, value2);
100
- },
101
- [onStateChange]
123
+ prevFlatRef.current = nextFlat;
124
+ if (Object.keys(updates).length > 0) {
125
+ store.update(updates);
126
+ }
127
+ }, [externalStore, initialState, store]);
128
+ const state = (0, import_react.useSyncExternalStore)(
129
+ store.subscribe,
130
+ store.getSnapshot,
131
+ store.getServerSnapshot ?? store.getSnapshot
102
132
  );
103
- const update = (0, import_react.useCallback)(
104
- (updates) => {
105
- const entries = Object.entries(updates);
106
- setStateInternal((prev) => {
107
- const next = { ...prev };
108
- for (const [path, value2] of entries) {
109
- (0, import_core.setByPath)(next, path, value2);
133
+ const onStateChangeRef = (0, import_react.useRef)(onStateChange);
134
+ onStateChangeRef.current = onStateChange;
135
+ const set = (0, import_react.useCallback)((path, value2) => {
136
+ const s = storeRef.current;
137
+ const prev = s.getSnapshot();
138
+ s.set(path, value2);
139
+ if (!isControlledRef.current && s.getSnapshot() !== prev) {
140
+ onStateChangeRef.current?.([{ path, value: value2 }]);
141
+ }
142
+ }, []);
143
+ const update = (0, import_react.useCallback)((updates) => {
144
+ const s = storeRef.current;
145
+ const prev = s.getSnapshot();
146
+ s.update(updates);
147
+ if (!isControlledRef.current && s.getSnapshot() !== prev) {
148
+ const changes = [];
149
+ for (const [path, value2] of Object.entries(updates)) {
150
+ if ((0, import_core.getByPath)(prev, path) !== value2) {
151
+ changes.push({ path, value: value2 });
110
152
  }
111
- return next;
112
- });
113
- for (const [path, value2] of entries) {
114
- onStateChange?.(path, value2);
115
153
  }
116
- },
117
- [onStateChange]
118
- );
154
+ if (changes.length > 0) {
155
+ onStateChangeRef.current?.(changes);
156
+ }
157
+ }
158
+ }, []);
159
+ const get = (0, import_react.useCallback)((path) => storeRef.current.get(path), []);
160
+ const getSnapshot = (0, import_react.useCallback)(() => storeRef.current.getSnapshot(), []);
119
161
  const value = (0, import_react.useMemo)(
120
- () => ({
121
- state,
122
- get,
123
- set,
124
- update
125
- }),
126
- [state, get, set, update]
162
+ () => ({ state, get, set, update, getSnapshot }),
163
+ [state, get, set, update, getSnapshot]
127
164
  );
128
165
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateContext.Provider, { value, children });
129
166
  }
@@ -226,7 +263,7 @@ function ActionProvider({
226
263
  navigate,
227
264
  children
228
265
  }) {
229
- const { state, get, set } = useStateStore();
266
+ const { get, set, getSnapshot } = useStateStore();
230
267
  const [handlers, setHandlers] = (0, import_react3.useState)(initialHandlers);
231
268
  const [loadingActions, setLoadingActions] = (0, import_react3.useState)(/* @__PURE__ */ new Set());
232
269
  const [pendingConfirmation, setPendingConfirmation] = (0, import_react3.useState)(null);
@@ -238,7 +275,7 @@ function ActionProvider({
238
275
  );
239
276
  const execute = (0, import_react3.useCallback)(
240
277
  async (binding) => {
241
- const resolved = (0, import_core3.resolveAction)(binding, state);
278
+ const resolved = (0, import_core3.resolveAction)(binding, getSnapshot());
242
279
  if (resolved.action === "setState" && resolved.params) {
243
280
  const statePath = resolved.params.statePath;
244
281
  const value2 = resolved.params.value;
@@ -361,7 +398,7 @@ function ActionProvider({
361
398
  });
362
399
  }
363
400
  },
364
- [state, handlers, get, set, navigate]
401
+ [handlers, get, set, getSnapshot, navigate]
365
402
  );
366
403
  const confirm = (0, import_react3.useCallback)(() => {
367
404
  pendingConfirmation?.resolve();
@@ -762,6 +799,9 @@ var schema = (0, import_core5.defineSchema)(
762
799
  );
763
800
  var elementTreeSchema = schema;
764
801
 
802
+ // src/index.ts
803
+ var import_core8 = require("@json-render/core");
804
+
765
805
  // src/renderer.tsx
766
806
  var import_react7 = __toESM(require("react"));
767
807
  var import_core7 = require("@json-render/core");
@@ -1994,6 +2034,7 @@ var ElementRenderer = import_react7.default.memo(function ElementRenderer2({
1994
2034
  const repeatScope = useRepeatScope();
1995
2035
  const { ctx } = useVisibility();
1996
2036
  const { execute } = useActions();
2037
+ const { getSnapshot } = useStateStore();
1997
2038
  const fullCtx = (0, import_react7.useMemo)(
1998
2039
  () => repeatScope ? {
1999
2040
  ...ctx,
@@ -2006,23 +2047,27 @@ var ElementRenderer = import_react7.default.memo(function ElementRenderer2({
2006
2047
  const isVisible = element.visible === void 0 ? true : (0, import_core7.evaluateVisibility)(element.visible, fullCtx);
2007
2048
  const onBindings = element.on;
2008
2049
  const emit = (0, import_react7.useCallback)(
2009
- (eventName) => {
2050
+ async (eventName) => {
2010
2051
  const binding = onBindings?.[eventName];
2011
2052
  if (!binding) return;
2012
2053
  const actionBindings = Array.isArray(binding) ? binding : [binding];
2013
2054
  for (const b of actionBindings) {
2014
2055
  if (!b.params) {
2015
- execute(b);
2056
+ await execute(b);
2016
2057
  continue;
2017
2058
  }
2059
+ const liveCtx = {
2060
+ ...fullCtx,
2061
+ stateModel: getSnapshot()
2062
+ };
2018
2063
  const resolved = {};
2019
2064
  for (const [key, val] of Object.entries(b.params)) {
2020
- resolved[key] = (0, import_core7.resolveActionParam)(val, fullCtx);
2065
+ resolved[key] = (0, import_core7.resolveActionParam)(val, liveCtx);
2021
2066
  }
2022
- execute({ ...b, params: resolved });
2067
+ await execute({ ...b, params: resolved });
2023
2068
  }
2024
2069
  },
2025
- [onBindings, execute, fullCtx]
2070
+ [onBindings, execute, fullCtx, getSnapshot]
2026
2071
  );
2027
2072
  if (!isVisible) {
2028
2073
  return null;
@@ -2160,6 +2205,7 @@ function Renderer({
2160
2205
  }
2161
2206
  function JSONUIProvider({
2162
2207
  registry,
2208
+ store,
2163
2209
  initialState,
2164
2210
  handlers,
2165
2211
  navigate,
@@ -2167,10 +2213,18 @@ function JSONUIProvider({
2167
2213
  onStateChange,
2168
2214
  children
2169
2215
  }) {
2170
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StateProvider, { initialState, onStateChange, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VisibilityProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ActionProvider, { handlers, navigate, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ValidationProvider, { customFunctions: validationFunctions, children: [
2171
- children,
2172
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConfirmationDialogManager, {})
2173
- ] }) }) }) });
2216
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2217
+ StateProvider,
2218
+ {
2219
+ store,
2220
+ initialState,
2221
+ onStateChange,
2222
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VisibilityProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ActionProvider, { handlers, navigate, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ValidationProvider, { customFunctions: validationFunctions, children: [
2223
+ children,
2224
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConfirmationDialogManager, {})
2225
+ ] }) }) })
2226
+ }
2227
+ );
2174
2228
  }
2175
2229
  function ConfirmationDialogManager() {
2176
2230
  const { pendingConfirmation, confirm, cancel } = useActions();
@@ -2235,6 +2289,7 @@ function createRenderer(catalog, components) {
2235
2289
  const registry = components;
2236
2290
  return function CatalogRenderer({
2237
2291
  spec,
2292
+ store,
2238
2293
  state,
2239
2294
  onAction,
2240
2295
  onStateChange,
@@ -2250,18 +2305,26 @@ function createRenderer(catalog, components) {
2250
2305
  has: () => true
2251
2306
  }
2252
2307
  ) : void 0;
2253
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StateProvider, { initialState: state, onStateChange, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VisibilityProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ActionProvider, { handlers: actionHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ValidationProvider, { children: [
2254
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2255
- Renderer,
2256
- {
2257
- spec,
2258
- registry,
2259
- loading,
2260
- fallback
2261
- }
2262
- ),
2263
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConfirmationDialogManager, {})
2264
- ] }) }) }) });
2308
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2309
+ StateProvider,
2310
+ {
2311
+ store,
2312
+ initialState: state,
2313
+ onStateChange,
2314
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VisibilityProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ActionProvider, { handlers: actionHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ValidationProvider, { children: [
2315
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2316
+ Renderer,
2317
+ {
2318
+ spec,
2319
+ registry,
2320
+ loading,
2321
+ fallback
2322
+ }
2323
+ ),
2324
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ConfirmationDialogManager, {})
2325
+ ] }) }) })
2326
+ }
2327
+ );
2265
2328
  };
2266
2329
  }
2267
2330
 
@@ -2671,6 +2734,7 @@ var standardActionDefinitions = {
2671
2734
  VisibilityProvider,
2672
2735
  createRenderer,
2673
2736
  createStandardActionHandlers,
2737
+ createStateStore,
2674
2738
  defineRegistry,
2675
2739
  elementTreeSchema,
2676
2740
  flatToTree,