@occluze/tether 0.6.7 → 0.7.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.
Files changed (250) hide show
  1. package/README.md +11 -11
  2. package/dist/esm/astro.js +2 -2
  3. package/dist/esm/chunks/account-UIPWJQ3Y.js +1 -0
  4. package/dist/esm/chunks/account-pages-6ROA6Y4V.js +1 -0
  5. package/dist/esm/chunks/analytics-2V632IRV.js +1 -0
  6. package/dist/esm/chunks/chunk-4GCXM764.js +1 -0
  7. package/dist/esm/chunks/chunk-56FCLJJD.js +1 -0
  8. package/dist/esm/chunks/chunk-5Z5O3767.js +1 -0
  9. package/dist/esm/chunks/chunk-6OZJCAGZ.js +1 -0
  10. package/dist/esm/chunks/chunk-A5SYCVQM.js +1 -0
  11. package/dist/esm/chunks/chunk-BA4LQJJQ.js +1 -0
  12. package/dist/esm/chunks/chunk-BFTZR4OB.js +4 -0
  13. package/dist/esm/chunks/chunk-C5JYQCWH.js +1 -0
  14. package/dist/esm/chunks/chunk-E5YO6274.js +1 -0
  15. package/dist/esm/chunks/chunk-MPDWM2NN.js +1 -0
  16. package/dist/esm/chunks/chunk-T44MUL4Y.js +1 -0
  17. package/dist/esm/chunks/chunk-YLUULATY.js +1 -0
  18. package/dist/esm/chunks/diagnose-3FEKRIEK.js +14 -0
  19. package/dist/esm/chunks/extras-6POFBNOP.js +1 -0
  20. package/dist/esm/chunks/markets-ui-FD6NI2OG.js +1 -0
  21. package/dist/esm/chunks/search-UJ73YBQ5.js +1 -0
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/server.js +2 -1
  24. package/dist/presets/barba.esm.js +55 -39
  25. package/dist/tether.account-pages.js +781 -495
  26. package/dist/tether.account-pages.min.js +1 -1
  27. package/dist/tether.account.js +462 -381
  28. package/dist/tether.account.min.js +1 -1
  29. package/dist/tether.analytics.js +299 -194
  30. package/dist/tether.analytics.min.js +1 -1
  31. package/dist/tether.diagnose.js +354 -262
  32. package/dist/tether.diagnose.min.js +2 -2
  33. package/dist/tether.extras.js +82 -45
  34. package/dist/tether.extras.min.js +1 -1
  35. package/dist/tether.js +3653 -2116
  36. package/dist/tether.markets.js +238 -150
  37. package/dist/tether.markets.min.js +1 -1
  38. package/dist/tether.min.js +3 -3
  39. package/dist/tether.min.js.map +4 -4
  40. package/dist/tether.search.js +207 -136
  41. package/dist/tether.search.min.js +1 -1
  42. package/dist/types/server/src/shared/account-orders.d.ts +44 -0
  43. package/dist/types/server/src/shared/account-routes.d.ts +153 -0
  44. package/dist/types/server/src/shared/api-versions.d.ts +13 -0
  45. package/dist/types/server/src/shared/error-message.d.ts +2 -0
  46. package/dist/types/server/src/shared/json.d.ts +25 -0
  47. package/dist/types/server/src/shared/market-codes.d.ts +16 -0
  48. package/dist/types/src/account/addresses-view.d.ts +5 -0
  49. package/dist/types/src/account/answers.d.ts +40 -0
  50. package/dist/types/src/account/markup.d.ts +19 -0
  51. package/dist/types/src/account/operations.d.ts +41 -0
  52. package/dist/types/src/account/order-lines.d.ts +13 -0
  53. package/dist/types/src/account/order-list.d.ts +12 -0
  54. package/dist/types/src/account/order-page.d.ts +6 -0
  55. package/dist/types/src/account/page-answers.d.ts +182 -0
  56. package/dist/types/src/account/page-events.d.ts +2 -0
  57. package/dist/types/src/account/server-client.d.ts +60 -0
  58. package/dist/types/src/account/subscriptions-view.d.ts +2 -0
  59. package/dist/types/src/account-api.d.ts +18 -0
  60. package/dist/types/src/account-marks.d.ts +15 -0
  61. package/dist/types/src/account-pages.d.ts +8 -0
  62. package/dist/types/src/account.d.ts +64 -0
  63. package/dist/types/src/amounts.d.ts +12 -0
  64. package/dist/types/src/analytics-shopify.d.ts +41 -0
  65. package/dist/types/src/analytics.d.ts +2 -0
  66. package/dist/types/src/api-version.d.ts +28 -0
  67. package/dist/types/src/astro.d.ts +42 -0
  68. package/dist/types/src/cart/cart-shape.d.ts +43 -0
  69. package/dist/types/src/cart/checkout.d.ts +16 -0
  70. package/dist/types/src/cart/drawer.d.ts +18 -0
  71. package/dist/types/src/cart/mutations.d.ts +79 -0
  72. package/dist/types/src/cart/render.d.ts +17 -0
  73. package/dist/types/src/cart/store.d.ts +182 -0
  74. package/dist/types/src/cart.d.ts +106 -0
  75. package/dist/types/src/client.d.ts +100 -0
  76. package/dist/types/src/collection.d.ts +25 -0
  77. package/dist/types/src/config-sections.d.ts +40 -0
  78. package/dist/types/src/config.d.ts +185 -0
  79. package/dist/types/src/controls/cart-controls.d.ts +2 -0
  80. package/dist/types/src/controls/discount.d.ts +2 -0
  81. package/dist/types/src/controls/extras.d.ts +5 -0
  82. package/dist/types/src/controls/navigation.d.ts +12 -0
  83. package/dist/types/src/diagnose-markup.d.ts +19 -0
  84. package/dist/types/src/diagnose.d.ts +60 -0
  85. package/dist/types/src/dom.d.ts +75 -0
  86. package/dist/types/src/extras.d.ts +21 -0
  87. package/dist/types/src/fragments.d.ts +158 -0
  88. package/dist/types/src/globals.d.ts +15 -0
  89. package/dist/types/src/images.d.ts +20 -0
  90. package/dist/types/src/index.d.ts +167 -0
  91. package/dist/types/src/initial.d.ts +56 -0
  92. package/dist/types/src/lazy.d.ts +28 -0
  93. package/dist/types/src/loader.d.ts +84 -0
  94. package/dist/types/src/market-codes.d.ts +6 -0
  95. package/dist/types/src/markets-ui.d.ts +32 -0
  96. package/dist/types/src/markets.d.ts +72 -0
  97. package/dist/types/src/markup.d.ts +131 -0
  98. package/dist/types/src/mounting.d.ts +46 -0
  99. package/dist/types/src/page-market.d.ts +27 -0
  100. package/dist/types/src/presets/barba.d.ts +56 -0
  101. package/dist/types/src/product-events.d.ts +2 -0
  102. package/dist/types/src/product-render.d.ts +17 -0
  103. package/dist/types/src/product-shape.d.ts +88 -0
  104. package/dist/types/src/product-state.d.ts +110 -0
  105. package/dist/types/src/product.d.ts +66 -0
  106. package/dist/types/src/repeaters.d.ts +16 -0
  107. package/dist/types/src/search.d.ts +33 -0
  108. package/dist/types/src/selling-plans.d.ts +64 -0
  109. package/dist/types/src/server.d.ts +88 -0
  110. package/dist/types/src/shopify-values.d.ts +46 -0
  111. package/dist/types/src/status.d.ts +33 -0
  112. package/dist/types/src/storage.d.ts +12 -0
  113. package/dist/types/src/store-html.d.ts +39 -0
  114. package/dist/types/src/storefront/catalog.d.ts +38 -0
  115. package/dist/types/src/storefront/json-ld.d.ts +20 -0
  116. package/dist/types/src/variant-render.d.ts +14 -0
  117. package/package.json +42 -22
  118. package/src/account/addresses-view.ts +58 -0
  119. package/src/account/answers.ts +79 -0
  120. package/src/account/markup.ts +36 -0
  121. package/src/account/operations.ts +145 -0
  122. package/src/account/order-lines.ts +75 -0
  123. package/src/account/order-list.ts +107 -0
  124. package/src/account/order-page.ts +137 -0
  125. package/src/account/page-answers.ts +317 -0
  126. package/src/account/page-events.ts +253 -0
  127. package/src/account/server-client.ts +183 -0
  128. package/src/account/subscriptions-view.ts +115 -0
  129. package/src/account-api.ts +98 -0
  130. package/src/account-marks.ts +35 -0
  131. package/src/account-pages.ts +81 -0
  132. package/src/account.ts +284 -0
  133. package/src/amounts.ts +64 -0
  134. package/src/analytics-shopify.ts +246 -0
  135. package/src/analytics.ts +315 -0
  136. package/src/api-version.ts +79 -0
  137. package/src/astro.ts +272 -0
  138. package/src/cart/cart-shape.ts +25 -0
  139. package/src/cart/checkout.ts +101 -0
  140. package/src/cart/drawer.ts +125 -0
  141. package/src/cart/mutations.ts +237 -0
  142. package/src/cart/render.ts +266 -0
  143. package/src/cart/store.ts +279 -0
  144. package/src/cart.ts +345 -0
  145. package/src/client.ts +391 -0
  146. package/src/collection.ts +175 -0
  147. package/src/config-sections.ts +284 -0
  148. package/src/config.ts +480 -0
  149. package/src/controls/cart-controls.ts +123 -0
  150. package/src/controls/discount.ts +75 -0
  151. package/src/controls/extras.ts +54 -0
  152. package/src/controls/navigation.ts +77 -0
  153. package/src/diagnose-markup.ts +298 -0
  154. package/src/diagnose.ts +294 -0
  155. package/src/dom.ts +268 -0
  156. package/src/extras.ts +136 -0
  157. package/src/fragments.ts +261 -0
  158. package/src/globals.d.ts +15 -0
  159. package/src/images.ts +91 -0
  160. package/src/index.ts +415 -0
  161. package/src/initial.ts +101 -0
  162. package/src/lazy-iife.ts +197 -0
  163. package/src/lazy.ts +42 -0
  164. package/src/loader.ts +363 -0
  165. package/src/market-codes.ts +6 -0
  166. package/src/markets-ui.ts +227 -0
  167. package/src/markets.ts +246 -0
  168. package/src/markup.ts +127 -0
  169. package/src/mounting.ts +264 -0
  170. package/src/page-market.ts +110 -0
  171. package/src/part-integrity.ts +7 -0
  172. package/src/parts/account-pages.ts +7 -0
  173. package/src/parts/account.ts +7 -0
  174. package/src/parts/analytics.ts +7 -0
  175. package/src/parts/diagnose.ts +7 -0
  176. package/src/parts/extras.ts +7 -0
  177. package/src/parts/markets.ts +7 -0
  178. package/src/parts/search.ts +7 -0
  179. package/src/presets/barba.ts +194 -0
  180. package/src/product-events.ts +115 -0
  181. package/src/product-render.ts +218 -0
  182. package/src/product-shape.ts +49 -0
  183. package/src/product-state.ts +318 -0
  184. package/src/product.ts +308 -0
  185. package/src/repeaters.ts +161 -0
  186. package/src/search.ts +305 -0
  187. package/src/selling-plans.ts +145 -0
  188. package/src/server.ts +211 -0
  189. package/src/shopify-values.ts +91 -0
  190. package/src/status.ts +106 -0
  191. package/src/storage.ts +34 -0
  192. package/src/store-html.ts +359 -0
  193. package/src/storefront/catalog.ts +196 -0
  194. package/src/storefront/json-ld.ts +144 -0
  195. package/src/variant-render.ts +139 -0
  196. package/dist/esm/chunks/account-Q6E2TFEV.js +0 -1
  197. package/dist/esm/chunks/account-pages-UZXR4R5F.js +0 -1
  198. package/dist/esm/chunks/analytics-IJBKATUP.js +0 -1
  199. package/dist/esm/chunks/chunk-4QJKLPYR.js +0 -1
  200. package/dist/esm/chunks/chunk-64TUD3QR.js +0 -1
  201. package/dist/esm/chunks/chunk-AJLPU2JC.js +0 -4
  202. package/dist/esm/chunks/chunk-FIOZPPC5.js +0 -1
  203. package/dist/esm/chunks/chunk-K2YEQAIH.js +0 -1
  204. package/dist/esm/chunks/chunk-KIDH76B7.js +0 -1
  205. package/dist/esm/chunks/chunk-PAYT5ZD7.js +0 -1
  206. package/dist/esm/chunks/chunk-RREHGH4A.js +0 -1
  207. package/dist/esm/chunks/chunk-SSJT43CJ.js +0 -1
  208. package/dist/esm/chunks/chunk-VC46IEJQ.js +0 -1
  209. package/dist/esm/chunks/diagnose-3WVAWNTX.js +0 -14
  210. package/dist/esm/chunks/extras-7I7WJX35.js +0 -1
  211. package/dist/esm/chunks/markets-ui-545XLFTE.js +0 -1
  212. package/dist/esm/chunks/search-NILMGYXG.js +0 -1
  213. package/src/account-pages.js +0 -318
  214. package/src/account.js +0 -385
  215. package/src/analytics.js +0 -232
  216. package/src/api-version.js +0 -35
  217. package/src/astro.js +0 -101
  218. package/src/cart.js +0 -559
  219. package/src/client.js +0 -131
  220. package/src/collection.js +0 -114
  221. package/src/config.js +0 -85
  222. package/src/diagnose.js +0 -246
  223. package/src/dom.js +0 -288
  224. package/src/extras.js +0 -63
  225. package/src/fragments.js +0 -144
  226. package/src/index.js +0 -395
  227. package/src/initial.js +0 -75
  228. package/src/lazy-iife.js +0 -46
  229. package/src/lazy.js +0 -18
  230. package/src/loader.js +0 -198
  231. package/src/markets-ui.js +0 -90
  232. package/src/markets.js +0 -133
  233. package/src/mounting.js +0 -154
  234. package/src/parts/account-pages.js +0 -3
  235. package/src/parts/account.js +0 -3
  236. package/src/parts/analytics.js +0 -3
  237. package/src/parts/diagnose.js +0 -3
  238. package/src/parts/extras.js +0 -3
  239. package/src/parts/markets.js +0 -3
  240. package/src/parts/search.js +0 -3
  241. package/src/presets/barba.js +0 -100
  242. package/src/product.js +0 -570
  243. package/src/search.js +0 -153
  244. package/src/selling-plans.js +0 -94
  245. package/src/server.js +0 -252
  246. package/src/status.js +0 -66
  247. package/types/astro.d.ts +0 -17
  248. package/types/barba.d.ts +0 -16
  249. package/types/index.d.ts +0 -426
  250. package/types/server.d.ts +0 -110
