@glimt/record 0.0.71 → 0.0.73

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/dist/record.cjs CHANGED
@@ -10281,52 +10281,6 @@ const debugLog = (...args) => {
10281
10281
  if (!isDebug()) return;
10282
10282
  console.log("[recapt:rrweb]", ...args);
10283
10283
  };
10284
- const _StormSnapshotManager = class _StormSnapshotManager2 {
10285
- constructor() {
10286
- __publicField(this, "lastFullSnapshot", -1);
10287
- __publicField(this, "intervalBetweenSnapshots", 150);
10288
- __publicField(this, "debounceTimeout", null);
10289
- __publicField(this, "debounceTime", 10);
10290
- if (_StormSnapshotManager2.instance) {
10291
- return _StormSnapshotManager2.instance;
10292
- }
10293
- _StormSnapshotManager2.instance = this;
10294
- }
10295
- //we're debouncing here because of how mutation buffers work.
10296
- //multiple observers create their own mutation buffer, and
10297
- //each buffer will handle mutations storms, so multiple buffers
10298
- //will probably request a full snapshot at (basically) the same time.
10299
- //we want to ensure all buffers have requested a full snapshot
10300
- //(so we can be sure that all mutations have been made)
10301
- //before we actually take a full snapshot.
10302
- //also, we want a low debounceTime, bc if theres multiple, distinctive mutation storms,
10303
- //in a somewhat quick succession, we want to record activity between them
10304
- //not just one full snapshot after all the storms:
10305
- //[mutation storm] [full snapshot] [mutation storm] [full snapshot]
10306
- //NOT
10307
- //[mutation storm] [timeout] [mutation storm] [full snapshot] (in this case, we probably miss all events which fired during the timeout)
10308
- requestFullSnapshot() {
10309
- if (this.debounceTimeout) {
10310
- clearTimeout(this.debounceTimeout);
10311
- }
10312
- this.debounceTimeout = setTimeout(() => {
10313
- this.debounceTimeout = null;
10314
- this.takeSnapshot();
10315
- }, this.debounceTime);
10316
- }
10317
- takeSnapshot() {
10318
- if (Date.now() - this.lastFullSnapshot < this.intervalBetweenSnapshots) {
10319
- debugLog("StormSnapshotManager, takeSnapshot: too soon");
10320
- return;
10321
- }
10322
- debugLog("StormSnapshotManager, takeSnapshot: taking full snapshot");
10323
- takeFullSnapshot();
10324
- this.lastFullSnapshot = Date.now();
10325
- }
10326
- };
10327
- __publicField(_StormSnapshotManager, "instance");
10328
- let StormSnapshotManager = _StormSnapshotManager;
10329
- const stormSnapshotManager = new StormSnapshotManager();
10330
10284
  const _MutationRateLimiter = class _MutationRateLimiter2 {
10331
10285
  constructor() {
10332
10286
  __publicField(this, "mutTracker");
@@ -10337,6 +10291,9 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10337
10291
  __publicField(this, "inGlobalStorm", false);
10338
10292
  __publicField(this, "currentStormStartedAt", -1);
10339
10293
  __publicField(this, "stormTimeLimit", 5e3);
10294
+ __publicField(this, "debounceTimeout", null);
10295
+ __publicField(this, "debounceTimeoutMs", 250);
10296
+ __publicField(this, "handleStormFinishMethods", {});
10340
10297
  if (_MutationRateLimiter2.instance) {
10341
10298
  return _MutationRateLimiter2.instance;
10342
10299
  }
@@ -10361,11 +10318,19 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10361
10318
  this.resetExitTracker();
10362
10319
  this.currentStormStartedAt = -1;
10363
10320
  }
10364
- stormStopped() {
10321
+ stormStopped(stoppedByBuffer) {
10322
+ if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
10365
10323
  this.inGlobalStorm = false;
10366
10324
  this.reset();
10325
+ for (const [bufId, method] of Object.entries(
10326
+ this.handleStormFinishMethods
10327
+ )) {
10328
+ if (bufId === stoppedByBuffer) continue;
10329
+ method();
10330
+ }
10331
+ this.handleStormFinishMethods = {};
10367
10332
  }
10368
- handleStormExit(muts) {
10333
+ handleStormExit(muts, bufId) {
10369
10334
  const now = Date.now();
10370
10335
  if (this.exitMutTracker.requested === -1) {
10371
10336
  this.exitMutTracker = {
@@ -10392,29 +10357,41 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10392
10357
  mutTracker: this.mutTracker,
10393
10358
  exitMutTracker: this.exitMutTracker
10394
10359
  });
10395
- this.stormStopped();
10360
+ this.stormStopped(bufId);
10396
10361
  return false;
10397
10362
  }
10398
10363
  }
10399
10364
  }
10400
10365
  return true;
10401
10366
  }
