@statsig/web-analytics 0.0.1-beta.28 → 0.0.1-beta.29

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,9 +1,9 @@
1
1
  {
2
2
  "name": "@statsig/web-analytics",
3
- "version": "0.0.1-beta.28",
3
+ "version": "0.0.1-beta.29",
4
4
  "dependencies": {
5
- "@statsig/client-core": "0.0.1-beta.28",
6
- "@statsig/js-client": "0.0.1-beta.28"
5
+ "@statsig/client-core": "0.0.1-beta.29",
6
+ "@statsig/js-client": "0.0.1-beta.29"
7
7
  },
8
8
  "jsdelivr": "./build/statsig-web-analytics.min.js",
9
9
  "type": "commonjs",
@@ -2,6 +2,7 @@ import { StatsigClient } from '@statsig/js-client';
2
2
  export declare function runStatsigAutoCapture(client: StatsigClient): void;
3
3
  export declare class AutoCapture {
4
4
  private _client;
5
+ private _errorBoundary;
5
6
  private _startTime;
6
7
  private _deepestScroll;
7
8
  constructor(_client: StatsigClient);
@@ -14,28 +14,33 @@ class AutoCapture {
14
14
  this._startTime = Date.now();
15
15
  this._deepestScroll = 0;
16
16
  const { sdkKey } = _client.getContext();
17
+ this._errorBoundary = new client_core_1.ErrorBoundary(sdkKey);
18
+ (0, client_core_1.monitorClass)(this._errorBoundary, this);
17
19
  __STATSIG__ = __STATSIG__ !== null && __STATSIG__ !== void 0 ? __STATSIG__ : {};
18
20
  const instances = (_a = __STATSIG__.acInstances) !== null && _a !== void 0 ? _a : {};
19
21
  instances[sdkKey] = this;
20
22
  __STATSIG__.acInstances = instances;
21
- if (typeof document !== 'undefined' && document.readyState === 'loading') {
22
- document.addEventListener('DOMContentLoaded', () => this._initialize());
23
+ const doc = (0, Utils_1._getDocumentSafe)();
24
+ if ((doc === null || doc === void 0 ? void 0 : doc.readyState) === 'loading') {
25
+ doc.addEventListener('DOMContentLoaded', () => this._initialize());
23
26
  return;
24
27
  }
25
28
  this._initialize();
26
29
  }
27
30
  _addEventHandlers() {
28
- if (typeof window === 'undefined' || typeof document === 'undefined') {
31
+ const win = (0, Utils_1._getWindowSafe)();
32
+ const doc = (0, Utils_1._getDocumentSafe)();
33
+ if (!win || !doc) {
29
34
  return;
30
35
  }
31
36
  const eventHandler = (event) => {
32
- this._autoLogEvent(event || window.event);
37
+ this._autoLogEvent(event || win.event);
33
38
  };
34
- (0, Utils_1.registerEventHandler)(document, 'click', eventHandler);
35
- (0, Utils_1.registerEventHandler)(document, 'submit', eventHandler);
36
- (0, Utils_1.registerEventHandler)(window, 'error', eventHandler);
37
- (0, Utils_1.registerEventHandler)(window, 'beforeunload', () => this._pageUnloadHandler());
38
- (0, Utils_1.registerEventHandler)(window, 'scroll', () => this._scrollEventHandler());
39
+ (0, Utils_1._registerEventHandler)(doc, 'click', eventHandler);
40
+ (0, Utils_1._registerEventHandler)(doc, 'submit', eventHandler);
41
+ (0, Utils_1._registerEventHandler)(win, 'error', eventHandler);
42
+ (0, Utils_1._registerEventHandler)(win, 'beforeunload', () => this._pageUnloadHandler());
43
+ (0, Utils_1._registerEventHandler)(win, 'scroll', () => this._scrollEventHandler());
39
44
  }
40
45
  _autoLogEvent(event) {
41
46
  var _a;
@@ -44,17 +49,17 @@ class AutoCapture {
44
49
  this._logError(event);
45
50
  return;
46
51
  }
47
- const target = (0, Utils_1.getTargetNode)(event);
52
+ const target = (0, Utils_1._getTargetNode)(event);
48
53
  if (!target) {
49
54
  return;
50
55
  }
51
- if (!(0, Utils_1.shouldLogEvent)(event, target)) {
56
+ if (!(0, Utils_1._shouldLogEvent)(event, target)) {
52
57
  return;
53
58
  }
54
59
  if (eventType === 'submit') {
55
60
  eventType = 'form_submit';
56
61
  }
57
- const { value, metadata } = (0, Utils_1.gatherEventData)(target);
62
+ const { value, metadata } = (0, Utils_1._gatherEventData)(target);
58
63
  this._enqueueAutoCapture(eventType, value, metadata);
59
64
  }
60
65
  _initialize() {
@@ -86,23 +91,24 @@ class AutoCapture {
86
91
  }
87
92
  _logPageView() {
88
93
  setTimeout(() => {
89
- const url = (0, Utils_1.getSafeUrl)();
90
- this._logAutoCaptureImmediately('page_view', (0, Utils_1.getSanitizedPageUrl)(), {
91
- title: document === null || document === void 0 ? void 0 : document.title,
94
+ var _a;
95
+ const url = (0, Utils_1._getSafeUrl)();
96
+ this._logAutoCaptureImmediately('page_view', (0, Utils_1._getSanitizedPageUrl)(), {
97
+ title: (_a = (0, Utils_1._getDocumentSafe)()) === null || _a === void 0 ? void 0 : _a.title,
92
98
  queryParams: Object.fromEntries(url.searchParams),
93
99
  });
94
100
  }, 1);
95
101
  }
96
102
  _logPerformance() {
97
- if (typeof window === 'undefined' ||
98
- typeof window.performance === 'undefined' ||
99
- typeof window.performance.getEntriesByType !== 'function' ||
100
- typeof window.performance.getEntriesByName !== 'function') {
103
+ const win = (0, Utils_1._getWindowSafe)();
104
+ if (typeof (win === null || win === void 0 ? void 0 : win.performance) === 'undefined' ||
105
+ typeof win.performance.getEntriesByType !== 'function' ||
106
+ typeof win.performance.getEntriesByName !== 'function') {
101
107
  return;
102
108
  }
103
109
  setTimeout(() => {
104
110
  const metadata = {};
105
- const navEntries = window.performance.getEntriesByType('navigation');
111
+ const navEntries = win.performance.getEntriesByType('navigation');
106
112
  if (navEntries &&
107
113
  navEntries.length > 0 &&
108
114
  navEntries[0] instanceof PerformanceNavigationTiming) {
@@ -113,27 +119,27 @@ class AutoCapture {
113
119
  metadata['redirect_count'] = nav.redirectCount;
114
120
  metadata['transfer_bytes'] = nav.transferSize;
115
121
  }
116
- const fpEntries = window.performance.getEntriesByName('first-contentful-paint');
122
+ const fpEntries = win.performance.getEntriesByName('first-contentful-paint');
117
123
  if (fpEntries &&
118
124
  fpEntries.length > 0 &&
119
125
  fpEntries[0] instanceof PerformancePaintTiming) {
120
126
  metadata['first_contentful_paint_time_ms'] = fpEntries[0].startTime;
121
127
  }
122
- this._enqueueAutoCapture('performance', (0, Utils_1.getSanitizedPageUrl)(), metadata);
128
+ this._enqueueAutoCapture('performance', (0, Utils_1._getSanitizedPageUrl)(), metadata);
123
129
  }, 1);
124
130
  }
125
131
  _pageUnloadHandler() {
126
- this._logAutoCaptureImmediately('page_view_end', (0, Utils_1.getSanitizedPageUrl)(), {
132
+ this._logAutoCaptureImmediately('page_view_end', (0, Utils_1._getSanitizedPageUrl)(), {
127
133
  scrollDepth: this._deepestScroll,
128
134
  pageViewLength: Date.now() - this._startTime,
129
135
  });
130
136
  }
131
137
  _enqueueAutoCapture(name, value, metadata) {
132
- var _a;
138
+ var _a, _b, _c;
133
139
  const event = {
134
140
  eventName: `auto_capture::${name}`,
135
141
  value,
136
- metadata: Object.assign({ sessionId: (0, Utils_1.getWebSessionId)(this._client.getContext().sdkKey), page_url: ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.href) || '' }, metadata),
142
+ metadata: Object.assign({ sessionId: (0, Utils_1._getWebSessionId)(this._client.getContext().sdkKey), page_url: (_c = (_b = (_a = (0, Utils_1._getWindowSafe)()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : '' }, metadata),
137
143
  };
138
144
  this._client.logEvent(event);
139
145
  client_core_1.Log.debug('Enqueued Event', event);
@@ -145,8 +151,12 @@ class AutoCapture {
145
151
  });
146
152
  }
147
153
  _scrollEventHandler() {
148
- const scrollHeight = document.body.scrollHeight || 1;
149
- this._deepestScroll = Math.max(this._deepestScroll, Math.min(100, Math.round(((window.scrollY + window.innerHeight) / scrollHeight) * 100)));
154
+ var _a, _b, _c, _d;
155
+ const scrollHeight = (_b = (_a = (0, Utils_1._getDocumentSafe)()) === null || _a === void 0 ? void 0 : _a.body.scrollHeight) !== null && _b !== void 0 ? _b : 1;
156
+ const win = (0, Utils_1._getWindowSafe)();
157
+ const scrollY = (_c = win === null || win === void 0 ? void 0 : win.scrollY) !== null && _c !== void 0 ? _c : 1;
158
+ const innerHeight = (_d = win === null || win === void 0 ? void 0 : win.innerHeight) !== null && _d !== void 0 ? _d : 1;
159
+ this._deepestScroll = Math.max(this._deepestScroll, Math.min(100, Math.round(((scrollY + innerHeight) / scrollHeight) * 100)));
150
160
  }
151
161
  }
152
162
  exports.AutoCapture = AutoCapture;
package/src/Utils.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- export declare function gatherEventData(target: Element): {
1
+ export declare function _getDocumentSafe(): Document | null;
2
+ export declare function _getWindowSafe(): Window | null;
3
+ export declare function _gatherEventData(target: Element): {
2
4
  value: string;
3
5
  metadata: Record<string, string | null>;
4
6
  };
5
- export declare function getTargetNode(e: Event): Element | null;
6
- export declare function shouldLogEvent(e: Event, el: Element): boolean;
7
- export declare function getSafeUrl(): URL;
8
- export declare function getWebSessionId(sdkKey: string): string;
9
- export declare function getSanitizedPageUrl(): string;
10
- export declare function registerEventHandler(element: Document | Window, eventType: string, handler: (event: Event) => void): void;
7
+ export declare function _getTargetNode(e: Event): Element | null;
8
+ export declare function _shouldLogEvent(e: Event, el: Element): boolean;
9
+ export declare function _getSafeUrl(): URL;
10
+ export declare function _getWebSessionId(sdkKey: string): string;
11
+ export declare function _getSanitizedPageUrl(): string;
12
+ export declare function _registerEventHandler(element: Document | Window, eventType: string, handler: (event: Event) => void): void;
package/src/Utils.js CHANGED
@@ -1,11 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerEventHandler = exports.getSanitizedPageUrl = exports.getWebSessionId = exports.getSafeUrl = exports.shouldLogEvent = exports.getTargetNode = exports.gatherEventData = void 0;
3
+ exports._registerEventHandler = exports._getSanitizedPageUrl = exports._getWebSessionId = exports._getSafeUrl = exports._shouldLogEvent = exports._getTargetNode = exports._gatherEventData = exports._getWindowSafe = exports._getDocumentSafe = void 0;
4
4
  const client_core_1 = require("@statsig/client-core");
5
5
  const MAX_SESSION_IDLE_TIME = 10 * 60 * 1000; // 10 minutes
6
6
  const MAX_SESSION_AGE = 4 * 60 * 60 * 1000; // 4 hours
7
7
  const globals = {};
8
- function gatherEventData(target) {
8
+ function _getDocumentSafe() {
9
+ var _a;
10
+ const win = _getWindowSafe();
11
+ return (_a = win === null || win === void 0 ? void 0 : win.document) !== null && _a !== void 0 ? _a : null;
12
+ }
13
+ exports._getDocumentSafe = _getDocumentSafe;
14
+ function _getWindowSafe() {
15
+ return typeof window !== 'undefined' ? window : null;
16
+ }
17
+ exports._getWindowSafe = _getWindowSafe;
18
+ function _gatherEventData(target) {
9
19
  var _a;
10
20
  const tagName = target.tagName.toLowerCase();
11
21
  const metadata = {};
@@ -30,8 +40,8 @@ function gatherEventData(target) {
30
40
  }
31
41
  return { value, metadata };
32
42
  }
33
- exports.gatherEventData = gatherEventData;
34
- function getTargetNode(e) {
43
+ exports._gatherEventData = _gatherEventData;
44
+ function _getTargetNode(e) {
35
45
  if (!e) {
36
46
  return null;
37
47
  }
@@ -44,8 +54,8 @@ function getTargetNode(e) {
44
54
  }
45
55
  return target;
46
56
  }
47
- exports.getTargetNode = getTargetNode;
48
- function shouldLogEvent(e, el) {
57
+ exports._getTargetNode = _getTargetNode;
58
+ function _shouldLogEvent(e, el) {
49
59
  if (!e || !el || el.nodeType !== 1) {
50
60
  return false;
51
61
  }
@@ -73,10 +83,10 @@ function shouldLogEvent(e, el) {
73
83
  return false;
74
84
  }
75
85
  }
76
- exports.shouldLogEvent = shouldLogEvent;
77
- function getSafeUrl() {
78
- var _a;
79
- const href = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.href) || '';
86
+ exports._shouldLogEvent = _shouldLogEvent;
87
+ function _getSafeUrl() {
88
+ var _a, _b, _c;
89
+ const href = (_c = (_b = (_a = _getWindowSafe()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : '';
80
90
  let url;
81
91
  try {
82
92
  url = new URL(href);
@@ -86,8 +96,8 @@ function getSafeUrl() {
86
96
  }
87
97
  return url;
88
98
  }
89
- exports.getSafeUrl = getSafeUrl;
90
- function getWebSessionId(sdkKey) {
99
+ exports._getSafeUrl = _getSafeUrl;
100
+ function _getWebSessionId(sdkKey) {
91
101
  const key = `statsig.web_analytics.session.${(0, client_core_1.DJB2)(sdkKey)}`;
92
102
  const json = _getLocalValue(key);
93
103
  const now = Date.now();
@@ -103,20 +113,20 @@ function getWebSessionId(sdkKey) {
103
113
  _setLocalValue(key, JSON.stringify(session));
104
114
  return session.id;
105
115
  }
106
- exports.getWebSessionId = getWebSessionId;
107
- function getSanitizedPageUrl() {
108
- var _a, _b;
109
- const url = (_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.href) === null || _b === void 0 ? void 0 : _b.split(/[?#]/)[0];
116
+ exports._getWebSessionId = _getWebSessionId;
117
+ function _getSanitizedPageUrl() {
118
+ var _a, _b, _c;
119
+ const url = (_c = (_b = (_a = _getWindowSafe()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) === null || _c === void 0 ? void 0 : _c.split(/[?#]/)[0];
110
120
  return url || '';
111
121
  }
112
- exports.getSanitizedPageUrl = getSanitizedPageUrl;
113
- function registerEventHandler(element, eventType, handler) {
122
+ exports._getSanitizedPageUrl = _getSanitizedPageUrl;
123
+ function _registerEventHandler(element, eventType, handler) {
114
124
  if (!element || !element.addEventListener) {
115
125
  return;
116
126
  }
117
127
  element.addEventListener(eventType, handler, true);
118
128
  }
119
- exports.registerEventHandler = registerEventHandler;
129
+ exports._registerEventHandler = _registerEventHandler;
120
130
  function _getAnchorNodeInHierarchy(node) {
121
131
  if (!node) {
122
132
  return null;
@@ -135,17 +145,19 @@ function _getAnchorNodeInHierarchy(node) {
135
145
  return null;
136
146
  }
137
147
  function _setLocalValue(key, value) {
138
- if (window && window.localStorage) {
139
- window.localStorage.setItem(key, value);
148
+ const win = _getWindowSafe();
149
+ if (win && win.localStorage) {
150
+ win.localStorage.setItem(key, value);
140
151
  }
141
152
  else {
142
153
  globals[key] = value;
143
- client_core_1.Log.error('Statsig Web AutoCapture: No window.localStorage');
154
+ client_core_1.Log.error('AutoCapture: No window.localStorage');
144
155
  }
145
156
  }
146
157
  function _getLocalValue(key) {
147
- if (window && window.localStorage) {
148
- return window.localStorage.getItem(key);
158
+ const win = _getWindowSafe();
159
+ if (win && win.localStorage) {
160
+ return win.localStorage.getItem(key);
149
161
  }
150
162
  return globals[key];
151
163
  }