@seekora-ai/ui-sdk-core 0.2.13 → 0.2.15
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 +36 -2
- package/dist/index.esm.js +81 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1404,6 +1404,9 @@ class SearchStateManager {
|
|
|
1404
1404
|
this.autoSearch = config.autoSearch !== false;
|
|
1405
1405
|
this.debounceMs = config.debounceMs || 300;
|
|
1406
1406
|
this.defaultSearchOptions = config.defaultSearchOptions || { widget_mode: true };
|
|
1407
|
+
this.keepResultsOnClear = config.keepResultsOnClear !== false;
|
|
1408
|
+
this.abTestId = config.abTestId;
|
|
1409
|
+
this.abVariant = config.abVariant;
|
|
1407
1410
|
this.state = {
|
|
1408
1411
|
query: config.initialQuery || '',
|
|
1409
1412
|
refinements: [],
|
|
@@ -1452,6 +1455,15 @@ class SearchStateManager {
|
|
|
1452
1455
|
}
|
|
1453
1456
|
return;
|
|
1454
1457
|
}
|
|
1458
|
+
// When query is cleared to empty and keepResultsOnClear is true,
|
|
1459
|
+
// preserve previous results and skip triggering a search
|
|
1460
|
+
if (query === '' && this.keepResultsOnClear) {
|
|
1461
|
+
log.verbose('SearchStateManager: Query cleared, keeping previous results');
|
|
1462
|
+
this.state.query = '';
|
|
1463
|
+
this.state.currentPage = 1;
|
|
1464
|
+
this.notifyListeners();
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1455
1467
|
this.state.query = query;
|
|
1456
1468
|
this.state.currentPage = 1; // Reset to first page on new query
|
|
1457
1469
|
log.verbose('SearchStateManager: Query updated', { query, triggerSearch, autoSearch: this.autoSearch });
|
|
@@ -1650,6 +1662,23 @@ class SearchStateManager {
|
|
|
1650
1662
|
}
|
|
1651
1663
|
});
|
|
1652
1664
|
}
|
|
1665
|
+
/** Explicitly clear results (bypasses keepResultsOnClear) */
|
|
1666
|
+
clearResults() {
|
|
1667
|
+
this.setState({ results: null, loading: false, error: null });
|
|
1668
|
+
log.verbose('SearchStateManager: Results explicitly cleared');
|
|
1669
|
+
}
|
|
1670
|
+
// A/B test getters
|
|
1671
|
+
getAbTestId() {
|
|
1672
|
+
return this.abTestId;
|
|
1673
|
+
}
|
|
1674
|
+
getAbVariant() {
|
|
1675
|
+
return this.abVariant;
|
|
1676
|
+
}
|
|
1677
|
+
setAbTest(abTestId, abVariant) {
|
|
1678
|
+
this.abTestId = abTestId;
|
|
1679
|
+
this.abVariant = abVariant;
|
|
1680
|
+
log.verbose('SearchStateManager: A/B test updated', { abTestId, abVariant });
|
|
1681
|
+
}
|
|
1653
1682
|
// Clear all state
|
|
1654
1683
|
clear() {
|
|
1655
1684
|
this.state = {
|
|
@@ -2629,6 +2658,57 @@ async function getFingerprint(config) {
|
|
|
2629
2658
|
return fingerprint.get();
|
|
2630
2659
|
}
|
|
2631
2660
|
|
|
2661
|
+
/**
|
|
2662
|
+
* Analytics beacon utility
|
|
2663
|
+
*
|
|
2664
|
+
* Uses navigator.sendBeacon() for reliable event delivery during page navigation,
|
|
2665
|
+
* with fetch() as the primary method for normal operation.
|
|
2666
|
+
*/
|
|
2667
|
+
/**
|
|
2668
|
+
* Send an analytics event using sendBeacon (for page unload scenarios)
|
|
2669
|
+
* or fetch (for normal operation). Returns true if the event was queued.
|
|
2670
|
+
*/
|
|
2671
|
+
function sendAnalyticsBeacon(url, payload) {
|
|
2672
|
+
const body = JSON.stringify(payload);
|
|
2673
|
+
// Try sendBeacon first (works during page unload)
|
|
2674
|
+
if (typeof navigator !== 'undefined' && navigator.sendBeacon) {
|
|
2675
|
+
const blob = new Blob([body], { type: 'application/json' });
|
|
2676
|
+
return navigator.sendBeacon(url, blob);
|
|
2677
|
+
}
|
|
2678
|
+
// Fallback to fetch with keepalive
|
|
2679
|
+
if (typeof fetch !== 'undefined') {
|
|
2680
|
+
fetch(url, {
|
|
2681
|
+
method: 'POST',
|
|
2682
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2683
|
+
body,
|
|
2684
|
+
keepalive: true,
|
|
2685
|
+
}).catch(() => {
|
|
2686
|
+
// Silently fail — beacon is best-effort
|
|
2687
|
+
});
|
|
2688
|
+
return true;
|
|
2689
|
+
}
|
|
2690
|
+
return false;
|
|
2691
|
+
}
|
|
2692
|
+
/**
|
|
2693
|
+
* Send an analytics event via fetch (normal operation).
|
|
2694
|
+
* Returns the fetch promise for awaiting if needed.
|
|
2695
|
+
*/
|
|
2696
|
+
async function sendAnalyticsEvent(url, payload) {
|
|
2697
|
+
if (typeof fetch === 'undefined')
|
|
2698
|
+
return false;
|
|
2699
|
+
try {
|
|
2700
|
+
const response = await fetch(url, {
|
|
2701
|
+
method: 'POST',
|
|
2702
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2703
|
+
body: JSON.stringify(payload),
|
|
2704
|
+
});
|
|
2705
|
+
return response.ok;
|
|
2706
|
+
}
|
|
2707
|
+
catch {
|
|
2708
|
+
return false;
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2632
2712
|
exports.Fingerprint = Fingerprint;
|
|
2633
2713
|
exports.SearchStateManager = SearchStateManager;
|
|
2634
2714
|
exports.URLRouter = URLRouter;
|
|
@@ -2667,6 +2747,8 @@ exports.parseHighlightedParts = parseHighlightedParts;
|
|
|
2667
2747
|
exports.parseQueryHighlightParts = parseQueryHighlightParts;
|
|
2668
2748
|
exports.prefersHighContrast = prefersHighContrast;
|
|
2669
2749
|
exports.prefersReducedMotion = prefersReducedMotion;
|
|
2750
|
+
exports.sendAnalyticsBeacon = sendAnalyticsBeacon;
|
|
2751
|
+
exports.sendAnalyticsEvent = sendAnalyticsEvent;
|
|
2670
2752
|
exports.setAriaDescribedBy = setAriaDescribedBy;
|
|
2671
2753
|
exports.setDefaultLogger = setDefaultLogger;
|
|
2672
2754
|
exports.setLogLevel = setLogLevel;
|