@paymanai/payman-typescript-ask-sdk 1.2.4 → 1.2.5
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.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +176 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -8
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +181 -7
- package/dist/index.native.js.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useRef,
|
|
1
|
+
import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
// src/hooks/useChat.ts
|
|
4
4
|
|
|
@@ -612,6 +612,84 @@ async function cancelUserAction(config, userActionId) {
|
|
|
612
612
|
async function resendUserAction(config, userActionId) {
|
|
613
613
|
return sendUserActionRequest(config, userActionId, "resend");
|
|
614
614
|
}
|
|
615
|
+
|
|
616
|
+
// src/utils/chatStore.ts
|
|
617
|
+
var memoryStore = /* @__PURE__ */ new Map();
|
|
618
|
+
var chatStore = {
|
|
619
|
+
get(key) {
|
|
620
|
+
return memoryStore.get(key) ?? [];
|
|
621
|
+
},
|
|
622
|
+
set(key, messages) {
|
|
623
|
+
memoryStore.set(key, messages);
|
|
624
|
+
},
|
|
625
|
+
delete(key) {
|
|
626
|
+
memoryStore.delete(key);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/utils/activeStreamStore.ts
|
|
631
|
+
var streams = /* @__PURE__ */ new Map();
|
|
632
|
+
var activeStreamStore = {
|
|
633
|
+
has(key) {
|
|
634
|
+
return streams.has(key);
|
|
635
|
+
},
|
|
636
|
+
get(key) {
|
|
637
|
+
const entry = streams.get(key);
|
|
638
|
+
if (!entry) return null;
|
|
639
|
+
return { messages: entry.messages, isWaiting: entry.isWaiting };
|
|
640
|
+
},
|
|
641
|
+
// Called before startStream — registers the controller and initial messages
|
|
642
|
+
start(key, abortController, initialMessages) {
|
|
643
|
+
const existing = streams.get(key);
|
|
644
|
+
streams.set(key, {
|
|
645
|
+
messages: initialMessages,
|
|
646
|
+
isWaiting: true,
|
|
647
|
+
abortController,
|
|
648
|
+
listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
|
|
649
|
+
});
|
|
650
|
+
},
|
|
651
|
+
// Called by the stream on every event — applies the same updater pattern React uses
|
|
652
|
+
applyMessages(key, updater) {
|
|
653
|
+
const entry = streams.get(key);
|
|
654
|
+
if (!entry) return;
|
|
655
|
+
const next = typeof updater === "function" ? updater(entry.messages) : updater;
|
|
656
|
+
entry.messages = next;
|
|
657
|
+
entry.listeners.forEach((l) => l(next, entry.isWaiting));
|
|
658
|
+
},
|
|
659
|
+
setWaiting(key, waiting) {
|
|
660
|
+
const entry = streams.get(key);
|
|
661
|
+
if (!entry) return;
|
|
662
|
+
entry.isWaiting = waiting;
|
|
663
|
+
entry.listeners.forEach((l) => l(entry.messages, waiting));
|
|
664
|
+
},
|
|
665
|
+
// Called when stream completes — persists to chatStore and cleans up
|
|
666
|
+
complete(key) {
|
|
667
|
+
const entry = streams.get(key);
|
|
668
|
+
if (!entry) return;
|
|
669
|
+
entry.isWaiting = false;
|
|
670
|
+
entry.listeners.forEach((l) => l(entry.messages, false));
|
|
671
|
+
const toSave = entry.messages.filter((m) => !m.isStreaming);
|
|
672
|
+
if (toSave.length > 0) chatStore.set(key, toSave);
|
|
673
|
+
streams.delete(key);
|
|
674
|
+
},
|
|
675
|
+
// Subscribe — returns unsubscribe fn. Component calls this on mount, cleanup on unmount.
|
|
676
|
+
subscribe(key, listener) {
|
|
677
|
+
const entry = streams.get(key);
|
|
678
|
+
if (!entry) return () => {
|
|
679
|
+
};
|
|
680
|
+
entry.listeners.add(listener);
|
|
681
|
+
return () => {
|
|
682
|
+
streams.get(key)?.listeners.delete(listener);
|
|
683
|
+
};
|
|
684
|
+
},
|
|
685
|
+
// Explicit user cancel — aborts the controller and removes the entry
|
|
686
|
+
abort(key) {
|
|
687
|
+
const entry = streams.get(key);
|
|
688
|
+
if (!entry) return;
|
|
689
|
+
entry.abortController.abort();
|
|
690
|
+
streams.delete(key);
|
|
691
|
+
}
|
|
692
|
+
};
|
|
615
693
|
function useStreamManager(config, callbacks, setMessages, setIsWaitingForResponse) {
|
|
616
694
|
const abortControllerRef = useRef(null);
|
|
617
695
|
const configRef = useRef(config);
|
|
@@ -619,9 +697,9 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
619
697
|
const callbacksRef = useRef(callbacks);
|
|
620
698
|
callbacksRef.current = callbacks;
|
|
621
699
|
const startStream = useCallback(
|
|
622
|
-
async (userMessage, streamingId, sessionId) => {
|
|
700
|
+
async (userMessage, streamingId, sessionId, externalAbortController) => {
|
|
623
701
|
abortControllerRef.current?.abort();
|
|
624
|
-
const abortController = new AbortController();
|
|
702
|
+
const abortController = externalAbortController ?? new AbortController();
|
|
625
703
|
abortControllerRef.current = abortController;
|
|
626
704
|
const state = {
|
|
627
705
|
accumulatedContent: "",
|
|
@@ -825,13 +903,43 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
825
903
|
|
|
826
904
|
// src/hooks/useChat.ts
|
|
827
905
|
function useChat(config, callbacks = {}) {
|
|
828
|
-
const [messages, setMessages] = useState(
|
|
906
|
+
const [messages, setMessages] = useState(() => {
|
|
907
|
+
if (config.userId) return chatStore.get(config.userId);
|
|
908
|
+
return config.initialMessages ?? [];
|
|
909
|
+
});
|
|
829
910
|
const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
|
|
830
|
-
const sessionIdRef = useRef(
|
|
911
|
+
const sessionIdRef = useRef(
|
|
912
|
+
config.userId ? chatStore.get(config.userId).find((m) => m.sessionId)?.sessionId ?? config.initialSessionId ?? void 0 : config.initialSessionId ?? void 0
|
|
913
|
+
);
|
|
914
|
+
const prevUserIdRef = useRef(config.userId);
|
|
831
915
|
const callbacksRef = useRef(callbacks);
|
|
832
916
|
callbacksRef.current = callbacks;
|
|
833
917
|
const configRef = useRef(config);
|
|
834
918
|
configRef.current = config;
|
|
919
|
+
const messagesRef = useRef(messages);
|
|
920
|
+
messagesRef.current = messages;
|
|
921
|
+
const storeAwareSetMessages = useCallback(
|
|
922
|
+
(updater) => {
|
|
923
|
+
const { userId } = configRef.current;
|
|
924
|
+
if (userId && activeStreamStore.has(userId)) {
|
|
925
|
+
activeStreamStore.applyMessages(userId, updater);
|
|
926
|
+
}
|
|
927
|
+
setMessages(updater);
|
|
928
|
+
},
|
|
929
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
930
|
+
[]
|
|
931
|
+
);
|
|
932
|
+
const storeAwareSetIsWaiting = useCallback(
|
|
933
|
+
(waiting) => {
|
|
934
|
+
const { userId } = configRef.current;
|
|
935
|
+
if (userId && activeStreamStore.has(userId)) {
|
|
936
|
+
activeStreamStore.setWaiting(userId, waiting);
|
|
937
|
+
}
|
|
938
|
+
setIsWaitingForResponse(waiting);
|
|
939
|
+
},
|
|
940
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
941
|
+
[]
|
|
942
|
+
);
|
|
835
943
|
const [userActionState, setUserActionState] = useState({
|
|
836
944
|
request: null,
|
|
837
945
|
result: null,
|
|
@@ -874,8 +982,8 @@ function useChat(config, callbacks = {}) {
|
|
|
874
982
|
const { startStream, cancelStream: cancelStreamManager, abortControllerRef } = useStreamManager(
|
|
875
983
|
config,
|
|
876
984
|
wrappedCallbacks,
|
|
877
|
-
|
|
878
|
-
|
|
985
|
+
storeAwareSetMessages,
|
|
986
|
+
storeAwareSetIsWaiting
|
|
879
987
|
);
|
|
880
988
|
const sendMessage = useCallback(
|
|
881
989
|
async (userMessage) => {
|
|
@@ -912,11 +1020,21 @@ function useChat(config, callbacks = {}) {
|
|
|
912
1020
|
currentMessage: void 0
|
|
913
1021
|
};
|
|
914
1022
|
setMessages((prev) => [...prev, streamingMsg]);
|
|
1023
|
+
const abortController = new AbortController();
|
|
1024
|
+
const { userId } = configRef.current;
|
|
1025
|
+
if (userId) {
|
|
1026
|
+
const initialMessages = [...messagesRef.current, userMsg, streamingMsg];
|
|
1027
|
+
activeStreamStore.start(userId, abortController, initialMessages);
|
|
1028
|
+
}
|
|
915
1029
|
const newSessionId = await startStream(
|
|
916
1030
|
userMessage,
|
|
917
1031
|
streamingId,
|
|
918
|
-
sessionIdRef.current
|
|
1032
|
+
sessionIdRef.current,
|
|
1033
|
+
abortController
|
|
919
1034
|
);
|
|
1035
|
+
if (userId) {
|
|
1036
|
+
activeStreamStore.complete(userId);
|
|
1037
|
+
}
|
|
920
1038
|
if (newSessionId && newSessionId !== sessionIdRef.current) {
|
|
921
1039
|
sessionIdRef.current = newSessionId;
|
|
922
1040
|
}
|
|
@@ -924,9 +1042,18 @@ function useChat(config, callbacks = {}) {
|
|
|
924
1042
|
[startStream]
|
|
925
1043
|
);
|
|
926
1044
|
const clearMessages = useCallback(() => {
|
|
1045
|
+
if (configRef.current.userId) {
|
|
1046
|
+
chatStore.delete(configRef.current.userId);
|
|
1047
|
+
}
|
|
927
1048
|
setMessages([]);
|
|
928
1049
|
}, []);
|
|
1050
|
+
const prependMessages = useCallback((msgs) => {
|
|
1051
|
+
setMessages((prev) => [...msgs, ...prev]);
|
|
1052
|
+
}, []);
|
|
929
1053
|
const cancelStream = useCallback(() => {
|
|
1054
|
+
if (configRef.current.userId) {
|
|
1055
|
+
activeStreamStore.abort(configRef.current.userId);
|
|
1056
|
+
}
|
|
930
1057
|
cancelStreamManager();
|
|
931
1058
|
setIsWaitingForResponse(false);
|
|
932
1059
|
setUserActionState((prev) => ({ ...prev, request: null, result: null }));
|
|
@@ -946,6 +1073,10 @@ function useChat(config, callbacks = {}) {
|
|
|
946
1073
|
);
|
|
947
1074
|
}, [cancelStreamManager]);
|
|
948
1075
|
const resetSession = useCallback(() => {
|
|
1076
|
+
if (configRef.current.userId) {
|
|
1077
|
+
activeStreamStore.abort(configRef.current.userId);
|
|
1078
|
+
chatStore.delete(configRef.current.userId);
|
|
1079
|
+
}
|
|
949
1080
|
setMessages([]);
|
|
950
1081
|
sessionIdRef.current = void 0;
|
|
951
1082
|
abortControllerRef.current?.abort();
|
|
@@ -1008,10 +1139,48 @@ function useChat(config, callbacks = {}) {
|
|
|
1008
1139
|
throw error;
|
|
1009
1140
|
}
|
|
1010
1141
|
}, []);
|
|
1142
|
+
useEffect(() => {
|
|
1143
|
+
const { userId } = config;
|
|
1144
|
+
if (!userId) return;
|
|
1145
|
+
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
|
|
1146
|
+
setMessages(msgs);
|
|
1147
|
+
setIsWaitingForResponse(isWaiting);
|
|
1148
|
+
});
|
|
1149
|
+
const active = activeStreamStore.get(userId);
|
|
1150
|
+
if (active) {
|
|
1151
|
+
setMessages(active.messages);
|
|
1152
|
+
setIsWaitingForResponse(active.isWaiting);
|
|
1153
|
+
}
|
|
1154
|
+
return unsubscribe;
|
|
1155
|
+
}, []);
|
|
1156
|
+
useEffect(() => {
|
|
1157
|
+
if (!config.userId) return;
|
|
1158
|
+
const toSave = messages.filter((m) => !m.isStreaming);
|
|
1159
|
+
if (toSave.length > 0) {
|
|
1160
|
+
chatStore.set(config.userId, toSave);
|
|
1161
|
+
}
|
|
1162
|
+
}, [messages, config.userId]);
|
|
1163
|
+
useEffect(() => {
|
|
1164
|
+
const prevUserId = prevUserIdRef.current;
|
|
1165
|
+
prevUserIdRef.current = config.userId;
|
|
1166
|
+
if (prevUserId === config.userId) return;
|
|
1167
|
+
if (prevUserId && !config.userId) {
|
|
1168
|
+
chatStore.delete(prevUserId);
|
|
1169
|
+
setMessages([]);
|
|
1170
|
+
sessionIdRef.current = void 0;
|
|
1171
|
+
setIsWaitingForResponse(false);
|
|
1172
|
+
setUserActionState({ request: null, result: null, clearOtpTrigger: 0 });
|
|
1173
|
+
} else if (config.userId) {
|
|
1174
|
+
const stored = chatStore.get(config.userId);
|
|
1175
|
+
setMessages(stored);
|
|
1176
|
+
sessionIdRef.current = stored.find((m) => m.sessionId)?.sessionId;
|
|
1177
|
+
}
|
|
1178
|
+
}, [config.userId]);
|
|
1011
1179
|
return {
|
|
1012
1180
|
messages,
|
|
1013
1181
|
sendMessage,
|
|
1014
1182
|
clearMessages,
|
|
1183
|
+
prependMessages,
|
|
1015
1184
|
cancelStream,
|
|
1016
1185
|
resetSession,
|
|
1017
1186
|
getSessionId,
|