@abconvert/headless 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,7 +25,7 @@ The package has no runtime dependencies. React, Next.js, and Hydrogen are option
25
25
  |---|---|
26
26
  | `@abconvert/headless` | The client for any server, edge runtime, or browser. Start here on a stack that is not listed below. |
27
27
  | `@abconvert/headless/react` | `ABConvertProvider` and the `useABConvert` hook for a React app. |
28
- | `@abconvert/headless/next` | Next.js 14 and later: the middleware that assigns before the page renders, and the client for your server components. |
28
+ | `@abconvert/headless/next` | Next.js 14.2.10 and later 14.2 releases, 15.1 to 15.4, and 16: the middleware that assigns before the page renders, and the client for your server components. |
29
29
  | `@abconvert/headless/hydrogen` | Hydrogen 2026.10 and later. Tracks from Hydrogen's analytics and waits for the visitor's consent. |
30
30
  | `@abconvert/headless/hydrogen/analytics-provider` | Hydrogen before 2026.10, where your app renders `<Analytics.Provider>`. |
31
31
 
@@ -1 +1 @@
1
- var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var analytics_provider_exports={};__export(analytics_provider_exports,{ABConvertProvider:()=>ABConvertProvider,createABConvert:()=>createABConvert,keepPrivateWhenTested:()=>keepPrivateWhenTested,useABConvert:()=>import_react3.useABConvert});module.exports=__toCommonJS(analytics_provider_exports);var import_hydrogen=require("@shopify/hydrogen");var import_react=require("react"),import_headless=require("@abconvert/headless"),import_react2=require("@abconvert/headless/react");async function createABConvert(options){return(await(0,import_headless.openClient)({...options,expectCustomerPrivacy:!0},{write:"changed"})).client}var PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect2,warning){function HydrogenEvents(){let{track}=(0,import_react2.useABConvert)(),connect=useConnect2();return(0,import_react.useEffect)(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return(0,import_react.createElement)(import_react2.ABConvertProvider,{...props,expectCustomerPrivacy:!0},(0,import_react.createElement)(HydrogenEvents),props.children)}}var import_react3=require("@abconvert/headless/react");function useConnect(){let{subscribe}=(0,import_hydrogen.useAnalytics)();return track=>subscribe.length<2?!1:(subscribeTo(subscribe,track),!0)}var ABConvertProvider=hydrogenProvider(useConnect,"[ABConvert] <ABConvertProvider> is outside <Analytics.Provider>, so page views, product views and add to cart are not tracked. Render it inside, or on Hydrogen 2026.10 and later import from @abconvert/headless/hydrogen.");
1
+ var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var analytics_provider_exports={};__export(analytics_provider_exports,{ABConvertProvider:()=>ABConvertProvider,createABConvert:()=>createABConvert,keepPrivateWhenTested:()=>keepPrivateWhenTested,useABConvert:()=>import_react3.useABConvert});module.exports=__toCommonJS(analytics_provider_exports);var import_hydrogen=require("@shopify/hydrogen");var import_react=require("react"),import_headless=require("@abconvert/headless"),import_react2=require("@abconvert/headless/react");async function createABConvert(options){let{client,cacheFacts}=await(0,import_headless.openClient)({...options,expectCustomerPrivacy:!0},{write:"changed"});return cacheFacts().loaded||withoutTests.add(client),client}var withoutTests=new WeakSet,PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!withoutTests.has(client)&&!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect2,warning){function HydrogenEvents(){let{track}=(0,import_react2.useABConvert)(),connect=useConnect2();return(0,import_react.useEffect)(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return(0,import_react.createElement)(import_react2.ABConvertProvider,{...props,expectCustomerPrivacy:!0},(0,import_react.createElement)(HydrogenEvents),props.children)}}var import_react3=require("@abconvert/headless/react");function useConnect(){let{subscribe}=(0,import_hydrogen.useAnalytics)();return track=>subscribe.length<2?!1:(subscribeTo(subscribe,track),!0)}var ABConvertProvider=hydrogenProvider(useConnect,"[ABConvert] <ABConvertProvider> is outside <Analytics.Provider>, so page views, product views and add to cart are not tracked. Render it inside, or on Hydrogen 2026.10 and later import from @abconvert/headless/hydrogen.");
@@ -8,5 +8,5 @@ export type HydrogenProviderProps = Omit<ABConvertProviderProps, 'expectCustomer
8
8
  export declare const ABConvertProvider: (props: HydrogenProviderProps) => ReactElement;
9
9
  /** The core client for your loaders. It tracks nothing until Shopify's Customer Privacy API holds the visitor's answer, and sets a cookie only when one changed. */
10
10
  export declare function createABConvert(options: Omit<ABConvertOptions, 'expectCustomerPrivacy'> & { request: RequestLike }): Promise<ServerABConvert>;
11
- /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), or when the response sets a cookie. True when it changed a header. */
11
+ /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), when the response sets a cookie, or when the client could not load the tests. True when it changed a header. */
12
12
  export declare function keepPrivateWhenTested(headers: Headers, client: Pick<ServerABConvert, 'isPageTested' | 'getSetCookieHeaders'>): boolean;
