@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 +3 -3
- package/src/AutoCapture.d.ts +1 -0
- package/src/AutoCapture.js +37 -27
- package/src/Utils.d.ts +9 -7
- package/src/Utils.js +36 -24
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statsig/web-analytics",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.29",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"@statsig/client-core": "0.0.1-beta.
|
|
6
|
-
"@statsig/js-client": "0.0.1-beta.
|
|
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",
|
package/src/AutoCapture.d.ts
CHANGED
|
@@ -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);
|
package/src/AutoCapture.js
CHANGED
|
@@ -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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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 ||
|
|
37
|
+
this._autoLogEvent(event || win.event);
|
|
33
38
|
};
|
|
34
|
-
(0, Utils_1.
|
|
35
|
-
(0, Utils_1.
|
|
36
|
-
(0, Utils_1.
|
|
37
|
-
(0, Utils_1.
|
|
38
|
-
(0, Utils_1.
|
|
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.
|
|
52
|
+
const target = (0, Utils_1._getTargetNode)(event);
|
|
48
53
|
if (!target) {
|
|
49
54
|
return;
|
|
50
55
|
}
|
|
51
|
-
if (!(0, Utils_1.
|
|
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.
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
typeof
|
|
100
|
-
typeof
|
|
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 =
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
149
|
-
|
|
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
|
|
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
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
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.
|
|
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
|
|
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.
|
|
34
|
-
function
|
|
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.
|
|
48
|
-
function
|
|
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.
|
|
77
|
-
function
|
|
78
|
-
var _a;
|
|
79
|
-
const href = ((_a =
|
|
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.
|
|
90
|
-
function
|
|
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.
|
|
107
|
-
function
|
|
108
|
-
var _a, _b;
|
|
109
|
-
const url = (_b = (_a =
|
|
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.
|
|
113
|
-
function
|
|
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.
|
|
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
|
-
|
|
139
|
-
|
|
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('
|
|
154
|
+
client_core_1.Log.error('AutoCapture: No window.localStorage');
|
|
144
155
|
}
|
|
145
156
|
}
|
|
146
157
|
function _getLocalValue(key) {
|
|
147
|
-
|
|
148
|
-
|
|
158
|
+
const win = _getWindowSafe();
|
|
159
|
+
if (win && win.localStorage) {
|
|
160
|
+
return win.localStorage.getItem(key);
|
|
149
161
|
}
|
|
150
162
|
return globals[key];
|
|
151
163
|
}
|