@glimt/record 0.0.80 → 0.0.82

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