@depict-ai/ui 1.1.4 → 1.2.0

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.
@@ -1,8 +1,8 @@
1
- import {add_to_version_info as $gco9i$add_to_version_info, observer as $gco9i$observer, catchify as $gco9i$catchify, fetch_recs as $gco9i$fetch_recs, snakeCasifyObject as $gco9i$snakeCasifyObject, instant_exec_on_suspect_history_change as $gco9i$instant_exec_on_suspect_history_change, base_url as $gco9i$base_url, dlog as $gco9i$dlog, get_depict_id as $gco9i$get_depict_id, get_user_id as $gco9i$get_user_id, get_session_id as $gco9i$get_session_id, make_url_with_query_params as $gco9i$make_url_with_query_params, fetch_retry as $gco9i$fetch_retry, add_version_query_params as $gco9i$add_version_query_params, sort_obj as $gco9i$sort_obj, report as $gco9i$report, javascript_media_query as $gco9i$javascript_media_query, standard_price_format as $gco9i$standard_price_format, make_random_classname as $gco9i$make_random_classname, n_col_styling_with_dist as $gco9i$n_col_styling_with_dist, useExpandingContainer as $gco9i$useExpandingContainer, Amazing_Slider as $gco9i$Amazing_Slider, slider_snap_css as $gco9i$slider_snap_css, slider_fading_factory as $gco9i$slider_fading_factory, hsl_to_rgb as $gco9i$hsl_to_rgb, relative_luminance_from_rgb as $gco9i$relative_luminance_from_rgb, base64_encode_unicode as $gco9i$base64_encode_unicode, base64_decode_unicode as $gco9i$base64_decode_unicode, queueMacroTask as $gco9i$queueMacroTask, is_debug as $gco9i$is_debug, dwarn as $gco9i$dwarn, Layout as $gco9i$Layout, async_iterable_ipns as $gco9i$async_iterable_ipns, make_asyncIterable_exiter as $gco9i$make_asyncIterable_exiter, href_change_ipns as $gco9i$href_change_ipns, ContainedImage as $gco9i$ContainedImage, buildThresholdList as $gco9i$buildThresholdList, deparallelize_no_drop as $gco9i$deparallelize_no_drop, insert_surfaces as $gco9i$insert_surfaces} from "@depict-ai/utilishared";
1
+ import {add_to_version_info as $gco9i$add_to_version_info, observer as $gco9i$observer, catchify as $gco9i$catchify, fetch_recs as $gco9i$fetch_recs, snakeCasifyObject as $gco9i$snakeCasifyObject, instant_exec_on_suspect_history_change as $gco9i$instant_exec_on_suspect_history_change, base_url as $gco9i$base_url, dlog as $gco9i$dlog, get_depict_id as $gco9i$get_depict_id, get_user_id as $gco9i$get_user_id, get_session_id as $gco9i$get_session_id, sort_obj as $gco9i$sort_obj, fetch_retry as $gco9i$fetch_retry, add_version_query_params as $gco9i$add_version_query_params, dwarn as $gco9i$dwarn, make_url_with_query_params as $gco9i$make_url_with_query_params, report as $gco9i$report, javascript_media_query as $gco9i$javascript_media_query, standard_price_format as $gco9i$standard_price_format, make_random_classname as $gco9i$make_random_classname, n_col_styling_with_dist as $gco9i$n_col_styling_with_dist, useExpandingContainer as $gco9i$useExpandingContainer, Amazing_Slider as $gco9i$Amazing_Slider, slider_snap_css as $gco9i$slider_snap_css, slider_fading_factory as $gco9i$slider_fading_factory, hsl_to_rgb as $gco9i$hsl_to_rgb, relative_luminance_from_rgb as $gco9i$relative_luminance_from_rgb, base64_encode_unicode as $gco9i$base64_encode_unicode, base64_decode_unicode as $gco9i$base64_decode_unicode, queueMacroTask as $gco9i$queueMacroTask, is_debug as $gco9i$is_debug, Layout as $gco9i$Layout, async_iterable_ipns as $gco9i$async_iterable_ipns, make_asyncIterable_exiter as $gco9i$make_asyncIterable_exiter, href_change_ipns as $gco9i$href_change_ipns, ContainedImage as $gco9i$ContainedImage, buildThresholdList as $gco9i$buildThresholdList, deparallelize_no_drop as $gco9i$deparallelize_no_drop, insert_surfaces as $gco9i$insert_surfaces} from "@depict-ai/utilishared";
2
2
  import {createRoot as $gco9i$createRoot, createSignal as $gco9i$createSignal, getOwner as $gco9i$getOwner, runWithOwner as $gco9i$runWithOwner, onCleanup as $gco9i$onCleanup, createComputed as $gco9i$createComputed, createRenderEffect as $gco9i$createRenderEffect, createEffect as $gco9i$createEffect, untrack as $gco9i$untrack, batch as $gco9i$batch, createResource as $gco9i$createResource, createMemo as $gco9i$createMemo, Show as $gco9i$Show, createReaction as $gco9i$createReaction, Suspense as $gco9i$Suspense, on as $gco9i$on, ErrorBoundary as $gco9i$ErrorBoundary, For as $gco9i$For, Index as $gco9i$Index} from "solid-js";
