userlens-analytics-sdk 0.1.8 → 0.1.10

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.
@@ -669,7 +669,16 @@ class EventCollector {
669
669
  )
670
670
  return;
671
671
 
672
- const referrer = new URL(document.referrer || "");
672
+ let referrer = "";
673
+ try {
674
+ if (document.referrer && /^https?:\/\//.test(document.referrer)) {
675
+ referrer =
676
+ new URL(document.referrer).origin +
677
+ new URL(document.referrer).pathname;
678
+ }
679
+ } catch (e) {
680
+ referrer = "";
681
+ }
673
682
 
674
683
  // Convert query params to object
675
684
  const queryParams = Object.fromEntries(url.searchParams.entries());
@@ -677,7 +686,7 @@ class EventCollector {
677
686
  const pageview = {
678
687
  event: url?.origin + url?.pathname || "pageview",
679
688
  properties: {
680
- referrer: referrer.origin + referrer.pathname,
689
+ referrer,
681
690
  query: queryParams,
682
691
  },
683
692
  };
@@ -688,7 +697,7 @@ class EventCollector {
688
697
  JSON.stringify(this.events)
689
698
  );
690
699
  } catch (err) {
691
- console.error("Userlens EventCollector error: ", err);
700
+ console.warn("Userlens EventCollector error: tracking page view failed");
692
701
  }
693
702
  }
694
703
 
