@memori.ai/memori-react 8.41.0 → 8.41.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/components/MemoriWidget/MemoriWidget.js +123 -26
  3. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  4. package/dist/helpers/nats/isSessionExpiredError.d.ts +3 -0
  5. package/dist/helpers/nats/isSessionExpiredError.js +37 -0
  6. package/dist/helpers/nats/isSessionExpiredError.js.map +1 -0
  7. package/dist/locales/de.json +1 -0
  8. package/dist/locales/en.json +1 -0
  9. package/dist/locales/es.json +1 -0
  10. package/dist/locales/fr.json +1 -0
  11. package/dist/locales/it.json +1 -0
  12. package/dist/version.d.ts +1 -1
  13. package/dist/version.js +1 -1
  14. package/esm/components/MemoriWidget/MemoriWidget.js +123 -26
  15. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  16. package/esm/helpers/nats/isSessionExpiredError.d.ts +3 -0
  17. package/esm/helpers/nats/isSessionExpiredError.js +32 -0
  18. package/esm/helpers/nats/isSessionExpiredError.js.map +1 -0
  19. package/esm/locales/de.json +1 -0
  20. package/esm/locales/en.json +1 -0
  21. package/esm/locales/es.json +1 -0
  22. package/esm/locales/fr.json +1 -0
  23. package/esm/locales/it.json +1 -0
  24. package/esm/version.d.ts +1 -1
  25. package/esm/version.js +1 -1
  26. package/package.json +1 -1
  27. package/src/components/MemoriWidget/MemoriWidget.tsx +195 -46
  28. package/src/helpers/nats/isSessionExpiredError.test.ts +38 -0
  29. package/src/helpers/nats/isSessionExpiredError.ts +51 -0
  30. package/src/index.stories.tsx +16 -0
  31. package/src/locales/de.json +1 -0
  32. package/src/locales/en.json +1 -0
  33. package/src/locales/es.json +1 -0
  34. package/src/locales/fr.json +1 -0
  35. package/src/locales/it.json +1 -0
  36. package/src/version.ts +1 -1
@@ -0,0 +1,3 @@
1
+ import type { NatsDialogResponseEvent, NatsErrorEvent } from './useNatsSession';
2
+ export declare function isSessionExpiredNatsError(event: NatsErrorEvent): boolean;
3
+ export declare function isSessionExpiredNatsResponse(event: NatsDialogResponseEvent): boolean;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSessionExpiredNatsResponse = exports.isSessionExpiredNatsError = void 0;
4
+ const SESSION_NOT_FOUND = -101;
5
+ const SESSION_EXPIRED = -103;
6
+ const SESSION_NOT_FOUND_MESSAGE = /session\s+with\s+id\s+["']?[^"']+["']?\s+not\s+found/i;
7
+ function isExpiredResultCode(resultCode) {
8
+ return (resultCode === 404 ||
9
+ resultCode === SESSION_EXPIRED ||
10
+ resultCode === SESSION_NOT_FOUND);
11
+ }
12
+ function isExpiredErrorMessage(message) {
13
+ if (!message)
14
+ return false;
15
+ return SESSION_NOT_FOUND_MESSAGE.test(message);
16
+ }
17
+ function isSessionExpiredNatsError(event) {
18
+ if (isExpiredResultCode(event.errorCode)) {
19
+ return true;
20
+ }
21
+ if (typeof event.errorCode === 'string') {
22
+ const code = event.errorCode.toUpperCase();
23
+ if (code.includes('SESSION_EXPIRED') || code.includes('SESSION_NOT_FOUND')) {
24
+ return true;
25
+ }
26
+ }
27
+ return isExpiredErrorMessage(event.errorMessage);
28
+ }
29
+ exports.isSessionExpiredNatsError = isSessionExpiredNatsError;
30
+ function isSessionExpiredNatsResponse(event) {
31
+ if (isExpiredResultCode(event.resultCode)) {
32
+ return true;
33
+ }
34
+ return isExpiredErrorMessage(event.resultMessage);
35
+ }
36
+ exports.isSessionExpiredNatsResponse = isSessionExpiredNatsResponse;
37
+ //# sourceMappingURL=isSessionExpiredError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isSessionExpiredError.js","sourceRoot":"","sources":["../../../src/helpers/nats/isSessionExpiredError.ts"],"names":[],"mappings":";;;AAMA,MAAM,iBAAiB,GAAG,CAAC,GAAG,CAAC;AAC/B,MAAM,eAAe,GAAG,CAAC,GAAG,CAAC;AAE7B,MAAM,yBAAyB,GAC7B,uDAAuD,CAAC;AAE1D,SAAS,mBAAmB,CAAC,UAAmB;IAC9C,OAAO,CACL,UAAU,KAAK,GAAG;QAClB,UAAU,KAAK,eAAe;QAC9B,UAAU,KAAK,iBAAiB,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgB;IAC7C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAGD,SAAgB,yBAAyB,CAAC,KAAqB;IAC7D,IAAI,mBAAmB,CAAC,KAAK,CAAC,SAA+B,CAAC,EAAE;QAC9D,OAAO,IAAI,CAAC;KACb;IAED,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YAC1E,OAAO,IAAI,CAAC;SACb;KACF;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAbD,8DAaC;AAGD,SAAgB,4BAA4B,CAC1C,KAA8B;IAE9B,IAAI,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;QACzC,OAAO,IAAI,CAAC;KACb;IAED,OAAO,qBAAqB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;AACpD,CAAC;AARD,oEAQC"}
@@ -75,6 +75,7 @@
75
75
  "errorFetchingSession": "Fehler beim Laden der Sitzung",
