@dataxamas/tracker-js 2.3.0 → 2.4.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.
- package/README.md +2 -2
- package/dist/index.cjs +11 -53
- package/dist/index.d.cts +2 -9
- package/dist/index.d.ts +2 -9
- package/dist/index.js +11 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,7 +201,7 @@ Begin collecting. Waits for `DOMContentLoaded` if the document is still loading,
|
|
|
201
201
|
- **`CLICK`** — element `tagName`, `text`, `href`, `id`, `classes`, plus heat-map coordinates (viewport ratios, scroll offsets, layout fingerprint) when `heatMapEnabled`.
|
|
202
202
|
- **`SCROLL`** — scroll-depth percentage (debounced).
|
|
203
203
|
|
|
204
|
-
Events are queued and flushed to `POST /api/v1/events` with a 4s spacing. Every request sends `Authorization: Bearer <apiKey>`. The key is visible to anyone who opens the page, and it can also read events through `GET /api/v1/events` — treat it as public and rotate it from the dashboard if abused.
|
|
204
|
+
Events are queued and flushed to `POST /api/v1/events` with a 4s spacing. Every request sends `Authorization: Bearer <apiKey>`. The key is visible to anyone who opens the page, and it can also read events through `GET /api/v1/events` — treat it as public and rotate it from the dashboard if abused. Nothing is stored in the browser to identify the visitor: the server derives the session id from `sha256(daily salt + IP + user agent + websiteId)`, and the salt is replaced every day.
|
|
205
205
|
|
|
206
206
|
If `replayEnabled` is on and the server config allows it, session replay starts: `rrweb` is lazy-imported and recordings are sent to `POST /api/v1/replay`.
|
|
207
207
|
|
|
@@ -250,7 +250,7 @@ Exported for use in your own typings:
|
|
|
250
250
|
## Notes
|
|
251
251
|
|
|
252
252
|
- **Default endpoint:** `https://dataxamas.com`. Override with `baseUrl`.
|
|
253
|
-
- **
|
|
253
|
+
- **Visitor identity:** computed server-side, no cookies or `localStorage`. Only replay touches the browser, in `sessionStorage["@dataxamas/replay-recording"]`, and only for sampled visitors.
|
|
254
254
|
- **Event flush spacing:** 4 seconds between queued analytics events.
|
|
255
255
|
- **Replay masking classes:** `dx-mask` (text) and `dx-block` (element); all inputs masked by default.
|
|
256
256
|
- **Bundle:** `rrweb` is bundled but split into its own async chunk, loaded only when replay starts — the server/import path never touches it.
|
package/dist/index.cjs
CHANGED
|
@@ -328,7 +328,7 @@ var REPLAY_RECORDING_KEY = `${STORAGE_PREFIX}/replay-recording`;
|
|
|
328
328
|
function isStoredRecording(value) {
|
|
329
329
|
if (typeof value !== "object" || value === null) return false;
|
|
330
330
|
const stored = value;
|
|
331
|
-
return typeof stored.id === "string" && typeof stored.
|
|
331
|
+
return typeof stored.id === "string" && typeof stored.startedAt === "string" && typeof stored.startedAtMs === "number" && typeof stored.seq === "number" && typeof stored.events === "number" && typeof stored.lastActivityAt === "number" && typeof stored.capped === "boolean";
|
|
332
332
|
}
|
|
333
333
|
var KEEPALIVE_LIMIT_BYTES = 60 * 1024;
|
|
334
334
|
var DataxamasTracking = class {
|
|
@@ -356,14 +356,14 @@ var DataxamasTracking = class {
|
|
|
356
356
|
this.apiKey = options.apiKey;
|
|
357
357
|
this.baseUrl = _nullishCoalesce(options.baseUrl, () => ( BASE_URL));
|
|
358
358
|
this.allowLocalhost = _nullishCoalesce(options.allowLocalhost, () => ( false));
|
|
359
|
-
this.
|
|
359
|
+
this.started = false;
|
|
360
360
|
this.currentPage = isBrowser() ? window.location.pathname : "";
|
|
361
361
|
this.heatMapEnabled = _nullishCoalesce(options.heatMapEnabled, () => ( true));
|
|
362
362
|
this.replayEnabled = _nullishCoalesce(options.replayEnabled, () => ( true));
|
|
363
363
|
this.webVitalsEnabled = _nullishCoalesce(options.webVitalsEnabled, () => ( true));
|
|
364
364
|
this.pendingVitals = /* @__PURE__ */ new Map();
|
|
365
365
|
this.vitalsPath = "";
|
|
366
|
-
this.
|
|
366
|
+
this.replaySampled = false;
|
|
367
367
|
this.eventQueue = [];
|
|
368
368
|
this.isProcessing = false;
|
|
369
369
|
this.rrwebRecord = null;
|
|
@@ -386,21 +386,6 @@ var DataxamasTracking = class {
|
|
|
386
386
|
isLocalhost() {
|
|
387
387
|
return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
388
388
|
}
|
|
389
|
-
getSessionId() {
|
|
390
|
-
try {
|
|
391
|
-
return window.localStorage.getItem(`${STORAGE_PREFIX}/session`);
|
|
392
|
-
} catch (_) {
|
|
393
|
-
return null;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
createSessionId() {
|
|
397
|
-
const id = crypto.randomUUID();
|
|
398
|
-
try {
|
|
399
|
-
window.localStorage.setItem(`${STORAGE_PREFIX}/session`, id);
|
|
400
|
-
} catch (_) {
|
|
401
|
-
}
|
|
402
|
-
return id;
|
|
403
|
-
}
|
|
404
389
|
async processQueue() {
|
|
405
390
|
if (this.isProcessing || this.eventQueue.length === 0) return;
|
|
406
391
|
this.isProcessing = true;
|
|
@@ -436,13 +421,12 @@ var DataxamasTracking = class {
|
|
|
436
421
|
path = this.currentPage,
|
|
437
422
|
data = {}
|
|
438
423
|
}) {
|
|
439
|
-
if (!this.
|
|
424
|
+
if (!this.started) return;
|
|
440
425
|
this.eventQueue.push({
|
|
441
426
|
name,
|
|
442
427
|
path,
|
|
443
428
|
referrer: document.referrer,
|
|
444
429
|
query: name === "PAGE_VIEW" ? this.utmQuery() : void 0,
|
|
445
|
-
sessionId: this.sessionId,
|
|
446
430
|
data
|
|
447
431
|
});
|
|
448
432
|
await this.processQueue();
|
|
@@ -468,9 +452,7 @@ var DataxamasTracking = class {
|
|
|
468
452
|
const cfg = await res.json();
|
|
469
453
|
if (typeof cfg.heatMapEnabled === "boolean") this.heatMapEnabled = cfg.heatMapEnabled;
|
|
470
454
|
if (typeof cfg.replayEnabled === "boolean") this.replayEnabled = cfg.replayEnabled;
|
|
471
|
-
if (typeof cfg.
|
|
472
|
-
this.replaySampleRate = cfg.replaySampleRate;
|
|
473
|
-
}
|
|
455
|
+
if (typeof cfg.replaySampled === "boolean") this.replaySampled = cfg.replaySampled;
|
|
474
456
|
} catch (_) {
|
|
475
457
|
}
|
|
476
458
|
}
|
|
@@ -551,14 +533,13 @@ var DataxamasTracking = class {
|
|
|
551
533
|
});
|
|
552
534
|
}
|
|
553
535
|
flushVitals() {
|
|
554
|
-
if (
|
|
536
|
+
if (this.pendingVitals.size === 0) return;
|
|
555
537
|
const metrics = Array.from(this.pendingVitals.values());
|
|
556
538
|
this.pendingVitals.clear();
|
|
557
539
|
window.fetch(`${this.baseUrl}/api/v1/vitals`, {
|
|
558
540
|
method: "POST",
|
|
559
541
|
headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
|
|
560
542
|
body: JSON.stringify({
|
|
561
|
-
sessionId: this.sessionId,
|
|
562
543
|
path: this.vitalsPath,
|
|
563
544
|
viewportWidth: window.innerWidth,
|
|
564
545
|
metrics
|
|
@@ -602,27 +583,6 @@ var DataxamasTracking = class {
|
|
|
602
583
|
const layoutFingerprint = `${this.currentPage}:${Math.round(pageWidth / 100)}x${Math.round(pageHeight / 100)}`;
|
|
603
584
|
return { viewportWidth, viewportHeight, pageWidth, pageHeight, layoutFingerprint };
|
|
604
585
|
}
|
|
605
|
-
/**
|
|
606
|
-
* Sorteio por visitante, não por gravação: quem entrou no sorteio tem a sessão inteira, em vez
|
|
607
|
-
* de um replay picotado que não dá para assistir.
|
|
608
|
-
*/
|
|
609
|
-
isReplaySampled() {
|
|
610
|
-
const rate = this.replaySampleRate;
|
|
611
|
-
if (rate >= 1) return true;
|
|
612
|
-
if (rate <= 0) return false;
|
|
613
|
-
const key = `${STORAGE_PREFIX}/replay-sample`;
|
|
614
|
-
try {
|
|
615
|
-
const [storedRate, storedDecision] = (_nullishCoalesce(window.localStorage.getItem(key), () => ( ""))).split(":");
|
|
616
|
-
if (Number(storedRate) === rate && (storedDecision === "1" || storedDecision === "0")) {
|
|
617
|
-
return storedDecision === "1";
|
|
618
|
-
}
|
|
619
|
-
const sampled = Math.random() < rate;
|
|
620
|
-
window.localStorage.setItem(key, `${rate}:${sampled ? "1" : "0"}`);
|
|
621
|
-
return sampled;
|
|
622
|
-
} catch (_) {
|
|
623
|
-
return Math.random() < rate;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
586
|
isRecording() {
|
|
627
587
|
return Boolean(this.stopRrweb);
|
|
628
588
|
}
|
|
@@ -638,10 +598,9 @@ var DataxamasTracking = class {
|
|
|
638
598
|
}
|
|
639
599
|
}
|
|
640
600
|
saveRecording() {
|
|
641
|
-
if (!this.
|
|
601
|
+
if (!this.recordingId || !this.recordingStartedAt) return;
|
|
642
602
|
const stored = {
|
|
643
603
|
id: this.recordingId,
|
|
644
|
-
sessionId: this.sessionId,
|
|
645
604
|
startedAt: this.recordingStartedAt,
|
|
646
605
|
startedAtMs: this.recordingStartedAtMs,
|
|
647
606
|
seq: this.recordingSeq,
|
|
@@ -667,7 +626,7 @@ var DataxamasTracking = class {
|
|
|
667
626
|
/** Reload ou navegação completa na mesma aba continua a gravação, se a visita ainda estiver ativa. */
|
|
668
627
|
resumeOrRotateRecording() {
|
|
669
628
|
const stored = this.loadRecording();
|
|
670
|
-
if (!stored || stored.capped ||
|
|
629
|
+
if (!stored || stored.capped || Date.now() - stored.lastActivityAt >= REPLAY_IDLE_TIMEOUT_MS) {
|
|
671
630
|
this.rotateRecording();
|
|
672
631
|
return;
|
|
673
632
|
}
|
|
@@ -690,7 +649,6 @@ var DataxamasTracking = class {
|
|
|
690
649
|
const events = this.replayBuffer;
|
|
691
650
|
this.replayBuffer = [];
|
|
692
651
|
const payload = JSON.stringify({
|
|
693
|
-
sessionId: this.sessionId,
|
|
694
652
|
recordingId: this.recordingId,
|
|
695
653
|
path: this.currentPage,
|
|
696
654
|
startedAt: this.recordingStartedAt,
|
|
@@ -839,15 +797,15 @@ var DataxamasTracking = class {
|
|
|
839
797
|
});
|
|
840
798
|
}
|
|
841
799
|
startTracking() {
|
|
842
|
-
this.
|
|
843
|
-
this.resumeOrRotateRecording();
|
|
800
|
+
this.started = true;
|
|
844
801
|
this.sendEvent({ name: "PAGE_VIEW" });
|
|
845
802
|
this.trackPageChanges();
|
|
846
803
|
this.trackClicks();
|
|
847
804
|
this.trackScroll();
|
|
848
805
|
this.trackWebVitals();
|
|
849
806
|
this.fetchWebsiteConfig().then(() => {
|
|
850
|
-
if (!this.replayEnabled || !this.
|
|
807
|
+
if (!this.replayEnabled || !this.replaySampled) return;
|
|
808
|
+
this.resumeOrRotateRecording();
|
|
851
809
|
this.setupReplayLifecycle();
|
|
852
810
|
});
|
|
853
811
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -109,14 +109,14 @@ declare class DataxamasTracking {
|
|
|
109
109
|
private apiKey;
|
|
110
110
|
private baseUrl;
|
|
111
111
|
private allowLocalhost;
|
|
112
|
-
private
|
|
112
|
+
private started;
|
|
113
113
|
private currentPage;
|
|
114
114
|
private heatMapEnabled;
|
|
115
115
|
private replayEnabled;
|
|
116
116
|
private webVitalsEnabled;
|
|
117
117
|
private pendingVitals;
|
|
118
118
|
private vitalsPath;
|
|
119
|
-
private
|
|
119
|
+
private replaySampled;
|
|
120
120
|
private eventQueue;
|
|
121
121
|
private isProcessing;
|
|
122
122
|
private rrwebRecord;
|
|
@@ -137,8 +137,6 @@ declare class DataxamasTracking {
|
|
|
137
137
|
private lastActivitySavedAt;
|
|
138
138
|
constructor(options: DataxamasTrackingOptions);
|
|
139
139
|
private isLocalhost;
|
|
140
|
-
private getSessionId;
|
|
141
|
-
private createSessionId;
|
|
142
140
|
private processQueue;
|
|
143
141
|
private utmQuery;
|
|
144
142
|
private sendEvent;
|
|
@@ -153,11 +151,6 @@ declare class DataxamasTracking {
|
|
|
153
151
|
private flushVitals;
|
|
154
152
|
private trackWebVitals;
|
|
155
153
|
private measureReplay;
|
|
156
|
-
/**
|
|
157
|
-
* Sorteio por visitante, não por gravação: quem entrou no sorteio tem a sessão inteira, em vez
|
|
158
|
-
* de um replay picotado que não dá para assistir.
|
|
159
|
-
*/
|
|
160
|
-
private isReplaySampled;
|
|
161
154
|
private isRecording;
|
|
162
155
|
private exceededReplayCaps;
|
|
163
156
|
private loadRecording;
|
package/dist/index.d.ts
CHANGED
|
@@ -109,14 +109,14 @@ declare class DataxamasTracking {
|
|
|
109
109
|
private apiKey;
|
|
110
110
|
private baseUrl;
|
|
111
111
|
private allowLocalhost;
|
|
112
|
-
private
|
|
112
|
+
private started;
|
|
113
113
|
private currentPage;
|
|
114
114
|
private heatMapEnabled;
|
|
115
115
|
private replayEnabled;
|
|
116
116
|
private webVitalsEnabled;
|
|
117
117
|
private pendingVitals;
|
|
118
118
|
private vitalsPath;
|
|
119
|
-
private
|
|
119
|
+
private replaySampled;
|
|
120
120
|
private eventQueue;
|
|
121
121
|
private isProcessing;
|
|
122
122
|
private rrwebRecord;
|
|
@@ -137,8 +137,6 @@ declare class DataxamasTracking {
|
|
|
137
137
|
private lastActivitySavedAt;
|
|
138
138
|
constructor(options: DataxamasTrackingOptions);
|
|
139
139
|
private isLocalhost;
|
|
140
|
-
private getSessionId;
|
|
141
|
-
private createSessionId;
|
|
142
140
|
private processQueue;
|
|
143
141
|
private utmQuery;
|
|
144
142
|
private sendEvent;
|
|
@@ -153,11 +151,6 @@ declare class DataxamasTracking {
|
|
|
153
151
|
private flushVitals;
|
|
154
152
|
private trackWebVitals;
|
|
155
153
|
private measureReplay;
|
|
156
|
-
/**
|
|
157
|
-
* Sorteio por visitante, não por gravação: quem entrou no sorteio tem a sessão inteira, em vez
|
|
158
|
-
* de um replay picotado que não dá para assistir.
|
|
159
|
-
*/
|
|
160
|
-
private isReplaySampled;
|
|
161
154
|
private isRecording;
|
|
162
155
|
private exceededReplayCaps;
|
|
163
156
|
private loadRecording;
|
package/dist/index.js
CHANGED
|
@@ -328,7 +328,7 @@ var REPLAY_RECORDING_KEY = `${STORAGE_PREFIX}/replay-recording`;
|
|
|
328
328
|
function isStoredRecording(value) {
|
|
329
329
|
if (typeof value !== "object" || value === null) return false;
|
|
330
330
|
const stored = value;
|
|
331
|
-
return typeof stored.id === "string" && typeof stored.
|
|
331
|
+
return typeof stored.id === "string" && typeof stored.startedAt === "string" && typeof stored.startedAtMs === "number" && typeof stored.seq === "number" && typeof stored.events === "number" && typeof stored.lastActivityAt === "number" && typeof stored.capped === "boolean";
|
|
332
332
|
}
|
|
333
333
|
var KEEPALIVE_LIMIT_BYTES = 60 * 1024;
|
|
334
334
|
var DataxamasTracking = class {
|
|
@@ -356,14 +356,14 @@ var DataxamasTracking = class {
|
|
|
356
356
|
this.apiKey = options.apiKey;
|
|
357
357
|
this.baseUrl = options.baseUrl ?? BASE_URL;
|
|
358
358
|
this.allowLocalhost = options.allowLocalhost ?? false;
|
|
359
|
-
this.
|
|
359
|
+
this.started = false;
|
|
360
360
|
this.currentPage = isBrowser() ? window.location.pathname : "";
|
|
361
361
|
this.heatMapEnabled = options.heatMapEnabled ?? true;
|
|
362
362
|
this.replayEnabled = options.replayEnabled ?? true;
|
|
363
363
|
this.webVitalsEnabled = options.webVitalsEnabled ?? true;
|
|
364
364
|
this.pendingVitals = /* @__PURE__ */ new Map();
|
|
365
365
|
this.vitalsPath = "";
|
|
366
|
-
this.
|
|
366
|
+
this.replaySampled = false;
|
|
367
367
|
this.eventQueue = [];
|
|
368
368
|
this.isProcessing = false;
|
|
369
369
|
this.rrwebRecord = null;
|
|
@@ -386,21 +386,6 @@ var DataxamasTracking = class {
|
|
|
386
386
|
isLocalhost() {
|
|
387
387
|
return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
388
388
|
}
|
|
389
|
-
getSessionId() {
|
|
390
|
-
try {
|
|
391
|
-
return window.localStorage.getItem(`${STORAGE_PREFIX}/session`);
|
|
392
|
-
} catch (_) {
|
|
393
|
-
return null;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
createSessionId() {
|
|
397
|
-
const id = crypto.randomUUID();
|
|
398
|
-
try {
|
|
399
|
-
window.localStorage.setItem(`${STORAGE_PREFIX}/session`, id);
|
|
400
|
-
} catch (_) {
|
|
401
|
-
}
|
|
402
|
-
return id;
|
|
403
|
-
}
|
|
404
389
|
async processQueue() {
|
|
405
390
|
if (this.isProcessing || this.eventQueue.length === 0) return;
|
|
406
391
|
this.isProcessing = true;
|
|
@@ -436,13 +421,12 @@ var DataxamasTracking = class {
|
|
|
436
421
|
path = this.currentPage,
|
|
437
422
|
data = {}
|
|
438
423
|
}) {
|
|
439
|
-
if (!this.
|
|
424
|
+
if (!this.started) return;
|
|
440
425
|
this.eventQueue.push({
|
|
441
426
|
name,
|
|
442
427
|
path,
|
|
443
428
|
referrer: document.referrer,
|
|
444
429
|
query: name === "PAGE_VIEW" ? this.utmQuery() : void 0,
|
|
445
|
-
sessionId: this.sessionId,
|
|
446
430
|
data
|
|
447
431
|
});
|
|
448
432
|
await this.processQueue();
|
|
@@ -468,9 +452,7 @@ var DataxamasTracking = class {
|
|
|
468
452
|
const cfg = await res.json();
|
|
469
453
|
if (typeof cfg.heatMapEnabled === "boolean") this.heatMapEnabled = cfg.heatMapEnabled;
|
|
470
454
|
if (typeof cfg.replayEnabled === "boolean") this.replayEnabled = cfg.replayEnabled;
|
|
471
|
-
if (typeof cfg.
|
|
472
|
-
this.replaySampleRate = cfg.replaySampleRate;
|
|
473
|
-
}
|
|
455
|
+
if (typeof cfg.replaySampled === "boolean") this.replaySampled = cfg.replaySampled;
|
|
474
456
|
} catch (_) {
|
|
475
457
|
}
|
|
476
458
|
}
|
|
@@ -551,14 +533,13 @@ var DataxamasTracking = class {
|
|
|
551
533
|
});
|
|
552
534
|
}
|
|
553
535
|
flushVitals() {
|
|
554
|
-
if (
|
|
536
|
+
if (this.pendingVitals.size === 0) return;
|
|
555
537
|
const metrics = Array.from(this.pendingVitals.values());
|
|
556
538
|
this.pendingVitals.clear();
|
|
557
539
|
window.fetch(`${this.baseUrl}/api/v1/vitals`, {
|
|
558
540
|
method: "POST",
|
|
559
541
|
headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
|
|
560
542
|
body: JSON.stringify({
|
|
561
|
-
sessionId: this.sessionId,
|
|
562
543
|
path: this.vitalsPath,
|
|
563
544
|
viewportWidth: window.innerWidth,
|
|
564
545
|
metrics
|
|
@@ -602,27 +583,6 @@ var DataxamasTracking = class {
|
|
|
602
583
|
const layoutFingerprint = `${this.currentPage}:${Math.round(pageWidth / 100)}x${Math.round(pageHeight / 100)}`;
|
|
603
584
|
return { viewportWidth, viewportHeight, pageWidth, pageHeight, layoutFingerprint };
|
|
604
585
|
}
|
|
605
|
-
/**
|
|
606
|
-
* Sorteio por visitante, não por gravação: quem entrou no sorteio tem a sessão inteira, em vez
|
|
607
|
-
* de um replay picotado que não dá para assistir.
|
|
608
|
-
*/
|
|
609
|
-
isReplaySampled() {
|
|
610
|
-
const rate = this.replaySampleRate;
|
|
611
|
-
if (rate >= 1) return true;
|
|
612
|
-
if (rate <= 0) return false;
|
|
613
|
-
const key = `${STORAGE_PREFIX}/replay-sample`;
|
|
614
|
-
try {
|
|
615
|
-
const [storedRate, storedDecision] = (window.localStorage.getItem(key) ?? "").split(":");
|
|
616
|
-
if (Number(storedRate) === rate && (storedDecision === "1" || storedDecision === "0")) {
|
|
617
|
-
return storedDecision === "1";
|
|
618
|
-
}
|
|
619
|
-
const sampled = Math.random() < rate;
|
|
620
|
-
window.localStorage.setItem(key, `${rate}:${sampled ? "1" : "0"}`);
|
|
621
|
-
return sampled;
|
|
622
|
-
} catch (_) {
|
|
623
|
-
return Math.random() < rate;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
586
|
isRecording() {
|
|
627
587
|
return Boolean(this.stopRrweb);
|
|
628
588
|
}
|
|
@@ -638,10 +598,9 @@ var DataxamasTracking = class {
|
|
|
638
598
|
}
|
|
639
599
|
}
|
|
640
600
|
saveRecording() {
|
|
641
|
-
if (!this.
|
|
601
|
+
if (!this.recordingId || !this.recordingStartedAt) return;
|
|
642
602
|
const stored = {
|
|
643
603
|
id: this.recordingId,
|
|
644
|
-
sessionId: this.sessionId,
|
|
645
604
|
startedAt: this.recordingStartedAt,
|
|
646
605
|
startedAtMs: this.recordingStartedAtMs,
|
|
647
606
|
seq: this.recordingSeq,
|
|
@@ -667,7 +626,7 @@ var DataxamasTracking = class {
|
|
|
667
626
|
/** Reload ou navegação completa na mesma aba continua a gravação, se a visita ainda estiver ativa. */
|
|
668
627
|
resumeOrRotateRecording() {
|
|
669
628
|
const stored = this.loadRecording();
|
|
670
|
-
if (!stored || stored.capped ||
|
|
629
|
+
if (!stored || stored.capped || Date.now() - stored.lastActivityAt >= REPLAY_IDLE_TIMEOUT_MS) {
|
|
671
630
|
this.rotateRecording();
|
|
672
631
|
return;
|
|
673
632
|
}
|
|
@@ -690,7 +649,6 @@ var DataxamasTracking = class {
|
|
|
690
649
|
const events = this.replayBuffer;
|
|
691
650
|
this.replayBuffer = [];
|
|
692
651
|
const payload = JSON.stringify({
|
|
693
|
-
sessionId: this.sessionId,
|
|
694
652
|
recordingId: this.recordingId,
|
|
695
653
|
path: this.currentPage,
|
|
696
654
|
startedAt: this.recordingStartedAt,
|
|
@@ -839,15 +797,15 @@ var DataxamasTracking = class {
|
|
|
839
797
|
});
|
|
840
798
|
}
|
|
841
799
|
startTracking() {
|
|
842
|
-
this.
|
|
843
|
-
this.resumeOrRotateRecording();
|
|
800
|
+
this.started = true;
|
|
844
801
|
this.sendEvent({ name: "PAGE_VIEW" });
|
|
845
802
|
this.trackPageChanges();
|
|
846
803
|
this.trackClicks();
|
|
847
804
|
this.trackScroll();
|
|
848
805
|
this.trackWebVitals();
|
|
849
806
|
this.fetchWebsiteConfig().then(() => {
|
|
850
|
-
if (!this.replayEnabled || !this.
|
|
807
|
+
if (!this.replayEnabled || !this.replaySampled) return;
|
|
808
|
+
this.resumeOrRotateRecording();
|
|
851
809
|
this.setupReplayLifecycle();
|
|
852
810
|
});
|
|
853
811
|
}
|