@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.
@@ -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 };