3
3
  import {template as $gco9i$template, getNextElement as $gco9i$getNextElement, spread as $gco9i$spread, mergeProps as $gco9i$mergeProps, runHydrationEvents as $gco9i$runHydrationEvents, effect as $gco9i$effect, setAttribute as $gco9i$setAttribute, insert as $gco9i$insert, isServer as $gco9i$isServer, createComponent as $gco9i$createComponent, getNextMarker as $gco9i$getNextMarker, use as $gco9i$use, memo as $gco9i$memo, addEventListener as $gco9i$addEventListener, delegateEvents as $gco9i$delegateEvents, classList as $gco9i$classList, style as $gco9i$style, className as $gco9i$className, Dynamic as $gco9i$Dynamic} from "solid-js/web";
4
4
 
5
- /*! Depict.ai search and product listing SDK */ const $ec291e0010116877$export$83d89fbfd8236492 = "1.1.4";
5
+ /*! Depict.ai search and product listing SDK */ const $ec291e0010116877$export$83d89fbfd8236492 = "1.2.0";
6
6
 
7
7
 
8
8
 
@@ -203,26 +203,77 @@ class $7fa23e2a0079eca4$export$e015ed2f2950f2e3 {
203
203
  #get_metadata;
204
204
  #get_user_id;
205
205
  #get_session_id;
206
- constructor({ get_metadata: get_metadata , get_user_id: get_user_id , get_session_id: get_session_id } = {}){
207
- this.#get_metadata = get_metadata;
208
- this.#get_user_id = get_user_id;
209
- this.#get_session_id = get_session_id;
206
+ #guard_url_creator_length(expected, received) {
207
+ if (expected.length !== received.length) {
208
+ const e = new Error("Page URL creator returned wrong number of page URLs, got " + received.length + ", expected " + expected.length);
209
+ queueMicrotask(()=>{
210
+ throw e;
211
+ });
212
+ throw e;
213
+ }
210
214
  }
211
- async suggest(input_req) {
212
- const request = this.#add_ids_to_request(input_req);
213
- const url = (0, $gco9i$make_url_with_query_params)($7fa23e2a0079eca4$var$search_base_url + "suggestions", request);
214
- const results = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(url));
215
- attempt_to_return_api_response: {
216
- if (!results) break attempt_to_return_api_response;
217
- const decoded_json = await results.json();
218
- if (!Array.isArray(decoded_json?.suggestions)) break attempt_to_return_api_response;
219
- return decoded_json;
215
+ async #run_url_creator_for_suggest(merchant, market, response) {
216
+ if (!this.page_url_creator) return response;
217
+ // find category suggestions, run thing with them, and then replace them
218
+ const category_suggestions = response.suggestions.filter((suggestion)=>suggestion.type === "category");
219
+ const page_urls = await this.page_url_creator({
220
+ type: "categories",
221
+ market: market,
222
+ merchant: merchant,
223
+ data: [
224
+ ...category_suggestions
225
+ ]
226
+ });
227
+ this.#guard_url_creator_length(category_suggestions, page_urls);
228
+ while(page_urls.length)Object.assign(category_suggestions.pop(), page_urls.pop());
229
+ return response;
230
+ }
231
+ async #run_url_creator_for_rest(merchant1, market1, input_data) {
232
+ if (!this.page_url_creator) return input_data;
233
+ const displays = input_data.displays;
234
+ const breadcrumb = input_data.breadcrumb;
235
+ const quick_links = input_data.quick_links;
236
+ if (displays) {
237
+ const page_urls = await this.page_url_creator({
238
+ type: "products",
239
+ merchant: merchant1,
240
+ market: market1,
241
+ displays: [
242
+ ...input_data.displays
243
+ ]
244
+ });
245
+ this.#guard_url_creator_length(displays, page_urls);
246
+ for(let i = 0; i < displays.length; i++){
247
+ const new_display_or_page_url = page_urls[i];
248
+ const old_display = displays[i];
249
+ if ("page_url" in new_display_or_page_url && Object.keys(new_display_or_page_url).length === 1) {
250
+ // they only returned page_url, let's put it into the display
251
+ const old_display_was_modern = "variant_index" in old_display;
252
+ if (old_display_was_modern) {
253
+ const variant_displays = old_display.variant_displays;
254
+ for(let i = 0; i < variant_displays.length; i++)variant_displays[i].page_url = new_display_or_page_url.page_url;
255
+ } else old_display.page_url = new_display_or_page_url.page_url;
256
+ } else // We got a whole new display, let's replace it
257
+ displays[i] = new_display_or_page_url;
258
+ }
220
259
  }
221
- return {
222
- "suggestions_request_id": "error",
223
- "suggestions": [],
224
- failed: true
225
- };
260
+ for (const category_display_array of [
261
+ breadcrumb,
262
+ quick_links
263
+ ]){
264
+ if (!category_display_array) continue;
265
+ const page_urls = await this.page_url_creator({
266
+ type: "categories",
267
+ merchant: merchant1,
268
+ market: market1,
269
+ data: [
270
+ ...category_display_array
271
+ ]
272
+ });
273
+ this.#guard_url_creator_length(category_display_array, page_urls);
274
+ for(let i = 0; i < category_display_array.length; i++)Object.assign(category_display_array[i], page_urls[i]);
275
+ }
276
+ return input_data;
226
277
  }
