swetrix 1.3.2 → 2.0.0

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.
@@ -55,9 +55,11 @@ export declare class Lib {
55
55
  private options?;
56
56
  private pageData;
57
57
  private pageViewsOptions;
58
+ private perfStatsCollected;
58
59
  constructor(projectID: string, options?: LibOptions | undefined);
59
60
  track(event: TrackEventOptions): void;
60
61
  trackPageViews(options?: PageViewsOptions): PageActions;
62
+ getPerformanceStats(): object;
61
63
  private heartbeat;
62
64
  private checkIgnore;
63
65
  private trackPathChange;
@@ -9,6 +9,7 @@ export class Lib {
9
9
  this.options = options;
10
10
  this.pageData = null;
11
11
  this.pageViewsOptions = null;
12
+ this.perfStatsCollected = false;
12
13
  this.trackPathChange = this.trackPathChange.bind(this);
13
14
  this.heartbeat = this.heartbeat.bind(this);
14
15
  }
@@ -51,6 +52,37 @@ export class Lib {
51
52
  this.trackPage(path, options?.unique);
52
53
  return this.pageData.actions;
53
54
  }
55
+ getPerformanceStats() {
56
+ if (!this.canTrack() || this.perfStatsCollected || !window.performance?.getEntriesByType) {
57
+ return {};
58
+ }
59
+ const perf = window.performance.getEntriesByType('navigation')[0];
60
+ if (!perf) {
61
+ return {};
62
+ }
63
+ this.perfStatsCollected = true;
64
+ return {
65
+ // Network
66
+ // @ts-ignore
67
+ dns: perf.domainLookupEnd - perf.domainLookupStart,
68
+ // @ts-ignore
69
+ tls: perf.secureConnectionStart ? perf.requestStart - perf.secureConnectionStart : 0,
70
+ // @ts-ignore
71
+ conn: perf.secureConnectionStart ? perf.secureConnectionStart - perf.connectStart : perf.connectEnd - perf.connectStart,
72
+ // @ts-ignore
73
+ response: perf.responseEnd - perf.responseStart,
74
+ // Frontend
75
+ // @ts-ignore
76
+ render: perf.domComplete - perf.domContentLoadedEventEnd,
77
+ // @ts-ignore
78
+ dom_load: perf.domContentLoadedEventEnd - perf.responseEnd,
79
+ // @ts-ignore
80
+ page_load: perf.loadEventStart,
81
+ // Backend
82
+ // @ts-ignore
83
+ ttfb: perf.responseStart - perf.requestStart,
84
+ };
85
+ }
54
86
  heartbeat() {
55
87
  if (!this.pageViewsOptions?.heartbeatOnBackground && document.visibilityState === 'hidden') {
56
88
  return;
@@ -89,6 +121,7 @@ export class Lib {
89
121
  this.pageData.path = pg;
90
122
  if (this.checkIgnore(pg))
91
123
  return;
124
+ const perf = this.getPerformanceStats();
92
125
  const data = {
93
126
  pid: this.projectID,
94
127
  lc: getLocale(),
@@ -99,6 +132,7 @@ export class Lib {
99
132
  ca: getUTMCampaign(),
100
133
  unique,
101
134
  pg,
135
+ perf,
102
136
  };
103
137
  this.sendRequest('', data);
104
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Lib.js","sourceRoot":"","sources":["../../src/Lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Lib.js","sourceRoot":"","sources":["../../src/Lib.ts"],"names":[],"mappings":"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"}
@@ -24,4 +24,4 @@ export declare function track(event: TrackEventOptions): void;
24
24
  * @param {PageViewsOptions} options The options related to the custom event.
25
25
  * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
26
26
  */
27
- export declare function trackViews(options?: PageViewsOptions): PageActions;
27
+ export declare function trackViews(options?: PageViewsOptions): Promise<PageActions>;
@@ -34,8 +34,21 @@ export function track(event) {
34
34
  * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
35
35
  */
36
36
  export function trackViews(options) {
37
- if (!LIB_INSTANCE)
38
- return defaultPageActions;
39
- return LIB_INSTANCE.trackPageViews(options);
37
+ return new Promise((resolve) => {
38
+ if (!LIB_INSTANCE) {
39
+ resolve(defaultPageActions);
40
+ return;
41
+ }
42
+ // We need to verify that document.readyState is complete for the performance stats to be collected correctly.
43
+ if (document.readyState === 'complete') {
44
+ resolve(LIB_INSTANCE.trackPageViews(options));
45
+ }
46
+ else {
47
+ window.addEventListener('load', () => {
48
+ // @ts-ignore
49
+ resolve(LIB_INSTANCE.trackPageViews(options));
50
+ });
51
+ }
52
+ });
40
53
  }
41
54
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EAAgE,kBAAkB,GACtF,MAAM,OAAO,CAAA;AAEd,MAAM,CAAC,IAAI,YAAY,GAAe,IAAI,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAE,GAAW,EAAE,OAAoB;IACrD,IAAI,CAAC,YAAY,EAAE;QACjB,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;KACrC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAE,KAAwB;IAC7C,IAAI,CAAC,YAAY;QAAE,OAAM;IAEzB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAE,OAA0B;IACpD,IAAI,CAAC,YAAY;QAAE,OAAO,kBAAkB,CAAA;IAE5C,OAAO,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;AAC7C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EAAgE,kBAAkB,GACtF,MAAM,OAAO,CAAA;AAEd,MAAM,CAAC,IAAI,YAAY,GAAe,IAAI,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,GAAW,EAAE,OAAoB;IACpD,IAAI,CAAC,YAAY,EAAE;QACjB,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;KACrC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,KAAwB;IAC5C,IAAI,CAAC,YAAY;QAAE,OAAM;IAEzB,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,OAA0B;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO,CAAC,kBAAkB,CAAC,CAAA;YAC3B,OAAM;SACP;QAED,8GAA8G;QAC9G,IAAI,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE;YACtC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;SAC9C;aAAM;YACL,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE;gBACnC,aAAa;gBACb,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;YAC/C,CAAC,CAAC,CAAA;SACH;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- /*! *****************************************************************************
5
+ /******************************************************************************
6
6
  Copyright (c) Microsoft Corporation.
7
7
 
8
8
  Permission to use, copy, modify, and/or distribute this software for any
@@ -76,6 +76,7 @@ var Lib = /** @class */ (function () {
76
76
  this.options = options;
77
77
  this.pageData = null;
78
78
  this.pageViewsOptions = null;
79
+ this.perfStatsCollected = false;
79
80
  this.trackPathChange = this.trackPathChange.bind(this);
80
81
  this.heartbeat = this.heartbeat.bind(this);
81
82
  }
@@ -115,6 +116,38 @@ var Lib = /** @class */ (function () {
115
116
  this.trackPage(path, options === null || options === void 0 ? void 0 : options.unique);
116
117
  return this.pageData.actions;
117
118
  };
119
+ Lib.prototype.getPerformanceStats = function () {
120
+ var _a;
121
+ if (!this.canTrack() || this.perfStatsCollected || !((_a = window.performance) === null || _a === void 0 ? void 0 : _a.getEntriesByType)) {
122
+ return {};
123
+ }
124
+ var perf = window.performance.getEntriesByType('navigation')[0];
125
+ if (!perf) {
126
+ return {};
127
+ }
128
+ this.perfStatsCollected = true;
129
+ return {
130
+ // Network
131
+ // @ts-ignore
132
+ dns: perf.domainLookupEnd - perf.domainLookupStart,
133
+ // @ts-ignore
134
+ tls: perf.secureConnectionStart ? perf.requestStart - perf.secureConnectionStart : 0,
135
+ // @ts-ignore
136
+ conn: perf.secureConnectionStart ? perf.secureConnectionStart - perf.connectStart : perf.connectEnd - perf.connectStart,
137
+ // @ts-ignore
138
+ response: perf.responseEnd - perf.responseStart,
139
+ // Frontend
140
+ // @ts-ignore
141
+ render: perf.domComplete - perf.domContentLoadedEventEnd,
142
+ // @ts-ignore
143
+ dom_load: perf.domContentLoadedEventEnd - perf.responseEnd,
144
+ // @ts-ignore
145
+ page_load: perf.loadEventStart,
146
+ // Backend
147
+ // @ts-ignore
148
+ ttfb: perf.responseStart - perf.requestStart,
149
+ };
150
+ };
118
151
  Lib.prototype.heartbeat = function () {
119
152
  var _a;
120
153
  if (!((_a = this.pageViewsOptions) === null || _a === void 0 ? void 0 : _a.heartbeatOnBackground) && document.visibilityState === 'hidden') {
@@ -156,6 +189,7 @@ var Lib = /** @class */ (function () {
156
189
  this.pageData.path = pg;
157
190
  if (this.checkIgnore(pg))
158
191
  return;
192
+ var perf = this.getPerformanceStats();
159
193
  var data = {
160
194
  pid: this.projectID,
161
195
  lc: getLocale(),
@@ -166,6 +200,7 @@ var Lib = /** @class */ (function () {
166
200
  ca: getUTMCampaign(),
167
201
  unique: unique,
168
202
  pg: pg,
203
+ perf: perf,
169
204
  };
170
205
  this.sendRequest('', data);
171
206
  };
@@ -244,9 +279,22 @@ function track(event) {
244
279
  * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
245
280
  */
246
281
  function trackViews(options) {
247
- if (!exports.LIB_INSTANCE)
248
- return defaultPageActions;
249
- return exports.LIB_INSTANCE.trackPageViews(options);
282
+ return new Promise(function (resolve) {
283
+ if (!exports.LIB_INSTANCE) {
284
+ resolve(defaultPageActions);
285
+ return;
286
+ }
287
+ // We need to verify that document.readyState is complete for the performance stats to be collected correctly.
288
+ if (document.readyState === 'complete') {
289
+ resolve(exports.LIB_INSTANCE.trackPageViews(options));
290
+ }
291
+ else {
292
+ window.addEventListener('load', function () {
293
+ // @ts-ignore
294
+ resolve(exports.LIB_INSTANCE.trackPageViews(options));
295
+ });
296
+ }
297
+ });
250
298
  }
251
299
 
252
300
  exports.init = init;
@@ -1,4 +1,4 @@
1
- /*! *****************************************************************************
1
+ /******************************************************************************
2
2
  Copyright (c) Microsoft Corporation.
3
3
 
4
4
  Permission to use, copy, modify, and/or distribute this software for any
@@ -72,6 +72,7 @@ var Lib = /** @class */ (function () {
72
72
  this.options = options;
73
73
  this.pageData = null;
74
74
  this.pageViewsOptions = null;
75
+ this.perfStatsCollected = false;
75
76
  this.trackPathChange = this.trackPathChange.bind(this);
76
77
  this.heartbeat = this.heartbeat.bind(this);
77
78
  }
@@ -111,6 +112,38 @@ var Lib = /** @class */ (function () {
111
112
  this.trackPage(path, options === null || options === void 0 ? void 0 : options.unique);
112
113
  return this.pageData.actions;
113
114
  };
115
+ Lib.prototype.getPerformanceStats = function () {
116
+ var _a;
117
+ if (!this.canTrack() || this.perfStatsCollected || !((_a = window.performance) === null || _a === void 0 ? void 0 : _a.getEntriesByType)) {
118
+ return {};
119
+ }
120
+ var perf = window.performance.getEntriesByType('navigation')[0];
121
+ if (!perf) {
122
+ return {};
123
+ }
124
+ this.perfStatsCollected = true;
125
+ return {
126
+ // Network
127
+ // @ts-ignore
128
+ dns: perf.domainLookupEnd - perf.domainLookupStart,
129
+ // @ts-ignore
130
+ tls: perf.secureConnectionStart ? perf.requestStart - perf.secureConnectionStart : 0,
131
+ // @ts-ignore
132
+ conn: perf.secureConnectionStart ? perf.secureConnectionStart - perf.connectStart : perf.connectEnd - perf.connectStart,
133
+ // @ts-ignore
134
+ response: perf.responseEnd - perf.responseStart,
135
+ // Frontend
136
+ // @ts-ignore
137
+ render: perf.domComplete - perf.domContentLoadedEventEnd,
138
+ // @ts-ignore
139
+ dom_load: perf.domContentLoadedEventEnd - perf.responseEnd,
140
+ // @ts-ignore
141
+ page_load: perf.loadEventStart,
142
+ // Backend
143
+ // @ts-ignore
144
+ ttfb: perf.responseStart - perf.requestStart,
145
+ };
146
+ };
114
147
  Lib.prototype.heartbeat = function () {
115
148
  var _a;
116
149
  if (!((_a = this.pageViewsOptions) === null || _a === void 0 ? void 0 : _a.heartbeatOnBackground) && document.visibilityState === 'hidden') {
@@ -152,6 +185,7 @@ var Lib = /** @class */ (function () {
152
185
  this.pageData.path = pg;
153
186
  if (this.checkIgnore(pg))
154
187
  return;
188
+ var perf = this.getPerformanceStats();
155
189
  var data = {
156
190
  pid: this.projectID,
157
191
  lc: getLocale(),
@@ -162,6 +196,7 @@ var Lib = /** @class */ (function () {
162
196
  ca: getUTMCampaign(),
163
197
  unique: unique,
164
198
  pg: pg,
199
+ perf: perf,
165
200
  };
166
201
  this.sendRequest('', data);
167
202
  };
@@ -240,9 +275,22 @@ function track(event) {
240
275
  * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
241
276
  */
242
277
  function trackViews(options) {
243
- if (!LIB_INSTANCE)
244
- return defaultPageActions;
245
- return LIB_INSTANCE.trackPageViews(options);
278
+ return new Promise(function (resolve) {
279
+ if (!LIB_INSTANCE) {
280
+ resolve(defaultPageActions);
281
+ return;
282
+ }
283
+ // We need to verify that document.readyState is complete for the performance stats to be collected correctly.
284
+ if (document.readyState === 'complete') {
285
+ resolve(LIB_INSTANCE.trackPageViews(options));
286
+ }
287
+ else {
288
+ window.addEventListener('load', function () {
289
+ // @ts-ignore
290
+ resolve(LIB_INSTANCE.trackPageViews(options));
291
+ });
292
+ }
293
+ });
246
294
  }
247
295
 
248
296
  export { LIB_INSTANCE, init, track, trackViews };
package/dist/swetrix.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).swetrix={})}(this,function(i){"use strict";function n(t){return(t=location.search.match(t))&&t[2]||void 0}function o(){return location.pathname||""}var e=function(){return(e=Object.assign||function(t){for(var e,i=1,n=arguments.length;i<n;i++)for(var o in e=arguments[i])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},a=/[?&](ref|source|utm_source)=([^?&]+)/,r=/[?&](utm_campaign)=([^?&]+)/,s=/[?&](utm_medium)=([^?&]+)/,c={stop:function(){}},u=(t.prototype.track=function(t){this.canTrack()&&(t=e({pid:this.projectID},t),this.sendRequest("custom",t))},t.prototype.trackPageViews=function(t){if(!this.canTrack())return c;if(this.pageData)return this.pageData.actions;var e,i;null!=(this.pageViewsOptions=t)&&t.unique||(i=setInterval(this.trackPathChange,2e3)),null!=t&&t.noHeartbeat||(setTimeout(this.heartbeat,3e3),e=setInterval(this.heartbeat,28e3));var n=o();return this.pageData={path:n,actions:{stop:function(){clearInterval(i),clearInterval(e)}}},this.trackPage(n,null==t?void 0:t.unique),this.pageData.actions},t.prototype.heartbeat=function(){var t;(null!==(t=this.pageViewsOptions)&&void 0!==t&&t.heartbeatOnBackground||"hidden"!==document.visibilityState)&&(t={pid:this.projectID},this.sendRequest("hb",t))},t.prototype.checkIgnore=function(t){var e,i=null===(e=this.pageViewsOptions)||void 0===e?void 0:e.ignore;if(Array.isArray(i))for(var n=0;n<i.length;++n){if(i[n]===t)return!0;if(i[n]instanceof RegExp&&i[n].test(t))return!0}return!1},t.prototype.trackPathChange=function(){var t;this.pageData&&(t=o(),this.pageData.path!==t&&this.trackPage(t,!1))},t.prototype.trackPage=function(t,e){void 0===e&&(e=!1),this.pageData&&(this.pageData.path=t,this.checkIgnore(t)||(t={pid:this.projectID,lc:void 0!==navigator.languages?navigator.languages[0]:navigator.language,tz:function(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch(t){return}}(),ref:document.referrer||void 0,so:n(a),me:n(s),ca:n(r),unique:e,pg:t},this.sendRequest("",t)))},t.prototype.debug=function(t){var e;null!==(e=this.options)&&void 0!==e&&e.debug&&console.log("[Swetrix]",t)},t.prototype.canTrack=function(){var t,e;return null!==(t=this.options)&&void 0!==t&&t.disabled?(this.debug("Tracking disabled: the 'disabled' setting is set to true."),!1):"undefined"==typeof window?(this.debug("Tracking disabled: script does not run in browser environment."),!1):null!==(t=this.options)&&void 0!==t&&t.respectDNT&&"1"===(null===(e=window.navigator)||void 0===e?void 0:e.doNotTrack)?(this.debug("Tracking disabled: respecting user's 'Do Not Track' preference."),!1):!!(null!==(e=this.options)&&void 0!==e&&e.debug||"localhost"!==(null===location||void 0===location?void 0:location.hostname)&&"127.0.0.1"!==(null===location||void 0===location?void 0:location.hostname)&&""!==(null===location||void 0===location?void 0:location.hostname))&&(null===navigator||void 0===navigator||!navigator.webdriver||(this.debug("Tracking disabled: navigation is automated by WebDriver."),!1))},t.prototype.sendRequest=function(t,e){var i=(null===(n=this.options)||void 0===n?void 0:n.apiURL)||"https://api.swetrix.com/log",n=new XMLHttpRequest;n.open("POST","".concat(i,"/").concat(t),!0),n.setRequestHeader("Content-Type","application/json"),n.send(JSON.stringify(e))},t);function t(t,e){this.projectID=t,this.options=e,this.pageData=null,this.pageViewsOptions=null,this.trackPathChange=this.trackPathChange.bind(this),this.heartbeat=this.heartbeat.bind(this)}i.LIB_INSTANCE=null,i.init=function(t,e){return i.LIB_INSTANCE||(i.LIB_INSTANCE=new u(t,e)),i.LIB_INSTANCE},i.track=function(t){i.LIB_INSTANCE&&i.LIB_INSTANCE.track(t)},i.trackViews=function(t){return i.LIB_INSTANCE?i.LIB_INSTANCE.trackPageViews(t):c},Object.defineProperty(i,"__esModule",{value:!0})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).swetrix={})}(this,function(n){"use strict";function o(t){return(t=location.search.match(t))&&t[2]||void 0}function a(){return location.pathname||""}var e=function(){return(e=Object.assign||function(t){for(var e,n=1,o=arguments.length;n<o;n++)for(var a in e=arguments[n])Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a]);return t}).apply(this,arguments)},i=/[?&](ref|source|utm_source)=([^?&]+)/,r=/[?&](utm_campaign)=([^?&]+)/,s=/[?&](utm_medium)=([^?&]+)/,c={stop:function(){}},u=(t.prototype.track=function(t){this.canTrack()&&(t=e({pid:this.projectID},t),this.sendRequest("custom",t))},t.prototype.trackPageViews=function(t){var e,n,o;return this.canTrack()?(this.pageData||(null!=(this.pageViewsOptions=t)&&t.unique||(n=setInterval(this.trackPathChange,2e3)),null!=t&&t.noHeartbeat||(setTimeout(this.heartbeat,3e3),e=setInterval(this.heartbeat,28e3)),o=a(),this.pageData={path:o,actions:{stop:function(){clearInterval(n),clearInterval(e)}}},this.trackPage(o,null==t?void 0:t.unique)),this.pageData.actions):c},t.prototype.getPerformanceStats=function(){var t;return this.canTrack()&&!this.perfStatsCollected&&null!=(t=window.performance)&&t.getEntriesByType&&(t=window.performance.getEntriesByType("navigation")[0])?(this.perfStatsCollected=!0,{dns:t.domainLookupEnd-t.domainLookupStart,tls:t.secureConnectionStart?t.requestStart-t.secureConnectionStart:0,conn:t.secureConnectionStart?t.secureConnectionStart-t.connectStart:t.connectEnd-t.connectStart,response:t.responseEnd-t.responseStart,render:t.domComplete-t.domContentLoadedEventEnd,dom_load:t.domContentLoadedEventEnd-t.responseEnd,page_load:t.loadEventStart,ttfb:t.responseStart-t.requestStart}):{}},t.prototype.heartbeat=function(){var t;(null!=(t=this.pageViewsOptions)&&t.heartbeatOnBackground||"hidden"!==document.visibilityState)&&(t={pid:this.projectID},this.sendRequest("hb",t))},t.prototype.checkIgnore=function(t){var e,n=null==(e=this.pageViewsOptions)?void 0:e.ignore;if(Array.isArray(n))for(var o=0;o<n.length;++o){if(n[o]===t)return!0;if(n[o]instanceof RegExp&&n[o].test(t))return!0}return!1},t.prototype.trackPathChange=function(){var t;this.pageData&&(t=a(),this.pageData.path!==t)&&this.trackPage(t,!1)},t.prototype.trackPage=function(t,e){var n;void 0===e&&(e=!1),this.pageData&&(this.pageData.path=t,this.checkIgnore(t)||(n=this.getPerformanceStats(),e={pid:this.projectID,lc:void 0!==navigator.languages?navigator.languages[0]:navigator.language,tz:function(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch(t){}}(),ref:document.referrer||void 0,so:o(i),me:o(s),ca:o(r),unique:e,pg:t,perf:n},this.sendRequest("",e)))},t.prototype.debug=function(t){var e;null!=(e=this.options)&&e.debug&&console.log("[Swetrix]",t)},t.prototype.canTrack=function(){var t;return null!=(t=this.options)&&t.disabled?(this.debug("Tracking disabled: the 'disabled' setting is set to true."),!1):"undefined"==typeof window?(this.debug("Tracking disabled: script does not run in browser environment."),!1):null!=(t=this.options)&&t.respectDNT&&"1"===(null==(t=window.navigator)?void 0:t.doNotTrack)?(this.debug("Tracking disabled: respecting user's 'Do Not Track' preference."),!1):!(!(null!=(t=this.options)&&t.debug||"localhost"!==(null===location||void 0===location?void 0:location.hostname)&&"127.0.0.1"!==(null===location||void 0===location?void 0:location.hostname)&&""!==(null===location||void 0===location?void 0:location.hostname))||null!==navigator&&void 0!==navigator&&navigator.webdriver&&(this.debug("Tracking disabled: navigation is automated by WebDriver."),1))},t.prototype.sendRequest=function(t,e){var n=(null==(n=this.options)?void 0:n.apiURL)||"https://api.swetrix.com/log",o=new XMLHttpRequest;o.open("POST","".concat(n,"/").concat(t),!0),o.setRequestHeader("Content-Type","application/json"),o.send(JSON.stringify(e))},t);function t(t,e){this.projectID=t,this.options=e,this.pageData=null,this.pageViewsOptions=null,this.perfStatsCollected=!1,this.trackPathChange=this.trackPathChange.bind(this),this.heartbeat=this.heartbeat.bind(this)}n.LIB_INSTANCE=null,n.init=function(t,e){return n.LIB_INSTANCE||(n.LIB_INSTANCE=new u(t,e)),n.LIB_INSTANCE},n.track=function(t){n.LIB_INSTANCE&&n.LIB_INSTANCE.track(t)},n.trackViews=function(e){return new Promise(function(t){n.LIB_INSTANCE?"complete"===document.readyState?t(n.LIB_INSTANCE.trackPageViews(e)):window.addEventListener("load",function(){t(n.LIB_INSTANCE.trackPageViews(e))}):t(c)})},Object.defineProperty(n,"__esModule",{value:!0})});
@@ -0,0 +1,308 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.swetrix = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+
22
+ var __assign = function() {
23
+ __assign = Object.assign || function __assign(t) {
24
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
25
+ s = arguments[i];
26
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27
+ }
28
+ return t;
29
+ };
30
+ return __assign.apply(this, arguments);
31
+ };
32
+
33
+ var findInSearch = function (exp) {
34
+ var res = location.search.match(exp);
35
+ return (res && res[2]) || undefined;
36
+ };
37
+ var utmSourceRegex = /[?&](ref|source|utm_source)=([^?&]+)/;
38
+ var utmCampaignRegex = /[?&](utm_campaign)=([^?&]+)/;
39
+ var utmMediumRegex = /[?&](utm_medium)=([^?&]+)/;
40
+ var isInBrowser = function () {
41
+ return typeof window !== 'undefined';
42
+ };
43
+ var isLocalhost = function () {
44
+ return (location === null || location === void 0 ? void 0 : location.hostname) === 'localhost' || (location === null || location === void 0 ? void 0 : location.hostname) === '127.0.0.1' || (location === null || location === void 0 ? void 0 : location.hostname) === '';
45
+ };
46
+ var isAutomated = function () {
47
+ return navigator === null || navigator === void 0 ? void 0 : navigator.webdriver;
48
+ };
49
+ var getLocale = function () {
50
+ return typeof navigator.languages !== 'undefined' ? navigator.languages[0] : navigator.language;
51
+ };
52
+ var getTimezone = function () {
53
+ try {
54
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
55
+ }
56
+ catch (e) {
57
+ return;
58
+ }
59
+ };
60
+ var getReferrer = function () {
61
+ return document.referrer || undefined;
62
+ };
63
+ var getUTMSource = function () { return findInSearch(utmSourceRegex); };
64
+ var getUTMMedium = function () { return findInSearch(utmMediumRegex); };
65
+ var getUTMCampaign = function () { return findInSearch(utmCampaignRegex); };
66
+ var getPath = function () {
67
+ // TODO: Maybe we should also include such data as location.hash or location.search
68
+ return location.pathname || '';
69
+ };
70
+
71
+ var defaultPageActions = {
72
+ stop: function () { },
73
+ };
74
+ var DEFAULT_API_HOST = 'https://api.swetrix.com/log';
75
+ var Lib = /** @class */ (function () {
76
+ function Lib(projectID, options) {
77
+ this.projectID = projectID;
78
+ this.options = options;
79
+ this.pageData = null;
80
+ this.pageViewsOptions = null;
81
+ this.perfStatsCollected = false;
82
+ this.trackPathChange = this.trackPathChange.bind(this);
83
+ this.heartbeat = this.heartbeat.bind(this);
84
+ }
85
+ Lib.prototype.track = function (event) {
86
+ if (!this.canTrack()) {
87
+ return;
88
+ }
89
+ var data = __assign({ pid: this.projectID }, event);
90
+ this.sendRequest('custom', data);
91
+ };
92
+ Lib.prototype.trackPageViews = function (options) {
93
+ if (!this.canTrack()) {
94
+ return defaultPageActions;
95
+ }
96
+ if (this.pageData) {
97
+ return this.pageData.actions;
98
+ }
99
+ this.pageViewsOptions = options;
100
+ var hbInterval, interval;
101
+ if (!(options === null || options === void 0 ? void 0 : options.unique)) {
102
+ interval = setInterval(this.trackPathChange, 2000);
103
+ }
104
+ if (!(options === null || options === void 0 ? void 0 : options.noHeartbeat)) {
105
+ setTimeout(this.heartbeat, 3000);
106
+ hbInterval = setInterval(this.heartbeat, 28000);
107
+ }
108
+ var path = getPath();
109
+ this.pageData = {
110
+ path: path,
111
+ actions: {
112
+ stop: function () {
113
+ clearInterval(interval);
114
+ clearInterval(hbInterval);
115
+ },
116
+ },
117
+ };
118
+ this.trackPage(path, options === null || options === void 0 ? void 0 : options.unique);
119
+ return this.pageData.actions;
120
+ };
121
+ Lib.prototype.getPerformanceStats = function () {
122
+ var _a;
123
+ if (!this.canTrack() || this.perfStatsCollected || !((_a = window.performance) === null || _a === void 0 ? void 0 : _a.getEntriesByType)) {
124
+ return {};
125
+ }
126
+ var perf = window.performance.getEntriesByType('navigation')[0];
127
+ if (!perf) {
128
+ return {};
129
+ }
130
+ this.perfStatsCollected = true;
131
+ return {
132
+ // Network
133
+ // @ts-ignore
134
+ dns: perf.domainLookupEnd - perf.domainLookupStart,
135
+ // @ts-ignore
136
+ tls: perf.secureConnectionStart ? perf.requestStart - perf.secureConnectionStart : 0,
137
+ // @ts-ignore
138
+ conn: perf.secureConnectionStart ? perf.secureConnectionStart - perf.connectStart : perf.connectEnd - perf.connectStart,
139
+ // @ts-ignore
140
+ response: perf.responseEnd - perf.responseStart,
141
+ // Frontend
142
+ // @ts-ignore
143
+ render: perf.domComplete - perf.domContentLoadedEventEnd,
144
+ // @ts-ignore
145
+ dom_load: perf.domContentLoadedEventEnd - perf.responseEnd,
146
+ // @ts-ignore
147
+ page_load: perf.loadEventStart,
148
+ // Backend
149
+ // @ts-ignore
150
+ ttfb: perf.responseStart - perf.requestStart,
151
+ };
152
+ };
153
+ Lib.prototype.heartbeat = function () {
154
+ var _a;
155
+ if (!((_a = this.pageViewsOptions) === null || _a === void 0 ? void 0 : _a.heartbeatOnBackground) && document.visibilityState === 'hidden') {
156
+ return;
157
+ }
158
+ var data = {
159
+ pid: this.projectID,
160
+ };
161
+ this.sendRequest('hb', data);
162
+ };
163
+ Lib.prototype.checkIgnore = function (path) {
164
+ var _a;
165
+ var ignore = (_a = this.pageViewsOptions) === null || _a === void 0 ? void 0 : _a.ignore;
166
+ if (Array.isArray(ignore)) {
167
+ for (var i = 0; i < ignore.length; ++i) {
168
+ if (ignore[i] === path)
169
+ return true;
170
+ // @ts-ignore
171
+ if (ignore[i] instanceof RegExp && ignore[i].test(path))
172
+ return true;
173
+ }
174
+ }
175
+ return false;
176
+ };
177
+ // Tracking path changes. If path changes -> calling this.trackPage method
178
+ Lib.prototype.trackPathChange = function () {
179
+ if (!this.pageData)
180
+ return;
181
+ var newPath = getPath();
182
+ var path = this.pageData.path;
183
+ if (path !== newPath) {
184
+ this.trackPage(newPath, false);
185
+ }
186
+ };
187
+ Lib.prototype.trackPage = function (pg, unique) {
188
+ if (unique === void 0) { unique = false; }
189
+ if (!this.pageData)
190
+ return;
191
+ this.pageData.path = pg;
192
+ if (this.checkIgnore(pg))
193
+ return;
194
+ var perf = this.getPerformanceStats();
195
+ var data = {
196
+ pid: this.projectID,
197
+ lc: getLocale(),
198
+ tz: getTimezone(),
199
+ ref: getReferrer(),
200
+ so: getUTMSource(),
201
+ me: getUTMMedium(),
202
+ ca: getUTMCampaign(),
203
+ unique: unique,
204
+ pg: pg,
205
+ perf: perf,
206
+ };
207
+ this.sendRequest('', data);
208
+ };
209
+ Lib.prototype.debug = function (message) {
210
+ var _a;
211
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.debug) {
212
+ console.log('[Swetrix]', message);
213
+ }
214
+ };
215
+ Lib.prototype.canTrack = function () {
216
+ var _a, _b, _c, _d;
217
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.disabled) {
218
+ this.debug('Tracking disabled: the \'disabled\' setting is set to true.');
219
+ return false;
220
+ }
221
+ if (!isInBrowser()) {
222
+ this.debug('Tracking disabled: script does not run in browser environment.');
223
+ return false;
224
+ }
225
+ if (((_b = this.options) === null || _b === void 0 ? void 0 : _b.respectDNT) && ((_c = window.navigator) === null || _c === void 0 ? void 0 : _c.doNotTrack) === '1') {
226
+ this.debug('Tracking disabled: respecting user\'s \'Do Not Track\' preference.');
227
+ return false;
228
+ }
229
+ if (!((_d = this.options) === null || _d === void 0 ? void 0 : _d.debug) && isLocalhost()) {
230
+ return false;
231
+ }
232
+ if (isAutomated()) {
233
+ this.debug('Tracking disabled: navigation is automated by WebDriver.');
234
+ return false;
235
+ }
236
+ return true;
237
+ };
238
+ Lib.prototype.sendRequest = function (path, body) {
239
+ var _a;
240
+ var host = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.apiURL) || DEFAULT_API_HOST;
241
+ var req = new XMLHttpRequest();
242
+ req.open('POST', "".concat(host, "/").concat(path), true);
243
+ req.setRequestHeader('Content-Type', 'application/json');
244
+ req.send(JSON.stringify(body));
245
+ };
246
+ return Lib;
247
+ }());
248
+
249
+ exports.LIB_INSTANCE = null;
250
+ /**
251
+ * Initialise the tracking library instance (other methods won't work if the library is not initialised).
252
+ *
253
+ * @param {string} pid The Project ID to link the instance of Swetrix.js to.
254
+ * @param {LibOptions} options Options related to the tracking.
255
+ * @returns {Lib} Instance of the Swetrix.js.
256
+ */
257
+ function init(pid, options) {
258
+ if (!exports.LIB_INSTANCE) {
259
+ exports.LIB_INSTANCE = new Lib(pid, options);
260
+ }
261
+ return exports.LIB_INSTANCE;
262
+ }
263
+ /**
264
+ * With this function you are able to track any custom events you want.
265
+ * You should never send any identifiable data (like User ID, email, session cookie, etc.) as an event name.
266
+ * The total number of track calls and their conversion rate will be saved.
267
+ *
268
+ * @param {TrackEventOptions} event The options related to the custom event.
269
+ */
270
+ function track(event) {
271
+ if (!exports.LIB_INSTANCE)
272
+ return;
273
+ exports.LIB_INSTANCE.track(event);
274
+ }
275
+ /**
276
+ * With this function you are able to track any custom events you want.
277
+ * You should never send any identifiable data (like User ID, email, session cookie, etc.) as an event name.
278
+ * The total number of track calls and their conversion rate will be saved.
279
+ *
280
+ * @param {PageViewsOptions} options The options related to the custom event.
281
+ * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
282
+ */
283
+ function trackViews(options) {
284
+ return new Promise(function (resolve) {
285
+ if (!exports.LIB_INSTANCE) {
286
+ resolve(defaultPageActions);
287
+ return;
288
+ }
289
+ // We need to verify that document.readyState is complete for the performance stats to be collected correctly.
290
+ if (document.readyState === 'complete') {
291
+ resolve(exports.LIB_INSTANCE.trackPageViews(options));
292
+ }
293
+ else {
294
+ window.addEventListener('load', function () {
295
+ // @ts-ignore
296
+ resolve(exports.LIB_INSTANCE.trackPageViews(options));
297
+ });
298
+ }
299
+ });
300
+ }
301
+
302
+ exports.init = init;
303
+ exports.track = track;
304
+ exports.trackViews = trackViews;
305
+
306
+ Object.defineProperty(exports, '__esModule', { value: true });
307
+
308
+ }));
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "swetrix",
3
- "version": "1.3.2",
3
+ "version": "2.0.0",
4
4
  "description": "The JavaScript analytics client for Swetrix Analytics",
5
5
  "main": "dist/swetrix.cjs.js",
6
6
  "module": "dist/swetrix.es5.js",
7
7
  "browser": "dist/swetrix.js",
8
+ "origbrowser": "dist/swetrix.orig.js",
8
9
  "esnext": "dist/esnext/index.js",
9
10
  "typings": "dist/esnext/index.d.ts",
10
11
  "keywords": [
@@ -26,18 +27,19 @@
26
27
  },
27
28
  "homepage": "https://swetrix.com/docs",
28
29
  "dependencies": {
29
- "@types/node": "^14.18.0"
30
+ "@types/node": "^18.11.18",
31
+ "tslib": "^2.4.1"
30
32
  },
31
33
  "devDependencies": {
32
- "@rollup/plugin-commonjs": "^21.0.1",
33
- "@rollup/plugin-node-resolve": "^13.0.6",
34
+ "@rollup/plugin-commonjs": "^24.0.0",
35
+ "@rollup/plugin-node-resolve": "^15.0.1",
34
36
  "rimraf": "^3.0.2",
35
- "rollup": "^2.61.1",
37
+ "rollup": "^2.79.1",
36
38
  "rollup-plugin-node-resolve": "^5.2.0",
37
39
  "rollup-plugin-sourcemaps": "^0.6.3",
38
- "rollup-plugin-typescript2": "^0.30.0",
40
+ "rollup-plugin-typescript2": "^0.34.1",
39
41
  "rollup-plugin-uglify": "^6.0.4",
40
- "typescript": "^4.5.3"
42
+ "typescript": "^4.9.4"
41
43
  },
42
44
  "scripts": {
43
45
  "prebuild": "rimraf dist",
package/rollup.config.js CHANGED
@@ -11,6 +11,7 @@ export default [
11
11
  output: [
12
12
  { file: pkg.main, format: 'cjs' },
13
13
  { file: pkg.module, format: 'es' },
14
+ { file: pkg.origbrowser, format: 'umd', name: 'swetrix' },
14
15
  ],
15
16
  plugins: [
16
17
  typescript(), nodeResolve(), commonjs(), sourceMaps(),
package/src/Lib.ts CHANGED
@@ -74,6 +74,7 @@ const DEFAULT_API_HOST = 'https://api.swetrix.com/log'
74
74
  export class Lib {
75
75
  private pageData: PageData | null = null
76
76
  private pageViewsOptions: PageViewsOptions | null | undefined = null
77
+ private perfStatsCollected: Boolean = false
77
78
 
78
79
  constructor(private projectID: string, private options?: LibOptions) {
79
80
  this.trackPathChange = this.trackPathChange.bind(this)
@@ -128,6 +129,45 @@ export class Lib {
128
129
  return this.pageData.actions
129
130
  }
130
131
 
132
+ getPerformanceStats(): object {
133
+ if (!this.canTrack() || this.perfStatsCollected || !window.performance?.getEntriesByType) {
134
+ return {}
135
+ }
136
+
137
+ const perf = window.performance.getEntriesByType('navigation')[0]
138
+
139
+ if (!perf) {
140
+ return {}
141
+ }
142
+
143
+ this.perfStatsCollected = true
144
+
145
+ return {
146
+ // Network
147
+ // @ts-ignore
148
+ dns: perf.domainLookupEnd - perf.domainLookupStart, // DNS Resolution
149
+ // @ts-ignore
150
+ tls: perf.secureConnectionStart ? perf.requestStart - perf.secureConnectionStart : 0, // TLS Setup; checking if secureConnectionStart is not 0 (it's 0 for non-https websites)
151
+ // @ts-ignore
152
+ conn: perf.secureConnectionStart ? perf.secureConnectionStart - perf.connectStart : perf.connectEnd - perf.connectStart, // Connection time
153
+ // @ts-ignore
154
+ response: perf.responseEnd - perf.responseStart, // Response Time (Download)
155
+
156
+ // Frontend
157
+ // @ts-ignore
158
+ render: perf.domComplete - perf.domContentLoadedEventEnd, // Browser rendering the HTML time
159
+ // @ts-ignore
160
+ dom_load: perf.domContentLoadedEventEnd - perf.responseEnd, // DOM loading timing
161
+ // @ts-ignore
162
+ page_load: perf.loadEventStart, // Page load time
163
+
164
+ // Backend
165
+ // @ts-ignore
166
+ ttfb: perf.responseStart - perf.requestStart,
167
+ }
168
+ }
169
+
170
+
131
171
  private heartbeat(): void {
132
172
  if (!this.pageViewsOptions?.heartbeatOnBackground && document.visibilityState === 'hidden') {
133
173
  return
@@ -170,6 +210,8 @@ export class Lib {
170
210
 
171
211
  if (this.checkIgnore(pg)) return
172
212
 
213
+ const perf = this.getPerformanceStats()
214
+
173
215
  const data = {
174
216
  pid: this.projectID,
175
217
  lc: getLocale(),
@@ -180,6 +222,7 @@ export class Lib {
180
222
  ca: getUTMCampaign(),
181
223
  unique,
182
224
  pg,
225
+ perf,
183
226
  }
184
227
 
185
228
  this.sendRequest('', data)
package/src/index.ts CHANGED
@@ -11,7 +11,7 @@ export let LIB_INSTANCE: Lib | null = null
11
11
  * @param {LibOptions} options Options related to the tracking.
12
12
  * @returns {Lib} Instance of the Swetrix.js.
13
13
  */
14
- export function init (pid: string, options?: LibOptions): Lib {
14
+ export function init(pid: string, options?: LibOptions): Lib {
15
15
  if (!LIB_INSTANCE) {
16
16
  LIB_INSTANCE = new Lib(pid, options)
17
17
  }
@@ -26,7 +26,7 @@ export function init (pid: string, options?: LibOptions): Lib {
26
26
  *
27
27
  * @param {TrackEventOptions} event The options related to the custom event.
28
28
  */
29
- export function track (event: TrackEventOptions): void {
29
+ export function track(event: TrackEventOptions): void {
30
30
  if (!LIB_INSTANCE) return
31
31
 
32
32
  LIB_INSTANCE.track(event)
@@ -40,8 +40,21 @@ export function track (event: TrackEventOptions): void {
40
40
  * @param {PageViewsOptions} options The options related to the custom event.
41
41
  * @returns {PageActions} The actions related to the tracking. Used to stop tracking pages.
42
42
  */
43
- export function trackViews (options?: PageViewsOptions): PageActions {
44
- if (!LIB_INSTANCE) return defaultPageActions
43
+ export function trackViews(options?: PageViewsOptions): Promise<PageActions> {
44
+ return new Promise((resolve) => {
45
+ if (!LIB_INSTANCE) {
46
+ resolve(defaultPageActions)
47
+ return
48
+ }
45
49
 
46
- return LIB_INSTANCE.trackPageViews(options)
50
+ // We need to verify that document.readyState is complete for the performance stats to be collected correctly.
51
+ if (document.readyState === 'complete') {
52
+ resolve(LIB_INSTANCE.trackPageViews(options))
53
+ } else {
54
+ window.addEventListener('load', () => {
55
+ // @ts-ignore
56
+ resolve(LIB_INSTANCE.trackPageViews(options))
57
+ })
58
+ }
59
+ })
47
60
  }