@xapp/chat-widget 1.78.1 → 1.79.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.
Files changed (33) hide show
  1. package/dist/App.d.ts +0 -0
  2. package/dist/components/ChatButton/ChatButton.d.ts +0 -0
  3. package/dist/components/ChatFooter/ChatFooter.d.ts +0 -0
  4. package/dist/components/ChatFooter/ChatFooter.stories.d.ts +3 -0
  5. package/dist/components/ChatWidget/ChatWidget.d.ts +0 -0
  6. package/dist/components/ChatWidget/ChatWidget.stories.d.ts +6 -0
  7. package/dist/components/ChatWidget/ChatWidget.test.d.ts +1 -0
  8. package/dist/components/ChatWidget/ChatWidgetContainer.d.ts +0 -0
  9. package/dist/components/ChatWidget/ChatWidgetEnv.stories.d.ts +1 -0
  10. package/dist/components/ErrorOverlay/ErrorOverlay.d.ts +0 -0
  11. package/dist/components/ErrorOverlay/ErrorOverlay.stories.d.ts +8 -0
  12. package/dist/components/ErrorOverlay/index.d.ts +0 -0
  13. package/dist/components/Input/Input.d.ts +0 -0
  14. package/dist/components/Input/Input.stories.d.ts +7 -3
  15. package/dist/components/SendButton/SendButton.d.ts +0 -0
  16. package/dist/components/SendButton/SendButton.stories.d.ts +8 -4
  17. package/dist/index.css +1 -1
  18. package/dist/index.es.js +596 -96
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.js +596 -96
  21. package/dist/index.js.map +1 -1
  22. package/dist/store/ChatAction.d.ts +0 -0
  23. package/dist/store/ChatState.d.ts +0 -0
  24. package/dist/store/DefaultState.d.ts +0 -0
  25. package/dist/store/actions/index.d.ts +0 -0
  26. package/dist/store/actions/toggleDebugMode.d.ts +0 -0
  27. package/dist/xapp/StentorRouterChat.d.ts +0 -0
  28. package/dist/xapp/XappChat.d.ts +0 -0
  29. package/dist/xapp/__tests__/StentorRouterChat.test.d.ts +2 -0
  30. package/dist/xapp-chat-widget.css +1 -1
  31. package/dist/xapp-chat-widget.js +4 -4
  32. package/dist/xapp-chat-widget.js.map +1 -1
  33. package/package.json +10 -10
package/dist/index.es.js CHANGED
@@ -305,6 +305,27 @@ function getTimeAgo(date) {
305
305
  }
306
306
 
307
307
  var EMAIL_REGEX = "^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$";
308
+ // Initialize log level from localStorage on module load
309
+ var STORAGE_KEY = 'xaLogLevel';
310
+ var storedLogLevel = localStorage.getItem(STORAGE_KEY);
311
+ if (storedLogLevel) {
312
+ window.xaLogLevel = storedLogLevel;
313
+ }
314
+ // Override the setter to persist to localStorage
315
+ Object.defineProperty(window, 'xaLogLevel', {
316
+ get: function () {
317
+ return this._xaLogLevel;
318
+ },
319
+ set: function (value) {
320
+ this._xaLogLevel = value;
321
+ if (value) {
322
+ localStorage.setItem(STORAGE_KEY, value);
323
+ }
324
+ else {
325
+ localStorage.removeItem(STORAGE_KEY);
326
+ }
327
+ }
328
+ });
308
329
  // Returns current timestamp