76
76
  "errorGettingReferralURL": "Fehler beim Laden des Referrals",
77
77
  "errorReopeningSession": "Fehler beim erneuten Öffnen der Sitzung",
78
+ "sessionExpiredReopening": "Sitzung abgelaufen, Sitzung wird neu geöffnet",
78
79
  "ageVerification": "Altersüberprüfung",
79
80
  "ageVerificationText": "Um mit diesem Zwilling interagieren zu können, müssen Sie mindestens sein {{minAge}} Jahre alt.",
80
81
  "nsfw": "NSFW: Dieser Agent enthält Inhalte für Erwachsene",
@@ -77,6 +77,7 @@
77
77
  "errorFetchingSession": "Error during session loading",
78
78
  "errorGettingReferralURL": "Error during referral loading",
79
79
  "errorReopeningSession": "Error during session reopening",
80
+ "sessionExpiredReopening": "Session expired, reopening session",
80
81
  "ageVerification": "Age verification",
81
82
  "ageVerificationText": "To interact with this agent, you must be at least {{minAge}} years old.",
82
83
  "nsfw": "NSFW: This agent contains adult contents",
@@ -75,6 +75,7 @@
75
75
  "errorFetchingSession": "Error durante el cargamento de la sesión",
76
76
  "errorGettingReferralURL": "Error durante el cargamento del référent",
77
77
  "errorReopeningSession": "Error durante el re-abrir la sesión",
78
+ "sessionExpiredReopening": "Sesión expirada, reabriendo sesión",
78
79
  "ageVerification": "Verificación de edad",
79
80
  "ageVerificationText": "Para interactuar con este Gemelo, debes tener al menos {{minAge}} años.",
80
81
  "nsfw": "NSFW: Este gemelo contiene contenido para adultos",
@@ -74,6 +74,7 @@
74
74
  "errorFetchingSession": "Erreur lors du chargement de la session",
75
75
  "errorGettingReferralURL": "Erreur lors du chargement du référent",
76
76
  "errorReopeningSession": "Erreur lors de la re-ouverture de la session",
77
+ "sessionExpiredReopening": "Session expirée, réouverture en cours",
77
78
  "ageVerification": "Vérification de l'âge",
78
79
  "ageVerificationText": "Pour interagir avec ce Agent, vous devez être au minimum {{minAge}} ans.",
79
80
  "nsfw": "NSFW : Ce jumeau contient du contenu pour adultes",
@@ -78,6 +78,7 @@
78
78
  "errorFetchingSession": "Errore durante il caricamento della sessione",
