@posthog/rrweb-record 0.0.45 → 0.0.47

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.
@@ -10579,7 +10579,7 @@ function initMutationObserver(options, rootEl) {
10579
10579
  childList: true,
10580
10580
  subtree: true
10581
10581
  });
10582
- return observer;
10582
+ return { observer, buffer: mutationBuffer };
10583
10583
  }
10584
10584
  function initMoveObserver({
10585
10585
  mousemoveCb,
@@ -11498,8 +11498,11 @@ function initObservers(o2, hooks = {}) {
11498
11498
  }
11499
11499
  mergeHooks(o2, hooks);
11500
11500
  let mutationObserver;
11501
+ let mutationBuffer;
11501
11502
  if (o2.recordDOM) {
11502
- mutationObserver = initMutationObserver(o2, o2.doc);
11503
+ const result2 = initMutationObserver(o2, o2.doc);
11504
+ mutationObserver = result2.observer;
11505
+ mutationBuffer = result2.buffer;
11503
11506
  }
11504
11507
  const mousemoveHandler = initMoveObserver(o2);
11505
11508
  const mouseInteractionHandler = initMouseInteractionObserver(o2);
@@ -11536,8 +11539,14 @@ function initObservers(o2, hooks = {}) {
11536
11539
  );
11537
11540
  }
11538
11541
  return callbackWrapper(() => {
11539
- mutationBuffers.forEach((b) => b.destroy());
11540
- mutationBuffers.forEach((b) => b.reset());
11542
+ if (mutationBuffer) {
11543
+ mutationBuffer.destroy();
11544
+ mutationBuffer.reset();
11545
+ const index2 = mutationBuffers.indexOf(mutationBuffer);
11546
+ if (index2 !== -1) {
11547
+ mutationBuffers.splice(index2, 1);
11548
+ }
11549
+ }
11541
11550
  mutationObserver == null ? void 0 : mutationObserver.disconnect();
11542
11551
  mousemoveHandler();
11543
11552
  mouseInteractionHandler();
@@ -11552,7 +11561,6 @@ function initObservers(o2, hooks = {}) {
11552
11561
  selectionObserver();
11553
11562
  customElementObserver();
11554
11563
  pluginHandlers.forEach((h) => h());
11555
- mutationBuffers.length = 0;
11556
11564
  });
11557
11565
  }
11558
11566
  function hasNestedCSSRule(prop) {
@@ -11952,7 +11960,7 @@ class ShadowDomManager {
11952
11960
  if (!isNativeShadowDom(shadowRoot2)) return;
11953
11961
  if (this.shadowDoms.has(shadowRoot2)) return;
11954
11962
  this.shadowDoms.add(shadowRoot2);
11955
- const observer = initMutationObserver(
11963
+ const { observer, buffer } = initMutationObserver(
11956
11964
  __spreadProps(__spreadValues({}, this.bypassOptions), {
11957
11965
  doc,
11958
11966
  mutationCb: this.mutationCb,
@@ -11961,7 +11969,15 @@ class ShadowDomManager {
11961
11969
  }),
11962
11970
  shadowRoot2
11963
11971
  );
11964
- this.restoreHandlers.push(() => observer.disconnect());
11972
+ this.restoreHandlers.push(() => {
11973
+ observer.disconnect();
11974
+ buffer.destroy();
11975
+ buffer.reset();
11976
+ const index2 = mutationBuffers.indexOf(buffer);
11977
+ if (index2 !== -1) {
11978
+ mutationBuffers.splice(index2, 1);
11979
+ }
11980
+ });
11965
11981
  this.restoreHandlers.push(
11966
11982
  initScrollObserver(__spreadProps(__spreadValues({}, this.bypassOptions), {
11967
11983
  scrollCb: this.scrollCb,
@@ -12350,7 +12366,7 @@ function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, dat
12350
12366
  handlers.forEach((h) => h());
12351
12367
  };
12352
12368
  }
12353
- const jsContent = '(function() {\n "use strict";\n var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256);\n for (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n }\n var encode = function(arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = "";\n for (i2 = 0; i2 < len; i2 += 3) {\n base64 += chars[bytes[i2] >> 2];\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\n base64 += chars[bytes[i2 + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + "=";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + "==";\n }\n return base64;\n };\n const lastBlobMap = /* @__PURE__ */ new Map();\n const transparentBlobMap = /* @__PURE__ */ new Map();\n async function getTransparentBlobFor(width, height, dataURLOptions) {\n const id = `${width}-${height}`;\n if ("OffscreenCanvas" in globalThis) {\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\n const offscreen = new OffscreenCanvas(width, height);\n offscreen.getContext("2d");\n const blob = await offscreen.convertToBlob(dataURLOptions);\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer);\n transparentBlobMap.set(id, base64);\n return base64;\n } else {\n return "";\n }\n }\n const worker = self;\n let reusableCanvas = null;\n let reusableCtx = null;\n worker.onmessage = async function(e) {\n if ("OffscreenCanvas" in globalThis) {\n const { id, bitmap, width, height, dataURLOptions } = e.data;\n const transparentBase64 = getTransparentBlobFor(\n width,\n height,\n dataURLOptions\n );\n if (!reusableCanvas || reusableCanvas.width !== width || reusableCanvas.height !== height) {\n reusableCanvas = new OffscreenCanvas(width, height);\n reusableCtx = reusableCanvas.getContext("2d");\n }\n reusableCtx.clearRect(0, 0, width, height);\n reusableCtx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await reusableCanvas.convertToBlob(dataURLOptions);\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer);\n if (!lastBlobMap.has(id) && await transparentBase64 === base64) {\n lastBlobMap.set(id, base64);\n return worker.postMessage({ id });\n }\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id });\n worker.postMessage({\n id,\n type,\n base64,\n width,\n height\n });\n lastBlobMap.set(id, base64);\n } else {\n e.data.bitmap.close();\n return worker.postMessage({ id: e.data.id });\n }\n };\n})();\n//# sourceMappingURL=image-bitmap-data-url-worker-ChEIhO0o.js.map\n';
12369
+ const jsContent = '(function() {\n "use strict";\n var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256);\n for (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n }\n var encode = function(arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = "";\n for (i2 = 0; i2 < len; i2 += 3) {\n base64 += chars[bytes[i2] >> 2];\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\n base64 += chars[bytes[i2 + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + "=";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + "==";\n }\n return base64;\n };\n const lastFingerprintMap = /* @__PURE__ */ new Map();\n const transparentBlobMap = /* @__PURE__ */ new Map();\n function fnv1aHash(buffer) {\n const view = new Uint8Array(buffer);\n let hash = 2166136261;\n for (let i2 = 0; i2 < view.length; i2++) {\n hash ^= view[i2];\n hash = hash * 16777619 | 0;\n }\n return (hash >>> 0).toString(16);\n }\n async function getTransparentBlobFor(width, height, dataURLOptions) {\n const id = `${width}-${height}`;\n if ("OffscreenCanvas" in globalThis) {\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\n const offscreen = new OffscreenCanvas(width, height);\n offscreen.getContext("2d");\n const blob = await offscreen.convertToBlob(dataURLOptions);\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer);\n transparentBlobMap.set(id, base64);\n return base64;\n } else {\n return "";\n }\n }\n const worker = self;\n let reusableCanvas = null;\n let reusableCtx = null;\n worker.onmessage = async function(e) {\n if ("OffscreenCanvas" in globalThis) {\n const { id, bitmap, width, height, dataURLOptions } = e.data;\n const transparentBase64 = getTransparentBlobFor(\n width,\n height,\n dataURLOptions\n );\n if (!reusableCanvas || reusableCanvas.width !== width || reusableCanvas.height !== height) {\n reusableCanvas = new OffscreenCanvas(width, height);\n reusableCtx = reusableCanvas.getContext("2d");\n }\n reusableCtx.clearRect(0, 0, width, height);\n reusableCtx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await reusableCanvas.convertToBlob(dataURLOptions);\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const fingerprint = fnv1aHash(arrayBuffer);\n if (!lastFingerprintMap.has(id)) {\n const base642 = encode(arrayBuffer);\n if (await transparentBase64 === base642) {\n lastFingerprintMap.set(id, fingerprint);\n return worker.postMessage({ id });\n }\n lastFingerprintMap.set(id, fingerprint);\n worker.postMessage({ id, type, base64: base642, width, height });\n return;\n }\n if (lastFingerprintMap.get(id) === fingerprint)\n return worker.postMessage({ id });\n const base64 = encode(arrayBuffer);\n worker.postMessage({ id, type, base64, width, height });\n lastFingerprintMap.set(id, fingerprint);\n } else {\n e.data.bitmap.close();\n return worker.postMessage({ id: e.data.id });\n }\n };\n})();\n//# sourceMappingURL=image-bitmap-data-url-worker-B8-18rdG.js.map\n';
12354
12370
  const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
12355
12371
  function WorkerWrapper(options) {
12356
12372
  let objURL;
@@ -12816,6 +12832,26 @@ function record(options = {}) {
12816
12832
  polyfill$1();
12817
12833
  let lastFullSnapshotEvent;
12818
12834
  let incrementalSnapshotCount = 0;
12835
+ const iframeObserverCleanups = /* @__PURE__ */ new Map();
12836
+ function cleanupDetachedIframeObservers() {
12837
+ for (const [iframeId, cleanup] of iframeObserverCleanups) {
12838
+ const iframe = mirror.getNode(iframeId);
12839
+ if (!iframe) {
12840
+ cleanup();
12841
+ iframeObserverCleanups.delete(iframeId);
12842
+ continue;
12843
+ }
12844
+ try {
12845
+ if (!iframe.contentDocument || !iframe.contentDocument.defaultView) {
12846
+ cleanup();
12847
+ iframeObserverCleanups.delete(iframeId);
12848
+ }
12849
+ } catch (e) {
12850
+ cleanup();
12851
+ iframeObserverCleanups.delete(iframeId);
12852
+ }
12853
+ }
12854
+ }
12819
12855
  const eventProcessor = (e2) => {
12820
12856
  for (const plugin of plugins || []) {
12821
12857
  if (plugin.eventProcessor) {
@@ -12866,9 +12902,15 @@ function record(options = {}) {
12866
12902
  const addedIds = m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;
12867
12903
  m.removes.forEach(({ id }) => {
12868
12904
  if (!addedIds || !addedIds.has(id)) {
12905
+ const cleanup = iframeObserverCleanups.get(id);
12906
+ if (cleanup) {
12907
+ cleanup();
12908
+ iframeObserverCleanups.delete(id);
12909
+ }
12869
12910
  iframeManager.removeIframeById(id);
12870
12911
  }
12871
12912
  });
12913
+ cleanupDetachedIframeObservers();
12872
12914
  }
12873
12915
  wrappedEmit({
12874
12916
  type: EventType.IncrementalSnapshot,
@@ -13143,7 +13185,12 @@ function record(options = {}) {
13143
13185
  };
13144
13186
  const loadListener = (iframeEl) => {
13145
13187
  try {
13146
- handlers.push(observe(iframeEl.contentDocument));
13188
+ const iframeId = mirror.getId(iframeEl);
13189
+ const cleanup = observe(iframeEl.contentDocument);
13190
+ handlers.push(cleanup);
13191
+ if (iframeId !== -1) {
13192
+ iframeObserverCleanups.set(iframeId, cleanup);
13193
+ }
13147
13194
  } catch (error) {
13148
13195
  console.warn(error);
13149
13196
  }
@@ -13185,6 +13232,7 @@ function record(options = {}) {
13185
13232
  processedNodeManager.destroy();
13186
13233
  iframeManager.removeLoadListener();
13187
13234
  iframeManager.destroy();
13235
+ iframeObserverCleanups.clear();
13188
13236
  mirror.reset();
13189
13237
  recording = false;
13190
13238
  unregisterErrorHandler();