309
330
  function getCurrentDateString() {
310
331
  return (new Date()).toISOString() + " ::";
@@ -604,7 +625,7 @@ function resize(vec, length) {
604
625
  return mul(vec, length / currentLength);
605
626
  }
606
627
  function rotateZ(vec, angle) {
607
- var rad = angle * Math.PI / 180;
628
+ var rad = (angle * Math.PI) / 180;
608
629
  var ca = Math.cos(rad);
609
630
  var sa = Math.sin(rad);
610
631
  var resx = vec.x * ca + vec.y * sa;
@@ -621,9 +642,9 @@ function intersectLineEllipsis(ellipsis, line) {
621
642
  var ry = ellipsis.radius.y;
622
643
  var rx2 = rx * rx;
623
644
  var ry2 = ry * ry;
624
- var a = (kx * kx / rx2 + ky * ky / ry2);
625
- var b = (2 * kx * sx / rx2 + 2 * ky * sy / ry2);
626
- var c = (sx * sx / rx2 + sy * sy / ry2 - 1);
645
+ var a = (kx * kx) / rx2 + (ky * ky) / ry2;
646
+ var b = (2 * kx * sx) / rx2 + (2 * ky * sy) / ry2;
647
+ var c = (sx * sx) / rx2 + (sy * sy) / ry2 - 1;
627
648
  var d2 = b * b - 4 * a * c;
628
649
  if (d2 >= 0) {
629
650
  var d = Math.sqrt(d2);
@@ -642,10 +663,13 @@ function intersectLineEllipsis(ellipsis, line) {
642
663
  return line.start;
643
664
  }
644
665
  function getTailSvgPath$1(props, viewport) {
645
- var baseAngleRad = props.direction * Math.PI / 180;
666
+ var baseAngleRad = (props.direction * Math.PI) / 180;
646
667
  var radius = { x: props.width / 2, y: props.height / 2 };
647
668
  var center = { x: viewport.x / 2, y: viewport.y / 2 };
648
- var intersectionRel = { x: radius.x * Math.cos(baseAngleRad), y: radius.y * Math.sin(baseAngleRad) };
669
+ var intersectionRel = {
670
+ x: radius.x * Math.cos(baseAngleRad),
671
+ y: radius.y * Math.sin(baseAngleRad),
672
+ };
649
673
  var farRel = resize(intersectionRel, len(intersectionRel) + props.length);
650
674
  var far = add$1(farRel, center);
651
675
  var direction = sub$1(intersectionRel, farRel);
@@ -654,15 +678,15 @@ function getTailSvgPath$1(props, viewport) {
654
678
  var rightDirection = rotateZ(direction, -angle / 2);
655
679
  var ellipsis = {
656
680
  center: center,
657
- radius: radius
681
+ radius: radius,
658
682
  };
659
683
  var left = intersectLineEllipsis(ellipsis, {
660
684
  start: far,
661
- direction: leftDirection
685
+ direction: leftDirection,
662
686
  });
663
687
  var right = intersectLineEllipsis(ellipsis, {
664
688
  start: far,
665
- direction: rightDirection
689
+ direction: rightDirection,
666
690
  });
667
691
  return "m ".concat(far.x, " ").concat(far.y, " L ").concat(left.x, " ").concat(left.y, " L ").concat(right.x, " ").concat(right.y, " z");
668
692
  }
@@ -670,9 +694,9 @@ var CtaBubbleTail = function (props) {
670
694
  var _a, _b;
671
695
  var _c = useDimensions(), ref = _c[0], rect = _c[1];
672
696
  var viewPort = { x: (_a = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _a !== void 0 ? _a : 0, y: (_b = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _b !== void 0 ? _b : 0 };
673
- return React$1.createElement("div", { ref: ref, className: "cta-bubble__tail" },
697
+ return (React$1.createElement("div", { ref: ref, className: "cta-bubble__tail" },
674
698
  React$1.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 ".concat(viewPort.x, " ").concat(viewPort.y) },
675
- React$1.createElement("path", { d: getTailSvgPath$1(props, viewPort), fill: "currentColor" })));
699
+ React$1.createElement("path", { d: getTailSvgPath$1(props, viewPort), fill: "currentColor" }))));
676
700
  };
677
701
  var CtaBubble = function (props) {
678
702
  var _a, _b, _c, _d;
@@ -685,10 +709,11 @@ var CtaBubble = function (props) {
685
709
  props.onDismiss();
686
710
  }
687
711
  };
712
+ console.log("Returning CTABubble with message: ", props.children);
688
713
  return (React$1.createElement("div", { ref: ref, style: {
689
- border: props.borderStyle ? 'solid' : 'none',
690
- borderWidth: ((_a = props.borderStyle) === null || _a === void 0 ? void 0 : _a.width) || '0px',
691
- borderColor: ((_b = props.borderStyle) === null || _b === void 0 ? void 0 : _b.color) || 'transparent',
714
+ border: props.borderStyle ? "solid" : "none",
715
+ borderWidth: ((_a = props.borderStyle) === null || _a === void 0 ? void 0 : _a.width) || "0px",
716
+ borderColor: ((_b = props.borderStyle) === null || _b === void 0 ? void 0 : _b.color) || "transparent",
692
717
  animation: "".concat(animation, " 1s infinite"),
693
718
  }, className: "cta-bubble", onClick: props.onClick },
694
719
  React$1.createElement(CtaBubbleTail, { width: (_c = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _c !== void 0 ? _c : 0, height: (_d = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _d !== void 0 ? _d : 0, direction: 60, angle: 45, length: 16 }),
@@ -700,54 +725,102 @@ var CtaBubble = function (props) {
700
725
 
701
726
  var CtaBubbleContainer = function (props) {
702
727
  var visible = props.visible, timeout = props.timeout, delay = props.delay, animate = props.animate, buttonAnimation = props.buttonAnimation, dismissible = props.dismissible, onClick = props.onClick, onDismiss = props.onDismiss, children = props.children;
728
+ // Debug: Log all props received
729
+ log("[CtaBubbleContainer] Props received:", {
730
+ visible: visible,
731
+ timeout: timeout,
732
+ delay: delay,
733
+ animate: animate,
734
+ buttonAnimation: buttonAnimation,
735
+ dismissible: dismissible,
736
+ hasOnClick: !!onClick,
737
+ hasOnDismiss: !!onDismiss,
738
+ hasChildren: !!children,
739
+ childrenContent: children,
740
+ });
703
741
  var startTime = useMemo(function () {
704
- return visible ? new Date().valueOf() : undefined;
742
+ var time = visible ? new Date().valueOf() : undefined;
743
+ log("[CtaBubbleContainer] StartTime calculated: visible=".concat(visible, ", startTime=").concat(time));
744
+ return time;
705
745
  }, [visible]);
706
746
  var _a = useState(false), showBubble = _a[0], setShowBubble = _a[1];
707
- var isMounted = useRef(true);
747
+ log("[CtaBubbleContainer] Current state: showBubble=".concat(showBubble));
708
748
  useEffect(function () {
749
+ log("[CtaBubbleContainer] useEffect triggered with:", {
750
+ startTime: startTime,
751
+ startTimeExists: !!startTime,
752
+ timeout: timeout,
753
+ timeoutType: typeof timeout,
754
+ delay: delay,
755
+ delayType: typeof delay,
756
+ visible: visible,
757
+ });
709
758
  var hideTimer = null;
759
+ var delayTimer = null;
760
+ var isMounted = true;
710
761
  if (startTime) {
711
- var delayTimer_1 = setTimeout(function () {
712
- if (isMounted.current) {
762
+ var actualDelay_1 = delay || 0;
763
+ log("[CtaBubbleContainer] Timer setup: actualDelay=".concat(actualDelay_1, "ms (from delay=").concat(delay, ")"));
764
+ delayTimer = setTimeout(function () {
765
+ log("[CtaBubbleContainer] Delay timer fired after ".concat(actualDelay_1, "ms, isMounted=").concat(isMounted));
766
+ if (isMounted) {
767
+ log("[CtaBubbleContainer] Component still mounted, setting showBubble=true");
713
768
  setShowBubble(true);
769
+ if (typeof timeout === "number") {
770
+ log("[CtaBubbleContainer] Hide timer setup: will hide after ".concat(timeout, "ms"));
771
+ hideTimer = setTimeout(function () {
772
+ log("[CtaBubbleContainer] Hide timer fired after ".concat(timeout, "ms, isMounted=").concat(isMounted));
773
+ if (isMounted) {
774
+ log("[CtaBubbleContainer] Component still mounted, setting showBubble=false");
775
+ setShowBubble(false);
776
+ }
777
+ else {
778
+ log("[CtaBubbleContainer] Component unmounted, skipping hide");
779
+ }
780
+ }, timeout);
781
+ }
782
+ else {
783
+ log("[CtaBubbleContainer] No hide timer set (timeout=".concat(timeout, ", type=").concat(typeof timeout, ")"));
784
+ }
714
785
  }
715
- if (typeof timeout === "number") {
716
- hideTimer = setTimeout(function () {
717
- if (isMounted.current) {
718
- setShowBubble(false);
719
- }
720
- }, timeout);
721
- }
722
- }, delay);
723
- return function () {
724
- if (hideTimer) {
725
- clearTimeout(hideTimer);
786
+ else {
787
+ log("[CtaBubbleContainer] Component unmounted before delay timer, not showing bubble");
726
788
  }
727
- clearTimeout(delayTimer_1);
728
- isMounted.current = false;
729
- };
789
+ }, actualDelay_1);
790
+ }
791
+ else {
792
+ log("[CtaBubbleContainer] No startTime, skipping timer setup");
730
793
  }
731
- // Return a cleanup function for the case where startTime is undefined
732
794
  return function () {
795
+ log("[CtaBubbleContainer] Cleanup triggered, unmounting component");
796
+ isMounted = false;
733
797
  if (hideTimer) {
798
+ log("[CtaBubbleContainer] Clearing hide timer");
734
799
  clearTimeout(hideTimer);
735
800
  }
736
- isMounted.current = false;
801
+ if (delayTimer) {
802
+ log("[CtaBubbleContainer] Clearing delay timer");
803
+ clearTimeout(delayTimer);
804
+ }
737
805
  };
738
- }, [startTime, timeout, delay]);
806
+ }, [startTime, timeout, delay, visible]);
739
807
  var handleDismiss = function () {
808
+ log("[CtaBubbleContainer] handleDismiss called, setting showBubble=false");
740
809
  setShowBubble(false);
741
810
  if (onDismiss) {
811
+ log("[CtaBubbleContainer] Calling onDismiss callback");
742
812
  onDismiss();
743
813
  }
744
814
  };
815
+ // Final render decision
816
+ var shouldRender = visible && showBubble;
817
+ log("[CtaBubbleContainer] Render decision: visible=".concat(visible, ", showBubble=").concat(showBubble, ", shouldRender=").concat(shouldRender));
745
818
  return (React$1.createElement(React$1.Fragment, null, visible && showBubble && (React$1.createElement(CtaBubble, { onClick: onClick, animate: animate, buttonAnimation: buttonAnimation, dismissible: dismissible, onDismiss: handleDismiss }, children))));
746
819
  };
747
820
 
748
821
  var ChatButton = function (_a) {
749
822
  var _b;
750
- var onClick = _a.onClick, addClass = _a.addClass, config = _a.config, visible = _a.visible, borderStyle = _a.borderStyle, imageUrl = _a.imageUrl;
823
+ var onClick = _a.onClick, addClass = _a.addClass, config = _a.config, visible = _a.visible, borderStyle = _a.borderStyle, imageUrl = _a.imageUrl, hasInteracted = _a.hasInteracted, onCtaDismiss = _a.onCtaDismiss;
751
824
  var _c = useState(defaultWidgetButtonWidth), buttonWidth = _c[0], setButtonWidth = _c[1];
752
825
  var _d = useState(false), animate = _d[0], setAnimate = _d[1];
753
826
  var mobileWidth = ((_b = config === null || config === void 0 ? void 0 : config.mobile) === null || _b === void 0 ? void 0 : _b.applyAtLessThanWidth) || defaultNonMobileScreenWidth;
@@ -766,6 +839,11 @@ var ChatButton = function (_a) {
766
839
  var _a;
767
840
  var delayTimer;
768
841
  var timeoutTimer;
842
+ // Don't animate if user has already interacted
843
+ if (hasInteracted) {
844
+ setAnimate(false);
845
+ return function () { }; // Return empty cleanup function
846
+ }
769
847
  // Use animationDelay if provided, otherwise fall back to delay for backwards compatibility
770
848
  var animationDelayToUse = (_a = configToApply === null || configToApply === void 0 ? void 0 : configToApply.animationDelay) !== null && _a !== void 0 ? _a : configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay;
771
849
  if (animationDelayToUse) {
@@ -798,8 +876,8 @@ var ChatButton = function (_a) {
798
876
  if (timeoutTimer)
799
877
  clearTimeout(timeoutTimer);
800
878
  };
801
- }, [configToApply, setAnimate]);
802
- var animation = animate ? (configToApply === null || configToApply === void 0 ? void 0 : configToApply.animation) || "wiggle" : "none";
879
+ }, [configToApply, setAnimate, hasInteracted]);
880
+ var animation = animate && !hasInteracted ? (configToApply === null || configToApply === void 0 ? void 0 : configToApply.animation) || "wiggle" : "none";
803
881
  useEffect(function () {
804
882
  var handleResize = function () {
805
883
  var screenWidth = window.innerWidth;
@@ -831,8 +909,8 @@ var ChatButton = function (_a) {
831
909
  // Fallback to default SVG
832
910
  React$1.createElement("svg", { width: svgSize, height: svgSize, viewBox: "0 0 22 22" },
833
911
  React$1.createElement("path", { d: "M13 22l-4-6H2c-1.11-.043-2-.935-2-2V2C0 .89.89 0 2 0h18c1.11 0 2 .892 2 2v12c0 1.067-.89 1.957-2 2h-3l-4 6zm3-8h4c-.005.3-.01-12 0-12-.01.004-18 .006-18 0 .005.006 0 12 0 12h8l3 5 3-5z", fill: "#FFF", fillRule: "evenodd" })))),
834
- configToApply && configToApply.message && (React$1.createElement("div", { className: "xapp-chat-button__cta" },
835
- React$1.createElement(CtaBubbleContainer, { timeout: configToApply === null || configToApply === void 0 ? void 0 : configToApply.timeout, delay: configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay, animate: animate, buttonAnimation: animation, dismissible: configToApply === null || configToApply === void 0 ? void 0 : configToApply.dismissible, visible: !visible /** Why is this !visible */ }, configToApply === null || configToApply === void 0 ? void 0 : configToApply.message)))));
912
+ configToApply && configToApply.message && !hasInteracted && (React$1.createElement("div", { className: "xapp-chat-button__cta" },
913
+ React$1.createElement(CtaBubbleContainer, { timeout: configToApply === null || configToApply === void 0 ? void 0 : configToApply.timeout, delay: configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay, animate: animate, buttonAnimation: animation, dismissible: configToApply === null || configToApply === void 0 ? void 0 : configToApply.dismissible, visible: !visible /** Why is this !visible */, onDismiss: onCtaDismiss }, configToApply === null || configToApply === void 0 ? void 0 : configToApply.message)))));
836
914
  };
837
915
 
838
916
  var ChatCard = function (props) {
@@ -2812,6 +2890,7 @@ var StentorRouterChat = /** @class */ (function () {
2812
2890
  this._sessionId = "";
2813
2891
  this.accessToken = "";
2814
2892
  this.attributes = {};
2893
+ this.routerAttributes = {};
2815
2894
  this.isAdmin = false;
2816
2895
  this.urlAttributes = {};
2817
2896
  this.handlers = {};
@@ -2880,13 +2959,19 @@ var StentorRouterChat = /** @class */ (function () {
2880
2959
  this.handlers["new message"] = function (data, sender, ts) {
2881
2960
  // Because the router's internal message format is Stentor channel compatible.
2882
2961
  // So the data is either a stentor Request (from widget) or a stentor Response (from bot)
2883
- var _a;
2962
+ var _a, _b;
2884
2963
  var message;
2885
2964
  if (sender.deviceId === "Bot") {
2886
- if (typeof ((_a = _this.options.hooks) === null || _a === void 0 ? void 0 : _a.onResponse) === "function") {
2887
- _this.options.hooks.onResponse(message);
2965
+ var response = data;
2966
+ // Extract custom attributes from router response
2967
+ if (((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.routerAttributes) && typeof response.data.routerAttributes === "object") {
2968
+ _this.routerAttributes = __assign({}, response.data.routerAttributes);
2969
+ log("Extracted router attributes: ".concat(JSON.stringify(_this.routerAttributes)));
2970
+ }
2971
+ if (typeof ((_b = _this.options.hooks) === null || _b === void 0 ? void 0 : _b.onResponse) === "function") {
2972
+ _this.options.hooks.onResponse(response);
2888
2973
  }
2889
- message = responseToMessage(data);
2974
+ message = responseToMessage(response);
2890
2975
  }
2891
2976
  else if (sender.deviceId === "Widget") {
2892
2977
  message = requestToMessage(data);
@@ -3319,7 +3404,7 @@ var StentorRouterChat = /** @class */ (function () {
3319
3404
  };
3320
3405
  StentorRouterChat.prototype.postMessage = function (message) {
3321
3406
  return __awaiter$1(this, void 0, void 0, function () {
3322
- var userId, sessionId, accessToken, attributes, rwgToken, merchantId, environment, enablePreferredTime, service, origin, request;
3407
+ var userId, sessionId, accessToken, attributes, rwgToken, merchantId, environment, enablePreferredTime, service, origin, mergedAttributes, request;
3323
3408
  return __generator$1(this, function (_a) {
3324
3409
  userId = this._userId;
3325
3410
  sessionId = this._sessionId;
@@ -3349,7 +3434,8 @@ var StentorRouterChat = /** @class */ (function () {
3349
3434
  if (origin) {
3350
3435
  attributes["origin"] = origin;
3351
3436
  }
3352
- request = requestFromMessage(message, userId, this.isNewSession, sessionId, accessToken, attributes, this.visitorInfo);
3437
+ mergedAttributes = __assign(__assign({}, attributes), this.routerAttributes);
3438
+ request = requestFromMessage(message, userId, this.isNewSession, sessionId, accessToken, mergedAttributes, this.visitorInfo);
3353
3439
  this.emit("new message", request);
3354
3440
  return [2 /*return*/];
3355
3441
  });
@@ -7641,22 +7727,21 @@ var StentorServerChat = /** @class */ (function () {
7641
7727
  return StentorServerChat;
7642
7728
  }());
7643
7729
 
7644
- // import { useWhatChanged } from '@simbathesailor/use-what-changed';
7645
7730
  function createChatServerCore(config, options) {
7646
7731
  switch (config.type) {
7647
7732
  case "direct":
7648
7733
  return new StentorDirectChat({
7649
7734
  url: config.serverUrl,
7650
7735
  key: config.accountKey,
7651
- timeout: config.timeout
7736
+ timeout: config.timeout,
7652
7737
  }, options);
7653
7738
  case "websocket":
7654
7739
  return new StentorServerChat({
7655
- url: config.serverUrl
7740
+ url: config.serverUrl,
7656
7741
  }, options);
7657
7742
  case "websocketraw":
7658
7743
  return new StentorRouterChat({
7659
- url: config.serverUrl
7744
+ url: config.serverUrl,
7660
7745
  }, options);
7661
7746
  case "local":
7662
7747
  return new StentorLocalChat();
@@ -7675,6 +7760,11 @@ function useChatServer(config, options) {
7675
7760
  // Log what caused the "effect"
7676
7761
  // useWhatChanged(deps, "options, config, dispatch");
7677
7762
  useEffect(function () {
7763
+ // Don't create server if config is null (waiting for async config load)
7764
+ if (!config || !options) {
7765
+ setServer(undefined);
7766
+ return undefined;
7767
+ }
7678
7768
  var newServer = createChatServer(config, options);
7679
7769
  newServer.init(dispatch);
7680
7770
  setServer(newServer);
@@ -8959,13 +9049,25 @@ var SendIcon = function () {
8959
9049
  };
8960
9050
 
8961
9051
  var SendButton = function (props) {
8962
- return (React$1.createElement(React$1.Fragment, null, !props.sendButtonIcon ? (React$1.createElement(IconButton_1, { className: "xappw-send-button ".concat(props.className || ""), tabIndex: props.tabIndex, onClick: props.onClick, icon: SendIcon })) : (React$1.createElement("button", { className: "xappw-custom-send-button", tabIndex: props.tabIndex ? Number(props.tabIndex) : 0, onClick: props.onClick },
8963
- React$1.createElement("img", { src: props.sendButtonIcon, alt: "Send button", draggable: false })))));
9052
+ var _a = props.disabled, disabled = _a === void 0 ? false : _a;
9053
+ var _b = React$1.useState(false), isHovered = _b[0], setIsHovered = _b[1];
9054
+ // Determine which icon to show based on state
9055
+ var getIconSrc = function () {
9056
+ if (disabled && props.sendButtonIconDisabled) {
9057
+ return props.sendButtonIconDisabled;
9058
+ }
9059
+ if (isHovered && !disabled && props.sendButtonIconHover) {
9060
+ return props.sendButtonIconHover;
9061
+ }
9062
+ return props.sendButtonIcon;
9063
+ };
9064
+ return (React$1.createElement(React$1.Fragment, null, !props.sendButtonIcon ? (React$1.createElement(IconButton_1, { className: "xappw-send-button ".concat(props.className || "", " ").concat(disabled ? 'disabled' : ''), tabIndex: props.tabIndex, onClick: disabled ? undefined : props.onClick, icon: SendIcon })) : (React$1.createElement("button", { className: "xappw-custom-send-button ".concat(disabled ? 'disabled' : ''), tabIndex: props.tabIndex ? Number(props.tabIndex) : 0, onClick: props.onClick, disabled: disabled, onMouseEnter: function () { return setIsHovered(true); }, onMouseLeave: function () { return setIsHovered(false); } },
9065
+ React$1.createElement("img", { src: getIconSrc(), alt: "Send button", draggable: false, className: "send-button-icon" })))));
8964
9066
  };
8965
9067
 
8966
9068
  var Input = function (props) {
8967
9069
  var _a, _b;
8968
- var value = props.value, placeholder = props.placeholder, sendButtonIcon = props.sendButtonIcon, suggestion = props.suggestion, footerConfig = props.footerConfig, inputConfig = props.inputConfig, onChange = props.onChange, onSubmit = props.onSubmit, onSuggestionCommand = props.onSuggestionCommand;
9070
+ var value = props.value, placeholder = props.placeholder, sendButtonIcon = props.sendButtonIcon, sendButtonIconHover = props.sendButtonIconHover, sendButtonIconDisabled = props.sendButtonIconDisabled, suggestion = props.suggestion, footerConfig = props.footerConfig, inputConfig = props.inputConfig, onChange = props.onChange, onSubmit = props.onSubmit, onSuggestionCommand = props.onSuggestionCommand;
8969
9071
  var _c = useState(false), dragover = _c[0], setDragover = _c[1];
8970
9072
  function onDragOver(event) {
8971
9073
  setDragover(true);
@@ -9021,7 +9123,7 @@ var Input = function (props) {
9021
9123
  value: value, spellCheck: true }),
9022
9124
  React$1.createElement("div", { className: "xappw-input-form__buttons" },
9023
9125
  value.text && (React$1.createElement(IconButton_1, { icon: CloseIcon, tabIndex: (_a = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.clearButton) === null || _a === void 0 ? void 0 : _a.tabIndex, className: "xappw-input-form__btn", onClick: handleClear })),
9024
- React$1.createElement(SendButton, { className: "xappw-input-form__btn", sendButtonIcon: sendButtonIcon, tabIndex: (_b = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.sendButton) === null || _b === void 0 ? void 0 : _b.tabIndex, onClick: handleOnSubmit })))));
9126
+ React$1.createElement(SendButton, { className: "xappw-input-form__btn", sendButtonIcon: sendButtonIcon, sendButtonIconHover: sendButtonIconHover, sendButtonIconDisabled: sendButtonIconDisabled, tabIndex: (_b = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.sendButton) === null || _b === void 0 ? void 0 : _b.tabIndex, disabled: !value.text, onClick: handleOnSubmit })))));
9025
9127
  };
9026
9128
 
9027
9129
  function createActions(onItemUse) {
@@ -9083,7 +9185,7 @@ var Suggestions = function (props) {
9083
9185
 
9084
9186
  var ChatFooter = function (props) {
9085
9187
  var _a, _b, _c;
9086
- var isAdmin = props.isAdmin, isChatting = props.isChatting, visible = props.visible, placeholder = props.placeholder, sendButtonIcon = props.sendButtonIcon, footerConfig = props.footerConfig, menuConfig = props.menuConfig, inputConfig = props.inputConfig, onSubmit = props.onSubmit;
9188
+ var isAdmin = props.isAdmin, isChatting = props.isChatting, visible = props.visible, placeholder = props.placeholder, sendButtonIcon = props.sendButtonIcon, sendButtonIconHover = props.sendButtonIconHover, sendButtonIconDisabled = props.sendButtonIconDisabled, footerConfig = props.footerConfig, menuConfig = props.menuConfig, inputConfig = props.inputConfig, onSubmit = props.onSubmit;
9087
9189
  var innerDispatch = useChatDispatch();
9088
9190
  var _d = useState(false), drawerOpen = _d[0], setDrawerState = _d[1]; // false initially
9089
9191
  var _e = useState(), suggestionSearch = _e[0], setSuggestionSearch = _e[1];
@@ -9149,7 +9251,7 @@ var ChatFooter = function (props) {
9149
9251
  React$1.createElement(Suggestions, { className: "xappw-chat-footer__suggestions", data: suggestions.suggestions, index: suggestions.index, searchTerms: suggestionSearch, onItemClick: handleItemClick, onItemUse: handleItemUse }),
9150
9252
  isAdmin && isChatting && visible && React$1.createElement(AdminBar, { onAdminJoin: handleAdminJoin }),
9151
9253
  React$1.createElement("div", { style: { pointerEvents: enableInput ? "auto" : "none", opacity: enableInput ? 1 : 0.5 } },
9152
- React$1.createElement(Input, { addClass: "chat-footer__input " + (isChatting && visible ? "visible" : ""), suggestion: suggestions.item, value: input, placeholder: placeholder, sendButtonIcon: sendButtonIcon, footerConfig: footerConfig, inputConfig: inputConfig, onSubmit: handleSubmit, onChange: handleChange, onSuggestionCommand: suggestions.execute,
9254
+ React$1.createElement(Input, { addClass: "chat-footer__input " + (isChatting && visible ? "visible" : ""), suggestion: suggestions.item, value: input, placeholder: placeholder, sendButtonIcon: sendButtonIcon, sendButtonIconHover: sendButtonIconHover, sendButtonIconDisabled: sendButtonIconDisabled, footerConfig: footerConfig, inputConfig: inputConfig, onSubmit: handleSubmit, onChange: handleChange, onSuggestionCommand: suggestions.execute,
9153
9255
  // onFocus={this.inputOnFocus}
9154
9256
  onFileUpload: props.onFileUpload })),
9155
9257
  brandingEnabled && brandingText && React$1.createElement(ChatBranding, { text: brandingText })));
@@ -31377,6 +31479,9 @@ function getButtonStyle(style) {
31377
31479
  _a.sent();
31378
31480
  return [4 /*yield*/, ["button-hover-bg", style === null || style === void 0 ? void 0 : style.hoverBackground]];
31379
31481
  case 4:
31482
+ _a.sent();
31483
+ return [4 /*yield*/, ["button-disabled-bg", style === null || style === void 0 ? void 0 : style.disabledBackground]];
31484
+ case 5:
31380
31485
  _a.sent();
31381
31486
  return [2 /*return*/];
31382
31487
  }
@@ -31433,6 +31538,285 @@ function getCtaStyle(style) {
31433
31538
  return union(getBackgroundStyle(style.background), getTextStyle(style.text));
31434
31539
  }
31435
31540
 
31541
+ /**
31542
+ * Safely stringify objects, handling circular references and errors
31543
+ */
31544
+ var safeStringify = function (arg) {
31545
+ if (arg === null)
31546
+ return "null";
31547
+ if (arg === undefined)
31548
+ return "undefined";
31549
+ if (typeof arg !== "object")
31550
+ return String(arg);
31551
+ try {
31552
+ var seen_1 = new WeakSet();
31553
+ return JSON.stringify(arg, function (_key, value) {
31554
+ if (typeof value === "object" && value !== null) {
31555
+ if (seen_1.has(value)) {
31556
+ return "[Circular]";
31557
+ }
31558
+ seen_1.add(value);
31559
+ }
31560
+ return value;
31561
+ }, 2);
31562
+ }
31563
+ catch (e) {
31564
+ return "[Object: ".concat(Object.prototype.toString.call(arg), "]");
31565
+ }
31566
+ };
31567
+ var ErrorOverlay = function () {
31568
+ var _a;
31569
+ var _b = useState([]), errors = _b[0], setErrors = _b[1];
31570
+ var _c = useState(false), isMinimized = _c[0], setIsMinimized = _c[1];
31571
+ var _d = useState(true), isVisible = _d[0], setIsVisible = _d[1];
31572
+ var _e = useState(false), isEnabled = _e[0], setIsEnabled = _e[1];
31573
+ var _f = useState("bottom"), position = _f[0], setPosition = _f[1];
31574
+ // Check if error overlay should be enabled and load position
31575
+ useEffect(function () {
31576
+ var _a;
31577
+ var checkEnabled = function () {
31578
+ var _a;
31579
+ if (typeof window === "undefined")
31580
+ return false;
31581
+ // Check localStorage
31582
+ var localStorageSetting = (_a = window.localStorage) === null || _a === void 0 ? void 0 : _a.getItem("xaErrorOverlay");
31583
+ if (localStorageSetting === "enabled") {
31584
+ console.log("[ErrorOverlay] Enabled via localStorage");
31585
+ return true;
31586
+ }
31587
+ if (localStorageSetting === "disabled") {
31588
+ console.log("[ErrorOverlay] Disabled via localStorage");
31589
+ return false;
31590
+ }
31591
+ // Check for React Native dev mode
31592
+ if (typeof globalThis.__DEV__ !== "undefined" && globalThis.__DEV__) {
31593
+ console.log("[ErrorOverlay] Enabled via __DEV__");
31594
+ return true;
31595
+ }
31596
+ return false;
31597
+ };
31598
+ var enabled = checkEnabled();
31599
+ setIsEnabled(enabled);
31600
+ // Load position preference
31601
+ var savedPosition = (_a = window.localStorage) === null || _a === void 0 ? void 0 : _a.getItem("xaErrorOverlayPosition");
31602
+ if (savedPosition === "top" || savedPosition === "bottom") {
31603
+ setPosition(savedPosition);
31604
+ }
31605
+ console.log("[ErrorOverlay] Component mounted, enabled:", enabled, "position:", savedPosition || "bottom");
31606
+ }, []);
31607
+ // Define addError with useCallback to prevent stale closures
31608
+ var addError = useCallback(function (error) {
31609
+ console.log("[ErrorOverlay] Adding error:", error);
31610
+ setErrors(function (prev) {
31611
+ var timestamp = new Date().toISOString();
31612
+ // Check if this is a duplicate of the last error
31613
+ var lastError = prev[prev.length - 1];
31614
+ if (lastError && lastError.message === error.message) {
31615
+ // Update count of last error
31616
+ return __spreadArray$1(__spreadArray$1([], prev.slice(0, -1), true), [
31617
+ __assign(__assign({}, lastError), { count: lastError.count + 1, timestamp: timestamp }),
31618
+ ], false);
31619
+ }
31620
+ // Add new error
31621
+ var newError = __assign({ id: "".concat(timestamp, "-").concat(Math.random()), timestamp: timestamp, count: 1 }, error);
31622
+ // Keep only last 50 errors
31623
+ var updated = __spreadArray$1(__spreadArray$1([], prev, true), [newError], false);
31624
+ return updated.slice(-50);
31625
+ });
31626
+ }, []);
31627
+ useEffect(function () {
31628
+ if (!isEnabled) {
31629
+ console.log("[ErrorOverlay] Not enabled, skipping error interception");
31630
+ return undefined;
31631
+ }
31632
+ console.log("[ErrorOverlay] Setting up error interception");
31633
+ // Store original console methods
31634
+ var originalError = console.error;
31635
+ var originalWarn = console.warn;
31636
+ // Override console.error
31637
+ console.error = function () {
31638
+ var args = [];
31639
+ for (var _i = 0; _i < arguments.length; _i++) {
31640
+ args[_i] = arguments[_i];
31641
+ }
31642
+ var message = args.map(function (arg) { return safeStringify(arg); }).join(" ");
31643
+ var error = new Error();
31644
+ addError({
31645
+ message: message,
31646
+ type: "error",
31647
+ stack: error.stack,
31648
+ });
31649
+ // Call original method
31650
+ originalError.apply(console, args);
31651
+ };
31652
+ // Override console.warn
31653
+ console.warn = function () {
31654
+ var args = [];
31655
+ for (var _i = 0; _i < arguments.length; _i++) {
31656
+ args[_i] = arguments[_i];
31657
+ }
31658
+ var message = args.map(function (arg) { return safeStringify(arg); }).join(" ");
31659
+ addError({
31660
+ message: message,
31661
+ type: "warning",
31662
+ });
31663
+ // Call original method
31664
+ originalWarn.apply(console, args);
31665
+ };
31666
+ // Capture unhandled errors
31667
+ var handleError = function (event) {
31668
+ var _a;
31669
+ addError({
31670
+ message: event.message,
31671
+ type: "error",
31672
+ stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
31673
+ });
31674
+ };
31675
+ // Capture unhandled promise rejections
31676
+ var handleRejection = function (event) {
31677
+ var _a;
31678
+ addError({
31679
+ message: "Unhandled Promise Rejection: ".concat(event.reason),
31680
+ type: "error",
31681
+ stack: (_a = event.reason) === null || _a === void 0 ? void 0 : _a.stack,
31682
+ });
31683
+ };
31684
+ window.addEventListener("error", handleError);
31685
+ window.addEventListener("unhandledrejection", handleRejection);
31686
+ // Cleanup
31687
+ return function () {
31688
+ console.log("[ErrorOverlay] Cleaning up error interception");
31689
+ console.error = originalError;
31690
+ console.warn = originalWarn;
31691
+ window.removeEventListener("error", handleError);
31692
+ window.removeEventListener("unhandledrejection", handleRejection);
31693
+ };
31694
+ }, [isEnabled, addError]);
31695
+ var clearErrors = function () {
31696
+ setErrors([]);
31697
+ };
31698
+ var copyToClipboard = function () { return __awaiter$1(void 0, void 0, void 0, function () {
31699
+ var errorText, err_1, textarea;
31700
+ return __generator$1(this, function (_a) {
31701
+ switch (_a.label) {
31702
+ case 0:
31703
+ errorText = errors
31704
+ .map(function (e) {
31705
+ return "[".concat(e.timestamp, "] ").concat(e.type.toUpperCase(), ": ").concat(e.message).concat(e.stack ? "\n" + e.stack : "");
31706
+ })
31707
+ .join("\n\n");
31708
+ _a.label = 1;
31709
+ case 1:
31710
+ _a.trys.push([1, 3, , 4]);
31711
+ return [4 /*yield*/, navigator.clipboard.writeText(errorText)];
31712
+ case 2:
31713
+ _a.sent();
31714
+ console.log("[ErrorOverlay] Errors copied to clipboard");
31715
+ return [3 /*break*/, 4];
31716
+ case 3:
31717
+ err_1 = _a.sent();
31718
+ console.error("[ErrorOverlay] Failed to copy to clipboard:", err_1);
31719
+ textarea = document.createElement("textarea");
31720
+ textarea.value = errorText;
31721
+ textarea.style.position = "fixed";
31722
+ textarea.style.opacity = "0";
31723
+ document.body.appendChild(textarea);
31724
+ textarea.select();
31725
+ try {
31726
+ document.execCommand("copy");
31727
+ console.log("[ErrorOverlay] Errors copied to clipboard using fallback method");
31728
+ }
31729
+ catch (fallbackErr) {
31730
+ console.error("[ErrorOverlay] Fallback copy method also failed:", fallbackErr);
31731
+ }
31732
+ document.body.removeChild(textarea);
31733
+ return [3 /*break*/, 4];
31734
+ case 4: return [2 /*return*/];
31735
+ }
31736
+ });
31737
+ }); };
31738
+ // Toggle enabled state
31739
+ var toggleEnabled = function () {
31740
+ var newState = !isEnabled;
31741
+ setIsEnabled(newState);
31742
+ if (typeof window !== "undefined" && window.localStorage) {
31743
+ window.localStorage.setItem("xaErrorOverlay", newState ? "enabled" : "disabled");
31744
+ }
31745
+ console.log("[ErrorOverlay] Toggled enabled state to:", newState);
31746
+ // Clear errors when disabling
31747
+ if (!newState) {
31748
+ setErrors([]);
31749
+ }
31750
+ };
31751
+ // Toggle position between top and bottom
31752
+ var togglePosition = function () {
31753
+ var newPosition = position === "bottom" ? "top" : "bottom";
31754
+ setPosition(newPosition);
31755
+ if (typeof window !== "undefined" && window.localStorage) {
31756
+ window.localStorage.setItem("xaErrorOverlayPosition", newPosition);
31757
+ }
31758
+ };
31759
+ // Don't render if not enabled
31760
+ if (!isEnabled) {
31761
+ // Show a small, subtle toggle button to enable (only visible on hover)
31762
+ return (React$1.createElement("button", { onClick: toggleEnabled, style: (_a = {
31763
+ position: "fixed"
31764
+ },
31765
+ _a[position] = "10px",
31766
+ _a.right = "10px",
31767
+ _a.zIndex = 999999,
31768
+ _a.background = "#ff6b6b",
31769
+ _a.color = "white",
31770
+ _a.border = "none",
31771
+ _a.borderRadius = "6px",
31772
+ _a.padding = "8px 12px",
31773
+ _a.fontSize = "20px",
31774
+ _a.cursor = "pointer",
31775
+ _a.opacity = 0.1, // Very subtle by default
31776
+ _a.transition = "opacity 0.2s",
31777
+ _a.minWidth = "44px",
31778
+ _a.minHeight = "44px",
31779
+ _a.display = "flex",
31780
+ _a.alignItems = "center",
31781
+ _a.justifyContent = "center",
31782
+ _a), onMouseEnter: function (e) { return (e.currentTarget.style.opacity = "0.8"); }, onMouseLeave: function (e) { return (e.currentTarget.style.opacity = "0.1"); }, title: "Enable Error Overlay (for debugging)" }, "\uD83D\uDC1B"));
31783
+ }
31784
+ // If enabled but not visible (user closed it), don't render
31785
+ if (!isVisible) {
31786
+ return null;
31787
+ }
31788
+ // If enabled and visible but no errors yet, don't show the overlay
31789
+ // Only show when there are actual errors to display
31790
+ if (errors.length === 0) {
31791
+ return null;
31792
+ }
31793
+ return (React$1.createElement("div", { className: "error-overlay error-overlay--".concat(position, " ").concat(isMinimized ? "minimized" : "") },
31794
+ React$1.createElement("div", { className: "error-overlay-header" },
31795
+ React$1.createElement("span", { className: "error-overlay-title" },
31796
+ "Debug Console (",
31797
+ errors.length,
31798
+ ")"),
31799
+ React$1.createElement("div", { className: "error-overlay-actions" },
31800
+ React$1.createElement("button", { onClick: copyToClipboard, title: "Copy all to clipboard" }, "\uD83D\uDCCB"),
31801
+ React$1.createElement("button", { onClick: clearErrors, title: "Clear all" }, "\uD83D\uDDD1\uFE0F"),
31802
+ React$1.createElement("button", { onClick: togglePosition, title: "Move to ".concat(position === "bottom" ? "top" : "bottom") }, position === "bottom" ? "⬆️" : "⬇️"),
31803
+ React$1.createElement("button", { onClick: toggleEnabled, title: "Disable Error Overlay" }, "\uD83D\uDD27"),
31804
+ React$1.createElement("button", { onClick: function () { return setIsMinimized(!isMinimized); }, title: "Minimize/Maximize" }, isMinimized ? "▲" : "▼"),
31805
+ React$1.createElement("button", { onClick: function () { return setIsVisible(false); }, title: "Close" }, "\u2715"))),
31806
+ !isMinimized && (React$1.createElement("div", { className: "error-overlay-content" }, errors.map(function (error) { return (React$1.createElement("div", { key: error.id, className: "error-entry error-".concat(error.type) },
31807
+ React$1.createElement("div", { className: "error-header" },
31808
+ React$1.createElement("span", { className: "error-time" }, new Date(error.timestamp).toLocaleTimeString()),
31809
+ error.count > 1 && (React$1.createElement("span", { className: "error-count" },
31810
+ "(",
31811
+ error.count,
31812
+ "x)")),
31813
+ React$1.createElement("span", { className: "error-badge error-badge-".concat(error.type) }, error.type)),
31814
+ React$1.createElement("div", { className: "error-message" }, error.message),
31815
+ error.stack && (React$1.createElement("details", { className: "error-stack" },
31816
+ React$1.createElement("summary", null, "Stack trace"),
31817
+ React$1.createElement("pre", null, error.stack))))); })))));
31818
+ };
31819
+
31436
31820
  var ModalContent = function (_a) {
31437
31821
  var onClose = _a.onClose, onReset = _a.onReset;
31438
31822
  return (React$1.createElement("div", { className: "modalContent" },
@@ -31445,7 +31829,44 @@ var ModalContent = function (_a) {
31445
31829
  };
31446
31830
 
31447
31831
  var ChatWidgetWrapper = function (props) {
31448
- var rawConfig = props.config;
31832
+ var _a;
31833
+ var _b = useState(props.config), rawConfig = _b[0], setRawConfig = _b[1];
31834
+ var _c = useState(!!props.getConfig), configLoading = _c[0], setConfigLoading = _c[1];
31835
+ var _d = useState(), configError = _d[0], setConfigError = _d[1];
31836
+ // Load config from callback if provided
31837
+ useEffect(function () {
31838
+ var cancelled = false;
31839
+ if (props.getConfig) {
31840
+ setConfigLoading(true);
31841
+ setConfigError(undefined);
31842
+ props
31843
+ .getConfig()
31844
+ .then(function (config) {
31845
+ if (!cancelled) {
31846
+ setRawConfig(config);
31847
+ setConfigLoading(false);
31848
+ log("[ChatWidget] Config loaded from getConfig callback");
31849
+ }
31850
+ })
31851
+ .catch(function (error) {
31852
+ if (!cancelled) {
31853
+ setConfigError(error);
31854
+ setConfigLoading(false);
31855
+ err("[ChatWidget] Failed to load config: ".concat(error.message));
31856
+ }
31857
+ });
31858
+ }
31859
+ else if (props.config) {
31860
+ // If no callback, use the config prop directly
31861
+ setRawConfig(props.config);
31862
+ setConfigLoading(false);
31863
+ }
31864
+ return function () {
31865
+ cancelled = true;
31866
+ };
31867
+ // Only depend on getConfig and config - not the entire props object to avoid infinite loops
31868
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31869
+ }, [props.getConfig, props.config]);
31449
31870
  var connection = useConnectionInfo(rawConfig);
31450
31871
  var config = useMemo(function () {
31451
31872
  var _a;
@@ -31454,7 +31875,7 @@ var ChatWidgetWrapper = function (props) {
31454
31875
  var token = useSelector(function (state) { return state.connection.token; });
31455
31876
  var options = useMemo(function () {
31456
31877
  var configurableMessages = getConfigurableMessages();
31457
- if (rawConfig.configurableMessages &&
31878
+ if ((rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.configurableMessages) &&
31458
31879
  Array.isArray(rawConfig.configurableMessages.items) &&
31459
31880
  rawConfig.configurableMessages.items.length > 0) {
31460
31881
  configurableMessages = rawConfig.configurableMessages;
@@ -31463,20 +31884,37 @@ var ChatWidgetWrapper = function (props) {
31463
31884
  token: token,
31464
31885
  bot: {
31465
31886
  nick: "Bot",
31466
- displayName: rawConfig.botName,
31467
- avatarPath: rawConfig.avatarUrl
31887
+ displayName: rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.botName,
31888
+ avatarPath: rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.avatarUrl,
31468
31889
  },
31469
31890
  configurableMessages: configurableMessages,
31470
- hooks: rawConfig.hooks
31891
+ hooks: rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.hooks,
31471
31892
  };
31472
31893
  }, [token, rawConfig]);
31473
- var chatServer = useChatServer(connection, options);
31894
+ // Only create chat server when config is ready (not loading and no error)
31895
+ var chatServer = useChatServer(configLoading || configError ? null : connection, configLoading || configError ? null : options);
31896
+ // Determine mode class for loading/error states
31897
+ var mode = (_a = props.mode) !== null && _a !== void 0 ? _a : "normal";
31898
+ var modeClass = "widget-container--".concat(mode);
31899
+ // Show loading state while config is being fetched
31900
+ if (configLoading) {
31901
+ return (React$1.createElement("div", { className: "widget-container widget-container--loading ".concat(modeClass) },
31902
+ React$1.createElement("div", { className: "xa-spinner-container visible" },
31903
+ React$1.createElement("div", { className: "xa-spinner" }))));
31904
+ }
31905
+ // Show error state if config failed to load
31906
+ if (configError) {
31907
+ return (React$1.createElement("div", { className: "widget-container widget-container--error ".concat(modeClass) },
31908
+ React$1.createElement("div", { className: "widget-error-message" },
31909
+ "Failed to load chat configuration: ",
31910
+ configError.message)));
31911
+ }
31474
31912
  return (React$1.createElement(ChatConfigContext.Provider, { value: config },
31475
31913
  React$1.createElement(ChatServerContext.Provider, { value: chatServer },
31476
- React$1.createElement(ChatWidget, __assign({}, props)))));
31914
+ React$1.createElement(ChatWidget, __assign({}, props, { config: rawConfig })))));
31477
31915
  };
31478
31916
  var ChatWidget = function (props) {
31479
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
31917
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
31480
31918
  var innerDispatch = useChatDispatch();
31481
31919
  var dispatch = useChatServerDispatch();
31482
31920
  // From Redux
@@ -31490,7 +31928,7 @@ var ChatWidget = function (props) {
31490
31928
  var canRefresh = (_c = (_b = props.config.header) === null || _b === void 0 ? void 0 : _b.actions) === null || _c === void 0 ? void 0 : _c.refresh;
31491
31929
  // can't minimize in docked mode or static mode.
31492
31930
  var canMinimize = !dockedMode && !staticMode && ((_e = (_d = props.config.header) === null || _d === void 0 ? void 0 : _d.actions) === null || _e === void 0 ? void 0 : _e.minimize);
31493
- log("docked: ".concat(dockedMode, " static: ").concat(staticMode, " minimimized: ").concat((_g = (_f = props.config.header) === null || _f === void 0 ? void 0 : _f.actions) === null || _g === void 0 ? void 0 : _g.minimize));
31931
+ log("docked: ".concat(dockedMode, " static: ").concat(staticMode, " minimized: ").concat((_g = (_f = props.config.header) === null || _f === void 0 ? void 0 : _f.actions) === null || _g === void 0 ? void 0 : _g.minimize));
31494
31932
  var canCancel;
31495
31933
  // To preserve legacy behavior, cancel needs a little more checks
31496
31934
  if (typeof ((_j = (_h = props.config.header) === null || _h === void 0 ? void 0 : _h.actions) === null || _j === void 0 ? void 0 : _j.cancel) === "boolean") {
@@ -31499,17 +31937,17 @@ var ChatWidget = function (props) {
31499
31937
  else {
31500
31938
  canCancel = !dockedMode && !staticMode;
31501
31939
  }
31502
- // For backward compatibility. Note: the action will create the actual "visuals" object" (this is a copy).
31940
+ // For backward compatibility. Note: the action will create the actual "visuals" object" (this is a copy).
31503
31941
  if (!chatState.visuals) {
31504
31942
  chatState.visuals = {};
31505
31943
  }
31506
31944
  // Our state - pull from storage
31507
- var _3 = useState((!canMinimize && !canCancel) ||
31945
+ var _8 = useState((!canMinimize && !canCancel) ||
31508
31946
  // !!get("visible") ||
31509
31947
  chatState.visuals.visible ||
31510
31948
  (((_m = props.config) === null || _m === void 0 ? void 0 : _m.autoOpenOnWidth) &&
31511
- window.matchMedia("(min-width: ".concat((_o = props.config) === null || _o === void 0 ? void 0 : _o.autoOpenOnWidth, ")")).matches)), visible = _3[0], setVisibleState = _3[1];
31512
- var _4 = useState(false), typing = _4[0], setTypingState = _4[1]; // false initially
31949
+ window.matchMedia("(min-width: ".concat((_o = props.config) === null || _o === void 0 ? void 0 : _o.autoOpenOnWidth, ")")).matches)), visible = _8[0], setVisibleState = _8[1];
31950
+ var _9 = useState(false), typing = _9[0], setTypingState = _9[1]; // false initially
31513
31951
  var chatServer = useContext(ChatServerContext);
31514
31952
  var patternsConfig = (_q = (_p = props.config) === null || _p === void 0 ? void 0 : _p.autoOpenOnPattern) === null || _q === void 0 ? void 0 : _q.patterns;
31515
31953
  var currentUrl = window.location.href;
@@ -31524,32 +31962,36 @@ var ChatWidget = function (props) {
31524
31962
  }
31525
31963
  setVisibleState(newVisible);
31526
31964
  innerDispatch(setVisualStatus({
31527
- visible: newVisible
31965
+ visible: newVisible,
31528
31966
  }));
31529
31967
  }, [innerDispatch, staticMode]);
31530
31968
  useEffect(function () {
31531
31969
  var _a, _b;
31532
- document.addEventListener("keydown", function (event) {
31970
+ var handleKeyDown = function (event) {
31533
31971
  var body = document.getElementsByTagName("body")[0];
31534
31972
  body.tabIndex = -1;
31535
31973
  if (event.key === "Escape") {
31536
31974
  body.focus();
31537
31975
  }
31538
- });
31976
+ };
31977
+ document.addEventListener("keydown", handleKeyDown);
31539
31978
  if (checkSessionExpiration((chatState === null || chatState === void 0 ? void 0 : chatState.sessionExpiration) || ((_a = props.config) === null || _a === void 0 ? void 0 : _a.sessionExpiration), (_b = chatState === null || chatState === void 0 ? void 0 : chatState.chats[chatState.chats.length - 1]) === null || _b === void 0 ? void 0 : _b.timestamp, chatState === null || chatState === void 0 ? void 0 : chatState.lastTimestamp)) {
31540
31979
  innerDispatch(setSessionId(undefined));
31541
31980
  innerDispatch(reset());
31542
31981
  }
31982
+ return function () {
31983
+ document.removeEventListener("keydown", handleKeyDown);
31984
+ };
31543
31985
  // eslint-disable-next-line react-hooks/exhaustive-deps
31544
31986
  }, []);
31545
- var _5 = useState(!document.hidden), isTabVisible = _5[0], setIsTabVisible = _5[1];
31987
+ var _10 = useState(!document.hidden), isTabVisible = _10[0], setIsTabVisible = _10[1];
31546
31988
  useEffect(function () {
31547
31989
  var handleVisibilityChange = function () {
31548
31990
  setIsTabVisible(!document.hidden);
31549
31991
  };
31550
- document.addEventListener('visibilitychange', handleVisibilityChange);
31992
+ document.addEventListener("visibilitychange", handleVisibilityChange);
31551
31993
  return function () {
31552
- document.removeEventListener('visibilitychange', handleVisibilityChange);
31994
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
31553
31995
  };
31554
31996
  }, []);
31555
31997
  useEffect(function () {
@@ -31583,7 +32025,15 @@ var ChatWidget = function (props) {
31583
32025
  if (currentWidth < +configWidth) {
31584
32026
  setVisible(false);
31585
32027
  }
31586
- }, [currentWidth, patternExist, patternMatches, configWidth, setVisible, chatState.visuals.opened, mode]);
32028
+ }, [
32029
+ currentWidth,
32030
+ patternExist,
32031
+ patternMatches,
32032
+ configWidth,
32033
+ setVisible,
32034
+ chatState.visuals.opened,
32035
+ mode,
32036
+ ]);
31587
32037
  function handleOnChange() {
31588
32038
  if (!typing) {
31589
32039
  dispatch(sendTyping(true));
@@ -31655,28 +32105,37 @@ var ChatWidget = function (props) {
31655
32105
  /** Called when minimize button is clicked */
31656
32106
  function handleMinimizeClick() {
31657
32107
  innerDispatch(setVisualStatus({
31658
- opened: false
32108
+ opened: false,
32109
+ hasInteracted: true,
31659
32110
  }));
31660
32111
  setVisible(false);
31661
32112
  }
31662
32113
  /** Called when cancel is clicked */
31663
32114
  function handleCancelClick() {
31664
- //set("opened", false);
32115
+ // First reset to clear all state
32116
+ innerDispatch(reset());
32117
+ // Then set hasInteracted to prevent CTA from showing after cancel
31665
32118
  innerDispatch(setVisualStatus({
31666
- opened: false
32119
+ opened: false,
32120
+ hasInteracted: true,
31667
32121
  }));
31668
- innerDispatch(reset());
31669
32122
  setVisible(false);
31670
32123
  }
31671
32124
  function chatButtonOnClick() {
31672
32125
  innerDispatch(setVisualStatus({
31673
- opened: true
32126
+ opened: true,
32127
+ hasInteracted: true,
31674
32128
  }));
31675
32129
  setVisible(true);
31676
32130
  setTimeout(function () {
31677
32131
  document.getElementById("chatWidgetInput").focus();
31678
32132
  }, 100);
31679
32133
  }
32134
+ function handleCtaDismiss() {
32135
+ innerDispatch(setVisualStatus({
32136
+ hasInteracted: true,
32137
+ }));
32138
+ }
31680
32139
  var isOffline = chatState.accountStatus === "offline" && !chatState.isChatting;
31681
32140
  var messages = chatState && chatState.chats;
31682
32141
  var config = props.config, onConnectionStatusChange = props.onConnectionStatusChange;
@@ -31689,8 +32148,12 @@ var ChatWidget = function (props) {
31689
32148
  }, [connectionStatus, onConnectionStatusChange]);
31690
32149
  useExternalScript((_t = props.config) === null || _t === void 0 ? void 0 : _t.middlewareUrl);
31691
32150
  // This is a pseudo agent. It represent's the widget (shown in the header avatar for instance)
31692
- var widgetAgent = ((_u = chatState.agents["agent:robot"]) === null || _u === void 0 ? void 0 : _u.user) || (config === null || config === void 0 ? void 0 : config.agent)
31693
- || { nick: "agent:robot", avatarPath: config.avatarUrl, display_name: "Agent" };
32151
+ var widgetAgent = ((_u = chatState.agents["agent:robot"]) === null || _u === void 0 ? void 0 : _u.user) ||
32152
+ (config === null || config === void 0 ? void 0 : config.agent) || {
32153
+ nick: "agent:robot",
32154
+ avatarPath: config.avatarUrl,
32155
+ display_name: "Agent",
32156
+ };
31694
32157
  return (React$1.createElement(React$1.Fragment, null,
31695
32158
  React$1.createElement("div", { className: "widget-container ".concat(modeClass, " ").concat(getVisibilityClass()) },
31696
32159
  React$1.createElement(WidgetStylesheet, { theme: config === null || config === void 0 ? void 0 : config.theme }),
@@ -31699,10 +32162,11 @@ var ChatWidget = function (props) {
31699
32162
  React$1.createElement("div", { className: "xa-spinner-container ".concat(visible && connectionStatus === "pending" ? "visible" : "") },
31700
32163
  React$1.createElement("div", { className: "xa-spinner" })),
31701
32164
  connectionStatus === "offline" && React$1.createElement(ServerOffline, null),
31702
- React$1.createElement(ChatFooter, { isAdmin: config === null || config === void 0 ? void 0 : config.isAdmin, isChatting: chatState.isChatting, placeholder: (_x = config === null || config === void 0 ? void 0 : config.input) === null || _x === void 0 ? void 0 : _x.placeholder, sendButtonIcon: (_z = (_y = config === null || config === void 0 ? void 0 : config.footer) === null || _y === void 0 ? void 0 : _y.sendButton) === null || _z === void 0 ? void 0 : _z.icon, visible: visible, menuConfig: props.config.menu, footerConfig: (_0 = props.config) === null || _0 === void 0 ? void 0 : _0.footer, inputConfig: (_1 = props.config) === null || _1 === void 0 ? void 0 : _1.input, onChange: handleOnChange, onSubmit: handleOnSubmit, onFileUpload: handleFileUpload }),
32165
+ React$1.createElement(ChatFooter, { isAdmin: config === null || config === void 0 ? void 0 : config.isAdmin, isChatting: chatState.isChatting, placeholder: (_x = config === null || config === void 0 ? void 0 : config.input) === null || _x === void 0 ? void 0 : _x.placeholder, sendButtonIcon: (_z = (_y = config === null || config === void 0 ? void 0 : config.footer) === null || _y === void 0 ? void 0 : _y.sendButton) === null || _z === void 0 ? void 0 : _z.icon, sendButtonIconHover: (_1 = (_0 = config === null || config === void 0 ? void 0 : config.footer) === null || _0 === void 0 ? void 0 : _0.sendButton) === null || _1 === void 0 ? void 0 : _1.iconHover, sendButtonIconDisabled: (_3 = (_2 = config === null || config === void 0 ? void 0 : config.footer) === null || _2 === void 0 ? void 0 : _2.sendButton) === null || _3 === void 0 ? void 0 : _3.iconDisabled, visible: visible, menuConfig: props.config.menu, footerConfig: (_4 = props.config) === null || _4 === void 0 ? void 0 : _4.footer, inputConfig: (_5 = props.config) === null || _5 === void 0 ? void 0 : _5.input, onChange: handleOnChange, onSubmit: handleOnSubmit, onFileUpload: handleFileUpload }),
31703
32166
  React$1.createElement("div", { className: "restartModal", ref: modalRef, onClick: handleRestartModalCloseClick },
31704
32167
  React$1.createElement(ModalContent, { onClose: handleRestartModalCloseClick, onReset: handleReset }))),
31705
- React$1.createElement(ChatButton, { addClass: getVisibilityClass(), onClick: chatButtonOnClick, config: config === null || config === void 0 ? void 0 : config.cta, imageUrl: (_2 = config === null || config === void 0 ? void 0 : config.chatButton) === null || _2 === void 0 ? void 0 : _2.imageUrl, visible: visible })));
32168
+ React$1.createElement(ChatButton, { addClass: getVisibilityClass(), onClick: chatButtonOnClick, config: config === null || config === void 0 ? void 0 : config.cta, imageUrl: (_6 = config === null || config === void 0 ? void 0 : config.chatButton) === null || _6 === void 0 ? void 0 : _6.imageUrl, visible: visible, hasInteracted: (_7 = chatState.visuals) === null || _7 === void 0 ? void 0 : _7.hasInteracted, onCtaDismiss: handleCtaDismiss }),
32169
+ React$1.createElement(ErrorOverlay, null)));
31706
32170
  };
31707
32171
 
31708
32172
  // src/utils/formatProdErrorMessage.ts
@@ -32179,17 +32643,37 @@ var DEFAULT_VISITOR = {
32179
32643
  nick: "visitor:",
32180
32644
  typing: false
32181
32645
  };
32182
- function createDefaultState(state) {
32646
+ function createDefaultState(state, options) {
32647
+ var _a;
32183
32648
  if (!state) {
32184
32649
  state = {};
32185
32650
  }
32186
32651
  state.userId = state.userId ? state.userId : visitorFingerprint();
32187
32652
  state.visitorId = state.userId;
32653
+ // Determine if debug mode should be enabled
32654
+ var debugMode = false;
32655
+ if (typeof window !== 'undefined') {
32656
+ var localStorageSetting = (_a = window.localStorage) === null || _a === void 0 ? void 0 : _a.getItem('xaErrorOverlay');
32657
+ if (localStorageSetting === 'enabled') {
32658
+ debugMode = true;
32659
+ }
32660
+ else if (localStorageSetting === 'disabled') {
32661
+ debugMode = false;
32662
+ }
32663
+ else if (options === null || options === void 0 ? void 0 : options.enableErrorOverlay) {
32664
+ // Use config option if no localStorage override
32665
+ debugMode = true;
32666
+ }
32667
+ else if (typeof globalThis.__DEV__ !== 'undefined' && globalThis.__DEV__) {
32668
+ // For React Native, default to true in development mode
32669
+ debugMode = true;
32670
+ }
32671
+ }
32188
32672
  return __assign({ connection: {
32189
32673
  connectionStatus: "offline",
32190
32674
  token: null,
32191
32675
  greetingRequested: false
32192
- }, accountStatus: "offline", departments: {}, visitor: DEFAULT_VISITOR, agents: {}, chats: [], lastTimestamp: 0, lastRatingRequestTimestamp: 0, hasRating: false, isChatting: false, queuePosition: 0, failureMsg: null, visitorId: visitorFingerprint(), chips: [], sessionExpiration: "24h", visuals: {} }, state);
32676
+ }, accountStatus: "offline", departments: {}, visitor: DEFAULT_VISITOR, agents: {}, chats: [], lastTimestamp: 0, lastRatingRequestTimestamp: 0, hasRating: false, isChatting: false, queuePosition: 0, failureMsg: null, visitorId: visitorFingerprint(), chips: [], sessionExpiration: "24h", visuals: {}, debugMode: debugMode }, state);
32193
32677
  }
32194
32678
  var DEFAULT_STATE = createDefaultState();
32195
32679
 
@@ -32238,6 +32722,10 @@ var LocalStorage = /** @class */ (function () {
32238
32722
  function persistStateReducer(storage, initialState, innerReducer) {
32239
32723
  var _a;
32240
32724
  var obj = (_a = storage.get()) !== null && _a !== void 0 ? _a : initialState;
32725
+ // Clean up hasInteracted flag on page load - don't persist across browser refreshes
32726
+ if (obj && obj.visuals) {
32727
+ obj = __assign(__assign({}, obj), { visuals: __assign(__assign({}, obj.visuals), { hasInteracted: undefined }) });
32728
+ }
32241
32729
  return function (state, action) {
32242
32730
  if (state === void 0) { state = obj; }
32243
32731
  var res = innerReducer(state, action);
@@ -32296,13 +32784,14 @@ function memberLeave(state, detail) {
32296
32784
 
32297
32785
  function resetReducer(state) {
32298
32786
  if (state === void 0) { state = DEFAULT_STATE; }
32299
- // pass through some of the items to persis
32300
32787
  return __assign(__assign({}, createDefaultState({
32301
32788
  accessToken: state.accessToken,
32302
32789
  userId: state.userId,
32303
32790
  attributes: state.attributes,
32304
32791
  sessionExpiration: state.sessionExpiration
32305
- })), { connection: __assign(__assign({}, state.connection), { greetingRequested: false, nonce: uuid_1() }), visitor: state.visitor, visitorId: state.visitorId });
32792
+ })), { connection: __assign(__assign({}, state.connection), { greetingRequested: false, nonce: uuid_1() }), visitor: state.visitor, visitorId: state.visitorId,
32793
+ // Explicitly reset visuals to clear hasInteracted flag for widget refresh
32794
+ visuals: {} });
32306
32795
  }
32307
32796
 
32308
32797
  // todo: create reducer (requires redux-thunk dependency)
@@ -32335,7 +32824,14 @@ function update(state, action) {
32335
32824
  case "session_id":
32336
32825
  return __assign(__assign({}, state), { lastTimestamp: (_g = action.detail) === null || _g === void 0 ? void 0 : _g.timestamp, sessionId: action.detail.sessionId });
32337
32826
  case "visual_status":
32338
- return __assign(__assign({}, state), { lastTimestamp: (_h = action.detail) === null || _h === void 0 ? void 0 : _h.timestamp, visuals: __assign(__assign(__assign(__assign({}, (state.visuals || {})), (action.detail.status.drawer !== undefined && { drawer: action.detail.status.drawer })), (action.detail.status.opened !== undefined && { opened: action.detail.status.opened })), (action.detail.status.visible !== undefined && { visible: action.detail.status.visible })) });
32827
+ return __assign(__assign({}, state), { lastTimestamp: (_h = action.detail) === null || _h === void 0 ? void 0 : _h.timestamp, visuals: __assign(__assign(__assign(__assign(__assign({}, (state.visuals || {})), (action.detail.status.drawer !== undefined && { drawer: action.detail.status.drawer })), (action.detail.status.opened !== undefined && { opened: action.detail.status.opened })), (action.detail.status.visible !== undefined && { visible: action.detail.status.visible })), (action.detail.status.hasInteracted !== undefined && { hasInteracted: action.detail.status.hasInteracted })) });
32828
+ case "toggle_debug_mode":
32829
+ var newDebugMode = !state.debugMode;
32830
+ // Update localStorage to persist the setting
32831
+ if (typeof window !== 'undefined' && window.localStorage) {
32832
+ window.localStorage.setItem('xaErrorOverlay', newDebugMode ? 'enabled' : 'disabled');
32833
+ }
32834
+ return __assign(__assign({}, state), { debugMode: newDebugMode });
32339
32835
  case "department_update":
32340
32836
  return __assign(__assign({}, state), { lastTimestamp: (_j = action.detail) === null || _j === void 0 ? void 0 : _j.timestamp, departments: __assign(__assign({}, state.departments), (_a = {}, _a[action.detail.id] = __assign({}, action.detail), _a)) });
32341
32837
  case "visitor_update":
@@ -32486,6 +32982,8 @@ function createChatStore(config, dataStorage) {
32486
32982
  userId: config.userId,
32487
32983
  attributes: config.attributes,
32488
32984
  sessionExpiration: config.sessionExpiration
32985
+ }, {
32986
+ enableErrorOverlay: config.enableErrorOverlay
32489
32987
  });
32490
32988
  var chatReducer = persistStateReducer(storage, defaultState, storeHandler);
32491
32989
  // Configure store with @reduxjs/toolkit
@@ -32525,23 +33023,25 @@ function generateKey(connection, sessionId) {
32525
33023
  }
32526
33024
 
32527
33025
  var ChatWidgetContainer = function (props) {
32528
- var _a, _b, _c, _d, _e;
33026
+ var _a, _b, _c, _d, _e, _f;
32529
33027
  var messageMiddleware = useStandardMiddleware();
32530
33028
  var connection = useServerConfig(props.config);
32531
33029
  var chatStore = useMemo(function () {
32532
- var _a, _b, _c, _d;
33030
+ var _a, _b, _c, _d, _e;
32533
33031
  return createChatStore({
32534
33032
  connection: connection,
32535
33033
  userId: (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId,
32536
33034
  accessToken: (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken,
32537
33035
  attributes: (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes,
32538
- sessionExpiration: (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration
33036
+ sessionExpiration: (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration,
33037
+ enableErrorOverlay: (_e = props.config) === null || _e === void 0 ? void 0 : _e.enableErrorOverlay
32539
33038
  });
32540
- }, [connection, (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId, (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken, (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes, (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration]);
32541
- if ((_e = props.config) === null || _e === void 0 ? void 0 : _e.disabled) {
33039
+ }, [connection, (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId, (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken, (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes, (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration, (_e = props.config) === null || _e === void 0 ? void 0 : _e.enableErrorOverlay]);
33040
+ if ((_f = props.config) === null || _f === void 0 ? void 0 : _f.disabled) {
32542
33041
  return React$1.createElement(React$1.Fragment, null);
32543
33042
  }
32544
- var widgetProps = __assign(__assign({}, props), { messageMiddleware: messageMiddleware });
33043
+ var widgetProps = __assign(__assign({}, props), { messageMiddleware: messageMiddleware, getConfig: props.getConfig // Pass through getConfig callback
33044
+ });
32545
33045
  return (React$1.createElement(Provider, { store: chatStore },
32546
33046
  React$1.createElement(ChatWidgetWrapper, __assign({}, widgetProps))));
32547
33047
  };