@indiebob/tracker 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@ This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [0.2.0] — 2026-03-09
10
+
11
+ ### Added
12
+ - **Auto-detection engine** — SDK automatically fires semantic events without manual `track()` calls
13
+ - URL intent detection for 7 categories: signup, login, pricing, checkout, success, onboarding, contact
14
+ - Multilingual URL patterns: EN, ES, FR, DE, PT, IT, NL (e.g. `/registro`, `/connexion`, `/kasse`)
15
+ - Signup vs login detection via `identify()` — first call fires `signup`, subsequent calls fire `login`
16
+ - Form submit tracking on intent pages: `signup_submit`, `login_submit`, `checkout_submit`
17
+ - Outbound click tracking: `outbound_click` event with `{ url, hostname }` properties
18
+ - `data-ib-event` attribute convention for declarative event tracking (zero JS required)
19
+ - `data-ib-*` attributes automatically become event properties
20
+ - `autoDetect` configuration option with per-feature toggles (`dataAttributes`, `formSubmit`, `outboundClicks`)
21
+ - Custom URL pattern overrides for all 7 categories (`signupPaths`, `checkoutPaths`, etc.)
22
+
23
+ ### Changed
24
+ - Funnel queries now include optional Checkout step between Signed Up and Paid
25
+
26
+ ---
27
+
9
28
  ## [1.0.0] — 2026-02-24
10
29
 
11
30
  ### Added
package/README.md CHANGED
@@ -38,6 +38,7 @@ const bob = IndieBob.init({
38
38
  debug: false, // Optional. Logs events to console when true.
39
39
  respectDnt: true, // Optional. Honor browser Do Not Track. Default: true.
40
40
  respectGpc: true, // Optional. Honor Global Privacy Control. Default: true.
41
+ autoDetect: true, // Optional. Auto-detect signups, logins, checkouts, etc. Default: true.
41
42
  })