79
79
  "errorGettingReferralURL": "Errore durante il caricamento del riferimento",
80
80
  "errorReopeningSession": "Errore durante il riapertura della sessione",
81
+ "sessionExpiredReopening": "Sessione scaduta, riapertura in corso",
81
82
  "ageVerification": "Verifica dell'età",
82
83
  "ageVerificationText": "Per interagire con questo agente, devi aver almeno {{minAge}} anni.",
83
84
  "nsfw": "NSFW: Questo agente contiene contenuti per adulti",
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "8.41.0";
1
+ export declare const version = "8.41.1";
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
- exports.version = '8.41.0';
4
+ exports.version = '8.41.1';
5
5
  //# sourceMappingURL=version.js.map
@@ -39,6 +39,7 @@ import { useTTS } from '../../helpers/tts/useTTS';
39
39
  import ChatHistoryDrawer from '../ChatHistoryDrawer/ChatHistory';
40
40
  import { useSTT } from '../../helpers/stt/useSTT';
41
41
  import { useNats } from '../../helpers/nats/useNats';
42
+ import { isSessionExpiredNatsError, isSessionExpiredNatsResponse, } from '../../helpers/nats/isSessionExpiredError';
42
43
  const getMemoriState = (integrationId) => {
43
44
  var _a, _b, _c, _d, _f;
44
45
  let widget = integrationId
@@ -392,8 +393,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
392
393
  });
393
394
  };
394
395
  const [chatLogID, setChatLogID] = useState(undefined);
395
- const sendMessage = async (text, media, newSessionId, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false) => {
396
- var _a, _b, _c, _d;
396
+ const sendMessage = async (text, media, newSessionId, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false, skipHistoryPush = false) => {
397
+ var _a, _b;
397
398
  const sessionID = newSessionId ||
398
399
  sessionId ||
399
400
  ((_a = window.getMemoriState()) === null || _a === void 0 ? void 0 : _a.sessionID);
@@ -437,7 +438,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
437
438
  return;
438
439
  }
439
440
  }
