@occluze/tether 0.8.1 → 0.9.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.
- package/README.md +5 -5
- package/dist/esm/astro.js +1 -1
- package/dist/esm/chunks/account-FKLGF264.js +1 -0
- package/dist/esm/chunks/{account-pages-XR6QZ3DX.js → account-pages-PNORWX72.js} +1 -1
- package/dist/esm/chunks/analytics-V24XX2J7.js +1 -0
- package/dist/esm/chunks/{chunk-FPJGQ7Z5.js → chunk-2IHA3PVC.js} +1 -1
- package/dist/esm/chunks/chunk-2LYWZ72A.js +1 -0
- package/dist/esm/chunks/{chunk-A2PCQK2F.js → chunk-2NV5PSJ2.js} +1 -1
- package/dist/esm/chunks/chunk-2X5U24IC.js +1 -0
- package/dist/esm/chunks/chunk-5B36ISJF.js +1 -0
- package/dist/esm/chunks/chunk-6WE7XCHH.js +1 -0
- package/dist/esm/chunks/chunk-6ZIOAYKF.js +1 -0
- package/dist/esm/chunks/{chunk-FM7ZLLVP.js → chunk-CR5IGHCO.js} +1 -1
- package/dist/esm/chunks/{chunk-X2JZPXLF.js → chunk-E3JL6WS3.js} +1 -1
- package/dist/esm/chunks/{chunk-COQ6ATC6.js → chunk-F5CLIGSC.js} +1 -1
- package/dist/esm/chunks/{chunk-HXZSNZOV.js → chunk-GOKJQGLG.js} +1 -1
- package/dist/esm/chunks/chunk-RW23CJDZ.js +1 -0
- package/dist/esm/chunks/chunk-TW34GYSL.js +1 -0
- package/dist/esm/chunks/chunk-VKKKH75V.js +1 -0
- package/dist/esm/chunks/{chunk-A3GXCQJ4.js → chunk-YWQWLKFW.js} +1 -1
- package/dist/esm/chunks/chunk-YYNBHXQF.js +1 -0
- package/dist/esm/chunks/{diagnose-IFRNCEYG.js → diagnose-3RTKEBNW.js} +1 -1
- package/dist/esm/chunks/extras-O54VUXK6.js +1 -0
- package/dist/esm/chunks/lists-MRTI5RXY.js +1 -0
- package/dist/esm/chunks/markets-ui-P7G33T6Y.js +1 -0
- package/dist/esm/chunks/search-YSRDFVD7.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/tether.account-pages.js +2 -2
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +2 -2
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +2 -2
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +4 -4
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +1 -1
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +75 -200
- package/dist/tether.lists.js +268 -0
- package/dist/tether.lists.min.js +1 -0
- package/dist/tether.markets.js +3 -3
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +1 -1
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +2 -2
- package/dist/tether.search.min.js +1 -1
- package/dist/types/src/client.d.ts +6 -6
- package/dist/types/src/collection.d.ts +7 -23
- package/dist/types/src/config-sections.d.ts +7 -0
- package/dist/types/src/config.d.ts +6 -0
- package/dist/types/src/index.d.ts +4 -3
- package/dist/types/src/lazy.d.ts +1 -0
- package/dist/types/src/lists.d.ts +20 -0
- package/dist/types/src/loader.d.ts +7 -27
- package/dist/types/src/mounting.d.ts +1 -6
- package/dist/types/src/product-shape.d.ts +13 -36
- package/dist/types/src/server.d.ts +5 -4
- package/dist/types/src/shopify-values.d.ts +6 -0
- package/dist/types/src/storefront/catalog.d.ts +2 -4
- package/dist/types/src/version.d.ts +1 -1
- package/package.json +5 -5
- package/dist/esm/chunks/account-BS5MCC2R.js +0 -1
- package/dist/esm/chunks/analytics-BYN3QHBA.js +0 -1
- package/dist/esm/chunks/chunk-2IVIZDT5.js +0 -1
- package/dist/esm/chunks/chunk-EGIDFV3T.js +0 -1
- package/dist/esm/chunks/chunk-EW3GKRT4.js +0 -1
- package/dist/esm/chunks/chunk-GXCCTPDF.js +0 -1
- package/dist/esm/chunks/chunk-MJFKAMFM.js +0 -1
- package/dist/esm/chunks/chunk-TE5PNI76.js +0 -1
- package/dist/esm/chunks/extras-3477M6Y7.js +0 -1
- package/dist/esm/chunks/markets-ui-3L2UZ7PK.js +0 -1
- package/dist/esm/chunks/search-YR73GIWY.js +0 -1
package/dist/tether.js
CHANGED
|
@@ -240,6 +240,7 @@
|
|
|
240
240
|
sellingPlansFirst: 25,
|
|
241
241
|
collectionFirst: 24,
|
|
242
242
|
retries: 2,
|
|
243
|
+
requestTimeout: 15e3,
|
|
243
244
|
revalidate: true,
|
|
244
245
|
storageKey: "",
|
|
245
246
|
cartDrawerOpenClass: "is-open",
|
|
@@ -304,6 +305,7 @@
|
|
|
304
305
|
"sellingPlansFirst",
|
|
305
306
|
"collectionFirst",
|
|
306
307
|
"retries",
|
|
308
|
+
"requestTimeout",
|
|
307
309
|
"maxAge",
|
|
308
310
|
"lowStock",
|
|
309
311
|
"searchDelay"
|
|
@@ -338,8 +340,11 @@
|
|
|
338
340
|
dropped(name, value);
|
|
339
341
|
}
|
|
340
342
|
}
|
|
343
|
+
var DELAY_OPTIONS = /* @__PURE__ */ new Set(["requestTimeout", "searchDelay"]);
|
|
344
|
+
var MAX_TIMER_MS = 2147483647;
|
|
341
345
|
function countOption(name, value) {
|
|
342
|
-
|
|
346
|
+
const maximum = DELAY_OPTIONS.has(name) ? MAX_TIMER_MS : Number.POSITIVE_INFINITY;
|
|
347
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= maximum) return value;
|
|
343
348
|
return invalidOption(name, value, DEFAULTS[name]);
|
|
344
349
|
}
|
|
345
350
|
function switchOption(name, value) {
|
|
@@ -545,13 +550,27 @@
|
|
|
545
550
|
const unclear = res.ok && (serverError || operation === "mutation" && data == null);
|
|
546
551
|
throw graphQLFailure(res, errors, conf, unclear ? "SERVER_ERROR" : void 0);
|
|
547
552
|
}
|
|
548
|
-
async function
|
|
553
|
+
async function withTimeout(ms, send2) {
|
|
554
|
+
if (!ms) return send2(null);
|
|
555
|
+
const controller = new AbortController();
|
|
556
|
+
const timer = setTimeout(() => {
|
|
557
|
+
controller.abort(new DOMException("signal timed out", "TimeoutError"));
|
|
558
|
+
}, ms);
|
|
559
|
+
try {
|
|
560
|
+
return await send2(controller.signal);
|
|
561
|
+
} finally {
|
|
562
|
+
clearTimeout(timer);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
async function attempt(conf, query2, variables, isData, retry, operation, signal) {
|
|
549
566
|
let res;
|
|
550
567
|
try {
|
|
551
568
|
res = await (conf.fetch ?? fetch)(endpoint(conf), {
|
|
552
569
|
method: "POST",
|
|
553
570
|
headers: { "Content-Type": "application/json", "X-Shopify-Storefront-Access-Token": conf.token },
|
|
554
|
-
body: JSON.stringify({ query: query2, variables })
|
|
571
|
+
body: JSON.stringify({ query: query2, variables }),
|
|
572
|
+
// A `fetch` given to the server helpers has to honour the signal, as the platform's does.
|
|
573
|
+
signal
|
|
555
574
|
});
|
|
556
575
|
} catch (error) {
|
|
557
576
|
return networkFailure(error, retry);
|
|
@@ -588,7 +607,10 @@
|
|
|
588
607
|
const access = { inventory: !storesWithoutInventory.has(store) };
|
|
589
608
|
const sent = queryText(conf, query2, access, { context, operation });
|
|
590
609
|
const retry = retries < conf.retries ? retryWhileLeft : "none";
|
|
591
|
-
const outcome = await
|
|
610
|
+
const outcome = await withTimeout(
|
|
611
|
+
conf.requestTimeout,
|
|
612
|
+
(signal) => attempt(conf, sent, variables, isData, retry, operation, signal)
|
|
613
|
+
);
|
|
592
614
|
switch (outcome.kind) {
|
|
593
615
|
case "data":
|
|
594
616
|
return outcome.data;
|
|
@@ -598,9 +620,9 @@
|
|
|
598
620
|
storesWithoutInventory.add(store);
|
|
599
621
|
break;
|
|
600
622
|
case "retry":
|
|
623
|
+
await sleep(outcome.backoffMs * 2 ** retries);
|
|
601
624
|
retries += 1;
|
|
602
625
|
log("retry", retries);
|
|
603
|
-
await sleep(outcome.backoffMs * 2 ** retries);
|
|
604
626
|
break;
|
|
605
627
|
}
|
|
606
628
|
}
|
|
@@ -1369,6 +1391,13 @@
|
|
|
1369
1391
|
};
|
|
1370
1392
|
var isProductShape = (value) => field(value, "id") !== "" && field(value, "handle") !== "" && matches(value, PRODUCT);
|
|
1371
1393
|
var PRODUCT_NODE = (node) => isRecord(node) && (node["id"] === void 0 || matches(node, PRODUCT));
|
|
1394
|
+
var isCollectionAnswer = shaped({
|
|
1395
|
+
collection: orNull({ handle: "string", products: PRODUCT_CONNECTION })
|
|
1396
|
+
});
|
|
1397
|
+
var isSearchAnswer = shaped({ products: PRODUCT_CONNECTION });
|
|
1398
|
+
var isRecommendationsAnswer = shaped({
|
|
1399
|
+
productRecommendations: orNull([PRODUCT])
|
|
1400
|
+
});
|
|
1372
1401
|
|
|
1373
1402
|
// src/cart/cart-shape.ts
|
|
1374
1403
|
var LINE = {
|
|
@@ -1623,64 +1652,6 @@
|
|
|
1623
1652
|
if (normalized) productCache.delete(normalized);
|
|
1624
1653
|
return getProduct(key);
|
|
1625
1654
|
}
|
|
1626
|
-
var isCollectionAnswer = shaped({
|
|
1627
|
-
collection: orNull({ handle: "string", products: PRODUCT_CONNECTION })
|
|
1628
|
-
});
|
|
1629
|
-
var isSearchAnswer = shaped({ products: PRODUCT_CONNECTION });
|
|
1630
|
-
var isRecommendationsAnswer = shaped({
|
|
1631
|
-
productRecommendations: orNull([PRODUCT])
|
|
1632
|
-
});
|
|
1633
|
-
var COLLECTION_QUERY = `query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${collectionFields()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`;
|
|
1634
|
-
var SEARCH_QUERY = `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}}}`;
|
|
1635
|
-
async function getProducts({
|
|
1636
|
-
collection,
|
|
1637
|
-
query: query2,
|
|
1638
|
-
first = cfg.collectionFirst,
|
|
1639
|
-
after = null,
|
|
1640
|
-
sortKey,
|
|
1641
|
-
reverse = false,
|
|
1642
|
-
filters
|
|
1643
|
-
} = {}) {
|
|
1644
|
-
if (collection) {
|
|
1645
|
-
const data2 = await gql(
|
|
1646
|
-
withProductFragment(COLLECTION_QUERY),
|
|
1647
|
-
{
|
|
1648
|
-
handle: collection,
|
|
1649
|
-
first,
|
|
1650
|
-
after,
|
|
1651
|
-
sortKey: sortKey || void 0,
|
|
1652
|
-
reverse,
|
|
1653
|
-
filters: filters ?? void 0
|
|
1654
|
-
},
|
|
1655
|
-
isCollectionAnswer
|
|
1656
|
-
);
|
|
1657
|
-
if (!data2.collection) throw new TetherError(`Collection not found: ${collection}`, { code: "NOT_FOUND" });
|
|
1658
|
-
const { products, ...rest } = data2.collection;
|
|
1659
|
-
products.nodes.forEach(primeProduct);
|
|
1660
|
-
return { collection: rest, products: products.nodes, pageInfo: products.pageInfo };
|
|
1661
|
-
}
|
|
1662
|
-
const data = await gql(
|
|
1663
|
-
withProductFragment(SEARCH_QUERY),
|
|
1664
|
-
{ first, after, query: query2 || void 0, sortKey: sortKey || void 0, reverse },
|
|
1665
|
-
isSearchAnswer
|
|
1666
|
-
);
|
|
1667
|
-
data.products.nodes.forEach(primeProduct);
|
|
1668
|
-
return { collection: null, products: data.products.nodes, pageInfo: data.products.pageInfo };
|
|
1669
|
-
}
|
|
1670
|
-
async function getRecommendations(product, intent = "RELATED") {
|
|
1671
|
-
const key = normalizeProductKey(typeof product === "object" ? product?.id : product);
|
|
1672
|
-
const byId = key?.startsWith("gid://") ?? false;
|
|
1673
|
-
const data = await gql(
|
|
1674
|
-
withProductFragment(
|
|
1675
|
-
`query TetherRecs(${byId ? "$id: ID!" : "$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${byId ? "productId: $id" : "productHandle: $handle"},intent:$intent){...TetherProduct}}`
|
|
1676
|
-
),
|
|
1677
|
-
byId ? { id: key, intent } : { handle: key, intent },
|
|
1678
|
-
isRecommendationsAnswer
|
|
1679
|
-
);
|
|
1680
|
-
const list = data.productRecommendations ?? [];
|
|
1681
|
-
list.forEach(primeProduct);
|
|
1682
|
-
return list;
|
|
1683
|
-
}
|
|
1684
1655
|
|
|
1685
1656
|
// src/product-render.ts
|
|
1686
1657
|
var NTH_IMAGE_BIND = /^image:(\d+)$/;
|
|
@@ -3217,128 +3188,6 @@
|
|
|
3217
3188
|
}
|
|
3218
3189
|
};
|
|
3219
3190
|
|
|
3220
|
-
// src/collection.ts
|
|
3221
|
-
var URL_QUERY_SOURCE = "url:";
|
|
3222
|
-
var listSelector = () => `${sel("collection")},${sel("products")},${sel("recommendations")}`;
|
|
3223
|
-
var isElement2 = (target) => target instanceof window.Element;
|
|
3224
|
-
var toLimit = (raw) => parseInt(raw ?? "", 10) || void 0;
|
|
3225
|
-
var toIntent = (raw) => raw === "COMPLEMENTARY" ? "COMPLEMENTARY" : "RELATED";
|
|
3226
|
-
var ListScope = class {
|
|
3227
|
-
constructor(root) {
|
|
3228
|
-
__publicField(this, "root");
|
|
3229
|
-
__publicField(this, "products", []);
|
|
3230
|
-
__publicField(this, "pageInfo", null);
|
|
3231
|
-
__publicField(this, "collection", null);
|
|
3232
|
-
/** Counts loads, so only the latest one renders. */
|
|
3233
|
-
__publicField(this, "loadToken", 0);
|
|
3234
|
-
this.root = root;
|
|
3235
|
-
setScopeStatus(root, "loading");
|
|
3236
|
-
root.addEventListener("click", (event) => {
|
|
3237
|
-
if (!isElement2(event.target)) return;
|
|
3238
|
-
const more = event.target.closest(sel("load-more"));
|
|
3239
|
-
if (more?.closest(listSelector()) !== root) return;
|
|
3240
|
-
event.preventDefault();
|
|
3241
|
-
void busy(more, () => this.load(true));
|
|
3242
|
-
});
|
|
3243
|
-
}
|
|
3244
|
-
$(selector) {
|
|
3245
|
-
return scoped(this.root, selector, listSelector());
|
|
3246
|
-
}
|
|
3247
|
-
/** The collection or search query of the list's attributes. */
|
|
3248
|
-
options() {
|
|
3249
|
-
const { root } = this;
|
|
3250
|
-
const query2 = { reverse: get(root, "reverse") === "true" };
|
|
3251
|
-
const first = toLimit(get(root, "limit"));
|
|
3252
|
-
if (first) query2.first = first;
|
|
3253
|
-
const sortKey = get(root, "sort");
|
|
3254
|
-
if (sortKey) query2.sortKey = sortKey;
|
|
3255
|
-
if (has(root, "collection")) {
|
|
3256
|
-
query2.collection = get(root, "collection") ?? "";
|
|
3257
|
-
return query2;
|
|
3258
|
-
}
|
|
3259
|
-
const raw = get(root, "products") ?? "";
|
|
3260
|
-
query2.query = raw.startsWith(URL_QUERY_SOURCE) ? new URL(window.location.href).searchParams.get(raw.slice(URL_QUERY_SOURCE.length)) || "" : raw;
|
|
3261
|
-
return query2;
|
|
3262
|
-
}
|
|
3263
|
-
/**
|
|
3264
|
-
* The product of a recommendations list: a handle, `url:…` (one dynamic product page), or empty inside a product
|
|
3265
|
-
* scope for that product.
|
|
3266
|
-
*
|
|
3267
|
-
* @throws {TetherError} `NOT_FOUND` when there is no product to recommend for.
|
|
3268
|
-
*/
|
|
3269
|
-
async loadRecommendations() {
|
|
3270
|
-
let { key } = resolveProductKey(this.root, window.location, "recommendations");
|
|
3271
|
-
const scope = this.root.closest(sel("product"));
|
|
3272
|
-
if (!key && scope) ({ key } = resolveProductKey(scope));
|
|
3273
|
-
if (!key) throw new TetherError("No product for recommendations", { code: "NOT_FOUND" });
|
|
3274
|
-
return getRecommendations(key, toIntent(get(this.root, "intent")));
|
|
3275
|
-
}
|
|
3276
|
-
/** @param more Appends the next page instead of replacing the products. */
|
|
3277
|
-
async load(more = false) {
|
|
3278
|
-
this.loadToken += 1;
|
|
3279
|
-
const token = this.loadToken;
|
|
3280
|
-
const stale2 = () => token !== this.loadToken;
|
|
3281
|
-
try {
|
|
3282
|
-
if (has(this.root, "recommendations")) {
|
|
3283
|
-
const recommendations = await this.loadRecommendations();
|
|
3284
|
-
if (stale2()) return;
|
|
3285
|
-
const limit = toLimit(get(this.root, "limit"));
|
|
3286
|
-
this.products = limit ? recommendations.slice(0, limit) : recommendations;
|
|
3287
|
-
} else {
|
|
3288
|
-
const page = await getProducts({ ...this.options(), after: more ? this.pageInfo?.endCursor ?? null : null });
|
|
3289
|
-
if (stale2()) return;
|
|
3290
|
-
this.collection = page.collection;
|
|
3291
|
-
this.pageInfo = page.pageInfo;
|
|
3292
|
-
this.products = more ? [...this.products, ...page.products] : page.products;
|
|
3293
|
-
}
|
|
3294
|
-
this.render();
|
|
3295
|
-
setScopeStatus(this.root, "ready");
|
|
3296
|
-
emit("list-ready", { products: this.products, collection: this.collection }, this.root);
|
|
3297
|
-
} catch (error) {
|
|
3298
|
-
if (stale2()) return;
|
|
3299
|
-
if (!more) setScopeStatus(this.root, isNotFound(error) ? "not-found" : "error", error);
|
|
3300
|
-
if (!(isNotFound(error) && has(this.root, "recommendations"))) reportError(error, "list load failed");
|
|
3301
|
-
emit("error", { error, context: "list" }, this.root);
|
|
3302
|
-
}
|
|
3303
|
-
}
|
|
3304
|
-
render() {
|
|
3305
|
-
const { collection } = this;
|
|
3306
|
-
this.$(sel("collection-bind")).forEach((el) => {
|
|
3307
|
-
switch (get(el, "collection-bind") ?? "") {
|
|
3308
|
-
case "title":
|
|
3309
|
-
setText(el, collection?.title ?? "");
|
|
3310
|
-
break;
|
|
3311
|
-
case "description":
|
|
3312
|
-
setStoreHtml(el, collection?.descriptionHtml);
|
|
3313
|
-
break;
|
|
3314
|
-
case "image":
|
|
3315
|
-
setImage(el, collection?.image?.url, collection?.image?.altText || collection?.title);
|
|
3316
|
-
break;
|
|
3317
|
-
case "count":
|
|
3318
|
-
setText(el, this.products.length);
|
|
3319
|
-
break;
|
|
3320
|
-
}
|
|
3321
|
-
});
|
|
3322
|
-
this.$(sel("list")).forEach((container) => {
|
|
3323
|
-
repeat(container, this.products, (node, product) => {
|
|
3324
|
-
node.setAttribute(attr("product"), product.handle);
|
|
3325
|
-
node.removeAttribute(attr("state"));
|
|
3326
|
-
});
|
|
3327
|
-
emit("list-rendered", { container }, this.root);
|
|
3328
|
-
});
|
|
3329
|
-
const empty = this.products.length === 0;
|
|
3330
|
-
this.$(sel("show")).forEach((el) => {
|
|
3331
|
-
const key = get(el, "show");
|
|
3332
|
-
if (key === "list-empty") show(el, empty);
|
|
3333
|
-
if (key === "list-filled") show(el, !empty);
|
|
3334
|
-
});
|
|
3335
|
-
this.$(sel("load-more")).forEach((el) => {
|
|
3336
|
-
show(el, Boolean(this.pageInfo?.hasNextPage));
|
|
3337
|
-
});
|
|
3338
|
-
notifyLayoutChanged("list");
|
|
3339
|
-
}
|
|
3340
|
-
};
|
|
3341
|
-
|
|
3342
3191
|
// src/mounting.ts
|
|
3343
3192
|
var HYDRATE_SELECTOR = 'script[type="application/json"][data-tether-hydrate]';
|
|
3344
3193
|
var mountedProducts = /* @__PURE__ */ new WeakSet();
|
|
@@ -3578,7 +3427,7 @@
|
|
|
3578
3427
|
}
|
|
3579
3428
|
|
|
3580
3429
|
// src/part-integrity.ts
|
|
3581
|
-
var PART_INTEGRITY = { "tether.diagnose.js": "sha384-
|
|
3430
|
+
var PART_INTEGRITY = { "tether.diagnose.js": "sha384-6b98ZqhqrOFydwTyklda6rjvyWrgz1OnmffApLQ3+gg6VPSU1Yy3LhR1OT4lprfa", "tether.markets.js": "sha384-f9ZeUfc/tMICwVFPrC44Sa1oxm9c6jTQASJdNhHWDk55thsEVScodDBKSYUiuDgr", "tether.search.js": "sha384-kNQI7aVmvUyNgV2e6+PRy53xmbKiZi2n1hhYmHUDFCGU3BR6SoGpGKVKVbPE0ZtG", "tether.lists.js": "sha384-MfQgl9RjiTn6vr80fQymnFikrsDXh3wcmT8cu858s7z9p/oByQaJUKZo92qhjX1P", "tether.extras.js": "sha384-H4CWsEibHw/99UiBAi366ctyaNZrVMkK6Y1YJYYcGDbNthy5eQdS+RRcrlm1clmQ", "tether.account.js": "sha384-UeOp/wddJlVjmlYcVqqO9hU7ANLYEtY/TtK/y5cFkQ6J+SPBmqI/VReaAh+reCMC", "tether.account-pages.js": "sha384-jBeU+vF/U13v+9LZxg5R8lQb/PDHTXPVvu1EmsdDUrlh7BmIntbZJh2+iT6YykTy", "tether.analytics.js": "sha384-4gJ/lcu+S+sfpEHu64+0m2zbXpvNsyOxKDQchPEIb1SFg3ky1JlXODNSdRoodST9" };
|
|
3582
3431
|
|
|
3583
3432
|
// src/part-registry.ts
|
|
3584
3433
|
function isTetherInternals(value) {
|
|
@@ -3586,7 +3435,7 @@
|
|
|
3586
3435
|
}
|
|
3587
3436
|
|
|
3588
3437
|
// src/version.ts
|
|
3589
|
-
var VERSION = "0.
|
|
3438
|
+
var VERSION = "0.9.0";
|
|
3590
3439
|
|
|
3591
3440
|
// src/lazy-iife.ts
|
|
3592
3441
|
var coreModules = {
|
|
@@ -3594,13 +3443,14 @@
|
|
|
3594
3443
|
return [cfg, isConfigured, log, MARKET_SOURCES, parseMarkets, reportError, warn];
|
|
3595
3444
|
},
|
|
3596
3445
|
get "client.ts"() {
|
|
3597
|
-
return [endpoint, gql, orNull, shaped, TetherError];
|
|
3446
|
+
return [endpoint, gql, matches, orNull, shaped, TetherError];
|
|
3598
3447
|
},
|
|
3599
3448
|
get "dom.ts"() {
|
|
3600
3449
|
return [
|
|
3601
3450
|
ANALYTICS_EVENTS,
|
|
3602
3451
|
attr,
|
|
3603
3452
|
attributesFromJson,
|
|
3453
|
+
busy,
|
|
3604
3454
|
emit,
|
|
3605
3455
|
formatDate,
|
|
3606
3456
|
formatMoney2,
|
|
@@ -3608,24 +3458,30 @@
|
|
|
3608
3458
|
has,
|
|
3609
3459
|
hasTemplate,
|
|
3610
3460
|
isOwnEvent,
|
|
3461
|
+
notifyLayoutChanged,
|
|
3611
3462
|
parseJSONAttr,
|
|
3612
3463
|
productUrl2,
|
|
3613
3464
|
qsa,
|
|
3614
3465
|
repeat,
|
|
3466
|
+
scoped,
|
|
3615
3467
|
sel,
|
|
3616
3468
|
setImage,
|
|
3469
|
+
setStoreHtml,
|
|
3617
3470
|
setText,
|
|
3618
3471
|
show
|
|
3619
3472
|
];
|
|
3620
3473
|
},
|
|
3621
3474
|
get "loader.ts"() {
|
|
3622
|
-
return [clearProductCache, getProduct];
|
|
3475
|
+
return [clearProductCache, getProduct, normalizeProductKey, primeProduct, withProductFragment];
|
|
3476
|
+
},
|
|
3477
|
+
get "fragments.ts"() {
|
|
3478
|
+
return [collectionFields];
|
|
3623
3479
|
},
|
|
3624
3480
|
get "selling-plans.ts"() {
|
|
3625
3481
|
return [allPlans];
|
|
3626
3482
|
},
|
|
3627
3483
|
get "status.ts"() {
|
|
3628
|
-
return [boundary, resolveProductKey];
|
|
3484
|
+
return [boundary, isNotFound, resolveProductKey, setScopeStatus];
|
|
3629
3485
|
},
|
|
3630
3486
|
get "cart.ts"() {
|
|
3631
3487
|
return [Cart];
|
|
@@ -3688,12 +3544,16 @@
|
|
|
3688
3544
|
return;
|
|
3689
3545
|
}
|
|
3690
3546
|
parts.delete(name);
|
|
3691
|
-
const problem = isTetherInternals(tether) ? "did not register" : "can't register: window.Tether is no longer this Tether script's";
|
|
3547
|
+
const problem = isTetherInternals(tether) ? "did not register" : "can't register: window.Tether is no longer this Tether script's, another script replaced it";
|
|
3692
3548
|
reject(new Error(`${url2} ${problem}`));
|
|
3693
3549
|
};
|
|
3694
3550
|
script.onerror = () => {
|
|
3695
3551
|
parts.delete(name);
|
|
3696
|
-
reject(
|
|
3552
|
+
reject(
|
|
3553
|
+
new Error(
|
|
3554
|
+
`Could not load ${url2}, or it is not the file built with this Tether script. Host the same release's files next to the Tether script or at partsUrl.`
|
|
3555
|
+
)
|
|
3556
|
+
);
|
|
3697
3557
|
};
|
|
3698
3558
|
document.head.appendChild(script);
|
|
3699
3559
|
});
|
|
@@ -3719,6 +3579,19 @@
|
|
|
3719
3579
|
return loading;
|
|
3720
3580
|
}
|
|
3721
3581
|
|
|
3582
|
+
// src/collection.ts
|
|
3583
|
+
var listSelector = () => `${sel("collection")},${sel("products")},${sel("recommendations")}`;
|
|
3584
|
+
function mountedList(root) {
|
|
3585
|
+
setScopeStatus(root, "loading");
|
|
3586
|
+
return {
|
|
3587
|
+
root,
|
|
3588
|
+
load: () => loadPart("lists").then((part) => part.loadList(root)).catch((error) => {
|
|
3589
|
+
setScopeStatus(root, "error", error);
|
|
3590
|
+
reportError(error, "lists");
|
|
3591
|
+
})
|
|
3592
|
+
};
|
|
3593
|
+
}
|
|
3594
|
+
|
|
3722
3595
|
// src/account-marks.ts
|
|
3723
3596
|
var hintKey = () => `${cfg.prefix}:account-hint:${cfg.domain}`;
|
|
3724
3597
|
function removeFromBothAreas(key) {
|
|
@@ -3781,7 +3654,7 @@
|
|
|
3781
3654
|
|
|
3782
3655
|
// src/controls/cart-controls.ts
|
|
3783
3656
|
var lineKeyAttribute = () => `data-${cfg.prefix}-key`;
|
|
3784
|
-
var
|
|
3657
|
+
var isElement2 = (target) => target instanceof window.Element;
|
|
3785
3658
|
function lineOf(target) {
|
|
3786
3659
|
const line = target.closest(`[${lineKeyAttribute()}]`);
|
|
3787
3660
|
const id = line?.getAttribute(lineKeyAttribute());
|
|
@@ -3814,7 +3687,7 @@
|
|
|
3814
3687
|
}
|
|
3815
3688
|
function onClick2(event) {
|
|
3816
3689
|
const { target } = event;
|
|
3817
|
-
if (!
|
|
3690
|
+
if (!isElement2(target)) return;
|
|
3818
3691
|
if (target.closest(sel("cart-open"))) {
|
|
3819
3692
|
event.preventDefault();
|
|
3820
3693
|
Cart.toggle();
|
|
@@ -3851,7 +3724,7 @@
|
|
|
3851
3724
|
}
|
|
3852
3725
|
function onChange2(event) {
|
|
3853
3726
|
const { target } = event;
|
|
3854
|
-
if (!
|
|
3727
|
+
if (!isElement2(target)) return;
|
|
3855
3728
|
const found = lineOf(target);
|
|
3856
3729
|
if (found && target instanceof window.HTMLInputElement && target.matches(sel("line", "quantity"))) {
|
|
3857
3730
|
showLineBusy(found.line, Cart.updateLine(found.id, parseInt(target.value, 10) || 0), "cart line");
|
|
@@ -3877,7 +3750,7 @@
|
|
|
3877
3750
|
}
|
|
3878
3751
|
|
|
3879
3752
|
// src/controls/discount.ts
|
|
3880
|
-
var
|
|
3753
|
+
var isElement3 = (target) => target instanceof window.Element;
|
|
3881
3754
|
function codeInputOf(form) {
|
|
3882
3755
|
const input = form.querySelector(sel("discount-input")) ?? form.querySelector("input");
|
|
3883
3756
|
return input instanceof window.HTMLInputElement ? input : null;
|
|
@@ -3901,7 +3774,7 @@
|
|
|
3901
3774
|
}
|
|
3902
3775
|
function onSubmit(event) {
|
|
3903
3776
|
const { target } = event;
|
|
3904
|
-
const form =
|
|
3777
|
+
const form = isElement3(target) ? target.closest(sel("discount-form")) : null;
|
|
3905
3778
|
if (!form) return;
|
|
3906
3779
|
event.preventDefault();
|
|
3907
3780
|
const input = codeInputOf(form);
|
|
@@ -3911,7 +3784,7 @@
|
|
|
3911
3784
|
}
|
|
3912
3785
|
function onInput(event) {
|
|
3913
3786
|
const { target } = event;
|
|
3914
|
-
if (!
|
|
3787
|
+
if (!isElement3(target)) return;
|
|
3915
3788
|
const form = target.closest(sel("discount-form"));
|
|
3916
3789
|
if (!form) return;
|
|
3917
3790
|
form.classList.remove("is-invalid");
|
|
@@ -3919,7 +3792,7 @@
|
|
|
3919
3792
|
}
|
|
3920
3793
|
function onClick3(event) {
|
|
3921
3794
|
const { target } = event;
|
|
3922
|
-
const remove =
|
|
3795
|
+
const remove = isElement3(target) ? target.closest(sel("discount-remove")) : null;
|
|
3923
3796
|
if (!remove) return;
|
|
3924
3797
|
event.preventDefault();
|
|
3925
3798
|
const code = remove.closest(sel("discount-code"))?.getAttribute(attr("discount-code"));
|
|
@@ -4033,7 +3906,7 @@
|
|
|
4033
3906
|
if (mountedLists.has(el)) return;
|
|
4034
3907
|
mountedLists.add(el);
|
|
4035
3908
|
count++;
|
|
4036
|
-
const list =
|
|
3909
|
+
const list = mountedList(el);
|
|
4037
3910
|
liveLists.add(list);
|
|
4038
3911
|
el.addEventListener(`${cfg.prefix}:list-rendered`, (event) => {
|
|
4039
3912
|
if (isOwnEvent(event, "list-rendered")) mount(event.detail.container);
|
|
@@ -4165,6 +4038,8 @@
|
|
|
4165
4038
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
4166
4039
|
}
|
|
4167
4040
|
var detectMarket = (markets) => loadPart("markets").then((part) => part.detectMarket(markets ?? cfg.markets));
|
|
4041
|
+
var getProducts = (query2) => loadPart("lists").then((part) => part.getProducts(query2));
|
|
4042
|
+
var getRecommendations = (product, intent) => loadPart("lists").then((part) => part.getRecommendations(product, intent));
|
|
4168
4043
|
var getLocalization = () => loadPart("markets").then((part) => part.getLocalization());
|
|
4169
4044
|
var diagnose = (options) => loadPart("diagnose").then((part) => part.diagnose({ ...options, version: VERSION }));
|
|
4170
4045
|
function on(name, listener) {
|