@occluze/tether 0.9.7 → 0.9.8

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.
Files changed (56) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/astro.js +1 -1
  3. package/dist/esm/chunks/account-QFGF5FKX.js +1 -0
  4. package/dist/esm/chunks/{account-pages-LKNIXA6Q.js → account-pages-LMGIPFB7.js} +1 -1
  5. package/dist/esm/chunks/{analytics-TEU7HS7C.js → analytics-YSTR6H2W.js} +1 -1
  6. package/dist/esm/chunks/{chunk-YZC4KFT3.js → chunk-4BZ4X2Z6.js} +1 -1
  7. package/dist/esm/chunks/{chunk-47OLTPHV.js → chunk-ADA2ZGPO.js} +1 -1
  8. package/dist/esm/chunks/{chunk-BRI56DD5.js → chunk-B7SC7UOJ.js} +1 -1
  9. package/dist/esm/chunks/{chunk-SVJWBCRY.js → chunk-BGUUUMJO.js} +1 -1
  10. package/dist/esm/chunks/{chunk-KJLA4CVH.js → chunk-GOGPMJ2U.js} +1 -1
  11. package/dist/esm/chunks/{chunk-JJRRVUDP.js → chunk-HGNFQHEU.js} +1 -1
  12. package/dist/esm/chunks/{chunk-HRRJ7KUG.js → chunk-I54NQEVK.js} +1 -1
  13. package/dist/esm/chunks/{chunk-QPSIX4DK.js → chunk-IBOX3YGQ.js} +1 -1
  14. package/dist/esm/chunks/chunk-KF76466X.js +1 -0
  15. package/dist/esm/chunks/chunk-KH7NEM4B.js +1 -0
  16. package/dist/esm/chunks/{chunk-74HC6MR2.js → chunk-PHTINCRN.js} +1 -1
  17. package/dist/esm/chunks/chunk-QUBBZNJ7.js +1 -0
  18. package/dist/esm/chunks/chunk-R3UWDQL5.js +1 -0
  19. package/dist/esm/chunks/{chunk-Y5LISDPZ.js → chunk-SA5G3AUJ.js} +1 -1
  20. package/dist/esm/chunks/{chunk-O6Z6O5NW.js → chunk-UJH5ZECZ.js} +1 -1
  21. package/dist/esm/chunks/chunk-XQCBGVU2.js +1 -0
  22. package/dist/esm/chunks/{diagnose-YNVDJDSH.js → diagnose-IOC3BCP5.js} +1 -1
  23. package/dist/esm/chunks/{extras-BUH3OWBN.js → extras-5E72QFSJ.js} +1 -1
  24. package/dist/esm/chunks/{lists-6KQIGAO6.js → lists-35SUHUOX.js} +1 -1
  25. package/dist/esm/chunks/markets-ui-B3ILTPN7.js +1 -0
  26. package/dist/esm/chunks/{search-NPGWPFMA.js → search-QN457Q2G.js} +1 -1
  27. package/dist/esm/index.js +1 -1
  28. package/dist/esm/server.js +2 -2
  29. package/dist/tether.account.js +12 -11
  30. package/dist/tether.account.min.js +1 -1
  31. package/dist/tether.js +119 -113
  32. package/dist/tether.lists.js +13 -11
  33. package/dist/tether.lists.min.js +1 -1
  34. package/dist/tether.markets.js +12 -0
  35. package/dist/tether.markets.min.js +1 -1
  36. package/dist/tether.min.js +1 -1
  37. package/dist/tether.min.js.map +4 -4
  38. package/dist/types/server/src/shared/serial.d.ts +2 -6
  39. package/dist/types/src/cart/checkout.d.ts +2 -1
  40. package/dist/types/src/cart/drawer.d.ts +5 -1
  41. package/dist/types/src/cart/mutations.d.ts +13 -13
  42. package/dist/types/src/cart/store.d.ts +4 -0
  43. package/dist/types/src/cart.d.ts +7 -2
  44. package/dist/types/src/config.d.ts +3 -1
  45. package/dist/types/src/fragments.d.ts +0 -2
  46. package/dist/types/src/part-use.d.ts +3 -0
  47. package/dist/types/src/shopify-fields.d.ts +8 -0
  48. package/dist/types/src/version.d.ts +1 -1
  49. package/package.json +5 -2
  50. package/dist/esm/chunks/account-53WAVEJF.js +0 -1
  51. package/dist/esm/chunks/chunk-EIPYBAVZ.js +0 -1
  52. package/dist/esm/chunks/chunk-FYGRVUVB.js +0 -1
  53. package/dist/esm/chunks/chunk-IG23NTJK.js +0 -1
  54. package/dist/esm/chunks/chunk-NXDME6AM.js +0 -1
  55. package/dist/esm/chunks/chunk-X2HBGPFB.js +0 -1
  56. package/dist/esm/chunks/markets-ui-YAEXVFRK.js +0 -1
package/dist/tether.js CHANGED
@@ -507,11 +507,16 @@
507
507
  warn("onError threw", hookError);
508
508
  }
509
509
  }
510
+ var reportedHookFailures = /* @__PURE__ */ new Set();
510
511
  function callHook(name, hook2, fallback) {
511
512
  try {
512
513
  return hook2();
513
514
  } catch (error) {
514
- reportError(error, name);
515
+ const failure = error instanceof Error && `${name}: ${error.message}`;
516
+ if (!failure || !reportedHookFailures.has(failure)) {
517
+ if (failure) reportedHookFailures.add(failure);
518
+ reportError(error, name);
519
+ }
515
520
  return fallback?.();
516
521
  }
517
522
  }
@@ -1325,11 +1330,13 @@
1325
1330
  return Object.entries(attributes).map(([key, value]) => ({ key, value: String(value ?? "") }));
1326
1331
  }
1327
1332
 
1333
+ // src/shopify-fields.ts
1334
+ var IMAGE_FIELDS = "url altText width height";
1335
+
1328
1336
  // src/fragments.ts
1329
1337
  var MONEY = "amount currencyCode";
1330
1338
  var FULL_ACCESS = { inventory: true };
1331
1339
  var inventoryField = (access) => access.inventory ? "quantityAvailable" : "";
1332
- var IMAGE = "url altText width height";
1333
1340
  function metafieldsField(metafields) {
1334
1341
  const identifiers = [];
1335
1342
  for (const ref of metafields) {
@@ -1338,18 +1345,15 @@
1338
1345
  }
1339
1346
  if (!identifiers.length) return "";
1340
1347
  const list = identifiers.map(({ namespace, key }) => `{namespace: ${JSON.stringify(namespace)}, key: ${JSON.stringify(key)}}`).join(", ");
1341
- return `metafields(identifiers:[${list}]){namespace key type value reference{... on MediaImage{image{${IMAGE}}}}}`;
1348
+ return `metafields(identifiers:[${list}]){namespace key type value reference{... on MediaImage{image{${IMAGE_FIELDS}}}}}`;
1342
1349
  }
1343
1350
  var SELLING_PLAN_FIELDS = ` id name description recurringDeliveries options{name value}priceAdjustments{orderCount adjustmentValue{__typename ... on SellingPlanPercentagePriceAdjustment{adjustmentPercentage}... on SellingPlanFixedAmountPriceAdjustment{adjustmentAmount{${MONEY}}}... on SellingPlanFixedPriceAdjustment{price{${MONEY}}}}}`;
