@faststats/web 0.4.0 → 0.4.2

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.
@@ -0,0 +1 @@
1
+ const e=`https://metrics.faststats.dev`,t=`https://flags.faststats.dev`;function n(e,t){return e?.replace(/\/+$/,``)||t}const r={events:`/v1/web`,identify:`/v1/identify`,replay:`/v1/replay`,vitals:`/v1/vitals`,flags:`/v1/check`},i=[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`];function a(){let e={page:location.pathname,url:location.href,referrer:document.referrer||null,title:document.title||``};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of i){let r=t.get(n);r&&(e[n]=r)}return e}export{n as a,a as i,t as n,r,e as t};
@@ -1 +1 @@
1
- import{o as e,r as t}from"./send-data-BXrEi1iz.js";const n=`faststats_anon_id`;function r(){try{return globalThis.localStorage}catch{return}}function i(){let e=r();if(!e)return``;try{let t=e.getItem(n);if(t)return t}catch{return``}let i=t();try{e.setItem(n,i)}catch{return``}return i}function a(t){return t??e()?``:i()}function o(e){if(e)return``;try{let e=r();if(!e)return``;e.removeItem(n)}catch{return``}return i()}export{o as n,a as t};
1
+ import{o as e,r as t}from"./send-data-Cc1nxIlg.js";const n=`faststats_anon_id`;function r(){try{return globalThis.localStorage}catch{return}}function i(){let e=r();if(!e)return``;try{let t=e.getItem(n);if(t)return t}catch{return``}let i=t();try{e.setItem(n,i)}catch{return``}return i}function a(t){return t??e()?``:i()}function o(e){if(e)return``;try{let e=r();if(!e)return``;e.removeItem(n)}catch{return``}return i()}export{o as n,a as t};
@@ -7,10 +7,10 @@ interface ReplayTrackerOptions {
7
7
  baseUrl?: string;
8
8
  debug?: boolean;
9
9
  compress?: boolean;
10
- cookieless?: boolean;
11
10
  samplingPercentage?: number;
12
11
  flushInterval?: number;
13
12
  maxEvents?: number;
13
+ maxBatchSizeBytes?: number;
14
14
  maxPendingBatches?: number;
15
15
  maxQueueSizeBytes?: number;
16
16
  minReplayLengthMs?: number;
@@ -32,12 +32,14 @@ declare class ReplayTracker {
32
32
  private readonly compressionSupported;
33
33
  private readonly flushInterval;
34
34
  private readonly maxEvents;
35
+ private readonly maxBatchSizeBytes;
35
36
  private readonly maxPendingBatches;
36
37
  private readonly maxQueueSizeBytes;
37
38
  private readonly minReplayLengthMs;
38
39
  private readonly sampled;
39
40
  private readonly events;
40
41
  private readonly pending;
42
+ private queuedEventsSizeBytes;
41
43
  private pendingSizeBytes;
42
44
  private viewId;
43
45
  private chunkStartedAt;
@@ -54,10 +56,9 @@ declare class ReplayTracker {
54
56
  private flushQueued;
55
57
  private flushQueuedLowLatency;
56
58
  private unsubscribeRotation?;
57
- private cookieless;
59
+ private lastCookielessMode;
58
60
  constructor(options: ReplayTrackerOptions);
59
61
  private log;
60
- private sessionContext;
61
62
  private clearFlushTimers;
62
63
  private clearQueues;
63
64
  setCookielessMode(cookieless: boolean): void;
@@ -75,6 +76,7 @@ declare class ReplayTracker {
75
76
  private scheduleMinLengthFlush;
76
77
  private enqueueEventsIfReady;
77
78
  private createBatch;
79
+ private eventSizeBytes;
78
80
  private batchSizeBytes;
79
81
  private dropOldestPending;
80
82
  private enqueueBatch;
package/dist/error.js CHANGED
@@ -1,2 +1,2 @@
1
- import{n as e,r as t,t as n}from"./chunks/api-urls-DYXBPqSP.js";import{i as r,n as i}from"./chunks/send-data-BXrEi1iz.js";import{t as a}from"./chunks/identifiers-CWMNnPWe.js";const o=/(?:^|\()(chrome|moz|ms-browser|safari-web)-extension:\/\//;function s(e,t,n,r){return t instanceof Error?{error:e,message:t.message||r,handled:n,stack:t.stack?.split(`
2
- `).map(e=>e.trim()).filter(Boolean)}:{error:e,message:typeof t==`string`?t:r,handled:n}}function c({error:e,message:t,handled:n}){return`${e}\0${t??``}\0${n}`}function l(e,t){let n=t instanceof Error?t.stack??``:``;return o.test(`${e}\n${n}`)}var u=class{endpoint;queue=new Map;timer=null;started=!1;flushing=!1;constructor(e){this.options=e,this.endpoint=`${t(e.baseUrl)}${n.events}`}log(...e){this.options.debug&&console.log(`[ErrorTracker]`,...e)}start(){this.started||typeof window>`u`||(this.started=!0,window.addEventListener(`error`,this.onError),window.addEventListener(`unhandledrejection`,this.onRejection),this.timer=setInterval(()=>void this.flush(),this.options.flushInterval??5e3),this.log(`Started`))}stop(){!this.started||typeof window>`u`||(this.started=!1,window.removeEventListener(`error`,this.onError),window.removeEventListener(`unhandledrejection`,this.onRejection),this.timer&&clearInterval(this.timer),this.timer=null,this.flush(),this.log(`Stopped`))}onPageHidden(e=!1){e||this.flush()}captureError(e){this.enqueue(s(`Error`,e,!0,e.message))}onError=e=>{l(e.filename??``,e.error)||this.enqueue(s(`Error`,e.error,!1,e.message||`Unknown error`))};onRejection=e=>{l(``,e.reason)||this.enqueue(s(`UnhandledRejection`,e.reason,!1,`Unhandled promise rejection`))};enqueue(e){let t=c(e),n=this.queue.get(t);if(n){n.count++;return}this.queue.set(t,{...e,count:1}),this.log(`Captured:`,e),this.queue.size>=(this.options.maxQueueSize??50)&&this.flush()}async flush(){if(this.flushing||this.queue.size===0)return;this.flushing=!0;let t=this.queue;this.queue=new Map;let n=[...t.values()];this.log(`Flushing:`,n);try{let o=globalThis.__SOURCEMAPS_BUILD__?.buildId,s=a(),c=r(this.options.siteKey);if(!await i({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,...s?{userId:s}:{},sessionId:c.sessionId,windowId:c.windowId,...typeof o==`string`&&o.trim()?{buildId:o}:{},sdkName:this.options.sdkName??`@faststats/web`,sdkVersion:this.options.sdkVersion??`0.4.0`,event:`error`,...e(),properties:{},errors:n}),debug:this.options.debug,debugPrefix:`[ErrorTracker]`}))for(let[e,n]of t){let t=this.queue.get(e);t?t.count+=n.count:this.queue.set(e,n)}}finally{this.flushing=!1}}};export{u as default};
1
+ import{a as e,i as t,r as n,t as r}from"./chunks/api-urls-Bh77rElT.js";import{i,n as a}from"./chunks/send-data-Cc1nxIlg.js";import{t as o}from"./chunks/identifiers-uytEhnH9.js";const s=/(?:^|\()(chrome|moz|ms-browser|safari-web)-extension:\/\//;function c(e,t,n,r){return t instanceof Error?{error:e,message:t.message||r,handled:n,stack:t.stack?.split(`
2
+ `).map(e=>e.trim()).filter(Boolean)}:{error:e,message:typeof t==`string`?t:r,handled:n}}function l({error:e,message:t,handled:n}){return`${e}\0${t??``}\0${n}`}function u(e,t){let n=t instanceof Error?t.stack??``:``;return s.test(`${e}\n${n}`)}var d=class{options;endpoint;queue=new Map;timer=null;started=!1;flushing=!1;constructor(t){this.options=t,this.endpoint=`${e(t.baseUrl,r)}${n.events}`}log(...e){this.options.debug&&console.log(`[ErrorTracker]`,...e)}start(){this.started||typeof window>`u`||(this.started=!0,window.addEventListener(`error`,this.onError),window.addEventListener(`unhandledrejection`,this.onRejection),this.timer=setInterval(()=>void this.flush(),this.options.flushInterval??5e3),this.log(`Started`))}stop(){!this.started||typeof window>`u`||(this.started=!1,window.removeEventListener(`error`,this.onError),window.removeEventListener(`unhandledrejection`,this.onRejection),this.timer&&clearInterval(this.timer),this.timer=null,this.flush(),this.log(`Stopped`))}onPageHidden(e=!1){e||this.flush()}captureError(e){this.enqueue(c(`Error`,e,!0,e.message))}onError=e=>{u(e.filename??``,e.error)||this.enqueue(c(`Error`,e.error,!1,e.message||`Unknown error`))};onRejection=e=>{u(``,e.reason)||this.enqueue(c(`UnhandledRejection`,e.reason,!1,`Unhandled promise rejection`))};enqueue(e){let t=l(e),n=this.queue.get(t);if(n){n.count++;return}this.queue.set(t,{...e,count:1}),this.log(`Captured:`,e),this.queue.size>=(this.options.maxQueueSize??50)&&this.flush()}async flush(){if(this.flushing||this.queue.size===0)return;this.flushing=!0;let e=this.queue;this.queue=new Map;let n=[...e.values()];this.log(`Flushing:`,n);try{let r=globalThis.__SOURCEMAPS_BUILD__?.buildId,s=o(),c=i(this.options.siteKey);if(!await a({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,...s?{userId:s}:{},sessionId:c.sessionId,windowId:c.windowId,...typeof r==`string`&&r.trim()?{buildId:r}:{},sdkName:this.options.sdkName??`@faststats/web`,sdkVersion:this.options.sdkVersion??`0.4.2`,event:`error`,...t(),properties:{},errors:n}),debug:this.options.debug,debugPrefix:`[ErrorTracker]`}))for(let[t,n]of e){let e=this.queue.get(t);e?e.count+=n.count:this.queue.set(t,n)}}finally{this.flushing=!1}}};export{d as default};
@@ -7,7 +7,6 @@ type FeatureFlagEvaluation = {
7
7
  type FeatureFlagCheckContext = {
8
8
  baseUrl?: string;
9
9
  projectToken?: string;
10
- projectId?: string;
11
10
  identifier?: string;
12
11
  externalId?: string;
13
12
  sessionId?: string;
@@ -1 +1 @@
1
- import{i as e,t}from"./chunks/api-urls-DYXBPqSP.js";async function n(n,r){if(r.projectToken&&r.projectId)throw Error(`provide either projectToken or projectId, not both`);let i=r.projectToken,a=r.projectId,o=r.identifier,s=r.externalId,c=r.sessionId;if(!i&&!a)throw Error(`feature flag check requires projectToken or projectId`);if(!o&&!s)throw Error(`feature flag check requires serverId or externalId`);let l={key:n,...a?{projectId:a}:{},...o?{identifier:o}:{},...s?{externalId:s}:{},...c?{sessionId:c}:{}},u=r.attributes??{};Object.keys(u).length>0&&(l.attributes=u);let d={"Content-Type":`application/json`};i&&(d.Authorization=`Bearer ${i}`);let f=`${e(r.baseUrl)}${t.flags}`,p=await fetch(f,{method:`POST`,headers:d,body:JSON.stringify(l),credentials:`omit`,signal:r.signal});if(!p.ok){let e=``;try{let t=await p.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${p.status}${e}`)}return await p.json()}export{n as fetchFeatureFlagEvaluation};
1
+ import{a as e,n as t,r as n}from"./chunks/api-urls-Bh77rElT.js";async function r(r,i){if(!i.projectToken)throw Error(`feature flag check requires projectToken`);if(!i.identifier&&!i.externalId)throw Error(`feature flag check requires serverId or externalId`);let{baseUrl:a,projectToken:o,signal:s,attributes:c,...l}=i,u={key:r,...l};c&&Object.keys(c).length>0&&(u.attributes=c);let d={"Content-Type":`application/json`,Authorization:`Bearer ${o}`},f=`${e(a,t)}${n.flags}`,p=await fetch(f,{method:`POST`,headers:d,body:JSON.stringify(u),credentials:`omit`,signal:s});if(!p.ok){let e=``;try{let t=await p.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${p.status}${e}`)}return await p.json()}export{r as fetchFeatureFlagEvaluation};
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FeatureFlagEvaluation } from "./feature-flags.js";
2
- import { n as ReplayTrackerOptions } from "./chunks/replay-BL2Ev5IF.js";
2
+ import { n as ReplayTrackerOptions } from "./chunks/replay-DLpWrsx1.js";
3
3
 
4
4
  //#region src/analytics.d.ts
5
5
  type ConsentMode = "pending" | "granted" | "denied";
@@ -60,11 +60,12 @@ declare class WebAnalytics {
60
60
  private started;
61
61
  private destroyed;
62
62
  private epoch;
63
- private navTimer;
64
63
  private heartbeatTimer;
65
64
  private pageKey;
66
65
  private entry;
67
66
  private left;
67
+ private initialPageviewPending;
68
+ private initialPageviewTrigger;
68
69
  private consentMode;
69
70
  private readonly pendingBehavior;
70
71
  private readonly cleanup;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{i as e,n as t,r as n,t as r}from"./chunks/api-urls-DYXBPqSP.js";import{c as i,i as a,l as o,n as s,t as c,u as l}from"./chunks/send-data-BXrEi1iz.js";import{n as u,t as d}from"./chunks/identifiers-CWMNnPWe.js";let f=null,p;function m(){return f}function h(e,t){typeof window>`u`||S()||f?.track(e,t??{})}function g(e,t,n){return typeof window>`u`||S()?Promise.resolve(!1):f?.identify(e,t,n??{})??Promise.resolve(!1)}function _(e=!0){typeof window>`u`||S()||f?.logout(e)}function v(e){f?f.setConsentMode(e):p=e}function y(){v(`granted`)}function b(){v(`denied`)}function x(e){typeof window>`u`||S()||f?.reportError(e)}function S(){try{let e=globalThis.localStorage?.getItem(`disable-faststats`);return e===`true`||e===`1`}catch{return!1}}var C=class{baseUrl;debug;started=!1;destroyed=!1;epoch=0;navTimer=null;heartbeatTimer=null;pageKey=``;entry={path:``,url:``,hash:``};left=!1;consentMode;pendingBehavior;cleanup=[];childTrackers=[];constructor(e){if(this.options=e,this.baseUrl=n(e.baseUrl),this.debug=e.debug??!1,this.consentMode=p??e.consent?.mode??`granted`,p=void 0,this.pendingBehavior=e.consent?.pendingBehavior??`anonymous`,e.autoTrack??!0){if(typeof window>`u`)return;if(S()){this.log(`disabled`);return}setTimeout(()=>void this.start(),0)}}log(e){this.debug&&console.log(`[Analytics] ${e}`)}ensureActive(){return typeof window>`u`||this.destroyed||S()?!1:(this.started||this.start(),this.started&&!this.destroyed&&f===this)}canTrack(){return!(this.consentMode===`pending`&&this.pendingBehavior===`disabled`)}cookieless(){return!!this.options.cookieless||this.consentMode===`denied`||this.consentMode===`pending`&&this.pendingBehavior===`anonymous`}touch(){this.canTrack()&&l(this.options.siteKey,this.cookieless())}bind(e,t,n,r){e.addEventListener(t,n,r),this.cleanup.push(()=>e.removeEventListener(t,n,r))}loadChild(e,t){let n=this.epoch;t().then(async t=>{if(this.epoch!==n||!this.started||(await t.start(),this.epoch!==n||!this.started))return t.stop?.();this.childTrackers.push(t),this.log(`${e} loaded`)}).catch(t=>this.log(`failed to initialize ${e} tracker: ${String(t)}`))}loadOptionalTrackers(){let e=this.options,t={siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug};if(e.sessionReplays?.enabled){let n=e.replayOptions??{};this.loadChild(`replay`,async()=>{let{default:r}=await import(`./replay.js`);return new r({...t,...n,samplingPercentage:c(n.samplingPercentage??e.sessionReplays?.sampling?.percentage),cookieless:this.cookieless()})})}e.errorTracking?.enabled&&this.loadChild(`error`,async()=>{let{default:n}=await import(`./error.js`);return new n({...t,sdkName:e.sdkName,sdkVersion:e.sdkVersion})}),e.webVitals?.enabled&&this.loadChild(`web-vitals`,async()=>{let{default:n}=await import(`./web-vitals.js`);return new n({...t,samplingPercentage:c(e.webVitals?.sampling?.percentage),attribution:e.webVitals?.attribution??!1})})}beginTracking(e){this.touch(),this.loadOptionalTrackers(),this.entry={path:location.pathname,url:location.href,hash:location.hash},this.left=!1,this.pageKey=``,this.pageview({trigger:e})}onLinkClick=e=>{let t=e.target;for(;t;){if(t instanceof HTMLAnchorElement&&t.href&&t.host!==location.host){this.track(`outbound_link`,{outbound_link:t.href});return}t=t.parentNode}};onVisibilityChange=()=>{if(this.touch(),document.visibilityState===`hidden`){for(let e of this.childTrackers)e.onPageHidden?.();this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;return}this.startHeartbeat()};onPageHide=e=>{let t=e.persisted;for(let e of this.childTrackers)e.onPageHidden?.(t);t||this.leavePage()};onPageShow=e=>{for(let t of this.childTrackers)t.onPageShow?.(e.persisted)};async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(f&&f!==this){this.log(`already started by another instance`);return}if(S()){this.log(`disabled`);return}this.started=!0,f=this,o(this.cookieless()),this.canTrack()&&this.beginTracking(`load`),this.startHeartbeat();let e=()=>this.navigate(),t=[[document,`click`,this.onLinkClick],[document,`auxclick`,this.onLinkClick],[document,`visibilitychange`,this.onVisibilityChange],[window,`pagehide`,this.onPageHide],[window,`pageshow`,this.onPageShow],[window,`popstate`,e]];(this.options.trackHash??!1)&&t.push([window,`hashchange`,e]);for(let[e,n,r]of t)this.bind(e,n,r);for(let e of[`pushState`,`replaceState`]){let t=history[e].bind(history);history[e]=(e,n,r)=>{t(e,n,r),this.navigate()},this.cleanup.push(()=>{history[e]=t})}}destroy(){if(!this.destroyed){this.epoch++,this.started&&typeof window<`u`&&this.leavePage(),this.navTimer&&clearTimeout(this.navTimer),this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;for(let e of this.cleanup.splice(0))e();for(let e of this.childTrackers.splice(0))e.stop?.();f===this&&(f=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureActive())return;let t=this.options.trackHash??!1,n=`${location.pathname}|${t?location.hash:``}`;n!==this.pageKey&&(this.pageKey=n,this.send(`pageview`,e))}track(e,t={}){if(!this.ensureActive())return;let n=e.trim();n&&this.send(n,t)}identify(e,t,n={}){if(!this.ensureActive()||!this.canTrack()||this.cookieless())return Promise.resolve(!1);let i=e.trim(),a=t.trim();return!i||!a?Promise.resolve(!1):s({url:`${this.baseUrl}${r.identify}`,data:JSON.stringify({token:this.options.siteKey,identifier:this.getAnonymousId(),externalId:i,email:a,name:n.name?.trim()||void 0,phone:n.phone?.trim()||void 0,avatarUrl:n.avatarUrl?.trim()||void 0,traits:n.traits??{}}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] identify`,useBeacon:!1})}logout(e=!0){this.ensureActive()&&(e&&u(this.cookieless()),i(this.options.siteKey))}setConsentMode(e){let t=!this.canTrack();this.consentMode=e;let n=this.cookieless();o(n);for(let e of this.childTrackers)e.setCookielessMode?.(n);t&&this.canTrack()&&this.started&&this.beginTracking(`consent`)}getConsentMode(){return this.consentMode}getAnonymousId(){return this.canTrack()?d(this.cookieless()):``}getSessionId(){return a(this.options.siteKey,this.cookieless()).sessionId}getWindowId(){return a(this.options.siteKey,this.cookieless()).windowId}async checkFeatureFlag(t,n,r){if(typeof window>`u`||S()||!this.canTrack())return{value:`false`};let i=r?.externalId?.trim(),a=this.getAnonymousId();if(!i&&!a)return{value:`false`};let{fetchFeatureFlagEvaluation:o}=await import(`./feature-flags.js`);return o(t,{baseUrl:e(this.options.featureFlagsBaseUrl),projectToken:this.options.siteKey,...a?{identifier:a}:{},...i?{externalId:i}:{},sessionId:this.getSessionId(),attributes:n,signal:r?.signal})}reportError(e){!this.ensureActive()||!this.options.errorTracking?.enabled||!this.canTrack()||this.childTrackers.find(e=>`captureError`in e)?.captureError(e)}send(e,n={},i={}){if(typeof window>`u`||this.destroyed||S()||!this.canTrack())return;let o=this.cookieless(),c=d(o),l=a(this.options.siteKey,o);this.log(e),s({url:`${this.baseUrl}${r.events}`,data:JSON.stringify({token:this.options.siteKey,...c?{userId:c}:{},sessionId:l.sessionId,windowId:l.windowId,event:e,...t(),...i,properties:n}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}leavePage(){if(this.destroyed||this.left)return;this.left=!0;let e=a(this.options.siteKey,this.cookieless());this.send(`page_leave`,{session_duration:Date.now()-e.sessionStart},{page:this.entry.path,url:this.entry.url})}startHeartbeat(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;return}this.touch()},300*1e3)}navigate(){!this.started||this.destroyed||(this.navTimer&&clearTimeout(this.navTimer),this.navTimer=setTimeout(()=>{this.navTimer=null;let e=this.options.trackHash??!1;if(!(location.pathname===this.entry.path&&(!e||location.hash===this.entry.hash))){for(let e of this.childTrackers)e.trackPageChange?.(location.href);this.leavePage(),this.entry={path:location.pathname,url:location.href,hash:location.hash},this.left=!1,this.pageview({trigger:`navigation`})}},300))}};export{C as WebAnalytics,m as getInstance,g as identify,S as isTrackingDisabled,_ as logout,y as optIn,b as optOut,x as reportError,v as setConsentMode,h as trackEvent};
