@eshal-bot/chat-widget 0.1.122 → 0.1.123
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/{chat-widget-MarkdownRenderer-BTPQ0BG0.esm.js → chat-widget-MarkdownRenderer-B5jGiiT4.esm.js} +11 -5
- package/dist/{chat-widget-index-CbBUA9Lj.esm.js → chat-widget-index-Bn-k9Jjr.esm.js} +1 -1
- package/dist/chat-widget-markdown-chunk.js +621 -239
- package/dist/chat-widget-markdown-chunk.min.js +26 -26
- package/dist/chat-widget.esm.js +1 -1
- package/dist/chat-widget.js +82 -31
- package/dist/chat-widget.min.js +4 -4
- package/dist/chat-widget.umd.js +7 -7
- package/package.json +1 -1
package/dist/chat-widget.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{S as default}from"./chat-widget-index-
|
|
1
|
+
export{S as default}from"./chat-widget-index-Bn-k9Jjr.esm.js";import"react";import"react-dom/client";import"react-dom";import"react/jsx-runtime";
|
package/dist/chat-widget.js
CHANGED
|
@@ -16627,6 +16627,11 @@
|
|
|
16627
16627
|
};
|
|
16628
16628
|
}, [isVoiceSessionActive, voiceStatus]);
|
|
16629
16629
|
const normalizedDisclaimerLinkUrl = reactExports.useMemo(() => normalizeExternalUrl(disclaimerLinkUrl), [disclaimerLinkUrl]);
|
|
16630
|
+
|
|
16631
|
+
// EV-2351: the disclaimer's direction comes from its own text. Falls back to
|
|
16632
|
+
// the configured `isRtl` when the text has no strongly-directional character
|
|
16633
|
+
// (digits, punctuation, emoji only), same contract as the message bubbles.
|
|
16634
|
+
const disclaimerIsRtl = reactExports.useMemo(() => detectTextDirection(disclaimerText, isRtl), [disclaimerText, isRtl]);
|
|
16630
16635
|
return /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
16631
16636
|
children: [disclaimerEnabled && disclaimerText && disclaimerPosition === "top" && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
|
|
16632
16637
|
className: "flex justify-center",
|
|
@@ -16636,13 +16641,21 @@
|
|
|
16636
16641
|
color: isDark ? "#d1d5db" : "#6b7280",
|
|
16637
16642
|
fontFamily: fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter",
|
|
16638
16643
|
fontSize: fontSize !== undefined && fontSize !== null ? "calc(".concat(fontSize, " - 2px)") : "12px",
|
|
16639
|
-
|
|
16644
|
+
// EV-2351: direction from the disclaimer's OWN text, not from
|
|
16645
|
+
// the configured default language. This is static configured
|
|
16646
|
+
// copy rather than message content, which is why the earlier
|
|
16647
|
+
// per-message passes never reached it - an English disclaimer
|
|
16648
|
+
// under an Arabic-default concierge rendered with its trailing
|
|
16649
|
+
// period pushed to the front (".Please verify important
|
|
16650
|
+
// information"). Same helper and same fallback as the message
|
|
16651
|
+
// bubbles below.
|
|
16652
|
+
direction: disclaimerIsRtl ? "rtl" : "ltr",
|
|
16640
16653
|
textAlign: "center",
|
|
16641
16654
|
borderColor: isDark ? "#374151" : "#e5e7eb"
|
|
16642
16655
|
},
|
|
16643
16656
|
children: /*#__PURE__*/jsxRuntimeExports.jsxs("p", {
|
|
16644
16657
|
className: "leading-relaxed whitespace-pre-wrap break-words inline",
|
|
16645
|
-
dir:
|
|
16658
|
+
dir: disclaimerIsRtl ? "rtl" : "ltr",
|
|
16646
16659
|
style: {
|
|
16647
16660
|
color: isDark ? "#d1d5db" : "#6b7280",
|
|
16648
16661
|
fontFamily: fontFamily !== undefined && fontFamily !== null ? fontFamily : "Inter",
|
|
@@ -17107,24 +17120,42 @@
|
|
|
17107
17120
|
return;
|
|
17108
17121
|
}
|
|
17109
17122
|
|
|
17110
|
-
//
|
|
17111
|
-
//
|
|
17112
|
-
//
|
|
17113
|
-
//
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17123
|
+
// How many bytes the SERVER is currently holding for this attachment.
|
|
17124
|
+
// Only ever non-zero when we know a reservation exists (EV-2791) -
|
|
17125
|
+
// releasing bytes the server never reserved silently hands the
|
|
17126
|
+
// conversation extra budget, which is as wrong as over-counting.
|
|
17127
|
+
let heldServerBytes = 0;
|
|
17128
|
+
const releaseHeld = () => {
|
|
17129
|
+
if (heldServerBytes > 0) {
|
|
17130
|
+
releaseSessionBytes({
|
|
17131
|
+
apiEndpoint,
|
|
17132
|
+
conversationId,
|
|
17133
|
+
size: heldServerBytes,
|
|
17134
|
+
authHeader
|
|
17135
|
+
});
|
|
17136
|
+
heldServerBytes = 0;
|
|
17137
|
+
patchAttachment(attachmentId, {
|
|
17138
|
+
reservedBytes: 0
|
|
17139
|
+
});
|
|
17140
|
+
}
|
|
17141
|
+
};
|
|
17142
|
+
const undoLocalEstimate = () => {
|
|
17143
|
+
sessionBytesRef.current.bytes = Math.max(0, sessionBytesRef.current.bytes - file.size);
|
|
17144
|
+
};
|
|
17117
17145
|
let presign;
|
|
17118
17146
|
try {
|
|
17119
17147
|
presign = await presignRes.json();
|
|
17120
17148
|
} catch (_unused5) {
|
|
17149
|
+
// Body unreadable, so we cannot tell whether a reservation was made.
|
|
17150
|
+
// Release the declared size - the server clamps at zero, and this
|
|
17151
|
+
// path needs the policy check to have already passed.
|
|
17121
17152
|
releaseSessionBytes({
|
|
17122
17153
|
apiEndpoint,
|
|
17123
17154
|
conversationId,
|
|
17124
17155
|
size: file.size,
|
|
17125
17156
|
authHeader
|
|
17126
17157
|
});
|
|
17127
|
-
|
|
17158
|
+
undoLocalEstimate();
|
|
17128
17159
|
patchAttachment(attachmentId, {
|
|
17129
17160
|
reservedBytes: 0
|
|
17130
17161
|
});
|
|
@@ -17132,6 +17163,20 @@
|
|
|
17132
17163
|
return;
|
|
17133
17164
|
}
|
|
17134
17165
|
|
|
17166
|
+
// `reserved` tells us whether /presign itself charged the session cap.
|
|
17167
|
+
// It is false on the NFS/multipart branch, where /multipart is the
|
|
17168
|
+
// reserving gate - reserving in both places is what double-counted the
|
|
17169
|
+
// "already used" figure (EV-2791). An older backend omits the field;
|
|
17170
|
+
// fall back to the legacy assumption so a widget deployed ahead of the
|
|
17171
|
+
// backend still releases correctly.
|
|
17172
|
+
const presignReserved = typeof presign.reserved === "boolean" ? presign.reserved : !presign.useMultipart;
|
|
17173
|
+
if (presignReserved) {
|
|
17174
|
+
heldServerBytes = file.size;
|
|
17175
|
+
patchAttachment(attachmentId, {
|
|
17176
|
+
reservedBytes: file.size
|
|
17177
|
+
});
|
|
17178
|
+
}
|
|
17179
|
+
|
|
17135
17180
|
// Step B - upload bytes. Two paths:
|
|
17136
17181
|
// * useMultipart=true → POST FormData to /multipart (NFS + any
|
|
17137
17182
|
// backend without a direct-PUT endpoint).
|
|
@@ -17160,6 +17205,13 @@
|
|
|
17160
17205
|
});
|
|
17161
17206
|
uploadedReadUrl = multipartResp.url;
|
|
17162
17207
|
uploadedStorageKey = multipartResp.storageKey;
|
|
17208
|
+
// /multipart is the reserving gate on this path, and it only
|
|
17209
|
+
// reserves once its own policy check passes - the bytes are held
|
|
17210
|
+
// from here on, so removing the chip must release them.
|
|
17211
|
+
heldServerBytes = file.size;
|
|
17212
|
+
patchAttachment(attachmentId, {
|
|
17213
|
+
reservedBytes: file.size
|
|
17214
|
+
});
|
|
17163
17215
|
} else if (presign.uploadUrl) {
|
|
17164
17216
|
await putWithProgress({
|
|
17165
17217
|
url: presign.uploadUrl,
|
|
@@ -17186,16 +17238,8 @@
|
|
|
17186
17238
|
});
|
|
17187
17239
|
if (!confirmed.ok) {
|
|
17188
17240
|
inflightRef.current.delete(attachmentId);
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
conversationId,
|
|
17192
|
-
size: file.size,
|
|
17193
|
-
authHeader
|
|
17194
|
-
});
|
|
17195
|
-
sessionBytesRef.current.bytes = Math.max(0, sessionBytesRef.current.bytes - file.size);
|
|
17196
|
-
patchAttachment(attachmentId, {
|
|
17197
|
-
reservedBytes: 0
|
|
17198
|
-
});
|
|
17241
|
+
releaseHeld();
|
|
17242
|
+
undoLocalEstimate();
|
|
17199
17243
|
errorPatch(attachmentId, confirmed.code, confirmed.message);
|
|
17200
17244
|
return;
|
|
17201
17245
|
}
|
|
@@ -17207,16 +17251,12 @@
|
|
|
17207
17251
|
// Aborted means removeAttachment already released this reservation -
|
|
17208
17252
|
// releasing again here would double-count the give-back.
|
|
17209
17253
|
if (err && err.aborted) return;
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
|
|
17214
|
-
|
|
17215
|
-
|
|
17216
|
-
sessionBytesRef.current.bytes = Math.max(0, sessionBytesRef.current.bytes - file.size);
|
|
17217
|
-
patchAttachment(attachmentId, {
|
|
17218
|
-
reservedBytes: 0
|
|
17219
|
-
});
|
|
17254
|
+
// On the multipart path a failure means either the policy check
|
|
17255
|
+
// rejected (nothing reserved) or the write failed (the route released
|
|
17256
|
+
// its own reservation) - `heldServerBytes` is 0 either way, so
|
|
17257
|
+
// releaseHeld() correctly does nothing.
|
|
17258
|
+
releaseHeld();
|
|
17259
|
+
undoLocalEstimate();
|
|
17220
17260
|
errorPatch(attachmentId, "network", "Upload failed. Please retry.");
|
|
17221
17261
|
return;
|
|
17222
17262
|
}
|
|
@@ -18190,6 +18230,15 @@
|
|
|
18190
18230
|
useGoogleFont(resolvedHeaderFontFamily);
|
|
18191
18231
|
const t = reactExports.useMemo(() => createTranslator(defaultLanguage), [defaultLanguage]);
|
|
18192
18232
|
const isRtl = isRtlLocale(defaultLanguage);
|
|
18233
|
+
|
|
18234
|
+
// EV-2351: the subtitle is operator-authored copy, so its direction has to
|
|
18235
|
+
// come from the text itself rather than from the configured default
|
|
18236
|
+
// language. With Arabic as the default, an English subtitle inherited the
|
|
18237
|
+
// header's RTL container and rendered with its trailing punctuation pushed
|
|
18238
|
+
// to the front ("!Do what you love. We'll do the rest"). Falls back to the
|
|
18239
|
+
// configured direction when the text carries no strongly-directional
|
|
18240
|
+
// character, same contract as the message bubbles.
|
|
18241
|
+
const subtitleIsRtl = reactExports.useMemo(() => detectTextDirection(subtitle, isRtl), [subtitle, isRtl]);
|
|
18193
18242
|
const agentStatus = reactExports.useMemo(() => computeAgentStatus({
|
|
18194
18243
|
showStatus,
|
|
18195
18244
|
statusMode,
|
|
@@ -18270,9 +18319,11 @@
|
|
|
18270
18319
|
}), subtitle ? /*#__PURE__*/jsxRuntimeExports.jsx("p", {
|
|
18271
18320
|
title: subtitle,
|
|
18272
18321
|
className: "leading-snug truncate opacity-75",
|
|
18322
|
+
dir: subtitleIsRtl ? "rtl" : "ltr",
|
|
18273
18323
|
style: {
|
|
18274
18324
|
fontSize: "12px",
|
|
18275
|
-
color: iconColor
|
|
18325
|
+
color: iconColor,
|
|
18326
|
+
textAlign: subtitleIsRtl ? "right" : "left"
|
|
18276
18327
|
},
|
|
18277
18328
|
children: subtitle
|
|
18278
18329
|
}) : null]
|