@@ -0,0 +1,167 @@
1
+ /// <reference path="./globals.d.ts" />
2
+ import { query, TetherError, withContext } from './client.js';
3
+ import { getProduct, getProducts, getRecommendations, clearProductCache, primeProduct } from './loader.js';
4
+ import * as plans from './selling-plans.js';
5
+ import { resolveProductKey } from './status.js';
6
+ import { formatMoney, imageUrl } from './dom.js';
7
+ import { setCountry } from './page-market.js';
8
+ import { addGroup } from './controls/extras.js';
9
+ import type { TetherConfig, TetherOptions, MarketsConfig } from './config.js';
10
+ import type { ShopifyCart } from './cart/store.js';
11
+ import type { ProductScope } from './product.js';
12
+ import type { DiagnoseOptions } from './diagnose.js';
13
+ import type { TetherEvents } from './markup.js';
14
+ export { addGroup, setCountry };
15
+ export type { TetherOptions as TetherConfig, TetherConfig as ResolvedTetherConfig } from './config.js';
16
+ export type { MarketsConfig, CartWarning } from './config.js';
17
+ export type { Money } from './shopify-values.js';
18
+ export type { Image as ShopifyImage, Metafield as ShopifyMetafield, Product as ShopifyProduct, ProductVariant as ShopifyVariant, SellingPlan as ShopifySellingPlanNode, SellingPlanAdjustmentValue, SellingPlanAllocation as ShopifySellingPlanAllocation, SellingPlanGroup as ShopifySellingPlanGroup, } from './fragments.js';
19
+ export type { PlanInGroup as ShopifySellingPlan, PlanAdjustment, ProductWithPlans, VariantWithPlans, } from './selling-plans.js';
20
+ export type { CartStatus, CartVariant as ShopifyCartVariant, ShopifyCart, ShopifyCartLine } from './cart/store.js';
21
+ export type { Attributes, LineSpec as LineInput } from './cart/mutations.js';
22
+ export type { TetherError, TetherErrorCode, GraphQLError, UserError } from './client.js';
23
+ export type { ProductScope } from './product.js';
24
+ export type { Purchase } from './product-state.js';
25
+ export type { ProductPage, ProductQuery } from './loader.js';
26
+ export type { DetectedMarket, Localization, MarketSource } from './markets.js';
27
+ export type { SetCountryOptions } from './page-market.js';
28
+ export type { DiagnoseOptions, DiagnoseReport } from './diagnose.js';
29
+ export type { TetherEvents } from './markup.js';
30
+ export type { AccountCustomer } from './account/answers.js';
31
+ export type { AccountImage as ImageRef, AccountOrder, AccountOrderLine } from '../server/src/shared/account-orders.js';
32
+ export type { AddressFields as CustomerAddressInput } from './account/operations.js';
33
+ export type { CustomerAddress, Fulfillment, MailingAddress, OrderDetail, OrderDetailLine, SubscriptionContract, SubscriptionLine, } from './account/page-answers.js';
34
+ /** The helpers for selling plans, `Tether.plans`. */
35
+ export type SellingPlanHelpers = typeof plans;
36
+ export declare const VERSION = "0.7.0";
37
+ /**
38
+ * Mounts every product scope and product list inside `root`. Safe to call repeatedly.
39
+ *
40
+ * @returns The scopes and lists newly mounted.
41
+ */
42
+ export declare function mount(root?: Document | Element): number;
43
+ /** Call before a page transition removes the page: closes the cart drawer. */
44
+ export declare function unmount(): void;
45
+ /** @returns The product scope `el` is in. */
46
+ export declare function getScope(el: Element | null | undefined): ProductScope | null;
47
+ /**
48
+ * Configures Tether (`window.TETHER_CONFIG` with `overrides` over it), applies the visitor's market and loads the
49
+ * cart. A second call without overrides returns the first one's promise.
50
+ *
51
+ * @returns `null` without a domain and token, when Tether stays idle.
52
+ */
53
+ export declare function init(overrides?: TetherOptions): Promise<Tether | null>;
54
+ /**
55
+ * Listens to the Tether event `<prefix>:<name>`. Only the events Tether dispatched reach the listener: one another
56
+ * script dispatches under the same name is ignored, so the detail is always the one `TetherEvents` gives.
57
+ *
58
+ * @returns Stops listening.
59
+ */
60
+ declare function on<Name extends keyof TetherEvents>(name: Name, listener: (detail: TetherEvents[Name], event: CustomEvent<TetherEvents[Name]>) => void): () => void;
61
+ declare const publicApi: {
62
+ VERSION: string;
63
+ init: typeof init;
64
+ mount: typeof mount;
65
+ unmount: typeof unmount;
66
+ /** The live config, read-only. */
67
+ readonly config: Readonly<TetherConfig>;
68
+ readonly ready: Promise<Tether | null>;
69
+ query: typeof query;
70
+ withContext: typeof withContext;
71
+ cart: {
72
+ init: () => Promise<ShopifyCart | null>;
73
+ id: () => string | null;
74
+ readonly status: import("./cart/store.js").CartStatus;
75
+ readonly state: ShopifyCart | null;
76
+ readonly lines: import("./cart/store.js").ShopifyCartLine[];
77
+ readonly count: number;
78
+ readonly loaded: boolean;
79
+ readonly lastError: Error | null;
80
+ readonly warnings: import("./config.js").CartWarning[];
81
+ readonly pendingQty: ReadonlyMap<string, {
82
+ quantity: number;
83
+ }>;
84
+ setCheckoutResolver: typeof import("./cart/checkout.js").setCheckoutResolver;
85
+ forgetSaved(): void;
86
+ render: typeof import("./cart/store.js").render;
87
+ subscribe: typeof import("./cart/store.js").subscribe;
88
+ add(input: string | number | import("./cart/mutations.js").LineSpec | (string | number | import("./cart/mutations.js").LineSpec)[], quantity?: number, options?: Omit<import("./cart/mutations.js").LineSpec, "variantId" | "quantity">): Promise<ShopifyCart>;
89
+ updateLine(lineId: string, patch: number | import("./cart/mutations.js").LinePatch): Promise<ShopifyCart | null>;
90
+ changeQuantity: (lineId: string, delta: number) => Promise<ShopifyCart | null>;
91
+ quantityOf: (line: import("./cart/store.js").ShopifyCartLine) => number;
92
+ removeLine(lineIds: string | string[]): Promise<ShopifyCart | null>;
93
+ clear(): Promise<ShopifyCart | null>;
94
+ setNote(note: string | null | undefined): Promise<ShopifyCart | null>;
95
+ setAttributes(attributes: import("./cart/mutations.js").Attributes): Promise<ShopifyCart | null>;
96
+ setDiscountCodes(codes: string | string[] | ((current: string[]) => string[])): Promise<ShopifyCart | null>;
97
+ applyDiscount(code: string): Promise<ShopifyCart | null>;
98
+ removeDiscount(code: string): Promise<ShopifyCart | null>;
99
+ setBuyerIdentity(buyerIdentity: {
100
+ countryCode?: string;
101
+ email?: string;
102
+ phone?: string;
103
+ }, { create }?: {
104
+ create?: boolean;
105
+ }): Promise<ShopifyCart | null>;
106
+ checkout: typeof import("./cart/checkout.js").checkout;
107
+ drawers: () => HTMLElement[];
108
+ isOpen: typeof import("./cart/drawer.js").isOpen;
109
+ open: typeof import("./cart/drawer.js").openCart;
110
+ close: typeof import("./cart/drawer.js").closeCart;
111
+ toggle: typeof import("./cart/drawer.js").toggleCart;
112
+ };
113
+ getProduct: typeof getProduct;
114
+ getProducts: typeof getProducts;
115
+ getRecommendations: typeof getRecommendations;
116
+ getScope: typeof getScope;
117
+ addGroup: (button: Element) => Promise<ShopifyCart | null>;
118
+ account: {
119
+ login: (args_0?: {
120
+ returnTo?: string;
121
+ locale?: string;
122
+ } | undefined) => Promise<void>;
123
+ customer: () => Promise<import("./account/answers.js").AccountCustomer | null>;
124
+ orders: (args_0?: {
125
+ first?: number;
126
+ } | undefined) => Promise<import("../server/src/shared/account-orders.js").AccountOrder[]>;
127
+ logout: (args_0?: {
128
+ returnTo?: string;
129
+ } | undefined) => Promise<void>;
130
+ render: (root?: ParentNode | undefined) => Promise<void>;
131
+ mountAccount: (root?: ParentNode | undefined) => Promise<void>;
132
+ readonly isLoggedIn: () => Promise<boolean>;
133
+ readonly order: (id: string | number) => Promise<import("./account/page-answers.js").OrderDetail | null>;
134
+ readonly updateProfile: (fields?: {
135
+ firstName?: string;
136
+ lastName?: string;
137
+ }) => Promise<import("./account/page-answers.js").Profile>;
138
+ readonly addresses: () => Promise<import("./account/page-answers.js").CustomerAddress[]>;
139
+ readonly saveAddress: (address: import("./account/operations.js").AddressFields | null, options?: {
140
+ id?: string;
141
+ isDefault?: boolean;
142
+ }) => Promise<import("./account/page-answers.js").AccountAddress>;
143
+ readonly deleteAddress: (id: string) => Promise<string>;
144
+ readonly subscriptions: () => Promise<import("./account/page-answers.js").SubscriptionContract[]>;
145
+ readonly subscriptionAction: (id: string | number, action: import("../server/src/shared/account-routes.js").SubscriptionAction) => Promise<import("./account/page-answers.js").SubscriptionChange>;
146
+ readonly requestReturn: (orderId: string | number, lines: import("./account/operations.js").ReturnLine[]) => Promise<import("./account/page-answers.js").OpenedReturn>;
147
+ };
148
+ primeProduct: typeof primeProduct;
149
+ normalizeProductKey: typeof import("./shopify-values.js").productKey;
150
+ clearProductCache: typeof clearProductCache;
151
+ formatMoney: typeof formatMoney;
152
+ imageUrl: typeof imageUrl;
153
+ plans: typeof plans;
154
+ TetherError: typeof TetherError;
155
+ resolveProductKey: typeof resolveProductKey;
156
+ setCountry: typeof setCountry;
157
+ detectMarket: (markets?: MarketsConfig | null) => Promise<import("./markets.js").DetectedMarket>;
158
+ getLocalization: () => Promise<import("./markets.js").Localization>;
159
+ diagnose: (options?: Omit<DiagnoseOptions, "version">) => Promise<import("./diagnose.js").DiagnoseReport>;
160
+ on: typeof on;
161
+ };
162
+ /** `window.Tether`, and what `import Tether from '@occluze/tether'` gives. */
163
+ export type Tether = typeof publicApi;
164
+ /** `Tether`, also carrying `TetherInternals`, which the published type leaves out. */
165
+ export declare const api: Tether;
166
+ /** @alias `api`, for `import Tether from '@occluze/tether'`. */
167
+ export default api;
@@ -0,0 +1,56 @@
1
+ import type { Money } from './shopify-values.js';
2
+ import type { Product, ProductVariant } from './fragments.js';
3
+ import type { PlanInGroup } from './selling-plans.js';
4
+ import type { Selection, ShowCondition } from './product-state.js';
5
+ export interface InitialOptions {
6
+ /** The page's `?variant=`; the first variant for sale without. */
7
+ variant?: string | null | undefined;
8
+ /** The page's `?selling_plan=`: subscribes on that plan. */
9
+ sellingPlan?: string | null | undefined;
10
+ /** `subscription` subscribes on the first plan. */
11
+ defaultPurchase?: string | null | undefined;
12
+ /** `low-stock` at this many or fewer. */
13
+ lowStock?: number | undefined;
14
+ }
15
+ /** A plan in the plan list (`tether-plan-list`). */
16
+ interface InitialPlan {
17
+ id: string;
18
+ name: string;
19
+ /** On this plan, for the variant. */
20
+ price: Money | null;
21
+ /** In %, 0 without savings. */
22
+ savings: number;
23
+ /** `is-selected`: the line is bought on this plan. */
24
+ selected: boolean;
25
+ /** The variant is on this plan; `is-unavailable` when not. */
26
+ available: boolean;
27
+ }
28
+ export interface InitialState {
29
+ variant: ProductVariant;
30
+ /** Option name → value of the variant: `is-selected` on those buttons. */
31
+ selected: Selection;
32
+ purchase: 'one-time' | 'subscription';
33
+ /** The plan the line is bought on, `null` when bought once. */
34
+ plan: PlanInGroup | null;
35
+ plans: InitialPlan[];
36
+ /** The offered plan's savings in % (`tether-bind="subscription-savings"`), 0 without. */
37
+ savings: number;
38
+ price: Money;
39
+ /** Only when on sale. */
40
+ compareAtPrice: Money | null;
41
+ available: boolean;
42
+ /** The `tether-show` conditions: `hidden={!state.show['out-of-stock']}`. */
43
+ show: Record<ShowCondition, boolean>;
44
+ /**
45
+ * Per option, the values without a variant for sale (given the other selected values), as plain data for
46
+ * frameworks that serialise props.
47
+ */
48
+ unavailable: Record<string, string[]>;
49
+ /** The same as a function: `is-unavailable`. */
50
+ isUnavailable: (name: string, value: string) => boolean;
51
+ }
52
+ /** @throws TetherError For a product without variants, which Shopify never sends: every product has one. */
53
+ export declare function initialState(product: Product, options?: InitialOptions): InitialState;
54
+ /** @returns `null` without a product. */
55
+ export declare function initialState(product: Product | null | undefined, options?: InitialOptions): InitialState | null;
56
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Optional parts that most pages never need, loaded on first use. In the ESM and Node builds they are dynamic
3
+ * imports, which bundlers split into their own chunks; the `<script>` build swaps this file for `lazy-iife.ts`
4
+ * (scripts/build.ts).
5
+ */
6
+ export interface Parts {
7
+ diagnose: typeof import('./diagnose.js');
8
+ markets: typeof import('./markets-ui.js');
9
+ search: typeof import('./search.js');
10
+ extras: typeof import('./extras.js');
11
+ account: typeof import('./account.js');
12
+ 'account-pages': typeof import('./account-pages.js');
13
+ analytics: typeof import('./analytics.js');
14
+ }
15
+ export type PartName = keyof Parts;
16
+ /**
17
+ * What `window.Tether` carries for the `<script>` build's separately loaded parts, besides the API sites use. Left out
18
+ * of the published `Tether` type.
19
+ */
20
+ export interface TetherInternals {
21
+ /** `coreModules`: the modules the parts use instead of bundling copies, in the `<script>` build only. */
22
+ __core: unknown;
23
+ /** Each part registers its module here when its file has loaded. */
24
+ __parts: Partial<Parts>;
25
+ }
26
+ export declare const loadPart: <Name extends PartName>(name: Name) => Promise<Parts[Name]>;
27
+ /** Only the `<script>` build shares its modules with separately loaded parts. */
28
+ export declare const coreModules: undefined;
@@ -0,0 +1,84 @@
1
+ import { productKey } from './shopify-values.js';
2
+ import type { Product, Image } from './fragments.js';
3
+ import type { ProductConnection } from './product-shape.js';
4
+ /** Accepts a handle, numeric id, gid or a full product URL. */
5
+ export declare const normalizeProductKey: typeof productKey;
6
+ /** Puts a product the page already has (from a collection query) in the cache, under its handle and its id. */
7
+ export declare function primeProduct(product: Product | null | undefined): void;
8
+ /**
9
+ * @param rawKey A handle, numeric id, gid or product URL.
10
+ * @throws {TetherError} `NOT_FOUND` (rejected) for an empty key or a product the store doesn't have.
11
+ */
12
+ export declare function getProduct(rawKey: string | number | null | undefined): Promise<Product>;
13
+ /** Forgets every product, for a new market: requests already sent no longer fill the cache. */
14
+ export declare function clearProductCache(): void;
15
+ /**
16
+ * Uses products the server rendered, unless the page loaded the same product live in the last `FRESH_MS` (an earlier
17
+ * page of a View Transition visit), whose copy is newer.
18
+ */
19
+ export declare function hydrateProducts(products: readonly Product[] | null | undefined): void;
20
+ /** @returns True once per server-rendered product: the caller then refreshes it. */
21
+ export declare function takeStale(rawKey: string | number | null | undefined): boolean;
22
+ /** Loads this product again, past the cache. Products refreshed in the same tick go out as one request. */
23
+ export declare function refreshProduct(key: string | number): Promise<Product>;
24
+ export interface PageInfo {
25
+ hasNextPage: boolean;
26
+ endCursor: string | null;
27
+ }
28
+ export interface Collection {
29
+ id: string;
30
+ handle: string;
31
+ title: string;
32
+ description: string;
33
+ descriptionHtml: string;
34
+ image: Image | null;
35
+ seo: {
36
+ title: string | null;
37
+ description: string | null;
38
+ };
39
+ }
40
+ export interface ProductPage {
41
+ collection: Collection | null;
42
+ products: Product[];
43
+ pageInfo: PageInfo;
44
+ }
45
+ export interface ProductQuery {
46
+ /** A collection handle; without one, a search. */
47
+ collection?: string;
48
+ /** Storefront search syntax, for a search. */
49
+ query?: string;
50
+ first?: number;
51
+ /** The cursor of the page before. */
52
+ after?: string | null;
53
+ /** `ProductCollectionSortKeys` for a collection, `ProductSortKeys` for a search. */
54
+ sortKey?: string;
55
+ reverse?: boolean;
56
+ /** `ProductFilter` values, for a collection. */
57
+ filters?: unknown[];
58
+ }
59
+ /** A collection's answer: `null` for a handle the store doesn't have. Its other fields are written as text. */
60
+ export declare const isCollectionAnswer: import("./client.js").DataCheck<{
61
+ collection: (Collection & {
62
+ products: ProductConnection;
63
+ }) | null;
64
+ }>;
65
+ export declare const isSearchAnswer: import("./client.js").DataCheck<{
66
+ products: ProductConnection;
67
+ }>;
68
+ export declare const isRecommendationsAnswer: import("./client.js").DataCheck<{
69
+ productRecommendations: Product[] | null;
70
+ }>;
71
+ /**
72
+ * A page of products from a collection (by handle) or from a search. Every product on it is cached.
73
+ *
74
+ * @throws {TetherError} `NOT_FOUND` for a collection the store doesn't have.
75
+ */
76
+ export declare function getProducts({ collection, query, first, after, sortKey, reverse, filters, }?: ProductQuery): Promise<ProductPage>;
77
+ /**
78
+ * Shopify's recommendations for a product. Every product in them is cached.
79
+ *
80
+ * @param product A product, or its handle, id or gid.
81
+ */
82
+ export declare function getRecommendations(product: string | number | {
83
+ id: string;
84
+ } | null | undefined, intent?: 'RELATED' | 'COMPLEMENTARY'): Promise<Product[]>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Country and language codes as Shopify's `@inContext` takes them, parsed by the module the Worker uses for the
3
+ * login's market, so the browser and the Worker accept and refuse the same values.
4
+ */
5
+ export { toCountry, toLanguage } from '../server/src/shared/market-codes.js';
6
+ export type { CountryCode, LanguageCode } from '../server/src/shared/market-codes.js';
@@ -0,0 +1,32 @@
1
+ import { Cart } from './cart.js';
2
+ import type { Localization } from './markets.js';
3
+ export { detectMarket } from './markets.js';
4
+ /**
5
+ * The countries the store sells to (Shopify Markets), with their currency. Cached per page; a failed request is not
6
+ * cached, so the next call tries again.
7
+ */
8
+ export declare function getLocalization(): Promise<Localization>;
9
+ interface SetCountryOptions {
10
+ /** A Shopify language; `null` clears it. Default: the `markets.locales` entry for the country, else unchanged. */
11
+ language?: string | null | undefined;
12
+ /** The money format. Default: the `markets.locales` entry, else unchanged. */
13
+ locale?: string | undefined;
14
+ /** Save the choice for the next pages (default true). */
15
+ remember?: boolean | undefined;
16
+ }
17
+ /**
18
+ * Fills `select[tether-country-select]` with the countries the store sells to (Shopify Markets), and
19
+ * `tether-country-bind="name|code|currency|symbol"` with the current country. `tether-country-label` sets the option
20
+ * text from `{name}`, `{code}`, `{currency}` and `{symbol}`. A failure is reported, never thrown.
21
+ */
22
+ export declare function renderCountrySelects(root?: ParentNode): Promise<void>;
23
+ /**
24
+ * Switches the market: prices, currency and translations follow (`@inContext`), the cart's
25
+ * `buyerIdentity.countryCode` is updated, and every product and list on the page re-renders.
26
+ *
27
+ * Tether.setCountry('DE') Tether.setCountry('BE', { language: 'FR' })
28
+ *
29
+ * @returns The cart once everything is in the new market.
30
+ * @throws {TetherError} `INVALID_COUNTRY` for anything that isn't a country code.
31
+ */
32
+ export declare function setCountry(code: string, { language, locale, remember }?: SetCountryOptions): Promise<typeof Cart.state>;
@@ -0,0 +1,72 @@
1
+ import type { MarketsConfig } from './config.js';
2
+ import type { CountryCode, LanguageCode } from './market-codes.js';
3
+ /** A market a visitor chose, as `setCountry()` stores it. */
4
+ export interface Market {
5
+ country: CountryCode;
6
+ language: LanguageCode | undefined;
7
+ /** An `Intl` locale for money and dates. */
8
+ locale: string | undefined;
9
+ }
10
+ export type MarketSource = 'saved' | 'server' | 'webflow';
11
+ type MarketField = 'country' | 'language' | 'locale';
12
+ type MarketSources = Partial<Record<MarketField, MarketSource>>;
13
+ /** The fields detection found, and the source each came from. */
14
+ export interface DetectedMarket {
15
+ country?: CountryCode;
16
+ language?: LanguageCode;
17
+ locale?: string;
18
+ /** Absent when `detect: false` turns detection off. */
19
+ sources?: MarketSources;
20
+ }
21
+ /** What detection reads, passed in so it runs on any document. */
22
+ interface MarketEnv {
23
+ document: Pick<Document, 'cookie' | 'querySelector' | 'documentElement'> | null;
24
+ location: Pick<Location, 'pathname'> | null;
25
+ /** `localStorage`, read through `getStored`, which finds nothing where the browser blocks it. */
26
+ storage: Pick<Storage, 'getItem'>;
27
+ /** Where `TETHER_COUNTRY` and `TETHER_LANGUAGE` are read from (`window`). */
28
+ global: object;
29
+ }
30
+ interface NamedCode {
31
+ isoCode: string;
32
+ name: string;
33
+ }
34
+ interface Currency {
35
+ isoCode: string;
36
+ symbol: string;
37
+ }
38
+ export type LocalizedCountry = NamedCode & {
39
+ currency: Currency;
40
+ };
41
+ /** The store's markets, from the Storefront API's `localization`. */
42
+ export interface Localization {
43
+ /** The country of the current `@inContext`. */
44
+ country: LocalizedCountry;
45
+ language: NamedCode;
46
+ availableCountries: (LocalizedCountry & {
47
+ availableLanguages: NamedCode[];
48
+ })[];
49
+ }
50
+ /** The localStorage key of the visitor's market: `<prefix>:market:<domain>`. */
51
+ export declare const storageKey: () => string;
52
+ /**
53
+ * The visitor's saved market (`setCountry()`, `tether-country-select`), validated: storage is written by other tabs,
54
+ * older versions and other scripts too.
55
+ *
56
+ * @param storage Default `localStorage`.
57
+ * @returns `null` when nothing valid is saved.
58
+ */
59
+ export declare function readSavedMarket(storage?: Pick<Storage, 'getItem'>): Market | null;
60
+ /**
61
+ * The market the page's sources point to. Reads the DOM and storage only, so it can run on any `env`.
62
+ *
63
+ * @returns Only the fields found; `{}` with `detect: false`.
64
+ */
65
+ export declare function detectMarket(markets?: MarketsConfig | null | undefined, env?: MarketEnv): DetectedMarket;
66
+ /** Saves the visitor's choice for the next pages, unless `markets.remember` is false. */
67
+ export declare function rememberMarket(market: {
68
+ country: CountryCode;
69
+ language?: string | null | undefined;
70
+ locale?: string | null | undefined;
71
+ }): void;
72
+ export {};
@@ -0,0 +1,131 @@
1
+ import type { ShopifyCart } from './cart/store.js';
2
+ import type { CartLineInput } from './cart/mutations.js';
3
+ import type { CartWarning } from './config.js';
4
+ import type { Product, ProductVariant } from './fragments.js';
5
+ import type { Collection } from './loader.js';
6
+ import type { ProductScope } from './product.js';
7
+ import type { Purchase } from './product-state.js';
8
+ import type { SearchResults } from './search.js';
9
+ /** @returns The prefixed attribute name: `product` → `tether-product`. */
10
+ export declare const attr: (name: string) => string;
11
+ /** @returns A selector for the attribute, with that exact value when given. */
12
+ export declare const sel: (name: string, value?: string) => string;
13
+ export declare const get: (el: Element, name: string) => string | null;
14
+ export declare const has: (el: Element, name: string) => boolean;
15
+ /**
16
+ * Tether's attributes go on HTML elements, so matches are typed as such. An SVG element that carries one still has
17
+ * the `style`, `dataset` and attribute methods Tether uses.
18
+ *
19
+ * @returns The matches in `root`, none without a root.
20
+ */
21
+ export declare function qsa(root: ParentNode | null | undefined, selector: string): HTMLElement[];
22
+ /** @returns Matches in `root` whose nearest `scopeSelector` ancestor is `root` itself, not a nested scope. */
23
+ export declare const scoped: (root: Element | null | undefined, selector: string, scopeSelector: string) => HTMLElement[];
24
+ /**
25
+ * The events Tether dispatches, as `<prefix>:<name>` (`tether:cart-updated`), bubbling up to `document`, with the
26
+ * detail each carries. `emit` takes only these, and `Tether.on()` passes on only the events `emit` dispatched, so a listener gets the
27
+ * detail its event really has.
28
+ */
29
+ export interface TetherEvents {
30
+ ready: {
31
+ cart: ShopifyCart | null;
32
+ };
33
+ 'product-ready': {
34
+ product: Product;
35
+ scope: ProductScope;
36
+ };
37
+ 'product-updated': {
38
+ product: Product;
39
+ scope: ProductScope;
40
+ };
41
+ /** `key` is null when the scope names no product; `source` is what it named. */
42
+ 'product-not-found': {
43
+ key: string | null;
44
+ source: string;
45
+ };
46
+ 'variant-changed': {
47
+ product: Product;
48
+ variant: ProductVariant;
49
+ selected: Record<string, string>;
50
+ purchase: Purchase['kind'];
51
+ sellingPlanId: string | null;
52
+ };
53
+ 'product-added': {
54
+ product: Product;
55
+ variant: ProductVariant;
56
+ line: CartLineInput;
57
+ };
58
+ added: {
59
+ cart: ShopifyCart;
60
+ lines: CartLineInput[];
61
+ };
62
+ 'group-added': {
63
+ group: string | null;
64
+ lines: CartLineInput[];
65
+ };
66
+ 'cart-warning': {
67
+ warnings: readonly CartWarning[];
68
+ };
69
+ 'cart-updated': {
70
+ cart: ShopifyCart | null;
71
+ reason: string;
72
+ };
73
+ 'cart-toggled': {
74
+ open: boolean;
75
+ };
76
+ 'cart-error': {
77
+ error: unknown;
78
+ };
79
+ checkout: {
80
+ url: string;
81
+ cart: ShopifyCart | null;
82
+ };
83
+ 'list-ready': {
84
+ products: Product[];
85
+ collection: Collection | null;
86
+ };
87
+ /** A list's cards were drawn (again): `container` holds them. */
88
+ 'list-rendered': {
89
+ container: Element;
90
+ };
91
+ /** The search part's suggestions for `term`. */
92
+ search: SearchResults & {
93
+ term: string;
94
+ };
95
+ 'country-changed': {
96
+ country: string;
97
+ language: string | undefined;
98
+ };
99
+ 'discount-applied': {
100
+ code: string;
101
+ };
102
+ 'discount-invalid': {
103
+ code: string;
104
+ };
105
+ 'layout-changed': {
106
+ reason: string;
107
+ };
108
+ error: {
109
+ error: unknown;
110
+ context: string;
111
+ key?: string | null;
112
+ };
113
+ 'account-login': Record<string, never>;
114
+ 'account-logout': Record<string, never>;
115
+ /** A login that failed: `expired` (it took too long, or came back to another browser) or `error`. */
116
+ 'account-error': {
117
+ error: 'expired' | 'error';
118
+ };
119
+ 'account-updated': {
120
+ what: 'profile' | 'addresses' | 'subscriptions' | 'orders';
121
+ };
122
+ }
123
+ /** The events the analytics part reports, which the core buffers from `init()` until the part has loaded. */
124
+ export declare const ANALYTICS_EVENTS: readonly ["product-ready", "list-ready", "cart-updated", "cart-toggled", "checkout", "search"];
125
+ export type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[number];
126
+ /** @returns The bubbling event `<prefix>:<name>`, known to `isOwnEvent`. */
127
+ export declare function ownEvent<Name extends keyof TetherEvents>(name: Name, detail: TetherEvents[Name]): CustomEvent<TetherEvents[Name]>;
128
+ /** @returns True for an event `ownEvent` created as `name`, false for any other, such as one another script dispatched. */
129
+ export declare function isOwnEvent<Name extends keyof TetherEvents>(event: Event, name: Name): event is CustomEvent<TetherEvents[Name]>;
130
+ /** Dispatches the bubbling event `<prefix>:<name>`. */
131
+ export declare function emit<Name extends keyof TetherEvents>(name: Name, detail: TetherEvents[Name], target?: EventTarget): void;
@@ -0,0 +1,46 @@
1
+ /** A mounted `ListScope`. */
2
+ interface MountedList {
3
+ root: Element;
4
+ load: (more?: boolean) => Promise<unknown>;
5
+ }
6
+ export declare const mountedProducts: WeakSet<Element>;
7
+ export declare const mountedLists: WeakSet<Element>;
8
+ /** Product roots to re-render after a country switch; pruned once disconnected. */
9
+ export declare const liveProducts: Set<HTMLElement>;
10
+ /** Lists to reload after a country switch; pruned once disconnected. */
11
+ export declare const liveLists: Set<MountedList>;
12
+ /** Forgets roots a page transition removed, so they aren't kept alive. */
13
+ export declare function pruneLive(): void;
14
+ /** @returns `root` itself when it matches, then the matches inside it. */
15
+ export declare function within(root: ParentNode & Partial<Pick<Element, 'matches'>>, selector: string): HTMLElement[];
16
+ /**
17
+ * Mounts one product root.
18
+ *
19
+ * @returns True when a product request was started.
20
+ */
21
+ export declare function mountProduct(el: HTMLElement): boolean;
22
+ /** Loads again the product scopes that failed on a network or API error, for when the browser is back online. */
23
+ export declare function retryFailed(): void;
24
+ /**
25
+ * Lists, and anything else that loads prices, hold `html.tether-market-pending` until they are in.
26
+ *
27
+ * @returns `loading` itself.
28
+ */
29
+ export declare const trackMarket: <T>(loading: Promise<T>) => Promise<T>;
30
+ /** After a mount: drops `html.tether-market-pending` once this page's products are live. */
31
+ export declare function settleMarket(): void;
32
+ /**
33
+ * Uses the products in the page's hydrate tags (`tether/server` `hydrate()`) without a request. A tag made for another
34
+ * market is skipped, and marks the page (`html.tether-market-pending`) until the live prices are in, so CSS can hide
35
+ * prices meanwhile.
36
+ *
37
+ * Trust: a hydrate tag is part of the page, written by the site's own build like the rest of its HTML and scripts, so
38
+ * its prices and products are shown until the background refresh replaces them. Whoever can write a tag into the page
39
+ * can already write a script there; the shape check (`isProductShape`) is for a truncated or hand-written tag, which
40
+ * is skipped instead of failing a render.
41
+ *
42
+ * @param root Where to look: the document for a mount (a tag may sit in `<head>` or anywhere else on the page), the
43
+ * added elements for `observe`.
44
+ */
45
+ export declare function hydrateFromPage(root?: Document | Element): void;
46
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { TetherOptions } from './config.js';
2
+ import type { Parts } from './lazy.js';
3
+ import type { ShopifyCart } from './cart/store.js';
4
+ export type SetCountryOptions = Parameters<Parts['markets']['setCountry']>[1];
5
+ /**
6
+ * Sets `cfg`'s market for the first page, over the configured one.
7
+ *
8
+ * @param overrides What `init()` was called with: a `locale` there wins over the visitor's.
9
+ */
10
+ export declare function applyStartMarket(overrides: TetherOptions): Promise<void>;
11
+ /**
12
+ * The market to switch to on arriving at the current page. A page built for a market switches to it; the first page
13
+ * without one after such a page switches back to the visitor's own choice, else to the configured market.
14
+ *
15
+ * @returns `null` when the page stays in the market in use.
16
+ */
17
+ export declare function marketForArrival(): {
18
+ country: string;
19
+ language: string | undefined;
20
+ locale: string | undefined;
21
+ } | null;
22
+ /**
23
+ * `Tether.setCountry('DE')`: loads the markets part on first use.
24
+ *
25
+ * @returns The cart once everything is in the new market.
26
+ */
27
+ export declare function setCountry(code: string, options?: SetCountryOptions): Promise<ShopifyCart | null>;