@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.
Files changed (51) hide show
  1. package/dist/chunks/api-urls-nKmJnyjD.js +1 -0
  2. package/dist/chunks/identifiers-wylBcW5K.js +1 -0
  3. package/dist/chunks/{replay-BuX3_0xs.d.ts → replay-Dpl1P6cw.d.ts} +17 -12
  4. package/dist/chunks/send-data-D6WdryL7.js +1 -0
  5. package/dist/error.d.ts +4 -12
  6. package/dist/error.js +2 -1
  7. package/dist/feature-flags.d.ts +19 -2
  8. package/dist/feature-flags.js +1 -1
  9. package/dist/index.d.ts +15 -37
  10. package/dist/index.js +1 -1
  11. package/dist/replay.d.ts +2 -2
  12. package/dist/replay.js +1 -1
  13. package/dist/web-vitals.d.ts +4 -7
  14. package/dist/web-vitals.js +1 -1
  15. package/package.json +9 -11
  16. package/CHANGELOG.md +0 -177
  17. package/dist/chunks/api-urls-DaeYkG0_.js +0 -1
  18. package/dist/chunks/error-CDVOMiI9.js +0 -2
  19. package/dist/chunks/feature-flags-BClx56v5.d.ts +0 -19
  20. package/dist/chunks/feature-flags-DSOCIZHK.js +0 -1
  21. package/dist/chunks/identifiers-CQeWm7wi.js +0 -1
  22. package/dist/chunks/replay-CHFW2q4E.js +0 -1
  23. package/dist/chunks/rolldown-runtime-MP-BAFHD.js +0 -1
  24. package/dist/chunks/send-data-DL_GlsQw.js +0 -1
  25. package/dist/chunks/types-CYzR5xtT.js +0 -1
  26. package/dist/chunks/web-vitals-GwPlL7Zy.js +0 -1
  27. package/scripts/check-bundle-size.mjs +0 -96
  28. package/src/analytics.ts +0 -776
  29. package/src/entries/error.ts +0 -6
  30. package/src/entries/feature-flags.ts +0 -5
  31. package/src/entries/main.ts +0 -21
  32. package/src/entries/replay.ts +0 -1
  33. package/src/entries/web-vitals.ts +0 -1
  34. package/src/env.d.ts +0 -2
  35. package/src/error.ts +0 -252
  36. package/src/feature-flags.ts +0 -84
  37. package/src/replay.ts +0 -469
  38. package/src/sdk.ts +0 -8
  39. package/src/utils/api-urls.ts +0 -24
  40. package/src/utils/identifiers.ts +0 -89
  41. package/src/utils/send-data.ts +0 -52
  42. package/src/utils/types.ts +0 -15
  43. package/src/web-vitals.ts +0 -159
  44. package/tests/analytics.test.ts +0 -450
  45. package/tests/identifiers.test.ts +0 -95
  46. package/tests/replay.test.ts +0 -412
  47. package/tests/web-vitals.test.ts +0 -208
  48. package/tsconfig.json +0 -30
  49. package/tsdown.config.ts +0 -27
  50. package/worker/index.ts +0 -22
  51. 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 { eventWithTime } from "@rrweb/types";
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?: recordOptions<eventWithTime>["sampling"];
18
- slimDOMOptions?: SlimDOMOptions;
17
+ sampling?: RecordOptions["sampling"];
18
+ slimDOMOptions?: RecordOptions["slimDOMOptions"];
19
19
  maskAllInputs?: boolean;
20
- maskInputOptions?: recordOptions<eventWithTime>["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 sessionId;
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
- getSessionId(): string | undefined;
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 readonly seen;
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 onVisibility;
38
- private scheduleFlush;
39
- private capture;
32
+ private enqueue;
40
33
  private flush;
41
- private requeue;
42
34
  }
43
35
  //#endregion
44
- export { type ErrorEntry, type ErrorTracking, type ErrorTrackingOptions, ErrorTracker as default };
36
+ export { ErrorEntry, ErrorTrackingOptions, ErrorTracker as default };
package/dist/error.js CHANGED
@@ -1 +1,2 @@
1
- import{t as e}from"./chunks/error-CDVOMiI9.js";export{e as default};
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};
@@ -1,2 +1,19 @@
1
- import { n as FeatureFlagEvaluation, r as fetchFeatureFlagEvaluation, t as FeatureFlagCheckContext } from "./chunks/feature-flags-BClx56v5.js";
2
- export { type FeatureFlagCheckContext, type FeatureFlagEvaluation, fetchFeatureFlagEvaluation };
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 };
@@ -1 +1 @@
1
- import{n as e}from"./chunks/feature-flags-DSOCIZHK.js";export{e as fetchFeatureFlagEvaluation};
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 { n as FeatureFlagEvaluation, r as fetchFeatureFlagEvaluation, t as FeatureFlagCheckContext } from "./chunks/feature-flags-BClx56v5.js";
2
- import { n as ReplayTrackerOptions } from "./chunks/replay-BuX3_0xs.js";
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 scrollHandler;
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 handlePopState;
99
- private readonly handleHashChange;
83
+ private readonly handlePageShow;
100
84
  constructor(options: WebAnalyticsOptions);
101
85
  private log;
102
86
  private init;
103
- private registerCleanup;
104
- private addWindowListener;
105
- private addDocumentListener;
106
- private patchHistory;
87
+ private isActive;
107
88
  private ensureStarted;
108
- private stopHeartbeat;
109
- private stopNavigationTimer;
110
- private stopChildTrackers;
111
- private registerChildTracker;
89
+ private addListener;
90
+ private patchHistory;
91
+ private notifyChildren;
112
92
  private startChildTracker;
113
- private startErrorTracker;
114
- private startWebVitalsTracker;
115
- private startReplayTracker;
93
+ private startOptionalTrackers;
116
94
  start(): Promise<void>;
117
95
  destroy(): void;
118
- pageview(extra?: Dict): void;
119
- track(name: string, extra?: Dict): void;
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 FeatureFlagCheckContext, type FeatureFlagEvaluation, type IdentifyOptions, WebAnalytics, type WebAnalyticsOptions, fetchFeatureFlagEvaluation, getInstance, identify, isTrackingDisabled, logout, optIn, optOut, reportError, sendData, setConsentMode, trackEvent };
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-BuX3_0xs.js";
2
- export { type ReplayTrackerOptions, ReplayTracker as default };
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{t as e}from"./chunks/replay-CHFW2q4E.js";export{e as default};
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};
@@ -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 onHidden;
23
- private onPageHide;
24
- private capture;
22
+ private onMetric;
25
23
  private flush;
26
- private removeListeners;
27
24
  }
28
25
  //#endregion
29
- export { type WebVitalsOptions, WebVitalsTracker as default };
26
+ export { WebVitalsOptions, WebVitalsTracker as default };
@@ -1 +1 @@
1
- import{t as e}from"./chunks/web-vitals-GwPlL7Zy.js";export{e as default};
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.2.13",
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.0-alpha.20",
60
- "@rrweb/rrweb-plugin-sequential-id-record": "^2.0.0-alpha.20",
61
- "@rrweb/types": "^2.0.0-alpha.20",
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};