@json-render/solid 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.
package/dist/index.js CHANGED
@@ -482,146 +482,172 @@ function ActionProvider(props) {
482
482
  };
483
483
  const execute = async (binding) => {
484
484
  const resolved = (0, import_core4.resolveAction)(binding, getSnapshot());
485
- if (resolved.action === "setState" && resolved.params) {
486
- const statePath = resolved.params.statePath;
487
- const value = resolved.params.value;
488
- if (statePath) {
489
- set(statePath, value);
490
- }
491
- return;
492
- }
493
- if (resolved.action === "pushState" && resolved.params) {
494
- const statePath = resolved.params.statePath;
495
- const rawValue = resolved.params.value;
496
- if (statePath) {
497
- const resolvedValue = deepResolveValue(rawValue, get);
498
- const arr = get(statePath) ?? [];
499
- set(statePath, [...arr, resolvedValue]);
500
- const clearStatePath = resolved.params.clearStatePath;
501
- if (clearStatePath) {
502
- set(clearStatePath, "");
485
+ const dispatchId = (0, import_core4.nextActionDispatchId)();
486
+ const dispatchedAt = Date.now();
487
+ (0, import_core4.notifyActionDispatch)({
488
+ id: dispatchId,
489
+ name: resolved.action,
490
+ params: resolved.params,
491
+ at: dispatchedAt
492
+ });
493
+ let __ok = true;
494
+ let __error = void 0;
495
+ try {
496
+ if (resolved.action === "setState" && resolved.params) {
497
+ const statePath = resolved.params.statePath;
498
+ const value = resolved.params.value;
499
+ if (statePath) {
500
+ set(statePath, value);
503
501
  }
502
+ return;
504
503
  }
505
- return;
506
- }
507
- if (resolved.action === "removeState" && resolved.params) {
508
- const statePath = resolved.params.statePath;
509
- const index = resolved.params.index;
510
- if (statePath !== void 0 && index !== void 0) {
511
- const arr = get(statePath) ?? [];
512
- set(statePath, arr.filter((_, i) => i !== index));
513
- }
514
- return;
515
- }
516
- if (resolved.action === "push" && resolved.params) {
517
- const screen = resolved.params.screen;
518
- if (screen) {
519
- const currentScreen = get("/currentScreen");
520
- const navStack = get("/navStack") ?? [];
521
- if (currentScreen) {
522
- set("/navStack", [...navStack, currentScreen]);
523
- } else {
524
- set("/navStack", [...navStack, ""]);
504
+ if (resolved.action === "pushState" && resolved.params) {
505
+ const statePath = resolved.params.statePath;
506
+ const rawValue = resolved.params.value;
507
+ if (statePath) {
508
+ const resolvedValue = deepResolveValue(rawValue, get);
509
+ const arr = get(statePath) ?? [];
510
+ set(statePath, [...arr, resolvedValue]);
511
+ const clearStatePath = resolved.params.clearStatePath;
512
+ if (clearStatePath) {
513
+ set(clearStatePath, "");
514
+ }
525
515
  }
526
- set("/currentScreen", screen);
516
+ return;
527
517
  }
528
- return;
529
- }
530
- if (resolved.action === "pop") {
531
- const navStack = get("/navStack") ?? [];
532
- if (navStack.length > 0) {
533
- const previousScreen = navStack[navStack.length - 1];
534
- set("/navStack", navStack.slice(0, -1));
535
- if (previousScreen) {
536
- set("/currentScreen", previousScreen);
537
- } else {
538
- set("/currentScreen", void 0);
518
+ if (resolved.action === "removeState" && resolved.params) {
519
+ const statePath = resolved.params.statePath;
520
+ const index = resolved.params.index;
521
+ if (statePath !== void 0 && index !== void 0) {
522
+ const arr = get(statePath) ?? [];
523
+ set(statePath, arr.filter((_, i) => i !== index));
539
524
  }
525
+ return;
540
526
  }
541
- return;
542
- }
543
- if (resolved.action === "validateForm") {
544
- const validateAll = validation?.validateAll;
545
- if (!validateAll) {
546
- console.warn("validateForm action was dispatched but no ValidationProvider is connected. Ensure ValidationProvider is rendered inside the provider tree.");
527
+ if (resolved.action === "push" && resolved.params) {
528
+ const screen = resolved.params.screen;
529
+ if (screen) {
530
+ const currentScreen = get("/currentScreen");
531
+ const navStack = get("/navStack") ?? [];
532
+ if (currentScreen) {
533
+ set("/navStack", [...navStack, currentScreen]);
534
+ } else {
535
+ set("/navStack", [...navStack, ""]);
536
+ }
537
+ set("/currentScreen", screen);
538
+ }
547
539
  return;
548
540
  }
549
- const valid = validateAll();
550
- const errors = {};
551
- for (const [path, fs] of Object.entries(validation.fieldStates)) {
552
- if (fs.result && !fs.result.valid) {
553
- errors[path] = fs.result.errors;
541
+ if (resolved.action === "pop") {
542
+ const navStack = get("/navStack") ?? [];
543
+ if (navStack.length > 0) {
544
+ const previousScreen = navStack[navStack.length - 1];
545
+ set("/navStack", navStack.slice(0, -1));
546
+ if (previousScreen) {
547
+ set("/currentScreen", previousScreen);
548
+ } else {
549
+ set("/currentScreen", void 0);
550
+ }
554
551
  }
552
+ return;
555
553
  }
556
- const statePath = resolved.params?.statePath || "/formValidation";
557
- set(statePath, {
558
- valid,
559
- errors
560
- });
561
- return;
562
- }
563
- const handler = handlers()[resolved.action];
564
- if (!handler) {
565
- console.warn(`No handler registered for action: ${resolved.action}`);
566
- return;
567
- }
568
- if (resolved.confirm) {
569
- return new Promise((resolve, reject) => {
570
- setPendingConfirmation({
571
- action: resolved,
572
- handler,
573
- resolve: () => {
574
- setPendingConfirmation(null);
575
- resolve();
576
- },
577
- reject: () => {
578
- setPendingConfirmation(null);
579
- reject(new Error("Action cancelled"));
554
+ if (resolved.action === "validateForm") {
555
+ const validateAll = validation?.validateAll;
556
+ if (!validateAll) {
557
+ console.warn("validateForm action was dispatched but no ValidationProvider is connected. Ensure ValidationProvider is rendered inside the provider tree.");
558
+ return;
559
+ }
560
+ const valid = validateAll();
561
+ const errors = {};
562
+ for (const [path, fs] of Object.entries(validation.fieldStates)) {
563
+ if (fs.result && !fs.result.valid) {
564
+ errors[path] = fs.result.errors;
580
565
  }
566
+ }
567
+ const statePath = resolved.params?.statePath || "/formValidation";
568
+ set(statePath, {
569
+ valid,
570
+ errors
581
571
  });
582
- }).then(async () => {
583
- setLoadingActions((prev) => new Set(prev).add(resolved.action));
584
- try {
585
- await (0, import_core4.executeAction)({
572
+ return;
573
+ }
574
+ const handler = handlers()[resolved.action];
575
+ if (!handler) {
576
+ console.warn(`No handler registered for action: ${resolved.action}`);
577
+ return;
578
+ }
579
+ if (resolved.confirm) {
580
+ return new Promise((resolve, reject) => {
581
+ setPendingConfirmation({
586
582
  action: resolved,
587
583
  handler,
588
- setState: set,
589
- navigate: props.navigate,
590
- executeAction: async (name) => {
591
- const subBinding = {
592
- action: name
593
- };
594
- await execute(subBinding);
584
+ resolve: () => {
585
+ setPendingConfirmation(null);
586
+ resolve();
587
+ },
588
+ reject: () => {
589
+ setPendingConfirmation(null);
590
+ reject(new Error("Action cancelled"));
595
591
  }
596
592
  });
597
- } finally {
598
- setLoadingActions((prev) => {
599
- const next = new Set(prev);
600
- next.delete(resolved.action);
601
- return next;
602
- });
603
- }
604
- });
605
- }
606
- setLoadingActions((prev) => new Set(prev).add(resolved.action));
607
- try {
608
- await (0, import_core4.executeAction)({
609
- action: resolved,
610
- handler,
611
- setState: set,
612
- navigate: props.navigate,
613
- executeAction: async (name) => {
614
- const subBinding = {
615
- action: name
616
- };
617
- await execute(subBinding);
618
- }
619
- });
593
+ }).then(async () => {
594
+ setLoadingActions((prev) => new Set(prev).add(resolved.action));
595
+ try {
596
+ await (0, import_core4.executeAction)({
597
+ action: resolved,
598
+ handler,
599
+ setState: set,
600
+ navigate: props.navigate,
601
+ executeAction: async (name) => {
602
+ const subBinding = {
603
+ action: name
604
+ };
605
+ await execute(subBinding);
606
+ }
607
+ });
608
+ } finally {
609
+ setLoadingActions((prev) => {
610
+ const next = new Set(prev);
611
+ next.delete(resolved.action);
612
+ return next;
613
+ });
614
+ }
615
+ });
616
+ }
617
+ setLoadingActions((prev) => new Set(prev).add(resolved.action));
618
+ try {
619
+ await (0, import_core4.executeAction)({
620
+ action: resolved,
621
+ handler,
622
+ setState: set,
623
+ navigate: props.navigate,
624
+ executeAction: async (name) => {
625
+ const subBinding = {
626
+ action: name
627
+ };
628
+ await execute(subBinding);
629
+ }
630
+ });
631
+ } finally {
632
+ setLoadingActions((prev) => {
633
+ const next = new Set(prev);
634
+ next.delete(resolved.action);
635
+ return next;
636
+ });
637
+ }
638
+ } catch (err) {
639
+ __ok = false;
640
+ __error = err;
641
+ throw err;
620
642
  } finally {
621
- setLoadingActions((prev) => {
622
- const next = new Set(prev);
623
- next.delete(resolved.action);
624
- return next;
643
+ const now = Date.now();
644
+ (0, import_core4.notifyActionSettle)({
645
+ id: dispatchId,
646
+ name: resolved.action,
647
+ ok: __ok,
648
+ at: now,
649
+ durationMs: now - dispatchedAt,
650
+ error: __error
625
651
  });
626
652
  }
627
653
  };
@@ -797,13 +823,24 @@ var import_core8 = require("@json-render/core");
797
823
  // src/renderer.tsx
798
824
  var import_web13 = require("solid-js/web");
799
825
  var import_web14 = require("solid-js/web");
826
+ var import_web15 = require("solid-js/web");
827
+ var import_web16 = require("solid-js/web");
828
+ var import_web17 = require("solid-js/web");
829
+ var import_web18 = require("solid-js/web");
800
830
  var import_solid_js6 = require("solid-js");
801
831
  var import_core6 = require("@json-render/core");
832
+ var _tmpl$2 = /* @__PURE__ */ (0, import_web13.template)(`<span style=display:contents>`);
802
833
  var EMPTY_FUNCTIONS = {};
803
834
  var FunctionsContext = (0, import_solid_js6.createContext)(EMPTY_FUNCTIONS);
804
835
  function useFunctions() {
805
836
  return (0, import_solid_js6.useContext)(FunctionsContext) ?? EMPTY_FUNCTIONS;
806
837
  }
838
+ function useDevtoolsActive() {
839
+ const [active, setActive] = (0, import_solid_js6.createSignal)((0, import_core6.isDevtoolsActive)());
840
+ const unsub = (0, import_core6.subscribeDevtoolsActive)(() => setActive((0, import_core6.isDevtoolsActive)()));
841
+ (0, import_solid_js6.onCleanup)(unsub);
842
+ return active;
843
+ }
807
844
  function ElementRenderer(props) {
808
845
  const repeatScope = useRepeatScope();
809
846
  const {
@@ -929,21 +966,24 @@ function ElementRenderer(props) {
929
966
  props: resolvedProps
930
967
  } : props.element;
931
968
  });
932
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
969
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
933
970
  get when() {
934
971
  return isVisible();
935
972
  },
936
973
  get children() {
937
- return (0, import_web14.createComponent)(import_solid_js6.ErrorBoundary, {
974
+ return (0, import_web18.createComponent)(import_solid_js6.ErrorBoundary, {
938
975
  fallback: (err) => {
939
976
  console.error(`[json-render] Rendering error in <${props.element.type}>:`, err);
940
977
  return null;
941
978
  },
942
979
  get children() {
943
- return (0, import_web14.createComponent)(ElementRendererContent, {
980
+ return (0, import_web18.createComponent)(ElementRendererContent, {
944
981
  get resolvedElement() {
945
982
  return resolvedElement();
946
983
  },
984
+ get elementKey() {
985
+ return props.elementKey;
986
+ },
947
987
  get spec() {
948
988
  return props.spec;
949
989
  },
@@ -968,8 +1008,9 @@ function ElementRenderer(props) {
968
1008
  });
969
1009
  }
970
1010
  function ElementRendererContent(props) {
1011
+ const devtoolsActive = useDevtoolsActive();
971
1012
  const Comp = () => props.registry[props.resolvedElement.type] ?? props.fallback;
972
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
1013
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
973
1014
  get when() {
974
1015
  return Comp();
975
1016
  },
@@ -979,7 +1020,7 @@ function ElementRendererContent(props) {
979
1020
  },
980
1021
  children: (ComponentFn) => {
981
1022
  const Component = ComponentFn();
982
- const children = () => props.resolvedElement.repeat ? (0, import_web14.createComponent)(RepeatChildren, {
1023
+ const children = () => props.resolvedElement.repeat ? (0, import_web18.createComponent)(RepeatChildren, {
983
1024
  get element() {
984
1025
  return props.resolvedElement;
985
1026
  },
@@ -995,13 +1036,13 @@ function ElementRendererContent(props) {
995
1036
  get fallback() {
996
1037
  return props.fallback;
997
1038
  }
998
- }) : (0, import_web14.createComponent)(import_solid_js6.For, {
1039
+ }) : (0, import_web18.createComponent)(import_solid_js6.For, {
999
1040
  get each() {
1000
1041
  return props.resolvedElement.children ?? [];
1001
1042
  },
1002
1043
  children: (childKey) => {
1003
1044
  const childElement = () => props.spec.elements[childKey];
1004
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
1045
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
1005
1046
  get when() {
1006
1047
  return childElement();
1007
1048
  },
@@ -1011,10 +1052,11 @@ function ElementRendererContent(props) {
1011
1052
  }
1012
1053
  return null;
1013
1054
  },
1014
- children: (el) => (0, import_web14.createComponent)(ElementRenderer, {
1055
+ children: (el) => (0, import_web18.createComponent)(ElementRenderer, {
1015
1056
  get element() {
1016
1057
  return el();
1017
1058
  },
1059
+ elementKey: childKey,
1018
1060
  get spec() {
1019
1061
  return props.spec;
1020
1062
  },
@@ -1031,7 +1073,7 @@ function ElementRendererContent(props) {
1031
1073
  });
1032
1074
  }
1033
1075
  });
1034
- return (0, import_web14.createComponent)(Component, {
1076
+ const rendered = (0, import_web18.createComponent)(Component, {
1035
1077
  get element() {
1036
1078
  return props.resolvedElement;
1037
1079
  },
@@ -1051,6 +1093,18 @@ function ElementRendererContent(props) {
1051
1093
  return children();
1052
1094
  }
1053
1095
  });
1096
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
1097
+ get when() {
1098
+ return (0, import_web17.memo)(() => !!devtoolsActive())() && props.elementKey;
1099
+ },
1100
+ fallback: rendered,
1101
+ get children() {
1102
+ var _el$ = _tmpl$2();
1103
+ (0, import_web16.insert)(_el$, rendered);
1104
+ (0, import_web15.effect)(() => (0, import_web14.setAttribute)(_el$, "data-jr-key", props.elementKey));
1105
+ return _el$;
1106
+ }
1107
+ });
1054
1108
  }
1055
1109
  });
1056
1110
  }
@@ -1059,7 +1113,7 @@ function RepeatChildren(props) {
1059
1113
  const repeat = () => props.element.repeat;
1060
1114
  const statePath = () => repeat().statePath;
1061
1115
  const items = () => (0, import_core6.getByPath)(stateStore.state, statePath()) ?? [];
1062
- return (0, import_web14.createComponent)(import_solid_js6.For, {
1116
+ return (0, import_web18.createComponent)(import_solid_js6.For, {
1063
1117
  get each() {
1064
1118
  return items();
1065
1119
  },
@@ -1068,7 +1122,7 @@ function RepeatChildren(props) {
1068
1122
  const r = repeat();
1069
1123
  return r.key && typeof itemValue === "object" && itemValue !== null ? String(itemValue[r.key] ?? index()) : String(index());
1070
1124
  };
1071
- return (0, import_web14.createComponent)(RepeatScopeProvider, {
1125
+ return (0, import_web18.createComponent)(RepeatScopeProvider, {
1072
1126
  item: itemValue,
1073
1127
  get index() {
1074
1128
  return index();
@@ -1077,13 +1131,13 @@ function RepeatChildren(props) {
1077
1131
  return `${statePath()}/${index()}`;
1078
1132
  },
1079
1133
  get children() {
1080
- return (0, import_web14.createComponent)(import_solid_js6.For, {
1134
+ return (0, import_web18.createComponent)(import_solid_js6.For, {
1081
1135
  get each() {
1082
1136
  return props.element.children ?? [];
1083
1137
  },
1084
1138
  children: (childKey) => {
1085
1139
  const childElement = () => props.spec.elements[childKey];
1086
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
1140
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
1087
1141
  get when() {
1088
1142
  return childElement();
1089
1143
  },
@@ -1093,7 +1147,7 @@ function RepeatChildren(props) {
1093
1147
  }
1094
1148
  return null;
1095
1149
  },
1096
- children: (el) => (0, import_web14.createComponent)(ElementRenderer, {
1150
+ children: (el) => (0, import_web18.createComponent)(ElementRenderer, {
1097
1151
  get element() {
1098
1152
  return el();
1099
1153
  },
@@ -1124,14 +1178,17 @@ function Renderer(props) {
1124
1178
  if (!spec || !spec.root) return void 0;
1125
1179
  return spec.elements[spec.root];
1126
1180
  });
1127
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
1181
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
1128
1182
  get when() {
1129
1183
  return rootElement();
1130
1184
  },
1131
- children: (el) => (0, import_web14.createComponent)(ElementRenderer, {
1185
+ children: (el) => (0, import_web18.createComponent)(ElementRenderer, {
1132
1186
  get element() {
1133
1187
  return el();
1134
1188
  },
1189
+ get elementKey() {
1190
+ return props.spec.root;
1191
+ },
1135
1192
  get spec() {
1136
1193
  return props.spec;
1137
1194
  },
@@ -1148,7 +1205,7 @@ function Renderer(props) {
1148
1205
  });
1149
1206
  }
1150
1207
  function JSONUIProvider(props) {
1151
- return (0, import_web14.createComponent)(StateProvider, {
1208
+ return (0, import_web18.createComponent)(StateProvider, {
1152
1209
  get store() {
1153
1210
  return props.store;
1154
1211
  },
@@ -1159,14 +1216,14 @@ function JSONUIProvider(props) {
1159
1216
  return props.onStateChange;
1160
1217
  },
1161
1218
  get children() {
1162
- return (0, import_web14.createComponent)(VisibilityProvider, {
1219
+ return (0, import_web18.createComponent)(VisibilityProvider, {
1163
1220
  get children() {
1164
- return (0, import_web14.createComponent)(ValidationProvider, {
1221
+ return (0, import_web18.createComponent)(ValidationProvider, {
1165
1222
  get customFunctions() {
1166
1223
  return props.validationFunctions;
1167
1224
  },
1168
1225
  get children() {
1169
- return (0, import_web14.createComponent)(ActionProvider, {
1226
+ return (0, import_web18.createComponent)(ActionProvider, {
1170
1227
  get handlers() {
1171
1228
  return props.handlers;
1172
1229
  },
@@ -1174,12 +1231,12 @@ function JSONUIProvider(props) {
1174
1231
  return props.navigate;
1175
1232
  },
1176
1233
  get children() {
1177
- return (0, import_web14.createComponent)(FunctionsContext.Provider, {
1234
+ return (0, import_web18.createComponent)(FunctionsContext.Provider, {
1178
1235
  get value() {
1179
1236
  return props.functions ?? EMPTY_FUNCTIONS;
1180
1237
  },
1181
1238
  get children() {
1182
- return [(0, import_web13.memo)(() => props.children), (0, import_web14.createComponent)(ConfirmationDialogManager, {})];
1239
+ return [(0, import_web17.memo)(() => props.children), (0, import_web18.createComponent)(ConfirmationDialogManager, {})];
1183
1240
  }
1184
1241
  });
1185
1242
  }
@@ -1197,11 +1254,11 @@ function ConfirmationDialogManager() {
1197
1254
  confirm,
1198
1255
  cancel
1199
1256
  } = useActions();
1200
- return (0, import_web14.createComponent)(import_solid_js6.Show, {
1257
+ return (0, import_web18.createComponent)(import_solid_js6.Show, {
1201
1258
  get when() {
1202
1259
  return pendingConfirmation?.action.confirm;
1203
1260
  },
1204
- children: (confirmConfig) => (0, import_web14.createComponent)(ConfirmDialog, {
1261
+ children: (confirmConfig) => (0, import_web18.createComponent)(ConfirmDialog, {
1205
1262
  get confirm() {
1206
1263
  return confirmConfig();
1207
1264
  },
@@ -1271,7 +1328,7 @@ function createRenderer(catalog, components) {
1271
1328
  },
1272
1329
  has: () => true
1273
1330
  }) : void 0;
1274
- return (0, import_web14.createComponent)(StateProvider, {
1331
+ return (0, import_web18.createComponent)(StateProvider, {
1275
1332
  get store() {
1276
1333
  return props.store;
1277
1334
  },
@@ -1282,21 +1339,21 @@ function createRenderer(catalog, components) {
1282
1339
  return props.onStateChange;
1283
1340
  },
1284
1341
  get children() {
1285
- return (0, import_web14.createComponent)(VisibilityProvider, {
1342
+ return (0, import_web18.createComponent)(VisibilityProvider, {
1286
1343
  get children() {
1287
- return (0, import_web14.createComponent)(ValidationProvider, {
1344
+ return (0, import_web18.createComponent)(ValidationProvider, {
1288
1345
  get children() {
1289
- return (0, import_web14.createComponent)(ActionProvider, {
1346
+ return (0, import_web18.createComponent)(ActionProvider, {
1290
1347
  get handlers() {
1291
1348
  return actionHandlers();
1292
1349
  },
1293
1350
  get children() {
1294
- return (0, import_web14.createComponent)(FunctionsContext.Provider, {
1351
+ return (0, import_web18.createComponent)(FunctionsContext.Provider, {
1295
1352
  get value() {
1296
1353
  return props.functions ?? EMPTY_FUNCTIONS;
1297
1354
  },
1298
1355
  get children() {
1299
- return [(0, import_web14.createComponent)(Renderer, {
1356
+ return [(0, import_web18.createComponent)(Renderer, {
1300
1357
  get spec() {
1301
1358
  return props.spec;
1302
1359
  },
@@ -1307,7 +1364,7 @@ function createRenderer(catalog, components) {
1307
1364
  get fallback() {
1308
1365
  return props.fallback;
1309
1366
  }
1310
- }), (0, import_web14.createComponent)(ConfirmationDialogManager, {})];
1367
+ }), (0, import_web18.createComponent)(ConfirmationDialogManager, {})];
1311
1368
  }
1312
1369
  });
1313
1370
  }