@strata-ds/core 2.1.0 → 2.1.2

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