@nosto/search-js 1.0.3 → 1.1.0

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/README.md CHANGED
@@ -5,6 +5,12 @@ Search JS is a wrapper for the Nosto Search functionality with some extended fun
5
5
  * Nosto product thumbnails
6
6
  * Retry logic
7
7
 
8
+ For @nosto/search-js specific API documentation, see [Our Typedoc](https://nosto.github.io/search-js/).
9
+
10
+ For more information about Nosto platform, see [Our documentation](https://docs.nosto.com/techdocs).
11
+
12
+ For sources, issues and contributions, see the [GitHub repository](https://github.com/Nosto/search-js).
13
+
8
14
  ## Installation
9
15
 
10
16
  To install the package, use your preferred package manager:
@@ -1,14 +1,14 @@
1
1
  import { SearchProduct, SearchProductSku } from "@nosto/nosto-js/client";
2
2
  import { CurrencyConfig } from "./getCurrencyFormatting";
3
- type FormattedPrices = {
3
+ export type FormattedPrices = {
4
4
  priceText?: string;
5
5
  listPriceText?: string;
6
6
  };
7
+ export type Result = SearchProduct & FormattedPrices & {
8
+ skus?: (SearchProductSku & FormattedPrices)[];
9
+ };
7
10
  /**
8
11
  * Exposes currency formatting logic as a SearchProduct decorator
9
12
  * Sets priceText and listPriceText fields on product and SKU level
10
13
  */
11
- export declare function priceDecorator(config?: Partial<CurrencyConfig>): (hit: SearchProduct) => SearchProduct & FormattedPrices & {
12
- skus?: (SearchProductSku & FormattedPrices)[];
13
- };
14
- export {};
14
+ export declare function priceDecorator(config?: Partial<CurrencyConfig>): (hit: SearchProduct) => Result;
@@ -1,2 +1,3 @@
1
+ /** @module currencies */
1
2
  export { getCurrencyFormatting, type CurrencyConfig } from "./currencies/getCurrencyFormatting";
2
- export { priceDecorator } from "./currencies/priceDecorator";
3
+ export { priceDecorator, type FormattedPrices, type Result } from "./currencies/priceDecorator";
@@ -0,0 +1,21 @@
1
+ import { SearchResult } from "@nosto/nosto-js/client";
2
+ import { HitDecorator } from "./types";
3
+ export declare function applyDecorators<HD extends HitDecorator[]>(response: SearchResult, decorators?: HD): {
4
+ products: {
5
+ hits: ((ReturnType<HD[number]> extends infer T ? T extends ReturnType<HD[number]> ? T extends any ? (x: T) => void : never : never : never) extends (x: infer I) => void ? I : never)[];
6
+ categoryId?: string;
7
+ categoryPath?: string;
8
+ collapse?: string;
9
+ facets?: import("@nosto/nosto-js/client").SearchFacet[];
10
+ from?: number;
11
+ fuzzy?: boolean;
12
+ size?: number;
13
+ total: number;
14
+ };
15
+ autocorrect?: import("@nosto/nosto-js/client").SearchAutocorrect;
16
+ explain?: import("@nosto/nosto-js/client").SearchExplain;
17
+ keywords?: import("@nosto/nosto-js/client").SearchKeywords;
18
+ query?: string;
19
+ redirect?: string;
20
+ abTests?: import("@nosto/nosto-js/client").ABTest[];
21
+ };
@@ -0,0 +1,28 @@
1
+ import { SearchQuery } from "@nosto/nosto-js/client";
2
+ import { HitDecorator, Options } from "./types";
3
+ /**
4
+ * Performs a search operation using the provided query and options.
5
+ *
6
+ * @param query - The search query to be executed.
7
+ * @param options - An object containing optional parameters for the search.
8
+ * @returns A promise that resolves to the search result.
9
+ */
10
+ export declare function search<HD extends HitDecorator[]>(query: SearchQuery, options?: Options<HD>): Promise<{
11
+ products: {
12
+ hits: ((ReturnType<HD[number]> extends infer T ? T extends ReturnType<HD[number]> ? T extends any ? (x: T) => void : never : never : never) extends (x: infer I) => void ? I : never)[];
13
+ categoryId?: string;
14
+ categoryPath?: string;
15
+ collapse?: string;
16
+ facets?: import("@nosto/nosto-js/client").SearchFacet[];
17
+ from?: number;
18
+ fuzzy?: boolean;
19
+ size?: number;
20
+ total: number;
21
+ };
22
+ autocorrect?: import("@nosto/nosto-js/client").SearchAutocorrect;
23
+ explain?: import("@nosto/nosto-js/client").SearchExplain;
24
+ keywords?: import("@nosto/nosto-js/client").SearchKeywords;
25
+ query?: string;
26
+ redirect?: string;
27
+ abTests?: import("@nosto/nosto-js/client").ABTest[];
28
+ }>;
@@ -0,0 +1,7 @@
1
+ import { API, SearchQuery, SearchResult } from "@nosto/nosto-js/client";
2
+ import { Options } from "./types";
3
+ export declare function searchWithRetries(api: API, query: SearchQuery, options: Options<[]>): Promise<SearchResult>;
4
+ /**
5
+ * Should the error trigger a search retry
6
+ */
7
+ export declare function shouldRetry(error: unknown): error is object;
@@ -0,0 +1,24 @@
1
+ import { SearchOptions, SearchProduct, SearchResult } from "@nosto/nosto-js/client";
2
+ export type Options<HD extends HitDecorator[]> = SearchOptions & {
3
+ /**
4
+ * Hit decorators to apply to the search results.
5
+ */
6
+ hitDecorators?: HD;
7
+ /**
8
+ * Maximum number of retry attempts. Default: 0 (no retries).
9
+ */
10
+ maxRetries?: number;
11
+ /**
12
+ * Interval (in ms) between retry attempts. Default: 1000 ms.
13
+ */
14
+ retryInterval?: number;
15
+ };
16
+ export type HitDecorator = (hit: SearchProduct) => SearchProduct;
17
+ type ToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
18
+ export type DecoratedProduct<HD extends HitDecorator[]> = ToIntersection<ReturnType<HD[number]>>;
19
+ export type DecoratedResult<HD extends HitDecorator[]> = Omit<SearchResult, "products"> & {
20
+ products: SearchResult["products"] & {
21
+ hits: DecoratedProduct<HD>[];
22
+ };
23
+ };
24
+ export {};
@@ -0,0 +1 @@
1
+ export declare function delay(ms: number): Promise<void>;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./index.es-D_7T9vdv.cjs");function a(t,e){if(!t.products||!(e!=null&&e.length))return t;const r=i=>e.reduce((u,n)=>n(u),i);return{...t,products:{...t.products,hits:t.products.hits.map(r)}}}function o(t){return new Promise(e=>setTimeout(e,t))}async function l(t,e,r){const{maxRetries:i=0,retryInterval:u=1e3}=r;let n=0;for(;;)try{return await t.search(e,r)}catch(c){if(!f(c))throw console.info("Skipping retry logic for",c),c;if(n>=i)throw c;n++,await o(u)}}function f(t){return!t||typeof t!="object"?!1:!("status"in t)||h(t.status)}function h(t){return typeof t=="number"&&(t<400||t>=500)}async function y(t,e={}){const{hitDecorators:r,...i}=e,u=await new Promise(s.s),n=await l(u,t,i);return a(n,r)}exports.search=y;
package/dist/search.d.ts CHANGED
@@ -1,17 +1,3 @@
1
- import { SearchOptions, SearchProduct, SearchQuery, SearchResult } from "@nosto/nosto-js/client";
2
- export type Options = SearchOptions & {
3
- /**
4
- * Hit decorators to apply to the search results.
5
- */
6
- hitDecorators?: HitDecorator[];
7
- };
8
- /**
9
- * Performs a search operation using the provided query and options.
10
- *
11
- * @param query - The search query to be executed.
12
- * @param options - An object containing optional parameters for the search.
13
- * @param options.hitDecorators - An optional array of decorators to be applied to the search results.
14
- * @returns A promise that resolves to the search result.
15
- */
16
- export declare function search(query: SearchQuery, { hitDecorators, ...options }?: Options): Promise<SearchResult>;
17
- export type HitDecorator = (hit: SearchProduct) => SearchProduct;
1
+ /** @module ./ */
2
+ export { search } from "./search/search";
3
+ export type { Options, HitDecorator } from "./search/types";
@@ -0,0 +1,43 @@
1
+ import { s as a } from "./index.es-Bcd5IQh9.js";
2
+ function s(t, r) {
3
+ if (!t.products || !(r != null && r.length))
4
+ return t;
5
+ const e = (i) => r.reduce((u, n) => n(u), i);
6
+ return {
7
+ ...t,
8
+ products: {
9
+ ...t.products,
10
+ hits: t.products.hits.map(e)
11
+ }
12
+ };
13
+ }
14
+ function o(t) {
15
+ return new Promise((r) => setTimeout(r, t));
16
+ }
17
+ async function f(t, r, e) {
18
+ const { maxRetries: i = 0, retryInterval: u = 1e3 } = e;
19
+ let n = 0;
20
+ for (; ; )
21
+ try {
22
+ return await t.search(r, e);
23
+ } catch (c) {
24
+ if (!h(c))
25
+ throw console.info("Skipping retry logic for", c), c;
26
+ if (n >= i)
27
+ throw c;
28
+ n++, await o(u);
29
+ }
30
+ }
31
+ function h(t) {
32
+ return !t || typeof t != "object" ? !1 : !("status" in t) || l(t.status);
33
+ }
34
+ function l(t) {
35
+ return typeof t == "number" && (t < 400 || t >= 500);
36
+ }
37
+ async function p(t, r = {}) {
38
+ const { hitDecorators: e, ...i } = r, u = await new Promise(a), n = await f(u, t, i);
39
+ return s(n, e);
40
+ }
41
+ export {
42
+ p as search
43
+ };
@@ -1,8 +1,10 @@
1
1
  import { ThumbnailSize } from "./types";
2
- type Props = {
2
+ export type Props = {
3
3
  size: ThumbnailSize;
4
4
  productId: string;
5
5
  hash: string;
6
6
  };
7
+ /**
8
+ * Generates a thumbnail URL for a given product and size
9
+ */
7
10
  export declare function generateThumbnailUrl({ size, productId, hash }: Props): string;
8
- export {};
@@ -1,6 +1,6 @@
1
1
  import { SearchProduct } from "@nosto/nosto-js/client";
2
2
  import { ShopifySize } from "./types";
3
- type Config = {
3
+ export type Config = {
4
4
  size: ShopifySize;
5
5
  };
6
6
  /**
@@ -8,4 +8,3 @@ type Config = {
8
8
  * This decorator will only affect the image URLs from Shopify CDN.
9
9
  */
10
10
  export declare function shopifyThumbnailDecorator({ size }: Config): (hit: SearchProduct) => SearchProduct;
11
- export {};
@@ -1,10 +1,9 @@
1
1
  import { SearchProduct } from "@nosto/nosto-js/client";
2
2
  import { ThumbnailSize } from "./types";
3
- type Config = {
3
+ export type Config = {
4
4
  size: ThumbnailSize;
5
5
  };
6
6
  /**
7
7
  * Replaces full size images with thumbnail sized versions.
8
8
  */
9
9
  export declare function thumbnailDecorator({ size }: Config): (hit: SearchProduct) => SearchProduct;
10
- export {};
@@ -1,33 +1,33 @@
1
1
  /**
2
2
  * Nosto thumbnail size code.
3
3
  *
4
- * "1": 170x170 px
5
- * "2": 100x100 px
6
- * "3": 90x70 px
7
- * "4": 50x50 px
8
- * "5": 30x30 px
9
- * "6": 100x140 px
10
- * "7": 200x200 px
11
- * "8": 400x400 px
12
- * "9": 750x750 px
13
- * "10": Original (Square)
14
- * "11": 200x200 px (Square)
15
- * "12": 400x400 px (Square)
16
- * "13": 750x750 px (Square)
4
+ * * 1: 170x170 px
5
+ * * 2: 100x100 px
6
+ * * 3: 90x70 px
7
+ * * 4: 50x50 px
8
+ * * 5: 30x30 px
9
+ * * 6: 100x140 px
10
+ * * 7: 200x200 px
11
+ * * 8: 400x400 px
12
+ * * 9: 750x750 px
13
+ * * 10: Original (Square)
14
+ * * 11: 200x200 px (Square)
15
+ * * 12: 400x400 px (Square)
16
+ * * 13: 750x750 px (Square)
17
17
  */
18
18
  export type ThumbnailSize = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "orig";
19
19
  /**
20
20
  * Shopify thumbnail size code.
21
21
  *
22
- * Pico (16×16 px)
23
- * Icon (32×32 px)
24
- * Thumb (50×50 px)
25
- * Small (100×100 px)
26
- * Compact (160×160 px)
27
- * Medium (240×240 px)
28
- * Large (480×480 px)
29
- * Grande (600×600 px)
30
- * Original (1024×1024 px)
31
- * Master (full size)
22
+ * * Pico (16×16 px)
23
+ * * Icon (32×32 px)
24
+ * * Thumb (50×50 px)
25
+ * * Small (100×100 px)
26
+ * * Compact (160×160 px)
27
+ * * Medium (240×240 px)
28
+ * * Large (480×480 px)
29
+ * * Grande (600×600 px)
30
+ * * Original (1024×1024 px)
31
+ * * Master (full size)
32
32
  */
33
33
  export type ShopifySize = "pico" | "icon" | "thumb" | "small" | "compact" | "medium" | "large" | "grande" | "original" | "master";
@@ -1,4 +1,5 @@
1
- export { generateThumbnailUrl } from "./thumbnails/generateThumbnailUrl";
2
- export { thumbnailDecorator } from "./thumbnails/thumbnailDecorator";
3
- export { shopifyThumbnailDecorator } from "./thumbnails/shopifyThumbnailDecorator";
1
+ /** @module thumbnails */
2
+ export { generateThumbnailUrl, type Props } from "./thumbnails/generateThumbnailUrl";
3
+ export { thumbnailDecorator, type Config } from "./thumbnails/thumbnailDecorator";
4
+ export { shopifyThumbnailDecorator, type Config as ShopifyConfig } from "./thumbnails/shopifyThumbnailDecorator";
4
5
  export type { ThumbnailSize, ShopifySize } from "./thumbnails/types";
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@nosto/search-js",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
9
- "main": "./dist/index.cjs.js",
10
- "module": "./dist/index.es.js",
11
- "types": "./dist/index.d.ts",
9
+ "main": "./dist/search.cjs.js",
10
+ "module": "./dist/search.es.js",
11
+ "types": "./dist/search.d.ts",
12
12
  "directories": {
13
13
  "doc": "docs",
14
14
  "test": "test"
15
15
  },
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/index.d.ts",
19
- "import": "./dist/index.es.js",
20
- "require": "./dist/index.cjs.js"
18
+ "types": "./dist/search.d.ts",
19
+ "import": "./dist/search.es.js",
20
+ "require": "./dist/search.cjs.js"
21
21
  },
22
22
  "./currencies": {
23
23
  "types": "./dist/currencies.d.ts",
@@ -39,7 +39,7 @@
39
39
  "test": "vitest --run",
40
40
  "lint": "eslint '{src,test}/**/*.ts'",
41
41
  "preview": "vite preview",
42
- "typedoc": "typedoc src/index.ts"
42
+ "typedoc": "typedoc src/search.ts src/currencies.ts src/thumbnails.ts"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@nosto/nosto-js": "^1.4.4",
package/dist/index.cjs.js DELETED
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index.es-D_7T9vdv.cjs");async function i(t,{hitDecorators:r,...u}={}){const c=await new Promise(a.s);return r!=null&&r.length?d(await c.search(t,u),r):await c.search(t,u)}function d(t,r){if(!t.products)return t;const u=c=>r.reduce((e,n)=>n(e),c);return{...t,products:{...t.products,hits:t.products.hits.map(u)}}}exports.search=i;
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export { search, type Options, type HitDecorator } from "./search";
package/dist/index.es.js DELETED
@@ -1,20 +0,0 @@
1
- import { s as d } from "./index.es-Bcd5IQh9.js";
2
- async function p(r, { hitDecorators: t, ...u } = {}) {
3
- const a = await new Promise(d);
4
- return t != null && t.length ? i(await a.search(r, u), t) : await a.search(r, u);
5
- }
6
- function i(r, t) {
7
- if (!r.products)
8
- return r;
9
- const u = (a) => t.reduce((c, n) => n(c), a);
10
- return {
11
- ...r,
12
- products: {
13
- ...r.products,
14
- hits: r.products.hits.map(u)
15
- }
16
- };
17
- }
18
- export {
19
- p as search
20
- };