@@ -8,5 +8,5 @@ export type HydrogenProviderProps = Omit<ABConvertProviderProps, 'expectCustomer
8
8
  export declare const ABConvertProvider: (props: HydrogenProviderProps) => ReactElement;
9
9
  /** The core client for your loaders. It tracks nothing until Shopify's Customer Privacy API holds the visitor's answer, and sets a cookie only when one changed. */
10
10
  export declare function createABConvert(options: Omit<ABConvertOptions, 'expectCustomerPrivacy'> & { request: RequestLike }): Promise<ServerABConvert>;
11
- /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), or when the response sets a cookie. True when it changed a header. */
11
+ /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), when the response sets a cookie, or when the client could not load the tests. True when it changed a header. */
12
12
  export declare function keepPrivateWhenTested(headers: Headers, client: Pick<ServerABConvert, 'isPageTested' | 'getSetCookieHeaders'>): boolean;
@@ -1 +1 @@
1
- import{useAnalytics}from"@shopify/hydrogen";import{createElement,useEffect}from"react";import{openClient}from"@abconvert/headless";import{ABConvertProvider as ReactProvider,useABConvert}from"@abconvert/headless/react";async function createABConvert(options){return(await openClient({...options,expectCustomerPrivacy:!0},{write:"changed"})).client}var PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect2,warning){function HydrogenEvents(){let{track}=useABConvert(),connect=useConnect2();return useEffect(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return createElement(ReactProvider,{...props,expectCustomerPrivacy:!0},createElement(HydrogenEvents),props.children)}}import{useABConvert as useABConvert2}from"@abconvert/headless/react";function useConnect(){let{subscribe}=useAnalytics();return track=>subscribe.length<2?!1:(subscribeTo(subscribe,track),!0)}var ABConvertProvider=hydrogenProvider(useConnect,"[ABConvert] <ABConvertProvider> is outside <Analytics.Provider>, so page views, product views and add to cart are not tracked. Render it inside, or on Hydrogen 2026.10 and later import from @abconvert/headless/hydrogen.");export{ABConvertProvider,createABConvert,keepPrivateWhenTested,useABConvert2 as useABConvert};
1
+ import{useAnalytics}from"@shopify/hydrogen";import{createElement,useEffect}from"react";import{openClient}from"@abconvert/headless";import{ABConvertProvider as ReactProvider,useABConvert}from"@abconvert/headless/react";async function createABConvert(options){let{client,cacheFacts}=await openClient({...options,expectCustomerPrivacy:!0},{write:"changed"});return cacheFacts().loaded||withoutTests.add(client),client}var withoutTests=new WeakSet,PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!withoutTests.has(client)&&!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect2,warning){function HydrogenEvents(){let{track}=useABConvert(),connect=useConnect2();return useEffect(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return createElement(ReactProvider,{...props,expectCustomerPrivacy:!0},createElement(HydrogenEvents),props.children)}}import{useABConvert as useABConvert2}from"@abconvert/headless/react";function useConnect(){let{subscribe}=useAnalytics();return track=>subscribe.length<2?!1:(subscribeTo(subscribe,track),!0)}var ABConvertProvider=hydrogenProvider(useConnect,"[ABConvert] <ABConvertProvider> is outside <Analytics.Provider>, so page views, product views and add to cart are not tracked. Render it inside, or on Hydrogen 2026.10 and later import from @abconvert/headless/hydrogen.");export{ABConvertProvider,createABConvert,keepPrivateWhenTested,useABConvert2 as useABConvert};
package/dist/hydrogen.cjs CHANGED
@@ -1 +1 @@
1
- var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var index_exports={};__export(index_exports,{ABConvertProvider:()=>ABConvertProvider,createABConvert:()=>createABConvert,keepPrivateWhenTested:()=>keepPrivateWhenTested,useABConvert:()=>import_react3.useABConvert});module.exports=__toCommonJS(index_exports);var globals=()=>globalThis;function attempt(read,fallback){try{return read()??fallback}catch{return fallback}}function shopifyAnalytics(){return attempt(()=>{let bus=globals().Shopify?.analytics;return typeof bus?.addDestination=="function"?bus:null},null)}var import_react=require("react"),import_headless=require("@abconvert/headless"),import_react2=require("@abconvert/headless/react");async function createABConvert(options){return(await(0,import_headless.openClient)({...options,expectCustomerPrivacy:!0},{write:"changed"})).client}var PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect,warning){function HydrogenEvents(){let{track}=(0,import_react2.useABConvert)(),connect=useConnect();return(0,import_react.useEffect)(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return(0,import_react.createElement)(import_react2.ABConvertProvider,{...props,expectCustomerPrivacy:!0},(0,import_react.createElement)(HydrogenEvents),props.children)}}var import_react3=require("@abconvert/headless/react"),connectBus=()=>track=>{let bus=shopifyAnalytics();return bus?.addDestination({name:"abconvert",setup:({subscribe})=>subscribeTo(subscribe,track)}),bus!==null},ABConvertProvider=hydrogenProvider(connectBus,"[ABConvert] No Hydrogen analytics bus on this page, so page views, product views and add to cart are not tracked. Render <ShopifyScripts> above <ABConvertProvider>, or on Hydrogen 2026.4 and earlier import from @abconvert/headless/hydrogen/analytics-provider.");
1
+ var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var index_exports={};__export(index_exports,{ABConvertProvider:()=>ABConvertProvider,createABConvert:()=>createABConvert,keepPrivateWhenTested:()=>keepPrivateWhenTested,useABConvert:()=>import_react3.useABConvert});module.exports=__toCommonJS(index_exports);var globals=()=>globalThis;function attempt(read,fallback){try{return read()??fallback}catch{return fallback}}function shopifyAnalytics(){return attempt(()=>{let bus=globals().Shopify?.analytics;return typeof bus?.addDestination=="function"?bus:null},null)}var import_react=require("react"),import_headless=require("@abconvert/headless"),import_react2=require("@abconvert/headless/react");async function createABConvert(options){let{client,cacheFacts}=await(0,import_headless.openClient)({...options,expectCustomerPrivacy:!0},{write:"changed"});return cacheFacts().loaded||withoutTests.add(client),client}var withoutTests=new WeakSet,PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!withoutTests.has(client)&&!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect,warning){function HydrogenEvents(){let{track}=(0,import_react2.useABConvert)(),connect=useConnect();return(0,import_react.useEffect)(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return(0,import_react.createElement)(import_react2.ABConvertProvider,{...props,expectCustomerPrivacy:!0},(0,import_react.createElement)(HydrogenEvents),props.children)}}var import_react3=require("@abconvert/headless/react"),connectBus=()=>track=>{let bus=shopifyAnalytics();return bus?.addDestination({name:"abconvert",setup:({subscribe})=>subscribeTo(subscribe,track)}),bus!==null},ABConvertProvider=hydrogenProvider(connectBus,"[ABConvert] No Hydrogen analytics bus on this page, so page views, product views and add to cart are not tracked. Render <ShopifyScripts> above <ABConvertProvider>, or on Hydrogen 2026.4 and earlier import from @abconvert/headless/hydrogen/analytics-provider.");
@@ -8,5 +8,5 @@ export type HydrogenProviderProps = Omit<ABConvertProviderProps, 'expectCustomer
8
8
  export declare const ABConvertProvider: (props: HydrogenProviderProps) => ReactElement;
9
9
  /** The core client for your loaders. It tracks nothing until Shopify's Customer Privacy API holds the visitor's answer, and sets a cookie only when one changed. */
10
10
  export declare function createABConvert(options: Omit<ABConvertOptions, 'expectCustomerPrivacy'> & { request: RequestLike }): Promise<ServerABConvert>;
11
- /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), or when the response sets a cookie. True when it changed a header. */
11
+ /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), when the response sets a cookie, or when the client could not load the tests. True when it changed a header. */
12
12
  export declare function keepPrivateWhenTested(headers: Headers, client: Pick<ServerABConvert, 'isPageTested' | 'getSetCookieHeaders'>): boolean;