440
- if (!hidden)
441
+ if (!hidden && !skipHistoryPush)
441
442
  pushMessage({
442
443
  text: text,
443
444
  translatedText,
@@ -462,6 +463,11 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
462
463
  if (response.resultCode === 0 && correlationID) {
463
464
  registerPendingEnterText(correlationID, {
464
465
  msg,
466
+ text,
467
+ media,
468
+ translate,
469
+ translatedText,
470
+ hidden,
465
471
  typingText,
466
472
  useLoaderTextAsMsg,
467
473
  hasBatchQueued,
@@ -473,18 +479,17 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
473
479
  logWidgetError('enter-text missing correlationID', response);
474
480
  }
475
481
  else if (response.resultCode === 404) {
476
- setHistory(h => [...h.slice(0, h.length - 1)]);
477
- reopenSession(true, memoriPwd || memori.secretToken, memoriTokens, undefined, undefined, {
478
- LANG: userLang,
479
- PATHNAME: window.location.pathname,
480
- ROUTE: ((_d = (_c = window.location.pathname) === null || _c === void 0 ? void 0 : _c.split('/')) === null || _d === void 0 ? void 0 : _d.pop()) || '',
481
- ...(initialContextVars || {}),
482
- }, initialQuestion, undefined, undefined, undefined, undefined, true).then(state => {
483
- if (state === null || state === void 0 ? void 0 : state.sessionID) {
484
- setTimeout(() => {
485
- sendMessage(text, media, state === null || state === void 0 ? void 0 : state.sessionID);
486
- }, 500);
487
- }
482
+ retryAfterExpiredSessionRef.current({
483
+ text,
484
+ media,
485
+ translate,
486
+ translatedText,
487
+ hidden,
488
+ typingText,
489
+ useLoaderTextAsMsg,
490
+ hasBatchQueued,
491
+ expiredSessionID: sessionID,
492
+ continueFromChatLogID: chatLogID,
488
493
  });
489
494
  }
490
495
  else if (response.resultCode === 500 && response.resultMessage) {
@@ -789,7 +794,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
789
794
  logWidgetError('fetchSession failed', err);
790
795
  }
791
796
  };
792
- const reopenSession = async (updateDialogState = false, password, recoveryTokens, tag, pin, initialContextVars, initialQuestion, birthDate, additionalInfoProp, continueFromChatLogID, continueFromSessionID, isSessionExpired) => {
797
+ const reopenSession = async (updateDialogState = false, password, recoveryTokens, tag, pin, initialContextVars, initialQuestion, birthDate, additionalInfoProp, continueFromChatLogID, continueFromSessionID, isSessionExpired, suppressHistoryUpdate) => {
793
798
  var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m;
794
799
  setLoading(true);
795
800
  let storageBirthDate = getLocalConfig('birthDate', undefined);
@@ -848,9 +853,22 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
848
853
  setSessionId(sessionID);
849
854
  if (updateDialogState) {
850
855
  setCurrentDialogState(currentState);
851
- if (currentState.emission) {
852
- const initialStatus = isSessionExpired && history.length > 1
853
- ? 'Session Expired, reopening session'
856
+ const sessionExpiredStatus = isSessionExpired && history.length > 1
857
+ ? t('sessionExpiredReopening')
858
+ : null;
859
+ if (sessionExpiredStatus && suppressHistoryUpdate) {
860
+ pushMessage({
861
+ text: '',
862
+ emitter: 'system',
863
+ fromUser: false,
864
+ initial: sessionExpiredStatus,
865
+ contextVars: {},
866
+ date: new Date().toISOString(),
867
+ });
868
+ }
869
+ if (currentState.emission && !suppressHistoryUpdate) {
870
+ const initialStatus = sessionExpiredStatus
871
+ ? sessionExpiredStatus
854
872
  : history.length <= 1
855
873
  ? true
856
874
  : undefined;
@@ -917,6 +935,50 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
917
935
  setLoading(false);
918
936
  return null;
919
937
  };
938
+ const retryAfterExpiredSessionRef = useRef(() => Promise.resolve(null));
939
+ retryAfterExpiredSessionRef.current = (params) => {
940
+ const { text, media, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false, expiredSessionID, continueFromChatLogID: continueFromChatLogIDParam, } = params;
941
+ const continueFromSessionID = expiredSessionID !== null && expiredSessionID !== void 0 ? expiredSessionID : sessionId;
942
+ const continueFromChatLogID = continueFromChatLogIDParam !== null && continueFromChatLogIDParam !== void 0 ? continueFromChatLogIDParam : chatLogID;
943
+ const reopenAfterExpiry = () => {
944
+ var _a, _b;
945
+ return reopenSession(true, memoriPwd || memori.secretToken, memoriTokens, undefined, undefined, {
946
+ LANG: userLang,
947
+ PATHNAME: window.location.pathname,
948
+ ROUTE: ((_b = (_a = window.location.pathname) === null || _a === void 0 ? void 0 : _a.split('/')) === null || _b === void 0 ? void 0 : _b.pop()) || '',
949
+ ...(initialContextVars || {}),
950
+ }, initialQuestion, undefined, undefined, continueFromChatLogID, continueFromSessionID, true, true);
951
+ };
952
+ const scheduleRetry = (newSessionID) => {
953
+ setTimeout(() => {
954
+ sendMessage(text, media, newSessionID, translate, translatedText, hidden, typingText, useLoaderTextAsMsg, hasBatchQueued, true);
955
+ }, 500);
956
+ };
957
+ const handleReopenFailure = (state) => {
958
+ setMemoriTyping(false);
959
+ setTypingText(undefined);
960
+ if (state === null && text && !hidden) {
961
+ toast.error(t('errors.SESSION_EXPIRED'));
962
+ }
963
+ };
964
+ if (!text) {
965
+ return reopenAfterExpiry().then(state => {
966
+ if (!(state === null || state === void 0 ? void 0 : state.sessionID)) {
967
+ handleReopenFailure(state);
968
+ }
969
+ return state;
970
+ });
971
+ }
972
+ return reopenAfterExpiry().then(state => {
973
+ if (state === null || state === void 0 ? void 0 : state.sessionID) {
974
+ scheduleRetry(state.sessionID);
975
+ }
976
+ else {
977
+ handleReopenFailure(state);
978
+ }
979
+ return state;
980
+ });
981
+ };
920
982
  const changeTag = async (memoriId, sessionId, tag, pin) => {
921
983
  var _a, _b, _c, _d, _f, _g, _h, _j, _k;
922
984
  if (!memoriId || !sessionId) {
@@ -1112,6 +1174,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1112
1174
  const { msg, typingText: pendingTypingText, useLoaderTextAsMsg, } = pending;
1113
1175
  const currentState = event.currentState;
1114
1176
  if (event.resultCode !== 0 || !currentState) {
1177
+ if (isSessionExpiredNatsResponse(event) && pending.text) {
1178
+ setMemoriTyping(false);
1179
+ setTypingText(undefined);
1180
+ retryAfterExpiredSessionRef.current({
1181
+ text: pending.text,
1182
+ media: pending.media,
1183
+ translate: pending.translate,
1184
+ translatedText: pending.translatedText,
1185
+ hidden: pending.hidden,
1186
+ typingText: pending.typingText,
1187
+ useLoaderTextAsMsg: pending.useLoaderTextAsMsg,
1188
+ hasBatchQueued: pending.hasBatchQueued,
1189
+ expiredSessionID: sessionId,
1190
+ continueFromChatLogID: chatLogID,
1191
+ });
1192
+ return;
1193
+ }
1115
1194
  if (event.resultCode === 500 && event.resultMessage) {
1116
1195
  setHistory(h => [
1117
1196
  ...h,
@@ -1192,6 +1271,31 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1192
1271
  const deliverEnterTextNatsError = useCallback((event) => {
1193
1272
  var _a, _b, _c;
1194
1273
  const correlationID = event.correlationID;
1274
+ let pending;
1275
+ if (correlationID) {
1276
+ pending = pendingEnterTextRef.current.get(correlationID);
1277
+ if (pending) {
1278
+ clearEnterTextPending(correlationID, pending);
1279
+ (_a = pending.waitForResponse) === null || _a === void 0 ? void 0 : _a.reject(new Error((_b = event.errorMessage) !== null && _b !== void 0 ? _b : String((_c = event.errorCode) !== null && _c !== void 0 ? _c : 'NATS error')));
1280
+ }
1281
+ }
1282
+ if (isSessionExpiredNatsError(event) && (pending === null || pending === void 0 ? void 0 : pending.text)) {
1283
+ setMemoriTyping(false);
1284
+ setTypingText(undefined);
1285
+ retryAfterExpiredSessionRef.current({
1286
+ text: pending.text,
1287
+ media: pending.media,
1288
+ translate: pending.translate,
1289
+ translatedText: pending.translatedText,
1290
+ hidden: pending.hidden,
1291
+ typingText: pending.typingText,
1292
+ useLoaderTextAsMsg: pending.useLoaderTextAsMsg,
1293
+ hasBatchQueued: pending.hasBatchQueued,
1294
+ expiredSessionID: sessionId,
1295
+ continueFromChatLogID: chatLogID,
1296
+ });
1297
+ return;
1298
+ }
1195
1299
  const errorText = event.errorMessage
1196
1300
  ? `Error: ${event.errorMessage}`
1197
1301
  : event.errorCode
@@ -1205,13 +1309,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1205
1309
  contextVars: {},
1206
1310
  date: new Date().toISOString(),
1207
1311
  });
1208
- if (correlationID) {
1209
- const pending = pendingEnterTextRef.current.get(correlationID);
1210
- if (pending) {
1211
- clearEnterTextPending(correlationID, pending);
1212
- (_a = pending.waitForResponse) === null || _a === void 0 ? void 0 : _a.reject(new Error((_b = event.errorMessage) !== null && _b !== void 0 ? _b : String((_c = event.errorCode) !== null && _c !== void 0 ? _c : 'NATS error')));
1213
- }
1214
- }
1215
1312
  setMemoriTyping(false);
1216
1313
  setTypingText(undefined);
1217
1314
  }, [clearEnterTextPending]);