@blotoutio/providers-evo-search-sdk 1.58.1 → 1.59.1
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/core.cjs.js +8 -10
- package/core.js +8 -10
- package/core.mjs +8 -10
- package/hooks.cjs.js +8 -21
- package/hooks.d.ts +1 -14
- package/hooks.mjs +8 -21
- package/index.cjs.js +123 -211
- package/index.js +123 -211
- package/index.mjs +123 -211
- package/package.json +1 -1
package/core.cjs.js
CHANGED
|
@@ -656,8 +656,8 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
656
656
|
};
|
|
657
657
|
// Only `/user/*` endpoints return per-user PII (recents, profile-bound
|
|
658
658
|
// data) and rely on the worker's HMAC-signed cookie. Sending
|
|
659
|
-
// `credentials: 'include'` on the public read endpoints (
|
|
660
|
-
//
|
|
659
|
+
// `credentials: 'include'` on the public read endpoints (search,
|
|
660
|
+
// trending) is pointless and triggers the strict CORS contract
|
|
661
661
|
// (`Allow-Credentials: true` + non-wildcard origin echo) on every
|
|
662
662
|
// response — so default to `omit` and opt in below.
|
|
663
663
|
const needsCredentials = (path) => path.startsWith('/user/');
|
|
@@ -679,12 +679,6 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
679
679
|
}
|
|
680
680
|
return (await response.json());
|
|
681
681
|
};
|
|
682
|
-
const autocomplete = async (query, limit = 8, signal) => {
|
|
683
|
-
logger.info(`EvoSearch API: Autocomplete request - query length: ${query.length}, limit: ${limit}`);
|
|
684
|
-
const data = await getJSON('/autocomplete', 'Autocomplete', { q: query, limit: String(limit) }, signal);
|
|
685
|
-
logger.info(`EvoSearch API: Autocomplete success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
686
|
-
return data;
|
|
687
|
-
};
|
|
688
682
|
const trending = (signal) => {
|
|
689
683
|
logger.info('EvoSearch API: Fetching trending searches');
|
|
690
684
|
return getJSON('/trending', 'Trending', undefined, signal);
|
|
@@ -735,7 +729,7 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
735
729
|
const search = async (query, limit = 8, signal) => {
|
|
736
730
|
logger.info(`EvoSearch API: Search request - query length: ${query.length}, limit: ${limit}`);
|
|
737
731
|
const data = await getJSON('/search', 'Search', { q: query, limit: String(limit) }, signal);
|
|
738
|
-
logger.info(`EvoSearch API: Search success - ${data.
|
|
732
|
+
logger.info(`EvoSearch API: Search success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
739
733
|
return data;
|
|
740
734
|
};
|
|
741
735
|
// SSE consumer for Ask AI. Decodes `event: <type>\ndata: <json>` frames
|
|
@@ -804,6 +798,11 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
804
798
|
},
|
|
805
799
|
}),
|
|
806
800
|
credentials: 'include',
|
|
801
|
+
// Finalize events often fire at widget teardown (disconnectedCallback
|
|
802
|
+
// settles the on-screen query) — i.e. right as the shopper navigates
|
|
803
|
+
// away after a result click. keepalive lets the POST outlive the page;
|
|
804
|
+
// sendBeacon can't carry the identity headers or credentials.
|
|
805
|
+
keepalive: true,
|
|
807
806
|
})
|
|
808
807
|
.then(async (response) => {
|
|
809
808
|
if (!response.ok) {
|
|
@@ -831,7 +830,6 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
831
830
|
});
|
|
832
831
|
};
|
|
833
832
|
return {
|
|
834
|
-
autocomplete,
|
|
835
833
|
trending,
|
|
836
834
|
config,
|
|
837
835
|
warm,
|
package/core.js
CHANGED
|
@@ -657,8 +657,8 @@ var ProvidersEvoSearchSdk = (function () {
|
|
|
657
657
|
};
|
|
658
658
|
// Only `/user/*` endpoints return per-user PII (recents, profile-bound
|
|
659
659
|
// data) and rely on the worker's HMAC-signed cookie. Sending
|
|
660
|
-
// `credentials: 'include'` on the public read endpoints (
|
|
661
|
-
//
|
|
660
|
+
// `credentials: 'include'` on the public read endpoints (search,
|
|
661
|
+
// trending) is pointless and triggers the strict CORS contract
|
|
662
662
|
// (`Allow-Credentials: true` + non-wildcard origin echo) on every
|
|
663
663
|
// response — so default to `omit` and opt in below.
|
|
664
664
|
const needsCredentials = (path) => path.startsWith('/user/');
|
|
@@ -680,12 +680,6 @@ var ProvidersEvoSearchSdk = (function () {
|
|
|
680
680
|
}
|
|
681
681
|
return (await response.json());
|
|
682
682
|
};
|
|
683
|
-
const autocomplete = async (query, limit = 8, signal) => {
|
|
684
|
-
logger.info(`EvoSearch API: Autocomplete request - query length: ${query.length}, limit: ${limit}`);
|
|
685
|
-
const data = await getJSON('/autocomplete', 'Autocomplete', { q: query, limit: String(limit) }, signal);
|
|
686
|
-
logger.info(`EvoSearch API: Autocomplete success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
687
|
-
return data;
|
|
688
|
-
};
|
|
689
683
|
const trending = (signal) => {
|
|
690
684
|
logger.info('EvoSearch API: Fetching trending searches');
|
|
691
685
|
return getJSON('/trending', 'Trending', undefined, signal);
|
|
@@ -736,7 +730,7 @@ var ProvidersEvoSearchSdk = (function () {
|
|
|
736
730
|
const search = async (query, limit = 8, signal) => {
|
|
737
731
|
logger.info(`EvoSearch API: Search request - query length: ${query.length}, limit: ${limit}`);
|
|
738
732
|
const data = await getJSON('/search', 'Search', { q: query, limit: String(limit) }, signal);
|
|
739
|
-
logger.info(`EvoSearch API: Search success - ${data.
|
|
733
|
+
logger.info(`EvoSearch API: Search success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
740
734
|
return data;
|
|
741
735
|
};
|
|
742
736
|
// SSE consumer for Ask AI. Decodes `event: <type>\ndata: <json>` frames
|
|
@@ -805,6 +799,11 @@ var ProvidersEvoSearchSdk = (function () {
|
|
|
805
799
|
},
|
|
806
800
|
}),
|
|
807
801
|
credentials: 'include',
|
|
802
|
+
// Finalize events often fire at widget teardown (disconnectedCallback
|
|
803
|
+
// settles the on-screen query) — i.e. right as the shopper navigates
|
|
804
|
+
// away after a result click. keepalive lets the POST outlive the page;
|
|
805
|
+
// sendBeacon can't carry the identity headers or credentials.
|
|
806
|
+
keepalive: true,
|
|
808
807
|
})
|
|
809
808
|
.then(async (response) => {
|
|
810
809
|
if (!response.ok) {
|
|
@@ -832,7 +831,6 @@ var ProvidersEvoSearchSdk = (function () {
|
|
|
832
831
|
});
|
|
833
832
|
};
|
|
834
833
|
return {
|
|
835
|
-
autocomplete,
|
|
836
834
|
trending,
|
|
837
835
|
config,
|
|
838
836
|
warm,
|
package/core.mjs
CHANGED
|
@@ -654,8 +654,8 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
654
654
|
};
|
|
655
655
|
// Only `/user/*` endpoints return per-user PII (recents, profile-bound
|
|
656
656
|
// data) and rely on the worker's HMAC-signed cookie. Sending
|
|
657
|
-
// `credentials: 'include'` on the public read endpoints (
|
|
658
|
-
//
|
|
657
|
+
// `credentials: 'include'` on the public read endpoints (search,
|
|
658
|
+
// trending) is pointless and triggers the strict CORS contract
|
|
659
659
|
// (`Allow-Credentials: true` + non-wildcard origin echo) on every
|
|
660
660
|
// response — so default to `omit` and opt in below.
|
|
661
661
|
const needsCredentials = (path) => path.startsWith('/user/');
|
|
@@ -677,12 +677,6 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
677
677
|
}
|
|
678
678
|
return (await response.json());
|
|
679
679
|
};
|
|
680
|
-
const autocomplete = async (query, limit = 8, signal) => {
|
|
681
|
-
logger.info(`EvoSearch API: Autocomplete request - query length: ${query.length}, limit: ${limit}`);
|
|
682
|
-
const data = await getJSON('/autocomplete', 'Autocomplete', { q: query, limit: String(limit) }, signal);
|
|
683
|
-
logger.info(`EvoSearch API: Autocomplete success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
684
|
-
return data;
|
|
685
|
-
};
|
|
686
680
|
const trending = (signal) => {
|
|
687
681
|
logger.info('EvoSearch API: Fetching trending searches');
|
|
688
682
|
return getJSON('/trending', 'Trending', undefined, signal);
|
|
@@ -733,7 +727,7 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
733
727
|
const search = async (query, limit = 8, signal) => {
|
|
734
728
|
logger.info(`EvoSearch API: Search request - query length: ${query.length}, limit: ${limit}`);
|
|
735
729
|
const data = await getJSON('/search', 'Search', { q: query, limit: String(limit) }, signal);
|
|
736
|
-
logger.info(`EvoSearch API: Search success - ${data.
|
|
730
|
+
logger.info(`EvoSearch API: Search success - ${data.llmSuggestions.length} suggestions, ${data.products.length} products`);
|
|
737
731
|
return data;
|
|
738
732
|
};
|
|
739
733
|
// SSE consumer for Ask AI. Decodes `event: <type>\ndata: <json>` frames
|
|
@@ -802,6 +796,11 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
802
796
|
},
|
|
803
797
|
}),
|
|
804
798
|
credentials: 'include',
|
|
799
|
+
// Finalize events often fire at widget teardown (disconnectedCallback
|
|
800
|
+
// settles the on-screen query) — i.e. right as the shopper navigates
|
|
801
|
+
// away after a result click. keepalive lets the POST outlive the page;
|
|
802
|
+
// sendBeacon can't carry the identity headers or credentials.
|
|
803
|
+
keepalive: true,
|
|
805
804
|
})
|
|
806
805
|
.then(async (response) => {
|
|
807
806
|
if (!response.ok) {
|
|
@@ -829,7 +828,6 @@ const createEvoSearchAPI = ({ fetch: fetchImpl = window.fetch, baseURL, userId,
|
|
|
829
828
|
});
|
|
830
829
|
};
|
|
831
830
|
return {
|
|
832
|
-
autocomplete,
|
|
833
831
|
trending,
|
|
834
832
|
config,
|
|
835
833
|
warm,
|
package/hooks.cjs.js
CHANGED
|
@@ -665,9 +665,6 @@ const processAutocompleteResponse = (response) => {
|
|
|
665
665
|
products: response.products.map(mapAPIProductToSDKProduct),
|
|
666
666
|
};
|
|
667
667
|
};
|
|
668
|
-
const processSearchResponse = (response) => {
|
|
669
|
-
return response.results.map(mapAPIProductToSDKProduct);
|
|
670
|
-
};
|
|
671
668
|
|
|
672
669
|
const isDevEnv$1 = () => typeof process != 'undefined' && process.env['NODE_ENV'] != 'production';
|
|
673
670
|
const emptyReturn = (query, setQuery, trackClick) => ({
|
|
@@ -707,9 +704,10 @@ const useEvoSearch = (options = {}) => {
|
|
|
707
704
|
setError(null);
|
|
708
705
|
return;
|
|
709
706
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
707
|
+
// A single /search call serves both results and suggestions; `mode` only
|
|
708
|
+
// controls whether the suggestions state populates.
|
|
709
|
+
const wantsSuggestions = mode === 'autocomplete' || mode === 'both';
|
|
710
|
+
if (!wantsSuggestions) {
|
|
713
711
|
setSuggestions([]);
|
|
714
712
|
}
|
|
715
713
|
setLoading(true);
|
|
@@ -717,28 +715,17 @@ const useEvoSearch = (options = {}) => {
|
|
|
717
715
|
const controller = new AbortController();
|
|
718
716
|
const timer = setTimeout(async () => {
|
|
719
717
|
try {
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
? api.autocomplete(query, undefined, controller.signal)
|
|
724
|
-
: null,
|
|
725
|
-
]);
|
|
726
|
-
if (searchRes) {
|
|
727
|
-
setResults(processSearchResponse(searchRes));
|
|
728
|
-
}
|
|
729
|
-
if (autocompleteRes) {
|
|
718
|
+
const res = await api.search(query, undefined, controller.signal);
|
|
719
|
+
setResults(processAutocompleteResponse(res).products);
|
|
720
|
+
if (wantsSuggestions) {
|
|
730
721
|
setSuggestions((prev) => {
|
|
731
|
-
const next =
|
|
722
|
+
const next = res.llmSuggestions;
|
|
732
723
|
if (prev.length === next.length &&
|
|
733
724
|
prev.every((p, i) => p.phrase === next[i])) {
|
|
734
725
|
return prev;
|
|
735
726
|
}
|
|
736
727
|
return next.map((phrase) => ({ phrase }));
|
|
737
728
|
});
|
|
738
|
-
if (!searchRes) {
|
|
739
|
-
const processed = processAutocompleteResponse(autocompleteRes);
|
|
740
|
-
setResults(processed.products);
|
|
741
|
-
}
|
|
742
729
|
}
|
|
743
730
|
}
|
|
744
731
|
catch (err) {
|
package/hooks.d.ts
CHANGED
|
@@ -56,14 +56,6 @@ declare module '@blotoutio/providers-evo-search-sdk/hooks' {
|
|
|
56
56
|
llmSuggestions: string[]
|
|
57
57
|
products: AutocompleteAPIProduct[]
|
|
58
58
|
collections?: AutocompleteAPICollection[]
|
|
59
|
-
didYouMean?: string
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export type SearchAPIResponse = {
|
|
63
|
-
query: string
|
|
64
|
-
results: AutocompleteAPIProduct[]
|
|
65
|
-
collections?: AutocompleteAPICollection[]
|
|
66
|
-
didYouMean?: string
|
|
67
59
|
}
|
|
68
60
|
|
|
69
61
|
export type RecentsAPIResponse = {
|
|
@@ -130,16 +122,11 @@ declare module '@blotoutio/providers-evo-search-sdk/hooks' {
|
|
|
130
122
|
| { type: 'error'; message: string }
|
|
131
123
|
|
|
132
124
|
export type EvoSearchAPI = {
|
|
133
|
-
autocomplete: (
|
|
134
|
-
query: string,
|
|
135
|
-
limit?: number,
|
|
136
|
-
signal?: AbortSignal
|
|
137
|
-
) => Promise<AutocompleteAPIResponse>
|
|
138
125
|
search: (
|
|
139
126
|
query: string,
|
|
140
127
|
limit?: number,
|
|
141
128
|
signal?: AbortSignal
|
|
142
|
-
) => Promise<
|
|
129
|
+
) => Promise<AutocompleteAPIResponse>
|
|
143
130
|
trending: (signal?: AbortSignal) => Promise<{
|
|
144
131
|
trending: string[]
|
|
145
132
|
recommended_products: AutocompleteAPIProduct[]
|
package/hooks.mjs
CHANGED
|
@@ -663,9 +663,6 @@ const processAutocompleteResponse = (response) => {
|
|
|
663
663
|
products: response.products.map(mapAPIProductToSDKProduct),
|
|
664
664
|
};
|
|
665
665
|
};
|
|
666
|
-
const processSearchResponse = (response) => {
|
|
667
|
-
return response.results.map(mapAPIProductToSDKProduct);
|
|
668
|
-
};
|
|
669
666
|
|
|
670
667
|
const isDevEnv$1 = () => typeof process != 'undefined' && process.env['NODE_ENV'] != 'production';
|
|
671
668
|
const emptyReturn = (query, setQuery, trackClick) => ({
|
|
@@ -705,9 +702,10 @@ const useEvoSearch = (options = {}) => {
|
|
|
705
702
|
setError(null);
|
|
706
703
|
return;
|
|
707
704
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
705
|
+
// A single /search call serves both results and suggestions; `mode` only
|
|
706
|
+
// controls whether the suggestions state populates.
|
|
707
|
+
const wantsSuggestions = mode === 'autocomplete' || mode === 'both';
|
|
708
|
+
if (!wantsSuggestions) {
|
|
711
709
|
setSuggestions([]);
|
|
712
710
|
}
|
|
713
711
|
setLoading(true);
|
|
@@ -715,28 +713,17 @@ const useEvoSearch = (options = {}) => {
|
|
|
715
713
|
const controller = new AbortController();
|
|
716
714
|
const timer = setTimeout(async () => {
|
|
717
715
|
try {
|
|
718
|
-
const
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
? api.autocomplete(query, undefined, controller.signal)
|
|
722
|
-
: null,
|
|
723
|
-
]);
|
|
724
|
-
if (searchRes) {
|
|
725
|
-
setResults(processSearchResponse(searchRes));
|
|
726
|
-
}
|
|
727
|
-
if (autocompleteRes) {
|
|
716
|
+
const res = await api.search(query, undefined, controller.signal);
|
|
717
|
+
setResults(processAutocompleteResponse(res).products);
|
|
718
|
+
if (wantsSuggestions) {
|
|
728
719
|
setSuggestions((prev) => {
|
|
729
|
-
const next =
|
|
720
|
+
const next = res.llmSuggestions;
|
|
730
721
|
if (prev.length === next.length &&
|
|
731
722
|
prev.every((p, i) => p.phrase === next[i])) {
|
|
732
723
|
return prev;
|
|
733
724
|
}
|
|
734
725
|
return next.map((phrase) => ({ phrase }));
|
|
735
726
|
});
|
|
736
|
-
if (!searchRes) {
|
|
737
|
-
const processed = processAutocompleteResponse(autocompleteRes);
|
|
738
|
-
setResults(processed.products);
|
|
739
|
-
}
|
|
740
727
|
}
|
|
741
728
|
}
|
|
742
729
|
catch (err) {
|