@@ -8,5 +8,5 @@ export type HydrogenProviderProps = Omit<ABConvertProviderProps, 'expectCustomer
8
8
  export declare const ABConvertProvider: (props: HydrogenProviderProps) => ReactElement;
9
9
  /** The core client for your loaders. It tracks nothing until Shopify's Customer Privacy API holds the visitor's answer, and sets a cookie only when one changed. */
10
10
  export declare function createABConvert(options: Omit<ABConvertOptions, 'expectCustomerPrivacy'> & { request: RequestLike }): Promise<ServerABConvert>;
11
- /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), or when the response sets a cookie. True when it changed a header. */
11
+ /** On a route in Oxygen's full-page cache, after the loader's reads: turns a public Cache-Control private when a test can change this route (isPageTested), when the response sets a cookie, or when the client could not load the tests. True when it changed a header. */
12
12
  export declare function keepPrivateWhenTested(headers: Headers, client: Pick<ServerABConvert, 'isPageTested' | 'getSetCookieHeaders'>): boolean;
package/dist/hydrogen.js CHANGED
@@ -1 +1 @@
1
- var globals=()=>globalThis;function attempt(read,fallback){try{return read()??fallback}catch{return fallback}}function shopifyAnalytics(){return attempt(()=>{let bus=globals().Shopify?.analytics;return typeof bus?.addDestination=="function"?bus:null},null)}import{createElement,useEffect}from"react";import{openClient}from"@abconvert/headless";import{ABConvertProvider as ReactProvider,useABConvert}from"@abconvert/headless/react";async function createABConvert(options){return(await openClient({...options,expectCustomerPrivacy:!0},{write:"changed"})).client}var PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect,warning){function HydrogenEvents(){let{track}=useABConvert(),connect=useConnect();return useEffect(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return createElement(ReactProvider,{...props,expectCustomerPrivacy:!0},createElement(HydrogenEvents),props.children)}}import{useABConvert as useABConvert2}from"@abconvert/headless/react";var connectBus=()=>track=>{let bus=shopifyAnalytics();return bus?.addDestination({name:"abconvert",setup:({subscribe})=>subscribeTo(subscribe,track)}),bus!==null},ABConvertProvider=hydrogenProvider(connectBus,"[ABConvert] No Hydrogen analytics bus on this page, so page views, product views and add to cart are not tracked. Render <ShopifyScripts> above <ABConvertProvider>, or on Hydrogen 2026.4 and earlier import from @abconvert/headless/hydrogen/analytics-provider.");export{ABConvertProvider,createABConvert,keepPrivateWhenTested,useABConvert2 as useABConvert};
1
+ var globals=()=>globalThis;function attempt(read,fallback){try{return read()??fallback}catch{return fallback}}function shopifyAnalytics(){return attempt(()=>{let bus=globals().Shopify?.analytics;return typeof bus?.addDestination=="function"?bus:null},null)}import{createElement,useEffect}from"react";import{openClient}from"@abconvert/headless";import{ABConvertProvider as ReactProvider,useABConvert}from"@abconvert/headless/react";async function createABConvert(options){let{client,cacheFacts}=await openClient({...options,expectCustomerPrivacy:!0},{write:"changed"});return cacheFacts().loaded||withoutTests.add(client),client}var withoutTests=new WeakSet,PUBLIC=/(^|,)\s*public\s*(?=,|$)/i;function keepPrivateWhenTested(headers,client){if(!withoutTests.has(client)&&!client.isPageTested()&&!client.getSetCookieHeaders().length)return!1;let changed=!1;for(let name of["Cache-Control","Oxygen-Cache-Control"]){let value=headers.get(name);!value||!PUBLIC.test(value)||(headers.set(name,value.replace(PUBLIC,"$1private")),changed=!0)}return changed}function fromAddToCart(payload){let{currentLine,prevLine}=payload??{},variantId=currentLine?.merchandise?.id,quantity=(currentLine?.quantity??0)-(prevLine?.quantity??0);return!variantId||!(quantity>0)?null:{variantId,productId:currentLine.merchandise?.product?.id,quantity}}function fromPageView(payload){let url=payload?.url;return typeof url=="string"?{url}:{}}function fromProductView(payload){let products=payload?.products;if(!Array.isArray(products))return[];let page=fromPageView(payload);return products.flatMap(product=>product?.id||product?.variantId?[{productId:product.id,variantId:product.variantId,...page}]:[])}function subscribeTo(subscribe,track){subscribe("page_viewed",payload=>track("page_viewed",fromPageView(payload))),subscribe("product_viewed",payload=>{for(let viewed of fromProductView(payload))track("product_viewed",viewed)}),subscribe("product_added_to_cart",payload=>{let added=fromAddToCart(payload);added&&track("product_added_to_cart",added)})}var connected=!1;function hydrogenProvider(useConnect,warning){function HydrogenEvents(){let{track}=useABConvert(),connect=useConnect();return useEffect(()=>{connected||(connected=!0,connect(track)||console.warn(warning))},[]),null}return function(props){return createElement(ReactProvider,{...props,expectCustomerPrivacy:!0},createElement(HydrogenEvents),props.children)}}import{useABConvert as useABConvert2}from"@abconvert/headless/react";var connectBus=()=>track=>{let bus=shopifyAnalytics();return bus?.addDestination({name:"abconvert",setup:({subscribe})=>subscribeTo(subscribe,track)}),bus!==null},ABConvertProvider=hydrogenProvider(connectBus,"[ABConvert] No Hydrogen analytics bus on this page, so page views, product views and add to cart are not tracked. Render <ShopifyScripts> above <ABConvertProvider>, or on Hydrogen 2026.4 and earlier import from @abconvert/headless/hydrogen/analytics-provider.");export{ABConvertProvider,createABConvert,keepPrivateWhenTested,useABConvert2 as useABConvert};