@seekora-ai/ui-sdk-core 0.2.12 → 0.2.14

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.ts CHANGED
@@ -311,6 +311,12 @@ interface SearchStateManagerConfig {
311
311
  autoSearch?: boolean;
312
312
  debounceMs?: number;
313
313
  defaultSearchOptions?: Partial<SearchOptions>;
314
+ /** When query is cleared to empty string, retain previous results instead of triggering a search (default: true) */
315
+ keepResultsOnClear?: boolean;
316
+ /** A/B test experiment ID to include in all analytics events */
317
+ abTestId?: string;
318
+ /** A/B test variant to include in all analytics events */
319
+ abVariant?: string;
314
320
  }
315
321
  declare class SearchStateManager {
316
322
  private client;
@@ -320,6 +326,9 @@ declare class SearchStateManager {
320
326
  private autoSearch;
321
327
  private debounceMs;
322
328
  private defaultSearchOptions;
329
+ private keepResultsOnClear;
330
+ private abTestId?;
331
+ private abVariant?;
323
332
  constructor(config: SearchStateManagerConfig);
324
333
  getState(): SearchState;
325
334
  getQuery(): string;
@@ -341,6 +350,11 @@ declare class SearchStateManager {
341
350
  subscribe(listener: (state: SearchState) => void): () => void;
342
351
  private setState;
343
352
  private notifyListeners;
353
+ /** Explicitly clear results (bypasses keepResultsOnClear) */
354
+ clearResults(): void;
355
+ getAbTestId(): string | undefined;
356
+ getAbVariant(): string | undefined;
357
+ setAbTest(abTestId?: string, abVariant?: string): void;
344
358
  clear(): void;
345
359
  }
346
360
 
@@ -572,5 +586,25 @@ declare class Fingerprint {
572
586
  */
573
587
  declare function getFingerprint(config?: Partial<FingerprintConfig>): Promise<FingerprintResult>;
574
588
 
575
- export { Fingerprint, LogLevel, SearchStateManager, URLRouter, announce, announceFilterChange, announceResults, createFocusTrap, createKeyboardShortcuts, createLogger, createRovingTabIndex, createTheme, createURLRouter, darkThemeVariables, extractField, focusFirstError, formatPrice, generateCompleteStylesheet, generateId, generateThemeStylesheet, getFingerprint, getFocusableElements, getHighlightedValue, getLogger, getNestedValue, getSnippetedValue, getTheme, handleKeyboardNavigation, highContrastThemeVariables, highlightQuery, injectStyles, lightThemeVariables, log, mergeThemes, minimalThemeVariables, parseHighlightedParts, parseQueryHighlightParts, prefersHighContrast, prefersReducedMotion, setAriaDescribedBy, setDefaultLogger, setLogLevel, setLogPrefix, setLogTimestamp, setTheme, stripHighlightTags, themeToCSSVariables };
576
- export type { CSSVariablesConfig, FingerprintComponents, FingerprintConfig, FingerprintResult, HighlightOptions, HighlightPart, KeyboardNavigationOptions, KeyboardShortcut, LoggerConfig, Refinement, SearchState, SearchStateManagerConfig, SnippetOptions, URLRouterConfig, URLStateMapping };
589
+ /**
590
+ * Analytics beacon utility
591
+ *
592
+ * Uses navigator.sendBeacon() for reliable event delivery during page navigation,
593
+ * with fetch() as the primary method for normal operation.
594
+ */
595
+ interface BeaconPayload {
596
+ [key: string]: unknown;
597
+ }
598
+ /**
599
+ * Send an analytics event using sendBeacon (for page unload scenarios)
600
+ * or fetch (for normal operation). Returns true if the event was queued.
601
+ */
602
+ declare function sendAnalyticsBeacon(url: string, payload: BeaconPayload): boolean;
603
+ /**
604
+ * Send an analytics event via fetch (normal operation).
605
+ * Returns the fetch promise for awaiting if needed.
606
+ */
607
+ declare function sendAnalyticsEvent(url: string, payload: BeaconPayload): Promise<boolean>;
608
+
609
+ export { Fingerprint, LogLevel, SearchStateManager, URLRouter, announce, announceFilterChange, announceResults, createFocusTrap, createKeyboardShortcuts, createLogger, createRovingTabIndex, createTheme, createURLRouter, darkThemeVariables, extractField, focusFirstError, formatPrice, generateCompleteStylesheet, generateId, generateThemeStylesheet, getFingerprint, getFocusableElements, getHighlightedValue, getLogger, getNestedValue, getSnippetedValue, getTheme, handleKeyboardNavigation, highContrastThemeVariables, highlightQuery, injectStyles, lightThemeVariables, log, mergeThemes, minimalThemeVariables, parseHighlightedParts, parseQueryHighlightParts, prefersHighContrast, prefersReducedMotion, sendAnalyticsBeacon, sendAnalyticsEvent, setAriaDescribedBy, setDefaultLogger, setLogLevel, setLogPrefix, setLogTimestamp, setTheme, stripHighlightTags, themeToCSSVariables };
610
+ export type { BeaconPayload, CSSVariablesConfig, FingerprintComponents, FingerprintConfig, FingerprintResult, HighlightOptions, HighlightPart, KeyboardNavigationOptions, KeyboardShortcut, LoggerConfig, Refinement, SearchState, SearchStateManagerConfig, SnippetOptions, URLRouterConfig, URLStateMapping };
package/dist/index.esm.js CHANGED
@@ -1402,6 +1402,9 @@ class SearchStateManager {
1402
1402
  this.autoSearch = config.autoSearch !== false;
1403
1403
  this.debounceMs = config.debounceMs || 300;
1404
1404
  this.defaultSearchOptions = config.defaultSearchOptions || { widget_mode: true };
1405
+ this.keepResultsOnClear = config.keepResultsOnClear !== false;
1406
+ this.abTestId = config.abTestId;
1407
+ this.abVariant = config.abVariant;
1405
1408
  this.state = {
1406
1409
  query: config.initialQuery || '',
1407
1410
  refinements: [],
@@ -1450,6 +1453,15 @@ class SearchStateManager {
1450
1453
  }
1451
1454
  return;
1452
1455
  }
1456
+ // When query is cleared to empty and keepResultsOnClear is true,
1457
+ // preserve previous results and skip triggering a search
1458
+ if (query === '' && this.keepResultsOnClear) {
1459
+ log.verbose('SearchStateManager: Query cleared, keeping previous results');
1460
+ this.state.query = '';
1461
+ this.state.currentPage = 1;
1462
+ this.notifyListeners();
1463
+ return;
1464
+ }
1453
1465
  this.state.query = query;
1454
1466
  this.state.currentPage = 1; // Reset to first page on new query
1455
1467
  log.verbose('SearchStateManager: Query updated', { query, triggerSearch, autoSearch: this.autoSearch });
@@ -1648,6 +1660,23 @@ class SearchStateManager {
1648
1660
  }
1649
1661
  });
1650
1662
  }
1663
+ /** Explicitly clear results (bypasses keepResultsOnClear) */
1664
+ clearResults() {
1665
+ this.setState({ results: null, loading: false, error: null });
1666
+ log.verbose('SearchStateManager: Results explicitly cleared');
1667
+ }
1668
+ // A/B test getters
1669
+ getAbTestId() {
1670
+ return this.abTestId;
1671
+ }
1672
+ getAbVariant() {
1673
+ return this.abVariant;
1674
+ }
1675
+ setAbTest(abTestId, abVariant) {
1676
+ this.abTestId = abTestId;
1677
+ this.abVariant = abVariant;
1678
+ log.verbose('SearchStateManager: A/B test updated', { abTestId, abVariant });
1679
+ }
1651
1680
  // Clear all state
1652
1681
  clear() {
1653
1682
  this.state = {
@@ -2627,5 +2656,56 @@ async function getFingerprint(config) {
2627
2656
  return fingerprint.get();
2628
2657
  }
2629
2658
 
2630
- export { Fingerprint, LogLevel, SearchStateManager, URLRouter, announce, announceFilterChange, announceResults, createFocusTrap, createKeyboardShortcuts, createLogger, createRovingTabIndex, createTheme, createURLRouter, darkThemeVariables, extractField, focusFirstError, formatPrice, generateCompleteStylesheet, generateId, generateThemeStylesheet, getFingerprint, getFocusableElements, getHighlightedValue, getLogger, getNestedValue$1 as getNestedValue, getSnippetedValue, getTheme, handleKeyboardNavigation, highContrastThemeVariables, highlightQuery, injectStyles, lightThemeVariables, log, mergeThemes, minimalThemeVariables, parseHighlightedParts, parseQueryHighlightParts, prefersHighContrast, prefersReducedMotion, setAriaDescribedBy, setDefaultLogger, setLogLevel, setLogPrefix, setLogTimestamp, setTheme, stripHighlightTags, themeToCSSVariables };
2659
+ /**
2660
+ * Analytics beacon utility
2661
+ *
2662
+ * Uses navigator.sendBeacon() for reliable event delivery during page navigation,
2663
+ * with fetch() as the primary method for normal operation.
2664
+ */
2665
+ /**
2666
+ * Send an analytics event using sendBeacon (for page unload scenarios)
2667
+ * or fetch (for normal operation). Returns true if the event was queued.
2668
+ */
2669
+ function sendAnalyticsBeacon(url, payload) {
2670
+ const body = JSON.stringify(payload);
2671
+ // Try sendBeacon first (works during page unload)
2672
+ if (typeof navigator !== 'undefined' && navigator.sendBeacon) {
2673
+ const blob = new Blob([body], { type: 'application/json' });
2674
+ return navigator.sendBeacon(url, blob);
2675
+ }
2676
+ // Fallback to fetch with keepalive
2677
+ if (typeof fetch !== 'undefined') {
2678
+ fetch(url, {
2679
+ method: 'POST',
2680
+ headers: { 'Content-Type': 'application/json' },
2681
+ body,
2682
+ keepalive: true,
2683
+ }).catch(() => {
2684
+ // Silently fail — beacon is best-effort
2685
+ });
2686
+ return true;
2687
+ }
2688
+ return false;
2689
+ }
2690
+ /**
2691
+ * Send an analytics event via fetch (normal operation).
2692
+ * Returns the fetch promise for awaiting if needed.
2693
+ */
2694
+ async function sendAnalyticsEvent(url, payload) {
2695
+ if (typeof fetch === 'undefined')
2696
+ return false;
2697
+ try {
2698
+ const response = await fetch(url, {
2699
+ method: 'POST',
2700
+ headers: { 'Content-Type': 'application/json' },
2701
+ body: JSON.stringify(payload),
2702
+ });
2703
+ return response.ok;
2704
+ }
2705
+ catch {
2706
+ return false;
2707
+ }
2708
+ }
2709
+
2710
+ export { Fingerprint, LogLevel, SearchStateManager, URLRouter, announce, announceFilterChange, announceResults, createFocusTrap, createKeyboardShortcuts, createLogger, createRovingTabIndex, createTheme, createURLRouter, darkThemeVariables, extractField, focusFirstError, formatPrice, generateCompleteStylesheet, generateId, generateThemeStylesheet, getFingerprint, getFocusableElements, getHighlightedValue, getLogger, getNestedValue$1 as getNestedValue, getSnippetedValue, getTheme, handleKeyboardNavigation, highContrastThemeVariables, highlightQuery, injectStyles, lightThemeVariables, log, mergeThemes, minimalThemeVariables, parseHighlightedParts, parseQueryHighlightParts, prefersHighContrast, prefersReducedMotion, sendAnalyticsBeacon, sendAnalyticsEvent, setAriaDescribedBy, setDefaultLogger, setLogLevel, setLogPrefix, setLogTimestamp, setTheme, stripHighlightTags, themeToCSSVariables };
2631
2711
  //# sourceMappingURL=index.esm.js.map