@tell-rs/browser 0.2.8 → 0.3.2
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/README.md +8 -7
- package/dist/index.cjs +76 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +76 -39
- package/dist/index.js.map +1 -1
- package/dist/tell.global.js +3 -3
- package/dist/tell.global.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ tell.track("Button Clicked", { button: "signup" });
|
|
|
32
32
|
tell.identify("user_123", { name: "Alice" });
|
|
33
33
|
|
|
34
34
|
// Structured logging
|
|
35
|
-
tell.logInfo("Checkout started", "commerce");
|
|
35
|
+
tell.logInfo("Checkout started", { section: "commerce" });
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Events called before `configure()` are automatically queued and replayed.
|
|
@@ -57,6 +57,7 @@ tell.configure("feed1e11feed1e11feed1e11feed1e11", {
|
|
|
57
57
|
disabled: false, // disable all tracking
|
|
58
58
|
maxQueueSize: 1000, // max queued items
|
|
59
59
|
sessionTimeout: 1_800_000, // 30 min session timeout
|
|
60
|
+
maxSessionLength: 86_400_000, // 24 hour max session length
|
|
60
61
|
persistence: "localStorage", // "localStorage" | "memory"
|
|
61
62
|
respectDoNotTrack: false, // honor browser DNT setting
|
|
62
63
|
botDetection: true, // auto-disable for bots
|
|
@@ -81,13 +82,13 @@ No `userId` parameter on `track`, `group`, or `revenue` — the browser SDK uses
|
|
|
81
82
|
### Logging
|
|
82
83
|
|
|
83
84
|
```ts
|
|
84
|
-
tell.log(level, message,
|
|
85
|
+
tell.log(level, message, data?)
|
|
85
86
|
|
|
86
87
|
// Convenience methods
|
|
87
|
-
tell.logError(message,
|
|
88
|
-
tell.logWarning(message,
|
|
89
|
-
tell.logInfo(message,
|
|
90
|
-
tell.logDebug(message,
|
|
88
|
+
tell.logError(message, data?)
|
|
89
|
+
tell.logWarning(message, data?)
|
|
90
|
+
tell.logInfo(message, data?)
|
|
91
|
+
tell.logDebug(message, data?)
|
|
91
92
|
// ... and logEmergency, logAlert, logCritical, logNotice, logTrace
|
|
92
93
|
```
|
|
93
94
|
|
|
@@ -129,7 +130,7 @@ tell.configure("feed1e11feed1e11feed1e11feed1e11", production()); // defaults,
|
|
|
129
130
|
|
|
130
131
|
## Features
|
|
131
132
|
|
|
132
|
-
- **Automatic sessions** — rotated on 30-min inactivity or
|
|
133
|
+
- **Automatic sessions** — persisted across page loads, rotated on 30-min inactivity or 24-hour max lifetime
|
|
133
134
|
- **Pre-init queue** — events called before `configure()` are buffered and replayed
|
|
134
135
|
- **sendBeacon flush** — events are flushed via `navigator.sendBeacon` on page unload
|
|
135
136
|
- **Bot detection** — auto-disables for headless browsers and bots
|
package/dist/index.cjs
CHANGED
|
@@ -353,6 +353,8 @@ var DEFAULTS = {
|
|
|
353
353
|
maxQueueSize: 1e3,
|
|
354
354
|
sessionTimeout: 18e5,
|
|
355
355
|
// 30 min
|
|
356
|
+
maxSessionLength: 864e5,
|
|
357
|
+
// 24 hours
|
|
356
358
|
persistence: "localStorage",
|
|
357
359
|
respectDoNotTrack: false,
|
|
358
360
|
botDetection: true,
|
|
@@ -585,20 +587,41 @@ function captureUtm() {
|
|
|
585
587
|
}
|
|
586
588
|
|
|
587
589
|
// src/session.ts
|
|
590
|
+
var SESSION_ID_KEY = "tell_session_id";
|
|
591
|
+
var SESSION_TS_KEY = "tell_session_ts";
|
|
592
|
+
var SESSION_START_KEY = "tell_session_start";
|
|
593
|
+
var PERSIST_INTERVAL = 6e4;
|
|
588
594
|
var SessionManager = class {
|
|
589
595
|
_sessionId;
|
|
590
596
|
lastHiddenAt = 0;
|
|
591
597
|
lastActivityAt;
|
|
598
|
+
sessionStartedAt;
|
|
599
|
+
lastPersistedAt = 0;
|
|
592
600
|
timeout;
|
|
601
|
+
maxLength;
|
|
602
|
+
storage;
|
|
593
603
|
onNewSession;
|
|
594
604
|
visibilityHandler;
|
|
595
|
-
lastContextAt = {};
|
|
596
605
|
constructor(config) {
|
|
597
606
|
this.timeout = config.timeout;
|
|
607
|
+
this.maxLength = config.maxLength;
|
|
608
|
+
this.storage = config.storage;
|
|
598
609
|
this.onNewSession = config.onNewSession;
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
this.
|
|
610
|
+
const now = Date.now();
|
|
611
|
+
const storedId = this.storage.get(SESSION_ID_KEY);
|
|
612
|
+
const storedTs = Number(this.storage.get(SESSION_TS_KEY) || 0);
|
|
613
|
+
const storedStart = Number(this.storage.get(SESSION_START_KEY) || 0);
|
|
614
|
+
if (storedId && storedTs > 0 && storedStart > 0 && now - storedTs < this.timeout && now - storedStart < this.maxLength) {
|
|
615
|
+
this._sessionId = storedId;
|
|
616
|
+
this.lastActivityAt = storedTs;
|
|
617
|
+
this.sessionStartedAt = storedStart;
|
|
618
|
+
} else {
|
|
619
|
+
this._sessionId = generateId();
|
|
620
|
+
this.lastActivityAt = now;
|
|
621
|
+
this.sessionStartedAt = now;
|
|
622
|
+
this.persist();
|
|
623
|
+
this.onNewSession("session_start", this._sessionId);
|
|
624
|
+
}
|
|
602
625
|
this.visibilityHandler = () => this.handleVisibility();
|
|
603
626
|
if (typeof document !== "undefined") {
|
|
604
627
|
document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
@@ -609,14 +632,21 @@ var SessionManager = class {
|
|
|
609
632
|
}
|
|
610
633
|
set sessionId(id) {
|
|
611
634
|
this._sessionId = id;
|
|
635
|
+
const now = Date.now();
|
|
636
|
+
this.lastActivityAt = now;
|
|
637
|
+
this.sessionStartedAt = now;
|
|
638
|
+
this.persist();
|
|
612
639
|
}
|
|
613
|
-
/** Update activity timestamp; rotates session if idle longer than timeout. */
|
|
640
|
+
/** Update activity timestamp; rotates session if idle longer than timeout or exceeds max length. */
|
|
614
641
|
touch() {
|
|
615
642
|
const now = Date.now();
|
|
616
|
-
if (now - this.lastActivityAt > this.timeout) {
|
|
643
|
+
if (now - this.lastActivityAt > this.timeout || now - this.sessionStartedAt > this.maxLength) {
|
|
617
644
|
this.rotateSession("session_timeout");
|
|
618
645
|
}
|
|
619
646
|
this.lastActivityAt = now;
|
|
647
|
+
if (now - this.lastPersistedAt >= PERSIST_INTERVAL) {
|
|
648
|
+
this.persistActivity();
|
|
649
|
+
}
|
|
620
650
|
}
|
|
621
651
|
destroy() {
|
|
622
652
|
if (typeof document !== "undefined") {
|
|
@@ -627,26 +657,31 @@ var SessionManager = class {
|
|
|
627
657
|
if (document.visibilityState === "hidden") {
|
|
628
658
|
this.lastHiddenAt = Date.now();
|
|
629
659
|
} else if (document.visibilityState === "visible") {
|
|
630
|
-
|
|
660
|
+
const now = Date.now();
|
|
661
|
+
if (this.lastHiddenAt > 0 && (now - this.lastHiddenAt > this.timeout || now - this.sessionStartedAt > this.maxLength)) {
|
|
631
662
|
this.rotateSession("session_timeout");
|
|
632
|
-
} else if (this.lastHiddenAt > 0) {
|
|
633
|
-
this.emitContext("app_foreground");
|
|
634
663
|
}
|
|
635
664
|
this.lastHiddenAt = 0;
|
|
636
665
|
}
|
|
637
666
|
}
|
|
638
667
|
rotateSession(reason) {
|
|
639
668
|
this._sessionId = generateId();
|
|
640
|
-
this.lastActivityAt = Date.now();
|
|
641
|
-
this.emitContext(reason);
|
|
642
|
-
}
|
|
643
|
-
emitContext(reason) {
|
|
644
669
|
const now = Date.now();
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
this.
|
|
670
|
+
this.lastActivityAt = now;
|
|
671
|
+
this.sessionStartedAt = now;
|
|
672
|
+
this.persist();
|
|
648
673
|
this.onNewSession(reason, this._sessionId);
|
|
649
674
|
}
|
|
675
|
+
persist() {
|
|
676
|
+
this.storage.set(SESSION_ID_KEY, this._sessionId);
|
|
677
|
+
this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));
|
|
678
|
+
this.storage.set(SESSION_START_KEY, String(this.sessionStartedAt));
|
|
679
|
+
this.lastPersistedAt = Date.now();
|
|
680
|
+
}
|
|
681
|
+
persistActivity() {
|
|
682
|
+
this.storage.set(SESSION_TS_KEY, String(this.lastActivityAt));
|
|
683
|
+
this.lastPersistedAt = Date.now();
|
|
684
|
+
}
|
|
650
685
|
};
|
|
651
686
|
|
|
652
687
|
// src/transport.ts
|
|
@@ -968,6 +1003,8 @@ var tell = {
|
|
|
968
1003
|
});
|
|
969
1004
|
sessionManager = new SessionManager({
|
|
970
1005
|
timeout: resolvedConfig.sessionTimeout,
|
|
1006
|
+
maxLength: resolvedConfig.maxSessionLength,
|
|
1007
|
+
storage,
|
|
971
1008
|
onNewSession
|
|
972
1009
|
});
|
|
973
1010
|
if (typeof window !== "undefined") {
|
|
@@ -987,7 +1024,7 @@ var tell = {
|
|
|
987
1024
|
if (event.lineno) data.lineno = event.lineno;
|
|
988
1025
|
if (event.colno) data.colno = event.colno;
|
|
989
1026
|
if (event.error?.stack) data.stack = event.error.stack;
|
|
990
|
-
tell.logError(msg,
|
|
1027
|
+
tell.logError(msg, data);
|
|
991
1028
|
};
|
|
992
1029
|
rejectionHandler = (event) => {
|
|
993
1030
|
if (_disabled || _optedOut || closed) return;
|
|
@@ -995,7 +1032,7 @@ var tell = {
|
|
|
995
1032
|
const msg = reason instanceof Error ? reason.message : String(reason ?? "Unhandled promise rejection");
|
|
996
1033
|
const data = {};
|
|
997
1034
|
if (reason instanceof Error && reason.stack) data.stack = reason.stack;
|
|
998
|
-
tell.logError(msg,
|
|
1035
|
+
tell.logError(msg, data);
|
|
999
1036
|
};
|
|
1000
1037
|
window.addEventListener("error", errorHandler);
|
|
1001
1038
|
window.addEventListener("unhandledrejection", rejectionHandler);
|
|
@@ -1188,9 +1225,9 @@ var tell = {
|
|
|
1188
1225
|
// -----------------------------------------------------------------------
|
|
1189
1226
|
// Logging
|
|
1190
1227
|
// -----------------------------------------------------------------------
|
|
1191
|
-
log(level, message,
|
|
1228
|
+
log(level, message, data) {
|
|
1192
1229
|
if (!configured) {
|
|
1193
|
-
queue.push({ method: "log", args: [level, message,
|
|
1230
|
+
queue.push({ method: "log", args: [level, message, data] });
|
|
1194
1231
|
return;
|
|
1195
1232
|
}
|
|
1196
1233
|
if (_disabled || _optedOut) return;
|
|
@@ -1208,7 +1245,7 @@ var tell = {
|
|
|
1208
1245
|
level,
|
|
1209
1246
|
message,
|
|
1210
1247
|
source: resolvedConfig.source,
|
|
1211
|
-
service:
|
|
1248
|
+
service: resolvedService,
|
|
1212
1249
|
session_id: sessionManager.sessionId,
|
|
1213
1250
|
timestamp: Date.now(),
|
|
1214
1251
|
data
|
|
@@ -1219,32 +1256,32 @@ var tell = {
|
|
|
1219
1256
|
}
|
|
1220
1257
|
logBatcher.add(logEntry);
|
|
1221
1258
|
},
|
|
1222
|
-
logEmergency(message,
|
|
1223
|
-
tell.log("emergency", message,
|
|
1259
|
+
logEmergency(message, data) {
|
|
1260
|
+
tell.log("emergency", message, data);
|
|
1224
1261
|
},
|
|
1225
|
-
logAlert(message,
|
|
1226
|
-
tell.log("alert", message,
|
|
1262
|
+
logAlert(message, data) {
|
|
1263
|
+
tell.log("alert", message, data);
|
|
1227
1264
|
},
|
|
1228
|
-
logCritical(message,
|
|
1229
|
-
tell.log("critical", message,
|
|
1265
|
+
logCritical(message, data) {
|
|
1266
|
+
tell.log("critical", message, data);
|
|
1230
1267
|
},
|
|
1231
|
-
logError(message,
|
|
1232
|
-
tell.log("error", message,
|
|
1268
|
+
logError(message, data) {
|
|
1269
|
+
tell.log("error", message, data);
|
|
1233
1270
|
},
|
|
1234
|
-
logWarning(message,
|
|
1235
|
-
tell.log("warning", message,
|
|
1271
|
+
logWarning(message, data) {
|
|
1272
|
+
tell.log("warning", message, data);
|
|
1236
1273
|
},
|
|
1237
|
-
logNotice(message,
|
|
1238
|
-
tell.log("notice", message,
|
|
1274
|
+
logNotice(message, data) {
|
|
1275
|
+
tell.log("notice", message, data);
|
|
1239
1276
|
},
|
|
1240
|
-
logInfo(message,
|
|
1241
|
-
tell.log("info", message,
|
|
1277
|
+
logInfo(message, data) {
|
|
1278
|
+
tell.log("info", message, data);
|
|
1242
1279
|
},
|
|
1243
|
-
logDebug(message,
|
|
1244
|
-
tell.log("debug", message,
|
|
1280
|
+
logDebug(message, data) {
|
|
1281
|
+
tell.log("debug", message, data);
|
|
1245
1282
|
},
|
|
1246
|
-
logTrace(message,
|
|
1247
|
-
tell.log("trace", message,
|
|
1283
|
+
logTrace(message, data) {
|
|
1284
|
+
tell.log("trace", message, data);
|
|
1248
1285
|
},
|
|
1249
1286
|
// -----------------------------------------------------------------------
|
|
1250
1287
|
// Super Properties
|