@xapp/chat-widget 1.104.1 → 1.105.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3871,6 +3871,31 @@ function useVisualViewportProperties(enabled) {
3871
3871
  return trackVisualViewport();
3872
3872
  }, [enabled]);
3873
3873
  }
3874
+ /** The sessionStorage key the booking page writes the flag to. */
3875
+ var TEST_LEAD_STORAGE_KEY = "xa_test";
3876
+ /** The attribute sent with a lead submission. */
3877
+ var TEST_LEAD_ATTRIBUTE = "xaTest";
3878
+ /** True when the current browser session is a test-lead page view. */
3879
+ function isTestLeadSession() {
3880
+ try {
3881
+ return sessionStorage.getItem(TEST_LEAD_STORAGE_KEY) === "1";
3882
+ }
3883
+ catch (_a) {
3884
+ // Storage can be blocked by the browser; treat that as a real visit.
3885
+ return false;
3886
+ }
3887
+ }
3888
+ /**
3889
+ * Tags the attributes as a test lead when the session flag is set. A test must
3890
+ * never be counted as Google traffic, so any `rwg_token` is dropped as well.
3891
+ */
3892
+ function addTestLeadAttribute(attributes) {
3893
+ if (isTestLeadSession()) {
3894
+ attributes[TEST_LEAD_ATTRIBUTE] = true;
3895
+ delete attributes["rwg_token"];
3896
+ }
3897
+ return attributes;
3898
+ }
3874
3899
 