10402
- canMutationBufferExitMutationStorm() {
10403
- return !this.inGlobalStorm;
10367
+ isInGlobalStorm() {
10368
+ return this.inGlobalStorm;
10369
+ }
10370
+ doDebounce() {
10371
+ if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
10372
+ if (!this.inGlobalStorm) return;
10373
+ this.debounceTimeout = setTimeout(() => {
10374
+ this.debounceTimeout = null;
10375
+ debugLog(`MutationRateLimiter, stopping storm because of debounce`);
10376
+ this.stormStopped();
10377
+ }, this.debounceTimeoutMs);
10404
10378
  }
10405
- isStorming(muts) {
10379
+ isStorming(muts, buffer) {
10380
+ if (!(buffer.bufId in this.handleStormFinishMethods)) {
10381
+ this.handleStormFinishMethods[buffer.bufId] = buffer.handleStormFinish.bind(buffer);
10382
+ }
10406
10383
  const now = Date.now();
10407
10384
  if (this.inGlobalStorm) {
10385
+ this.doDebounce();
10408
10386
  if (now - this.currentStormStartedAt > this.stormTimeLimit) {
10409
10387
  debugLog(
10410
10388
  `MutationRateLimiter, storm time limit reached, stopping storm`
10411
10389
  );
10412
- this.stormStopped();
10390
+ this.stormStopped(buffer.bufId);
10413
10391
  return false;
10414
10392
  }
10415
- if (now - this.mutTracker.ts > this.interval) {
10416
- return this.handleStormExit(muts);
10417
- }
10393
+ if (now - this.mutTracker.ts > this.interval)
10394
+ return this.handleStormExit(muts, buffer.bufId);
10418
10395
  this.mutTracker.muts += muts;
10419
10396
  this.mutTracker.ts = now;
10420
10397
  return true;
@@ -10428,6 +10405,7 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10428
10405
  this.inGlobalStorm = true;
10429
10406
  debugLog(`MutationRateLimiter, detected global rolling storm`);
10430
10407
  this.currentStormStartedAt = now;
10408
+ this.doDebounce();
10431
10409
  return true;
10432
10410
  }
10433
10411
  }
@@ -10439,6 +10417,52 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10439
10417
  __publicField(_MutationRateLimiter, "instance");
10440
10418
  let MutationRateLimiter = _MutationRateLimiter;
10441
10419
  const mutationRateLimiter = new MutationRateLimiter();
10420
+ const _StormSnapshotManager = class _StormSnapshotManager2 {
10421
+ constructor() {
10422
+ __publicField(this, "lastFullSnapshot", -1);
10423
+ __publicField(this, "intervalBetweenSnapshots", 150);
10424
+ __publicField(this, "debounceTimeout", null);
10425
+ __publicField(this, "debounceTime", 10);
10426
+ if (_StormSnapshotManager2.instance) {
10427
+ return _StormSnapshotManager2.instance;
10428
+ }
10429
+ _StormSnapshotManager2.instance = this;
10430
+ }
10431
+ //we're debouncing here because of how mutation buffers work.
10432
+ //multiple observers create their own mutation buffer, and
10433
+ //each buffer will handle mutations storms, so multiple buffers
10434
+ //will probably request a full snapshot at (basically) the same time.
10435
+ //we want to ensure all buffers have requested a full snapshot
10436
+ //(so we can be sure that all mutations have been made)
10437
+ //before we actually take a full snapshot.
10438
+ //also, we want a low debounceTime, bc if theres multiple, distinctive mutation storms,
10439
+ //in a somewhat quick succession, we want to record activity between them
10440
+ //not just one full snapshot after all the storms:
10441
+ //[mutation storm] [full snapshot] [mutation storm] [full snapshot]
10442
+ //NOT
10443
+ //[mutation storm] [timeout] [mutation storm] [full snapshot] (in this case, we probably miss all events which fired during the timeout)
10444
+ requestFullSnapshot() {
10445
+ if (this.debounceTimeout) {
10446
+ clearTimeout(this.debounceTimeout);
10447
+ }
10448
+ this.debounceTimeout = setTimeout(() => {
10449
+ this.debounceTimeout = null;
10450
+ this.takeSnapshot();
10451
+ }, this.debounceTime);
10452
+ }
10453
+ takeSnapshot() {
10454
+ if (Date.now() - this.lastFullSnapshot < this.intervalBetweenSnapshots) {
10455
+ debugLog("StormSnapshotManager, takeSnapshot: too soon");
10456
+ return;
10457
+ }
10458
+ debugLog("StormSnapshotManager, takeSnapshot: taking full snapshot");
10459
+ takeFullSnapshot();
10460
+ this.lastFullSnapshot = Date.now();
10461
+ }
10462
+ };
10463
+ __publicField(_StormSnapshotManager, "instance");
10464
+ let StormSnapshotManager = _StormSnapshotManager;
10465
+ const stormSnapshotManager = new StormSnapshotManager();
10442
10466
  function isNodeInLinkedList(n2) {
10443
10467
  return "__ln" in n2;
10444
10468
  }
@@ -10564,7 +10588,7 @@ class MutationBuffer {
10564
10588
  __publicField(this, "canvasManager");
10565
10589
  __publicField(this, "processedNodeManager");
10566
10590
  __publicField(this, "unattachedDoc");
10567
- __publicField(this, "bufId", isDebug() ? makeid() : "");
10591
+ __publicField(this, "bufId", makeid());
10568
10592
  __publicField(this, "stormBatches", []);
10569
10593
  __publicField(this, "stormInfo", null);
10570
10594
  __publicField(this, "stormSettings", {
@@ -10577,6 +10601,7 @@ class MutationBuffer {
10577
10601
  });
10578
10602
  __publicField(this, "debounceStormFinish", () => {
10579
10603
  if (!this.stormInfo) return;
10604
+ if (mutationRateLimiter.isInGlobalStorm()) return;
10580
10605
  this.stormInfo.timeout = setTimeout(
10581
10606
  this.handleStormFinish,
10582
10607
  this.stormSettings.timeout
@@ -10593,9 +10618,9 @@ class MutationBuffer {
10593
10618
  this.stormInfo = {
10594
10619
  startedAt: time,
10595
10620
  totalMutations: 0,
10596
- timeout: setTimeout(this.handleStormFinish, this.stormSettings.timeout),
10597
10621
  stormExceededLimit: false
10598
10622
  };
10623
+ if (canFinishStorm) this.debounceStormFinish();
10599
10624
  }
10600
10625
  this.stormInfo.totalMutations += muts.length;
10601
10626
  if (this.stormInfo.totalMutations >= this.stormSettings.mutationLimit) {
@@ -10616,10 +10641,6 @@ class MutationBuffer {
10616
10641
  });
10617
10642
  __publicField(this, "handleStormFinish", () => {
10618
10643
  if (!this.stormInfo) return;
10619
- if (!mutationRateLimiter.canMutationBufferExitMutationStorm()) {
10620
- this.debounceStormFinish();
10621
- return;
10622
- }
10623
10644
  const { stormExceededLimit } = this.stormInfo;
10624
10645
  debugLog(
10625
10646
  "mutation storm finished",
@@ -10649,7 +10670,7 @@ class MutationBuffer {
10649
10670
  });
10650
10671
  __publicField(this, "processInternalMutations", (muts, overrideStorm = false) => {
10651
10672
  if (!overrideStorm) {
10652
- const isStorming = mutationRateLimiter.isStorming(muts.length);
10673
+ const isStorming = mutationRateLimiter.isStorming(muts.length, this);
10653
10674
  if (isStorming) {
10654
10675
  this.handleStormMutations(muts, false);
10655
10676
  return;
@@ -12171,6 +12192,7 @@ function initObservers(o2, hooks = {}) {
12171
12192
  mergeHooks(o2, hooks);
12172
12193
  let mutationObserver;
12173
12194
  if (o2.recordDOM) {
12195
+ debugLog("adding mutation observer in initObservers");
12174
12196
  mutationObserver = initMutationObserver(o2, o2.doc);
12175
12197
  }
12176
12198
  const mousemoveHandler = initMoveObserver(o2);
@@ -12820,6 +12842,7 @@ class ShadowDomManager {
12820
12842
  if (!isNativeShadowDom(shadowRoot2)) return;
12821
12843
  if (this.shadowDoms.has(shadowRoot2)) return;
12822
12844
  this.shadowDoms.add(shadowRoot2);
12845
+ debugLog(`Adding mutation observer for shadowRoot ${shadowRoot2.host}`);
12823
12846
  const observer = initMutationObserver(
12824
12847
  {
12825
12848
  ...this.bypassOptions,
@@ -13399,6 +13422,7 @@ function record(options = {}) {
13399
13422
  };
13400
13423
  iframeManager.addLoadListener((iframeEl) => {
13401
13424
  try {
13425
+ debugLog("adding observers for new iframe", iframeEl);
13402
13426
  handlers.push(observe(iframeEl.contentDocument));
13403
13427
  } catch (error) {
13404
13428
  if (isDebug()) {