@statsig/web-analytics 3.18.2 → 3.18.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statsig/web-analytics",
3
- "version": "3.18.2",
3
+ "version": "3.18.3",
4
4
  "license": "ISC",
5
5
  "homepage": "https://github.com/statsig-io/js-client-monorepo",
6
6
  "repository": {
@@ -9,8 +9,9 @@
9
9
  "directory": "packages/web-analytics"
10
10
  },
11
11
  "dependencies": {
12
- "@statsig/client-core": "3.18.2",
13
- "@statsig/js-client": "3.18.2"
12
+ "@statsig/client-core": "3.18.3",
13
+ "@statsig/js-client": "3.18.3",
14
+ "web-vitals": "5.0.3"
14
15
  },
15
16
  "jsdelivr": "./build/statsig-web-analytics.min.js",
16
17
  "type": "commonjs",
@@ -19,6 +19,7 @@ export declare class AutoCapture {
19
19
  private _hasLoggedPageViewEnd;
20
20
  private _engagementManager;
21
21
  private _rageClickManager;
22
+ private _webVitalsManager;
22
23
  constructor(_client: PrecomputedEvaluationsInterface, options?: AutoCaptureOptions);
23
24
  private _addEventHandlers;
24
25
  private _addPageViewTracking;
@@ -31,6 +32,7 @@ export declare class AutoCapture {
31
32
  private _logRageClick;
32
33
  private _logPerformance;
33
34
  private _enqueueAutoCapture;
35
+ private _flushImmediately;
34
36
  private _isNewSession;
35
37
  private _getSessionFromClient;
36
38
  }
@@ -5,9 +5,10 @@ const client_core_1 = require("@statsig/client-core");
5
5
  const AutoCaptureEvent_1 = require("./AutoCaptureEvent");
6
6
  const EngagementManager_1 = require("./EngagementManager");
7
7
  const RageClickManager_1 = require("./RageClickManager");
8
- const commonUtils_1 = require("./commonUtils");
9
- const eventUtils_1 = require("./eventUtils");
10
- const metadataUtils_1 = require("./metadataUtils");
8
+ const WebVitalsManager_1 = require("./WebVitalsManager");
9
+ const commonUtils_1 = require("./utils/commonUtils");
10
+ const eventUtils_1 = require("./utils/eventUtils");
11
+ const metadataUtils_1 = require("./utils/metadataUtils");
11
12
  const AUTO_EVENT_MAPPING = {
12
13
  submit: AutoCaptureEvent_1.AutoCaptureEventName.FORM_SUBMIT,
13
14
  click: AutoCaptureEvent_1.AutoCaptureEventName.CLICK,
@@ -23,6 +24,15 @@ class StatsigAutoCapturePlugin {
23
24
  }
24
25
  exports.StatsigAutoCapturePlugin = StatsigAutoCapturePlugin;
25
26
  function runStatsigAutoCapture(client, options) {
27
+ var _a;
28
+ const { sdkKey } = client.getContext();
29
+ if (!(0, client_core_1._isServerEnv)()) {
30
+ const global = (0, client_core_1._getStatsigGlobal)();
31
+ const instances = (_a = global.acInstances) !== null && _a !== void 0 ? _a : {};
32
+ if (instances[sdkKey]) {
33
+ return instances[sdkKey];
34
+ }
35
+ }
26
36
  return new AutoCapture(client, options);
27
37
  }
28
38
  exports.runStatsigAutoCapture = runStatsigAutoCapture;
@@ -45,6 +55,7 @@ class AutoCapture {
45
55
  });
46
56
  this._engagementManager = new EngagementManager_1.EngagementManager();
47
57
  this._rageClickManager = new RageClickManager_1.default();
58
+ this._webVitalsManager = new WebVitalsManager_1.WebVitalsManager(this._enqueueAutoCapture.bind(this));
48
59
  this._eventFilterFunc = options === null || options === void 0 ? void 0 : options.eventFilterFunc;
49
60
  const doc = (0, client_core_1._getDocumentSafe)();
50
61
  if (!(0, client_core_1._isServerEnv)()) {
@@ -123,6 +134,7 @@ class AutoCapture {
123
134
  this._enqueueAutoCapture(eventName, value, Object.assign(Object.assign({}, allMetadata), metadata));
124
135
  }
125
136
  _initialize() {
137
+ this._webVitalsManager.startTracking();
126
138
  this._engagementManager.startInactivityTracking(() => this._tryLogPageViewEnd(true));
127
139
  this._addEventHandlers();
128
140
  this._addPageViewTracking();
@@ -249,15 +261,18 @@ class AutoCapture {
249
261
  }
250
262
  this._client.logEvent(event);
251
263
  if (options === null || options === void 0 ? void 0 : options.flushImmediately) {
252
- this._client.flush().catch((e) => {
253
- client_core_1.Log.error(e);
254
- });
264
+ this._flushImmediately();
255
265
  }
256
266
  }
257
267
  catch (err) {
258
268
  this._errorBoundary.logError('AC::enqueue', err);
259
269
  }
260
270
  }
271
+ _flushImmediately() {
272
+ this._client.flush().catch((e) => {
273
+ client_core_1.Log.error(e);
274
+ });
275
+ }
261
276
  _isNewSession(session) {
262
277
  // within the last second
263
278
  return Math.abs(session.data.startTime - Date.now()) < 1000;
@@ -8,6 +8,7 @@ export declare const AutoCaptureEventName: {
8
8
  readonly FORM_SUBMIT: "auto_capture::form_submit";
9
9
  readonly CLICK: "auto_capture::click";
10
10
  readonly RAGE_CLICK: "auto_capture::rage_click";
11
+ readonly WEB_VITALS: "auto_capture::web_vitals";
11
12
  };
12
13
  export type AutoCaptureEventName = (typeof AutoCaptureEventName)[keyof typeof AutoCaptureEventName] & string;
13
14
  export type AutoCaptureEvent = StatsigEvent & {
@@ -10,4 +10,5 @@ exports.AutoCaptureEventName = {
10
10
  FORM_SUBMIT: 'auto_capture::form_submit',
11
11
  CLICK: 'auto_capture::click',
12
12
  RAGE_CLICK: 'auto_capture::rage_click',
13
+ WEB_VITALS: 'auto_capture::web_vitals',
13
14
  };
@@ -0,0 +1,9 @@
1
+ import { AutoCaptureEventName } from './AutoCaptureEvent';
2
+ export declare class WebVitalsManager {
3
+ private _enqueueFn;
4
+ private _isInitialized;
5
+ constructor(_enqueueFn: (eventName: AutoCaptureEventName, value: string, metadata: Record<string, unknown>) => void);
6
+ startTracking(): void;
7
+ private _handleMetric;
8
+ private _enqueueWebVitalsAutoCaptureEvent;
9
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebVitalsManager = void 0;
4
+ const web_vitals_1 = require("web-vitals");
5
+ const client_core_1 = require("@statsig/client-core");
6
+ const AutoCaptureEvent_1 = require("./AutoCaptureEvent");
7
+ const commonUtils_1 = require("./utils/commonUtils");
8
+ const VALID_METRIC_NAMES = ['CLS', 'FCP', 'LCP', 'TTFB'];
9
+ class WebVitalsManager {
10
+ constructor(_enqueueFn) {
11
+ this._enqueueFn = _enqueueFn;
12
+ this._isInitialized = false;
13
+ }
14
+ startTracking() {
15
+ var _a, _b;
16
+ if (this._isInitialized) {
17
+ return;
18
+ }
19
+ const protocol = (_b = (_a = (0, client_core_1._getWindowSafe)()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.protocol;
20
+ if (protocol !== 'https:' && protocol !== 'http:') {
21
+ return;
22
+ }
23
+ (0, web_vitals_1.onCLS)((metric) => this._handleMetric(metric));
24
+ (0, web_vitals_1.onFCP)((metric) => this._handleMetric(metric));
25
+ (0, web_vitals_1.onLCP)((metric) => this._handleMetric(metric));
26
+ (0, web_vitals_1.onTTFB)((metric) => this._handleMetric(metric));
27
+ this._isInitialized = true;
28
+ }
29
+ _handleMetric(metric) {
30
+ if (metric === undefined || (metric === null || metric === void 0 ? void 0 : metric.name) === undefined) {
31
+ return;
32
+ }
33
+ const currentUrl = (0, commonUtils_1._getSafeUrlString)();
34
+ if (currentUrl === '') {
35
+ // If the URL is not valid, we don't want to track the metric
36
+ return;
37
+ }
38
+ if (!VALID_METRIC_NAMES.includes(metric.name)) {
39
+ return;
40
+ }
41
+ this._enqueueWebVitalsAutoCaptureEvent(metric, currentUrl);
42
+ }
43
+ _enqueueWebVitalsAutoCaptureEvent(metric, url) {
44
+ if (url === '') {
45
+ return;
46
+ }
47
+ this._enqueueFn(AutoCaptureEvent_1.AutoCaptureEventName.WEB_VITALS, url, {
48
+ name: metric.name,
49
+ value: metric.value,
50
+ delta: metric.delta,
51
+ id: metric.id,
52
+ });
53
+ }
54
+ }
55
+ exports.WebVitalsManager = WebVitalsManager;
@@ -8,6 +8,7 @@ export declare function _stripEmptyValues<T extends Record<string, string | numb
8
8
  export declare function _getTargetNode(e: Event): Element | null;
9
9
  export declare function _shouldLogEvent(e: Event, el: Element): boolean;
10
10
  export declare function _getSafeUrl(): URL;
11
+ export declare function _getSafeUrlString(): string;
11
12
  export declare function _getSanitizedPageUrl(): string;
12
13
  export declare function _registerEventHandler(element: Document | Window, eventType: string, handler: (event: Event) => void): void;
13
14
  export declare function _getSafeNetworkInformation(): NetworkInformation | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._getAnchorNodeInHierarchy = exports._getSafeTimezoneOffset = exports._getSafeTimezone = exports._getSafeNetworkInformation = exports._registerEventHandler = exports._getSanitizedPageUrl = exports._getSafeUrl = exports._shouldLogEvent = exports._getTargetNode = exports._stripEmptyValues = void 0;
3
+ exports._getAnchorNodeInHierarchy = exports._getSafeTimezoneOffset = exports._getSafeTimezone = exports._getSafeNetworkInformation = exports._registerEventHandler = exports._getSanitizedPageUrl = exports._getSafeUrlString = exports._getSafeUrl = exports._shouldLogEvent = exports._getTargetNode = exports._stripEmptyValues = void 0;
4
4
  const client_core_1 = require("@statsig/client-core");
5
5
  function _stripEmptyValues(obj) {
6
6
  return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value != null && value !== '' && value !== undefined));
@@ -62,6 +62,14 @@ function _getSafeUrl() {
62
62
  return url;
63
63
  }
64
64
  exports._getSafeUrl = _getSafeUrl;
65
+ function _getSafeUrlString() {
66
+ const urlString = _getSafeUrl().toString();
67
+ if (urlString.startsWith('error:')) {
68
+ return '';
69
+ }
70
+ return urlString;
71
+ }
72
+ exports._getSafeUrlString = _getSafeUrlString;
65
73
  function _getSanitizedPageUrl() {
66
74
  return (0, client_core_1._getCurrentPageUrlSafe)() || '';
67
75
  }
File without changes
File without changes