1344
1351
  var ALLOCATION_FIELDS = ` sellingPlan{id}checkoutChargeAmount{${MONEY}}remainingBalanceChargeAmount{${MONEY}}priceAdjustments{price{${MONEY}}compareAtPrice{${MONEY}}perDeliveryPrice{${MONEY}}unitPrice{${MONEY}}}`;
1345
1352
  function productFragment(o = cfg, access = FULL_ACCESS) {
1346
- return ` fragment TetherProduct on Product{id handle title description descriptionHtml productType vendor tags availableForSale publishedAt onlineStoreUrl requiresSellingPlan seo{title description}featuredImage{${IMAGE}}images(first:${o.imagesFirst}){nodes{${IMAGE}}}options{name optionValues{name swatch{color image{previewImage{${IMAGE}}}}}}priceRange{minVariantPrice{${MONEY}}maxVariantPrice{${MONEY}}}compareAtPriceRange{minVariantPrice{${MONEY}}maxVariantPrice{${MONEY}}}${metafieldsField(o.metafields)} sellingPlanGroups(first:${o.sellingPlanGroupsFirst}){nodes{name appName options{name values}sellingPlans(first:${o.sellingPlansFirst}){nodes{${SELLING_PLAN_FIELDS}}}}}variants(first:${o.variantsFirst}){nodes{id title availableForSale currentlyNotInStock ${inventoryField(access)} sku barcode selectedOptions{name value}image{${IMAGE}}price{${MONEY}}compareAtPrice{${MONEY}}unitPrice{${MONEY}}sellingPlanAllocations(first:${o.sellingPlansFirst}){nodes{${ALLOCATION_FIELDS}}}}}}`;
1353
+ return ` fragment TetherProduct on Product{id handle title description descriptionHtml productType vendor tags availableForSale publishedAt onlineStoreUrl requiresSellingPlan seo{title description}featuredImage{${IMAGE_FIELDS}}images(first:${o.imagesFirst}){nodes{${IMAGE_FIELDS}}}options{name optionValues{name swatch{color image{previewImage{${IMAGE_FIELDS}}}}}}priceRange{minVariantPrice{${MONEY}}maxVariantPrice{${MONEY}}}compareAtPriceRange{minVariantPrice{${MONEY}}maxVariantPrice{${MONEY}}}${metafieldsField(o.metafields)} sellingPlanGroups(first:${o.sellingPlanGroupsFirst}){nodes{name appName options{name values}sellingPlans(first:${o.sellingPlansFirst}){nodes{${SELLING_PLAN_FIELDS}}}}}variants(first:${o.variantsFirst}){nodes{id title availableForSale currentlyNotInStock ${inventoryField(access)} sku barcode selectedOptions{name value}image{${IMAGE_FIELDS}}price{${MONEY}}compareAtPrice{${MONEY}}unitPrice{${MONEY}}sellingPlanAllocations(first:${o.sellingPlansFirst}){nodes{${ALLOCATION_FIELDS}}}}}}`;
1347
1354
  }
1348
1355
  function cartFragment(access = FULL_ACCESS) {
1349
- return ` fragment TetherCart on Cart{id checkoutUrl totalQuantity note createdAt updatedAt attributes{key value}buyerIdentity{countryCode email}discountCodes{code applicable}cost{subtotalAmount{${MONEY}}totalAmount{${MONEY}}checkoutChargeAmount{${MONEY}}}lines(first:100){nodes{id quantity attributes{key value}cost{totalAmount{${MONEY}}subtotalAmount{${MONEY}}amountPerQuantity{${MONEY}}compareAtAmountPerQuantity{${MONEY}}}discountAllocations{discountedAmount{${MONEY}}}sellingPlanAllocation{sellingPlan{id name description recurringDeliveries options{name value}}checkoutChargeAmount{${MONEY}}priceAdjustments{price{${MONEY}}compareAtPrice{${MONEY}}perDeliveryPrice{${MONEY}}}}merchandise{... on ProductVariant{id title sku availableForSale requiresShipping ${inventoryField(access)} image{${IMAGE}}price{${MONEY}}compareAtPrice{${MONEY}}selectedOptions{name value}product{id title handle vendor featuredImage{${IMAGE}}}}}... on ComponentizableCartLine{lineComponents{id quantity merchandise{... on ProductVariant{id title product{title handle}}}}}}}}`;
1350
- }
1351
- function collectionFields() {
1352
- return ` id handle title description descriptionHtml image{${IMAGE}}seo{title description}`;
1356
+ return ` fragment TetherCart on Cart{id checkoutUrl totalQuantity note createdAt updatedAt attributes{key value}buyerIdentity{countryCode email}discountCodes{code applicable}cost{subtotalAmount{${MONEY}}totalAmount{${MONEY}}checkoutChargeAmount{${MONEY}}}lines(first:100){nodes{id quantity attributes{key value}cost{totalAmount{${MONEY}}subtotalAmount{${MONEY}}amountPerQuantity{${MONEY}}compareAtAmountPerQuantity{${MONEY}}}discountAllocations{discountedAmount{${MONEY}}}sellingPlanAllocation{sellingPlan{id name description recurringDeliveries options{name value}}checkoutChargeAmount{${MONEY}}priceAdjustments{price{${MONEY}}compareAtPrice{${MONEY}}perDeliveryPrice{${MONEY}}}}merchandise{... on ProductVariant{id title sku availableForSale requiresShipping ${inventoryField(access)} image{${IMAGE_FIELDS}}price{${MONEY}}compareAtPrice{${MONEY}}selectedOptions{name value}product{id title handle vendor featuredImage{${IMAGE_FIELDS}}}}}... on ComponentizableCartLine{lineComponents{id quantity merchandise{... on ProductVariant{id title product{title handle}}}}}}}}`;
1353
1357
  }
1354
1358
 
1355
1359
  // src/selling-plans.ts
@@ -1530,7 +1534,7 @@
1530
1534
  var openWithoutDrawer = false;
1531
1535
  var announcedOpen = false;
1532
1536
  var returnFocus = null;
1533
- var classWatcher = null;
1537
+ var pageWatcher = null;
1534
1538
  var isFocusable = (el) => el !== null && "focus" in el;
1535
1539
  var focusables = (drawer) => qsa(drawer, FOCUSABLE).filter((el) => el.offsetParent !== null || el === document.activeElement);
1536
1540
  var drawers = () => qsa(document, sel("cart-drawer"));
@@ -1538,18 +1542,15 @@
1538
1542
  var hasFocusInside = (all) => all.some((drawer) => drawer.contains(document.activeElement));
1539
1543
  var isManual = (drawer) => get(drawer, "cart-drawer") === "manual";
