@strata-ds/core 2.1.0 → 2.1.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.
Files changed (44) hide show
  1. package/README.md +541 -438
  2. package/dist/components/DynamicComponentDebug.d.ts +0 -1
  3. package/dist/components/DynamicComponents.d.ts +0 -1
  4. package/dist/components/StrataErrorBoundary.d.ts +37 -0
  5. package/dist/components/card-ui/Card.d.ts +0 -1
  6. package/dist/components/card-ui/DefaultCard.d.ts +0 -1
  7. package/dist/components/index.d.ts +1 -1
  8. package/dist/data/index.d.ts +0 -1
  9. package/dist/data/mock.types.d.ts +2 -1
  10. package/dist/hook/useCardData.d.ts +0 -1
  11. package/dist/hook/useComponent.d.ts +0 -1
  12. package/dist/hook/useComponents.d.ts +0 -1
  13. package/dist/hook/useDynamicComponents.d.ts +0 -1
  14. package/dist/index.d.ts +414 -1
  15. package/dist/index.esm.js +298 -70
  16. package/dist/index.js +301 -68
  17. package/dist/providers/StrataProvider.d.ts +5 -1
  18. package/dist/providers/index.d.ts +0 -1
  19. package/dist/registry/ComponentFactory.d.ts +0 -1
  20. package/dist/registry/ComponentRegistry.d.ts +0 -1
  21. package/dist/types/card-types.d.ts +0 -1
  22. package/dist/utils/normalize-component.d.ts +14 -0
  23. package/package.json +74 -74
  24. package/dist/components/DynamicComponentDebug.d.ts.map +0 -1
  25. package/dist/components/DynamicComponents.d.ts.map +0 -1
  26. package/dist/components/card-ui/Card.d.ts.map +0 -1
  27. package/dist/components/card-ui/DefaultCard.d.ts.map +0 -1
  28. package/dist/components/index.d.ts.map +0 -1
  29. package/dist/data/index.d.ts.map +0 -1
  30. package/dist/data/mock.types.d.ts.map +0 -1
  31. package/dist/hook/useCardData.d.ts.map +0 -1
  32. package/dist/hook/useComponent.d.ts.map +0 -1
  33. package/dist/hook/useComponents.d.ts.map +0 -1
  34. package/dist/hook/useDesignSystemSync.d.ts +0 -1
  35. package/dist/hook/useDesignSystemSync.d.ts.map +0 -1
  36. package/dist/hook/useDynamicComponents.d.ts.map +0 -1
  37. package/dist/index.d.ts.map +0 -1
  38. package/dist/index.esm.js.map +0 -1
  39. package/dist/index.js.map +0 -1
  40. package/dist/providers/StrataProvider.d.ts.map +0 -1
  41. package/dist/providers/index.d.ts.map +0 -1
  42. package/dist/registry/ComponentFactory.d.ts.map +0 -1
  43. package/dist/registry/ComponentRegistry.d.ts.map +0 -1
  44. package/dist/types/card-types.d.ts.map +0 -1
package/dist/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import React, { useState, useRef, useMemo, useCallback, useEffect, createContext, useContext } from 'react';
2
+ import React, { useState, useRef, useEffect, useMemo, useCallback, createContext, useContext } from 'react';
3
3
  import { extendTheme, ChakraProvider, Box, Flex, Text, Image, Button, VStack, HStack } from '@chakra-ui/react';
4
4
 
5
5
  function _arrayLikeToArray(r, a) {
@@ -10,6 +10,10 @@ function _arrayLikeToArray(r, a) {
10
10
  function _arrayWithHoles(r) {
11
11
  if (Array.isArray(r)) return r;
12
12
  }
13
+ function _assertThisInitialized(e) {
14
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
15
+ return e;
16
+ }
13
17
  function asyncGeneratorStep(n, t, e, r, o, a, c) {
14
18
  try {
15
19
  var i = n[a](c),
@@ -35,6 +39,9 @@ function _asyncToGenerator(n) {
35
39
  });
36
40
  };
37
41
  }
42
+ function _callSuper(t, o, e) {
43
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
44
+ }
38
45
  function _classCallCheck(a, n) {
39
46
  if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
40
47
  }
@@ -57,6 +64,31 @@ function _defineProperty(e, r, t) {
57
64
  writable: true
58
65
  }) : e[r] = t, e;
59
66
  }
