@posthog/rrweb 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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-bitmap-data-url-worker-B8-18rdG.js","sources":["../../../node_modules/.pnpm/base64-arraybuffer@1.0.2/node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js","../src/record/workers/image-bitmap-data-url-worker.ts"],"sourcesContent":["/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n base64 += chars[bytes[i + 2] & 63];\n }\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n }\n else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n return base64;\n};\nvar decode = function (base64) {\n var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\n for (i = 0; i < len; i += 4) {\n encoded1 = lookup[base64.charCodeAt(i)];\n encoded2 = lookup[base64.charCodeAt(i + 1)];\n encoded3 = lookup[base64.charCodeAt(i + 2)];\n encoded4 = lookup[base64.charCodeAt(i + 3)];\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n return arraybuffer;\n};\n\nexport { decode, encode };\n//# sourceMappingURL=base64-arraybuffer.es5.js.map\n","import { encode } from 'base64-arraybuffer';\nimport type {\n DataURLOptions,\n ImageBitmapDataURLWorkerParams,\n ImageBitmapDataURLWorkerResponse,\n} from '@posthog/rrweb-types';\n\nconst lastFingerprintMap: Map<number, string> = new Map();\nconst transparentBlobMap: Map<string, string> = new Map();\n\nfunction fnv1aHash(buffer: ArrayBuffer): string {\n const view = new Uint8Array(buffer);\n let hash = 0x811c9dc5;\n for (let i = 0; i < view.length; i++) {\n hash ^= view[i];\n hash = (hash * 0x01000193) | 0;\n }\n return (hash >>> 0).toString(16);\n}\n\nexport interface ImageBitmapDataURLRequestWorker {\n postMessage: (\n message: ImageBitmapDataURLWorkerParams,\n transfer?: [ImageBitmap],\n ) => void;\n onmessage: (message: MessageEvent<ImageBitmapDataURLWorkerResponse>) => void;\n}\n\ninterface ImageBitmapDataURLResponseWorker {\n onmessage:\n | null\n | ((message: MessageEvent<ImageBitmapDataURLWorkerParams>) => void);\n postMessage(e: ImageBitmapDataURLWorkerResponse): void;\n}\n\nasync function getTransparentBlobFor(\n width: number,\n height: number,\n dataURLOptions: DataURLOptions,\n): Promise<string> {\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'); // creates rendering context for `converToBlob`\n const blob = await offscreen.convertToBlob(dataURLOptions); // takes a while\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer); // cpu intensive\n transparentBlobMap.set(id, base64);\n return base64;\n } else {\n return '';\n }\n}\n\n// `as any` because: https://github.com/Microsoft/TypeScript/issues/20595\nconst worker: ImageBitmapDataURLResponseWorker = self;\n\nlet reusableCanvas: OffscreenCanvas | null = null;\nlet reusableCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n// eslint-disable-next-line @typescript-eslint/no-misused-promises\nworker.onmessage = async function (e) {\n if ('OffscreenCanvas' in globalThis) {\n const { id, bitmap, width, height, dataURLOptions } = e.data;\n\n const transparentBase64 = getTransparentBlobFor(\n width,\n height,\n dataURLOptions,\n );\n\n if (\n !reusableCanvas ||\n reusableCanvas.width !== width ||\n reusableCanvas.height !== height\n ) {\n reusableCanvas = new OffscreenCanvas(width, height);\n reusableCtx = reusableCanvas.getContext('2d')!;\n }\n\n reusableCtx!.clearRect(0, 0, width, height);\n reusableCtx!.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await reusableCanvas.convertToBlob(dataURLOptions); // takes a while\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const fingerprint = fnv1aHash(arrayBuffer);\n\n // on first try we should check if canvas is transparent,\n // no need to save it's contents in that case\n if (!lastFingerprintMap.has(id)) {\n const base64 = encode(arrayBuffer);\n if ((await transparentBase64) === base64) {\n lastFingerprintMap.set(id, fingerprint);\n return worker.postMessage({ id });\n }\n lastFingerprintMap.set(id, fingerprint);\n worker.postMessage({ id, type, base64, width, height });\n return;\n }\n\n if (lastFingerprintMap.get(id) === fingerprint)\n return worker.postMessage({ id }); // unchanged\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"],"names":["i","base64"],"mappings":"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","x_google_ignoreList":[0]}
package/dist/rrweb.cjs CHANGED
@@ -12617,7 +12617,7 @@ function initMutationObserver(options, rootEl) {
12617
12617
  childList: true,
12618
12618
  subtree: true
12619
12619
  });
12620
- return observer;
12620
+ return { observer, buffer: mutationBuffer };
12621
12621
  }
