@shopify/hydrogen 2026.10.0-preview.4 → 2026.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.mjs +23 -12
- package/dist/client/client.d.mts +18 -15
- package/dist/client/client.mjs +8 -3
- package/dist/client/client.mjs.map +1 -1
- package/dist/client/errors.d.mts +35 -13
- package/dist/client/errors.mjs +23 -13
- package/dist/client/errors.mjs.map +1 -1
- package/dist/client/types.d.mts +140 -90
- package/dist/core/analytics/cart-tracker.d.mts +19 -10
- package/dist/core/analytics/cart-tracker.mjs +18 -10
- package/dist/core/analytics/cart-tracker.mjs.map +1 -1
- package/dist/core/analytics/events.d.mts +17 -11
- package/dist/core/analytics/events.mjs +13 -4
- package/dist/core/analytics/events.mjs.map +1 -1
- package/dist/core/analytics/types.d.mts +207 -118
- package/dist/core/analytics/utils/flatten-connection.d.mts +11 -9
- package/dist/core/analytics/utils/flatten-connection.mjs +7 -6
- package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -1
- package/dist/core/cache/fetch-with-cache.d.mts +24 -4
- package/dist/core/cache/fetch-with-cache.mjs +17 -2
- package/dist/core/cache/fetch-with-cache.mjs.map +1 -1
- package/dist/core/cache/key.d.mts +2 -0
- package/dist/core/cache/key.mjs.map +1 -1
- package/dist/core/cache/run-with-cache.d.mts +56 -8
- package/dist/core/cache/run-with-cache.mjs +17 -6
- package/dist/core/cache/run-with-cache.mjs.map +1 -1
- package/dist/core/cache/store.d.mts +8 -6
- package/dist/core/cache/store.mjs.map +1 -1
- package/dist/core/cache/strategies.d.mts +27 -2
- package/dist/core/cache/strategies.mjs +6 -0
- package/dist/core/cache/strategies.mjs.map +1 -1
- package/dist/core/cart/actions.d.mts +37 -30
- package/dist/core/cart/actions.mjs +21 -9
- package/dist/core/cart/actions.mjs.map +1 -1
- package/dist/core/cart/attach-quantity-input.d.mts +8 -7
- package/dist/core/cart/attach-quantity-input.mjs +8 -7
- package/dist/core/cart/attach-quantity-input.mjs.map +1 -1
- package/dist/core/cart/buyer-identity-sync.d.mts +7 -6
- package/dist/core/cart/buyer-identity-sync.mjs.map +1 -1
- package/dist/core/cart/cart.d.mts +59 -46
- package/dist/core/cart/cart.mjs +46 -29
- package/dist/core/cart/cart.mjs.map +1 -1
- package/dist/core/cart/cookie.d.mts +8 -4
- package/dist/core/cart/cookie.mjs +8 -4
- package/dist/core/cart/cookie.mjs.map +1 -1
- package/dist/core/cart/form.d.mts +34 -20
- package/dist/core/cart/form.mjs +6 -4
- package/dist/core/cart/form.mjs.map +1 -1
- package/dist/core/cart/get-cart.d.mts +27 -15
- package/dist/core/cart/get-cart.mjs +13 -8
- package/dist/core/cart/get-cart.mjs.map +1 -1
- package/dist/core/cart/quantity.d.mts +16 -5
- package/dist/core/cart/quantity.mjs +16 -5
- package/dist/core/cart/quantity.mjs.map +1 -1
- package/dist/core/cart/queries.d.mts +25 -19
- package/dist/core/cart/queries.mjs +15 -1
- package/dist/core/cart/queries.mjs.map +1 -1
- package/dist/core/cart/server-handlers.d.mts +82 -45
- package/dist/core/cart/server-handlers.mjs +4 -0
- package/dist/core/cart/server-handlers.mjs.map +1 -1
- package/dist/core/cart/state.d.mts +110 -64
- package/dist/core/cart/state.mjs +24 -6
- package/dist/core/cart/state.mjs.map +1 -1
- package/dist/core/collection/collection.d.mts +52 -53
- package/dist/core/collection/collection.mjs +5 -3
- package/dist/core/collection/collection.mjs.map +1 -1
- package/dist/core/collection/reconciler.d.mts +23 -16
- package/dist/core/collection/reconciler.mjs +8 -4
- package/dist/core/collection/reconciler.mjs.map +1 -1
- package/dist/core/collection/state.d.mts +31 -26
- package/dist/core/collection/state.mjs +4 -3
- package/dist/core/collection/state.mjs.map +1 -1
- package/dist/core/collection/url.d.mts +70 -29
- package/dist/core/collection/url.mjs +63 -25
- package/dist/core/collection/url.mjs.map +1 -1
- package/dist/core/constants.d.mts +1 -0
- package/dist/core/constants.mjs +1 -0
- package/dist/core/constants.mjs.map +1 -1
- package/dist/core/logging/logging.d.mts +14 -8
- package/dist/core/logging/logging.mjs +15 -10
- package/dist/core/logging/logging.mjs.map +1 -1
- package/dist/core/logging/types.d.mts +28 -11
- package/dist/core/logging/types.mjs.map +1 -1
- package/dist/core/money/format.d.mts +6 -4
- package/dist/core/money/format.mjs +19 -9
- package/dist/core/money/format.mjs.map +1 -1
- package/dist/core/money/types.d.mts +41 -25
- package/dist/core/predictive-search/form.d.mts +37 -7
- package/dist/core/predictive-search/form.mjs +21 -3
- package/dist/core/predictive-search/form.mjs.map +1 -1
- package/dist/core/predictive-search/queries.d.mts +18 -30
- package/dist/core/predictive-search/queries.mjs +7 -3
- package/dist/core/predictive-search/queries.mjs.map +1 -1
- package/dist/core/predictive-search/search.d.mts +25 -27
- package/dist/core/predictive-search/search.mjs +20 -19
- package/dist/core/predictive-search/search.mjs.map +1 -1
- package/dist/core/predictive-search/server-handlers.d.mts +25 -26
- package/dist/core/predictive-search/server-handlers.mjs +4 -0
- package/dist/core/predictive-search/server-handlers.mjs.map +1 -1
- package/dist/core/predictive-search/store.d.mts +65 -24
- package/dist/core/predictive-search/store.mjs +12 -1
- package/dist/core/predictive-search/store.mjs.map +1 -1
- package/dist/core/predictive-search/url.d.mts +36 -37
- package/dist/core/predictive-search/url.mjs +14 -6
- package/dist/core/predictive-search/url.mjs.map +1 -1
- package/dist/core/product/form.d.mts +63 -16
- package/dist/core/product/form.mjs +8 -2
- package/dist/core/product/form.mjs.map +1 -1
- package/dist/core/product/options.d.mts +8 -10
- package/dist/core/product/options.mjs +8 -10
- package/dist/core/product/options.mjs.map +1 -1
- package/dist/core/product/product-form.d.mts +77 -29
- package/dist/core/product/product-form.mjs +32 -10
- package/dist/core/product/product-form.mjs.map +1 -1
- package/dist/core/product/state.d.mts +55 -32
- package/dist/core/product/url.d.mts +19 -13
- package/dist/core/product/url.mjs +10 -10
- package/dist/core/product/url.mjs.map +1 -1
- package/dist/core/request-context.d.mts +77 -19
- package/dist/core/request-context.mjs +5 -1
- package/dist/core/request-context.mjs.map +1 -1
- package/dist/core/request-routing/handle-shopify-redirects.d.mts +12 -4
- package/dist/core/request-routing/handle-shopify-redirects.mjs +9 -2
- package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
- package/dist/core/request-routing/handle-shopify-routes.d.mts +5 -5
- package/dist/core/request-routing/handle-shopify-routes.mjs +7 -5
- package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/proxy.mjs +79 -43
- package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
- package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs +6 -1
- package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/well-known.mjs +1 -1
- package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -1
- package/dist/core/request-routing/registered-routes.d.mts +12 -0
- package/dist/core/request-routing/registered-routes.mjs +12 -0
- package/dist/core/request-routing/registered-routes.mjs.map +1 -1
- package/dist/core/request-routing/route-types.d.mts +43 -18
- package/dist/core/shop-pay/shop-pay.d.mts +71 -35
- package/dist/core/shop-pay/shop-pay.mjs +36 -10
- package/dist/core/shop-pay/shop-pay.mjs.map +1 -1
- package/dist/core/shopify-scripts/index.d.mts +15 -5
- package/dist/core/shopify-scripts/index.mjs +15 -5
- package/dist/core/shopify-scripts/index.mjs.map +1 -1
- package/dist/core/shopify-scripts/initialize.d.mts +12 -4
- package/dist/core/shopify-scripts/initialize.mjs +12 -4
- package/dist/core/shopify-scripts/initialize.mjs.map +1 -1
- package/dist/core/shopify-scripts/types.d.mts +58 -25
- package/dist/core/standard-routes/build.d.mts +11 -12
- package/dist/core/standard-routes/build.mjs +11 -12
- package/dist/core/standard-routes/build.mjs.map +1 -1
- package/dist/core/standard-routes/types.d.mts +30 -24
- package/dist/core/url.mjs +2 -1
- package/dist/core/url.mjs.map +1 -1
- package/dist/customer-account/client.d.mts +36 -69
- package/dist/customer-account/client.mjs +7 -8
- package/dist/customer-account/client.mjs.map +1 -1
- package/dist/customer-account/errors.d.mts +45 -36
- package/dist/customer-account/errors.mjs +21 -36
- package/dist/customer-account/errors.mjs.map +1 -1
- package/dist/customer-account/graphql.d.mts +11 -23
- package/dist/customer-account/graphql.mjs +3 -9
- package/dist/customer-account/graphql.mjs.map +1 -1
- package/dist/customer-account/session.d.mts +130 -100
- package/dist/customer-account/session.mjs +32 -10
- package/dist/customer-account/session.mjs.map +1 -1
- package/dist/customer-account/type-resolver.d.mts +7 -8
- package/dist/development/client/client.d.mts +18 -15
- package/dist/development/client/client.mjs +8 -3
- package/dist/development/client/client.mjs.map +1 -1
- package/dist/development/client/errors.d.mts +35 -13
- package/dist/development/client/errors.mjs +23 -13
- package/dist/development/client/errors.mjs.map +1 -1
- package/dist/development/client/types.d.mts +140 -90
- package/dist/development/core/analytics/cart-tracker.d.mts +19 -10
- package/dist/development/core/analytics/cart-tracker.mjs +18 -10
- package/dist/development/core/analytics/cart-tracker.mjs.map +1 -1
- package/dist/development/core/analytics/events.d.mts +17 -11
- package/dist/development/core/analytics/events.mjs +13 -4
- package/dist/development/core/analytics/events.mjs.map +1 -1
- package/dist/development/core/analytics/types.d.mts +207 -118
- package/dist/development/core/analytics/utils/flatten-connection.d.mts +11 -9
- package/dist/development/core/analytics/utils/flatten-connection.mjs +7 -6
- package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -1
- package/dist/development/core/cache/fetch-with-cache.d.mts +24 -4
- package/dist/development/core/cache/fetch-with-cache.mjs +17 -2
- package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -1
- package/dist/development/core/cache/key.d.mts +2 -0
- package/dist/development/core/cache/key.mjs.map +1 -1
- package/dist/development/core/cache/run-with-cache.d.mts +56 -8
- package/dist/development/core/cache/run-with-cache.mjs +17 -6
- package/dist/development/core/cache/run-with-cache.mjs.map +1 -1
- package/dist/development/core/cache/store.d.mts +8 -6
- package/dist/development/core/cache/store.mjs.map +1 -1
- package/dist/development/core/cache/strategies.d.mts +27 -2
- package/dist/development/core/cache/strategies.mjs +6 -0
- package/dist/development/core/cache/strategies.mjs.map +1 -1
- package/dist/development/core/cart/actions.d.mts +37 -30
- package/dist/development/core/cart/actions.mjs +21 -9
- package/dist/development/core/cart/actions.mjs.map +1 -1
- package/dist/development/core/cart/attach-quantity-input.d.mts +8 -7
- package/dist/development/core/cart/attach-quantity-input.mjs +8 -7
- package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -1
- package/dist/development/core/cart/buyer-identity-sync.d.mts +6 -5
- package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -1
- package/dist/development/core/cart/cart.d.mts +59 -46
- package/dist/development/core/cart/cart.mjs +46 -29
- package/dist/development/core/cart/cart.mjs.map +1 -1
- package/dist/development/core/cart/cookie.d.mts +8 -4
- package/dist/development/core/cart/cookie.mjs +8 -4
- package/dist/development/core/cart/cookie.mjs.map +1 -1
- package/dist/development/core/cart/form.d.mts +34 -20
- package/dist/development/core/cart/form.mjs +6 -4
- package/dist/development/core/cart/form.mjs.map +1 -1
- package/dist/development/core/cart/get-cart.d.mts +27 -15
- package/dist/development/core/cart/get-cart.mjs +13 -8
- package/dist/development/core/cart/get-cart.mjs.map +1 -1
- package/dist/development/core/cart/quantity.d.mts +16 -5
- package/dist/development/core/cart/quantity.mjs +16 -5
- package/dist/development/core/cart/quantity.mjs.map +1 -1
- package/dist/development/core/cart/queries.d.mts +25 -19
- package/dist/development/core/cart/queries.mjs +15 -1
- package/dist/development/core/cart/queries.mjs.map +1 -1
- package/dist/development/core/cart/server-handlers.d.mts +82 -45
- package/dist/development/core/cart/server-handlers.mjs +4 -0
- package/dist/development/core/cart/server-handlers.mjs.map +1 -1
- package/dist/development/core/cart/state.d.mts +110 -64
- package/dist/development/core/cart/state.mjs +24 -6
- package/dist/development/core/cart/state.mjs.map +1 -1
- package/dist/development/core/collection/collection.d.mts +52 -53
- package/dist/development/core/collection/collection.mjs +5 -3
- package/dist/development/core/collection/collection.mjs.map +1 -1
- package/dist/development/core/collection/reconciler.d.mts +23 -16
- package/dist/development/core/collection/reconciler.mjs +8 -4
- package/dist/development/core/collection/reconciler.mjs.map +1 -1
- package/dist/development/core/collection/state.d.mts +31 -26
- package/dist/development/core/collection/state.mjs +4 -3
- package/dist/development/core/collection/state.mjs.map +1 -1
- package/dist/development/core/collection/url.d.mts +70 -29
- package/dist/development/core/collection/url.mjs +63 -25
- package/dist/development/core/collection/url.mjs.map +1 -1
- package/dist/development/core/constants.mjs.map +1 -1
- package/dist/development/core/logging/logging.d.mts +14 -8
- package/dist/development/core/logging/logging.mjs +15 -10
- package/dist/development/core/logging/logging.mjs.map +1 -1
- package/dist/development/core/logging/types.d.mts +28 -11
- package/dist/development/core/logging/types.mjs.map +1 -1
- package/dist/development/core/money/format.d.mts +6 -4
- package/dist/development/core/money/format.mjs +19 -9
- package/dist/development/core/money/format.mjs.map +1 -1
- package/dist/development/core/money/types.d.mts +41 -25
- package/dist/development/core/predictive-search/form.d.mts +37 -7
- package/dist/development/core/predictive-search/form.mjs +21 -3
- package/dist/development/core/predictive-search/form.mjs.map +1 -1
- package/dist/development/core/predictive-search/queries.d.mts +18 -30
- package/dist/development/core/predictive-search/queries.mjs +7 -3
- package/dist/development/core/predictive-search/queries.mjs.map +1 -1
- package/dist/development/core/predictive-search/search.d.mts +25 -27
- package/dist/development/core/predictive-search/search.mjs +20 -19
- package/dist/development/core/predictive-search/search.mjs.map +1 -1
- package/dist/development/core/predictive-search/server-handlers.d.mts +25 -26
- package/dist/development/core/predictive-search/server-handlers.mjs +4 -0
- package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -1
- package/dist/development/core/predictive-search/store.d.mts +65 -24
- package/dist/development/core/predictive-search/store.mjs +12 -1
- package/dist/development/core/predictive-search/store.mjs.map +1 -1
- package/dist/development/core/predictive-search/url.d.mts +36 -37
- package/dist/development/core/predictive-search/url.mjs +14 -6
- package/dist/development/core/predictive-search/url.mjs.map +1 -1
- package/dist/development/core/product/form.d.mts +63 -16
- package/dist/development/core/product/form.mjs +8 -2
- package/dist/development/core/product/form.mjs.map +1 -1
- package/dist/development/core/product/options.d.mts +8 -10
- package/dist/development/core/product/options.mjs +8 -10
- package/dist/development/core/product/options.mjs.map +1 -1
- package/dist/development/core/product/product-form.d.mts +77 -29
- package/dist/development/core/product/product-form.mjs +32 -10
- package/dist/development/core/product/product-form.mjs.map +1 -1
- package/dist/development/core/product/state.d.mts +55 -32
- package/dist/development/core/product/url.d.mts +19 -13
- package/dist/development/core/product/url.mjs +10 -10
- package/dist/development/core/product/url.mjs.map +1 -1
- package/dist/development/core/request-context.d.mts +77 -19
- package/dist/development/core/request-context.mjs +5 -1
- package/dist/development/core/request-context.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +12 -4
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs +9 -2
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +9 -1
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +7 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-routes.mjs +7 -5
- package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/proxy.mjs +79 -43
- package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
- package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs +6 -1
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/well-known.mjs +1 -1
- package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -1
- package/dist/development/core/request-routing/registered-routes.d.mts +12 -0
- package/dist/development/core/request-routing/registered-routes.mjs +12 -0
- package/dist/development/core/request-routing/registered-routes.mjs.map +1 -1
- package/dist/development/core/request-routing/route-types.d.mts +43 -18
- package/dist/development/core/shop-pay/shop-pay.d.mts +71 -35
- package/dist/development/core/shop-pay/shop-pay.mjs +36 -10
- package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/index.d.mts +15 -5
- package/dist/development/core/shopify-scripts/index.mjs +15 -5
- package/dist/development/core/shopify-scripts/index.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/initialize.d.mts +12 -4
- package/dist/development/core/shopify-scripts/initialize.mjs +12 -4
- package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/types.d.mts +58 -25
- package/dist/development/core/standard-routes/build.d.mts +11 -12
- package/dist/development/core/standard-routes/build.mjs +11 -12
- package/dist/development/core/standard-routes/build.mjs.map +1 -1
- package/dist/development/core/standard-routes/types.d.mts +30 -24
- package/dist/development/core/url.mjs +2 -1
- package/dist/development/core/url.mjs.map +1 -1
- package/dist/development/customer-account/session.d.mts +45 -54
- package/dist/development/customer-account/session.mjs +20 -4
- package/dist/development/customer-account/session.mjs.map +1 -1
- package/dist/development/globals.d.mts +20 -11
- package/dist/development/graphql/generated/storefront-api-types.d.mts +127 -1
- package/dist/development/graphql/graphql.d.mts +17 -16
- package/dist/development/graphql/graphql.mjs +7 -8
- package/dist/development/graphql/graphql.mjs.map +1 -1
- package/dist/development/graphql/type-resolver.d.mts +15 -8
- package/dist/development/react/cart.d.mts +78 -32
- package/dist/development/react/cart.mjs +56 -29
- package/dist/development/react/cart.mjs.map +1 -1
- package/dist/development/react/collection.d.mts +40 -22
- package/dist/development/react/collection.mjs +27 -7
- package/dist/development/react/collection.mjs.map +1 -1
- package/dist/development/react/predictive-search.d.mts +65 -50
- package/dist/development/react/predictive-search.mjs +23 -21
- package/dist/development/react/predictive-search.mjs.map +1 -1
- package/dist/development/react/product.d.mts +45 -16
- package/dist/development/react/product.mjs +13 -11
- package/dist/development/react/product.mjs.map +1 -1
- package/dist/development/react/shop-pay.d.mts +15 -0
- package/dist/development/react/shop-pay.mjs +9 -0
- package/dist/development/react/shop-pay.mjs.map +1 -1
- package/dist/development/react/shopify-scripts.d.mts +23 -2
- package/dist/development/react/shopify-scripts.mjs +9 -0
- package/dist/development/react/shopify-scripts.mjs.map +1 -1
- package/dist/development/vue/cart.d.mts +28 -23
- package/dist/development/vue/cart.mjs +42 -25
- package/dist/development/vue/cart.mjs.map +1 -1
- package/dist/development/vue/collection.d.mts +20 -12
- package/dist/development/vue/collection.mjs +15 -7
- package/dist/development/vue/collection.mjs.map +1 -1
- package/dist/development/vue/index.d.mts +2 -2
- package/dist/development/vue/index.mjs +2 -2
- package/dist/development/vue/predictive-search.d.mts +31 -36
- package/dist/development/vue/predictive-search.mjs +16 -22
- package/dist/development/vue/predictive-search.mjs.map +1 -1
- package/dist/development/vue/product.d.mts +16 -15
- package/dist/development/vue/product.mjs +11 -11
- package/dist/development/vue/product.mjs.map +1 -1
- package/dist/development/vue/shop-pay.d.mts +14 -17
- package/dist/development/vue/shop-pay.mjs +8 -0
- package/dist/development/vue/shop-pay.mjs.map +1 -1
- package/dist/development/vue/shopify-scripts.d.mts +11 -0
- package/dist/development/vue/shopify-scripts.mjs +6 -0
- package/dist/development/vue/shopify-scripts.mjs.map +1 -1
- package/dist/globals.d.mts +20 -11
- package/dist/graphql/generated/storefront-api-types.d.mts +127 -1
- package/dist/graphql/graphql.d.mts +17 -16
- package/dist/graphql/graphql.mjs +7 -8
- package/dist/graphql/graphql.mjs.map +1 -1
- package/dist/graphql/type-resolver.d.mts +15 -8
- package/dist/react/cart.d.mts +78 -32
- package/dist/react/cart.mjs +56 -29
- package/dist/react/cart.mjs.map +1 -1
- package/dist/react/collection.d.mts +40 -22
- package/dist/react/collection.mjs +27 -7
- package/dist/react/collection.mjs.map +1 -1
- package/dist/react/predictive-search.d.mts +65 -50
- package/dist/react/predictive-search.mjs +23 -21
- package/dist/react/predictive-search.mjs.map +1 -1
- package/dist/react/product.d.mts +45 -16
- package/dist/react/product.mjs +13 -11
- package/dist/react/product.mjs.map +1 -1
- package/dist/react/shop-pay.d.mts +15 -0
- package/dist/react/shop-pay.mjs +9 -0
- package/dist/react/shop-pay.mjs.map +1 -1
- package/dist/react/shopify-scripts.d.mts +23 -2
- package/dist/react/shopify-scripts.mjs +9 -0
- package/dist/react/shopify-scripts.mjs.map +1 -1
- package/dist/ts-plugin/index.cjs +6 -0
- package/dist/ts-plugin/index.cjs.map +1 -1
- package/dist/ts-plugin/index.d.cts +6 -0
- package/dist/vite/local-https.d.mts +51 -17
- package/dist/vite/local-https.mjs +26 -5
- package/dist/vite/local-https.mjs.map +1 -1
- package/dist/vue/cart.d.mts +28 -23
- package/dist/vue/cart.mjs +42 -25
- package/dist/vue/cart.mjs.map +1 -1
- package/dist/vue/collection.d.mts +20 -12
- package/dist/vue/collection.mjs +15 -7
- package/dist/vue/collection.mjs.map +1 -1
- package/dist/vue/index.d.mts +2 -2
- package/dist/vue/index.mjs +2 -2
- package/dist/vue/predictive-search.d.mts +31 -36
- package/dist/vue/predictive-search.mjs +16 -22
- package/dist/vue/predictive-search.mjs.map +1 -1
- package/dist/vue/product.d.mts +16 -15
- package/dist/vue/product.mjs +11 -11
- package/dist/vue/product.mjs.map +1 -1
- package/dist/vue/shop-pay.d.mts +14 -17
- package/dist/vue/shop-pay.mjs +8 -0
- package/dist/vue/shop-pay.mjs.map +1 -1
- package/dist/vue/shopify-scripts.d.mts +11 -0
- package/dist/vue/shopify-scripts.mjs +6 -0
- package/dist/vue/shopify-scripts.mjs.map +1 -1
- package/package.json +3 -1
- package/skills/hydrogen-analytics/SKILL.md +1 -1
- package/skills/hydrogen-cart-ui/SKILL.md +28 -2
- package/skills/hydrogen-collection-browser/SKILL.md +9 -1
- package/skills/hydrogen-collection-browser/references/nextjs.md +1 -1
- package/skills/hydrogen-collection-browser/references/nuxt.md +1 -1
- package/skills/hydrogen-collection-browser/references/react.md +151 -32
- package/skills/hydrogen-customer-account/SKILL.md +2 -0
- package/skills/hydrogen-request-handlers/SKILL.md +21 -11
- package/skills/hydrogen-setup/references/analytics.md +14 -8
- package/skills/hydrogen-setup/steps/1-inspect-app.md +2 -2
- package/skills/hydrogen-setup/steps/6-product-detail-page.md +21 -11
- package/skills/hydrogen-storefront-client/SKILL.md +1 -1
- package/skills/hydrogen-storefront-client/references/caching.md +2 -0
- package/skills/hydrogen-variant-form/SKILL.md +25 -7
- package/skills/hydrogen-variant-form/references/nextjs.md +39 -4
- package/skills/hydrogen-variant-form/references/nuxt.md +83 -42
- package/skills/hydrogen-variant-form/references/react.md +45 -9
|
@@ -2,11 +2,23 @@ import { ShopifyRoutesOptions, ShopifyScriptTagsOptions } from "../core/shopify-
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/react/shopify-scripts.d.ts
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Props for the `ShopifyScripts` component in React and Vue. The component renders Shopify's script
|
|
7
|
+
* tags and starts the scripts in the browser after hydration. The component starts the scripts
|
|
8
|
+
* once, with the first props. Later prop changes don't restart the scripts.
|
|
9
|
+
*
|
|
10
|
+
* In Next.js App Router, render the component from a client component when you pass a consent `setup` function. Function props can't cross the server-to-client boundary.
|
|
11
|
+
*
|
|
12
|
+
* @publicDocs
|
|
13
|
+
*/
|
|
14
|
+
interface ShopifyScriptsProps extends ShopifyScriptTagsOptions {
|
|
15
|
+
/** Navigates after Shopify's scripts resolve a URL to your app's route. Defaults to a full page load. */
|
|
6
16
|
navigate?: ShopifyRoutesOptions["navigate"];
|
|
17
|
+
/** Your app's custom route templates, which Shopify's scripts use to match storefront URLs. */
|
|
7
18
|
routes?: ShopifyRoutesOptions["routes"];
|
|
19
|
+
/** Loads Shopify's WebMCP tools when the browser supports WebMCP. Defaults to `true`. */
|
|
8
20
|
webMcp?: boolean;
|
|
9
|
-
}
|
|
21
|
+
}
|
|
10
22
|
declare module "react" {
|
|
11
23
|
namespace JSX {
|
|
12
24
|
interface IntrinsicElements {
|
|
@@ -14,6 +26,15 @@ declare module "react" {
|
|
|
14
26
|
}
|
|
15
27
|
}
|
|
16
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Renders Shopify's script tags and starts the scripts in the browser after hydration. The component starts the scripts once, with the first props. Later prop changes don't restart the scripts.
|
|
31
|
+
*
|
|
32
|
+
* `ShopifyScripts` is a client component. In Next.js App Router, render it from a client component when you pass a consent `setup` function. Function props can't cross the server-to-client boundary.
|
|
33
|
+
*
|
|
34
|
+
* @param options - The script tag options, plus the consent, route, and WebMCP settings for starting the scripts.
|
|
35
|
+
* @returns Shopify's link and script tags, with the link tags first.
|
|
36
|
+
* @publicDocs
|
|
37
|
+
*/
|
|
17
38
|
declare function ShopifyScripts(options: ShopifyScriptsProps): React.FunctionComponentElement<React.FragmentProps>;
|
|
18
39
|
//#endregion
|
|
19
40
|
export { ShopifyScripts, ShopifyScriptsProps };
|
|
@@ -5,6 +5,15 @@ import { getShopifyScriptTags } from "../core/shopify-scripts/index.mjs";
|
|
|
5
5
|
import { Fragment, createElement, useEffect } from "react";
|
|
6
6
|
|
|
7
7
|
//#region src/react/shopify-scripts.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Renders Shopify's script tags and starts the scripts in the browser after hydration. The component starts the scripts once, with the first props. Later prop changes don't restart the scripts.
|
|
10
|
+
*
|
|
11
|
+
* `ShopifyScripts` is a client component. In Next.js App Router, render it from a client component when you pass a consent `setup` function. Function props can't cross the server-to-client boundary.
|
|
12
|
+
*
|
|
13
|
+
* @param options - The script tag options, plus the consent, route, and WebMCP settings for starting the scripts.
|
|
14
|
+
* @returns Shopify's link and script tags, with the link tags first.
|
|
15
|
+
* @publicDocs
|
|
16
|
+
*/
|
|
8
17
|
function ShopifyScripts(options) {
|
|
9
18
|
const { consent, navigate, routes, webMcp = true, ...scriptOptions } = options;
|
|
10
19
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shopify-scripts.mjs","names":[],"sources":["../../../src/react/shopify-scripts.tsx"],"sourcesContent":["\"use client\";\n\nimport { createElement, Fragment, useEffect } from \"react\";\nimport type * as React from \"react\";\n\nimport {\n getShopifyScriptTags,\n initializeShopifyScripts,\n type ShopifyRoutesOptions,\n type ShopifyScriptTagsOptions,\n} from \"../core/shopify-scripts\";\n\nexport
|
|
1
|
+
{"version":3,"file":"shopify-scripts.mjs","names":[],"sources":["../../../src/react/shopify-scripts.tsx"],"sourcesContent":["\"use client\";\n\nimport { createElement, Fragment, useEffect } from \"react\";\nimport type * as React from \"react\";\n\nimport {\n getShopifyScriptTags,\n initializeShopifyScripts,\n type ShopifyRoutesOptions,\n type ShopifyScriptTagsOptions,\n} from \"../core/shopify-scripts\";\n\n/**\n * Props for the `ShopifyScripts` component in React and Vue. The component renders Shopify's script\n * tags and starts the scripts in the browser after hydration. The component starts the scripts\n * once, with the first props. Later prop changes don't restart the scripts.\n *\n * In Next.js App Router, render the component from a client component when you pass a consent `setup` function. Function props can't cross the server-to-client boundary.\n *\n * @publicDocs\n */\nexport interface ShopifyScriptsProps extends ShopifyScriptTagsOptions {\n /** Navigates after Shopify's scripts resolve a URL to your app's route. Defaults to a full page load. */\n navigate?: ShopifyRoutesOptions[\"navigate\"];\n /** Your app's custom route templates, which Shopify's scripts use to match storefront URLs. */\n routes?: ShopifyRoutesOptions[\"routes\"];\n /** Loads Shopify's WebMCP tools when the browser supports WebMCP. Defaults to `true`. */\n webMcp?: boolean;\n}\n\ndeclare module \"react\" {\n namespace JSX {\n interface IntrinsicElements {\n \"shopify-chat\": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n }\n }\n}\n\n/**\n * Renders Shopify's script tags and starts the scripts in the browser after hydration. The component starts the scripts once, with the first props. Later prop changes don't restart the scripts.\n *\n * `ShopifyScripts` is a client component. In Next.js App Router, render it from a client component when you pass a consent `setup` function. Function props can't cross the server-to-client boundary.\n *\n * @param options - The script tag options, plus the consent, route, and WebMCP settings for starting the scripts.\n * @returns Shopify's link and script tags, with the link tags first.\n * @publicDocs\n */\nexport function ShopifyScripts(options: ShopifyScriptsProps) {\n const { consent, navigate, routes, webMcp = true, ...scriptOptions } = options;\n\n useEffect(() => {\n void initializeShopifyScripts({ consent, navigate, routes, webMcp });\n // oxlint-disable-next-line react-hooks/exhaustive-deps -- ShopifyScripts browser startup is initialized once from initial props.\n }, []);\n\n return createElement(\n Fragment,\n null,\n getShopifyScriptTags({ ...scriptOptions, consent }).tags.map(\n ({ tagName, attributes, innerHTML }, index) =>\n createElement(tagName, {\n key: index,\n ...getReactAttributes(attributes),\n ...(innerHTML ? { dangerouslySetInnerHTML: { __html: innerHTML } } : {}),\n }),\n ),\n );\n}\n\nfunction getReactAttributes(attributes: Record<string, string | boolean> = {}) {\n const reactAttributes = Object.fromEntries(\n Object.entries(attributes).map(([name, value]) => [\n name === \"crossorigin\" ? \"crossOrigin\" : name,\n value,\n ]),\n );\n\n if (attributes.nonce !== undefined) {\n // Browsers intentionally hide nonce content attributes from getAttribute(),\n // which can make React report a false hydration mismatch for SSR scripts.\n reactAttributes.suppressHydrationWarning = true;\n }\n\n if (attributes.async === true && typeof attributes.src === \"string\") {\n // React hoists async scripts without handlers, which can let them execute before\n // the inline Shopify bootstrap scripts that configure their globals.\n return { ...reactAttributes, onLoad: disableReactScriptHoisting };\n }\n\n return reactAttributes;\n}\n\nconst disableReactScriptHoisting = () => {};\n"],"mappings":";;;;;;;;;;;;;;;;AA+CA,SAAgB,eAAe,SAA8B;CAC3D,MAAM,EAAE,SAAS,UAAU,QAAQ,SAAS,MAAM,GAAG,kBAAkB;AAEvE,iBAAgB;AACd,EAAK,yBAAyB;GAAE;GAAS;GAAU;GAAQ;GAAQ,CAAC;IAEnE,EAAE,CAAC;AAEN,QAAO,cACL,UACA,MACA,qBAAqB;EAAE,GAAG;EAAe;EAAS,CAAC,CAAC,KAAK,KACtD,EAAE,SAAS,YAAY,aAAa,UACnC,cAAc,SAAS;EACrB,KAAK;EACL,GAAG,mBAAmB,WAAW;EACjC,GAAI,YAAY,EAAE,yBAAyB,EAAE,QAAQ,WAAW,EAAE,GAAG,EAAE;EACxE,CAAC,CACL,CACF;;AAGH,SAAS,mBAAmB,aAA+C,EAAE,EAAE;CAC7E,MAAM,kBAAkB,OAAO,YAC7B,OAAO,QAAQ,WAAW,CAAC,KAAK,CAAC,MAAM,WAAW,CAChD,SAAS,gBAAgB,gBAAgB,MACzC,MACD,CAAC,CACH;AAED,KAAI,WAAW,UAAU,OAGvB,iBAAgB,2BAA2B;AAG7C,KAAI,WAAW,UAAU,QAAQ,OAAO,WAAW,QAAQ,SAGzD,QAAO;EAAE,GAAG;EAAiB,QAAQ;EAA4B;AAGnE,QAAO;;AAGT,MAAM,mCAAmC"}
|
|
@@ -18,18 +18,20 @@ type TypedCartProvider<TData extends CartData> = {
|
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
+
/** Cart provider and composables whose cart state carries the custom fields from your cart server handlers. */
|
|
21
22
|
type TypedCartComponents<TData extends CartData> = {
|
|
22
|
-
CartProvider: TypedCartProvider<TData>;
|
|
23
|
-
useCart: TypedUseCart<TData>;
|
|
24
|
-
useOptionalCart: TypedUseOptionalCart<TData>;
|
|
25
|
-
useCartActions: typeof useCartActions;
|
|
23
|
+
/** The provider that creates the cart store. The provider connects the store on mount and destroys the store on unmount. */CartProvider: TypedCartProvider<TData>; /** Returns cart state as a read-only shallow ref. The selector is optional. Without a selector, the ref holds the full cart state. */
|
|
24
|
+
useCart: TypedUseCart<TData>; /** Returns the slice of cart state that the selector picks as a read-only shallow ref. Outside the provider, the ref holds `undefined`. */
|
|
25
|
+
useOptionalCart: TypedUseOptionalCart<TData>; /** Returns the `refresh` action. Call `refresh` after a server-side cart mutation that bypasses cart forms. */
|
|
26
|
+
useCartActions: typeof useCartActions; /** Returns form props, a register function, and pending state for cart forms. */
|
|
26
27
|
useCartForm: typeof useCartForm;
|
|
27
28
|
};
|
|
28
29
|
/**
|
|
29
|
-
* Returns cart
|
|
30
|
+
* Returns the cart action that syncs the cart after a mutation outside cart forms.
|
|
30
31
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
32
|
+
* Call `refresh` after a server-side cart mutation that bypasses cart forms, such as a server action that creates the cart.
|
|
33
|
+
*
|
|
34
|
+
* @returns The `refresh` action.
|
|
33
35
|
*
|
|
34
36
|
* @example
|
|
35
37
|
* ```vue
|
|
@@ -42,13 +44,13 @@ type TypedCartComponents<TData extends CartData> = {
|
|
|
42
44
|
* }
|
|
43
45
|
* </script>
|
|
44
46
|
* ```
|
|
47
|
+
* @publicDocs
|
|
45
48
|
*/
|
|
46
49
|
declare function useCartActions(): CartActions;
|
|
47
50
|
/**
|
|
48
|
-
*
|
|
51
|
+
* Publishes cart analytics events when the cart changes.
|
|
49
52
|
*
|
|
50
|
-
* Call once near the root of your app.
|
|
51
|
-
* and cleans up via `onScopeDispose`.
|
|
53
|
+
* Call the composable once near the root of your app. The composable starts tracking on mount and stops when the component's scope ends. The composable throws when you call it outside the cart provider.
|
|
52
54
|
*
|
|
53
55
|
* @example
|
|
54
56
|
* ```vue
|
|
@@ -56,19 +58,19 @@ declare function useCartActions(): CartActions;
|
|
|
56
58
|
* useCartAnalytics();
|
|
57
59
|
* </script>
|
|
58
60
|
* ```
|
|
61
|
+
* @publicDocs
|
|
59
62
|
*/
|
|
60
63
|
declare function useCartAnalytics(): void;
|
|
61
64
|
/**
|
|
62
|
-
* Returns form props, a
|
|
63
|
-
*
|
|
65
|
+
* Returns form props, a register function, and pending state for cart forms.
|
|
66
|
+
*
|
|
67
|
+
* The form props post to the cart endpoint and send each submission through the cart store. A `beforeSubmit` callback that prevents the event's default skips the cart submission.
|
|
64
68
|
*
|
|
65
|
-
*
|
|
66
|
-
* object with `initial` (`ComputedRef<boolean>`) for the initial cart load
|
|
67
|
-
* and `lines(lineId?)` for checking per-line or any-line pending state.
|
|
69
|
+
* The pending state holds a computed ref that's `true` during a full cart load, and a function that checks whether one line or any line has a mutation in flight.
|
|
68
70
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
71
|
+
* Registering the quantity field with `interactive: true` returns numeric input attributes without auto-submit. Call attachQuantityInput on the input to submit the form when the quantity changes.
|
|
72
|
+
*
|
|
73
|
+
* @returns The form props function, the register function, and the pending state.
|
|
72
74
|
*
|
|
73
75
|
* @example
|
|
74
76
|
* ```vue
|
|
@@ -87,6 +89,7 @@ declare function useCartAnalytics(): void;
|
|
|
87
89
|
* </form>
|
|
88
90
|
* </template>
|
|
89
91
|
* ```
|
|
92
|
+
* @publicDocs
|
|
90
93
|
*/
|
|
91
94
|
declare function useCartForm(): {
|
|
92
95
|
formProps: (opts?: {
|
|
@@ -100,11 +103,12 @@ declare function useCartForm(): {
|
|
|
100
103
|
};
|
|
101
104
|
};
|
|
102
105
|
/**
|
|
103
|
-
*
|
|
104
|
-
* server
|
|
106
|
+
* Returns a cart provider and composables typed to the cart query in your cart server handlers.
|
|
107
|
+
* Pass the type of your cart server handlers as the `THandlers` type argument. Every composable's cart state then includes your custom cart fields.
|
|
108
|
+
*
|
|
109
|
+
* On mount, the provider points cart requests at `/api/cart` and connects the store. Every composable except the optional cart composable throws when you call it outside the provider.
|
|
105
110
|
*
|
|
106
|
-
* The
|
|
107
|
-
* call, so every composable's {@link CartState} carries your custom cart fields.
|
|
111
|
+
* @returns The typed cart provider, the cart state composables, and the cart actions and form composables.
|
|
108
112
|
*
|
|
109
113
|
* @example
|
|
110
114
|
* ```ts
|
|
@@ -118,8 +122,9 @@ declare function useCartForm(): {
|
|
|
118
122
|
* useCartForm,
|
|
119
123
|
* } = createCartComponents<typeof cartServerHandlers>();
|
|
120
124
|
* ```
|
|
125
|
+
* @publicDocs
|
|
121
126
|
*/
|
|
122
127
|
declare function createCartComponents<THandlers>(): TypedCartComponents<CartDataFromHandlers<THandlers>>;
|
|
123
128
|
//#endregion
|
|
124
|
-
export { createCartComponents,
|
|
129
|
+
export { createCartComponents, useCartAnalytics };
|
|
125
130
|
//# sourceMappingURL=cart.d.mts.map
|
|
@@ -26,11 +26,9 @@ function useOptionalCartStore() {
|
|
|
26
26
|
return inject(CartStoreKey, null);
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Creates a cart store and shares the store with the cart composables below the provider.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
* All cart composables (`useCart`, `useCartForm`, `useCartActions`) must be
|
|
33
|
-
* descendants of this component.
|
|
31
|
+
* The provider connects the store on mount and destroys the store on unmount. Render every cart composable inside the provider. The provider creates its store once from the first initial data and ignores later changes.
|
|
34
32
|
*
|
|
35
33
|
* @example
|
|
36
34
|
* ```vue
|
|
@@ -38,6 +36,7 @@ function useOptionalCartStore() {
|
|
|
38
36
|
* <App />
|
|
39
37
|
* </CartProvider>
|
|
40
38
|
* ```
|
|
39
|
+
* @publicDocs
|
|
41
40
|
*/
|
|
42
41
|
const CartProvider = defineComponent({
|
|
43
42
|
name: "CartProvider",
|
|
@@ -62,10 +61,11 @@ function useCart(selector, isEqual) {
|
|
|
62
61
|
return useCartSelector(useCartStore("useCart"), selector ?? ((state) => state), isEqual);
|
|
63
62
|
}
|
|
64
63
|
/**
|
|
65
|
-
* Returns cart
|
|
64
|
+
* Returns the cart action that syncs the cart after a mutation outside cart forms.
|
|
66
65
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
66
|
+
* Call `refresh` after a server-side cart mutation that bypasses cart forms, such as a server action that creates the cart.
|
|
67
|
+
*
|
|
68
|
+
* @returns The `refresh` action.
|
|
69
69
|
*
|
|
70
70
|
* @example
|
|
71
71
|
* ```vue
|
|
@@ -78,15 +78,15 @@ function useCart(selector, isEqual) {
|
|
|
78
78
|
* }
|
|
79
79
|
* <\/script>
|
|
80
80
|
* ```
|
|
81
|
+
* @publicDocs
|
|
81
82
|
*/
|
|
82
83
|
function useCartActions() {
|
|
83
84
|
return { refresh: useCartStore("useCartActions").refresh };
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
|
-
*
|
|
87
|
+
* Publishes cart analytics events when the cart changes.
|
|
87
88
|
*
|
|
88
|
-
* Call once near the root of your app.
|
|
89
|
-
* and cleans up via `onScopeDispose`.
|
|
89
|
+
* Call the composable once near the root of your app. The composable starts tracking on mount and stops when the component's scope ends. The composable throws when you call it outside the cart provider.
|
|
90
90
|
*
|
|
91
91
|
* @example
|
|
92
92
|
* ```vue
|
|
@@ -94,6 +94,7 @@ function useCartActions() {
|
|
|
94
94
|
* useCartAnalytics();
|
|
95
95
|
* <\/script>
|
|
96
96
|
* ```
|
|
97
|
+
* @publicDocs
|
|
97
98
|
*/
|
|
98
99
|
function useCartAnalytics() {
|
|
99
100
|
const store = useCartStore("useCartAnalytics");
|
|
@@ -104,8 +105,22 @@ function useCartAnalytics() {
|
|
|
104
105
|
onScopeDispose(() => stopTracking?.());
|
|
105
106
|
}
|
|
106
107
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
108
|
+
* Returns the slice of cart state that the selector picks as a read-only shallow ref. Outside the cart provider, the ref holds `undefined`.
|
|
109
|
+
*
|
|
110
|
+
* Use the composable in a component that also renders above the provider, such as a header cart badge on an error page.
|
|
111
|
+
* Wherever the provider always exists, use the cart composable that throws. A missing provider then fails with an error.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```vue
|
|
115
|
+
* <script setup>
|
|
116
|
+
* const count = useOptionalCart((state) => state.data.totalQuantity);
|
|
117
|
+
* <\/script>
|
|
118
|
+
*
|
|
119
|
+
* <template>
|
|
120
|
+
* <span v-if="count !== undefined">Cart ({{ count }})</span>
|
|
121
|
+
* </template>
|
|
122
|
+
* ```
|
|
123
|
+
* @publicDocs
|
|
109
124
|
*/
|
|
110
125
|
function useOptionalCart(selector, isEqual) {
|
|
111
126
|
const store = useOptionalCartStore();
|
|
@@ -122,16 +137,15 @@ function useCartSelector(store, selector, isEqual) {
|
|
|
122
137
|
return selected;
|
|
123
138
|
}
|
|
124
139
|
/**
|
|
125
|
-
* Returns form props, a
|
|
126
|
-
* for building cart forms in Vue.
|
|
140
|
+
* Returns form props, a register function, and pending state for cart forms.
|
|
127
141
|
*
|
|
128
|
-
*
|
|
129
|
-
* object with `initial` (`ComputedRef<boolean>`) for the initial cart load
|
|
130
|
-
* and `lines(lineId?)` for checking per-line or any-line pending state.
|
|
142
|
+
* The form props post to the cart endpoint and send each submission through the cart store. A `beforeSubmit` callback that prevents the event's default skips the cart submission.
|
|
131
143
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
144
|
+
* The pending state holds a computed ref that's `true` during a full cart load, and a function that checks whether one line or any line has a mutation in flight.
|
|
145
|
+
*
|
|
146
|
+
* Registering the quantity field with `interactive: true` returns numeric input attributes without auto-submit. Call attachQuantityInput on the input to submit the form when the quantity changes.
|
|
147
|
+
*
|
|
148
|
+
* @returns The form props function, the register function, and the pending state.
|
|
135
149
|
*
|
|
136
150
|
* @example
|
|
137
151
|
* ```vue
|
|
@@ -150,6 +164,7 @@ function useCartSelector(store, selector, isEqual) {
|
|
|
150
164
|
* </form>
|
|
151
165
|
* </template>
|
|
152
166
|
* ```
|
|
167
|
+
* @publicDocs
|
|
153
168
|
*/
|
|
154
169
|
function useCartForm() {
|
|
155
170
|
const store = useCartStore("useCartForm");
|
|
@@ -177,11 +192,12 @@ function useCartForm() {
|
|
|
177
192
|
};
|
|
178
193
|
}
|
|
179
194
|
/**
|
|
180
|
-
*
|
|
181
|
-
* server
|
|
195
|
+
* Returns a cart provider and composables typed to the cart query in your cart server handlers.
|
|
196
|
+
* Pass the type of your cart server handlers as the `THandlers` type argument. Every composable's cart state then includes your custom cart fields.
|
|
197
|
+
*
|
|
198
|
+
* On mount, the provider points cart requests at `/api/cart` and connects the store. Every composable except the optional cart composable throws when you call it outside the provider.
|
|
182
199
|
*
|
|
183
|
-
* The
|
|
184
|
-
* call, so every composable's {@link CartState} carries your custom cart fields.
|
|
200
|
+
* @returns The typed cart provider, the cart state composables, and the cart actions and form composables.
|
|
185
201
|
*
|
|
186
202
|
* @example
|
|
187
203
|
* ```ts
|
|
@@ -195,6 +211,7 @@ function useCartForm() {
|
|
|
195
211
|
* useCartForm,
|
|
196
212
|
* } = createCartComponents<typeof cartServerHandlers>();
|
|
197
213
|
* ```
|
|
214
|
+
* @publicDocs
|
|
198
215
|
*/
|
|
199
216
|
function createCartComponents() {
|
|
200
217
|
const TypedCartProvider = createTypedCartProvider();
|
|
@@ -213,5 +230,5 @@ function createCartComponents() {
|
|
|
213
230
|
}
|
|
214
231
|
|
|
215
232
|
//#endregion
|
|
216
|
-
export { createCartComponents, getCartEndpoint,
|
|
233
|
+
export { createCartComponents, getCartEndpoint, useCartAnalytics, useCartStore };
|
|
217
234
|
//# sourceMappingURL=cart.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cart.mjs","names":[],"sources":["../../../src/vue/cart.ts"],"sourcesContent":["import {\n computed,\n defineComponent,\n h,\n inject,\n onMounted,\n onScopeDispose,\n onUnmounted,\n provide,\n shallowRef,\n type ComputedRef,\n type InjectionKey,\n type PropType,\n type ShallowRef,\n} from \"vue\";\n\nimport { trackCartAnalytics } from \"../core/analytics/cart-tracker\";\nimport {\n configureCartEndpoint as configureCoreCartEndpoint,\n createCartStore,\n type CreateCartStoreOptions,\n type CartActions,\n type CartStore,\n} from \"../core/cart/cart\";\nimport { createCartFormRegister, type CartFormRegister } from \"../core/cart/form\";\nimport type { CartDataFromHandlers } from \"../core/cart/server-handlers\";\nimport type { CartData, CartState } from \"../core/cart/state\";\n\nconst DEFAULT_CART_ENDPOINT = \"/api/cart\";\n\nlet cartEndpoint = DEFAULT_CART_ENDPOINT;\n\nconst CartStoreKey: InjectionKey<CartStore> = Symbol(\"CartStore\");\n\nexport function configureCartEndpoint(endpoint: string): void {\n cartEndpoint = endpoint;\n configureCoreCartEndpoint(endpoint);\n}\n\nexport function getCartEndpoint(): string {\n return cartEndpoint;\n}\n\ntype TypedUseCart<TData extends CartData> = {\n (): Readonly<ShallowRef<CartState<TData>>>;\n <S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n ): Readonly<ShallowRef<S>>;\n};\n\ntype TypedUseOptionalCart<TData extends CartData> = <S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n) => Readonly<ShallowRef<S | undefined>>;\n\ntype CartInitialData<TData extends CartData = CartData> =\n CreateCartStoreOptions<TData>[\"initialData\"];\n\ntype TypedCartProvider<TData extends CartData> = {\n new (): { $props: { initialData?: CartInitialData<TData> } };\n};\n\nexport type { CartActions };\n\ntype TypedCartComponents<TData extends CartData> = {\n CartProvider: TypedCartProvider<TData>;\n useCart: TypedUseCart<TData>;\n useOptionalCart: TypedUseOptionalCart<TData>;\n useCartActions: typeof useCartActions;\n useCartForm: typeof useCartForm;\n};\n\nfunction createTypedCartProvider<TData extends CartData>(): TypedCartProvider<TData> {\n const TypedCartProvider = defineComponent(\n (props: { initialData?: CartInitialData<TData> }, { slots }) => {\n return () =>\n h(\n CartProvider,\n { initialData: props.initialData as CartInitialData | undefined },\n slots.default,\n );\n },\n { name: \"CartProvider\", props: [\"initialData\"] },\n );\n\n return TypedCartProvider as unknown as TypedCartProvider<TData>;\n}\n\nexport function useCartStore(composableName = \"useCartStore\"): CartStore {\n const store = inject(CartStoreKey, null);\n if (!store) {\n throw new Error(`${composableName} must be used inside a <CartProvider>.`);\n }\n return store;\n}\n\nfunction useOptionalCartStore(): CartStore | null {\n return inject(CartStoreKey, null);\n}\n\n/**\n * Vue component that creates and manages a {@link CartStore} instance.\n *\n * Calls {@link CartStore.connect} on mount and {@link CartStore.destroy} on unmount.\n * All cart composables (`useCart`, `useCartForm`, `useCartActions`) must be\n * descendants of this component.\n *\n * @example\n * ```vue\n * <CartProvider :initialData=\"{ cart: loaderData.cart }\">\n * <App />\n * </CartProvider>\n * ```\n */\nexport const CartProvider = defineComponent({\n name: \"CartProvider\",\n props: {\n initialData: {\n type: Object as PropType<CartInitialData>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n const store = createCartStore({ initialData: props.initialData });\n provide(CartStoreKey, store);\n\n onMounted(() => {\n configureCoreCartEndpoint(cartEndpoint);\n store.connect();\n });\n\n onUnmounted(() => {\n store.destroy();\n });\n\n return () => slots.default?.();\n },\n});\n\n/**\n * Subscribes to {@link CartState} as a Vue `ShallowRef`.\n *\n * Without a selector, returns the full `CartState`. With a selector, returns\n * a `ShallowRef` of the selected slice — the ref updates only when the\n * selected value changes (by reference, or by custom `isEqual`).\n *\n * @example\n * ```vue\n * <script setup>\n * // Full state\n * const state = useCart();\n *\n * // Selected slice — re-renders only when lines change\n * const lines = useCart((s) => s.data.lines.nodes);\n *\n * // Check if a specific line is pending\n * const isPending = useCart((s) => s.pending.lines.has(lineId));\n * </script>\n * ```\n */\nexport function useCart(): Readonly<ShallowRef<CartState>>;\nexport function useCart<TData extends CartData = CartData, S = unknown>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>>;\nexport function useCart<TData extends CartData = CartData, S = unknown>(\n selector?: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S | CartState>> {\n const store = useCartStore(\"useCart\");\n const resolve = selector ?? ((state: CartState<TData>) => state as unknown as S);\n return useCartSelector(store, resolve, isEqual) as Readonly<ShallowRef<S>>;\n}\n\n/**\n * Returns cart actions for reconciling state after out-of-band mutations.\n *\n * Currently exposes {@link CartStore.refresh} — call it after server-side cart\n * mutations that bypass the form system.\n *\n * @example\n * ```vue\n * <script setup>\n * const { refresh } = useCartActions();\n *\n * async function handleServerAction() {\n * await createCartOnServer();\n * refresh();\n * }\n * </script>\n * ```\n */\nexport function useCartActions(): CartActions {\n const store = useCartStore(\"useCartActions\");\n return { refresh: store.refresh };\n}\n\n/**\n * Subscribes the {@link CartStore} to the analytics event dispatcher.\n *\n * Call once near the root of your app. Starts tracking on mount via `onMounted`\n * and cleans up via `onScopeDispose`.\n *\n * @example\n * ```vue\n * <script setup>\n * useCartAnalytics();\n * </script>\n * ```\n */\nexport function useCartAnalytics(): void {\n const store = useCartStore(\"useCartAnalytics\");\n let stopTracking: (() => void) | undefined;\n\n onMounted(() => {\n stopTracking = trackCartAnalytics(store);\n });\n\n onScopeDispose(() => stopTracking?.());\n}\n\n/**\n * Like `useCart`, but returns `undefined` when rendered outside a `<CartProvider>`.\n * @internal\n */\nexport function useOptionalCart<TData extends CartData = CartData, S = unknown>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S | undefined>> {\n const store = useOptionalCartStore();\n if (!store) return shallowRef<S | undefined>(undefined);\n return useCartSelector(store, selector, isEqual);\n}\n\nfunction useCartSelector<TData extends CartData = CartData, S = unknown>(\n store: CartStore,\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>> {\n const selected = shallowRef<S>(selector(store.getState() as CartState<TData>));\n\n const unsubscribe = store.subscribe(() => {\n const next = selector(store.getState() as CartState<TData>);\n if (isEqual?.(selected.value, next)) return;\n selected.value = next;\n });\n\n onScopeDispose(unsubscribe);\n\n return selected as Readonly<ShallowRef<S>>;\n}\n\n/**\n * Returns form props, a field register function, and reactive pending state\n * for building cart forms in Vue.\n *\n * Unlike the React hook, the Vue variant includes `isPending` — a reactive\n * object with `initial` (`ComputedRef<boolean>`) for the initial cart load\n * and `lines(lineId?)` for checking per-line or any-line pending state.\n *\n * Note: `interactive: true` returns numeric input attributes but does **not**\n * auto-submit on change — that behavior requires `attachQuantityInput`, which\n * is only wired by the React adapter.\n *\n * @example\n * ```vue\n * <script setup>\n * const { formProps, register, isPending } = useCartForm();\n * </script>\n *\n * <template>\n * <form v-bind=\"formProps()\">\n * <input v-bind=\"register('lineId', { value: line.id })\" />\n * <input v-bind=\"register('quantity', { value: line.quantity })\" />\n * <button v-bind=\"register('set')\" />\n * <button v-bind=\"register('increase')\">+</button>\n * <button v-bind=\"register('decrease')\">−</button>\n * <span v-if=\"isPending.lines(line.id)\">Updating…</span>\n * </form>\n * </template>\n * ```\n */\nexport function useCartForm(): {\n formProps: (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }) => Record<string, unknown>;\n register: CartFormRegister;\n isPending: {\n initial: ComputedRef<boolean>;\n lines: (lineId?: string) => boolean;\n };\n} {\n const store = useCartStore(\"useCartForm\");\n const loading = useCart((s) => s.loading);\n const pendingLines = useCart((s) => s.pending.lines);\n const register = createCartFormRegister();\n\n const formProps = (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }): Record<string, unknown> => ({\n onSubmit: (e: SubmitEvent) => {\n opts?.beforeSubmit?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n store.handleFormSubmit(e).catch(() => {});\n opts?.afterSubmit?.(e);\n },\n method: \"post\",\n action: cartEndpoint,\n });\n\n const isPending = {\n initial: computed(() => loading.value),\n lines: (lineId?: string): boolean =>\n lineId ? pendingLines.value.has(lineId) : pendingLines.value.size > 0,\n };\n\n return { formProps, register, isPending };\n}\n\n/**\n * Factory that returns typed cart components and composables matched to your\n * server handler's cart query shape.\n *\n * The generic `THandlers` parameter is inferred from your `createCartServerHandlers`\n * call, so every composable's {@link CartState} carries your custom cart fields.\n *\n * @example\n * ```ts\n * import type { cartServerHandlers } from \"./server/cart.server\";\n *\n * const {\n * CartProvider,\n * useCart,\n * useOptionalCart,\n * useCartActions,\n * useCartForm,\n * } = createCartComponents<typeof cartServerHandlers>();\n * ```\n */\nexport function createCartComponents<THandlers>(): TypedCartComponents<\n CartDataFromHandlers<THandlers>\n> {\n type TData = CartDataFromHandlers<THandlers>;\n const TypedCartProvider = createTypedCartProvider<TData>();\n\n const useTypedCart = ((\n selector?: (state: CartState<TData>) => unknown,\n isEqual?: (a: unknown, b: unknown) => boolean,\n ) => {\n if (!selector) return useCart() as Readonly<ShallowRef<CartState<TData>>>;\n return useCart<TData, unknown>(selector, isEqual);\n }) as TypedUseCart<TData>;\n\n const useTypedOptionalCart = (<S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n ) => useOptionalCart<TData, S>(selector, isEqual)) as TypedUseOptionalCart<TData>;\n\n return {\n CartProvider: TypedCartProvider,\n useCart: useTypedCart,\n useOptionalCart: useTypedOptionalCart,\n useCartActions,\n useCartForm,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cart.mjs","names":[],"sources":["../../../src/vue/cart.ts"],"sourcesContent":["import {\n computed,\n defineComponent,\n h,\n inject,\n onMounted,\n onScopeDispose,\n onUnmounted,\n provide,\n shallowRef,\n type ComputedRef,\n type InjectionKey,\n type PropType,\n type ShallowRef,\n} from \"vue\";\n\nimport { trackCartAnalytics } from \"../core/analytics/cart-tracker\";\nimport {\n configureCartEndpoint as configureCoreCartEndpoint,\n createCartStore,\n type CreateCartStoreOptions,\n type CartActions,\n type CartStore,\n} from \"../core/cart/cart\";\nimport { createCartFormRegister, type CartFormRegister } from \"../core/cart/form\";\nimport type { CartDataFromHandlers } from \"../core/cart/server-handlers\";\nimport type { CartData, CartState } from \"../core/cart/state\";\n\nconst DEFAULT_CART_ENDPOINT = \"/api/cart\";\n\nlet cartEndpoint = DEFAULT_CART_ENDPOINT;\n\nconst CartStoreKey: InjectionKey<CartStore> = Symbol(\"CartStore\");\n\nexport function configureCartEndpoint(endpoint: string): void {\n cartEndpoint = endpoint;\n configureCoreCartEndpoint(endpoint);\n}\n\nexport function getCartEndpoint(): string {\n return cartEndpoint;\n}\n\ntype TypedUseCart<TData extends CartData> = {\n (): Readonly<ShallowRef<CartState<TData>>>;\n <S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n ): Readonly<ShallowRef<S>>;\n};\n\ntype TypedUseOptionalCart<TData extends CartData> = <S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n) => Readonly<ShallowRef<S | undefined>>;\n\ntype CartInitialData<TData extends CartData = CartData> =\n CreateCartStoreOptions<TData>[\"initialData\"];\n\ntype TypedCartProvider<TData extends CartData> = {\n new (): { $props: { initialData?: CartInitialData<TData> } };\n};\n\nexport type { CartActions };\n\n/** Cart provider and composables whose cart state carries the custom fields from your cart server handlers. */\ntype TypedCartComponents<TData extends CartData> = {\n /** The provider that creates the cart store. The provider connects the store on mount and destroys the store on unmount. */\n CartProvider: TypedCartProvider<TData>;\n /** Returns cart state as a read-only shallow ref. The selector is optional. Without a selector, the ref holds the full cart state. */\n useCart: TypedUseCart<TData>;\n /** Returns the slice of cart state that the selector picks as a read-only shallow ref. Outside the provider, the ref holds `undefined`. */\n useOptionalCart: TypedUseOptionalCart<TData>;\n /** Returns the `refresh` action. Call `refresh` after a server-side cart mutation that bypasses cart forms. */\n useCartActions: typeof useCartActions;\n /** Returns form props, a register function, and pending state for cart forms. */\n useCartForm: typeof useCartForm;\n};\n\nfunction createTypedCartProvider<TData extends CartData>(): TypedCartProvider<TData> {\n const TypedCartProvider = defineComponent(\n (props: { initialData?: CartInitialData<TData> }, { slots }) => {\n return () =>\n h(\n CartProvider,\n { initialData: props.initialData as CartInitialData | undefined },\n slots.default,\n );\n },\n { name: \"CartProvider\", props: [\"initialData\"] },\n );\n\n return TypedCartProvider as unknown as TypedCartProvider<TData>;\n}\n\nexport function useCartStore(composableName = \"useCartStore\"): CartStore {\n const store = inject(CartStoreKey, null);\n if (!store) {\n throw new Error(`${composableName} must be used inside a <CartProvider>.`);\n }\n return store;\n}\n\nfunction useOptionalCartStore(): CartStore | null {\n return inject(CartStoreKey, null);\n}\n\n/**\n * Creates a cart store and shares the store with the cart composables below the provider.\n *\n * The provider connects the store on mount and destroys the store on unmount. Render every cart composable inside the provider. The provider creates its store once from the first initial data and ignores later changes.\n *\n * @example\n * ```vue\n * <CartProvider :initialData=\"{ cart: loaderData.cart }\">\n * <App />\n * </CartProvider>\n * ```\n * @publicDocs\n */\nexport const CartProvider = defineComponent({\n name: \"CartProvider\",\n props: {\n initialData: {\n type: Object as PropType<CartInitialData>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n const store = createCartStore({ initialData: props.initialData });\n provide(CartStoreKey, store);\n\n onMounted(() => {\n configureCoreCartEndpoint(cartEndpoint);\n store.connect();\n });\n\n onUnmounted(() => {\n store.destroy();\n });\n\n return () => slots.default?.();\n },\n});\n\n/**\n * Returns cart state as a read-only shallow ref.\n *\n * Without a selector, the ref holds the full cart state. With a selector, the ref holds the selected value. The ref updates when the selected value changes by reference, or when your `isEqual` function reports a change.\n *\n * @example\n * ```vue\n * <script setup>\n * // Full state\n * const state = useCart();\n *\n * // Selected slice — re-renders only when lines change\n * const lines = useCart((s) => s.data.lines.nodes);\n *\n * // Check if a specific line is pending\n * const isPending = useCart((s) => s.pending.lines.has(lineId));\n * </script>\n * ```\n * @publicDocs\n */\nexport function useCart(): Readonly<ShallowRef<CartState>>;\nexport function useCart<TData extends CartData = CartData, S = unknown>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>>;\nexport function useCart<TData extends CartData = CartData, S = unknown>(\n selector?: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S | CartState>> {\n const store = useCartStore(\"useCart\");\n const resolve = selector ?? ((state: CartState<TData>) => state as unknown as S);\n return useCartSelector(store, resolve, isEqual) as Readonly<ShallowRef<S>>;\n}\n\n/**\n * Returns the cart action that syncs the cart after a mutation outside cart forms.\n *\n * Call `refresh` after a server-side cart mutation that bypasses cart forms, such as a server action that creates the cart.\n *\n * @returns The `refresh` action.\n *\n * @example\n * ```vue\n * <script setup>\n * const { refresh } = useCartActions();\n *\n * async function handleServerAction() {\n * await createCartOnServer();\n * refresh();\n * }\n * </script>\n * ```\n * @publicDocs\n */\nexport function useCartActions(): CartActions {\n const store = useCartStore(\"useCartActions\");\n return { refresh: store.refresh };\n}\n\n/**\n * Publishes cart analytics events when the cart changes.\n *\n * Call the composable once near the root of your app. The composable starts tracking on mount and stops when the component's scope ends. The composable throws when you call it outside the cart provider.\n *\n * @example\n * ```vue\n * <script setup>\n * useCartAnalytics();\n * </script>\n * ```\n * @publicDocs\n */\nexport function useCartAnalytics(): void {\n const store = useCartStore(\"useCartAnalytics\");\n let stopTracking: (() => void) | undefined;\n\n onMounted(() => {\n stopTracking = trackCartAnalytics(store);\n });\n\n onScopeDispose(() => stopTracking?.());\n}\n\n/**\n * Returns the slice of cart state that the selector picks as a read-only shallow ref. Outside the cart provider, the ref holds `undefined`.\n *\n * Use the composable in a component that also renders above the provider, such as a header cart badge on an error page.\n * Wherever the provider always exists, use the cart composable that throws. A missing provider then fails with an error.\n *\n * @example\n * ```vue\n * <script setup>\n * const count = useOptionalCart((state) => state.data.totalQuantity);\n * </script>\n *\n * <template>\n * <span v-if=\"count !== undefined\">Cart ({{ count }})</span>\n * </template>\n * ```\n * @publicDocs\n */\nexport function useOptionalCart<TData extends CartData = CartData, S = unknown>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S | undefined>> {\n const store = useOptionalCartStore();\n if (!store) return shallowRef<S | undefined>(undefined);\n return useCartSelector(store, selector, isEqual);\n}\n\nfunction useCartSelector<TData extends CartData = CartData, S = unknown>(\n store: CartStore,\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>> {\n const selected = shallowRef<S>(selector(store.getState() as CartState<TData>));\n\n const unsubscribe = store.subscribe(() => {\n const next = selector(store.getState() as CartState<TData>);\n if (isEqual?.(selected.value, next)) return;\n selected.value = next;\n });\n\n onScopeDispose(unsubscribe);\n\n return selected as Readonly<ShallowRef<S>>;\n}\n\n/**\n * Returns form props, a register function, and pending state for cart forms.\n *\n * The form props post to the cart endpoint and send each submission through the cart store. A `beforeSubmit` callback that prevents the event's default skips the cart submission.\n *\n * The pending state holds a computed ref that's `true` during a full cart load, and a function that checks whether one line or any line has a mutation in flight.\n *\n * Registering the quantity field with `interactive: true` returns numeric input attributes without auto-submit. Call attachQuantityInput on the input to submit the form when the quantity changes.\n *\n * @returns The form props function, the register function, and the pending state.\n *\n * @example\n * ```vue\n * <script setup>\n * const { formProps, register, isPending } = useCartForm();\n * </script>\n *\n * <template>\n * <form v-bind=\"formProps()\">\n * <input v-bind=\"register('lineId', { value: line.id })\" />\n * <input v-bind=\"register('quantity', { value: line.quantity })\" />\n * <button v-bind=\"register('set')\" />\n * <button v-bind=\"register('increase')\">+</button>\n * <button v-bind=\"register('decrease')\">−</button>\n * <span v-if=\"isPending.lines(line.id)\">Updating…</span>\n * </form>\n * </template>\n * ```\n * @publicDocs\n */\nexport function useCartForm(): {\n formProps: (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }) => Record<string, unknown>;\n register: CartFormRegister;\n isPending: {\n initial: ComputedRef<boolean>;\n lines: (lineId?: string) => boolean;\n };\n} {\n const store = useCartStore(\"useCartForm\");\n const loading = useCart((s) => s.loading);\n const pendingLines = useCart((s) => s.pending.lines);\n const register = createCartFormRegister();\n\n const formProps = (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }): Record<string, unknown> => ({\n onSubmit: (e: SubmitEvent) => {\n opts?.beforeSubmit?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n store.handleFormSubmit(e).catch(() => {});\n opts?.afterSubmit?.(e);\n },\n method: \"post\",\n action: cartEndpoint,\n });\n\n const isPending = {\n initial: computed(() => loading.value),\n lines: (lineId?: string): boolean =>\n lineId ? pendingLines.value.has(lineId) : pendingLines.value.size > 0,\n };\n\n return { formProps, register, isPending };\n}\n\n/**\n * Returns a cart provider and composables typed to the cart query in your cart server handlers.\n * Pass the type of your cart server handlers as the `THandlers` type argument. Every composable's cart state then includes your custom cart fields.\n *\n * On mount, the provider points cart requests at `/api/cart` and connects the store. Every composable except the optional cart composable throws when you call it outside the provider.\n *\n * @returns The typed cart provider, the cart state composables, and the cart actions and form composables.\n *\n * @example\n * ```ts\n * import type { cartServerHandlers } from \"./server/cart.server\";\n *\n * const {\n * CartProvider,\n * useCart,\n * useOptionalCart,\n * useCartActions,\n * useCartForm,\n * } = createCartComponents<typeof cartServerHandlers>();\n * ```\n * @publicDocs\n */\nexport function createCartComponents<THandlers>(): TypedCartComponents<\n CartDataFromHandlers<THandlers>\n> {\n type TData = CartDataFromHandlers<THandlers>;\n const TypedCartProvider = createTypedCartProvider<TData>();\n\n const useTypedCart = ((\n selector?: (state: CartState<TData>) => unknown,\n isEqual?: (a: unknown, b: unknown) => boolean,\n ) => {\n if (!selector) return useCart() as Readonly<ShallowRef<CartState<TData>>>;\n return useCart<TData, unknown>(selector, isEqual);\n }) as TypedUseCart<TData>;\n\n const useTypedOptionalCart = (<S>(\n selector: (state: CartState<TData>) => S,\n isEqual?: (a: S, b: S) => boolean,\n ) => useOptionalCart<TData, S>(selector, isEqual)) as TypedUseOptionalCart<TData>;\n\n return {\n CartProvider: TypedCartProvider,\n useCart: useTypedCart,\n useOptionalCart: useTypedOptionalCart,\n useCartActions,\n useCartForm,\n };\n}\n"],"mappings":";;;;;;AA8BA,IAAI,eAAe;AAEnB,MAAM,eAAwC,OAAO,YAAY;AAOjE,SAAgB,kBAA0B;AACxC,QAAO;;AAuCT,SAAS,0BAA4E;AAanF,QAZ0B,iBACvB,OAAiD,EAAE,YAAY;AAC9D,eACE,EACE,cACA,EAAE,aAAa,MAAM,aAA4C,EACjE,MAAM,QACP;IAEL;EAAE,MAAM;EAAgB,OAAO,CAAC,cAAc;EAAE,CAG1B;;AAG1B,SAAgB,aAAa,iBAAiB,gBAA2B;CACvE,MAAM,QAAQ,OAAO,cAAc,KAAK;AACxC,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,GAAG,eAAe,wCAAwC;AAE5E,QAAO;;AAGT,SAAS,uBAAyC;AAChD,QAAO,OAAO,cAAc,KAAK;;;;;;;;;;;;;;;AAgBnC,MAAa,eAAe,gBAAgB;CAC1C,MAAM;CACN,OAAO,EACL,aAAa;EACX,MAAM;EACN,SAAS;EACV,EACF;CACD,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,QAAQ,gBAAgB,EAAE,aAAa,MAAM,aAAa,CAAC;AACjE,UAAQ,cAAc,MAAM;AAE5B,kBAAgB;AACd,yBAA0B,aAAa;AACvC,SAAM,SAAS;IACf;AAEF,oBAAkB;AAChB,SAAM,SAAS;IACf;AAEF,eAAa,MAAM,WAAW;;CAEjC,CAAC;AA2BF,SAAgB,QACd,UACA,SACqC;AAGrC,QAAO,gBAFO,aAAa,UAEC,EADZ,cAAc,UAA4B,QACnB,QAAQ;;;;;;;;;;;;;;;;;;;;;;AAuBjD,SAAgB,iBAA8B;AAE5C,QAAO,EAAE,SADK,aAAa,iBACJ,CAAC,SAAS;;;;;;;;;;;;;;;AAgBnC,SAAgB,mBAAyB;CACvC,MAAM,QAAQ,aAAa,mBAAmB;CAC9C,IAAI;AAEJ,iBAAgB;AACd,iBAAe,mBAAmB,MAAM;GACxC;AAEF,sBAAqB,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;AAqBxC,SAAgB,gBACd,UACA,SACqC;CACrC,MAAM,QAAQ,sBAAsB;AACpC,KAAI,CAAC,MAAO,QAAO,WAA0B,OAAU;AACvD,QAAO,gBAAgB,OAAO,UAAU,QAAQ;;AAGlD,SAAS,gBACP,OACA,UACA,SACyB;CACzB,MAAM,WAAW,WAAc,SAAS,MAAM,UAAU,CAAqB,CAAC;AAQ9E,gBANoB,MAAM,gBAAgB;EACxC,MAAM,OAAO,SAAS,MAAM,UAAU,CAAqB;AAC3D,MAAI,UAAU,SAAS,OAAO,KAAK,CAAE;AACrC,WAAS,QAAQ;GAGO,CAAC;AAE3B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCT,SAAgB,cAUd;CACA,MAAM,QAAQ,aAAa,cAAc;CACzC,MAAM,UAAU,SAAS,MAAM,EAAE,QAAQ;CACzC,MAAM,eAAe,SAAS,MAAM,EAAE,QAAQ,MAAM;CACpD,MAAM,WAAW,wBAAwB;CAEzC,MAAM,aAAa,UAGa;EAC9B,WAAW,MAAmB;AAC5B,SAAM,eAAe,EAAE;AACvB,OAAI,EAAE,iBAAkB;AACxB,KAAE,gBAAgB;AAClB,SAAM,iBAAiB,EAAE,CAAC,YAAY,GAAG;AACzC,SAAM,cAAc,EAAE;;EAExB,QAAQ;EACR,QAAQ;EACT;AAQD,QAAO;EAAE;EAAW;EAAU;GAL5B,SAAS,eAAe,QAAQ,MAAM;GACtC,QAAQ,WACN,SAAS,aAAa,MAAM,IAAI,OAAO,GAAG,aAAa,MAAM,OAAO;GAGjC;EAAE;;;;;;;;;;;;;;;;;;;;;;;;AAyB3C,SAAgB,uBAEd;CAEA,MAAM,oBAAoB,yBAAgC;CAE1D,MAAM,iBACJ,UACA,YACG;AACH,MAAI,CAAC,SAAU,QAAO,SAAS;AAC/B,SAAO,QAAwB,UAAU,QAAQ;;CAGnD,MAAM,yBACJ,UACA,YACG,gBAA0B,UAAU,QAAQ;AAEjD,QAAO;EACL,cAAc;EACd,SAAS;EACT,iBAAiB;EACjB;EACA;EACD"}
|
|
@@ -5,9 +5,10 @@ import { PropType, ShallowRef } from "vue";
|
|
|
5
5
|
|
|
6
6
|
//#region src/vue/collection.d.ts
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Creates a collection store and keeps its filters and sort in sync with the URL.
|
|
9
|
+
* The provider creates a new store when the collection handle changes, such as on navigation to a different collection.
|
|
10
|
+
*
|
|
11
|
+
* The provider takes `data` and `url-search` props, emits a `change` event with the search string to navigate to, and renders its default slot.
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* ```vue
|
|
@@ -33,6 +34,7 @@ import { PropType, ShallowRef } from "vue";
|
|
|
33
34
|
* </CollectionProvider>
|
|
34
35
|
* </template>
|
|
35
36
|
* ```
|
|
37
|
+
* @publicDocs
|
|
36
38
|
*/
|
|
37
39
|
declare const CollectionProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
|
|
38
40
|
data: {
|
|
@@ -62,8 +64,7 @@ declare const CollectionProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
|
|
|
62
64
|
urlSearch: string;
|
|
63
65
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
|
|
64
66
|
/**
|
|
65
|
-
*
|
|
66
|
-
* state snapshot.
|
|
67
|
+
* Returns a read-only shallow ref of the collection state. The ref follows the new store when the provider replaces the store.
|
|
67
68
|
*
|
|
68
69
|
* @example
|
|
69
70
|
* ```vue
|
|
@@ -75,12 +76,12 @@ declare const CollectionProvider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
|
|
|
75
76
|
* <p>{{ state.status }}</p>
|
|
76
77
|
* </template>
|
|
77
78
|
* ```
|
|
79
|
+
* @publicDocs
|
|
78
80
|
*/
|
|
79
81
|
declare function useCollection(): Readonly<ShallowRef<CollectionState>>;
|
|
80
82
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* updates when the derived value is structurally unchanged.
|
|
83
|
+
* With a selector, the composable returns a ref of the selector's value.
|
|
84
|
+
* Pass an `isEqual` comparator to skip updates for equal values. The composable throws outside the collection provider.
|
|
84
85
|
*
|
|
85
86
|
* @example
|
|
86
87
|
* ```vue
|
|
@@ -88,16 +89,22 @@ declare function useCollection(): Readonly<ShallowRef<CollectionState>>;
|
|
|
88
89
|
* const status = useCollection(s => s.status);
|
|
89
90
|
* </script>
|
|
90
91
|
* ```
|
|
92
|
+
* @publicDocs
|
|
91
93
|
*/
|
|
92
94
|
declare function useCollection<S>(selector: (state: CollectionState) => S, isEqual?: (a: S, b: S) => boolean): Readonly<ShallowRef<S>>;
|
|
93
95
|
/**
|
|
94
|
-
* Returns methods that change filters and sort.
|
|
95
|
-
*
|
|
96
|
-
*
|
|
96
|
+
* Returns methods that change filters and sort. After each change, the collection provider emits a `change` event with the new search string.
|
|
97
|
+
*
|
|
98
|
+
* The composable throws outside the collection provider.
|
|
99
|
+
*
|
|
100
|
+
* @publicDocs
|
|
97
101
|
*/
|
|
98
102
|
declare function useCollectionActions(): CollectionActions;
|
|
99
103
|
/**
|
|
100
|
-
* Returns form props
|
|
104
|
+
* Returns form props that progressively enhance collection filter forms.
|
|
105
|
+
*
|
|
106
|
+
* Bind the result of `formProps()` on the form. Its submit handler cancels the native submission and applies the form's filter and sort fields to the store.
|
|
107
|
+
* The `beforeSubmit` and `afterSubmit` callbacks receive the native submit event. The composable throws outside the collection provider.
|
|
101
108
|
*
|
|
102
109
|
* @example
|
|
103
110
|
* ```vue
|
|
@@ -112,6 +119,7 @@ declare function useCollectionActions(): CollectionActions;
|
|
|
112
119
|
* </form>
|
|
113
120
|
* </template>
|
|
114
121
|
* ```
|
|
122
|
+
* @publicDocs
|
|
115
123
|
*/
|
|
116
124
|
declare function useCollectionForm(): {
|
|
117
125
|
formProps: (opts?: {
|
|
@@ -5,9 +5,10 @@ import { defineComponent, inject, onUnmounted, provide, shallowRef, toValue, wat
|
|
|
5
5
|
//#region src/vue/collection.ts
|
|
6
6
|
const CollectionStoreKey = Symbol("CollectionStore");
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Creates a collection store and keeps its filters and sort in sync with the URL.
|
|
9
|
+
* The provider creates a new store when the collection handle changes, such as on navigation to a different collection.
|
|
10
|
+
*
|
|
11
|
+
* The provider takes `data` and `url-search` props, emits a `change` event with the search string to navigate to, and renders its default slot.
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* ```vue
|
|
@@ -33,6 +34,7 @@ const CollectionStoreKey = Symbol("CollectionStore");
|
|
|
33
34
|
* </CollectionProvider>
|
|
34
35
|
* </template>
|
|
35
36
|
* ```
|
|
37
|
+
* @publicDocs
|
|
36
38
|
*/
|
|
37
39
|
const CollectionProvider = defineComponent({
|
|
38
40
|
name: "CollectionProvider",
|
|
@@ -110,9 +112,11 @@ function useCollection(selector, isEqual) {
|
|
|
110
112
|
return selected;
|
|
111
113
|
}
|
|
112
114
|
/**
|
|
113
|
-
* Returns methods that change filters and sort.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
115
|
+
* Returns methods that change filters and sort. After each change, the collection provider emits a `change` event with the new search string.
|
|
116
|
+
*
|
|
117
|
+
* The composable throws outside the collection provider.
|
|
118
|
+
*
|
|
119
|
+
* @publicDocs
|
|
116
120
|
*/
|
|
117
121
|
function useCollectionActions() {
|
|
118
122
|
const storeRef = useRequiredStoreRef("useCollectionActions");
|
|
@@ -127,7 +131,10 @@ function useCollectionActions() {
|
|
|
127
131
|
};
|
|
128
132
|
}
|
|
129
133
|
/**
|
|
130
|
-
* Returns form props
|
|
134
|
+
* Returns form props that progressively enhance collection filter forms.
|
|
135
|
+
*
|
|
136
|
+
* Bind the result of `formProps()` on the form. Its submit handler cancels the native submission and applies the form's filter and sort fields to the store.
|
|
137
|
+
* The `beforeSubmit` and `afterSubmit` callbacks receive the native submit event. The composable throws outside the collection provider.
|
|
131
138
|
*
|
|
132
139
|
* @example
|
|
133
140
|
* ```vue
|
|
@@ -142,6 +149,7 @@ function useCollectionActions() {
|
|
|
142
149
|
* </form>
|
|
143
150
|
* </template>
|
|
144
151
|
* ```
|
|
152
|
+
* @publicDocs
|
|
145
153
|
*/
|
|
146
154
|
function useCollectionForm() {
|
|
147
155
|
const actions = useCollectionActions();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.mjs","names":[],"sources":["../../../src/vue/collection.ts"],"sourcesContent":["import {\n defineComponent,\n inject,\n onUnmounted,\n provide,\n shallowRef,\n toValue,\n watch,\n type InjectionKey,\n type PropType,\n type ShallowRef,\n} from \"vue\";\n\nimport {\n createCollectionStore,\n createCollectionReconciler,\n type CollectionActions,\n type CollectionData,\n type CollectionReconciler,\n type CollectionStore,\n} from \"../core/collection\";\nimport type { CollectionState } from \"../core/collection\";\n\nexport type { CollectionActions, CollectionData };\n\nconst CollectionStoreKey: InjectionKey<ShallowRef<CollectionStore>> = Symbol(\"CollectionStore\");\n\n/**\n * Manages the lifecycle of a {@link CollectionStore}: creates on mount and syncs\n * with URL changes. Recreates the store when `data.handle` changes\n * (navigating to a different collection).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { CollectionProvider, type CollectionData } from '@shopify/hydrogen/vue';\n * import { useRoute, useRouter } from 'vue-router';\n *\n * const props = defineProps<{ data: CollectionData; urlSearch: string }>();\n * const route = useRoute();\n * const router = useRouter();\n *\n * // `search` includes the leading `?`, so append it to the path as-is.\n * const onChange = (search: string) => router.replace(`${route.path}${search}`);\n * </script>\n *\n * <template>\n * <CollectionProvider\n * :data=\"props.data\"\n * :url-search=\"props.urlSearch\"\n * @change=\"onChange\"\n * >\n * <slot />\n * </CollectionProvider>\n * </template>\n * ```\n */\nexport const CollectionProvider = defineComponent({\n name: \"CollectionProvider\",\n props: {\n data: {\n type: Object as PropType<CollectionData>,\n required: true,\n },\n urlSearch: {\n type: String,\n default: \"\",\n },\n },\n emits: {\n change: (searchString: string) => typeof searchString === \"string\",\n },\n setup(props, { slots, emit }) {\n const readUrlSearch = () => toValue(props.urlSearch);\n\n const initialStore = createCollectionStore({\n data: props.data,\n urlSearch: readUrlSearch(),\n });\n const storeRef = shallowRef<CollectionStore>(initialStore);\n provide(CollectionStoreKey, storeRef);\n\n let reconciler: CollectionReconciler = createCollectionReconciler(\n {\n getStore: () => storeRef.value,\n readUrlSearch,\n emitChange: (s) => emit(\"change\", s),\n },\n readUrlSearch(),\n );\n initialStore.setOnBrowseChange(() => reconciler.handleBrowseChange());\n\n function resetStore() {\n storeRef.value.setOnBrowseChange(null);\n const store = createCollectionStore({\n data: props.data,\n urlSearch: readUrlSearch(),\n });\n storeRef.value = store;\n reconciler.reset(readUrlSearch());\n store.setOnBrowseChange(() => reconciler.handleBrowseChange());\n }\n\n watch(\n () => props.data.handle,\n (newHandle, oldHandle) => {\n if (newHandle === oldHandle) return;\n resetStore();\n },\n );\n\n watch(\n () => [readUrlSearch(), props.data] as const,\n () => {\n reconciler.reconcile(readUrlSearch(), props.data.dataSearch);\n },\n { flush: \"sync\", immediate: true, deep: true },\n );\n\n onUnmounted(() => {\n storeRef.value.setOnBrowseChange(null);\n });\n\n return () => slots.default?.();\n },\n});\n\nfunction useRequiredStoreRef(composableName: string): ShallowRef<CollectionStore> {\n const storeRef = inject(CollectionStoreKey, null);\n if (!storeRef) {\n throw new Error(`${composableName} must be used inside a <CollectionProvider>.`);\n }\n return storeRef;\n}\n\n/**\n * Subscribes to the collection store and returns a reactive ref of the full\n * state snapshot.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const state = useCollection();\n * </script>\n *\n * <template>\n * <p>{{ state.status }}</p>\n * </template>\n * ```\n */\nexport function useCollection(): Readonly<ShallowRef<CollectionState>>;\n/**\n * Subscribes to the collection store and returns a reactive ref of a derived\n * value via `selector`. Optionally accepts an `isEqual` comparator to skip\n * updates when the derived value is structurally unchanged.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const status = useCollection(s => s.status);\n * </script>\n * ```\n */\nexport function useCollection<S>(\n selector: (state: CollectionState) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>>;\nexport function useCollection<S>(\n selector?: (state: CollectionState) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<CollectionState | S>> {\n const storeRef = useRequiredStoreRef(\"useCollection\");\n const resolve = selector ?? ((state: CollectionState) => state as unknown as S);\n const selected = shallowRef<CollectionState | S>(resolve(storeRef.value.getState()));\n\n watch(\n () => storeRef.value,\n (store, _, onCleanup) => {\n selected.value = resolve(store.getState());\n\n const unsubscribe = store.subscribe(() => {\n const next = resolve(store.getState());\n if (isEqual && selector) {\n if (isEqual(selected.value as S, next)) return;\n }\n selected.value = next;\n });\n\n onCleanup(unsubscribe);\n },\n { immediate: true },\n );\n\n return selected as Readonly<ShallowRef<CollectionState | S>>;\n}\n\n/**\n * Returns methods that change filters and sort. The store's `onBrowseChange`\n * callback (set by {@link CollectionProvider}) handles emitting `change` with a\n * serialized search string.\n */\nexport function useCollectionActions(): CollectionActions {\n const storeRef = useRequiredStoreRef(\"useCollectionActions\");\n\n return {\n setFilters: (...args) => storeRef.value.setFilters(...args),\n toggleFilter: (...args) => storeRef.value.toggleFilter(...args),\n toggleFilterInput: (...args) => storeRef.value.toggleFilterInput(...args),\n setSortKey: (...args) => storeRef.value.setSortKey(...args),\n setSortByValue: (...args) => storeRef.value.setSortByValue(...args),\n reset: (...args) => storeRef.value.reset(...args),\n handleFormSubmit: (...args) => storeRef.value.handleFormSubmit(...args),\n };\n}\n\n/**\n * Returns form props for progressive-enhancement of collection filter forms.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const { formProps } = useCollectionForm();\n * </script>\n *\n * <template>\n * <form v-bind=\"formProps()\" action=\"/collections/shoes\">\n * <input type=\"checkbox\" name=\"filter.p.tag\" value=\"sale\" />\n * <button type=\"submit\">Apply</button>\n * </form>\n * </template>\n * ```\n */\nexport function useCollectionForm(): {\n formProps: (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }) => Record<string, unknown>;\n} {\n const actions = useCollectionActions();\n\n const formProps = (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }): Record<string, unknown> => ({\n onSubmit: (e: SubmitEvent) => {\n opts?.beforeSubmit?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n actions.handleFormSubmit(e);\n opts?.afterSubmit?.(e);\n },\n });\n\n return { formProps };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collection.mjs","names":[],"sources":["../../../src/vue/collection.ts"],"sourcesContent":["import {\n defineComponent,\n inject,\n onUnmounted,\n provide,\n shallowRef,\n toValue,\n watch,\n type InjectionKey,\n type PropType,\n type ShallowRef,\n} from \"vue\";\n\nimport {\n createCollectionStore,\n createCollectionReconciler,\n type CollectionActions,\n type CollectionData,\n type CollectionReconciler,\n type CollectionStore,\n} from \"../core/collection\";\nimport type { CollectionState } from \"../core/collection\";\n\nexport type { CollectionActions, CollectionData };\n\nconst CollectionStoreKey: InjectionKey<ShallowRef<CollectionStore>> = Symbol(\"CollectionStore\");\n\n/**\n * Creates a collection store and keeps its filters and sort in sync with the URL.\n * The provider creates a new store when the collection handle changes, such as on navigation to a different collection.\n *\n * The provider takes `data` and `url-search` props, emits a `change` event with the search string to navigate to, and renders its default slot.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { CollectionProvider, type CollectionData } from '@shopify/hydrogen/vue';\n * import { useRoute, useRouter } from 'vue-router';\n *\n * const props = defineProps<{ data: CollectionData; urlSearch: string }>();\n * const route = useRoute();\n * const router = useRouter();\n *\n * // `search` includes the leading `?`, so append it to the path as-is.\n * const onChange = (search: string) => router.replace(`${route.path}${search}`);\n * </script>\n *\n * <template>\n * <CollectionProvider\n * :data=\"props.data\"\n * :url-search=\"props.urlSearch\"\n * @change=\"onChange\"\n * >\n * <slot />\n * </CollectionProvider>\n * </template>\n * ```\n * @publicDocs\n */\nexport const CollectionProvider = defineComponent({\n name: \"CollectionProvider\",\n props: {\n data: {\n type: Object as PropType<CollectionData>,\n required: true,\n },\n urlSearch: {\n type: String,\n default: \"\",\n },\n },\n emits: {\n change: (searchString: string) => typeof searchString === \"string\",\n },\n setup(props, { slots, emit }) {\n const readUrlSearch = () => toValue(props.urlSearch);\n\n const initialStore = createCollectionStore({\n data: props.data,\n urlSearch: readUrlSearch(),\n });\n const storeRef = shallowRef<CollectionStore>(initialStore);\n provide(CollectionStoreKey, storeRef);\n\n let reconciler: CollectionReconciler = createCollectionReconciler(\n {\n getStore: () => storeRef.value,\n readUrlSearch,\n emitChange: (s) => emit(\"change\", s),\n },\n readUrlSearch(),\n );\n initialStore.setOnBrowseChange(() => reconciler.handleBrowseChange());\n\n function resetStore() {\n storeRef.value.setOnBrowseChange(null);\n const store = createCollectionStore({\n data: props.data,\n urlSearch: readUrlSearch(),\n });\n storeRef.value = store;\n reconciler.reset(readUrlSearch());\n store.setOnBrowseChange(() => reconciler.handleBrowseChange());\n }\n\n watch(\n () => props.data.handle,\n (newHandle, oldHandle) => {\n if (newHandle === oldHandle) return;\n resetStore();\n },\n );\n\n watch(\n () => [readUrlSearch(), props.data] as const,\n () => {\n reconciler.reconcile(readUrlSearch(), props.data.dataSearch);\n },\n { flush: \"sync\", immediate: true, deep: true },\n );\n\n onUnmounted(() => {\n storeRef.value.setOnBrowseChange(null);\n });\n\n return () => slots.default?.();\n },\n});\n\nfunction useRequiredStoreRef(composableName: string): ShallowRef<CollectionStore> {\n const storeRef = inject(CollectionStoreKey, null);\n if (!storeRef) {\n throw new Error(`${composableName} must be used inside a <CollectionProvider>.`);\n }\n return storeRef;\n}\n\n/**\n * Returns a read-only shallow ref of the collection state. The ref follows the new store when the provider replaces the store.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const state = useCollection();\n * </script>\n *\n * <template>\n * <p>{{ state.status }}</p>\n * </template>\n * ```\n * @publicDocs\n */\nexport function useCollection(): Readonly<ShallowRef<CollectionState>>;\n/**\n * With a selector, the composable returns a ref of the selector's value.\n * Pass an `isEqual` comparator to skip updates for equal values. The composable throws outside the collection provider.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const status = useCollection(s => s.status);\n * </script>\n * ```\n * @publicDocs\n */\nexport function useCollection<S>(\n selector: (state: CollectionState) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<S>>;\nexport function useCollection<S>(\n selector?: (state: CollectionState) => S,\n isEqual?: (a: S, b: S) => boolean,\n): Readonly<ShallowRef<CollectionState | S>> {\n const storeRef = useRequiredStoreRef(\"useCollection\");\n const resolve = selector ?? ((state: CollectionState) => state as unknown as S);\n const selected = shallowRef<CollectionState | S>(resolve(storeRef.value.getState()));\n\n watch(\n () => storeRef.value,\n (store, _, onCleanup) => {\n selected.value = resolve(store.getState());\n\n const unsubscribe = store.subscribe(() => {\n const next = resolve(store.getState());\n if (isEqual && selector) {\n if (isEqual(selected.value as S, next)) return;\n }\n selected.value = next;\n });\n\n onCleanup(unsubscribe);\n },\n { immediate: true },\n );\n\n return selected as Readonly<ShallowRef<CollectionState | S>>;\n}\n\n/**\n * Returns methods that change filters and sort. After each change, the collection provider emits a `change` event with the new search string.\n *\n * The composable throws outside the collection provider.\n *\n * @publicDocs\n */\nexport function useCollectionActions(): CollectionActions {\n const storeRef = useRequiredStoreRef(\"useCollectionActions\");\n\n return {\n setFilters: (...args) => storeRef.value.setFilters(...args),\n toggleFilter: (...args) => storeRef.value.toggleFilter(...args),\n toggleFilterInput: (...args) => storeRef.value.toggleFilterInput(...args),\n setSortKey: (...args) => storeRef.value.setSortKey(...args),\n setSortByValue: (...args) => storeRef.value.setSortByValue(...args),\n reset: (...args) => storeRef.value.reset(...args),\n handleFormSubmit: (...args) => storeRef.value.handleFormSubmit(...args),\n };\n}\n\n/**\n * Returns form props that progressively enhance collection filter forms.\n *\n * Bind the result of `formProps()` on the form. Its submit handler cancels the native submission and applies the form's filter and sort fields to the store.\n * The `beforeSubmit` and `afterSubmit` callbacks receive the native submit event. The composable throws outside the collection provider.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * const { formProps } = useCollectionForm();\n * </script>\n *\n * <template>\n * <form v-bind=\"formProps()\" action=\"/collections/shoes\">\n * <input type=\"checkbox\" name=\"filter.p.tag\" value=\"sale\" />\n * <button type=\"submit\">Apply</button>\n * </form>\n * </template>\n * ```\n * @publicDocs\n */\nexport function useCollectionForm(): {\n formProps: (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }) => Record<string, unknown>;\n} {\n const actions = useCollectionActions();\n\n const formProps = (opts?: {\n beforeSubmit?: (e: SubmitEvent) => void;\n afterSubmit?: (e: SubmitEvent) => void;\n }): Record<string, unknown> => ({\n onSubmit: (e: SubmitEvent) => {\n opts?.beforeSubmit?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n actions.handleFormSubmit(e);\n opts?.afterSubmit?.(e);\n },\n });\n\n return { formProps };\n}\n"],"mappings":"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"}
|
|
@@ -4,10 +4,10 @@ import { CollectionActions, CollectionData } from "../core/collection/collection
|
|
|
4
4
|
import { ValidProductSelectionResult } from "../core/product/product-form.mjs";
|
|
5
5
|
import { ProductAddToCartProps, ProductFormRegister, ProductMerchandiseIdProps, ProductOptionValueProps, ProductQuantityDefaultProps, ProductQuantityProps } from "../core/product/form.mjs";
|
|
6
6
|
import { PredictiveSearchActions } from "../core/predictive-search/store.mjs";
|
|
7
|
-
import { createCartComponents,
|
|
7
|
+
import { createCartComponents, useCartAnalytics } from "./cart.mjs";
|
|
8
8
|
import { CollectionProvider, useCollection, useCollectionActions, useCollectionForm } from "./collection.mjs";
|
|
9
9
|
import { PredictiveSearchFormPropsOptions, PredictiveSearchFormResult, PredictiveSearchProvider, PredictiveSearchQueryInputPropsOptions, usePredictiveSearch, usePredictiveSearchActions, usePredictiveSearchForm } from "./predictive-search.mjs";
|
|
10
10
|
import { UseProductFormOptions, UseProductFormResult, UseProductResult, createProductComponents, useProductForm } from "./product.mjs";
|
|
11
11
|
import { ShopPayButton, ShopPayButtonProps } from "./shop-pay.mjs";
|
|
12
12
|
import { ShopifyScripts, ShopifyScriptsProps } from "./shopify-scripts.mjs";
|
|
13
|
-
export { type CartActions, type CollectionActions, type CollectionData, CollectionProvider, type PredictiveSearchActions, type PredictiveSearchFormPropsOptions, type PredictiveSearchFormResult, PredictiveSearchProvider, type PredictiveSearchQueryInputPropsOptions, type ProductAddToCartProps, type ProductFormRegister, type ProductMerchandiseIdProps, type ProductOptionValueProps, type ProductQuantityDefaultProps, type ProductQuantityProps, ShopPayButton, type ShopPayButtonProps, type ShopifyGlobal, ShopifyScripts, type ShopifyScriptsProps, type UseProductFormOptions, type UseProductFormResult, type UseProductResult, type ValidProductSelectionResult, createCartComponents, createProductComponents,
|
|
13
|
+
export { type CartActions, type CollectionActions, type CollectionData, CollectionProvider, type PredictiveSearchActions, type PredictiveSearchFormPropsOptions, type PredictiveSearchFormResult, PredictiveSearchProvider, type PredictiveSearchQueryInputPropsOptions, type ProductAddToCartProps, type ProductFormRegister, type ProductMerchandiseIdProps, type ProductOptionValueProps, type ProductQuantityDefaultProps, type ProductQuantityProps, ShopPayButton, type ShopPayButtonProps, type ShopifyGlobal, ShopifyScripts, type ShopifyScriptsProps, type UseProductFormOptions, type UseProductFormResult, type UseProductResult, type ValidProductSelectionResult, createCartComponents, createProductComponents, useCartAnalytics, useCollection, useCollectionActions, useCollectionForm, usePredictiveSearch, usePredictiveSearchActions, usePredictiveSearchForm, useProductForm };
|