@depict-ai/ui 2.1.4 → 2.1.6

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
@@ -76,7 +76,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $33eed84f447aa0c0$expo
76
76
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $33eed84f447aa0c0$export$7bf543b9d9be2c22);
77
77
  $parcel$export(module.exports, "version", () => $aa1938dec50d6c12$export$83d89fbfd8236492);
78
78
  /*! Depict.ai search and product listing SDK */
79
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.1.4";
79
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "2.1.6";
80
80
  const $a68b73fd7ba0853f$var$fallback_operator = "in";
81
81
  const $a68b73fd7ba0853f$var$fallback_token = "";
82
82
  const $a68b73fd7ba0853f$var$legacy_filter_prefix = "filter_";
@@ -276,7 +276,6 @@ function $ce467edb5343cfcd$export$94026ee33dbabc26(props) {
276
276
  return _el$;
277
277
  })();
278
278
  }
279
- const $858fdcf73148519f$var$_tmpl$ = /*#__PURE__*/$52FdA$solidjsweb.template(`<img>`);
280
279
  function $858fdcf73148519f$export$e6fffe67d4cdd848(whatToWatch) {
281
280
  const [size, setSize] = $52FdA$solidjs.createSignal(0);
282
281
  const resizeObserver = new ResizeObserver($52FdA$depictaiutilishared.catchify(records => {
@@ -304,6 +303,7 @@ function $858fdcf73148519f$export$e6fffe67d4cdd848(whatToWatch) {
304
303
  });
305
304
  return size;
306
305
  }
306
+ const $858fdcf73148519f$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
307
307
  function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
308
308
  // Enable reactive props
309
309
  const otherOptions = $52FdA$solidjs.createMemo(() => {
@@ -326,16 +326,95 @@ function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
326
326
  srcset: srcset
327
327
  };
328
328
  });
329
- return (() => {
330
- const _el$ = $52FdA$solidjsweb.getNextElement($858fdcf73148519f$var$_tmpl$);
331
- $52FdA$solidjsweb.spread(_el$, $52FdA$solidjsweb.mergeProps(otherOptions, src_options, {
332
- get sizes() {
333
- return props.size() + "px";
329
+ // Work around https://github.com/solidjs/solid/issues/1828
330
+ const img = new Image(); // Need to use new Image or browser might not start loading image before it's in the DOM
331
+ const [hasSetSize, setHasSetSize] = $52FdA$solidjs.createSignal(false);
332
+ const [hasDecoded, setHasDecoded] = $52FdA$solidjs.createSignal(false);
333
+ const sizePX = $52FdA$solidjs.createMemo(() => "".concat(props.size(), "px")); // props.size could be a getter that expects a cleanup so get it in this memo instead of where we set img.sizes
334
+ const listingContext = $d067f3a30f047b41$export$8d0c4fdbb05a2f2e();
335
+ // Batch idle callbacks so that MutationObserver can batch the resulting mutations better, so we don't lose tons of CPU time to MutationObservers doing lots of things for each image
336
+ // Happened on singular, they have some weird observer (+we also have one but ours is at least 3x more efficient)
337
+ const executeWhenIdleBatched = fn => {
338
+ if (typeof requestIdleCallback !== "function") setTimeout(fn); // Old browsers don't get optimisation
339
+ const existingStack = listingContext === null || listingContext === void 0 ? void 0 : listingContext[$858fdcf73148519f$var$onIdleFunctionsSymbol];
340
+ if (existingStack) return existingStack.add(fn);
341
+ const newStack = new Set([fn]);
342
+ if (listingContext) listingContext[$858fdcf73148519f$var$onIdleFunctionsSymbol] = newStack;
343
+ const processStackWhenIdle = () => requestIdleCallback(deadline => {
344
+ const start = performance.now();
345
+ const thirdDeadlineTime = deadline.timeRemaining() / 3; // observers coming after this take up 2-3x the time so don't use all of it
346
+ for (const fn of newStack) {
347
+ newStack.delete(fn);
348
+ fn();
349
+ const timeTaken = performance.now() - start;
350
+ if ((!deadline.timeRemaining() || timeTaken > thirdDeadlineTime) && newStack.size) {
351
+ // There's still work to be done but no time, so schedule another idle callback
352
+ processStackWhenIdle();
353
+ return;
354
+ }
334
355
  }
335
- }), false, false);
336
- $52FdA$solidjsweb.runHydrationEvents();
337
- return _el$;
338
- })();
356
+ // Stack is empty
357
+ if (listingContext) delete listingContext[$858fdcf73148519f$var$onIdleFunctionsSymbol];
358
+ }, {
359
+ timeout: 15000
360
+ } // long timeout, better to not have images than to freeze the browser. But also we don't want to confuse user why no iamges are loading
361
+ );
362
+
363
+ processStackWhenIdle();
364
+ };
365
+ let sizeSetFastPath = false;
366
+ let hasDecodedFastPath = false;
367
+ let timeoutSet = false;
368
+ let gotCleanedUp = false;
369
+ $52FdA$solidjs.onCleanup(() => gotCleanedUp = true);
370
+ $52FdA$solidjsweb.spread(img, $52FdA$solidjs.mergeProps(otherOptions), false, true);
371
+ $52FdA$solidjs.createEffect(() => {
372
+ if (!props.size()) return; // wait until we have a size
373
+ if (timeoutSet) return;
374
+ const handler = $52FdA$depictaiutilishared.catchify(() => {
375
+ if (gotCleanedUp) return;
376
+ img.sizes = sizePX(); // use latest available value of props.size
377
+ if (!sizeSetFastPath) {
378
+ setHasSetSize(true);
379
+ sizeSetFastPath = true;
380
+ }
381
+ timeoutSet = false;
382
+ });
383
+ // Throttle the updating of sizes to avoid unnecessary image re-fetches during resize
384
+ // And also because we first set src after sizes has been set, wait with loading and decoding images until browser is idle
385
+ // This greatly improves performance when loading (more) products
386
+ // See https://depictaiworkspace.slack.com/archives/C05NJ0K3WRL/p1698220617663139
387
+ executeWhenIdleBatched(handler);
388
+ timeoutSet = true;
389
+ });
390
+ $52FdA$solidjs.createEffect(() => {
391
+ if (!props.size() || !hasSetSize()) return; // If size isn't known or set, don't assign src yet since it would cause the most low res image to load
392
+ Object.assign(img, src_options());
393
+ // Add to DOM once decoded to not require/block any paints before image has completed loading and avoid showing broken image symbol
394
+ // We can do this because there has to be a container around us giving us a size
395
+ // No need to listen if we're already in the DOM
396
+ if (hasDecodedFastPath) return;
397
+ if (props.loading === "lazy") {
398
+ // For lazy loading there's no decoding to wait for as it only occurs when the image is visible
399
+ // Make sure src is set before we put the image into the DOM though so no broken image symbol is shown
400
+ setHasDecoded(true);
401
+ hasDecodedFastPath = true;
402
+ }
403
+ img.decode().catch(e => $52FdA$depictaiutilishared.dwarn("Failed to decode image", e, img)) // Display the image also if loading failed so webdev can debug and doesn't get "no image"
404
+ .then(async () => {
405
+ // Also wait with inserting image (i.e. paint) until browser is idle
406
+ await new Promise(r => executeWhenIdleBatched(r));
407
+ if (gotCleanedUp) return;
408
+ setHasDecoded(true);
409
+ hasDecodedFastPath = true;
410
+ });
411
+ });
412
+ return $52FdA$solidjsweb.createComponent((0, $52FdA$solidjs.Show), {
413
+ get when() {
414
+ return hasDecoded();
415
+ },
416
+ children: img
417
+ });
339
418
  }
340
419
  function $858fdcf73148519f$var$make_srcset(url, resolutions) {
341
420
  return resolutions.map(width => "".concat($858fdcf73148519f$var$generateImageUrl(url, width), " ").concat(width, "w")).join(", ");
@@ -373,7 +452,7 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
373
452
  $52FdA$depictaiutilishared.queueMacroTask(() => setCurrentImageSize(undefined)); // unset the size accessor next event loop iteration, so that all onCleanup's have time to run, since the effects run more aggressively and can create a size accessor with a cleaned up owner otherwise
374
453
  });