12622
12622
  function initMoveObserver({
12623
12623
  mousemoveCb,
@@ -13538,8 +13538,11 @@ function initObservers(o2, hooks = {}) {
13538
13538
  }
13539
13539
  mergeHooks(o2, hooks);
13540
13540
  let mutationObserver;
13541
+ let mutationBuffer;
13541
13542
  if (o2.recordDOM) {
13542
- mutationObserver = initMutationObserver(o2, o2.doc);
13543
+ const result2 = initMutationObserver(o2, o2.doc);
13544
+ mutationObserver = result2.observer;
13545
+ mutationBuffer = result2.buffer;
13543
13546
  }
13544
13547
  const mousemoveHandler = initMoveObserver(o2);
13545
13548
  const mouseInteractionHandler = initMouseInteractionObserver(o2);
@@ -13576,8 +13579,14 @@ function initObservers(o2, hooks = {}) {
13576
13579
  );
13577
13580
  }
13578
13581
  return callbackWrapper(() => {
13579
- mutationBuffers.forEach((b) => b.destroy());
13580
- mutationBuffers.forEach((b) => b.reset());
13582
+ if (mutationBuffer) {
13583
+ mutationBuffer.destroy();
13584
+ mutationBuffer.reset();
13585
+ const index2 = mutationBuffers.indexOf(mutationBuffer);
13586
+ if (index2 !== -1) {
13587
+ mutationBuffers.splice(index2, 1);
13588
+ }
13589
+ }
13581
13590
  mutationObserver == null ? void 0 : mutationObserver.disconnect();
13582
13591
  mousemoveHandler();
13583
13592
  mouseInteractionHandler();
@@ -13592,7 +13601,6 @@ function initObservers(o2, hooks = {}) {
13592
13601
  selectionObserver();
13593
13602
  customElementObserver();
13594
13603
  pluginHandlers.forEach((h) => h());
13595
- mutationBuffers.length = 0;
13596
13604
  });
13597
13605
  }
13598
13606
  function hasNestedCSSRule(prop) {
@@ -13993,7 +14001,7 @@ class ShadowDomManager {
13993
14001
  if (!isNativeShadowDom(shadowRoot2)) return;
13994
14002
  if (this.shadowDoms.has(shadowRoot2)) return;
13995
14003
  this.shadowDoms.add(shadowRoot2);
13996
- const observer = initMutationObserver(
14004
+ const { observer, buffer } = initMutationObserver(
13997
14005
  {
13998
14006
  ...this.bypassOptions,
13999
14007
  doc,
@@ -14003,7 +14011,15 @@ class ShadowDomManager {
14003
14011
  },
14004
14012
  shadowRoot2
14005
14013
  );
14006
- this.restoreHandlers.push(() => observer.disconnect());
14014
+ this.restoreHandlers.push(() => {
14015
+ observer.disconnect();
14016
+ buffer.destroy();
14017
+ buffer.reset();
14018
+ const index2 = mutationBuffers.indexOf(buffer);
14019
+ if (index2 !== -1) {
14020
+ mutationBuffers.splice(index2, 1);
14021
+ }
14022
+ });
14007
14023
  this.restoreHandlers.push(
14008
14024
  initScrollObserver({
14009
14025
  ...this.bypassOptions,
@@ -14413,7 +14429,7 @@ function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, dat
14413
14429
  handlers.forEach((h) => h());
14414
14430
  };
14415
14431
  }
14416
- 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';
14432
+ 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';
14417
14433
  const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
14418
14434
  function WorkerWrapper(options) {
14419
14435
  let objURL;
@@ -14880,6 +14896,26 @@ function record(options = {}) {
14880
14896
  polyfill$1();
14881
14897
  let lastFullSnapshotEvent;
14882
14898
  let incrementalSnapshotCount = 0;
14899
+ const iframeObserverCleanups = /* @__PURE__ */ new Map();
14900
+ function cleanupDetachedIframeObservers() {
14901
+ for (const [iframeId, cleanup] of iframeObserverCleanups) {
14902
+ const iframe = mirror.getNode(iframeId);
14903
+ if (!iframe) {
14904
+ cleanup();
14905
+ iframeObserverCleanups.delete(iframeId);
14906
+ continue;
14907
+ }
14908
+ try {
14909
+ if (!iframe.contentDocument || !iframe.contentDocument.defaultView) {
14910
+ cleanup();
14911
+ iframeObserverCleanups.delete(iframeId);
14912
+ }
14913
+ } catch {
14914
+ cleanup();
14915
+ iframeObserverCleanups.delete(iframeId);
14916
+ }
14917
+ }
14918
+ }
14883
14919
  const eventProcessor = (e2) => {
14884
14920
  for (const plugin of plugins || []) {
14885
14921
  if (plugin.eventProcessor) {
@@ -14930,9 +14966,15 @@ function record(options = {}) {
14930
14966
  const addedIds = m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;
14931
14967
  m.removes.forEach(({ id }) => {
14932
14968
  if (!addedIds || !addedIds.has(id)) {
14969
+ const cleanup = iframeObserverCleanups.get(id);
14970
+ if (cleanup) {
14971
+ cleanup();
14972
+ iframeObserverCleanups.delete(id);
14973
+ }
14933
14974
  iframeManager.removeIframeById(id);
14934
14975
  }
14935
14976
  });
14977
+ cleanupDetachedIframeObservers();
14936
14978
  }
14937
14979
  wrappedEmit({
14938
14980
  type: EventType.IncrementalSnapshot,
@@ -15220,7 +15262,12 @@ function record(options = {}) {
15220
15262
  };
15221
15263
  const loadListener = (iframeEl) => {
15222
15264
  try {
15223
- handlers.push(observe(iframeEl.contentDocument));
15265
+ const iframeId = mirror.getId(iframeEl);
15266
+ const cleanup = observe(iframeEl.contentDocument);
15267
+ handlers.push(cleanup);
15268
+ if (iframeId !== -1) {
15269
+ iframeObserverCleanups.set(iframeId, cleanup);
15270
+ }
15224
15271
  } catch (error) {
15225
15272
  console.warn(error);
15226
15273
  }
@@ -15262,6 +15309,7 @@ function record(options = {}) {
15262
15309
  processedNodeManager.destroy();
15263
15310
  iframeManager.removeLoadListener();
15264
15311
  iframeManager.destroy();
15312
+ iframeObserverCleanups.clear();
15265
15313
  mirror.reset();
15266
15314
  recording = false;
15267
15315
  unregisterErrorHandler();