@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.d.mts +136 -7
- package/dist/index.d.ts +136 -7
- package/dist/index.js +198 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +190 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -148,6 +148,8 @@ interface UseSearchSuggestionsResult {
|
|
|
148
148
|
hasMoreResults: boolean;
|
|
149
149
|
/** `true` when the trimmed query is non-empty. */
|
|
150
150
|
hasQuery: boolean;
|
|
151
|
+
/** `true` when the latest suggestions request failed. */
|
|
152
|
+
suggestionFetchFailed: boolean;
|
|
151
153
|
/** Normalised "Did You Mean?" items from the API. */
|
|
152
154
|
didYouMean: DidYouMeanItem[];
|
|
153
155
|
/** `true` while a debounced fetch is in flight. */
|
|
@@ -205,25 +207,25 @@ interface SearchServiceOptions {
|
|
|
205
207
|
*/
|
|
206
208
|
onSuggestionAction?: (option: SuggestionOption) => Promise<boolean> | boolean | undefined;
|
|
207
209
|
}
|
|
208
|
-
/** Public API returned by `createSearchService`.
|
|
210
|
+
/** Public API returned by `createSearchService`. */
|
|
209
211
|
interface SearchService {
|
|
210
212
|
/** Returns fallback placeholder + aria-label copy. */
|
|
211
213
|
getSearchChromeCopy: () => Promise<SearchChromeCopy>;
|
|
212
214
|
/** Fetches typeahead suggestions from the Equinox catalog. */
|
|
213
215
|
fetchSuggestions: (searchTerm: string) => Promise<SuggestionsResponse>;
|
|
214
216
|
/**
|
|
215
|
-
* Records the query in recent searches, then
|
|
216
|
-
*
|
|
217
|
+
* Records the query in recent searches, then returns the option URL or the
|
|
218
|
+
* fallback search-results path for the consuming router to navigate.
|
|
217
219
|
*/
|
|
218
220
|
submitProductSearch: (query: string, option?: SuggestionOption) => string | undefined;
|
|
219
221
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
+
* Returns the suggestion's URL if one is resolvable; otherwise submits the
|
|
223
|
+
* suggestion's textual value as a product search.
|
|
222
224
|
*/
|
|
223
225
|
activateSuggestionAction: (option: SuggestionOption) => string | undefined;
|
|
224
226
|
/** Returns the navigable URL for a suggestion option (or `""`). */
|
|
225
227
|
getSuggestionHref: (option: SuggestionOption) => string;
|
|
226
|
-
/**
|
|
228
|
+
/** Returns the search-results page path for `query`. */
|
|
227
229
|
viewMoreResults: (input: {
|
|
228
230
|
query: string;
|
|
229
231
|
}) => string | undefined;
|
|
@@ -473,6 +475,133 @@ declare function getSeeMoreResultsPayload(query: string, totalResultsCount: numb
|
|
|
473
475
|
visibleResultsCount: number;
|
|
474
476
|
};
|
|
475
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Types + Window augmentation for the GTM (Google Tag Manager) tracking layer.
|
|
480
|
+
*/
|
|
481
|
+
declare global {
|
|
482
|
+
interface Window {
|
|
483
|
+
dataLayer?: unknown[];
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
type SearchGtmUserStatus = 'guest' | 'logged_in';
|
|
487
|
+
type SearchGtmSearchType = 'semantic search' | 'AI agent';
|
|
488
|
+
/**
|
|
489
|
+
* Context shared by every AI-chat GTM event. Values that are unknown at
|
|
490
|
+
* emit time should be passed as an empty string so the schema stays stable
|
|
491
|
+
* (matches the placeholder shape the data team provided in COMX-3277).
|
|
492
|
+
*/
|
|
493
|
+
interface SearchGtmContext {
|
|
494
|
+
/** Conversation id from ChatService.createConversation, coerced to string. */
|
|
495
|
+
chatId?: string | number;
|
|
496
|
+
/** Page type where the chat was initiated (e.g. `plp`, `pdp`, `home`). */
|
|
497
|
+
pageType?: string;
|
|
498
|
+
/** ISO 3166-1 alpha-2 country code (e.g. `US`, `DE`). */
|
|
499
|
+
countryCode?: string;
|
|
500
|
+
/** Language code (e.g. `en`, `de`). */
|
|
501
|
+
language?: string;
|
|
502
|
+
/**
|
|
503
|
+
* Whether the visitor is a guest or a logged-in user.
|
|
504
|
+
* Falls back to the `IsAuthenticated` localStorage flag written by the
|
|
505
|
+
* storefront `Session` model when not supplied by the host.
|
|
506
|
+
*/
|
|
507
|
+
userStatus?: SearchGtmUserStatus;
|
|
508
|
+
/** Authenticated user id, or empty for guests. */
|
|
509
|
+
userId?: string;
|
|
510
|
+
/**
|
|
511
|
+
* Customer account type (e.g. `Retail Customer`, `Brand Affiliate`).
|
|
512
|
+
* Falls back to the `accountType` localStorage value written by the
|
|
513
|
+
* storefront `Customer` / `MyAccount` flows when not supplied.
|
|
514
|
+
*/
|
|
515
|
+
accountType?: string;
|
|
516
|
+
}
|
|
517
|
+
/** Payload for the Search_Type event (query the user submitted). */
|
|
518
|
+
interface SearchTypeEventInput extends SearchGtmContext {
|
|
519
|
+
/** Type of AI search: `semantic search` or `AI agent`. */
|
|
520
|
+
searchType?: SearchGtmSearchType;
|
|
521
|
+
/** User's raw search query / response text. */
|
|
522
|
+
searchResponse?: string;
|
|
523
|
+
}
|
|
524
|
+
/** Payload for the ProductSearch event (results returned to the user). */
|
|
525
|
+
interface ProductSearchEventInput extends SearchGtmContext {
|
|
526
|
+
searchType?: SearchGtmSearchType;
|
|
527
|
+
/** Number of product results shown to the user. */
|
|
528
|
+
productResults?: number;
|
|
529
|
+
/** Raw products payload to send into Product_results as JSON string. */
|
|
530
|
+
productResultsData?: unknown;
|
|
531
|
+
}
|
|
532
|
+
/** Payload for the Error_popup event. */
|
|
533
|
+
interface ErrorPopupEventInput extends SearchGtmContext {
|
|
534
|
+
searchType?: SearchGtmSearchType;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Extracts `{ countryCode, language }` from a storefront-shaped path
|
|
539
|
+
* (`/{country}/{language}/...`, e.g. `/us/en/product/x`).
|
|
540
|
+
*
|
|
541
|
+
* Reads `window.location.pathname` when called with no argument. Returns `{}`
|
|
542
|
+
* if the first two path segments are not both 2-letter locale codes.
|
|
543
|
+
*/
|
|
544
|
+
declare function getLocaleFromUrl(pathname?: string): {
|
|
545
|
+
countryCode?: string;
|
|
546
|
+
language?: string;
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* GTM constants — event names, storage keys, and enum-like value maps.
|
|
551
|
+
* Types are declared in `./gtmTypes` and imported here only for `satisfies`.
|
|
552
|
+
*/
|
|
553
|
+
declare const SEARCH_GTM_EVENTS: {
|
|
554
|
+
readonly CHAT_ENTRY_POINT: "Begin_chat";
|
|
555
|
+
readonly SEARCH_TYPE: "Search_Type";
|
|
556
|
+
readonly PRODUCT_SEARCH: "ProductSearch";
|
|
557
|
+
readonly ERROR_POPUP: "Error_popup";
|
|
558
|
+
};
|
|
559
|
+
declare const SEARCH_GTM_SEARCH_TYPES: {
|
|
560
|
+
readonly SEMANTIC: "semantic search";
|
|
561
|
+
readonly AI_AGENT: "AI agent";
|
|
562
|
+
};
|
|
563
|
+
declare const SEARCH_GTM_USER_STATUS: {
|
|
564
|
+
readonly GUEST: "guest";
|
|
565
|
+
readonly LOGGED_IN: "logged_in";
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* GTM (Google Tag Manager) dataLayer tracking for the AI Chat Bot.
|
|
570
|
+
*
|
|
571
|
+
* Implements the events specified in COMX-3277:
|
|
572
|
+
* 1. Chatentry_Point - user initiates the AI chat from an entry point
|
|
573
|
+
* 2. Search_Type - user submits a query in the AI chat
|
|
574
|
+
* 3. ProductSearch - AI chat returns product results (fires even on 0)
|
|
575
|
+
* 4. Error_popup - API errors / unhandled exceptions during a session
|
|
576
|
+
*
|
|
577
|
+
* All UI repos (react-search-components, and any host consuming the SDK)
|
|
578
|
+
* should call these helpers instead of touching `window.dataLayer` directly,
|
|
579
|
+
* so that payload shape and error handling stay consistent.
|
|
580
|
+
*
|
|
581
|
+
* Types live in `./gtmTypes`, constants in `./gtmConstants`, and generic
|
|
582
|
+
* helpers in `./commonUtils` / `./storage`.
|
|
583
|
+
*/
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Pushes a raw event object onto `window.dataLayer`.
|
|
587
|
+
*
|
|
588
|
+
* Silently no-ops when `window` is unavailable (SSR) or the dataLayer is
|
|
589
|
+
* missing - GTM tag firing is a best-effort side effect, never a blocker for
|
|
590
|
+
* the search flow.
|
|
591
|
+
*/
|
|
592
|
+
declare function pushGtmEvent(event: Record<string, unknown>): void;
|
|
593
|
+
/** Fires `Begin_chat` when the user initiates the AI chat. */
|
|
594
|
+
declare function trackChatEntryPoint(ctx: SearchGtmContext): void;
|
|
595
|
+
/** Fires `Search_Type` when the user submits a query in the AI chat. */
|
|
596
|
+
declare function trackSearchType(input: SearchTypeEventInput): void;
|
|
597
|
+
/**
|
|
598
|
+
* Fires `ProductSearch` when the AI chat returns results.
|
|
599
|
+
* Must be called even when 0 products are returned.
|
|
600
|
+
*/
|
|
601
|
+
declare function trackProductSearch(input: ProductSearchEventInput): void;
|
|
602
|
+
/** Fires `Error_popup` for API errors and unhandled exceptions during chat. */
|
|
603
|
+
declare function trackErrorPopup(input: ErrorPopupEventInput): void;
|
|
604
|
+
|
|
476
605
|
/**
|
|
477
606
|
* Constants for the search SDK. Ported from
|
|
478
607
|
* `header-mfe/src/utils/search/search.constants.js` — only the values the
|
|
@@ -515,4 +644,4 @@ declare const DEFAULT_AI_CHAT_CONVERSATIONS_URL = "https://admin.tst.nuskin.ai/a
|
|
|
515
644
|
/** Default POST endpoint for sending AI chat messages. */
|
|
516
645
|
declare const DEFAULT_AI_CHAT_MESSAGES_URL = "https://admin.tst.nuskin.ai/api/analytics/v1/embed/messages";
|
|
517
646
|
|
|
518
|
-
export { CATALOG_SUGGESTIONS_PATH, type CatalogSuggestionItem, type ChatMessageResult, type ChatProduct, type ChatService, type ChatServiceOptions, 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, type DidYouMeanItem, type GetMarketConfig, type LocaleParts, type LocationLike, MAX_VISIBLE_SUGGESTIONS, type MarketConfig, type ProductType, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, type SearchChromeCopy, type SearchHistoryEntry, type SearchHistoryState, type SearchHistoryEntry as SearchHistoryStoreEntry, type SearchService, type SearchServiceOptions, type SuggestionOption, type SuggestionsResponse, TRIGGER_PLACEHOLDER, type UseSearchHistoryResult, type UseSearchSuggestionsOptions, type UseSearchSuggestionsResult, type UseVoiceSearchOptions, type UseVoiceSearchResult, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, resolveApiGatewayPath, resolveSuggestionImageSrc, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
|
|
647
|
+
export { CATALOG_SUGGESTIONS_PATH, type CatalogSuggestionItem, type ChatMessageResult, type ChatProduct, type ChatService, type ChatServiceOptions, 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, type DidYouMeanItem, type ErrorPopupEventInput, type GetMarketConfig, type LocaleParts, type LocationLike, MAX_VISIBLE_SUGGESTIONS, type MarketConfig, type ProductSearchEventInput, type ProductType, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_GTM_EVENTS, SEARCH_GTM_SEARCH_TYPES, SEARCH_GTM_USER_STATUS, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, type SearchChromeCopy, type SearchGtmContext, type SearchGtmSearchType, type SearchGtmUserStatus, type SearchHistoryEntry, type SearchHistoryState, type SearchHistoryEntry as SearchHistoryStoreEntry, type SearchService, type SearchServiceOptions, type SearchTypeEventInput, type SuggestionOption, type SuggestionsResponse, TRIGGER_PLACEHOLDER, type UseSearchHistoryResult, type UseSearchSuggestionsOptions, type UseSearchSuggestionsResult, type UseVoiceSearchOptions, type UseVoiceSearchResult, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getLocaleFromUrl, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, pushGtmEvent, resolveApiGatewayPath, resolveSuggestionImageSrc, trackChatEntryPoint, trackErrorPopup, trackProductSearch, trackSearchType, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,8 @@ interface UseSearchSuggestionsResult {
|
|
|
148
148
|
hasMoreResults: boolean;
|
|
149
149
|
/** `true` when the trimmed query is non-empty. */
|
|
150
150
|
hasQuery: boolean;
|
|
151
|
+
/** `true` when the latest suggestions request failed. */
|
|
152
|
+
suggestionFetchFailed: boolean;
|
|
151
153
|
/** Normalised "Did You Mean?" items from the API. */
|
|
152
154
|
didYouMean: DidYouMeanItem[];
|
|
153
155
|
/** `true` while a debounced fetch is in flight. */
|
|
@@ -205,25 +207,25 @@ interface SearchServiceOptions {
|
|
|
205
207
|
*/
|
|
206
208
|
onSuggestionAction?: (option: SuggestionOption) => Promise<boolean> | boolean | undefined;
|
|
207
209
|
}
|
|
208
|
-
/** Public API returned by `createSearchService`.
|
|
210
|
+
/** Public API returned by `createSearchService`. */
|
|
209
211
|
interface SearchService {
|
|
210
212
|
/** Returns fallback placeholder + aria-label copy. */
|
|
211
213
|
getSearchChromeCopy: () => Promise<SearchChromeCopy>;
|
|
212
214
|
/** Fetches typeahead suggestions from the Equinox catalog. */
|
|
213
215
|
fetchSuggestions: (searchTerm: string) => Promise<SuggestionsResponse>;
|
|
214
216
|
/**
|
|
215
|
-
* Records the query in recent searches, then
|
|
216
|
-
*
|
|
217
|
+
* Records the query in recent searches, then returns the option URL or the
|
|
218
|
+
* fallback search-results path for the consuming router to navigate.
|
|
217
219
|
*/
|
|
218
220
|
submitProductSearch: (query: string, option?: SuggestionOption) => string | undefined;
|
|
219
221
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
+
* Returns the suggestion's URL if one is resolvable; otherwise submits the
|
|
223
|
+
* suggestion's textual value as a product search.
|
|
222
224
|
*/
|
|
223
225
|
activateSuggestionAction: (option: SuggestionOption) => string | undefined;
|
|
224
226
|
/** Returns the navigable URL for a suggestion option (or `""`). */
|
|
225
227
|
getSuggestionHref: (option: SuggestionOption) => string;
|
|
226
|
-
/**
|
|
228
|
+
/** Returns the search-results page path for `query`. */
|
|
227
229
|
viewMoreResults: (input: {
|
|
228
230
|
query: string;
|
|
229
231
|
}) => string | undefined;
|
|
@@ -473,6 +475,133 @@ declare function getSeeMoreResultsPayload(query: string, totalResultsCount: numb
|
|
|
473
475
|
visibleResultsCount: number;
|
|
474
476
|
};
|
|
475
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Types + Window augmentation for the GTM (Google Tag Manager) tracking layer.
|
|
480
|
+
*/
|
|
481
|
+
declare global {
|
|
482
|
+
interface Window {
|
|
483
|
+
dataLayer?: unknown[];
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
type SearchGtmUserStatus = 'guest' | 'logged_in';
|
|
487
|
+
type SearchGtmSearchType = 'semantic search' | 'AI agent';
|
|
488
|
+
/**
|
|
489
|
+
* Context shared by every AI-chat GTM event. Values that are unknown at
|
|
490
|
+
* emit time should be passed as an empty string so the schema stays stable
|
|
491
|
+
* (matches the placeholder shape the data team provided in COMX-3277).
|
|
492
|
+
*/
|
|
493
|
+
interface SearchGtmContext {
|
|
494
|
+
/** Conversation id from ChatService.createConversation, coerced to string. */
|
|
495
|
+
chatId?: string | number;
|
|
496
|
+
/** Page type where the chat was initiated (e.g. `plp`, `pdp`, `home`). */
|
|
497
|
+
pageType?: string;
|
|
498
|
+
/** ISO 3166-1 alpha-2 country code (e.g. `US`, `DE`). */
|
|
499
|
+
countryCode?: string;
|
|
500
|
+
/** Language code (e.g. `en`, `de`). */
|
|
501
|
+
language?: string;
|
|
502
|
+
/**
|
|
503
|
+
* Whether the visitor is a guest or a logged-in user.
|
|
504
|
+
* Falls back to the `IsAuthenticated` localStorage flag written by the
|
|
505
|
+
* storefront `Session` model when not supplied by the host.
|
|
506
|
+
*/
|
|
507
|
+
userStatus?: SearchGtmUserStatus;
|
|
508
|
+
/** Authenticated user id, or empty for guests. */
|
|
509
|
+
userId?: string;
|
|
510
|
+
/**
|
|
511
|
+
* Customer account type (e.g. `Retail Customer`, `Brand Affiliate`).
|
|
512
|
+
* Falls back to the `accountType` localStorage value written by the
|
|
513
|
+
* storefront `Customer` / `MyAccount` flows when not supplied.
|
|
514
|
+
*/
|
|
515
|
+
accountType?: string;
|
|
516
|
+
}
|
|
517
|
+
/** Payload for the Search_Type event (query the user submitted). */
|
|
518
|
+
interface SearchTypeEventInput extends SearchGtmContext {
|
|
519
|
+
/** Type of AI search: `semantic search` or `AI agent`. */
|
|
520
|
+
searchType?: SearchGtmSearchType;
|
|
521
|
+
/** User's raw search query / response text. */
|
|
522
|
+
searchResponse?: string;
|
|
523
|
+
}
|
|
524
|
+
/** Payload for the ProductSearch event (results returned to the user). */
|
|
525
|
+
interface ProductSearchEventInput extends SearchGtmContext {
|
|
526
|
+
searchType?: SearchGtmSearchType;
|
|
527
|
+
/** Number of product results shown to the user. */
|
|
528
|
+
productResults?: number;
|
|
529
|
+
/** Raw products payload to send into Product_results as JSON string. */
|
|
530
|
+
productResultsData?: unknown;
|
|
531
|
+
}
|
|
532
|
+
/** Payload for the Error_popup event. */
|
|
533
|
+
interface ErrorPopupEventInput extends SearchGtmContext {
|
|
534
|
+
searchType?: SearchGtmSearchType;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Extracts `{ countryCode, language }` from a storefront-shaped path
|
|
539
|
+
* (`/{country}/{language}/...`, e.g. `/us/en/product/x`).
|
|
540
|
+
*
|
|
541
|
+
* Reads `window.location.pathname` when called with no argument. Returns `{}`
|
|
542
|
+
* if the first two path segments are not both 2-letter locale codes.
|
|
543
|
+
*/
|
|
544
|
+
declare function getLocaleFromUrl(pathname?: string): {
|
|
545
|
+
countryCode?: string;
|
|
546
|
+
language?: string;
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* GTM constants — event names, storage keys, and enum-like value maps.
|
|
551
|
+
* Types are declared in `./gtmTypes` and imported here only for `satisfies`.
|
|
552
|
+
*/
|
|
553
|
+
declare const SEARCH_GTM_EVENTS: {
|
|
554
|
+
readonly CHAT_ENTRY_POINT: "Begin_chat";
|
|
555
|
+
readonly SEARCH_TYPE: "Search_Type";
|
|
556
|
+
readonly PRODUCT_SEARCH: "ProductSearch";
|
|
557
|
+
readonly ERROR_POPUP: "Error_popup";
|
|
558
|
+
};
|
|
559
|
+
declare const SEARCH_GTM_SEARCH_TYPES: {
|
|
560
|
+
readonly SEMANTIC: "semantic search";
|
|
561
|
+
readonly AI_AGENT: "AI agent";
|
|
562
|
+
};
|
|
563
|
+
declare const SEARCH_GTM_USER_STATUS: {
|
|
564
|
+
readonly GUEST: "guest";
|
|
565
|
+
readonly LOGGED_IN: "logged_in";
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* GTM (Google Tag Manager) dataLayer tracking for the AI Chat Bot.
|
|
570
|
+
*
|
|
571
|
+
* Implements the events specified in COMX-3277:
|
|
572
|
+
* 1. Chatentry_Point - user initiates the AI chat from an entry point
|
|
573
|
+
* 2. Search_Type - user submits a query in the AI chat
|
|
574
|
+
* 3. ProductSearch - AI chat returns product results (fires even on 0)
|
|
575
|
+
* 4. Error_popup - API errors / unhandled exceptions during a session
|
|
576
|
+
*
|
|
577
|
+
* All UI repos (react-search-components, and any host consuming the SDK)
|
|
578
|
+
* should call these helpers instead of touching `window.dataLayer` directly,
|
|
579
|
+
* so that payload shape and error handling stay consistent.
|
|
580
|
+
*
|
|
581
|
+
* Types live in `./gtmTypes`, constants in `./gtmConstants`, and generic
|
|
582
|
+
* helpers in `./commonUtils` / `./storage`.
|
|
583
|
+
*/
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Pushes a raw event object onto `window.dataLayer`.
|
|
587
|
+
*
|
|
588
|
+
* Silently no-ops when `window` is unavailable (SSR) or the dataLayer is
|
|
589
|
+
* missing - GTM tag firing is a best-effort side effect, never a blocker for
|
|
590
|
+
* the search flow.
|
|
591
|
+
*/
|
|
592
|
+
declare function pushGtmEvent(event: Record<string, unknown>): void;
|
|
593
|
+
/** Fires `Begin_chat` when the user initiates the AI chat. */
|
|
594
|
+
declare function trackChatEntryPoint(ctx: SearchGtmContext): void;
|
|
595
|
+
/** Fires `Search_Type` when the user submits a query in the AI chat. */
|
|
596
|
+
declare function trackSearchType(input: SearchTypeEventInput): void;
|
|
597
|
+
/**
|
|
598
|
+
* Fires `ProductSearch` when the AI chat returns results.
|
|
599
|
+
* Must be called even when 0 products are returned.
|
|
600
|
+
*/
|
|
601
|
+
declare function trackProductSearch(input: ProductSearchEventInput): void;
|
|
602
|
+
/** Fires `Error_popup` for API errors and unhandled exceptions during chat. */
|
|
603
|
+
declare function trackErrorPopup(input: ErrorPopupEventInput): void;
|
|
604
|
+
|
|
476
605
|
/**
|
|
477
606
|
* Constants for the search SDK. Ported from
|
|
478
607
|
* `header-mfe/src/utils/search/search.constants.js` — only the values the
|
|
@@ -515,4 +644,4 @@ declare const DEFAULT_AI_CHAT_CONVERSATIONS_URL = "https://admin.tst.nuskin.ai/a
|
|
|
515
644
|
/** Default POST endpoint for sending AI chat messages. */
|
|
516
645
|
declare const DEFAULT_AI_CHAT_MESSAGES_URL = "https://admin.tst.nuskin.ai/api/analytics/v1/embed/messages";
|
|
517
646
|
|
|
518
|
-
export { CATALOG_SUGGESTIONS_PATH, type CatalogSuggestionItem, type ChatMessageResult, type ChatProduct, type ChatService, type ChatServiceOptions, 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, type DidYouMeanItem, type GetMarketConfig, type LocaleParts, type LocationLike, MAX_VISIBLE_SUGGESTIONS, type MarketConfig, type ProductType, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, type SearchChromeCopy, type SearchHistoryEntry, type SearchHistoryState, type SearchHistoryEntry as SearchHistoryStoreEntry, type SearchService, type SearchServiceOptions, type SuggestionOption, type SuggestionsResponse, TRIGGER_PLACEHOLDER, type UseSearchHistoryResult, type UseSearchSuggestionsOptions, type UseSearchSuggestionsResult, type UseVoiceSearchOptions, type UseVoiceSearchResult, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, resolveApiGatewayPath, resolveSuggestionImageSrc, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
|
|
647
|
+
export { CATALOG_SUGGESTIONS_PATH, type CatalogSuggestionItem, type ChatMessageResult, type ChatProduct, type ChatService, type ChatServiceOptions, 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, type DidYouMeanItem, type ErrorPopupEventInput, type GetMarketConfig, type LocaleParts, type LocationLike, MAX_VISIBLE_SUGGESTIONS, type MarketConfig, type ProductSearchEventInput, type ProductType, RECENT_SEARCHES_DEFAULT_LIMIT, RECENT_SEARCHES_PREFIX, SEARCH_GTM_EVENTS, SEARCH_GTM_SEARCH_TYPES, SEARCH_GTM_USER_STATUS, SEARCH_PLACEHOLDER, STOREFRONT_SHOPPING_CONTEXT, type SearchChromeCopy, type SearchGtmContext, type SearchGtmSearchType, type SearchGtmUserStatus, type SearchHistoryEntry, type SearchHistoryState, type SearchHistoryEntry as SearchHistoryStoreEntry, type SearchService, type SearchServiceOptions, type SearchTypeEventInput, type SuggestionOption, type SuggestionsResponse, TRIGGER_PLACEHOLDER, type UseSearchHistoryResult, type UseSearchSuggestionsOptions, type UseSearchSuggestionsResult, type UseVoiceSearchOptions, type UseVoiceSearchResult, createChatService, createSearchService, getImageFromProperty, getIngredientTerms, getLocaleFromUrl, getSeeMoreResultsPayload, getVisibleSuggestions, isCartActionDisabled, isSellableProductStatus, isSuggestionDisabled, mapCatalogProductToSuggestion, normalizeDidYouMean, pushGtmEvent, resolveApiGatewayPath, resolveSuggestionImageSrc, trackChatEntryPoint, trackErrorPopup, trackProductSearch, trackSearchType, useSearchHistory, useSearchHistoryStore, useSearchSuggestions, useVoiceSearch };
|
package/dist/index.js
CHANGED
|
@@ -1254,6 +1254,7 @@ function useSearchSuggestions({
|
|
|
1254
1254
|
const [didYouMean, setDidYouMean] = React.useState([]);
|
|
1255
1255
|
const [loading, setLoading] = React.useState(false);
|
|
1256
1256
|
const [emptyFetched, setEmptyFetched] = React.useState(false);
|
|
1257
|
+
const [suggestionFetchFailed, setSuggestionFetchFailed] = React.useState(false);
|
|
1257
1258
|
const [hasMoreResults, setHasMoreResults] = React.useState(false);
|
|
1258
1259
|
const [totalResultsCount, setTotalResultsCount] = React.useState(0);
|
|
1259
1260
|
const fetchDebounced = React.useRef(null);
|
|
@@ -1262,6 +1263,7 @@ function useSearchSuggestions({
|
|
|
1262
1263
|
setSuggestions([]);
|
|
1263
1264
|
setDidYouMean([]);
|
|
1264
1265
|
setEmptyFetched(false);
|
|
1266
|
+
setSuggestionFetchFailed(false);
|
|
1265
1267
|
setHasMoreResults(false);
|
|
1266
1268
|
setTotalResultsCount(0);
|
|
1267
1269
|
setLoading(false);
|
|
@@ -1270,6 +1272,7 @@ function useSearchSuggestions({
|
|
|
1270
1272
|
(nextQuery) => {
|
|
1271
1273
|
const hasNextQuery = Boolean(nextQuery.trim());
|
|
1272
1274
|
setEmptyFetched(false);
|
|
1275
|
+
setSuggestionFetchFailed(false);
|
|
1273
1276
|
setLoading(enabled && hasNextQuery);
|
|
1274
1277
|
setQuery(nextQuery);
|
|
1275
1278
|
},
|
|
@@ -1289,6 +1292,7 @@ function useSearchSuggestions({
|
|
|
1289
1292
|
}
|
|
1290
1293
|
setLoading(true);
|
|
1291
1294
|
setEmptyFetched(false);
|
|
1295
|
+
setSuggestionFetchFailed(false);
|
|
1292
1296
|
try {
|
|
1293
1297
|
const fetchedSuggestions = await service.fetchSuggestions(trimmedQuery);
|
|
1294
1298
|
if (requestId !== latestRequestId.current) {
|
|
@@ -1311,6 +1315,7 @@ function useSearchSuggestions({
|
|
|
1311
1315
|
!hasDidYouMean && effectiveTotal > MAX_VISIBLE_SUGGESTIONS
|
|
1312
1316
|
);
|
|
1313
1317
|
setTotalResultsCount(effectiveTotal);
|
|
1318
|
+
setSuggestionFetchFailed(false);
|
|
1314
1319
|
setEmptyFetched(
|
|
1315
1320
|
hasDidYouMean ? false : visibleSuggestions.length === 0 && suggestedTerms.length === 0
|
|
1316
1321
|
);
|
|
@@ -1321,6 +1326,7 @@ function useSearchSuggestions({
|
|
|
1321
1326
|
setSuggestions([]);
|
|
1322
1327
|
setDidYouMean([]);
|
|
1323
1328
|
setEmptyFetched(true);
|
|
1329
|
+
setSuggestionFetchFailed(true);
|
|
1324
1330
|
setHasMoreResults(false);
|
|
1325
1331
|
setTotalResultsCount(0);
|
|
1326
1332
|
} finally {
|
|
@@ -1358,6 +1364,7 @@ function useSearchSuggestions({
|
|
|
1358
1364
|
loading,
|
|
1359
1365
|
query,
|
|
1360
1366
|
setQuery,
|
|
1367
|
+
suggestionFetchFailed,
|
|
1361
1368
|
suggestions,
|
|
1362
1369
|
totalResultsCount,
|
|
1363
1370
|
updateQuery
|
|
@@ -1740,6 +1747,188 @@ function useVoiceSearch({
|
|
|
1740
1747
|
return { listening, supported, start, stop };
|
|
1741
1748
|
}
|
|
1742
1749
|
|
|
1750
|
+
// src/utils/commonUtils.ts
|
|
1751
|
+
var IS_BROWSER = typeof window !== "undefined";
|
|
1752
|
+
function toEventString(value, fallback = " ") {
|
|
1753
|
+
if (value === void 0 || value === null) return fallback;
|
|
1754
|
+
const str = String(value).trim();
|
|
1755
|
+
return str.length > 0 ? str : fallback;
|
|
1756
|
+
}
|
|
1757
|
+
function getLocaleFromUrl(pathname) {
|
|
1758
|
+
const path = pathname ?? (IS_BROWSER ? window.location.pathname : "");
|
|
1759
|
+
const [country, language] = path.split("/").filter(Boolean);
|
|
1760
|
+
if (!/^[a-z]{2}$/i.test(country ?? "") || !/^[a-z]{2}$/i.test(language ?? "")) {
|
|
1761
|
+
return {};
|
|
1762
|
+
}
|
|
1763
|
+
return {
|
|
1764
|
+
countryCode: country.toUpperCase(),
|
|
1765
|
+
language: language.toLowerCase()
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
function safeParse(raw) {
|
|
1769
|
+
try {
|
|
1770
|
+
return JSON.parse(raw);
|
|
1771
|
+
} catch {
|
|
1772
|
+
return raw;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
function getLocalStorage(key) {
|
|
1776
|
+
if (!IS_BROWSER) return void 0;
|
|
1777
|
+
try {
|
|
1778
|
+
const raw = window.localStorage.getItem(key);
|
|
1779
|
+
return raw === null ? void 0 : safeParse(raw);
|
|
1780
|
+
} catch {
|
|
1781
|
+
return void 0;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
function getSessionStorage2(key) {
|
|
1785
|
+
if (!IS_BROWSER) return void 0;
|
|
1786
|
+
try {
|
|
1787
|
+
const raw = window.sessionStorage.getItem(key);
|
|
1788
|
+
return raw === null ? void 0 : safeParse(raw);
|
|
1789
|
+
} catch {
|
|
1790
|
+
return void 0;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
// src/utils/gtmConstants.ts
|
|
1795
|
+
var SEARCH_GTM_EVENTS = {
|
|
1796
|
+
CHAT_ENTRY_POINT: "Begin_chat",
|
|
1797
|
+
SEARCH_TYPE: "Search_Type",
|
|
1798
|
+
PRODUCT_SEARCH: "ProductSearch",
|
|
1799
|
+
ERROR_POPUP: "Error_popup"
|
|
1800
|
+
};
|
|
1801
|
+
var SEARCH_GTM_SEARCH_TYPES = {
|
|
1802
|
+
SEMANTIC: "semantic search",
|
|
1803
|
+
AI_AGENT: "AI agent"
|
|
1804
|
+
};
|
|
1805
|
+
var SEARCH_GTM_USER_STATUS = {
|
|
1806
|
+
GUEST: "guest",
|
|
1807
|
+
LOGGED_IN: "logged_in"
|
|
1808
|
+
};
|
|
1809
|
+
var AI_CHAT_CONVERSATION_ID_KEY = "ai_chat_conversation_id";
|
|
1810
|
+
var IS_AUTHENTICATED_KEY = "IsAuthenticated";
|
|
1811
|
+
var ACCOUNT_TYPE_KEY = "accountType";
|
|
1812
|
+
var NUSKIN_ACCOUNT_DATA_KEY = "nuskin.account.data";
|
|
1813
|
+
var GTM_FALLBACK_NA = "NA";
|
|
1814
|
+
|
|
1815
|
+
// src/utils/gtmTracking.ts
|
|
1816
|
+
function readSessionChatId() {
|
|
1817
|
+
const raw = getSessionStorage2(AI_CHAT_CONVERSATION_ID_KEY);
|
|
1818
|
+
return typeof raw === "string" || typeof raw === "number" ? String(raw) : void 0;
|
|
1819
|
+
}
|
|
1820
|
+
function readUserStatusFromStorage() {
|
|
1821
|
+
const value = getLocalStorage(IS_AUTHENTICATED_KEY);
|
|
1822
|
+
if (value === void 0) return void 0;
|
|
1823
|
+
if (value === SEARCH_GTM_USER_STATUS.GUEST || value === SEARCH_GTM_USER_STATUS.LOGGED_IN) {
|
|
1824
|
+
return value;
|
|
1825
|
+
}
|
|
1826
|
+
const isAuthenticated = value === true || typeof value === "string" && ["true", "1", "yes", "y"].includes(value.toLowerCase().trim());
|
|
1827
|
+
return isAuthenticated ? SEARCH_GTM_USER_STATUS.LOGGED_IN : SEARCH_GTM_USER_STATUS.GUEST;
|
|
1828
|
+
}
|
|
1829
|
+
function readAccountTypeFromStorage() {
|
|
1830
|
+
const value = getLocalStorage(ACCOUNT_TYPE_KEY);
|
|
1831
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1832
|
+
}
|
|
1833
|
+
function readUserIdFromStorage() {
|
|
1834
|
+
const raw = getLocalStorage(NUSKIN_ACCOUNT_DATA_KEY);
|
|
1835
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1836
|
+
const user = raw.user;
|
|
1837
|
+
if (!user || typeof user !== "object") return void 0;
|
|
1838
|
+
const id = user.id;
|
|
1839
|
+
return typeof id === "string" && id.trim().length > 0 ? id : void 0;
|
|
1840
|
+
}
|
|
1841
|
+
function resolveUserId(explicit) {
|
|
1842
|
+
return toEventString(explicit ?? readUserIdFromStorage(), GTM_FALLBACK_NA);
|
|
1843
|
+
}
|
|
1844
|
+
function baseEventPayload(ctx) {
|
|
1845
|
+
const urlLocale = getLocaleFromUrl();
|
|
1846
|
+
const chatId = ctx.chatId ?? readSessionChatId();
|
|
1847
|
+
const userStatus = ctx.userStatus ?? readUserStatusFromStorage();
|
|
1848
|
+
const accountType = ctx.accountType ?? readAccountTypeFromStorage();
|
|
1849
|
+
const resolvedUserStatus = userStatus ?? SEARCH_GTM_USER_STATUS.GUEST;
|
|
1850
|
+
const documentTitle = IS_BROWSER && typeof document?.title === "string" ? document.title : void 0;
|
|
1851
|
+
return {
|
|
1852
|
+
Chat_ID: toEventString(chatId, GTM_FALLBACK_NA),
|
|
1853
|
+
page_type: toEventString(
|
|
1854
|
+
ctx.pageType ?? documentTitle,
|
|
1855
|
+
GTM_FALLBACK_NA
|
|
1856
|
+
),
|
|
1857
|
+
country_code: toEventString(
|
|
1858
|
+
ctx.countryCode ?? urlLocale.countryCode,
|
|
1859
|
+
GTM_FALLBACK_NA
|
|
1860
|
+
),
|
|
1861
|
+
language: toEventString(
|
|
1862
|
+
ctx.language ?? urlLocale.language,
|
|
1863
|
+
GTM_FALLBACK_NA
|
|
1864
|
+
),
|
|
1865
|
+
user_status: toEventString(
|
|
1866
|
+
resolvedUserStatus,
|
|
1867
|
+
SEARCH_GTM_USER_STATUS.GUEST
|
|
1868
|
+
),
|
|
1869
|
+
account_type: toEventString(accountType, GTM_FALLBACK_NA)
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
function serializeProductResults(productResultsData, productResults) {
|
|
1873
|
+
if (productResultsData !== void 0) {
|
|
1874
|
+
try {
|
|
1875
|
+
return JSON.stringify(productResultsData);
|
|
1876
|
+
} catch {
|
|
1877
|
+
return GTM_FALLBACK_NA;
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
if (productResults === void 0 || productResults === null) {
|
|
1881
|
+
return GTM_FALLBACK_NA;
|
|
1882
|
+
}
|
|
1883
|
+
return String(productResults);
|
|
1884
|
+
}
|
|
1885
|
+
function pushGtmEvent(event) {
|
|
1886
|
+
if (!IS_BROWSER) return;
|
|
1887
|
+
try {
|
|
1888
|
+
const layer = window.dataLayer ?? (window.dataLayer = []);
|
|
1889
|
+
layer.push(event);
|
|
1890
|
+
} catch (err) {
|
|
1891
|
+
if (typeof console !== "undefined") {
|
|
1892
|
+
console.warn("[react-search-sdk] pushGtmEvent failed:", err);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
function trackChatEntryPoint(ctx) {
|
|
1897
|
+
pushGtmEvent({
|
|
1898
|
+
event: SEARCH_GTM_EVENTS.CHAT_ENTRY_POINT,
|
|
1899
|
+
...baseEventPayload(ctx)
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
function trackSearchType(input) {
|
|
1903
|
+
pushGtmEvent({
|
|
1904
|
+
event: SEARCH_GTM_EVENTS.SEARCH_TYPE,
|
|
1905
|
+
...baseEventPayload(input),
|
|
1906
|
+
id: resolveUserId(input.userId),
|
|
1907
|
+
type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC,
|
|
1908
|
+
search_response: toEventString(input.searchResponse, GTM_FALLBACK_NA)
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
function trackProductSearch(input) {
|
|
1912
|
+
pushGtmEvent({
|
|
1913
|
+
event: SEARCH_GTM_EVENTS.PRODUCT_SEARCH,
|
|
1914
|
+
...baseEventPayload(input),
|
|
1915
|
+
id: resolveUserId(input.userId),
|
|
1916
|
+
search_type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC,
|
|
1917
|
+
Product_results: serializeProductResults(
|
|
1918
|
+
input.productResultsData,
|
|
1919
|
+
input.productResults
|
|
1920
|
+
)
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
function trackErrorPopup(input) {
|
|
1924
|
+
pushGtmEvent({
|
|
1925
|
+
event: SEARCH_GTM_EVENTS.ERROR_POPUP,
|
|
1926
|
+
...baseEventPayload(input),
|
|
1927
|
+
id: resolveUserId(input.userId),
|
|
1928
|
+
search_type: input.searchType ?? SEARCH_GTM_SEARCH_TYPES.SEMANTIC
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1743
1932
|
exports.CATALOG_SUGGESTIONS_PATH = CATALOG_SUGGESTIONS_PATH;
|
|
1744
1933
|
exports.DEBOUNCE_MS = DEBOUNCE_MS;
|
|
1745
1934
|
exports.DEFAULT_AI_CHAT_BASE_URL = DEFAULT_AI_CHAT_BASE_URL;
|
|
@@ -1751,6 +1940,9 @@ exports.DEFAULT_SUGGESTION_SIZE = DEFAULT_SUGGESTION_SIZE;
|
|
|
1751
1940
|
exports.MAX_VISIBLE_SUGGESTIONS = MAX_VISIBLE_SUGGESTIONS;
|
|
1752
1941
|
exports.RECENT_SEARCHES_DEFAULT_LIMIT = RECENT_SEARCHES_DEFAULT_LIMIT;
|
|
1753
1942
|
exports.RECENT_SEARCHES_PREFIX = RECENT_SEARCHES_PREFIX;
|
|
1943
|
+
exports.SEARCH_GTM_EVENTS = SEARCH_GTM_EVENTS;
|
|
1944
|
+
exports.SEARCH_GTM_SEARCH_TYPES = SEARCH_GTM_SEARCH_TYPES;
|
|
1945
|
+
exports.SEARCH_GTM_USER_STATUS = SEARCH_GTM_USER_STATUS;
|
|
1754
1946
|
exports.SEARCH_PLACEHOLDER = SEARCH_PLACEHOLDER;
|
|
1755
1947
|
exports.STOREFRONT_SHOPPING_CONTEXT = STOREFRONT_SHOPPING_CONTEXT;
|
|
1756
1948
|
exports.TRIGGER_PLACEHOLDER = TRIGGER_PLACEHOLDER;
|
|
@@ -1758,6 +1950,7 @@ exports.createChatService = createChatService;
|
|
|
1758
1950
|
exports.createSearchService = createSearchService;
|
|
1759
1951
|
exports.getImageFromProperty = getImageFromProperty;
|
|
1760
1952
|
exports.getIngredientTerms = getIngredientTerms;
|
|
1953
|
+
exports.getLocaleFromUrl = getLocaleFromUrl;
|
|
1761
1954
|
exports.getSeeMoreResultsPayload = getSeeMoreResultsPayload;
|
|
1762
1955
|
exports.getVisibleSuggestions = getVisibleSuggestions;
|
|
1763
1956
|
exports.isCartActionDisabled = isCartActionDisabled;
|
|
@@ -1765,8 +1958,13 @@ exports.isSellableProductStatus = isSellableProductStatus;
|
|
|
1765
1958
|
exports.isSuggestionDisabled = isSuggestionDisabled;
|
|
1766
1959
|
exports.mapCatalogProductToSuggestion = mapCatalogProductToSuggestion;
|
|
1767
1960
|
exports.normalizeDidYouMean = normalizeDidYouMean;
|
|
1961
|
+
exports.pushGtmEvent = pushGtmEvent;
|
|
1768
1962
|
exports.resolveApiGatewayPath = resolveApiGatewayPath;
|
|
1769
1963
|
exports.resolveSuggestionImageSrc = resolveSuggestionImageSrc;
|
|
1964
|
+
exports.trackChatEntryPoint = trackChatEntryPoint;
|
|
1965
|
+
exports.trackErrorPopup = trackErrorPopup;
|
|
1966
|
+
exports.trackProductSearch = trackProductSearch;
|
|
1967
|
+
exports.trackSearchType = trackSearchType;
|
|
1770
1968
|
exports.useSearchHistory = useSearchHistory;
|
|
1771
1969
|
exports.useSearchHistoryStore = useSearchHistoryStore;
|
|
1772
1970
|
exports.useSearchSuggestions = useSearchSuggestions;
|