@bilyai/js 2.0.1 → 2.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.4 - 2026-09-07
4
+
5
+ - Omits calculated order money when finite product inputs overflow, while preserving explicit finite totals and zero.
6
+ - Preserves custom event names such as `constructor` and `toString` during queued and immediate delivery.
7
+ - Applies only documented event aliases, keeping their routing and explicit event metadata unchanged.
8
+ - Verifies browser event delivery through both packed ESM and CommonJS exports before publication.
9
+
10
+ ## 2.0.3 - 2026-08-25
11
+
12
+ - Resolves the deprecated tracking-origin shorthand to the canonical managed browser initializer instead of the
13
+ retired root-only loader path.
14
+ - Keeps exact `scriptUrl` initialization unchanged, including every query parameter.
15
+ - Adds autocomplete for the current SaaS conversion event catalog.
16
+
17
+ ## 2.0.2 - 2026-07-14
18
+
19
+ - Rejects a fresh SDK instance when the page already reserves the Bily script element for a different URL.
20
+ - Keeps readiness and queued delivery bound to the exact script URL and element that started the load.
21
+ - Refuses to adopt an unowned or replaced browser runtime, including before initialization and after a failed cutover.
22
+ - Requires an explicit `init()` retry after terminal load errors instead of silently adopting a later runtime.
23
+ - Replaces a failed externally declared script element when that explicit retry begins.
24
+ - Adds packed-package compatibility checks for the major browser frameworks supported by Bily.
25
+ - Documents the full-page reload required when moving an installation to a new tracking URL.
26
+
3
27
  ## 2.0.1 - 2026-07-14
4
28
 
5
29
  - Corrected the in-app path for copying the exact customer tracking URL.
package/README.md CHANGED
@@ -17,13 +17,65 @@ parameter in the URL.
17
17
  import { init } from "@bilyai/js";
18
18
 
19
19
  init({
20
- scriptUrl: "https://tracking.example.com/b.js?shop=store.example.com",
20
+ scriptUrl: "https://tracking.example.com/path-from-bily.js?shop=store.example.com",
21
21
  });
22
22
  ```
23
23
 
24
24
  The SDK safely queues calls made while the browser script loads. Repeated `init()` calls with the same URL do not
25
25
  load it twice.
26
26
 
27
+ ## Framework compatibility
28
+
29
+ The packed SDK is tested in browser ESM, React Router, Next.js App and Pages Routers, Vue 3, Nuxt 3 and 4, Svelte 5
30
+ with SvelteKit 2, Angular 20 and 21, Astro 5, Remix 2, and React Router Framework Mode 7 and 8.
31
+
32
+ The package is safe to import during server rendering. Call `init()` from a client-side lifecycle, then send one
33
+ `PageView` after each client-side route change. The browser script sends the first page view, so do not send it twice.
34
+
35
+ ### Astro client transitions
36
+
37
+ Astro's client router replaces the document head. Declare the reserved script once with `transition:persist`, then
38
+ initialize the SDK from that element's exact URL. The SDK reuses this one browser script; it does not add a second
39
+ loader. Send later page views from `astro:page-load`.
40
+
41
+ ```astro
42
+ ---
43
+ const bilyScriptUrl = import.meta.env.PUBLIC_BILY_SCRIPT_URL;
44
+ ---
45
+
46
+ <script
47
+ id="bily-tracking-script"
48
+ src={bilyScriptUrl}
49
+ async
50
+ referrerpolicy="strict-origin-when-cross-origin"
51
+ transition:persist="bily-tracking-script"
52
+ is:inline
53
+ ></script>
54
+
55
+ <script>
56
+ import { init } from "@bilyai/js";
57
+
58
+ const script = document.querySelector("#bily-tracking-script");
59
+ if (script instanceof HTMLScriptElement) init({ scriptUrl: script.src });
60
+ </script>
61
+ ```
62
+
63
+ ## Change the tracking URL
64
+
65
+ Treat `scriptUrl` as fixed for the life of the current page. To move to a first-party tracking URL:
66
+
67
+ 1. Replace the complete `scriptUrl`, including every query parameter.
68
+ 2. Rebuild and redeploy when the value comes from a public build-time environment variable.
69
+ 3. Hard reload the page, then confirm `#bily-tracking-script` uses the new URL.
70
+
71
+ Do not hot-switch URLs in the same document or through hot module replacement. Once this SDK instance is loading or
72
+ ready, a second `init()` with another URL is ignored to protect the active installation and its queue. A fresh SDK
73
+ instance that finds the reserved script ID attached to another URL rejects initialization instead. In either case,
74
+ reload the document to change URLs. `ready()` never proves that a different URL replaced the active installation.
75
+
76
+ After a terminal load error, call `init()` explicitly to retry. Later `ready()` calls keep reporting that error until
77
+ the retry begins.
78
+
27
79
  ## Track an event
28
80
 