375
454
 
376
- container.append($52FdA$solidjsweb.createComponent((0, $858fdcf73148519f$export$6e5611bc7e57e477), {
455
+ $52FdA$solidjsweb.insert(container, $52FdA$solidjsweb.createComponent((0, $858fdcf73148519f$export$6e5611bc7e57e477), {
377
456
  style: "width: 100%; height: 100%; object-fit: contain; position: absolute; inset: 0;",
378
457
  get size() {
379
458
  return $52FdA$solidjs.createMemo(() => {
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 { ProductListingRequestV2 } from "@depict-ai/types/api/ProductListingRequestV2";
10
- export const version = "2.1.4";
10
+ export const version = "2.1.6";
11
11
  /**
12
12
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
13
13
  */
@@ -152,17 +152,19 @@ export function ImageContainer(props: {
152
152
  export function makeSizeAccessor(whatToWatch: HTMLElement): Accessor<number>;
153
153
  /**
154
154
  * Automatically generate a srcset from the shopify CDN for an image and set the sizes attribute to the provided accessor.
155
+ * Will also delay loading and decoding of image until the browser is idle (with 5s timeout) to improve filtering/loading more performance.
155
156
  * This is used for our responsive images:
156
157
  * 1. The image must have a container with a fixed size (or aspect ratio) that is independent of the image. When aspectRatio is configured on the depict-cards element as data attribute, we will wrap the image in a ImageContainer for this. If it's false, the user has to provide this container themselves.
157
158
  * 2. We set a ResizeObserver on one of the currently visible images (see makeSizeAccessor)
158
159
  * 3. We set the size attribute of all the visible images to the size of the container we're observing. The point of this is that the sizes attribute is used to determine which image to load, and usually it's set by the user and depends on the relationship between image size and viewport size. By using a ResizeObserver, we can make sure the sizes attribute is always set to the correct value without it having to be configured. This will make so the browser always loads the correct image size for a crisp image but still fast load.
160
+ * You need to use insert(domNode, <ShopifyResponsiveImg size={sizeAccessor} src={src} />) if you want to insert the return value of this component into a DOM element manually, where you `import { insert } from "solid-js/web";` because we first want to insert the image once it has loaded.
159
161
  */
160
162
  export function ShopifyResponsiveImg(props: {
161
163
  resolutions?: number[];
162
164
  size: Accessor<number>;
163
165
  } & Omit<JSX.ImgHTMLAttributes<HTMLImageElement>, "srcset" | "src" | "sizes"> & {
164
166
  src: string;
165
- }): HTMLImageElement;
167
+ }): JSX.Element;
166
168
  export const shopifyContainedImageContextSymbol: unique symbol;
167
169
  /**
168
170
  * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
package/ES10/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { add_to_version_info as $8tj43$add_to_version_info, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, dlog as $8tj43$dlog, 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, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, 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, javascript_media_query as $8tj43$javascript_media_query, use_href_accessor as $8tj43$use_href_accessor, 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
- 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, setProperty as $8tj43$setProperty } from "solid-js/web";
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, untrack as $8tj43$untrack, createRenderEffect as $8tj43$createRenderEffect, Index as $8tj43$Index, createRoot as $8tj43$createRoot, For as $8tj43$For, createUniqueId as $8tj43$createUniqueId, createComputed as $8tj43$createComputed, ErrorBoundary as $8tj43$ErrorBoundary, on as $8tj43$on, batch as $8tj43$batch, createReaction as $8tj43$createReaction, mapArray as $8tj43$mapArray, mergeProps as $8tj43$mergeProps1 } from "solid-js";
1
+ import { add_to_version_info as $8tj43$add_to_version_info, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, dlog as $8tj43$dlog, queueMacroTask as $8tj43$queueMacroTask, catchify as $8tj43$catchify, is_safari as $8tj43$is_safari, observer as $8tj43$observer, dwarn as $8tj43$dwarn, 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, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, 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, sort_obj as $8tj43$sort_obj, edit_current_page_meta_tags as $8tj43$edit_current_page_meta_tags, javascript_media_query as $8tj43$javascript_media_query, use_href_accessor as $8tj43$use_href_accessor, 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
+ import { createComponent as $8tj43$createComponent, insert as $8tj43$insert, template as $8tj43$template, getNextElement as $8tj43$getNextElement, effect as $8tj43$effect, style as $8tj43$style, spread as $8tj43$spread, setAttribute as $8tj43$setAttribute, mergeProps as $8tj43$mergeProps1, isServer as $8tj43$isServer, runHydrationEvents as $8tj43$runHydrationEvents, 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, setProperty as $8tj43$setProperty } from "solid-js/web";
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, mergeProps as $8tj43$mergeProps, Show as $8tj43$Show, createResource as $8tj43$createResource, Suspense as $8tj43$Suspense, untrack as $8tj43$untrack, createRenderEffect as $8tj43$createRenderEffect, Index as $8tj43$Index, createRoot as $8tj43$createRoot, For as $8tj43$For, createUniqueId as $8tj43$createUniqueId, createComputed as $8tj43$createComputed, ErrorBoundary as $8tj43$ErrorBoundary, on as $8tj43$on, batch as $8tj43$batch, createReaction as $8tj43$createReaction, mapArray as $8tj43$mapArray } from "solid-js";
4
4
  import $8tj43$babelruntimehelpersclassPrivateFieldSet from "@babel/runtime/helpers/classPrivateFieldSet";
5
5
  import $8tj43$babelruntimehelpersclassPrivateFieldGet from "@babel/runtime/helpers/classPrivateFieldGet";
6
6
  import $8tj43$babelruntimehelpersdefineProperty from "@babel/runtime/helpers/defineProperty";
@@ -9,7 +9,7 @@ import { createStore as $8tj43$createStore, reconcile as $8tj43$reconcile } from
9
9
  /*! Depict.ai search and product listing SDK */
10
10
  import { register_es_version } from "../multi_import_deduplicator.mjs";
11
11
  register_es_version("ui", "ES10");
12
- const $8db9a15135765c11$export$83d89fbfd8236492 = "2.1.4";
12
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "2.1.6";
13
13
  const $2855bffe06ef7a03$var$fallback_operator = "in";
14
14
  const $2855bffe06ef7a03$var$fallback_token = "";
15
15
  const $2855bffe06ef7a03$var$legacy_filter_prefix = "filter_";
@@ -209,7 +209,6 @@ function $801e8845d3fa3653$export$94026ee33dbabc26(props) {
209
209
  return _el$;
210
210
  })();
211
211
  }
212
- const $56047603f9d212b6$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<img>`);
213
212
  function $56047603f9d212b6$export$e6fffe67d4cdd848(whatToWatch) {
214
213
  const [size, setSize] = $8tj43$createSignal(0);
215
214
  const resizeObserver = new ResizeObserver($8tj43$catchify(records => {
@@ -237,6 +236,7 @@ function $56047603f9d212b6$export$e6fffe67d4cdd848(whatToWatch) {
237
236
  });
238
237
  return size;
239
238
  }
239
+ const $56047603f9d212b6$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
240
240
  function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
241
241
  // Enable reactive props
242
242
  const otherOptions = $8tj43$createMemo(() => {
@@ -259,16 +259,95 @@ function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
259
259
  srcset: srcset
260
260
  };
261
261
  });
262
- return (() => {
263
- const _el$ = $8tj43$getNextElement($56047603f9d212b6$var$_tmpl$);
264
- $8tj43$spread(_el$, $8tj43$mergeProps(otherOptions, src_options, {
265
- get sizes() {
266
- return props.size() + "px";
262
+ // Work around https://github.com/solidjs/solid/issues/1828
263
+ const img = new Image(); // Need to use new Image or browser might not start loading image before it's in the DOM
264
+ const [hasSetSize, setHasSetSize] = $8tj43$createSignal(false);
265
+ const [hasDecoded, setHasDecoded] = $8tj43$createSignal(false);
266
+ const sizePX = $8tj43$createMemo(() => "".concat(props.size(), "px")); // props.size could be a getter that expects a cleanup so get it in this memo instead of where we set img.sizes
267
+ const listingContext = $5441862cd2f5e111$export$8d0c4fdbb05a2f2e();
268
+ // Batch idle callbacks so that MutationObserver can batch the resulting mutations better, so we don't lose tons of CPU time to MutationObservers doing lots of things for each image
269
+ // Happened on singular, they have some weird observer (+we also have one but ours is at least 3x more efficient)
270
+ const executeWhenIdleBatched = fn => {
271
+ if (typeof requestIdleCallback !== "function") setTimeout(fn); // Old browsers don't get optimisation
272
+ const existingStack = listingContext === null || listingContext === void 0 ? void 0 : listingContext[$56047603f9d212b6$var$onIdleFunctionsSymbol];
273
+ if (existingStack) return existingStack.add(fn);
274
+ const newStack = new Set([fn]);
275
+ if (listingContext) listingContext[$56047603f9d212b6$var$onIdleFunctionsSymbol] = newStack;
276
+ const processStackWhenIdle = () => requestIdleCallback(deadline => {
277
+ const start = performance.now();
278
+ const thirdDeadlineTime = deadline.timeRemaining() / 3; // observers coming after this take up 2-3x the time so don't use all of it
279
+ for (const fn of newStack) {
280
+ newStack.delete(fn);
281
+ fn();
282
+ const timeTaken = performance.now() - start;
283
+ if ((!deadline.timeRemaining() || timeTaken > thirdDeadlineTime) && newStack.size) {
284
+ // There's still work to be done but no time, so schedule another idle callback
285
+ processStackWhenIdle();
286
+ return;
287
+ }
267
288
  }
268
- }), false, false);
269
- $8tj43$runHydrationEvents();
270
- return _el$;
271
- })();
289
+ // Stack is empty
290
+ if (listingContext) delete listingContext[$56047603f9d212b6$var$onIdleFunctionsSymbol];
291
+ }, {
292
+ timeout: 15000
293
+ } // long timeout, better to not have images than to freeze the browser. But also we don't want to confuse user why no iamges are loading
294
+ );
295
+
296
+ processStackWhenIdle();
297
+ };
298
+ let sizeSetFastPath = false;
299
+ let hasDecodedFastPath = false;
300
+ let timeoutSet = false;
301
+ let gotCleanedUp = false;
302
+ $8tj43$onCleanup(() => gotCleanedUp = true);
303
+ $8tj43$spread(img, $8tj43$mergeProps(otherOptions), false, true);
304
+ $8tj43$createEffect(() => {
305
+ if (!props.size()) return; // wait until we have a size
306
+ if (timeoutSet) return;
307
+ const handler = $8tj43$catchify(() => {
308
+ if (gotCleanedUp) return;
309
+ img.sizes = sizePX(); // use latest available value of props.size
310
+ if (!sizeSetFastPath) {
311
+ setHasSetSize(true);
312
+ sizeSetFastPath = true;
313
+ }
314
+ timeoutSet = false;
315
+ });
316
+ // Throttle the updating of sizes to avoid unnecessary image re-fetches during resize
317
+ // And also because we first set src after sizes has been set, wait with loading and decoding images until browser is idle
318
+ // This greatly improves performance when loading (more) products
319
+ // See https://depictaiworkspace.slack.com/archives/C05NJ0K3WRL/p1698220617663139
320
+ executeWhenIdleBatched(handler);
321
+ timeoutSet = true;
322
+ });
323
+ $8tj43$createEffect(() => {
324
+ if (!props.size() || !hasSetSize()) return; // If size isn't known or set, don't assign src yet since it would cause the most low res image to load
325
+ Object.assign(img, src_options());
326
+ // Add to DOM once decoded to not require/block any paints before image has completed loading and avoid showing broken image symbol
327
+ // We can do this because there has to be a container around us giving us a size
328
+ // No need to listen if we're already in the DOM
329
+ if (hasDecodedFastPath) return;
330
+ if (props.loading === "lazy") {
331
+ // For lazy loading there's no decoding to wait for as it only occurs when the image is visible
332
+ // Make sure src is set before we put the image into the DOM though so no broken image symbol is shown
333
+ setHasDecoded(true);
334
+ hasDecodedFastPath = true;
335
+ }
336
+ img.decode().catch(e => $8tj43$dwarn("Failed to decode image", e, img)) // Display the image also if loading failed so webdev can debug and doesn't get "no image"
337
+ .then(async () => {
338
+ // Also wait with inserting image (i.e. paint) until browser is idle
339
+ await new Promise(r => executeWhenIdleBatched(r));
340
+ if (gotCleanedUp) return;
341
+ setHasDecoded(true);
342
+ hasDecodedFastPath = true;
343
+ });
344
+ });
345
+ return $8tj43$createComponent((0, $8tj43$Show), {
346
+ get when() {
347
+ return hasDecoded();
348
+ },
349
+ children: img
350
+ });
272
351
  }
273
352
  function $56047603f9d212b6$var$make_srcset(url, resolutions) {
274
353
  return resolutions.map(width => "".concat($56047603f9d212b6$var$generateImageUrl(url, width), " ").concat(width, "w")).join(", ");
@@ -306,7 +385,7 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
306
385
  $8tj43$queueMacroTask(() => setCurrentImageSize(undefined)); // unset the size accessor next event loop iteration, so that all onCleanup's have time to run, since the effects run more aggressively and can create a size accessor with a cleaned up owner otherwise
307
386
  });
308
387
 
309
- container.append($8tj43$createComponent((0, $56047603f9d212b6$export$6e5611bc7e57e477), {
388
+ $8tj43$insert(container, $8tj43$createComponent((0, $56047603f9d212b6$export$6e5611bc7e57e477), {
310
389
  style: "width: 100%; height: 100%; object-fit: contain; position: absolute; inset: 0;",
311
390
  get size() {
312
391
  return $8tj43$createMemo(() => {
@@ -741,7 +820,7 @@ function $63f1f8dbcd07d3b0$export$d21e32dfedac04be(props) {
741
820
  const container_class = "x" + $8tj43$createUniqueId();
742
821
  const container_element_ = (() => {
743
822
  const _el$ = $8tj43$getNextElement($63f1f8dbcd07d3b0$var$_tmpl$);
744
- $8tj43$spread(_el$, $8tj43$mergeProps(() => props.element_attributes, {
823
+ $8tj43$spread(_el$, $8tj43$mergeProps1(() => props.element_attributes, {
745
824
  "classList": {
746
825
  [container_class]: true
747
826
  }
@@ -904,7 +983,7 @@ function $39ddb986053fb759$export$d41d19e89346fa2(_ref) {
904
983
  } = slider;
905
984
  const Layout = props => $63f1f8dbcd07d3b0$export$445d8d3f5f706a40(props, insert_here, true);
906
985
  // Do like this, so we don't have to call mergeProps ourselves
907
- $8tj43$createComponent(Layout, $8tj43$mergeProps({
986
+ $8tj43$createComponent(Layout, $8tj43$mergeProps1({
908
987
  rows: "all",
909
988
  layout: "slider"
910
989
  }, layout_options_));
@@ -1037,7 +1116,7 @@ function $e3efeb558d952696$export$7da560f849543dff(_ref) {
1037
1116
  _el$4 = _el$3.nextSibling,
1038
1117
  [_el$5, _co$2] = $8tj43$getNextMarker(_el$4.nextSibling);
1039
1118
  $8tj43$insert(_el$, (0, $ca55612a53dbbdd2$export$a2cc176055f8f08), _el$3, _co$);
1040
- $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps({
1119
+ $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps1({
1041
1120
  get rows() {
1042
1121
  return rows_object_();
1043
1122
  },
@@ -1441,7 +1520,7 @@ function $9783d437ad61594c$export$3b621d86b1566b2() {
1441
1520
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1442
1521
  return (() => {
1443
1522
  const _el$ = $8tj43$getNextElement($9783d437ad61594c$var$_tmpl$);
1444
- $8tj43$spread(_el$, $8tj43$mergeProps(props, {
1523
+ $8tj43$spread(_el$, $8tj43$mergeProps1(props, {
1445
1524
  "xmlns": "http://www.w3.org/2000/svg",
1446
1525
  "width": "21.064",
1447
1526
  "height": "21.047",
@@ -1840,7 +1919,7 @@ const $ff3225aef892a467$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<svg><path d=
1840
1919
  function $ff3225aef892a467$export$f21ab0717a89c77f(props) {
1841
1920
  return (() => {
1842
1921
  const _el$ = $8tj43$getNextElement($ff3225aef892a467$var$_tmpl$);
1843
- $8tj43$spread(_el$, $8tj43$mergeProps(props, {
1922
+ $8tj43$spread(_el$, $8tj43$mergeProps1(props, {
1844
1923
  "xmlns": "http://www.w3.org/2000/svg",
1845
1924
  "width": "11",
1846
1925
  "height": "12"
@@ -3065,7 +3144,7 @@ const $830ea8efda59884e$export$414f6a19d38e655c = _ref => {
3065
3144
  [_el$6, _co$] = $8tj43$getNextMarker(_el$5.nextSibling),
3066
3145
  _el$7 = _el$6.nextSibling,
3067
3146
  [_el$8, _co$2] = $8tj43$getNextMarker(_el$7.nextSibling);
3068
- $8tj43$spread(_el$2, $8tj43$mergeProps(attributes, {
3147
+ $8tj43$spread(_el$2, $8tj43$mergeProps1(attributes, {
3069
3148
  get disabled() {
3070
3149
  return $8tj43$memo(() => value().count_ === 0)() && !is_selected();
3071
3150
  },
@@ -4984,7 +5063,7 @@ function $64d94dcaa058dc7b$export$ab6b147eec64fea5(props) {
4984
5063
  const container_class = "x" + $8tj43$createUniqueId();
4985
5064
  const container_element_ = (() => {
4986
5065
  const _el$ = $8tj43$getNextElement($64d94dcaa058dc7b$var$_tmpl$);
4987
- $8tj43$spread(_el$, $8tj43$mergeProps(() => props.element_attributes, {
5066
+ $8tj43$spread(_el$, $8tj43$mergeProps1(() => props.element_attributes, {
4988
5067
  "classList": {
4989
5068
  [container_class]: true
4990
5069
  }
@@ -5310,7 +5389,7 @@ function $ff7feae4dddd6073$var$wrap_blocks_in_div(rendered_content_blocks, max_s
5310
5389
  return _el$;
5311
5390
  }
5312
5391
  });
5313
- return $8tj43$mergeProps1(block, {
5392
+ return $8tj43$mergeProps(block, {
5314
5393
  // Create content divs for the blocks with as much fine-grained diffing as possible?
5315
5394
  content: () => {
5316
5395
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
@@ -6029,7 +6108,7 @@ function $082c4ed3e22f8d71$export$9bf11afa910f536e(_ref) {
6029
6108
  get children() {
6030
6109
  return (() => {
6031
6110
  const _el$34 = $8tj43$getNextElement($082c4ed3e22f8d71$var$_tmpl$5);
6032
- $8tj43$insert(_el$34, $8tj43$createComponent((0, $f6b0500577e1b210$export$3f1a388cc0d8fed7), $8tj43$mergeProps(args_for_filtering_, {
6111
+ $8tj43$insert(_el$34, $8tj43$createComponent((0, $f6b0500577e1b210$export$3f1a388cc0d8fed7), $8tj43$mergeProps1(args_for_filtering_, {
6033
6112
  are_in_modal_: true
6034
6113
  })));
6035
6114
  return _el$34;
@@ -8469,7 +8548,7 @@ function $ef0f18a578b32578$export$82eafebb825fc23f() {
8469
8548
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8470
8549
  return (() => {
8471
8550
  const _el$ = $8tj43$getNextElement($ef0f18a578b32578$var$_tmpl$);
8472
- $8tj43$spread(_el$, $8tj43$mergeProps(props, {
8551
+ $8tj43$spread(_el$, $8tj43$mergeProps1(props, {
8473
8552
  "xmlns": "http://www.w3.org/2000/svg",
8474
8553
  "width": "20",
8475
8554
  "height": "22"
@@ -8652,7 +8731,7 @@ function $8ef6232475d44150$export$7de92c4c2205ebf3(_ref) {
8652
8731
  [_el$6, _co$2] = $8tj43$getNextMarker(_el$5.nextSibling);
8653
8732
  $8tj43$insert(_el$2, () => i18n_.search_recs_title_());
8654
8733
  $8tj43$insert(_el$, (0, $ca55612a53dbbdd2$export$a2cc176055f8f08), _el$4, _co$);
8655
- $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps({
8734
+ $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps1({
8656
8735
  rows: rows_object,
8657
8736
  layout: "grid",
8658
8737
  element_attributes: {
@@ -10688,7 +10767,7 @@ function $22470de5f42cc35d$export$f631859cab12b342(_ref) {
10688
10767
  [_el$8, _co$] = $8tj43$getNextMarker(_el$7.nextSibling),
10689
10768
  _el$9 = _el$8.nextSibling,
10690
10769
  [_el$10, _co$2] = $8tj43$getNextMarker(_el$9.nextSibling);
10691
- $8tj43$insert(_el$4, $8tj43$createComponent(LinkIfPossible, $8tj43$mergeProps(make_link_attributes, {
10770
+ $8tj43$insert(_el$4, $8tj43$createComponent(LinkIfPossible, $8tj43$mergeProps1(make_link_attributes, {
10692
10771
  tabIndex: "-1",
10693
10772
  get children() {
10694
10773
  return $8tj43$createComponent((0, $3c5e15c6ee4227a9$export$605674723bcc715c), {
@@ -10697,7 +10776,7 @@ function $22470de5f42cc35d$export$f631859cab12b342(_ref) {
10697
10776
  });
10698
10777
  }
10699
10778
  })));
10700
- $8tj43$insert(_el$5, $8tj43$createComponent(LinkIfPossible, $8tj43$mergeProps({
10779
+ $8tj43$insert(_el$5, $8tj43$createComponent(LinkIfPossible, $8tj43$mergeProps1({
10701
10780
  "class": "content-title line-clamp"
10702
10781
  }, make_link_attributes, {
10703
10782
  get title() {
@@ -10859,7 +10938,7 @@ function $d53ebed6f63304e4$export$6d0c9c22f6652669(_ref) {
10859
10938
  },
10860
10939
  number_of_results_: num_results
10861
10940
  }), _el$3, _co$);
10862
- $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps({
10941
+ $8tj43$insert(_el$, $8tj43$createComponent((0, $63f1f8dbcd07d3b0$export$d21e32dfedac04be), $8tj43$mergeProps1({
10863
10942
  layout: "grid",
10864
10943
  element_attributes: {
10865
10944
  class: "cards"
@@ -11040,7 +11119,7 @@ function $da279c5a540c6846$export$a54ec244c8863715(_ref) {
11040
11119
  var _search_results_4, _search_results_4$con;
11041
11120
  return ((_search_results_4 = search_results_()) !== null && _search_results_4 !== void 0 && (_search_results_4$con = _search_results_4.content_search_links) !== null && _search_results_4$con !== void 0 && _search_results_4$con.length ? i18n_.no_products_ : i18n_.no_results_text_)();
11042
11121
  });
11043
- const results_for = $8tj43$createComponent((0, $69602b3d8fd54c38$export$9dd50d35b9d94fdf), $8tj43$mergeProps({
11122
+ const results_for = $8tj43$createComponent((0, $69602b3d8fd54c38$export$9dd50d35b9d94fdf), $8tj43$mergeProps1({
11044
11123
  get type() {
11045
11124
  return (0, $69602b3d8fd54c38$export$2452208c79fe93ea).products;
11046
11125
  },
package/latest/index.cjs CHANGED
@@ -70,7 +70,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $a3280f0aad997933$expo
70
70
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $a3280f0aad997933$export$7bf543b9d9be2c22);
71
71
  $parcel$export(module.exports, "version", () => $b757f75811f3261f$export$83d89fbfd8236492);
72
72
  /*! Depict.ai search and product listing SDK */
73
- const $b757f75811f3261f$export$83d89fbfd8236492 = "2.1.4";
73
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "2.1.6";
74
74
  const $1ab22f2cd39b3061$var$fallback_operator = "in";
75
75
  const $1ab22f2cd39b3061$var$fallback_token = "";
76
76
  const $1ab22f2cd39b3061$var$legacy_filter_prefix = "filter_";
@@ -265,7 +265,6 @@ function $93304d59a9747aa6$export$94026ee33dbabc26(props) {
265
265
  return _el$;
266
266
  })();
267
267
  }
268
- const $19950faaac026e09$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<img>`);
269
268
  function $19950faaac026e09$export$e6fffe67d4cdd848(whatToWatch) {
270
269
  const [size, setSize] = $gVhhF$solidjs.createSignal(0);
271
270
  const resizeObserver = new ResizeObserver($gVhhF$depictaiutilishared.catchify(records => {
@@ -290,6 +289,7 @@ function $19950faaac026e09$export$e6fffe67d4cdd848(whatToWatch) {
290
289
  });
291
290
  return size;
292
291
  }
292
+ const $19950faaac026e09$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
293
293
  function $19950faaac026e09$export$6e5611bc7e57e477(props) {
294
294
  // Enable reactive props
295
295
  const otherOptions = $gVhhF$solidjs.createMemo(() => {
@@ -312,16 +312,95 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
312
312
  srcset: srcset
313
313
  };
314
314
  });
315
- return (() => {
316
- const _el$ = $gVhhF$solidjsweb.getNextElement($19950faaac026e09$var$_tmpl$);
317
- $gVhhF$solidjsweb.spread(_el$, $gVhhF$solidjsweb.mergeProps(otherOptions, src_options, {
318
- get sizes() {
319
- return props.size() + "px";
315
+ // Work around https://github.com/solidjs/solid/issues/1828
316
+ const img = new Image(); // Need to use new Image or browser might not start loading image before it's in the DOM
317
+ const [hasSetSize, setHasSetSize] = $gVhhF$solidjs.createSignal(false);
318
+ const [hasDecoded, setHasDecoded] = $gVhhF$solidjs.createSignal(false);
319
+ const sizePX = $gVhhF$solidjs.createMemo(() => `${props.size()}px`); // props.size could be a getter that expects a cleanup so get it in this memo instead of where we set img.sizes
320
+ const listingContext = $84798aaa863a4909$export$8d0c4fdbb05a2f2e();
321
+ // Batch idle callbacks so that MutationObserver can batch the resulting mutations better, so we don't lose tons of CPU time to MutationObservers doing lots of things for each image
322
+ // Happened on singular, they have some weird observer (+we also have one but ours is at least 3x more efficient)
323
+ const executeWhenIdleBatched = fn => {
324
+ if (typeof requestIdleCallback !== "function") setTimeout(fn); // Old browsers don't get optimisation
325
+ const existingStack = listingContext?.[$19950faaac026e09$var$onIdleFunctionsSymbol];
326
+ if (existingStack) return existingStack.add(fn);
327
+ const newStack = new Set([fn]);
328
+ if (listingContext) listingContext[$19950faaac026e09$var$onIdleFunctionsSymbol] = newStack;
329
+ const processStackWhenIdle = () => requestIdleCallback(deadline => {
330
+ const start = performance.now();
331
+ const thirdDeadlineTime = deadline.timeRemaining() / 3; // observers coming after this take up 2-3x the time so don't use all of it
332
+ for (const fn of newStack) {
333
+ newStack.delete(fn);
334
+ fn();
335
+ const timeTaken = performance.now() - start;
336
+ if ((!deadline.timeRemaining() || timeTaken > thirdDeadlineTime) && newStack.size) {
337
+ // There's still work to be done but no time, so schedule another idle callback
338
+ processStackWhenIdle();
339
+ return;
340
+ }
320
341
  }
321
- }), false, false);
322
- $gVhhF$solidjsweb.runHydrationEvents();
323
- return _el$;
324
- })();
342
+ // Stack is empty
343
+ if (listingContext) delete listingContext[$19950faaac026e09$var$onIdleFunctionsSymbol];
344
+ }, {
345
+ timeout: 15000
346
+ } // long timeout, better to not have images than to freeze the browser. But also we don't want to confuse user why no iamges are loading
347
+ );
348
+
349
+ processStackWhenIdle();
350
+ };
351
+ let sizeSetFastPath = false;
352
+ let hasDecodedFastPath = false;
353
+ let timeoutSet = false;
354
+ let gotCleanedUp = false;
355
+ $gVhhF$solidjs.onCleanup(() => gotCleanedUp = true);
356
+ $gVhhF$solidjsweb.spread(img, $gVhhF$solidjs.mergeProps(otherOptions), false, true);
357
+ $gVhhF$solidjs.createEffect(() => {
358
+ if (!props.size()) return; // wait until we have a size
359
+ if (timeoutSet) return;
360
+ const handler = $gVhhF$depictaiutilishared.catchify(() => {
361
+ if (gotCleanedUp) return;
362
+ img.sizes = sizePX(); // use latest available value of props.size
363
+ if (!sizeSetFastPath) {
364
+ setHasSetSize(true);
365
+ sizeSetFastPath = true;
366
+ }
367
+ timeoutSet = false;
368
+ });
369
+ // Throttle the updating of sizes to avoid unnecessary image re-fetches during resize
370
+ // And also because we first set src after sizes has been set, wait with loading and decoding images until browser is idle
371
+ // This greatly improves performance when loading (more) products
372
+ // See https://depictaiworkspace.slack.com/archives/C05NJ0K3WRL/p1698220617663139
373
+ executeWhenIdleBatched(handler);
374
+ timeoutSet = true;
375
+ });
376
+ $gVhhF$solidjs.createEffect(() => {
377
+ if (!props.size() || !hasSetSize()) return; // If size isn't known or set, don't assign src yet since it would cause the most low res image to load
378
+ Object.assign(img, src_options());
379
+ // Add to DOM once decoded to not require/block any paints before image has completed loading and avoid showing broken image symbol
380
+ // We can do this because there has to be a container around us giving us a size
381
+ // No need to listen if we're already in the DOM
382
+ if (hasDecodedFastPath) return;
383
+ if (props.loading === "lazy") {
384
+ // For lazy loading there's no decoding to wait for as it only occurs when the image is visible
385
+ // Make sure src is set before we put the image into the DOM though so no broken image symbol is shown
386
+ setHasDecoded(true);
387
+ hasDecodedFastPath = true;
388
+ }
389
+ img.decode().catch(e => $gVhhF$depictaiutilishared.dwarn("Failed to decode image", e, img)) // Display the image also if loading failed so webdev can debug and doesn't get "no image"
390
+ .then(async () => {
391
+ // Also wait with inserting image (i.e. paint) until browser is idle
392
+ await new Promise(r => executeWhenIdleBatched(r));
393
+ if (gotCleanedUp) return;
394
+ setHasDecoded(true);
395
+ hasDecodedFastPath = true;
396
+ });
397
+ });
398
+ return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
399
+ get when() {
400
+ return hasDecoded();
401
+ },
402
+ children: img
403
+ });
325
404
  }
326
405
  function $19950faaac026e09$var$make_srcset(url, resolutions) {
327
406
  return resolutions.map(width => `${$19950faaac026e09$var$generateImageUrl(url, width)} ${width}w`).join(", ");
@@ -359,7 +438,7 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
359
438
  $gVhhF$depictaiutilishared.queueMacroTask(() => setCurrentImageSize(undefined)); // unset the size accessor next event loop iteration, so that all onCleanup's have time to run, since the effects run more aggressively and can create a size accessor with a cleaned up owner otherwise
360
439
  });
361
440
 
362
- container.append($gVhhF$solidjsweb.createComponent((0, $19950faaac026e09$export$6e5611bc7e57e477), {
441
+ $gVhhF$solidjsweb.insert(container, $gVhhF$solidjsweb.createComponent((0, $19950faaac026e09$export$6e5611bc7e57e477), {
363
442
  style: "width: 100%; height: 100%; object-fit: contain; position: absolute; inset: 0;",
364
443
  get size() {
365
444
  return $gVhhF$solidjs.createMemo(() => currentImageSize()?.() || 0);
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 { ProductListingRequestV2 } from "@depict-ai/types/api/ProductListingRequestV2";
10
- export const version = "2.1.4";
10
+ export const version = "2.1.6";
11
11
  /**
12
12
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
13
13
  */
@@ -152,17 +152,19 @@ export function ImageContainer(props: {
152
152
  export function makeSizeAccessor(whatToWatch: HTMLElement): Accessor<number>;
153
153
  /**
154
154
  * Automatically generate a srcset from the shopify CDN for an image and set the sizes attribute to the provided accessor.
155
+ * Will also delay loading and decoding of image until the browser is idle (with 5s timeout) to improve filtering/loading more performance.
155
156
  * This is used for our responsive images:
156
157
  * 1. The image must have a container with a fixed size (or aspect ratio) that is independent of the image. When aspectRatio is configured on the depict-cards element as data attribute, we will wrap the image in a ImageContainer for this. If it's false, the user has to provide this container themselves.
157
158
  * 2. We set a ResizeObserver on one of the currently visible images (see makeSizeAccessor)
158
159
  * 3. We set the size attribute of all the visible images to the size of the container we're observing. The point of this is that the sizes attribute is used to determine which image to load, and usually it's set by the user and depends on the relationship between image size and viewport size. By using a ResizeObserver, we can make sure the sizes attribute is always set to the correct value without it having to be configured. This will make so the browser always loads the correct image size for a crisp image but still fast load.
160
+ * You need to use insert(domNode, <ShopifyResponsiveImg size={sizeAccessor} src={src} />) if you want to insert the return value of this component into a DOM element manually, where you `import { insert } from "solid-js/web";` because we first want to insert the image once it has loaded.
159
161
  */
160
162
  export function ShopifyResponsiveImg(props: {
161
163
  resolutions?: number[];
162
164
  size: Accessor<number>;
163
165
  } & Omit<JSX.ImgHTMLAttributes<HTMLImageElement>, "srcset" | "src" | "sizes"> & {
164
166
  src: string;
165
- }): HTMLImageElement;
167
+ }): JSX.Element;
166
168
  export const shopifyContainedImageContextSymbol: unique symbol;
167
169
  /**
168
170
  * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.