@capillarytech/cap-ui-utils 1.2.2 → 1.2.4
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/GA/index.js +104 -38
- package/GA/utils/tracker.js +1 -1
- package/package.json +1 -1
package/GA/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ReactGA from 'react-ga';
|
|
2
|
-
|
|
2
|
+
import ttiPolyfill from 'tti-polyfill';
|
|
3
|
+
|
|
3
4
|
import timeTracker from './utils/timeTracker';
|
|
4
5
|
import tracker from './utils/tracker';
|
|
5
6
|
import routeTrackerWrapper from './utils/routeTrackerWrapper';
|
|
@@ -9,18 +10,18 @@ import warn from '../utils/console/warn';
|
|
|
9
10
|
import log from '../utils/console/log';
|
|
10
11
|
|
|
11
12
|
const _initialize = (GAConfigs) => {
|
|
12
|
-
|
|
13
|
+
const { accessKey, trackUIError, trackLoadPerformance } = GAConfigs || {}
|
|
14
|
+
if (!accessKey) {
|
|
13
15
|
warn("Cannot initialize GA without accessKey");
|
|
14
16
|
return;
|
|
17
|
+
} else {
|
|
18
|
+
ReactGA.initialize(accessKey,{debug: true,});
|
|
15
19
|
}
|
|
16
|
-
if(
|
|
17
|
-
|
|
20
|
+
if(trackUIError){
|
|
21
|
+
errorTracks();
|
|
18
22
|
}
|
|
19
|
-
if(
|
|
20
|
-
|
|
21
|
-
window.addEventListener('error', (e) =>{
|
|
22
|
-
tracker.trackException(`UI Error ${e.message}`);
|
|
23
|
-
});
|
|
23
|
+
if(trackLoadPerformance){
|
|
24
|
+
loadPerformanceTracking(trackLoadPerformance);
|
|
24
25
|
}
|
|
25
26
|
eventsAfterInitialize();
|
|
26
27
|
log("Cap GA initialized");
|
|
@@ -28,19 +29,67 @@ const _initialize = (GAConfigs) => {
|
|
|
28
29
|
const setCustomDimension= value => {
|
|
29
30
|
ReactGA.set(value);
|
|
30
31
|
}
|
|
32
|
+
const loadPerformanceTracking = module =>{
|
|
33
|
+
//requestStart: when the browser issues a request to get the webpage from the server
|
|
34
|
+
// responsesStart: when the first byte of the website arrives
|
|
35
|
+
// responseEnd: When the last byte of the website arrives
|
|
36
|
+
|
|
37
|
+
const callback = list => {
|
|
38
|
+
list.getEntries().forEach(entry => {
|
|
39
|
+
const { responseStart = 0, requestStart = 0, responseEnd = 0 } = entry || {};
|
|
40
|
+
const serverLatency = Math.round((responseStart - requestStart).toFixed(2));
|
|
41
|
+
const downloadTime = Math.round((responseEnd - responseStart).toFixed(2));
|
|
42
|
+
const loadTime = Math.round((responseEnd - requestStart).toFixed(2));
|
|
43
|
+
// Server latency:
|
|
44
|
+
ReactGA.timing({
|
|
45
|
+
category: "performance- server latentcy",
|
|
46
|
+
variable: module,
|
|
47
|
+
value: serverLatency,
|
|
48
|
+
})
|
|
49
|
+
// Download time:
|
|
50
|
+
ReactGA.timing({
|
|
51
|
+
category: "performance- download time",
|
|
52
|
+
variable: module,
|
|
53
|
+
value: downloadTime
|
|
54
|
+
})
|
|
55
|
+
// Total app load time:
|
|
56
|
+
ReactGA.timing({
|
|
57
|
+
category: "performance- load time",
|
|
58
|
+
variable: module,
|
|
59
|
+
value: loadTime
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
var observer = new PerformanceObserver(callback);
|
|
66
|
+
observer.observe({ entryTypes: ['navigation'] });
|
|
67
|
+
// Time to Interactive metric is essentially how long it takes for a user to be able to interact with your site.
|
|
68
|
+
// Time to Interactive is defined as the point at which the layout has stabilized, key webfonts are visible,
|
|
69
|
+
// and the main thread is available enough to handle user input.
|
|
70
|
+
ttiPolyfill.getFirstConsistentlyInteractive().then((tti) => {
|
|
71
|
+
ReactGA.timing({
|
|
72
|
+
category: "Time to Interactive",
|
|
73
|
+
variable: module,
|
|
74
|
+
value: Math.round(tti.toFixed(2))
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
}catch(e){
|
|
78
|
+
console.log(e);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
31
81
|
const initialize = (GAConfigs) =>{
|
|
32
82
|
if (isEmpty(GAConfigs)) {
|
|
33
83
|
warn("Cannot initialize empty object");
|
|
34
84
|
return;
|
|
35
85
|
}
|
|
36
86
|
for ( const config in GAConfigs) {
|
|
37
|
-
if (
|
|
87
|
+
if (!GAConfigs[config]) {
|
|
38
88
|
warn("Config is empty");
|
|
39
89
|
return;
|
|
40
90
|
}
|
|
41
91
|
}
|
|
42
92
|
_initialize(GAConfigs);
|
|
43
|
-
|
|
44
93
|
return true;
|
|
45
94
|
}
|
|
46
95
|
const eventsAfterInitialize = () => {
|
|
@@ -52,39 +101,56 @@ const eventsAfterInitialize = () => {
|
|
|
52
101
|
});
|
|
53
102
|
}
|
|
54
103
|
|
|
104
|
+
const errorTracks = () => {
|
|
105
|
+
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
|
106
|
+
// to avoid 2 times same error log
|
|
107
|
+
if (error.hasBeenCaught !== undefined){
|
|
108
|
+
return false
|
|
109
|
+
}
|
|
110
|
+
error.hasBeenCaught = true
|
|
111
|
+
const message = [
|
|
112
|
+
'Message: ' + msg,
|
|
113
|
+
'URL: ' + url,
|
|
114
|
+
].join(' - ');
|
|
115
|
+
tracker.trackException({
|
|
116
|
+
description: message,
|
|
117
|
+
fatal: true,
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const getCallerName = () => {
|
|
122
|
+
let nameTrace;
|
|
123
|
+
try {
|
|
124
|
+
throw new Error();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// Error.prototype.stack Manually throw an error and catch the function name by tracing the stack
|
|
127
|
+
//As per MDN, the use of Error.prototype.stack is discouraged because of it's non-standard behaviour and it's behaviour might change on different browsers
|
|
128
|
+
//once we find better solution we will make the changes
|
|
129
|
+
let stackLines = e.stack.split('\n');
|
|
130
|
+
let callerIndex = 0;
|
|
131
|
+
for (let i in stackLines) {
|
|
132
|
+
if (stackLines.hasOwnProperty(i)) {
|
|
133
|
+
if (!stackLines[i].match(/http[s]?:\/\//)) continue;
|
|
134
|
+
callerIndex = Number(i) + 2;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
nameTrace = stackLines[callerIndex].match(/([^(]+)@|at ([^(]+) \(/);
|
|
139
|
+
if (nameTrace === null) {
|
|
140
|
+
callerIndex = callerIndex - 2;
|
|
141
|
+
nameTrace = stackLines[callerIndex].match(/([^(]+)@|at ([^(]+) \(/);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return nameTrace !== null ? nameTrace[1] || nameTrace[2] : '';
|
|
145
|
+
}
|
|
55
146
|
|
|
56
|
-
// ttiPolyfill.getFirstConsistentlyInteractive().then(tti => {
|
|
57
|
-
// console.log('performance tti', tti);
|
|
58
|
-
// });
|
|
59
|
-
|
|
60
|
-
// const callback = list => {
|
|
61
|
-
// list.getEntries().forEach(entry => {
|
|
62
|
-
// console.log('performance callback entry', entry);
|
|
63
|
-
// console.log(
|
|
64
|
-
// 'performance callback server latentcy',
|
|
65
|
-
// entry.responseStart - entry.requestStart,
|
|
66
|
-
// );
|
|
67
|
-
// console.log(
|
|
68
|
-
// 'performance callback download time',
|
|
69
|
-
// entry.responseEnd - entry.responseStart,
|
|
70
|
-
// );
|
|
71
|
-
// console.log(
|
|
72
|
-
// 'performance callback load time',
|
|
73
|
-
// entry.responseEnd - entry.requestStart,
|
|
74
|
-
// );
|
|
75
|
-
// });
|
|
76
|
-
// };
|
|
77
147
|
|
|
78
|
-
// var observer = new PerformanceObserver(callback);
|
|
79
|
-
// observer.observe({ entryTypes: ['navigation'] });
|
|
80
|
-
// var perfData = window.performance.timing;
|
|
81
|
-
// var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
|
|
82
|
-
// console.log('Performance metrics', perfData, pageLoadTime);
|
|
83
148
|
|
|
84
149
|
export default{
|
|
85
150
|
initialize,
|
|
86
151
|
timeTracker,
|
|
87
152
|
tracker,
|
|
88
153
|
routeTrackerWrapper,
|
|
89
|
-
setCustomDimension
|
|
154
|
+
setCustomDimension,
|
|
155
|
+
getCallerName,
|
|
90
156
|
}
|
package/GA/utils/tracker.js
CHANGED