67
+ function _getPrototypeOf(t) {
68
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
69
+ return t.__proto__ || Object.getPrototypeOf(t);
70
+ }, _getPrototypeOf(t);
71
+ }
72
+ function _inherits(t, e) {
73
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
74
+ t.prototype = Object.create(e && e.prototype, {
75
+ constructor: {
76
+ value: t,
77
+ writable: true,
78
+ configurable: true
79
+ }
80
+ }), Object.defineProperty(t, "prototype", {
81
+ writable: false
82
+ }), e && _setPrototypeOf(t, e);
83
+ }
84
+ function _isNativeReflectConstruct() {
85
+ try {
86
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
87
+ } catch (t) {}
88
+ return (_isNativeReflectConstruct = function () {
89
+ return !!t;
90
+ })();
91
+ }
60
92
  function _iterableToArrayLimit(r, l) {
61
93
  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
62
94
  if (null != t) {
@@ -128,6 +160,11 @@ function _objectWithoutPropertiesLoose(r, e) {
128
160
  }
129
161
  return t;
130
162
  }
163
+ function _possibleConstructorReturn(t, e) {
164
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
165
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
166
+ return _assertThisInitialized(t);
167
+ }
131
168
  function _regenerator() {
132
169
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
133
170
  var e,
@@ -236,6 +273,11 @@ function _regeneratorDefine(e, r, n, t) {
236
273
  }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2));
237
274
  }, _regeneratorDefine(e, r, n, t);
238
275
  }
276
+ function _setPrototypeOf(t, e) {
277
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
278
+ return t.__proto__ = e, t;
279
+ }, _setPrototypeOf(t, e);
280
+ }
239
281
  function _slicedToArray(r, e) {
240
282
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
241
283
  }
@@ -270,6 +312,106 @@ function _unsupportedIterableToArray(r, a) {
270
312
  }
271
313
  }
272
314
 
315
+ var _excluded$3 = ["class"];
316
+ /**
317
+ * Convert a StrataNode styles object into a ComponentProperty record and a
318
+ * class attribute string. CSS properties (all keys except "class") are mapped
319
+ * to ComponentProperty entries so that resolveComponentStyles() in
320
+ * ComponentFactory applies them as inline CSS.
321
+ */
322
+ function parseStrataStyles(styles) {
323
+ var _ref = styles || {},
324
+ className = _ref["class"],
325
+ styleProps = _objectWithoutProperties(_ref, _excluded$3);
326
+ var properties = {};
327
+ Object.entries(styleProps).forEach(function (_ref2) {
328
+ var _ref3 = _slicedToArray(_ref2, 2),
329
+ k = _ref3[0],
330
+ v = _ref3[1];
331
+ if (v != null) {
332
+ properties[k] = {
333
+ value: String(v),
334
+ unit: null,
335
+ type: "string",
336
+ comment: ""
337
+ };
338
+ }
339
+ });
340
+ return {
341
+ properties: properties,
342
+ className: className != null ? String(className) : undefined
343
+ };
344
+ }
345
+ /**
346
+ * Convert a flat array of backend StrataNode children into a
347
+ * Record<string, ComponentNode> keyed by child.role or array index.
348
+ */
349
+ function strataChildrenToRecord(children) {
350
+ var result = {};
351
+ children.forEach(function (child, index) {
352
+ var key = child.role != null ? String(child.role) : String(index);
353
+ var _parseStrataStyles = parseStrataStyles(child.styles),
354
+ properties = _parseStrataStyles.properties,
355
+ className = _parseStrataStyles.className;
356
+ var attributes = {};
357
+ if (className != null) {
358
+ attributes["class"] = className;
359
+ }
360
+ var grandchildren = strataChildrenToRecord(child.children || []);
361
+ result[key] = {
362
+ linkedElement: {
363
+ htmlTag: child.tag || "div",
364
+ attributes: attributes
365
+ },
366
+ textContent: child.textContent,
367
+ properties: Object.keys(properties).length > 0 ? properties : undefined,
368
+ children: Object.keys(grandchildren).length > 0 ? grandchildren : null
369
+ };
370
+ });
371
+ return result;
372
+ }
373
+ /**
374
+ * Normalize a raw component payload from the Strata backend into the
375
+ * legacy `ComponentNode` shape expected by `StrataComponentFactory` and
376
+ * `ComponentRegistryService`.
377
+ *
378
+ * Handles two cases:
379
+ * 1. `nodes[]` format — backend shape: `{ name, nodes: [StrataNode, …] }`
380
+ * 2. Legacy shape — already has `linkedElement`; returned unchanged.
381
+ *
382
+ * @param raw - The raw component object from the design-system payload.
383
+ * @returns A fully-formed `ComponentNode`.
384
+ */
385
+ function normalizeComponentNode(raw) {
386
+ // Already in legacy shape — pass through unchanged.
387
+ if ((raw === null || raw === void 0 ? void 0 : raw.linkedElement) != null) {
388
+ return raw;
389
+ }
390
+ // Not in nodes[] format either — return as-is so existing fallbacks apply.
391
+ if (!Array.isArray(raw === null || raw === void 0 ? void 0 : raw.nodes) || raw.nodes.length === 0) {
392
+ return raw;
393
+ }
394
+ var rootNode = raw.nodes[0];
395
+ var _parseStrataStyles2 = parseStrataStyles(rootNode.styles),
396
+ properties = _parseStrataStyles2.properties,
397
+ className = _parseStrataStyles2.className;
398
+ var attributes = {};
399
+ if (className != null) {
400
+ attributes["class"] = className;
401
+ }
402
+ var children = strataChildrenToRecord(rootNode.children || []);
403
+ return {
404
+ displayName: raw.name || raw.displayName,
405
+ linkedElement: {
406
+ htmlTag: rootNode.tag || "div",
407
+ attributes: attributes
408
+ },
409
+ textContent: rootNode.textContent,
410
+ properties: Object.keys(properties).length > 0 ? properties : undefined,
411
+ children: Object.keys(children).length > 0 ? children : null
412
+ };
413
+ }
414
+
273
415
  var _excluded$2 = ["children", "style", "className"],