42
43
  ```
43
44
 
@@ -48,6 +49,7 @@ const bob = IndieBob.init({
48
49
  | `debug` | `boolean` | `false` | Log all events to browser console |
49
50
  | `respectDnt` | `boolean` | `true` | Honor the browser's Do Not Track header |
50
51
  | `respectGpc` | `boolean` | `true` | Honor Global Privacy Control signal (legally binding in CA/GDPR) |
52
+ | `autoDetect` | `boolean \| object` | `true` | Auto-detect user intent from URL patterns, form submissions, outbound clicks, and data attributes. See [Auto-Detection](#auto-detection). |
51
53
 
52
54
  ## API Reference
53
55
 
@@ -149,6 +151,92 @@ bob.flush() // Force-send all queued events immediately
149
151
 
150
152
  ---
151
153
 
154
+ ## Auto-Detection
155
+
156
+ The SDK automatically fires semantic events out of the box — no manual `bob.track()` calls needed for common user journeys. This powers IndieBob's attribution funnels (visit → signup → checkout → paid).
157
+
158
+ ### URL Intent Detection
159
+
160
+ When `bob.page()` is called, the SDK checks the URL path against known patterns (multilingual: EN, ES, FR, DE, PT, IT, NL) and fires the corresponding event:
161
+
162
+ | Event | Triggered By |
163
+ |---|---|
164
+ | `signup_start` | `/signup`, `/register`, `/join`, `/registro`, `/inscription`, `/anmeldung`, ... |
165
+ | `login_view` | `/login`, `/sign-in`, `/iniciar-sesion`, `/connexion`, `/anmelden`, ... |
166
+ | `pricing_view` | `/pricing`, `/plans`, `/precios`, `/tarifs`, `/preise`, ... |
167
+ | `checkout_view` | `/checkout`, `/cart`, `/basket`, `/panier`, `/warenkorb`, `/kasse`, ... |
168
+ | `success_view` | `/success`, `/thank-you`, `/confirmation`, `/danke`, `/merci`, ... |
169
+ | `onboarding_view` | `/onboarding`, `/welcome`, `/getting-started`, `/bienvenido`, ... |
170
+ | `contact_view` | `/contact`, `/contacto`, `/kontakt`, `/nous-contacter`, ... |
171
+
172
+ ### Signup vs Login Detection
173
+
174
+ When `bob.identify()` is called:
175
+ - **First call** for this visitor fires `signup` (new user)
176
+ - **Subsequent calls** fire `login` (returning user)
177
+
178
+ This uses a localStorage flag — no server round-trip needed.
179
+
180
+ ### Form Submit Detection
181
+
182
+ On signup, login, and checkout pages, form submissions are automatically tracked:
183
+ - `signup_submit` — form submitted on a signup page
184
+ - `login_submit` — form submitted on a login page
185
+ - `checkout_submit` — form submitted on a checkout page
186
+
187
+ ### Outbound Click Tracking
188
+
189
+ Clicks on links pointing to external domains automatically fire `outbound_click` with `{ url, hostname }` properties.
190
+
191
+ ### Data Attribute Tracking
192
+
193
+ Add `data-ib-event` to any element for zero-JS custom event tracking:
194
+
195
+ ```html
196
+ <button data-ib-event="add_to_cart" data-ib-plan="pro" data-ib-price="29">
197
+ Add to Cart
198
+ </button>
199
+ ```
200
+
201
+ This fires `track('add_to_cart', { plan: 'pro', price: '29' })` on click. All `data-ib-*` attributes (except `data-ib-event`) become event properties.
202
+
203
+ ### Customizing Auto-Detection
204
+
205
+ Override the default URL patterns or disable specific features:
206
+
207
+ ```ts
208
+ const bob = IndieBob.init({
209
+ projectId: 'proj_abc123',
210
+ autoDetect: {
211
+ // Custom URL patterns (override defaults)
212
+ signupPaths: [/\/my-signup-page/i],
213
+ checkoutPaths: [/\/buy|\/purchase/i],
214
+
215
+ // Disable specific features
216
+ outboundClicks: false,
217
+ formSubmit: false,
218
+ dataAttributes: false,
219
+ },
220
+ })
221
+ ```
222
+
223
+ Set `autoDetect: false` to disable all auto-detection entirely.
224
+
225
+ | Option | Type | Default | Description |
226
+ |---|---|---|---|
227
+ | `signupPaths` | `RegExp[]` | built-in i18n | URL patterns for signup pages |
228
+ | `loginPaths` | `RegExp[]` | built-in i18n | URL patterns for login pages |
229
+ | `pricingPaths` | `RegExp[]` | built-in i18n | URL patterns for pricing pages |
230
+ | `checkoutPaths` | `RegExp[]` | built-in i18n | URL patterns for checkout/cart pages |
231
+ | `successPaths` | `RegExp[]` | built-in i18n | URL patterns for success/thank-you pages |
232
+ | `onboardingPaths` | `RegExp[]` | built-in i18n | URL patterns for onboarding pages |
233
+ | `contactPaths` | `RegExp[]` | built-in i18n | URL patterns for contact pages |
234
+ | `dataAttributes` | `boolean` | `true` | Track clicks on `data-ib-event` elements |
235
+ | `formSubmit` | `boolean` | `true` | Track form submissions on intent pages |
236
+ | `outboundClicks` | `boolean` | `true` | Track clicks on external links |
237
+
238
+ ---
239
+
152
240
  ## Framework Integrations
153
241
 
154
242
  ### Vue / Nuxt
@@ -276,6 +364,25 @@ The SDK respects:
276
364
  | Timezone | `Intl.DateTimeFormat().resolvedOptions().timeZone` | String |
277
365
  | Country | Derived server-side from IP | String (e.g. `'US'`) |
278
366
 
367
+ ### Auto-detected events (when `autoDetect` is enabled)
368
+
369
+ | Event | Trigger |
370
+ |---|---|
371
+ | `signup_start` | User visits a signup/register page |
372
+ | `signup_submit` | User submits a form on a signup page |
373
+ | `signup` | First `identify()` call (new user) |
374
+ | `login_view` | User visits a login page |
375
+ | `login_submit` | User submits a form on a login page |
376
+ | `login` | Subsequent `identify()` call (returning user) |
377
+ | `pricing_view` | User visits a pricing page |
378
+ | `checkout_view` | User visits a checkout/cart page |
379
+ | `checkout_submit` | User submits a form on a checkout page |
380
+ | `success_view` | User visits a success/thank-you page |
381
+ | `onboarding_view` | User visits an onboarding page |
382
+ | `contact_view` | User visits a contact page |
383
+ | `outbound_click` | User clicks an external link |
384
+ | Custom via `data-ib-event` | User clicks an element with the attribute |
385
+
279
386
  ### NOT collected
280
387
 
281
388
  - IP addresses (never stored, used only for country lookup then discarded)
@@ -0,0 +1,2 @@
1
+ var tt=Object.defineProperty,et=Object.defineProperties;var nt=Object.getOwnPropertyDescriptors;var P=Object.getOwnPropertySymbols;var ot=Object.prototype.hasOwnProperty,it=Object.prototype.propertyIsEnumerable;var k=(e,t,n)=>t in e?tt(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,d=(e,t)=>{for(var n in t||(t={}))ot.call(t,n)&&k(e,n,t[n]);if(P)for(var n of P(t))it.call(t,n)&&k(e,n,t[n]);return e},A=(e,t)=>et(e,nt(t));var c=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{f(n.next(a));}catch(u){i(u);}},s=a=>{try{f(n.throw(a));}catch(u){i(u);}},f=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,s);f((n=n.apply(e,t)).next());});var rt="https://www.indiebob.com/api/collect";function N(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:rt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var l="_ib_anon";function m(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(l);return e||(e=m(),localStorage.setItem(l,e)),e}catch(e){try{let t=sessionStorage.getItem(l);return t||(t=m(),sessionStorage.setItem(l,t)),t}catch(t){return m()}}}function U(){try{localStorage.removeItem(l);}catch(e){}try{sessionStorage.removeItem(l);}catch(e){}}var y="_ib_session",I="_ib_session_last";function M(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function S(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),o=sessionStorage.getItem(y),i=n>0&&t-n>18e5;return (!o||i)&&(o=M(),sessionStorage.setItem(y,o)),sessionStorage.setItem(I,String(t)),o}catch(t){return M()}}function F(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var b="_ib_first_utm",q="_ib_last_utm",_="_ib_referrer";function B(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function j(e,t){let n=B(e);try{n&&!localStorage.getItem(b)&&localStorage.setItem(b,JSON.stringify(n)),n&&localStorage.setItem(q,JSON.stringify(n)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(o){}}function L(e){var t;return (t=B(e))!=null?t:void 0}function Y(){try{localStorage.removeItem(b);}catch(e){}try{localStorage.removeItem(q);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var g="_ib_optout",st="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(g,"1");}catch(e){}U(),F(),Y();try{localStorage.removeItem(st);}catch(e){}}function Q(){try{localStorage.removeItem(g);}catch(e){}}function V(){try{return !!localStorage.getItem(g)}catch(e){return false}}var at=[1e3,2e3,4e3];function ct(e){return c(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function E(e,t,n=false){return c(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield ct(at[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var w="_ib_queue",ut=10,lt=5e3,ft=50,h=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=ut&&this.flush();}flush(t=false){return c(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield E({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return c(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield E({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},lt);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-ft);localStorage.setItem(w,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(w);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(w);}catch(t){}}};function H(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var u,C,x,D;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(C=e==null?void 0:e.title)!=null?C:t?"":document.title,r=(x=e==null?void 0:e.referrer)!=null?x:t?"":document.referrer,s=X(),f=H(),a=t?void 0:L(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:A(d({},s),{type:f}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(D=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?D:"UTC",sdkVersion:"0.1.1"}}function J(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var R={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?)/i],pricing:[/\/(pricing|plans|upgrade|subscribe)/i]};function z(e,t){var o,i,r;let n={signup:(o=t==null?void 0:t.signup)!=null?o:R.signup,login:(i=t==null?void 0:t.login)!=null?i:R.login,pricing:(r=t==null?void 0:t.pricing)!=null?r:R.pricing};return n.signup.some(s=>s.test(e))?"signup_start":n.login.some(s=>s.test(e))?"login_view":n.pricing.some(s=>s.test(e))?"pricing_view":null}var O="ib_identified";function $(){return typeof localStorage=="undefined"?true:!localStorage.getItem(O)}function G(){typeof localStorage!="undefined"&&localStorage.setItem(O,"1");}function W(){typeof localStorage!="undefined"&&localStorage.removeItem(O);}var Z=class e{constructor(t){this.cleanupHistory=null;this.config=t,this.queue=new h(t),typeof window!="undefined"&&j(window.location.search,document.referrer);}static init(t){let n=N(t);return new e(n)}page(t){if(!p(this.config))return;let n=T(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let o=n.page.path,i=typeof this.config.autoDetect=="object"?{signup:this.config.autoDetect.signupPaths,login:this.config.autoDetect.loginPaths,pricing:this.config.autoDetect.pricingPaths}:void 0,r=z(o,i);r&&(this.queue.push(this.buildEvent("track",{event:r,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${r} on ${o}`));}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=$(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&G(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){this.queue.flush(),K(),W(),this.userId=void 0,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){Q(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return V()}flush(){return c(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return S()}getConfig(){return Object.freeze(d({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=J(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(o=this.userId)!=null?o:n.userId,sessionId:S(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:T(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};
2
+ export{Z as a};
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var J=Object.defineProperty,z=Object.defineProperties;var G=Object.getOwnPropertyDescriptors;var k=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,Z=Object.prototype.propertyIsEnumerable;var A=(e,t,o)=>t in e?J(e,t,{enumerable:true,configurable:true,writable:true,value:o}):e[t]=o,d=(e,t)=>{for(var o in t||(t={}))W.call(t,o)&&A(e,o,t[o]);if(k)for(var o of k(t))Z.call(t,o)&&A(e,o,t[o]);return e},x=(e,t)=>z(e,G(t));var a=(e,t,o)=>new Promise((n,i)=>{var r=s=>{try{l(o.next(s));}catch(c){i(c);}},g=s=>{try{l(o.throw(s));}catch(c){i(c);}},l=s=>s.done?n(s.value):Promise.resolve(s.value).then(r,g);l((o=o.apply(e,t)).next());});var $="https://www.indiebob.com/api/collect";function D(e){var t,o,n,i;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:$,debug:(o=e.debug)!=null?o:false,respectDnt:(n=e.respectDnt)!=null?n:true,respectGpc:(i=e.respectGpc)!=null?i:true}}var u="_ib_anon";function h(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let o=new Uint8Array(21);crypto.getRandomValues(o);for(let n of o)t+=e[n%e.length];}else for(let o=0;o<21;o++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(u);return e||(e=h(),localStorage.setItem(u,e)),e}catch(e){try{let t=sessionStorage.getItem(u);return t||(t=h(),sessionStorage.setItem(u,t)),t}catch(t){return h()}}}function P(){try{localStorage.removeItem(u);}catch(e){}try{sessionStorage.removeItem(u);}catch(e){}}var y="_ib_session",I="_ib_session_last";function N(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function S(){var e;try{let t=Date.now(),o=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),n=sessionStorage.getItem(y),i=o>0&&t-o>18e5;return (!n||i)&&(n=N(),sessionStorage.setItem(y,n)),sessionStorage.setItem(I,String(t)),n}catch(t){return N()}}function U(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var b="_ib_first_utm",M="_ib_last_utm",_="_ib_referrer";function q(e){let t=new URLSearchParams(e),o={},n=false;return t.has("utm_source")&&(o.source=t.get("utm_source"),n=true),t.has("utm_medium")&&(o.medium=t.get("utm_medium"),n=true),t.has("utm_campaign")&&(o.campaign=t.get("utm_campaign"),n=true),t.has("utm_term")&&(o.term=t.get("utm_term"),n=true),t.has("utm_content")&&(o.content=t.get("utm_content"),n=true),n?o:null}function B(e,t){let o=q(e);try{o&&!localStorage.getItem(b)&&localStorage.setItem(b,JSON.stringify(o)),o&&localStorage.setItem(M,JSON.stringify(o)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(n){}}function F(e){var t;return (t=q(e))!=null?t:void 0}function L(){try{localStorage.removeItem(b);}catch(e){}try{localStorage.removeItem(M);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var p="_ib_optout",tt="_ib_queue";function f(e){try{if(localStorage.getItem(p))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function j(){try{localStorage.setItem(p,"1");}catch(e){}P(),U(),L();try{localStorage.removeItem(tt);}catch(e){}}function Y(){try{localStorage.removeItem(p);}catch(e){}}function K(){try{return !!localStorage.getItem(p)}catch(e){return false}}var et=[1e3,2e3,4e3];function ot(e){return a(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function w(e,t,o=false){return a(this,null,function*(){let n=JSON.stringify(e);if(o&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([n],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield ot(et[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var E="_ib_queue",nt=10,it=5e3,rt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=nt&&this.flush();}flush(t=false){return a(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let o=this.queue.splice(0);(yield w({batch:o},this.config,t))||this.pushToOfflineQueue(o),this.flushing=false;})}flushOfflineQueue(){return a(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield w({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},it);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-rt);localStorage.setItem(E,JSON.stringify(i));}catch(o){}}getOfflineQueue(){try{let t=localStorage.getItem(E);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(E);}catch(t){}}};function Q(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function V(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var c,O,R,C;let t=typeof window=="undefined",o=(c=e==null?void 0:e.path)!=null?c:t?"":window.location.pathname+window.location.search,n=t?"":window.location.href,i=(O=e==null?void 0:e.title)!=null?O:t?"":document.title,r=(R=e==null?void 0:e.referrer)!=null?R:t?"":document.referrer,g=V(),l=Q(),s=t?void 0:F(window.location.search);return {page:{path:o,url:n,title:i,referrer:r},device:x(d({},g),{type:l}),utm:s,locale:t?"en":navigator.language,timezone:t?"UTC":(C=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?C:"UTC",sdkVersion:"0.1.1"}}function H(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...n){t(...n),e();},history.replaceState=function(...n){o(...n);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=o,window.removeEventListener("popstate",e);}}var X=class e{constructor(t){this.cleanupHistory=null;this.config=t,this.queue=new m(t),typeof window!="undefined"&&B(window.location.search,document.referrer);}static init(t){let o=D(t);return new e(o)}page(t){f(this.config)&&this.queue.push(this.buildEvent("page",{context:T(t)}));}track(t,o){f(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:o}));}identify(t,o){f(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:o,userId:t})));}revenue(t){var o;f(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(o=t.currency)!=null?o:"USD",plan:t.plan,type:t.type}}));}optOut(){this.queue.flush(),j(),this.userId=void 0,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){Y(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return K()}flush(){return a(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return S()}getConfig(){return Object.freeze(d({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=H(()=>this.page()),()=>{var o;(o=this.cleanupHistory)==null||o.call(this),this.cleanupHistory=null;}}buildEvent(t,o){var n,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(n=this.userId)!=null?n:o.userId,sessionId:S(),timestamp:new Date().toISOString(),context:(i=o.context)!=null?i:T(),event:o.event,properties:o.properties,traits:o.traits,revenue:o.revenue}}};
2
- exports.IndieBob=X;
1
+ 'use strict';var st=Object.defineProperty,at=Object.defineProperties;var ct=Object.getOwnPropertyDescriptors;var A=Object.getOwnPropertySymbols;var ut=Object.prototype.hasOwnProperty,lt=Object.prototype.propertyIsEnumerable;var C=(e,t,n)=>t in e?st(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))ut.call(t,n)&&C(e,n,t[n]);if(A)for(var n of A(t))lt.call(t,n)&&C(e,n,t[n]);return e},P=(e,t)=>at(e,ct(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var dt="https://www.indiebob.com/api/collect";function D(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:dt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function h(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(d);return e||(e=h(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=h(),sessionStorage.setItem(d,t)),t}catch(t){return h()}}}function N(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var y="_ib_session",b="_ib_session_last";function F(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function I(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(b))!=null?e:"0",10),o=sessionStorage.getItem(y),i=n>0&&t-n>18e5;return (!o||i)&&(o=F(),sessionStorage.setItem(y,o)),sessionStorage.setItem(b,String(t)),o}catch(t){return F()}}function L(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(b);}catch(e){}}var E="_ib_first_utm",M="_ib_last_utm",S="_ib_referrer";function U(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function j(e,t){let n=U(e);try{n&&!localStorage.getItem(E)&&localStorage.setItem(E,JSON.stringify(n)),n&&localStorage.setItem(M,JSON.stringify(n)),t&&!localStorage.getItem(S)&&localStorage.setItem(S,t);}catch(o){}}function q(e){var t;return (t=U(e))!=null?t:void 0}function B(){try{localStorage.removeItem(E);}catch(e){}try{localStorage.removeItem(M);}catch(e){}try{localStorage.removeItem(S);}catch(e){}}var g="_ib_optout",pt="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function Y(){try{localStorage.setItem(g,"1");}catch(e){}N(),L(),B();try{localStorage.removeItem(pt);}catch(e){}}function H(){try{localStorage.removeItem(g);}catch(e){}}function K(){try{return !!localStorage.getItem(g)}catch(e){return false}}var ft=[1e3,2e3,4e3];function gt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function _(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield gt(ft[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var w="_ib_queue",mt=10,ht=5e3,vt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=mt&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield _({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield _({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},ht);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-vt);localStorage.setItem(w,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(w);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(w);}catch(t){}}};function V(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function Q(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var u,R,O,x;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(R=e==null?void 0:e.title)!=null?R:t?"":document.title,r=(O=e==null?void 0:e.referrer)!=null?O:t?"":document.referrer,c=Q(),s=V(),a=t?void 0:q(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:P(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(x=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?x:"UTC",sdkVersion:"0.2.0"}}function z(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var yt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},X={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function J(e,t){var n;for(let o of Object.keys(X))if(((n=t==null?void 0:t[o])!=null?n:yt[o]).some(r=>r.test(e)))return X[o];return null}function $(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function G(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var k="ib_identified";function W(){return typeof localStorage=="undefined"?true:!localStorage.getItem(k)}function Z(){typeof localStorage!="undefined"&&localStorage.setItem(k,"1");}function tt(){typeof localStorage!="undefined"&&localStorage.removeItem(k);}var et="data-ib-event",nt="data-ib-";function ot(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(et);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(nt)&&c.name!==et){let s=c.name.slice(nt.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function it(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var rt=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(j(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=ot((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=it((o,i)=>this.track(o,i)));}}static init(t){let n=D(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=T(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=J(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=$(s);a&&(this.cleanupFormSubmit=G(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=W(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&Z(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),Y(),tt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){H(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return K()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return I()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=z(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(o=this.userId)!=null?o:n.userId,sessionId:I(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:T(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};
2
+ exports.IndieBob=rt;
package/dist/index.d.mts CHANGED
@@ -12,6 +12,37 @@ interface TrackerConfig {
12
12
  respectDnt?: boolean;
13
13
  /** Honor Global Privacy Control signal (legally binding in CA/GDPR). Default: true */
14
14
  respectGpc?: boolean;
15
+ /**
16
+ * Auto-detect user intent from URL patterns and identify() calls.
17
+ * When enabled (default), the SDK automatically fires:
18
+ * - 'signup_start' when user navigates to /signup, /register, /join, /get-started, etc.
19
+ * - 'signup' when identify() is called for the first time (new user)
20
+ * - 'login' when identify() is called for a returning user
21
+ * - 'login_view' when user navigates to /login, /signin, etc.
22
+ * - 'pricing_view' when user navigates to /pricing, /plans, etc.
23
+ *
24
+ * Set to false to disable. Or pass custom regex patterns:
25
+ * @example
26
+ * autoDetect: {
27
+ * signupPaths: [/\/my-custom-signup/i],
28
+ * loginPaths: [/\/my-login/i],
29
+ * }
30
+ */
31
+ autoDetect?: boolean | {
32
+ signupPaths?: RegExp[];
33
+ loginPaths?: RegExp[];
34
+ pricingPaths?: RegExp[];
35
+ checkoutPaths?: RegExp[];
36
+ successPaths?: RegExp[];
37
+ onboardingPaths?: RegExp[];
38
+ contactPaths?: RegExp[];
39
+ /** Track clicks on elements with data-ib-event attribute. Default: true */
40
+ dataAttributes?: boolean;
41
+ /** Track form submissions on intent pages (signup/login/checkout). Default: true */
42
+ formSubmit?: boolean;
43
+ /** Track clicks on outbound links. Default: true */
44
+ outboundClicks?: boolean;
45
+ };
15
46
  }
16
47
  /** Resolved config with all defaults applied. */
17
48
  interface ResolvedConfig {
@@ -20,6 +51,18 @@ interface ResolvedConfig {
20
51
  debug: boolean;
21
52
  respectDnt: boolean;
22
53
  respectGpc: boolean;
54
+ autoDetect: boolean | {
55
+ signupPaths?: RegExp[];
56
+ loginPaths?: RegExp[];
57
+ pricingPaths?: RegExp[];
58
+ checkoutPaths?: RegExp[];
59
+ successPaths?: RegExp[];
60
+ onboardingPaths?: RegExp[];
61
+ contactPaths?: RegExp[];
62
+ dataAttributes?: boolean;
63
+ formSubmit?: boolean;
64
+ outboundClicks?: boolean;
65
+ };
23
66
  }
24
67
  /** The tracking event type. */
25
68
  type EventType = 'page' | 'track' | 'identify' | 'revenue';
@@ -100,6 +143,9 @@ declare class IndieBob {
100
143
  private queue;
101
144
  private userId;
102
145
  private cleanupHistory;
146
+ private cleanupAttributes;
147
+ private cleanupOutbound;
148
+ private cleanupFormSubmit;
103
149
  private constructor();
104
150
  /**
105
151
  * Create a tracker instance. Call once at app startup.
@@ -110,6 +156,7 @@ declare class IndieBob {
110
156
  static init(config: TrackerConfig): IndieBob;
111
157
  /**
112
158
  * Track a page view. Call on every page load and SPA navigation.
159
+ * Auto-detects signup/login/pricing pages and fires semantic events.
113
160
  *
114
161
  * @example
115
162
  * bob.page()
@@ -128,6 +175,10 @@ declare class IndieBob {
128
175
  * Associate the current anonymous visitor with a known user ID.
129
176
  * Call after login or signup.
130
177
  *
178
+ * When autoDetect is enabled (default), this also fires:
179
+ * - 'signup' if this is the first time this visitor is identified (new user)
180
+ * - 'login' if this visitor was previously identified (returning user)
181
+ *
131
182
  * @example
132
183
  * bob.identify('user_123', { email: 'jane@example.com', plan: 'pro' })
133
184
  */
package/dist/index.d.ts CHANGED
@@ -12,6 +12,37 @@ interface TrackerConfig {
12
12
  respectDnt?: boolean;
13
13
  /** Honor Global Privacy Control signal (legally binding in CA/GDPR). Default: true */
14
14
  respectGpc?: boolean;
15
+ /**
16
+ * Auto-detect user intent from URL patterns and identify() calls.
17
+ * When enabled (default), the SDK automatically fires:
18
+ * - 'signup_start' when user navigates to /signup, /register, /join, /get-started, etc.
19
+ * - 'signup' when identify() is called for the first time (new user)
20
+ * - 'login' when identify() is called for a returning user
21
+ * - 'login_view' when user navigates to /login, /signin, etc.
22
+ * - 'pricing_view' when user navigates to /pricing, /plans, etc.
23
+ *
24
+ * Set to false to disable. Or pass custom regex patterns:
25
+ * @example
26
+ * autoDetect: {
27
+ * signupPaths: [/\/my-custom-signup/i],
28
+ * loginPaths: [/\/my-login/i],
29
+ * }
30
+ */
31
+ autoDetect?: boolean | {
32
+ signupPaths?: RegExp[];
33
+ loginPaths?: RegExp[];
34
+ pricingPaths?: RegExp[];
35
+ checkoutPaths?: RegExp[];
36
+ successPaths?: RegExp[];
37
+ onboardingPaths?: RegExp[];
38
+ contactPaths?: RegExp[];
39
+ /** Track clicks on elements with data-ib-event attribute. Default: true */
40
+ dataAttributes?: boolean;
41
+ /** Track form submissions on intent pages (signup/login/checkout). Default: true */
42
+ formSubmit?: boolean;
43
+ /** Track clicks on outbound links. Default: true */
44
+ outboundClicks?: boolean;
45
+ };
15
46
  }
16
47
  /** Resolved config with all defaults applied. */
17
48
  interface ResolvedConfig {
@@ -20,6 +51,18 @@ interface ResolvedConfig {
20
51
  debug: boolean;
21
52
  respectDnt: boolean;
22
53
  respectGpc: boolean;
54
+ autoDetect: boolean | {
55
+ signupPaths?: RegExp[];
56
+ loginPaths?: RegExp[];
57
+ pricingPaths?: RegExp[];
58
+ checkoutPaths?: RegExp[];
59
+ successPaths?: RegExp[];
60
+ onboardingPaths?: RegExp[];
61
+ contactPaths?: RegExp[];
62
+ dataAttributes?: boolean;
63
+ formSubmit?: boolean;
64
+ outboundClicks?: boolean;
65
+ };
23
66
  }
24
67
  /** The tracking event type. */
25
68
  type EventType = 'page' | 'track' | 'identify' | 'revenue';
@@ -100,6 +143,9 @@ declare class IndieBob {
100
143
  private queue;
101
144
  private userId;
102
145
  private cleanupHistory;
146
+ private cleanupAttributes;
147
+ private cleanupOutbound;
148
+ private cleanupFormSubmit;
103
149
  private constructor();
104
150
  /**
105
151
  * Create a tracker instance. Call once at app startup.
@@ -110,6 +156,7 @@ declare class IndieBob {
110
156
  static init(config: TrackerConfig): IndieBob;
111
157
  /**
112
158
  * Track a page view. Call on every page load and SPA navigation.
159
+ * Auto-detects signup/login/pricing pages and fires semantic events.
113
160
  *
114
161
  * @example
115
162
  * bob.page()
@@ -128,6 +175,10 @@ declare class IndieBob {
128
175
  * Associate the current anonymous visitor with a known user ID.
129
176
  * Call after login or signup.
130
177
  *
178
+ * When autoDetect is enabled (default), this also fires:
179
+ * - 'signup' if this is the first time this visitor is identified (new user)
180
+ * - 'login' if this visitor was previously identified (returning user)
181
+ *
131
182
  * @example
132
183
  * bob.identify('user_123', { email: 'jane@example.com', plan: 'pro' })
133
184
  */
@@ -1,2 +1,2 @@
1
- var IndieBob=(function(exports){'use strict';var J=Object.defineProperty,z=Object.defineProperties;var G=Object.getOwnPropertyDescriptors;var k=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,Z=Object.prototype.propertyIsEnumerable;var A=(e,t,o)=>t in e?J(e,t,{enumerable:true,configurable:true,writable:true,value:o}):e[t]=o,d=(e,t)=>{for(var o in t||(t={}))W.call(t,o)&&A(e,o,t[o]);if(k)for(var o of k(t))Z.call(t,o)&&A(e,o,t[o]);return e},x=(e,t)=>z(e,G(t));var a=(e,t,o)=>new Promise((n,i)=>{var r=s=>{try{l(o.next(s));}catch(c){i(c);}},g=s=>{try{l(o.throw(s));}catch(c){i(c);}},l=s=>s.done?n(s.value):Promise.resolve(s.value).then(r,g);l((o=o.apply(e,t)).next());});var $="https://www.indiebob.com/api/collect";function D(e){var t,o,n,i;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:$,debug:(o=e.debug)!=null?o:false,respectDnt:(n=e.respectDnt)!=null?n:true,respectGpc:(i=e.respectGpc)!=null?i:true}}var u="_ib_anon";function h(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let o=new Uint8Array(21);crypto.getRandomValues(o);for(let n of o)t+=e[n%e.length];}else for(let o=0;o<21;o++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(u);return e||(e=h(),localStorage.setItem(u,e)),e}catch(e){try{let t=sessionStorage.getItem(u);return t||(t=h(),sessionStorage.setItem(u,t)),t}catch(t){return h()}}}function P(){try{localStorage.removeItem(u);}catch(e){}try{sessionStorage.removeItem(u);}catch(e){}}var y="_ib_session",I="_ib_session_last";function N(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function S(){var e;try{let t=Date.now(),o=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),n=sessionStorage.getItem(y),i=o>0&&t-o>18e5;return (!n||i)&&(n=N(),sessionStorage.setItem(y,n)),sessionStorage.setItem(I,String(t)),n}catch(t){return N()}}function U(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var b="_ib_first_utm",M="_ib_last_utm",_="_ib_referrer";function q(e){let t=new URLSearchParams(e),o={},n=false;return t.has("utm_source")&&(o.source=t.get("utm_source"),n=true),t.has("utm_medium")&&(o.medium=t.get("utm_medium"),n=true),t.has("utm_campaign")&&(o.campaign=t.get("utm_campaign"),n=true),t.has("utm_term")&&(o.term=t.get("utm_term"),n=true),t.has("utm_content")&&(o.content=t.get("utm_content"),n=true),n?o:null}function B(e,t){let o=q(e);try{o&&!localStorage.getItem(b)&&localStorage.setItem(b,JSON.stringify(o)),o&&localStorage.setItem(M,JSON.stringify(o)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(n){}}function F(e){var t;return (t=q(e))!=null?t:void 0}function L(){try{localStorage.removeItem(b);}catch(e){}try{localStorage.removeItem(M);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var p="_ib_optout",tt="_ib_queue";function f(e){try{if(localStorage.getItem(p))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function j(){try{localStorage.setItem(p,"1");}catch(e){}P(),U(),L();try{localStorage.removeItem(tt);}catch(e){}}function Y(){try{localStorage.removeItem(p);}catch(e){}}function K(){try{return !!localStorage.getItem(p)}catch(e){return false}}var et=[1e3,2e3,4e3];function ot(e){return a(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function w(e,t,o=false){return a(this,null,function*(){let n=JSON.stringify(e);if(o&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([n],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield ot(et[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var E="_ib_queue",nt=10,it=5e3,rt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=nt&&this.flush();}flush(t=false){return a(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let o=this.queue.splice(0);(yield w({batch:o},this.config,t))||this.pushToOfflineQueue(o),this.flushing=false;})}flushOfflineQueue(){return a(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield w({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},it);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-rt);localStorage.setItem(E,JSON.stringify(i));}catch(o){}}getOfflineQueue(){try{let t=localStorage.getItem(E);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(E);}catch(t){}}};function Q(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function V(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var c,O,R,C;let t=typeof window=="undefined",o=(c=e==null?void 0:e.path)!=null?c:t?"":window.location.pathname+window.location.search,n=t?"":window.location.href,i=(O=e==null?void 0:e.title)!=null?O:t?"":document.title,r=(R=e==null?void 0:e.referrer)!=null?R:t?"":document.referrer,g=V(),l=Q(),s=t?void 0:F(window.location.search);return {page:{path:o,url:n,title:i,referrer:r},device:x(d({},g),{type:l}),utm:s,locale:t?"en":navigator.language,timezone:t?"UTC":(C=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?C:"UTC",sdkVersion:"0.1.1"}}function H(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...n){t(...n),e();},history.replaceState=function(...n){o(...n);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=o,window.removeEventListener("popstate",e);}}var X=class e{constructor(t){this.cleanupHistory=null;this.config=t,this.queue=new m(t),typeof window!="undefined"&&B(window.location.search,document.referrer);}static init(t){let o=D(t);return new e(o)}page(t){f(this.config)&&this.queue.push(this.buildEvent("page",{context:T(t)}));}track(t,o){f(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:o}));}identify(t,o){f(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:o,userId:t})));}revenue(t){var o;f(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(o=t.currency)!=null?o:"USD",plan:t.plan,type:t.type}}));}optOut(){this.queue.flush(),j(),this.userId=void 0,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){Y(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return K()}flush(){return a(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return S()}getConfig(){return Object.freeze(d({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=H(()=>this.page()),()=>{var o;(o=this.cleanupHistory)==null||o.call(this),this.cleanupHistory=null;}}buildEvent(t,o){var n,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(n=this.userId)!=null?n:o.userId,sessionId:S(),timestamp:new Date().toISOString(),context:(i=o.context)!=null?i:T(),event:o.event,properties:o.properties,traits:o.traits,revenue:o.revenue}}};
2
- exports.IndieBob=X;return exports;})({});
1
+ var IndieBob=(function(exports){'use strict';var st=Object.defineProperty,at=Object.defineProperties;var ct=Object.getOwnPropertyDescriptors;var A=Object.getOwnPropertySymbols;var ut=Object.prototype.hasOwnProperty,lt=Object.prototype.propertyIsEnumerable;var C=(e,t,n)=>t in e?st(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))ut.call(t,n)&&C(e,n,t[n]);if(A)for(var n of A(t))lt.call(t,n)&&C(e,n,t[n]);return e},P=(e,t)=>at(e,ct(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var dt="https://www.indiebob.com/api/collect";function D(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:dt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function h(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(d);return e||(e=h(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=h(),sessionStorage.setItem(d,t)),t}catch(t){return h()}}}function N(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var y="_ib_session",b="_ib_session_last";function F(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function I(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(b))!=null?e:"0",10),o=sessionStorage.getItem(y),i=n>0&&t-n>18e5;return (!o||i)&&(o=F(),sessionStorage.setItem(y,o)),sessionStorage.setItem(b,String(t)),o}catch(t){return F()}}function L(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(b);}catch(e){}}var E="_ib_first_utm",M="_ib_last_utm",S="_ib_referrer";function U(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function j(e,t){let n=U(e);try{n&&!localStorage.getItem(E)&&localStorage.setItem(E,JSON.stringify(n)),n&&localStorage.setItem(M,JSON.stringify(n)),t&&!localStorage.getItem(S)&&localStorage.setItem(S,t);}catch(o){}}function q(e){var t;return (t=U(e))!=null?t:void 0}function B(){try{localStorage.removeItem(E);}catch(e){}try{localStorage.removeItem(M);}catch(e){}try{localStorage.removeItem(S);}catch(e){}}var g="_ib_optout",pt="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function Y(){try{localStorage.setItem(g,"1");}catch(e){}N(),L(),B();try{localStorage.removeItem(pt);}catch(e){}}function H(){try{localStorage.removeItem(g);}catch(e){}}function K(){try{return !!localStorage.getItem(g)}catch(e){return false}}var ft=[1e3,2e3,4e3];function gt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function _(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield gt(ft[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var w="_ib_queue",mt=10,ht=5e3,vt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=mt&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield _({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield _({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},ht);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-vt);localStorage.setItem(w,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(w);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(w);}catch(t){}}};function V(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function Q(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var u,R,O,x;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(R=e==null?void 0:e.title)!=null?R:t?"":document.title,r=(O=e==null?void 0:e.referrer)!=null?O:t?"":document.referrer,c=Q(),s=V(),a=t?void 0:q(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:P(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(x=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?x:"UTC",sdkVersion:"0.2.0"}}function z(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var yt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},X={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function J(e,t){var n;for(let o of Object.keys(X))if(((n=t==null?void 0:t[o])!=null?n:yt[o]).some(r=>r.test(e)))return X[o];return null}function $(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function G(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var k="ib_identified";function W(){return typeof localStorage=="undefined"?true:!localStorage.getItem(k)}function Z(){typeof localStorage!="undefined"&&localStorage.setItem(k,"1");}function tt(){typeof localStorage!="undefined"&&localStorage.removeItem(k);}var et="data-ib-event",nt="data-ib-";function ot(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(et);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(nt)&&c.name!==et){let s=c.name.slice(nt.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function it(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var rt=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(j(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=ot((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=it((o,i)=>this.track(o,i)));}}static init(t){let n=D(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=T(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=J(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=$(s);a&&(this.cleanupFormSubmit=G(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=W(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&Z(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),Y(),tt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){H(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return K()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return I()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=z(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(o=this.userId)!=null?o:n.userId,sessionId:I(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:T(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};
2
+ exports.IndieBob=rt;return exports;})({});
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- export{a as IndieBob}from'./chunk-4IK5PET7.js';
1
+ var st=Object.defineProperty,at=Object.defineProperties;var ct=Object.getOwnPropertyDescriptors;var A=Object.getOwnPropertySymbols;var ut=Object.prototype.hasOwnProperty,lt=Object.prototype.propertyIsEnumerable;var C=(e,t,n)=>t in e?st(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))ut.call(t,n)&&C(e,n,t[n]);if(A)for(var n of A(t))lt.call(t,n)&&C(e,n,t[n]);return e},P=(e,t)=>at(e,ct(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var dt="https://www.indiebob.com/api/collect";function D(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:dt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function h(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function v(){try{let e=localStorage.getItem(d);return e||(e=h(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=h(),sessionStorage.setItem(d,t)),t}catch(t){return h()}}}function N(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var y="_ib_session",b="_ib_session_last";function F(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function I(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(b))!=null?e:"0",10),o=sessionStorage.getItem(y),i=n>0&&t-n>18e5;return (!o||i)&&(o=F(),sessionStorage.setItem(y,o)),sessionStorage.setItem(b,String(t)),o}catch(t){return F()}}function L(){try{sessionStorage.removeItem(y);}catch(e){}try{sessionStorage.removeItem(b);}catch(e){}}var E="_ib_first_utm",M="_ib_last_utm",S="_ib_referrer";function U(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function j(e,t){let n=U(e);try{n&&!localStorage.getItem(E)&&localStorage.setItem(E,JSON.stringify(n)),n&&localStorage.setItem(M,JSON.stringify(n)),t&&!localStorage.getItem(S)&&localStorage.setItem(S,t);}catch(o){}}function q(e){var t;return (t=U(e))!=null?t:void 0}function B(){try{localStorage.removeItem(E);}catch(e){}try{localStorage.removeItem(M);}catch(e){}try{localStorage.removeItem(S);}catch(e){}}var g="_ib_optout",pt="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function Y(){try{localStorage.setItem(g,"1");}catch(e){}N(),L(),B();try{localStorage.removeItem(pt);}catch(e){}}function H(){try{localStorage.removeItem(g);}catch(e){}}function K(){try{return !!localStorage.getItem(g)}catch(e){return false}}var ft=[1e3,2e3,4e3];function gt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function _(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield gt(ft[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var w="_ib_queue",mt=10,ht=5e3,vt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=mt&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield _({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield _({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},ht);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-vt);localStorage.setItem(w,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(w);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(w);}catch(t){}}};function V(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function Q(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function T(e){var u,R,O,x;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(R=e==null?void 0:e.title)!=null?R:t?"":document.title,r=(O=e==null?void 0:e.referrer)!=null?O:t?"":document.referrer,c=Q(),s=V(),a=t?void 0:q(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:P(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(x=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?x:"UTC",sdkVersion:"0.2.0"}}function z(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var yt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},X={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function J(e,t){var n;for(let o of Object.keys(X))if(((n=t==null?void 0:t[o])!=null?n:yt[o]).some(r=>r.test(e)))return X[o];return null}function $(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function G(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var k="ib_identified";function W(){return typeof localStorage=="undefined"?true:!localStorage.getItem(k)}function Z(){typeof localStorage!="undefined"&&localStorage.setItem(k,"1");}function tt(){typeof localStorage!="undefined"&&localStorage.removeItem(k);}var et="data-ib-event",nt="data-ib-";function ot(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(et);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(nt)&&c.name!==et){let s=c.name.slice(nt.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function it(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var rt=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(j(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=ot((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=it((o,i)=>this.track(o,i)));}}static init(t){let n=D(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=T(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=J(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=$(s);a&&(this.cleanupFormSubmit=G(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=W(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&Z(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),Y(),tt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){H(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return K()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return I()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=z(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:v(),userId:(o=this.userId)!=null?o:n.userId,sessionId:I(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:T(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};
2
+ export{rt as IndieBob};
package/dist/server.d.mts CHANGED
@@ -12,6 +12,37 @@ interface TrackerConfig {
12
12
  respectDnt?: boolean;
13
13
  /** Honor Global Privacy Control signal (legally binding in CA/GDPR). Default: true */
14
14
  respectGpc?: boolean;
15
+ /**
16
+ * Auto-detect user intent from URL patterns and identify() calls.
17
+ * When enabled (default), the SDK automatically fires:
18
+ * - 'signup_start' when user navigates to /signup, /register, /join, /get-started, etc.
19
+ * - 'signup' when identify() is called for the first time (new user)
20
+ * - 'login' when identify() is called for a returning user
21
+ * - 'login_view' when user navigates to /login, /signin, etc.
22
+ * - 'pricing_view' when user navigates to /pricing, /plans, etc.
23
+ *
24
+ * Set to false to disable. Or pass custom regex patterns:
25
+ * @example
26
+ * autoDetect: {
27
+ * signupPaths: [/\/my-custom-signup/i],
28
+ * loginPaths: [/\/my-login/i],
29
+ * }
30
+ */
31
+ autoDetect?: boolean | {
32
+ signupPaths?: RegExp[];
33
+ loginPaths?: RegExp[];
34
+ pricingPaths?: RegExp[];
35
+ checkoutPaths?: RegExp[];
36
+ successPaths?: RegExp[];
37
+ onboardingPaths?: RegExp[];
38
+ contactPaths?: RegExp[];
39
+ /** Track clicks on elements with data-ib-event attribute. Default: true */
40
+ dataAttributes?: boolean;
41
+ /** Track form submissions on intent pages (signup/login/checkout). Default: true */
42
+ formSubmit?: boolean;
43
+ /** Track clicks on outbound links. Default: true */
44
+ outboundClicks?: boolean;
45
+ };
15
46
  }
16
47
 
17
48
  /**
package/dist/server.d.ts CHANGED
@@ -12,6 +12,37 @@ interface TrackerConfig {
12
12
  respectDnt?: boolean;
13
13
  /** Honor Global Privacy Control signal (legally binding in CA/GDPR). Default: true */
14
14
  respectGpc?: boolean;
15
+ /**
16
+ * Auto-detect user intent from URL patterns and identify() calls.
17
+ * When enabled (default), the SDK automatically fires:
18
+ * - 'signup_start' when user navigates to /signup, /register, /join, /get-started, etc.
19
+ * - 'signup' when identify() is called for the first time (new user)
20
+ * - 'login' when identify() is called for a returning user
21
+ * - 'login_view' when user navigates to /login, /signin, etc.
22
+ * - 'pricing_view' when user navigates to /pricing, /plans, etc.
23
+ *
24
+ * Set to false to disable. Or pass custom regex patterns:
25
+ * @example
26
+ * autoDetect: {
27
+ * signupPaths: [/\/my-custom-signup/i],
28
+ * loginPaths: [/\/my-login/i],
29
+ * }
30
+ */
31
+ autoDetect?: boolean | {
32
+ signupPaths?: RegExp[];
33
+ loginPaths?: RegExp[];
34
+ pricingPaths?: RegExp[];
35
+ checkoutPaths?: RegExp[];
36
+ successPaths?: RegExp[];
37
+ onboardingPaths?: RegExp[];
38
+ contactPaths?: RegExp[];
39
+ /** Track clicks on elements with data-ib-event attribute. Default: true */
40
+ dataAttributes?: boolean;
41
+ /** Track form submissions on intent pages (signup/login/checkout). Default: true */
42
+ formSubmit?: boolean;
43
+ /** Track clicks on outbound links. Default: true */
44
+ outboundClicks?: boolean;
45
+ };
15
46
  }
16
47
 
17
48
  /**
package/dist/server.js CHANGED
@@ -13,7 +13,8 @@ function resolveConfig(input) {
13
13
  endpoint: input.endpoint ?? DEFAULT_ENDPOINT,
14
14
  debug: input.debug ?? false,
15
15
  respectDnt: input.respectDnt ?? true,
16
- respectGpc: input.respectGpc ?? true
16
+ respectGpc: input.respectGpc ?? true,
17
+ autoDetect: input.autoDetect ?? true
17
18
  };
18
19
  }
19
20
 
@@ -79,7 +80,7 @@ var IndieBobServer = class _IndieBobServer {
79
80
  device: { width: 0, height: 0, type: "desktop" },
80
81
  locale: "en",
81
82
  timezone: "UTC",
82
- sdkVersion: "0.1.1"
83
+ sdkVersion: "0.2.0"
83
84
  },
84
85
  event: extras.event,
85
86
  properties: extras.properties,
package/dist/server.mjs CHANGED
@@ -11,7 +11,8 @@ function resolveConfig(input) {
11
11
  endpoint: input.endpoint ?? DEFAULT_ENDPOINT,
12
12
  debug: input.debug ?? false,
13
13
  respectDnt: input.respectDnt ?? true,
14
- respectGpc: input.respectGpc ?? true
14
+ respectGpc: input.respectGpc ?? true,
15
+ autoDetect: input.autoDetect ?? true
15
16
  };
16
17
  }
17
18
 
@@ -77,7 +78,7 @@ var IndieBobServer = class _IndieBobServer {
77
78
  device: { width: 0, height: 0, type: "desktop" },
78
79
  locale: "en",
79
80
  timezone: "UTC",
80
- sdkVersion: "0.1.1"
81
+ sdkVersion: "0.2.0"
81
82
  },
82
83
  event: extras.event,
83
84
  properties: extras.properties,
package/dist/vue.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var z=Object.defineProperty,G=Object.defineProperties;var W=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var $=Object.prototype.hasOwnProperty,Z=Object.prototype.propertyIsEnumerable;var P=(t,e,o)=>e in t?z(t,e,{enumerable:true,configurable:true,writable:true,value:o}):t[e]=o,d=(t,e)=>{for(var o in e||(e={}))$.call(e,o)&&P(t,o,e[o]);if(x)for(var o of x(e))Z.call(e,o)&&P(t,o,e[o]);return t},D=(t,e)=>G(t,W(e));var a=(t,e,o)=>new Promise((n,r)=>{var i=s=>{try{l(o.next(s));}catch(u){r(u);}},h=s=>{try{l(o.throw(s));}catch(u){r(u);}},l=s=>s.done?n(s.value):Promise.resolve(s.value).then(i,h);l((o=o.apply(t,e)).next());});var ee="https://www.indiebob.com/api/collect";function N(t){var e,o,n,r;if(!t.projectId||!t.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${t.projectId}". Must start with "proj_".`);return {projectId:t.projectId,endpoint:(e=t.endpoint)!=null?e:ee,debug:(o=t.debug)!=null?o:false,respectDnt:(n=t.respectDnt)!=null?n:true,respectGpc:(r=t.respectGpc)!=null?r:true}}var c="_ib_anon";function y(){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",e="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let o=new Uint8Array(21);crypto.getRandomValues(o);for(let n of o)e+=t[n%t.length];}else for(let o=0;o<21;o++)e+=t[Math.floor(Math.random()*t.length)];return e}function v(){try{let t=localStorage.getItem(c);return t||(t=y(),localStorage.setItem(c,t)),t}catch(t){try{let e=sessionStorage.getItem(c);return e||(e=y(),sessionStorage.setItem(c,e)),e}catch(e){return y()}}}function B(){try{localStorage.removeItem(c);}catch(t){}try{sessionStorage.removeItem(c);}catch(t){}}var I="_ib_session",S="_ib_session_last";function U(){try{return crypto.randomUUID()}catch(t){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function b(){var t;try{let e=Date.now(),o=parseInt((t=sessionStorage.getItem(S))!=null?t:"0",10),n=sessionStorage.getItem(I),r=o>0&&e-o>18e5;return (!n||r)&&(n=U(),sessionStorage.setItem(I,n)),sessionStorage.setItem(S,String(e)),n}catch(e){return U()}}function M(){try{sessionStorage.removeItem(I);}catch(t){}try{sessionStorage.removeItem(S);}catch(t){}}var _="_ib_first_utm",q="_ib_last_utm",w="_ib_referrer";function F(t){let e=new URLSearchParams(t),o={},n=false;return e.has("utm_source")&&(o.source=e.get("utm_source"),n=true),e.has("utm_medium")&&(o.medium=e.get("utm_medium"),n=true),e.has("utm_campaign")&&(o.campaign=e.get("utm_campaign"),n=true),e.has("utm_term")&&(o.term=e.get("utm_term"),n=true),e.has("utm_content")&&(o.content=e.get("utm_content"),n=true),n?o:null}function L(t,e){let o=F(t);try{o&&!localStorage.getItem(_)&&localStorage.setItem(_,JSON.stringify(o)),o&&localStorage.setItem(q,JSON.stringify(o)),e&&!localStorage.getItem(w)&&localStorage.setItem(w,e);}catch(n){}}function j(t){var e;return (e=F(t))!=null?e:void 0}function Y(){try{localStorage.removeItem(_);}catch(t){}try{localStorage.removeItem(q);}catch(t){}try{localStorage.removeItem(w);}catch(t){}}var p="_ib_optout",te="_ib_queue";function f(t){try{if(localStorage.getItem(p))return !1}catch(e){}return !(t.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||t.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(p,"1");}catch(t){}B(),M(),Y();try{localStorage.removeItem(te);}catch(t){}}function Q(){try{localStorage.removeItem(p);}catch(t){}}function V(){try{return !!localStorage.getItem(p)}catch(t){return false}}var oe=[1e3,2e3,4e3];function ne(t){return a(this,null,function*(){return new Promise(e=>setTimeout(e,t))})}function T(t,e,o=false){return a(this,null,function*(){let n=JSON.stringify(t);if(o&&typeof navigator!="undefined"&&navigator.sendBeacon){let r=new Blob([n],{type:"application/json"}),i=navigator.sendBeacon(e.endpoint,r);return e.debug&&console.log("[IndieBob] sendBeacon:",i,t.batch.length,"events"),i}for(let r=0;r<3;r++){try{let i=yield fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0});if(i.ok)return e.debug&&console.log("[IndieBob] sent:",t.batch.length,"events"),!0;if(i.status>=400&&i.status<500)return e.debug&&console.warn("[IndieBob] 4xx error, not retrying:",i.status),!1}catch(i){e.debug&&console.warn("[IndieBob] fetch error (attempt",r+1,"):",i);}r<2&&(yield ne(oe[r]));}return e.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var E="_ib_queue",re=10,ie=5e3,se=50,m=class{constructor(e){this.queue=[];this.timer=null;this.flushing=false;this.config=e,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(e){this.queue.push(e),this.queue.length>=re&&this.flush();}flush(e=false){return a(this,null,function*(){if(this.flushing&&!e||this.queue.length===0)return;this.flushing=true;let o=this.queue.splice(0);(yield T({batch:o},this.config,e))||this.pushToOfflineQueue(o),this.flushing=false;})}flushOfflineQueue(){return a(this,null,function*(){let e=this.getOfflineQueue();if(e.length===0)return;this.clearOfflineQueue(),yield T({batch:e},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},ie);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(e){try{let r=[...this.getOfflineQueue(),...e].slice(-se);localStorage.setItem(E,JSON.stringify(r));}catch(o){}}getOfflineQueue(){try{let e=localStorage.getItem(E);return e?JSON.parse(e):[]}catch(e){return []}}clearOfflineQueue(){try{localStorage.removeItem(E);}catch(e){}}};function H(){if(typeof window=="undefined")return "desktop";let t=window.innerWidth;return t<=768?"mobile":t<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function R(t){var u,C,k,A;let e=typeof window=="undefined",o=(u=t==null?void 0:t.path)!=null?u:e?"":window.location.pathname+window.location.search,n=e?"":window.location.href,r=(C=t==null?void 0:t.title)!=null?C:e?"":document.title,i=(k=t==null?void 0:t.referrer)!=null?k:e?"":document.referrer,h=X(),l=H(),s=e?void 0:j(window.location.search);return {page:{path:o,url:n,title:r,referrer:i},device:D(d({},h),{type:l}),utm:s,locale:e?"en":navigator.language,timezone:e?"UTC":(A=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?A:"UTC",sdkVersion:"0.1.1"}}function J(t){if(typeof window=="undefined")return ()=>{};let e=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...n){e(...n),t();},history.replaceState=function(...n){o(...n);},window.addEventListener("popstate",t),()=>{history.pushState=e,history.replaceState=o,window.removeEventListener("popstate",t);}}var g=class t{constructor(e){this.cleanupHistory=null;this.config=e,this.queue=new m(e),typeof window!="undefined"&&L(window.location.search,document.referrer);}static init(e){let o=N(e);return new t(o)}page(e){f(this.config)&&this.queue.push(this.buildEvent("page",{context:R(e)}));}track(e,o){f(this.config)&&this.queue.push(this.buildEvent("track",{event:e,properties:o}));}identify(e,o){f(this.config)&&(this.userId=e,this.queue.push(this.buildEvent("identify",{traits:o,userId:e})));}revenue(e){var o;f(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:e.amount,currency:(o=e.currency)!=null?o:"USD",plan:e.plan,type:e.type}}));}optOut(){this.queue.flush(),K(),this.userId=void 0,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){Q(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return V()}flush(){return a(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return b()}getConfig(){return Object.freeze(d({},this.config))}enableAutoPage(){var e;return (e=this.cleanupHistory)==null||e.call(this),this.cleanupHistory=J(()=>this.page()),()=>{var o;(o=this.cleanupHistory)==null||o.call(this),this.cleanupHistory=null;}}buildEvent(e,o){var n,r;return {v:1,projectId:this.config.projectId,type:e,anonymousId:v(),userId:(n=this.userId)!=null?n:o.userId,sessionId:b(),timestamp:new Date().toISOString(),context:(r=o.context)!=null?r:R(),event:o.event,properties:o.properties,traits:o.traits,revenue:o.revenue}}};var ae=Symbol("indiebob"),O=null,Fe={install(t,e){let o=g.init(e);O=o,t.provide(ae,o),t.config.globalProperties.$bob=o;let n=t.config.globalProperties.$router;n&&n.afterEach(()=>{o.page();});}};function Le(){if(O)return O;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
2
- exports.IndieBob=g;exports.IndieBobPlugin=Fe;exports.useTracker=Le;
1
+ 'use strict';var at=Object.defineProperty,ct=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var P=Object.getOwnPropertySymbols;var lt=Object.prototype.hasOwnProperty,dt=Object.prototype.propertyIsEnumerable;var D=(e,t,n)=>t in e?at(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))lt.call(t,n)&&D(e,n,t[n]);if(P)for(var n of P(t))dt.call(t,n)&&D(e,n,t[n]);return e},N=(e,t)=>ct(e,ut(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var pt="https://www.indiebob.com/api/collect";function F(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:pt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function v(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function y(){try{let e=localStorage.getItem(d);return e||(e=v(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=v(),sessionStorage.setItem(d,t)),t}catch(t){return v()}}}function L(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var b="_ib_session",I="_ib_session_last";function B(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function E(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),o=sessionStorage.getItem(b),i=n>0&&t-n>18e5;return (!o||i)&&(o=B(),sessionStorage.setItem(b,o)),sessionStorage.setItem(I,String(t)),o}catch(t){return B()}}function M(){try{sessionStorage.removeItem(b);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var S="_ib_first_utm",U="_ib_last_utm",_="_ib_referrer";function j(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function q(e,t){let n=j(e);try{n&&!localStorage.getItem(S)&&localStorage.setItem(S,JSON.stringify(n)),n&&localStorage.setItem(U,JSON.stringify(n)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(o){}}function Y(e){var t;return (t=j(e))!=null?t:void 0}function H(){try{localStorage.removeItem(S);}catch(e){}try{localStorage.removeItem(U);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var g="_ib_optout",ft="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(g,"1");}catch(e){}L(),M(),H();try{localStorage.removeItem(ft);}catch(e){}}function V(){try{localStorage.removeItem(g);}catch(e){}}function Q(){try{return !!localStorage.getItem(g)}catch(e){return false}}var gt=[1e3,2e3,4e3];function mt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function w(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield mt(gt[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var T="_ib_queue",ht=10,vt=5e3,yt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=ht&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield w({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield w({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},vt);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-yt);localStorage.setItem(T,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(T);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(T);}catch(t){}}};function z(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function k(e){var u,x,A,C;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(x=e==null?void 0:e.title)!=null?x:t?"":document.title,r=(A=e==null?void 0:e.referrer)!=null?A:t?"":document.referrer,c=X(),s=z(),a=t?void 0:Y(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:N(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(C=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?C:"UTC",sdkVersion:"0.2.0"}}function $(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var bt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},J={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function G(e,t){var n;for(let o of Object.keys(J))if(((n=t==null?void 0:t[o])!=null?n:bt[o]).some(r=>r.test(e)))return J[o];return null}function W(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function Z(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var R="ib_identified";function tt(){return typeof localStorage=="undefined"?true:!localStorage.getItem(R)}function et(){typeof localStorage!="undefined"&&localStorage.setItem(R,"1");}function nt(){typeof localStorage!="undefined"&&localStorage.removeItem(R);}var ot="data-ib-event",it="data-ib-";function rt(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(ot);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(it)&&c.name!==ot){let s=c.name.slice(it.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function st(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var h=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(q(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=rt((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=st((o,i)=>this.track(o,i)));}}static init(t){let n=F(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=k(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=G(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=W(s);a&&(this.cleanupFormSubmit=Z(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=tt(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&et(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),K(),nt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){V(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return Q()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return y()}getSessionId(){return E()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=$(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:y(),userId:(o=this.userId)!=null?o:n.userId,sessionId:E(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:k(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};var It=Symbol("indiebob"),O=null,ie={install(e,t){let n=h.init(t);O=n,e.provide(It,n),e.config.globalProperties.$bob=n;let o=e.config.globalProperties.$router;o&&o.afterEach(()=>{n.page();});}};function re(){if(O)return O;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
2
+ exports.IndieBob=h;exports.IndieBobPlugin=ie;exports.useTracker=re;
@@ -1,2 +1,2 @@
1
- var IndieBob=(function(exports){'use strict';var z=Object.defineProperty,G=Object.defineProperties;var W=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var $=Object.prototype.hasOwnProperty,Z=Object.prototype.propertyIsEnumerable;var P=(t,e,o)=>e in t?z(t,e,{enumerable:true,configurable:true,writable:true,value:o}):t[e]=o,d=(t,e)=>{for(var o in e||(e={}))$.call(e,o)&&P(t,o,e[o]);if(x)for(var o of x(e))Z.call(e,o)&&P(t,o,e[o]);return t},D=(t,e)=>G(t,W(e));var a=(t,e,o)=>new Promise((n,r)=>{var i=s=>{try{l(o.next(s));}catch(u){r(u);}},h=s=>{try{l(o.throw(s));}catch(u){r(u);}},l=s=>s.done?n(s.value):Promise.resolve(s.value).then(i,h);l((o=o.apply(t,e)).next());});var ee="https://www.indiebob.com/api/collect";function N(t){var e,o,n,r;if(!t.projectId||!t.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${t.projectId}". Must start with "proj_".`);return {projectId:t.projectId,endpoint:(e=t.endpoint)!=null?e:ee,debug:(o=t.debug)!=null?o:false,respectDnt:(n=t.respectDnt)!=null?n:true,respectGpc:(r=t.respectGpc)!=null?r:true}}var c="_ib_anon";function y(){let t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",e="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let o=new Uint8Array(21);crypto.getRandomValues(o);for(let n of o)e+=t[n%t.length];}else for(let o=0;o<21;o++)e+=t[Math.floor(Math.random()*t.length)];return e}function v(){try{let t=localStorage.getItem(c);return t||(t=y(),localStorage.setItem(c,t)),t}catch(t){try{let e=sessionStorage.getItem(c);return e||(e=y(),sessionStorage.setItem(c,e)),e}catch(e){return y()}}}function B(){try{localStorage.removeItem(c);}catch(t){}try{sessionStorage.removeItem(c);}catch(t){}}var I="_ib_session",S="_ib_session_last";function U(){try{return crypto.randomUUID()}catch(t){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function b(){var t;try{let e=Date.now(),o=parseInt((t=sessionStorage.getItem(S))!=null?t:"0",10),n=sessionStorage.getItem(I),r=o>0&&e-o>18e5;return (!n||r)&&(n=U(),sessionStorage.setItem(I,n)),sessionStorage.setItem(S,String(e)),n}catch(e){return U()}}function M(){try{sessionStorage.removeItem(I);}catch(t){}try{sessionStorage.removeItem(S);}catch(t){}}var _="_ib_first_utm",q="_ib_last_utm",w="_ib_referrer";function F(t){let e=new URLSearchParams(t),o={},n=false;return e.has("utm_source")&&(o.source=e.get("utm_source"),n=true),e.has("utm_medium")&&(o.medium=e.get("utm_medium"),n=true),e.has("utm_campaign")&&(o.campaign=e.get("utm_campaign"),n=true),e.has("utm_term")&&(o.term=e.get("utm_term"),n=true),e.has("utm_content")&&(o.content=e.get("utm_content"),n=true),n?o:null}function L(t,e){let o=F(t);try{o&&!localStorage.getItem(_)&&localStorage.setItem(_,JSON.stringify(o)),o&&localStorage.setItem(q,JSON.stringify(o)),e&&!localStorage.getItem(w)&&localStorage.setItem(w,e);}catch(n){}}function j(t){var e;return (e=F(t))!=null?e:void 0}function Y(){try{localStorage.removeItem(_);}catch(t){}try{localStorage.removeItem(q);}catch(t){}try{localStorage.removeItem(w);}catch(t){}}var p="_ib_optout",te="_ib_queue";function f(t){try{if(localStorage.getItem(p))return !1}catch(e){}return !(t.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||t.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(p,"1");}catch(t){}B(),M(),Y();try{localStorage.removeItem(te);}catch(t){}}function Q(){try{localStorage.removeItem(p);}catch(t){}}function V(){try{return !!localStorage.getItem(p)}catch(t){return false}}var oe=[1e3,2e3,4e3];function ne(t){return a(this,null,function*(){return new Promise(e=>setTimeout(e,t))})}function T(t,e,o=false){return a(this,null,function*(){let n=JSON.stringify(t);if(o&&typeof navigator!="undefined"&&navigator.sendBeacon){let r=new Blob([n],{type:"application/json"}),i=navigator.sendBeacon(e.endpoint,r);return e.debug&&console.log("[IndieBob] sendBeacon:",i,t.batch.length,"events"),i}for(let r=0;r<3;r++){try{let i=yield fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0});if(i.ok)return e.debug&&console.log("[IndieBob] sent:",t.batch.length,"events"),!0;if(i.status>=400&&i.status<500)return e.debug&&console.warn("[IndieBob] 4xx error, not retrying:",i.status),!1}catch(i){e.debug&&console.warn("[IndieBob] fetch error (attempt",r+1,"):",i);}r<2&&(yield ne(oe[r]));}return e.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var E="_ib_queue",re=10,ie=5e3,se=50,m=class{constructor(e){this.queue=[];this.timer=null;this.flushing=false;this.config=e,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(e){this.queue.push(e),this.queue.length>=re&&this.flush();}flush(e=false){return a(this,null,function*(){if(this.flushing&&!e||this.queue.length===0)return;this.flushing=true;let o=this.queue.splice(0);(yield T({batch:o},this.config,e))||this.pushToOfflineQueue(o),this.flushing=false;})}flushOfflineQueue(){return a(this,null,function*(){let e=this.getOfflineQueue();if(e.length===0)return;this.clearOfflineQueue(),yield T({batch:e},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},ie);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(e){try{let r=[...this.getOfflineQueue(),...e].slice(-se);localStorage.setItem(E,JSON.stringify(r));}catch(o){}}getOfflineQueue(){try{let e=localStorage.getItem(E);return e?JSON.parse(e):[]}catch(e){return []}}clearOfflineQueue(){try{localStorage.removeItem(E);}catch(e){}}};function H(){if(typeof window=="undefined")return "desktop";let t=window.innerWidth;return t<=768?"mobile":t<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function R(t){var u,C,k,A;let e=typeof window=="undefined",o=(u=t==null?void 0:t.path)!=null?u:e?"":window.location.pathname+window.location.search,n=e?"":window.location.href,r=(C=t==null?void 0:t.title)!=null?C:e?"":document.title,i=(k=t==null?void 0:t.referrer)!=null?k:e?"":document.referrer,h=X(),l=H(),s=e?void 0:j(window.location.search);return {page:{path:o,url:n,title:r,referrer:i},device:D(d({},h),{type:l}),utm:s,locale:e?"en":navigator.language,timezone:e?"UTC":(A=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?A:"UTC",sdkVersion:"0.1.1"}}function J(t){if(typeof window=="undefined")return ()=>{};let e=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...n){e(...n),t();},history.replaceState=function(...n){o(...n);},window.addEventListener("popstate",t),()=>{history.pushState=e,history.replaceState=o,window.removeEventListener("popstate",t);}}var g=class t{constructor(e){this.cleanupHistory=null;this.config=e,this.queue=new m(e),typeof window!="undefined"&&L(window.location.search,document.referrer);}static init(e){let o=N(e);return new t(o)}page(e){f(this.config)&&this.queue.push(this.buildEvent("page",{context:R(e)}));}track(e,o){f(this.config)&&this.queue.push(this.buildEvent("track",{event:e,properties:o}));}identify(e,o){f(this.config)&&(this.userId=e,this.queue.push(this.buildEvent("identify",{traits:o,userId:e})));}revenue(e){var o;f(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:e.amount,currency:(o=e.currency)!=null?o:"USD",plan:e.plan,type:e.type}}));}optOut(){this.queue.flush(),K(),this.userId=void 0,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){Q(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return V()}flush(){return a(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return v()}getSessionId(){return b()}getConfig(){return Object.freeze(d({},this.config))}enableAutoPage(){var e;return (e=this.cleanupHistory)==null||e.call(this),this.cleanupHistory=J(()=>this.page()),()=>{var o;(o=this.cleanupHistory)==null||o.call(this),this.cleanupHistory=null;}}buildEvent(e,o){var n,r;return {v:1,projectId:this.config.projectId,type:e,anonymousId:v(),userId:(n=this.userId)!=null?n:o.userId,sessionId:b(),timestamp:new Date().toISOString(),context:(r=o.context)!=null?r:R(),event:o.event,properties:o.properties,traits:o.traits,revenue:o.revenue}}};var ae=Symbol("indiebob"),O=null,Fe={install(t,e){let o=g.init(e);O=o,t.provide(ae,o),t.config.globalProperties.$bob=o;let n=t.config.globalProperties.$router;n&&n.afterEach(()=>{o.page();});}};function Le(){if(O)return O;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
2
- exports.IndieBob=g;exports.IndieBobPlugin=Fe;exports.useTracker=Le;return exports;})({});
1
+ var IndieBob=(function(exports){'use strict';var at=Object.defineProperty,ct=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var P=Object.getOwnPropertySymbols;var lt=Object.prototype.hasOwnProperty,dt=Object.prototype.propertyIsEnumerable;var D=(e,t,n)=>t in e?at(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))lt.call(t,n)&&D(e,n,t[n]);if(P)for(var n of P(t))dt.call(t,n)&&D(e,n,t[n]);return e},N=(e,t)=>ct(e,ut(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var pt="https://www.indiebob.com/api/collect";function F(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:pt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function v(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function y(){try{let e=localStorage.getItem(d);return e||(e=v(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=v(),sessionStorage.setItem(d,t)),t}catch(t){return v()}}}function L(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var b="_ib_session",I="_ib_session_last";function B(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function E(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),o=sessionStorage.getItem(b),i=n>0&&t-n>18e5;return (!o||i)&&(o=B(),sessionStorage.setItem(b,o)),sessionStorage.setItem(I,String(t)),o}catch(t){return B()}}function M(){try{sessionStorage.removeItem(b);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var S="_ib_first_utm",U="_ib_last_utm",_="_ib_referrer";function j(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function q(e,t){let n=j(e);try{n&&!localStorage.getItem(S)&&localStorage.setItem(S,JSON.stringify(n)),n&&localStorage.setItem(U,JSON.stringify(n)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(o){}}function Y(e){var t;return (t=j(e))!=null?t:void 0}function H(){try{localStorage.removeItem(S);}catch(e){}try{localStorage.removeItem(U);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var g="_ib_optout",ft="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(g,"1");}catch(e){}L(),M(),H();try{localStorage.removeItem(ft);}catch(e){}}function V(){try{localStorage.removeItem(g);}catch(e){}}function Q(){try{return !!localStorage.getItem(g)}catch(e){return false}}var gt=[1e3,2e3,4e3];function mt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function w(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield mt(gt[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var T="_ib_queue",ht=10,vt=5e3,yt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=ht&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield w({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield w({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},vt);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-yt);localStorage.setItem(T,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(T);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(T);}catch(t){}}};function z(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function k(e){var u,x,A,C;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(x=e==null?void 0:e.title)!=null?x:t?"":document.title,r=(A=e==null?void 0:e.referrer)!=null?A:t?"":document.referrer,c=X(),s=z(),a=t?void 0:Y(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:N(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(C=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?C:"UTC",sdkVersion:"0.2.0"}}function $(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var bt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},J={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function G(e,t){var n;for(let o of Object.keys(J))if(((n=t==null?void 0:t[o])!=null?n:bt[o]).some(r=>r.test(e)))return J[o];return null}function W(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function Z(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var R="ib_identified";function tt(){return typeof localStorage=="undefined"?true:!localStorage.getItem(R)}function et(){typeof localStorage!="undefined"&&localStorage.setItem(R,"1");}function nt(){typeof localStorage!="undefined"&&localStorage.removeItem(R);}var ot="data-ib-event",it="data-ib-";function rt(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(ot);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(it)&&c.name!==ot){let s=c.name.slice(it.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function st(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var h=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(q(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=rt((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=st((o,i)=>this.track(o,i)));}}static init(t){let n=F(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=k(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=G(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=W(s);a&&(this.cleanupFormSubmit=Z(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=tt(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&et(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),K(),nt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){V(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return Q()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return y()}getSessionId(){return E()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=$(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:y(),userId:(o=this.userId)!=null?o:n.userId,sessionId:E(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:k(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};var It=Symbol("indiebob"),O=null,ie={install(e,t){let n=h.init(t);O=n,e.provide(It,n),e.config.globalProperties.$bob=n;let o=e.config.globalProperties.$router;o&&o.afterEach(()=>{n.page();});}};function re(){if(O)return O;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
2
+ exports.IndieBob=h;exports.IndieBobPlugin=ie;exports.useTracker=re;return exports;})({});
package/dist/vue.js CHANGED
@@ -1 +1,2 @@
1
- import {a}from'./chunk-4IK5PET7.js';export{a as IndieBob}from'./chunk-4IK5PET7.js';var l=Symbol("indiebob"),r=null,b={install(o,n){let e=a.init(n);r=e,o.provide(l,e),o.config.globalProperties.$bob=e;let t=o.config.globalProperties.$router;t&&t.afterEach(()=>{e.page();});}};function p(){if(r)return r;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}export{b as IndieBobPlugin,p as useTracker};
1
+ var at=Object.defineProperty,ct=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var P=Object.getOwnPropertySymbols;var lt=Object.prototype.hasOwnProperty,dt=Object.prototype.propertyIsEnumerable;var D=(e,t,n)=>t in e?at(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,f=(e,t)=>{for(var n in t||(t={}))lt.call(t,n)&&D(e,n,t[n]);if(P)for(var n of P(t))dt.call(t,n)&&D(e,n,t[n]);return e},N=(e,t)=>ct(e,ut(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var pt="https://www.indiebob.com/api/collect";function F(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:pt,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function v(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function y(){try{let e=localStorage.getItem(d);return e||(e=v(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=v(),sessionStorage.setItem(d,t)),t}catch(t){return v()}}}function L(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var b="_ib_session",I="_ib_session_last";function B(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function E(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(I))!=null?e:"0",10),o=sessionStorage.getItem(b),i=n>0&&t-n>18e5;return (!o||i)&&(o=B(),sessionStorage.setItem(b,o)),sessionStorage.setItem(I,String(t)),o}catch(t){return B()}}function M(){try{sessionStorage.removeItem(b);}catch(e){}try{sessionStorage.removeItem(I);}catch(e){}}var S="_ib_first_utm",U="_ib_last_utm",_="_ib_referrer";function j(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")&&(n.source=t.get("utm_source"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function q(e,t){let n=j(e);try{n&&!localStorage.getItem(S)&&localStorage.setItem(S,JSON.stringify(n)),n&&localStorage.setItem(U,JSON.stringify(n)),t&&!localStorage.getItem(_)&&localStorage.setItem(_,t);}catch(o){}}function Y(e){var t;return (t=j(e))!=null?t:void 0}function H(){try{localStorage.removeItem(S);}catch(e){}try{localStorage.removeItem(U);}catch(e){}try{localStorage.removeItem(_);}catch(e){}}var g="_ib_optout",ft="_ib_queue";function p(e){try{if(localStorage.getItem(g))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function K(){try{localStorage.setItem(g,"1");}catch(e){}L(),M(),H();try{localStorage.removeItem(ft);}catch(e){}}function V(){try{localStorage.removeItem(g);}catch(e){}}function Q(){try{return !!localStorage.getItem(g)}catch(e){return false}}var gt=[1e3,2e3,4e3];function mt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function w(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"application/json"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield mt(gt[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var T="_ib_queue",ht=10,vt=5e3,yt=50,m=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=ht&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield w({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield w({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},vt);}setupVisibilityFlush(){typeof document!="undefined"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true});}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-yt);localStorage.setItem(T,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(T);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(T);}catch(t){}}};function z(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function X(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}function k(e){var u,x,A,C;let t=typeof window=="undefined",n=(u=e==null?void 0:e.path)!=null?u:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(x=e==null?void 0:e.title)!=null?x:t?"":document.title,r=(A=e==null?void 0:e.referrer)!=null?A:t?"":document.referrer,c=X(),s=z(),a=t?void 0:Y(window.location.search);return {page:{path:n,url:o,title:i,referrer:r},device:N(f({},c),{type:s}),utm:a,locale:t?"en":navigator.language,timezone:t?"UTC":(C=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?C:"UTC",sdkVersion:"0.2.0"}}function $(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var bt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},J={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function G(e,t){var n;for(let o of Object.keys(J))if(((n=t==null?void 0:t[o])!=null?n:bt[o]).some(r=>r.test(e)))return J[o];return null}function W(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function Z(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var R="ib_identified";function tt(){return typeof localStorage=="undefined"?true:!localStorage.getItem(R)}function et(){typeof localStorage!="undefined"&&localStorage.setItem(R,"1");}function nt(){typeof localStorage!="undefined"&&localStorage.removeItem(R);}var ot="data-ib-event",it="data-ib-";function rt(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(ot);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(it)&&c.name!==ot){let s=c.name.slice(it.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function st(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var h=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new m(t),typeof window!="undefined"&&(q(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=rt((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=st((o,i)=>this.track(o,i)));}}static init(t){let n=F(t);return new e(n)}page(t){var o;if(!p(this.config))return;let n=k(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=G(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=W(s);a&&(this.cleanupFormSubmit=Z(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){p(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(p(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=tt(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&et(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;p(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),K(),nt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){V(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return Q()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return y()}getSessionId(){return E()}getConfig(){return Object.freeze(f({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=$(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:y(),userId:(o=this.userId)!=null?o:n.userId,sessionId:E(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:k(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};var It=Symbol("indiebob"),O=null,ie={install(e,t){let n=h.init(t);O=n,e.provide(It,n),e.config.globalProperties.$bob=n;let o=e.config.globalProperties.$router;o&&o.afterEach(()=>{n.page();});}};function re(){if(O)return O;throw new Error("[IndieBob] useTracker() called before IndieBobPlugin was installed.")}
2
+ export{h as IndieBob,ie as IndieBobPlugin,re as useTracker};
package/package.json CHANGED
@@ -1,16 +1,11 @@
1
1
  {
2
2
  "name": "@indiebob/tracker",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Privacy-first analytics SDK for web applications. <5KB gzipped. No cookies.",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "author": "IndieBob <hello@indiebob.com>",
8
8
  "homepage": "https://indiebob.com/docs/sdk",
9
- "repository": {
10
- "type": "git",
11
- "url": "https://gitlab.com/indiebob/indiebob-monorepo.git",
12
- "directory": "packages/tracker"
13
- },
14
9
  "keywords": [
15
10
  "analytics",
16
11
  "tracking",