@nuskin/react-search-sdk 1.0.0-comx-2233.1 → 1.0.0-comx-2233.2
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 +14 -9
- package/dist/index.d.ts +14 -9
- package/dist/index.js +82 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +82 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ var DEBOUNCE_MS = 220;
|
|
|
12
12
|
var MAX_VISIBLE_SUGGESTIONS = 6;
|
|
13
13
|
var SEARCH_PLACEHOLDER = "Search by product name, ingredient, benefits, or SKU";
|
|
14
14
|
var TRIGGER_PLACEHOLDER = "Product Search";
|
|
15
|
-
var DEFAULT_AI_CHAT_BASE_URL = "https://admin.tst.nuskin.ai/api/analytics/v1/
|
|
15
|
+
var DEFAULT_AI_CHAT_BASE_URL = "https://admin.tst.nuskin.ai/api/analytics/v1/embed";
|
|
16
16
|
var DEFAULT_AI_CHAT_CONVERSATIONS_URL = `${DEFAULT_AI_CHAT_BASE_URL}/conversations`;
|
|
17
17
|
var DEFAULT_AI_CHAT_MESSAGES_URL = `${DEFAULT_AI_CHAT_BASE_URL}/messages`;
|
|
18
18
|
|
|
@@ -763,6 +763,19 @@ function findClosingFence(content, fromIndex) {
|
|
|
763
763
|
}
|
|
764
764
|
return -1;
|
|
765
765
|
}
|
|
766
|
+
function isRecord(value) {
|
|
767
|
+
return value !== null && typeof value === "object";
|
|
768
|
+
}
|
|
769
|
+
function getRenderProductListItems(event) {
|
|
770
|
+
if (event["type"] !== "render" || event["pattern"] !== "product_list") {
|
|
771
|
+
return [];
|
|
772
|
+
}
|
|
773
|
+
const data = event["data"];
|
|
774
|
+
if (!isRecord(data) || !Array.isArray(data["items"])) {
|
|
775
|
+
return [];
|
|
776
|
+
}
|
|
777
|
+
return data["items"].filter(isRecord);
|
|
778
|
+
}
|
|
766
779
|
function extractProductsFromMarkdown(content) {
|
|
767
780
|
const products = [];
|
|
768
781
|
const summaryParts = [];
|
|
@@ -791,7 +804,8 @@ function extractProductsFromMarkdown(content) {
|
|
|
791
804
|
if (Array.isArray(parsed)) {
|
|
792
805
|
products.push(...parsed);
|
|
793
806
|
}
|
|
794
|
-
} catch {
|
|
807
|
+
} catch (e) {
|
|
808
|
+
console.error("Failed to parse products block:", e);
|
|
795
809
|
}
|
|
796
810
|
summaryParts.push(content.slice(summaryCursor, start));
|
|
797
811
|
summaryCursor = end + MARKDOWN_CLOSING_FENCE.length;
|
|
@@ -804,8 +818,10 @@ function createChatService(options) {
|
|
|
804
818
|
const {
|
|
805
819
|
conversationsUrl = DEFAULT_AI_CHAT_CONVERSATIONS_URL,
|
|
806
820
|
messagesUrl = DEFAULT_AI_CHAT_MESSAGES_URL,
|
|
807
|
-
|
|
808
|
-
|
|
821
|
+
salesAiAppKey,
|
|
822
|
+
salesAiParentOrigin,
|
|
823
|
+
market,
|
|
824
|
+
language,
|
|
809
825
|
fetchImpl: fetchImplOption
|
|
810
826
|
} = options;
|
|
811
827
|
let fetchImpl;
|
|
@@ -818,22 +834,30 @@ function createChatService(options) {
|
|
|
818
834
|
throw new Error("ChatService: no fetch implementation available");
|
|
819
835
|
};
|
|
820
836
|
}
|
|
821
|
-
function buildHeaders(extra) {
|
|
837
|
+
function buildHeaders(extra, includeJsonContentType = true) {
|
|
822
838
|
const headers = {
|
|
823
|
-
"Content-Type": "application/json",
|
|
824
839
|
...extra
|
|
825
840
|
};
|
|
826
|
-
if (
|
|
827
|
-
|
|
828
|
-
|
|
841
|
+
if (includeJsonContentType) {
|
|
842
|
+
headers["Content-Type"] = "application/json";
|
|
843
|
+
}
|
|
844
|
+
const accessToken = typeof window !== "undefined" ? window.localStorage?.getItem("accessToken") : null;
|
|
845
|
+
if (accessToken) {
|
|
846
|
+
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
847
|
+
}
|
|
848
|
+
if (salesAiAppKey) {
|
|
849
|
+
headers["X-Sales-AI-App-Key"] = salesAiAppKey;
|
|
850
|
+
}
|
|
851
|
+
if (salesAiParentOrigin) {
|
|
852
|
+
headers["X-Sales-AI-Parent-Origin"] = salesAiParentOrigin;
|
|
853
|
+
}
|
|
829
854
|
return headers;
|
|
830
855
|
}
|
|
831
856
|
return {
|
|
832
|
-
async createConversation(
|
|
857
|
+
async createConversation() {
|
|
833
858
|
const res = await fetchImpl(conversationsUrl, {
|
|
834
859
|
method: "POST",
|
|
835
|
-
headers: buildHeaders()
|
|
836
|
-
body: JSON.stringify({ title })
|
|
860
|
+
headers: buildHeaders(void 0, false)
|
|
837
861
|
});
|
|
838
862
|
if (!res.ok) {
|
|
839
863
|
throw new Error(
|
|
@@ -850,14 +874,26 @@ function createChatService(options) {
|
|
|
850
874
|
return id;
|
|
851
875
|
},
|
|
852
876
|
async sendMessage(conversationId, content, onChunk) {
|
|
877
|
+
const requestBody = {
|
|
878
|
+
conversation_id: conversationId,
|
|
879
|
+
content
|
|
880
|
+
};
|
|
881
|
+
if (market || language) {
|
|
882
|
+
requestBody.scope_context = {
|
|
883
|
+
market: market ?? "US",
|
|
884
|
+
language: language ?? "en"
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
requestBody.client_capabilities = {
|
|
888
|
+
patterns: {
|
|
889
|
+
product_list: [1],
|
|
890
|
+
follow_up: [1]
|
|
891
|
+
}
|
|
892
|
+
};
|
|
853
893
|
const res = await fetchImpl(messagesUrl, {
|
|
854
894
|
method: "POST",
|
|
855
|
-
headers: buildHeaders({ Accept: "
|
|
856
|
-
body: JSON.stringify(
|
|
857
|
-
conversation_id: conversationId,
|
|
858
|
-
content,
|
|
859
|
-
compact: false
|
|
860
|
-
})
|
|
895
|
+
headers: buildHeaders({ Accept: "text/event-stream" }),
|
|
896
|
+
body: JSON.stringify(requestBody)
|
|
861
897
|
});
|
|
862
898
|
if (!res.ok) {
|
|
863
899
|
throw new Error(
|
|
@@ -865,6 +901,7 @@ function createChatService(options) {
|
|
|
865
901
|
);
|
|
866
902
|
}
|
|
867
903
|
let accumulated = "";
|
|
904
|
+
const renderedProducts = [];
|
|
868
905
|
const parser = createParser({
|
|
869
906
|
onEvent(event) {
|
|
870
907
|
const data = event.data;
|
|
@@ -873,6 +910,9 @@ function createChatService(options) {
|
|
|
873
910
|
const parsed = JSON.parse(data);
|
|
874
911
|
const parsedType = parsed["type"];
|
|
875
912
|
const type = typeof parsedType === "string" ? parsedType : "";
|
|
913
|
+
renderedProducts.push(
|
|
914
|
+
...getRenderProductListItems(parsed)
|
|
915
|
+
);
|
|
876
916
|
if (type === "content" && typeof parsed["text"] === "string") {
|
|
877
917
|
const text = parsed["text"];
|
|
878
918
|
accumulated += text;
|
|
@@ -900,7 +940,12 @@ function createChatService(options) {
|
|
|
900
940
|
parser.feed(rawBody);
|
|
901
941
|
}
|
|
902
942
|
const { summary, products } = extractProductsFromMarkdown(accumulated);
|
|
903
|
-
|
|
943
|
+
const finalProducts = renderedProducts.length > 0 ? renderedProducts : products;
|
|
944
|
+
return {
|
|
945
|
+
summary,
|
|
946
|
+
products: finalProducts,
|
|
947
|
+
rawContent: accumulated
|
|
948
|
+
};
|
|
904
949
|
}
|
|
905
950
|
};
|
|
906
951
|
}
|
|
@@ -1647,6 +1692,7 @@ function getSpeechRecognition() {
|
|
|
1647
1692
|
}
|
|
1648
1693
|
function useVoiceSearch({
|
|
1649
1694
|
lang,
|
|
1695
|
+
onInterimResult,
|
|
1650
1696
|
onResult,
|
|
1651
1697
|
onError
|
|
1652
1698
|
}) {
|
|
@@ -1664,11 +1710,24 @@ function useVoiceSearch({
|
|
|
1664
1710
|
stop();
|
|
1665
1711
|
const rec = new SR();
|
|
1666
1712
|
rec.lang = lang ?? navigator.language ?? "en-US";
|
|
1667
|
-
rec.interimResults =
|
|
1713
|
+
rec.interimResults = true;
|
|
1668
1714
|
rec.maxAlternatives = 1;
|
|
1669
1715
|
rec.onresult = (event) => {
|
|
1670
|
-
|
|
1671
|
-
|
|
1716
|
+
let finalTranscript = "";
|
|
1717
|
+
let interimTranscript = "";
|
|
1718
|
+
const startIndex = event.resultIndex ?? 0;
|
|
1719
|
+
for (let index = startIndex; index < event.results.length; index += 1) {
|
|
1720
|
+
const result = event.results[index];
|
|
1721
|
+
const transcript = result?.[0]?.transcript ?? "";
|
|
1722
|
+
if (!transcript) continue;
|
|
1723
|
+
if (result?.isFinal) {
|
|
1724
|
+
finalTranscript += transcript;
|
|
1725
|
+
} else {
|
|
1726
|
+
interimTranscript += transcript;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
if (interimTranscript) onInterimResult?.(interimTranscript);
|
|
1730
|
+
if (finalTranscript) onResult(finalTranscript);
|
|
1672
1731
|
};
|
|
1673
1732
|
rec.onerror = (event) => {
|
|
1674
1733
|
onError?.(event);
|
|
@@ -1678,7 +1737,7 @@ function useVoiceSearch({
|
|
|
1678
1737
|
recognitionRef.current = rec;
|
|
1679
1738
|
rec.start();
|
|
1680
1739
|
setListening(true);
|
|
1681
|
-
}, [lang, onResult, onError, stop]);
|
|
1740
|
+
}, [lang, onInterimResult, onResult, onError, stop]);
|
|
1682
1741
|
return { listening, supported, start, stop };
|
|
1683
1742
|
}
|
|
1684
1743
|
|