274
416
  _excluded2$2 = ["children", "style", "className"],
275
417
  _excluded3$1 = ["key", "ref", "children", "style", "className"];
@@ -283,6 +425,7 @@ var StrataComponentFactory = /*#__PURE__*/function () {
283
425
  // Create component with enhanced attribute handling
284
426
  function createComponent(componentName, componentData, designSystem) {
285
427
  var _this = this;
428
+ componentData = normalizeComponentNode(componentData);
286
429
  var Component = function Component(_ref) {
287
430
  var children = _ref.children,
288
431
  style = _ref.style,
@@ -307,6 +450,7 @@ var StrataComponentFactory = /*#__PURE__*/function () {
307
450
  key: "createSubComponent",
308
451
  value: function createSubComponent(componentName, componentData, designSystem) {
309
452
  var _this2 = this;
453
+ componentData = normalizeComponentNode(componentData);
310
454
  var SubComponent = function SubComponent(_ref2) {
311
455
  var children = _ref2.children,
312
456
  style = _ref2.style,
@@ -661,6 +805,7 @@ var StrataComponentFactory = /*#__PURE__*/function () {
661
805
  }, {
662
806
  key: "validateComponent",
663
807
  value: function validateComponent(componentData) {
808
+ componentData = normalizeComponentNode(componentData);
664
809
  var errors = [];
665
810
  // Check for required linked element attributes
666
811
  if (componentData.linkedElement) {
@@ -751,7 +896,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
751
896
  console.warn("\u26A0\uFE0F Invalid component name:", name);
752
897
  return "UnknownComponent";
753
898
  }
754
- console.log("\uD83D\uDD0D formatComponentName INPUT: \"".concat(name, "\""));
755
899
  // Remove any file extensions
756
900
  var cleanName = name.replace(/\.[^/.]+$/, "");
757
901
  // Handle various naming conventions and convert to PascalCase
@@ -782,7 +926,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
782
926
  if (!result) {
783
927
  result = "UnknownComponent";
784
928
  }
785
- console.log("\uD83D\uDCDD FINAL CONVERSION: \"".concat(name, "\" \u2192 \"").concat(result, "\""));
786
929
  return result;
787
930
  }
788
931
  // Test method to verify PascalCase conversion
@@ -802,12 +945,11 @@ var ComponentRegistryService = /*#__PURE__*/function () {
802
945
  key: "registerComponent",
803
946
  value: function registerComponent(componentName, componentData, designSystem) {
804
947
  var _this2 = this;
805
- console.log("\uD83D\uDD04 REGISTER COMPONENT CALLED with: \"".concat(componentName, "\""));
948
+ componentData = normalizeComponentNode(componentData);
806
949
  // Use PascalCase for the main component name
807
950
  var pascalCaseName = this.formatComponentName(componentName);
808
951
  // Store mapping for debugging and reverse lookup
809
952
  this.originalToPascalMap.set(componentName, pascalCaseName);
810
- console.log("\uD83D\uDCDD MAPPING STORED: \"".concat(componentName, "\" \u2192 \"").concat(pascalCaseName, "\""));
811
953
  // Create the main component
812
954
  var MainComponent = StrataComponentFactory.createComponent(pascalCaseName, componentData, designSystem);
813
955
  // Create sub-components recursively with proper PascalCase
@@ -817,7 +959,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
817
959
  childName = _ref2[0],
818
960
  childData = _ref2[1];
819
961
  var childComponentName = _this2.formatComponentName(childName);
820
- console.log("\uD83D\uDCDD Nested conversion: \"".concat(childName, "\" \u2192 \"").concat(childComponentName, "\""));
821
962
  // Store nested component mapping
822
963
  _this2.originalToPascalMap.set("".concat(componentName, ".").concat(childName), "".concat(pascalCaseName, ".").concat(childComponentName));
823
964
  MainComponent[childComponentName] = StrataComponentFactory.createSubComponent(childComponentName, childData, designSystem);
@@ -827,8 +968,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
827
968
  }
828
969
  // Register with PascalCase name only for cleaner API
829
970
  this.registry[pascalCaseName] = MainComponent;
830
- console.log("\u2705 Registered: \"".concat(pascalCaseName, "\""));
831
- console.log("\uD83D\uDCCA Current registry:", Object.keys(this.registry));
832
971
  this.notifyListeners();
833
972
  }
834
973
  // Recursively add nested components with mapping
@@ -893,10 +1032,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
893
1032
  key: "syncWithDesignSystem",
894
1033
  value: function syncWithDesignSystem(designSystem) {
895
1034
  var _this4 = this;
896
- console.log("🔄 SYNC WITH DESIGN SYSTEM CALLED");
897
- console.log("🔍 Design system components:", Object.keys(designSystem.components));
898
- // Test PascalCase conversion before proceeding
899
- this.testPascalCaseConversion();
900
1035
  // Clear existing registry and mappings
901
1036
  this.registry = {};
902
1037
  this.originalToPascalMap.clear();
@@ -905,11 +1040,8 @@ var ComponentRegistryService = /*#__PURE__*/function () {
905
1040
  var _ref6 = _slicedToArray(_ref5, 2),
906
1041
  componentName = _ref6[0],
907
1042
  componentData = _ref6[1];
908
- console.log("\uD83D\uDD04 Processing component from design system: \"".concat(componentName, "\""));
909
1043
  _this4.registerComponent(componentName, componentData, designSystem);
910
1044
  });
911
- console.log("✅ Sync completed. Final registry:", Object.keys(this.registry));
912
- console.log("🗺️ Component mapping:", Array.from(this.originalToPascalMap.entries()));
913
1045
  this.notifyListeners();
914
1046
  }
915
1047
  // Subscribe to registry changes
@@ -928,7 +1060,6 @@ var ComponentRegistryService = /*#__PURE__*/function () {
928
1060
  key: "notifyListeners",
929
1061
  value: function notifyListeners() {
930
1062
  var currentRegistry = this.getRegistry();
931
- console.log("📋 FINAL REGISTRY STATE:", Object.keys(currentRegistry));
932
1063
  this.listeners.forEach(function (listener) {
933
1064
  return listener(currentRegistry);
934
1065
  });
@@ -974,14 +1105,15 @@ var StrataProvider = function StrataProvider(_ref) {
974
1105
  _ref$syncEnabled = _ref.syncEnabled,
975
1106
  syncEnabled = _ref$syncEnabled === void 0 ? false : _ref$syncEnabled,
976
1107
  _ref$syncUrl = _ref.syncUrl,
977
- syncUrl = _ref$syncUrl === void 0 ? "http://localhost:4000" : _ref$syncUrl,
1108
+ syncUrl = _ref$syncUrl === void 0 ? "" : _ref$syncUrl,
978
1109
  _ref$syncInterval = _ref.syncInterval,
979
1110
  syncInterval = _ref$syncInterval === void 0 ? 3000 : _ref$syncInterval,
980
1111
  syncToken = _ref.syncToken,
981
1112
  snapshotCdnBase = _ref.snapshotCdnBase,
982
1113
  projectId = _ref.projectId,
983
1114
  onSyncError = _ref.onSyncError,
984
- onSyncSuccess = _ref.onSyncSuccess;
1115
+ onSyncSuccess = _ref.onSyncSuccess,
1116
+ onSyncStart = _ref.onSyncStart;
985
1117
  var _useState = useState(userDesignSystem || initialData || {
986
1118
  variables: {},
987
1119
  components: {},
@@ -1010,13 +1142,43 @@ var StrataProvider = function StrataProvider(_ref) {
1010
1142
  // value. This keeps the callback stable and prevents the polling interval
1011
1143
  // from being continuously reset after each successful sync.
1012
1144
  var lastSyncedStringRef = useRef(null);
1145
+ // Refs for lifecycle callbacks so that syncDesignSystem does not need to
1146
+ // close over them. Inline functions passed by the consumer (e.g. anonymous
1147
+ // arrow functions) would otherwise change identity on every render, forcing
1148
+ // the polling interval to restart after each render cycle.
1149
+ var onSyncStartRef = useRef(onSyncStart);
1150
+ var onSyncSuccessRef = useRef(onSyncSuccess);
1151
+ var onSyncErrorRef = useRef(onSyncError);
1152
+ useEffect(function () {
1153
+ onSyncStartRef.current = onSyncStart;
1154
+ onSyncSuccessRef.current = onSyncSuccess;
1155
+ onSyncErrorRef.current = onSyncError;
1156
+ });
1013
1157
  // Derive the CDN snapshot URL once — used in both syncDesignSystem and the
1014
1158
  // polling effect so the condition is computed in a single place.
1015
1159
  var snapshotUrl = useMemo(function () {
1016
- return snapshotCdnBase && projectId ? "".concat(snapshotCdnBase, "/snapshots/").concat(projectId, "/strata.json") : null;
1160
+ if (!snapshotCdnBase || !projectId) return null;
1161
+ var base = snapshotCdnBase.replace(/\/+$/, "");
1162
+ // Prevent duplication: if the base already includes /snapshots, just append the projectId
1163
+ if (base.endsWith("/snapshots")) return "".concat(base, "/").concat(projectId, "/strata.json");
1164
+ // Otherwise append the standard /snapshots/ path
1165
+ return "".concat(base, "/snapshots/").concat(projectId, "/strata.json");
1017
1166
  }, [snapshotCdnBase, projectId]);
1167
+ /** Normalize all components in a design-system payload from the nodes[]
1168
+ * backend format into the legacy ComponentNode shape. */
1169
+ var normalizeComponents = useCallback(function (data) {
1170
+ return _objectSpread2(_objectSpread2({}, data), {}, {
1171
+ components: Object.fromEntries(Object.entries(data.components).map(function (_ref2) {
1172
+ var _ref3 = _slicedToArray(_ref2, 2),
1173
+ name = _ref3[0],
1174
+ comp = _ref3[1];
1175
+ return [name, normalizeComponentNode(comp)];
1176
+ }))
1177
+ });
1178
+ }, []);
1018
1179
  var syncDesignSystem = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
1019
- var headers, remoteData, res, data, _yield$Promise$all, _yield$Promise$all2, variablesRes, componentsRes, customRes, _yield$Promise$all3, _yield$Promise$all4, variables, components, custom, newDataString, _t;
1180
+ var _onSyncStartRef$curre;
1181
+ var headers, remoteData, res, _onSyncErrorRef$curre, data, _onSyncErrorRef$curre2, _yield$Promise$all, _yield$Promise$all2, variablesRes, componentsRes, customRes, _yield$Promise$all3, _yield$Promise$all4, variables, components, custom, newDataString, _onSyncSuccessRef$cur, _onSyncErrorRef$curre3, _t;
1020
1182
  return _regenerator().w(function (_context) {
1021
1183
  while (1) switch (_context.p = _context.n) {
1022
1184
  case 0:
@@ -1027,8 +1189,8 @@ var StrataProvider = function StrataProvider(_ref) {
1027
1189
  return _context.a(2);
1028
1190
  case 1:
1029
1191
  setSyncStatus("syncing");
1192
+ (_onSyncStartRef$curre = onSyncStartRef.current) === null || _onSyncStartRef$curre === void 0 || _onSyncStartRef$curre.call(onSyncStartRef);
1030
1193
  _context.p = 2;
1031
- console.log("🔄 Starting design system sync...");
1032
1194
  headers = syncToken ? {
1033
1195
  Authorization: "Bearer ".concat(syncToken)
1034
1196
  } : {};
@@ -1047,7 +1209,7 @@ var StrataProvider = function StrataProvider(_ref) {
1047
1209
  break;
1048
1210
  }
1049
1211
  setSyncStatus("error");
1050
- onSyncError === null || onSyncError === void 0 || onSyncError({
1212
+ (_onSyncErrorRef$curre = onSyncErrorRef.current) === null || _onSyncErrorRef$curre === void 0 || _onSyncErrorRef$curre.call(onSyncErrorRef, {
1051
1213
  code: res.status,
1052
1214
  message: "CDN fetch failed: ".concat(res.status, " ").concat(res.statusText),
1053
1215
  source: "cdn"
@@ -1070,7 +1232,7 @@ var StrataProvider = function StrataProvider(_ref) {
1070
1232
  }
1071
1233
  console.warn("[strata] Invalid snapshot shape received from CDN — skipping update.");
1072
1234
  setSyncStatus("error");
1073
- onSyncError === null || onSyncError === void 0 || onSyncError({
1235
+ (_onSyncErrorRef$curre2 = onSyncErrorRef.current) === null || _onSyncErrorRef$curre2 === void 0 || _onSyncErrorRef$curre2.call(onSyncErrorRef, {
1074
1236
  code: 0,
1075
1237
  message: "Invalid snapshot shape: missing variables or components",
1076
1238
  source: "cdn"
@@ -1085,6 +1247,10 @@ var StrataProvider = function StrataProvider(_ref) {
1085
1247
  components: {}
1086
1248
  }
1087
1249
  };
1250
+ // Normalize all components from nodes[] format into the legacy
1251
+ // ComponentNode shape so that useDynamicComponents and the registry
1252
+ // always receive consistently-shaped data.
1253
+ remoteData = normalizeComponents(remoteData);
1088
1254
  _context.n = 14;
1089
1255
  break;
1090
1256
  case 8:
@@ -1136,34 +1302,26 @@ var StrataProvider = function StrataProvider(_ref) {
1136
1302
  components: {}
1137
1303
  }
1138
1304
  };
1305
+ // Normalize all components from nodes[] format into the legacy
1306
+ // ComponentNode shape so that useDynamicComponents and the registry
1307
+ // always receive consistently-shaped data.
1308
+ remoteData = normalizeComponents(remoteData);
1139
1309
  case 14:
1140
1310
  // Only update if data actually changed (compared against the last synced
1141
1311
  // snapshot via ref, so this callback stays stable across renders).
1142
1312
  newDataString = JSON.stringify(remoteData);
1143
1313
  if (lastSyncedStringRef.current !== newDataString) {
1144
- console.log("🔄 Design system data changed, updating...");
1145
1314
  lastSyncedStringRef.current = newDataString;
1146
1315
  setDesignSystem(remoteData);
1147
- Object.entries(remoteData.components).forEach(function (_ref3) {
1148
- var _ref4 = _slicedToArray(_ref3, 2),
1149
- componentName = _ref4[0],
1150
- componentData = _ref4[1];
1151
- if (!strataRegistry.hasComponent(componentName)) {
1152
- strataRegistry.registerComponent(componentName, componentData, remoteData);
1153
- }
1154
- });
1316
+ strataRegistry.syncWithDesignSystem(remoteData);
1155
1317
  setSyncVersion(function (prev) {
1156
1318
  return prev + 1;
1157
1319
  });
1158
1320
  setSyncStatus("success");
1159
1321
  setLastSynced(new Date());
1160
- onSyncSuccess === null || onSyncSuccess === void 0 || onSyncSuccess(remoteData);
1161
- console.log("✅ Design system synced successfully");
1162
- console.log("📊 Components available:", Object.keys(remoteData.components));
1163
- console.log("🎨 Variables available:", Object.keys(remoteData.variables));
1322
+ (_onSyncSuccessRef$cur = onSyncSuccessRef.current) === null || _onSyncSuccessRef$cur === void 0 || _onSyncSuccessRef$cur.call(onSyncSuccessRef, remoteData);
1164
1323
  } else {
1165
1324
  setSyncStatus("idle");
1166
- console.log("⚡ Design system already up to date");
1167
1325
  }
1168
1326
  _context.n = 16;
1169
1327
  break;
@@ -1172,7 +1330,7 @@ var StrataProvider = function StrataProvider(_ref) {
1172
1330
  _t = _context.v;
1173
1331
  console.error("❌ Sync failed:", _t);
1174
1332
  setSyncStatus("error");
1175
- onSyncError === null || onSyncError === void 0 || onSyncError({
1333
+ (_onSyncErrorRef$curre3 = onSyncErrorRef.current) === null || _onSyncErrorRef$curre3 === void 0 || _onSyncErrorRef$curre3.call(onSyncErrorRef, {
1176
1334
  code: 0,
1177
1335
  message: _t instanceof Error ? _t.message : String(_t),
1178
1336
  source: snapshotUrl ? "cdn" : "sync"
@@ -1181,7 +1339,7 @@ var StrataProvider = function StrataProvider(_ref) {
1181
1339
  return _context.a(2);
1182
1340
  }
1183
1341
  }, _callee, null, [[2, 15]]);
1184
- })), [syncEnabled, syncUrl, syncToken, snapshotUrl, onSyncSuccess, onSyncError]);
1342
+ })), [syncEnabled, syncUrl, syncToken, snapshotUrl, normalizeComponents]);
1185
1343
  // Force sync function for manual triggering
1186
1344
  var forceSync = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
1187
1345
  return _regenerator().w(function (_context2) {
@@ -1197,12 +1355,10 @@ var StrataProvider = function StrataProvider(_ref) {
1197
1355
  // Polling for real-time updates
1198
1356
  useEffect(function () {
1199
1357
  if (!syncEnabled || !snapshotUrl && !syncUrl) return;
1200
- console.log("🔄 Starting sync polling...");
1201
1358
  var interval = setInterval(syncDesignSystem, syncInterval);
1202
1359
  // Initial sync
1203
1360
  syncDesignSystem();
1204
1361
  return function () {
1205
- console.log("🔄 Stopping sync polling...");
1206
1362
  clearInterval(interval);
1207
1363
  };
1208
1364
  }, [syncEnabled, syncUrl, snapshotUrl, syncInterval, syncDesignSystem]);
@@ -1508,6 +1664,27 @@ var useCardData = function useCardData() {
1508
1664
  componentName: 'card'
1509
1665
  });
1510
1666
  };
1667
+ // Hook for custom components
1668
+ var useCustomComponent = function useCustomComponent(componentName) {
1669
+ return useComponentData({
1670
+ componentName: componentName,
1671
+ fallbackToDefault: false
1672
+ });
1673
+ };
1674
+ // Hook to get all available components
1675
+ var useAvailableComponents = function useAvailableComponents() {
1676
+ var _designSystem$custom2;
1677
+ var _useStrata2 = useStrata(),
1678
+ designSystem = _useStrata2.designSystem;
1679
+ return {
1680
+ baseComponents: Object.keys(designSystem.components).filter(function (key) {
1681
+ var _designSystem$custom;
1682
+ return !((_designSystem$custom = designSystem.custom) !== null && _designSystem$custom !== void 0 && (_designSystem$custom = _designSystem$custom.components) !== null && _designSystem$custom !== void 0 && _designSystem$custom[key]);
1683
+ }),
1684
+ customComponents: Object.keys(((_designSystem$custom2 = designSystem.custom) === null || _designSystem$custom2 === void 0 ? void 0 : _designSystem$custom2.components) || {}),
1685
+ allComponents: Object.keys(designSystem.components)
1686
+ };
1687
+ };
1511
1688
 
1512
1689
  // "use client";
1513
1690
  // import * as React from "react";
@@ -2808,52 +2985,36 @@ var useDynamicComponents = function useDynamicComponents() {
2808
2985
  var _useStrata = useStrata(),
2809
2986
  designSystem = _useStrata.designSystem,
2810
2987
  syncVersion = _useStrata.syncVersion;
2811
- var _useState = useState(strataRegistry.getRegistry()),
2988
+ // Synchronously populate the registry from the design system on first render
2989
+ // so that components from `initialData` are available without a render flash.
2990
+ var _useState = useState(function () {
2991
+ if (Object.keys(designSystem.components).length > 0) {
2992
+ strataRegistry.syncWithDesignSystem(designSystem);
2993
+ }
2994
+ return strataRegistry.getRegistry();
2995
+ }),
2812
2996
  _useState2 = _slicedToArray(_useState, 2),
2813
2997
  registry = _useState2[0],
2814
2998
  setRegistry = _useState2[1];
2815
- var _useState3 = useState(false),
2816
- _useState4 = _slicedToArray(_useState3, 2),
2817
- isInitialized = _useState4[0],
2818
- setIsInitialized = _useState4[1];
2819
- // Sync components when design system changes
2999
+ // Re-sync when the design system changes (e.g. after a live sync poll)
2820
3000
  useEffect(function () {
2821
- console.log('🔄 useDynamicComponents: Design system changed', {
2822
- components: Object.keys(designSystem.components),
2823
- syncVersion: syncVersion
2824
- });
2825
3001
  if (Object.keys(designSystem.components).length > 0) {
2826
- console.log('🔄 Syncing registry with design system...');
2827
- // Sync the entire registry with the current design system
2828
3002
  strataRegistry.syncWithDesignSystem(designSystem);
2829
- setIsInitialized(true);
2830
3003
  }
2831
3004
  }, [designSystem, syncVersion]);
2832
- // Subscribe to registry changes
3005
+ // Subscribe to registry changes so state stays in sync
2833
3006
  useEffect(function () {
2834
- console.log('🔄 useDynamicComponents: Subscribing to registry changes');
2835
3007
  var unsubscribe = strataRegistry.subscribe(function (newRegistry) {
2836
- console.log('🔄 Registry updated:', Object.keys(newRegistry));
2837
3008
  setRegistry(newRegistry);
2838
3009
  });
2839
3010
  return unsubscribe;
2840
3011
  }, []);
2841
- console.log('📋 useDynamicComponents returning registry:', {
2842
- registryKeys: Object.keys(registry),
2843
- isInitialized: isInitialized,
2844
- hasRoboForm: 'RoboForm' in registry
2845
- });
2846
3012
  return registry;
2847
3013
  };
2848
3014
 
2849
3015
  // This hook provides direct access to all components in PascalCase
2850
3016
  var useComponents = function useComponents() {
2851
- var dynamicComponents = useDynamicComponents();
2852
- console.log('🔄 useComponents returning:', {
2853
- componentCount: Object.keys(dynamicComponents).length,
2854
- componentNames: Object.keys(dynamicComponents)
2855
- });
2856
- return dynamicComponents;
3017
+ return useDynamicComponents();
2857
3018
  };
2858
3019
 
2859
3020
  var StrataDebug = function StrataDebug() {
@@ -2969,6 +3130,74 @@ var StrataDebug = function StrataDebug() {
2969
3130
  });
2970
3131
  };
2971
3132
 
3133
+ /**
3134
+ * `StrataErrorBoundary` wraps sections of your app that render synced
3135
+ * Strata components. When a component throws during render, this boundary
3136
+ * catches the error so the rest of the page stays functional.
3137
+ *
3138
+ * @example
3139
+ * ```tsx
3140
+ * <StrataErrorBoundary fallback={<p>Component failed to load.</p>}>
3141
+ * <MyStrataComponent />
3142
+ * </StrataErrorBoundary>
3143
+ * ```
3144
+ */
3145
+ var StrataErrorBoundary = /*#__PURE__*/function (_React$Component) {
3146
+ function StrataErrorBoundary(props) {
3147
+ var _this;
3148
+ _classCallCheck(this, StrataErrorBoundary);
3149
+ _this = _callSuper(this, StrataErrorBoundary, [props]);
3150
+ _this.state = {
3151
+ hasError: false,
3152
+ error: null
3153
+ };
3154
+ return _this;
3155
+ }
3156
+ _inherits(StrataErrorBoundary, _React$Component);
3157
+ return _createClass(StrataErrorBoundary, [{
3158
+ key: "componentDidCatch",
3159
+ value: function componentDidCatch(error, info) {
3160
+ var _this$props$onError, _this$props;
3161
+ (_this$props$onError = (_this$props = this.props).onError) === null || _this$props$onError === void 0 || _this$props$onError.call(_this$props, error, info);
3162
+ }
3163
+ }, {
3164
+ key: "render",
3165
+ value: function render() {
3166
+ if (this.state.hasError && this.state.error) {
3167
+ var fallback = this.props.fallback;
3168
+ if (typeof fallback === "function") {
3169
+ return fallback(this.state.error);
3170
+ }
3171
+ if (fallback !== undefined) {
3172
+ return fallback;
3173
+ }
3174
+ return jsxs("div", {
3175
+ style: {
3176
+ padding: "12px 16px",
3177
+ border: "1px solid #f87171",
3178
+ borderRadius: "6px",
3179
+ backgroundColor: "#fff1f1",
3180
+ color: "#b91c1c",
3181
+ fontSize: "0.875rem"
3182
+ },
3183
+ children: [jsx("strong", {
3184
+ children: "Strata component error:"
3185
+ }), " ", this.state.error.message || "An unknown error occurred."]
3186
+ });
3187
+ }
3188
+ return this.props.children;
3189
+ }
3190
+ }], [{
3191
+ key: "getDerivedStateFromError",
3192
+ value: function getDerivedStateFromError(error) {
3193
+ return {
3194
+ hasError: true,
3195
+ error: error
3196
+ };
3197
+ }
3198
+ }]);
3199
+ }(React.Component);
3200
+
2972
3201
  //working
2973
3202
  // "use client";
2974
3203
  // import { useDynamicComponents } from './useDynamicComponents';
@@ -3045,5 +3274,4 @@ var AutoForm = function AutoForm(_ref2) {
3045
3274
  return /*#__PURE__*/React.createElement(FormComponent, props, children);
3046
3275
  };
3047
3276
 
3048
- export { AutoForm, Card, DefaultCard, DynamicComponent, StrataComponentFactory, StrataDebug, StrataProvider, strataRegistry, useComponent, useComponents, useDynamicComponents, useStrata };
3049
- //# sourceMappingURL=index.esm.js.map
3277
+ export { AutoForm, Card, DefaultCard, DynamicComponent, StrataComponentFactory, StrataDebug, StrataErrorBoundary, StrataProvider, strataRegistry, useAvailableComponents, useCardData, useComponent, useComponentData, useComponents, useCustomComponent, useDynamicComponents, useStrata };