227
278
  async #cached_post_request(endpoint1, input_req, fallback_response) {
228
279
  const cache_obj = this.#get_cache_obj_for_endpoint(endpoint1);
@@ -239,66 +290,101 @@ class $7fa23e2a0079eca4$export$e015ed2f2950f2e3 {
239
290
  let resolve_in_progress;
240
291
  cache_obj.in_progress_[body] = new Promise((r)=>resolve_in_progress = r);
241
292
  try {
242
- let search_results = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(endpoint1), {
293
+ let api_response = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(endpoint1), {
243
294
  method: "POST",
244
295
  body: body
245
296
  });
246
297
  if ("query_id" in request && request.type === "collection") // FIXME: Remove. Backwards compatibility layer
247
298
  // This will retry the request without the collection type if the first request fails
248
299
  {
249
- if (!search_results || search_results?.status === 404) {
300
+ if (!api_response || api_response?.status === 404) {
250
301
  (0, $gco9i$dlog)("Fallback request for collections due to failure");
251
302
  const fallback_body = JSON.parse(body);
252
303
  delete fallback_body.type;
253
- search_results = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(endpoint1), {
304
+ api_response = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(endpoint1), {
254
305
  method: "POST",
255
306
  body: JSON.stringify(fallback_body)
256
307
  });
257
308
  }
258
309
  }
259
- if (!search_results || search_results.status !== 200) {
260
- const retval = fallback_response(input_req);
261
- resolve_in_progress(retval);
262
- return retval;
310
+ return_successfully: {
311
+ if (!api_response || api_response.status !== 200) break return_successfully;
312
+ let result;
313
+ try {
314
+ const unmodified_result = await api_response.json();
315
+ result = await this.#run_url_creator_for_rest(input_req.tenant, input_req.market, unmodified_result);
316
+ } catch (e) {
317
+ (0, $gco9i$dwarn)("URL creator or json decoding failed", e);
318
+ break return_successfully;
319
+ }
320
+ cache_obj.cache_[body] = new WeakRef(result);
321
+ resolve_in_progress(result);
322
+ setTimeout((0, $gco9i$catchify)(()=>{
323
+ if (this.#supports_finalization_registry) cache_obj.finalization_registry_.register(result, body); // delete key from cache when value (WeakRefs) are collected
324
+ else // delete things from cache after 5 minutes, so it doesn't get too heavy
325
+ setTimeout((0, $gco9i$catchify)(()=>delete cache_obj.cache_[body]), 300000);
326
+ }), 60000 // cache values for at least 60 seconds
327
+ );
328
+ return result;
263
329
  }
264
- const result = await search_results.json();
265
- cache_obj.cache_[body] = new WeakRef(result);
266
- resolve_in_progress(result);
267
- setTimeout((0, $gco9i$catchify)(()=>{
268
- if (this.#supports_finalization_registry) cache_obj.finalization_registry_.register(result, body); // delete key from cache when value (WeakRefs) are collected
269
- else // delete things from cache after 5 minutes, so it doesn't get too heavy
270
- setTimeout((0, $gco9i$catchify)(()=>delete cache_obj.cache_[body]), 300000);
271
- }), 30000 // cache values for at least 30 seconds
272
- );
273
- return result;
330
+ // If we get here, the request failed
331
+ const retval = fallback_response(input_req);
332
+ resolve_in_progress(retval);
333
+ return retval;
274
334
  } finally{
275
335
  delete cache_obj.in_progress_[body];
276
336
  }
277
337
  }
338
+ constructor(options){
339
+ const { get_metadata: get_metadata , get_user_id: get_user_id , get_session_id: get_session_id , page_url_creator: page_url_creator } = options ?? {};
340
+ this.#get_metadata = get_metadata;
341
+ this.#get_user_id = get_user_id;
342
+ this.#get_session_id = get_session_id;
343
+ this.page_url_creator = page_url_creator;
344
+ }
345
+ async suggest(input_req) {
346
+ const request = this.#add_ids_to_request(input_req);
347
+ const url = (0, $gco9i$make_url_with_query_params)($7fa23e2a0079eca4$var$search_base_url + "suggestions", request);
348
+ const results = await (0, $gco9i$fetch_retry)((0, $gco9i$add_version_query_params)(url));
349
+ attempt_to_return_api_response: {
350
+ if (!results) break attempt_to_return_api_response;
351
+ const decoded_json = await results.json();
352
+ if (!Array.isArray(decoded_json?.suggestions)) break attempt_to_return_api_response;
353
+ try {
354
+ return await this.#run_url_creator_for_suggest(input_req.tenant, input_req.market, decoded_json);
355
+ } catch (e) {
356
+ (0, $gco9i$dwarn)("URL creator failed", e);
357
+ }
358
+ }
359
+ return {
360
+ "suggestions_request_id": "error",
361
+ "suggestions": [],
362
+ failed: true
363
+ };
364
+ }
278
365
  async query(input_req) {
279
- return await this.#cached_post_request($7fa23e2a0079eca4$var$search_base_url + "results", input_req, (request)=>({
366
+ return await this.#cached_post_request($7fa23e2a0079eca4$var$search_base_url + "results", input_req, ()=>({
280
367
  "n_hits": 0,
281
- "page": request.page ?? 1,
282
368
  "displays": [],
283
- "facets": [],
284
- "suggestions": [],
369
+ "sorts": [],
370
+ "filters": [],
285
371
  "search_request_id": "error",
286
372
  failed: true
287
373
  }));
288
374
  }
289
375
  async list(input_req) {
290
- return await this.#cached_post_request($7fa23e2a0079eca4$var$v2_base_url + "product-listing", input_req, (request)=>({
376
+ return await this.#cached_post_request($7fa23e2a0079eca4$var$v2_base_url + "product-listing", input_req, ()=>({
291
377
  "n_hits": 0,
292
- "page": request.page ?? 1,
293
378
  "displays": [],
294
- "facets": [],
295
- "suggestions": [],
379
+ "sorts": [],
380
+ "filters": [],
381
+ "breadcrumb": [],
382
+ "quick_links": [],
296
383
  "product_listing_request_id": "error",
297
384
  failed: true
298
385
  }));
