@glimt/record 0.0.80 → 0.0.81

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
@@ -1750,12 +1750,7 @@ function slimDOMExcluded(sn, slimDOMOptions) {
1750
1750
  }
1751
1751
  return false;
1752
1752
  }
1753
- const debugging = {
1754
- index: 0,
1755
- store: {}
1756
- };
1757
1753
  function serializeNodeWithId(n2, options) {
1758
- const start = Date.now();
1759
1754
  const {
1760
1755
  doc,
1761
1756
  mirror: mirror2,
@@ -1985,16 +1980,6 @@ function serializeNodeWithId(n2, options) {
1985
1980
  stylesheetLoadTimeout
1986
1981
  );
1987
1982
  }
1988
- debugging.index++;
1989
- const took = Date.now() - start;
1990
- if (!(n2.nodeName in debugging.store)) {
1991
- debugging.store[n2.nodeName] = [];
1992
- }
1993
- debugging.store[n2.nodeName].push(took);
1994
- if (debugging.index % 5e3 === 0) {
1995
- debugging.index = 0;
1996
- debugging.store = {};
1997
- }
1998
1983
  return serializedNode;
1999
1984
  }
2000
1985
  function snapshot(n2, options) {
@@ -10082,6 +10067,11 @@ class IframeManager {
10082
10067
  window.addEventListener("message", this.handleMessage.bind(this));
10083
10068
  }
10084
10069
  }
