@memori.ai/memori-react 8.40.4 → 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.
- package/CHANGELOG.md +19 -0
- package/dist/components/MemoriWidget/MemoriWidget.js +123 -26
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/helpers/nats/getNatsConfig.d.ts +4 -0
- package/dist/helpers/nats/getNatsConfig.js +42 -5
- package/dist/helpers/nats/getNatsConfig.js.map +1 -1
- package/dist/helpers/nats/isSessionExpiredError.d.ts +3 -0
- package/dist/helpers/nats/isSessionExpiredError.js +37 -0
- package/dist/helpers/nats/isSessionExpiredError.js.map +1 -0
- package/dist/helpers/nats/useNats.js +6 -2
- package/dist/helpers/nats/useNats.js.map +1 -1
- package/dist/helpers/nats/useNatsSession.d.ts +2 -1
- package/dist/helpers/nats/useNatsSession.js +122 -25
- package/dist/helpers/nats/useNatsSession.js.map +1 -1
- package/dist/locales/de.json +1 -0
- package/dist/locales/en.json +1 -0
- package/dist/locales/es.json +1 -0
- package/dist/locales/fr.json +1 -0
- package/dist/locales/it.json +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +123 -26
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/helpers/nats/getNatsConfig.d.ts +4 -0
- package/esm/helpers/nats/getNatsConfig.js +40 -4
- package/esm/helpers/nats/getNatsConfig.js.map +1 -1
- package/esm/helpers/nats/isSessionExpiredError.d.ts +3 -0
- package/esm/helpers/nats/isSessionExpiredError.js +32 -0
- package/esm/helpers/nats/isSessionExpiredError.js.map +1 -0
- package/esm/helpers/nats/useNats.js +6 -2
- package/esm/helpers/nats/useNats.js.map +1 -1
- package/esm/helpers/nats/useNatsSession.d.ts +2 -1
- package/esm/helpers/nats/useNatsSession.js +123 -26
- package/esm/helpers/nats/useNatsSession.js.map +1 -1
- package/esm/locales/de.json +1 -0
- package/esm/locales/en.json +1 -0
- package/esm/locales/es.json +1 -0
- package/esm/locales/fr.json +1 -0
- package/esm/locales/it.json +1 -0
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +2 -1
- package/src/components/MemoriWidget/MemoriWidget.tsx +195 -46
- package/src/helpers/nats/getNatsConfig.ts +83 -7
- package/src/helpers/nats/isSessionExpiredError.test.ts +38 -0
- package/src/helpers/nats/isSessionExpiredError.ts +51 -0
- package/src/helpers/nats/useNats.ts +8 -6
- package/src/helpers/nats/useNatsSession.ts +203 -39
- package/src/index.stories.tsx +16 -0
- package/src/locales/de.json +1 -0
- package/src/locales/en.json +1 -0
- package/src/locales/es.json +1 -0
- package/src/locales/fr.json +1 -0
- package/src/locales/it.json +1 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## [8.41.1](https://github.com/memori-ai/memori-react/compare/v8.41.0...v8.41.1) (2026-06-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* implement session expiration handling in MemoriWidget and add related tests ([65e96fa](https://github.com/memori-ai/memori-react/commit/65e96fa561462fc60abbcd71ef461cacd7b2b263))
|
|
9
|
+
|
|
10
|
+
## [8.41.0](https://github.com/memori-ai/memori-react/compare/v8.40.4...v8.41.0) (2026-06-22)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* integrate JetStream support in NATS configuration and session handling ([d133c95](https://github.com/memori-ai/memori-react/commit/d133c95fc9385a7e06875dadcc6ea9be444f3868))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* update NATS subject default value to include session ID format ([dc0e7ea](https://github.com/memori-ai/memori-react/commit/dc0e7ea0a1c0eba5fb8f834df3ef55d598e05166))
|
|
21
|
+
|
|
3
22
|
## [8.40.4](https://github.com/memori-ai/memori-react/compare/v8.40.3...v8.40.4) (2026-06-19)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -42,6 +42,7 @@ const useTTS_1 = require("../../helpers/tts/useTTS");
|
|
|
42
42
|
const ChatHistory_1 = tslib_1.__importDefault(require("../ChatHistoryDrawer/ChatHistory"));
|
|
43
43
|
const useSTT_1 = require("../../helpers/stt/useSTT");
|
|
44
44
|
const useNats_1 = require("../../helpers/nats/useNats");
|
|
45
|
+
const isSessionExpiredError_1 = require("../../helpers/nats/isSessionExpiredError");
|
|
45
46
|
const getMemoriState = (integrationId) => {
|
|
46
47
|
var _a, _b, _c, _d, _f;
|
|
47
48
|
let widget = integrationId
|
|
@@ -395,8 +396,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
395
396
|
});
|
|
396
397
|
};
|
|
397
398
|
const [chatLogID, setChatLogID] = (0, react_1.useState)(undefined);
|
|
398
|
-
const sendMessage = async (text, media, newSessionId, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false) => {
|
|
399
|
-
var _a, _b
|
|
399
|
+
const sendMessage = async (text, media, newSessionId, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false, skipHistoryPush = false) => {
|
|
400
|
+
var _a, _b;
|
|
400
401
|
const sessionID = newSessionId ||
|
|
401
402
|
sessionId ||
|
|
402
403
|
((_a = window.getMemoriState()) === null || _a === void 0 ? void 0 : _a.sessionID);
|
|
@@ -440,7 +441,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
440
441
|
return;
|
|
441
442
|
}
|
|
442
443
|
}
|
|
443
|
-
if (!hidden)
|
|
444
|
+
if (!hidden && !skipHistoryPush)
|
|
444
445
|
pushMessage({
|
|
445
446
|
text: text,
|
|
446
447
|
translatedText,
|
|
@@ -465,6 +466,11 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
465
466
|
if (response.resultCode === 0 && correlationID) {
|
|
466
467
|
registerPendingEnterText(correlationID, {
|
|
467
468
|
msg,
|
|
469
|
+
text,
|
|
470
|
+
media,
|
|
471
|
+
translate,
|
|
472
|
+
translatedText,
|
|
473
|
+
hidden,
|
|
468
474
|
typingText,
|
|
469
475
|
useLoaderTextAsMsg,
|
|
470
476
|
hasBatchQueued,
|
|
@@ -476,18 +482,17 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
476
482
|
logWidgetError('enter-text missing correlationID', response);
|
|
477
483
|
}
|
|
478
484
|
else if (response.resultCode === 404) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
485
|
+
retryAfterExpiredSessionRef.current({
|
|
486
|
+
text,
|
|
487
|
+
media,
|
|
488
|
+
translate,
|
|
489
|
+
translatedText,
|
|
490
|
+
hidden,
|
|
491
|
+
typingText,
|
|
492
|
+
useLoaderTextAsMsg,
|
|
493
|
+
hasBatchQueued,
|
|
494
|
+
expiredSessionID: sessionID,
|
|
495
|
+
continueFromChatLogID: chatLogID,
|
|
491
496
|
});
|
|
492
497
|
}
|
|
493
498
|
else if (response.resultCode === 500 && response.resultMessage) {
|
|
@@ -792,7 +797,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
792
797
|
logWidgetError('fetchSession failed', err);
|
|
793
798
|
}
|
|
794
799
|
};
|
|
795
|
-
const reopenSession = async (updateDialogState = false, password, recoveryTokens, tag, pin, initialContextVars, initialQuestion, birthDate, additionalInfoProp, continueFromChatLogID, continueFromSessionID, isSessionExpired) => {
|
|
800
|
+
const reopenSession = async (updateDialogState = false, password, recoveryTokens, tag, pin, initialContextVars, initialQuestion, birthDate, additionalInfoProp, continueFromChatLogID, continueFromSessionID, isSessionExpired, suppressHistoryUpdate) => {
|
|
796
801
|
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m;
|
|
797
802
|
setLoading(true);
|
|
798
803
|
let storageBirthDate = (0, configuration_1.getLocalConfig)('birthDate', undefined);
|
|
@@ -851,9 +856,22 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
851
856
|
setSessionId(sessionID);
|
|
852
857
|
if (updateDialogState) {
|
|
853
858
|
setCurrentDialogState(currentState);
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
859
|
+
const sessionExpiredStatus = isSessionExpired && history.length > 1
|
|
860
|
+
? t('sessionExpiredReopening')
|
|
861
|
+
: null;
|
|
862
|
+
if (sessionExpiredStatus && suppressHistoryUpdate) {
|
|
863
|
+
pushMessage({
|
|
864
|
+
text: '',
|
|
865
|
+
emitter: 'system',
|
|
866
|
+
fromUser: false,
|
|
867
|
+
initial: sessionExpiredStatus,
|
|
868
|
+
contextVars: {},
|
|
869
|
+
date: new Date().toISOString(),
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
if (currentState.emission && !suppressHistoryUpdate) {
|
|
873
|
+
const initialStatus = sessionExpiredStatus
|
|
874
|
+
? sessionExpiredStatus
|
|
857
875
|
: history.length <= 1
|
|
858
876
|
? true
|
|
859
877
|
: undefined;
|
|
@@ -920,6 +938,50 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
920
938
|
setLoading(false);
|
|
921
939
|
return null;
|
|
922
940
|
};
|
|
941
|
+
const retryAfterExpiredSessionRef = (0, react_1.useRef)(() => Promise.resolve(null));
|
|
942
|
+
retryAfterExpiredSessionRef.current = (params) => {
|
|
943
|
+
const { text, media, translate = true, translatedText, hidden = false, typingText, useLoaderTextAsMsg = false, hasBatchQueued = false, expiredSessionID, continueFromChatLogID: continueFromChatLogIDParam, } = params;
|
|
944
|
+
const continueFromSessionID = expiredSessionID !== null && expiredSessionID !== void 0 ? expiredSessionID : sessionId;
|
|
945
|
+
const continueFromChatLogID = continueFromChatLogIDParam !== null && continueFromChatLogIDParam !== void 0 ? continueFromChatLogIDParam : chatLogID;
|
|
946
|
+
const reopenAfterExpiry = () => {
|
|
947
|
+
var _a, _b;
|
|
948
|
+
return reopenSession(true, memoriPwd || memori.secretToken, memoriTokens, undefined, undefined, {
|
|
949
|
+
LANG: userLang,
|
|
950
|
+
PATHNAME: window.location.pathname,
|
|
951
|
+
ROUTE: ((_b = (_a = window.location.pathname) === null || _a === void 0 ? void 0 : _a.split('/')) === null || _b === void 0 ? void 0 : _b.pop()) || '',
|
|
952
|
+
...(initialContextVars || {}),
|
|
953
|
+
}, initialQuestion, undefined, undefined, continueFromChatLogID, continueFromSessionID, true, true);
|
|
954
|
+
};
|
|
955
|
+
const scheduleRetry = (newSessionID) => {
|
|
956
|
+
setTimeout(() => {
|
|
957
|
+
sendMessage(text, media, newSessionID, translate, translatedText, hidden, typingText, useLoaderTextAsMsg, hasBatchQueued, true);
|
|
958
|
+
}, 500);
|
|
959
|
+
};
|
|
960
|
+
const handleReopenFailure = (state) => {
|
|
961
|
+
setMemoriTyping(false);
|
|
962
|
+
setTypingText(undefined);
|
|
963
|
+
if (state === null && text && !hidden) {
|
|
964
|
+
react_hot_toast_1.default.error(t('errors.SESSION_EXPIRED'));
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
if (!text) {
|
|
968
|
+
return reopenAfterExpiry().then(state => {
|
|
969
|
+
if (!(state === null || state === void 0 ? void 0 : state.sessionID)) {
|
|
970
|
+
handleReopenFailure(state);
|
|
971
|
+
}
|
|
972
|
+
return state;
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
return reopenAfterExpiry().then(state => {
|
|
976
|
+
if (state === null || state === void 0 ? void 0 : state.sessionID) {
|
|
977
|
+
scheduleRetry(state.sessionID);
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
handleReopenFailure(state);
|
|
981
|
+
}
|
|
982
|
+
return state;
|
|
983
|
+
});
|
|
984
|
+
};
|
|
923
985
|
const changeTag = async (memoriId, sessionId, tag, pin) => {
|
|
924
986
|
var _a, _b, _c, _d, _f, _g, _h, _j, _k;
|
|
925
987
|
if (!memoriId || !sessionId) {
|
|
@@ -1115,6 +1177,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1115
1177
|
const { msg, typingText: pendingTypingText, useLoaderTextAsMsg, } = pending;
|
|
1116
1178
|
const currentState = event.currentState;
|
|
1117
1179
|
if (event.resultCode !== 0 || !currentState) {
|
|
1180
|
+
if ((0, isSessionExpiredError_1.isSessionExpiredNatsResponse)(event) && pending.text) {
|
|
1181
|
+
setMemoriTyping(false);
|
|
1182
|
+
setTypingText(undefined);
|
|
1183
|
+
retryAfterExpiredSessionRef.current({
|
|
1184
|
+
text: pending.text,
|
|
1185
|
+
media: pending.media,
|
|
1186
|
+
translate: pending.translate,
|
|
1187
|
+
translatedText: pending.translatedText,
|
|
1188
|
+
hidden: pending.hidden,
|
|
1189
|
+
typingText: pending.typingText,
|
|
1190
|
+
useLoaderTextAsMsg: pending.useLoaderTextAsMsg,
|
|
1191
|
+
hasBatchQueued: pending.hasBatchQueued,
|
|
1192
|
+
expiredSessionID: sessionId,
|
|
1193
|
+
continueFromChatLogID: chatLogID,
|
|
1194
|
+
});
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1118
1197
|
if (event.resultCode === 500 && event.resultMessage) {
|
|
1119
1198
|
setHistory(h => [
|
|
1120
1199
|
...h,
|
|
@@ -1195,6 +1274,31 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1195
1274
|
const deliverEnterTextNatsError = (0, react_1.useCallback)((event) => {
|
|
1196
1275
|
var _a, _b, _c;
|
|
1197
1276
|
const correlationID = event.correlationID;
|
|
1277
|
+
let pending;
|
|
1278
|
+
if (correlationID) {
|
|
1279
|
+
pending = pendingEnterTextRef.current.get(correlationID);
|
|
1280
|
+
if (pending) {
|
|
1281
|
+
clearEnterTextPending(correlationID, pending);
|
|
1282
|
+
(_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')));
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
if ((0, isSessionExpiredError_1.isSessionExpiredNatsError)(event) && (pending === null || pending === void 0 ? void 0 : pending.text)) {
|
|
1286
|
+
setMemoriTyping(false);
|
|
1287
|
+
setTypingText(undefined);
|
|
1288
|
+
retryAfterExpiredSessionRef.current({
|
|
1289
|
+
text: pending.text,
|
|
1290
|
+
media: pending.media,
|
|
1291
|
+
translate: pending.translate,
|
|
1292
|
+
translatedText: pending.translatedText,
|
|
1293
|
+
hidden: pending.hidden,
|
|
1294
|
+
typingText: pending.typingText,
|
|
1295
|
+
useLoaderTextAsMsg: pending.useLoaderTextAsMsg,
|
|
1296
|
+
hasBatchQueued: pending.hasBatchQueued,
|
|
1297
|
+
expiredSessionID: sessionId,
|
|
1298
|
+
continueFromChatLogID: chatLogID,
|
|
1299
|
+
});
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1198
1302
|
const errorText = event.errorMessage
|
|
1199
1303
|
? `Error: ${event.errorMessage}`
|
|
1200
1304
|
: event.errorCode
|
|
@@ -1208,13 +1312,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1208
1312
|
contextVars: {},
|
|
1209
1313
|
date: new Date().toISOString(),
|
|
1210
1314
|
});
|
|
1211
|
-
if (correlationID) {
|
|
1212
|
-
const pending = pendingEnterTextRef.current.get(correlationID);
|
|
1213
|
-
if (pending) {
|
|
1214
|
-
clearEnterTextPending(correlationID, pending);
|
|
1215
|
-
(_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')));
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
1315
|
setMemoriTyping(false);
|
|
1219
1316
|
setTypingText(undefined);
|
|
1220
1317
|
}, [clearEnterTextPending]);
|