@shopify/hydrogen-react 2023.1.7 → 2023.4.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 (261) hide show
  1. package/dist/browser-dev/CartProvider.mjs.map +1 -1
  2. package/dist/browser-dev/Image.mjs +336 -90
  3. package/dist/browser-dev/Image.mjs.map +1 -1
  4. package/dist/browser-dev/MediaFile.mjs.map +1 -1
  5. package/dist/browser-dev/ModelViewer.mjs.map +1 -1
  6. package/dist/browser-dev/Money.mjs.map +1 -1
  7. package/dist/browser-dev/ProductProvider.mjs +2 -2
  8. package/dist/browser-dev/ProductProvider.mjs.map +1 -1
  9. package/dist/browser-dev/Video.mjs +2 -2
  10. package/dist/browser-dev/Video.mjs.map +1 -1
  11. package/dist/browser-dev/analytics-utils.mjs +1 -1
  12. package/dist/browser-dev/analytics-utils.mjs.map +1 -1
  13. package/dist/browser-dev/index.mjs +2 -3
  14. package/dist/browser-dev/index.mjs.map +1 -1
  15. package/dist/browser-dev/node_modules/@xstate/react/es/useConstant.mjs +2 -2
  16. package/dist/browser-dev/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  17. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs +2 -2
  18. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs +2 -2
  19. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  20. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs +2 -2
  21. package/dist/browser-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs +2 -2
  22. package/dist/browser-dev/storefront-api-constants.mjs +1 -1
  23. package/dist/browser-dev/storefront-api-constants.mjs.map +1 -1
  24. package/dist/browser-dev/useCartAPIStateMachine.mjs.map +1 -1
  25. package/dist/browser-dev/useCartActions.mjs.map +1 -1
  26. package/dist/browser-prod/CartProvider.mjs.map +1 -1
  27. package/dist/browser-prod/Image.mjs +302 -82
  28. package/dist/browser-prod/Image.mjs.map +1 -1
  29. package/dist/browser-prod/MediaFile.mjs.map +1 -1
  30. package/dist/browser-prod/ModelViewer.mjs.map +1 -1
  31. package/dist/browser-prod/Money.mjs.map +1 -1
  32. package/dist/browser-prod/ProductProvider.mjs +2 -2
  33. package/dist/browser-prod/ProductProvider.mjs.map +1 -1
  34. package/dist/browser-prod/Video.mjs +2 -2
  35. package/dist/browser-prod/Video.mjs.map +1 -1
  36. package/dist/browser-prod/analytics-utils.mjs +1 -1
  37. package/dist/browser-prod/analytics-utils.mjs.map +1 -1
  38. package/dist/browser-prod/index.mjs +2 -3
  39. package/dist/browser-prod/index.mjs.map +1 -1
  40. package/dist/browser-prod/node_modules/@xstate/react/es/useConstant.mjs +2 -2
  41. package/dist/browser-prod/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  42. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs +2 -2
  43. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs +2 -2
  44. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  45. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs +2 -2
  46. package/dist/browser-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs +2 -2
  47. package/dist/browser-prod/storefront-api-constants.mjs +1 -1
  48. package/dist/browser-prod/storefront-api-constants.mjs.map +1 -1
  49. package/dist/browser-prod/useCartAPIStateMachine.mjs.map +1 -1
  50. package/dist/browser-prod/useCartActions.mjs.map +1 -1
  51. package/dist/node-dev/AddToCartButton.js +4 -4
  52. package/dist/node-dev/AddToCartButton.js.map +1 -1
  53. package/dist/node-dev/BaseButton.js +2 -2
  54. package/dist/node-dev/BaseButton.js.map +1 -1
  55. package/dist/node-dev/BuyNowButton.js +4 -4
  56. package/dist/node-dev/BuyNowButton.js.map +1 -1
  57. package/dist/node-dev/CartCheckoutButton.js +3 -3
  58. package/dist/node-dev/CartCheckoutButton.js.map +1 -1
  59. package/dist/node-dev/CartLineProvider.js +3 -3
  60. package/dist/node-dev/CartLineProvider.js.map +1 -1
  61. package/dist/node-dev/CartLineQuantityAdjustButton.js +2 -2
  62. package/dist/node-dev/CartLineQuantityAdjustButton.js.map +1 -1
  63. package/dist/node-dev/CartProvider.js +20 -20
  64. package/dist/node-dev/CartProvider.js.map +1 -1
  65. package/dist/node-dev/CartProvider.mjs.map +1 -1
  66. package/dist/node-dev/Image.js +350 -87
  67. package/dist/node-dev/Image.js.map +1 -1
  68. package/dist/node-dev/Image.mjs +336 -90
  69. package/dist/node-dev/Image.mjs.map +1 -1
  70. package/dist/node-dev/MediaFile.js.map +1 -1
  71. package/dist/node-dev/MediaFile.mjs.map +1 -1
  72. package/dist/node-dev/ModelViewer.js +4 -4
  73. package/dist/node-dev/ModelViewer.js.map +1 -1
  74. package/dist/node-dev/ModelViewer.mjs.map +1 -1
  75. package/dist/node-dev/Money.js.map +1 -1
  76. package/dist/node-dev/Money.mjs.map +1 -1
  77. package/dist/node-dev/ProductProvider.js +16 -16
  78. package/dist/node-dev/ProductProvider.js.map +1 -1
  79. package/dist/node-dev/ProductProvider.mjs +2 -2
  80. package/dist/node-dev/ProductProvider.mjs.map +1 -1
  81. package/dist/node-dev/ShopifyProvider.js +4 -4
  82. package/dist/node-dev/ShopifyProvider.js.map +1 -1
  83. package/dist/node-dev/Video.js +4 -4
  84. package/dist/node-dev/Video.js.map +1 -1
  85. package/dist/node-dev/Video.mjs +2 -2
  86. package/dist/node-dev/Video.mjs.map +1 -1
  87. package/dist/node-dev/analytics-utils.js +1 -1
  88. package/dist/node-dev/analytics-utils.js.map +1 -1
  89. package/dist/node-dev/analytics-utils.mjs +1 -1
  90. package/dist/node-dev/analytics-utils.mjs.map +1 -1
  91. package/dist/node-dev/cart-hooks.js +2 -2
  92. package/dist/node-dev/cart-hooks.js.map +1 -1
  93. package/dist/node-dev/index.js +1 -2
  94. package/dist/node-dev/index.js.map +1 -1
  95. package/dist/node-dev/index.mjs +2 -3
  96. package/dist/node-dev/index.mjs.map +1 -1
  97. package/dist/node-dev/load-script.js +3 -3
  98. package/dist/node-dev/load-script.js.map +1 -1
  99. package/dist/node-dev/node_modules/@xstate/react/es/fsm.js +6 -6
  100. package/dist/node-dev/node_modules/@xstate/react/es/fsm.js.map +1 -1
  101. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.js +3 -3
  102. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.js.map +1 -1
  103. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.mjs +2 -2
  104. package/dist/node-dev/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  105. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js +2 -2
  106. package/dist/node-dev/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js.map +1 -1
  107. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js +3 -3
  108. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -1
  109. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs +2 -2
  110. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js +2 -2
  111. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -1
  112. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs +2 -2
  113. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  114. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js +6 -6
  115. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -1
  116. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs +2 -2
  117. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js +2 -2
  118. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js.map +1 -1
  119. package/dist/node-dev/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs +2 -2
  120. package/dist/node-dev/storefront-api-constants.js +1 -1
  121. package/dist/node-dev/storefront-api-constants.js.map +1 -1
  122. package/dist/node-dev/storefront-api-constants.mjs +1 -1
  123. package/dist/node-dev/storefront-api-constants.mjs.map +1 -1
  124. package/dist/node-dev/useCartAPIStateMachine.js +3 -3
  125. package/dist/node-dev/useCartAPIStateMachine.js.map +1 -1
  126. package/dist/node-dev/useCartAPIStateMachine.mjs.map +1 -1
  127. package/dist/node-dev/useCartActions.js +11 -11
  128. package/dist/node-dev/useCartActions.js.map +1 -1
  129. package/dist/node-dev/useCartActions.mjs.map +1 -1
  130. package/dist/node-dev/useMoney.js +5 -5
  131. package/dist/node-dev/useMoney.js.map +1 -1
  132. package/dist/node-dev/useShopifyCookies.js +2 -2
  133. package/dist/node-dev/useShopifyCookies.js.map +1 -1
  134. package/dist/node-prod/AddToCartButton.js +4 -4
  135. package/dist/node-prod/AddToCartButton.js.map +1 -1
  136. package/dist/node-prod/BaseButton.js +2 -2
  137. package/dist/node-prod/BaseButton.js.map +1 -1
  138. package/dist/node-prod/BuyNowButton.js +4 -4
  139. package/dist/node-prod/BuyNowButton.js.map +1 -1
  140. package/dist/node-prod/CartCheckoutButton.js +3 -3
  141. package/dist/node-prod/CartCheckoutButton.js.map +1 -1
  142. package/dist/node-prod/CartLineProvider.js +3 -3
  143. package/dist/node-prod/CartLineProvider.js.map +1 -1
  144. package/dist/node-prod/CartLineQuantityAdjustButton.js +2 -2
  145. package/dist/node-prod/CartLineQuantityAdjustButton.js.map +1 -1
  146. package/dist/node-prod/CartProvider.js +20 -20
  147. package/dist/node-prod/CartProvider.js.map +1 -1
  148. package/dist/node-prod/CartProvider.mjs.map +1 -1
  149. package/dist/node-prod/Image.js +317 -80
  150. package/dist/node-prod/Image.js.map +1 -1
  151. package/dist/node-prod/Image.mjs +302 -82
  152. package/dist/node-prod/Image.mjs.map +1 -1
  153. package/dist/node-prod/MediaFile.js.map +1 -1
  154. package/dist/node-prod/MediaFile.mjs.map +1 -1
  155. package/dist/node-prod/ModelViewer.js +4 -4
  156. package/dist/node-prod/ModelViewer.js.map +1 -1
  157. package/dist/node-prod/ModelViewer.mjs.map +1 -1
  158. package/dist/node-prod/Money.js.map +1 -1
  159. package/dist/node-prod/Money.mjs.map +1 -1
  160. package/dist/node-prod/ProductProvider.js +16 -16
  161. package/dist/node-prod/ProductProvider.js.map +1 -1
  162. package/dist/node-prod/ProductProvider.mjs +2 -2
  163. package/dist/node-prod/ProductProvider.mjs.map +1 -1
  164. package/dist/node-prod/ShopifyProvider.js +4 -4
  165. package/dist/node-prod/ShopifyProvider.js.map +1 -1
  166. package/dist/node-prod/Video.js +4 -4
  167. package/dist/node-prod/Video.js.map +1 -1
  168. package/dist/node-prod/Video.mjs +2 -2
  169. package/dist/node-prod/Video.mjs.map +1 -1
  170. package/dist/node-prod/analytics-utils.js +1 -1
  171. package/dist/node-prod/analytics-utils.js.map +1 -1
  172. package/dist/node-prod/analytics-utils.mjs +1 -1
  173. package/dist/node-prod/analytics-utils.mjs.map +1 -1
  174. package/dist/node-prod/cart-hooks.js +2 -2
  175. package/dist/node-prod/cart-hooks.js.map +1 -1
  176. package/dist/node-prod/index.js +1 -2
  177. package/dist/node-prod/index.js.map +1 -1
  178. package/dist/node-prod/index.mjs +2 -3
  179. package/dist/node-prod/index.mjs.map +1 -1
  180. package/dist/node-prod/load-script.js +3 -3
  181. package/dist/node-prod/load-script.js.map +1 -1
  182. package/dist/node-prod/node_modules/@xstate/react/es/fsm.js +6 -6
  183. package/dist/node-prod/node_modules/@xstate/react/es/fsm.js.map +1 -1
  184. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.js +3 -3
  185. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.js.map +1 -1
  186. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.mjs +2 -2
  187. package/dist/node-prod/node_modules/@xstate/react/es/useConstant.mjs.map +1 -1
  188. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js +2 -2
  189. package/dist/node-prod/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.esm.js.map +1 -1
  190. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js +3 -3
  191. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -1
  192. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.mjs +2 -2
  193. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js +2 -2
  194. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -1
  195. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs +2 -2
  196. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.mjs.map +1 -1
  197. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js +6 -6
  198. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -1
  199. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.mjs +2 -2
  200. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js +2 -2
  201. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.js.map +1 -1
  202. package/dist/node-prod/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.min.mjs +2 -2
  203. package/dist/node-prod/storefront-api-constants.js +1 -1
  204. package/dist/node-prod/storefront-api-constants.js.map +1 -1
  205. package/dist/node-prod/storefront-api-constants.mjs +1 -1
  206. package/dist/node-prod/storefront-api-constants.mjs.map +1 -1
  207. package/dist/node-prod/useCartAPIStateMachine.js +3 -3
  208. package/dist/node-prod/useCartAPIStateMachine.js.map +1 -1
  209. package/dist/node-prod/useCartAPIStateMachine.mjs.map +1 -1
  210. package/dist/node-prod/useCartActions.js +11 -11
  211. package/dist/node-prod/useCartActions.js.map +1 -1
  212. package/dist/node-prod/useCartActions.mjs.map +1 -1
  213. package/dist/node-prod/useMoney.js +5 -5
  214. package/dist/node-prod/useMoney.js.map +1 -1
  215. package/dist/node-prod/useShopifyCookies.js +2 -2
  216. package/dist/node-prod/useShopifyCookies.js.map +1 -1
  217. package/dist/types/CartProvider.d.ts +4 -2
  218. package/dist/types/Image.d.ts +235 -38
  219. package/dist/types/MediaFile.d.ts +2 -2
  220. package/dist/types/ModelViewer.d.ts +1 -1
  221. package/dist/types/Money.d.ts +1 -1
  222. package/dist/types/ProductProvider.d.ts +8 -4
  223. package/dist/types/Video.d.ts +3 -3
  224. package/dist/types/index.d.cts +1 -2
  225. package/dist/types/index.d.ts +1 -2
  226. package/dist/types/storefront-api-constants.d.ts +1 -1
  227. package/dist/types/storefront-api-types.d.ts +862 -118
  228. package/dist/types/useCartAPIStateMachine.d.ts +2 -2
  229. package/dist/types/useCartActions.d.ts +2 -2
  230. package/dist/umd/hydrogen-react.dev.js +334 -182
  231. package/dist/umd/hydrogen-react.dev.js.map +1 -1
  232. package/dist/umd/hydrogen-react.prod.js +22 -15
  233. package/dist/umd/hydrogen-react.prod.js.map +1 -1
  234. package/package.json +2 -2
  235. package/storefront.schema.json +1 -1
  236. package/dist/browser-dev/CartLinePrice.mjs +0 -21
  237. package/dist/browser-dev/CartLinePrice.mjs.map +0 -1
  238. package/dist/browser-dev/image-size.mjs +0 -80
  239. package/dist/browser-dev/image-size.mjs.map +0 -1
  240. package/dist/browser-prod/CartLinePrice.mjs +0 -18
  241. package/dist/browser-prod/CartLinePrice.mjs.map +0 -1
  242. package/dist/browser-prod/image-size.mjs +0 -80
  243. package/dist/browser-prod/image-size.mjs.map +0 -1
  244. package/dist/node-dev/CartLinePrice.js +0 -21
  245. package/dist/node-dev/CartLinePrice.js.map +0 -1
  246. package/dist/node-dev/CartLinePrice.mjs +0 -21
  247. package/dist/node-dev/CartLinePrice.mjs.map +0 -1
  248. package/dist/node-dev/image-size.js +0 -80
  249. package/dist/node-dev/image-size.js.map +0 -1
  250. package/dist/node-dev/image-size.mjs +0 -80
  251. package/dist/node-dev/image-size.mjs.map +0 -1
  252. package/dist/node-prod/CartLinePrice.js +0 -18
  253. package/dist/node-prod/CartLinePrice.js.map +0 -1
  254. package/dist/node-prod/CartLinePrice.mjs +0 -18
  255. package/dist/node-prod/CartLinePrice.mjs.map +0 -1
  256. package/dist/node-prod/image-size.js +0 -80
  257. package/dist/node-prod/image-size.js.map +0 -1
  258. package/dist/node-prod/image-size.mjs +0 -80
  259. package/dist/node-prod/image-size.mjs.map +0 -1
  260. package/dist/types/CartLinePrice.d.ts +0 -31
  261. package/dist/types/image-size.d.ts +0 -36
