@depict-ai/react-ui 0.0.105 → 1.0.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/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { BaseProductListingConfig, BaseProviderConfig, BaseSearchProviderConfig, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholderProps, TextPlaceholderProps } from "@depict-ai/ui";
1
+ import { BaseProductListingConfig, BaseProviderConfig, BaseSearchProviderConfig, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholderProps, TextPlaceholderProps, fetchDepictRecommendations, ExclusiveId } from "@depict-ai/ui";
2
2
  import { Display } from "@depict-ai/utilishared";
3
3
  import React, { ReactNode, PropsWithChildren, ReactElement } from "react";
4
+ import { DPC } from "@depict-ai/dpc";
4
5
  import { Locale } from "@depict-ai/ui/locales";
5
- export const version = "0.0.105";
6
+ export const version = "1.0.1";
6
7
  interface PLPConfig<T extends Display> extends BaseProductListingConfig {
7
8
  /**
8
9
  * The product card to use for rendering products.
@@ -20,6 +21,32 @@ export interface DepictProductCardProps<T extends Display> {
20
21
  * Depict product card to use for rendering products.
21
22
  */
22
23
  export type DepictProductCard<T extends Display> = (props: DepictProductCardProps<T>) => ReactNode;
24
+ interface UsePerformanceClientReturn {
25
+ dpc: DPC;
26
+ }
27
+ /**
28
+ * Hook used to access the Depict Performance Client.
29
+ * Calls on the returned DPC instance can not be done server side.
30
+ * @example
31
+ * Send an add-to-cart event
32
+ * ```tsx
33
+ * import { useEffect } from "react";
34
+ * import { usePerformanceClient } from "@depict-ai/react-ui";
35
+ *
36
+ * const ProductPage = ({ productId }) => {
37
+ * const { dpc } = usePerformanceClient();
38
+ *
39
+ * useEffect(() => {
40
+ * dpc.setProductId(productId);
41
+ * }, [dpc, productId]);
42
+ *
43
+ * return <div>Showing product {productId}</div>;
44
+ * }
45
+ * ```
46
+ * @returns {UsePerformanceClientReturn}
47
+ }
48
+ */
49
+ export const usePerformanceClient: () => UsePerformanceClientReturn;
23
50
  /**
24
51
  * relativeUrl: The relative url to navigate to.
25
52
  * replace: Whether to replace the current url or push a new one.
@@ -322,7 +349,7 @@ interface UseSearchModalReturn {
322
349
  * );
323
350
  * };
324
351
  * ```
325
- * @returns {JSX.Element}
352
+ * @returns {UseSearchModalReturn}
326
353
  */
327
354
  export function useSearchModal(params?: UseSearchModalParams): UseSearchModalReturn;
328
355
  interface SearchFieldProps {
@@ -380,14 +407,83 @@ interface UseSearchFieldReturn {
380
407
  * );
381
408
  * };
382
409
  * ```
383
- * @returns {JSX.Element}
410
+ * @returns {UseSearchFieldReturn}
384
411
  */
385
412
  export const useSearchField: (props?: SearchFieldProps) => UseSearchFieldReturn;
413
+ type FetchRecsOptions = Omit<Parameters<typeof fetchDepictRecommendations>[0], "merchant" | "market" | "userId" | "sessionId"> & ExclusiveId;
414
+ interface UseFetchRecommendationsReturn<T extends Display> {
415
+ /**
416
+ * Fetch recommendations from the Depict API.
417
+ * @example
418
+ * General recommendations for a landing page:
419
+ * ```tsx
420
+ * fetchRecommendations({ type: "landing_page" });
421
+ * ```
422
+ * @example
423
+ * Fetch targeted recommendations for a product details page (PDP):
424
+ * ```tsx
425
+ * fetchRecommendations({ type: "related", productId: "t-shirt-white" })
426
+ * ```
427
+ * @returns {Promise<T[]>}
428
+ */
429
+ fetchRecommendations: (opts: FetchRecsOptions) => Promise<T[]>;
430
+ }
431
+ /**
432
+ * Hook used to fetch Depict recommendations.
433
+ * @example
434
+ * Fetch general recommendations for a landing page:
435
+ * ```tsx
436
+ * import React from "react";
437
+ * import { useFetchRecommendations } from "@depict-ai/react-ui";
438
+ *
439
+ * export const LandingPage = () => {
440
+ * const [recs, setRecs] = React.useState();
441
+ * const { fetchRecommendations } = useFetchRecommendations();
442
+ *
443
+ * React.useEffect(() => {
444
+ * fetchRecommendations({ type: "landing_page" }).then(setRecs);
445
+ * }, [fetchRecommendations]);
446
+ *
447
+ * return (
448
+ * <div>
449
+ * {recs?.map((display) => (
450
+ * <ProductCard display={display} />
451
+ * ))}
452
+ * </div>
453
+ * );
454
+ * };
455
+ * ```
456
+ * @example
457
+ * Fetch targeted recommendations for a product details page (PDP):
458
+ * ```tsx
459
+ * import React from "react";
460
+ * import { useFetchRecommendations } from "@depict-ai/react-ui";
461
+ *
462
+ * export const ProductPage = ({ productId }) => {
463
+ * const [recs, setRecs] = React.useState();
464
+ * const { fetchRecommendations } = useFetchRecommendations();
465
+ *
466
+ * React.useEffect(() => {
467
+ * fetchRecommendations({ type: "related", productId }).then(setRecs);
468
+ * }, [fetchRecommendations, productId]);
469
+ *
470
+ * return (
471
+ * <div>
472
+ * {recs?.map((display) => (
473
+ * <ProductCard display={display} />
474
+ * ))}
475
+ * </div>
476
+ * );
477
+ * };
478
+ * ```
479
+ * @returns {UseFetchRecommendationsReturn}
480
+ */
481
+ export function useFetchRecommendations<T extends Display>(): UseFetchRecommendationsReturn<T>;
386
482
  /**
387
483
  * Helper function to navigate to a new page depending on the navigation library used.
388
484
  */
389
485
  export const Navigation: {
390
486
  nextRouterNavigation: (router: import("next/router").NextRouter) => (relativeUrl: string) => void;
391
487
  };
392
- export { CategoryTitle, embedded_num_products as EmbeddedNumProducts, fetchDepictRecommendations } from "@depict-ai/ui";
488
+ export { CategoryTitle, embedded_num_products as EmbeddedNumProducts } from "@depict-ai/ui";
393
489
  export type { Locale } from "@depict-ai/ui/locales";
package/dist/main.js CHANGED
@@ -6,6 +6,8 @@ var $4GYXz$depictaiuilocales = require("@depict-ai/ui/locales");
6
6
  var $4GYXz$solidjsweb = require("solid-js/web");
7
7
  var $4GYXz$reactjsxruntime = require("react/jsx-runtime");
8
8
  var $4GYXz$reactdom = require("react-dom");
9
+ var $4GYXz$solidjsstore = require("solid-js/store");
10
+ var $4GYXz$depictaidpc = require("@depict-ai/dpc");
9
11
 
10
12
  function $parcel$export(e, n, v, s) {
11
13
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
@@ -21,14 +23,15 @@ $parcel$export(module.exports, "ImagePlaceholder", () => $df522c8a81ed5a01$expor
21
23
  $parcel$export(module.exports, "TextPlaceholder", () => $7c8b440edc188ad5$export$89c6019e4baa40b1);
22
24
  $parcel$export(module.exports, "useSearchModal", () => $ae73b15c325f1b21$export$912994940e660d32);
23
25
  $parcel$export(module.exports, "useSearchField", () => $913da7f4d0bc77f2$export$9bb30bbe003b82e0);
26
+ $parcel$export(module.exports, "useFetchRecommendations", () => $a134ea100690b628$export$6501da23a2770fc);
27
+ $parcel$export(module.exports, "usePerformanceClient", () => $25c0a91312868994$export$38b98fae14bd1f64);
24
28
  $parcel$export(module.exports, "CategoryTitle", () => $b03e4eee8610ebbe$re_export$CategoryTitle);
25
29
  $parcel$export(module.exports, "EmbeddedNumProducts", () => $b03e4eee8610ebbe$re_export$EmbeddedNumProducts);
26
- $parcel$export(module.exports, "fetchDepictRecommendations", () => $b03e4eee8610ebbe$re_export$fetchDepictRecommendations);
27
30
  $parcel$export(module.exports, "version", () => $db7b67857900028b$export$83d89fbfd8236492);
28
31
  $parcel$export(module.exports, "Navigation", () => $b742053c966024b4$export$b8a61e5c71402559);
29
32
  /*! Depict.ai search and product listing react SDK wrapper */ // This is where the actual source of your React stuff should live
30
33
  // Note, if you add an export here, also add one in src-server/main.ts
31
- const $db7b67857900028b$export$83d89fbfd8236492 = "0.0.105";
34
+ const $db7b67857900028b$export$83d89fbfd8236492 = "1.0.1";
32
35
 
33
36
 
34
37
 
@@ -37,67 +40,23 @@ const $db7b67857900028b$export$83d89fbfd8236492 = "0.0.105";
37
40
 
38
41
 
39
42
 
40
- let $6319748b4f0426f0$var$set = false;
41
- let $6319748b4f0426f0$var$padding_animation;
42
- function $6319748b4f0426f0$export$6453cbc34515a94d(is_search_page) {
43
- if ($6319748b4f0426f0$var$set) return; // Just being safe
44
- $6319748b4f0426f0$var$set = true;
45
- let should_use_old_scroll = false;
46
- const old_scrollTo = window.scrollTo;
47
- window.scrollTo = (...args)=>{
48
- if (should_use_old_scroll || process.env.__NEXT_SCROLL_RESTORATION || !is_search_page(location)) return Reflect.apply(old_scrollTo, window, args);
49
- else should_use_old_scroll = true;
50
- };
51
- addEventListener("popstate", (0, $4GYXz$depictaiutilishared.catchify)(()=>{
52
- if (!is_search_page(location)) {
53
- $6319748b4f0426f0$var$removeLotsOfPadding(); // Just making sure
54
- return;
55
- }
56
- should_use_old_scroll = false;
57
- $6319748b4f0426f0$var$addLotsOfPadding();
58
- (0, $4GYXz$depictaiutilishared.observer).wait_for_element(".depict.plp .listing-page").then(()=>{
59
- $6319748b4f0426f0$var$removeLotsOfPadding();
60
- });
61
- }));
62
- (0, $4GYXz$depictaiutilishared.history_replacer)(()=>{
63
- (0, $4GYXz$depictaiutilishared.queueMacroTask)(()=>{
64
- $6319748b4f0426f0$var$removeLotsOfPadding();
65
- });
66
- }, false);
67
- window?.next?.router?.events?.on("routeChangeStart", ()=>{
68
- $6319748b4f0426f0$var$addLotsOfPadding();
69
- });
70
- }
71
- /*
72
- Here we want to be able to add padding that *definitely* gets applied and then be able to revert precisely to what was before.
73
- The best way to achieve this is using an animation that with the fill set to none. This is because animations have the absolute highest precedence in CSS, even higher than !important. Then, to revert to the old padding, we just play the animation which is 1ms long so, it immediately finishes and whatever was defined before takes precedence again.
74
- */ function $6319748b4f0426f0$var$addLotsOfPadding() {
75
- if ($6319748b4f0426f0$var$padding_animation) return; // We're already showing a bunch of padding
76
- $6319748b4f0426f0$var$padding_animation = document.body.animate({
77
- paddingBottom: (history.state?.search_scroll_restoration_data?.[0]?.min_results_loaded || 150) * 500 + "px",
78
- offset: 0
79
- }, 1);
80
- $6319748b4f0426f0$var$padding_animation.pause();
81
- }
82
- function $6319748b4f0426f0$var$removeLotsOfPadding() {
83
- if ($6319748b4f0426f0$var$padding_animation) {
84
- $6319748b4f0426f0$var$padding_animation.play();
85
- $6319748b4f0426f0$var$padding_animation = undefined;
86
- }
87
- }
88
-
89
43
 
90
44
 
91
45
  const $0b7cd4fb39fc3502$export$8e769ad4338a911e = {
92
46
  search: null,
93
47
  category: null,
94
48
  api: null,
49
+ dpc: null,
50
+ merchant: null,
51
+ market: null,
95
52
  userId: undefined,
96
53
  sessionId: undefined,
97
54
  metaData: undefined,
98
- category_path: null,
55
+ known_category_paths: new Set(),
99
56
  search_page_path_: (0, $4GYXz$solidjs.createSignal)(),
100
- required_state_set_: (0, $4GYXz$solidjs.createSignal)(false)
57
+ required_state_set_: (0, $4GYXz$solidjs.createSignal)(false),
58
+ search_page_in_dom: (0, $4GYXz$solidjs.createSignal)(false),
59
+ category_page_in_dom: (0, $4GYXz$solidjs.createSignal)(false)
101
60
  };
102
61
 
103
62
 
@@ -107,7 +66,6 @@ const $0b7cd4fb39fc3502$export$8e769ad4338a911e = {
107
66
 
108
67
 
109
68
 
110
-
111
69
  let $b4d0d98857ed9934$var$run_on_href_change;
112
70
  let $b4d0d98857ed9934$var$old_href = location.href;
113
71
  function $b4d0d98857ed9934$export$74f3924c5027fe1d(cb) {
@@ -119,19 +77,19 @@ function $b4d0d98857ed9934$export$74f3924c5027fe1d(cb) {
119
77
  $b4d0d98857ed9934$var$run_on_href_change?.(href);
120
78
  $b4d0d98857ed9934$var$old_href = href;
121
79
  }));
122
- const $b4d0d98857ed9934$export$775e6b3892b5ad52 = (url)=>url.pathname == (0, $4GYXz$solidjs.untrack)((0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).search_page_path_[0]); // might have changed therefore get it from globalState
123
- const $b4d0d98857ed9934$export$92a8f8b3c630fa0d = (url)=>{
124
- return $b4d0d98857ed9934$export$775e6b3892b5ad52(url) || url.pathname === (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).category_path;
125
- };
126
- function $b4d0d98857ed9934$export$f6e64e17bd69eeef(solid_component, props, wrapper_type = "div", wrapper_style = {}, react_render_handler) {
80
+ const $b4d0d98857ed9934$export$775e6b3892b5ad52 = (url = location)=>url.pathname == (0, $4GYXz$solidjs.untrack)((0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).search_page_path_[0]); // might have changed therefore get it from globalState
81
+ const $b4d0d98857ed9934$export$30c8a12df09be0e4 = (url = location)=>(0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).known_category_paths.has(url.pathname);
82
+ function $b4d0d98857ed9934$export$f6e64e17bd69eeef(solid_component, props, wrapper_type = "div", wrapper_style = {}) {
127
83
  const [portals, set_portals] = (0, $4GYXz$react.useState)([]);
128
84
  const wrapper_element_ref = (0, $4GYXz$react.useRef)();
85
+ const [[store, write_store]] = (0, $4GYXz$react.useState)(()=>(0, $4GYXz$solidjsstore.createStore)(props));
86
+ // Update store when props change
87
+ write_store((0, $4GYXz$solidjsstore.reconcile)(props));
129
88
  (0, $4GYXz$react.useEffect)(()=>{
130
89
  const wrapper_element = wrapper_element_ref.current;
131
- const dispose = (0, $4GYXz$solidjsweb.render)(()=>solid_component(props, set_portals), wrapper_element);
90
+ const dispose = (0, $4GYXz$solidjsweb.render)(()=>solid_component(store, set_portals), wrapper_element);
132
91
  return dispose;
133
92
  }, []);
134
- react_render_handler?.(props);
135
93
  return (0, $4GYXz$react.createElement)(wrapper_type, {
136
94
  ref: wrapper_element_ref,
137
95
  style: wrapper_style
@@ -151,17 +109,14 @@ function $b4d0d98857ed9934$export$e5139bbbb9a05035(component, is_set = (0, $0b7c
151
109
  };
152
110
  }
153
111
  async function $b4d0d98857ed9934$export$79c79419c1ef0081({ display: display , component_portals: component_portals , set_portals: set_portals , react_template: react_template }) {
112
+ let set_react_has_ran_hooks;
113
+ const react_has_ran_hooks = new Promise((r)=>set_react_has_ran_hooks = r);
154
114
  const solid_container = document.createElement("div");
155
- const react_has_rendered = new Promise((r)=>{
156
- const m_o = new MutationObserver(()=>{
157
- m_o.disconnect();
158
- r();
159
- });
160
- m_o.observe(solid_container, {
161
- childList: true
162
- });
163
- });
164
- const reactProductCard = (0, $4GYXz$reactjsxruntime.jsx)(react_template, {
115
+ const reactProductCard = (0, $4GYXz$reactjsxruntime.jsx)((props)=>{
116
+ // Sneak in a hook into their product card component
117
+ (0, $4GYXz$react.useEffect)(set_react_has_ran_hooks, []);
118
+ return react_template(props);
119
+ }, {
165
120
  display: display
166
121
  });
167
122
  const portal = $4GYXz$reactdom.createPortal(reactProductCard, solid_container);
@@ -176,23 +131,144 @@ async function $b4d0d98857ed9934$export$79c79419c1ef0081({ display: display , co
176
131
  ...component_portals
177
132
  ]);
178
133
  });
179
- await react_has_rendered; // wait for react to have finish portaling the elements so that the placeholders get removed once we have an actual result and so that the PLP code knows it has a placeholder when this is a placeholder rendering
134
+ await react_has_ran_hooks; // After react has created elements it still takes some time to actually connect the refs and run the hooks. We don't want to replace placeholders before then.
180
135
  return [
181
136
  solid_container
182
137
  ];
183
138
  }
184
139
 
185
140
 
141
+
142
+
143
+ let $6319748b4f0426f0$var$set = false;
144
+ let $6319748b4f0426f0$var$padding_animation;
145
+ function $6319748b4f0426f0$export$6453cbc34515a94d() {
146
+ const are_on_search_or_category_page = ()=>(0, $b4d0d98857ed9934$export$775e6b3892b5ad52)() || (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)();
147
+ if ($6319748b4f0426f0$var$set) return; // Just being safe
148
+ $6319748b4f0426f0$var$set = true;
149
+ let should_use_old_scroll = false;
150
+ const old_scrollTo = window.scrollTo;
151
+ const next_router_event_target = $6319748b4f0426f0$var$make_next_router_event_target(); // So we can use once: true
152
+ window.scrollTo = (...args)=>{
153
+ if (should_use_old_scroll || process.env.__NEXT_SCROLL_RESTORATION || !are_on_search_or_category_page()) return Reflect.apply(old_scrollTo, window, args);
154
+ else should_use_old_scroll = true;
155
+ };
156
+ // When popping state, add padding in the same event as the "popstate" event (required) and then remove it once our stuff is in the DOM
157
+ addEventListener("popstate", (0, $4GYXz$depictaiutilishared.catchify)(()=>{
158
+ if (!are_on_search_or_category_page()) {
159
+ $6319748b4f0426f0$var$removeLotsOfPadding(); // Just making sure
160
+ return;
161
+ }
162
+ should_use_old_scroll = false;
163
+ const [get_search_page_in_dom] = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).search_page_in_dom;
164
+ const [get_category_page_in_dom] = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).category_page_in_dom;
165
+ const search_page_in_dom = (0, $4GYXz$solidjs.untrack)(get_search_page_in_dom);
166
+ const category_page_in_dom = (0, $4GYXz$solidjs.untrack)(get_category_page_in_dom);
167
+ const new_is_search = (0, $b4d0d98857ed9934$export$775e6b3892b5ad52)();
168
+ const new_is_category = (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)();
169
+ let accessor_to_wait_for;
170
+ if (search_page_in_dom && new_is_search || category_page_in_dom && new_is_category) {
171
+ // Already on the page we're going to
172
+ $6319748b4f0426f0$var$removeLotsOfPadding();
173
+ return;
174
+ }
175
+ $6319748b4f0426f0$var$addLotsOfPadding();
176
+ if (new_is_search && category_page_in_dom) accessor_to_wait_for = get_search_page_in_dom;
177
+ else if (new_is_category && search_page_in_dom) accessor_to_wait_for = get_category_page_in_dom;
178
+ else accessor_to_wait_for = new_is_search ? get_search_page_in_dom : get_category_page_in_dom;
179
+ (0, $4GYXz$solidjs.createRoot)((dispose)=>(0, $4GYXz$solidjs.createEffect)(()=>{
180
+ if (accessor_to_wait_for()) {
181
+ $6319748b4f0426f0$var$removeLotsOfPadding();
182
+ dispose();
183
+ }
184
+ }));
185
+ }));
186
+ window?.next?.router?.events?.on(// We have to use the actual next router here, if we'd use next_router_event_target for this window.event wouldn't be the popstate anymore
187
+ "routeChangeStart", (0, $4GYXz$depictaiutilishared.catchify)(()=>{
188
+ // this is for when we navigate to a new page (replaceState or pushState)
189
+ // We need to ensure that the page doesn't get shorter before the new history entry has been pushed
190
+ // There is beforeHistoryChange which fires literally the line of code before the history API is called, so we make the page long until a task after that
191
+ // The challenge is knowing on routeChangeStart if we're in a popstate (back/forward) or a pushState/replaceState
192
+ // We use the deprecated window.event property for that
193
+ // This is catchified, so we should see in sentry when it starts failing if browsers ever remove it???
194
+ if (window.event instanceof PopStateEvent) return;
195
+ $6319748b4f0426f0$var$addLotsOfPadding();
196
+ next_router_event_target.addEventListener("beforeHistoryChange", (0, $4GYXz$depictaiutilishared.catchify)(()=>(0, $4GYXz$depictaiutilishared.queueMacroTask)($6319748b4f0426f0$var$removeLotsOfPadding)), {
197
+ once: true
198
+ });
199
+ }));
200
+ }
201
+ /*
202
+ Here we want to be able to add padding that *definitely* gets applied and then be able to revert precisely to what was before.
203
+ The best way to achieve this is using an animation that with the fill set to none. This is because animations have the absolute highest precedence in CSS, even higher than !important. Then, to revert to the old padding, we just play the animation which is 1ms long so, it immediately finishes and whatever was defined before takes precedence again.
204
+ */ function $6319748b4f0426f0$var$addLotsOfPadding() {
205
+ if ($6319748b4f0426f0$var$padding_animation) return; // We're already showing a bunch of padding
206
+ $6319748b4f0426f0$var$padding_animation = document.body.animate({
207
+ paddingBottom: (history.state?.search_scroll_restoration_data?.[0]?.min_results_loaded || 150) * 500 + "px",
208
+ offset: 0
209
+ }, 1);
210
+ $6319748b4f0426f0$var$padding_animation.pause();
211
+ }
212
+ function $6319748b4f0426f0$var$removeLotsOfPadding() {
213
+ if ($6319748b4f0426f0$var$padding_animation) {
214
+ $6319748b4f0426f0$var$padding_animation.play();
215
+ $6319748b4f0426f0$var$padding_animation = undefined;
216
+ }
217
+ }
218
+ function $6319748b4f0426f0$var$make_next_router_event_target() {
219
+ const next_router_event_target = new EventTarget();
220
+ window?.next?.router?.events?.on("beforeHistoryChange", ()=>next_router_event_target.dispatchEvent(new CustomEvent("beforeHistoryChange")));
221
+ return next_router_event_target;
222
+ }
223
+
224
+
225
+
226
+
186
227
  const $bc389476eeb2b615$export$599d4515591ef232 = (relativeUrl, isReplace)=>{
187
- const shallow = (0, $b4d0d98857ed9934$export$92a8f8b3c630fa0d)(location);
228
+ let Page;
229
+ (function(Page) {
230
+ Page[Page["OTHER"] = 0] = "OTHER";
231
+ Page[Page["SEARCH"] = 1] = "SEARCH";
232
+ Page[Page["CATEGORY"] = 2] = "CATEGORY";
233
+ })(Page || (Page = {}));
234
+ const current_page = (0, $b4d0d98857ed9934$export$775e6b3892b5ad52)() ? Page.SEARCH : (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)() ? Page.CATEGORY : Page.OTHER;
235
+ const target_u_o = new URL(relativeUrl, location.origin);
236
+ const target_page = (0, $b4d0d98857ed9934$export$775e6b3892b5ad52)(target_u_o) ? Page.SEARCH : (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)(target_u_o) ? Page.CATEGORY : Page.OTHER;
188
237
  window.next.router[isReplace ? "replace" : "push"](relativeUrl, undefined, {
189
- shallow: shallow,
238
+ shallow: current_page === target_page,
190
239
  scroll: true
191
240
  });
192
241
  };
193
242
 
194
243
 
195
244
 
245
+
246
+ const $25c0a91312868994$export$38b98fae14bd1f64 = ()=>{
247
+ if (!(0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).dpc) throw new Error("Depict tracking is not configured. Wrap your app in a DepictProvider.");
248
+ return {
249
+ dpc: (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).dpc
250
+ };
251
+ };
252
+ const $25c0a91312868994$export$47e064413edabf36 = (merchant, market, userId, sessionId)=>{
253
+ if (!merchant) return;
254
+ try {
255
+ let { dpc: dpc } = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e);
256
+ if (!dpc) dpc = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).dpc = new (0, $4GYXz$depictaidpc.DPC)(merchant, {
257
+ market: market
258
+ });
259
+ dpc.merchant = merchant;
260
+ dpc.market = market;
261
+ dpc.setUserId(userId);
262
+ dpc.setSessionId(sessionId);
263
+ } catch (e) {
264
+ // Make sure to not break the users app if we throw
265
+ queueMicrotask(()=>{
266
+ throw e;
267
+ });
268
+ }
269
+ };
270
+
271
+
196
272
  function $24b00503eef73528$export$9fac37a9c21c2f3b(props) {
197
273
  const { children: children , navigateFunction: navigateFunction , market: market , merchant: merchant , locale: locale , metaData: metaData , userId: userId , sessionId: sessionId } = props;
198
274
  const usedLocale = locale ?? (0, $4GYXz$depictaiuilocales.en);
@@ -201,13 +277,15 @@ function $24b00503eef73528$export$9fac37a9c21c2f3b(props) {
201
277
  (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).userId = userId;
202
278
  (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).sessionId = sessionId;
203
279
  (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).metaData = metaData;
280
+ (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).market = market;
281
+ (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).merchant = merchant;
282
+ (0, $25c0a91312868994$export$47e064413edabf36)(merchant, market, userId, sessionId);
204
283
  if (!market || !merchant) {
205
284
  (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).required_state_set_[1](false);
206
285
  return (0, $4GYXz$react.createElement)((0, $4GYXz$react.Fragment), null, children);
207
286
  }
208
287
  try {
209
- const { search: search , category: category , api: api } = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e);
210
- const [get_search_page_path, set_search_page_path] = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).search_page_path_;
288
+ const { search: search , category: category , api: api , search_page_path_: [get_search_page_path, set_search_page_path] } = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e);
211
289
  if (typeof window?.next?.router === "undefined" && !navigateFunction) throw new Error("You must provide a navigateFunction when not using Next.js.");
212
290
  const on_navigation = ({ is_replace: is_replace , new_url: new_url })=>{
213
291
  const new_relative_url = new_url.origin === location.origin ? new_url.pathname + new_url.search + new_url.hash : new_url.href; // bail out of making URL relative if it's not possible
@@ -252,7 +330,7 @@ function $24b00503eef73528$export$9fac37a9c21c2f3b(props) {
252
330
  category.merchant = merchant;
253
331
  category.localization = usedLocale;
254
332
  }
255
- (0, $6319748b4f0426f0$export$6453cbc34515a94d)((0, $b4d0d98857ed9934$export$92a8f8b3c630fa0d));
333
+ (0, $6319748b4f0426f0$export$6453cbc34515a94d)();
256
334
  (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).required_state_set_[1](true);
257
335
  } catch (e) {
258
336
  // Make sure to not break the users app if we throw
@@ -298,6 +376,10 @@ function $7ad7a3d0011b7b1b$var$SolidSearchPage(props, set_portals) {
298
376
  const update_updating_blocked_signal = ()=>{
299
377
  set_search_query_updating_blocked_signal(!(0, $b4d0d98857ed9934$export$775e6b3892b5ad52)(location));
300
378
  };
379
+ const [, set_search_page_in_dom] = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).search_page_in_dom;
380
+ // We should only get here once react already has a DOM node which means we should be in the DOM
381
+ set_search_page_in_dom(true);
382
+ (0, $4GYXz$solidjs.onCleanup)(()=>set_search_page_in_dom(false));
301
383
  // react is really slow with disposing components, we want to avoid a flash of another search query when you click on a product and navigate away
302
384
  (0, $b4d0d98857ed9934$export$74f3924c5027fe1d)(update_updating_blocked_signal); // if we navigate, re-check
303
385
  (0, $4GYXz$solidjs.createComputed)(()=>{
@@ -307,8 +389,8 @@ function $7ad7a3d0011b7b1b$var$SolidSearchPage(props, set_portals) {
307
389
  const component_portals = new Set();
308
390
  return (0, $4GYXz$depictaiui.SearchPage)({
309
391
  // Default config goes here
310
- include_input_field: props.includeInputField ?? true,
311
- cols_at_size: props.columnsAtSize ?? [
392
+ include_input_field: (0, $4GYXz$solidjs.untrack)(()=>props.includeInputField) ?? true,
393
+ cols_at_size: (0, $4GYXz$solidjs.untrack)(()=>props.columnsAtSize) ?? [
312
394
  [
313
395
  4
314
396
  ],
@@ -321,11 +403,11 @@ function $7ad7a3d0011b7b1b$var$SolidSearchPage(props, set_portals) {
321
403
  901
322
404
  ]
323
405
  ],
324
- grid_spacing: props.gridSpacing ?? "2%",
406
+ grid_spacing: (0, $4GYXz$solidjs.untrack)(()=>props.gridSpacing) ?? "2%",
325
407
  depict_search: depict_search,
326
408
  product_card_template: (display)=>(0, $b4d0d98857ed9934$export$79c79419c1ef0081)({
327
409
  display: display,
328
- react_template: props.productCard,
410
+ react_template: (0, $4GYXz$solidjs.untrack)(()=>props.productCard),
329
411
  component_portals: component_portals,
330
412
  set_portals: set_portals
331
413
  })
@@ -337,25 +419,30 @@ function $7ad7a3d0011b7b1b$var$SolidSearchPage(props, set_portals) {
337
419
 
338
420
 
339
421
 
340
- let $5aa5fcb9f8a2bebc$var$render_cb;
341
422
  function $5aa5fcb9f8a2bebc$export$f7d2f673fc2f091d(props) {
342
423
  return (0, $b4d0d98857ed9934$export$f6e64e17bd69eeef)(// @ts-ignore
343
- (0, $b4d0d98857ed9934$export$e5139bbbb9a05035)($5aa5fcb9f8a2bebc$var$SolidCategoryPage), props, "div", {}, (props)=>$5aa5fcb9f8a2bebc$var$render_cb?.(props));
424
+ (0, $b4d0d98857ed9934$export$e5139bbbb9a05035)($5aa5fcb9f8a2bebc$var$SolidCategoryPage), props, "div", {});
344
425
  }
345
426
  function $5aa5fcb9f8a2bebc$var$SolidCategoryPage(props, set_portals) {
346
427
  const depict_category = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).category;
347
428
  if (!depict_category) throw Error("No depict_category instance when rendering SearchPage. Did you forget to wrap your app in DepictProvider?");
348
429
  const [category_state_set, set_category_state_set] = (0, $4GYXz$solidjs.createSignal)(false);
349
- $5aa5fcb9f8a2bebc$var$render_cb = (props)=>{
350
- depict_category.category_id = props.categoryId;
351
- (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).category_path = location.pathname;
352
- if (props.categoryId) set_category_state_set(true);
353
- };
354
- $5aa5fcb9f8a2bebc$var$render_cb(props);
355
430
  const component_portals = new Set();
431
+ const [, set_category_page_in_dom] = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).category_page_in_dom;
432
+ // We should only get here once react already has a DOM node which means we should be in the DOM
433
+ set_category_page_in_dom(true);
434
+ (0, $4GYXz$solidjs.onCleanup)(()=>set_category_page_in_dom(false));
435
+ (0, $4GYXz$solidjs.createComputed)(()=>{
436
+ const { categoryId: categoryId } = props;
437
+ depict_category.category_id = categoryId;
438
+ if (categoryId) {
439
+ set_category_state_set(true);
440
+ (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e).known_category_paths.add(location.pathname);
441
+ }
442
+ });
356
443
  const category = ()=>(0, $4GYXz$depictaiui.CategoryPage)({
357
444
  depict_category: depict_category,
358
- cols_at_size: props.columnsAtSize ?? [
445
+ cols_at_size: (0, $4GYXz$solidjs.untrack)(()=>props.columnsAtSize) ?? [
359
446
  [
360
447
  4
361
448
  ],
@@ -368,13 +455,13 @@ function $5aa5fcb9f8a2bebc$var$SolidCategoryPage(props, set_portals) {
368
455
  901
369
456
  ]
370
457
  ],
371
- grid_spacing: props.gridSpacing ?? "2%",
372
- category_title: props.categoryTitlePlugin || (0, $4GYXz$depictaiui.CategoryTitle),
373
- show_breadcrumbs: props.showBreadcrumbs === undefined ? true : props.showBreadcrumbs,
374
- show_quicklinks: props.showQuicklinks === undefined ? true : props.showQuicklinks,
458
+ grid_spacing: (0, $4GYXz$solidjs.untrack)(()=>props.gridSpacing) ?? "2%",
459
+ category_title: (0, $4GYXz$solidjs.untrack)(()=>props.categoryTitlePlugin) || (0, $4GYXz$depictaiui.CategoryTitle),
460
+ show_breadcrumbs: (0, $4GYXz$solidjs.untrack)(()=>props.showBreadcrumbs === undefined ? true : props.showBreadcrumbs),
461
+ show_quicklinks: (0, $4GYXz$solidjs.untrack)(()=>props.showQuicklinks === undefined ? true : props.showQuicklinks),
375
462
  product_card_template: (display)=>(0, $b4d0d98857ed9934$export$79c79419c1ef0081)({
376
463
  display: display,
377
- react_template: props.productCard,
464
+ react_template: (0, $4GYXz$solidjs.untrack)(()=>props.productCard),
378
465
  component_portals: component_portals,
379
466
  set_portals: set_portals
380
467
  })
@@ -415,10 +502,11 @@ function $f16af0e861aff3d0$var$vanilla_quick_links() {
415
502
 
416
503
 
417
504
 
418
- const $df522c8a81ed5a01$export$3f37af283f8fb843 = ({ aspectRatio: aspectRatio })=>{
419
- return (0, $b4d0d98857ed9934$export$f6e64e17bd69eeef)(()=>(0, $4GYXz$depictaiutilishared.ContainedPlaceholderImage)({
420
- aspect_ratio: aspectRatio
421
- }), {}, "div", {
505
+
506
+ const $df522c8a81ed5a01$export$3f37af283f8fb843 = (props)=>{
507
+ return (0, $b4d0d98857ed9934$export$f6e64e17bd69eeef)((solid_props_store)=>(0, $4GYXz$solidjs.createMemo)(()=>(0, $4GYXz$depictaiutilishared.ContainedPlaceholderImage)({
508
+ aspect_ratio: solid_props_store.aspectRatio
509
+ })), props, "div", {
422
510
  "height": "100%"
423
511
  });
424
512
  };
@@ -497,11 +585,40 @@ const $913da7f4d0bc77f2$export$9bb30bbe003b82e0 = (props)=>{
497
585
 
498
586
 
499
587
 
588
+ function $a134ea100690b628$export$6501da23a2770fc() {
589
+ return {
590
+ fetchRecommendations: $a134ea100690b628$var$fetchRecommendations
591
+ };
592
+ }
593
+ function $a134ea100690b628$var$fetchRecommendations(opts) {
594
+ const { merchant: merchant , market: market , userId: userId , sessionId: sessionId } = (0, $0b7cd4fb39fc3502$export$8e769ad4338a911e);
595
+ if (!merchant || !market) throw new Error("Depict recommendations are not configured. Wrap your app in a DepictProvider.");
596
+ return (0, $4GYXz$depictaiui.fetchDepictRecommendations)({
597
+ merchant: merchant,
598
+ market: market,
599
+ userId: userId,
600
+ sessionId: sessionId,
601
+ ...opts
602
+ });
603
+ }
604
+
605
+
606
+
607
+
608
+
500
609
 
501
610
  const $e387bd534de10acd$export$804fac5697cfbe35 = (router)=>(relativeUrl)=>{
502
- const shallow = (0, $b4d0d98857ed9934$export$92a8f8b3c630fa0d)(location);
611
+ let Page;
612
+ (function(Page) {
613
+ Page[Page["OTHER"] = 0] = "OTHER";
614
+ Page[Page["SEARCH"] = 1] = "SEARCH";
615
+ Page[Page["CATEGORY"] = 2] = "CATEGORY";
616
+ })(Page || (Page = {}));
617
+ const current_page = (0, $b4d0d98857ed9934$export$775e6b3892b5ad52)() ? Page.SEARCH : (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)() ? Page.CATEGORY : Page.OTHER;
618
+ const target_u_o = new URL(relativeUrl, location.origin);
619
+ const target_page = (0, $b4d0d98857ed9934$export$775e6b3892b5ad52)(target_u_o) ? Page.SEARCH : (0, $b4d0d98857ed9934$export$30c8a12df09be0e4)(target_u_o) ? Page.CATEGORY : Page.OTHER;
503
620
  router.push(relativeUrl, undefined, {
504
- shallow: shallow,
621
+ shallow: current_page === target_page,
505
622
  scroll: true
506
623
  });
507
624
  };
package/dist/module.js CHANGED
@@ -1,15 +1,17 @@
1
- import {add_to_version_info as $TZSbU$add_to_version_info, catchify as $TZSbU$catchify, observer as $TZSbU$observer, history_replacer as $TZSbU$history_replacer, queueMacroTask as $TZSbU$queueMacroTask, instant_exec_on_suspect_history_change as $TZSbU$instant_exec_on_suspect_history_change, ContainedPlaceholderImage as $TZSbU$ContainedPlaceholderImage, Placeholder as $TZSbU$Placeholder} from "@depict-ai/utilishared";
2
- import {CategoryTitle as $43099132aad1ceb6$re_export$CategoryTitle, embedded_num_products as $43099132aad1ceb6$re_export$EmbeddedNumProducts, fetchDepictRecommendations as $43099132aad1ceb6$re_export$fetchDepictRecommendations, DepictAPI as $TZSbU$DepictAPI, DepictSearch as $TZSbU$DepictSearch, DepictCategory as $TZSbU$DepictCategory, get_search_query_updating_blocked_signal as $TZSbU$get_search_query_updating_blocked_signal, SearchPage as $TZSbU$SearchPage, CategoryPage as $TZSbU$CategoryPage, BreadCrumbs as $TZSbU$BreadCrumbs, QuickLinks as $TZSbU$QuickLinks, open_modal_with_alignment as $TZSbU$open_modal_with_alignment, SearchField as $TZSbU$SearchField} from "@depict-ai/ui";
3
- import {createRoot as $TZSbU$createRoot, untrack as $TZSbU$untrack, createSignal as $TZSbU$createSignal, createComponent as $TZSbU$createComponent, Show as $TZSbU$Show, onCleanup as $TZSbU$onCleanup, createComputed as $TZSbU$createComputed} from "solid-js";
1
+ import {add_to_version_info as $TZSbU$add_to_version_info, catchify as $TZSbU$catchify, queueMacroTask as $TZSbU$queueMacroTask, instant_exec_on_suspect_history_change as $TZSbU$instant_exec_on_suspect_history_change, ContainedPlaceholderImage as $TZSbU$ContainedPlaceholderImage, Placeholder as $TZSbU$Placeholder} from "@depict-ai/utilishared";
2
+ import {CategoryTitle as $43099132aad1ceb6$re_export$CategoryTitle, embedded_num_products as $43099132aad1ceb6$re_export$EmbeddedNumProducts, DepictAPI as $TZSbU$DepictAPI, DepictSearch as $TZSbU$DepictSearch, DepictCategory as $TZSbU$DepictCategory, get_search_query_updating_blocked_signal as $TZSbU$get_search_query_updating_blocked_signal, SearchPage as $TZSbU$SearchPage, CategoryPage as $TZSbU$CategoryPage, BreadCrumbs as $TZSbU$BreadCrumbs, QuickLinks as $TZSbU$QuickLinks, open_modal_with_alignment as $TZSbU$open_modal_with_alignment, SearchField as $TZSbU$SearchField, fetchDepictRecommendations as $TZSbU$fetchDepictRecommendations} from "@depict-ai/ui";
3
+ import {createRoot as $TZSbU$createRoot, untrack as $TZSbU$untrack, createEffect as $TZSbU$createEffect, createComponent as $TZSbU$createComponent, Show as $TZSbU$Show, onCleanup as $TZSbU$onCleanup, createSignal as $TZSbU$createSignal, createComputed as $TZSbU$createComputed, createMemo as $TZSbU$createMemo} from "solid-js";
4
4
  import {createElement as $TZSbU$createElement, Fragment as $TZSbU$Fragment, useState as $TZSbU$useState, useRef as $TZSbU$useRef, useEffect as $TZSbU$useEffect, forwardRef as $TZSbU$forwardRef} from "react";
5
5
  import {en as $TZSbU$en} from "@depict-ai/ui/locales";
6
6
  import {render as $TZSbU$render} from "solid-js/web";
7
7
  import {jsx as $TZSbU$jsx} from "react/jsx-runtime";
8
8
  import {createPortal as $TZSbU$createPortal} from "react-dom";
9
+ import {createStore as $TZSbU$createStore, reconcile as $TZSbU$reconcile} from "solid-js/store";
10
+ import {DPC as $TZSbU$DPC} from "@depict-ai/dpc";
9
11
 
10
12
  /*! Depict.ai search and product listing react SDK wrapper */ // This is where the actual source of your React stuff should live
11
13
  // Note, if you add an export here, also add one in src-server/main.ts
12
- const $c9c4d066f9a5b51b$export$83d89fbfd8236492 = "0.0.105";
14
+ const $c9c4d066f9a5b51b$export$83d89fbfd8236492 = "1.0.1";
13
15
 
14
16
 
15
17
 
@@ -18,67 +20,23 @@ const $c9c4d066f9a5b51b$export$83d89fbfd8236492 = "0.0.105";
18
20
 
19
21
 
20
22
 
21
- let $8071251ee4e9ffa1$var$set = false;
22
- let $8071251ee4e9ffa1$var$padding_animation;
23
- function $8071251ee4e9ffa1$export$6453cbc34515a94d(is_search_page) {
24
- if ($8071251ee4e9ffa1$var$set) return; // Just being safe
25
- $8071251ee4e9ffa1$var$set = true;
26
- let should_use_old_scroll = false;
27
- const old_scrollTo = window.scrollTo;
28
- window.scrollTo = (...args)=>{
29
- if (should_use_old_scroll || process.env.__NEXT_SCROLL_RESTORATION || !is_search_page(location)) return Reflect.apply(old_scrollTo, window, args);
30
- else should_use_old_scroll = true;
31
- };
32
- addEventListener("popstate", (0, $TZSbU$catchify)(()=>{
33
- if (!is_search_page(location)) {
34
- $8071251ee4e9ffa1$var$removeLotsOfPadding(); // Just making sure
35
- return;
36
- }
37
- should_use_old_scroll = false;
38
- $8071251ee4e9ffa1$var$addLotsOfPadding();
39
- (0, $TZSbU$observer).wait_for_element(".depict.plp .listing-page").then(()=>{
40
- $8071251ee4e9ffa1$var$removeLotsOfPadding();
41
- });
42
- }));
43
- (0, $TZSbU$history_replacer)(()=>{
44
- (0, $TZSbU$queueMacroTask)(()=>{
45
- $8071251ee4e9ffa1$var$removeLotsOfPadding();
46
- });
47
- }, false);
48
- window?.next?.router?.events?.on("routeChangeStart", ()=>{
49
- $8071251ee4e9ffa1$var$addLotsOfPadding();
50
- });
51
- }
52
- /*
53
- Here we want to be able to add padding that *definitely* gets applied and then be able to revert precisely to what was before.
54
- The best way to achieve this is using an animation that with the fill set to none. This is because animations have the absolute highest precedence in CSS, even higher than !important. Then, to revert to the old padding, we just play the animation which is 1ms long so, it immediately finishes and whatever was defined before takes precedence again.
55
- */ function $8071251ee4e9ffa1$var$addLotsOfPadding() {
56
- if ($8071251ee4e9ffa1$var$padding_animation) return; // We're already showing a bunch of padding
57
- $8071251ee4e9ffa1$var$padding_animation = document.body.animate({
58
- paddingBottom: (history.state?.search_scroll_restoration_data?.[0]?.min_results_loaded || 150) * 500 + "px",
59
- offset: 0
60
- }, 1);
61
- $8071251ee4e9ffa1$var$padding_animation.pause();
62
- }
63
- function $8071251ee4e9ffa1$var$removeLotsOfPadding() {
64
- if ($8071251ee4e9ffa1$var$padding_animation) {
65
- $8071251ee4e9ffa1$var$padding_animation.play();
66
- $8071251ee4e9ffa1$var$padding_animation = undefined;
67
- }
68
- }
69
-
70
23
 
71
24
 
72
25
  const $42858f023ef23dab$export$8e769ad4338a911e = {
73
26
  search: null,
74
27
  category: null,
75
28
  api: null,
29
+ dpc: null,
30
+ merchant: null,
31
+ market: null,
76
32
  userId: undefined,
77
33
  sessionId: undefined,
78
34
  metaData: undefined,
79
- category_path: null,
35
+ known_category_paths: new Set(),
80
36
  search_page_path_: (0, $TZSbU$createSignal)(),
81
- required_state_set_: (0, $TZSbU$createSignal)(false)
37
+ required_state_set_: (0, $TZSbU$createSignal)(false),
38
+ search_page_in_dom: (0, $TZSbU$createSignal)(false),
39
+ category_page_in_dom: (0, $TZSbU$createSignal)(false)
82
40
  };
83
41
 
84
42
 
@@ -88,7 +46,6 @@ const $42858f023ef23dab$export$8e769ad4338a911e = {
88
46
 
89
47
 
90
48
 
91
-
92
49
  let $c83ba9ab79386687$var$run_on_href_change;
93
50
  let $c83ba9ab79386687$var$old_href = location.href;
94
51
  function $c83ba9ab79386687$export$74f3924c5027fe1d(cb) {
@@ -100,19 +57,19 @@ function $c83ba9ab79386687$export$74f3924c5027fe1d(cb) {
100
57
  $c83ba9ab79386687$var$run_on_href_change?.(href);
101
58
  $c83ba9ab79386687$var$old_href = href;
102
59
  }));
103
- const $c83ba9ab79386687$export$775e6b3892b5ad52 = (url)=>url.pathname == (0, $TZSbU$untrack)((0, $42858f023ef23dab$export$8e769ad4338a911e).search_page_path_[0]); // might have changed therefore get it from globalState
104
- const $c83ba9ab79386687$export$92a8f8b3c630fa0d = (url)=>{
105
- return $c83ba9ab79386687$export$775e6b3892b5ad52(url) || url.pathname === (0, $42858f023ef23dab$export$8e769ad4338a911e).category_path;
106
- };
107
- function $c83ba9ab79386687$export$f6e64e17bd69eeef(solid_component, props, wrapper_type = "div", wrapper_style = {}, react_render_handler) {
60
+ const $c83ba9ab79386687$export$775e6b3892b5ad52 = (url = location)=>url.pathname == (0, $TZSbU$untrack)((0, $42858f023ef23dab$export$8e769ad4338a911e).search_page_path_[0]); // might have changed therefore get it from globalState
61
+ const $c83ba9ab79386687$export$30c8a12df09be0e4 = (url = location)=>(0, $42858f023ef23dab$export$8e769ad4338a911e).known_category_paths.has(url.pathname);
62
+ function $c83ba9ab79386687$export$f6e64e17bd69eeef(solid_component, props, wrapper_type = "div", wrapper_style = {}) {
108
63
  const [portals, set_portals] = (0, $TZSbU$useState)([]);
109
64
  const wrapper_element_ref = (0, $TZSbU$useRef)();
65
+ const [[store, write_store]] = (0, $TZSbU$useState)(()=>(0, $TZSbU$createStore)(props));
66
+ // Update store when props change
67
+ write_store((0, $TZSbU$reconcile)(props));
110
68
  (0, $TZSbU$useEffect)(()=>{
111
69
  const wrapper_element = wrapper_element_ref.current;
112
- const dispose = (0, $TZSbU$render)(()=>solid_component(props, set_portals), wrapper_element);
70
+ const dispose = (0, $TZSbU$render)(()=>solid_component(store, set_portals), wrapper_element);
113
71
  return dispose;
114
72
  }, []);
115
- react_render_handler?.(props);
116
73
  return (0, $TZSbU$createElement)(wrapper_type, {
117
74
  ref: wrapper_element_ref,
118
75
  style: wrapper_style
@@ -132,17 +89,14 @@ function $c83ba9ab79386687$export$e5139bbbb9a05035(component, is_set = (0, $4285
132
89
  };
133
90
  }
134
91
  async function $c83ba9ab79386687$export$79c79419c1ef0081({ display: display , component_portals: component_portals , set_portals: set_portals , react_template: react_template }) {
92
+ let set_react_has_ran_hooks;
93
+ const react_has_ran_hooks = new Promise((r)=>set_react_has_ran_hooks = r);
135
94
  const solid_container = document.createElement("div");
136
- const react_has_rendered = new Promise((r)=>{
137
- const m_o = new MutationObserver(()=>{
138
- m_o.disconnect();
139
- r();
140
- });
141
- m_o.observe(solid_container, {
142
- childList: true
143
- });
144
- });
145
- const reactProductCard = (0, $TZSbU$jsx)(react_template, {
95
+ const reactProductCard = (0, $TZSbU$jsx)((props)=>{
96
+ // Sneak in a hook into their product card component
97
+ (0, $TZSbU$useEffect)(set_react_has_ran_hooks, []);
98
+ return react_template(props);
99
+ }, {
146
100
  display: display
147
101
  });
148
102
  const portal = $TZSbU$createPortal(reactProductCard, solid_container);
@@ -157,23 +111,144 @@ async function $c83ba9ab79386687$export$79c79419c1ef0081({ display: display , co
157
111
  ...component_portals
158
112
  ]);
159
113
  });
160
- await react_has_rendered; // wait for react to have finish portaling the elements so that the placeholders get removed once we have an actual result and so that the PLP code knows it has a placeholder when this is a placeholder rendering
114
+ await react_has_ran_hooks; // After react has created elements it still takes some time to actually connect the refs and run the hooks. We don't want to replace placeholders before then.
161
115
  return [
162
116
  solid_container
163
117
  ];
164
118
  }
165
119
 
166
120
 
121
+
122
+
123
+ let $8071251ee4e9ffa1$var$set = false;
124
+ let $8071251ee4e9ffa1$var$padding_animation;
125
+ function $8071251ee4e9ffa1$export$6453cbc34515a94d() {
126
+ const are_on_search_or_category_page = ()=>(0, $c83ba9ab79386687$export$775e6b3892b5ad52)() || (0, $c83ba9ab79386687$export$30c8a12df09be0e4)();
127
+ if ($8071251ee4e9ffa1$var$set) return; // Just being safe
128
+ $8071251ee4e9ffa1$var$set = true;
129
+ let should_use_old_scroll = false;
130
+ const old_scrollTo = window.scrollTo;
131
+ const next_router_event_target = $8071251ee4e9ffa1$var$make_next_router_event_target(); // So we can use once: true
132
+ window.scrollTo = (...args)=>{
133
+ if (should_use_old_scroll || process.env.__NEXT_SCROLL_RESTORATION || !are_on_search_or_category_page()) return Reflect.apply(old_scrollTo, window, args);
134
+ else should_use_old_scroll = true;
135
+ };
136
+ // When popping state, add padding in the same event as the "popstate" event (required) and then remove it once our stuff is in the DOM
137
+ addEventListener("popstate", (0, $TZSbU$catchify)(()=>{
138
+ if (!are_on_search_or_category_page()) {
139
+ $8071251ee4e9ffa1$var$removeLotsOfPadding(); // Just making sure
140
+ return;
141
+ }
142
+ should_use_old_scroll = false;
143
+ const [get_search_page_in_dom] = (0, $42858f023ef23dab$export$8e769ad4338a911e).search_page_in_dom;
144
+ const [get_category_page_in_dom] = (0, $42858f023ef23dab$export$8e769ad4338a911e).category_page_in_dom;
145
+ const search_page_in_dom = (0, $TZSbU$untrack)(get_search_page_in_dom);
146
+ const category_page_in_dom = (0, $TZSbU$untrack)(get_category_page_in_dom);
147
+ const new_is_search = (0, $c83ba9ab79386687$export$775e6b3892b5ad52)();
148
+ const new_is_category = (0, $c83ba9ab79386687$export$30c8a12df09be0e4)();
149
+ let accessor_to_wait_for;
150
+ if (search_page_in_dom && new_is_search || category_page_in_dom && new_is_category) {
151
+ // Already on the page we're going to
152
+ $8071251ee4e9ffa1$var$removeLotsOfPadding();
153
+ return;
154
+ }
155
+ $8071251ee4e9ffa1$var$addLotsOfPadding();
156
+ if (new_is_search && category_page_in_dom) accessor_to_wait_for = get_search_page_in_dom;
157
+ else if (new_is_category && search_page_in_dom) accessor_to_wait_for = get_category_page_in_dom;
158
+ else accessor_to_wait_for = new_is_search ? get_search_page_in_dom : get_category_page_in_dom;
159
+ (0, $TZSbU$createRoot)((dispose)=>(0, $TZSbU$createEffect)(()=>{
160
+ if (accessor_to_wait_for()) {
161
+ $8071251ee4e9ffa1$var$removeLotsOfPadding();
162
+ dispose();
163
+ }
164
+ }));
165
+ }));
166
+ window?.next?.router?.events?.on(// We have to use the actual next router here, if we'd use next_router_event_target for this window.event wouldn't be the popstate anymore
167
+ "routeChangeStart", (0, $TZSbU$catchify)(()=>{
168
+ // this is for when we navigate to a new page (replaceState or pushState)
169
+ // We need to ensure that the page doesn't get shorter before the new history entry has been pushed
170
+ // There is beforeHistoryChange which fires literally the line of code before the history API is called, so we make the page long until a task after that
171
+ // The challenge is knowing on routeChangeStart if we're in a popstate (back/forward) or a pushState/replaceState
172
+ // We use the deprecated window.event property for that
173
+ // This is catchified, so we should see in sentry when it starts failing if browsers ever remove it???
174
+ if (window.event instanceof PopStateEvent) return;
175
+ $8071251ee4e9ffa1$var$addLotsOfPadding();
176
+ next_router_event_target.addEventListener("beforeHistoryChange", (0, $TZSbU$catchify)(()=>(0, $TZSbU$queueMacroTask)($8071251ee4e9ffa1$var$removeLotsOfPadding)), {
177
+ once: true
178
+ });
179
+ }));
180
+ }
181
+ /*
182
+ Here we want to be able to add padding that *definitely* gets applied and then be able to revert precisely to what was before.
183
+ The best way to achieve this is using an animation that with the fill set to none. This is because animations have the absolute highest precedence in CSS, even higher than !important. Then, to revert to the old padding, we just play the animation which is 1ms long so, it immediately finishes and whatever was defined before takes precedence again.
184
+ */ function $8071251ee4e9ffa1$var$addLotsOfPadding() {
185
+ if ($8071251ee4e9ffa1$var$padding_animation) return; // We're already showing a bunch of padding
186
+ $8071251ee4e9ffa1$var$padding_animation = document.body.animate({
187
+ paddingBottom: (history.state?.search_scroll_restoration_data?.[0]?.min_results_loaded || 150) * 500 + "px",
188
+ offset: 0
189
+ }, 1);
190
+ $8071251ee4e9ffa1$var$padding_animation.pause();
191
+ }
192
+ function $8071251ee4e9ffa1$var$removeLotsOfPadding() {
193
+ if ($8071251ee4e9ffa1$var$padding_animation) {
194
+ $8071251ee4e9ffa1$var$padding_animation.play();
195
+ $8071251ee4e9ffa1$var$padding_animation = undefined;
196
+ }
197
+ }
198
+ function $8071251ee4e9ffa1$var$make_next_router_event_target() {
199
+ const next_router_event_target = new EventTarget();
200
+ window?.next?.router?.events?.on("beforeHistoryChange", ()=>next_router_event_target.dispatchEvent(new CustomEvent("beforeHistoryChange")));
201
+ return next_router_event_target;
202
+ }
203
+
204
+
205
+
206
+
167
207
  const $7216ca4c8308a0f9$export$599d4515591ef232 = (relativeUrl, isReplace)=>{
168
- const shallow = (0, $c83ba9ab79386687$export$92a8f8b3c630fa0d)(location);
208
+ let Page;
209
+ (function(Page) {
210
+ Page[Page["OTHER"] = 0] = "OTHER";
211
+ Page[Page["SEARCH"] = 1] = "SEARCH";
212
+ Page[Page["CATEGORY"] = 2] = "CATEGORY";
213
+ })(Page || (Page = {}));
214
+ const current_page = (0, $c83ba9ab79386687$export$775e6b3892b5ad52)() ? Page.SEARCH : (0, $c83ba9ab79386687$export$30c8a12df09be0e4)() ? Page.CATEGORY : Page.OTHER;
215
+ const target_u_o = new URL(relativeUrl, location.origin);
216
+ const target_page = (0, $c83ba9ab79386687$export$775e6b3892b5ad52)(target_u_o) ? Page.SEARCH : (0, $c83ba9ab79386687$export$30c8a12df09be0e4)(target_u_o) ? Page.CATEGORY : Page.OTHER;
169
217
  window.next.router[isReplace ? "replace" : "push"](relativeUrl, undefined, {
170
- shallow: shallow,
218
+ shallow: current_page === target_page,
171
219
  scroll: true
172
220
  });
173
221
  };
174
222
 
175
223
 
176
224
 
225
+
226
+ const $a00d8f27abd5d0b0$export$38b98fae14bd1f64 = ()=>{
227
+ if (!(0, $42858f023ef23dab$export$8e769ad4338a911e).dpc) throw new Error("Depict tracking is not configured. Wrap your app in a DepictProvider.");
228
+ return {
229
+ dpc: (0, $42858f023ef23dab$export$8e769ad4338a911e).dpc
230
+ };
231
+ };
232
+ const $a00d8f27abd5d0b0$export$47e064413edabf36 = (merchant, market, userId, sessionId)=>{
233
+ if (!merchant) return;
234
+ try {
235
+ let { dpc: dpc } = (0, $42858f023ef23dab$export$8e769ad4338a911e);
236
+ if (!dpc) dpc = (0, $42858f023ef23dab$export$8e769ad4338a911e).dpc = new (0, $TZSbU$DPC)(merchant, {
237
+ market: market
238
+ });
239
+ dpc.merchant = merchant;
240
+ dpc.market = market;
241
+ dpc.setUserId(userId);
242
+ dpc.setSessionId(sessionId);
243
+ } catch (e) {
244
+ // Make sure to not break the users app if we throw
245
+ queueMicrotask(()=>{
246
+ throw e;
247
+ });
248
+ }
249
+ };
250
+
251
+
177
252
  function $5376eb2a386cd90d$export$9fac37a9c21c2f3b(props) {
178
253
  const { children: children , navigateFunction: navigateFunction , market: market , merchant: merchant , locale: locale , metaData: metaData , userId: userId , sessionId: sessionId } = props;
179
254
  const usedLocale = locale ?? (0, $TZSbU$en);
@@ -182,13 +257,15 @@ function $5376eb2a386cd90d$export$9fac37a9c21c2f3b(props) {
182
257
  (0, $42858f023ef23dab$export$8e769ad4338a911e).userId = userId;
183
258
  (0, $42858f023ef23dab$export$8e769ad4338a911e).sessionId = sessionId;
184
259
  (0, $42858f023ef23dab$export$8e769ad4338a911e).metaData = metaData;
260
+ (0, $42858f023ef23dab$export$8e769ad4338a911e).market = market;
261
+ (0, $42858f023ef23dab$export$8e769ad4338a911e).merchant = merchant;
262
+ (0, $a00d8f27abd5d0b0$export$47e064413edabf36)(merchant, market, userId, sessionId);
185
263
  if (!market || !merchant) {
186
264
  (0, $42858f023ef23dab$export$8e769ad4338a911e).required_state_set_[1](false);
187
265
  return (0, $TZSbU$createElement)((0, $TZSbU$Fragment), null, children);
188
266
  }
189
267
  try {
190
- const { search: search , category: category , api: api } = (0, $42858f023ef23dab$export$8e769ad4338a911e);
191
- const [get_search_page_path, set_search_page_path] = (0, $42858f023ef23dab$export$8e769ad4338a911e).search_page_path_;
268
+ const { search: search , category: category , api: api , search_page_path_: [get_search_page_path, set_search_page_path] } = (0, $42858f023ef23dab$export$8e769ad4338a911e);
192
269
  if (typeof window?.next?.router === "undefined" && !navigateFunction) throw new Error("You must provide a navigateFunction when not using Next.js.");
193
270
  const on_navigation = ({ is_replace: is_replace , new_url: new_url })=>{
194
271
  const new_relative_url = new_url.origin === location.origin ? new_url.pathname + new_url.search + new_url.hash : new_url.href; // bail out of making URL relative if it's not possible
@@ -233,7 +310,7 @@ function $5376eb2a386cd90d$export$9fac37a9c21c2f3b(props) {
233
310
  category.merchant = merchant;
234
311
  category.localization = usedLocale;
235
312
  }
236
- (0, $8071251ee4e9ffa1$export$6453cbc34515a94d)((0, $c83ba9ab79386687$export$92a8f8b3c630fa0d));
313
+ (0, $8071251ee4e9ffa1$export$6453cbc34515a94d)();
237
314
  (0, $42858f023ef23dab$export$8e769ad4338a911e).required_state_set_[1](true);
238
315
  } catch (e) {
239
316
  // Make sure to not break the users app if we throw
@@ -279,6 +356,10 @@ function $4a678f0c87b12e78$var$SolidSearchPage(props, set_portals) {
279
356
  const update_updating_blocked_signal = ()=>{
280
357
  set_search_query_updating_blocked_signal(!(0, $c83ba9ab79386687$export$775e6b3892b5ad52)(location));
281
358
  };
359
+ const [, set_search_page_in_dom] = (0, $42858f023ef23dab$export$8e769ad4338a911e).search_page_in_dom;
360
+ // We should only get here once react already has a DOM node which means we should be in the DOM
361
+ set_search_page_in_dom(true);
362
+ (0, $TZSbU$onCleanup)(()=>set_search_page_in_dom(false));
282
363
  // react is really slow with disposing components, we want to avoid a flash of another search query when you click on a product and navigate away
283
364
  (0, $c83ba9ab79386687$export$74f3924c5027fe1d)(update_updating_blocked_signal); // if we navigate, re-check
284
365
  (0, $TZSbU$createComputed)(()=>{
@@ -288,8 +369,8 @@ function $4a678f0c87b12e78$var$SolidSearchPage(props, set_portals) {
288
369
  const component_portals = new Set();
289
370
  return (0, $TZSbU$SearchPage)({
290
371
  // Default config goes here
291
- include_input_field: props.includeInputField ?? true,
292
- cols_at_size: props.columnsAtSize ?? [
372
+ include_input_field: (0, $TZSbU$untrack)(()=>props.includeInputField) ?? true,
373
+ cols_at_size: (0, $TZSbU$untrack)(()=>props.columnsAtSize) ?? [
293
374
  [
294
375
  4
295
376
  ],
@@ -302,11 +383,11 @@ function $4a678f0c87b12e78$var$SolidSearchPage(props, set_portals) {
302
383
  901
303
384
  ]
304
385
  ],
305
- grid_spacing: props.gridSpacing ?? "2%",
386
+ grid_spacing: (0, $TZSbU$untrack)(()=>props.gridSpacing) ?? "2%",
306
387
  depict_search: depict_search,
307
388
  product_card_template: (display)=>(0, $c83ba9ab79386687$export$79c79419c1ef0081)({
308
389
  display: display,
309
- react_template: props.productCard,
390
+ react_template: (0, $TZSbU$untrack)(()=>props.productCard),
310
391
  component_portals: component_portals,
311
392
  set_portals: set_portals
312
393
  })
@@ -318,25 +399,30 @@ function $4a678f0c87b12e78$var$SolidSearchPage(props, set_portals) {
318
399
 
319
400
 
320
401
 
321
- let $48d7f568740a317d$var$render_cb;
322
402
  function $48d7f568740a317d$export$f7d2f673fc2f091d(props) {
323
403
  return (0, $c83ba9ab79386687$export$f6e64e17bd69eeef)(// @ts-ignore
324
- (0, $c83ba9ab79386687$export$e5139bbbb9a05035)($48d7f568740a317d$var$SolidCategoryPage), props, "div", {}, (props)=>$48d7f568740a317d$var$render_cb?.(props));
404
+ (0, $c83ba9ab79386687$export$e5139bbbb9a05035)($48d7f568740a317d$var$SolidCategoryPage), props, "div", {});
325
405
  }
326
406
  function $48d7f568740a317d$var$SolidCategoryPage(props, set_portals) {
327
407
  const depict_category = (0, $42858f023ef23dab$export$8e769ad4338a911e).category;
328
408
  if (!depict_category) throw Error("No depict_category instance when rendering SearchPage. Did you forget to wrap your app in DepictProvider?");
329
409
  const [category_state_set, set_category_state_set] = (0, $TZSbU$createSignal)(false);
330
- $48d7f568740a317d$var$render_cb = (props)=>{
331
- depict_category.category_id = props.categoryId;
332
- (0, $42858f023ef23dab$export$8e769ad4338a911e).category_path = location.pathname;
333
- if (props.categoryId) set_category_state_set(true);
334
- };
335
- $48d7f568740a317d$var$render_cb(props);
336
410
  const component_portals = new Set();
411
+ const [, set_category_page_in_dom] = (0, $42858f023ef23dab$export$8e769ad4338a911e).category_page_in_dom;
412
+ // We should only get here once react already has a DOM node which means we should be in the DOM
413
+ set_category_page_in_dom(true);
414
+ (0, $TZSbU$onCleanup)(()=>set_category_page_in_dom(false));
415
+ (0, $TZSbU$createComputed)(()=>{
416
+ const { categoryId: categoryId } = props;
417
+ depict_category.category_id = categoryId;
418
+ if (categoryId) {
419
+ set_category_state_set(true);
420
+ (0, $42858f023ef23dab$export$8e769ad4338a911e).known_category_paths.add(location.pathname);
421
+ }
422
+ });
337
423
  const category = ()=>(0, $TZSbU$CategoryPage)({
338
424
  depict_category: depict_category,
339
- cols_at_size: props.columnsAtSize ?? [
425
+ cols_at_size: (0, $TZSbU$untrack)(()=>props.columnsAtSize) ?? [
340
426
  [
341
427
  4
342
428
  ],
@@ -349,13 +435,13 @@ function $48d7f568740a317d$var$SolidCategoryPage(props, set_portals) {
349
435
  901
350
436
  ]
351
437
  ],
352
- grid_spacing: props.gridSpacing ?? "2%",
353
- category_title: props.categoryTitlePlugin || (0, $43099132aad1ceb6$re_export$CategoryTitle),
354
- show_breadcrumbs: props.showBreadcrumbs === undefined ? true : props.showBreadcrumbs,
355
- show_quicklinks: props.showQuicklinks === undefined ? true : props.showQuicklinks,
438
+ grid_spacing: (0, $TZSbU$untrack)(()=>props.gridSpacing) ?? "2%",
439
+ category_title: (0, $TZSbU$untrack)(()=>props.categoryTitlePlugin) || (0, $43099132aad1ceb6$re_export$CategoryTitle),
440
+ show_breadcrumbs: (0, $TZSbU$untrack)(()=>props.showBreadcrumbs === undefined ? true : props.showBreadcrumbs),
441
+ show_quicklinks: (0, $TZSbU$untrack)(()=>props.showQuicklinks === undefined ? true : props.showQuicklinks),
356
442
  product_card_template: (display)=>(0, $c83ba9ab79386687$export$79c79419c1ef0081)({
357
443
  display: display,
358
- react_template: props.productCard,
444
+ react_template: (0, $TZSbU$untrack)(()=>props.productCard),
359
445
  component_portals: component_portals,
360
446
  set_portals: set_portals
361
447
  })
@@ -396,10 +482,11 @@ function $b68a14248b7ef667$var$vanilla_quick_links() {
396
482
 
397
483
 
398
484
 
399
- const $f446a84f85ba06f6$export$3f37af283f8fb843 = ({ aspectRatio: aspectRatio })=>{
400
- return (0, $c83ba9ab79386687$export$f6e64e17bd69eeef)(()=>(0, $TZSbU$ContainedPlaceholderImage)({
401
- aspect_ratio: aspectRatio
402
- }), {}, "div", {
485
+
486
+ const $f446a84f85ba06f6$export$3f37af283f8fb843 = (props)=>{
487
+ return (0, $c83ba9ab79386687$export$f6e64e17bd69eeef)((solid_props_store)=>(0, $TZSbU$createMemo)(()=>(0, $TZSbU$ContainedPlaceholderImage)({
488
+ aspect_ratio: solid_props_store.aspectRatio
489
+ })), props, "div", {
403
490
  "height": "100%"
404
491
  });
405
492
  };
@@ -478,11 +565,40 @@ const $2b886cf548a4775c$export$9bb30bbe003b82e0 = (props)=>{
478
565
 
479
566
 
480
567
 
568
+ function $1bb4271dc44722e2$export$6501da23a2770fc() {
569
+ return {
570
+ fetchRecommendations: $1bb4271dc44722e2$var$fetchRecommendations
571
+ };
572
+ }
573
+ function $1bb4271dc44722e2$var$fetchRecommendations(opts) {
574
+ const { merchant: merchant , market: market , userId: userId , sessionId: sessionId } = (0, $42858f023ef23dab$export$8e769ad4338a911e);
575
+ if (!merchant || !market) throw new Error("Depict recommendations are not configured. Wrap your app in a DepictProvider.");
576
+ return (0, $TZSbU$fetchDepictRecommendations)({
577
+ merchant: merchant,
578
+ market: market,
579
+ userId: userId,
580
+ sessionId: sessionId,
581
+ ...opts
582
+ });
583
+ }
584
+
585
+
586
+
587
+
588
+
481
589
 
482
590
  const $a92aa2beb560b8af$export$804fac5697cfbe35 = (router)=>(relativeUrl)=>{
483
- const shallow = (0, $c83ba9ab79386687$export$92a8f8b3c630fa0d)(location);
591
+ let Page;
592
+ (function(Page) {
593
+ Page[Page["OTHER"] = 0] = "OTHER";
594
+ Page[Page["SEARCH"] = 1] = "SEARCH";
595
+ Page[Page["CATEGORY"] = 2] = "CATEGORY";
596
+ })(Page || (Page = {}));
597
+ const current_page = (0, $c83ba9ab79386687$export$775e6b3892b5ad52)() ? Page.SEARCH : (0, $c83ba9ab79386687$export$30c8a12df09be0e4)() ? Page.CATEGORY : Page.OTHER;
598
+ const target_u_o = new URL(relativeUrl, location.origin);
599
+ const target_page = (0, $c83ba9ab79386687$export$775e6b3892b5ad52)(target_u_o) ? Page.SEARCH : (0, $c83ba9ab79386687$export$30c8a12df09be0e4)(target_u_o) ? Page.CATEGORY : Page.OTHER;
484
600
  router.push(relativeUrl, undefined, {
485
- shallow: shallow,
601
+ shallow: current_page === target_page,
486
602
  scroll: true
487
603
  });
488
604
  };
@@ -496,4 +612,4 @@ const $97603d19204ec48d$export$b8a61e5c71402559 = {
496
612
  (0, $TZSbU$add_to_version_info)("react-ui", (0, $c9c4d066f9a5b51b$export$83d89fbfd8236492));
497
613
 
498
614
 
499
- export {$b68a14248b7ef667$export$466cdc317043f6cb as QuickLinks, $f866f7ed9f751af4$export$5646050d516e06bc as BreadCrumbs, $421f32789b6f111f$export$80e99ee6b29cadd2 as ComponentAligner, $5376eb2a386cd90d$export$9fac37a9c21c2f3b as DepictProvider, $48d7f568740a317d$export$f7d2f673fc2f091d as CategoryPage, $4a678f0c87b12e78$export$a54ec244c8863715 as SearchPage, $f446a84f85ba06f6$export$3f37af283f8fb843 as ImagePlaceholder, $cbd250061abf11cb$export$89c6019e4baa40b1 as TextPlaceholder, $70344e5e0d0fea06$export$912994940e660d32 as useSearchModal, $2b886cf548a4775c$export$9bb30bbe003b82e0 as useSearchField, $43099132aad1ceb6$re_export$CategoryTitle as CategoryTitle, $43099132aad1ceb6$re_export$EmbeddedNumProducts as EmbeddedNumProducts, $43099132aad1ceb6$re_export$fetchDepictRecommendations as fetchDepictRecommendations, $c9c4d066f9a5b51b$export$83d89fbfd8236492 as version, $97603d19204ec48d$export$b8a61e5c71402559 as Navigation};
615
+ export {$b68a14248b7ef667$export$466cdc317043f6cb as QuickLinks, $f866f7ed9f751af4$export$5646050d516e06bc as BreadCrumbs, $421f32789b6f111f$export$80e99ee6b29cadd2 as ComponentAligner, $5376eb2a386cd90d$export$9fac37a9c21c2f3b as DepictProvider, $48d7f568740a317d$export$f7d2f673fc2f091d as CategoryPage, $4a678f0c87b12e78$export$a54ec244c8863715 as SearchPage, $f446a84f85ba06f6$export$3f37af283f8fb843 as ImagePlaceholder, $cbd250061abf11cb$export$89c6019e4baa40b1 as TextPlaceholder, $70344e5e0d0fea06$export$912994940e660d32 as useSearchModal, $2b886cf548a4775c$export$9bb30bbe003b82e0 as useSearchField, $1bb4271dc44722e2$export$6501da23a2770fc as useFetchRecommendations, $a00d8f27abd5d0b0$export$38b98fae14bd1f64 as usePerformanceClient, $43099132aad1ceb6$re_export$CategoryTitle as CategoryTitle, $43099132aad1ceb6$re_export$EmbeddedNumProducts as EmbeddedNumProducts, $c9c4d066f9a5b51b$export$83d89fbfd8236492 as version, $97603d19204ec48d$export$b8a61e5c71402559 as Navigation};
@@ -1,4 +1,7 @@
1
1
  import { ReactElement } from "react";
2
+ import { DPC } from "@depict-ai/dpc";
3
+ import { fetchDepictRecommendations, ExclusiveId } from "@depict-ai/ui";
4
+ import { Display } from "@depict-ai/utilishared";
2
5
  type OpenModal = () => void;
3
6
  interface UseSearchModalReturn {
4
7
  open: OpenModal;
@@ -9,8 +12,28 @@ interface UseSearchFieldReturn {
9
12
  */
10
13
  SearchField: () => ReactElement;
11
14
  }
12
- export const version = "0.0.105";
13
- export const fetchDepictRecommendations: any;
15
+ interface UsePerformanceClientReturn {
16
+ dpc: DPC;
17
+ }
18
+ type FetchRecsOptions = Omit<Parameters<typeof fetchDepictRecommendations>[0], "merchant" | "market" | "userId" | "sessionId"> & ExclusiveId;
19
+ interface UseFetchRecommendationsReturn<T extends Display> {
20
+ /**
21
+ * Fetch recommendations from the Depict API.
22
+ * @example
23
+ * General recommendations for a landing page:
24
+ * ```tsx
25
+ * fetchRecommendations({ type: "landing_page" });
26
+ * ```
27
+ * @example
28
+ * Fetch targeted recommendations for a product details page (PDP):
29
+ * ```tsx
30
+ * fetchRecommendations({ type: "related", productId: "t-shirt-white" })
31
+ * ```
32
+ * @returns {Promise<T[]>}
33
+ */
34
+ fetchRecommendations: (opts: FetchRecsOptions) => Promise<T[]>;
35
+ }
36
+ export const version = "1.0.1";
14
37
  export function DepictProvider(props: any): any;
15
38
  export function SearchPage(): any;
16
39
  export function CategoryPage(): any;
@@ -27,3 +50,5 @@ export function TextPlaceholder(): any;
27
50
  export function useSearchField(): UseSearchFieldReturn;
28
51
  export function openModal(): void;
29
52
  export function useSearchModal(): UseSearchModalReturn;
53
+ export function usePerformanceClient(): UsePerformanceClientReturn;
54
+ export function useFetchRecommendations<T extends Display>(): UseFetchRecommendationsReturn<T>;
@@ -5,7 +5,6 @@ function $parcel$export(e, n, v, s) {
5
5
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
6
6
  }
7
7
 
8
- $parcel$export(module.exports, "fetchDepictRecommendations", () => $41e7e5d85b5e0d49$export$58e808b1db15d3bc);
9
8
  $parcel$export(module.exports, "DepictProvider", () => $41e7e5d85b5e0d49$export$9fac37a9c21c2f3b);
10
9
  $parcel$export(module.exports, "SearchPage", () => $41e7e5d85b5e0d49$export$a54ec244c8863715);
11
10
  $parcel$export(module.exports, "CategoryPage", () => $41e7e5d85b5e0d49$export$f7d2f673fc2f091d);
@@ -17,15 +16,14 @@ $parcel$export(module.exports, "TextPlaceholder", () => $41e7e5d85b5e0d49$export
17
16
  $parcel$export(module.exports, "useSearchField", () => $41e7e5d85b5e0d49$export$9bb30bbe003b82e0);
18
17
  $parcel$export(module.exports, "openModal", () => $41e7e5d85b5e0d49$export$a7f6cffb6b8ba11c);
19
18
  $parcel$export(module.exports, "useSearchModal", () => $41e7e5d85b5e0d49$export$912994940e660d32);
19
+ $parcel$export(module.exports, "usePerformanceClient", () => $41e7e5d85b5e0d49$export$38b98fae14bd1f64);
20
+ $parcel$export(module.exports, "useFetchRecommendations", () => $41e7e5d85b5e0d49$export$6501da23a2770fc);
20
21
  $parcel$export(module.exports, "version", () => $db7b67857900028b$export$83d89fbfd8236492);
21
22
 
22
23
 
23
- const $db7b67857900028b$export$83d89fbfd8236492 = "0.0.105";
24
+ const $db7b67857900028b$export$83d89fbfd8236492 = "1.0.1";
24
25
 
25
26
 
26
- const $41e7e5d85b5e0d49$export$58e808b1db15d3bc = ()=>{
27
- throw new Error("fetchDepictRecommendations is currently not available on the server due to personalisation/user_id related issues. Please only call it on the client");
28
- };
29
27
  function $41e7e5d85b5e0d49$export$9fac37a9c21c2f3b(props) {
30
28
  return props.children;
31
29
  }
@@ -80,5 +78,25 @@ function $41e7e5d85b5e0d49$export$912994940e660d32() {
80
78
  open: ()=>{}
81
79
  };
82
80
  }
81
+ function $41e7e5d85b5e0d49$export$38b98fae14bd1f64() {
82
+ const mock = {
83
+ get: function(target, property) {
84
+ if (typeof target[property] === "undefined") return ()=>{
85
+ throw new Error("Depict Performance Client is currently not available on the server. Please wrap your call in a useEffect hook or user event handler.");
86
+ };
87
+ return target[property];
88
+ }
89
+ };
90
+ return {
91
+ dpc: new Proxy({}, mock)
92
+ };
93
+ }
94
+ function $41e7e5d85b5e0d49$export$6501da23a2770fc() {
95
+ return {
96
+ fetchRecommendations: ()=>{
97
+ throw new Error("fetchRecommendations is currently not available on the server due to personalisation/user_id related issues. Please only call it on the client.");
98
+ }
99
+ };
100
+ }
83
101
 
84
102
 
@@ -3,12 +3,9 @@ import {jsx as $1RlIW$jsx} from "react/jsx-runtime";
3
3
 
4
4
 
5
5
 
6
- const $c9c4d066f9a5b51b$export$83d89fbfd8236492 = "0.0.105";
6
+ const $c9c4d066f9a5b51b$export$83d89fbfd8236492 = "1.0.1";
7
7
 
8
8
 
9
- const $2b1fdeb83610500f$export$58e808b1db15d3bc = ()=>{
10
- throw new Error("fetchDepictRecommendations is currently not available on the server due to personalisation/user_id related issues. Please only call it on the client");
11
- };
12
9
  function $2b1fdeb83610500f$export$9fac37a9c21c2f3b(props) {
13
10
  return props.children;
14
11
  }
@@ -63,6 +60,26 @@ function $2b1fdeb83610500f$export$912994940e660d32() {
63
60
  open: ()=>{}
64
61
  };
65
62
  }
63
+ function $2b1fdeb83610500f$export$38b98fae14bd1f64() {
64
+ const mock = {
65
+ get: function(target, property) {
66
+ if (typeof target[property] === "undefined") return ()=>{
67
+ throw new Error("Depict Performance Client is currently not available on the server. Please wrap your call in a useEffect hook or user event handler.");
68
+ };
69
+ return target[property];
70
+ }
71
+ };
72
+ return {
73
+ dpc: new Proxy({}, mock)
74
+ };
75
+ }
76
+ function $2b1fdeb83610500f$export$6501da23a2770fc() {
77
+ return {
78
+ fetchRecommendations: ()=>{
79
+ throw new Error("fetchRecommendations is currently not available on the server due to personalisation/user_id related issues. Please only call it on the client.");
80
+ }
81
+ };
82
+ }
66
83
 
67
84
 
68
- export {$2b1fdeb83610500f$export$58e808b1db15d3bc as fetchDepictRecommendations, $2b1fdeb83610500f$export$9fac37a9c21c2f3b as DepictProvider, $2b1fdeb83610500f$export$a54ec244c8863715 as SearchPage, $2b1fdeb83610500f$export$f7d2f673fc2f091d as CategoryPage, $2b1fdeb83610500f$export$5646050d516e06bc as BreadCrumbs, $2b1fdeb83610500f$export$466cdc317043f6cb as QuickLinks, $2b1fdeb83610500f$export$80e99ee6b29cadd2 as ComponentAligner, $2b1fdeb83610500f$export$3f37af283f8fb843 as ImagePlaceholder, $2b1fdeb83610500f$export$89c6019e4baa40b1 as TextPlaceholder, $2b1fdeb83610500f$export$9bb30bbe003b82e0 as useSearchField, $2b1fdeb83610500f$export$a7f6cffb6b8ba11c as openModal, $2b1fdeb83610500f$export$912994940e660d32 as useSearchModal, $c9c4d066f9a5b51b$export$83d89fbfd8236492 as version};
85
+ export {$2b1fdeb83610500f$export$9fac37a9c21c2f3b as DepictProvider, $2b1fdeb83610500f$export$a54ec244c8863715 as SearchPage, $2b1fdeb83610500f$export$f7d2f673fc2f091d as CategoryPage, $2b1fdeb83610500f$export$5646050d516e06bc as BreadCrumbs, $2b1fdeb83610500f$export$466cdc317043f6cb as QuickLinks, $2b1fdeb83610500f$export$80e99ee6b29cadd2 as ComponentAligner, $2b1fdeb83610500f$export$3f37af283f8fb843 as ImagePlaceholder, $2b1fdeb83610500f$export$89c6019e4baa40b1 as TextPlaceholder, $2b1fdeb83610500f$export$9bb30bbe003b82e0 as useSearchField, $2b1fdeb83610500f$export$a7f6cffb6b8ba11c as openModal, $2b1fdeb83610500f$export$912994940e660d32 as useSearchModal, $2b1fdeb83610500f$export$38b98fae14bd1f64 as usePerformanceClient, $2b1fdeb83610500f$export$6501da23a2770fc as useFetchRecommendations, $c9c4d066f9a5b51b$export$83d89fbfd8236492 as version};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depict-ai/react-ui",
3
- "version": "0.0.105",
3
+ "version": "1.0.1",
4
4
  "packageManager": "yarn@3.2.2",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/main.js",
@@ -96,9 +96,10 @@
96
96
  "/locales"
97
97
  ],
98
98
  "dependencies": {
99
- "@depict-ai/plp-styling": "^1.0.1",
100
- "@depict-ai/ui": "^1.0.1",
101
- "@depict-ai/utilishared": "^1.0.1",
99
+ "@depict-ai/dpc": "^1.0.3",
100
+ "@depict-ai/plp-styling": "^1.0.3",
101
+ "@depict-ai/ui": "^1.0.3",
102
+ "@depict-ai/utilishared": "^1.0.3",
102
103
  "solid-js": "^1.7.3"
103
104
  },
104
105
  "peerDependencies": {
@@ -111,7 +112,7 @@
111
112
  "@babel/preset-typescript": "latest",
112
113
  "@babel/runtime": "latest",
113
114
  "@babel/runtime-corejs3": "latest",
114
- "@depict-ai/plp-styling": "^1.0.1",
115
+ "@depict-ai/plp-styling": "^1.0.3",
115
116
  "@jest/globals": "^29.3.1",
116
117
  "@parcel/babel-preset-env": "latest",
117
118
  "@parcel/resolver-default": "^2.8.0",