@eshal-bot/chat-widget 0.2.19 → 0.2.20
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-D50nDQ4t.esm.js → chat-widget-MarkdownRenderer-DI8SFsfM.esm.js} +1 -1
- package/dist/chat-widget-index-CjJ4shXp.esm.js +20 -0
- package/dist/chat-widget.esm.js +1 -1
- package/dist/chat-widget.js +95 -2
- package/dist/chat-widget.min.js +4 -4
- package/dist/chat-widget.umd.js +8 -8
- package/package.json +1 -1
- package/dist/chat-widget-index-ClEAcv15.esm.js +0 -20
package/dist/chat-widget.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{e as default}from"./chat-widget-index-
|
|
1
|
+
export{e as default}from"./chat-widget-index-CjJ4shXp.esm.js";import"react";import"react-dom/client";import"react/jsx-runtime";import"react-dom";
|
package/dist/chat-widget.js
CHANGED
|
@@ -7955,6 +7955,22 @@
|
|
|
7955
7955
|
}
|
|
7956
7956
|
}
|
|
7957
7957
|
|
|
7958
|
+
/** HTTP status the backend answers for an erased conversation. */
|
|
7959
|
+
const CONVERSATION_ERASED_STATUS = 410;
|
|
7960
|
+
|
|
7961
|
+
/**
|
|
7962
|
+
* Thrown when the conversation this widget holds was erased in the console
|
|
7963
|
+
* ("Erase permanently", on the conversation or its contact). The backend
|
|
7964
|
+
* answers every widget call on it with 410 `conversation_erased`; the caller
|
|
7965
|
+
* starts a new conversation instead of treating it as a failed send.
|
|
7966
|
+
*/
|
|
7967
|
+
class ConversationErasedError extends Error {
|
|
7968
|
+
constructor(message = 'This conversation was erased') {
|
|
7969
|
+
super(message);
|
|
7970
|
+
this.name = 'ConversationErasedError';
|
|
7971
|
+
}
|
|
7972
|
+
}
|
|
7973
|
+
|
|
7958
7974
|
// ============================================================================
|
|
7959
7975
|
// NETWORK
|
|
7960
7976
|
// ============================================================================
|
|
@@ -7991,6 +8007,9 @@
|
|
|
7991
8007
|
signal
|
|
7992
8008
|
} : {})
|
|
7993
8009
|
});
|
|
8010
|
+
if (response.status === CONVERSATION_ERASED_STATUS) {
|
|
8011
|
+
throw new ConversationErasedError();
|
|
8012
|
+
}
|
|
7994
8013
|
if (!response.ok) {
|
|
7995
8014
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
7996
8015
|
}
|
|
@@ -12242,6 +12261,16 @@
|
|
|
12242
12261
|
return generateWidgetSessionId();
|
|
12243
12262
|
});
|
|
12244
12263
|
|
|
12264
|
+
// Erase permanently (console): the conversation this widget holds was
|
|
12265
|
+
// erased, and every widget call on it now answers 410 conversation_erased.
|
|
12266
|
+
// Set below once resetConversation exists; the history fetch, the live
|
|
12267
|
+
// stream, the hand-off and sendMessage all call it to start a new
|
|
12268
|
+
// conversation instead of showing or reviving the erased one.
|
|
12269
|
+
const conversationErasedRef = reactExports.useRef(() => {});
|
|
12270
|
+
// The visitor's message whose send was refused because the conversation
|
|
12271
|
+
// was erased. Re-sent on the new conversation once it exists.
|
|
12272
|
+
const pendingResendRef = reactExports.useRef(null);
|
|
12273
|
+
|
|
12245
12274
|
// Handoff EventSource - receives human agent messages in real-time
|
|
12246
12275
|
const handoffEventSourceRef = reactExports.useRef(null);
|
|
12247
12276
|
const HANDOFF_TRIGGER = "Connect with a human representative";
|
|
@@ -12413,6 +12442,10 @@
|
|
|
12413
12442
|
headers,
|
|
12414
12443
|
credentials: 'include'
|
|
12415
12444
|
});
|
|
12445
|
+
if (res.status === CONVERSATION_ERASED_STATUS) {
|
|
12446
|
+
conversationErasedRef.current(null);
|
|
12447
|
+
return;
|
|
12448
|
+
}
|
|
12416
12449
|
if (!res.ok) return;
|
|
12417
12450
|
const data = await res.json();
|
|
12418
12451
|
const serverMsgs = Array.isArray(data?.messages) ? data.messages : [];
|
|
@@ -12449,6 +12482,13 @@
|
|
|
12449
12482
|
es.onmessage = event => {
|
|
12450
12483
|
try {
|
|
12451
12484
|
const data = JSON.parse(event.data);
|
|
12485
|
+
// Erased in the console while open: stop listening and start over.
|
|
12486
|
+
if (data.type === 'conversation_erased') {
|
|
12487
|
+
es.close();
|
|
12488
|
+
if (handoffEventSourceRef.current === es) handoffEventSourceRef.current = null;
|
|
12489
|
+
conversationErasedRef.current(null);
|
|
12490
|
+
return;
|
|
12491
|
+
}
|
|
12452
12492
|
if (data.type === 'message_created' && data.message) {
|
|
12453
12493
|
// Advance the backfill watermark so a later reconnect doesn't
|
|
12454
12494
|
// re-request everything we have already rendered live.
|
|
@@ -12729,7 +12769,13 @@
|
|
|
12729
12769
|
headers,
|
|
12730
12770
|
credentials: 'include'
|
|
12731
12771
|
});
|
|
12732
|
-
if (
|
|
12772
|
+
if (cancelled) return;
|
|
12773
|
+
// Erased in the console: the saved transcript must not be shown.
|
|
12774
|
+
if (res.status === CONVERSATION_ERASED_STATUS) {
|
|
12775
|
+
conversationErasedRef.current(null);
|
|
12776
|
+
return;
|
|
12777
|
+
}
|
|
12778
|
+
if (!res.ok) return;
|
|
12733
12779
|
const data = await res.json();
|
|
12734
12780
|
const serverMsgs = Array.isArray(data?.messages) ? data.messages : [];
|
|
12735
12781
|
const agentMsgs = serverMsgs.filter(isRepliedOutsideStream);
|
|
@@ -12942,6 +12988,10 @@
|
|
|
12942
12988
|
body: JSON.stringify({
|
|
12943
12989
|
reason: 'User clicked handoff button'
|
|
12944
12990
|
})
|
|
12991
|
+
}).then(res => {
|
|
12992
|
+
// Erased: nobody to hand off to. Start a new conversation,
|
|
12993
|
+
// where the visitor can ask for a person again.
|
|
12994
|
+
if (res.status === CONVERSATION_ERASED_STATUS) conversationErasedRef.current(null);
|
|
12945
12995
|
}).catch(() => {});
|
|
12946
12996
|
}
|
|
12947
12997
|
};
|
|
@@ -13184,6 +13234,8 @@
|
|
|
13184
13234
|
if (done) break;
|
|
13185
13235
|
}
|
|
13186
13236
|
} catch (err) {
|
|
13237
|
+
// Erased: handled once, below, like any other send.
|
|
13238
|
+
if (err instanceof ConversationErasedError) throw err;
|
|
13187
13239
|
// L4: this catch used to swallow the failure - but in a handed-off
|
|
13188
13240
|
// conversation this POST is the ONLY path to the human agent, so a
|
|
13189
13241
|
// dropped send meant the customer's message never reached anyone
|
|
@@ -13265,6 +13317,21 @@
|
|
|
13265
13317
|
success: true
|
|
13266
13318
|
};
|
|
13267
13319
|
} catch (error) {
|
|
13320
|
+
// Erased in the console: not a failed send. Start a new conversation
|
|
13321
|
+
// and send this message again there, with no error bubble.
|
|
13322
|
+
if (error instanceof ConversationErasedError) {
|
|
13323
|
+
const isChat = apiType === 'inquiry' || apiType === 'complaint' || apiType === 'technical';
|
|
13324
|
+
conversationErasedRef.current(isChat ? {
|
|
13325
|
+
text: trimmed,
|
|
13326
|
+
attachments: attachmentsPayload,
|
|
13327
|
+
sessionId: bidiSessionId
|
|
13328
|
+
} : null);
|
|
13329
|
+
return {
|
|
13330
|
+
success: false,
|
|
13331
|
+
error: 'conversation_erased',
|
|
13332
|
+
erased: true
|
|
13333
|
+
};
|
|
13334
|
+
}
|
|
13268
13335
|
console.error("Error sending message:", error);
|
|
13269
13336
|
if (apiType === 'inquiry' || apiType === 'complaint' || apiType === 'technical') {
|
|
13270
13337
|
setIsLoading(false);
|
|
@@ -13317,6 +13384,16 @@
|
|
|
13317
13384
|
// bubble first, then routes back through sendMessage so the retry gets the
|
|
13318
13385
|
// full pipeline (concurrency guard, stream retries, delivery state) instead
|
|
13319
13386
|
// of a bespoke resend path.
|
|
13387
|
+
// A send refused because the conversation was erased goes out again on the
|
|
13388
|
+
// new conversation, once the reset has rotated the session id.
|
|
13389
|
+
reactExports.useEffect(() => {
|
|
13390
|
+
const pending = pendingResendRef.current;
|
|
13391
|
+
if (!pending || pending.sessionId === bidiSessionId) return;
|
|
13392
|
+
pendingResendRef.current = null;
|
|
13393
|
+
void sendMessage(pending.text, undefined, {
|
|
13394
|
+
attachments: pending.attachments
|
|
13395
|
+
});
|
|
13396
|
+
}, [bidiSessionId, sendMessage]);
|
|
13320
13397
|
const retryMessage = reactExports.useCallback(failedMessage => {
|
|
13321
13398
|
if (!failedMessage || failedMessage.status !== 'failed') {
|
|
13322
13399
|
return Promise.resolve({
|
|
@@ -14688,6 +14765,22 @@
|
|
|
14688
14765
|
resetConversationRef.current = resetConversation;
|
|
14689
14766
|
}, [resetConversation]);
|
|
14690
14767
|
|
|
14768
|
+
// The conversation was erased in the console: drop the saved transcript and
|
|
14769
|
+
// start a new conversation, the same reset as after CSAT. Idempotent per
|
|
14770
|
+
// conversation id, since the history fetch, the stream and a send can all
|
|
14771
|
+
// learn it at once. `resend` is the visitor's refused message, sent again
|
|
14772
|
+
// on the new conversation unless onboarding has to run first.
|
|
14773
|
+
const erasedHandledForRef = reactExports.useRef(null);
|
|
14774
|
+
reactExports.useEffect(() => {
|
|
14775
|
+
conversationErasedRef.current = resend => {
|
|
14776
|
+
if (erasedHandledForRef.current === bidiSessionId) return;
|
|
14777
|
+
erasedHandledForRef.current = bidiSessionId;
|
|
14778
|
+
const needsOnboarding = onboardingEnabled && getOnboardingQuestions(onboardingQuestions).length > 0;
|
|
14779
|
+
pendingResendRef.current = resend && !needsOnboarding ? resend : null;
|
|
14780
|
+
resetConversationRef.current();
|
|
14781
|
+
};
|
|
14782
|
+
}, [bidiSessionId, onboardingEnabled, onboardingQuestions]);
|
|
14783
|
+
|
|
14691
14784
|
// Precise inactivity timeout: schedules a setTimeout for exact remaining time,
|
|
14692
14785
|
// then reschedules itself after each check (handles activity updates in localStorage).
|
|
14693
14786
|
//
|
|
@@ -21773,7 +21866,7 @@
|
|
|
21773
21866
|
* value by its own test (that constant sat at 0.1.113 while this package was
|
|
21774
21867
|
* at 0.2.2 precisely because nothing enforced it - EV-2431).
|
|
21775
21868
|
*/
|
|
21776
|
-
const WIDGET_VERSION = '0.2.
|
|
21869
|
+
const WIDGET_VERSION = '0.2.20';
|
|
21777
21870
|
|
|
21778
21871
|
/**
|
|
21779
21872
|
* API utility functions
|