@faststats/web 0.2.13 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/api-urls-nKmJnyjD.js +1 -0
- package/dist/chunks/identifiers-wylBcW5K.js +1 -0
- package/dist/chunks/{replay-BuX3_0xs.d.ts → replay-Dpl1P6cw.d.ts} +17 -12
- package/dist/chunks/send-data-D6WdryL7.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 +15 -37
- 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 +4 -7
- package/dist/web-vitals.js +1 -1
- package/package.json +9 -11
- package/CHANGELOG.md +0 -177
- package/dist/chunks/api-urls-DaeYkG0_.js +0 -1
- package/dist/chunks/error-CDVOMiI9.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/identifiers-CQeWm7wi.js +0 -1
- package/dist/chunks/replay-CHFW2q4E.js +0 -1
- package/dist/chunks/rolldown-runtime-MP-BAFHD.js +0 -1
- package/dist/chunks/send-data-DL_GlsQw.js +0 -1
- package/dist/chunks/types-CYzR5xtT.js +0 -1
- package/dist/chunks/web-vitals-GwPlL7Zy.js +0 -1
- package/scripts/check-bundle-size.mjs +0 -96
- package/src/analytics.ts +0 -776
- 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 -252
- package/src/feature-flags.ts +0 -84
- package/src/replay.ts +0 -469
- package/src/sdk.ts +0 -8
- package/src/utils/api-urls.ts +0 -24
- package/src/utils/identifiers.ts +0 -89
- package/src/utils/send-data.ts +0 -52
- package/src/utils/types.ts +0 -15
- package/src/web-vitals.ts +0 -159
- package/tests/analytics.test.ts +0 -450
- package/tests/identifiers.test.ts +0 -95
- package/tests/replay.test.ts +0 -412
- 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
- package/wrangler.toml +0 -8
|
@@ -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-D6WdryL7.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,23 +1,23 @@
|
|
|
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;
|
|
9
8
|
debug?: boolean;
|
|
10
9
|
compress?: boolean;
|
|
10
|
+
cookieless?: boolean;
|
|
11
11
|
samplingPercentage?: number;
|
|
12
12
|
flushInterval?: number;
|
|
13
13
|
maxEvents?: number;
|
|
14
14
|
maxPendingBatches?: number;
|
|
15
15
|
maxQueueSizeBytes?: number;
|
|
16
16
|
minReplayLengthMs?: number;
|
|
17
|
-
sampling?:
|
|
18
|
-
slimDOMOptions?:
|
|
17
|
+
sampling?: RecordOptions["sampling"];
|
|
18
|
+
slimDOMOptions?: RecordOptions["slimDOMOptions"];
|
|
19
19
|
maskAllInputs?: boolean;
|
|
20
|
-
maskInputOptions?:
|
|
20
|
+
maskInputOptions?: RecordOptions["maskInputOptions"];
|
|
21
21
|
blockClass?: string;
|
|
22
22
|
blockSelector?: string;
|
|
23
23
|
maskTextClass?: string;
|
|
@@ -34,7 +34,8 @@ declare class ReplayTracker {
|
|
|
34
34
|
private readonly events;
|
|
35
35
|
private readonly pending;
|
|
36
36
|
private pendingSizeBytes;
|
|
37
|
-
private
|
|
37
|
+
private viewId;
|
|
38
|
+
private chunkStartedAt;
|
|
38
39
|
private started;
|
|
39
40
|
private startTime;
|
|
40
41
|
private sequence;
|
|
@@ -44,27 +45,31 @@ declare class ReplayTracker {
|
|
|
44
45
|
private minLengthFlushTask;
|
|
45
46
|
private stopRecording?;
|
|
46
47
|
private sending;
|
|
48
|
+
private unsubscribeRotation?;
|
|
49
|
+
private cookieless;
|
|
47
50
|
constructor(options: ReplayTrackerOptions);
|
|
48
|
-
private get debug();
|
|
49
51
|
private get flushInterval();
|
|
50
52
|
private get maxEvents();
|
|
51
53
|
private get maxPendingBatches();
|
|
52
54
|
private get maxQueueSizeBytes();
|
|
53
55
|
private get minReplayLengthMs();
|
|
54
|
-
private get shouldCompress();
|
|
55
56
|
private log;
|
|
57
|
+
private sessionContext;
|
|
58
|
+
setCookielessMode(cookieless: boolean): void;
|
|
59
|
+
private resetChunk;
|
|
56
60
|
start(): void;
|
|
61
|
+
trackPageChange(url?: string): void;
|
|
62
|
+
onPageHidden(persisted?: boolean): void;
|
|
63
|
+
onPageShow(persisted?: boolean): void;
|
|
57
64
|
private beginRecording;
|
|
58
65
|
stop(): void;
|
|
59
|
-
|
|
66
|
+
private onSessionRotated;
|
|
60
67
|
private onEvent;
|
|
61
68
|
private onUnload;
|
|
62
|
-
private onVisibilityChange;
|
|
63
69
|
private hasReachedMinLength;
|
|
64
70
|
private requestFlush;
|
|
65
71
|
private scheduleMinLengthFlush;
|
|
66
72
|
private createBatch;
|
|
67
|
-
private createBatchId;
|
|
68
73
|
private getBatchSizeBytes;
|
|
69
74
|
private dropOldestPendingBatch;
|
|
70
75
|
private enqueueBatch;
|
|
@@ -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`&&Number.isFinite(t.start)&&Number.isFinite(t.activity))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-D6WdryL7.js";import{t as o}from"./chunks/identifiers-wylBcW5K.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.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{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}:{}};r.attributes&&Object.keys(r.attributes).length>0&&(l.attributes=r.attributes);let u={"Content-Type":`application/json`};i&&(u.Authorization=`Bearer ${i}`);let d=`${e(r.baseUrl)}${t.flags}`,f=await fetch(d,{method:`POST`,headers:u,body:JSON.stringify(l),credentials:`omit`,signal:r.signal});if(!f.ok){let e=``;try{let t=await f.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${f.status}${e}`)}return await f.json()}export{n as fetchFeatureFlagEvaluation};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,12 @@
|
|
|
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-Dpl1P6cw.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
5
|
interface SamplingOptions {
|
|
22
6
|
percentage?: number;
|
|
23
7
|
}
|
|
24
8
|
interface WebVitalsConfig {
|
|
9
|
+
enabled?: boolean;
|
|
25
10
|
sampling?: SamplingOptions;
|
|
26
11
|
attribution?: boolean;
|
|
27
12
|
}
|
|
@@ -86,7 +71,7 @@ declare class WebAnalytics {
|
|
|
86
71
|
private pageUrl;
|
|
87
72
|
private pageHash;
|
|
88
73
|
private hasLeftCurrentPage;
|
|
89
|
-
private
|
|
74
|
+
private scrollUpdate;
|
|
90
75
|
private consentMode;
|
|
91
76
|
private readonly cookielessWhilePending;
|
|
92
77
|
private readonly cleanupCallbacks;
|
|
@@ -95,36 +80,28 @@ declare class WebAnalytics {
|
|
|
95
80
|
private errorTracker;
|
|
96
81
|
private readonly handleVisibilityChange;
|
|
97
82
|
private readonly handlePageHide;
|
|
98
|
-
private readonly
|
|
99
|
-
private readonly handleHashChange;
|
|
83
|
+
private readonly handlePageShow;
|
|
100
84
|
constructor(options: WebAnalyticsOptions);
|
|
101
85
|
private log;
|
|
102
86
|
private init;
|
|
103
|
-
private
|
|
104
|
-
private addWindowListener;
|
|
105
|
-
private addDocumentListener;
|
|
106
|
-
private patchHistory;
|
|
87
|
+
private isActive;
|
|
107
88
|
private ensureStarted;
|
|
108
|
-
private
|
|
109
|
-
private
|
|
110
|
-
private
|
|
111
|
-
private registerChildTracker;
|
|
89
|
+
private addListener;
|
|
90
|
+
private patchHistory;
|
|
91
|
+
private notifyChildren;
|
|
112
92
|
private startChildTracker;
|
|
113
|
-
private
|
|
114
|
-
private startWebVitalsTracker;
|
|
115
|
-
private startReplayTracker;
|
|
93
|
+
private startOptionalTrackers;
|
|
116
94
|
start(): Promise<void>;
|
|
117
95
|
destroy(): void;
|
|
118
|
-
pageview(extra?:
|
|
119
|
-
track(name: string, extra?:
|
|
96
|
+
pageview(extra?: Record<string, unknown>): void;
|
|
97
|
+
track(name: string, extra?: Record<string, unknown>): void;
|
|
120
98
|
identify(externalId: string, email: string, options?: IdentifyOptions): Promise<boolean>;
|
|
121
99
|
logout(resetAnonymousIdentity?: boolean): void;
|
|
122
100
|
setConsentMode(mode: ConsentMode): void;
|
|
123
|
-
optIn(): void;
|
|
124
|
-
optOut(): void;
|
|
125
101
|
getConsentMode(): ConsentMode;
|
|
126
102
|
getAnonymousId(): string;
|
|
127
103
|
getSessionId(): string;
|
|
104
|
+
getWindowId(): string;
|
|
128
105
|
checkFeatureFlag(key: string, attributes?: Record<string, unknown>, opts?: {
|
|
129
106
|
externalId?: string;
|
|
130
107
|
signal?: AbortSignal;
|
|
@@ -136,8 +113,9 @@ declare class WebAnalytics {
|
|
|
136
113
|
private leavePage;
|
|
137
114
|
private trackScroll;
|
|
138
115
|
private startHeartbeat;
|
|
116
|
+
private stopHeartbeat;
|
|
139
117
|
private navigate;
|
|
140
118
|
private links;
|
|
141
119
|
}
|
|
142
120
|
//#endregion
|
|
143
|
-
export { type ConsentMode, type
|
|
121
|
+
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,i,n as a,o,r as s,s as c,t as l}from"./chunks/identifiers-CQeWm7wi.js";import{t as u}from"./chunks/send-data-DL_GlsQw.js";import{t as d}from"./chunks/types-CYzR5xtT.js";import{n as f}from"./chunks/feature-flags-DSOCIZHK.js";function p(e){return e.replayOptions?.samplingPercentage!==void 0||e.sessionReplays?.sampling?.percentage!==void 0}function m(e,t,n){if(!(e.sessionReplays?.enabled??e.trackReplay??p(e)))return null;let r=e.replayOptions??{};return{siteKey:e.siteKey,baseUrl:t,debug:n,...r,samplingPercentage:d(r.samplingPercentage??e.sessionReplays?.sampling?.percentage)}}const h={instance:null,pendingConsentMode:void 0};function g(){return h.instance}function _(e,t){typeof window>`u`||w()||h.instance?.track(e,t??{})}function v(e,t,n){return typeof window>`u`||w()?Promise.resolve(!1):h.instance?.identify(e,t,n??{})??Promise.resolve(!1)}function y(e=!0){typeof window>`u`||w()||h.instance?.logout(e)}function b(e){if(h.instance){h.instance.setConsentMode(e);return}h.pendingConsentMode=e}function x(){b(`granted`)}function S(){b(`denied`)}function C(e){typeof window>`u`||w()||h.instance?.reportError(e)}function w(){if(typeof localStorage>`u`)return!1;let e=localStorage.getItem(`disable-faststats`);return e===`true`||e===`1`}function T(e){for(;e;){if(e instanceof HTMLAnchorElement&&e.href)return e;e=e.parentNode}return null}function E(){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 D=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,h.pendingConsentMode!==void 0&&(this.consentMode=h.pendingConsentMode,h.pendingConsentMode=void 0),(r.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(!(typeof window>`u`)){if(w()){this.log(`disabled`);return}h.instance=this,c(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||w()?!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||h.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||h.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-CDVOMiI9.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-GwPlL7Zy.js`).then(e=>e.n);return new e({siteKey:this.options.siteKey,baseUrl:this.baseUrl,debug:this.debug,samplingPercentage:d(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-CHFW2q4E.js`).then(e=>e.n);return new t(e)})}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(w()){this.log(`disabled`);return}this.started=!0,h.instance=this,c(this.isCookielessMode()),a();let e=this.options,t=m(e,this.baseUrl,this.debug);t&&this.startReplayTracker(t),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(),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={}){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):u({url:`${this.baseUrl}${n.identify}`,data:JSON.stringify({token:this.options.siteKey,identifier:l(!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&&r(this.isCookielessMode()),o())}setConsentMode(e){this.consentMode=e,c(this.isCookielessMode())}optIn(){this.setConsentMode(`granted`)}optOut(){this.setConsentMode(`denied`)}getConsentMode(){return this.consentMode}getAnonymousId(){return l(this.isCookielessMode())}getSessionId(){return a()}async checkFeatureFlag(e,t,n){if(typeof window>`u`||w())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`||w()||!(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||w())return;let n=l(this.isCookielessMode()),r=JSON.stringify({token:this.options.siteKey,...n?{userId:n}:{},sessionId:a(),data:{event:e,page:location.pathname,referrer:document.referrer||null,title:document.title||``,url:location.href,...E(),...t}});this.log(e),u({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-s()})}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)){this.leavePage(),this.enterPage();for(let e of this.childTrackers)e.trackPageChange?.(this.pageUrl);this.trackScroll(),this.pageview({trigger:`navigation`})}},300))}links(){let e=e=>{let t=T(e.target);t&&t.host!==location.host&&this.track(`outbound_link`,{outbound_link:t.href})};this.addDocumentListener(`click`,e),this.addDocumentListener(`auxclick`,e)}};export{D as WebAnalytics,f as fetchFeatureFlagEvaluation,g as getInstance,v as identify,w as isTrackingDisabled,y as logout,x as optIn,S as optOut,C as reportError,u as sendData,b as setConsentMode,_ 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-D6WdryL7.js";import{n as d,t as f}from"./chunks/identifiers-wylBcW5K.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[r]=i:n[r]=i;return{dimensions:t,properties:n}}function h(e,t,n){if(!(e.sessionReplays?.enabled??e.trackReplay))return null;let r=e.replayOptions??{};return{siteKey:e.siteKey,baseUrl:t,debug:n,...r,samplingPercentage:u(r.samplingPercentage??e.sessionReplays?.sampling?.percentage)}}const g={instance:null,pendingConsentMode:void 0};function _(){return typeof window>`u`||E()?null:g.instance}function v(){return g.instance}function y(e,t){_()?.track(e,t??{})}function b(e,t,n){return _()?.identify(e,t,n??{})??Promise.resolve(!1)}function x(e=!0){_()?.logout(e)}function S(e){if(g.instance){g.instance.setConsentMode(e);return}g.pendingConsentMode=e}function C(){S(`granted`)}function w(){S(`denied`)}function T(e){_()?.reportError(e)}function E(){try{let e=globalThis.localStorage;if(!e)return!1;let t=e.getItem(`disable-faststats`);return t===`true`||t===`1`}catch{return!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;scrollUpdate=null;consentMode;cookielessWhilePending;cleanupCallbacks=[];childTrackers=[];pendingReportedErrors=[];errorTracker=null;handleVisibilityChange=()=>{if(l(this.options.siteKey,this.isCookielessMode()),document.visibilityState===`hidden`){this.notifyChildren(`onPageHidden`),this.leavePage(),this.stopHeartbeat();return}this.enterPage(),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=t.consent?.mode??`granted`,this.cookielessWhilePending=t.consent?.cookielessWhilePending??!0,g.pendingConsentMode!==void 0&&(this.consentMode=g.pendingConsentMode,g.pendingConsentMode=void 0),(t.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(!(typeof window>`u`)){if(E()){this.log(`disabled`);return}setTimeout(()=>void this.start(),0)}}isActive(){return this.started&&!this.destroyed&&g.instance===this}ensureStarted(){return typeof window>`u`||this.destroyed||E()?!1:(this.started||this.start(),this.isActive())}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.isActive()||(await Promise.resolve(n.start()),!this.isActive())?(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,t=h(e,this.baseUrl,this.debug);t&&this.startChildTracker(`replay`,async()=>{let{default:e}=await import(`./replay.js`);return new e({...t,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`)){if(g.instance&&g.instance!==this){this.log(`already started by another instance`);return}if(E()){this.log(`disabled`);return}this.started=!0,g.instance=this,a(this.isCookielessMode()),o(),this.startOptionalTrackers(),this.enterPage(),this.pageview({trigger:`load`}),this.links(),this.trackScroll(),this.startHeartbeat(),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,g.instance===this&&(g.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,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`||E())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||E())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(),...O(),...o,properties:l}),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(),t=c(this.options.siteKey,this.isCookielessMode());this.send(`page_leave`,{page:this.pagePath,url:this.pageUrl,time_on_page:e-this.pageEntryTime,scroll_depth:this.scrollDepth,session_duration:e-t.sessionStart})}trackScroll(){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.scrollUpdate=e,e(),this.addListener(window,`scroll`,e,{passive:!0})}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=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.scrollUpdate?.(),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.addListener(document,`click`,e),this.addListener(document,`auxclick`,e)}};export{k as WebAnalytics,v as getInstance,b as identify,E as isTrackingDisabled,x as logout,C as optIn,w as optOut,T as reportError,S as setConsentMode,y 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-Dpl1P6cw.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-D6WdryL7.js";import{t as u}from"./chunks/identifiers-wylBcW5K.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 encodeBatch(e){let t=JSON.stringify(e);if(!(this.options.compress??!0)||!this.compressionSupported)return{data:t,isCompressed:!1};try{let e=await this.compress(t);return this.log(`Compressed ${t.length}B -> ${e.byteLength}B (${Math.round(e.byteLength/t.length*100)}%)`),{data:e,isCompressed:!0}}catch{return this.log(`Compression failed, using uncompressed`),{data:t,isCompressed:!1}}}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;let n=await this.encodeBatch(t);if(!await this.send(n.data,n.isCompressed,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 compress(e){let t=new Blob([e]).stream().pipeThrough(new CompressionStream(`gzip`)),n=await new Response(t).arrayBuffer();return new Uint8Array(n)}send(e,t,n){return r({url:t?`${this.endpoint}?encoding=gzip`:this.endpoint,data:e,contentType:t?`application/octet-stream`:`application/json`,debug:!1,useBeacon:n,keepalive:n})??Promise.resolve(!1)}};export{h as default};
|
package/dist/web-vitals.d.ts
CHANGED
|
@@ -12,18 +12,15 @@ declare class WebVitalsTracker {
|
|
|
12
12
|
private readonly sampled;
|
|
13
13
|
private readonly 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-D6WdryL7.js";function o(e){let t=a(e);return t>=100?!0:t<=0?!1:n(r())%100<t}var s=class{endpoint;sampled;metrics=new Map;started=!1;flushing=!1;url=``;constructor(n){this.options=n,this.endpoint=`${e(n.baseUrl)}${t.vitals}`,this.sampled=o(n.samplingPercentage)}async start(){if(this.started||typeof window>`u`)return;this.started=!0,this.url=window.location.href;let e=this.options.attribution?await import(`web-vitals/attribution`):await 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;this.metrics.set(t,{metric:t,value:e.value,attributes:{id:e.id,rating:e.rating,delta:e.delta,navigationType:e.navigationType,...e.attribution??{}}})};flush(){if(!this.metrics.size||this.flushing)return;let e=[...this.metrics.values()],t=new Set(e.map(e=>e.metric));this.flushing=!0;let n=JSON.stringify({token:this.options.siteKey,sessionId:r(),vitals:e,metadata:{url:this.url}});i({url:this.endpoint,data:n,debug:this.options.debug,debugPrefix:`[WebVitals]`}).then(e=>{if(e)for(let e of t)this.metrics.delete(e)}).finally(()=>{this.flushing=!1})}};export{s as default};
|
package/package.json
CHANGED
|
@@ -35,32 +35,30 @@
|
|
|
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.0",
|
|
43
46
|
"scripts": {
|
|
44
47
|
"build": "tsdown && bun run check-size",
|
|
45
48
|
"dev": "bun run build",
|
|
46
49
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
47
50
|
"test": "bun test",
|
|
48
|
-
"check-size": "node scripts/check-bundle-size.mjs"
|
|
49
|
-
"deploy:worker": "wrangler deploy"
|
|
51
|
+
"check-size": "node scripts/check-bundle-size.mjs"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@biomejs/biome": "2.4.2",
|
|
53
55
|
"@types/bun": "latest",
|
|
54
56
|
"tsdown": "^0.21.4",
|
|
55
|
-
"typescript": "^5.9.3"
|
|
56
|
-
"wrangler": "^4.66.0"
|
|
57
|
+
"typescript": "^5.9.3"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"@rrweb/rrweb-plugin-console-record": "^2.0.
|
|
60
|
-
"@rrweb/
|
|
61
|
-
"
|
|
62
|
-
"rrweb": "^2.0.0-alpha.4",
|
|
63
|
-
"rrweb-snapshot": "^2.0.0-alpha.4",
|
|
64
|
-
"web-vitals": "^5.1.0"
|
|
60
|
+
"@rrweb/rrweb-plugin-console-record": "^2.0.1",
|
|
61
|
+
"@rrweb/record": "^2.0.1",
|
|
62
|
+
"web-vitals": "^5.3.0"
|
|
65
63
|
}
|
|
66
64
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# @faststats/web
|
|
2
|
-
|
|
3
|
-
## 0.2.13
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- 28fb1ce: chore: provide session_id to flag validation service
|
|
8
|
-
|
|
9
|
-
## 0.2.12
|
|
10
|
-
|
|
11
|
-
### Patch Changes
|
|
12
|
-
|
|
13
|
-
- d96a750: fix: refreshSessionTimestamp on replay page hide
|
|
14
|
-
|
|
15
|
-
## 0.2.11
|
|
16
|
-
|
|
17
|
-
### Patch Changes
|
|
18
|
-
|
|
19
|
-
- 754b67f: fix(replays): dedupe secquences to reduce risk of duplicate data sending
|
|
20
|
-
- d21ce42: refactor: more reliable and unified data sending
|
|
21
|
-
|
|
22
|
-
## 0.2.10
|
|
23
|
-
|
|
24
|
-
## 0.2.9
|
|
25
|
-
|
|
26
|
-
### Patch Changes
|
|
27
|
-
|
|
28
|
-
- dd3bbcb: fix: make identify call async
|
|
29
|
-
|
|
30
|
-
## 0.2.8
|
|
31
|
-
|
|
32
|
-
### Patch Changes
|
|
33
|
-
|
|
34
|
-
- 5d0afa5: perf: shrink bundle and improve treeshaking
|
|
35
|
-
|
|
36
|
-
- mark package as side-effect free (`"sideEffects": false`)
|
|
37
|
-
- add subpath exports: `@faststats/web/feature-flags`, `/replay`, `/error`, `/web-vitals`
|
|
38
|
-
- lazy-load `fetchFeatureFlagEvaluation` from `checkFeatureFlag`
|
|
39
|
-
- default web-vitals to the core build; opt into attribution via `webVitals.attribution: true`
|
|
40
|
-
- dynamically import rrweb sequential-id and console plugins (console only when `recordConsole !== false`)
|
|
41
|
-
- import `EventType` from `@rrweb/types` instead of the rrweb barrel so consumer bundlers can prune the playback engine, packer, and replay-side console plugin
|
|
42
|
-
- move `@rrweb/types` from devDependencies to dependencies (now a runtime import)
|
|
43
|
-
- main entry filename is now `dist/index.js` (was `dist/module.js`); the public entry no longer re-exports `featureFlagsCheckUrl` / `normalizeFeatureFlagsBaseUrl`
|
|
44
|
-
- per-entry raw + gzip budgets enforced by `scripts/check-bundle-size.mjs`
|
|
45
|
-
|
|
46
|
-
- cdf521f: chore: report sdk name and version for error tracking
|
|
47
|
-
- a844fed: fix: enable compression for replays by default
|
|
48
|
-
|
|
49
|
-
## 0.2.7
|
|
50
|
-
|
|
51
|
-
### Patch Changes
|
|
52
|
-
|
|
53
|
-
- 08f3719: fix: don't rotate session_id while replay
|
|
54
|
-
|
|
55
|
-
## 0.2.6
|
|
56
|
-
|
|
57
|
-
### Patch Changes
|
|
58
|
-
|
|
59
|
-
- 7d57d50: fix: replay flushing issues
|
|
60
|
-
|
|
61
|
-
## 0.2.5
|
|
62
|
-
|
|
63
|
-
### Patch Changes
|
|
64
|
-
|
|
65
|
-
- dd932a0: fix: replay config mismatch
|
|
66
|
-
|
|
67
|
-
## 0.2.4
|
|
68
|
-
|
|
69
|
-
### Patch Changes
|
|
70
|
-
|
|
71
|
-
- 547db41: fix: resolve old type issues
|
|
72
|
-
|
|
73
|
-
## 0.2.3
|
|
74
|
-
|
|
75
|
-
### Patch Changes
|
|
76
|
-
|
|
77
|
-
- 3371933: fix: use identifier rather then server_id
|
|
78
|
-
|
|
79
|
-
## 0.2.2
|
|
80
|
-
|
|
81
|
-
### Patch Changes
|
|
82
|
-
|
|
83
|
-
- 9d7369d: fix: remove useless evaluation object from response
|
|
84
|
-
- 7b79f71: fix: use header over body for project token
|
|
85
|
-
- 7317c3c: fix: remove useless enabled propery
|
|
86
|
-
|
|
87
|
-
## 0.2.1
|
|
88
|
-
|
|
89
|
-
### Patch Changes
|
|
90
|
-
|
|
91
|
-
- d80a042: fix: use new check endpoint
|
|
92
|
-
|
|
93
|
-
## 0.2.0
|
|
94
|
-
|
|
95
|
-
### Minor Changes
|
|
96
|
-
|
|
97
|
-
- 55032f8: feat: add feature flags
|
|
98
|
-
|
|
99
|
-
### Patch Changes
|
|
100
|
-
|
|
101
|
-
- 98385da: refactor: reduce bundle size and make results more stable
|
|
102
|
-
|
|
103
|
-
## 0.1.9
|
|
104
|
-
|
|
105
|
-
### Patch Changes
|
|
106
|
-
|
|
107
|
-
- b9f489f: fix racecondition because of gzip
|
|
108
|
-
|
|
109
|
-
## 0.1.8
|
|
110
|
-
|
|
111
|
-
### Patch Changes
|
|
112
|
-
|
|
113
|
-
- 29dbdea: add initial snapshot metadata
|
|
114
|
-
|
|
115
|
-
## 0.1.7
|
|
116
|
-
|
|
117
|
-
### Patch Changes
|
|
118
|
-
|
|
119
|
-
- 7d6d563: fix: better sending
|
|
120
|
-
|
|
121
|
-
## 0.1.6
|
|
122
|
-
|
|
123
|
-
### Patch Changes
|
|
124
|
-
|
|
125
|
-
- 48a1008: refactor: perf & bulletproof parts of the core sdk
|
|
126
|
-
|
|
127
|
-
## 0.1.5
|
|
128
|
-
|
|
129
|
-
### Patch Changes
|
|
130
|
-
|
|
131
|
-
- f7347cd: fix: Improve replay flushing
|
|
132
|
-
|
|
133
|
-
## 0.1.4
|
|
134
|
-
|
|
135
|
-
### Patch Changes
|
|
136
|
-
|
|
137
|
-
- 376922e: updates
|
|
138
|
-
|
|
139
|
-
## 0.1.3
|
|
140
|
-
|
|
141
|
-
## 0.1.2
|
|
142
|
-
|
|
143
|
-
### Patch Changes
|
|
144
|
-
|
|
145
|
-
- 5d1cc90: fix: enforce proper minimum duration of 3 seconds
|
|
146
|
-
|
|
147
|
-
## 0.1.1
|
|
148
|
-
|
|
149
|
-
### Patch Changes
|
|
150
|
-
|
|
151
|
-
- 2326d00: fix: some cleanup
|
|
152
|
-
|
|
153
|
-
## 0.1.0
|
|
154
|
-
|
|
155
|
-
### Minor Changes
|
|
156
|
-
|
|
157
|
-
- 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.
|
|
158
|
-
|
|
159
|
-
## 0.0.4
|
|
160
|
-
|
|
161
|
-
### Patch Changes
|
|
162
|
-
|
|
163
|
-
- 93393c0: Remove redundant isTrackingDisabled checks from sub-trackers (ErrorTracker, WebVitalsTracker, ReplayTracker).
|
|
164
|
-
Simplify web vitals config - single source of truth (trackWebVitals ?? webVitals?.enabled ?? hasWebVitalsSampling).
|
|
165
|
-
Fix custom events via trackEvent: set window.\_\_FA_webAnalyticsInstance in init() so it works before async start() completes.
|
|
166
|
-
|
|
167
|
-
## 0.0.3
|
|
168
|
-
|
|
169
|
-
### Patch Changes
|
|
170
|
-
|
|
171
|
-
- bb3dcd1: ESM only for now
|
|
172
|
-
|
|
173
|
-
## 0.0.2
|
|
174
|
-
|
|
175
|
-
### Patch Changes
|
|
176
|
-
|
|
177
|
-
- f1f66de: feat: add track event function
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=`https://metrics.faststats.dev`,t=`https://flags.faststats.dev`;function n(e){return e.replace(/\/+$/,``)}function r(t){return t===void 0||t===``?e:n(t)||e}const i={events:`/v1/web`,identify:`/v1/identify`,replay:`/v1/replay`,vitals:`/v1/vitals`,flags:`/v1/check`};function a(e){return e===void 0||e===``?t:n(e)||t}export{r as n,a as r,i as t};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-MP-BAFHD.js";import{n as t,t as n}from"./api-urls-DaeYkG0_.js";import{n as r,t as i}from"./identifiers-CQeWm7wi.js";import{t as a}from"./send-data-DL_GlsQw.js";var o=e({default:()=>p});const s=/(?:^|\()(chrome|moz|ms-browser|safari-web)-extension:\/\//,c=e=>e?.split(`
|
|
2
|
-
`).map(e=>e.trim()).filter(Boolean);function l(e){if(e instanceof Error)return{error:e.name?.trim()||`Error`,message:e.message,stack:c(e.stack),cause:l(e.cause)};if(typeof e==`string`)return{error:`Error`,message:e}}function u(e){let t=``;for(let n=e;n;n=n.cause)t+=`${n.error}\0${n.message??``}\0`;return t}function d(e){let t=2166136261,n=3598710387;for(let r=0;r<e.length;r++){let i=e.charCodeAt(r);t=Math.imul(t^i,16777619),n=Math.imul(n^i,2246822519)}return`err_${(t>>>0).toString(16).padStart(8,`0`)}${(n>>>0).toString(16).padStart(8,`0`)}`}function f(){let e=globalThis.__SOURCEMAPS_BUILD__?.buildId;return typeof e==`string`&&e.trim()?e:void 0}var p=class{endpoint;seen=new WeakSet;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),window.addEventListener(`pagehide`,this.scheduleFlush),document.addEventListener(`visibilitychange`,this.onVisibility),this.timer=setInterval(this.scheduleFlush,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),window.removeEventListener(`pagehide`,this.scheduleFlush),document.removeEventListener(`visibilitychange`,this.onVisibility),this.timer&&clearInterval(this.timer),this.timer=null,this.scheduleFlush(),this.log(`Stopped`))}captureError(e){this.capture(`error`,e.message,!0,e)}onError=e=>{this.capture(`error`,e.message||`Unknown error`,!1,e.error,e.filename||``,e.lineno)};onRejection=e=>{let t=e.reason,n=t instanceof Error?t.message:typeof t==`string`?t:`Unhandled promise rejection`;this.capture(`unhandledrejection`,n,!1,t)};onVisibility=()=>{document.visibilityState===`hidden`&&this.scheduleFlush()};scheduleFlush=()=>{this.flush()};capture(e,t,n,r,i=``,a=``){let o=r instanceof Error?r.stack??``:``;if(s.test(`${i}\n${o}`))return;if(typeof r==`object`&&r){if(this.seen.has(r)){this.log(`Skipping duplicate:`,t);return}this.seen.add(r)}let f={error:e===`unhandledrejection`?`UnhandledRejection`:`Error`,message:t,handled:n};if(r instanceof Error){f.stack=c(r.stack);let e=l(r.cause);e&&(f.cause=e)}let p=d(`${e}\0${n?`handled`:`unhandled`}\0${t}\0${i}\0${a}\0${u(f.cause)}`),m=this.queue.get(p);m?m.count++:this.queue.set(p,{hash:p,count:1,...f}),this.log(`Captured:`,f),this.queue.size>=(this.options.maxQueueSize??50)&&this.scheduleFlush()}async flush(){if(this.flushing||this.queue.size===0)return;let e=[...this.queue.values()];this.queue.clear(),this.flushing=!0;let t=i(),n=f(),o=JSON.stringify({token:this.options.siteKey,...t?{userId:t}:{},sessionId:r(),...n?{buildId:n}:{},sdkName:this.options.sdkName??`@faststats/web`,sdkVersion:this.options.sdkVersion??`0.2.13`,data:{url:location.href,page:location.pathname,referrer:document.referrer||null,title:document.title},errors:e});this.log(`Flushing:`,e);try{await a({url:this.endpoint,data:o,debug:this.options.debug,debugPrefix:`[ErrorTracker]`})||this.requeue(e)}catch{this.requeue(e)}finally{this.flushing=!1}}requeue(e){for(let t of e){let e=this.queue.get(t.hash);e?e.count+=t.count:this.queue.set(t.hash,t)}}};export{o as n,p as t};
|
|
@@ -1,19 +0,0 @@
|
|
|
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 { FeatureFlagEvaluation as n, fetchFeatureFlagEvaluation as r, FeatureFlagCheckContext as t };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-MP-BAFHD.js";import{r as t,t as n}from"./api-urls-DaeYkG0_.js";var r=e({fetchFeatureFlagEvaluation:()=>i});async function i(e,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:e,...a?{projectId:a}:{},...o?{identifier:o}:{},...s?{externalId:s}:{},...c?{sessionId:c}:{}};r.attributes&&Object.keys(r.attributes).length>0&&(l.attributes=r.attributes);let u={"Content-Type":`application/json`};i&&(u.Authorization=`Bearer ${i}`);let d=`${t(r.baseUrl)}${n.flags}`,f=await fetch(d,{method:`POST`,headers:u,body:JSON.stringify(l),credentials:`omit`,signal:r.signal});if(!f.ok){let e=``;try{let t=await f.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${f.status}${e}`)}return await f.json()}export{i as n,r as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=`faststats_anon_id`,t=`session_id`,n=`session_timestamp`,r=`session_start`;let i=!1;function a(e){i=e}function o(e){return e??i?``:s()}function s(){if(!localStorage)return``;let t=localStorage.getItem(e);if(t)return t;let n=crypto.randomUUID();return localStorage.setItem(e,n),n}function c(t){return t||!localStorage?``:(localStorage.removeItem(e),s())}function l(){if(!sessionStorage)return``;let e=sessionStorage.getItem(t),i=sessionStorage.getItem(n);if(e&&i){if(Date.now()-Number.parseInt(i,10)<18e5)return sessionStorage.setItem(n,Date.now().toString()),e;p(sessionStorage)}let a=Date.now().toString(),o=crypto.randomUUID();return sessionStorage.setItem(t,o),sessionStorage.setItem(n,a),sessionStorage.setItem(r,a),o}function u(){return sessionStorage?(p(sessionStorage),l()):``}function d(){sessionStorage&&sessionStorage.getItem(t)&&sessionStorage.setItem(n,Date.now().toString())}function f(){if(!sessionStorage)return Date.now();let e=sessionStorage.getItem(r);if(e)return Number.parseInt(e,10);let t=sessionStorage.getItem(n);return t?Number.parseInt(t,10):Date.now()}function p(e){e.removeItem(t),e.removeItem(n),e.removeItem(r)}export{c as a,d as i,l as n,u as o,f as r,a as s,o as t};
|