10070
+ destroy() {
10071
+ this.iframes = /* @__PURE__ */ new WeakMap();
10072
+ this.crossOriginIframeMap = /* @__PURE__ */ new WeakMap();
10073
+ this.crossOriginIframeRootIdMap = /* @__PURE__ */ new WeakMap();
10074
+ }
10085
10075
  addIframe(iframeEl) {
10086
10076
  this.iframes.set(iframeEl, true);
10087
10077
  if (iframeEl.contentWindow)
@@ -10293,188 +10283,45 @@ const _ObserveManager = class _ObserveManager2 {
10293
10283
  constructor() {
10294
10284
  __publicField(this, "docsObservers", /* @__PURE__ */ new WeakSet());
10295
10285
  __publicField(this, "shadowRootsObservers", /* @__PURE__ */ new WeakSet());
10296
- __publicField(this, "docsDebounceTimers", /* @__PURE__ */ new WeakMap());
10297
- __publicField(this, "shadowRootsDebounceTimers", /* @__PURE__ */ new WeakMap());
10298
- __publicField(this, "debounceTime", 15);
10299
- __publicField(this, "mutationOptions");
10300
- __publicField(this, "emitter", null);
10301
- __publicField(this, "isSnapshottingShadowRoots", false);
10302
- __publicField(this, "isSnapshottingDocs", false);
10286
+ __publicField(this, "docObservers", /* @__PURE__ */ new WeakMap());
10303
10287
  if (_ObserveManager2.instance) {
10304
10288
  return _ObserveManager2.instance;
10305
10289
  }
10306
10290
  _ObserveManager2.instance = this;
10307
10291
  }
10308
- setEmitter(emitter) {
10309
- this.emitter = emitter;
10310
- }
10311
- setMutationOptions(options) {
10312
- this.mutationOptions = options;
10313
- }
10314
- get usable() {
10315
- const result2 = this.emitter != null;
10316
- if (!result2) debugLog("observerManager: emitter is null");
10317
- return result2;
10318
- }
10319
- serializeDoc(doc) {
10320
- var _a2, _b2, _c;
10321
- if (!((_a2 = this.mutationOptions) == null ? void 0 : _a2.mirror)) return null;
10322
- const serialized = serializeNodeWithId(doc, {
10323
- ...this.mutationOptions,
10324
- doc,
10325
- skipChild: false,
10326
- maskTextFn: (_b2 = this.mutationOptions) == null ? void 0 : _b2.maskTextFn,
10327
- maskInputFn: (_c = this.mutationOptions) == null ? void 0 : _c.maskInputFn
10328
- });
10329
- if (!serialized) {
10330
- debugLog("snapshotDoc: no serialized node");
10331
- return null;
10292
+ observeIframe(doc, init, cleanup) {
10293
+ const current = this.docObservers.get(doc);
10294
+ if (current) {
10295
+ debugLog(
10296
+ doc,
10297
+ "iframe is already observed, cleaning up and registering again"
10298
+ );
10299
+ current();
10332
10300
  }
10333
- return serialized;
10334
- }
10335
- emitDoc(serialized) {
10336
- if (!this.emitter || !serialized) return;
10337
- this.emitter({
10338
- type: EventType.FullSnapshot,
10339
- data: {
10340
- node: serialized,
10341
- initialOffset: {
10342
- left: 0,
10343
- top: 0
10344
- }
10345
- }
10301
+ const id = makeid();
10302
+ init(id);
10303
+ this.docObservers.set(doc, () => {
10304
+ cleanup(id);
10346
10305
  });
10347
10306
  }
10348
- emitShadowRoot(serialized, shadowRoot2) {
10349
- var _a2;
10350
- if (!this.emitter || !serialized || !((_a2 = this.mutationOptions) == null ? void 0 : _a2.mirror)) return;
10351
- const hostId = this.mutationOptions.mirror.getId(shadowRoot2.host);
10352
- const shadowId = this.mutationOptions.mirror.getId(shadowRoot2);
10353
- this.emitter({
10354
- type: EventType.IncrementalSnapshot,
10355
- data: {
10356
- source: IncrementalSource.Mutation,
10357
- adds: [
10358
- {
10359
- parentId: hostId,
10360
- nextId: null,
10361
- node: serialized
10362
- }
10363
- ],
10364
- removes: [
10365
- {
10366
- id: shadowId,
10367
- parentId: hostId
10368
- }
10369
- ],
10370
- attributes: [],
10371
- texts: []
10372
- }
10373
- });
10374
- }
10375
- serializeAndEmitDoc(doc) {
10376
- debugLog(
10377
- "onDocObserver: doc already observed, emitting full snapshot for doc",
10378
- doc
10379
- );
10380
- this.isSnapshottingDocs = true;
10381
- const serialized = this.serializeDoc(doc);
10382
- this.emitDoc(serialized);
10383
- this.isSnapshottingDocs = false;
10384
- }
10385
- serializeAndEmitShadowRoot(shadowRoot2) {
10386
- debugLog(
10387
- "onShadowRootObserver: shadowRoot already observed, emitting full snapshot for shadowRoot",
10388
- shadowRoot2
10389
- );
10390
- this.isSnapshottingShadowRoots = true;
10391
- const serialized = this.serializeDoc(shadowRoot2.ownerDocument);
10392
- this.emitShadowRoot(serialized, shadowRoot2);
10393
- this.isSnapshottingShadowRoots = false;
10394
- }
10395
- debounceEmitDoc(doc) {
10396
- const existingTimer = this.docsDebounceTimers.get(doc);
10397
- if (existingTimer) clearTimeout(existingTimer);
10398
- this.docsDebounceTimers.set(
10399
- doc,
10400
- setTimeout(() => {
10401
- this.docsDebounceTimers.delete(doc);
10402
- this.serializeAndEmitDoc(doc);
10403
- }, this.debounceTime)
10404
- );
10405
- }
10406
- debounceEmitShadowRoot(shadowRoot2) {
10407
- const existingTimer = this.shadowRootsDebounceTimers.get(shadowRoot2);
10408
- if (existingTimer) clearTimeout(existingTimer);
10409
- this.shadowRootsDebounceTimers.set(
10410
- shadowRoot2,
10411
- setTimeout(() => {
10412
- this.shadowRootsDebounceTimers.delete(shadowRoot2);
10413
- this.serializeAndEmitShadowRoot(shadowRoot2);
10414
- }, this.debounceTime)
10415
- );
10416
- }
10417
- onDocObserver(doc) {
10418
- if (this.isSnapshottingDocs) return false;
10419
- if (!this.usable) return false;
10307
+ canRegisterDocObserver(doc) {
10420
10308
  if (!this.docsObservers.has(doc)) {
10421
10309
  this.docsObservers.add(doc);
10422
10310
  return true;
10423
10311
  }
10424
- debugLog(
10425
- "onDocObserver: doc already observed, debouncing full snapshot for doc",
10426
- doc
10427
- );
10428
- this.debounceEmitDoc(doc);
10429
10312
  return false;
10430
10313
  }
10431
- onShadowRootObserver(shadowRoot2) {
10432
- if (this.isSnapshottingShadowRoots) return false;
10433
- if (!this.usable) return false;
10314
+ canRegisterShadowRootObserver(shadowRoot2) {
10434
10315
  if (!this.shadowRootsObservers.has(shadowRoot2)) {
10435
10316
  this.shadowRootsObservers.add(shadowRoot2);
10436
10317
  return true;
10437
10318
  }
10438
- debugLog(
10439
- "onShadowRootObserver: shadowRoot already observed, debouncing full snapshot for shadowRoot",
10440
- shadowRoot2
10441
- );
10442
- this.debounceEmitShadowRoot(shadowRoot2);
10443
10319
  return false;
10444
10320
  }
10445
- // canObserveDoc(doc: Document) {
10446
- // if (!this.usable) return false;
10447
- // const hasObserver = this.docsObservers.has(doc);
10448
- // if (!hasObserver) return true;
10449
- // return false;
10450
- // }
10451
- // canObserveShadowRoot(shadowRoot: ShadowRoot) {
10452
- // if (!this.usable) return false;
10453
- // return !this.shadowRootsObserved.has(shadowRoot);
10454
- // }
10455
- // observerAttached(doc: Document, onCleanup: VoidFunction) {
10456
- // if (!this.usable) return;
10457
- // debugLog('[doc] attaching observer to doc', doc);
10458
- // if (this.docsObservers.has(doc)) {
10459
- // debugLog('[doc] detected existing observer, cleaning up old observer');
10460
- // const cleanupFn = this.docsObservers.get(doc);
10461
- // cleanupFn?.();
10462
- // }
10463
- // this.docsObservers.set(doc, onCleanup);
10464
- // }
10465
- // observerAttachedToShadow(shadowRoot: ShadowRoot, onCleanup: VoidFunction) {
10466
- // if (!this.usable) return;
10467
- // debugLog('[shadow] attaching observer to shadowRoot', shadowRoot);
10468
- // if (this.shadowRootsObserved.has(shadowRoot)) {
10469
- // debugLog('[shadow] detected existing observer, cleaning up old observer');
10470
- // const cleanupFn = this.shadowRootsObserved.get(shadowRoot);
10471
- // cleanupFn?.();
10472
- // }
10473
- // this.shadowRootsObserved.set(shadowRoot, onCleanup);
10474
- // }
10475
10321
  destroy() {
10476
10322
  this.docsObservers = /* @__PURE__ */ new WeakSet();
10477
10323
  this.shadowRootsObservers = /* @__PURE__ */ new WeakSet();
10324
+ this.docObservers = /* @__PURE__ */ new WeakMap();
10478
10325
  }
10479
10326
  };
10480
10327
  __publicField(_ObserveManager, "instance");
@@ -10486,7 +10333,7 @@ const _MutationRateLimiter = class _MutationRateLimiter2 {
10486
10333
  __publicField(this, "exitMutTracker");
10487
10334
  __publicField(this, "interval", 50);
10488
10335
  __publicField(this, "exitInterval", 100);
10489
- __publicField(this, "mutThreshold", 100);
10336
+ __publicField(this, "mutThreshold", 250);
10490
10337
  __publicField(this, "inGlobalStorm", false);
10491
10338
  __publicField(this, "currentStormStartedAt", -1);
10492
10339
  __publicField(this, "stormTimeLimit", 5e3);
@@ -13018,7 +12865,6 @@ class ShadowDomManager {
13018
12865
  __publicField(this, "bypassOptions");
13019
12866
  __publicField(this, "mirror");
13020
12867
  __publicField(this, "restoreHandlers", []);
13021
- __publicField(this, "mappedRestoreHandlers", {});
13022
12868
  this.mutationCb = options.mutationCb;
13023
12869
  this.scrollCb = options.scrollCb;
13024
12870
  this.bypassOptions = options.bypassOptions;
@@ -13031,10 +12877,15 @@ class ShadowDomManager {
13031
12877
  }
13032
12878
  addShadowRoot(shadowRoot2, doc) {
13033
12879
  if (!isNativeShadowDom(shadowRoot2)) return;
13034
- if (!observeManager.onShadowRootObserver(shadowRoot2)) return;
12880
+ if (!observeManager.canRegisterShadowRootObserver(shadowRoot2)) return;
13035
12881
  if (this.shadowDoms.has(shadowRoot2)) return;
13036
12882
  this.shadowDoms.add(shadowRoot2);
13037
- debugLog(`Adding mutation observer for shadowRoot ${shadowRoot2.host}`);
12883
+ debugLog(
12884
+ `Adding mutation observer for shadowRoot`,
12885
+ shadowRoot2.host,
12886
+ "restoreHandlers",
12887
+ this.restoreHandlers.length
12888
+ );
13038
12889
  const observer = initMutationObserver(
13039
12890
  {
13040
12891
  ...this.bypassOptions,
@@ -13111,15 +12962,6 @@ class ShadowDomManager {
13111
12962
  } catch (e2) {
13112
12963
  }
13113
12964
  });
13114
- Object.values(this.mappedRestoreHandlers).forEach((handlers) => {
13115
- for (const handler of handlers) {
13116
- try {
13117
- handler();
13118
- } catch (e2) {
13119
- }
13120
- }
13121
- });
13122
- this.mappedRestoreHandlers = {};
13123
12965
  this.restoreHandlers = [];
13124
12966
  this.shadowDoms = /* @__PURE__ */ new WeakSet();
13125
12967
  }
@@ -13305,10 +13147,10 @@ function record(options = {}) {
13305
13147
  }
13306
13148
  return e2;
13307
13149
  };
13308
- wrappedEmit = (r2, isCheckout) => {
13150
+ wrappedEmit = (r2, isCheckout, customOpts) => {
13309
13151
  var _a2;
13310
13152
  const e2 = r2;
13311
- e2.timestamp = nowTimestamp();
13153
+ e2.timestamp = (customOpts == null ? void 0 : customOpts.overrideTimestamp) ?? nowTimestamp();
13312
13154
  if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && e2.type !== EventType.FullSnapshot && !(e2.type === EventType.IncrementalSnapshot && e2.data.source === IncrementalSource.Mutation)) {
13313
13155
  mutationBuffers.forEach((buf) => buf.unfreeze());
13314
13156
  }
@@ -13423,29 +13265,6 @@ function record(options = {}) {
13423
13265
  },
13424
13266
  mirror
13425
13267
  });
13426
- observeManager.setEmitter(wrappedEmit);
13427
- observeManager.setMutationOptions({
13428
- blockClass,
13429
- blockSelector,
13430
- maskTextClass,
13431
- maskTextSelector,
13432
- inlineStylesheet,
13433
- maskInputOptions,
13434
- maskTextFn,
13435
- maskInputFn,
13436
- slimDOMOptions,
13437
- dataURLOptions,
13438
- canvasManager,
13439
- stylesheetManager,
13440
- shadowDomManager,
13441
- recordCanvas,
13442
- inlineImages,
13443
- mirror,
13444
- iframeManager,
13445
- keepIframeSrcFn,
13446
- mutationCb: wrappedMutationEmit,
13447
- processedNodeManager
13448
- });
13449
13268
  takeFullSnapshot$1 = (isCheckout = false) => {
13450
13269
  if (!recordDOM) {
13451
13270
  return;
@@ -13521,7 +13340,6 @@ function record(options = {}) {
13521
13340
  };
13522
13341
  try {
13523
13342
  const handlers = [];
13524
- const registeredHandlers = {};
13525
13343
  const observe = (doc) => {
13526
13344
  var _a2;
13527
13345
  return callbackWrapper(initObservers)(
@@ -13645,11 +13463,31 @@ function record(options = {}) {
13645
13463
  hooks
13646
13464
  );
13647
13465
  };
13466
+ const registeredHandlers = {};
13648
13467
  iframeManager.addLoadListener((iframeEl) => {
13649
13468
  try {
13650
- if (!observeManager.onDocObserver(iframeEl.contentDocument)) return;
13651
- debugLog("Adding mutation observer for iframe", iframeEl);
13652
- handlers.push(observe(iframeEl.contentDocument));
13469
+ observeManager.observeIframe(
13470
+ iframeEl.contentDocument,
13471
+ (id) => {
13472
+ const cleanup = observe(iframeEl.contentDocument);
13473
+ registeredHandlers[id] = cleanup;
13474
+ debugLog(
13475
+ iframeEl.contentDocument,
13476
+ "did register handler on iframe. current registered handlers",
13477
+ Object.keys(registeredHandlers).length
13478
+ );
13479
+ },
13480
+ (id) => {
13481
+ const handler = registeredHandlers[id];
13482
+ if (handler) handler();
13483
+ delete registeredHandlers[id];
13484
+ debugLog(
13485
+ iframeEl.contentDocument,
13486
+ "did cleanup for regisited handler on iframe. current registered handlers",
13487
+ Object.keys(registeredHandlers).length
13488
+ );
13489
+ }
13490
+ );
13653
13491
  } catch (error) {
13654
13492
  if (isDebug()) {
13655
13493
  console.warn("internal error");
@@ -13710,6 +13548,7 @@ function record(options = {}) {
13710
13548
  handlers.forEach((h) => h());
13711
13549
  Object.values(registeredHandlers).forEach((h) => h());
13712
13550
  processedNodeManager.destroy();
13551
+ iframeManager.destroy();
13713
13552
  observeManager.destroy();
13714
13553
  recording = false;
13715
13554
  unregisterErrorHandler();