@logspace/sdk 1.1.4 → 1.1.7
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/logspace.esm.js +48 -4
- package/logspace.esm.js.map +1 -1
- package/logspace.iife.js +1 -1
- package/logspace.iife.js.map +1 -1
- package/logspace.umd.js +1 -1
- package/logspace.umd.js.map +1 -1
- package/package.json +1 -1
- package/sdk/types.d.ts +2 -2
package/logspace.esm.js
CHANGED
|
@@ -14524,6 +14524,10 @@ let rateLimiter = { count: 0, windowStart: 0 };
|
|
|
14524
14524
|
let deduplication = { lastLogHash: null, lastLogCount: 0 };
|
|
14525
14525
|
let currentSize = 0;
|
|
14526
14526
|
let rrwebSize = 0;
|
|
14527
|
+
let lastRateLimitWarningTime = 0;
|
|
14528
|
+
const RATE_LIMIT_WARNING_THROTTLE_MS = 1e3;
|
|
14529
|
+
let rrwebRateLimiter = { count: 0, windowStart: 0 };
|
|
14530
|
+
const RRWEB_RATE_LIMIT = 500;
|
|
14527
14531
|
let idleTimer = null;
|
|
14528
14532
|
let durationTimer = null;
|
|
14529
14533
|
let checkpointTimer = null;
|
|
@@ -14751,7 +14755,11 @@ function checkRateLimit() {
|
|
|
14751
14755
|
rateLimiter.count++;
|
|
14752
14756
|
if (rateLimiter.count > config.limits.rateLimit) {
|
|
14753
14757
|
if (config.debug) {
|
|
14754
|
-
|
|
14758
|
+
const now2 = Date.now();
|
|
14759
|
+
if (now2 - lastRateLimitWarningTime >= RATE_LIMIT_WARNING_THROTTLE_MS) {
|
|
14760
|
+
lastRateLimitWarningTime = now2;
|
|
14761
|
+
console.warn("[LogSpace] Rate limit exceeded, dropping log");
|
|
14762
|
+
}
|
|
14755
14763
|
}
|
|
14756
14764
|
return false;
|
|
14757
14765
|
}
|
|
@@ -15497,13 +15505,21 @@ async function sendPayload(payload) {
|
|
|
15497
15505
|
const type = log.type || "unknown";
|
|
15498
15506
|
logsByType[type] = (logsByType[type] || 0) + 1;
|
|
15499
15507
|
}
|
|
15508
|
+
let rrwebDuration = payload.duration;
|
|
15509
|
+
if (payload.rrwebEvents && payload.rrwebEvents.length > 0) {
|
|
15510
|
+
const timestamps = payload.rrwebEvents.map((e) => e.timestamp);
|
|
15511
|
+
const minTs = Math.min(...timestamps);
|
|
15512
|
+
const maxTs = Math.max(...timestamps);
|
|
15513
|
+
rrwebDuration = maxTs - minTs;
|
|
15514
|
+
}
|
|
15500
15515
|
const metadata = {
|
|
15501
15516
|
totalLogs: payload.logs.length,
|
|
15502
15517
|
logsByType,
|
|
15503
15518
|
videoSize: 0,
|
|
15504
15519
|
// SDK uses rrweb, not video
|
|
15505
15520
|
videoType: "rrweb",
|
|
15506
|
-
videoDuration:
|
|
15521
|
+
videoDuration: rrwebDuration,
|
|
15522
|
+
// Use actual rrweb duration, not session wall-clock time
|
|
15507
15523
|
userAgent: payload.userAgent,
|
|
15508
15524
|
timestamp: payload.startTime,
|
|
15509
15525
|
// Use actual session start time for correct video seek calculation
|
|
@@ -15512,6 +15528,7 @@ async function sendPayload(payload) {
|
|
|
15512
15528
|
userId: payload.userId,
|
|
15513
15529
|
userTraits: payload.userTraits,
|
|
15514
15530
|
duration: payload.duration,
|
|
15531
|
+
// Keep session wall-clock duration for reference
|
|
15515
15532
|
stats: payload.stats
|
|
15516
15533
|
};
|
|
15517
15534
|
formData.append("log_metadata", JSON.stringify(metadata));
|
|
@@ -15565,12 +15582,20 @@ async function sendPayloadToServer(payload) {
|
|
|
15565
15582
|
const type = log.type || "unknown";
|
|
15566
15583
|
logsByType[type] = (logsByType[type] || 0) + 1;
|
|
15567
15584
|
}
|
|
15585
|
+
let rrwebDuration = payload.duration;
|
|
15586
|
+
if (payload.rrwebEvents && payload.rrwebEvents.length > 0) {
|
|
15587
|
+
const timestamps = payload.rrwebEvents.map((e) => e.timestamp);
|
|
15588
|
+
const minTs = Math.min(...timestamps);
|
|
15589
|
+
const maxTs = Math.max(...timestamps);
|
|
15590
|
+
rrwebDuration = maxTs - minTs;
|
|
15591
|
+
}
|
|
15568
15592
|
const metadata = {
|
|
15569
15593
|
totalLogs: payload.logs.length,
|
|
15570
15594
|
logsByType,
|
|
15571
15595
|
videoSize: 0,
|
|
15572
15596
|
videoType: "rrweb",
|
|
15573
|
-
videoDuration:
|
|
15597
|
+
videoDuration: rrwebDuration,
|
|
15598
|
+
// Use actual rrweb duration, not session wall-clock time
|
|
15574
15599
|
userAgent: payload.userAgent,
|
|
15575
15600
|
timestamp: payload.startTime,
|
|
15576
15601
|
// Use actual session start time for correct video seek calculation
|
|
@@ -15581,6 +15606,7 @@ async function sendPayloadToServer(payload) {
|
|
|
15581
15606
|
userId: payload.userId,
|
|
15582
15607
|
userTraits: payload.userTraits,
|
|
15583
15608
|
duration: payload.duration,
|
|
15609
|
+
// Keep session wall-clock duration for reference
|
|
15584
15610
|
stats: payload.stats
|
|
15585
15611
|
};
|
|
15586
15612
|
formData.append("log_metadata", JSON.stringify(metadata));
|
|
@@ -15670,6 +15696,12 @@ function mergeRecoveredData(recoveredLogs, recoveredEvents) {
|
|
|
15670
15696
|
for (const event of newEvents) {
|
|
15671
15697
|
rrwebSize += JSON.stringify(event).length;
|
|
15672
15698
|
}
|
|
15699
|
+
if (config?.sampling.enabled && samplingTrimTimer) {
|
|
15700
|
+
stopSamplingTrimTimer();
|
|
15701
|
+
if (config?.debug) {
|
|
15702
|
+
console.log("[LogSpace] Stopped sampling trim timer to preserve recovered rrweb events");
|
|
15703
|
+
}
|
|
15704
|
+
}
|
|
15673
15705
|
if (config?.debug) {
|
|
15674
15706
|
console.log(
|
|
15675
15707
|
`[LogSpace] Merged ${newEvents.length} recovered rrweb events (${recoveredEvents.length - newEvents.length} duplicates skipped)`
|
|
@@ -15928,6 +15960,8 @@ const LogSpace = {
|
|
|
15928
15960
|
currentSize = 0;
|
|
15929
15961
|
rrwebSize = 0;
|
|
15930
15962
|
rateLimiter = { count: 0, windowStart: 0 };
|
|
15963
|
+
rrwebRateLimiter = { count: 0, windowStart: 0 };
|
|
15964
|
+
lastRateLimitWarningTime = 0;
|
|
15931
15965
|
deduplication = { lastLogHash: null, lastLogCount: 0 };
|
|
15932
15966
|
endReason = "manual";
|
|
15933
15967
|
let sessionId;
|
|
@@ -15995,7 +16029,17 @@ const LogSpace = {
|
|
|
15995
16029
|
},
|
|
15996
16030
|
(event) => {
|
|
15997
16031
|
if (!session || session.status !== "recording") return;
|
|
15998
|
-
const
|
|
16032
|
+
const now = Date.now();
|
|
16033
|
+
if (now - rrwebRateLimiter.windowStart > 1e3) {
|
|
16034
|
+
rrwebRateLimiter.windowStart = now;
|
|
16035
|
+
rrwebRateLimiter.count = 1;
|
|
16036
|
+
} else {
|
|
16037
|
+
rrwebRateLimiter.count++;
|
|
16038
|
+
if (rrwebRateLimiter.count > RRWEB_RATE_LIMIT) {
|
|
16039
|
+
return;
|
|
16040
|
+
}
|
|
16041
|
+
}
|
|
16042
|
+
const eventSize = event.type === 2 ? 5e4 : 500;
|
|
15999
16043
|
rrwebSize += eventSize;
|
|
16000
16044
|
const totalSize = currentSize + rrwebSize;
|
|
16001
16045
|
if (config && totalSize >= config.limits.maxSize) {
|