@statsig/web-analytics 0.0.1-beta.28 → 0.0.1-beta.30
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 +7 -7
- package/src/Utils.js +26 -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.30",
|
|
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.30",
|
|
6
|
+
"@statsig/js-client": "0.0.1-beta.30"
|
|
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, client_core_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, client_core_1._getWindowSafe)();
|
|
32
|
+
const doc = (0, client_core_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, client_core_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, client_core_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, client_core_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, client_core_1._getDocumentSafe)()) === null || _a === void 0 ? void 0 : _a.body.scrollHeight) !== null && _b !== void 0 ? _b : 1;
|
|
156
|
+
const win = (0, client_core_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,10 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function _gatherEventData(target: Element): {
|
|
2
2
|
value: string;
|
|
3
3
|
metadata: Record<string, string | null>;
|
|
4
4
|
};
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
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;
|
package/src/Utils.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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 = 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 _gatherEventData(target) {
|
|
9
9
|
var _a;
|
|
10
10
|
const tagName = target.tagName.toLowerCase();
|
|
11
11
|
const metadata = {};
|
|
@@ -30,8 +30,8 @@ function gatherEventData(target) {
|
|
|
30
30
|
}
|
|
31
31
|
return { value, metadata };
|
|
32
32
|
}
|
|
33
|
-
exports.
|
|
34
|
-
function
|
|
33
|
+
exports._gatherEventData = _gatherEventData;
|
|
34
|
+
function _getTargetNode(e) {
|
|
35
35
|
if (!e) {
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
@@ -44,8 +44,8 @@ function getTargetNode(e) {
|
|
|
44
44
|
}
|
|
45
45
|
return target;
|
|
46
46
|
}
|
|
47
|
-
exports.
|
|
48
|
-
function
|
|
47
|
+
exports._getTargetNode = _getTargetNode;
|
|
48
|
+
function _shouldLogEvent(e, el) {
|
|
49
49
|
if (!e || !el || el.nodeType !== 1) {
|
|
50
50
|
return false;
|
|
51
51
|
}
|
|
@@ -73,10 +73,10 @@ function shouldLogEvent(e, el) {
|
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
exports.
|
|
77
|
-
function
|
|
78
|
-
var _a;
|
|
79
|
-
const href = ((_a =
|
|
76
|
+
exports._shouldLogEvent = _shouldLogEvent;
|
|
77
|
+
function _getSafeUrl() {
|
|
78
|
+
var _a, _b, _c;
|
|
79
|
+
const href = (_c = (_b = (_a = (0, client_core_1._getWindowSafe)()) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : '';
|
|
80
80
|
let url;
|
|
81
81
|
try {
|
|
82
82
|
url = new URL(href);
|
|
@@ -86,8 +86,8 @@ function getSafeUrl() {
|
|
|
86
86
|
}
|
|
87
87
|
return url;
|
|
88
88
|
}
|
|
89
|
-
exports.
|
|
90
|
-
function
|
|
89
|
+
exports._getSafeUrl = _getSafeUrl;
|
|
90
|
+
function _getWebSessionId(sdkKey) {
|
|
91
91
|
const key = `statsig.web_analytics.session.${(0, client_core_1.DJB2)(sdkKey)}`;
|
|
92
92
|
const json = _getLocalValue(key);
|
|
93
93
|
const now = Date.now();
|
|
@@ -103,20 +103,20 @@ function getWebSessionId(sdkKey) {
|
|
|
103
103
|
_setLocalValue(key, JSON.stringify(session));
|
|
104
104
|
return session.id;
|
|
105
105
|
}
|
|
106
|
-
exports.
|
|
107
|
-
function
|
|
108
|
-
var _a, _b;
|
|
109
|
-
const url = (_b = (_a =
|
|
106
|
+
exports._getWebSessionId = _getWebSessionId;
|
|
107
|
+
function _getSanitizedPageUrl() {
|
|
108
|
+
var _a, _b, _c;
|
|
109
|
+
const url = (_c = (_b = (_a = (0, client_core_1._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
110
|
return url || '';
|
|
111
111
|
}
|
|
112
|
-
exports.
|
|
113
|
-
function
|
|
112
|
+
exports._getSanitizedPageUrl = _getSanitizedPageUrl;
|
|
113
|
+
function _registerEventHandler(element, eventType, handler) {
|
|
114
114
|
if (!element || !element.addEventListener) {
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
element.addEventListener(eventType, handler, true);
|
|
118
118
|
}
|
|
119
|
-
exports.
|
|
119
|
+
exports._registerEventHandler = _registerEventHandler;
|
|
120
120
|
function _getAnchorNodeInHierarchy(node) {
|
|
121
121
|
if (!node) {
|
|
122
122
|
return null;
|
|
@@ -135,17 +135,19 @@ function _getAnchorNodeInHierarchy(node) {
|
|
|
135
135
|
return null;
|
|
136
136
|
}
|
|
137
137
|
function _setLocalValue(key, value) {
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
const win = (0, client_core_1._getWindowSafe)();
|
|
139
|
+
if (win && win.localStorage) {
|
|
140
|
+
win.localStorage.setItem(key, value);
|
|
140
141
|
}
|
|
141
142
|
else {
|
|
142
143
|
globals[key] = value;
|
|
143
|
-
client_core_1.Log.error('
|
|
144
|
+
client_core_1.Log.error('AutoCapture: No window.localStorage');
|
|
144
145
|
}
|
|
145
146
|
}
|
|
146
147
|
function _getLocalValue(key) {
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
const win = (0, client_core_1._getWindowSafe)();
|
|
149
|
+
if (win && win.localStorage) {
|
|
150
|
+
return win.localStorage.getItem(key);
|
|
149
151
|
}
|
|
150
152
|
return globals[key];
|
|
151
153
|
}
|