1540
1544
  function isOpen() {
1545
+ const openClassed = [...document.getElementsByClassName(cfg.cartDrawerOpenClass)];
1546
+ return openClassed.some((el) => el.matches(sel("cart-drawer"))) || openWithoutDrawer && !drawers().length;
1547
+ }
1548
+ function announceChange() {
1549
+ const open = isOpen();
1550
+ if (open === announcedOpen) return;
1541
1551
  const all = drawers();
1542
- return all.length ? all.some(isOpenDrawer) : openWithoutDrawer;
1543
- }
1544
- function watchOpenClass(drawer) {
1545
- classWatcher ?? (classWatcher = new MutationObserver(() => {
1546
- const open = isOpen();
1547
- if (open === announcedOpen) return;
1548
- const all = drawers();
1549
- if (open) announceOpen(all.filter(isOpenDrawer));
1550
- else announceClosed(all, hasFocusInside(all));
1551
- }));
1552
- classWatcher.observe(drawer, { attributes: true, attributeFilter: ["class"] });
1552
+ if (open) announceOpen(all.filter(isOpenDrawer));
1553
+ else announceClosed(all, hasFocusInside(all));
1553
1554
  }
1554
1555
  function syncDrawerAria() {
1555
1556
  qsa(document, sel("cart-open")).forEach((button) => {
@@ -1564,7 +1565,14 @@
1564
1565
  drawer.setAttribute("aria-modal", String(open));
1565
1566
  drawer.setAttribute("aria-hidden", String(!open));
1566
1567
  drawer.inert = !open;
1567
- watchOpenClass(drawer);
1568
+ });
1569
+ if (pageWatcher) return;
1570
+ pageWatcher = new MutationObserver(announceChange);
1571
+ pageWatcher.observe(document.documentElement, {
1572
+ attributes: true,
1573
+ attributeFilter: ["class"],
1574
+ childList: true,
1575
+ subtree: true
1568
1576
  });
1569
1577
  }
1570
1578
  function focusInto(drawer) {
@@ -1587,6 +1595,7 @@
1587
1595
  }
1588
1596
  function announceClosed(all, hadFocus) {
1589
1597
  announcedOpen = false;
1598
+ openWithoutDrawer = false;
1590
1599
  syncDrawerAria();
1591
1600
  if (hadFocus && returnFocus?.isConnected) returnFocus.focus({ preventScroll: true });
1592
1601
  returnFocus = null;
@@ -1606,7 +1615,6 @@
1606
1615
  }
