@nuskin/react-search-sdk 1.0.0-comx-2233.3 → 1.0.0-comx-2233.4

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.mjs CHANGED
@@ -1248,6 +1248,7 @@ function useSearchSuggestions({
1248
1248
  const [didYouMean, setDidYouMean] = useState([]);
1249
1249
  const [loading, setLoading] = useState(false);
1250
1250
  const [emptyFetched, setEmptyFetched] = useState(false);
1251
+ const [suggestionFetchFailed, setSuggestionFetchFailed] = useState(false);
1251
1252
  const [hasMoreResults, setHasMoreResults] = useState(false);
1252
1253
  const [totalResultsCount, setTotalResultsCount] = useState(0);
1253
1254
  const fetchDebounced = useRef(null);
@@ -1256,6 +1257,7 @@ function useSearchSuggestions({
1256
1257
  setSuggestions([]);
1257
1258
  setDidYouMean([]);
1258
1259
  setEmptyFetched(false);
1260
+ setSuggestionFetchFailed(false);
1259
1261
  setHasMoreResults(false);
1260
1262
  setTotalResultsCount(0);
1261
1263
  setLoading(false);
@@ -1264,6 +1266,7 @@ function useSearchSuggestions({
1264
1266
  (nextQuery) => {
1265
1267
  const hasNextQuery = Boolean(nextQuery.trim());
1266
1268
  setEmptyFetched(false);
1269
+ setSuggestionFetchFailed(false);
1267
1270
  setLoading(enabled && hasNextQuery);
1268
1271
  setQuery(nextQuery);
1269
1272
  },
@@ -1283,6 +1286,7 @@ function useSearchSuggestions({
1283
1286
  }
1284
1287
  setLoading(true);
1285
1288
  setEmptyFetched(false);
1289
+ setSuggestionFetchFailed(false);
1286
1290
  try {
1287
1291
  const fetchedSuggestions = await service.fetchSuggestions(trimmedQuery);
1288
1292
  if (requestId !== latestRequestId.current) {
@@ -1305,6 +1309,7 @@ function useSearchSuggestions({
1305
1309
  !hasDidYouMean && effectiveTotal > MAX_VISIBLE_SUGGESTIONS
1306
1310
  );
1307
1311
  setTotalResultsCount(effectiveTotal);
1312
+ setSuggestionFetchFailed(false);
1308
1313
  setEmptyFetched(
1309
1314
  hasDidYouMean ? false : visibleSuggestions.length === 0 && suggestedTerms.length === 0
1310
1315
  );
@@ -1315,6 +1320,7 @@ function useSearchSuggestions({
1315
1320
  setSuggestions([]);
1316
1321
  setDidYouMean([]);
1317
1322
  setEmptyFetched(true);
1323
+ setSuggestionFetchFailed(true);
1318
1324
  setHasMoreResults(false);
1319
1325
  setTotalResultsCount(0);
1320
1326
  } finally {
@@ -1352,6 +1358,7 @@ function useSearchSuggestions({
1352
1358
  loading,
1353
1359
  query,
1354
1360
  setQuery,
1361
+ suggestionFetchFailed,
1355
1362
  suggestions,
1356
1363
  totalResultsCount,
1357
1364
  updateQuery
@@ -1734,6 +1741,188 @@ function useVoiceSearch({
1734
1741
  return { listening, supported, start, stop };
1735
1742
  }
1736
1743
 
1737
- export { CATALOG_SUGGESTIONS_PATH, DEBOUNCE_MS, DEFAULT_AI_CHAT_BASE_URL, DEFAULT_AI_CHAT_CONVERSATIONS_URL, DEFAULT_AI_CHAT_MESSAGES_URL, DEFAULT_SEARCH_PATH, DEFAULT_SUGGESTION_PAGE, DEFAULT_SUGGESTION_SIZE, MAX_VISIBLE_SUGGESTIONS, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, TRIGGER_PLACEHOLDER, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, resolveApiGatewayPath, resolveSuggestionImageSrc, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
1744
+ // src/utils/commonUtils.ts
1745
+ var IS_BROWSER = typeof window !== "undefined";
1746
+ function toEventString(value, fallback = " ") {
1747
+ if (value === void 0 || value === null) return fallback;
1748
+ const str = String(value).trim();
1749
+ return str.length > 0 ? str : fallback;
1750
+ }
1751
+ function getLocaleFromUrl(pathname) {
1752
+ const path = pathname ?? (IS_BROWSER ? window.location.pathname : "");
1753
+ const [country, language] = path.split("/").filter(Boolean);
1754
+ if (!/^[a-z]{2}$/i.test(country ?? "") || !/^[a-z]{2}$/i.test(language ?? "")) {
1755
+ return {};
1756
+ }
1757
+ return {
1758
+ countryCode: country.toUpperCase(),
1759
+ language: language.toLowerCase()
1760
+ };
1761
+ }
1762
+ function safeParse(raw) {
1763
+ try {
1764
+ return JSON.parse(raw);
1765
+ } catch {
1766
+ return raw;
1767
+ }
1768
+ }
1769
+ function getLocalStorage(key) {
1770
+ if (!IS_BROWSER) return void 0;
1771
+ try {
1772
+ const raw = window.localStorage.getItem(key);
1773
+ return raw === null ? void 0 : safeParse(raw);
1774
+ } catch {
1775
+ return void 0;
1776
+ }
1777
+ }
1778
+ function getSessionStorage2(key) {
1779
+ if (!IS_BROWSER) return void 0;
1780
+ try {
1781
+ const raw = window.sessionStorage.getItem(key);
1782
+ return raw === null ? void 0 : safeParse(raw);
1783
+ } catch {
1784
+ return void 0;
1785
+ }
1786
+ }
1787
+
1788
+ // src/utils/gtmConstants.ts
1789
+ var SEARCH_GTM_EVENTS = {
1790
+ CHAT_ENTRY_POINT: "Begin_chat",
1791
+ SEARCH_TYPE: "Search_Type",
1792
+ PRODUCT_SEARCH: "ProductSearch",
1793
+ ERROR_POPUP: "Error_popup"
1794
+ };
1795
+ var SEARCH_GTM_SEARCH_TYPES = {
1796
+ SEMANTIC: "semantic search",
1797
+ AI_AGENT: "AI agent"
1798
+ };
1799
+ var SEARCH_GTM_USER_STATUS = {
1800
+ GUEST: "guest",
1801
+ LOGGED_IN: "logged_in"
1802
+ };
1803
+ var AI_CHAT_CONVERSATION_ID_KEY = "ai_chat_conversation_id";
1804
+ var IS_AUTHENTICATED_KEY = "IsAuthenticated";
1805
+ var ACCOUNT_TYPE_KEY = "accountType";
1806
+ var NUSKIN_ACCOUNT_DATA_KEY = "nuskin.account.data";
1807
+ var GTM_FALLBACK_NA = "NA";
1808
+
1809
+ // src/utils/gtmTracking.ts
1810
+ function readSessionChatId() {
1811
+ const raw = getSessionStorage2(AI_CHAT_CONVERSATION_ID_KEY);
1812
+ return typeof raw === "string" || typeof raw === "number" ? String(raw) : void 0;
1813
+ }
1814
+ function readUserStatusFromStorage() {
1815
+ const value = getLocalStorage(IS_AUTHENTICATED_KEY);
1816
+ if (value === void 0) return void 0;
1817
+ if (value === SEARCH_GTM_USER_STATUS.GUEST || value === SEARCH_GTM_USER_STATUS.LOGGED_IN) {
1818
+ return value;
1819
+ }
1820
+ const isAuthenticated = value === true || typeof value === "string" && ["true", "1", "yes", "y"].includes(value.toLowerCase().trim());
1821
+ return isAuthenticated ? SEARCH_GTM_USER_STATUS.LOGGED_IN : SEARCH_GTM_USER_STATUS.GUEST;
1822
+ }
1823
+ function readAccountTypeFromStorage() {
1824
+ const value = getLocalStorage(ACCOUNT_TYPE_KEY);
1825
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1826
+ }
1827
+ function readUserIdFromStorage() {
1828
+ const raw = getLocalStorage(NUSKIN_ACCOUNT_DATA_KEY);
1829
+ if (!raw || typeof raw !== "object") return void 0;
1830
+ const user = raw.user;
1831
+ if (!user || typeof user !== "object") return void 0;
1832
+ const id = user.id;
1833
+ return typeof id === "string" && id.trim().length > 0 ? id : void 0;
1834
+ }
1835
+ function resolveUserId(explicit) {
1836
+ return toEventString(explicit ?? readUserIdFromStorage(), GTM_FALLBACK_NA);
1837
+ }
1838
+ function baseEventPayload(ctx) {
1839
+ const urlLocale = getLocaleFromUrl();
1840
+ const chatId = ctx.chatId ?? readSessionChatId();
1841
+ const userStatus = ctx.userStatus ?? readUserStatusFromStorage();
1842
+ const accountType = ctx.accountType ?? readAccountTypeFromStorage();
1843
+ const resolvedUserStatus = userStatus ?? SEARCH_GTM_USER_STATUS.GUEST;
1844
+ const documentTitle = IS_BROWSER && typeof document?.title === "string" ? document.title : void 0;
1845
+ return {
1846
+ Chat_ID: toEventString(chatId, GTM_FALLBACK_NA),
1847
+ page_type: toEventString(
1848
+ ctx.pageType ?? documentTitle,
1849
+ GTM_FALLBACK_NA
1850
+ ),
1851
+ country_code: toEventString(
1852
+ ctx.countryCode ?? urlLocale.countryCode,
1853
+ GTM_FALLBACK_NA
1854
+ ),
1855
+ language: toEventString(
1856
+ ctx.language ?? urlLocale.language,
1857
+ GTM_FALLBACK_NA
1858
+ ),
1859
+ user_status: toEventString(
1860
+ resolvedUserStatus,
1861
+ SEARCH_GTM_USER_STATUS.GUEST
1862
+ ),
1863
+ account_type: toEventString(accountType, GTM_FALLBACK_NA)
1864
+ };
1865
+ }
1866
+ function serializeProductResults(productResultsData, productResults) {
1867
+ if (productResultsData !== void 0) {
1868
+ try {
1869
+ return JSON.stringify(productResultsData);
1870
+ } catch {
1871
+ return GTM_FALLBACK_NA;
1872
+ }
1873
+ }
1874
+ if (productResults === void 0 || productResults === null) {
1875
+ return GTM_FALLBACK_NA;
1876
+ }
1877
+ return String(productResults);
1878
+ }
1879
+ function pushGtmEvent(event) {
1880
+ if (!IS_BROWSER) return;
1881
+ try {
1882
+ const layer = window.dataLayer ?? (window.dataLayer = []);
1883
+ layer.push(event);
1884
+ } catch (err) {
1885
+ if (typeof console !== "undefined") {
1886
+ console.warn("[react-search-sdk] pushGtmEvent failed:", err);
1887
+ }
1888
+ }
1889
+ }
1890
+ function trackChatEntryPoint(ctx) {
1891
+ pushGtmEvent({
1892
+ event: SEARCH_GTM_EVENTS.CHAT_ENTRY_POINT,
1893
+ ...baseEventPayload(ctx)
1894
+ });
1895
+ }
1896
+ function trackSearchType(input) {
1897
+ pushGtmEvent({
1898
+ event: SEARCH_GTM_EVENTS.SEARCH_TYPE,
1899
+ ...baseEventPayload(input),
1900
+ id: resolveUserId(input.userId),
1901
+ type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC,
1902
+ search_response: toEventString(input.searchResponse, GTM_FALLBACK_NA)
1903
+ });
1904
+ }
1905
+ function trackProductSearch(input) {
1906
+ pushGtmEvent({
1907
+ event: SEARCH_GTM_EVENTS.PRODUCT_SEARCH,
1908
+ ...baseEventPayload(input),
1909
+ id: resolveUserId(input.userId),
1910
+ search_type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC,
1911
+ Product_results: serializeProductResults(
1912
+ input.productResultsData,
1913
+ input.productResults
1914
+ )
1915
+ });
1916
+ }
1917
+ function trackErrorPopup(input) {
1918
+ pushGtmEvent({
1919
+ event: SEARCH_GTM_EVENTS.ERROR_POPUP,
1920
+ ...baseEventPayload(input),
1921
+ id: resolveUserId(input.userId),
1922
+ search_type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC
1923
+ });
1924
+ }
1925
+
1926
+ export { CATALOG_SUGGESTIONS_PATH, DEBOUNCE_MS, DEFAULT_AI_CHAT_BASE_URL, DEFAULT_AI_CHAT_CONVERSATIONS_URL, DEFAULT_AI_CHAT_MESSAGES_URL, DEFAULT_SEARCH_PATH, DEFAULT_SUGGESTION_PAGE, DEFAULT_SUGGESTION_SIZE, MAX_VISIBLE_SUGGESTIONS, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_GTM_EVENTS, SEARCH_GTM_SEARCH_TYPES, SEARCH_GTM_USER_STATUS, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, TRIGGER_PLACEHOLDER, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getLocaleFromUrl, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, pushGtmEvent, resolveApiGatewayPath, resolveSuggestionImageSrc, trackChatEntryPoint, trackErrorPopup, trackProductSearch, trackSearchType, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
1738
1927
  //# sourceMappingURL=index.mjs.map
1739
1928
  //# sourceMappingURL=index.mjs.map