@@ -21303,11 +21312,11 @@ class SessionRecorder {
21303
21312
  constructor({
21304
21313
  WRITE_CODE,
21305
21314
  userId,
21306
- TIMEOUT = 10 * 60 * 1000,
21315
+ TIMEOUT = 30 * 60 * 1000,
21307
21316
  BUFFER_SIZE = 50,
21308
21317
  maskingOptions = ["passwords"], // "passwords", "all"
21309
21318
  }) {
21310
- if (window === undefined) {
21319
+ if (typeof window === "undefined") {
21311
21320
  console.error(
21312
21321
  "Userlens EventCollector error: unavailable outside of browser environment."
21313
21322
  );
@@ -21366,7 +21375,11 @@ class SessionRecorder {
21366
21375
 
21367
21376
  // init rrweb recorder
21368
21377
  #initRecorder() {
21369
- record({
21378
+ if (this.stopRecording) {
21379
+ this.stopRecording();
21380
+ }
21381
+
21382
+ this.stopRecording = record({
21370
21383
  emit: (event) => {
21371
21384
  this.#handleEvent(event);
21372
21385
  },
@@ -21377,8 +21390,19 @@ class SessionRecorder {
21377
21390
  }
21378
21391
 
21379
21392
  #handleEvent(event) {
21393
+ const lastActive = Number(
21394
+ window.localStorage.getItem("userlensSessionLastActive")
21395
+ );
21396
+
21397
+ if (lastActive) {
21398
+ const now = Date.now();
21399
+
21400
+ if (now - lastActive > this.TIMEOUT) {
21401
+ this.#handleInactivity();
21402
+ }
21403
+ }
21404
+
21380
21405
  this.sessionEvents.push(event);
21381
- // update last active in storage
21382
21406
  window.localStorage.setItem("userlensSessionLastActive", event.timestamp);
21383
21407
 
21384
21408
  if (this.sessionEvents.length >= this.BUFFER_SIZE) {
@@ -21386,6 +21410,22 @@ class SessionRecorder {
21386
21410
  }
21387
21411
  }
21388
21412
 
21413
+ #handleInactivity() {
21414
+ if (this.sessionEvents.length > 0) {
21415
+ this.#trackEvents();
21416
+ }
21417
+
21418
+ if (this.stopRecording) {
21419
+ this.stopRecording();
21420
+ }
21421
+
21422
+ localStorage.removeItem("userlensSessionUuid");
21423
+ localStorage.removeItem("userlensSessionLastActive");
21424
+
21425
+ this.#createSession();
21426
+ this.#initRecorder();
21427
+ }
21428
+
21389
21429
  #initUnloadListener() {
21390
21430
  window.addEventListener("beforeunload", () => {
21391
21431
  // save events on session.userlens.io service
@@ -21401,7 +21441,6 @@ class SessionRecorder {
21401
21441
 
21402
21442
  this.#clearEvents();
21403
21443
 
21404
- // add try/retry ?
21405
21444
  await fetch(`https://sessions.userlens.io/session/${this.sessionUuid}`, {
21406
21445
  method: "POST",
21407
21446
  headers: {
@@ -665,7 +665,16 @@ class EventCollector {
665
665
  )
666
666
  return;
667
667
 
668
- const referrer = new URL(document.referrer || "");
668
+ let referrer = "";
669
+ try {
670
+ if (document.referrer && /^https?:\/\//.test(document.referrer)) {
671
+ referrer =
672
+ new URL(document.referrer).origin +
673
+ new URL(document.referrer).pathname;
674
+ }
675
+ } catch (e) {
676
+ referrer = "";
677
+ }
669
678
 
670
679
  // Convert query params to object
671
680
  const queryParams = Object.fromEntries(url.searchParams.entries());
@@ -673,7 +682,7 @@ class EventCollector {
673
682
  const pageview = {
674
683
  event: url?.origin + url?.pathname || "pageview",
675
684
  properties: {
676
- referrer: referrer.origin + referrer.pathname,
685
+ referrer,
677
686
  query: queryParams,
678
687
  },
679
688
  };
@@ -684,7 +693,7 @@ class EventCollector {
684
693
  JSON.stringify(this.events)
685
694
  );
686
695
  } catch (err) {
687
- console.error("Userlens EventCollector error: ", err);
696
+ console.warn("Userlens EventCollector error: tracking page view failed");
688
697
  }
689
698
  }
690
699
 
@@ -21299,11 +21308,11 @@ class SessionRecorder {
21299
21308
  constructor({
21300
21309
  WRITE_CODE,
21301
21310
  userId,
21302
- TIMEOUT = 10 * 60 * 1000,
21311
+ TIMEOUT = 30 * 60 * 1000,
21303
21312
  BUFFER_SIZE = 50,
21304
21313
  maskingOptions = ["passwords"], // "passwords", "all"
21305
21314
  }) {
21306
- if (window === undefined) {
21315
+ if (typeof window === "undefined") {
21307
21316
  console.error(
21308
21317
  "Userlens EventCollector error: unavailable outside of browser environment."
21309
21318
  );
@@ -21362,7 +21371,11 @@ class SessionRecorder {
21362
21371
 
21363
21372
  // init rrweb recorder
21364
21373
  #initRecorder() {
21365
- record({
21374
+ if (this.stopRecording) {
21375
+ this.stopRecording();
21376
+ }
21377
+
21378
+ this.stopRecording = record({
21366
21379
  emit: (event) => {
21367
21380
  this.#handleEvent(event);
21368
21381
  },
@@ -21373,8 +21386,19 @@ class SessionRecorder {
21373
21386
  }
21374
21387
 
21375
21388
  #handleEvent(event) {
21389
+ const lastActive = Number(
21390
+ window.localStorage.getItem("userlensSessionLastActive")
21391
+ );
21392
+
21393
+ if (lastActive) {
21394
+ const now = Date.now();
21395
+
21396
+ if (now - lastActive > this.TIMEOUT) {
21397
+ this.#handleInactivity();
21398
+ }
21399
+ }
21400
+
21376
21401
  this.sessionEvents.push(event);
21377
- // update last active in storage
21378
21402
  window.localStorage.setItem("userlensSessionLastActive", event.timestamp);
21379
21403
 
21380
21404
  if (this.sessionEvents.length >= this.BUFFER_SIZE) {
@@ -21382,6 +21406,22 @@ class SessionRecorder {
21382
21406
  }
21383
21407
  }
21384
21408
 
21409
+ #handleInactivity() {
21410
+ if (this.sessionEvents.length > 0) {
21411
+ this.#trackEvents();
21412
+ }
21413
+
21414
+ if (this.stopRecording) {
21415
+ this.stopRecording();
21416
+ }
21417
+
21418
+ localStorage.removeItem("userlensSessionUuid");
21419
+ localStorage.removeItem("userlensSessionLastActive");
21420
+
21421
+ this.#createSession();
21422
+ this.#initRecorder();
21423
+ }
21424
+
21385
21425
  #initUnloadListener() {
21386
21426
  window.addEventListener("beforeunload", () => {
21387
21427
  // save events on session.userlens.io service
@@ -21397,7 +21437,6 @@ class SessionRecorder {
21397
21437
 
21398
21438
  this.#clearEvents();
21399
21439
 
21400
- // add try/retry ?
21401
21440
  await fetch(`https://sessions.userlens.io/session/${this.sessionUuid}`, {
21402
21441
  method: "POST",
21403
21442
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "userlens-analytics-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "main": "dist/userlens.cjs.js",
5
5
  "module": "dist/userlens.esm.js",
6
6
  "scripts": {
@@ -52,7 +52,16 @@ export default class EventCollector {
52
52
  )
53
53
  return;
54
54
 
55
- const referrer = new URL(document.referrer || "");
55
+ let referrer = "";
56
+ try {
57
+ if (document.referrer && /^https?:\/\//.test(document.referrer)) {
58
+ referrer =
59
+ new URL(document.referrer).origin +
60
+ new URL(document.referrer).pathname;
61
+ }
62
+ } catch (e) {
63
+ referrer = "";
64
+ }
56
65
 
57
66
  // Convert query params to object
58
67
  const queryParams = Object.fromEntries(url.searchParams.entries());
@@ -60,7 +69,7 @@ export default class EventCollector {
60
69
  const pageview = {
61
70
  event: url?.origin + url?.pathname || "pageview",
62
71
  properties: {
63
- referrer: referrer.origin + referrer.pathname,
72
+ referrer,
64
73
  query: queryParams,
65
74
  },
66
75
  };
@@ -71,7 +80,7 @@ export default class EventCollector {
71
80
  JSON.stringify(this.events)
72
81
  );
73
82
  } catch (err) {
74
- console.error("Userlens EventCollector error: ", err);
83
+ console.warn("Userlens EventCollector error: tracking page view failed");
75
84
  }
76
85
  }
77
86
 
@@ -5,11 +5,11 @@ export default class SessionRecorder {
5
5
  constructor({
6
6
  WRITE_CODE,
7
7
  userId,
8
- TIMEOUT = 10 * 60 * 1000,
8
+ TIMEOUT = 30 * 60 * 1000,
9
9
  BUFFER_SIZE = 50,
10
10
  maskingOptions = ["passwords"], // "passwords", "all"
11
11
  }) {
12
- if (window === undefined) {
12
+ if (typeof window === "undefined") {
13
13
  console.error(
14
14
  "Userlens EventCollector error: unavailable outside of browser environment."
15
15
  );
@@ -68,7 +68,11 @@ export default class SessionRecorder {
68
68
 
69
69
  // init rrweb recorder
70
70
  #initRecorder() {
71
- rrwebRecord({
71
+ if (this.stopRecording) {
72
+ this.stopRecording();
73
+ }
74
+
75
+ this.stopRecording = rrwebRecord({
72
76
  emit: (event) => {
73
77
  this.#handleEvent(event);
74
78
  },
@@ -79,8 +83,19 @@ export default class SessionRecorder {
79
83
  }
80
84
 
81
85
  #handleEvent(event) {
86
+ const lastActive = Number(
87
+ window.localStorage.getItem("userlensSessionLastActive")
88
+ );
89
+
90
+ if (lastActive) {
91
+ const now = Date.now();
92
+
93
+ if (now - lastActive > this.TIMEOUT) {
94
+ this.#handleInactivity();
95
+ }
96
+ }
97
+
82
98
  this.sessionEvents.push(event);
83
- // update last active in storage
84
99
  window.localStorage.setItem("userlensSessionLastActive", event.timestamp);
85
100
 
86
101
  if (this.sessionEvents.length >= this.BUFFER_SIZE) {
@@ -88,6 +103,22 @@ export default class SessionRecorder {
88
103
  }
89
104
  }
90
105
 
106
+ #handleInactivity() {
107
+ if (this.sessionEvents.length > 0) {
108
+ this.#trackEvents();
109
+ }
110
+
111
+ if (this.stopRecording) {
112
+ this.stopRecording();
113
+ }
114
+
115
+ localStorage.removeItem("userlensSessionUuid");
116
+ localStorage.removeItem("userlensSessionLastActive");
117
+
118
+ this.#createSession();
119
+ this.#initRecorder();
120
+ }
121
+
91
122
  #initUnloadListener() {
92
123
  window.addEventListener("beforeunload", () => {
93
124
  // save events on session.userlens.io service
@@ -103,7 +134,6 @@ export default class SessionRecorder {
103
134
 
104
135
  this.#clearEvents();
105
136
 
106
- // add try/retry ?
107
137
  await fetch(`https://sessions.userlens.io/session/${this.sessionUuid}`, {
108
138
  method: "POST",
109
139
  headers: {