1607
1616
  function closeCart() {
1608
1617
  if (!isOpen()) return;
1609
- openWithoutDrawer = false;
1610
1618
  const all = drawers();
1611
1619
  const hadFocus = hasFocusInside(all);
1612
1620
  all.forEach((drawer) => {
@@ -2146,19 +2154,14 @@
2146
2154
  var CART_ID = /^gid:\/\/shopify\/Cart\/[\w-]+(\?key=[\w-]+)?$/;
2147
2155
 
2148
2156
  // server/src/shared/serial.ts
2157
+ var settled = () => void 0;
2149
2158
  function createSerialQueue() {
2150
2159
  let tail = Promise.resolve();
2151
- let pending2 = 0;
2152
- const settled = () => {
2153
- pending2--;
2154
- };
2155
- const run = (task) => {
2156
- pending2++;
2160
+ return (task) => {
2157
2161
  const result = tail.then(task);
2158
2162
  tail = result.then(settled, settled);
2159
2163
  return result;
2160
2164
  };
2161
- return Object.assign(run, { idle: () => !pending2 });
2162
2165
  }
2163
2166
 
2164
2167
  // src/cart/store.ts
@@ -2235,6 +2238,14 @@
2235
2238
  if (warnings.length) emit("cart-warning", { warnings });
2236
2239
  }
2237
2240
  var runInOrder = createSerialQueue();
2241
+ var fillingTasks = 0;
2242
+ function queueFilling(queue) {
2243
+ fillingTasks++;
2244
+ return queue().finally(() => {
2245
+ fillingTasks--;
2246
+ });
2247
+ }
2248
+ var mayFill = () => fillingTasks > 0;
2238
2249
  function enqueue(task) {
2239
2250
  return runInOrder(task).then(
2240
2251
  (value) => {
@@ -2313,17 +2324,15 @@
2313
2324
  const withIdentity = cfg.country ? { buyerIdentity: { countryCode: cfg.country }, ...input } : input;
2314
2325
  return send("cartCreate", "$input: CartInput!", "input: $input", { input: withIdentity });
2315
2326
  }
2316
- async function mutateCart({
2317
- name,
2318
- args,
2319
- inner,
2320
- variables,
2321
- createInput
2322
- }) {
2327
+ async function mutateCart({ name, variable, type, value, create }) {
2328
+ const createInput = create ? { [variable]: value } : null;
2323
2329
  const cartId = savedCartId();
2324
2330
  if (!cartId) return createInput ? createCart(createInput) : null;
2325
2331
  try {
2326
- return await send(name, `$cartId: ID!, ${args}`, `cartId: $cartId, ${inner}`, { ...variables, cartId });
2332
+ return await send(name, `$cartId: ID!, $${variable}: ${type}`, `cartId: $cartId, ${variable}: $${variable}`, {
2333
+ [variable]: value,
2334
+ cartId
2335
+ });
2327
2336
  } catch (error) {
2328
2337
  if (!isCartGone(error)) throw error;
2329
2338
  forgetSavedCart();
@@ -2361,17 +2370,17 @@
2361
2370
  }
2362
2371
  var updateLines = (lines) => mutateCart({
2363
2372
  name: "cartLinesUpdate",
2364
- args: "$lines: [CartLineUpdateInput!]!",
2365
- inner: "lines: $lines",
2366
- variables: { lines },
2367
- createInput: null
2373
+ variable: "lines",
2374
+ type: "[CartLineUpdateInput!]!",
2375
+ value: lines,
2376
+ create: false
2368
2377
  });
2369
2378
  var removeLines = (lineIds) => mutateCart({
2370
2379
  name: "cartLinesRemove",
2371
- args: "$lineIds: [ID!]!",
2372
- inner: "lineIds: $lineIds",
2373
- variables: { lineIds },
2374
- createInput: null
2380
+ variable: "lineIds",
2381
+ type: "[ID!]!",
2382
+ value: lineIds,
2383
+ create: false
2375
2384
  });
2376
2385
  var setLineQuantity = (lineId, target) => target > 0 ? updateLines([{ id: lineId, quantity: target }]) : removeLines([lineId]);
2377
2386
 
@@ -2414,7 +2423,7 @@
2414
2423
  return cart && !cart.totalQuantity ? null : savedCartId();
2415
2424
  }
2416
2425
  async function checkout(target = cfg.checkoutTarget) {
2417
- if (runInOrder.idle() && !cartToCheckOut()) return null;
2426
+ if (!cartToCheckOut() && !mayFill()) return null;
2418
2427
  const tab = target === "_blank" ? window.open("", "_blank") : null;
2419
2428
  if (tab) detachOpenerIfAllowed(tab);
2420
2429
  try {
@@ -2450,7 +2459,9 @@
2450
2459
  reportError(error, "cart reload after a failed change");
2451
2460
  }
2452
2461
  }
2462
+ var queuedLoad = null;
2453
2463
  function runChange(task) {
2464
+ queuedLoad = null;
2454
2465
  return enqueue(
2455
2466
  () => task().catch(async (error) => {
2456
2467
  if (isUnclearFailure(error)) await reloadAfterUnclearFailure();
@@ -2511,9 +2522,17 @@
2511
2522
  }
2512
2523
  return currentCart();
2513
2524
  }
2525
+ function reload() {
2526
+ queuedLoad ?? (queuedLoad = queueFilling(
2527
+ () => runInOrder(() => {
2528
+ queuedLoad = null;
2529
+ return load();
2530
+ })
2531
+ ));
2532
+ return queuedLoad;
2533
+ }
2514
2534
  var Cart = {
2515
- /** Loads the saved cart in the queue, so a change Shopify answers meanwhile isn't replaced by an older answer. */
2516
- init: () => runInOrder(load),
2535
+ init: reload,
2517
2536
  /** The saved cart's id. */
2518
2537
  id: savedCartId,
2519
2538
  get status() {
@@ -2575,20 +2594,22 @@
2575
2594
  const lines = (Array.isArray(input) ? input : [input]).map(
2576
2595
  (line) => toLineInput(line, quantity, options)
2577
2596
  );
2578
- return runChange(async () => {
2579
- const cart = await mutateCart({
2580
- name: "cartLinesAdd",
2581
- args: "$lines: [CartLineInput!]!",
2582
- inner: "lines: $lines",
2583
- variables: { lines },
2584
- createInput: { lines }
2585
- });
2586
- if (!cart) throw new TetherError("Shopify answered the add without a cart");
2587
- commit(cart, "add");
2588
- emit("added", { cart, lines });
2589
- if (cfg.openCartOnAdd) openCart();
2590
- return cart;
2591
- });
2597
+ return queueFilling(
2598
+ () => runChange(async () => {
2599
+ const cart = await mutateCart({
2600
+ name: "cartLinesAdd",
2601
+ variable: "lines",
2602
+ type: "[CartLineInput!]!",
2603
+ value: lines,
2604
+ create: true
2605
+ });
2606
+ if (!cart) throw new TetherError("Shopify answered the add without a cart");
2607
+ commit(cart, "add");
2608
+ emit("added", { cart, lines });
2609
+ if (cfg.openCartOnAdd) openCart();
2610
+ return cart;
2611
+ })
2612
+ );
2592
2613
  },
2593
2614
  /**
2594
2615
  * `updateLine(lineId, 3)` or `updateLine(lineId, { quantity, sellingPlanId, attributes })`.
@@ -2617,15 +2638,14 @@
2617
2638
  });
2618
2639
  },
2619
2640
  setNote(note) {
2620
- const variables = { note: note ?? "" };
2621
2641
  return runChange(
2622
2642
  async () => commit(
2623
2643
  await mutateCart({
2624
2644
  name: "cartNoteUpdate",
2625
- args: "$note: String!",
2626
- inner: "note: $note",
2627
- variables,
2628
- createInput: variables
2645
+ variable: "note",
2646
+ type: "String!",
2647
+ value: note ?? "",
2648
+ create: true
2629
2649
  }),
2630
2650
  "note"
2631
2651
  )
@@ -2638,13 +2658,12 @@
2638
2658
  */
2639
2659
  setAttributes(attributes) {
2640
2660
  return runChange(async () => {
2641
- const variables = { attributes: mergedAttributes(attributes) };
2642
2661
  const cart = await mutateCart({
2643
2662
  name: "cartAttributesUpdate",
2644
- args: "$attributes: [AttributeInput!]!",
2645
- inner: "attributes: $attributes",
2646
- variables,
2647
- createInput: variables
2663
+ variable: "attributes",
2664
+ type: "[AttributeInput!]!",
2665
+ value: mergedAttributes(attributes),
2666
+ create: true
2648
2667
  });
2649
2668
  return commit(cart, "attributes");
2650
2669
  });
@@ -2652,13 +2671,12 @@
2652
2671
  /** Replaces the discount codes; `[]` removes them all. */
2653
2672
  setDiscountCodes(codes) {
2654
2673
  return runChange(async () => {
2655
- const variables = { discountCodes: discountCodesFrom(codes) };
2656
2674
  const cart = await mutateCart({
2657
2675
  name: "cartDiscountCodesUpdate",
2658
- args: "$discountCodes: [String!]!",
2659
- inner: "discountCodes: $discountCodes",
2660
- variables,
2661
- createInput: variables
2676
+ variable: "discountCodes",
2677
+ type: "[String!]!",
2678
+ value: discountCodesFrom(codes),
2679
+ create: true
2662
2680
  });
2663
2681
  return commit(cart, "discount");
2664
2682
  });
@@ -2695,10 +2713,10 @@
2695
2713
  return runChange(async () => {
2696
2714
  const cart = await mutateCart({
2697
2715
  name: "cartBuyerIdentityUpdate",
2698
- args: "$buyerIdentity: CartBuyerIdentityInput!",
2699
- inner: "buyerIdentity: $buyerIdentity",
2700
- variables: { buyerIdentity },
2701
- createInput: create ? { buyerIdentity } : null
2716
+ variable: "buyerIdentity",
2717
+ type: "CartBuyerIdentityInput!",
2718
+ value: buyerIdentity,
2719
+ create
2702
2720
  }).catch((error) => {
2703
2721
  if (create || !isCartGone(error)) throw error;
2704
2722
  return null;
@@ -3597,7 +3615,7 @@
3597
3615
  }
3598
3616
 
3599
3617
  // src/part-integrity.ts
3600
- var PART_INTEGRITY = { "tether.diagnose.js": "sha384-CqtXzvWbLD8aIgyTM43+KMXEFA7r7lhG+0XyQAw3Sp7B5qrzPsxlA9QfzBjoPqZz", "tether.markets.js": "sha384-WjowbRhM7OzzZOrCPZWSZqN7EjIiiR7u9cGmdI+9kgFVgmEQS8lVGWjgx+8jILOf", "tether.search.js": "sha384-fLQ7eKc5XOv0Cg2FfrZyeFAkRR4wDMjUWFpwvKrfPRnT2NvTuhKg80+KVu8Qce/G", "tether.lists.js": "sha384-l2uyr96zTetjo2WWhGsBamd1ZYkC3OB3G3+OScLEvxdok0c8k9GXLAh1WRALUr4S", "tether.extras.js": "sha384-qx7paZ/rjwtn1Yy9TgszulmBuJsIQ9y4eZ590AArnZ+IDB8IzwJ5dNOFJ+yMHPdb", "tether.account.js": "sha384-82dpAxK4rPlXuNxSk/dvaItjRQf+Z79EJnUqXtT9D8HjpF9XwoTIUxDViiV1dIhz", "tether.account-pages.js": "sha384-ND3kIaRypgnHG3QMDb8CqDxt7fuukDCdHsIAHoOUUsz3+FjvBqXgRDV4Mjp6x8jr", "tether.analytics.js": "sha384-jnLesn/+edWBSPuXLj7VX1kSAGwEqtb0VbHjuU//ofqgxkndHlDFsS8Bc8htlGt8" };
3618
+ var PART_INTEGRITY = { "tether.diagnose.js": "sha384-CqtXzvWbLD8aIgyTM43+KMXEFA7r7lhG+0XyQAw3Sp7B5qrzPsxlA9QfzBjoPqZz", "tether.markets.js": "sha384-4UK4+noZOE06Ra3Eyin9kAUXz/bbvcbq3gvdwNBItnPCQzmPyD398YoM0P1aTL0Q", "tether.search.js": "sha384-fLQ7eKc5XOv0Cg2FfrZyeFAkRR4wDMjUWFpwvKrfPRnT2NvTuhKg80+KVu8Qce/G", "tether.lists.js": "sha384-C+ibx3RT6OStQI+eq0K+ai44lQsHeI4iueLoZaW/+AqVZ7D+gcjoHiohd0CFyNUd", "tether.extras.js": "sha384-qx7paZ/rjwtn1Yy9TgszulmBuJsIQ9y4eZ590AArnZ+IDB8IzwJ5dNOFJ+yMHPdb", "tether.account.js": "sha384-A5LC6eOq1My82IYPD0qA/NKhefGuBvA+9vwY7l/t0S40/SwIjWCBXJIO3YNyYGPc", "tether.account-pages.js": "sha384-ND3kIaRypgnHG3QMDb8CqDxt7fuukDCdHsIAHoOUUsz3+FjvBqXgRDV4Mjp6x8jr", "tether.analytics.js": "sha384-jnLesn/+edWBSPuXLj7VX1kSAGwEqtb0VbHjuU//ofqgxkndHlDFsS8Bc8htlGt8" };
3601
3619
 
3602
3620
  // src/part-registry.ts
3603
3621
  function isTetherInternals(value) {
@@ -3605,7 +3623,7 @@
3605
3623
  }
3606
3624
 
3607
3625
  // src/version.ts
3608
- var VERSION = "0.9.7";
3626
+ var VERSION = "0.9.8";
3609
3627
 
3610
3628
  // src/lazy-iife.ts
3611
3629
  var coreModules = {
@@ -3645,9 +3663,6 @@
3645
3663
  get "loader.ts"() {
3646
3664
  return [clearProductCache, getProduct, normalizeProductKey, primeProduct, withProductFragment];
3647
3665
  },
3648
- get "fragments.ts"() {
3649
- return [collectionFields];
3650
- },
3651
3666
  get "selling-plans.ts"() {
3652
3667
  return [allPlans];
3653
3668
  },
@@ -3792,6 +3807,13 @@
3792
3807
  }
3793
3808
  var isLoginOutcome = (value) => value === "in" || value === "expired" || value === "error";
3794
3809
 
3810
+ // src/part-use.ts
3811
+ function withPart(name, use) {
3812
+ loadPart(name).then(use).catch((error) => {
3813
+ reportError(error, name);
3814
+ });
3815
+ }
3816
+
3795
3817
  // src/account-api.ts
3796
3818
  var ACCOUNT_ATTRIBUTES = [
3797
3819
  "account-login",
@@ -3812,9 +3834,7 @@
3812
3834
  if (!cfg.account) return;
3813
3835
  const needed = within(root, accountSelector()).length > 0 || isLoginOutcome(new URLSearchParams(window.location.search).get("account")) || hasLoginHint();
3814
3836
  if (!needed) return;
3815
- loadPart("account").then((part) => part.mountAccount(root)).catch((error) => {
3816
- reportError(error, "account");
3817
- });
3837
+ withPart("account", (part) => part.mountAccount(root));
3818
3838
  }
3819
3839
  function fromPart(name) {
3820
3840
  return (...args) => loadPart("account").then((part) => {
@@ -3993,30 +4013,29 @@
3993
4013
 
3994
4014
  // src/controls/extras.ts
3995
4015
  var addGroup = (button) => loadPart("extras").then((part) => part.addGroup(button));
3996
- var reportExtrasError = (error) => {
3997
- reportError(error, "extras");
3998
- };
3999
4016
  function onClick4(event) {
4000
4017
  const { target } = event;
4001
4018
  const button = target instanceof window.Element ? target.closest(sel("group-add")) : null;
4002
4019
  if (!button) return;
4003
4020
  event.preventDefault();
4004
- busy(button, () => addGroup(button)).catch(reportExtrasError);
4021
+ busy(button, () => addGroup(button)).catch((error) => {
4022
+ reportError(error, "extras");
4023
+ });
4005
4024
  }
4006
4025
  function onStorage(event) {
4007
4026
  if (!cfg.domain || !event.key?.startsWith(`${cfg.prefix}:`)) return;
4008
- loadPart("extras").then((part) => {
4027
+ withPart("extras", (part) => {
4009
4028
  part.onStorage(event);
4010
- }).catch(reportExtrasError);
4029
+ });
4011
4030
  }
4012
4031
  function onVariantChanged(event) {
4013
4032
  if (!isOwnEvent(event, "variant-changed")) return;
4014
4033
  const { target } = event;
4015
4034
  if (!(target instanceof window.Element)) return;
4016
4035
  if (!cfg.variantUrl && !target.hasAttribute(attr("variant-url"))) return;
4017
- loadPart("extras").then((part) => {
4036
+ withPart("extras", (part) => {
4018
4037
  part.writeVariantUrl(target, event.detail);
4019
- }).catch(reportExtrasError);
4038
+ });
4020
4039
  }
4021
4040
  function bindExtrasControls() {
4022
4041
  document.addEventListener("click", onClick4);
@@ -4054,14 +4073,6 @@
4054
4073
  hooks.unmount();
4055
4074
  });
4056
4075
  }
4057
- function onChange3(event) {
4058
- const { target } = event;
4059
- if (!(target instanceof window.HTMLSelectElement) || !target.matches(sel("country-select"))) return;
4060
- if (!target.value) return;
4061
- setCountry(target.value).catch((error) => {
4062
- reportError(error, "country");
4063
- });
4064
- }
4065
4076
  function onOnline() {
4066
4077
  retryFailed();
4067
4078
  liveLists.forEach((list) => {
@@ -4070,7 +4081,6 @@
4070
4081
  }
4071
4082
  function bindNavigation(hooks) {
4072
4083
  if (cfg.astro) bindAstroRouter(hooks);
4073
- document.addEventListener("change", onChange3);
4074
4084
  window.addEventListener("online", onOnline);
4075
4085
  }
4076
4086
 
@@ -4101,16 +4111,12 @@
4101
4111
  }
4102
4112
  function mountParts(root) {
4103
4113
  if (within(root, `${sel("country-select")},${sel("country-bind")}`).length) {
4104
- loadPart("markets").then((part) => part.renderCountrySelects(root)).catch((error) => {
4105
- reportError(error, "markets");
4106
- });
4114
+ withPart("markets", (part) => part.renderCountrySelects(root));
4107
4115
  }
4108
4116
  mountAccountIfUsed(root);
4109
4117
  if (within(root, sel("search")).length) {
4110
- loadPart("search").then((part) => {
4118
+ withPart("search", (part) => {
4111
4119
  part.mountSearch(root);
4112
- }).catch((error) => {
4113
- reportError(error, "search");
4114
4120
  });
4115
4121
  }
4116
4122
  }
@@ -4165,7 +4171,7 @@
4165
4171
  async function cartInPageMarket(cart) {
4166
4172
  const country = cfg.country;
4167
4173
  const cartCountry = cart?.buyerIdentity.countryCode;
4168
- if (!cart || !country || !cartCountry || cartCountry === country) return cart;
4174
+ if (!country || !cartCountry || cartCountry === country) return cart;
4169
4175
  try {
4170
4176
  return await Cart.setBuyerIdentity({ countryCode: country }, { create: false });
4171
4177
  } catch (error) {
@@ -27,13 +27,15 @@
27
27
  var m3 = window.Tether.__core["dom.ts"];
28
28
  var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, integerAttribute, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
29
29
 
30
- // tether-core:fragments.ts
31
- var m4 = window.Tether.__core["fragments.ts"];
32
- var [collectionFields] = m4;
30
+ // src/shopify-fields.ts
31
+ var IMAGE_FIELDS = "url altText width height";
32
+ function collectionFields() {
33
+ return ` id handle title description descriptionHtml image{${IMAGE_FIELDS}}seo{title description}`;
34
+ }
33
35
 
34
36
  // tether-core:loader.ts
35
- var m5 = window.Tether.__core["loader.ts"];
36
- var [clearProductCache, getProduct, normalizeProductKey, primeProduct, withProductFragment] = m5;
37
+ var m4 = window.Tether.__core["loader.ts"];
38
+ var [clearProductCache, getProduct, normalizeProductKey, primeProduct, withProductFragment] = m4;
37
39
 
38
40
  // server/src/shared/json.ts
39
41
  function isRecord(value) {
@@ -64,16 +66,16 @@
64
66
  });
65
67
 
66
68
  // tether-core:status.ts
67
- var m6 = window.Tether.__core["status.ts"];
68
- var [boundary, isNotFound, resolveProductKey, setScopeStatus] = m6;
69
+ var m5 = window.Tether.__core["status.ts"];
70
+ var [boundary, isNotFound, resolveProductKey, setScopeStatus] = m5;
69
71
 
70
72
  // tether-core:collection.ts
71
- var m7 = window.Tether.__core["collection.ts"];
72
- var [listSelector] = m7;
73
+ var m6 = window.Tether.__core["collection.ts"];
74
+ var [listSelector] = m6;
73
75
 
74
76
  // tether-core:shopify-values.ts
75
- var m8 = window.Tether.__core["shopify-values.ts"];
76
- var [isHttpsUrl, MAX_CONNECTION_SIZE] = m8;
77
+ var m7 = window.Tether.__core["shopify-values.ts"];
78
+ var [isHttpsUrl, MAX_CONNECTION_SIZE] = m7;
77
79
 
78
80
  // src/lists.ts
79
81
  var URL_QUERY_SOURCE = "url:";
@@ -1 +1 @@
1
- (()=>{var b=Object.defineProperty;var rt=(e,t,o)=>t in e?b(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var nt=(e,t)=>{for(var o in t)b(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>rt(e,typeof t!="symbol"?t+"":t,o);var O={};nt(O,{getProducts:()=>X,getRecommendations:()=>G,loadList:()=>yt});var st=window.Tether.__core["config.ts"],[P,Et,xt,It,Ct,A,Nt]=st;var it=window.Tether.__core["client.ts"],[$t,l,ct,T,u,E,_t]=it;var at=window.Tether.__core["dom.ts"],[Ot,x,St,L,m,bt,At,s,p,Lt,M,Mt,K,Kt,Ut,Ft,U,F,c,q,v,I,f]=at;var dt=window.Tether.__core["fragments.ts"],[D]=dt;var lt=window.Tether.__core["loader.ts"],[Dt,Ht,H,h,g]=lt;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var C={amount:"string",currencyCode:"string"},Q={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:C,maxVariantPrice:C},variants:{nodes:[{id:"string",price:C,selectedOptions:["object"]}]}},Y={nodes:[Q],pageInfo:{hasNextPage:"boolean"}};var j=u({collection:T({handle:"string",products:Y})}),z=u({products:Y}),B=u({productRecommendations:T([Q])});var ut=window.Tether.__core["status.ts"],[Wt,N,R,$]=ut;var mt=window.Tether.__core["collection.ts"],[_]=mt;var pt=window.Tether.__core["shopify-values.ts"],[Xt,V]=pt;var W="url:",ft=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${D()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,ht="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function X({collection:e,query:t,first:o=P.collectionFirst,after:r=null,sortKey:n,reverse:i=!1,filters:et}={}){if(e){let S=await l(g(ft),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:i,filters:et??void 0},j);if(!S.collection)throw new E(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...ot}=S.collection;return y.nodes.forEach(h),{collection:ot,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(ht),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:i},z);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function G(e,t="RELATED"){let o=H(typeof e=="object"?e?.id:e);if(!o)throw new E("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),i=(await l(g(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:o,intent:t}:{handle:o,intent:t},B)).productRecommendations??[];return i.forEach(h),i}var gt=e=>e instanceof window.Element,Z=(e,t)=>M(e,"limit",{min:1,max:V,fallback:t}),wt=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",k=class{constructor(t){a(this,"root");a(this,"products",[]);a(this,"pageInfo",null);a(this,"collection",null);a(this,"loadToken",0);this.root=t,t.addEventListener("click",o=>{if(!gt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(_())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return F(this.root,t,_())}options(){let{root:t}=this,o={reverse:s(t,"reverse")==="true",first:Z(t,P.collectionFirst)},r=s(t,"sort");if(r&&(o.sortKey=r),p(t,"collection"))return o.collection=s(t,"collection")??"",o;let n=s(t,"products")??"";return o.query=n.startsWith(W)?new URL(window.location.href).searchParams.get(n.slice(W.length))||"":n,o}async loadRecommendations(){let{key:t}=R(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=R(o)),G(t,wt(s(this.root,"intent")))}async load(t=!1){this.loadToken+=1;let o=this.loadToken,r=()=>o!==this.loadToken;try{if(p(this.root,"recommendations")){let n=await this.loadRecommendations();if(r())return;this.products=n.slice(0,Z(this.root,n.length))}else{let n=await X({...this.options(),after:t?this.pageInfo?.endCursor??null:null});if(r())return;this.collection=n.collection,this.pageInfo=n.pageInfo,this.products=t?[...this.products,...n.products]:n.products}this.render(),$(this.root,"ready"),m("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||$(this.root,N(n)?"not-found":"error",n),N(n)&&p(this.root,"recommendations")||A(n,"list load failed"),m("error",{error:n,context:"list"},this.root)}}render(){let{collection:t}=this;this.$(c("collection-bind")).forEach(r=>{switch(s(r,"collection-bind")??""){case"title":I(r,t?.title??"");break;case"description":v(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":I(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{U(r,this.products,(n,i)=>{n.setAttribute(x("product"),i.handle),n.removeAttribute(x("state"))}),m("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=s(r,"show");n==="list-empty"&&f(r,o),n==="list-filled"&&f(r,!o)}),this.$(c("load-more")).forEach(r=>{f(r,!!this.pageInfo?.hasNextPage)}),K("list")}},J=new WeakMap;function yt(e){let t=J.get(e);return t||(t=new k(e),J.set(e,t)),t.load()}function Pt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function tt(e,t){let o=Reflect.get(window,"Tether");if(!Pt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}tt("lists",O);})();
1
+ (()=>{var b=Object.defineProperty;var rt=(e,t,o)=>t in e?b(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var nt=(e,t)=>{for(var o in t)b(e,o,{get:t[o],enumerable:!0})};var a=(e,t,o)=>rt(e,typeof t!="symbol"?t+"":t,o);var k={};nt(k,{getProducts:()=>X,getRecommendations:()=>G,loadList:()=>yt});var st=window.Tether.__core["config.ts"],[P,Et,xt,It,$t,A,Ct]=st;var it=window.Tether.__core["client.ts"],[Rt,l,ct,T,u,E,_t]=it;var at=window.Tether.__core["dom.ts"],[kt,x,Ot,L,p,bt,At,s,m,Lt,M,Mt,K,Kt,Ft,Ut,F,U,c,q,D,I,f]=at;var dt="url altText width height";function v(){return` id handle title description descriptionHtml image{${dt}}seo{title description}`}var lt=window.Tether.__core["loader.ts"],[vt,Ht,H,h,g]=lt;function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var $={amount:"string",currencyCode:"string"},Q={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:$,maxVariantPrice:$},variants:{nodes:[{id:"string",price:$,selectedOptions:["object"]}]}},Y={nodes:[Q],pageInfo:{hasNextPage:"boolean"}};var j=u({collection:T({handle:"string",products:Y})}),z=u({products:Y}),B=u({productRecommendations:T([Q])});var ut=window.Tether.__core["status.ts"],[Wt,C,N,R]=ut;var pt=window.Tether.__core["collection.ts"],[_]=pt;var mt=window.Tether.__core["shopify-values.ts"],[Xt,V]=mt;var W="url:",ft=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${v()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,ht="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function X({collection:e,query:t,first:o=P.collectionFirst,after:r=null,sortKey:n,reverse:i=!1,filters:et}={}){if(e){let O=await l(g(ft),{handle:e,first:o,after:r,sortKey:n||void 0,reverse:i,filters:et??void 0},j);if(!O.collection)throw new E(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:y,...ot}=O.collection;return y.nodes.forEach(h),{collection:ot,products:y.nodes,pageInfo:y.pageInfo}}let w=await l(g(ht),{first:o,after:r,query:t||void 0,sortKey:n||void 0,reverse:i},z);return w.products.nodes.forEach(h),{collection:null,products:w.products.nodes,pageInfo:w.products.pageInfo}}async function G(e,t="RELATED"){let o=H(typeof e=="object"?e?.id:e);if(!o)throw new E("No product for recommendations",{code:"NOT_FOUND"});let r=o.startsWith("gid://"),i=(await l(g(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:o,intent:t}:{handle:o,intent:t},B)).productRecommendations??[];return i.forEach(h),i}var gt=e=>e instanceof window.Element,Z=(e,t)=>M(e,"limit",{min:1,max:V,fallback:t}),wt=e=>e==="COMPLEMENTARY"?"COMPLEMENTARY":"RELATED",S=class{constructor(t){a(this,"root");a(this,"products",[]);a(this,"pageInfo",null);a(this,"collection",null);a(this,"loadToken",0);this.root=t,t.addEventListener("click",o=>{if(!gt(o.target))return;let r=o.target.closest(c("load-more"));r?.closest(_())===t&&(o.preventDefault(),L(r,()=>this.load(!0)))})}$(t){return U(this.root,t,_())}options(){let{root:t}=this,o={reverse:s(t,"reverse")==="true",first:Z(t,P.collectionFirst)},r=s(t,"sort");if(r&&(o.sortKey=r),m(t,"collection"))return o.collection=s(t,"collection")??"",o;let n=s(t,"products")??"";return o.query=n.startsWith(W)?new URL(window.location.href).searchParams.get(n.slice(W.length))||"":n,o}async loadRecommendations(){let{key:t}=N(this.root,window.location,"recommendations"),o=this.root.closest(c("product"));return!t&&o&&({key:t}=N(o)),G(t,wt(s(this.root,"intent")))}async load(t=!1){this.loadToken+=1;let o=this.loadToken,r=()=>o!==this.loadToken;try{if(m(this.root,"recommendations")){let n=await this.loadRecommendations();if(r())return;this.products=n.slice(0,Z(this.root,n.length))}else{let n=await X({...this.options(),after:t?this.pageInfo?.endCursor??null:null});if(r())return;this.collection=n.collection,this.pageInfo=n.pageInfo,this.products=t?[...this.products,...n.products]:n.products}this.render(),R(this.root,"ready"),p("list-ready",{products:this.products,collection:this.collection},this.root)}catch(n){if(r())return;t||R(this.root,C(n)?"not-found":"error",n),C(n)&&m(this.root,"recommendations")||A(n,"list load failed"),p("error",{error:n,context:"list"},this.root)}}render(){let{collection:t}=this;this.$(c("collection-bind")).forEach(r=>{switch(s(r,"collection-bind")??""){case"title":I(r,t?.title??"");break;case"description":D(r,t?.descriptionHtml);break;case"image":q(r,t?.image?.url,t?.image?.altText||t?.title);break;case"count":I(r,this.products.length);break}}),this.$(c("list")).forEach(r=>{F(r,this.products,(n,i)=>{n.setAttribute(x("product"),i.handle),n.removeAttribute(x("state"))}),p("list-rendered",{container:r},this.root)});let o=this.products.length===0;this.$(c("show")).forEach(r=>{let n=s(r,"show");n==="list-empty"&&f(r,o),n==="list-filled"&&f(r,!o)}),this.$(c("load-more")).forEach(r=>{f(r,!!this.pageInfo?.hasNextPage)}),K("list")}},J=new WeakMap;function yt(e){let t=J.get(e);return t||(t=new S(e),J.set(e,t)),t.load()}function Pt(e){return d(e)&&d(e.__core)&&d(e.__parts)}function tt(e,t){let o=Reflect.get(window,"Tether");if(!Pt(o))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);o.__parts[e]=t}tt("lists",k);})();
@@ -246,9 +246,21 @@
246
246
  el.textContent = countryField(inUse, get(el, "country-bind") || DEFAULT_BIND);
247
247
  });
248
248
  }
249
+ var followingSelects = false;
250
+ function onCountrySelectChange(event) {
251
+ const { target } = event;
252
+ if (!(target instanceof window.HTMLSelectElement) || !target.matches(sel("country-select")) || !target.value) return;
253
+ setCountry(target.value).catch((error) => {
254
+ reportError(error, "country");
255
+ });
256
+ }
249
257
  function renderCountrySelects(root = document) {
250
258
  const selects = within(root, `select${sel("country-select")}`);
251
259
  const binds = within(root, sel("country-bind"));
260
+ if (selects.length && !followingSelects) {
261
+ followingSelects = true;
262
+ document.addEventListener("change", onCountrySelectChange);
263
+ }
252
264
  if (!selects.length && !binds.length) return Promise.resolve();
253
265
  return getLocalization().then((localization) => {
254
266
  fillCountries(selects, binds, localization);
@@ -1 +1 @@
1
- (()=>{var G=Object.defineProperty;var V=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})};var b={};V(b,{detectMarket:()=>K,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>Ee});var Z=window.Tether.__core["config.ts"],[i,Ae,Ne,M,S,C,ve]=Z;var Q=window.Tether.__core["client.ts"],[Ie,x,ze,Re,T,E,Ue]=Q;var X=window.Tether.__core["cart.ts"],[g]=X;var ee=window.Tether.__core["collection.ts"],[P]=ee;var te=window.Tether.__core["loader.ts"],[_,je,Ke,$e,qe]=te;var ne=window.Tether.__core["dom.ts"],[Ye,m,Be,We,A,Ge,Ve,N,Ze,Qe,Xe,et,tt,nt,ot,rt,at,it,w,ct,ut,lt,st]=ne;var oe=window.Tether.__core["mounting.ts"],[v,O,I,z,R,k]=oe;var re=window.Tether.__core["market-codes.ts"],[s,d]=re;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}function F(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}var ae="tether_country",D=()=>`${i.prefix}:market:${i.domain}`,j={getItem:e=>U(e)};function ie(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function ce(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ue(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var le=e=>ue(ce(e));function se(e=j){let t=e.getItem(D());return t?le(t):null}function de(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?F(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function ge(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),c=n("tether-country")||de(t.document,e.cookie||ae);return{country:a||c,language:o||n("tether-language")}}function fe(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let c=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(c)return{locale:o,...c};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function me(e,t,n){switch(e){case"saved":return t.remember===!1?null:se(n.storage);case"server":return ge(t,n);case"webflow":return fe(t,n)}}function pe(e){return e?e===!0?M:e:["saved"]}function K(e=i.markets,t=ie()){let n=(e===i.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let c of pe(n.detect)){let r=me(c,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=c),l&&!o.language&&(o.language=l,a.language=c),f&&!o.locale&&(o.locale=f,a.locale=c)}return o}function $(e){if(i.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var ye="{name} ({currency})",Ce="name",p=null;function we(){p=null}var ke="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},he=T({localization:{country:q,availableCountries:[q]}});function J(){return p??(p=x(ke,{},he).then(e=>e.localization,e=>{throw p=null,e})),p}function Y(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var Le=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>Y(t,a));function be(e,t,n){let a=e.getAttribute(m("country-label"))||ye,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),c=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...c.map(r=>new Option(Le(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=c.length<2&&!e.hasAttribute(m("always-enabled"))}function Me(e,t,n){let a=(i.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,i.locale||void 0)),c=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{be(r,o,a)}),t.forEach(r=>{r.textContent=Y(c,N(r,"country-bind")||Ce)})}function L(e=document){let t=k(e,`select${w("country-select")}`),n=k(e,w("country-bind"));return!t.length&&!n.length?Promise.resolve():J().then(a=>{Me(t,n,a)}).catch(a=>{C(a,"country select")})}var Se=e=>Object.values(i.markets?.locales??{}).find(t=>s(t.country)===e);function xe(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:i.language}function Te(e){_();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{C(n,"cart country")})),R(),v.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(P())||(I.delete(n),z(n))}),t}async function Ee(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new E(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let c=Se(o),r=n||c?.locale,u=r||i.locale,l=xe(t,c),f=o!==i.country||l!==i.language||u!==i.locale;if(i.country=o,i.language=l||void 0,i.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&we();let W=Te(o);return L(),A("country-changed",{country:o,language:i.language}),await Promise.all(W),g.state}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Pe(e){return y(e)&&y(e.__core)&&y(e.__parts)}function B(e,t){let n=Reflect.get(window,"Tether");if(!Pe(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}B("markets",b);})();
1
+ (()=>{var Z=Object.defineProperty;var Q=(e,t)=>{for(var n in t)Z(e,n,{get:t[n],enumerable:!0})};var b={};Q(b,{detectMarket:()=>K,getLocalization:()=>Y,renderCountrySelects:()=>L,setCountry:()=>W});var X=window.Tether.__core["config.ts"],[c,Ne,Oe,S,M,m,Ie]=X;var ee=window.Tether.__core["client.ts"],[Re,x,Ue,He,E,T,Fe]=ee;var te=window.Tether.__core["cart.ts"],[g]=te;var ne=window.Tether.__core["collection.ts"],[P]=ne;var oe=window.Tether.__core["loader.ts"],[_,$e,qe,Je,Ye]=oe;var re=window.Tether.__core["dom.ts"],[We,p,Ge,Ve,v,Ze,Qe,A,Xe,et,tt,nt,ot,rt,at,ct,it,ut,y,lt,st,dt,gt]=re;var ae=window.Tether.__core["mounting.ts"],[N,O,I,z,R,k]=ae;var ce=window.Tether.__core["market-codes.ts"],[s,d]=ce;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}function F(e){try{return decodeURIComponent(e)}catch(t){if(t instanceof URIError)return e;throw t}}var ie="tether_country",D=()=>`${c.prefix}:market:${c.domain}`,j={getItem:e=>U(e)};function ue(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:j,global:e?window:{}}}function le(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function se(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var de=e=>se(le(e));function ge(e=j){let t=e.getItem(D());return t?de(t):null}function fe(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?F(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function me(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),i=n("tether-country")||fe(t.document,e.cookie||ie);return{country:a||i,language:o||n("tether-language")}}function pe(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let i=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(i)return{locale:o,...i};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function ye(e,t,n){switch(e){case"saved":return t.remember===!1?null:ge(n.storage);case"server":return me(t,n);case"webflow":return pe(t,n)}}function we(e){return e?e===!0?S:e:["saved"]}function K(e=c.markets,t=ue()){let n=(e===c.markets?e:M(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let i of we(n.detect)){let r=ye(i,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=i),l&&!o.language&&(o.language=l,a.language=i),f&&!o.locale&&(o.locale=f,a.locale=i)}return o}function $(e){if(c.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var Ce="{name} ({currency})",ke="name",w=null;function he(){w=null}var Le="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},be=E({localization:{country:q,availableCountries:[q]}});function Y(){return w??(w=x(Le,{},be).then(e=>e.localization,e=>{throw w=null,e})),w}function B(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var Se=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>B(t,a));function Me(e,t,n){let a=e.getAttribute(p("country-label"))||Ce,o=(e.getAttribute(p("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),i=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...i.map(r=>new Option(Se(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=i.length<2&&!e.hasAttribute(p("always-enabled"))}function xe(e,t,n){let a=(c.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,c.locale||void 0)),i=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{Me(r,o,a)}),t.forEach(r=>{r.textContent=B(i,A(r,"country-bind")||ke)})}var J=!1;function Ee(e){let{target:t}=e;!(t instanceof window.HTMLSelectElement)||!t.matches(y("country-select"))||!t.value||W(t.value).catch(n=>{m(n,"country")})}function L(e=document){let t=k(e,`select${y("country-select")}`),n=k(e,y("country-bind"));return t.length&&!J&&(J=!0,document.addEventListener("change",Ee)),!t.length&&!n.length?Promise.resolve():Y().then(a=>{xe(t,n,a)}).catch(a=>{m(a,"country select")})}var Te=e=>Object.values(c.markets?.locales??{}).find(t=>s(t.country)===e);function Pe(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:c.language}function _e(e){_();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{m(n,"cart country")})),R(),N.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(P())||(I.delete(n),z(n))}),t}async function W(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new T(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let i=Te(o),r=n||i?.locale,u=r||c.locale,l=Pe(t,i),f=o!==c.country||l!==c.language||u!==c.locale;if(c.country=o,c.language=l||void 0,c.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&he();let V=_e(o);return L(),v("country-changed",{country:o,language:c.language}),await Promise.all(V),g.state}function C(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function ve(e){return C(e)&&C(e.__core)&&C(e.__parts)}function G(e,t){let n=Reflect.get(window,"Tether");if(!ve(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}G("markets",b);})();