@depict-ai/ui 2.0.16 → 2.0.18

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/ES10/index.cjs CHANGED
@@ -72,7 +72,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $33eed84f447aa0c0$expo
72
72
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $33eed84f447aa0c0$export$7bf543b9d9be2c22);
73
73
  $parcel$export(module.exports, "version", () => $aa1938dec50d6c12$export$83d89fbfd8236492);
74
74
  /*! Depict.ai search and product listing SDK */
75
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.0.16";
75
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.0.18";
76
76
  const $d067f3a30f047b41$var$ListingContext = /*@__PURE__*/$52FdA$solidjs.createContext();
77
77
  function $d067f3a30f047b41$export$e68cff63f76bd15b(props) {
78
78
  const our_object = {};
@@ -182,6 +182,7 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
182
182
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
183
183
  // ensure we always have a size accessor
184
184
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
185
+ createdSizeAccessor = true;
185
186
  setCurrentImageSize(() => $52FdA$solidjs.runWithOwner(owner, () => $858fdcf73148519f$export$e6fffe67d4cdd848(container)));
186
187
  });
187
188
  $52FdA$solidjs.onCleanup(() => {
@@ -446,6 +447,7 @@ function $b85edfec41cd3989$export$548d053aba053d79(display) {
446
447
  }
447
448
  return display.product_id;
448
449
  }
450
+ let $76012c4468a53d1f$var$printedCloneError = false;
449
451
  function $76012c4468a53d1f$export$7f8bd308237ab5a5(get_displays_) {
450
452
  const displays_by_key_ = $52FdA$solidjs.createMemo(() => {
451
453
  const displays = get_displays_();
@@ -490,7 +492,17 @@ function $76012c4468a53d1f$export$43f0fb951fcb0c54(_ref) {
490
492
  // (We don't want to re-render if nothing has changed)
491
493
  _ref2 => {
492
494
  let [merchant, market, display] = _ref2;
493
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
495
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
496
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
497
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
498
+ try {
499
+ display = structuredClone(display);
500
+ } catch (e) {
501
+ if (!$76012c4468a53d1f$var$printedCloneError) {
502
+ $76012c4468a53d1f$var$printedCloneError = true;
503
+ $52FdA$depictaiutilishared.dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
504
+ }
505
+ }
494
506
  return product_card_template_(display, {
495
507
  set_on_index_change: fn => $52FdA$solidjs.runWithOwner(owner, () => $52FdA$solidjs.createEffect(() => fn(index()))),
496
508
  merchant: merchant,
package/ES10/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import { CategorySuggestion, SearchSuggestionsResponse } from "@depict-ai/types/
7
7
  import { BaseSearchRequest } from "@depict-ai/types/api/BaseSearchRequest";
8
8
  import { SearchSuggestionsRequest } from "@depict-ai/types/api/SearchSuggestionsRequest";
9
9
  import { ProductListingRequest } from "@depict-ai/types/api/ProductListingRequest";
10
- export const version = "2.0.16";
10
+ export const version = "2.0.18";
11
11
  /**
12
12
  * Provider to wrap every listing (group of products) in
13
13
  * Used for example for deduplicating ResizeObservers for responsive images
@@ -47,10 +47,12 @@ export function ShopifyResponsiveImg(props: {
47
47
  }): HTMLImageElement;
48
48
  export const shopifyContainedImageContextSymbol: unique symbol;
49
49
  /**
50
- * Abstraction built on top of ShopifyResponsiveImg
51
- * @param src TODO
52
- * @param aspectRatio
53
- * @constructor
50
+ * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
51
+ * Will return a div of the provided aspect ratio that always has the same size, to avoid content layout shift. Will then put the image inside of the container once it loads.
52
+ * Also makes a responsive image without you having to do anything: uses shopify's CDN which picks the best image format to resize the image to the size of the first image container in a certain listing.
53
+ * This works because the listings (recs, search, plp) all are wrapped in `<ListingProvider>`'s. This means all components rendered within can use `useListing` to get an object to write data to that will be the same for all components rendered within that listing. The first instance of this component rendered within a listing puts a ResizeObserver on its div and the other components then just set the sizes attribute of their image to that.
54
+ * @property src image source
55
+ * @property aspectRatio aspect ratio of the image
54
56
  */
55
57
  export function ShopifyContainedImage(props: {
56
58
  src: string;
package/ES10/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { add_to_version_info as $8tj43$add_to_version_info, queueMacroTask as $8tj43$queueMacroTask, catchify as $8tj43$catchify, is_safari as $8tj43$is_safari, observer as $8tj43$observer, Amazing_Slider as $8tj43$Amazing_Slider, slider_snap_css as $8tj43$slider_snap_css, slider_fading_factory as $8tj43$slider_fading_factory, slider_fractional_factory as $8tj43$slider_fractional_factory, camelCasifyObject as $8tj43$camelCasifyObject, make_random_classname as $8tj43$make_random_classname, n_col_styling_with_dist as $8tj43$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $8tj43$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $8tj43$layout_get_total_rec_amount_for_row, layout_media_query_header as $8tj43$layout_media_query_header, report as $8tj43$report, useExpandingContainer as $8tj43$useExpandingContainer, standard_price_format as $8tj43$standard_price_format, dlog as $8tj43$dlog, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, javascript_media_query as $8tj43$javascript_media_query, fetch_recs as $8tj43$fetch_recs, snakeCasifyObject as $8tj43$snakeCasifyObject, instant_exec_on_suspect_history_change as $8tj43$instant_exec_on_suspect_history_change, base_url as $8tj43$base_url, get_depict_id as $8tj43$get_depict_id, get_user_id as $8tj43$get_user_id, get_session_id as $8tj43$get_session_id, make_url_with_query_params as $8tj43$make_url_with_query_params, fetch_retry as $8tj43$fetch_retry, add_version_query_params as $8tj43$add_version_query_params, dwarn as $8tj43$dwarn, sort_obj as $8tj43$sort_obj, edit_current_page_meta_tags as $8tj43$edit_current_page_meta_tags, use_href_accessor as $8tj43$use_href_accessor, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, is_debug as $8tj43$is_debug, make_asyncIterable_exiter as $8tj43$make_asyncIterable_exiter, href_change_ipns as $8tj43$href_change_ipns, ContainedImage as $8tj43$ContainedImage, buildThresholdList as $8tj43$buildThresholdList, deparallelize_no_drop as $8tj43$deparallelize_no_drop, ListenableSet as $8tj43$ListenableSet, insert_surfaces as $8tj43$insert_surfaces } from "@depict-ai/utilishared/ES10";
1
+ import { add_to_version_info as $8tj43$add_to_version_info, queueMacroTask as $8tj43$queueMacroTask, catchify as $8tj43$catchify, is_safari as $8tj43$is_safari, observer as $8tj43$observer, Amazing_Slider as $8tj43$Amazing_Slider, slider_snap_css as $8tj43$slider_snap_css, slider_fading_factory as $8tj43$slider_fading_factory, slider_fractional_factory as $8tj43$slider_fractional_factory, dlog as $8tj43$dlog, camelCasifyObject as $8tj43$camelCasifyObject, make_random_classname as $8tj43$make_random_classname, n_col_styling_with_dist as $8tj43$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $8tj43$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $8tj43$layout_get_total_rec_amount_for_row, layout_media_query_header as $8tj43$layout_media_query_header, report as $8tj43$report, useExpandingContainer as $8tj43$useExpandingContainer, standard_price_format as $8tj43$standard_price_format, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, javascript_media_query as $8tj43$javascript_media_query, fetch_recs as $8tj43$fetch_recs, snakeCasifyObject as $8tj43$snakeCasifyObject, instant_exec_on_suspect_history_change as $8tj43$instant_exec_on_suspect_history_change, base_url as $8tj43$base_url, get_depict_id as $8tj43$get_depict_id, get_user_id as $8tj43$get_user_id, get_session_id as $8tj43$get_session_id, make_url_with_query_params as $8tj43$make_url_with_query_params, fetch_retry as $8tj43$fetch_retry, add_version_query_params as $8tj43$add_version_query_params, dwarn as $8tj43$dwarn, sort_obj as $8tj43$sort_obj, edit_current_page_meta_tags as $8tj43$edit_current_page_meta_tags, use_href_accessor as $8tj43$use_href_accessor, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, is_debug as $8tj43$is_debug, make_asyncIterable_exiter as $8tj43$make_asyncIterable_exiter, href_change_ipns as $8tj43$href_change_ipns, ContainedImage as $8tj43$ContainedImage, buildThresholdList as $8tj43$buildThresholdList, deparallelize_no_drop as $8tj43$deparallelize_no_drop, ListenableSet as $8tj43$ListenableSet, insert_surfaces as $8tj43$insert_surfaces } from "@depict-ai/utilishared/ES10";
2
2
  import { createComponent as $8tj43$createComponent, template as $8tj43$template, getNextElement as $8tj43$getNextElement, effect as $8tj43$effect, style as $8tj43$style, spread as $8tj43$spread, mergeProps as $8tj43$mergeProps, runHydrationEvents as $8tj43$runHydrationEvents, insert as $8tj43$insert, setAttribute as $8tj43$setAttribute, isServer as $8tj43$isServer, addEventListener as $8tj43$addEventListener, className as $8tj43$className, memo as $8tj43$memo, delegateEvents as $8tj43$delegateEvents, classList as $8tj43$classList, getNextMarker as $8tj43$getNextMarker, Dynamic as $8tj43$Dynamic, use as $8tj43$use } from "solid-js/web";
3
3
  import { createSignal as $8tj43$createSignal, getOwner as $8tj43$getOwner, createEffect as $8tj43$createEffect, runWithOwner as $8tj43$runWithOwner, onCleanup as $8tj43$onCleanup, createMemo as $8tj43$createMemo, createContext as $8tj43$createContext, useContext as $8tj43$useContext, createResource as $8tj43$createResource, Suspense as $8tj43$Suspense, Show as $8tj43$Show, createRenderEffect as $8tj43$createRenderEffect, createRoot as $8tj43$createRoot, For as $8tj43$For, createUniqueId as $8tj43$createUniqueId, untrack as $8tj43$untrack, createComputed as $8tj43$createComputed, ErrorBoundary as $8tj43$ErrorBoundary, Index as $8tj43$Index, on as $8tj43$on, batch as $8tj43$batch, createReaction as $8tj43$createReaction } from "solid-js";
4
4
  import $8tj43$babelruntimehelpersclassPrivateFieldSet from "@babel/runtime/helpers/classPrivateFieldSet";
@@ -8,7 +8,7 @@ import $8tj43$babelruntimehelpersdefineProperty from "@babel/runtime/helpers/def
8
8
  /*! Depict.ai search and product listing SDK */
9
9
  import { register_es_version } from "../multi_import_deduplicator.mjs";
10
10
  register_es_version("ui", "ES10");
11
- const $8db9a15135765c11$export$83d89fbfd8236492 = "2.0.16";
11
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "2.0.18";
12
12
  const $5441862cd2f5e111$var$ListingContext = /*@__PURE__*/$8tj43$createContext();
13
13
  function $5441862cd2f5e111$export$e68cff63f76bd15b(props) {
14
14
  const our_object = {};
@@ -118,6 +118,7 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
118
118
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
119
119
  // ensure we always have a size accessor
120
120
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
121
+ createdSizeAccessor = true;
121
122
  setCurrentImageSize(() => $8tj43$runWithOwner(owner, () => $56047603f9d212b6$export$e6fffe67d4cdd848(container)));
122
123
  });
123
124
  $8tj43$onCleanup(() => {
@@ -382,6 +383,7 @@ function $6a4c7ed6d005505c$export$548d053aba053d79(display) {
382
383
  }
383
384
  return display.product_id;
384
385
  }
386
+ let $2d7bad8684bc7f44$var$printedCloneError = false;
385
387
  function $2d7bad8684bc7f44$export$7f8bd308237ab5a5(get_displays_) {
386
388
  const displays_by_key_ = $8tj43$createMemo(() => {
387
389
  const displays = get_displays_();
@@ -426,7 +428,17 @@ function $2d7bad8684bc7f44$export$43f0fb951fcb0c54(_ref) {
426
428
  // (We don't want to re-render if nothing has changed)
427
429
  _ref2 => {
428
430
  let [merchant, market, display] = _ref2;
429
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
431
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
432
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
433
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
434
+ try {
435
+ display = structuredClone(display);
436
+ } catch (e) {
437
+ if (!$2d7bad8684bc7f44$var$printedCloneError) {
438
+ $2d7bad8684bc7f44$var$printedCloneError = true;
439
+ $8tj43$dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
440
+ }
441
+ }
430
442
  return product_card_template_(display, {
431
443
  set_on_index_change: fn => $8tj43$runWithOwner(owner, () => $8tj43$createEffect(() => fn(index()))),
432
444
  merchant: merchant,
package/latest/index.cjs CHANGED
@@ -66,7 +66,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $a3280f0aad997933$expo
66
66
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $a3280f0aad997933$export$7bf543b9d9be2c22);
67
67
  $parcel$export(module.exports, "version", () => $b757f75811f3261f$export$83d89fbfd8236492);
68
68
  /*! Depict.ai search and product listing SDK */
69
- const $b757f75811f3261f$export$83d89fbfd8236492 = "2.0.16";
69
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "2.0.18";
70
70
  const $84798aaa863a4909$var$ListingContext = /*@__PURE__*/$gVhhF$solidjs.createContext();
71
71
  function $84798aaa863a4909$export$e68cff63f76bd15b(props) {
72
72
  const our_object = {};
@@ -173,6 +173,7 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
173
173
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
174
174
  // ensure we always have a size accessor
175
175
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
176
+ createdSizeAccessor = true;
176
177
  setCurrentImageSize(() => $gVhhF$solidjs.runWithOwner(owner, () => $19950faaac026e09$export$e6fffe67d4cdd848(container)));
177
178
  });
178
179
  $gVhhF$solidjs.onCleanup(() => {
@@ -417,6 +418,7 @@ function $a5871dacf261adf8$export$548d053aba053d79(display) {
417
418
  }
418
419
  return display.product_id;
419
420
  }
421
+ let $a73063cc642f3e5f$var$printedCloneError = false;
420
422
  function $a73063cc642f3e5f$export$7f8bd308237ab5a5(get_displays_) {
421
423
  const displays_by_key_ = $gVhhF$solidjs.createMemo(() => {
422
424
  const displays = get_displays_();
@@ -459,7 +461,17 @@ function $a73063cc642f3e5f$export$43f0fb951fcb0c54({
459
461
  // re-render when the reference to the display object changes or the merchant or market changes
460
462
  // (We don't want to re-render if nothing has changed)
461
463
  ([merchant, market, display]) => {
462
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
464
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
465
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
466
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
467
+ try {
468
+ display = structuredClone(display);
469
+ } catch (e) {
470
+ if (!$a73063cc642f3e5f$var$printedCloneError) {
471
+ $a73063cc642f3e5f$var$printedCloneError = true;
472
+ $gVhhF$depictaiutilishared.dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
473
+ }
474
+ }
463
475
  return product_card_template_(display, {
464
476
  set_on_index_change: fn => $gVhhF$solidjs.runWithOwner(owner, () => $gVhhF$solidjs.createEffect(() => fn(index()))),
465
477
  merchant: merchant,
package/latest/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import { CategorySuggestion, SearchSuggestionsResponse } from "@depict-ai/types/
7
7
  import { BaseSearchRequest } from "@depict-ai/types/api/BaseSearchRequest";
8
8
  import { SearchSuggestionsRequest } from "@depict-ai/types/api/SearchSuggestionsRequest";
9
9
  import { ProductListingRequest } from "@depict-ai/types/api/ProductListingRequest";
10
- export const version = "2.0.16";
10
+ export const version = "2.0.18";
11
11
  /**
12
12
  * Provider to wrap every listing (group of products) in
13
13
  * Used for example for deduplicating ResizeObservers for responsive images
@@ -47,10 +47,12 @@ export function ShopifyResponsiveImg(props: {
47
47
  }): HTMLImageElement;
48
48
  export const shopifyContainedImageContextSymbol: unique symbol;
49
49
  /**
50
- * Abstraction built on top of ShopifyResponsiveImg
51
- * @param src TODO
52
- * @param aspectRatio
53
- * @constructor
50
+ * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
51
+ * Will return a div of the provided aspect ratio that always has the same size, to avoid content layout shift. Will then put the image inside of the container once it loads.
52
+ * Also makes a responsive image without you having to do anything: uses shopify's CDN which picks the best image format to resize the image to the size of the first image container in a certain listing.
53
+ * This works because the listings (recs, search, plp) all are wrapped in `<ListingProvider>`'s. This means all components rendered within can use `useListing` to get an object to write data to that will be the same for all components rendered within that listing. The first instance of this component rendered within a listing puts a ResizeObserver on its div and the other components then just set the sizes attribute of their image to that.
54
+ * @property src image source
55
+ * @property aspectRatio aspect ratio of the image
54
56
  */
55
57
  export function ShopifyContainedImage(props: {
56
58
  src: string;
package/latest/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { add_to_version_info as $9HbP8$add_to_version_info, queueMacroTask as $9HbP8$queueMacroTask, catchify as $9HbP8$catchify, is_safari as $9HbP8$is_safari, observer as $9HbP8$observer, Amazing_Slider as $9HbP8$Amazing_Slider, slider_snap_css as $9HbP8$slider_snap_css, slider_fading_factory as $9HbP8$slider_fading_factory, slider_fractional_factory as $9HbP8$slider_fractional_factory, camelCasifyObject as $9HbP8$camelCasifyObject, make_random_classname as $9HbP8$make_random_classname, n_col_styling_with_dist as $9HbP8$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $9HbP8$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $9HbP8$layout_get_total_rec_amount_for_row, layout_media_query_header as $9HbP8$layout_media_query_header, report as $9HbP8$report, useExpandingContainer as $9HbP8$useExpandingContainer, standard_price_format as $9HbP8$standard_price_format, dlog as $9HbP8$dlog, hex_to_rgb as $9HbP8$hex_to_rgb, relative_luminance_from_rgb as $9HbP8$relative_luminance_from_rgb, javascript_media_query as $9HbP8$javascript_media_query, fetch_recs as $9HbP8$fetch_recs, snakeCasifyObject as $9HbP8$snakeCasifyObject, instant_exec_on_suspect_history_change as $9HbP8$instant_exec_on_suspect_history_change, base_url as $9HbP8$base_url, get_depict_id as $9HbP8$get_depict_id, get_user_id as $9HbP8$get_user_id, get_session_id as $9HbP8$get_session_id, sort_obj as $9HbP8$sort_obj, fetch_retry as $9HbP8$fetch_retry, add_version_query_params as $9HbP8$add_version_query_params, dwarn as $9HbP8$dwarn, make_url_with_query_params as $9HbP8$make_url_with_query_params, edit_current_page_meta_tags as $9HbP8$edit_current_page_meta_tags, use_href_accessor as $9HbP8$use_href_accessor, base64_encode_unicode as $9HbP8$base64_encode_unicode, base64_decode_unicode as $9HbP8$base64_decode_unicode, is_debug as $9HbP8$is_debug, make_asyncIterable_exiter as $9HbP8$make_asyncIterable_exiter, href_change_ipns as $9HbP8$href_change_ipns, ContainedImage as $9HbP8$ContainedImage, buildThresholdList as $9HbP8$buildThresholdList, deparallelize_no_drop as $9HbP8$deparallelize_no_drop, ListenableSet as $9HbP8$ListenableSet, insert_surfaces as $9HbP8$insert_surfaces } from "@depict-ai/utilishared/latest";
1
+ import { add_to_version_info as $9HbP8$add_to_version_info, queueMacroTask as $9HbP8$queueMacroTask, catchify as $9HbP8$catchify, is_safari as $9HbP8$is_safari, observer as $9HbP8$observer, Amazing_Slider as $9HbP8$Amazing_Slider, slider_snap_css as $9HbP8$slider_snap_css, slider_fading_factory as $9HbP8$slider_fading_factory, slider_fractional_factory as $9HbP8$slider_fractional_factory, dlog as $9HbP8$dlog, camelCasifyObject as $9HbP8$camelCasifyObject, make_random_classname as $9HbP8$make_random_classname, n_col_styling_with_dist as $9HbP8$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $9HbP8$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $9HbP8$layout_get_total_rec_amount_for_row, layout_media_query_header as $9HbP8$layout_media_query_header, report as $9HbP8$report, useExpandingContainer as $9HbP8$useExpandingContainer, standard_price_format as $9HbP8$standard_price_format, hex_to_rgb as $9HbP8$hex_to_rgb, relative_luminance_from_rgb as $9HbP8$relative_luminance_from_rgb, javascript_media_query as $9HbP8$javascript_media_query, fetch_recs as $9HbP8$fetch_recs, snakeCasifyObject as $9HbP8$snakeCasifyObject, instant_exec_on_suspect_history_change as $9HbP8$instant_exec_on_suspect_history_change, base_url as $9HbP8$base_url, get_depict_id as $9HbP8$get_depict_id, get_user_id as $9HbP8$get_user_id, get_session_id as $9HbP8$get_session_id, sort_obj as $9HbP8$sort_obj, fetch_retry as $9HbP8$fetch_retry, add_version_query_params as $9HbP8$add_version_query_params, dwarn as $9HbP8$dwarn, make_url_with_query_params as $9HbP8$make_url_with_query_params, edit_current_page_meta_tags as $9HbP8$edit_current_page_meta_tags, use_href_accessor as $9HbP8$use_href_accessor, base64_encode_unicode as $9HbP8$base64_encode_unicode, base64_decode_unicode as $9HbP8$base64_decode_unicode, is_debug as $9HbP8$is_debug, make_asyncIterable_exiter as $9HbP8$make_asyncIterable_exiter, href_change_ipns as $9HbP8$href_change_ipns, ContainedImage as $9HbP8$ContainedImage, buildThresholdList as $9HbP8$buildThresholdList, deparallelize_no_drop as $9HbP8$deparallelize_no_drop, ListenableSet as $9HbP8$ListenableSet, insert_surfaces as $9HbP8$insert_surfaces } from "@depict-ai/utilishared/latest";
2
2
  import { createComponent as $9HbP8$createComponent, template as $9HbP8$template, getNextElement as $9HbP8$getNextElement, effect as $9HbP8$effect, style as $9HbP8$style, spread as $9HbP8$spread, mergeProps as $9HbP8$mergeProps, runHydrationEvents as $9HbP8$runHydrationEvents, insert as $9HbP8$insert, setAttribute as $9HbP8$setAttribute, isServer as $9HbP8$isServer, addEventListener as $9HbP8$addEventListener, className as $9HbP8$className, memo as $9HbP8$memo, delegateEvents as $9HbP8$delegateEvents, classList as $9HbP8$classList, getNextMarker as $9HbP8$getNextMarker, Dynamic as $9HbP8$Dynamic, use as $9HbP8$use } from "solid-js/web";
3
3
  import { createSignal as $9HbP8$createSignal, getOwner as $9HbP8$getOwner, createEffect as $9HbP8$createEffect, runWithOwner as $9HbP8$runWithOwner, onCleanup as $9HbP8$onCleanup, createMemo as $9HbP8$createMemo, createContext as $9HbP8$createContext, useContext as $9HbP8$useContext, createResource as $9HbP8$createResource, Suspense as $9HbP8$Suspense, Show as $9HbP8$Show, createRenderEffect as $9HbP8$createRenderEffect, createRoot as $9HbP8$createRoot, For as $9HbP8$For, createUniqueId as $9HbP8$createUniqueId, untrack as $9HbP8$untrack, createComputed as $9HbP8$createComputed, ErrorBoundary as $9HbP8$ErrorBoundary, Index as $9HbP8$Index, on as $9HbP8$on, batch as $9HbP8$batch, createReaction as $9HbP8$createReaction } from "solid-js";
4
4
 
5
5
  /*! Depict.ai search and product listing SDK */
6
6
  import { register_es_version } from "../multi_import_deduplicator.mjs";
7
7
  register_es_version("ui", "latest");
8
- const $ec291e0010116877$export$83d89fbfd8236492 = "2.0.16";
8
+ const $ec291e0010116877$export$83d89fbfd8236492 = "2.0.18";
9
9
  const $011607bdf658f807$var$ListingContext = /*@__PURE__*/$9HbP8$createContext();
10
10
  function $011607bdf658f807$export$e68cff63f76bd15b(props) {
11
11
  const our_object = {};
@@ -112,6 +112,7 @@ function $660070e2a394b3c3$export$e4b984597b71e989(props) {
112
112
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
113
113
  // ensure we always have a size accessor
114
114
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
115
+ createdSizeAccessor = true;
115
116
  setCurrentImageSize(() => $9HbP8$runWithOwner(owner, () => $e8ffe11ed01df0fe$export$e6fffe67d4cdd848(container)));
116
117
  });
117
118
  $9HbP8$onCleanup(() => {
@@ -356,6 +357,7 @@ function $16351e4c87b90b3d$export$548d053aba053d79(display) {
356
357
  }
357
358
  return display.product_id;
358
359
  }
360
+ let $29ec7cddbe1d3484$var$printedCloneError = false;
359
361
  function $29ec7cddbe1d3484$export$7f8bd308237ab5a5(get_displays_) {
360
362
  const displays_by_key_ = $9HbP8$createMemo(() => {
361
363
  const displays = get_displays_();
@@ -398,7 +400,17 @@ function $29ec7cddbe1d3484$export$43f0fb951fcb0c54({
398
400
  // re-render when the reference to the display object changes or the merchant or market changes
399
401
  // (We don't want to re-render if nothing has changed)
400
402
  ([merchant, market, display]) => {
401
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
403
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
404
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
405
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
406
+ try {
407
+ display = structuredClone(display);
408
+ } catch (e) {
409
+ if (!$29ec7cddbe1d3484$var$printedCloneError) {
410
+ $29ec7cddbe1d3484$var$printedCloneError = true;
411
+ $9HbP8$dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
412
+ }
413
+ }
402
414
  return product_card_template_(display, {
403
415
  set_on_index_change: fn => $9HbP8$runWithOwner(owner, () => $9HbP8$createEffect(() => fn(index()))),
404
416
  merchant: merchant,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depict-ai/ui",
3
- "version": "2.0.16",
3
+ "version": "2.0.18",
4
4
  "description": "Base package containing the actual UI of Depict UI along with translations, with a not-simplified API. We recommend using @depict-ai/js-ui or @depict-ai/react-ui instead.",
5
5
  "packageManager": "yarn@3.2.2",
6
6
  "sass": "styles.scss",
@@ -72,7 +72,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $33eed84f447aa0c0$expo
72
72
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $33eed84f447aa0c0$export$7bf543b9d9be2c22);
73
73
  $parcel$export(module.exports, "version", () => $aa1938dec50d6c12$export$83d89fbfd8236492);
74
74
  /*! Depict.ai search and product listing SDK */
75
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.0.16";
75
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.0.18";
76
76
  const $d067f3a30f047b41$var$ListingContext = /*@__PURE__*/$3hooq$solidjs.createContext();
77
77
  function $d067f3a30f047b41$export$e68cff63f76bd15b(props) {
78
78
  const our_object = {};
@@ -172,6 +172,7 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
172
172
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
173
173
  // ensure we always have a size accessor
174
174
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
175
+ createdSizeAccessor = true;
175
176
  setCurrentImageSize(() => $3hooq$solidjs.runWithOwner(owner, () => $858fdcf73148519f$export$e6fffe67d4cdd848(container)));
176
177
  });
177
178
  $3hooq$solidjs.onCleanup(() => {
@@ -415,6 +416,7 @@ function $b85edfec41cd3989$export$548d053aba053d79(display) {
415
416
  }
416
417
  return display.product_id;
417
418
  }
419
+ let $76012c4468a53d1f$var$printedCloneError = false;
418
420
  function $76012c4468a53d1f$export$7f8bd308237ab5a5(get_displays_) {
419
421
  const displays_by_key_ = $3hooq$solidjs.createMemo(() => {
420
422
  const displays = get_displays_();
@@ -459,7 +461,17 @@ function $76012c4468a53d1f$export$43f0fb951fcb0c54(_ref) {
459
461
  // (We don't want to re-render if nothing has changed)
460
462
  _ref2 => {
461
463
  let [merchant, market, display] = _ref2;
462
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
464
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
465
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
466
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
467
+ try {
468
+ display = structuredClone(display);
469
+ } catch (e) {
470
+ if (!$76012c4468a53d1f$var$printedCloneError) {
471
+ $76012c4468a53d1f$var$printedCloneError = true;
472
+ $3hooq$depictaiutilishared.dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
473
+ }
474
+ }
463
475
  return product_card_template_(display, {
464
476
  set_on_index_change: fn => $3hooq$solidjs.runWithOwner(owner, () => $3hooq$solidjs.createEffect(() => fn(index()))),
465
477
  merchant: merchant,
@@ -7,7 +7,7 @@ import { CategorySuggestion, SearchSuggestionsResponse } from "@depict-ai/types/
7
7
  import { BaseSearchRequest } from "@depict-ai/types/api/BaseSearchRequest";
8
8
  import { SearchSuggestionsRequest } from "@depict-ai/types/api/SearchSuggestionsRequest";
9
9
  import { ProductListingRequest } from "@depict-ai/types/api/ProductListingRequest";
10
- export const version = "2.0.16";
10
+ export const version = "2.0.18";
11
11
  /**
12
12
  * Provider to wrap every listing (group of products) in
13
13
  * Used for example for deduplicating ResizeObservers for responsive images
@@ -47,10 +47,12 @@ export function ShopifyResponsiveImg(props: {
47
47
  }): HTMLImageElement;
48
48
  export const shopifyContainedImageContextSymbol: unique symbol;
49
49
  /**
50
- * Abstraction built on top of ShopifyResponsiveImg
51
- * @param src TODO
52
- * @param aspectRatio
53
- * @constructor
50
+ * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
51
+ * Will return a div of the provided aspect ratio that always has the same size, to avoid content layout shift. Will then put the image inside of the container once it loads.
52
+ * Also makes a responsive image without you having to do anything: uses shopify's CDN which picks the best image format to resize the image to the size of the first image container in a certain listing.
53
+ * This works because the listings (recs, search, plp) all are wrapped in `<ListingProvider>`'s. This means all components rendered within can use `useListing` to get an object to write data to that will be the same for all components rendered within that listing. The first instance of this component rendered within a listing puts a ResizeObserver on its div and the other components then just set the sizes attribute of their image to that.
54
+ * @property src image source
55
+ * @property aspectRatio aspect ratio of the image
54
56
  */
55
57
  export function ShopifyContainedImage(props: {
56
58
  src: string;
@@ -1,4 +1,4 @@
1
- import { add_to_version_info as $b8hua$add_to_version_info, queueMacroTask as $b8hua$queueMacroTask, catchify as $b8hua$catchify, is_safari as $b8hua$is_safari, observer as $b8hua$observer, Amazing_Slider as $b8hua$Amazing_Slider, slider_snap_css as $b8hua$slider_snap_css, slider_fading_factory as $b8hua$slider_fading_factory, slider_fractional_factory as $b8hua$slider_fractional_factory, camelCasifyObject as $b8hua$camelCasifyObject, make_random_classname as $b8hua$make_random_classname, n_col_styling_with_dist as $b8hua$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $b8hua$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $b8hua$layout_get_total_rec_amount_for_row, layout_media_query_header as $b8hua$layout_media_query_header, report as $b8hua$report, useExpandingContainer as $b8hua$useExpandingContainer, standard_price_format as $b8hua$standard_price_format, dlog as $b8hua$dlog, hex_to_rgb as $b8hua$hex_to_rgb, relative_luminance_from_rgb as $b8hua$relative_luminance_from_rgb, javascript_media_query as $b8hua$javascript_media_query, fetch_recs as $b8hua$fetch_recs, snakeCasifyObject as $b8hua$snakeCasifyObject, instant_exec_on_suspect_history_change as $b8hua$instant_exec_on_suspect_history_change, base_url as $b8hua$base_url, get_depict_id as $b8hua$get_depict_id, get_user_id as $b8hua$get_user_id, get_session_id as $b8hua$get_session_id, make_url_with_query_params as $b8hua$make_url_with_query_params, fetch_retry as $b8hua$fetch_retry, add_version_query_params as $b8hua$add_version_query_params, dwarn as $b8hua$dwarn, sort_obj as $b8hua$sort_obj, edit_current_page_meta_tags as $b8hua$edit_current_page_meta_tags, use_href_accessor as $b8hua$use_href_accessor, base64_encode_unicode as $b8hua$base64_encode_unicode, base64_decode_unicode as $b8hua$base64_decode_unicode, make_asyncIterable_exiter as $b8hua$make_asyncIterable_exiter, href_change_ipns as $b8hua$href_change_ipns, ContainedImage as $b8hua$ContainedImage, deparallelize_no_drop as $b8hua$deparallelize_no_drop, ListenableSet as $b8hua$ListenableSet, insert_surfaces as $b8hua$insert_surfaces } from "@depict-ai/utilishared/ES10";
1
+ import { add_to_version_info as $b8hua$add_to_version_info, queueMacroTask as $b8hua$queueMacroTask, catchify as $b8hua$catchify, is_safari as $b8hua$is_safari, observer as $b8hua$observer, Amazing_Slider as $b8hua$Amazing_Slider, slider_snap_css as $b8hua$slider_snap_css, slider_fading_factory as $b8hua$slider_fading_factory, slider_fractional_factory as $b8hua$slider_fractional_factory, dlog as $b8hua$dlog, camelCasifyObject as $b8hua$camelCasifyObject, make_random_classname as $b8hua$make_random_classname, n_col_styling_with_dist as $b8hua$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $b8hua$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $b8hua$layout_get_total_rec_amount_for_row, layout_media_query_header as $b8hua$layout_media_query_header, report as $b8hua$report, useExpandingContainer as $b8hua$useExpandingContainer, standard_price_format as $b8hua$standard_price_format, hex_to_rgb as $b8hua$hex_to_rgb, relative_luminance_from_rgb as $b8hua$relative_luminance_from_rgb, javascript_media_query as $b8hua$javascript_media_query, fetch_recs as $b8hua$fetch_recs, snakeCasifyObject as $b8hua$snakeCasifyObject, instant_exec_on_suspect_history_change as $b8hua$instant_exec_on_suspect_history_change, base_url as $b8hua$base_url, get_depict_id as $b8hua$get_depict_id, get_user_id as $b8hua$get_user_id, get_session_id as $b8hua$get_session_id, make_url_with_query_params as $b8hua$make_url_with_query_params, fetch_retry as $b8hua$fetch_retry, add_version_query_params as $b8hua$add_version_query_params, dwarn as $b8hua$dwarn, sort_obj as $b8hua$sort_obj, edit_current_page_meta_tags as $b8hua$edit_current_page_meta_tags, use_href_accessor as $b8hua$use_href_accessor, base64_encode_unicode as $b8hua$base64_encode_unicode, base64_decode_unicode as $b8hua$base64_decode_unicode, make_asyncIterable_exiter as $b8hua$make_asyncIterable_exiter, href_change_ipns as $b8hua$href_change_ipns, ContainedImage as $b8hua$ContainedImage, deparallelize_no_drop as $b8hua$deparallelize_no_drop, ListenableSet as $b8hua$ListenableSet, insert_surfaces as $b8hua$insert_surfaces } from "@depict-ai/utilishared/ES10";
2
2
  import { createComponent as $b8hua$createComponent, ssr as $b8hua$ssr, ssrHydrationKey as $b8hua$ssrHydrationKey, ssrStyle as $b8hua$ssrStyle, ssrElement as $b8hua$ssrElement, escape as $b8hua$escape, insert as $b8hua$insert, ssrAttribute as $b8hua$ssrAttribute, mergeProps as $b8hua$mergeProps, isServer as $b8hua$isServer, ssrClassList as $b8hua$ssrClassList, Dynamic as $b8hua$Dynamic } from "solid-js/web";
3
3
  import { createSignal as $b8hua$createSignal, getOwner as $b8hua$getOwner, createEffect as $b8hua$createEffect, runWithOwner as $b8hua$runWithOwner, onCleanup as $b8hua$onCleanup, createMemo as $b8hua$createMemo, createContext as $b8hua$createContext, useContext as $b8hua$useContext, createResource as $b8hua$createResource, Suspense as $b8hua$Suspense, Show as $b8hua$Show, createRenderEffect as $b8hua$createRenderEffect, createRoot as $b8hua$createRoot, For as $b8hua$For, createUniqueId as $b8hua$createUniqueId, untrack as $b8hua$untrack, createComputed as $b8hua$createComputed, ErrorBoundary as $b8hua$ErrorBoundary, Index as $b8hua$Index, on as $b8hua$on, batch as $b8hua$batch, createReaction as $b8hua$createReaction } from "solid-js";
4
4
  import $b8hua$babelruntimehelpersclassPrivateFieldSet from "@babel/runtime/helpers/classPrivateFieldSet";
@@ -8,7 +8,7 @@ import $b8hua$babelruntimehelpersdefineProperty from "@babel/runtime/helpers/def
8
8
  /*! Depict.ai search and product listing SDK */
9
9
  import { register_es_version } from "../../multi_import_deduplicator.mjs";
10
10
  register_es_version("ui", "ES10");
11
- const $8db9a15135765c11$export$83d89fbfd8236492 = "2.0.16";
11
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "2.0.18";
12
12
  const $5441862cd2f5e111$var$ListingContext = /*@__PURE__*/$b8hua$createContext();
13
13
  function $5441862cd2f5e111$export$e68cff63f76bd15b(props) {
14
14
  const our_object = {};
@@ -108,6 +108,7 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
108
108
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
109
109
  // ensure we always have a size accessor
110
110
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
111
+ createdSizeAccessor = true;
111
112
  setCurrentImageSize(() => $b8hua$runWithOwner(owner, () => $56047603f9d212b6$export$e6fffe67d4cdd848(container)));
112
113
  });
113
114
  $b8hua$onCleanup(() => {
@@ -351,6 +352,7 @@ function $6a4c7ed6d005505c$export$548d053aba053d79(display) {
351
352
  }
352
353
  return display.product_id;
353
354
  }
355
+ let $2d7bad8684bc7f44$var$printedCloneError = false;
354
356
  function $2d7bad8684bc7f44$export$7f8bd308237ab5a5(get_displays_) {
355
357
  const displays_by_key_ = $b8hua$createMemo(() => {
356
358
  const displays = get_displays_();
@@ -395,7 +397,17 @@ function $2d7bad8684bc7f44$export$43f0fb951fcb0c54(_ref) {
395
397
  // (We don't want to re-render if nothing has changed)
396
398
  _ref2 => {
397
399
  let [merchant, market, display] = _ref2;
398
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
400
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
401
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
402
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
403
+ try {
404
+ display = structuredClone(display);
405
+ } catch (e) {
406
+ if (!$2d7bad8684bc7f44$var$printedCloneError) {
407
+ $2d7bad8684bc7f44$var$printedCloneError = true;
408
+ $b8hua$dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
409
+ }
410
+ }
399
411
  return product_card_template_(display, {
400
412
  set_on_index_change: fn => $b8hua$runWithOwner(owner, () => $b8hua$createEffect(() => fn(index()))),
401
413
  merchant: merchant,
@@ -66,7 +66,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $a3280f0aad997933$expo
66
66
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $a3280f0aad997933$export$7bf543b9d9be2c22);
67
67
  $parcel$export(module.exports, "version", () => $b757f75811f3261f$export$83d89fbfd8236492);
68
68
  /*! Depict.ai search and product listing SDK */
69
- const $b757f75811f3261f$export$83d89fbfd8236492 = "2.0.16";
69
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "2.0.18";
70
70
  const $84798aaa863a4909$var$ListingContext = /*@__PURE__*/$5vyXB$solidjs.createContext();
71
71
  function $84798aaa863a4909$export$e68cff63f76bd15b(props) {
72
72
  const our_object = {};
@@ -163,6 +163,7 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
163
163
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
164
164
  // ensure we always have a size accessor
165
165
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
166
+ createdSizeAccessor = true;
166
167
  setCurrentImageSize(() => $5vyXB$solidjs.runWithOwner(owner, () => $19950faaac026e09$export$e6fffe67d4cdd848(container)));
167
168
  });
168
169
  $5vyXB$solidjs.onCleanup(() => {
@@ -386,6 +387,7 @@ function $a5871dacf261adf8$export$548d053aba053d79(display) {
386
387
  }
387
388
  return display.product_id;
388
389
  }
390
+ let $a73063cc642f3e5f$var$printedCloneError = false;
389
391
  function $a73063cc642f3e5f$export$7f8bd308237ab5a5(get_displays_) {
390
392
  const displays_by_key_ = $5vyXB$solidjs.createMemo(() => {
391
393
  const displays = get_displays_();
@@ -428,7 +430,17 @@ function $a73063cc642f3e5f$export$43f0fb951fcb0c54({
428
430
  // re-render when the reference to the display object changes or the merchant or market changes
429
431
  // (We don't want to re-render if nothing has changed)
430
432
  ([merchant, market, display]) => {
431
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
433
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
434
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
435
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
436
+ try {
437
+ display = structuredClone(display);
438
+ } catch (e) {
439
+ if (!$a73063cc642f3e5f$var$printedCloneError) {
440
+ $a73063cc642f3e5f$var$printedCloneError = true;
441
+ $5vyXB$depictaiutilishared.dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
442
+ }
443
+ }
432
444
  return product_card_template_(display, {
433
445
  set_on_index_change: fn => $5vyXB$solidjs.runWithOwner(owner, () => $5vyXB$solidjs.createEffect(() => fn(index()))),
434
446
  merchant: merchant,
@@ -7,7 +7,7 @@ import { CategorySuggestion, SearchSuggestionsResponse } from "@depict-ai/types/
7
7
  import { BaseSearchRequest } from "@depict-ai/types/api/BaseSearchRequest";
8
8
  import { SearchSuggestionsRequest } from "@depict-ai/types/api/SearchSuggestionsRequest";
9
9
  import { ProductListingRequest } from "@depict-ai/types/api/ProductListingRequest";
10
- export const version = "2.0.16";
10
+ export const version = "2.0.18";
11
11
  /**
12
12
  * Provider to wrap every listing (group of products) in
13
13
  * Used for example for deduplicating ResizeObservers for responsive images
@@ -47,10 +47,12 @@ export function ShopifyResponsiveImg(props: {
47
47
  }): HTMLImageElement;
48
48
  export const shopifyContainedImageContextSymbol: unique symbol;
49
49
  /**
50
- * Abstraction built on top of ShopifyResponsiveImg
51
- * @param src TODO
52
- * @param aspectRatio
53
- * @constructor
50
+ * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
51
+ * Will return a div of the provided aspect ratio that always has the same size, to avoid content layout shift. Will then put the image inside of the container once it loads.
52
+ * Also makes a responsive image without you having to do anything: uses shopify's CDN which picks the best image format to resize the image to the size of the first image container in a certain listing.
53
+ * This works because the listings (recs, search, plp) all are wrapped in `<ListingProvider>`'s. This means all components rendered within can use `useListing` to get an object to write data to that will be the same for all components rendered within that listing. The first instance of this component rendered within a listing puts a ResizeObserver on its div and the other components then just set the sizes attribute of their image to that.
54
+ * @property src image source
55
+ * @property aspectRatio aspect ratio of the image
54
56
  */
55
57
  export function ShopifyContainedImage(props: {
56
58
  src: string;
@@ -1,11 +1,11 @@
1
- import { add_to_version_info as $i7OB2$add_to_version_info, queueMacroTask as $i7OB2$queueMacroTask, catchify as $i7OB2$catchify, is_safari as $i7OB2$is_safari, observer as $i7OB2$observer, Amazing_Slider as $i7OB2$Amazing_Slider, slider_snap_css as $i7OB2$slider_snap_css, slider_fading_factory as $i7OB2$slider_fading_factory, slider_fractional_factory as $i7OB2$slider_fractional_factory, camelCasifyObject as $i7OB2$camelCasifyObject, make_random_classname as $i7OB2$make_random_classname, n_col_styling_with_dist as $i7OB2$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $i7OB2$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $i7OB2$layout_get_total_rec_amount_for_row, layout_media_query_header as $i7OB2$layout_media_query_header, report as $i7OB2$report, useExpandingContainer as $i7OB2$useExpandingContainer, standard_price_format as $i7OB2$standard_price_format, dlog as $i7OB2$dlog, hex_to_rgb as $i7OB2$hex_to_rgb, relative_luminance_from_rgb as $i7OB2$relative_luminance_from_rgb, javascript_media_query as $i7OB2$javascript_media_query, fetch_recs as $i7OB2$fetch_recs, snakeCasifyObject as $i7OB2$snakeCasifyObject, instant_exec_on_suspect_history_change as $i7OB2$instant_exec_on_suspect_history_change, base_url as $i7OB2$base_url, get_depict_id as $i7OB2$get_depict_id, get_user_id as $i7OB2$get_user_id, get_session_id as $i7OB2$get_session_id, sort_obj as $i7OB2$sort_obj, fetch_retry as $i7OB2$fetch_retry, add_version_query_params as $i7OB2$add_version_query_params, dwarn as $i7OB2$dwarn, make_url_with_query_params as $i7OB2$make_url_with_query_params, edit_current_page_meta_tags as $i7OB2$edit_current_page_meta_tags, use_href_accessor as $i7OB2$use_href_accessor, base64_encode_unicode as $i7OB2$base64_encode_unicode, base64_decode_unicode as $i7OB2$base64_decode_unicode, make_asyncIterable_exiter as $i7OB2$make_asyncIterable_exiter, href_change_ipns as $i7OB2$href_change_ipns, ContainedImage as $i7OB2$ContainedImage, deparallelize_no_drop as $i7OB2$deparallelize_no_drop, ListenableSet as $i7OB2$ListenableSet, insert_surfaces as $i7OB2$insert_surfaces } from "@depict-ai/utilishared/latest";
1
+ import { add_to_version_info as $i7OB2$add_to_version_info, queueMacroTask as $i7OB2$queueMacroTask, catchify as $i7OB2$catchify, is_safari as $i7OB2$is_safari, observer as $i7OB2$observer, Amazing_Slider as $i7OB2$Amazing_Slider, slider_snap_css as $i7OB2$slider_snap_css, slider_fading_factory as $i7OB2$slider_fading_factory, slider_fractional_factory as $i7OB2$slider_fractional_factory, dlog as $i7OB2$dlog, camelCasifyObject as $i7OB2$camelCasifyObject, make_random_classname as $i7OB2$make_random_classname, n_col_styling_with_dist as $i7OB2$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $i7OB2$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $i7OB2$layout_get_total_rec_amount_for_row, layout_media_query_header as $i7OB2$layout_media_query_header, report as $i7OB2$report, useExpandingContainer as $i7OB2$useExpandingContainer, standard_price_format as $i7OB2$standard_price_format, hex_to_rgb as $i7OB2$hex_to_rgb, relative_luminance_from_rgb as $i7OB2$relative_luminance_from_rgb, javascript_media_query as $i7OB2$javascript_media_query, fetch_recs as $i7OB2$fetch_recs, snakeCasifyObject as $i7OB2$snakeCasifyObject, instant_exec_on_suspect_history_change as $i7OB2$instant_exec_on_suspect_history_change, base_url as $i7OB2$base_url, get_depict_id as $i7OB2$get_depict_id, get_user_id as $i7OB2$get_user_id, get_session_id as $i7OB2$get_session_id, sort_obj as $i7OB2$sort_obj, fetch_retry as $i7OB2$fetch_retry, add_version_query_params as $i7OB2$add_version_query_params, dwarn as $i7OB2$dwarn, make_url_with_query_params as $i7OB2$make_url_with_query_params, edit_current_page_meta_tags as $i7OB2$edit_current_page_meta_tags, use_href_accessor as $i7OB2$use_href_accessor, base64_encode_unicode as $i7OB2$base64_encode_unicode, base64_decode_unicode as $i7OB2$base64_decode_unicode, make_asyncIterable_exiter as $i7OB2$make_asyncIterable_exiter, href_change_ipns as $i7OB2$href_change_ipns, ContainedImage as $i7OB2$ContainedImage, deparallelize_no_drop as $i7OB2$deparallelize_no_drop, ListenableSet as $i7OB2$ListenableSet, insert_surfaces as $i7OB2$insert_surfaces } from "@depict-ai/utilishared/latest";
2
2
  import { createComponent as $i7OB2$createComponent, ssr as $i7OB2$ssr, ssrHydrationKey as $i7OB2$ssrHydrationKey, ssrStyle as $i7OB2$ssrStyle, ssrElement as $i7OB2$ssrElement, escape as $i7OB2$escape, insert as $i7OB2$insert, ssrAttribute as $i7OB2$ssrAttribute, mergeProps as $i7OB2$mergeProps, isServer as $i7OB2$isServer, ssrClassList as $i7OB2$ssrClassList, Dynamic as $i7OB2$Dynamic } from "solid-js/web";
3
3
  import { createSignal as $i7OB2$createSignal, getOwner as $i7OB2$getOwner, createEffect as $i7OB2$createEffect, runWithOwner as $i7OB2$runWithOwner, onCleanup as $i7OB2$onCleanup, createMemo as $i7OB2$createMemo, createContext as $i7OB2$createContext, useContext as $i7OB2$useContext, createResource as $i7OB2$createResource, Suspense as $i7OB2$Suspense, Show as $i7OB2$Show, createRenderEffect as $i7OB2$createRenderEffect, createRoot as $i7OB2$createRoot, For as $i7OB2$For, createUniqueId as $i7OB2$createUniqueId, untrack as $i7OB2$untrack, createComputed as $i7OB2$createComputed, ErrorBoundary as $i7OB2$ErrorBoundary, Index as $i7OB2$Index, on as $i7OB2$on, batch as $i7OB2$batch, createReaction as $i7OB2$createReaction } from "solid-js";
4
4
 
5
5
  /*! Depict.ai search and product listing SDK */
6
6
  import { register_es_version } from "../../multi_import_deduplicator.mjs";
7
7
  register_es_version("ui", "latest");
8
- const $ec291e0010116877$export$83d89fbfd8236492 = "2.0.16";
8
+ const $ec291e0010116877$export$83d89fbfd8236492 = "2.0.18";
9
9
  const $011607bdf658f807$var$ListingContext = /*@__PURE__*/$i7OB2$createContext();
10
10
  function $011607bdf658f807$export$e68cff63f76bd15b(props) {
11
11
  const our_object = {};
@@ -102,6 +102,7 @@ function $660070e2a394b3c3$export$e4b984597b71e989(props) {
102
102
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
103
103
  // ensure we always have a size accessor
104
104
  // what this whole thing does is set the sizes attribute to the actual size of one of the existing image containers, therefore the value doesn't have to manually be specified
105
+ createdSizeAccessor = true;
105
106
  setCurrentImageSize(() => $i7OB2$runWithOwner(owner, () => $e8ffe11ed01df0fe$export$e6fffe67d4cdd848(container)));
106
107
  });
107
108
  $i7OB2$onCleanup(() => {
@@ -325,6 +326,7 @@ function $16351e4c87b90b3d$export$548d053aba053d79(display) {
325
326
  }
326
327
  return display.product_id;
327
328
  }
329
+ let $29ec7cddbe1d3484$var$printedCloneError = false;
328
330
  function $29ec7cddbe1d3484$export$7f8bd308237ab5a5(get_displays_) {
329
331
  const displays_by_key_ = $i7OB2$createMemo(() => {
330
332
  const displays = get_displays_();
@@ -367,7 +369,17 @@ function $29ec7cddbe1d3484$export$43f0fb951fcb0c54({
367
369
  // re-render when the reference to the display object changes or the merchant or market changes
368
370
  // (We don't want to re-render if nothing has changed)
369
371
  ([merchant, market, display]) => {
370
- // get display in the function that re-runs when merchant or market have changed, since the display may have changed but product_id not
372
+ // It's easy for merchants to accidentally mutate the display or some sub-object thereof
373
+ // We had a case on singular where they popped an image url and due to use caching after some time there was no image
374
+ // Attempt cloning the displays if possible (99.9% of the cases probably) and if not, just use the original display
375
+ try {
376
+ display = structuredClone(display);
377
+ } catch (e) {
378
+ if (!$29ec7cddbe1d3484$var$printedCloneError) {
379
+ $29ec7cddbe1d3484$var$printedCloneError = true;
380
+ $i7OB2$dlog("Can't clone display", display, " (uncloneable objects in it), make sure you don't mutate it in the template since we cache.", e);
381
+ }
382
+ }
371
383
  return product_card_template_(display, {
372
384
  set_on_index_change: fn => $i7OB2$runWithOwner(owner, () => $i7OB2$createEffect(() => fn(index()))),
373
385
  merchant: merchant,