1
+ import{a as e,i as t,n,r,t as i}from"./chunks/api-urls-Bh77rElT.js";import{c as a,i as o,l as s,n as c,t as l,u}from"./chunks/send-data-Cc1nxIlg.js";import{n as d,t as f}from"./chunks/identifiers-uytEhnH9.js";let p=null,m;function h(){return p}function g(e,t){typeof window>`u`||C()||p?.track(e,t??{})}function _(e,t,n){return typeof window>`u`||C()?Promise.resolve(!1):p?.identify(e,t,n??{})??Promise.resolve(!1)}function v(e=!0){typeof window>`u`||C()||p?.logout(e)}function y(e){p?p.setConsentMode(e):m=e}function b(){y(`granted`)}function x(){y(`denied`)}function S(e){typeof window>`u`||C()||p?.reportError(e)}function C(){try{let e=globalThis.localStorage?.getItem(`disable-faststats`);return e===`true`||e===`1`}catch{return!1}}var w=class{options;baseUrl;debug;started=!1;destroyed=!1;epoch=0;heartbeatTimer=null;pageKey=``;entry={path:``,url:``,hash:``};left=!1;initialPageviewPending=!1;initialPageviewTrigger=`load`;consentMode;pendingBehavior;cleanup=[];childTrackers=[];constructor(t){if(this.options=t,this.baseUrl=e(t.baseUrl,i),this.debug=t.debug??!1,this.consentMode=m??t.consent?.mode??`granted`,m=void 0,this.pendingBehavior=t.consent?.pendingBehavior??`anonymous`,t.autoTrack??!0){if(typeof window>`u`)return;if(C()){this.log(`disabled`);return}setTimeout(()=>void this.start(),0)}}log(e){this.debug&&console.log(`[Analytics] ${e}`)}ensureActive(){return typeof window>`u`||this.destroyed||C()?!1:(this.started||this.start(),this.started&&!this.destroyed&&p===this)}canTrack(){return!(this.consentMode===`pending`&&this.pendingBehavior===`disabled`)}cookieless(){return!!this.options.cookieless||this.consentMode===`denied`||this.consentMode===`pending`&&this.pendingBehavior===`anonymous`}touch(){this.canTrack()&&u(this.options.siteKey,this.cookieless())}bind(e,t,n,r){e.addEventListener(t,n,r),this.cleanup.push(()=>e.removeEventListener(t,n,r))}loadChild(e,t){let n=this.epoch;t().then(async t=>{if(this.epoch!==n||!this.started||(await t.start(),this.epoch!==n||!this.started))return t.stop?.();this.childTrackers.push(t),this.log(`${e} loaded`)}).catch(t=>this.log(`failed to initialize ${e} tracker: ${String(t)}`))}loadOptionalTrackers(){let e=this.options,t={siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug};if(e.sessionReplays?.enabled){let n=e.replayOptions??{};this.loadChild(`replay`,async()=>{let{default:r}=await import(`./replay.js`);return new r({...t,...n,samplingPercentage:l(n.samplingPercentage??e.sessionReplays?.sampling?.percentage)})})}e.errorTracking?.enabled&&this.loadChild(`error`,async()=>{let{default:n}=await import(`./error.js`);return new n({...t,sdkName:e.sdkName,sdkVersion:e.sdkVersion})}),e.webVitals?.enabled&&this.loadChild(`web-vitals`,async()=>{let{default:n}=await import(`./web-vitals.js`);return new n({...t,samplingPercentage:l(e.webVitals?.sampling?.percentage),attribution:e.webVitals?.attribution??!1})})}beginTracking(e){if(this.touch(),this.loadOptionalTrackers(),this.entry={path:location.pathname,url:location.href,hash:location.hash},this.left=!1,this.pageKey=``,document.visibilityState===`visible`){this.pageview({trigger:e});return}this.initialPageviewTrigger=e,this.initialPageviewPending=!0}onLinkClick=e=>{let t=e.target;for(;t;){if(t instanceof HTMLAnchorElement&&t.href&&t.host!==location.host){this.track(`outbound_link`,{outbound_link:t.href});return}t=t.parentNode}};onVisibilityChange=()=>{if(this.touch(),document.visibilityState===`hidden`){for(let e of this.childTrackers)e.onPageHidden?.();this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;return}this.startHeartbeat(),this.initialPageviewPending&&(this.initialPageviewPending=!1,this.pageview({trigger:this.initialPageviewTrigger}))};onPageHide=e=>{let t=e.persisted;for(let e of this.childTrackers)e.onPageHidden?.(t);t||this.leavePage()};onPageShow=e=>{for(let t of this.childTrackers)t.onPageShow?.(e.persisted)};async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(p&&p!==this){this.log(`already started by another instance`);return}if(C()){this.log(`disabled`);return}this.started=!0,p=this,s(this.cookieless());let e=()=>this.navigate(),t=[[document,`click`,this.onLinkClick],[document,`auxclick`,this.onLinkClick],[document,`visibilitychange`,this.onVisibilityChange],[window,`pagehide`,this.onPageHide],[window,`pageshow`,this.onPageShow],[window,`popstate`,e]];(this.options.trackHash??!1)&&t.push([window,`hashchange`,e]);for(let[e,n,r]of t)this.bind(e,n,r);for(let e of[`pushState`,`replaceState`]){let t=history[e].bind(history);history[e]=(e,n,r)=>{t(e,n,r),this.navigate()},this.cleanup.push(()=>{history[e]=t})}this.startHeartbeat(),this.canTrack()&&this.beginTracking(`load`)}destroy(){if(!this.destroyed){this.epoch++,this.started&&typeof window<`u`&&this.leavePage(),this.initialPageviewPending=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;for(let e of this.cleanup.splice(0))e();for(let e of this.childTrackers.splice(0))e.stop?.();p===this&&(p=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureActive())return;let t=this.options.trackHash??!1,n=`${location.pathname}|${t?location.hash:``}`;n!==this.pageKey&&(this.pageKey=n,this.send(`pageview`,e))}track(e,t={}){if(!this.ensureActive())return;let n=e.trim();n&&this.send(n,t)}identify(e,t,n={}){if(!this.ensureActive()||!this.canTrack()||this.cookieless())return Promise.resolve(!1);let i=e.trim(),a=t.trim();return!i||!a?Promise.resolve(!1):c({url:`${this.baseUrl}${r.identify}`,data:JSON.stringify({token:this.options.siteKey,identifier:this.getAnonymousId(),externalId:i,email:a,name:n.name?.trim()||void 0,phone:n.phone?.trim()||void 0,avatarUrl:n.avatarUrl?.trim()||void 0,traits:n.traits??{}}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] identify`,useBeacon:!1})}logout(e=!0){this.ensureActive()&&(e&&d(this.cookieless()),a(this.options.siteKey))}setConsentMode(e){let t=!this.canTrack();this.consentMode=e;let n=this.cookieless();s(n);for(let e of this.childTrackers)e.setCookielessMode?.(n);t&&this.canTrack()&&this.started&&this.beginTracking(`consent`)}getConsentMode(){return this.consentMode}getAnonymousId(){return this.canTrack()?f(this.cookieless()):``}getSessionId(){return o(this.options.siteKey,this.cookieless()).sessionId}getWindowId(){return o(this.options.siteKey,this.cookieless()).windowId}async checkFeatureFlag(t,r,i){if(typeof window>`u`||C()||!this.canTrack())return{value:`false`};let a=i?.externalId?.trim(),o=this.getAnonymousId();if(!a&&!o)return{value:`false`};let{fetchFeatureFlagEvaluation:s}=await import(`./feature-flags.js`);return s(t,{baseUrl:e(this.options.featureFlagsBaseUrl,n),projectToken:this.options.siteKey,...o?{identifier:o}:{},...a?{externalId:a}:{},sessionId:this.getSessionId(),attributes:r,signal:i?.signal})}reportError(e){!this.ensureActive()||!this.options.errorTracking?.enabled||!this.canTrack()||this.childTrackers.find(e=>`captureError`in e)?.captureError(e)}send(e,n={},i={}){if(typeof window>`u`||this.destroyed||C()||!this.canTrack())return;let a=this.cookieless(),s=f(a),l=o(this.options.siteKey,a);this.log(e),c({url:`${this.baseUrl}${r.events}`,data:JSON.stringify({token:this.options.siteKey,...s?{userId:s}:{},sessionId:l.sessionId,windowId:l.windowId,event:e,...t(),...i,properties:n}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}leavePage(){if(this.destroyed||this.left)return;this.left=!0;let e=o(this.options.siteKey,this.cookieless());this.send(`page_leave`,{session_duration:Date.now()-e.sessionStart},{page:this.entry.path,url:this.entry.url})}startHeartbeat(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null;return}this.touch()},300*1e3)}navigate(){if(!this.started||this.destroyed)return;let e=this.options.trackHash??!1;if(!(location.pathname===this.entry.path&&(!e||location.hash===this.entry.hash))){for(let e of this.childTrackers)e.trackPageChange?.(location.href);this.leavePage(),this.entry={path:location.pathname,url:location.href,hash:location.hash},this.left=!1,this.pageview({trigger:`navigation`})}}};export{w as WebAnalytics,h as getInstance,_ as identify,C as isTrackingDisabled,v as logout,b as optIn,x as optOut,S as reportError,y as setConsentMode,g as trackEvent};
package/dist/replay.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { n as ReplayTrackerOptions, t as ReplayTracker } from "./chunks/replay-BL2Ev5IF.js";
1
+ import { n as ReplayTrackerOptions, t as ReplayTracker } from "./chunks/replay-DLpWrsx1.js";
2
2
  export { ReplayTrackerOptions, ReplayTracker as default };
package/dist/replay.js CHANGED
@@ -1 +1 @@
1
- import{r as e,t}from"./chunks/api-urls-DYXBPqSP.js";import{a as n,i as r,n as i,r as a,s as o,t as s,u as c}from"./chunks/send-data-BXrEi1iz.js";import{t as l}from"./chunks/identifiers-CWMNnPWe.js";import{record as u}from"@rrweb/record";const d={mousemove:50,mouseInteraction:!0,scroll:150,media:800,input:`last`};function f(e){return`faststats_replay_sampled_${e}`}function p(e,t,i){let a=s(t);if(a>=100)return!0;if(a<=0)return!1;let o=r(e,i).sessionId,c=f(e),l=`${o}:${a}`;try{let e=sessionStorage?.getItem(c);if(e===l)return!0;if(e?.startsWith(`${o}:`))return!1}catch{}let u=n(o)%100<a;try{sessionStorage?.setItem(c,u?l:`${o}:out`)}catch{}return u}var m=class{endpoint;compressionSupported=typeof window<`u`&&`CompressionStream`in window;flushInterval;maxEvents;maxPendingBatches;maxQueueSizeBytes;minReplayLengthMs;sampled;events=[];pending=[];pendingSizeBytes=0;viewId=a();chunkStartedAt=0;started=!1;startGeneration=0;startTime=0;sequence=0;intervalId=null;flushTask=null;retryTask=null;minLengthFlushTask=null;stopRecording;sending=!1;flushQueued=!1;flushQueuedLowLatency=!1;unsubscribeRotation;cookieless;constructor(n){this.options=n,this.endpoint=`${e(n.baseUrl)}${t.replay}`,this.cookieless=n.cookieless??!1,this.flushInterval=n.flushInterval??1e4,this.maxEvents=n.maxEvents??500,this.maxPendingBatches=n.maxPendingBatches??30,this.maxQueueSizeBytes=n.maxQueueSizeBytes??2097152,this.minReplayLengthMs=n.minReplayLengthMs??3e3,this.sampled=p(n.siteKey,n.samplingPercentage??100,this.cookieless)}log(...e){this.options.debug&&console.log(`[Replay]`,...e)}sessionContext(){return r(this.options.siteKey,this.cookieless)}clearFlushTimers(){this.flushTask&&clearTimeout(this.flushTask),this.retryTask&&clearTimeout(this.retryTask),this.minLengthFlushTask&&clearTimeout(this.minLengthFlushTask),this.flushTask=null,this.retryTask=null,this.minLengthFlushTask=null}clearQueues(){this.events.length=0,this.pending.length=0,this.pendingSizeBytes=0}setCookielessMode(e){this.cookieless!==e&&(this.cookieless=e,e&&(this.clearQueues(),this.clearFlushTimers()),this.startTime=this.sessionContext().sessionStart,this.chunkStartedAt=Date.now())}start(){if(this.started||typeof window>`u`||!this.sampled)return;this.started=!0,this.viewId=a(),this.startTime=this.sessionContext().sessionStart,this.chunkStartedAt=Date.now(),this.unsubscribeRotation=o(e=>{this.onSessionRotated(e)});let e=++this.startGeneration;this.beginRecording(e),this.intervalId=setInterval(this.requestFlush,this.flushInterval),window.addEventListener(`beforeunload`,this.onUnload),this.log(`Recording started`)}trackPageChange(e){this.started&&(this.viewId=a(),this.chunkStartedAt=Date.now(),this.onEvent({type:5,timestamp:Date.now(),data:{tag:`faststats:view`,payload:{href:e??window.location.href,viewId:this.viewId}}},!1))}onPageHidden(e=!1){e||this.flush(!0,!0)}onPageShow(e=!1){!e||!this.started||this.pending.length>0&&this.flush(!1)}async beginRecording(e){let t=this.options.recordConsole===!1?null:await import(`@rrweb/rrweb-plugin-console-record`);if(e!==this.startGeneration)return;let n=[];t&&n.push(t.getRecordConsolePlugin());let r=u({emit:this.onEvent,sampling:this.options.sampling??d,slimDOMOptions:this.options.slimDOMOptions??{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:!0,headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0},maskAllInputs:this.options.maskAllInputs??!0,maskInputOptions:this.options.maskInputOptions??{password:!0,email:!0,tel:!0},blockClass:this.options.blockClass,blockSelector:this.options.blockSelector,maskTextClass:this.options.maskTextClass,maskTextSelector:this.options.maskTextSelector,checkoutEveryNms:this.options.checkoutEveryNms??6e4,checkoutEveryNth:this.options.checkoutEveryNth,plugins:n});if(e!==this.startGeneration){r?.();return}this.stopRecording=r}stop(){this.started&&(this.started=!1,this.startGeneration++,this.unsubscribeRotation?.(),this.unsubscribeRotation=void 0,this.stopRecording?.(),this.stopRecording=void 0,this.intervalId&&clearInterval(this.intervalId),this.clearFlushTimers(),this.intervalId=null,window.removeEventListener(`beforeunload`,this.onUnload),this.hasReachedMinLength()||(this.events.length=0,this.log(`Session too short (${Date.now()-this.startTime}ms), discarding events`)),this.flush(!0,!0),this.log(`Recording stopped`))}onSessionRotated(e){this.started&&(this.enqueueEventsIfReady(e,!0),this.pending.length>0&&queueMicrotask(()=>void this.flush(!1)))}onEvent=(e,t)=>{if(this.events.push(e),t||this.events.length>=this.maxEvents||e.type===2&&this.hasReachedMinLength()){this.requestFlush();return}this.scheduleMinLengthFlush()};onUnload=()=>{this.flush(!0,!0)};hasReachedMinLength(){return this.minReplayLengthMs<=0||Date.now()-this.startTime>=this.minReplayLengthMs}requestFlush=()=>{this.flushTask||this.events.length===0||(this.minLengthFlushTask&&=(clearTimeout(this.minLengthFlushTask),null),this.flushTask=setTimeout(()=>{this.flushTask=null,this.flush(!1)},0))};scheduleMinLengthFlush(){if(this.minLengthFlushTask||this.events.length===0||this.hasReachedMinLength())return;let e=Math.max(0,this.minReplayLengthMs-(Date.now()-this.startTime));this.minLengthFlushTask=setTimeout(()=>{this.minLengthFlushTask=null,this.requestFlush()},Math.min(e,2147483647))}enqueueEventsIfReady(e,t){if(this.events.length!==0){if(!t&&!this.hasReachedMinLength()){this.scheduleMinLengthFlush();return}this.enqueueBatch(this.createBatch(this.events.splice(0),e,t))}}createBatch(e,t,n){let r=l(this.cookieless),i=this.sequence++,a=this.chunkStartedAt,o=Date.now();return this.chunkStartedAt=o,{token:this.options.siteKey,sessionId:t.sessionId,windowId:t.windowId,viewId:this.viewId,sessionStart:t.sessionStart,chunkStartedAt:a,chunkEndedAt:o,...r?{identifier:r}:{},batchId:`${t.sessionId}-${i}-${a}`,sequence:i,timestamp:o,url:window.location.href,...n?{isFinal:!0}:{},events:e}}batchSizeBytes(e){return new TextEncoder().encode(JSON.stringify(e)).byteLength}dropOldestPending(e){let t=this.pending.shift();t&&(this.pendingSizeBytes=Math.max(0,this.pendingSizeBytes-this.batchSizeBytes(t)),this.log(`${e}, dropping batch ${t.sequence}`))}enqueueBatch(e){let t=this.batchSizeBytes(e);if(t>this.maxQueueSizeBytes){this.log(`Replay batch ${e.sequence} is ${t}B, exceeding ${this.maxQueueSizeBytes}B queue limit; dropping`);return}for(;(this.pending.length>=this.maxPendingBatches||this.pendingSizeBytes+t>this.maxQueueSizeBytes)&&this.pending.length>0;)this.dropOldestPending(`Pending queue limit reached`);this.pending.push(e),this.pendingSizeBytes+=t}async flush(e,t){let n=c(this.options.siteKey,this.cookieless);if(n&&this.enqueueEventsIfReady(n.prev,!0),this.enqueueEventsIfReady(this.sessionContext(),t),this.pending.length!==0){if(this.sending){this.flushQueued=!0,this.flushQueuedLowLatency||=e;return}this.sending=!0;try{for(;this.pending.length>0;){let t=this.pending[0];if(!t)break;if(!await this.sendBatch(t,e)){this.log(`Failed to send replay batch ${t.sequence}, retrying`),this.scheduleRetry();break}this.dropOldestPending(`Sent replay batch`),e=!1}}finally{if(this.sending=!1,this.flushQueued){let e=this.flushQueuedLowLatency;this.flushQueued=!1,this.flushQueuedLowLatency=!1,this.flush(e)}}}}scheduleRetry(){this.retryTask||=setTimeout(()=>{this.retryTask=null,this.flush(!1)},1e3)}async sendBatch(e,t){let n=JSON.stringify(e),r={debug:!1,useBeacon:t,keepalive:t};if(!t&&(this.options.compress??!0)&&this.compressionSupported)try{let e=new Blob([n]).stream().pipeThrough(new CompressionStream(`gzip`)),t=new Uint8Array(await new Response(e).arrayBuffer());return this.log(`Compressed ${n.length}B -> ${t.byteLength}B (${Math.round(t.byteLength/n.length*100)}%)`),i({url:`${this.endpoint}?encoding=gzip`,data:t,contentType:`application/octet-stream`,...r})}catch{this.log(`Compression failed, using uncompressed`)}return i({url:this.endpoint,data:n,contentType:`application/json`,...r})}};export{m as default};
1
+ import{a as e,r as t,t as n}from"./chunks/api-urls-Bh77rElT.js";import{a as r,i,n as a,o,r as s,s as c,t as l,u}from"./chunks/send-data-Cc1nxIlg.js";import{t as d}from"./chunks/identifiers-uytEhnH9.js";import{record as f}from"@rrweb/record";const p=new TextEncoder,m=new WeakMap;function h(){return{mousemove:50,mouseInteraction:!0,scroll:150,media:800,input:`last`}}function g(e){return`faststats_replay_sampled_${e}`}function _(e,t){let n=l(t);if(n>=100)return!0;if(n<=0)return!1;let a=i(e).sessionId,o=g(e),s=`${a}:${n}`;try{let e=sessionStorage?.getItem(o);if(e===s)return!0;if(e?.startsWith(`${a}:`))return!1}catch{}let c=r(a)%100<n;try{sessionStorage?.setItem(o,c?s:`${a}:out`)}catch{}return c}var v=class{options;endpoint;compressionSupported=typeof window<`u`&&`CompressionStream`in window;flushInterval;maxEvents;maxBatchSizeBytes;maxPendingBatches;maxQueueSizeBytes;minReplayLengthMs;sampled;events=[];pending=[];queuedEventsSizeBytes=0;pendingSizeBytes=0;viewId=s();chunkStartedAt=0;started=!1;startGeneration=0;startTime=0;sequence=0;intervalId=null;flushTask=null;retryTask=null;minLengthFlushTask=null;stopRecording;sending=!1;flushQueued=!1;flushQueuedLowLatency=!1;unsubscribeRotation;lastCookielessMode=o();constructor(r){this.options=r,this.endpoint=`${e(r.baseUrl,n)}${t.replay}`,this.flushInterval=r.flushInterval??5e3,this.maxEvents=r.maxEvents??1e3,this.maxBatchSizeBytes=r.maxBatchSizeBytes??524288,this.maxPendingBatches=r.maxPendingBatches??30,this.maxQueueSizeBytes=r.maxQueueSizeBytes??2097152,this.minReplayLengthMs=r.minReplayLengthMs??3e3,this.sampled=_(r.siteKey,r.samplingPercentage??100)}log(...e){this.options.debug&&console.log(`[Replay]`,...e)}clearFlushTimers(){this.flushTask&&clearTimeout(this.flushTask),this.retryTask&&clearTimeout(this.retryTask),this.minLengthFlushTask&&clearTimeout(this.minLengthFlushTask),this.flushTask=null,this.retryTask=null,this.minLengthFlushTask=null}clearQueues(){this.events.length=0,this.queuedEventsSizeBytes=0,this.pending.length=0,this.pendingSizeBytes=0}setCookielessMode(e){this.lastCookielessMode!==e&&(this.lastCookielessMode=e,e&&(this.clearQueues(),this.clearFlushTimers()),this.startTime=i(this.options.siteKey).sessionStart,this.chunkStartedAt=Date.now())}start(){if(this.started||typeof window>`u`||!this.sampled)return;this.started=!0,this.viewId=s(),this.startTime=i(this.options.siteKey).sessionStart,this.chunkStartedAt=Date.now(),this.unsubscribeRotation=c(e=>{this.onSessionRotated(e)});let e=++this.startGeneration;this.beginRecording(e),this.intervalId=setInterval(()=>this.requestFlush(`interval`),this.flushInterval),window.addEventListener(`beforeunload`,this.onUnload),this.log(`Recording started`)}trackPageChange(e){this.started&&(this.viewId=s(),this.chunkStartedAt=Date.now(),this.onEvent({type:5,timestamp:Date.now(),data:{tag:`faststats:view`,payload:{href:e??window.location.href,viewId:this.viewId}}},!1))}onPageHidden(e=!1){e||this.flush(!0,!0,`pageHidden`)}onPageShow(e=!1){!e||!this.started||this.pending.length>0&&this.flush(!1,!1,`pageShow`)}async beginRecording(e){let t=this.options.recordConsole===!1?null:await import(`@rrweb/rrweb-plugin-console-record`);if(e!==this.startGeneration)return;let n=[];t&&n.push(t.getRecordConsolePlugin());let r=f({emit:this.onEvent,sampling:this.options.sampling??h(),slimDOMOptions:this.options.slimDOMOptions??{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:!0,headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0},maskAllInputs:this.options.maskAllInputs??!0,maskInputOptions:this.options.maskInputOptions??{password:!0,email:!0,tel:!0},blockClass:this.options.blockClass,blockSelector:this.options.blockSelector,maskTextClass:this.options.maskTextClass,maskTextSelector:this.options.maskTextSelector,checkoutEveryNms:this.options.checkoutEveryNms??6e4,checkoutEveryNth:this.options.checkoutEveryNth,plugins:n});if(e!==this.startGeneration){r?.();return}this.stopRecording=r}stop(){this.started&&(this.started=!1,this.startGeneration++,this.unsubscribeRotation?.(),this.unsubscribeRotation=void 0,this.stopRecording?.(),this.stopRecording=void 0,this.intervalId&&clearInterval(this.intervalId),this.clearFlushTimers(),this.intervalId=null,window.removeEventListener(`beforeunload`,this.onUnload),this.hasReachedMinLength()||(this.events.length=0,this.queuedEventsSizeBytes=0,this.log(`Session too short (${Date.now()-this.startTime}ms), discarding events`)),this.flush(!0,!0,`stop`),this.log(`Recording stopped`))}onSessionRotated(e){this.started&&(this.enqueueEventsIfReady(e,!0,`sessionRotate`),this.pending.length>0&&queueMicrotask(()=>void this.flush(!1)))}onEvent=(e,t)=>{if(this.events.push(e),this.queuedEventsSizeBytes+=this.eventSizeBytes(e),t){this.requestFlush(`checkout`);return}if(this.events.length>=this.maxEvents){this.requestFlush(`maxEvents`);return}if(this.queuedEventsSizeBytes>=this.maxBatchSizeBytes){this.requestFlush(`maxBytes`);return}if(e.type===2&&this.hasReachedMinLength()){this.requestFlush(`fullSnapshot`);return}this.scheduleMinLengthFlush()};onUnload=()=>{this.flush(!0,!0,`unload`)};hasReachedMinLength(){return this.minReplayLengthMs<=0||Date.now()-this.startTime>=this.minReplayLengthMs}requestFlush=(e=`manual`)=>{this.flushTask||this.events.length===0||(this.minLengthFlushTask&&=(clearTimeout(this.minLengthFlushTask),null),this.flushTask=setTimeout(()=>{this.flushTask=null,this.flush(!1,!1,e)},0))};scheduleMinLengthFlush(){if(this.minLengthFlushTask||this.events.length===0||this.hasReachedMinLength())return;let e=Math.max(0,this.minReplayLengthMs-(Date.now()-this.startTime));this.minLengthFlushTask=setTimeout(()=>{this.minLengthFlushTask=null,this.requestFlush(`minLength`)},Math.min(e,2147483647))}enqueueEventsIfReady(e,t,n=`manual`){if(this.events.length!==0){if(!t&&!this.hasReachedMinLength()){this.scheduleMinLengthFlush();return}this.enqueueBatch(this.createBatch(this.events.splice(0),e,t,n)),this.queuedEventsSizeBytes=0}}createBatch(e,t,n,r=`manual`){let i=d(),a=this.sequence++,o=this.chunkStartedAt,s=Date.now();return this.chunkStartedAt=s,{token:this.options.siteKey,sessionId:t.sessionId,windowId:t.windowId,viewId:this.viewId,sessionStart:t.sessionStart,chunkStartedAt:o,chunkEndedAt:s,...i?{identifier:i}:{},batchId:`${t.sessionId}-${a}-${o}`,sequence:a,timestamp:s,url:window.location.href,...n?{isFinal:!0}:{},flushReason:r,events:e}}eventSizeBytes(e){return p.encode(JSON.stringify(e)).byteLength+1}batchSizeBytes(e){let t=m.get(e);if(t!==void 0)return t;let n=p.encode(JSON.stringify(e)).byteLength;return m.set(e,n),n}dropOldestPending(e){let t=this.pending.shift();t&&(this.pendingSizeBytes=Math.max(0,this.pendingSizeBytes-this.batchSizeBytes(t)),this.log(`${e}, dropping batch ${t.sequence}`))}enqueueBatch(e){let t=this.batchSizeBytes(e);if(t>this.maxQueueSizeBytes){this.log(`Replay batch ${e.sequence} is ${t}B, exceeding ${this.maxQueueSizeBytes}B queue limit; dropping`);return}for(;(this.pending.length>=this.maxPendingBatches||this.pendingSizeBytes+t>this.maxQueueSizeBytes)&&this.pending.length>0;)this.dropOldestPending(`Pending queue limit reached`);this.pending.push(e),this.pendingSizeBytes+=t}async flush(e,t,n=`manual`){let r=u(this.options.siteKey);if(r&&this.enqueueEventsIfReady(r.prev,!0,`sessionRotate`),this.enqueueEventsIfReady(i(this.options.siteKey),t,n),this.pending.length!==0){if(this.sending){this.flushQueued=!0,this.flushQueuedLowLatency||=e;return}this.sending=!0;try{for(;this.pending.length>0;){let t=this.pending[0];if(!t)break;if(!await this.sendBatch(t,e)){this.log(`Failed to send replay batch ${t.sequence}, retrying`),this.scheduleRetry();break}this.dropOldestPending(`Sent replay batch`),e=!1}}finally{if(this.sending=!1,this.flushQueued){let e=this.flushQueuedLowLatency;this.flushQueued=!1,this.flushQueuedLowLatency=!1,this.flush(e)}}}}scheduleRetry(){this.retryTask||=setTimeout(()=>{this.retryTask=null,this.flush(!1)},1e3)}async sendBatch(e,t){let n=JSON.stringify(e),r={debug:!1,useBeacon:t,keepalive:t};if(!t&&(this.options.compress??!0)&&this.compressionSupported)try{let e=new Blob([n]).stream().pipeThrough(new CompressionStream(`gzip`)),t=new Uint8Array(await new Response(e).arrayBuffer());return this.log(`Compressed ${n.length}B -> ${t.byteLength}B (${Math.round(t.byteLength/n.length*100)}%)`),a({url:`${this.endpoint}?encoding=gzip`,data:t,contentType:`application/octet-stream`,...r})}catch{this.log(`Compression failed, using uncompressed`)}return a({url:this.endpoint,data:n,contentType:`application/json`,...r})}};export{v as default};
@@ -1 +1 @@
1
- import{r as e,t}from"./chunks/api-urls-DYXBPqSP.js";import{a as n,i as r,n as i,t as a}from"./chunks/send-data-BXrEi1iz.js";var o=class{endpoint;sampled;metrics=new Map;started=!1;flushing=!1;url=``;constructor(i){this.options=i,this.endpoint=`${e(i.baseUrl)}${t.vitals}`;let o=a(i.samplingPercentage);this.sampled=o>=100||o>0&&n(r(i.siteKey).sessionId)%100<o}async start(){if(this.started||typeof window>`u`)return;this.started=!0,this.url=window.location.href;let e=await(this.options.attribution?import(`web-vitals/attribution`):import(`web-vitals`));if(!this.started)return;let t={reportAllChanges:!0};e.onCLS(this.onMetric,t),e.onINP(this.onMetric,t),e.onLCP(this.onMetric,t),e.onFCP(this.onMetric),e.onTTFB(this.onMetric)}stop(){this.started&&(this.started=!1,this.flush())}onPageHidden(e=!1){e||this.flush()}trackPageChange(e){if(!this.started)return;let t=e??window.location.href;t!==this.url&&(this.flush(),this.url=t)}onMetric=e=>{if(!this.started||!this.sampled)return;let t=e.name,{id:n,rating:r,delta:i,navigationType:a}=e,o=`attribution`in e&&e.attribution?e.attribution:void 0;this.metrics.set(t,{metric:t,value:e.value,attributes:{id:n,rating:r,delta:i,navigationType:a,...o}})};flush(){if(!this.metrics.size||this.flushing)return;this.flushing=!0;let e=this.metrics;this.metrics=new Map;let t=r(this.options.siteKey);i({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,sessionId:t.sessionId,windowId:t.windowId,vitals:[...e.values()],metadata:{url:this.url}}),debug:this.options.debug,debugPrefix:`[WebVitals]`}).then(t=>{if(!t)for(let[t,n]of e)this.metrics.has(t)||this.metrics.set(t,n);this.flushing=!1})}};export{o as default};
1
+ import{a as e,r as t,t as n}from"./chunks/api-urls-Bh77rElT.js";import{a as r,i,n as a,t as o}from"./chunks/send-data-Cc1nxIlg.js";var s=class{options;endpoint;sampled;metrics=new Map;started=!1;flushing=!1;url=``;constructor(a){this.options=a,this.endpoint=`${e(a.baseUrl,n)}${t.vitals}`;let s=o(a.samplingPercentage);this.sampled=s>=100||s>0&&r(i(a.siteKey).sessionId)%100<s}async start(){if(this.started||typeof window>`u`)return;this.started=!0,this.url=window.location.href;let e=await(this.options.attribution?import(`web-vitals/attribution`):import(`web-vitals`));if(!this.started)return;let t={reportAllChanges:!0};e.onCLS(this.onMetric,t),e.onINP(this.onMetric,t),e.onLCP(this.onMetric,t),e.onFCP(this.onMetric),e.onTTFB(this.onMetric)}stop(){this.started&&(this.started=!1,this.flush())}onPageHidden(e=!1){e||this.flush()}trackPageChange(e){if(!this.started)return;let t=e??window.location.href;t!==this.url&&(this.flush(),this.url=t)}onMetric=e=>{if(!this.started||!this.sampled)return;let t=e.name,{id:n,rating:r,delta:i,navigationType:a}=e,o=`attribution`in e&&e.attribution?e.attribution:void 0;this.metrics.set(t,{metric:t,value:e.value,attributes:{id:n,rating:r,delta:i,navigationType:a,...o}})};flush(){if(!this.metrics.size||this.flushing)return;this.flushing=!0;let e=this.metrics;this.metrics=new Map;let t=i(this.options.siteKey);a({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,sessionId:t.sessionId,windowId:t.windowId,vitals:[...e.values()],metadata:{url:this.url}}),debug:this.options.debug,debugPrefix:`[WebVitals]`}).then(t=>{if(!t)for(let[t,n]of e)this.metrics.has(t)||this.metrics.set(t,n);this.flushing=!1})}};export{s as default};
package/package.json CHANGED
@@ -42,7 +42,7 @@
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
- "version": "0.4.0",
45
+ "version": "0.4.2",
46
46
  "scripts": {
47
47
  "build": "tsdown && bun run check-size",
48
48
  "dev": "bun run build",
@@ -53,8 +53,8 @@
53
53
  "devDependencies": {
54
54
  "@rrweb/types": "^2.0.1",
55
55
  "@types/bun": "latest",
56
- "tsdown": "^0.21.4",
57
- "typescript": "^5.9.3"
56
+ "tsdown": "^0.22.3",
57
+ "typescript": "^6.0.3"
58
58
  },
59
59
  "dependencies": {
60
60
  "@rrweb/rrweb-plugin-console-record": "^2.0.1",
@@ -1 +0,0 @@
1
- function e(e){return e.replace(/\/+$/,``)}function t(t,n){return t===void 0||t===``?n:e(t)||n}function n(e){return t(e,`https://metrics.faststats.dev`)}function r(e){return t(e,`https://flags.faststats.dev`)}const i={events:`/v1/web`,identify:`/v1/identify`,replay:`/v1/replay`,vitals:`/v1/vitals`,flags:`/v1/check`},a=[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`];function o(){let e={page:location.pathname,url:location.href,referrer:document.referrer||null,title:document.title||``};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of a){let r=t.get(n);r&&(e[n]=r)}return e}export{r as i,o as n,n as r,i as t};