299
386
  }
300
387
  async get_recommended(input_req) {
301
- // @ts-ignore ModernDisplay doesn't have arbitrary string access, and we'd like it to stay that way
302
388
  return await this.#cached_post_request($7fa23e2a0079eca4$var$search_base_url + "related", input_req, ()=>({
303
389
  displays: []
304
390
  }));
@@ -1148,6 +1234,7 @@ function $0449e7d49398c077$export$a1fd619a4743ca08({ plp_results_: plp_results_
1148
1234
  const record = records[i];
1149
1235
  const { target: target , intersectionRatio: intersectionRatio } = record;
1150
1236
  const index_of_target = target_to_index_map.get(target);
1237
+ if (index_of_target == undefined) return; // It seems like it can happen that we get IntersectionObserverEntries after the onCleanup function for a recommendation card has run, in Firefox. Probably a bug in Firefox? If I understood the bug correctly, this is a workaround.
1151
1238
  const is_in_set = currently_intersecting.has(index_of_target);
1152
1239
  if (intersectionRatio > 0) {
1153
1240
  if (!is_in_set) currently_intersecting.add(index_of_target);
@@ -5067,23 +5154,30 @@ function $641bba2917fe862b$export$6e49da55e449af7c({ scroll_restoration_data_: [
5067
5154
  ]); // get rid of old data the browser saves the old state and will restore it later on
5068
5155
  };
5069
5156
  (0, $gco9i$createComputed)((0, $gco9i$catchify)(()=>{
5070
- const r = get_last_result_in_viewport_();
5071
- if (r == undefined || r <= 0 || r == Infinity) return;
5157
+ const last_result = get_last_result_in_viewport_();
5158
+ if (last_result == undefined || last_result <= 0 || last_result == Infinity) return;
5159
+ if (isNaN(last_result)) {
5160
+ // if last_result is NaN there's an issue somewhere, but if we store something here that's not a number the for loop further down will break, and we won't be able to load results at all, so let's just continue
5161
+ (0, $gco9i$report)(new Error("last_result is NaN, this should not happen"), "error", {
5162
+ last_result: last_result
5163
+ });
5164
+ return;
5165
+ }
5072
5166
  // We can push to history.state max 100 times per 30 seconds (Safari) so we have to debounce/cap this at 300ms for aggressive scrolling.
5073
5167
  // Pushing to history.state right before we leave the page (onunload etc.) is unreliable, as it has to occur *before* the next page is pushed to history.
5074
- // Instead we delay our push with a timeout set to the next acceptable interval to the previous one, when necessary
5168
+ // Instead, we delay our push with a timeout set to the next acceptable interval to the previous one, when necessary
5075
5169
  const now = +new Date();
5076
5170
  const time_since_last_ran = now - last_time_history_changed;
5077
5171
  if (time_since_last_ran > $641bba2917fe862b$var$max_history_change_frequency) {
5078
5172
  // If the interval to the previous push is already long enough, it's fine to push the next value directly.
5079
- set_min_results_loaded(r);
5173
+ set_min_results_loaded(last_result);
5080
5174
  last_time_history_changed = now;
5081
5175
  // Even though the interval has passed, there could still be a delayed push timeout in flight (browser can delay timeouts at will).
5082
5176
  // We've already written the guaranteed-to-be-freshest value so we can just cancel it.
5083
5177
  clearTimeout(timeout);
5084
5178
  return;
5085
5179
  }
5086
- set_to_later = r;
5180
+ set_to_later = last_result;
5087
5181
  // If a delayed push timeout is already running, just changing the value that will be pushed is sufficient
5088
5182
  if (timeout) return;
5089
5183
  timeout = setTimeout((0, $gco9i$catchify)(()=>{
@@ -5960,7 +6054,7 @@ class $961b5c64bef4662f$export$f34314aa9505732e {
5960
6054
  set on_navigation(new_function) {
5961
6055
  this.#router.on_navigation_ = new_function;
5962
6056
  }
5963
- constructor({ api: api , on_navigation: on_navigation , ...props_on_class }){
6057
+ constructor({ api: api , on_navigation: on_navigation , page_url_creator: page_url_creator , ...props_on_class }){
5964
6058
  const owner = (0, $gco9i$getOwner)() || (0, $gco9i$createRoot)(()=>(0, $gco9i$getOwner)()); // we might have an owner, if so, pass it on. Otherwise, create one so solid doesn't print warnings to the console
5965
6059
  (0, $gco9i$runWithOwner)(owner, ()=>{
5966
6060
  if ($961b5c64bef4662f$export$f34314aa9505732e.#has_been_constructed && !(0, $gco9i$isServer)) // on the server we can't write stuff to history.state anyway so can have multiple
@@ -5988,7 +6082,9 @@ class $961b5c64bef4662f$export$f34314aa9505732e {
5988
6082
  quicklinks_signal_: (0, $gco9i$createSignal)(),
5989
6083
  i18n_: i18n_,
5990
6084
  reset_history_state_: reset_history_state_,
5991
- depict_api_: api ?? new (0, $7fa23e2a0079eca4$export$e015ed2f2950f2e3)(),
6085
+ depict_api_: api ?? new (0, $7fa23e2a0079eca4$export$e015ed2f2950f2e3)({
6086
+ page_url_creator: page_url_creator
6087
+ }),
5992
6088
  router_: this.#router,
5993
6089
  selected_filters_: selected_filters_,
5994
6090
  current_sorting_: current_sorting_,
@@ -8389,7 +8485,7 @@ class $806c97b931758897$export$ac6237957a15b3f0 {
8389
8485
  #modal_open_signal = (0, $gco9i$createSignal)(false);
8390
8486
  static #has_been_constructed = false;
8391
8487
  #router = new (0, $4fd2ba03703a7d92$export$7e1297a3a19f10d8)("hard_navigation");
8392
- constructor({ search_query_url_param_name: search_query_url_param_name_ = "query" , url_transformer: url_transformer , on_navigation: on_navigation , enable_category_suggestions: enable_category_suggestions = true , disable_scrolling_during_modal: // Stuff needed for non-standard customer deployments that we shouldn't actually expose
8488
+ constructor({ search_query_url_param_name: search_query_url_param_name_ = "query" , url_transformer: url_transformer , on_navigation: on_navigation , enable_category_suggestions: enable_category_suggestions = true , page_url_creator: page_url_creator , disable_scrolling_during_modal: // Stuff needed for non-standard customer deployments that we shouldn't actually expose
8393
8489
  disable_scrolling_during_modal = true , api: api , bottom_distance_under_modal: bottom_distance_under_modal , render_instant_card: render_instant_card , ...props_on_class }){
8394
8490
  const owner = (0, $gco9i$getOwner)() || (0, $gco9i$createRoot)(()=>(0, $gco9i$getOwner)()); // we might have an owner, if so, pass it on. Otherwise, create one so solid doesn't print warnings to the console
8395
8491
  (0, $gco9i$runWithOwner)(owner, ()=>{
@@ -8418,7 +8514,9 @@ class $806c97b931758897$export$ac6237957a15b3f0 {
8418
8514
  if (get_search_query_updating_blocked()) return previous_value;
8419
8515
  else return raw_search_query_accessor();
8420
8516
  });
8421
- const depict_api_ = api ?? new (0, $7fa23e2a0079eca4$export$e015ed2f2950f2e3)();
8517
+ const depict_api_ = api ?? new (0, $7fa23e2a0079eca4$export$e015ed2f2950f2e3)({
8518
+ page_url_creator: page_url_creator
8519
+ });
8422
8520
  const previous_searches = (0, $21f51c14cb3f586f$export$84bba84a7b837187)(get_search_query_);
8423
8521
  const [, set_search_showing_recommendation_rows] = state_.search_showing_recommendation_rows;
8424
8522
  const after_submit_ = ()=>set_search_showing_recommendation_rows((0, $172e1b898d457050$export$1c8c715550dc689d)); // do this every time after we have submitted a new query - otherwise there might already be a saved number of rows in the state