@iheartjane/dm-sdk 2.24.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/dist/chunk-VEW5EGZ2.js +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +1181 -0
- package/dist/index.d.ts +1181 -0
- package/dist/index.js +1 -0
- package/dist/smartSort-DJFM0D_n.d.cts +1075 -0
- package/dist/smartSort-DJFM0D_n.d.ts +1075 -0
- package/dist/test-utils.cjs +1 -0
- package/dist/test-utils.d.cts +189 -0
- package/dist/test-utils.d.ts +189 -0
- package/dist/test-utils.js +1 -0
- package/package.json +68 -0
- package/test-utils/package.json +4 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1181 @@
|
|
|
1
|
+
import { P as Placement, A as AdMode, F as FilterContext, a as PageContextEnum, S as SearchSortEnum, C as Click, I as Impression, b as CustomImageData, c as SmartSortProductProps, d as SmartSortClickIntent, e as SmartSortProps, f as ConversionExternalProduct, g as SessionEvent, R as RequiredConfig, J as JaneDMPublicConfig, h as JaneDMInternalConfig, i as FetchCartTopperRowProps, j as FetchCustomImageRowProps, k as Facets, l as FetchMenuRowProps, m as FetchMenuTopRowProps, n as FetchProductReviewsProps, o as ProductReviewsResponse, p as FetchRecommendedPDPRowProps, q as FetchRecommendedRowProps, r as FetchRecommendedSortProps, V as VirtualBudtenderQuery, s as IterateProductReviewsProps, t as ProductReviewsIterable } from './smartSort-DJFM0D_n.js';
|
|
2
|
+
export { u as AppMode, D as DEFAULT_PAGE_SIZE, v as FetchCartTopperRowByPosProductId, w as FetchCartTopperRowByProductProps, x as FetchRecommendedPDPRowByPosProductId, y as FetchRecommendedPDPRowByProductId, z as IntendedDisplay, B as JaneDMConfig, E as JaneDMIdentifiers, G as JaneDeviceIdSentinel, H as PaginationInfo, K as ProductKindEnum, L as ProductReview, M as ProductReviewsAggregate, N as ReviewSortEnum, O as SearchSort, Q as SmartSortNextPageProps, T as VirtualBudtenderSearchResponse, U as bestSellerRank, W as categoryAndNameAsc, X as defaultOrder, Y as priceAsc, Z as priceDesc, _ as priceEighthOunceAsc, $ as priceEighthOunceDesc, a0 as priceGramAsc, a1 as priceGramDesc, a2 as priceHalfGramAsc, a3 as priceHalfGramDesc, a4 as priceHalfOunceAsc, a5 as priceHalfOunceDesc, a6 as priceOunceAsc, a7 as priceOunceDesc, a8 as priceQuarterOunceAsc, a9 as priceQuarterOunceDesc, aa as priceTwoGramAsc, ab as priceTwoGramDesc, ac as rating, ad as recommendation, ae as searchSorts, af as thcPotencyAsc, ag as thcPotencyDesc } from './smartSort-DJFM0D_n.js';
|
|
3
|
+
|
|
4
|
+
interface CustomBestSellingProps {
|
|
5
|
+
placement: Placement.BestSelling;
|
|
6
|
+
title?: string;
|
|
7
|
+
}
|
|
8
|
+
interface CustomBrandSpecialsProps {
|
|
9
|
+
placement: Placement.BrandSpecials;
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
interface CustomBuyAgainRowProps {
|
|
13
|
+
placement: Placement.BuyAgainRow;
|
|
14
|
+
title?: string;
|
|
15
|
+
}
|
|
16
|
+
interface CustomFeaturedRowProps {
|
|
17
|
+
placement: Placement.FeaturedRow;
|
|
18
|
+
rowId: number;
|
|
19
|
+
}
|
|
20
|
+
interface CustomImageRowProps {
|
|
21
|
+
placement: Placement.CustomImageRow;
|
|
22
|
+
searchFilter?: string;
|
|
23
|
+
}
|
|
24
|
+
interface CustomMenuDynamicRowProps {
|
|
25
|
+
adMode?: AdMode;
|
|
26
|
+
filterContext?: FilterContext[];
|
|
27
|
+
pageContext?: PageContextEnum;
|
|
28
|
+
placement: Placement.MenuDynamicRow;
|
|
29
|
+
}
|
|
30
|
+
interface CustomMenuInlineProps {
|
|
31
|
+
adMode?: AdMode;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
placement: Placement.MenuInline;
|
|
34
|
+
searchFilter?: string;
|
|
35
|
+
searchQuery?: string;
|
|
36
|
+
searchSort?: SearchSortEnum;
|
|
37
|
+
title?: string;
|
|
38
|
+
}
|
|
39
|
+
interface CustomMenuInlineTableProps {
|
|
40
|
+
disableAds?: boolean;
|
|
41
|
+
maxProducts?: number;
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
pageSize?: number;
|
|
44
|
+
placement: Placement.MenuInlineTable;
|
|
45
|
+
searchFacets?: string[];
|
|
46
|
+
searchFilter?: string;
|
|
47
|
+
searchQuery?: string;
|
|
48
|
+
searchSort?: SearchSortEnum;
|
|
49
|
+
title?: string;
|
|
50
|
+
}
|
|
51
|
+
interface CustomMenuTopRowProps {
|
|
52
|
+
placement: Placement.MenuTopRow;
|
|
53
|
+
searchFilter?: string;
|
|
54
|
+
}
|
|
55
|
+
type CustomPlacementProps = CustomBestSellingProps | CustomBrandSpecialsProps | CustomBuyAgainRowProps | CustomFeaturedRowProps | CustomImageRowProps | CustomMenuDynamicRowProps | CustomMenuInlineProps | CustomMenuInlineTableProps | CustomMenuTopRowProps | CustomSaleProps | CustomSpecialsProps;
|
|
56
|
+
interface CustomSaleProps {
|
|
57
|
+
placement: Placement.Sale;
|
|
58
|
+
title?: string;
|
|
59
|
+
}
|
|
60
|
+
interface CustomSpecialsProps {
|
|
61
|
+
placement: Placement.Specials;
|
|
62
|
+
title?: string;
|
|
63
|
+
}
|
|
64
|
+
interface FetchCustomPlacementsProps extends CommonProps {
|
|
65
|
+
/**
|
|
66
|
+
* The placements to fetch.
|
|
67
|
+
*/
|
|
68
|
+
placements: CustomPlacementProps[];
|
|
69
|
+
}
|
|
70
|
+
interface FetchFeaturedPlacementProps extends CommonProps {
|
|
71
|
+
/**
|
|
72
|
+
* Whether to exclude the menu top row from the featured placements.
|
|
73
|
+
*/
|
|
74
|
+
excludeMenuTopRow?: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface CommonProps {
|
|
77
|
+
numColumns?: number;
|
|
78
|
+
/**
|
|
79
|
+
* The attributes to be returned in the response.
|
|
80
|
+
*/
|
|
81
|
+
searchAttributes: string[];
|
|
82
|
+
/**
|
|
83
|
+
* The ID of the store to fetch the placements from.
|
|
84
|
+
*/
|
|
85
|
+
storeId: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type FetchProductProps = {
|
|
89
|
+
searchAttributes: string[];
|
|
90
|
+
storeId: number;
|
|
91
|
+
} & (ProductById | ProductByPosProductId);
|
|
92
|
+
interface ProductById {
|
|
93
|
+
posProductId?: never;
|
|
94
|
+
productId: number;
|
|
95
|
+
}
|
|
96
|
+
interface ProductByPosProductId {
|
|
97
|
+
posProductId: string;
|
|
98
|
+
productId?: never;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The VirtualBudtenderClickIntent is used to determine if the click
|
|
103
|
+
* event should be treated as an "add to cart" event.
|
|
104
|
+
*/
|
|
105
|
+
interface VirtualBudtenderClickIntent {
|
|
106
|
+
/**
|
|
107
|
+
* When set to true, the click event will be treated as an "add to cart" event.
|
|
108
|
+
* @default false
|
|
109
|
+
*/
|
|
110
|
+
isAddToCart?: boolean;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Properties to create a `VirtualBudtenderProduct` instance.
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
interface VirtualBudtenderProductProps<ProductAttributes extends object = Record<string, unknown>> {
|
|
117
|
+
/**
|
|
118
|
+
* The raw Virtual Budtender product data
|
|
119
|
+
*/
|
|
120
|
+
attributes: ProductAttributes;
|
|
121
|
+
/**
|
|
122
|
+
* Click tracking payload
|
|
123
|
+
*/
|
|
124
|
+
clickPayload: Click;
|
|
125
|
+
/**
|
|
126
|
+
* Click tracking URL
|
|
127
|
+
*/
|
|
128
|
+
clickUrl: string;
|
|
129
|
+
/**
|
|
130
|
+
* Whether this product has been impressed yet
|
|
131
|
+
*/
|
|
132
|
+
hasBeenImpressed?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Impression tracking payload
|
|
135
|
+
*/
|
|
136
|
+
impressPayload: Impression;
|
|
137
|
+
/**
|
|
138
|
+
* Impression tracking URL
|
|
139
|
+
*/
|
|
140
|
+
impressUrl: string;
|
|
141
|
+
/**
|
|
142
|
+
* Boolean that indicates if a product is sponsored or not
|
|
143
|
+
*/
|
|
144
|
+
isSponsored: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* The primary identifier for this product
|
|
147
|
+
*/
|
|
148
|
+
objectId: string;
|
|
149
|
+
/**
|
|
150
|
+
* The reasoning for the product
|
|
151
|
+
*/
|
|
152
|
+
reasoning?: string;
|
|
153
|
+
/**
|
|
154
|
+
* The score of the product
|
|
155
|
+
*/
|
|
156
|
+
score?: number;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parameters for fetching virtual budtender query suggestions.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
interface VirtualBudtenderQueriesParams {
|
|
163
|
+
/**
|
|
164
|
+
* The store ID to get queries for
|
|
165
|
+
*/
|
|
166
|
+
storeId: number;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Parameters for virtual budtender search.
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
172
|
+
interface VirtualBudtenderSearchParams {
|
|
173
|
+
/**
|
|
174
|
+
* Natural language query for product search
|
|
175
|
+
*/
|
|
176
|
+
query: string;
|
|
177
|
+
/**
|
|
178
|
+
* Optional search attributes to include in the results
|
|
179
|
+
*/
|
|
180
|
+
searchAttributes?: string[];
|
|
181
|
+
/**
|
|
182
|
+
* Store ID to search products in
|
|
183
|
+
*/
|
|
184
|
+
storeId: number;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Parameters for fetching facets.
|
|
189
|
+
*/
|
|
190
|
+
interface FetchFacetsParams {
|
|
191
|
+
/**
|
|
192
|
+
* A list of search facets to be returned in the search results, such as
|
|
193
|
+
* `['kind']`.
|
|
194
|
+
*/
|
|
195
|
+
searchFacets?: string[];
|
|
196
|
+
/**
|
|
197
|
+
* A filter string to be applied to the search results, such as
|
|
198
|
+
* `'kind:flower'`.
|
|
199
|
+
*/
|
|
200
|
+
searchFilter?: string;
|
|
201
|
+
/**
|
|
202
|
+
* A search query to filter results.
|
|
203
|
+
*/
|
|
204
|
+
searchQuery?: string;
|
|
205
|
+
/**
|
|
206
|
+
* The store ID to fetch facets for.
|
|
207
|
+
*/
|
|
208
|
+
storeId: number;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Represents a product, called menu product in the Jane ecosystem, for a
|
|
213
|
+
* smart sort placement.
|
|
214
|
+
*/
|
|
215
|
+
declare class SmartSortProduct<ProductShape extends object = Record<string, unknown>> {
|
|
216
|
+
/**
|
|
217
|
+
* The attributes of this product.
|
|
218
|
+
* The shape and data of this field will change depending on the requested
|
|
219
|
+
* attributes.
|
|
220
|
+
* @example
|
|
221
|
+
* ```jsx
|
|
222
|
+
* { product_id: '1234' }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
attributes: ProductShape;
|
|
226
|
+
/**
|
|
227
|
+
* Boolean that indicates if a product is sponsored or not
|
|
228
|
+
*/
|
|
229
|
+
isSponsored: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* The primary identifier for this product.
|
|
232
|
+
*/
|
|
233
|
+
objectId: string;
|
|
234
|
+
private clickPayload;
|
|
235
|
+
private clickUrl;
|
|
236
|
+
private hasBeenImpressed;
|
|
237
|
+
private impressPayload;
|
|
238
|
+
private impressPromise?;
|
|
239
|
+
private impressUrl;
|
|
240
|
+
/**
|
|
241
|
+
* Builds a new SmartSortProduct instance based on the provided properties.
|
|
242
|
+
* This method should be used in conjunction with `serialize()` to recreate the instance.
|
|
243
|
+
*/
|
|
244
|
+
constructor(props: SmartSortProductProps<ProductShape>);
|
|
245
|
+
/**
|
|
246
|
+
* Converts the previously-serialized object back to an instance of this class.
|
|
247
|
+
* This method should be used in conjunction with `toJSON()` to recreate the instance.
|
|
248
|
+
*/
|
|
249
|
+
static fromJSON<ProductShape extends object = Record<string, unknown>>(serialized: string): SmartSortProduct<ProductShape>;
|
|
250
|
+
/**
|
|
251
|
+
* Records attribution data for this product. This method
|
|
252
|
+
* should be called when the product is clicked by the user.
|
|
253
|
+
* If the click is associated with an add to cart action,
|
|
254
|
+
* that intent should be passed to the click method.
|
|
255
|
+
* @example
|
|
256
|
+
* ```jsx
|
|
257
|
+
* placement.products.map((product) => {
|
|
258
|
+
* return (<ProductCard
|
|
259
|
+
* product={product}
|
|
260
|
+
* onClick={() => product.click()}
|
|
261
|
+
* key={product.objectId}
|
|
262
|
+
* >
|
|
263
|
+
* <Button
|
|
264
|
+
* title="Add to Cart"
|
|
265
|
+
* onClick={() => product.click({isAddToCart: true})}
|
|
266
|
+
* />
|
|
267
|
+
* </ProductCard>);
|
|
268
|
+
* });
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
click(props?: SmartSortClickIntent): Promise<void>;
|
|
272
|
+
/**
|
|
273
|
+
* Records attribution data for this product. This method
|
|
274
|
+
* should be called when the product is visible by the user in
|
|
275
|
+
* the viewport, as a visible DOM element.
|
|
276
|
+
* See {@link https://www.npmjs.com/package/react-intersection-observer react-intersection-observer} for a React component that can be used to detect when an element is in the viewport.
|
|
277
|
+
* @example
|
|
278
|
+
* ```jsx
|
|
279
|
+
* import { InView } from "react-intersection-observer";
|
|
280
|
+
*
|
|
281
|
+
* const Component = () => (
|
|
282
|
+
* <InView onChange={(inView) => {
|
|
283
|
+
* if(inView) {
|
|
284
|
+
* product.impress();
|
|
285
|
+
* }
|
|
286
|
+
* }}>
|
|
287
|
+
* <ProductCard />
|
|
288
|
+
* </InView>
|
|
289
|
+
* );
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
impress(): Promise<void>;
|
|
293
|
+
/**
|
|
294
|
+
* Converts the object in a JSON-serializable data structure that should be
|
|
295
|
+
* used **unmodified** in the constructor to create a new instance of this class.
|
|
296
|
+
* This method should be used in conjunction with `new SmartSortProduct()` to recreate the instance.
|
|
297
|
+
*
|
|
298
|
+
* This function is especially helpful in a server-side environment to
|
|
299
|
+
* keep track of the same instance across client side and server side
|
|
300
|
+
* rendered components.
|
|
301
|
+
* @example
|
|
302
|
+
* ```jsx
|
|
303
|
+
* let serializedObj = obj.serialize();
|
|
304
|
+
* let deserializedObj = new SmartSortProduct(serializedObj);
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
serialize(): SmartSortProductProps<ProductShape>;
|
|
308
|
+
/**
|
|
309
|
+
* Converts the object to a JSON string, using `serialize()` behind the
|
|
310
|
+
* scenes. The returned value should be used **unmodified** in the
|
|
311
|
+
* `SmartSortProduct.fromJSON()` static method.
|
|
312
|
+
* This method should be used in conjunction with `SmartSortProduct.fromJSON()` to recreate the instance.
|
|
313
|
+
*/
|
|
314
|
+
toJSON(): string;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Represents a configurable placement that can be used in
|
|
318
|
+
* different type of pages.
|
|
319
|
+
*
|
|
320
|
+
* In a server side context, this instance can be recreated over to the
|
|
321
|
+
* client by using the **unmodified** properties provided by the `serialize()`
|
|
322
|
+
* method.
|
|
323
|
+
*/
|
|
324
|
+
declare class SmartSort<ProductShape extends object = Record<string, unknown>> {
|
|
325
|
+
/**
|
|
326
|
+
* The custom images for the current instance. Always an array; empty when
|
|
327
|
+
* the placement returns no custom images.
|
|
328
|
+
*/
|
|
329
|
+
customImages: CustomImageData[];
|
|
330
|
+
/**
|
|
331
|
+
* The placement type of the current instance.
|
|
332
|
+
*/
|
|
333
|
+
placement?: Placement;
|
|
334
|
+
/**
|
|
335
|
+
* A mix of organic and sponsored products for this placement.
|
|
336
|
+
* @example
|
|
337
|
+
* ```jsx
|
|
338
|
+
* placement.products.map((product) => {
|
|
339
|
+
* return (<ProductCard
|
|
340
|
+
* product={product}
|
|
341
|
+
* onClick={() => product.click()}
|
|
342
|
+
* key={product.objectId}
|
|
343
|
+
* />);
|
|
344
|
+
* });
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
products: SmartSortProduct<ProductShape>[];
|
|
348
|
+
/**
|
|
349
|
+
* The row id of the placement.
|
|
350
|
+
*/
|
|
351
|
+
rowId?: number;
|
|
352
|
+
/**
|
|
353
|
+
* A map of search facets for this placement.
|
|
354
|
+
* @example
|
|
355
|
+
* ```json
|
|
356
|
+
* {
|
|
357
|
+
* "category": {
|
|
358
|
+
* "sativa": 20,
|
|
359
|
+
* "indica": 10,
|
|
360
|
+
* },
|
|
361
|
+
* "kind": {
|
|
362
|
+
* "flower": 31,
|
|
363
|
+
* "vape": 5,
|
|
364
|
+
* },
|
|
365
|
+
* }
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
searchFacets?: Record<string, Record<string, number>>;
|
|
369
|
+
/**
|
|
370
|
+
* The title of the placement.
|
|
371
|
+
*/
|
|
372
|
+
title: string | undefined;
|
|
373
|
+
/**
|
|
374
|
+
* The total number of products available for this placement.
|
|
375
|
+
*/
|
|
376
|
+
totalProducts: number;
|
|
377
|
+
/**
|
|
378
|
+
* Creative ids associated with the current request.
|
|
379
|
+
*
|
|
380
|
+
* @internal
|
|
381
|
+
*/
|
|
382
|
+
protected creativeIds: number[] | undefined;
|
|
383
|
+
private cachedProducts;
|
|
384
|
+
private config;
|
|
385
|
+
private loadPromise?;
|
|
386
|
+
private nextPageProps;
|
|
387
|
+
private nextPageUrl;
|
|
388
|
+
/**
|
|
389
|
+
* Builds a new SmartSort instance based on the provided properties.
|
|
390
|
+
*
|
|
391
|
+
* This method should be used in conjunction with `serialize()` to recreate the instance.
|
|
392
|
+
*/
|
|
393
|
+
constructor(props: SmartSortProps<ProductShape>);
|
|
394
|
+
/**
|
|
395
|
+
* Converts the previously-serialized object back to an instance of this class.
|
|
396
|
+
* This method should be used in conjunction with `toJSON()` to recreate the instance.
|
|
397
|
+
*/
|
|
398
|
+
static fromJSON<ProductShape extends object = Record<string, unknown>>(serialized: string): SmartSort<ProductShape>;
|
|
399
|
+
/**
|
|
400
|
+
* Boolean that indicates if more products are available for this placement.
|
|
401
|
+
*/
|
|
402
|
+
hasNextPage(): boolean;
|
|
403
|
+
/**
|
|
404
|
+
* Retrieves the next page of mixed organic and sponsored products for
|
|
405
|
+
* this placement.
|
|
406
|
+
*
|
|
407
|
+
* The `products` property will have the new products appended.
|
|
408
|
+
* @example
|
|
409
|
+
* ```jsx
|
|
410
|
+
* function ProductsList({ placement }) {
|
|
411
|
+
* let [hasMoreProducts, setHasMoreProducts] = useState(placement.hasNextPage());
|
|
412
|
+
* let [products, setProducts] = useState(placement.products);
|
|
413
|
+
*
|
|
414
|
+
* let loadMore = (async () => {
|
|
415
|
+
* await placement.nextPage();
|
|
416
|
+
* setHasMoreProducts(placement.hasNextPage());
|
|
417
|
+
* setProducts([...placement.products]);
|
|
418
|
+
* });
|
|
419
|
+
*
|
|
420
|
+
* return (
|
|
421
|
+
* <div>
|
|
422
|
+
* <button onclick={() => {loadMore()}} disabled={!hasMoreProducts}>Load more</button>
|
|
423
|
+
* <div>
|
|
424
|
+
* {products.map((product) => {
|
|
425
|
+
* return (<ProductCard
|
|
426
|
+
* product={product}
|
|
427
|
+
* onClick={() => product.click()}
|
|
428
|
+
* key={product.objectId}
|
|
429
|
+
* />);
|
|
430
|
+
* }}
|
|
431
|
+
* </div>
|
|
432
|
+
* </div>
|
|
433
|
+
* );
|
|
434
|
+
* }
|
|
435
|
+
* ```
|
|
436
|
+
*/
|
|
437
|
+
nextPage(): Promise<void>;
|
|
438
|
+
/**
|
|
439
|
+
* Triggers fingerprint collection and session event for the placement.
|
|
440
|
+
*
|
|
441
|
+
* **Note:** This method is called automatically when the placement is created on the client side,
|
|
442
|
+
* so manual calls are not necessary. It's safe to call multiple times due to built-in idempotency.
|
|
443
|
+
*
|
|
444
|
+
* @internal This is called automatically by the constructor. Manual calls are only needed for advanced use cases.
|
|
445
|
+
*/
|
|
446
|
+
onLoad(): Promise<void>;
|
|
447
|
+
/**
|
|
448
|
+
* Converts the object in a JSON-serializable data structure that should be
|
|
449
|
+
* used **unmodified** in the constructor to create a new instance of this class.
|
|
450
|
+
* This method should be used in conjunction with `new SmartSort()` to recreate the instance.
|
|
451
|
+
*
|
|
452
|
+
* This function is especially helpful in a server-side environment to
|
|
453
|
+
* keep track of the same instance across client side and server side
|
|
454
|
+
* rendered components.
|
|
455
|
+
* @example
|
|
456
|
+
* ```jsx
|
|
457
|
+
* let serializedObj = obj.serialize();
|
|
458
|
+
* let deserializedObj = new SmartSort(serializedObj);
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
serialize(): SmartSortProps<ProductShape>;
|
|
462
|
+
/**
|
|
463
|
+
* Converts the object to a JSON string, using `serialize()` behind the
|
|
464
|
+
* scenes. The returned value should be used **unmodified** in the
|
|
465
|
+
* `SmartSort.fromJSON()` static method.
|
|
466
|
+
* This method should be used in conjunction with `SmartSort.fromJSON()` to recreate the instance.
|
|
467
|
+
*/
|
|
468
|
+
toJSON(): string;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
type MultiPlacementResponse<ProductShape extends object = Record<string, unknown>> = BrandSpecials | SmartSort<ProductShape> | Specials;
|
|
472
|
+
declare class BrandSpecials {
|
|
473
|
+
placement: Placement.BrandSpecials;
|
|
474
|
+
title: string | undefined;
|
|
475
|
+
constructor(title: string | undefined);
|
|
476
|
+
}
|
|
477
|
+
declare class Specials {
|
|
478
|
+
placement: Placement.Specials;
|
|
479
|
+
title: string | undefined;
|
|
480
|
+
constructor(title: string | undefined);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Parameters to record attribution data for a checkout event.
|
|
485
|
+
*/
|
|
486
|
+
interface PosCheckoutParams {
|
|
487
|
+
/**
|
|
488
|
+
* The unique identifier for the order in the POS system.
|
|
489
|
+
*/
|
|
490
|
+
posOrderId: string;
|
|
491
|
+
/**
|
|
492
|
+
* The unique identifier for the authenticated user checking out in the
|
|
493
|
+
* POS system.
|
|
494
|
+
*/
|
|
495
|
+
posUserId?: string;
|
|
496
|
+
/**
|
|
497
|
+
* The products that were purchased at checkout.
|
|
498
|
+
*/
|
|
499
|
+
products: ConversionExternalProduct[];
|
|
500
|
+
/**
|
|
501
|
+
* The unique identifier for the store, according to the Jane ecosystem.
|
|
502
|
+
*/
|
|
503
|
+
storeId: number;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Parameters that represent events by the user in a given session.
|
|
508
|
+
*/
|
|
509
|
+
interface SessionEventParams {
|
|
510
|
+
/**
|
|
511
|
+
* Either events when user clicked to add a product to the cart or
|
|
512
|
+
* filtered for a category.
|
|
513
|
+
*/
|
|
514
|
+
events: SessionEvent[];
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
interface VirtualBudtenderSearchWithProductsResponse<ProductShape extends object = Record<string, unknown>> {
|
|
518
|
+
htmlResponse: string;
|
|
519
|
+
markdownResponse: string;
|
|
520
|
+
products: VirtualBudtenderProduct<ProductShape>[];
|
|
521
|
+
query: string;
|
|
522
|
+
totalResults: number;
|
|
523
|
+
unformattedResponse: string;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Represents a product returned from Virtual Budtender search.
|
|
527
|
+
* Provides tracking methods for click and impression events.
|
|
528
|
+
*
|
|
529
|
+
* @internal
|
|
530
|
+
*/
|
|
531
|
+
declare class VirtualBudtenderProduct<ProductShape extends object = Record<string, unknown>> {
|
|
532
|
+
/**
|
|
533
|
+
* The raw Virtual Budtender product data including search attributes and reasoning.
|
|
534
|
+
*/
|
|
535
|
+
attributes: ProductShape;
|
|
536
|
+
/**
|
|
537
|
+
* Boolean that indicates if a product is sponsored or not
|
|
538
|
+
*/
|
|
539
|
+
isSponsored: boolean;
|
|
540
|
+
/**
|
|
541
|
+
* The primary identifier for this product.
|
|
542
|
+
*/
|
|
543
|
+
objectId: string;
|
|
544
|
+
/**
|
|
545
|
+
* The reasoning for the product
|
|
546
|
+
*/
|
|
547
|
+
reasoning?: string;
|
|
548
|
+
/**
|
|
549
|
+
* The score of the product
|
|
550
|
+
*/
|
|
551
|
+
score?: number;
|
|
552
|
+
private clickPayload;
|
|
553
|
+
private clickUrl;
|
|
554
|
+
private hasBeenImpressed;
|
|
555
|
+
private impressPayload;
|
|
556
|
+
private impressPromise?;
|
|
557
|
+
private impressUrl;
|
|
558
|
+
/**
|
|
559
|
+
* Builds a new VirtualBudtenderProduct instance based on the provided properties.
|
|
560
|
+
* This method should be used in conjunction with `serialize()` to recreate the instance.
|
|
561
|
+
*/
|
|
562
|
+
constructor(props: VirtualBudtenderProductProps<ProductShape>);
|
|
563
|
+
/**
|
|
564
|
+
* Converts the previously-serialized object back to an instance of this class.
|
|
565
|
+
* This method should be used in conjunction with `toJSON()` to recreate the instance.
|
|
566
|
+
*/
|
|
567
|
+
static fromJSON<ProductShape extends object = Record<string, unknown>>(serialized: string): VirtualBudtenderProduct<ProductShape>;
|
|
568
|
+
/**
|
|
569
|
+
* Records attribution data for this product. This method
|
|
570
|
+
* should be called when the product is clicked by the user.
|
|
571
|
+
* If the click is associated with an add to cart action,
|
|
572
|
+
* that intent should be passed to the click method.
|
|
573
|
+
* @example
|
|
574
|
+
* ```jsx
|
|
575
|
+
* results.products.map((product) => {
|
|
576
|
+
* return (<ProductCard
|
|
577
|
+
* product={product}
|
|
578
|
+
* onClick={() => product.click()}
|
|
579
|
+
* key={product.objectId}
|
|
580
|
+
* >
|
|
581
|
+
* <Button
|
|
582
|
+
* title="Add to Cart"
|
|
583
|
+
* onClick={() => product.click({isAddToCart: true})}
|
|
584
|
+
* />
|
|
585
|
+
* </ProductCard>);
|
|
586
|
+
* });
|
|
587
|
+
* ```
|
|
588
|
+
*/
|
|
589
|
+
click(props?: VirtualBudtenderClickIntent): Promise<void>;
|
|
590
|
+
/**
|
|
591
|
+
* Records attribution data for this product. This method
|
|
592
|
+
* should be called when the product is visible by the user in
|
|
593
|
+
* the viewport, as a visible DOM element.
|
|
594
|
+
* See {@link https://www.npmjs.com/package/react-intersection-observer react-intersection-observer} for a React component that can be used to detect when an element is in the viewport.
|
|
595
|
+
* @example
|
|
596
|
+
* ```jsx
|
|
597
|
+
* import { InView } from "react-intersection-observer";
|
|
598
|
+
*
|
|
599
|
+
* const Component = () => (
|
|
600
|
+
* <InView onChange={(inView) => {
|
|
601
|
+
* if(inView) {
|
|
602
|
+
* product.impress();
|
|
603
|
+
* }
|
|
604
|
+
* }}>
|
|
605
|
+
* <ProductCard />
|
|
606
|
+
* </InView>
|
|
607
|
+
* );
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
impress(): Promise<void>;
|
|
611
|
+
/**
|
|
612
|
+
* Serializes the instance to a plain object for storage or transport.
|
|
613
|
+
* This method should be used in conjunction with `fromJSON()` to recreate the instance.
|
|
614
|
+
*/
|
|
615
|
+
serialize(): VirtualBudtenderProductProps<ProductShape>;
|
|
616
|
+
/**
|
|
617
|
+
* Converts the instance to a JSON string for storage or transport.
|
|
618
|
+
* This method should be used in conjunction with `fromJSON()` to recreate the instance.
|
|
619
|
+
*/
|
|
620
|
+
toJSON(): string;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
type Func<T> = () => Promise<T>;
|
|
624
|
+
/**
|
|
625
|
+
* Generic Cell Rate Algorithm (GCRA) rate limiter implementation.
|
|
626
|
+
*
|
|
627
|
+
* Provides smooth rate limiting with burst capacity, allowing temporary spikes
|
|
628
|
+
* in traffic while maintaining an average rate limit over time. Unlike simple
|
|
629
|
+
* token bucket algorithms, GCRA provides more predictable and smoother rate limiting.
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```typescript
|
|
633
|
+
* // Allow 10 requests per second with a burst of 3
|
|
634
|
+
* const limiter = new GcraRateLimiter(10, 3);
|
|
635
|
+
*
|
|
636
|
+
* // First 3 calls execute immediately (burst capacity)
|
|
637
|
+
* await limiter.schedule(() => apiCall1());
|
|
638
|
+
* await limiter.schedule(() => apiCall2());
|
|
639
|
+
* await limiter.schedule(() => apiCall3());
|
|
640
|
+
*
|
|
641
|
+
* // 4th call waits ~100ms to maintain 10 req/sec rate
|
|
642
|
+
* await limiter.schedule(() => apiCall4());
|
|
643
|
+
* ```
|
|
644
|
+
*
|
|
645
|
+
* @example
|
|
646
|
+
* ```typescript
|
|
647
|
+
* // Conservative rate limiting: 1 request per second, no burst
|
|
648
|
+
* const conservativeLimiter = new GcraRateLimiter(1, 1);
|
|
649
|
+
*
|
|
650
|
+
* await conservativeLimiter.schedule(() => slowApiCall1()); // immediate
|
|
651
|
+
* await conservativeLimiter.schedule(() => slowApiCall2()); // waits 1000ms
|
|
652
|
+
* ```
|
|
653
|
+
*/
|
|
654
|
+
declare class GcraRateLimiter {
|
|
655
|
+
/** Maximum number of requests that can be made in a burst */
|
|
656
|
+
private burst;
|
|
657
|
+
/** Time interval between requests in milliseconds */
|
|
658
|
+
private intervalMs;
|
|
659
|
+
/** Maximum requests per second */
|
|
660
|
+
private rate;
|
|
661
|
+
/** Theoretical arrival time in milliseconds - tracks when next request should ideally arrive */
|
|
662
|
+
private tat;
|
|
663
|
+
/** Burst window tolerance in milliseconds - how much early arrival is allowed */
|
|
664
|
+
private toleranceMs;
|
|
665
|
+
/**
|
|
666
|
+
* Creates a new GCRA rate limiter.
|
|
667
|
+
*
|
|
668
|
+
* @param rate - Maximum number of requests per second (must be > 0)
|
|
669
|
+
* @param burst - Maximum number of requests that can be made immediately without waiting (default: 1, must be >= 1)
|
|
670
|
+
*
|
|
671
|
+
* @throws {SdkError} When rate <= 0
|
|
672
|
+
* @throws {SdkError} When burst < 1
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* ```typescript
|
|
676
|
+
* // 5 requests per second, burst of 2
|
|
677
|
+
* const limiter = new GcraRateLimiter(5, 2);
|
|
678
|
+
* ```
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```typescript
|
|
682
|
+
* // 0.5 requests per second (one every 2 seconds), no burst
|
|
683
|
+
* const slowLimiter = new GcraRateLimiter(0.5, 1);
|
|
684
|
+
* ```
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```typescript
|
|
688
|
+
* // 20 requests per second, burst of 20
|
|
689
|
+
* const limiter = new GcraRateLimiter(20, 20);
|
|
690
|
+
* ```
|
|
691
|
+
*/
|
|
692
|
+
constructor(rate: number, burst?: number);
|
|
693
|
+
/**
|
|
694
|
+
* Schedules a function to be executed under rate limiting constraints.
|
|
695
|
+
*
|
|
696
|
+
* The function will either execute immediately (if within rate limits) or be
|
|
697
|
+
* delayed until the rate limit allows execution. The delay is calculated using
|
|
698
|
+
* the GCRA algorithm to maintain smooth, predictable rate limiting.
|
|
699
|
+
*
|
|
700
|
+
* @template T - The return type of the scheduled function
|
|
701
|
+
* @param fn - The function to execute. Must return a Promise.
|
|
702
|
+
* @returns Promise that resolves with the function's result after rate limiting
|
|
703
|
+
*
|
|
704
|
+
* @example
|
|
705
|
+
* ```typescript
|
|
706
|
+
* const limiter = new GcraRateLimiter(2, 1); // 2 req/sec, no burst
|
|
707
|
+
*
|
|
708
|
+
* // First call executes immediately
|
|
709
|
+
* const result1 = await limiter.schedule(async () => {
|
|
710
|
+
* const response = await fetch('/api/data');
|
|
711
|
+
* return response.json();
|
|
712
|
+
* });
|
|
713
|
+
*
|
|
714
|
+
* // Second call waits 500ms before executing
|
|
715
|
+
* const result2 = await limiter.schedule(async () => {
|
|
716
|
+
* return await someAsyncOperation();
|
|
717
|
+
* });
|
|
718
|
+
* ```
|
|
719
|
+
*
|
|
720
|
+
* @example
|
|
721
|
+
* ```typescript
|
|
722
|
+
* // 20 requests per second, burst of 20
|
|
723
|
+
* const limiter = new GcraRateLimiter(20, 20);
|
|
724
|
+
*
|
|
725
|
+
*
|
|
726
|
+
* // First 20 calls execute immediately (burst capacity)
|
|
727
|
+
* await limiter.schedule(async () => {
|
|
728
|
+
* return await someAsyncOperation();
|
|
729
|
+
* });
|
|
730
|
+
*
|
|
731
|
+
* // 21st call waits ~100ms to maintain 20 req/sec rate
|
|
732
|
+
* await limiter.schedule(async () => {
|
|
733
|
+
* return await someAsyncOperation();
|
|
734
|
+
* });
|
|
735
|
+
* ```
|
|
736
|
+
*
|
|
737
|
+
* @example
|
|
738
|
+
* ```typescript
|
|
739
|
+
* // Error handling
|
|
740
|
+
* try {
|
|
741
|
+
* const result = await limiter.schedule(async () => {
|
|
742
|
+
* throw new Error('API failed');
|
|
743
|
+
* });
|
|
744
|
+
* } catch (error) {
|
|
745
|
+
* console.error('Scheduled function failed:', error);
|
|
746
|
+
* }
|
|
747
|
+
* ```
|
|
748
|
+
*/
|
|
749
|
+
schedule<T>(fn: Func<T>): Promise<T>;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* JaneDM is the main class that is used to interact with the Jane DM API.
|
|
754
|
+
* An instance is required to fetch ads and send checkout events.
|
|
755
|
+
* This is the **entry point for the Jane DM SDK.**
|
|
756
|
+
* @example
|
|
757
|
+
* ```jsx
|
|
758
|
+
* // Create instance - initialization happens automatically on first fetch
|
|
759
|
+
* let client = new JaneDM({
|
|
760
|
+
* apiKey: 'your-api-key',
|
|
761
|
+
* endpoint: 'https://dmerch.iheartjane.com',
|
|
762
|
+
* identifier: { jdid: 'your-jdid', userId: 'your-user-id' },
|
|
763
|
+
* });
|
|
764
|
+
*
|
|
765
|
+
* // Or manually initialize if needed
|
|
766
|
+
* await client.init();
|
|
767
|
+
*
|
|
768
|
+
* function MenuTopRowComponent({ placement }) {
|
|
769
|
+
* // Fingerprint collection and session events happen automatically when
|
|
770
|
+
* // the placement is created - no manual calls needed
|
|
771
|
+
*
|
|
772
|
+
* return (<div>...</div>);
|
|
773
|
+
* }
|
|
774
|
+
*
|
|
775
|
+
* // init() is called automatically before the first fetch operation
|
|
776
|
+
* let placement = await client.fetchMenuTopRow({ storeId: 420 });
|
|
777
|
+
*
|
|
778
|
+
* <MenuTopRowComponent placement={placement} />
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
declare class JaneDM {
|
|
782
|
+
protected readonly config: RequiredConfig;
|
|
783
|
+
/**
|
|
784
|
+
* 20 requests per second, burst of 20
|
|
785
|
+
*
|
|
786
|
+
* DM Server rate is 40 requests per second, burst of 40
|
|
787
|
+
*/
|
|
788
|
+
protected readonly rateLimiter: GcraRateLimiter;
|
|
789
|
+
private initialized;
|
|
790
|
+
private readonly multiClient;
|
|
791
|
+
private readonly productClient;
|
|
792
|
+
private readonly smartSortClient;
|
|
793
|
+
private userProvidedJdid;
|
|
794
|
+
/**
|
|
795
|
+
* Creates an instance of the Jane DM SDK client.
|
|
796
|
+
*
|
|
797
|
+
* @param props - Public configuration options for the Jane DM SDK client.
|
|
798
|
+
* @param internalConfig - Internal configuration options for the Jane DM SDK client. **DO NOT MODIFY INTERNAL CONFIGURATION OPTIONS. Unexpected behavior will result.**
|
|
799
|
+
* Internal configuration options are experimental and may change in the future.
|
|
800
|
+
*/
|
|
801
|
+
constructor(props: JaneDMPublicConfig, internalConfig?: JaneDMInternalConfig);
|
|
802
|
+
/**
|
|
803
|
+
* Function used to generate a valid jane device id. This function is
|
|
804
|
+
* intended to be used upon initial setup in a SSR environment & stored in a cookie
|
|
805
|
+
*/
|
|
806
|
+
static generateJaneDeviceId(): string;
|
|
807
|
+
/**
|
|
808
|
+
* Fetches a cart topper row placement from the Jane DM API. This
|
|
809
|
+
* placement represents a row of sponsored and organic products to be
|
|
810
|
+
* displayed in the cart page.
|
|
811
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
812
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
813
|
+
* because it has a very short lifecycle.
|
|
814
|
+
* @example
|
|
815
|
+
* ```jsx
|
|
816
|
+
* let placement = await client.fetchCartTopperRow({
|
|
817
|
+
* // Required
|
|
818
|
+
* storeId: 420,
|
|
819
|
+
* // Required
|
|
820
|
+
* searchAttributes: ['product_id', 'name'],
|
|
821
|
+
* // Required
|
|
822
|
+
* cartProductIds: [123, 456],
|
|
823
|
+
* });
|
|
824
|
+
* ```
|
|
825
|
+
*/
|
|
826
|
+
fetchCartTopperRow<ProductShape extends object = Record<string, unknown>>(props: FetchCartTopperRowProps): Promise<SmartSort<ProductShape>>;
|
|
827
|
+
/**
|
|
828
|
+
* Fetches a custom image row placement from the Jane DM API. This
|
|
829
|
+
* placement represents a row of custom images to be displayed alongside
|
|
830
|
+
* lists or grids of products. The returned placement exposes the custom
|
|
831
|
+
* images through {@link SmartSort.customImages}.
|
|
832
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
833
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
834
|
+
* because it has a very short lifecycle.
|
|
835
|
+
* @internal
|
|
836
|
+
* @example
|
|
837
|
+
* ```jsx
|
|
838
|
+
* let placement = await client.fetchCustomImageRow({
|
|
839
|
+
* // Required
|
|
840
|
+
* storeId: 420,
|
|
841
|
+
* searchAttributes: ['product_id', 'name'],
|
|
842
|
+
* searchFilter: 'kind:flower',
|
|
843
|
+
* });
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
846
|
+
fetchCustomImageRow<ProductShape extends object = Record<string, unknown>>(props: FetchCustomImageRowProps): Promise<SmartSort<ProductShape>>;
|
|
847
|
+
/**
|
|
848
|
+
* Fetches a custom set of placements for the featured page for any given store.
|
|
849
|
+
*
|
|
850
|
+
* @example
|
|
851
|
+
* ```jsx
|
|
852
|
+
* const placements = await client.fetchCustomPlacements({
|
|
853
|
+
* storeId: 420,
|
|
854
|
+
* searchAttributes: ['product_id', 'name'],
|
|
855
|
+
* });
|
|
856
|
+
* ```
|
|
857
|
+
*/
|
|
858
|
+
fetchCustomPlacements<ProductShape extends object = Record<string, unknown>>(props: FetchCustomPlacementsProps): Promise<MultiPlacementResponse<ProductShape>[]>;
|
|
859
|
+
/**
|
|
860
|
+
* Fetches facets from the Jane DM API.
|
|
861
|
+
* This method gets facet information that can be used for filtering products.
|
|
862
|
+
* @example
|
|
863
|
+
* ```jsx
|
|
864
|
+
* const facets = await client.fetchFacets({
|
|
865
|
+
* storeId: 420,
|
|
866
|
+
* searchFilter: 'kind:flower',
|
|
867
|
+
* searchFacets: ['kind', 'category'],
|
|
868
|
+
* });
|
|
869
|
+
*
|
|
870
|
+
* console.log(facets.search_facets);
|
|
871
|
+
* ```
|
|
872
|
+
*/
|
|
873
|
+
fetchFacets(props: FetchFacetsParams): Promise<Facets>;
|
|
874
|
+
/**
|
|
875
|
+
* Fetches featured placements from the Jane DM API. This method returns
|
|
876
|
+
* a list of placements that should be displayed on the featured page of any given store's menu
|
|
877
|
+
*
|
|
878
|
+
* @example
|
|
879
|
+
* ```jsx
|
|
880
|
+
* const placements = await client.fetchFeaturedPlacements({
|
|
881
|
+
* storeId: 420,
|
|
882
|
+
* searchAttributes: ['product_id', 'name'],
|
|
883
|
+
* });
|
|
884
|
+
* ```
|
|
885
|
+
*/
|
|
886
|
+
fetchFeaturedPlacements<ProductShape extends object = Record<string, unknown>>(props: FetchFeaturedPlacementProps): Promise<MultiPlacementResponse<ProductShape>[]>;
|
|
887
|
+
/**
|
|
888
|
+
* Fetches a menu row placement from the Jane DM API. This placement
|
|
889
|
+
* represents a row of products to be displayed on a page displaying lists of products.
|
|
890
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
891
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
892
|
+
* because it has a very short lifecycle.
|
|
893
|
+
* @internal
|
|
894
|
+
* @example
|
|
895
|
+
* ```jsx
|
|
896
|
+
* let placement = await client.fetchMenuRow({
|
|
897
|
+
* // Required
|
|
898
|
+
* storeId: 420,
|
|
899
|
+
* searchAttributes: ['product_id', 'name'],
|
|
900
|
+
* searchFilter: 'kind:flower',
|
|
901
|
+
* });
|
|
902
|
+
* ```
|
|
903
|
+
*/
|
|
904
|
+
fetchMenuRow<ProductShape extends object = Record<string, unknown>>(props: FetchMenuRowProps): Promise<SmartSort<ProductShape>>;
|
|
905
|
+
/**
|
|
906
|
+
* Fetches a top of menu row placement from the Jane DM API. This
|
|
907
|
+
* placement represents a row of sponsored products to be displayed at
|
|
908
|
+
* the top of the page displaying lists or grids of products.
|
|
909
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
910
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
911
|
+
* because it has a very short lifecycle.
|
|
912
|
+
*
|
|
913
|
+
* @example
|
|
914
|
+
* ```jsx
|
|
915
|
+
* let placement = await client.fetchMenuTopRow({
|
|
916
|
+
* // Required
|
|
917
|
+
* storeId: 420,
|
|
918
|
+
* searchAttributes: ['product_id', 'name'],
|
|
919
|
+
* searchFilter: 'kind:flower',
|
|
920
|
+
* });
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
923
|
+
fetchMenuTopRow<ProductShape extends object = Record<string, unknown>, AdditionalTypes = object>(props: FetchMenuTopRowProps<AdditionalTypes>): Promise<SmartSort<ProductShape>>;
|
|
924
|
+
/**
|
|
925
|
+
* Fetches a product from the Jane DM API. This method returns a product object that can be used to display product details.
|
|
926
|
+
* @example
|
|
927
|
+
* ```jsx
|
|
928
|
+
* const product = await client.fetchProduct({
|
|
929
|
+
* // Required
|
|
930
|
+
* storeId: 420,
|
|
931
|
+
* // Required
|
|
932
|
+
* searchAttributes: ['product_id', 'name'],
|
|
933
|
+
* // Required one of, but not both
|
|
934
|
+
* productId: 1234,
|
|
935
|
+
* posProductId: '1234',
|
|
936
|
+
* });
|
|
937
|
+
* ```
|
|
938
|
+
*/
|
|
939
|
+
fetchProduct<ProductShape extends object = Record<string, unknown>>(props: FetchProductProps): Promise<SmartSortProduct<ProductShape>>;
|
|
940
|
+
/**
|
|
941
|
+
* Fetches one page of product reviews from the Jane DM API. Returns
|
|
942
|
+
* individual reviews, pagination metadata, and aggregate rating data.
|
|
943
|
+
* Supports filtering by activities, feelings, and ratings.
|
|
944
|
+
*
|
|
945
|
+
* Use this method for UIs that paginate with page numbers, next/prev
|
|
946
|
+
* buttons, or infinite scroll. For server-side scenarios that need to
|
|
947
|
+
* traverse every matching review, prefer {@link JaneDM.iterateProductReviews}.
|
|
948
|
+
*
|
|
949
|
+
* @see {@link ProductReviewsResponse} for the full response shape.
|
|
950
|
+
* @see [Pagination guide](https://dm-sdk-docs.iheartjane.com/app/pagination).
|
|
951
|
+
*
|
|
952
|
+
* @example Traditional pagination
|
|
953
|
+
* ```tsx
|
|
954
|
+
* const response = await client.fetchProductReviews({
|
|
955
|
+
* productId: 123,
|
|
956
|
+
* page: 1,
|
|
957
|
+
* pageSize: 20,
|
|
958
|
+
* ratings: [4, 5],
|
|
959
|
+
* });
|
|
960
|
+
*
|
|
961
|
+
* response.items; // ProductReview[]
|
|
962
|
+
* response.pagination.totalPages; // number of pages available
|
|
963
|
+
* response.pagination.hasNextPage; // boolean
|
|
964
|
+
* response.aggregate.averageRating; // number
|
|
965
|
+
* ```
|
|
966
|
+
*
|
|
967
|
+
* @example Next/prev navigation
|
|
968
|
+
* ```tsx
|
|
969
|
+
* <button disabled={!response.pagination.hasPreviousPage}>Prev</button>
|
|
970
|
+
* <button disabled={!response.pagination.hasNextPage}>Next</button>
|
|
971
|
+
* ```
|
|
972
|
+
*/
|
|
973
|
+
fetchProductReviews(props: FetchProductReviewsProps): Promise<ProductReviewsResponse>;
|
|
974
|
+
/**
|
|
975
|
+
* Fetches a recommended PDP row placement from the Jane DM API. This
|
|
976
|
+
* placement represents a row of sponsored products to be displayed in a
|
|
977
|
+
* product's details page.
|
|
978
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
979
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
980
|
+
* because it has a very short lifecycle.
|
|
981
|
+
* @example
|
|
982
|
+
* ```jsx
|
|
983
|
+
* let placement = await client.fetchRecommendedPDPRow({
|
|
984
|
+
* // Required
|
|
985
|
+
* storeId: 420,
|
|
986
|
+
* // Required one of, but not both
|
|
987
|
+
* productId: 420,
|
|
988
|
+
* posProductId: '420',
|
|
989
|
+
* searchAttributes: ['product_id', 'name'],
|
|
990
|
+
* });
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
fetchRecommendedPDPRow<ProductShape extends object = Record<string, unknown>>(props: FetchRecommendedPDPRowProps): Promise<SmartSort<ProductShape>>;
|
|
994
|
+
/**
|
|
995
|
+
* Fetches a recommended row placement from the Jane DM API. This
|
|
996
|
+
* placement represents a row of recommended organic and sponsored
|
|
997
|
+
* products to be displayed in any kind of page.
|
|
998
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
999
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
1000
|
+
* because it has a very short lifecycle.
|
|
1001
|
+
* @example
|
|
1002
|
+
* ```jsx
|
|
1003
|
+
* let placement = await client.fetchRecommendedRow({
|
|
1004
|
+
* // Required
|
|
1005
|
+
* storeId: 420,
|
|
1006
|
+
* searchAttributes: ['product_id', 'name'],
|
|
1007
|
+
* });
|
|
1008
|
+
* ```
|
|
1009
|
+
*/
|
|
1010
|
+
fetchRecommendedRow<ProductShape extends object = Record<string, unknown>>(props: FetchRecommendedRowProps): Promise<SmartSort<ProductShape>>;
|
|
1011
|
+
/**
|
|
1012
|
+
* Fetches a recommended sort placement from the Jane DM API. This
|
|
1013
|
+
* placement represents a list of mixed organic and sponsored products,
|
|
1014
|
+
* sorted according to user's recommendations, to be used when sorting
|
|
1015
|
+
* lists of products on your pages.
|
|
1016
|
+
* A placement can be serialized to and from JSON for the purpose of
|
|
1017
|
+
* server-side rendering, the serialized object **should not be persisted**
|
|
1018
|
+
* because it has a very short lifecycle.
|
|
1019
|
+
* @example
|
|
1020
|
+
* ```jsx
|
|
1021
|
+
* let placement = await client.fetchRecommendedSort({
|
|
1022
|
+
* // Required
|
|
1023
|
+
* storeId: 420,
|
|
1024
|
+
* // Required
|
|
1025
|
+
* searchSort: 'recommendation',
|
|
1026
|
+
* disableAds: false,
|
|
1027
|
+
* maxProducts: 10,
|
|
1028
|
+
* numColumns: 5,
|
|
1029
|
+
* pageSize: 10,
|
|
1030
|
+
* searchAttributes: ['product_id', 'name'],
|
|
1031
|
+
* searchFacets: ['kind'],
|
|
1032
|
+
* searchFilter: 'kind:flower',
|
|
1033
|
+
* searchQuery: '',
|
|
1034
|
+
* });
|
|
1035
|
+
* ```
|
|
1036
|
+
*/
|
|
1037
|
+
fetchRecommendedSort<ProductShape extends object = Record<string, unknown>>(props: FetchRecommendedSortProps): Promise<SmartSort<ProductShape>>;
|
|
1038
|
+
/**
|
|
1039
|
+
* Fetches virtual budtender query suggestions from the Jane DM API.
|
|
1040
|
+
* Returns curated queries optimized for natural language product search.
|
|
1041
|
+
* @internal
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```jsx
|
|
1044
|
+
* const queries = await client.fetchVirtualBudtenderQueries({
|
|
1045
|
+
* storeId: 420,
|
|
1046
|
+
* });
|
|
1047
|
+
*
|
|
1048
|
+
* console.log(queries); // [{ query: "help me sleep", displayText: "Help me sleep" }, ...]
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
1051
|
+
fetchVirtualBudtenderQueries(props: VirtualBudtenderQueriesParams): Promise<VirtualBudtenderQuery[]>;
|
|
1052
|
+
/**
|
|
1053
|
+
* Performs natural language product search using Virtual Budtender AI.
|
|
1054
|
+
* Returns personalized product recommendations with AI-generated explanations
|
|
1055
|
+
* and integrates sponsored products when relevant to the query.
|
|
1056
|
+
* @internal
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```jsx
|
|
1059
|
+
* const result = await client.fetchVirtualBudtenderSearch({
|
|
1060
|
+
* query: "help me sleep",
|
|
1061
|
+
* storeId: 420,
|
|
1062
|
+
* });
|
|
1063
|
+
*
|
|
1064
|
+
* console.log(result.markdownResponse); // AI-generated response
|
|
1065
|
+
* console.log(result.products); // Array of VirtualBudtenderProduct instances
|
|
1066
|
+
*
|
|
1067
|
+
* // Each product has click and impression tracking
|
|
1068
|
+
* result.products.forEach(product => {
|
|
1069
|
+
* console.log(product.attributes.reasoning); // AI reasoning
|
|
1070
|
+
* console.log(product.isSponsored); // Sponsored status
|
|
1071
|
+
* });
|
|
1072
|
+
* ```
|
|
1073
|
+
*/
|
|
1074
|
+
fetchVirtualBudtenderSearch<ProductShape extends object = Record<string, unknown>>(props: VirtualBudtenderSearchParams): Promise<VirtualBudtenderSearchWithProductsResponse<ProductShape>>;
|
|
1075
|
+
/**
|
|
1076
|
+
* Retrieves the configured JDID for the client.
|
|
1077
|
+
*/
|
|
1078
|
+
getJaneDeviceId(): string;
|
|
1079
|
+
/**
|
|
1080
|
+
* Initializes the SDK with async operations.
|
|
1081
|
+
* This method is automatically called before any fetch operations if not already initialized.
|
|
1082
|
+
* You can also call it explicitly for immediate initialization.
|
|
1083
|
+
* @example
|
|
1084
|
+
* ```jsx
|
|
1085
|
+
* const client = new JaneDM({ apiKey: 'your-api-key' });
|
|
1086
|
+
* await client.init(); // Optional - will be called automatically on first fetch
|
|
1087
|
+
* ```
|
|
1088
|
+
*/
|
|
1089
|
+
init(): Promise<void>;
|
|
1090
|
+
/**
|
|
1091
|
+
* Returns an async iterable over every review matching the given
|
|
1092
|
+
* filters. The iterator fetches pages lazily, one HTTP request per
|
|
1093
|
+
* page. It yields individual reviews by default; use the `.pages`
|
|
1094
|
+
* property to yield whole page envelopes instead (useful when you
|
|
1095
|
+
* need access to `pagination` or `aggregate` during traversal).
|
|
1096
|
+
*
|
|
1097
|
+
* The underlying API is page-indexed; the iterator always starts at
|
|
1098
|
+
* page 1 and advances until the server reports no more pages.
|
|
1099
|
+
*
|
|
1100
|
+
* For UIs that paginate, use {@link JaneDM.fetchProductReviews} instead.
|
|
1101
|
+
*
|
|
1102
|
+
* @see {@link ProductReviewsIterable} for the return shape.
|
|
1103
|
+
* @see [Pagination guide](https://dm-sdk-docs.iheartjane.com/app/pagination).
|
|
1104
|
+
*
|
|
1105
|
+
* @example Collect every 5-star review for a product
|
|
1106
|
+
* ```ts
|
|
1107
|
+
* const reviews: ProductReview[] = [];
|
|
1108
|
+
* for await (const review of client.iterateProductReviews({
|
|
1109
|
+
* productId: 123,
|
|
1110
|
+
* ratings: [5],
|
|
1111
|
+
* })) {
|
|
1112
|
+
* reviews.push(review);
|
|
1113
|
+
* }
|
|
1114
|
+
* ```
|
|
1115
|
+
*
|
|
1116
|
+
* @example Iterate page-by-page
|
|
1117
|
+
* ```ts
|
|
1118
|
+
* for await (const page of client.iterateProductReviews({ productId: 123 }).pages) {
|
|
1119
|
+
* console.log(
|
|
1120
|
+
* `Page ${page.pagination.currentPage}/${page.pagination.totalPages}`,
|
|
1121
|
+
* `avg rating: ${page.aggregate.averageRating}`,
|
|
1122
|
+
* );
|
|
1123
|
+
* }
|
|
1124
|
+
* ```
|
|
1125
|
+
*/
|
|
1126
|
+
iterateProductReviews(props: IterateProductReviewsProps): ProductReviewsIterable;
|
|
1127
|
+
/**
|
|
1128
|
+
* Signals the Jane DM API that a checkout event has happened.
|
|
1129
|
+
* This method should be called when a user has completed a purchase to
|
|
1130
|
+
* record attribution data for conversions.
|
|
1131
|
+
* It is preferable to call this method from the server-side to avoid
|
|
1132
|
+
* race conditions.
|
|
1133
|
+
* @example
|
|
1134
|
+
* ```jsx
|
|
1135
|
+
* await client.sendPosCheckout({
|
|
1136
|
+
* storeId: 420,
|
|
1137
|
+
* posOrderId: 'some-pos-order-id',
|
|
1138
|
+
* posUserId: 'some-pos-user-id',
|
|
1139
|
+
* products: [
|
|
1140
|
+
* {
|
|
1141
|
+
* posProductId: 'some-pos-product-id',
|
|
1142
|
+
* price: 10.99,
|
|
1143
|
+
* quantity: 1,
|
|
1144
|
+
* },
|
|
1145
|
+
* ],
|
|
1146
|
+
* });
|
|
1147
|
+
* ```
|
|
1148
|
+
*/
|
|
1149
|
+
sendPosCheckout(props: PosCheckoutParams): Promise<void>;
|
|
1150
|
+
/**
|
|
1151
|
+
* Signals the Jane DM API that session events happened.
|
|
1152
|
+
* This method should be called when a user clicked to add a product
|
|
1153
|
+
* to the cart or filtered a category.
|
|
1154
|
+
* @example
|
|
1155
|
+
* ```jsx
|
|
1156
|
+
* await client.sendSessionEvent({
|
|
1157
|
+
* events: [
|
|
1158
|
+
* {
|
|
1159
|
+
* type: 'clickedAddToCart',
|
|
1160
|
+
* posProductId: 'some-pos-product-id',
|
|
1161
|
+
* storeId: 420,
|
|
1162
|
+
* },
|
|
1163
|
+
* {
|
|
1164
|
+
* type: 'clickedAddToCart',
|
|
1165
|
+
* productId: 1234,
|
|
1166
|
+
* storeId: 420,
|
|
1167
|
+
* },
|
|
1168
|
+
* {
|
|
1169
|
+
* type: 'filteredCategory',
|
|
1170
|
+
* category: SessionEventCategory.Extract,
|
|
1171
|
+
* storeId: 420,
|
|
1172
|
+
* },
|
|
1173
|
+
* ],
|
|
1174
|
+
* });
|
|
1175
|
+
* ```
|
|
1176
|
+
*/
|
|
1177
|
+
sendSessionEvent(props: SessionEventParams): Promise<void>;
|
|
1178
|
+
private initializeClientSideJdid;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
export { AdMode, BrandSpecials, ConversionExternalProduct, CustomImageData, Facets, FetchCartTopperRowProps, FetchCustomImageRowProps, type FetchCustomPlacementsProps, type FetchFacetsParams, type FetchFeaturedPlacementProps, FetchMenuRowProps, FetchMenuTopRowProps, FetchProductReviewsProps, FetchRecommendedPDPRowProps, FetchRecommendedRowProps, FetchRecommendedSortProps, IterateProductReviewsProps, JaneDM, type MultiPlacementResponse, PageContextEnum, Placement, type PosCheckoutParams, ProductReviewsIterable, ProductReviewsResponse, SearchSortEnum, type SessionEventParams, SmartSort, SmartSortClickIntent, SmartSortProduct, SmartSortProductProps, SmartSortProps, Specials, type VirtualBudtenderClickIntent, VirtualBudtenderProduct, VirtualBudtenderQuery };
|