@faststats/web 0.2.14 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/api-urls-nKmJnyjD.js +1 -0
- package/dist/chunks/identifiers-DrjjHcKB.js +1 -0
- package/dist/chunks/{replay-DvJYurEC.d.ts → replay-DR_T0Iz4.d.ts} +12 -17
- package/dist/chunks/send-data-Cb4xlYF0.js +1 -0
- package/dist/error.d.ts +4 -12
- package/dist/error.js +2 -1
- package/dist/feature-flags.d.ts +19 -2
- package/dist/feature-flags.js +1 -1
- package/dist/index.d.ts +28 -59
- package/dist/index.js +1 -1
- package/dist/replay.d.ts +2 -2
- package/dist/replay.js +1 -1
- package/dist/web-vitals.d.ts +5 -8
- package/dist/web-vitals.js +1 -1
- package/package.json +7 -6
- package/CHANGELOG.md +0 -184
- package/REPLAY_PAYLOAD.md +0 -64
- package/dist/chunks/api-urls-DaeYkG0_.js +0 -1
- package/dist/chunks/error-Cd9PTS5v.js +0 -2
- package/dist/chunks/feature-flags-BClx56v5.d.ts +0 -19
- package/dist/chunks/feature-flags-DSOCIZHK.js +0 -1
- package/dist/chunks/replay-rTqcjOo2.js +0 -1
- package/dist/chunks/rolldown-runtime-MP-BAFHD.js +0 -1
- package/dist/chunks/send-data-B2fYGj6v.js +0 -1
- package/dist/chunks/session-manager-Cy63ptPF.js +0 -1
- package/dist/chunks/types-CYzR5xtT.js +0 -1
- package/dist/chunks/web-vitals-Be-Cg4Po.js +0 -1
- package/scripts/check-bundle-size.mjs +0 -96
- package/src/analytics.ts +0 -787
- package/src/entries/error.ts +0 -6
- package/src/entries/feature-flags.ts +0 -5
- package/src/entries/main.ts +0 -21
- package/src/entries/replay.ts +0 -1
- package/src/entries/web-vitals.ts +0 -1
- package/src/env.d.ts +0 -2
- package/src/error.ts +0 -257
- package/src/feature-flags.ts +0 -84
- package/src/replay.ts +0 -596
- package/src/sdk.ts +0 -8
- package/src/utils/api-urls.ts +0 -24
- package/src/utils/identifiers.ts +0 -47
- package/src/utils/send-data.ts +0 -52
- package/src/utils/session-manager.ts +0 -416
- package/src/utils/types.ts +0 -15
- package/src/web-vitals.ts +0 -159
- package/tests/analytics.test.ts +0 -453
- package/tests/identifiers.test.ts +0 -78
- package/tests/replay.test.ts +0 -582
- package/tests/session-manager.test.ts +0 -161
- package/tests/web-vitals.test.ts +0 -208
- package/tsconfig.json +0 -30
- package/tsdown.config.ts +0 -27
- package/worker/index.ts +0 -22
|
@@ -0,0 +1 @@
|
|
|
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`};function a(){return{page:location.pathname,url:location.href,referrer:document.referrer||null,title:document.title||``}}export{r as i,a as n,n as r,i as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e,r as t}from"./send-data-Cb4xlYF0.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,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { recordOptions } from "rrweb/typings/types";
|
|
3
|
-
import { SlimDOMOptions } from "rrweb-snapshot";
|
|
1
|
+
import { record } from "@rrweb/record";
|
|
4
2
|
|
|
5
3
|
//#region src/replay.d.ts
|
|
4
|
+
type RecordOptions = NonNullable<Parameters<typeof record>[0]>;
|
|
6
5
|
interface ReplayTrackerOptions {
|
|
7
6
|
siteKey: string;
|
|
8
7
|
baseUrl?: string;
|
|
@@ -15,10 +14,10 @@ interface ReplayTrackerOptions {
|
|
|
15
14
|
maxPendingBatches?: number;
|
|
16
15
|
maxQueueSizeBytes?: number;
|
|
17
16
|
minReplayLengthMs?: number;
|
|
18
|
-
sampling?:
|
|
19
|
-
slimDOMOptions?:
|
|
17
|
+
sampling?: RecordOptions["sampling"];
|
|
18
|
+
slimDOMOptions?: RecordOptions["slimDOMOptions"];
|
|
20
19
|
maskAllInputs?: boolean;
|
|
21
|
-
maskInputOptions?:
|
|
20
|
+
maskInputOptions?: RecordOptions["maskInputOptions"];
|
|
22
21
|
blockClass?: string;
|
|
23
22
|
blockSelector?: string;
|
|
24
23
|
maskTextClass?: string;
|
|
@@ -36,7 +35,7 @@ declare class ReplayTracker {
|
|
|
36
35
|
private readonly pending;
|
|
37
36
|
private pendingSizeBytes;
|
|
38
37
|
private viewId;
|
|
39
|
-
private
|
|
38
|
+
private chunkStartedAt;
|
|
40
39
|
private started;
|
|
41
40
|
private startTime;
|
|
42
41
|
private sequence;
|
|
@@ -47,40 +46,36 @@ declare class ReplayTracker {
|
|
|
47
46
|
private stopRecording?;
|
|
48
47
|
private sending;
|
|
49
48
|
private unsubscribeRotation?;
|
|
49
|
+
private cookieless;
|
|
50
50
|
constructor(options: ReplayTrackerOptions);
|
|
51
|
-
private get cookieless();
|
|
52
|
-
private get debug();
|
|
53
51
|
private get flushInterval();
|
|
54
52
|
private get maxEvents();
|
|
55
53
|
private get maxPendingBatches();
|
|
56
54
|
private get maxQueueSizeBytes();
|
|
57
55
|
private get minReplayLengthMs();
|
|
58
|
-
private get shouldCompress();
|
|
59
56
|
private log;
|
|
60
57
|
private sessionContext;
|
|
58
|
+
setCookielessMode(cookieless: boolean): void;
|
|
59
|
+
private resetChunk;
|
|
61
60
|
start(): void;
|
|
62
61
|
trackPageChange(url?: string): void;
|
|
62
|
+
onPageHidden(persisted?: boolean): void;
|
|
63
|
+
onPageShow(persisted?: boolean): void;
|
|
63
64
|
private beginRecording;
|
|
64
65
|
stop(): void;
|
|
65
|
-
getSessionId(): string;
|
|
66
|
-
getWindowId(): string;
|
|
67
66
|
private onSessionRotated;
|
|
68
67
|
private onEvent;
|
|
69
68
|
private onUnload;
|
|
70
|
-
private onVisibilityChange;
|
|
71
69
|
private hasReachedMinLength;
|
|
72
70
|
private requestFlush;
|
|
73
71
|
private scheduleMinLengthFlush;
|
|
74
72
|
private createBatch;
|
|
75
|
-
private createBatchId;
|
|
76
73
|
private getBatchSizeBytes;
|
|
77
74
|
private dropOldestPendingBatch;
|
|
78
75
|
private enqueueBatch;
|
|
79
|
-
private encodeBatch;
|
|
80
76
|
private flush;
|
|
81
77
|
private scheduleRetry;
|
|
82
|
-
private
|
|
83
|
-
private send;
|
|
78
|
+
private sendBatch;
|
|
84
79
|
}
|
|
85
80
|
//#endregion
|
|
86
81
|
export { ReplayTrackerOptions as n, ReplayTracker as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`faststats_session`;let t=!1,n=null;const r=new Set;function i(){try{return globalThis.localStorage}catch{return null}}function a(){try{return globalThis.sessionStorage}catch{return null}}function o(){return typeof crypto<`u`&&`randomUUID`in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function s(e){let t=0;for(let n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t|=0;return Math.abs(t)}function c(e){if(!e)return null;try{let t=JSON.parse(e);if(typeof t.id==`string`&&t.id&&Number.isFinite(t.start)&&t.start>0&&Number.isFinite(t.activity)&&t.activity>0)return t}catch{}return null}function l(){let t=i();if(!t)return n;let r=c(t.getItem(e));if(r)return r;let a=t.getItem(`faststats_session_id`),o=t.getItem(`faststats_session_activity`),s=o===null?NaN:Number(o);if(!a||!Number.isFinite(s))return n;let l=t.getItem(`faststats_session_start`),d=l===null?s:Number(l),f={id:a,start:Number.isFinite(d)?d:s,activity:s};return u(f),t.removeItem(`faststats_session_id`),t.removeItem(`faststats_session_activity`),t.removeItem(`faststats_session_start`),f}function u(t){let r=i();if(!r){n=t;return}try{r.setItem(e,JSON.stringify(t))}catch{n=t}}function d(){n=null;try{i()?.removeItem(e)}catch{}}function f(e,t){return t-e.activity>=18e5||t-e.start>=864e5}function p(e,t){for(let n of r)n(e,t)}function m(e,t){let r=Date.now();if(e)return n?t&&(n.activity=r):n={id:o(),start:r,activity:r},{session:n,rotated:!1,previous:null};let i=l();if(i&&!f(i,r))return t&&(i.activity=r,u(i)),{session:i,rotated:!1,previous:null};let a=i,s={id:o(),start:r,activity:r};return u(s),{session:s,rotated:a!==null,previous:a}}function h(e,t,n){if(t)return n;let r=`faststats_window_id_${e}`,i=a();if(!i)return n;try{let e=i.getItem(r);if(e)return e;let t=o();return i.setItem(r,t),t}catch{return n}}function g(e,t,n,r){let i=r??h(e,n,t.id);return{sessionId:t.id,windowId:i,sessionStart:t.start}}function _(e){t=e,e&&(n=null)}function v(){return t}function y(e,n){let r=n??t,{session:i}=m(r,!1);return h(e,r,i.id)}function b(e,n){let r=n??t,{session:i}=m(r,!1);return g(e,i,r)}function x(e){return m(e??t,!0).session.id}function S(e){return m(e??t,!1).session.start}function C(e,n){let r=n??t,{session:i,rotated:a,previous:o}=m(r,!0);if(!a||!o)return null;let s=h(e,r,i.id),c={prev:g(e,o,r,s),next:g(e,i,r,s)};return p(c.prev,c.next),c}function w(e){let r=t,i=b(e,r);if(d(),r){let e=Date.now();n={id:o(),start:e,activity:e}}else try{a()?.removeItem(`faststats_window_id_${e}`)}catch{}let s=b(e,r);return i.sessionId!==s.sessionId&&p(i,s),s}function T(e){return r.add(e),()=>r.delete(e)}function E(e){return typeof e!=`number`||!Number.isFinite(e)?100:Math.max(0,Math.min(100,e))}async function D(e){let{url:t,data:n,contentType:r=`application/json`,headers:i={},debug:a=!1,debugPrefix:o=`[Analytics]`,useBeacon:s=!0,keepalive:c=!0,signal:l}=e;if(l?.aborted)return!1;if(s&&typeof globalThis.navigator?.sendBeacon==`function`)try{let e=n instanceof Blob?n:typeof Blob<`u`?new Blob([n],{type:r}):n;if(globalThis.navigator.sendBeacon(t,e))return a&&console.log(`${o} Sent via beacon`),!0}catch{}if(typeof globalThis.fetch!=`function`)return a&&console.warn(`${o} Failed to send`),!1;try{let e=await fetch(t,{method:`POST`,body:n,headers:{"Content-Type":r,...i},keepalive:c,credentials:`omit`,signal:l}),s=e.ok;if(a){let t=s?`${o} Sent via fetch`:`${o} Failed: ${e.status}`;console[s?`log`:`warn`](t)}return s}catch{return a&&console.warn(`${o} Failed to send`),!1}}export{y as a,s as c,w as d,_ as f,x as i,v as l,D as n,b as o,C as p,o as r,S as s,E as t,T as u};
|
package/dist/error.d.ts
CHANGED
|
@@ -4,11 +4,6 @@ type ErrorEntry = {
|
|
|
4
4
|
message?: string;
|
|
5
5
|
stack?: string[];
|
|
6
6
|
handled?: boolean;
|
|
7
|
-
cause?: ErrorEntry;
|
|
8
|
-
};
|
|
9
|
-
type ErrorTracking = ErrorEntry & {
|
|
10
|
-
hash: string;
|
|
11
|
-
count: number;
|
|
12
7
|
};
|
|
13
8
|
interface ErrorTrackingOptions {
|
|
14
9
|
siteKey: string;
|
|
@@ -22,8 +17,7 @@ interface ErrorTrackingOptions {
|
|
|
22
17
|
declare class ErrorTracker {
|
|
23
18
|
private readonly options;
|
|
24
19
|
private readonly endpoint;
|
|
25
|
-
private
|
|
26
|
-
private readonly queue;
|
|
20
|
+
private queue;
|
|
27
21
|
private timer;
|
|
28
22
|
private started;
|
|
29
23
|
private flushing;
|
|
@@ -31,14 +25,12 @@ declare class ErrorTracker {
|
|
|
31
25
|
private log;
|
|
32
26
|
start(): void;
|
|
33
27
|
stop(): void;
|
|
28
|
+
onPageHidden(persisted?: boolean): void;
|
|
34
29
|
captureError(error: Error): void;
|
|
35
30
|
private onError;
|
|
36
31
|
private onRejection;
|
|
37
|
-
private
|
|
38
|
-
private scheduleFlush;
|
|
39
|
-
private capture;
|
|
32
|
+
private enqueue;
|
|
40
33
|
private flush;
|
|
41
|
-
private requeue;
|
|
42
34
|
}
|
|
43
35
|
//#endregion
|
|
44
|
-
export {
|
|
36
|
+
export { ErrorEntry, ErrorTrackingOptions, ErrorTracker as default };
|
package/dist/error.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{t as
|
|
1
|
+
import{n as e,r as t,t as n}from"./chunks/api-urls-nKmJnyjD.js";import{a as r,i,n as a}from"./chunks/send-data-Cb4xlYF0.js";import{t as o}from"./chunks/identifiers-DrjjHcKB.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{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(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 t=this.queue;this.queue=new Map;let n=[...t.values()];this.log(`Flushing:`,n);try{let s=globalThis.__SOURCEMAPS_BUILD__?.buildId,c=o();if(!await a({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,...c?{userId:c}:{},sessionId:i(),windowId:r(this.options.siteKey),...typeof s==`string`&&s.trim()?{buildId:s}:{},sdkName:this.options.sdkName??`@faststats/web`,sdkVersion:this.options.sdkVersion??`0.3.1`,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{d as default};
|
package/dist/feature-flags.d.ts
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/feature-flags.d.ts
|
|
2
|
+
type FeatureFlagEvaluation = {
|
|
3
|
+
value: string;
|
|
4
|
+
variantKey?: string;
|
|
5
|
+
variantValue?: string;
|
|
6
|
+
};
|
|
7
|
+
type FeatureFlagCheckContext = {
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
projectToken?: string;
|
|
10
|
+
projectId?: string;
|
|
11
|
+
identifier?: string;
|
|
12
|
+
externalId?: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
attributes?: Record<string, unknown>;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
};
|
|
17
|
+
declare function fetchFeatureFlagEvaluation(flagKey: string, context: FeatureFlagCheckContext): Promise<FeatureFlagEvaluation>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { FeatureFlagCheckContext, FeatureFlagEvaluation, fetchFeatureFlagEvaluation };
|
package/dist/feature-flags.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{i as e,t}from"./chunks/api-urls-nKmJnyjD.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};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ReplayTrackerOptions } from "./chunks/replay-
|
|
1
|
+
import { FeatureFlagEvaluation } from "./feature-flags.js";
|
|
2
|
+
import { n as ReplayTrackerOptions } from "./chunks/replay-DR_T0Iz4.js";
|
|
3
3
|
|
|
4
|
-
//#region src/utils/types.d.ts
|
|
5
|
-
interface SendDataOptions {
|
|
6
|
-
url: string;
|
|
7
|
-
data: string | Blob | Uint8Array;
|
|
8
|
-
contentType?: string;
|
|
9
|
-
headers?: Record<string, string>;
|
|
10
|
-
debug?: boolean;
|
|
11
|
-
debugPrefix?: string;
|
|
12
|
-
useBeacon?: boolean;
|
|
13
|
-
keepalive?: boolean;
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/utils/send-data.d.ts
|
|
17
|
-
declare function sendData(options: SendDataOptions): Promise<boolean>;
|
|
18
|
-
//#endregion
|
|
19
4
|
//#region src/analytics.d.ts
|
|
20
|
-
type Dict = Record<string, unknown>;
|
|
21
|
-
interface SamplingOptions {
|
|
22
|
-
percentage?: number;
|
|
23
|
-
}
|
|
24
|
-
interface WebVitalsConfig {
|
|
25
|
-
sampling?: SamplingOptions;
|
|
26
|
-
attribution?: boolean;
|
|
27
|
-
}
|
|
28
|
-
interface SessionReplayConfig {
|
|
29
|
-
enabled?: boolean;
|
|
30
|
-
sampling?: SamplingOptions;
|
|
31
|
-
}
|
|
32
5
|
type ConsentMode = "pending" | "granted" | "denied";
|
|
33
|
-
interface ConsentConfig {
|
|
34
|
-
mode?: ConsentMode;
|
|
35
|
-
cookielessWhilePending?: boolean;
|
|
36
|
-
}
|
|
37
6
|
interface IdentifyOptions {
|
|
38
7
|
name?: string;
|
|
39
8
|
phone?: string;
|
|
@@ -51,9 +20,23 @@ interface WebAnalyticsOptions {
|
|
|
51
20
|
trackWebVitals?: boolean;
|
|
52
21
|
trackReplay?: boolean;
|
|
53
22
|
cookieless?: boolean;
|
|
54
|
-
consent?:
|
|
55
|
-
|
|
56
|
-
|
|
23
|
+
consent?: {
|
|
24
|
+
mode?: ConsentMode;
|
|
25
|
+
cookielessWhilePending?: boolean;
|
|
26
|
+
};
|
|
27
|
+
webVitals?: {
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
sampling?: {
|
|
30
|
+
percentage?: number;
|
|
31
|
+
};
|
|
32
|
+
attribution?: boolean;
|
|
33
|
+
};
|
|
34
|
+
sessionReplays?: {
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
sampling?: {
|
|
37
|
+
percentage?: number;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
57
40
|
replayOptions?: Partial<ReplayTrackerOptions>;
|
|
58
41
|
/** @internal */
|
|
59
42
|
sdkName?: string;
|
|
@@ -80,13 +63,10 @@ declare class WebAnalytics {
|
|
|
80
63
|
private pageKey;
|
|
81
64
|
private navTimer;
|
|
82
65
|
private heartbeatTimer;
|
|
83
|
-
private scrollDepth;
|
|
84
|
-
private pageEntryTime;
|
|
85
66
|
private pagePath;
|
|
86
67
|
private pageUrl;
|
|
87
68
|
private pageHash;
|
|
88
69
|
private hasLeftCurrentPage;
|
|
89
|
-
private scrollHandler;
|
|
90
70
|
private consentMode;
|
|
91
71
|
private readonly cookielessWhilePending;
|
|
92
72
|
private readonly cleanupCallbacks;
|
|
@@ -95,33 +75,23 @@ declare class WebAnalytics {
|
|
|
95
75
|
private errorTracker;
|
|
96
76
|
private readonly handleVisibilityChange;
|
|
97
77
|
private readonly handlePageHide;
|
|
98
|
-
private readonly
|
|
99
|
-
private readonly handleHashChange;
|
|
78
|
+
private readonly handlePageShow;
|
|
100
79
|
constructor(options: WebAnalyticsOptions);
|
|
101
80
|
private log;
|
|
102
81
|
private init;
|
|
103
|
-
private registerCleanup;
|
|
104
|
-
private addWindowListener;
|
|
105
|
-
private addDocumentListener;
|
|
106
|
-
private patchHistory;
|
|
107
82
|
private ensureStarted;
|
|
108
|
-
private
|
|
109
|
-
private
|
|
110
|
-
private
|
|
111
|
-
private registerChildTracker;
|
|
83
|
+
private addListener;
|
|
84
|
+
private patchHistory;
|
|
85
|
+
private notifyChildren;
|
|
112
86
|
private startChildTracker;
|
|
113
|
-
private
|
|
114
|
-
private startWebVitalsTracker;
|
|
115
|
-
private startReplayTracker;
|
|
87
|
+
private startOptionalTrackers;
|
|
116
88
|
start(): Promise<void>;
|
|
117
89
|
destroy(): void;
|
|
118
|
-
pageview(extra?:
|
|
119
|
-
track(name: string, extra?:
|
|
90
|
+
pageview(extra?: Record<string, unknown>): void;
|
|
91
|
+
track(name: string, extra?: Record<string, unknown>): void;
|
|
120
92
|
identify(externalId: string, email: string, options?: IdentifyOptions): Promise<boolean>;
|
|
121
93
|
logout(resetAnonymousIdentity?: boolean): void;
|
|
122
94
|
setConsentMode(mode: ConsentMode): void;
|
|
123
|
-
optIn(): void;
|
|
124
|
-
optOut(): void;
|
|
125
95
|
getConsentMode(): ConsentMode;
|
|
126
96
|
getAnonymousId(): string;
|
|
127
97
|
getSessionId(): string;
|
|
@@ -135,10 +105,9 @@ declare class WebAnalytics {
|
|
|
135
105
|
private send;
|
|
136
106
|
private enterPage;
|
|
137
107
|
private leavePage;
|
|
138
|
-
private trackScroll;
|
|
139
108
|
private startHeartbeat;
|
|
109
|
+
private stopHeartbeat;
|
|
140
110
|
private navigate;
|
|
141
|
-
private links;
|
|
142
111
|
}
|
|
143
112
|
//#endregion
|
|
144
|
-
export { type ConsentMode, type
|
|
113
|
+
export { type ConsentMode, type FeatureFlagEvaluation, type IdentifyOptions, WebAnalytics, type WebAnalyticsOptions, getInstance, identify, isTrackingDisabled, logout, optIn, optOut, reportError, setConsentMode, trackEvent };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,r as t,t as n}from"./chunks/api-urls-DaeYkG0_.js";import{a as r,c as i,d as a,i as o,l as s,n as c,u as l}from"./chunks/session-manager-Cy63ptPF.js";import{n as u,r as d,t as f}from"./chunks/send-data-B2fYGj6v.js";import{t as p}from"./chunks/types-CYzR5xtT.js";import{n as m}from"./chunks/feature-flags-DSOCIZHK.js";function h(e){return e.replayOptions?.samplingPercentage!==void 0||e.sessionReplays?.sampling?.percentage!==void 0}function g(e,t,n){if(!(e.sessionReplays?.enabled??e.trackReplay??h(e)))return null;let r=e.replayOptions??{};return{siteKey:e.siteKey,baseUrl:t,debug:n,...r,samplingPercentage:p(r.samplingPercentage??e.sessionReplays?.sampling?.percentage)}}const _={instance:null,pendingConsentMode:void 0};function v(){return _.instance}function y(e,t){typeof window>`u`||E()||_.instance?.track(e,t??{})}function b(e,t,n){return typeof window>`u`||E()?Promise.resolve(!1):_.instance?.identify(e,t,n??{})??Promise.resolve(!1)}function x(e=!0){typeof window>`u`||E()||_.instance?.logout(e)}function S(e){if(_.instance){_.instance.setConsentMode(e);return}_.pendingConsentMode=e}function C(){S(`granted`)}function w(){S(`denied`)}function T(e){typeof window>`u`||E()||_.instance?.reportError(e)}function E(){if(typeof localStorage>`u`)return!1;let e=localStorage.getItem(`disable-faststats`);return e===`true`||e===`1`}function D(e){for(;e;){if(e instanceof HTMLAnchorElement&&e.href)return e;e=e.parentNode}return null}function O(){let e={};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`]){let r=t.get(n);r&&(e[n]=r)}return e}var k=class{webEndpoint;baseUrl;featureFlagsBaseUrl;debug;started=!1;destroyed=!1;pageKey=``;navTimer=null;heartbeatTimer=null;scrollDepth=0;pageEntryTime=0;pagePath=``;pageUrl=``;pageHash=``;hasLeftCurrentPage=!1;scrollHandler=null;consentMode;cookielessWhilePending;cleanupCallbacks=[];childTrackers=[];pendingReportedErrors=[];errorTracker=null;handleVisibilityChange=()=>{document.visibilityState===`hidden`?(i(),this.leavePage(),this.stopHeartbeat()):(i(),this.enterPage(),this.startHeartbeat())};handlePageHide=()=>{this.leavePage()};handlePopState=()=>{this.navigate()};handleHashChange=()=>{this.navigate()};constructor(r){this.options=r,this.baseUrl=e(r.baseUrl),this.featureFlagsBaseUrl=t(r.featureFlagsBaseUrl),this.webEndpoint=`${this.baseUrl}${n.events}`,this.debug=r.debug??!1,this.consentMode=r.consent?.mode??`granted`,this.cookielessWhilePending=r.consent?.cookielessWhilePending??!0,_.pendingConsentMode!==void 0&&(this.consentMode=_.pendingConsentMode,_.pendingConsentMode=void 0),(r.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(!(typeof window>`u`)){if(E()){this.log(`disabled`);return}_.instance=this,a(this.options.siteKey),l(this.isCookielessMode()),setTimeout(()=>void this.start(),0)}}registerCleanup(e){this.cleanupCallbacks.push(e)}addWindowListener(e,t){window.addEventListener(e,t),this.registerCleanup(()=>window.removeEventListener(e,t))}addDocumentListener(e,t){document.addEventListener(e,t),this.registerCleanup(()=>document.removeEventListener(e,t))}patchHistory(){let e=history.pushState.bind(history),t=history.replaceState.bind(history);history.pushState=(t,n,r)=>{e(t,n,r),this.navigate()},history.replaceState=(e,n,r)=>{t(e,n,r),this.navigate()},this.registerCleanup(()=>{history.pushState=e,history.replaceState=t})}ensureStarted(){return typeof window>`u`||this.destroyed||E()?!1:(this.started||this.start(),!0)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}stopNavigationTimer(){this.navTimer&&=(clearTimeout(this.navTimer),null)}stopChildTrackers(){for(let e of this.childTrackers.splice(0))e.stop?.();this.errorTracker=null}registerChildTracker(e){return!this.started||this.destroyed||_.instance!==this?(e.stop?.(),!1):(this.childTrackers.push(e),!0)}async startChildTracker(e,t,n){try{let r=await t();return!this.started||this.destroyed||_.instance!==this?(r.stop?.(),null):(r.start(),this.registerChildTracker(r)?(n?.(r),this.log(`${e} loaded`),r):null)}catch(t){return this.log(`failed to initialize ${e} tracker: ${String(t)}`),null}}async startErrorTracker(){await this.startChildTracker(`error`,async()=>{let{default:e}=await import(`./chunks/error-Cd9PTS5v.js`).then(e=>e.n);return new e({siteKey:this.options.siteKey,baseUrl:this.baseUrl,debug:this.debug,sdkName:this.options.sdkName,sdkVersion:this.options.sdkVersion})},e=>{for(this.errorTracker=e;this.pendingReportedErrors.length>0;){let t=this.pendingReportedErrors.shift();t&&e.captureError(t)}})}async startWebVitalsTracker(){await this.startChildTracker(`web-vitals`,async()=>{let{default:e}=await import(`./chunks/web-vitals-Be-Cg4Po.js`).then(e=>e.n);return new e({siteKey:this.options.siteKey,baseUrl:this.baseUrl,debug:this.debug,samplingPercentage:p(this.options.webVitals?.sampling?.percentage),attribution:this.options.webVitals?.attribution??!1})})}async startReplayTracker(e){await this.startChildTracker(`replay`,async()=>{let{default:t}=await import(`./chunks/replay-rTqcjOo2.js`).then(e=>e.n);return new t(e)})}async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(_.instance&&_.instance!==this){this.log(`already started by another instance`);return}if(E()){this.log(`disabled`);return}this.started=!0,_.instance=this,a(this.options.siteKey),l(this.isCookielessMode()),c();let e=this.options,t=g(e,this.baseUrl,this.debug);t&&this.startReplayTracker({...t,cookieless:this.isCookielessMode()}),e.trackErrors&&this.startErrorTracker(),e.trackWebVitals&&this.startWebVitalsTracker(),this.enterPage(),this.pageview({trigger:`load`}),this.links(),this.trackScroll(),this.startHeartbeat(),this.addDocumentListener(`visibilitychange`,this.handleVisibilityChange),this.addWindowListener(`pagehide`,this.handlePageHide),this.addWindowListener(`popstate`,this.handlePopState),e.trackHash&&this.addWindowListener(`hashchange`,this.handleHashChange),this.patchHistory()}destroy(){if(!this.destroyed){for(this.started&&typeof window<`u`&&this.leavePage(),this.pendingReportedErrors.length=0,this.stopNavigationTimer(),this.stopHeartbeat(),this.scrollHandler&&typeof window<`u`&&(window.removeEventListener(`scroll`,this.scrollHandler),this.scrollHandler=null);this.cleanupCallbacks.length>0;)this.cleanupCallbacks.pop()?.();this.stopChildTrackers(),_.instance===this&&(_.instance=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureStarted())return;let t=`${location.pathname}|${this.options.trackHash??!1?location.hash:``}`;t!==this.pageKey&&(this.pageKey=t,this.send(`pageview`,e))}track(e,t={}){this.ensureStarted()&&this.send(e,t)}identify(e,t,r={}){if(!this.ensureStarted()||this.isCookielessMode())return Promise.resolve(!1);let i=e.trim(),a=t.trim();return!i||!a?Promise.resolve(!1):f({url:`${this.baseUrl}${n.identify}`,data:JSON.stringify({token:this.options.siteKey,identifier:u(!1),externalId:i,email:a,name:r.name?.trim()||void 0,phone:r.phone?.trim()||void 0,avatarUrl:r.avatarUrl?.trim()||void 0,traits:r.traits??{}}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] identify`,useBeacon:!1})}logout(e=!0){this.ensureStarted()&&(e&&d(this.isCookielessMode()),s(this.options.siteKey))}setConsentMode(e){this.consentMode=e,l(this.isCookielessMode())}optIn(){this.setConsentMode(`granted`)}optOut(){this.setConsentMode(`denied`)}getConsentMode(){return this.consentMode}getAnonymousId(){return u(this.isCookielessMode())}getSessionId(){return c()}getWindowId(){return o(this.options.siteKey,this.isCookielessMode()).windowId}async checkFeatureFlag(e,t,n){if(typeof window>`u`||E())return{value:`false`};let r=n?.externalId?.trim(),i=this.getAnonymousId();if(!r&&!i)return{value:`false`};let{fetchFeatureFlagEvaluation:a}=await import(`./chunks/feature-flags-DSOCIZHK.js`).then(e=>e.t);return a(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,...i?{identifier:i}:{},...r?{externalId:r}:{},sessionId:this.getSessionId(),attributes:t,signal:n?.signal})}reportError(e){if(this.destroyed||typeof window>`u`||E()||!(this.options.trackErrors??!1)||!this.ensureStarted())return;let t=this.errorTracker;if(t){t.captureError(e);return}this.pendingReportedErrors.length>=50&&this.pendingReportedErrors.shift(),this.pendingReportedErrors.push(e)}isCookielessMode(){return this.options.cookieless||this.consentMode===`denied`?!0:this.consentMode===`pending`?this.cookielessWhilePending:!1}send(e,t={}){if(typeof window>`u`||this.destroyed||E())return;let n=u(this.isCookielessMode()),r=JSON.stringify({token:this.options.siteKey,...n?{userId:n}:{},sessionId:c(),data:{event:e,page:location.pathname,referrer:document.referrer||null,title:document.title||``,url:location.href,...O(),...t}});this.log(e),f({url:this.webEndpoint,data:r,contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}enterPage(){this.pageEntryTime=Date.now(),this.pagePath=location.pathname,this.pageUrl=location.href,this.pageHash=location.hash,this.scrollDepth=0,this.hasLeftCurrentPage=!1}leavePage(){if(this.destroyed||this.hasLeftCurrentPage)return;this.hasLeftCurrentPage=!0;let e=Date.now();this.send(`page_leave`,{page:this.pagePath,url:this.pageUrl,time_on_page:e-this.pageEntryTime,scroll_depth:this.scrollDepth,session_duration:e-r()})}trackScroll(){this.scrollHandler&&window.removeEventListener(`scroll`,this.scrollHandler);let e=()=>{let e=document.documentElement,t=document.body,n=window.innerHeight,r=Math.max(e.scrollHeight,t.scrollHeight);if(r<=n){this.scrollDepth=100;return}let i=Math.min(100,Math.round(((window.scrollY||e.scrollTop)+n)/r*100));i>this.scrollDepth&&(this.scrollDepth=i)};this.scrollHandler=e,e(),window.addEventListener(`scroll`,e,{passive:!0})}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.stopHeartbeat();return}i()},300*1e3)}navigate(){!this.started||this.destroyed||(this.stopNavigationTimer(),this.navTimer=setTimeout(()=>{this.navTimer=null;let e=location.pathname!==this.pagePath,t=(this.options.trackHash??!1)&&location.hash!==this.pageHash;if(!(!e&&!t)){for(let e of this.childTrackers)e.trackPageChange?.(location.href);this.leavePage(),this.enterPage(),this.trackScroll(),this.pageview({trigger:`navigation`})}},300))}links(){let e=e=>{let t=D(e.target);t&&t.host!==location.host&&this.track(`outbound_link`,{outbound_link:t.href})};this.addDocumentListener(`click`,e),this.addDocumentListener(`auxclick`,e)}};export{k as WebAnalytics,m as fetchFeatureFlagEvaluation,v as getInstance,b as identify,E as isTrackingDisabled,x as logout,C as optIn,w as optOut,T as reportError,f as sendData,S as setConsentMode,y as trackEvent};
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"./chunks/api-urls-nKmJnyjD.js";import{d as i,f as a,i as o,n as s,o as c,p as l,t as u}from"./chunks/send-data-Cb4xlYF0.js";import{n as d,t as f}from"./chunks/identifiers-DrjjHcKB.js";const p=new Set([`browser`,`browser_version`,`device`,`os`,`os_version`,`referrer`,`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`,`title`,`page`,`url`]);function m(e){let t={},n={};for(let[r,i]of Object.entries(e))(p.has(r)?t:n)[r]=i;return{dimensions:t,properties:n}}const h={instance:null,pendingConsentMode:void 0};function g(){return typeof window>`u`||T()?null:h.instance}function _(){return h.instance}function v(e,t){g()?.track(e,t??{})}function y(e,t,n){return g()?.identify(e,t,n??{})??Promise.resolve(!1)}function b(e=!0){g()?.logout(e)}function x(e){h.instance?h.instance.setConsentMode(e):h.pendingConsentMode=e}function S(){x(`granted`)}function C(){x(`denied`)}function w(e){g()?.reportError(e)}function T(){try{let e=globalThis.localStorage?.getItem(`disable-faststats`);return e===`true`||e===`1`}catch{return!1}}function E(e){for(;e;){if(e instanceof HTMLAnchorElement&&e.href)return e;e=e.parentNode}return null}function D(){let e={};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`]){let r=t.get(n);r&&(e[n]=r)}return e}var O=class{webEndpoint;baseUrl;featureFlagsBaseUrl;debug;started=!1;destroyed=!1;pageKey=``;navTimer=null;heartbeatTimer=null;pagePath=``;pageUrl=``;pageHash=``;hasLeftCurrentPage=!1;consentMode;cookielessWhilePending;cleanupCallbacks=[];childTrackers=[];pendingReportedErrors=[];errorTracker=null;handleVisibilityChange=()=>{if(l(this.options.siteKey,this.isCookielessMode()),document.visibilityState===`hidden`){this.notifyChildren(`onPageHidden`),this.stopHeartbeat();return}this.startHeartbeat()};handlePageHide=e=>{this.notifyChildren(`onPageHidden`,e.persisted),e.persisted||this.leavePage()};handlePageShow=e=>{this.notifyChildren(`onPageShow`,e.persisted)};constructor(t){this.options=t,this.baseUrl=n(t.baseUrl),this.featureFlagsBaseUrl=e(t.featureFlagsBaseUrl),this.webEndpoint=`${this.baseUrl}${r.events}`,this.debug=t.debug??!1,this.consentMode=h.pendingConsentMode??t.consent?.mode??`granted`,h.pendingConsentMode=void 0,this.cookielessWhilePending=t.consent?.cookielessWhilePending??!0,(t.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(typeof window>`u`||T()){T()&&this.log(`disabled`);return}setTimeout(()=>void this.start(),0)}ensureStarted(){return typeof window>`u`||this.destroyed||T()?!1:(this.started||this.start(),this.started&&!this.destroyed&&h.instance===this)}addListener(e,t,n,r){e.addEventListener(t,n,r),this.cleanupCallbacks.push(()=>e.removeEventListener(t,n,r))}patchHistory(){for(let e of[`pushState`,`replaceState`]){let t=history[e].bind(history);history[e]=(e,n,r)=>{t(e,n,r),this.navigate()},this.cleanupCallbacks.push(()=>{history[e]=t})}}notifyChildren(e,t=!1){for(let n of this.childTrackers)n[e]?.(t)}async startChildTracker(e,t){try{let n=await t();return!this.started||this.destroyed||h.instance!==this||(await Promise.resolve(n.start()),!this.started||this.destroyed||h.instance!==this)?(n.stop?.(),null):(this.childTrackers.push(n),this.log(`${e} loaded`),n)}catch(t){return this.log(`failed to initialize ${e} tracker: ${String(t)}`),null}}startOptionalTrackers(){let e=this.options;if(e.sessionReplays?.enabled??e.trackReplay){let t=e.replayOptions??{};this.startChildTracker(`replay`,async()=>{let{default:n}=await import(`./replay.js`);return new n({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,...t,samplingPercentage:u(t.samplingPercentage??e.sessionReplays?.sampling?.percentage),cookieless:this.isCookielessMode()})})}e.trackErrors&&this.startChildTracker(`error`,async()=>{let{default:t}=await import(`./error.js`);return new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,sdkName:e.sdkName,sdkVersion:e.sdkVersion})}).then(e=>{if(e){this.errorTracker=e;for(let t of this.pendingReportedErrors.splice(0))e.captureError(t)}}),(e.trackWebVitals??e.webVitals?.enabled)&&this.startChildTracker(`web-vitals`,async()=>{let{default:t}=await import(`./web-vitals.js`);return new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,samplingPercentage:u(e.webVitals?.sampling?.percentage),attribution:e.webVitals?.attribution??!1})})}async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(h.instance&&h.instance!==this){this.log(`already started by another instance`);return}if(T()){this.log(`disabled`);return}this.started=!0,h.instance=this,a(this.isCookielessMode()),o(),this.startOptionalTrackers(),this.enterPage(),this.pageview({trigger:`load`}),this.startHeartbeat();let e=e=>{let t=E(e.target);t&&t.host!==location.host&&this.track(`outbound_link`,{outbound_link:t.href})};this.addListener(document,`click`,e),this.addListener(document,`auxclick`,e),this.addListener(document,`visibilitychange`,this.handleVisibilityChange),this.addListener(window,`pagehide`,this.handlePageHide),this.addListener(window,`pageshow`,this.handlePageShow),this.addListener(window,`popstate`,()=>this.navigate()),this.options.trackHash&&this.addListener(window,`hashchange`,()=>this.navigate()),this.patchHistory()}destroy(){if(!this.destroyed){this.started&&typeof window<`u`&&this.leavePage(),this.pendingReportedErrors.length=0,this.navTimer&&clearTimeout(this.navTimer),this.stopHeartbeat();for(let e of this.cleanupCallbacks.splice(0))e();for(let e of this.childTrackers.splice(0))e.stop?.();this.errorTracker=null,h.instance===this&&(h.instance=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureStarted())return;let t=`${location.pathname}|${this.options.trackHash??!1?location.hash:``}`;t!==this.pageKey&&(this.pageKey=t,this.send(`pageview`,e))}track(e,t={}){if(!this.ensureStarted())return;let n=e.trim();n&&this.send(n,t)}identify(e,t,n={}){if(!this.ensureStarted()||this.isCookielessMode())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.ensureStarted()&&(e&&d(this.isCookielessMode()),i(this.options.siteKey))}setConsentMode(e){this.consentMode=e;let t=this.isCookielessMode();a(t);for(let e of this.childTrackers)e.setCookielessMode?.(t)}getConsentMode(){return this.consentMode}getAnonymousId(){return f(this.isCookielessMode())}getSessionId(){return o()}getWindowId(){return c(this.options.siteKey,this.isCookielessMode()).windowId}async checkFeatureFlag(e,t,n){if(typeof window>`u`||T())return{value:`false`};let r=n?.externalId?.trim(),i=this.getAnonymousId();if(!r&&!i)return{value:`false`};let{fetchFeatureFlagEvaluation:a}=await import(`./feature-flags.js`);return a(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,...i?{identifier:i}:{},...r?{externalId:r}:{},sessionId:this.getSessionId(),attributes:t,signal:n?.signal})}reportError(e){if(!(!this.ensureStarted()||!(this.options.trackErrors??!1))){if(this.errorTracker){this.errorTracker.captureError(e);return}this.pendingReportedErrors.length>=50&&this.pendingReportedErrors.shift(),this.pendingReportedErrors.push(e)}}isCookielessMode(){return this.options.cookieless||this.consentMode===`denied`?!0:this.consentMode===`pending`?this.cookielessWhilePending:!1}send(e,n={}){if(typeof window>`u`||this.destroyed||T())return;let r=this.isCookielessMode(),i=f(r),a=c(this.options.siteKey,r),{dimensions:o,properties:l}=m(n);this.log(e),s({url:this.webEndpoint,data:JSON.stringify({token:this.options.siteKey,...i?{userId:i}:{},sessionId:a.sessionId,event:e,...t(),...D(),...o,properties:l}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}enterPage(){this.pagePath=location.pathname,this.pageUrl=location.href,this.pageHash=location.hash,this.hasLeftCurrentPage=!1}leavePage(){if(this.destroyed||this.hasLeftCurrentPage)return;this.hasLeftCurrentPage=!0;let e=c(this.options.siteKey,this.isCookielessMode());this.send(`page_leave`,{page:this.pagePath,url:this.pageUrl,session_duration:Date.now()-e.sessionStart})}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.stopHeartbeat();return}l(this.options.siteKey,this.isCookielessMode())},300*1e3)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}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.pagePath&&(!e||location.hash===this.pageHash))){for(let e of this.childTrackers)e.trackPageChange?.(location.href);this.leavePage(),this.enterPage(),this.pageview({trigger:`navigation`})}},300))}};export{O as WebAnalytics,_ as getInstance,y as identify,T as isTrackingDisabled,b as logout,S as optIn,C as optOut,w as reportError,x as setConsentMode,v as trackEvent};
|
package/dist/replay.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ReplayTrackerOptions, t as ReplayTracker } from "./chunks/replay-
|
|
2
|
-
export {
|
|
1
|
+
import { n as ReplayTrackerOptions, t as ReplayTracker } from "./chunks/replay-DR_T0Iz4.js";
|
|
2
|
+
export { ReplayTrackerOptions, ReplayTracker as default };
|
package/dist/replay.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{r as e,t}from"./chunks/api-urls-nKmJnyjD.js";import{c as n,n as r,o as i,p as a,r as o,s,t as c,u as l}from"./chunks/send-data-Cb4xlYF0.js";import{t as u}from"./chunks/identifiers-DrjjHcKB.js";import{record as d}from"@rrweb/record";const f={mousemove:50,mouseInteraction:!0,scroll:150,media:800,input:`last`};function p(e){return`faststats_replay_sampled_${e}`}function m(e,t,r){let a=c(t);if(a>=100)return!0;if(a<=0)return!1;let o=i(e,r).sessionId,s=p(e),l=`${o}:${a}`;try{let e=sessionStorage;if(e){let t=e.getItem(s);if(t===l)return!0;if(t?.startsWith(`${o}:`))return!1}}catch{}let u=n(o)%100<a;try{sessionStorage?.setItem(s,u?l:`${o}:out`)}catch{}return u}var h=class{endpoint;compressionSupported=typeof window<`u`&&`CompressionStream`in window;sampled;events=[];pending=[];pendingSizeBytes=0;viewId=o();chunkStartedAt=0;started=!1;startTime=0;sequence=0;intervalId=null;flushTask=null;retryTask=null;minLengthFlushTask=null;stopRecording;sending=!1;unsubscribeRotation;cookieless;constructor(n){this.options=n,this.endpoint=`${e(n.baseUrl)}${t.replay}`,this.cookieless=n.cookieless??!1,this.sampled=m(n.siteKey,n.samplingPercentage??100,this.cookieless)}get flushInterval(){return this.options.flushInterval??1e4}get maxEvents(){return this.options.maxEvents??500}get maxPendingBatches(){return this.options.maxPendingBatches??30}get maxQueueSizeBytes(){return this.options.maxQueueSizeBytes??2097152}get minReplayLengthMs(){return this.options.minReplayLengthMs??3e3}log(...e){this.options.debug&&console.log(`[Replay]`,...e)}sessionContext(){return i(this.options.siteKey,this.cookieless)}setCookielessMode(e){this.cookieless!==e&&(this.cookieless=e,e&&(this.events.length=0,this.pending.length=0,this.pendingSizeBytes=0,this.flushTask&&clearTimeout(this.flushTask),this.retryTask&&clearTimeout(this.retryTask),this.minLengthFlushTask&&clearTimeout(this.minLengthFlushTask),this.flushTask=null,this.retryTask=null,this.minLengthFlushTask=null),this.startTime=s(this.cookieless),this.resetChunk())}resetChunk(){this.chunkStartedAt=Date.now()}start(){this.started||typeof window>`u`||!this.sampled||(this.started=!0,this.viewId=o(),this.startTime=s(this.cookieless),this.resetChunk(),this.unsubscribeRotation=l(e=>{this.onSessionRotated(e)}),this.beginRecording(),this.intervalId=setInterval(this.requestFlush,this.flushInterval),window.addEventListener(`beforeunload`,this.onUnload),this.log(`Recording started`))}trackPageChange(e){if(!this.started)return;let t=e??window.location.href;this.viewId=o(),this.resetChunk();let n={type:5,timestamp:Date.now(),data:{tag:`faststats:view`,payload:{href:t,viewId:this.viewId}}};this.onEvent(n,!1)}onPageHidden(e=!1){e||this.flush(!0,void 0,!0)}onPageShow(e=!1){!e||!this.started||this.pending.length>0&&this.flush(!1)}async beginRecording(){let e=this.options.recordConsole??!1?await import(`@rrweb/rrweb-plugin-console-record`):null;if(!this.started)return;let t=[];e&&t.push(e.getRecordConsolePlugin()),this.stopRecording=d({emit:this.onEvent,sampling:this.options.sampling??f,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:t})}stop(){if(this.started){if(this.started=!1,this.unsubscribeRotation?.(),this.unsubscribeRotation=void 0,this.stopRecording?.(),this.stopRecording=void 0,this.intervalId&&clearInterval(this.intervalId),this.flushTask&&clearTimeout(this.flushTask),this.retryTask&&clearTimeout(this.retryTask),this.minLengthFlushTask&&clearTimeout(this.minLengthFlushTask),this.intervalId=null,this.flushTask=null,this.retryTask=null,this.minLengthFlushTask=null,window.removeEventListener(`beforeunload`,this.onUnload),!this.hasReachedMinLength()){this.events.length=0,this.log(`Session too short (${Date.now()-this.startTime}ms), discarding events`);return}this.flush(!0,void 0,!0),this.log(`Recording stopped`)}}onSessionRotated(e){if(this.started){if(this.events.length>0)if(!this.hasReachedMinLength())this.scheduleMinLengthFlush();else{let t=this.createBatch(this.events.splice(0),e,!0);this.enqueueBatch(t)}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,void 0,!0)};hasReachedMinLength(){return this.minReplayLengthMs<=0||Date.now()-this.startTime>=this.minReplayLengthMs}requestFlush=()=>{this.flushTask||this.sending||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)),t=Math.min(e,2147483647);this.minLengthFlushTask=setTimeout(()=>{this.minLengthFlushTask=null,this.requestFlush()},t)}createBatch(e,t,n){let r=u(this.cookieless),i=this.sequence++,a=Date.now(),o=this.chunkStartedAt,s={token:this.options.siteKey,sessionId:t.sessionId,windowId:t.windowId,viewId:this.viewId,sessionStart:t.sessionStart,chunkStartedAt:o,chunkEndedAt:a,...r?{identifier:r}:{},batchId:`${t.sessionId}-${i}-${o}`,sequence:i,timestamp:a,url:window.location.href,...n?{isFinal:!0}:{},events:e};return this.resetChunk(),s}getBatchSizeBytes(e){return new TextEncoder().encode(JSON.stringify(e)).byteLength}dropOldestPendingBatch(e){let t=this.pending.shift();t&&(this.pendingSizeBytes=Math.max(0,this.pendingSizeBytes-this.getBatchSizeBytes(t)),this.log(`${e}, dropping batch ${t.sequence}`))}enqueueBatch(e){let t=this.getBatchSizeBytes(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>0&&this.pendingSizeBytes+t>this.maxQueueSizeBytes;)this.dropOldestPendingBatch(`Pending queue size limit reached`);for(;this.pending.length>=this.maxPendingBatches;)this.dropOldestPendingBatch(`Pending batch limit reached`);this.pending.push(e),this.pendingSizeBytes+=t}async flush(e,t,n){if(this.sending)return;let r=t?null:a(this.options.siteKey,this.cookieless);if(r&&this.events.length>0)if(!this.hasReachedMinLength())this.scheduleMinLengthFlush();else{let e=this.createBatch(this.events.splice(0),r.prev,!0);this.enqueueBatch(e)}let i=t??this.sessionContext();if(this.events.length>0)if(!this.hasReachedMinLength())this.scheduleMinLengthFlush();else{let e=this.createBatch(this.events.splice(0),i,n);this.enqueueBatch(e)}if(this.pending.length!==0){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.dropOldestPendingBatch(`Sent replay batch`),e=!1}}finally{this.sending=!1}}}scheduleRetry(){this.retryTask||=setTimeout(()=>{this.retryTask=null,this.flush(!1)},1e3)}async sendBatch(e,t){let n=JSON.stringify(e),i={debug:!1,useBeacon:t,keepalive:t};if((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)}%)`),r({url:`${this.endpoint}?encoding=gzip`,data:t,contentType:`application/octet-stream`,...i})??Promise.resolve(!1)}catch{this.log(`Compression failed, using uncompressed`)}return r({url:this.endpoint,data:n,contentType:`application/json`,...i})??Promise.resolve(!1)}};export{h as default};
|
package/dist/web-vitals.d.ts
CHANGED
|
@@ -10,20 +10,17 @@ declare class WebVitalsTracker {
|
|
|
10
10
|
private readonly options;
|
|
11
11
|
private readonly endpoint;
|
|
12
12
|
private readonly sampled;
|
|
13
|
-
private
|
|
13
|
+
private metrics;
|
|
14
14
|
private started;
|
|
15
|
+
private flushing;
|
|
15
16
|
private url;
|
|
16
17
|
constructor(options: WebVitalsOptions);
|
|
17
|
-
private get debug();
|
|
18
|
-
private log;
|
|
19
18
|
start(): Promise<void>;
|
|
20
19
|
stop(): void;
|
|
20
|
+
onPageHidden(persisted?: boolean): void;
|
|
21
21
|
trackPageChange(url?: string): void;
|
|
22
|
-
private
|
|
23
|
-
private onPageHide;
|
|
24
|
-
private capture;
|
|
22
|
+
private onMetric;
|
|
25
23
|
private flush;
|
|
26
|
-
private removeListeners;
|
|
27
24
|
}
|
|
28
25
|
//#endregion
|
|
29
|
-
export {
|
|
26
|
+
export { WebVitalsOptions, WebVitalsTracker as default };
|
package/dist/web-vitals.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{r as e,t}from"./chunks/api-urls-nKmJnyjD.js";import{c as n,i as r,n as i,t as a}from"./chunks/send-data-Cb4xlYF0.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())%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,i({url:this.endpoint,data:JSON.stringify({token:this.options.siteKey,sessionId:r(),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};
|
package/package.json
CHANGED
|
@@ -35,11 +35,14 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"type": "module",
|
|
38
|
+
"files": [
|
|
39
|
+
"dist"
|
|
40
|
+
],
|
|
38
41
|
"sideEffects": false,
|
|
39
42
|
"publishConfig": {
|
|
40
43
|
"access": "public"
|
|
41
44
|
},
|
|
42
|
-
"version": "0.
|
|
45
|
+
"version": "0.3.1",
|
|
43
46
|
"scripts": {
|
|
44
47
|
"build": "tsdown && bun run check-size",
|
|
45
48
|
"dev": "bun run build",
|
|
@@ -54,10 +57,8 @@
|
|
|
54
57
|
"typescript": "^5.9.3"
|
|
55
58
|
},
|
|
56
59
|
"dependencies": {
|
|
57
|
-
"@rrweb/rrweb-plugin-console-record": "^2.0.
|
|
58
|
-
"@rrweb/
|
|
59
|
-
"
|
|
60
|
-
"rrweb-snapshot": "^2.0.0-alpha.4",
|
|
61
|
-
"web-vitals": "^5.2.0"
|
|
60
|
+
"@rrweb/rrweb-plugin-console-record": "^2.0.1",
|
|
61
|
+
"@rrweb/record": "^2.0.1",
|
|
62
|
+
"web-vitals": "^5.3.0"
|
|
62
63
|
}
|
|
63
64
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# @faststats/web
|
|
2
|
-
|
|
3
|
-
## 0.2.14
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- bebbb67: chore: update web-vitals to 5.2.0
|
|
8
|
-
- ab51be7: fix: tag replay batches with per-tab window and page ids instead of rrweb sequential ids
|
|
9
|
-
|
|
10
|
-
## 0.2.13
|
|
11
|
-
|
|
12
|
-
### Patch Changes
|
|
13
|
-
|
|
14
|
-
- 28fb1ce: chore: provide session_id to flag validation service
|
|
15
|
-
|
|
16
|
-
## 0.2.12
|
|
17
|
-
|
|
18
|
-
### Patch Changes
|
|
19
|
-
|
|
20
|
-
- d96a750: fix: refreshSessionTimestamp on replay page hide
|
|
21
|
-
|
|
22
|
-
## 0.2.11
|
|
23
|
-
|
|
24
|
-
### Patch Changes
|
|
25
|
-
|
|
26
|
-
- 754b67f: fix(replays): dedupe secquences to reduce risk of duplicate data sending
|
|
27
|
-
- d21ce42: refactor: more reliable and unified data sending
|
|
28
|
-
|
|
29
|
-
## 0.2.10
|
|
30
|
-
|
|
31
|
-
## 0.2.9
|
|
32
|
-
|
|
33
|
-
### Patch Changes
|
|
34
|
-
|
|
35
|
-
- dd3bbcb: fix: make identify call async
|
|
36
|
-
|
|
37
|
-
## 0.2.8
|
|
38
|
-
|
|
39
|
-
### Patch Changes
|
|
40
|
-
|
|
41
|
-
- 5d0afa5: perf: shrink bundle and improve treeshaking
|
|
42
|
-
|
|
43
|
-
- mark package as side-effect free (`"sideEffects": false`)
|
|
44
|
-
- add subpath exports: `@faststats/web/feature-flags`, `/replay`, `/error`, `/web-vitals`
|
|
45
|
-
- lazy-load `fetchFeatureFlagEvaluation` from `checkFeatureFlag`
|
|
46
|
-
- default web-vitals to the core build; opt into attribution via `webVitals.attribution: true`
|
|
47
|
-
- dynamically import rrweb sequential-id and console plugins (console only when `recordConsole !== false`)
|
|
48
|
-
- import `EventType` from `@rrweb/types` instead of the rrweb barrel so consumer bundlers can prune the playback engine, packer, and replay-side console plugin
|
|
49
|
-
- move `@rrweb/types` from devDependencies to dependencies (now a runtime import)
|
|
50
|
-
- main entry filename is now `dist/index.js` (was `dist/module.js`); the public entry no longer re-exports `featureFlagsCheckUrl` / `normalizeFeatureFlagsBaseUrl`
|
|
51
|
-
- per-entry raw + gzip budgets enforced by `scripts/check-bundle-size.mjs`
|
|
52
|
-
|
|
53
|
-
- cdf521f: chore: report sdk name and version for error tracking
|
|
54
|
-
- a844fed: fix: enable compression for replays by default
|
|
55
|
-
|
|
56
|
-
## 0.2.7
|
|
57
|
-
|
|
58
|
-
### Patch Changes
|
|
59
|
-
|
|
60
|
-
- 08f3719: fix: don't rotate session_id while replay
|
|
61
|
-
|
|
62
|
-
## 0.2.6
|
|
63
|
-
|
|
64
|
-
### Patch Changes
|
|
65
|
-
|
|
66
|
-
- 7d57d50: fix: replay flushing issues
|
|
67
|
-
|
|
68
|
-
## 0.2.5
|
|
69
|
-
|
|
70
|
-
### Patch Changes
|
|
71
|
-
|
|
72
|
-
- dd932a0: fix: replay config mismatch
|
|
73
|
-
|
|
74
|
-
## 0.2.4
|
|
75
|
-
|
|
76
|
-
### Patch Changes
|
|
77
|
-
|
|
78
|
-
- 547db41: fix: resolve old type issues
|
|
79
|
-
|
|
80
|
-
## 0.2.3
|
|
81
|
-
|
|
82
|
-
### Patch Changes
|
|
83
|
-
|
|
84
|
-
- 3371933: fix: use identifier rather then server_id
|
|
85
|
-
|
|
86
|
-
## 0.2.2
|
|
87
|
-
|
|
88
|
-
### Patch Changes
|
|
89
|
-
|
|
90
|
-
- 9d7369d: fix: remove useless evaluation object from response
|
|
91
|
-
- 7b79f71: fix: use header over body for project token
|
|
92
|
-
- 7317c3c: fix: remove useless enabled propery
|
|
93
|
-
|
|
94
|
-
## 0.2.1
|
|
95
|
-
|
|
96
|
-
### Patch Changes
|
|
97
|
-
|
|
98
|
-
- d80a042: fix: use new check endpoint
|
|
99
|
-
|
|
100
|
-
## 0.2.0
|
|
101
|
-
|
|
102
|
-
### Minor Changes
|
|
103
|
-
|
|
104
|
-
- 55032f8: feat: add feature flags
|
|
105
|
-
|
|
106
|
-
### Patch Changes
|
|
107
|
-
|
|
108
|
-
- 98385da: refactor: reduce bundle size and make results more stable
|
|
109
|
-
|
|
110
|
-
## 0.1.9
|
|
111
|
-
|
|
112
|
-
### Patch Changes
|
|
113
|
-
|
|
114
|
-
- b9f489f: fix racecondition because of gzip
|
|
115
|
-
|
|
116
|
-
## 0.1.8
|
|
117
|
-
|
|
118
|
-
### Patch Changes
|
|
119
|
-
|
|
120
|
-
- 29dbdea: add initial snapshot metadata
|
|
121
|
-
|
|
122
|
-
## 0.1.7
|
|
123
|
-
|
|
124
|
-
### Patch Changes
|
|
125
|
-
|
|
126
|
-
- 7d6d563: fix: better sending
|
|
127
|
-
|
|
128
|
-
## 0.1.6
|
|
129
|
-
|
|
130
|
-
### Patch Changes
|
|
131
|
-
|
|
132
|
-
- 48a1008: refactor: perf & bulletproof parts of the core sdk
|
|
133
|
-
|
|
134
|
-
## 0.1.5
|
|
135
|
-
|
|
136
|
-
### Patch Changes
|
|
137
|
-
|
|
138
|
-
- f7347cd: fix: Improve replay flushing
|
|
139
|
-
|
|
140
|
-
## 0.1.4
|
|
141
|
-
|
|
142
|
-
### Patch Changes
|
|
143
|
-
|
|
144
|
-
- 376922e: updates
|
|
145
|
-
|
|
146
|
-
## 0.1.3
|
|
147
|
-
|
|
148
|
-
## 0.1.2
|
|
149
|
-
|
|
150
|
-
### Patch Changes
|
|
151
|
-
|
|
152
|
-
- 5d1cc90: fix: enforce proper minimum duration of 3 seconds
|
|
153
|
-
|
|
154
|
-
## 0.1.1
|
|
155
|
-
|
|
156
|
-
### Patch Changes
|
|
157
|
-
|
|
158
|
-
- 2326d00: fix: some cleanup
|
|
159
|
-
|
|
160
|
-
## 0.1.0
|
|
161
|
-
|
|
162
|
-
### Minor Changes
|
|
163
|
-
|
|
164
|
-
- c63d783: Remove all window globals; use module-level instance and dependency injection. Add dynamic imports for ErrorTracker, WebVitalsTracker, ReplayTracker (tree-shakable). Export identify, logout, setConsentMode, optIn, optOut, getInstance from @faststats/web. React package now uses getInstance instead of window.
|
|
165
|
-
|
|
166
|
-
## 0.0.4
|
|
167
|
-
|
|
168
|
-
### Patch Changes
|
|
169
|
-
|
|
170
|
-
- 93393c0: Remove redundant isTrackingDisabled checks from sub-trackers (ErrorTracker, WebVitalsTracker, ReplayTracker).
|
|
171
|
-
Simplify web vitals config - single source of truth (trackWebVitals ?? webVitals?.enabled ?? hasWebVitalsSampling).
|
|
172
|
-
Fix custom events via trackEvent: set window.\_\_FA_webAnalyticsInstance in init() so it works before async start() completes.
|
|
173
|
-
|
|
174
|
-
## 0.0.3
|
|
175
|
-
|
|
176
|
-
### Patch Changes
|
|
177
|
-
|
|
178
|
-
- bb3dcd1: ESM only for now
|
|
179
|
-
|
|
180
|
-
## 0.0.2
|
|
181
|
-
|
|
182
|
-
### Patch Changes
|
|
183
|
-
|
|
184
|
-
- f1f66de: feat: add track event function
|