3875
3900
  /**
3876
3901
  * Quicker configurable uuid
@@ -3894,6 +3919,7 @@ function uuid() {
3894
3919
  var IconButton_1 = IconButton;
3895
3920
  var RichInput_1 = RichInput;
3896
3921
  var SuggestionsList_1 = SuggestionsList;
3922
+ var addTestLeadAttribute_1 = addTestLeadAttribute;
3897
3923
  var findItemByIndex_1 = findItemByIndex;
3898
3924
  var getAttribution_1 = getAttribution;
3899
3925
  var getItemsLength_1 = getItemsLength;
@@ -4129,6 +4155,28 @@ function newMessage() {
4129
4155
 
4130
4156
  } (cjs));
4131
4157
 
4158
+ /**
4159
+ * Did this request fail because it never reached the server?
4160
+ *
4161
+ * The widget used to answer "the server is offline" to every failure, and on 2026-09-25 a retired
4162
+ * Bedrock model made every new chat fail with a 500 — so every visitor was told the server was
4163
+ * offline while it was up and serving. The message sent the investigation at DNS, CORS and CDNs for
4164
+ * 110 minutes and told customers something untrue.
4165
+ *
4166
+ * A status code is the discriminator: it only exists because the server answered. Present means
4167
+ * reachable-but-failing, which is a different message to a visitor and a different thing for us to
4168
+ * go and look at.
4169
+ *
4170
+ * An unrecognised failure counts as transport. It is the safer claim — "cannot reach the server"
4171
+ * when the truth is unknown is wrong in a way the visitor can act on, where leaving the widget
4172
+ * looking hung is not.
4173
+ */
4174
+ function isTransportFailure(error) {
4175
+ var status = Number(error === null || error === void 0 ? void 0 : error.statusCode);
4176
+ // A real HTTP status, so the server answered.
4177
+ return !(Number.isFinite(status) && status >= 100 && status <= 599);
4178
+ }
4179
+
4132
4180
  /**
4133
4181
  * Default configuration messages
4134
4182
  * @returns
@@ -4564,7 +4612,7 @@ var MCPChat = /** @class */ (function () {
4564
4612
  */
4565
4613
  MCPChat.prototype.initializeNewSession = function () {
4566
4614
  return __awaiter$1(this, void 0, void 0, function () {
4567
- var endpoint, error_2;
4615
+ var endpoint, error_2, statusCode;
4568
4616
  var _this = this;
4569
4617
  var _a;
4570
4618
  return __generator$1(this, function (_b) {
@@ -4594,11 +4642,18 @@ var MCPChat = /** @class */ (function () {
4594
4642
  return [3 /*break*/, 5];
4595
4643
  case 3:
4596
4644
  error_2 = _b.sent();
4597
- err("Failed to initialize new session: ".concat(error_2));
4645
+ statusCode = error_2 === null || error_2 === void 0 ? void 0 : error_2.statusCode;
4646
+ err("Failed to initialize new session: ".concat(error_2, ", statusCode: ").concat(statusCode));
4598
4647
  this.stopTyping();
4599
- this.setConnectionStatus("offline");
4648
+ // Only "offline" when the request never reached the server. A status code means it
4649
+ // answered, so the server is up and something behind it is broken -- and on 2026-09-25
4650
+ // a 500 from a retired model put "Server is offline" in front of every visitor, which
4651
+ // was untrue and sent the investigation at DNS, CORS and CDNs for 110 minutes.
4652
+ if (isTransportFailure(error_2)) {
4653
+ this.setConnectionStatus("offline");
4654
+ }
4600
4655
  // Show a failure message but don't block - user can still try sending messages
4601
- this.sendFailureMessage(0, 0, this.getErrorMessage(error_2));
4656
+ this.sendFailureMessage(0, 0, this.getErrorMessage(error_2, statusCode));
4602
4657
  return [3 /*break*/, 5];
4603
4658
  case 4:
4604
4659
  this.isInitializingSession = false;
@@ -5130,8 +5185,11 @@ var MCPChat = /** @class */ (function () {
5130
5185
  this.sendFailureMessage(0, 0, errorMessage);
5131
5186
  return [2 /*return*/];
5132
5187
  }
5133
- // Set offline status
5134
- this.setConnectionStatus("offline");
5188
+ // Same rule: a 5xx is the server answering, so it is not offline. Left as a
5189
+ // retryable failure, which is what the loop below treats it as anyway.
5190
+ if (isTransportFailure(error_4)) {
5191
+ this.setConnectionStatus("offline");
5192
+ }
5135
5193
  if (!isLastAttempt) return [3 /*break*/, 7];
5136
5194
  statusCode_1 = error_4 === null || error_4 === void 0 ? void 0 : error_4.statusCode;
5137
5195
  errorMessage = config.text || this.getErrorMessage(error_4, statusCode_1);
@@ -5693,7 +5751,7 @@ var MCPChat = /** @class */ (function () {
5693
5751
  };
5694
5752
  MCPChat.prototype.requestReplay = function () {
5695
5753
  return __awaiter$1(this, void 0, void 0, function () {
5696
- var error_5;
5754
+ var error_5, statusCode;
5697
5755
  return __generator$1(this, function (_a) {
5698
5756
  switch (_a.label) {
5699
5757
  case 0:
@@ -5715,8 +5773,12 @@ var MCPChat = /** @class */ (function () {
5715
5773
  return [3 /*break*/, 5];
5716
5774
  case 3:
5717
5775
  error_5 = _a.sent();
5718
- err("[MCPChat] Replay request failed: ".concat(error_5));
5719
- this.setConnectionStatus("offline");
5776
+ statusCode = error_5 === null || error_5 === void 0 ? void 0 : error_5.statusCode;
5777
+ err("[MCPChat] Replay request failed: ".concat(error_5, ", statusCode: ").concat(statusCode));
5778
+ // Same rule as session init: a status code means the server answered.
5779
+ if (isTransportFailure(error_5)) {
5780
+ this.setConnectionStatus("offline");
5781
+ }
5720
5782
  return [3 /*break*/, 5];
5721
5783
  case 4:
5722
5784
  this.stopTyping();
@@ -6363,6 +6425,8 @@ var StentorDirectChat = /** @class */ (function () {
6363
6425
  if (origin) {
6364
6426
  attributes["origin"] = origin;
6365
6427
  }
6428
+ // A test lead from Studio's "send yourself a test lead" booking page
6429
+ addTestLeadAttribute_1(attributes);
6366
6430
  // Add current time for accurate date/time responses
6367
6431
  attributes["currentTime"] = new Date().toISOString();
6368
6432
  now = new Date().getTime();
@@ -7591,6 +7655,8 @@ var StentorRouterChat = /** @class */ (function () {
7591
7655
  if (origin) {
7592
7656
  attributes["origin"] = origin;
7593
7657
  }
7658
+ // A test lead from Studio's "send yourself a test lead" booking page
7659
+ addTestLeadAttribute_1(attributes);
7594
7660
  // Add current time for accurate date/time responses
7595
7661
  attributes["currentTime"] = new Date().toISOString();
7596
7662
  request = requestFromMessage(message, userId, this.isNewSession, sessionId, accessToken, attributes, this.visitorInfo);
@@ -35900,8 +35966,17 @@ var MessageList = function (_a) {
35900
35966
  return (require$$0.jsxs("div", { className: "message-list-container", ref: containerRef, children: [require$$0.jsxs("div", { className: "message-list-container__msgs", children: [renderAll(), require$$0.jsx("div", { ref: messagesEndRef, style: { float: "left", clear: "both" } }), require$$0.jsx(QueuePosition, { position: queuePosition }), require$$0.jsx(TypingStatus, { agents: agents, textTypingStatusEnabled: textTypingStatusEnabled })] }), require$$0.jsx(ChatChipsContainer, {})] }));
35901
35967
  };
35902
35968
 
35969
+ /**
35970
+ * Shown when a chat request never reached the server -- see `isTransportFailure`.
35971
+ *
35972
+ * This overlay covers the conversation, so its two lines are the only thing the visitor sees. It
35973
+ * used to appear for every failure and say "Server is offline", which on 2026-09-25 was put in
35974
+ * front of every visitor by a 500 from a server that was up and serving. The copy is now limited to
35975
+ * what a failed request actually proves -- we could not reach it -- and names the one thing a
35976
+ * visitor can do about it.
35977
+ */
35903
35978
  var ServerOffline = function () {
35904
- return (require$$0.jsxs("div", { className: "server-offline", children: [require$$0.jsx("h2", { children: "Chat is currently unavailable" }), require$$0.jsx("h3", { children: "Server is offline" })] }));
35979
+ return (require$$0.jsxs("div", { className: "server-offline", children: [require$$0.jsx("h2", { children: "We can't reach the chat right now" }), require$$0.jsx("h3", { children: "Check your connection and try again in a moment." })] }));
35905
35980
  };
35906
35981
 
35907
35982
  /**