@@ -1 +1 @@
1
- {"version":3,"file":"CartProvider.mjs","sources":["../../src/CartProvider.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n createContext,\n useContext,\n} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n Cart as CartType,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n BuyerIdentityUpdateEvent,\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState,\n CartWithActions,\n} from './cart-types.js';\nimport {useCartAPIStateMachine} from './useCartAPIStateMachine.js';\nimport {CART_ID_STORAGE_KEY} from './cart-constants.js';\nimport {PartialDeep} from 'type-fest';\nimport {defaultCartFragment} from './cart-queries.js';\n\nexport const CartContext = createContext<CartWithActions | null>(null);\n\n/**\n * The `useCart` hook provides access to the cart object. It must be a descendent of a `CartProvider` component.\n */\nexport function useCart(): CartWithActions {\n const context = useContext(CartContext);\n\n if (!context) {\n throw new Error('Expected a Cart Context, but no Cart Context was found');\n }\n\n return context;\n}\n\ntype CartProviderProps = {\n /** Any `ReactNode` elements. */\n children: React.ReactNode;\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. */\n onCreate?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. */\n onLineAdd?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. */\n onLineRemove?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. */\n onLineUpdate?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. */\n onNoteUpdate?: () => void;\n /** A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. */\n onBuyerIdentityUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. */\n onAttributesUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. */\n onDiscountCodesUpdate?: () => void;\n /** A callback that is invoked when the process to create a cart completes */\n onCreateComplete?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart completes */\n onLineAddComplete?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart completes */\n onLineRemoveComplete?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart completes */\n onLineUpdateComplete?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart completes */\n onNoteUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the buyer identity completes */\n onBuyerIdentityUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart attributes completes */\n onAttributesUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes completes */\n onDiscountCodesUpdateComplete?: () => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/latest/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/latest/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment?: string;\n /** A customer access token that's accessible on the server if there's a customer login. */\n customerAccessToken?: CartBuyerIdentityInput['customerAccessToken'];\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n};\n\n/**\n * The `CartProvider` component synchronizes the state of the Storefront API Cart and a customer's cart,\n * and allows you to more easily manipulate the cart by adding, removing, and updating it.\n * It could be placed at the root of your app so that your whole app is able to use the `useCart()` hook anywhere.\n *\n * There are props that trigger when a call to the Storefront API is made, such as `onLineAdd={}` when a line is added to the cart.\n * There are also props that trigger when a call to the Storefront API is completed, such as `onLineAddComplete={}` when the fetch request for adding a line to the cart completes.\n */\nexport function CartProvider({\n children,\n numCartLines,\n onCreate,\n onLineAdd,\n onLineRemove,\n onLineUpdate,\n onNoteUpdate,\n onBuyerIdentityUpdate,\n onAttributesUpdate,\n onDiscountCodesUpdate,\n onCreateComplete,\n onLineAddComplete,\n onLineRemoveComplete,\n onLineUpdateComplete,\n onNoteUpdateComplete,\n onBuyerIdentityUpdateComplete,\n onAttributesUpdateComplete,\n onDiscountCodesUpdateComplete,\n data: cart,\n cartFragment = defaultCartFragment,\n customerAccessToken,\n countryCode = 'US',\n}: CartProviderProps): JSX.Element {\n if (countryCode) countryCode = countryCode.toUpperCase() as CountryCode;\n const [prevCountryCode, setPrevCountryCode] = useState(countryCode);\n const [prevCustomerAccessToken, setPrevCustomerAccessToken] =\n useState(customerAccessToken);\n const customerOverridesCountryCode = useRef(false);\n\n if (\n prevCountryCode !== countryCode ||\n prevCustomerAccessToken !== customerAccessToken\n ) {\n setPrevCountryCode(countryCode);\n setPrevCustomerAccessToken(customerAccessToken);\n customerOverridesCountryCode.current = false;\n }\n\n const [cartState, cartSend] = useCartAPIStateMachine({\n numCartLines,\n data: cart,\n cartFragment,\n countryCode,\n onCartActionEntry(_, event) {\n try {\n switch (event.type) {\n case 'CART_CREATE':\n return onCreate?.();\n case 'CARTLINE_ADD':\n return onLineAdd?.();\n case 'CARTLINE_REMOVE':\n return onLineRemove?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdate?.();\n case 'NOTE_UPDATE':\n return onNoteUpdate?.();\n case 'BUYER_IDENTITY_UPDATE':\n return onBuyerIdentityUpdate?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdate?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdate?.();\n }\n } catch (error) {\n console.error('Cart entry action failed', error);\n }\n },\n onCartActionOptimisticUI(context, event) {\n if (!context.cart) return {...context};\n switch (event.type) {\n case 'CARTLINE_REMOVE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.filter(\n (line) => line?.id && !event.payload.lines.includes(line?.id),\n ),\n },\n };\n case 'CARTLINE_UPDATE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.map((line) => {\n const updatedLine = event.payload.lines.find(\n ({id}) => id === line?.id,\n );\n\n if (updatedLine && updatedLine.quantity) {\n return {\n ...line,\n quantity: updatedLine.quantity,\n };\n }\n\n return line;\n }),\n },\n };\n }\n return {...context};\n },\n onCartActionComplete(context, event) {\n const cartActionEvent = event.payload.cartActionEvent;\n try {\n switch (event.type) {\n case 'RESOLVE':\n switch (cartActionEvent.type) {\n case 'CART_CREATE':\n return onCreateComplete?.();\n case 'CARTLINE_ADD':\n return onLineAddComplete?.();\n case 'CARTLINE_REMOVE':\n return onLineRemoveComplete?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdateComplete?.();\n case 'NOTE_UPDATE':\n return onNoteUpdateComplete?.();\n case 'BUYER_IDENTITY_UPDATE':\n if (countryCodeNotUpdated(context, cartActionEvent)) {\n customerOverridesCountryCode.current = true;\n }\n return onBuyerIdentityUpdateComplete?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdateComplete?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdateComplete?.();\n }\n }\n } catch (error) {\n console.error('onCartActionComplete failed', error);\n }\n },\n });\n\n const cartReady = useRef(false);\n const cartCompleted = cartState.matches('cartCompleted');\n\n const countryChanged =\n (cartState.value === 'idle' ||\n cartState.value === 'error' ||\n cartState.value === 'cartCompleted') &&\n countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&\n !cartState.context.errors;\n\n const fetchingFromStorage = useRef(false);\n\n /**\n * Initializes cart with priority in this order:\n * 1. cart props\n * 2. localStorage cartId\n */\n useEffect(() => {\n if (!cartReady.current && !fetchingFromStorage.current) {\n if (!cart && storageAvailable('localStorage')) {\n fetchingFromStorage.current = true;\n try {\n const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);\n if (cartId) {\n cartSend({type: 'CART_FETCH', payload: {cartId}});\n }\n } catch (error) {\n console.warn('error fetching cartId');\n console.warn(error);\n }\n }\n cartReady.current = true;\n }\n }, [cart, cartReady, cartSend]);\n\n // Update cart country code if cart and props countryCode's as different\n useEffect(() => {\n if (!countryChanged || customerOverridesCountryCode.current) return;\n cartSend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {buyerIdentity: {countryCode, customerAccessToken}},\n });\n }, [\n countryCode,\n customerAccessToken,\n countryChanged,\n customerOverridesCountryCode,\n cartSend,\n ]);\n\n // send cart events when ready\n const onCartReadySend = useCallback(\n (cartEvent: CartMachineEvent) => {\n if (!cartReady.current) {\n return console.warn(\"Cart isn't ready yet\");\n }\n cartSend(cartEvent);\n },\n [cartSend],\n );\n\n // save cart id to local storage\n useEffect(() => {\n if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {\n try {\n window.localStorage.setItem(\n CART_ID_STORAGE_KEY,\n cartState.context.cart?.id,\n );\n } catch (error) {\n console.warn('Failed to save cartId to localStorage', error);\n }\n }\n }, [cartState?.context?.cart?.id]);\n\n // delete cart from local storage if cart fetched has been completed\n useEffect(() => {\n if (cartCompleted && storageAvailable('localStorage')) {\n try {\n window.localStorage.removeItem(CART_ID_STORAGE_KEY);\n } catch (error) {\n console.warn('Failed to delete cartId from localStorage', error);\n }\n }\n }, [cartCompleted]);\n\n const cartCreate = useCallback(\n (cartInput: CartInput) => {\n if (countryCode && !cartInput.buyerIdentity?.countryCode) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.countryCode = countryCode;\n }\n\n if (\n customerAccessToken &&\n !cartInput.buyerIdentity?.customerAccessToken\n ) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.customerAccessToken = customerAccessToken;\n }\n onCartReadySend({\n type: 'CART_CREATE',\n payload: cartInput,\n });\n },\n [countryCode, customerAccessToken, onCartReadySend],\n );\n\n // Delays the cart state in the context if the page is hydrating\n // preventing suspense boundary errors.\n const cartDisplayState = useDelayedStateUntilHydration(cartState);\n\n const cartContextValue = useMemo<CartWithActions>(() => {\n return {\n ...(cartDisplayState?.context?.cart ?? {lines: [], attributes: []}),\n status: transposeStatus(cartDisplayState.value),\n error: cartDisplayState?.context?.errors,\n totalQuantity: cartDisplayState?.context?.cart?.totalQuantity ?? 0,\n cartCreate,\n linesAdd(lines: CartLineInput[]): void {\n if (cartDisplayState?.context?.cart?.id) {\n onCartReadySend({\n type: 'CARTLINE_ADD',\n payload: {lines},\n });\n } else {\n cartCreate({lines});\n }\n },\n linesRemove(lines: string[]): void {\n onCartReadySend({\n type: 'CARTLINE_REMOVE',\n payload: {\n lines,\n },\n });\n },\n linesUpdate(lines: CartLineUpdateInput[]): void {\n onCartReadySend({\n type: 'CARTLINE_UPDATE',\n payload: {\n lines,\n },\n });\n },\n noteUpdate(note: MutationCartNoteUpdateArgs['note']): void {\n onCartReadySend({\n type: 'NOTE_UPDATE',\n payload: {\n note,\n },\n });\n },\n buyerIdentityUpdate(buyerIdentity: CartBuyerIdentityInput): void {\n onCartReadySend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {\n buyerIdentity,\n },\n });\n },\n cartAttributesUpdate(attributes: AttributeInput[]): void {\n onCartReadySend({\n type: 'CART_ATTRIBUTES_UPDATE',\n payload: {\n attributes,\n },\n });\n },\n discountCodesUpdate(discountCodes: string[]): void {\n onCartReadySend({\n type: 'DISCOUNT_CODES_UPDATE',\n payload: {\n discountCodes,\n },\n });\n },\n cartFragment,\n };\n }, [\n cartCreate,\n cartDisplayState?.context?.cart,\n cartDisplayState?.context?.errors,\n cartDisplayState.value,\n cartFragment,\n onCartReadySend,\n ]);\n\n return (\n <CartContext.Provider value={cartContextValue}>\n {children}\n </CartContext.Provider>\n );\n}\n\nfunction transposeStatus(\n status: CartMachineTypeState['value'],\n): CartWithActions['status'] {\n switch (status) {\n case 'uninitialized':\n case 'initializationError':\n return 'uninitialized';\n case 'idle':\n case 'cartCompleted':\n case 'error':\n return 'idle';\n case 'cartFetching':\n return 'fetching';\n case 'cartCreating':\n return 'creating';\n case 'cartLineAdding':\n case 'cartLineRemoving':\n case 'cartLineUpdating':\n case 'noteUpdating':\n case 'buyerIdentityUpdating':\n case 'cartAttributesUpdating':\n case 'discountCodesUpdating':\n return 'updating';\n }\n}\n\n/**\n * Delays a state update until hydration finishes. Useful for preventing suspense boundaries errors when updating a context\n * @remarks this uses startTransition and waits for it to finish.\n */\nfunction useDelayedStateUntilHydration<T>(state: T): T {\n const [isPending, startTransition] = useTransition();\n const [delayedState, setDelayedState] = useState(state);\n\n const firstTimePending = useRef(false);\n if (isPending) {\n firstTimePending.current = true;\n }\n\n const firstTimePendingFinished = useRef(false);\n if (!isPending && firstTimePending.current) {\n firstTimePendingFinished.current = true;\n }\n\n useEffect(() => {\n startTransition(() => {\n if (!firstTimePendingFinished.current) {\n setDelayedState(state);\n }\n });\n }, [state]);\n\n const displayState = firstTimePendingFinished.current ? state : delayedState;\n\n return displayState;\n}\n\n/** Check for storage availability funciton obtained from\n * https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API\n */\nexport function storageAvailable(\n type: 'localStorage' | 'sessionStorage',\n): boolean {\n let storage;\n try {\n storage = window[type];\n const x = '__storage_test__';\n storage.setItem(x, x);\n storage.removeItem(x);\n return true;\n } catch (e) {\n return !!(\n e instanceof DOMException &&\n // everything except Firefox\n (e.code === 22 ||\n // Firefox\n e.code === 1014 ||\n // test name field too, because code might not be present\n // everything except Firefox\n e.name === 'QuotaExceededError' ||\n // Firefox\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&\n // acknowledge QuotaExceededError only if there's something already stored\n storage &&\n storage.length !== 0\n );\n }\n}\n\nfunction countryCodeNotUpdated(\n context: CartMachineContext,\n event: BuyerIdentityUpdateEvent,\n): boolean {\n return !!(\n event.payload.buyerIdentity.countryCode &&\n context.cart?.buyerIdentity?.countryCode !==\n event.payload.buyerIdentity.countryCode\n );\n}\n"],"names":["_b","_a","_d","_c"],"mappings":"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"}
1
+ {"version":3,"file":"CartProvider.mjs","sources":["../../src/CartProvider.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useTransition,\n createContext,\n useContext,\n} from 'react';\nimport {\n AttributeInput,\n CartBuyerIdentityInput,\n CartInput,\n CartLineInput,\n CartLineUpdateInput,\n CountryCode,\n Cart as CartType,\n MutationCartNoteUpdateArgs,\n} from './storefront-api-types.js';\nimport {\n BuyerIdentityUpdateEvent,\n CartMachineContext,\n CartMachineEvent,\n CartMachineTypeState,\n CartWithActions,\n} from './cart-types.js';\nimport {useCartAPIStateMachine} from './useCartAPIStateMachine.js';\nimport {CART_ID_STORAGE_KEY} from './cart-constants.js';\nimport {PartialDeep} from 'type-fest';\nimport {defaultCartFragment} from './cart-queries.js';\n\nexport const CartContext = createContext<CartWithActions | null>(null);\n\n/**\n * The `useCart` hook provides access to the cart object. It must be a descendent of a `CartProvider` component.\n */\nexport function useCart(): CartWithActions {\n const context = useContext(CartContext);\n\n if (!context) {\n throw new Error('Expected a Cart Context, but no Cart Context was found');\n }\n\n return context;\n}\n\ntype CartProviderProps = {\n /** Any `ReactNode` elements. */\n children: React.ReactNode;\n /** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */\n numCartLines?: number;\n /** A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. */\n onCreate?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. */\n onLineAdd?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. */\n onLineRemove?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. */\n onLineUpdate?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. */\n onNoteUpdate?: () => void;\n /** A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. */\n onBuyerIdentityUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. */\n onAttributesUpdate?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. */\n onDiscountCodesUpdate?: () => void;\n /** A callback that is invoked when the process to create a cart completes */\n onCreateComplete?: () => void;\n /** A callback that is invoked when the process to add a line item to the cart completes */\n onLineAddComplete?: () => void;\n /** A callback that is invoked when the process to remove a line item to the cart completes */\n onLineRemoveComplete?: () => void;\n /** A callback that is invoked when the process to update a line item in the cart completes */\n onLineUpdateComplete?: () => void;\n /** A callback that is invoked when the process to add or update a note in the cart completes */\n onNoteUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the buyer identity completes */\n onBuyerIdentityUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart attributes completes */\n onAttributesUpdateComplete?: () => void;\n /** A callback that is invoked when the process to update the cart discount codes completes */\n onDiscountCodesUpdateComplete?: () => void;\n /** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/2023-04/objects/cart). */\n data?: PartialDeep<CartType, {recurseIntoArrays: true}>;\n /** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/2023-04/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */\n cartFragment?: string;\n /** A customer access token that's accessible on the server if there's a customer login. */\n customerAccessToken?: CartBuyerIdentityInput['customerAccessToken'];\n /** The ISO country code for i18n. */\n countryCode?: CountryCode;\n};\n\n/**\n * The `CartProvider` component synchronizes the state of the Storefront API Cart and a customer's cart,\n * and allows you to more easily manipulate the cart by adding, removing, and updating it.\n * It could be placed at the root of your app so that your whole app is able to use the `useCart()` hook anywhere.\n *\n * There are props that trigger when a call to the Storefront API is made, such as `onLineAdd={}` when a line is added to the cart.\n * There are also props that trigger when a call to the Storefront API is completed, such as `onLineAddComplete={}` when the fetch request for adding a line to the cart completes.\n *\n * The `CartProvider` component must be a descendant of the `ShopifyProvider` component.\n */\nexport function CartProvider({\n children,\n numCartLines,\n onCreate,\n onLineAdd,\n onLineRemove,\n onLineUpdate,\n onNoteUpdate,\n onBuyerIdentityUpdate,\n onAttributesUpdate,\n onDiscountCodesUpdate,\n onCreateComplete,\n onLineAddComplete,\n onLineRemoveComplete,\n onLineUpdateComplete,\n onNoteUpdateComplete,\n onBuyerIdentityUpdateComplete,\n onAttributesUpdateComplete,\n onDiscountCodesUpdateComplete,\n data: cart,\n cartFragment = defaultCartFragment,\n customerAccessToken,\n countryCode = 'US',\n}: CartProviderProps): JSX.Element {\n if (countryCode) countryCode = countryCode.toUpperCase() as CountryCode;\n const [prevCountryCode, setPrevCountryCode] = useState(countryCode);\n const [prevCustomerAccessToken, setPrevCustomerAccessToken] =\n useState(customerAccessToken);\n const customerOverridesCountryCode = useRef(false);\n\n if (\n prevCountryCode !== countryCode ||\n prevCustomerAccessToken !== customerAccessToken\n ) {\n setPrevCountryCode(countryCode);\n setPrevCustomerAccessToken(customerAccessToken);\n customerOverridesCountryCode.current = false;\n }\n\n const [cartState, cartSend] = useCartAPIStateMachine({\n numCartLines,\n data: cart,\n cartFragment,\n countryCode,\n onCartActionEntry(_, event) {\n try {\n switch (event.type) {\n case 'CART_CREATE':\n return onCreate?.();\n case 'CARTLINE_ADD':\n return onLineAdd?.();\n case 'CARTLINE_REMOVE':\n return onLineRemove?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdate?.();\n case 'NOTE_UPDATE':\n return onNoteUpdate?.();\n case 'BUYER_IDENTITY_UPDATE':\n return onBuyerIdentityUpdate?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdate?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdate?.();\n }\n } catch (error) {\n console.error('Cart entry action failed', error);\n }\n },\n onCartActionOptimisticUI(context, event) {\n if (!context.cart) return {...context};\n switch (event.type) {\n case 'CARTLINE_REMOVE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.filter(\n (line) => line?.id && !event.payload.lines.includes(line?.id),\n ),\n },\n };\n case 'CARTLINE_UPDATE':\n return {\n ...context,\n cart: {\n ...context.cart,\n lines: context?.cart?.lines?.map((line) => {\n const updatedLine = event.payload.lines.find(\n ({id}) => id === line?.id,\n );\n\n if (updatedLine && updatedLine.quantity) {\n return {\n ...line,\n quantity: updatedLine.quantity,\n };\n }\n\n return line;\n }),\n },\n };\n }\n return {...context};\n },\n onCartActionComplete(context, event) {\n const cartActionEvent = event.payload.cartActionEvent;\n try {\n switch (event.type) {\n case 'RESOLVE':\n switch (cartActionEvent.type) {\n case 'CART_CREATE':\n return onCreateComplete?.();\n case 'CARTLINE_ADD':\n return onLineAddComplete?.();\n case 'CARTLINE_REMOVE':\n return onLineRemoveComplete?.();\n case 'CARTLINE_UPDATE':\n return onLineUpdateComplete?.();\n case 'NOTE_UPDATE':\n return onNoteUpdateComplete?.();\n case 'BUYER_IDENTITY_UPDATE':\n if (countryCodeNotUpdated(context, cartActionEvent)) {\n customerOverridesCountryCode.current = true;\n }\n return onBuyerIdentityUpdateComplete?.();\n case 'CART_ATTRIBUTES_UPDATE':\n return onAttributesUpdateComplete?.();\n case 'DISCOUNT_CODES_UPDATE':\n return onDiscountCodesUpdateComplete?.();\n }\n }\n } catch (error) {\n console.error('onCartActionComplete failed', error);\n }\n },\n });\n\n const cartReady = useRef(false);\n const cartCompleted = cartState.matches('cartCompleted');\n\n const countryChanged =\n (cartState.value === 'idle' ||\n cartState.value === 'error' ||\n cartState.value === 'cartCompleted') &&\n countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&\n !cartState.context.errors;\n\n const fetchingFromStorage = useRef(false);\n\n /**\n * Initializes cart with priority in this order:\n * 1. cart props\n * 2. localStorage cartId\n */\n useEffect(() => {\n if (!cartReady.current && !fetchingFromStorage.current) {\n if (!cart && storageAvailable('localStorage')) {\n fetchingFromStorage.current = true;\n try {\n const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);\n if (cartId) {\n cartSend({type: 'CART_FETCH', payload: {cartId}});\n }\n } catch (error) {\n console.warn('error fetching cartId');\n console.warn(error);\n }\n }\n cartReady.current = true;\n }\n }, [cart, cartReady, cartSend]);\n\n // Update cart country code if cart and props countryCode's as different\n useEffect(() => {\n if (!countryChanged || customerOverridesCountryCode.current) return;\n cartSend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {buyerIdentity: {countryCode, customerAccessToken}},\n });\n }, [\n countryCode,\n customerAccessToken,\n countryChanged,\n customerOverridesCountryCode,\n cartSend,\n ]);\n\n // send cart events when ready\n const onCartReadySend = useCallback(\n (cartEvent: CartMachineEvent) => {\n if (!cartReady.current) {\n return console.warn(\"Cart isn't ready yet\");\n }\n cartSend(cartEvent);\n },\n [cartSend],\n );\n\n // save cart id to local storage\n useEffect(() => {\n if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {\n try {\n window.localStorage.setItem(\n CART_ID_STORAGE_KEY,\n cartState.context.cart?.id,\n );\n } catch (error) {\n console.warn('Failed to save cartId to localStorage', error);\n }\n }\n }, [cartState?.context?.cart?.id]);\n\n // delete cart from local storage if cart fetched has been completed\n useEffect(() => {\n if (cartCompleted && storageAvailable('localStorage')) {\n try {\n window.localStorage.removeItem(CART_ID_STORAGE_KEY);\n } catch (error) {\n console.warn('Failed to delete cartId from localStorage', error);\n }\n }\n }, [cartCompleted]);\n\n const cartCreate = useCallback(\n (cartInput: CartInput) => {\n if (countryCode && !cartInput.buyerIdentity?.countryCode) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.countryCode = countryCode;\n }\n\n if (\n customerAccessToken &&\n !cartInput.buyerIdentity?.customerAccessToken\n ) {\n if (cartInput.buyerIdentity == null) {\n cartInput.buyerIdentity = {};\n }\n cartInput.buyerIdentity.customerAccessToken = customerAccessToken;\n }\n onCartReadySend({\n type: 'CART_CREATE',\n payload: cartInput,\n });\n },\n [countryCode, customerAccessToken, onCartReadySend],\n );\n\n // Delays the cart state in the context if the page is hydrating\n // preventing suspense boundary errors.\n const cartDisplayState = useDelayedStateUntilHydration(cartState);\n\n const cartContextValue = useMemo<CartWithActions>(() => {\n return {\n ...(cartDisplayState?.context?.cart ?? {lines: [], attributes: []}),\n status: transposeStatus(cartDisplayState.value),\n error: cartDisplayState?.context?.errors,\n totalQuantity: cartDisplayState?.context?.cart?.totalQuantity ?? 0,\n cartCreate,\n linesAdd(lines: CartLineInput[]): void {\n if (cartDisplayState?.context?.cart?.id) {\n onCartReadySend({\n type: 'CARTLINE_ADD',\n payload: {lines},\n });\n } else {\n cartCreate({lines});\n }\n },\n linesRemove(lines: string[]): void {\n onCartReadySend({\n type: 'CARTLINE_REMOVE',\n payload: {\n lines,\n },\n });\n },\n linesUpdate(lines: CartLineUpdateInput[]): void {\n onCartReadySend({\n type: 'CARTLINE_UPDATE',\n payload: {\n lines,\n },\n });\n },\n noteUpdate(note: MutationCartNoteUpdateArgs['note']): void {\n onCartReadySend({\n type: 'NOTE_UPDATE',\n payload: {\n note,\n },\n });\n },\n buyerIdentityUpdate(buyerIdentity: CartBuyerIdentityInput): void {\n onCartReadySend({\n type: 'BUYER_IDENTITY_UPDATE',\n payload: {\n buyerIdentity,\n },\n });\n },\n cartAttributesUpdate(attributes: AttributeInput[]): void {\n onCartReadySend({\n type: 'CART_ATTRIBUTES_UPDATE',\n payload: {\n attributes,\n },\n });\n },\n discountCodesUpdate(discountCodes: string[]): void {\n onCartReadySend({\n type: 'DISCOUNT_CODES_UPDATE',\n payload: {\n discountCodes,\n },\n });\n },\n cartFragment,\n };\n }, [\n cartCreate,\n cartDisplayState?.context?.cart,\n cartDisplayState?.context?.errors,\n cartDisplayState.value,\n cartFragment,\n onCartReadySend,\n ]);\n\n return (\n <CartContext.Provider value={cartContextValue}>\n {children}\n </CartContext.Provider>\n );\n}\n\nfunction transposeStatus(\n status: CartMachineTypeState['value'],\n): CartWithActions['status'] {\n switch (status) {\n case 'uninitialized':\n case 'initializationError':\n return 'uninitialized';\n case 'idle':\n case 'cartCompleted':\n case 'error':\n return 'idle';\n case 'cartFetching':\n return 'fetching';\n case 'cartCreating':\n return 'creating';\n case 'cartLineAdding':\n case 'cartLineRemoving':\n case 'cartLineUpdating':\n case 'noteUpdating':\n case 'buyerIdentityUpdating':\n case 'cartAttributesUpdating':\n case 'discountCodesUpdating':\n return 'updating';\n }\n}\n\n/**\n * Delays a state update until hydration finishes. Useful for preventing suspense boundaries errors when updating a context\n * @remarks this uses startTransition and waits for it to finish.\n */\nfunction useDelayedStateUntilHydration<T>(state: T): T {\n const [isPending, startTransition] = useTransition();\n const [delayedState, setDelayedState] = useState(state);\n\n const firstTimePending = useRef(false);\n if (isPending) {\n firstTimePending.current = true;\n }\n\n const firstTimePendingFinished = useRef(false);\n if (!isPending && firstTimePending.current) {\n firstTimePendingFinished.current = true;\n }\n\n useEffect(() => {\n startTransition(() => {\n if (!firstTimePendingFinished.current) {\n setDelayedState(state);\n }\n });\n }, [state]);\n\n const displayState = firstTimePendingFinished.current ? state : delayedState;\n\n return displayState;\n}\n\n/** Check for storage availability funciton obtained from\n * https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API\n */\nexport function storageAvailable(\n type: 'localStorage' | 'sessionStorage',\n): boolean {\n let storage;\n try {\n storage = window[type];\n const x = '__storage_test__';\n storage.setItem(x, x);\n storage.removeItem(x);\n return true;\n } catch (e) {\n return !!(\n e instanceof DOMException &&\n // everything except Firefox\n (e.code === 22 ||\n // Firefox\n e.code === 1014 ||\n // test name field too, because code might not be present\n // everything except Firefox\n e.name === 'QuotaExceededError' ||\n // Firefox\n e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&\n // acknowledge QuotaExceededError only if there's something already stored\n storage &&\n storage.length !== 0\n );\n }\n}\n\nfunction countryCodeNotUpdated(\n context: CartMachineContext,\n event: BuyerIdentityUpdateEvent,\n): boolean {\n return !!(\n event.payload.buyerIdentity.countryCode &&\n context.cart?.buyerIdentity?.countryCode !==\n event.payload.buyerIdentity.countryCode\n );\n}\n"],"names":["_b","_a","_d","_c"],"mappings":"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"}
@@ -1,115 +1,361 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { getShopifyImageDimensions, shopifyImageLoader, IMG_SRC_SET_SIZES, addImageSizeParametersToUrl } from "./image-size.mjs";
3
- function Image({
4
- data,
5
- width,
6
- height,
7
- loading,
8
- loader = shopifyImageLoader,
9
- loaderOptions,
10
- widths,
11
- decoding = "async",
12
- ...rest
13
- }) {
14
- if (!data.url) {
15
- const missingUrlError = `<Image/>: the 'data' prop requires the 'url' property. Image: ${data.id ?? "no ID provided"}`;
16
- {
17
- throw new Error(missingUrlError);
18
- }
19
- }
20
- if (!data.altText && !rest.alt) {
21
- console.warn(
22
- `<Image/>: the 'data' prop should have the 'altText' property, or the 'alt' prop, and one of them should not be empty. Image: ${data.id ?? data.url}`
23
- );
2
+ import * as React from "react";
3
+ const IMAGE_FRAGMENT = `#graphql
4
+ fragment Image on Image {
5
+ altText
6
+ url
7
+ width
8
+ height
24
9
  }
25
- const { width: imgElementWidth, height: imgElementHeight } = getShopifyImageDimensions({
10
+ `;
11
+ const Image = React.forwardRef(
12
+ ({
13
+ alt,
14
+ aspectRatio,
15
+ crop = "center",
26
16
  data,
17
+ decoding = "async",
18
+ height = "auto",
19
+ loader = shopifyLoader,
27
20
  loaderOptions,
28
- elementProps: {
21
+ loading = "lazy",
22
+ sizes,
23
+ src,
24
+ srcSetOptions = {
25
+ intervals: 15,
26
+ startingWidth: 200,
27
+ incrementSize: 200,
28
+ placeholderWidth: 100
29
+ },
30
+ width = "100%",
31
+ widths,
32
+ ...passthroughProps
33
+ }, ref) => {
34
+ {
35
+ if (loaderOptions) {
36
+ console.warn(
37
+ [
38
+ `Deprecated property from original Image component in use:`,
39
+ `Use the \`crop\`, \`width\`, \`height\`, and src props, or`,
40
+ `the \`data\` prop to achieve the same result. Image used is ${src || (data == null ? void 0 : data.url) || (passthroughProps == null ? void 0 : passthroughProps.key) || "unknown"}`
41
+ ].join(" ")
42
+ );
43
+ }
44
+ if (widths) {
45
+ console.warn(
46
+ [
47
+ `Deprecated property from original Image component in use:`,
48
+ `\`widths\` are now calculated automatically based on the`,
49
+ `config and width props. Image used is ${src || (data == null ? void 0 : data.url) || (passthroughProps == null ? void 0 : passthroughProps.key) || "unknown"}`
50
+ ].join(" ")
51
+ );
52
+ }
53
+ }
54
+ const normalizedData = React.useMemo(() => {
55
+ const dataWidth = (data == null ? void 0 : data.width) && (data == null ? void 0 : data.height) ? data == null ? void 0 : data.width : void 0;
56
+ const dataHeight = (data == null ? void 0 : data.width) && (data == null ? void 0 : data.height) ? data == null ? void 0 : data.height : void 0;
57
+ return {
58
+ width: dataWidth,
59
+ height: dataHeight,
60
+ unitsMatch: Boolean(unitsMatch(dataWidth, dataHeight))
61
+ };
62
+ }, [data]);
63
+ const normalizedProps = React.useMemo(() => {
64
+ const nWidthProp = width || "100%";
65
+ const widthParts = getUnitValueParts(nWidthProp.toString());
66
+ const nWidth = `${widthParts.number}${widthParts.unit}`;
67
+ const autoHeight = height === void 0 || height === null;
68
+ const heightParts = autoHeight ? null : getUnitValueParts(height.toString());
69
+ const fixedHeight = heightParts ? `${heightParts.number}${heightParts.unit}` : "";
70
+ const nHeight = autoHeight ? "auto" : fixedHeight;
71
+ const nSrc = src || (data == null ? void 0 : data.url);
72
+ if (!nSrc) {
73
+ console.warn(
74
+ `No src or data.url provided to Image component.`,
75
+ (passthroughProps == null ? void 0 : passthroughProps.key) || ""
76
+ );
77
+ }
78
+ const nAlt = (data == null ? void 0 : data.altText) && !alt ? data == null ? void 0 : data.altText : alt || "";
79
+ const nAspectRatio = aspectRatio ? aspectRatio : normalizedData.unitsMatch ? [
80
+ getNormalizedFixedUnit(normalizedData.width),
81
+ getNormalizedFixedUnit(normalizedData.height)
82
+ ].join("/") : void 0;
83
+ return {
84
+ width: nWidth,
85
+ height: nHeight,
86
+ src: nSrc,
87
+ alt: nAlt,
88
+ aspectRatio: nAspectRatio
89
+ };
90
+ }, [
29
91
  width,
30
- height
92
+ height,
93
+ src,
94
+ data,
95
+ alt,
96
+ aspectRatio,
97
+ normalizedData,
98
+ passthroughProps == null ? void 0 : passthroughProps.key
99
+ ]);
100
+ const { intervals, startingWidth, incrementSize, placeholderWidth } = srcSetOptions;
101
+ const imageWidths = React.useMemo(() => {
102
+ return generateImageWidths(
103
+ width,
104
+ intervals,
105
+ startingWidth,
106
+ incrementSize
107
+ );
108
+ }, [width, intervals, startingWidth, incrementSize]);
109
+ const fixedWidth = isFixedWidth(normalizedProps.width);
110
+ if (!sizes && !fixedWidth) {
111
+ console.warn(
112
+ [
113
+ "No sizes prop provided to Image component,",
114
+ "you may be loading unnecessarily large images.",
115
+ `Image used is ${src || (data == null ? void 0 : data.url) || (passthroughProps == null ? void 0 : passthroughProps.key) || "unknown"}`
116
+ ].join(" ")
117
+ );
31
118
  }
32
- });
33
- if (!imgElementWidth || !imgElementHeight) {
34
- console.warn(
35
- `<Image/>: the 'data' prop requires either 'width' or 'data.width', and 'height' or 'data.height' properties. Image: ${data.id ?? data.url}`
36
- );
37
- }
38
- let finalSrc = data.url;
39
- if (loader) {
40
- finalSrc = loader({
41
- ...loaderOptions,
42
- src: data.url,
43
- width: imgElementWidth,
44
- height: imgElementHeight
45
- });
46
- if (typeof finalSrc !== "string" || !finalSrc) {
47
- throw new Error(
48
- `<Image/>: 'loader' did not return a valid string. Image: ${data.id ?? data.url}`
119
+ if (fixedWidth) {
120
+ return /* @__PURE__ */ jsx(
121
+ FixedWidthImage,
122
+ {
123
+ aspectRatio,
124
+ crop,
125
+ decoding,
126
+ height,
127
+ imageWidths,
128
+ loader,
129
+ loading,
130
+ normalizedProps,
131
+ passthroughProps,
132
+ ref,
133
+ width
134
+ }
135
+ );
136
+ } else {
137
+ return /* @__PURE__ */ jsx(
138
+ FluidImage,
139
+ {
140
+ aspectRatio,
141
+ crop,
142
+ decoding,
143
+ imageWidths,
144
+ loader,
145
+ loading,
146
+ normalizedProps,
147
+ passthroughProps,
148
+ placeholderWidth,
149
+ ref,
150
+ sizes
151
+ }
49
152
  );
50
153
  }
51
154
  }
52
- const maxWidth = width && imgElementWidth && width < imgElementWidth ? width : imgElementWidth;
53
- const finalSrcset = rest.srcSet ?? internalImageSrcSet({
54
- ...loaderOptions,
55
- widths,
56
- src: data.url,
57
- width: maxWidth,
58
- height: imgElementHeight,
59
- loader
60
- });
155
+ );
156
+ function FixedWidthImage({
157
+ aspectRatio,
158
+ crop,
159
+ decoding,
160
+ height,
161
+ imageWidths,
162
+ loader = shopifyLoader,
163
+ loading,
164
+ normalizedProps,
165
+ passthroughProps,
166
+ ref,
167
+ width
168
+ }) {
169
+ const fixed = React.useMemo(() => {
170
+ const intWidth = getNormalizedFixedUnit(width);
171
+ const intHeight = getNormalizedFixedUnit(height);
172
+ const fixedAspectRatio = aspectRatio ? aspectRatio : unitsMatch(normalizedProps.width, normalizedProps.height) ? [intWidth, intHeight].join("/") : normalizedProps.aspectRatio ? normalizedProps.aspectRatio : void 0;
173
+ const sizesArray = imageWidths === void 0 ? void 0 : generateSizes(imageWidths, fixedAspectRatio, crop);
174
+ const fixedHeight = intHeight ? intHeight : fixedAspectRatio && intWidth ? intWidth * (parseAspectRatio(fixedAspectRatio) ?? 1) : void 0;
175
+ const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);
176
+ const src = loader({
177
+ src: normalizedProps.src,
178
+ width: intWidth,
179
+ height: fixedHeight,
180
+ crop: normalizedProps.height === "auto" ? void 0 : crop
181
+ });
182
+ return {
183
+ width: intWidth,
184
+ aspectRatio: fixedAspectRatio,
185
+ height: fixedHeight,
186
+ srcSet,
187
+ src
188
+ };
189
+ }, [aspectRatio, crop, height, imageWidths, loader, normalizedProps, width]);
61
190
  return /* @__PURE__ */ jsx(
62
191
  "img",
63
192
  {
64
- id: data.id ?? "",
65
- alt: data.altText ?? rest.alt ?? "",
66
- loading: loading ?? "lazy",
67
- ...rest,
68
- src: finalSrc,
69
- width: imgElementWidth ?? void 0,
70
- height: imgElementHeight ?? void 0,
71
- srcSet: finalSrcset,
72
- decoding
193
+ ref,
194
+ alt: normalizedProps.alt,
195
+ decoding,
196
+ height: fixed.height,
197
+ loading,
198
+ src: fixed.src,
199
+ srcSet: fixed.srcSet,
200
+ width: fixed.width,
201
+ style: {
202
+ aspectRatio: fixed.aspectRatio,
203
+ ...passthroughProps.style
204
+ },
205
+ ...passthroughProps
73
206
  }
74
207
  );
75
208
  }
76
- function internalImageSrcSet({
77
- src,
78
- width,
209
+ function FluidImage({
79
210
  crop,
80
- scale,
81
- widths,
82
- loader,
83
- height
211
+ decoding,
212
+ imageWidths,
213
+ loader = shopifyLoader,
214
+ loading,
215
+ normalizedProps,
216
+ passthroughProps,
217
+ placeholderWidth,
218
+ ref,
219
+ sizes
84
220
  }) {
85
- const hasCustomWidths = widths && Array.isArray(widths);
86
- if (hasCustomWidths && widths.some((size) => isNaN(size))) {
87
- throw new Error(
88
- `<Image/>: the 'widths' must be an array of numbers. Image: ${src}`
89
- );
221
+ const fluid = React.useMemo(() => {
222
+ const sizesArray = imageWidths === void 0 ? void 0 : generateSizes(imageWidths, normalizedProps.aspectRatio, crop);
223
+ const placeholderHeight = normalizedProps.aspectRatio && placeholderWidth ? placeholderWidth * (parseAspectRatio(normalizedProps.aspectRatio) ?? 1) : void 0;
224
+ const srcSet = generateSrcSet(normalizedProps.src, sizesArray, loader);
225
+ const src = loader({
226
+ src: normalizedProps.src,
227
+ width: placeholderWidth,
228
+ height: placeholderHeight,
229
+ crop
230
+ });
231
+ return {
232
+ placeholderHeight,
233
+ srcSet,
234
+ src
235
+ };
236
+ }, [crop, imageWidths, loader, normalizedProps, placeholderWidth]);
237
+ return /* @__PURE__ */ jsx(
238
+ "img",
239
+ {
240
+ ref,
241
+ alt: normalizedProps.alt,
242
+ decoding,
243
+ height: fluid.placeholderHeight,
244
+ loading,
245
+ sizes,
246
+ src: fluid.src,
247
+ srcSet: fluid.srcSet,
248
+ width: placeholderWidth,
249
+ ...passthroughProps,
250
+ style: {
251
+ width: normalizedProps.width,
252
+ aspectRatio: normalizedProps.aspectRatio,
253
+ ...passthroughProps.style
254
+ }
255
+ }
256
+ );
257
+ }
258
+ function shopifyLoader({ src, width, height, crop }) {
259
+ if (!src) {
260
+ return "";
261
+ }
262
+ const url = new URL(src);
263
+ if (width) {
264
+ url.searchParams.append("width", Math.round(width).toString());
265
+ }
266
+ if (height) {
267
+ url.searchParams.append("height", Math.round(height).toString());
268
+ }
269
+ if (crop) {
270
+ url.searchParams.append("crop", crop);
271
+ }
272
+ return url.href;
273
+ }
274
+ function unitsMatch(width = "100%", height = "auto") {
275
+ return getUnitValueParts(width.toString()).unit === getUnitValueParts(height.toString()).unit;
276
+ }
277
+ function getUnitValueParts(value) {
278
+ const unit = value.replace(/[0-9.]/g, "");
279
+ const number = parseFloat(value.replace(unit, ""));
280
+ return {
281
+ unit: unit === "" ? number === void 0 ? "auto" : "px" : unit,
282
+ number
283
+ };
284
+ }
285
+ function getNormalizedFixedUnit(value) {
286
+ if (value === void 0) {
287
+ return;
288
+ }
289
+ const { unit, number } = getUnitValueParts(value.toString());
290
+ switch (unit) {
291
+ case "em":
292
+ return number * 16;
293
+ case "rem":
294
+ return number * 16;
295
+ case "px":
296
+ return number;
297
+ case "":
298
+ return number;
299
+ default:
300
+ return;
90
301
  }
91
- let aspectRatio = 1;
92
- if (width && height) {
93
- aspectRatio = Number(height) / Number(width);
302
+ }
303
+ function isFixedWidth(width) {
304
+ const fixedEndings = /\d(px|em|rem)$/;
305
+ return typeof width === "number" || typeof width === "string" && fixedEndings.test(width);
306
+ }
307
+ function generateSrcSet(src, sizesArray, loader = shopifyLoader) {
308
+ if (!src) {
309
+ return "";
94
310
  }
95
- let setSizes = hasCustomWidths ? widths : IMG_SRC_SET_SIZES;
96
- if (!hasCustomWidths && width && width < IMG_SRC_SET_SIZES[IMG_SRC_SET_SIZES.length - 1]) {
97
- setSizes = IMG_SRC_SET_SIZES.filter((size) => size <= width);
311
+ if ((sizesArray == null ? void 0 : sizesArray.length) === 0 || !sizesArray) {
312
+ return src;
98
313
  }
99
- const srcGenerator = loader ? loader : addImageSizeParametersToUrl;
100
- return setSizes.map(
101
- (size) => `${srcGenerator({
314
+ return sizesArray.map(
315
+ (size, i) => `${loader({
102
316
  src,
103
- width: size,
104
- // height is not applied if there is no crop
105
- // if there is crop, then height is applied as a ratio of the original width + height aspect ratio * size
106
- height: crop ? Number(size) * aspectRatio : void 0,
107
- crop,
108
- scale
109
- })} ${size ?? ""}w`
110
- ).join(", ");
317
+ width: size.width,
318
+ height: size.height,
319
+ crop: size.crop
320
+ })} ${sizesArray.length === 3 ? `${i + 1}x` : `${size.width ?? 0}w`}`
321
+ ).join(`, `);
322
+ }
323
+ function generateImageWidths(width = "100%", intervals, startingWidth, incrementSize) {
324
+ const responsive = Array.from(
325
+ { length: intervals },
326
+ (_, i) => i * incrementSize + startingWidth
327
+ );
328
+ const fixed = Array.from(
329
+ { length: 3 },
330
+ (_, i) => (i + 1) * (getNormalizedFixedUnit(width) ?? 0)
331
+ );
332
+ return isFixedWidth(width) ? fixed : responsive;
333
+ }
334
+ function parseAspectRatio(aspectRatio) {
335
+ if (!aspectRatio)
336
+ return;
337
+ const [width, height] = aspectRatio.split("/");
338
+ return 1 / (Number(width) / Number(height));
339
+ }
340
+ function generateSizes(imageWidths, aspectRatio, crop = "center") {
341
+ if (!imageWidths)
342
+ return;
343
+ const sizes = imageWidths.map((width) => {
344
+ return {
345
+ width,
346
+ height: aspectRatio ? width * (parseAspectRatio(aspectRatio) ?? 1) : void 0,
347
+ crop
348
+ };
349
+ });
350
+ return sizes;
111
351
  }
112
352
  export {
113
- Image
353
+ IMAGE_FRAGMENT,
354
+ Image,
355
+ generateImageWidths,
356
+ generateSizes,
357
+ generateSrcSet,
358
+ parseAspectRatio,
359
+ shopifyLoader
114
360
  };
115
361
  //# sourceMappingURL=Image.mjs.map