29
81
  ```ts
@@ -63,3 +115,8 @@ await ready();
63
115
 
64
116
  See the [JavaScript SDK documentation](https://docs.bily.ai/sdk/javascript) for React, Next.js, event payload, and
65
117
  troubleshooting guides.
118
+
119
+ ## Contributing
120
+
121
+ Use the exact Node.js version in `.nvmrc` and npm version declared by `packageManager`. Framework smoke tests pin every
122
+ direct package and resolve transitive packages from a fixed registry snapshot.
package/dist/index.cjs CHANGED
@@ -1,2 +1 @@
1
- 'use strict';var ge=[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("");function a(){return typeof window!="undefined"&&typeof document!="undefined"}function m(){if(!a())return null;let e=window[ge];if(!e||typeof e!="object")return null;let n=e;return typeof n.track=="function"?n:null}function p(e,...n){if(typeof e=="function")return e(...n)}var E="sh_client_id",U=null;function we(){var r,i;let e=globalThis.crypto;if(typeof(e==null?void 0:e.randomUUID)=="function")return e.randomUUID();let n=new Uint8Array(16);if(typeof(e==null?void 0:e.getRandomValues)=="function")e.getRandomValues(n);else for(let o=0;o<n.length;o+=1)n[o]=Math.floor(Math.random()*256);n[6]=((r=n[6])!=null?r:0)&15|64,n[8]=((i=n[8])!=null?i:0)&63|128;let t=Array.from(n,o=>o.toString(16).padStart(2,"0")).join("");return `${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function pe(){if(!a())return null;try{let e=window.localStorage.getItem(E);return (e==null?void 0:e.trim())||null}catch{return null}}function he(e){if(a())try{window.localStorage.setItem(E,e);}catch{}}function ve(e){try{let n=p(e==null?void 0:e.get,E);return n&&typeof n.then=="function"&&Promise.resolve(n).catch(()=>{}),typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}function D(e,n){try{let t=p(e==null?void 0:e.set,E,n);t&&typeof t.then=="function"&&Promise.resolve(t).catch(()=>{});}catch{}}function L(e){var t,r;if(!a())return null;let n=(r=(t=U!=null?U:pe())!=null?t:ve(e))!=null?r:we();return U=n,he(n),D(e,n),n}var Ee={"Add to Wishlist":"Product Added to Wishlist","Category Viewed":"ViewCategory","Contact Form Submitted":"Contact","New Customer Order":"New Customer Purchase",Pageview:"PageView","Payment Add Address Info":"Checkout Address Info Submitted","Payment Add Contact Info":"AddContactInfo","Payment Add Shipping Info":"AddShippingInfo","Product Added To Wishlist":"Product Added to Wishlist","Remove from Cart":"Product Removed From Cart","Remove from Wishlist":"Product Removed From Wishlist",Search:"Products Searched"},be=new Set(["Product List Viewed","Products Searched","Product Clicked","Product Added","Product Added to Wishlist","Product Removed","Product Viewed","Cart Viewed","Checkout Started","Checkout Step Viewed","Checkout Step Completed","Payment Info Entered","Shipping Info Entered","Order Completed","Order Updated","Order Refunded","Order Cancelled","Clicked Promotion","Viewed Promotion"]),ke={dateOfBirth:"dob",email:"em",firstname:"fn",gender:"ge",lastname:"ln",phone:"ph",userId:"uid",userGroup:"user_group"},Be={city:"ct",country:"cn",state:"st",zip:"zp"};function f(e){return e!=null&&e!==""}function Ie(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}function b(e,n){return typeof e=="number"&&Number.isFinite(e)?e:n}function Re(e){return Ie({brand:e.brand,category:e.category,currency:e.currency,image:e.image,name:e.name,price:b(e.price),product_id:e.id,quantity:b(e.quantity,1),sku:e.sku})}function Y(e){return Array.isArray(e)?e.filter(n=>typeof n=="object"&&n!==null).map(Re):[]}function F(e){var n;return (n=Ee[e])!=null?n:e}function Z(e){return be.has(F(e))}function Se(){var t;let e=Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2),n=typeof((t=globalThis.crypto)==null?void 0:t.randomUUID)=="function"?globalThis.crypto.randomUUID():Date.now();return `${e}-${n}`}function G(e={},n){var K,W;let{client:t,order:r,pageTitle:i,products:o,searchQuery:c,sourceUrl:s,userAgent:H,...R}=e,u={...R};if(n&&(u.sh_client_id=n),t){for(let[l,v]of Object.entries(ke)){let g=t[l];f(g)&&(u[v]=g);}if(t.address)for(let[l,v]of Object.entries(Be)){let g=t.address[l];f(g)&&(u[v]=g);}}if(f(i)&&(u.page_title=i),f(s)&&(u.event_source_url=s,u.dl=s,u.landing_url=s),f(H)&&(u.uA=H),r){u.order_id=r.id;let l=Y(r.products);l.length>0&&(u.products=l);let v=l.reduce((C,_)=>{let me=typeof _.price=="number"?_.price:0,ye=typeof _.quantity=="number"?_.quantity:1;return C+me*ye},0),g=(K=b(r.total,v))!=null?K:v;u.value=g,u.revenue=g,b(r.tax)!==void 0&&(u.tax=r.tax),b(r.shippingFees)!==void 0&&(u.shippingFees=r.shippingFees),b(r.discount)!==void 0&&(u.discount=r.discount),f(r.discountCode)&&(u.discountCode=r.discountCode);let fe=(W=l.find(C=>f(C.currency)))==null?void 0:W.currency,X=f(r.currency)?r.currency:fe;f(X)&&(u.currency=X);}else {let l=Y(o);l.length>0&&(u.products=l);}return f(c)&&(u.search_query=c,u.query=c),u.ts=typeof R.ts=="string"?R.ts:new Date().toISOString(),u.event_id=f(R.event_id)?R.event_id:Se(),u}var O=100,Pe=1e3,J=15e3,Te=1e3,_e=6e4,Q="bily-tracking-script",ee="__bilySdkFacade",h=null,A=false,d="idle",S=O,w=[],P=N(),ue=0,x=null,B=null,k=null;function N(){let e,n,t=new Promise((r,i)=>{e=r,n=i;});return t.catch(()=>{}),{promise:t,reject:n,resolve:e}}function y(e,n,t){if(!(!A||typeof console=="undefined")){if(e==="warn"){t===void 0?console.warn("[Bily]",n):console.warn("[Bily]",n,t);return}t===void 0?console.info("[Bily]",n):console.info("[Bily]",n,t);}}function ne(e){return Number.isFinite(e)?Math.min(Pe,Math.max(1,Math.floor(e!=null?e:O))):O}function te(e){return Number.isFinite(e)?Math.min(_e,Math.max(Te,Math.floor(e!=null?e:J))):J}function z(e){let n=new URL(e),t=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&t))throw new Error("Bily script URLs must use HTTPS (HTTP is allowed for local development).");return n}function re(e){let n=z(e.trim()),t=n.pathname.replace(/\/+$/,"");return n.pathname=`${t}/b.js`.replace(/^\/\//,"/"),n.toString()}function ie(e){let n=e.trim();return z(n),n}function Ue(e){try{return /\.m?js$/i.test(z(e.trim()).pathname)}catch{return false}}function Le(e,n){var r,i,o;if(typeof e=="string"){let c=Ue(e)?ie(e):re(e);return {debug:(n==null?void 0:n.verbose)===true,loadTimeoutMs:te(n==null?void 0:n.loadTimeoutMs),maxQueueSize:ne(n==null?void 0:n.maxQueueSize),nonce:n==null?void 0:n.nonce,scriptUrl:c}}let t=(r=e.scriptUrl)!=null?r:e.trackingDomain;if(!(t!=null&&t.trim()))throw new Error("Provide a Bily scriptUrl or trackingDomain.");return {debug:(o=(i=e.debug)!=null?i:e.verbose)!=null?o:false,loadTimeoutMs:te(e.loadTimeoutMs),maxQueueSize:ne(e.maxQueueSize),nonce:e.nonce,scriptUrl:e.scriptUrl?ie(e.scriptUrl):re(t)}}function M(e,n){try{return new URL(e,document.baseURI).toString()===new URL(n,document.baseURI).toString()}catch{return e===n}}function Ae(e){let n=document.getElementById(Q);if(n instanceof HTMLScriptElement&&M(n.src,e))return n;for(let t of Array.from(document.querySelectorAll("script[src]")))if(M(t.src,e))return t;return null}function ce(e,n){let t=n.channel==="ecommerce"&&typeof e.ecommerce=="function"?e.ecommerce:e.track;try{let r=p(t,n.event,n.payload);r&&typeof r.then=="function"&&Promise.resolve(r).catch(i=>y("warn","Event delivery failed.",i));}catch(r){y("warn","Event delivery failed.",r);}}function xe(e){let n=w;w=[];for(let t of n)ce(e,t);}function $(){x!==null&&window.clearTimeout(x),x=null,B!==null&&window.clearTimeout(B),B=null;}function V(e){return e===ue&&d==="loading"}function I(e,n){if(n!==void 0&&!V(n))return;d==="error"&&(P=N()),$(),d="ready",k=null;let t=L(e);t&&D(e,t),xe(e),P.resolve(),y("info","Ready.");}function T(e,n){n!==void 0&&!V(n)||($(),d="error",k&&k.dataset.bilySdkOwned==="true"&&k.remove(),k=null,P.reject(e),y("warn",e.message));}function j(e){if(!V(e))return;let n=m();if(n){I(n,e);return}B===null&&(B=window.setTimeout(()=>{B=null,j(e);},16));}function Me(e){j(e);}function oe(e,n){let t=++ue;k=e,$(),x=window.setTimeout(()=>{let r=m();if(r){I(r,t);return}T(new Error(`Bily did not become ready within ${n}ms.`),t);},n),e.addEventListener("load",()=>Me(t),{once:true}),e.addEventListener("error",()=>T(new Error(`Unable to load the Bily browser script from ${h!=null?h:"the configured URL"}.`),t),{once:true}),j(t);}function Ce(e){var o,c;let n=document.getElementById(Q);if(n instanceof HTMLScriptElement&&!M(n.src,e.scriptUrl)){T(new Error("A Bily browser script is already installed with a different URL."));return}let t=Ae(e.scriptUrl);if(t){oe(t,e.loadTimeoutMs);let s=m();s&&I(s);return}let r=document.createElement("script");r.id=Q,r.src=e.scriptUrl,r.async=true,r.referrerPolicy="strict-origin-when-cross-origin",r.dataset.bilySdkOwned="true",e.nonce&&(r.nonce=e.nonce),oe(r,e.loadTimeoutMs);let i=(c=(o=document.head)!=null?o:document.body)!=null?c:document.documentElement;if(!i){T(new Error("Bily could not find a document element for its browser script."));return}i.appendChild(r);}function De(e){w.length>=S&&(w.shift(),y("warn",`Event queue reached ${S}; the oldest event was discarded.`)),w.push(e);}function de(e,n,t){if(!a())return;let r;try{r=String(e!=null?e:"").trim();}catch(s){y("warn","Ignored an event whose name could not be read.",s);return}if(!r){y("warn","Ignored an event with an empty name.");return}q();let i=m(),o=L(i),c;try{c={channel:t!=null?t:Z(r)?"ecommerce":"track",event:F(r),payload:{...G(n!=null?n:{},o),source:"web"}};}catch(s){y("warn",`Ignored ${r} because its payload could not be read.`,s);return}i?(d!=="ready"&&I(i),ce(i,c)):De(c);}function q(){if(!a())return;let e=window,n;try{n=e.bily;}catch{return}if((n==null?void 0:n[ee])===true)return;let t={[ee]:true,ecommerce:(r,i)=>de(r,i,"ecommerce"),get:r=>{if(r===E)return ae();let i=m();return p(i==null?void 0:i.get,r)},set:(r,i)=>{let o=m();return p(o==null?void 0:o.set,r,i)},track:(r,i)=>le(r,i)};try{Object.defineProperty(e,"bily",{configurable:!0,value:t,writable:!0});}catch{try{e.bily=t;}catch{}}}function se(e,n){var i;if(!a())return;let t;try{t=Le(e,n);}catch(o){if(h&&(d==="loading"||d==="ready")){y("warn","An invalid second initialization was ignored.");return}try{A=typeof e=="object"&&e!==null&&((i=e.debug)!=null?i:e.verbose)||typeof e=="string"&&(n==null?void 0:n.verbose)===!0;}catch{A=false;}let c=o instanceof Error?o:new Error(String(o));T(c);return}if(h&&!M(h,t.scriptUrl)&&d!=="error"){y("warn","Bily is already initialized with a different script URL; the second initialization was ignored.");return}A=t.debug,S=t.maxQueueSize,w.length>S&&(w=w.slice(-S)),q(),d==="error"&&(P=N(),d="idle"),h=t.scriptUrl;let r=m();if(r){I(r);return}d==="loading"||d==="ready"||(d="loading",Ce(t));}function le(e,n){de(e,n);}function ae(){return a()?(q(),L(m())):null}function Fe(){if(!a())return Promise.resolve();let e=m();return e&&d!=="ready"&&I(e),P.promise}function We(e,n){se(e,n);}
2
- exports.getBilyTrackingId=ae;exports.init=We;exports.ready=Fe;exports.track=le;
1
+ 'use strict';var Ae=[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("");function g(){return typeof window!="undefined"&&typeof document!="undefined"}function O(){if(!g())return null;let e=window[Ae];if(!e||typeof e!="object")return null;let n=e;return typeof n.track=="function"?n:null}function k(e,...n){if(typeof e=="function")return e(...n)}var U="sh_client_id",V=null;function Me(){var t,i;let e=globalThis.crypto;if(typeof(e==null?void 0:e.randomUUID)=="function")return e.randomUUID();let n=new Uint8Array(16);if(typeof(e==null?void 0:e.getRandomValues)=="function")e.getRandomValues(n);else for(let o=0;o<n.length;o+=1)n[o]=Math.floor(Math.random()*256);n[6]=((t=n[6])!=null?t:0)&15|64,n[8]=((i=n[8])!=null?i:0)&63|128;let r=Array.from(n,o=>o.toString(16).padStart(2,"0")).join("");return `${r.slice(0,8)}-${r.slice(8,12)}-${r.slice(12,16)}-${r.slice(16,20)}-${r.slice(20)}`}function xe(){if(!g())return null;try{let e=window.localStorage.getItem(U);return (e==null?void 0:e.trim())||null}catch{return null}}function Ce(e){if(g())try{window.localStorage.setItem(U,e);}catch{}}function De(e){try{let n=k(e==null?void 0:e.get,U);return n&&typeof n.then=="function"&&Promise.resolve(n).catch(()=>{}),typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}function ee(e,n){try{let r=k(e==null?void 0:e.set,U,n);r&&typeof r.then=="function"&&Promise.resolve(r).catch(()=>{});}catch{}}function $(e){var r,t;if(!g())return null;let n=(t=(r=V!=null?V:xe())!=null?r:De(e))!=null?t:Me();return V=n,Ce(n),ee(e,n),n}var ae={"Add to Wishlist":"Product Added to Wishlist","Category Viewed":"ViewCategory","Contact Form Submitted":"Contact","New Customer Order":"New Customer Purchase",Pageview:"PageView","Payment Add Address Info":"Checkout Address Info Submitted","Payment Add Contact Info":"AddContactInfo","Payment Add Shipping Info":"AddShippingInfo","Product Added To Wishlist":"Product Added to Wishlist","Remove from Cart":"Product Removed From Cart","Remove from Wishlist":"Product Removed From Wishlist",Search:"Products Searched"},Oe=new Set(["Product List Viewed","Products Searched","Product Clicked","Product Added","Product Added to Wishlist","Product Removed","Product Viewed","Cart Viewed","Checkout Started","Checkout Step Viewed","Checkout Step Completed","Payment Info Entered","Shipping Info Entered","Order Completed","Order Updated","Order Refunded","Order Cancelled","Clicked Promotion","Viewed Promotion"]),ze={dateOfBirth:"dob",email:"em",firstname:"fn",gender:"ge",lastname:"ln",phone:"ph",userId:"uid",userGroup:"user_group"},Fe={city:"ct",country:"cn",state:"st",zip:"zp"};function p(e){return e!=null&&e!==""}function He(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}function I(e,n){return typeof e=="number"&&Number.isFinite(e)?e:n}function Ne(e){return He({brand:e.brand,category:e.category,currency:e.currency,image:e.image,name:e.name,price:I(e.price),product_id:e.id,quantity:I(e.quantity,1),sku:e.sku})}function fe(e){return Array.isArray(e)?e.filter(n=>typeof n=="object"&&n!==null).map(Ne):[]}function ne(e){let n=Object.prototype.hasOwnProperty.call(ae,e)?ae[e]:void 0;return typeof n=="string"?n:e}function me(e){return Oe.has(ne(e))}function Qe(){var r;let e=Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2),n=typeof((r=globalThis.crypto)==null?void 0:r.randomUUID)=="function"?globalThis.crypto.randomUUID():Date.now();return `${e}-${n}`}function ye(e={},n){var ce;let{client:r,order:t,pageTitle:i,products:o,searchQuery:d,sourceUrl:a,userAgent:v,...C}=e,u={...C};if(n&&(u.sh_client_id=n),r){for(let[y,D]of Object.entries(ze)){let R=r[y];p(R)&&(u[D]=R);}if(r.address)for(let[y,D]of Object.entries(Fe)){let R=r.address[y];p(R)&&(u[D]=R);}}if(p(i)&&(u.page_title=i),p(a)&&(u.event_source_url=a,u.dl=a,u.landing_url=a),p(v)&&(u.uA=v),t){u.order_id=t.id;let y=fe(t.products);y.length>0&&(u.products=y);let D=y.reduce((J,q)=>{let Ue=typeof q.price=="number"?q.price:0,_e=typeof q.quantity=="number"?q.quantity:1;return J+Ue*_e},0),R=I(t.total,I(D));R!==void 0?(u.value=R,u.revenue=R):(delete u.value,delete u.revenue),I(t.tax)!==void 0&&(u.tax=t.tax),I(t.shippingFees)!==void 0&&(u.shippingFees=t.shippingFees),I(t.discount)!==void 0&&(u.discount=t.discount),p(t.discountCode)&&(u.discountCode=t.discountCode);let Le=(ce=y.find(J=>p(J.currency)))==null?void 0:ce.currency,de=p(t.currency)?t.currency:Le;p(de)&&(u.currency=de);}else {let y=fe(o);y.length>0&&(u.products=y);}return p(d)&&(u.search_query=d,u.query=d),u.ts=typeof C.ts=="string"?C.ts:new Date().toISOString(),u.event_id=p(C.event_id)?C.event_id:Qe(),u}var te=100,je=1e3,ge=15e3,qe=1e3,Ve=6e4,P="bily-tracking-script",pe="__bilySdkFacade",$e=["",`bily-${[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("")}`,"i.js"].join("/"),E=null,W=false,l="idle",z=te,b=[],A=ie(),F=0,K=null,_=null,c=null,Q=false,X=false,N=false,B=null,f=null,M=false,x=null,w=null,T=null,Y=false;function ie(){let e,n,r=new Promise((t,i)=>{e=t,n=i;});return r.catch(()=>{}),{promise:r,reject:n,resolve:e}}function h(e,n,r){if(!(!W||typeof console=="undefined")){if(e==="warn"){r===void 0?console.warn("[Bily]",n):console.warn("[Bily]",n,r);return}r===void 0?console.info("[Bily]",n):console.info("[Bily]",n,r);}}function we(e){return Number.isFinite(e)?Math.min(je,Math.max(1,Math.floor(e!=null?e:te))):te}function he(e){return Number.isFinite(e)?Math.min(Ve,Math.max(qe,Math.floor(e!=null?e:ge))):ge}function oe(e){let n=new URL(e),r=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&r))throw new Error("Bily script URLs must use HTTPS (HTTP is allowed for local development).");return n}function Ee(e){let n=oe(e.trim());return n.pathname=$e,n.search="",n.hash="",n.toString()}function be(e){let n=e.trim();return oe(n),n}function We(e){try{return /\.m?js$/i.test(oe(e.trim()).pathname)}catch{return false}}function Ke(e,n){var t,i,o;if(typeof e=="string"){let d=We(e)?be(e):Ee(e);return {debug:(n==null?void 0:n.verbose)===true,loadTimeoutMs:he(n==null?void 0:n.loadTimeoutMs),maxQueueSize:we(n==null?void 0:n.maxQueueSize),nonce:n==null?void 0:n.nonce,scriptUrl:d}}let r=(t=e.scriptUrl)!=null?t:e.trackingDomain;if(!(r!=null&&r.trim()))throw new Error("Provide a Bily scriptUrl or trackingDomain.");return {debug:(o=(i=e.debug)!=null?i:e.verbose)!=null?o:false,loadTimeoutMs:he(e.loadTimeoutMs),maxQueueSize:we(e.maxQueueSize),nonce:e.nonce,scriptUrl:e.scriptUrl?be(e.scriptUrl):Ee(r)}}function S(e,n){try{return new URL(e,document.baseURI).toString()===new URL(n,document.baseURI).toString()}catch{return e===n}}function Be(e){let n=document.getElementById(P);if(n instanceof HTMLScriptElement&&S(n.src,e))return n;for(let r of Array.from(document.querySelectorAll("script[src]")))if(S(r.src,e))return r;return null}function ue(e){if(!e)return false;let n=document.getElementById(P);return n instanceof HTMLScriptElement&&!S(n.src,e)}function G(){return new Error("A Bily browser script is already installed with a different URL.")}function ve(e,n=E,r=false){if(!e||!n)return null;let t=document.getElementById(P);return !e.isConnected||!S(e.src,n)||r&&t!==e||t instanceof HTMLScriptElement&&t!==e?new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."):null}function Xe(){return Y?new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."):c?ve(c,B,N):ve(f,E,M)}function Ye(){return !x||O()===x?null:new Error("The Bily browser runtime no longer matches the active script. Reload the page before initializing again.")}function L(){var e;return (e=Xe())!=null?e:Ye()}function m(e=E){if(Y||!e||L()||!(c!=null?c:f)||X&&!Q)return null;let r=O();return x&&r!==x?null:r&&!ue(e)?r:null}function Se(e,n){let r=n.channel==="ecommerce"&&typeof e.ecommerce=="function"?e.ecommerce:e.track;try{let t=k(r,n.event,n.payload);t&&typeof t.then=="function"&&Promise.resolve(t).catch(i=>h("warn","Event delivery failed.",i));}catch(t){h("warn","Event delivery failed.",t);}}function Ge(e){if(m()!==e)return false;let n=b;b=[];for(let r=0;r<n.length;r+=1){if(m()!==e)return b=[...n.slice(r),...b],false;Se(e,n[r]);}return m()===e}function le(){K!==null&&window.clearTimeout(K),K=null,_!==null&&window.clearTimeout(_),_=null;}function Z(e){return e===F&&l==="loading"}function j(e,n){if(n!==void 0&&!Z(n))return false;let r=L();if(r)return s(r,n,true),false;if(m()!==e)return s(G(),n,true),false;let t=c!=null?c:f,i=c?N:M;le(),x=e;let o=$(e);return o&&ee(e,o),m()!==e||!Ge(e)?(s(new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."),n,true),false):(l="ready",f=t,M=i,c=null,Q=false,X=false,N=false,B=null,w=null,T=null,A.resolve(),h("info","Ready."),true)}function s(e,n,r=false){if(n!==void 0&&!Z(n))return;l==="ready"&&(A=ie()),r&&(Y=true),le(),l="error";let t=c!=null?c:f,i=c?B:E;(t==null?void 0:t.dataset.bilySdkOwned)==="true"?t.remove():!r&&t&&i&&(w=t,T=i),r&&(w=null,T=null),c=null,Q=false,X=false,N=false,B=null,f=null,M=false,x=null,A.reject(e),h("warn",e.message);}function H(e){if(!Z(e))return;let n=L();if(n){s(n,e,true);return}let r=m();if(r){j(r,e);return}_===null&&(_=window.setTimeout(()=>{_=null,H(e);},16));}function Ze(e){Z(e)&&(Q=true,H(e));}function re(e,n,r=false){let t=++F;c=e,Q=!r,X=r,N=e.id===P,B=E,f=null,M=false,le(),K=window.setTimeout(()=>{let i=L();if(i){s(i,t,true);return}let o=m();if(o){j(o,t);return}s(new Error(`Bily did not become ready within ${n}ms.`),t);},n),e.addEventListener("load",()=>Ze(t),{once:true}),e.addEventListener("error",()=>s(new Error(`Unable to load the Bily browser script from ${B!=null?B:"the configured URL"}.`),t),{once:true});}function Je(e){let n=document.createElement("script");for(let r of Array.from(e.attributes))n.setAttribute(r.name,r.value);return n.async=e.async,n.referrerPolicy=e.referrerPolicy,e.nonce&&(n.nonce=e.nonce),n}function en(e){var o,d;let n=document.getElementById(P);if(n instanceof HTMLScriptElement&&!S(n.src,e.scriptUrl)){s(G(),void 0,true);return}if(w!=null&&w.isConnected&&T&&S(T,e.scriptUrl)&&S(w.src,e.scriptUrl)){if(O()){s(new Error("An existing Bily browser runtime cannot be matched to the configured script. Reload the page before initializing again."),void 0,true);return}let a=w,v=Je(a);w=null,T=null,re(v,e.loadTimeoutMs,true),a.replaceWith(v),H(F);return}w=null,T=null;let r=Be(e.scriptUrl);if(r){re(r,e.loadTimeoutMs),H(F);return}let t=document.createElement("script");t.id=P,t.src=e.scriptUrl,t.async=true,t.referrerPolicy="strict-origin-when-cross-origin",t.dataset.bilySdkOwned="true",e.nonce&&(t.nonce=e.nonce),re(t,e.loadTimeoutMs,true);let i=(d=(o=document.head)!=null?o:document.body)!=null?d:document.documentElement;if(!i){s(new Error("Bily could not find a document element for its browser script."));return}i.appendChild(t),H(F);}function Re(e){b.length>=z&&(b.shift(),h("warn",`Event queue reached ${z}; the oldest event was discarded.`)),b.push(e);}function ke(e,n,r){if(!g())return;let t;try{t=String(e!=null?e:"").trim();}catch(v){h("warn","Ignored an event whose name could not be read.",v);return}if(!t){h("warn","Ignored an event with an empty name.");return}se();let i=L();i&&s(i,void 0,true);let o=l==="error"?null:m(),d=$(o),a;try{a={channel:r!=null?r:me(t)?"ecommerce":"track",event:ne(t),payload:{...ye(n!=null?n:{},d),source:"web"}};}catch(v){h("warn",`Ignored ${t} because its payload could not be read.`,v);return}if(o&&l!=="error"){if(l!=="ready"&&!j(o)){Re(a);return}if(l==="ready"&&m()===o){Se(o,a);return}}Re(a);}function se(){if(!g())return;let e=window,n;try{n=e.bily;}catch{return}if((n==null?void 0:n[pe])===true)return;let r={[pe]:true,ecommerce:(t,i)=>ke(t,i,"ecommerce"),get:t=>{if(t===U)return Pe();let i=m();return k(i==null?void 0:i.get,t)},set:(t,i)=>{let o=m();return k(o==null?void 0:o.set,t,i)},track:(t,i)=>Te(t,i)};try{Object.defineProperty(e,"bily",{configurable:!0,value:r,writable:!0});}catch{try{e.bily=r;}catch{}}}function Ie(e,n){var o;if(!g())return;let r;try{r=Ke(e,n);}catch(d){if(E&&(l==="loading"||l==="ready")){h("warn","An invalid second initialization was ignored.");return}try{W=typeof e=="object"&&e!==null&&((o=e.debug)!=null?o:e.verbose)||typeof e=="string"&&(n==null?void 0:n.verbose)===!0;}catch{W=false;}let a=d instanceof Error?d:new Error(String(d));s(a);return}if(E&&!S(E,r.scriptUrl)&&l!=="error"){h("warn","Bily is already initialized with a different script URL; the second initialization was ignored.");return}if(Y){h("warn","Reload the page before initializing Bily again.");return}let t=L();if(t){s(t,void 0,true);return}if(W=r.debug,z=r.maxQueueSize,b.length>z&&(b=b.slice(-z)),se(),l==="loading"||l==="ready")return;l==="error"&&(A=ie(),l="idle"),E=r.scriptUrl;let i=O();if(i){if(ue(r.scriptUrl)){s(G(),void 0,true);return}if(f=Be(r.scriptUrl),!f||f===w){s(new Error("An existing Bily browser runtime cannot be matched to the configured script. Reload the page before initializing again."),void 0,true);return}M=(f==null?void 0:f.id)===P,j(i);return}l="loading",en(r);}function Te(e,n){ke(e,n);}function Pe(){return g()?(se(),$(l==="error"?null:m())):null}function nn(){if(!g())return Promise.resolve();let e=L();if(e&&s(e,void 0,true),ue(E)&&s(G(),void 0,true),l==="error")return A.promise;let n=m();return n&&l!=="ready"&&j(n),A.promise}function mn(e,n){Ie(e,n);}exports.getBilyTrackingId=Pe;exports.init=mn;exports.ready=nn;exports.track=Te;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- type KnownBilyEvent = "AddContactInfo" | "AddShippingInfo" | "Checkout Address Info Submitted" | "Contact" | "New Customer Purchase" | "PageView" | "Pageview" | "Product Removed From Cart" | "Product Removed From Wishlist" | "ViewCategory" | "Product List Viewed" | "Products Searched" | "Product Clicked" | "Product Added" | "Product Added to Wishlist" | "Product Removed" | "Product Viewed" | "Checkout Step Viewed" | "Checkout Step Completed" | "Shipping Info Entered" | "Order Refunded" | "Clicked Promotion" | "Viewed Promotion" | "Category Viewed" | "Checkout Started" | "Payment Info Entered" | "Payment Add Contact Info" | "Payment Add Shipping Info" | "Payment Add Address Info" | "Subscription" | "New Customer Order" | "New Customer Subscription" | "Order Completed" | "Cart Viewed" | "Remove from Cart" | "Cart Updated" | "Order Updated" | "Order Cancelled" | "Lead" | "Login" | "Logout" | "Search" | "Add to Wishlist" | "Remove from Wishlist" | "View Wishlist" | "Newsletter" | "Contact Form Submitted" | "Subscription Cancelled" | "Subscription Updated" | "Subscription Renewed";
1
+ type KnownBilyEvent = "AddContactInfo" | "AddShippingInfo" | "Checkout Address Info Submitted" | "Contact" | "Contact Submitted" | "Demo Requested" | "Download" | "New Customer Purchase" | "PageView" | "Pageview" | "Product Removed From Cart" | "Product Removed From Wishlist" | "ViewCategory" | "Product List Viewed" | "Products Searched" | "Product Clicked" | "Product Added" | "Product Added to Wishlist" | "Product Removed" | "Product Viewed" | "Checkout Step Viewed" | "Checkout Step Completed" | "Shipping Info Entered" | "Order Refunded" | "Clicked Promotion" | "Viewed Promotion" | "Category Viewed" | "Checkout Started" | "Payment Info Entered" | "Payment Add Contact Info" | "Payment Add Shipping Info" | "Payment Add Address Info" | "Subscription" | "New Customer Order" | "New Customer Subscription" | "Order Completed" | "Cart Viewed" | "Remove from Cart" | "Cart Updated" | "Order Updated" | "Order Cancelled" | "Lead" | "Login" | "Logout" | "Search" | "Sign Up" | "Add to Wishlist" | "Remove from Wishlist" | "View Wishlist" | "Newsletter" | "Contact Form Submitted" | "Subscription Cancelled" | "Subscription Started" | "Subscription Updated" | "Subscription Renewed" | "Trial Started";
2
2
  /** Known Bily events retain autocomplete while custom application events remain valid. */
3
3
  type BilyEvent = KnownBilyEvent | (string & Record<never, never>);
4
4
  type BilyAddress = {
@@ -71,7 +71,7 @@ type BilyInitOptions = BilyInitCommonOptions & ({
71
71
  scriptUrl: string;
72
72
  trackingDomain?: never;
73
73
  } | {
74
- /** Legacy tracking origin. The SDK loads b.js from this origin. */
74
+ /** Legacy tracking origin. The SDK loads the canonical managed browser initializer from this origin. */
75
75
  trackingDomain: string;
76
76
  scriptUrl?: never;
77
77
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type KnownBilyEvent = "AddContactInfo" | "AddShippingInfo" | "Checkout Address Info Submitted" | "Contact" | "New Customer Purchase" | "PageView" | "Pageview" | "Product Removed From Cart" | "Product Removed From Wishlist" | "ViewCategory" | "Product List Viewed" | "Products Searched" | "Product Clicked" | "Product Added" | "Product Added to Wishlist" | "Product Removed" | "Product Viewed" | "Checkout Step Viewed" | "Checkout Step Completed" | "Shipping Info Entered" | "Order Refunded" | "Clicked Promotion" | "Viewed Promotion" | "Category Viewed" | "Checkout Started" | "Payment Info Entered" | "Payment Add Contact Info" | "Payment Add Shipping Info" | "Payment Add Address Info" | "Subscription" | "New Customer Order" | "New Customer Subscription" | "Order Completed" | "Cart Viewed" | "Remove from Cart" | "Cart Updated" | "Order Updated" | "Order Cancelled" | "Lead" | "Login" | "Logout" | "Search" | "Add to Wishlist" | "Remove from Wishlist" | "View Wishlist" | "Newsletter" | "Contact Form Submitted" | "Subscription Cancelled" | "Subscription Updated" | "Subscription Renewed";
1
+ type KnownBilyEvent = "AddContactInfo" | "AddShippingInfo" | "Checkout Address Info Submitted" | "Contact" | "Contact Submitted" | "Demo Requested" | "Download" | "New Customer Purchase" | "PageView" | "Pageview" | "Product Removed From Cart" | "Product Removed From Wishlist" | "ViewCategory" | "Product List Viewed" | "Products Searched" | "Product Clicked" | "Product Added" | "Product Added to Wishlist" | "Product Removed" | "Product Viewed" | "Checkout Step Viewed" | "Checkout Step Completed" | "Shipping Info Entered" | "Order Refunded" | "Clicked Promotion" | "Viewed Promotion" | "Category Viewed" | "Checkout Started" | "Payment Info Entered" | "Payment Add Contact Info" | "Payment Add Shipping Info" | "Payment Add Address Info" | "Subscription" | "New Customer Order" | "New Customer Subscription" | "Order Completed" | "Cart Viewed" | "Remove from Cart" | "Cart Updated" | "Order Updated" | "Order Cancelled" | "Lead" | "Login" | "Logout" | "Search" | "Sign Up" | "Add to Wishlist" | "Remove from Wishlist" | "View Wishlist" | "Newsletter" | "Contact Form Submitted" | "Subscription Cancelled" | "Subscription Started" | "Subscription Updated" | "Subscription Renewed" | "Trial Started";
2
2
  /** Known Bily events retain autocomplete while custom application events remain valid. */
3
3
  type BilyEvent = KnownBilyEvent | (string & Record<never, never>);
4
4
  type BilyAddress = {
@@ -71,7 +71,7 @@ type BilyInitOptions = BilyInitCommonOptions & ({
71
71
  scriptUrl: string;
72
72
  trackingDomain?: never;
73
73
  } | {
74
- /** Legacy tracking origin. The SDK loads b.js from this origin. */
74
+ /** Legacy tracking origin. The SDK loads the canonical managed browser initializer from this origin. */
75
75
  trackingDomain: string;
76
76
  scriptUrl?: never;
77
77
  });
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- var ge=[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("");function a(){return typeof window!="undefined"&&typeof document!="undefined"}function m(){if(!a())return null;let e=window[ge];if(!e||typeof e!="object")return null;let n=e;return typeof n.track=="function"?n:null}function p(e,...n){if(typeof e=="function")return e(...n)}var E="sh_client_id",U=null;function we(){var r,i;let e=globalThis.crypto;if(typeof(e==null?void 0:e.randomUUID)=="function")return e.randomUUID();let n=new Uint8Array(16);if(typeof(e==null?void 0:e.getRandomValues)=="function")e.getRandomValues(n);else for(let o=0;o<n.length;o+=1)n[o]=Math.floor(Math.random()*256);n[6]=((r=n[6])!=null?r:0)&15|64,n[8]=((i=n[8])!=null?i:0)&63|128;let t=Array.from(n,o=>o.toString(16).padStart(2,"0")).join("");return `${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function pe(){if(!a())return null;try{let e=window.localStorage.getItem(E);return (e==null?void 0:e.trim())||null}catch{return null}}function he(e){if(a())try{window.localStorage.setItem(E,e);}catch{}}function ve(e){try{let n=p(e==null?void 0:e.get,E);return n&&typeof n.then=="function"&&Promise.resolve(n).catch(()=>{}),typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}function D(e,n){try{let t=p(e==null?void 0:e.set,E,n);t&&typeof t.then=="function"&&Promise.resolve(t).catch(()=>{});}catch{}}function L(e){var t,r;if(!a())return null;let n=(r=(t=U!=null?U:pe())!=null?t:ve(e))!=null?r:we();return U=n,he(n),D(e,n),n}var Ee={"Add to Wishlist":"Product Added to Wishlist","Category Viewed":"ViewCategory","Contact Form Submitted":"Contact","New Customer Order":"New Customer Purchase",Pageview:"PageView","Payment Add Address Info":"Checkout Address Info Submitted","Payment Add Contact Info":"AddContactInfo","Payment Add Shipping Info":"AddShippingInfo","Product Added To Wishlist":"Product Added to Wishlist","Remove from Cart":"Product Removed From Cart","Remove from Wishlist":"Product Removed From Wishlist",Search:"Products Searched"},be=new Set(["Product List Viewed","Products Searched","Product Clicked","Product Added","Product Added to Wishlist","Product Removed","Product Viewed","Cart Viewed","Checkout Started","Checkout Step Viewed","Checkout Step Completed","Payment Info Entered","Shipping Info Entered","Order Completed","Order Updated","Order Refunded","Order Cancelled","Clicked Promotion","Viewed Promotion"]),ke={dateOfBirth:"dob",email:"em",firstname:"fn",gender:"ge",lastname:"ln",phone:"ph",userId:"uid",userGroup:"user_group"},Be={city:"ct",country:"cn",state:"st",zip:"zp"};function f(e){return e!=null&&e!==""}function Ie(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}function b(e,n){return typeof e=="number"&&Number.isFinite(e)?e:n}function Re(e){return Ie({brand:e.brand,category:e.category,currency:e.currency,image:e.image,name:e.name,price:b(e.price),product_id:e.id,quantity:b(e.quantity,1),sku:e.sku})}function Y(e){return Array.isArray(e)?e.filter(n=>typeof n=="object"&&n!==null).map(Re):[]}function F(e){var n;return (n=Ee[e])!=null?n:e}function Z(e){return be.has(F(e))}function Se(){var t;let e=Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2),n=typeof((t=globalThis.crypto)==null?void 0:t.randomUUID)=="function"?globalThis.crypto.randomUUID():Date.now();return `${e}-${n}`}function G(e={},n){var K,W;let{client:t,order:r,pageTitle:i,products:o,searchQuery:c,sourceUrl:s,userAgent:H,...R}=e,u={...R};if(n&&(u.sh_client_id=n),t){for(let[l,v]of Object.entries(ke)){let g=t[l];f(g)&&(u[v]=g);}if(t.address)for(let[l,v]of Object.entries(Be)){let g=t.address[l];f(g)&&(u[v]=g);}}if(f(i)&&(u.page_title=i),f(s)&&(u.event_source_url=s,u.dl=s,u.landing_url=s),f(H)&&(u.uA=H),r){u.order_id=r.id;let l=Y(r.products);l.length>0&&(u.products=l);let v=l.reduce((C,_)=>{let me=typeof _.price=="number"?_.price:0,ye=typeof _.quantity=="number"?_.quantity:1;return C+me*ye},0),g=(K=b(r.total,v))!=null?K:v;u.value=g,u.revenue=g,b(r.tax)!==void 0&&(u.tax=r.tax),b(r.shippingFees)!==void 0&&(u.shippingFees=r.shippingFees),b(r.discount)!==void 0&&(u.discount=r.discount),f(r.discountCode)&&(u.discountCode=r.discountCode);let fe=(W=l.find(C=>f(C.currency)))==null?void 0:W.currency,X=f(r.currency)?r.currency:fe;f(X)&&(u.currency=X);}else {let l=Y(o);l.length>0&&(u.products=l);}return f(c)&&(u.search_query=c,u.query=c),u.ts=typeof R.ts=="string"?R.ts:new Date().toISOString(),u.event_id=f(R.event_id)?R.event_id:Se(),u}var O=100,Pe=1e3,J=15e3,Te=1e3,_e=6e4,Q="bily-tracking-script",ee="__bilySdkFacade",h=null,A=false,d="idle",S=O,w=[],P=N(),ue=0,x=null,B=null,k=null;function N(){let e,n,t=new Promise((r,i)=>{e=r,n=i;});return t.catch(()=>{}),{promise:t,reject:n,resolve:e}}function y(e,n,t){if(!(!A||typeof console=="undefined")){if(e==="warn"){t===void 0?console.warn("[Bily]",n):console.warn("[Bily]",n,t);return}t===void 0?console.info("[Bily]",n):console.info("[Bily]",n,t);}}function ne(e){return Number.isFinite(e)?Math.min(Pe,Math.max(1,Math.floor(e!=null?e:O))):O}function te(e){return Number.isFinite(e)?Math.min(_e,Math.max(Te,Math.floor(e!=null?e:J))):J}function z(e){let n=new URL(e),t=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&t))throw new Error("Bily script URLs must use HTTPS (HTTP is allowed for local development).");return n}function re(e){let n=z(e.trim()),t=n.pathname.replace(/\/+$/,"");return n.pathname=`${t}/b.js`.replace(/^\/\//,"/"),n.toString()}function ie(e){let n=e.trim();return z(n),n}function Ue(e){try{return /\.m?js$/i.test(z(e.trim()).pathname)}catch{return false}}function Le(e,n){var r,i,o;if(typeof e=="string"){let c=Ue(e)?ie(e):re(e);return {debug:(n==null?void 0:n.verbose)===true,loadTimeoutMs:te(n==null?void 0:n.loadTimeoutMs),maxQueueSize:ne(n==null?void 0:n.maxQueueSize),nonce:n==null?void 0:n.nonce,scriptUrl:c}}let t=(r=e.scriptUrl)!=null?r:e.trackingDomain;if(!(t!=null&&t.trim()))throw new Error("Provide a Bily scriptUrl or trackingDomain.");return {debug:(o=(i=e.debug)!=null?i:e.verbose)!=null?o:false,loadTimeoutMs:te(e.loadTimeoutMs),maxQueueSize:ne(e.maxQueueSize),nonce:e.nonce,scriptUrl:e.scriptUrl?ie(e.scriptUrl):re(t)}}function M(e,n){try{return new URL(e,document.baseURI).toString()===new URL(n,document.baseURI).toString()}catch{return e===n}}function Ae(e){let n=document.getElementById(Q);if(n instanceof HTMLScriptElement&&M(n.src,e))return n;for(let t of Array.from(document.querySelectorAll("script[src]")))if(M(t.src,e))return t;return null}function ce(e,n){let t=n.channel==="ecommerce"&&typeof e.ecommerce=="function"?e.ecommerce:e.track;try{let r=p(t,n.event,n.payload);r&&typeof r.then=="function"&&Promise.resolve(r).catch(i=>y("warn","Event delivery failed.",i));}catch(r){y("warn","Event delivery failed.",r);}}function xe(e){let n=w;w=[];for(let t of n)ce(e,t);}function $(){x!==null&&window.clearTimeout(x),x=null,B!==null&&window.clearTimeout(B),B=null;}function V(e){return e===ue&&d==="loading"}function I(e,n){if(n!==void 0&&!V(n))return;d==="error"&&(P=N()),$(),d="ready",k=null;let t=L(e);t&&D(e,t),xe(e),P.resolve(),y("info","Ready.");}function T(e,n){n!==void 0&&!V(n)||($(),d="error",k&&k.dataset.bilySdkOwned==="true"&&k.remove(),k=null,P.reject(e),y("warn",e.message));}function j(e){if(!V(e))return;let n=m();if(n){I(n,e);return}B===null&&(B=window.setTimeout(()=>{B=null,j(e);},16));}function Me(e){j(e);}function oe(e,n){let t=++ue;k=e,$(),x=window.setTimeout(()=>{let r=m();if(r){I(r,t);return}T(new Error(`Bily did not become ready within ${n}ms.`),t);},n),e.addEventListener("load",()=>Me(t),{once:true}),e.addEventListener("error",()=>T(new Error(`Unable to load the Bily browser script from ${h!=null?h:"the configured URL"}.`),t),{once:true}),j(t);}function Ce(e){var o,c;let n=document.getElementById(Q);if(n instanceof HTMLScriptElement&&!M(n.src,e.scriptUrl)){T(new Error("A Bily browser script is already installed with a different URL."));return}let t=Ae(e.scriptUrl);if(t){oe(t,e.loadTimeoutMs);let s=m();s&&I(s);return}let r=document.createElement("script");r.id=Q,r.src=e.scriptUrl,r.async=true,r.referrerPolicy="strict-origin-when-cross-origin",r.dataset.bilySdkOwned="true",e.nonce&&(r.nonce=e.nonce),oe(r,e.loadTimeoutMs);let i=(c=(o=document.head)!=null?o:document.body)!=null?c:document.documentElement;if(!i){T(new Error("Bily could not find a document element for its browser script."));return}i.appendChild(r);}function De(e){w.length>=S&&(w.shift(),y("warn",`Event queue reached ${S}; the oldest event was discarded.`)),w.push(e);}function de(e,n,t){if(!a())return;let r;try{r=String(e!=null?e:"").trim();}catch(s){y("warn","Ignored an event whose name could not be read.",s);return}if(!r){y("warn","Ignored an event with an empty name.");return}q();let i=m(),o=L(i),c;try{c={channel:t!=null?t:Z(r)?"ecommerce":"track",event:F(r),payload:{...G(n!=null?n:{},o),source:"web"}};}catch(s){y("warn",`Ignored ${r} because its payload could not be read.`,s);return}i?(d!=="ready"&&I(i),ce(i,c)):De(c);}function q(){if(!a())return;let e=window,n;try{n=e.bily;}catch{return}if((n==null?void 0:n[ee])===true)return;let t={[ee]:true,ecommerce:(r,i)=>de(r,i,"ecommerce"),get:r=>{if(r===E)return ae();let i=m();return p(i==null?void 0:i.get,r)},set:(r,i)=>{let o=m();return p(o==null?void 0:o.set,r,i)},track:(r,i)=>le(r,i)};try{Object.defineProperty(e,"bily",{configurable:!0,value:t,writable:!0});}catch{try{e.bily=t;}catch{}}}function se(e,n){var i;if(!a())return;let t;try{t=Le(e,n);}catch(o){if(h&&(d==="loading"||d==="ready")){y("warn","An invalid second initialization was ignored.");return}try{A=typeof e=="object"&&e!==null&&((i=e.debug)!=null?i:e.verbose)||typeof e=="string"&&(n==null?void 0:n.verbose)===!0;}catch{A=false;}let c=o instanceof Error?o:new Error(String(o));T(c);return}if(h&&!M(h,t.scriptUrl)&&d!=="error"){y("warn","Bily is already initialized with a different script URL; the second initialization was ignored.");return}A=t.debug,S=t.maxQueueSize,w.length>S&&(w=w.slice(-S)),q(),d==="error"&&(P=N(),d="idle"),h=t.scriptUrl;let r=m();if(r){I(r);return}d==="loading"||d==="ready"||(d="loading",Ce(t));}function le(e,n){de(e,n);}function ae(){return a()?(q(),L(m())):null}function Fe(){if(!a())return Promise.resolve();let e=m();return e&&d!=="ready"&&I(e),P.promise}function We(e,n){se(e,n);}
2
- export{ae as getBilyTrackingId,We as init,Fe as ready,le as track};
1
+ var Ae=[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("");function g(){return typeof window!="undefined"&&typeof document!="undefined"}function O(){if(!g())return null;let e=window[Ae];if(!e||typeof e!="object")return null;let n=e;return typeof n.track=="function"?n:null}function k(e,...n){if(typeof e=="function")return e(...n)}var U="sh_client_id",V=null;function Me(){var t,i;let e=globalThis.crypto;if(typeof(e==null?void 0:e.randomUUID)=="function")return e.randomUUID();let n=new Uint8Array(16);if(typeof(e==null?void 0:e.getRandomValues)=="function")e.getRandomValues(n);else for(let o=0;o<n.length;o+=1)n[o]=Math.floor(Math.random()*256);n[6]=((t=n[6])!=null?t:0)&15|64,n[8]=((i=n[8])!=null?i:0)&63|128;let r=Array.from(n,o=>o.toString(16).padStart(2,"0")).join("");return `${r.slice(0,8)}-${r.slice(8,12)}-${r.slice(12,16)}-${r.slice(16,20)}-${r.slice(20)}`}function xe(){if(!g())return null;try{let e=window.localStorage.getItem(U);return (e==null?void 0:e.trim())||null}catch{return null}}function Ce(e){if(g())try{window.localStorage.setItem(U,e);}catch{}}function De(e){try{let n=k(e==null?void 0:e.get,U);return n&&typeof n.then=="function"&&Promise.resolve(n).catch(()=>{}),typeof n=="string"&&n.trim()?n.trim():null}catch{return null}}function ee(e,n){try{let r=k(e==null?void 0:e.set,U,n);r&&typeof r.then=="function"&&Promise.resolve(r).catch(()=>{});}catch{}}function $(e){var r,t;if(!g())return null;let n=(t=(r=V!=null?V:xe())!=null?r:De(e))!=null?t:Me();return V=n,Ce(n),ee(e,n),n}var ae={"Add to Wishlist":"Product Added to Wishlist","Category Viewed":"ViewCategory","Contact Form Submitted":"Contact","New Customer Order":"New Customer Purchase",Pageview:"PageView","Payment Add Address Info":"Checkout Address Info Submitted","Payment Add Contact Info":"AddContactInfo","Payment Add Shipping Info":"AddShippingInfo","Product Added To Wishlist":"Product Added to Wishlist","Remove from Cart":"Product Removed From Cart","Remove from Wishlist":"Product Removed From Wishlist",Search:"Products Searched"},Oe=new Set(["Product List Viewed","Products Searched","Product Clicked","Product Added","Product Added to Wishlist","Product Removed","Product Viewed","Cart Viewed","Checkout Started","Checkout Step Viewed","Checkout Step Completed","Payment Info Entered","Shipping Info Entered","Order Completed","Order Updated","Order Refunded","Order Cancelled","Clicked Promotion","Viewed Promotion"]),ze={dateOfBirth:"dob",email:"em",firstname:"fn",gender:"ge",lastname:"ln",phone:"ph",userId:"uid",userGroup:"user_group"},Fe={city:"ct",country:"cn",state:"st",zip:"zp"};function p(e){return e!=null&&e!==""}function He(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}function I(e,n){return typeof e=="number"&&Number.isFinite(e)?e:n}function Ne(e){return He({brand:e.brand,category:e.category,currency:e.currency,image:e.image,name:e.name,price:I(e.price),product_id:e.id,quantity:I(e.quantity,1),sku:e.sku})}function fe(e){return Array.isArray(e)?e.filter(n=>typeof n=="object"&&n!==null).map(Ne):[]}function ne(e){let n=Object.prototype.hasOwnProperty.call(ae,e)?ae[e]:void 0;return typeof n=="string"?n:e}function me(e){return Oe.has(ne(e))}function Qe(){var r;let e=Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2),n=typeof((r=globalThis.crypto)==null?void 0:r.randomUUID)=="function"?globalThis.crypto.randomUUID():Date.now();return `${e}-${n}`}function ye(e={},n){var ce;let{client:r,order:t,pageTitle:i,products:o,searchQuery:d,sourceUrl:a,userAgent:v,...C}=e,u={...C};if(n&&(u.sh_client_id=n),r){for(let[y,D]of Object.entries(ze)){let R=r[y];p(R)&&(u[D]=R);}if(r.address)for(let[y,D]of Object.entries(Fe)){let R=r.address[y];p(R)&&(u[D]=R);}}if(p(i)&&(u.page_title=i),p(a)&&(u.event_source_url=a,u.dl=a,u.landing_url=a),p(v)&&(u.uA=v),t){u.order_id=t.id;let y=fe(t.products);y.length>0&&(u.products=y);let D=y.reduce((J,q)=>{let Ue=typeof q.price=="number"?q.price:0,_e=typeof q.quantity=="number"?q.quantity:1;return J+Ue*_e},0),R=I(t.total,I(D));R!==void 0?(u.value=R,u.revenue=R):(delete u.value,delete u.revenue),I(t.tax)!==void 0&&(u.tax=t.tax),I(t.shippingFees)!==void 0&&(u.shippingFees=t.shippingFees),I(t.discount)!==void 0&&(u.discount=t.discount),p(t.discountCode)&&(u.discountCode=t.discountCode);let Le=(ce=y.find(J=>p(J.currency)))==null?void 0:ce.currency,de=p(t.currency)?t.currency:Le;p(de)&&(u.currency=de);}else {let y=fe(o);y.length>0&&(u.products=y);}return p(d)&&(u.search_query=d,u.query=d),u.ts=typeof C.ts=="string"?C.ts:new Date().toISOString(),u.event_id=p(C.event_id)?C.event_id:Qe(),u}var te=100,je=1e3,ge=15e3,qe=1e3,Ve=6e4,P="bily-tracking-script",pe="__bilySdkFacade",$e=["",`bily-${[122,97,114,97,122].map(e=>String.fromCharCode(e)).join("")}`,"i.js"].join("/"),E=null,W=false,l="idle",z=te,b=[],A=ie(),F=0,K=null,_=null,c=null,Q=false,X=false,N=false,B=null,f=null,M=false,x=null,w=null,T=null,Y=false;function ie(){let e,n,r=new Promise((t,i)=>{e=t,n=i;});return r.catch(()=>{}),{promise:r,reject:n,resolve:e}}function h(e,n,r){if(!(!W||typeof console=="undefined")){if(e==="warn"){r===void 0?console.warn("[Bily]",n):console.warn("[Bily]",n,r);return}r===void 0?console.info("[Bily]",n):console.info("[Bily]",n,r);}}function we(e){return Number.isFinite(e)?Math.min(je,Math.max(1,Math.floor(e!=null?e:te))):te}function he(e){return Number.isFinite(e)?Math.min(Ve,Math.max(qe,Math.floor(e!=null?e:ge))):ge}function oe(e){let n=new URL(e),r=n.hostname==="localhost"||n.hostname==="127.0.0.1"||n.hostname==="[::1]";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&r))throw new Error("Bily script URLs must use HTTPS (HTTP is allowed for local development).");return n}function Ee(e){let n=oe(e.trim());return n.pathname=$e,n.search="",n.hash="",n.toString()}function be(e){let n=e.trim();return oe(n),n}function We(e){try{return /\.m?js$/i.test(oe(e.trim()).pathname)}catch{return false}}function Ke(e,n){var t,i,o;if(typeof e=="string"){let d=We(e)?be(e):Ee(e);return {debug:(n==null?void 0:n.verbose)===true,loadTimeoutMs:he(n==null?void 0:n.loadTimeoutMs),maxQueueSize:we(n==null?void 0:n.maxQueueSize),nonce:n==null?void 0:n.nonce,scriptUrl:d}}let r=(t=e.scriptUrl)!=null?t:e.trackingDomain;if(!(r!=null&&r.trim()))throw new Error("Provide a Bily scriptUrl or trackingDomain.");return {debug:(o=(i=e.debug)!=null?i:e.verbose)!=null?o:false,loadTimeoutMs:he(e.loadTimeoutMs),maxQueueSize:we(e.maxQueueSize),nonce:e.nonce,scriptUrl:e.scriptUrl?be(e.scriptUrl):Ee(r)}}function S(e,n){try{return new URL(e,document.baseURI).toString()===new URL(n,document.baseURI).toString()}catch{return e===n}}function Be(e){let n=document.getElementById(P);if(n instanceof HTMLScriptElement&&S(n.src,e))return n;for(let r of Array.from(document.querySelectorAll("script[src]")))if(S(r.src,e))return r;return null}function ue(e){if(!e)return false;let n=document.getElementById(P);return n instanceof HTMLScriptElement&&!S(n.src,e)}function G(){return new Error("A Bily browser script is already installed with a different URL.")}function ve(e,n=E,r=false){if(!e||!n)return null;let t=document.getElementById(P);return !e.isConnected||!S(e.src,n)||r&&t!==e||t instanceof HTMLScriptElement&&t!==e?new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."):null}function Xe(){return Y?new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."):c?ve(c,B,N):ve(f,E,M)}function Ye(){return !x||O()===x?null:new Error("The Bily browser runtime no longer matches the active script. Reload the page before initializing again.")}function L(){var e;return (e=Xe())!=null?e:Ye()}function m(e=E){if(Y||!e||L()||!(c!=null?c:f)||X&&!Q)return null;let r=O();return x&&r!==x?null:r&&!ue(e)?r:null}function Se(e,n){let r=n.channel==="ecommerce"&&typeof e.ecommerce=="function"?e.ecommerce:e.track;try{let t=k(r,n.event,n.payload);t&&typeof t.then=="function"&&Promise.resolve(t).catch(i=>h("warn","Event delivery failed.",i));}catch(t){h("warn","Event delivery failed.",t);}}function Ge(e){if(m()!==e)return false;let n=b;b=[];for(let r=0;r<n.length;r+=1){if(m()!==e)return b=[...n.slice(r),...b],false;Se(e,n[r]);}return m()===e}function le(){K!==null&&window.clearTimeout(K),K=null,_!==null&&window.clearTimeout(_),_=null;}function Z(e){return e===F&&l==="loading"}function j(e,n){if(n!==void 0&&!Z(n))return false;let r=L();if(r)return s(r,n,true),false;if(m()!==e)return s(G(),n,true),false;let t=c!=null?c:f,i=c?N:M;le(),x=e;let o=$(e);return o&&ee(e,o),m()!==e||!Ge(e)?(s(new Error("The Bily browser script no longer matches the active URL. Reload the page before initializing again."),n,true),false):(l="ready",f=t,M=i,c=null,Q=false,X=false,N=false,B=null,w=null,T=null,A.resolve(),h("info","Ready."),true)}function s(e,n,r=false){if(n!==void 0&&!Z(n))return;l==="ready"&&(A=ie()),r&&(Y=true),le(),l="error";let t=c!=null?c:f,i=c?B:E;(t==null?void 0:t.dataset.bilySdkOwned)==="true"?t.remove():!r&&t&&i&&(w=t,T=i),r&&(w=null,T=null),c=null,Q=false,X=false,N=false,B=null,f=null,M=false,x=null,A.reject(e),h("warn",e.message);}function H(e){if(!Z(e))return;let n=L();if(n){s(n,e,true);return}let r=m();if(r){j(r,e);return}_===null&&(_=window.setTimeout(()=>{_=null,H(e);},16));}function Ze(e){Z(e)&&(Q=true,H(e));}function re(e,n,r=false){let t=++F;c=e,Q=!r,X=r,N=e.id===P,B=E,f=null,M=false,le(),K=window.setTimeout(()=>{let i=L();if(i){s(i,t,true);return}let o=m();if(o){j(o,t);return}s(new Error(`Bily did not become ready within ${n}ms.`),t);},n),e.addEventListener("load",()=>Ze(t),{once:true}),e.addEventListener("error",()=>s(new Error(`Unable to load the Bily browser script from ${B!=null?B:"the configured URL"}.`),t),{once:true});}function Je(e){let n=document.createElement("script");for(let r of Array.from(e.attributes))n.setAttribute(r.name,r.value);return n.async=e.async,n.referrerPolicy=e.referrerPolicy,e.nonce&&(n.nonce=e.nonce),n}function en(e){var o,d;let n=document.getElementById(P);if(n instanceof HTMLScriptElement&&!S(n.src,e.scriptUrl)){s(G(),void 0,true);return}if(w!=null&&w.isConnected&&T&&S(T,e.scriptUrl)&&S(w.src,e.scriptUrl)){if(O()){s(new Error("An existing Bily browser runtime cannot be matched to the configured script. Reload the page before initializing again."),void 0,true);return}let a=w,v=Je(a);w=null,T=null,re(v,e.loadTimeoutMs,true),a.replaceWith(v),H(F);return}w=null,T=null;let r=Be(e.scriptUrl);if(r){re(r,e.loadTimeoutMs),H(F);return}let t=document.createElement("script");t.id=P,t.src=e.scriptUrl,t.async=true,t.referrerPolicy="strict-origin-when-cross-origin",t.dataset.bilySdkOwned="true",e.nonce&&(t.nonce=e.nonce),re(t,e.loadTimeoutMs,true);let i=(d=(o=document.head)!=null?o:document.body)!=null?d:document.documentElement;if(!i){s(new Error("Bily could not find a document element for its browser script."));return}i.appendChild(t),H(F);}function Re(e){b.length>=z&&(b.shift(),h("warn",`Event queue reached ${z}; the oldest event was discarded.`)),b.push(e);}function ke(e,n,r){if(!g())return;let t;try{t=String(e!=null?e:"").trim();}catch(v){h("warn","Ignored an event whose name could not be read.",v);return}if(!t){h("warn","Ignored an event with an empty name.");return}se();let i=L();i&&s(i,void 0,true);let o=l==="error"?null:m(),d=$(o),a;try{a={channel:r!=null?r:me(t)?"ecommerce":"track",event:ne(t),payload:{...ye(n!=null?n:{},d),source:"web"}};}catch(v){h("warn",`Ignored ${t} because its payload could not be read.`,v);return}if(o&&l!=="error"){if(l!=="ready"&&!j(o)){Re(a);return}if(l==="ready"&&m()===o){Se(o,a);return}}Re(a);}function se(){if(!g())return;let e=window,n;try{n=e.bily;}catch{return}if((n==null?void 0:n[pe])===true)return;let r={[pe]:true,ecommerce:(t,i)=>ke(t,i,"ecommerce"),get:t=>{if(t===U)return Pe();let i=m();return k(i==null?void 0:i.get,t)},set:(t,i)=>{let o=m();return k(o==null?void 0:o.set,t,i)},track:(t,i)=>Te(t,i)};try{Object.defineProperty(e,"bily",{configurable:!0,value:r,writable:!0});}catch{try{e.bily=r;}catch{}}}function Ie(e,n){var o;if(!g())return;let r;try{r=Ke(e,n);}catch(d){if(E&&(l==="loading"||l==="ready")){h("warn","An invalid second initialization was ignored.");return}try{W=typeof e=="object"&&e!==null&&((o=e.debug)!=null?o:e.verbose)||typeof e=="string"&&(n==null?void 0:n.verbose)===!0;}catch{W=false;}let a=d instanceof Error?d:new Error(String(d));s(a);return}if(E&&!S(E,r.scriptUrl)&&l!=="error"){h("warn","Bily is already initialized with a different script URL; the second initialization was ignored.");return}if(Y){h("warn","Reload the page before initializing Bily again.");return}let t=L();if(t){s(t,void 0,true);return}if(W=r.debug,z=r.maxQueueSize,b.length>z&&(b=b.slice(-z)),se(),l==="loading"||l==="ready")return;l==="error"&&(A=ie(),l="idle"),E=r.scriptUrl;let i=O();if(i){if(ue(r.scriptUrl)){s(G(),void 0,true);return}if(f=Be(r.scriptUrl),!f||f===w){s(new Error("An existing Bily browser runtime cannot be matched to the configured script. Reload the page before initializing again."),void 0,true);return}M=(f==null?void 0:f.id)===P,j(i);return}l="loading",en(r);}function Te(e,n){ke(e,n);}function Pe(){return g()?(se(),$(l==="error"?null:m())):null}function nn(){if(!g())return Promise.resolve();let e=L();if(e&&s(e,void 0,true),ue(E)&&s(G(),void 0,true),l==="error")return A.promise;let n=m();return n&&l!=="ready"&&j(n),A.promise}function mn(e,n){Ie(e,n);}export{Pe as getBilyTrackingId,mn as init,nn as ready,Te as track};
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@bilyai/js",
3
- "version": "2.0.1",
3
+ "version": "2.0.4",
4
4
  "description": "Official Bily browser SDK for page views, product events, and custom application events.",
5
5
  "license": "ISC",
6
6
  "author": "Bily <support@bily.ai>",
7
+ "packageManager": "npm@11.16.0",
7
8
  "keywords": [
8
9
  "analytics",
9
10
  "bily",
@@ -12,6 +13,10 @@
12
13
  "tracking"
13
14
  ],
14
15
  "homepage": "https://docs.bily.ai/sdk/javascript",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/the-boring-ai/bily-javascript.git"
19
+ },
15
20
  "bugs": {
16
21
  "email": "support@bily.ai",
17
22
  "url": "https://docs.bily.ai/sdk/troubleshooting"
@@ -55,6 +60,7 @@
55
60
  "test": "vitest run",
56
61
  "test:coverage": "vitest run --coverage",
57
62
  "check:public": "node scripts/check-public-language.mjs",
63
+ "check:framework": "node scripts/run-framework-smoke.mjs",
58
64
  "check:package": "publint && node scripts/check-package-types.mjs",
59
65
  "check:smoke": "node scripts/package-smoke.mjs",
60
66
  "check": "npm run typecheck && npm run test:coverage && npm run build && npm run check:public && npm run check:package && npm run check:smoke",