@nosto/search-js 3.21.0 → 3.21.2
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/core/src/addToCart.d.ts +17 -0
- package/dist/core/src/search.d.ts +28 -0
- package/dist/currencies/src/getCurrencyFormatting.d.ts +37 -0
- package/dist/currencies/src/priceDecorator.d.ts +44 -3
- package/dist/preact/hooks/hooks.cjs.js +1 -1
- package/dist/preact/hooks/hooks.es.js +68 -64
- package/dist/preact/hooks/src/useRange.d.ts +0 -7
- package/dist/preact/hooks/src/useRangeSelector.d.ts +2 -2
- package/dist/thumbnails/src/thumbnailDecorator.d.ts +24 -0
- package/package.json +10 -10
|
@@ -8,5 +8,22 @@ export type SearchHitWithSku = SearchHit & {
|
|
|
8
8
|
* @param type - The type of search that the hit belongs to.
|
|
9
9
|
* @param hit - The search hit to add to the cart.
|
|
10
10
|
* @param quantity - The quantity of the hit to add to the cart.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { addToCart } from '@nosto/search-js'
|
|
15
|
+
*
|
|
16
|
+
* // Add a single product to cart
|
|
17
|
+
* await addToCart('serp', {
|
|
18
|
+
* productId: '123',
|
|
19
|
+
* skuId: 'sku-123'
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* // Add multiple quantities
|
|
23
|
+
* await addToCart('serp', {
|
|
24
|
+
* productId: '456',
|
|
25
|
+
* skuId: 'sku-456'
|
|
26
|
+
* }, 3)
|
|
27
|
+
* ```
|
|
11
28
|
*/
|
|
12
29
|
export declare function addToCart(type: SearchTrackOptions, hit: SearchHitWithSku, quantity?: number): Promise<void>;
|
|
@@ -6,5 +6,33 @@ import { DecoratedResult, HitDecorator, SearchOptions } from './types';
|
|
|
6
6
|
* @param query - The search query to be executed.
|
|
7
7
|
* @param options - An object containing optional parameters for the search.
|
|
8
8
|
* @returns A promise that resolves to the search result.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { search } from '@nosto/search-js'
|
|
13
|
+
* import { priceDecorator } from '@nosto/search-js/currencies'
|
|
14
|
+
*
|
|
15
|
+
* // Basic search
|
|
16
|
+
* const results = await search({ query: 'shoes' })
|
|
17
|
+
*
|
|
18
|
+
* // Search with decorators
|
|
19
|
+
* const decoratedResults = await search(
|
|
20
|
+
* { query: 'shoes' },
|
|
21
|
+
* { hitDecorators: [priceDecorator()] }
|
|
22
|
+
* )
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { search } from '@nosto/search-js'
|
|
28
|
+
*
|
|
29
|
+
* // Search with filters
|
|
30
|
+
* const results = await search({
|
|
31
|
+
* query: 'shoes',
|
|
32
|
+
* filters: {
|
|
33
|
+
* color: ['red', 'blue']
|
|
34
|
+
* }
|
|
35
|
+
* })
|
|
36
|
+
* ```
|
|
9
37
|
*/
|
|
10
38
|
export declare function search<HD extends readonly HitDecorator[]>(query: SearchQuery, options?: SearchOptions<HD>): Promise<DecoratedResult<HD>>;
|
|
@@ -5,6 +5,43 @@ export interface CurrencyConfig {
|
|
|
5
5
|
defaultLocale: string;
|
|
6
6
|
currencySettings: CurrencyFormats;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a currency formatting function with customizable settings.
|
|
10
|
+
*
|
|
11
|
+
* @param overrides - Optional configuration to override default currency settings.
|
|
12
|
+
* @returns An object containing the formatCurrency function.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { getCurrencyFormatting } from '@nosto/search-js/currencies'
|
|
17
|
+
*
|
|
18
|
+
* // Use default settings from Nosto
|
|
19
|
+
* const { formatCurrency } = getCurrencyFormatting()
|
|
20
|
+
* console.log(formatCurrency(1234.56)) // Uses default currency
|
|
21
|
+
* console.log(formatCurrency(1234.56, 'USD')) // "$1,234.56"
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { getCurrencyFormatting } from '@nosto/search-js/currencies'
|
|
27
|
+
*
|
|
28
|
+
* // Override with custom settings
|
|
29
|
+
* const { formatCurrency } = getCurrencyFormatting({
|
|
30
|
+
* defaultCurrency: 'EUR',
|
|
31
|
+
* defaultLocale: 'de-DE',
|
|
32
|
+
* currencySettings: {
|
|
33
|
+
* EUR: {
|
|
34
|
+
* currencyBeforeAmount: false,
|
|
35
|
+
* currencyToken: '€',
|
|
36
|
+
* decimalCharacter: ',',
|
|
37
|
+
* groupingSeparator: '.',
|
|
38
|
+
* decimalPlaces: 2
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* })
|
|
42
|
+
* console.log(formatCurrency(1234.56)) // "1.234,56€"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
8
45
|
export declare function getCurrencyFormatting(overrides?: Partial<CurrencyConfig>): {
|
|
9
46
|
formatCurrency: (value: number, currency?: string) => string;
|
|
10
47
|
};
|
|
@@ -8,8 +8,49 @@ export type Result = SearchProduct & FormattedPrices & {
|
|
|
8
8
|
skus?: (SearchProductSku & FormattedPrices)[];
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
* Exposes currency formatting logic as a SearchProduct decorator
|
|
12
|
-
* Sets priceText and listPriceText fields on product and SKU level
|
|
13
|
-
* Requires price, listPrice and priceCurrencyCode fields to be present
|
|
11
|
+
* Exposes currency formatting logic as a SearchProduct decorator.
|
|
12
|
+
* Sets priceText and listPriceText fields on product and SKU level.
|
|
13
|
+
* Requires price, listPrice and priceCurrencyCode fields to be present.
|
|
14
|
+
*
|
|
15
|
+
* @param config - Optional configuration to customize currency formatting.
|
|
16
|
+
* @returns A decorator function that adds formatted price text to search products.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { search } from '@nosto/search-js'
|
|
21
|
+
* import { priceDecorator } from '@nosto/search-js/currencies'
|
|
22
|
+
*
|
|
23
|
+
* // Use with default settings
|
|
24
|
+
* const results = await search(
|
|
25
|
+
* { query: 'shoes' },
|
|
26
|
+
* { hitDecorators: [priceDecorator()] }
|
|
27
|
+
* )
|
|
28
|
+
* console.log(results.products.hits[0].priceText) // "$99.99"
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { search } from '@nosto/search-js'
|
|
34
|
+
* import { priceDecorator } from '@nosto/search-js/currencies'
|
|
35
|
+
*
|
|
36
|
+
* // Use with custom currency settings
|
|
37
|
+
* const customDecorator = priceDecorator({
|
|
38
|
+
* defaultCurrency: 'EUR',
|
|
39
|
+
* currencySettings: {
|
|
40
|
+
* EUR: {
|
|
41
|
+
* currencyBeforeAmount: true,
|
|
42
|
+
* currencyToken: '€',
|
|
43
|
+
* decimalCharacter: ',',
|
|
44
|
+
* groupingSeparator: '.',
|
|
45
|
+
* decimalPlaces: 2
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* })
|
|
49
|
+
* const results = await search(
|
|
50
|
+
* { query: 'shoes' },
|
|
51
|
+
* { hitDecorators: [customDecorator] }
|
|
52
|
+
* )
|
|
53
|
+
* console.log(results.products.hits[0].priceText) // "€99,99"
|
|
54
|
+
* ```
|
|
14
55
|
*/
|
|
15
56
|
export declare function priceDecorator(config?: Partial<CurrencyConfig>): (hit: SearchProduct) => Result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("../../useActions-CY9uts_o.cjs"),P=require("../../logger-Boh_C6Bz.cjs"),h=require("../../useLoadMore-CBshMpps.cjs"),R=require("../../eventBusSubscribe-oONOUGH8.cjs"),l=require("preact/hooks"),C=require("../../useHistory-rc2PvSkv.cjs"),q=require("../../index.es-Dp6Iaxz3.cjs"),z=require("../../eventBusDispatch-BKQcSHAB.cjs"),F=require("../../parseNumber-FsZ8w61u.cjs");function O(e){const s=h.useNostoAppState(t=>t.response);return e&&Array.isArray(e)||e&&P.isPlainObject(e)?e:s}function X(e,s){const t=e.data?.filter(f=>f.selected).length??0,{active:o}={active:t>0,...s},[n,u]=l.useState(o),{toggleProductFilter:c}=A.useActions(),a=l.useCallback(()=>{u(!n)},[n]);return R.useEventBusSubscribe({event:"events/removeAllFilters",callback:()=>{u(!1)}}),{active:n,selectedFiltersCount:t,toggleActive:a,toggleProductFilter:c}}function E(){const{loading:e,facets:s}=h.useNostoAppState(t=>({loading:t.loading,facets:t.response?.products?.facets??[]}));return{loading:e,facets:s}}function j(e,s){const t=s-e;return!isNaN(t)&&t>0?new Array(s-e).fill(void 0).map((o,n)=>n+e):[]}function B(e){const{query:s,products:t}=h.useNostoAppState(o=>({query:o.query,products:o.response.products}));return l.useMemo(()=>{if(!t)return{totalPages:0,resultsFrom:0,resultsTo:0,pages:[]};const o=s.products?.from??0,n=e?.width??1/0,u=Math.max(Math.floor(n-1)/2,1),c=t.size>0?Math.floor(o/t.size)+1:1,a=t.size>0?Math.ceil(t.total/t.size):0,f=y=>y>=c-u&&y<=c+u,r=o+1,i=Math.min(o+t.total,t.total),d={from:o,page:c,current:!0},p=y=>({from:(y-1)*t.size,page:y,current:y===c}),S=c>1?p(c-1):void 0,v=c<a?p(c+1):void 0,m=c-u-1>1?p(1):void 0,g=c+u+1<a?p(a):void 0,b=j(1,a+1).filter(f).map(p);return!m&&b[0]?.page===2&&b.unshift(p(1)),!g&&b[b.length-1]?.page===a-1&&b.push(p(a)),{totalPages:a,resultsFrom:r,resultsTo:i,current:d,prev:S,next:v,first:m,last:g,pages:b}},[s,t,e?.width])}function V(){const[e,s]=l.useState([]),[t,o]=l.useState([]);return l.useEffect(()=>{q.s(async n=>{const{products:u,segments:c}=await n.getSearchSessionParams();s(c??[]),o(u?.personalizationBoost??[])})},[]),{segments:e,boost:t}}function D(){const{facets:e}=h.useNostoAppState(r=>({facets:r.response.products?.facets??[]})),{replaceFilter:s,toggleProductFilter:t}=A.useActions(),o=l.useCallback(r=>{const i=e?.find(d=>d.type==="stats"&&d.field===r);if(i&&"min"in i&&"max"in i)return i},[e]),n=l.useCallback(r=>e?.find(i=>i.field===r)?.name??r,[e]),u=l.useCallback(r=>"field"in r&&(r.value instanceof Array||r.range instanceof Array),[]),c=l.useCallback(r=>({...r,range:r.range?.map(i=>({gt:i.gt?Number(i.gt):i.gt,gte:i.gte?Number(i.gte):i.gte,lt:i.lt?Number(i.lt):i.lt,lte:i.lte?Number(i.lte):i.lte}))}),[]),a=l.useCallback(r=>(r.value??[]).map(d=>({value:d,field:r.field,name:n(r.field),filter:c(r),remove:()=>{t(r.field,d,!1)}})),[c,n,t]),f=l.useCallback(r=>(r.range??[]).map(d=>{const p=d.gte??d.gt??o(r.field)?.min,S=d.lte??d.lt??o(r.field)?.max;if(p!==void 0&&S!==void 0)return{value:`${p} - ${S}`,field:r.field,name:n(r.field),filter:c(r),remove:()=>{s(r.field,void 0)}}}).filter(Boolean),[c,o,n,s]);return{selectFilters:u,toValueFilter:a,toRangeFilter:f}}function L(){const{filter:e}=h.useNostoAppState(a=>({filter:a.query.products?.filter??[]})),{updateSearch:s}=A.useActions(),{selectFilters:t,toValueFilter:o,toRangeFilter:n}=D(),u=l.useMemo(()=>e?e.filter(t).flatMap(a=>"value"in a?o(a):"range"in a?n(a):[]).filter(Boolean):[],[e,t,n,o]),c=l.useCallback(()=>{s({products:{filter:[]}}),z.dispatchNostoEvent({event:"events/removeAllFilters",params:null})},[s]);return{filters:u,removeAll:c}}function T(e){const{replaceFilter:s}=A.useActions(),{query:t,products:o}=h.useNostoAppState(g=>({query:g.query,products:g.response.products})),n=o?.facets?.find(g=>g.id===e),u=t.products?.filter?.find(g=>g.field===n?.field),[c,a]=_(u),f=n&&"min"in n?Math.floor(n.min??0):0,r=n&&"max"in n?Math.ceil(n.max??0):0,i=l.useMemo(()=>[c??f,a??r],[c,a,f,r]),d=c!==void 0||a!==void 0,[p,S]=l.useState(d),v=l.useCallback(()=>{S(g=>!g)},[]),m=l.useCallback(([g,b])=>{if(!n)return;const y=$(g,b,f,r);s(n.field,y)},[f,r,s,n]);return R.useEventBusSubscribe({event:"events/removeAllFilters",callback:()=>{S(!1)}}),n?{min:f,max:r,range:i,updateRange:m,active:p,toggleActive:v}:H}const H={min:0,max:0,range:[0,0],active:!1,toggleActive:()=>{},updateRange:()=>{}};function _(e){const s=e?.range?.[0];return typeof s=="object"&&("gte"in s||"lte"in s)?[F.parseNumber(s.gte),F.parseNumber(s.lte)]:[void 0,void 0]}function $(e,s,t,o){const n=e!==void 0?Math.floor(e):void 0,u=s!==void 0?Math.ceil(s):void 0,c=n!==void 0,a=u!==void 0;if((t===n||!c)&&(o===u||!a))return;const f={};return c&&n!==t&&(f.gte=n.toString()),a&&u!==o&&(f.lte=u.toString()),Object.keys(f).length>0?f:void 0}function U(e,s){const{min:t,max:o,range:n,updateRange:u}=T(e),{filters:c}=L(),a=l.useMemo(()=>{const d=c.find(m=>m?.filter?.range);let p=null;if(d){const m=d.filter.range?.[0];p=[F.parseNumber(m?.gte),F.parseNumber(m?.lte)]}const S=[];let v=Math.floor(t/s)*s;for(;v<o;){const m=v+s,g=p&&p[0]===v&&p[1]===m;S.push({min:v,max:m,selected:g}),v=m}return S},[c,t,o,s]),f=l.useCallback(d=>{u([d,n[1]])},[n,u]),r=l.useCallback(d=>{u([n[0],d])},[n,u]),i=t!==n[0]||o!==n[1];return{min:t,max:o,range:n,updateRange:u,ranges:a,handleMinChange:f,handleMaxChange:r,isSelected:i}}function I(){const{products:e,keywords:s}=h.useNostoAppState(t=>({products:t.response.products??{hits:[],total:0},keywords:t.response.keywords??{hits:[],total:0}}));return{products:e,keywords:s}}function K(){const e=h.useNostoAppState(t=>t.query.products?.filter);return l.useMemo(()=>e?e.reduce((t,o)=>t+(Array.isArray(o.value)?o.value.length:1),0):0,[e])}const Z=5*60*1e3,N=new Map;function G(e){const[s,t]=l.useState({product:null,loading:!0,error:null});return l.useEffect(()=>{if(!e){t({product:null,loading:!1,error:"Product handle is required"});return}t(n=>({...n,loading:!0,error:null}));const o=Q(e);if(o){t({product:o,loading:!1,error:null});return}J(e).then(n=>{W(e,n),t({product:n,loading:!1,error:null})}).catch(n=>{t({product:null,loading:!1,error:n.message||"Failed to fetch product"})})},[e]),s}async function J(e){const s=await fetch(`/products/${e}.js`);if(!s.ok)throw new Error(`Failed to fetch product: ${s.status} ${s.statusText}`);return s.json()}function Q(e){const s=N.get(e);return s?Date.now()-s.created>Z?(N.delete(e),null):s.product:null}function W(e,s){N.set(e,{product:s,created:Date.now()})}function k(e){return e&&!Number.isNaN(e)?e:0}function Y(e,s){const{from:t,size:o,total:n}=h.useNostoAppState(r=>({from:k(r.query.products?.from??0),size:k(r.response?.products?.size??s),total:k(r.response?.products?.total??0)})),{updateSearch:u}=A.useActions(),c=t+o,a=l.useMemo(()=>[...e].reverse().filter(r=>r<n),[e,n]),f=l.useCallback(r=>{u({products:{size:F.parseNumber(r)}})},[u]);return{from:t,to:c,total:n,size:o,sizeOptions:a,handleSizeChange:f}}function ee(e,s){return e.length!==s.length?!1:e.every(t=>s.find(o=>t.field===o.field&&t.order===o.order))}function te(e){const s=h.useNostoAppState(u=>u.query),{updateSearch:t}=A.useActions(),o=e.find(u=>ee(u.value.sort,s.products?.sort||[]))?.id??e[0]?.id,n=l.useCallback(u=>{const c=e.find(a=>a.id===u);c&&t({products:{sort:c.value.sort}})},[e,t]);return{activeSort:o,setSort:n}}const w=window.SpeechRecognition||window.webkitSpeechRecognition,x=!!(w&&typeof w=="function");function se(){return{listening:!1,startListening:()=>{},stopListening:()=>{}}}function ne({language:e="en-US",interimResults:s=!1,onResult:t,onError:o}={}){const[n,u]=l.useState(!1),c=l.useRef(null),a=l.useCallback(()=>{const r=new w;r.lang=e,r.interimResults=s,r.onstart=()=>u(!0),t&&(r.onresult=i=>{const{transcript:d}=i.results?.[0]?.[0];t(d)}),o&&(r.onerror=i=>o(i.error)),r.onend=()=>u(!1),c.current=r,r.start()},[e,s,o,t]),f=l.useCallback(()=>{c.current?.stop()},[c]);return{listening:n,startListening:a,stopListening:f}}const oe=x?ne:se;function re(e,s){if(!e.length||!s.length)return[];const t=s.reduce((o,n)=>(o[n]={},o),{});return e.forEach(o=>{o.customFields?.forEach(({key:n,value:u})=>{const c=n.toLowerCase();s.includes(c)&&(t[c][u]=t[c][u]||[],t[c][u].push(o))})}),Object.entries(t).filter(o=>Object.keys(o[1]).length).map(([o,n])=>({field:o,options:Object.entries(n).map(([u,c])=>({value:u,skus:c,unavailable:!1,selected:!1}))}))}function ue(e,s){return e.length?e.map(({field:t,options:o})=>({field:t,options:o.map(n=>{const u=!n.skus?.some(a=>Object.entries(s).every(([f,r])=>f===t?!0:a.customFields?.find(d=>d.key.toLowerCase()===f)?.value===r)),c=s[t]===n.value;return{...n,unavailable:u,selected:c}})})):[]}const M=["4XS","3XS","2XS","XXS","XS","S","M","L","XL","XXL","2XL","XXXL","3XL","4XL"];function ce(e){if(M.includes(e))return 1e3+M.indexOf(e);const s=parseFloat(e);return isNaN(s)?e:s}function ie(e,s){return[...s].sort((t,o)=>{const[n,u]=[t.value,o.value].map(ce);return n<u?-1:1})}function ae(e=[],s=[]){const[t,o]=l.useState({}),n=l.useMemo(()=>re(e,s).map(({field:r,options:i})=>({field:r,options:ie(r,i)})),[e,s]),u=l.useMemo(()=>ue(n,t),[n,t]),c=l.useCallback((f,r)=>{o(i=>{const d={...i};return d[f]===r?delete d[f]:d[f]=r,d})},[]),a=l.useMemo(()=>Object.keys(t).filter(i=>t[i]).length===0?[]:u.filter(({field:i})=>t[i]).map(({field:i,options:d})=>{const p=t[i];return d.find(v=>v.value===p)?.skus??[]}).reduce((i,d)=>i.filter(p=>d.includes(p))),[u,t]);return{swatches:u,toggleOption:c,matchedSkus:a}}exports.useActions=A.useActions;exports.useLoadMore=h.useLoadMore;exports.useNostoAppState=h.useNostoAppState;exports.addToHistory=C.addToHistory;exports.getSavedHistory=C.getSavedHistory;exports.useHistory=C.useHistory;exports.speechToTextSupported=x;exports.useDecoratedSearchResults=O;exports.useFacet=X;exports.useFacets=E;exports.usePagination=B;exports.usePersonalization=V;exports.useProductFilters=L;exports.useRange=T;exports.useRangeSelector=U;exports.useResponse=I;exports.useSelectedFiltersCount=K;exports.useShopifyProduct=G;exports.useSizeOptions=Y;exports.useSort=te;exports.useSpeechToText=oe;exports.useSwatches=ae;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("../../useActions-CY9uts_o.cjs"),P=require("../../logger-Boh_C6Bz.cjs"),h=require("../../useLoadMore-CBshMpps.cjs"),R=require("../../eventBusSubscribe-oONOUGH8.cjs"),l=require("preact/hooks"),C=require("../../useHistory-rc2PvSkv.cjs"),q=require("../../index.es-Dp6Iaxz3.cjs"),z=require("../../eventBusDispatch-BKQcSHAB.cjs"),F=require("../../parseNumber-FsZ8w61u.cjs");function O(e){const s=h.useNostoAppState(t=>t.response);return e&&Array.isArray(e)||e&&P.isPlainObject(e)?e:s}function X(e,s){const t=e.data?.filter(f=>f.selected).length??0,{active:o}={active:t>0,...s},[n,c]=l.useState(o),{toggleProductFilter:u}=A.useActions(),a=l.useCallback(()=>{c(!n)},[n]);return R.useEventBusSubscribe({event:"events/removeAllFilters",callback:()=>{c(!1)}}),{active:n,selectedFiltersCount:t,toggleActive:a,toggleProductFilter:u}}function E(){const{loading:e,facets:s}=h.useNostoAppState(t=>({loading:t.loading,facets:t.response?.products?.facets??[]}));return{loading:e,facets:s}}function j(e,s){const t=s-e;return!isNaN(t)&&t>0?new Array(s-e).fill(void 0).map((o,n)=>n+e):[]}function B(e){const{query:s,products:t}=h.useNostoAppState(o=>({query:o.query,products:o.response.products}));return l.useMemo(()=>{if(!t)return{totalPages:0,resultsFrom:0,resultsTo:0,pages:[]};const o=s.products?.from??0,n=e?.width??1/0,c=Math.max(Math.floor(n-1)/2,1),u=t.size>0?Math.floor(o/t.size)+1:1,a=t.size>0?Math.ceil(t.total/t.size):0,f=y=>y>=u-c&&y<=u+c,r=o+1,i=Math.min(o+t.total,t.total),d={from:o,page:u,current:!0},p=y=>({from:(y-1)*t.size,page:y,current:y===u}),S=u>1?p(u-1):void 0,v=u<a?p(u+1):void 0,m=u-c-1>1?p(1):void 0,g=u+c+1<a?p(a):void 0,b=j(1,a+1).filter(f).map(p);return!m&&b[0]?.page===2&&b.unshift(p(1)),!g&&b[b.length-1]?.page===a-1&&b.push(p(a)),{totalPages:a,resultsFrom:r,resultsTo:i,current:d,prev:S,next:v,first:m,last:g,pages:b}},[s,t,e?.width])}function V(){const[e,s]=l.useState([]),[t,o]=l.useState([]);return l.useEffect(()=>{q.s(async n=>{const{products:c,segments:u}=await n.getSearchSessionParams();s(u??[]),o(c?.personalizationBoost??[])})},[]),{segments:e,boost:t}}function D(){const{facets:e}=h.useNostoAppState(r=>({facets:r.response.products?.facets??[]})),{replaceFilter:s,toggleProductFilter:t}=A.useActions(),o=l.useCallback(r=>{const i=e?.find(d=>d.type==="stats"&&d.field===r);if(i&&"min"in i&&"max"in i)return i},[e]),n=l.useCallback(r=>e?.find(i=>i.field===r)?.name??r,[e]),c=l.useCallback(r=>"field"in r&&(r.value instanceof Array||r.range instanceof Array),[]),u=l.useCallback(r=>({...r,range:r.range?.map(i=>({gt:i.gt?Number(i.gt):i.gt,gte:i.gte?Number(i.gte):i.gte,lt:i.lt?Number(i.lt):i.lt,lte:i.lte?Number(i.lte):i.lte}))}),[]),a=l.useCallback(r=>(r.value??[]).map(d=>({value:d,field:r.field,name:n(r.field),filter:u(r),remove:()=>{t(r.field,d,!1)}})),[u,n,t]),f=l.useCallback(r=>(r.range??[]).map(d=>{const p=d.gte??d.gt??o(r.field)?.min,S=d.lte??d.lt??o(r.field)?.max;if(p!==void 0&&S!==void 0)return{value:`${p} - ${S}`,field:r.field,name:n(r.field),filter:u(r),remove:()=>{s(r.field,void 0)}}}).filter(Boolean),[u,o,n,s]);return{selectFilters:c,toValueFilter:a,toRangeFilter:f}}function L(){const{filter:e}=h.useNostoAppState(a=>({filter:a.query.products?.filter??[]})),{updateSearch:s}=A.useActions(),{selectFilters:t,toValueFilter:o,toRangeFilter:n}=D(),c=l.useMemo(()=>e?e.filter(t).flatMap(a=>"value"in a?o(a):"range"in a?n(a):[]).filter(Boolean):[],[e,t,n,o]),u=l.useCallback(()=>{s({products:{filter:[]}}),z.dispatchNostoEvent({event:"events/removeAllFilters",params:null})},[s]);return{filters:c,removeAll:u}}function T(e){const{replaceFilter:s}=A.useActions(),{query:t,products:o}=h.useNostoAppState(g=>({query:g.query,products:g.response.products})),n=o?.facets?.find(g=>g.id===e),c=t.products?.filter?.find(g=>g.field===n?.field),[u,a]=H(c),f=n&&"min"in n?Math.floor(n.min??0):0,r=n&&"max"in n?Math.ceil(n.max??0):0,i=l.useMemo(()=>[u??f,a??r],[u,a,f,r]),d=u!==void 0||a!==void 0,[p,S]=l.useState(d),v=l.useCallback(()=>{S(g=>!g)},[]),m=l.useCallback(([g,b])=>{if(!n)return;const y=U(g,b,f,r);s(n.field,y)},[f,r,s,n]);return R.useEventBusSubscribe({event:"events/removeAllFilters",callback:()=>{S(!1)}}),n?{min:f,max:r,range:i,updateRange:m,active:p,toggleActive:v}:$}const $={min:0,max:0,range:[0,0],active:!1,toggleActive:()=>{},updateRange:()=>{}};function H(e){const s=e?.range?.[0];return typeof s=="object"&&("gte"in s||"lte"in s)?[F.parseNumber(s.gte),F.parseNumber(s.lte)]:[void 0,void 0]}function U(e,s,t,o){const n=e!==void 0?Math.floor(e):void 0,c=s!==void 0?Math.ceil(s):void 0,u=n!==void 0,a=c!==void 0;if((t===n||!u)&&(o===c||!a))return;const f={};return u&&n!==t&&(f.gte=n.toString()),a&&c!==o&&(f.lte=c.toString()),Object.keys(f).length>0?f:void 0}function _(e,s){const{min:t,max:o,range:n,updateRange:c}=T(e),{filters:u}=L(),a=l.useMemo(()=>{const d=u.find(m=>m?.filter?.range);let p=null;if(d){const m=d.filter.range?.[0];p=[F.parseNumber(m?.gte),F.parseNumber(m?.lte)]}const S=[];let v=Math.floor(t/s)*s;for(;v<o;){const m=v+s,g=p&&p[0]===v&&p[1]===m;S.push({min:v,max:m,selected:g}),v=m}return S},[u,t,o,s]),f=l.useCallback(d=>{c([d,n[1]])},[n,c]),r=l.useCallback(d=>{c([n[0],d])},[n,c]),i=t!==n[0]||o!==n[1];return{min:t,max:o,range:n,updateRange:c,ranges:a,handleMinChange:f,handleMaxChange:r,isSelected:i}}function I(){const{products:e,keywords:s}=h.useNostoAppState(t=>({products:t.response.products??{hits:[],total:0},keywords:t.response.keywords??{hits:[],total:0}}));return{products:e,keywords:s}}function K(){const e=h.useNostoAppState(t=>t.query.products?.filter);return l.useMemo(()=>e?e.reduce((t,o)=>t+(Array.isArray(o.value)?o.value.length:1),0):0,[e])}const Z=5*60*1e3,k=new Map;function G(e){const[s,t]=l.useState({product:null,loading:!0,error:null});return l.useEffect(()=>{if(!e){t({product:null,loading:!1,error:"Product handle is required"});return}t(n=>({...n,loading:!0,error:null}));const o=W(e);if(o){t({product:o,loading:!1,error:null});return}Q(e).then(n=>{Y(e,n),t({product:n,loading:!1,error:null})}).catch(n=>{t({product:null,loading:!1,error:n.message||"Failed to fetch product"})})},[e]),s}function J(e){const s=window.Shopify?.routes?.root;return s?new URL(`${s}products/${e}`,window.location.href):e}async function Q(e){const s=await fetch(J(`/products/${e}.js`));if(!s.ok)throw new Error(`Failed to fetch product: ${s.status} ${s.statusText}`);return s.json()}function W(e){const s=k.get(e);return s?Date.now()-s.created>Z?(k.delete(e),null):s.product:null}function Y(e,s){k.set(e,{product:s,created:Date.now()})}function w(e){return e&&!Number.isNaN(e)?e:0}function ee(e,s){const{from:t,size:o,total:n}=h.useNostoAppState(r=>({from:w(r.query.products?.from??0),size:w(r.response?.products?.size??s),total:w(r.response?.products?.total??0)})),{updateSearch:c}=A.useActions(),u=t+o,a=l.useMemo(()=>[...e].reverse().filter(r=>r<n),[e,n]),f=l.useCallback(r=>{c({products:{size:F.parseNumber(r)}})},[c]);return{from:t,to:u,total:n,size:o,sizeOptions:a,handleSizeChange:f}}function te(e,s){return e.length!==s.length?!1:e.every(t=>s.find(o=>t.field===o.field&&t.order===o.order))}function se(e){const s=h.useNostoAppState(c=>c.query),{updateSearch:t}=A.useActions(),o=e.find(c=>te(c.value.sort,s.products?.sort||[]))?.id??e[0]?.id,n=l.useCallback(c=>{const u=e.find(a=>a.id===c);u&&t({products:{sort:u.value.sort}})},[e,t]);return{activeSort:o,setSort:n}}const N=window.SpeechRecognition||window.webkitSpeechRecognition,x=!!(N&&typeof N=="function");function ne(){return{listening:!1,startListening:()=>{},stopListening:()=>{}}}function oe({language:e="en-US",interimResults:s=!1,onResult:t,onError:o}={}){const[n,c]=l.useState(!1),u=l.useRef(null),a=l.useCallback(()=>{const r=new N;r.lang=e,r.interimResults=s,r.onstart=()=>c(!0),t&&(r.onresult=i=>{const{transcript:d}=i.results?.[0]?.[0];t(d)}),o&&(r.onerror=i=>o(i.error)),r.onend=()=>c(!1),u.current=r,r.start()},[e,s,o,t]),f=l.useCallback(()=>{u.current?.stop()},[u]);return{listening:n,startListening:a,stopListening:f}}const re=x?oe:ne;function ce(e,s){if(!e.length||!s.length)return[];const t=s.reduce((o,n)=>(o[n]={},o),{});return e.forEach(o=>{o.customFields?.forEach(({key:n,value:c})=>{const u=n.toLowerCase();s.includes(u)&&(t[u][c]=t[u][c]||[],t[u][c].push(o))})}),Object.entries(t).filter(o=>Object.keys(o[1]).length).map(([o,n])=>({field:o,options:Object.entries(n).map(([c,u])=>({value:c,skus:u,unavailable:!1,selected:!1}))}))}function ue(e,s){return e.length?e.map(({field:t,options:o})=>({field:t,options:o.map(n=>{const c=!n.skus?.some(a=>Object.entries(s).every(([f,r])=>f===t?!0:a.customFields?.find(d=>d.key.toLowerCase()===f)?.value===r)),u=s[t]===n.value;return{...n,unavailable:c,selected:u}})})):[]}const M=["4XS","3XS","2XS","XXS","XS","S","M","L","XL","XXL","2XL","XXXL","3XL","4XL"];function ie(e){if(M.includes(e))return 1e3+M.indexOf(e);const s=parseFloat(e);return isNaN(s)?e:s}function ae(e,s){return[...s].sort((t,o)=>{const[n,c]=[t.value,o.value].map(ie);return n<c?-1:1})}function le(e=[],s=[]){const[t,o]=l.useState({}),n=l.useMemo(()=>ce(e,s).map(({field:r,options:i})=>({field:r,options:ae(r,i)})),[e,s]),c=l.useMemo(()=>ue(n,t),[n,t]),u=l.useCallback((f,r)=>{o(i=>{const d={...i};return d[f]===r?delete d[f]:d[f]=r,d})},[]),a=l.useMemo(()=>Object.keys(t).filter(i=>t[i]).length===0?[]:c.filter(({field:i})=>t[i]).map(({field:i,options:d})=>{const p=t[i];return d.find(v=>v.value===p)?.skus??[]}).reduce((i,d)=>i.filter(p=>d.includes(p))),[c,t]);return{swatches:c,toggleOption:u,matchedSkus:a}}exports.useActions=A.useActions;exports.useLoadMore=h.useLoadMore;exports.useNostoAppState=h.useNostoAppState;exports.addToHistory=C.addToHistory;exports.getSavedHistory=C.getSavedHistory;exports.useHistory=C.useHistory;exports.speechToTextSupported=x;exports.useDecoratedSearchResults=O;exports.useFacet=X;exports.useFacets=E;exports.usePagination=B;exports.usePersonalization=V;exports.useProductFilters=L;exports.useRange=T;exports.useRangeSelector=_;exports.useResponse=I;exports.useSelectedFiltersCount=K;exports.useShopifyProduct=G;exports.useSizeOptions=ee;exports.useSort=se;exports.useSpeechToText=re;exports.useSwatches=le;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { h as A } from "../../useActions-CSNwQtT1.js";
|
|
2
2
|
import { a as k } from "../../logger-_fg_Za9y.js";
|
|
3
3
|
import { a as S } from "../../useLoadMore-2OmOqicJ.js";
|
|
4
|
-
import { u as
|
|
4
|
+
import { u as Re } from "../../useLoadMore-2OmOqicJ.js";
|
|
5
5
|
import { u as N } from "../../eventBusSubscribe-CzlS132j.js";
|
|
6
6
|
import { useState as b, useCallback as g, useMemo as y, useEffect as P, useRef as X } from "preact/hooks";
|
|
7
|
-
import { a as xe, g as
|
|
7
|
+
import { a as xe, g as Me, u as Te } from "../../useHistory-joVBx1r2.js";
|
|
8
8
|
import { s as z } from "../../index.es-XNBESE3P.js";
|
|
9
9
|
import { d as C } from "../../eventBusDispatch-DPR2Vwd4.js";
|
|
10
10
|
import { p as R } from "../../parseNumber-QA48nJLp.js";
|
|
11
|
-
function
|
|
11
|
+
function ue(e) {
|
|
12
12
|
const n = S((t) => t.response);
|
|
13
13
|
return e && Array.isArray(e) || e && k(e) ? e : n;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function le(e, n) {
|
|
16
16
|
const t = e.data?.filter((d) => d.selected).length ?? 0, { active: o } = {
|
|
17
17
|
active: t > 0,
|
|
18
18
|
...n
|
|
@@ -35,7 +35,7 @@ function ue(e, n) {
|
|
|
35
35
|
toggleProductFilter: i
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function de() {
|
|
39
39
|
const { loading: e, facets: n } = S((t) => ({
|
|
40
40
|
loading: t.loading,
|
|
41
41
|
facets: t.response?.products?.facets ?? []
|
|
@@ -51,7 +51,7 @@ function O(e, n) {
|
|
|
51
51
|
const t = n - e;
|
|
52
52
|
return !isNaN(t) && t > 0 ? new Array(n - e).fill(void 0).map((o, r) => r + e) : [];
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function fe(e) {
|
|
55
55
|
const { query: n, products: t } = S((o) => ({
|
|
56
56
|
query: o.query,
|
|
57
57
|
products: o.response.products
|
|
@@ -86,7 +86,7 @@ function de(e) {
|
|
|
86
86
|
};
|
|
87
87
|
}, [n, t, e?.width]);
|
|
88
88
|
}
|
|
89
|
-
function
|
|
89
|
+
function ge() {
|
|
90
90
|
const [e, n] = b([]), [t, o] = b([]);
|
|
91
91
|
return P(() => {
|
|
92
92
|
z(async (r) => {
|
|
@@ -176,13 +176,13 @@ function E(e) {
|
|
|
176
176
|
const { replaceFilter: n } = A(), { query: t, products: o } = S((p) => ({
|
|
177
177
|
query: p.query,
|
|
178
178
|
products: p.response.products
|
|
179
|
-
})), r = o?.facets?.find((p) => p.id === e), c = t.products?.filter?.find((p) => p.field === r?.field), [i, u] =
|
|
179
|
+
})), r = o?.facets?.find((p) => p.id === e), c = t.products?.filter?.find((p) => p.field === r?.field), [i, u] = $(c), d = r && "min" in r ? Math.floor(r.min ?? 0) : 0, s = r && "max" in r ? Math.ceil(r.max ?? 0) : 0, a = y(() => [i ?? d, u ?? s], [i, u, d, s]), l = i !== void 0 || u !== void 0, [f, h] = b(l), v = g(() => {
|
|
180
180
|
h((p) => !p);
|
|
181
181
|
}, []), m = g(
|
|
182
182
|
([p, F]) => {
|
|
183
183
|
if (!r)
|
|
184
184
|
return;
|
|
185
|
-
const w =
|
|
185
|
+
const w = U(p, F, d, s);
|
|
186
186
|
n(r.field, w);
|
|
187
187
|
},
|
|
188
188
|
[d, s, n, r]
|
|
@@ -217,18 +217,18 @@ const V = {
|
|
|
217
217
|
updateRange: () => {
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
|
-
function
|
|
220
|
+
function $(e) {
|
|
221
221
|
const n = e?.range?.[0];
|
|
222
222
|
return typeof n == "object" && ("gte" in n || "lte" in n) ? [R(n.gte), R(n.lte)] : [void 0, void 0];
|
|
223
223
|
}
|
|
224
|
-
function
|
|
224
|
+
function U(e, n, t, o) {
|
|
225
225
|
const r = e !== void 0 ? Math.floor(e) : void 0, c = n !== void 0 ? Math.ceil(n) : void 0, i = r !== void 0, u = c !== void 0;
|
|
226
226
|
if ((t === r || !i) && (o === c || !u))
|
|
227
227
|
return;
|
|
228
228
|
const d = {};
|
|
229
229
|
return i && r !== t && (d.gte = r.toString()), u && c !== o && (d.lte = c.toString()), Object.keys(d).length > 0 ? d : void 0;
|
|
230
230
|
}
|
|
231
|
-
function
|
|
231
|
+
function pe(e, n) {
|
|
232
232
|
const { min: t, max: o, range: r, updateRange: c } = E(e), { filters: i } = q(), u = y(() => {
|
|
233
233
|
const l = i.find((m) => m?.filter?.range);
|
|
234
234
|
let f = null;
|
|
@@ -277,7 +277,7 @@ function ge(e, n) {
|
|
|
277
277
|
isSelected: a
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
|
-
function
|
|
280
|
+
function me() {
|
|
281
281
|
const { products: e, keywords: n } = S((t) => ({
|
|
282
282
|
products: t.response.products ?? { hits: [], total: 0 },
|
|
283
283
|
keywords: t.response.keywords ?? { hits: [], total: 0 }
|
|
@@ -289,12 +289,12 @@ function pe() {
|
|
|
289
289
|
keywords: n
|
|
290
290
|
};
|
|
291
291
|
}
|
|
292
|
-
function
|
|
292
|
+
function he() {
|
|
293
293
|
const e = S((t) => t.query.products?.filter);
|
|
294
294
|
return y(() => e ? e.reduce((t, o) => t + (Array.isArray(o.value) ? o.value.length : 1), 0) : 0, [e]);
|
|
295
295
|
}
|
|
296
|
-
const
|
|
297
|
-
function
|
|
296
|
+
const B = 5 * 60 * 1e3, x = /* @__PURE__ */ new Map();
|
|
297
|
+
function ve(e) {
|
|
298
298
|
const [n, t] = b({
|
|
299
299
|
product: null,
|
|
300
300
|
loading: !0,
|
|
@@ -314,7 +314,7 @@ function he(e) {
|
|
|
314
314
|
loading: !0,
|
|
315
315
|
error: null
|
|
316
316
|
}));
|
|
317
|
-
const o =
|
|
317
|
+
const o = H(e);
|
|
318
318
|
if (o) {
|
|
319
319
|
t({
|
|
320
320
|
product: o,
|
|
@@ -323,8 +323,8 @@ function he(e) {
|
|
|
323
323
|
});
|
|
324
324
|
return;
|
|
325
325
|
}
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
_(e).then((r) => {
|
|
327
|
+
I(e, r), t({
|
|
328
328
|
product: r,
|
|
329
329
|
loading: !1,
|
|
330
330
|
error: null
|
|
@@ -338,30 +338,34 @@ function he(e) {
|
|
|
338
338
|
});
|
|
339
339
|
}, [e]), n;
|
|
340
340
|
}
|
|
341
|
-
|
|
342
|
-
const n =
|
|
341
|
+
function D(e) {
|
|
342
|
+
const n = window.Shopify?.routes?.root;
|
|
343
|
+
return n ? new URL(`${n}products/${e}`, window.location.href) : e;
|
|
344
|
+
}
|
|
345
|
+
async function _(e) {
|
|
346
|
+
const n = await fetch(D(`/products/${e}.js`));
|
|
343
347
|
if (!n.ok)
|
|
344
348
|
throw new Error(`Failed to fetch product: ${n.status} ${n.statusText}`);
|
|
345
349
|
return n.json();
|
|
346
350
|
}
|
|
347
|
-
function
|
|
348
|
-
const n =
|
|
349
|
-
return n ? Date.now() - n.created >
|
|
351
|
+
function H(e) {
|
|
352
|
+
const n = x.get(e);
|
|
353
|
+
return n ? Date.now() - n.created > B ? (x.delete(e), null) : n.product : null;
|
|
350
354
|
}
|
|
351
|
-
function
|
|
352
|
-
|
|
355
|
+
function I(e, n) {
|
|
356
|
+
x.set(e, {
|
|
353
357
|
product: n,
|
|
354
358
|
created: Date.now()
|
|
355
359
|
});
|
|
356
360
|
}
|
|
357
|
-
function
|
|
361
|
+
function L(e) {
|
|
358
362
|
return e && !Number.isNaN(e) ? e : 0;
|
|
359
363
|
}
|
|
360
|
-
function
|
|
364
|
+
function Se(e, n) {
|
|
361
365
|
const { from: t, size: o, total: r } = S((s) => ({
|
|
362
|
-
from:
|
|
363
|
-
size:
|
|
364
|
-
total:
|
|
366
|
+
from: L(s.query.products?.from ?? 0),
|
|
367
|
+
size: L(s.response?.products?.size ?? n),
|
|
368
|
+
total: L(s.response?.products?.total ?? 0)
|
|
365
369
|
})), { updateSearch: c } = A(), i = t + o, u = y(() => [...e].reverse().filter((s) => s < r), [e, r]), d = g(
|
|
366
370
|
(s) => {
|
|
367
371
|
c({
|
|
@@ -387,11 +391,11 @@ function ve(e, n) {
|
|
|
387
391
|
handleSizeChange: d
|
|
388
392
|
};
|
|
389
393
|
}
|
|
390
|
-
function
|
|
394
|
+
function K(e, n) {
|
|
391
395
|
return e.length !== n.length ? !1 : e.every((t) => n.find((o) => t.field === o.field && t.order === o.order));
|
|
392
396
|
}
|
|
393
|
-
function
|
|
394
|
-
const n = S((c) => c.query), { updateSearch: t } = A(), o = e.find((c) =>
|
|
397
|
+
function ye(e) {
|
|
398
|
+
const n = S((c) => c.query), { updateSearch: t } = A(), o = e.find((c) => K(c.value.sort, n.products?.sort || []))?.id ?? e[0]?.id, r = g(
|
|
395
399
|
(c) => {
|
|
396
400
|
const i = e.find((u) => u.id === c);
|
|
397
401
|
i && t({
|
|
@@ -409,8 +413,8 @@ function Se(e) {
|
|
|
409
413
|
setSort: r
|
|
410
414
|
};
|
|
411
415
|
}
|
|
412
|
-
const M = window.SpeechRecognition || window.webkitSpeechRecognition,
|
|
413
|
-
function
|
|
416
|
+
const M = window.SpeechRecognition || window.webkitSpeechRecognition, Z = !!(M && typeof M == "function");
|
|
417
|
+
function G() {
|
|
414
418
|
return {
|
|
415
419
|
listening: !1,
|
|
416
420
|
startListening: () => {
|
|
@@ -419,7 +423,7 @@ function Z() {
|
|
|
419
423
|
}
|
|
420
424
|
};
|
|
421
425
|
}
|
|
422
|
-
function
|
|
426
|
+
function J({
|
|
423
427
|
language: e = "en-US",
|
|
424
428
|
interimResults: n = !1,
|
|
425
429
|
onResult: t,
|
|
@@ -440,8 +444,8 @@ function G({
|
|
|
440
444
|
stopListening: d
|
|
441
445
|
};
|
|
442
446
|
}
|
|
443
|
-
const
|
|
444
|
-
function
|
|
447
|
+
const Fe = Z ? J : G;
|
|
448
|
+
function Q(e, n) {
|
|
445
449
|
if (!e.length || !n.length) return [];
|
|
446
450
|
const t = n.reduce((o, r) => (o[r] = {}, o), {});
|
|
447
451
|
return e.forEach((o) => {
|
|
@@ -459,7 +463,7 @@ function J(e, n) {
|
|
|
459
463
|
}))
|
|
460
464
|
}));
|
|
461
465
|
}
|
|
462
|
-
function
|
|
466
|
+
function W(e, n) {
|
|
463
467
|
return e.length ? e.map(({ field: t, options: o }) => ({
|
|
464
468
|
field: t,
|
|
465
469
|
options: o.map((r) => {
|
|
@@ -473,23 +477,23 @@ function Q(e, n) {
|
|
|
473
477
|
})) : [];
|
|
474
478
|
}
|
|
475
479
|
const T = ["4XS", "3XS", "2XS", "XXS", "XS", "S", "M", "L", "XL", "XXL", "2XL", "XXXL", "3XL", "4XL"];
|
|
476
|
-
function
|
|
480
|
+
function Y(e) {
|
|
477
481
|
if (T.includes(e))
|
|
478
482
|
return 1e3 + T.indexOf(e);
|
|
479
483
|
const n = parseFloat(e);
|
|
480
484
|
return isNaN(n) ? e : n;
|
|
481
485
|
}
|
|
482
|
-
function
|
|
486
|
+
function ee(e, n) {
|
|
483
487
|
return [...n].sort((t, o) => {
|
|
484
|
-
const [r, c] = [t.value, o.value].map(
|
|
488
|
+
const [r, c] = [t.value, o.value].map(Y);
|
|
485
489
|
return r < c ? -1 : 1;
|
|
486
490
|
});
|
|
487
491
|
}
|
|
488
|
-
function
|
|
489
|
-
const [t, o] = b({}), r = y(() =>
|
|
492
|
+
function we(e = [], n = []) {
|
|
493
|
+
const [t, o] = b({}), r = y(() => Q(e, n).map(({ field: s, options: a }) => ({
|
|
490
494
|
field: s,
|
|
491
|
-
options:
|
|
492
|
-
})), [e, n]), c = y(() =>
|
|
495
|
+
options: ee(s, a)
|
|
496
|
+
})), [e, n]), c = y(() => W(r, t), [r, t]), i = g((d, s) => {
|
|
493
497
|
o((a) => {
|
|
494
498
|
const l = { ...a };
|
|
495
499
|
return l[d] === s ? delete l[d] : l[d] = s, l;
|
|
@@ -502,25 +506,25 @@ function Fe(e = [], n = []) {
|
|
|
502
506
|
}
|
|
503
507
|
export {
|
|
504
508
|
xe as addToHistory,
|
|
505
|
-
|
|
506
|
-
|
|
509
|
+
Me as getSavedHistory,
|
|
510
|
+
Z as speechToTextSupported,
|
|
507
511
|
A as useActions,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
512
|
+
ue as useDecoratedSearchResults,
|
|
513
|
+
le as useFacet,
|
|
514
|
+
de as useFacets,
|
|
515
|
+
Te as useHistory,
|
|
516
|
+
Re as useLoadMore,
|
|
513
517
|
S as useNostoAppState,
|
|
514
|
-
|
|
515
|
-
|
|
518
|
+
fe as usePagination,
|
|
519
|
+
ge as usePersonalization,
|
|
516
520
|
q as useProductFilters,
|
|
517
521
|
E as useRange,
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
522
|
+
pe as useRangeSelector,
|
|
523
|
+
me as useResponse,
|
|
524
|
+
he as useSelectedFiltersCount,
|
|
525
|
+
ve as useShopifyProduct,
|
|
526
|
+
Se as useSizeOptions,
|
|
527
|
+
ye as useSort,
|
|
528
|
+
Fe as useSpeechToText,
|
|
529
|
+
we as useSwatches
|
|
526
530
|
};
|
|
@@ -31,13 +31,6 @@ type RangeProps = [number | undefined, number | undefined];
|
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
export declare function useRange(id: string): {
|
|
34
|
-
readonly min: 0;
|
|
35
|
-
readonly max: 0;
|
|
36
|
-
readonly range: readonly [0, 0];
|
|
37
|
-
readonly active: false;
|
|
38
|
-
readonly toggleActive: () => void;
|
|
39
|
-
readonly updateRange: () => void;
|
|
40
|
-
} | {
|
|
41
34
|
/** Min value */
|
|
42
35
|
min: number;
|
|
43
36
|
/** Max value */
|
|
@@ -80,9 +80,9 @@ export declare function useRangeSelector(id: string, rangeSize: number): {
|
|
|
80
80
|
/** Maximum value */
|
|
81
81
|
max: number;
|
|
82
82
|
/** Range value */
|
|
83
|
-
range: number[]
|
|
83
|
+
range: number[];
|
|
84
84
|
/** Update range function */
|
|
85
|
-
updateRange: (
|
|
85
|
+
updateRange: ([from, to]: [number | undefined, number | undefined]) => void;
|
|
86
86
|
/** Ranges */
|
|
87
87
|
ranges: {
|
|
88
88
|
min: number;
|
|
@@ -5,5 +5,29 @@ export type Config = {
|
|
|
5
5
|
/**
|
|
6
6
|
* Replaces full size images with thumbnail sized versions.
|
|
7
7
|
* Uses `shopifyThumbnailDecorator` and `nostoThumbnailDecorator` based on the platform.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Configuration object specifying the desired thumbnail size.
|
|
10
|
+
* @returns A decorator function that transforms image URLs to thumbnail versions.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { search } from '@nosto/search-js'
|
|
15
|
+
* import { thumbnailDecorator } from '@nosto/search-js/thumbnails'
|
|
16
|
+
*
|
|
17
|
+
* // Use thumbnail decorator with search
|
|
18
|
+
* const results = await search(
|
|
19
|
+
* { query: 'shoes' },
|
|
20
|
+
* {
|
|
21
|
+
* hitDecorators: [
|
|
22
|
+
* thumbnailDecorator({ size: '200x200' })
|
|
23
|
+
* ]
|
|
24
|
+
* }
|
|
25
|
+
* )
|
|
26
|
+
* console.log(results.products.hits[0].thumb_url)
|
|
27
|
+
*
|
|
28
|
+
* // Available sizes: '100x100', '200x200', '400x400', '600x600', '800x800'
|
|
29
|
+
* const smallThumbs = thumbnailDecorator({ size: '100x100' })
|
|
30
|
+
* const largeThumbs = thumbnailDecorator({ size: '800x800' })
|
|
31
|
+
* ```
|
|
8
32
|
*/
|
|
9
33
|
export declare function thumbnailDecorator({ size }: Config): (hit: import('@nosto/nosto-js/client').SearchProduct) => import('@nosto/nosto-js/client').SearchProduct;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nosto/search-js",
|
|
3
|
-
"version": "3.21.
|
|
3
|
+
"version": "3.21.2",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -99,30 +99,30 @@
|
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@commitlint/cli": "^20.1.0",
|
|
101
101
|
"@commitlint/config-conventional": "^20.0.0",
|
|
102
|
-
"@nosto/nosto-js": "^2.
|
|
102
|
+
"@nosto/nosto-js": "^2.9.0",
|
|
103
103
|
"@testing-library/dom": "^10.4.1",
|
|
104
104
|
"@types/dom-speech-recognition": "^0.0.7",
|
|
105
105
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
106
|
-
"@types/node": "^24.
|
|
106
|
+
"@types/node": "^24.9.0",
|
|
107
107
|
"@vitest/coverage-v8": "^3.2.4",
|
|
108
108
|
"concurrently": "^9.2.1",
|
|
109
109
|
"copyfiles": "^2.4.1",
|
|
110
|
-
"eslint": "^9.
|
|
110
|
+
"eslint": "^9.38.0",
|
|
111
111
|
"eslint-config-prettier": "^10.1.8",
|
|
112
112
|
"eslint-plugin-barrel-files": "^3.0.1",
|
|
113
113
|
"eslint-plugin-prettier": "^5.5.4",
|
|
114
114
|
"eslint-plugin-react": "^7.37.5",
|
|
115
|
-
"eslint-plugin-react-hooks": "^
|
|
115
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
116
116
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
117
|
-
"eslint-plugin-unused-imports": "^4.
|
|
117
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
118
118
|
"husky": "^9.1.7",
|
|
119
119
|
"isbot": "^5.1.31",
|
|
120
|
-
"jsdom": "^27.0.
|
|
120
|
+
"jsdom": "^27.0.1",
|
|
121
121
|
"prettier": "^3.6.2",
|
|
122
|
-
"typedoc": "^0.28.
|
|
122
|
+
"typedoc": "^0.28.14",
|
|
123
123
|
"typescript": "^5.9.3",
|
|
124
|
-
"typescript-eslint": "^8.46.
|
|
125
|
-
"vite": "^7.1.
|
|
124
|
+
"typescript-eslint": "^8.46.2",
|
|
125
|
+
"vite": "^7.1.11",
|
|
126
126
|
"vite-plugin-dts": "^4.5.4",
|
|
127
127
|
"vitest": "^3.1.3"
|
|
128
128
|
},
|