@kalayanasundaram123/rrweb 2.0.1 → 2.0.3

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/rrweb.cjs CHANGED
@@ -4963,10 +4963,10 @@ function requireNoWorkResult$1() {
4963
4963
  let str = stringify;
4964
4964
  this.result = new Result(this._processor, root2, this._opts);
4965
4965
  this.result.css = css;
4966
- let self2 = this;
4966
+ let self = this;
4967
4967
  Object.defineProperty(this.result, "root", {
4968
4968
  get() {
4969
- return self2.root;
4969
+ return self.root;
4970
4970
  }
4971
4971
  });
4972
4972
  let map = new MapGenerator(str, root2, this._opts, css);
@@ -9244,10 +9244,10 @@ function requireNoWorkResult() {
9244
9244
  let str = stringify;
9245
9245
  this.result = new Result(this._processor, root2, this._opts);
9246
9246
  this.result.css = css;
9247
- let self2 = this;
9247
+ let self = this;
9248
9248
  Object.defineProperty(this.result, "root", {
9249
9249
  get() {
9250
- return self2.root;
9250
+ return self.root;
9251
9251
  }
9252
9252
  });
9253
9253
  let map = new MapGenerator(str, root2, this._opts, css);
@@ -13938,30 +13938,17 @@ function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector) {
13938
13938
  handlers.forEach((h) => h());
13939
13939
  };
13940
13940
  }
13941
- 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 try {\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 }\n const base64 = encode(arrayBuffer);\n worker.postMessage({ id, type, base64, width, height });\n lastFingerprintMap.set(id, fingerprint);\n } catch {\n worker.postMessage({ id });\n }\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-DIbJg1p8.js.map\n';
13942
- const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
13943
- function WorkerWrapper(options) {
13944
- let objURL;
13945
- try {
13946
- objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);
13947
- if (!objURL) throw "";
13948
- const worker = new Worker(objURL, {
13949
- name: options == null ? void 0 : options.name
13950
- });
13951
- worker.addEventListener("error", () => {
13952
- (self.URL || self.webkitURL).revokeObjectURL(objURL);
13953
- });
13954
- return worker;
13955
- } catch (e2) {
13956
- return new Worker(
13957
- "data:text/javascript;charset=utf-8," + encodeURIComponent(jsContent),
13958
- {
13959
- name: options == null ? void 0 : options.name
13960
- }
13961
- );
13962
- } finally {
13963
- objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);
13941
+ function fnv1aHash(buffer) {
13942
+ const view = new Uint8Array(buffer);
13943
+ let hash = 2166136261;
13944
+ for (let i2 = 0; i2 < view.length; i2++) {
13945
+ hash ^= view[i2];
13946
+ hash = hash * 16777619 | 0;
13964
13947
  }
13948
+ return (hash >>> 0).toString(16);
13949
+ }
13950
+ function canSnapshotCanvas() {
13951
+ return typeof OffscreenCanvas !== "undefined";
13965
13952
  }
13966
13953
  class CanvasManager {
13967
13954
  constructor(options) {
@@ -13982,7 +13969,9 @@ class CanvasManager {
13982
13969
  __publicField(this, "frozen", false);
13983
13970
  __publicField(this, "locked", false);
13984
13971
  __publicField(this, "snapshotInProgressMap", /* @__PURE__ */ new Map());
13985
- __publicField(this, "worker", null);
13972
+ __publicField(this, "lastFingerprintMap", /* @__PURE__ */ new Map());
13973
+ __publicField(this, "snapshotCanvas", null);
13974
+ __publicField(this, "snapshotCtx", null);
13986
13975
  __publicField(this, "lastSnapshotTime", 0);
13987
13976
  __publicField(this, "processMutation", (target, mutation) => {
13988
13977
  const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;
@@ -13998,20 +13987,16 @@ class CanvasManager {
13998
13987
  this.mutationCb = options.mutationCb;
13999
13988
  this.mirror = options.mirror;
14000
13989
  this.options = options;
14001
- if (recordCanvas && typeof sampling === "number") {
14002
- this.worker = this.initFPSWorker();
14003
- }
14004
13990
  this.addWindow(win);
14005
13991
  if (recordCanvas && sampling === "all") {
14006
13992
  this.startRAFTimestamping();
14007
13993
  this.startPendingCanvasMutationFlusher();
14008
13994
  }
14009
- if (recordCanvas && typeof sampling === "number") {
13995
+ if (recordCanvas && typeof sampling === "number" && canSnapshotCanvas()) {
14010
13996
  this.initCanvasFPSObserver();
14011
13997
  }
14012
13998
  }
14013
13999
  reset() {
14014
- var _a2;
14015
14000
  this.pendingCanvasMutations.clear();
14016
14001
  this.restoreHandlers.forEach((handler) => {
14017
14002
  try {
@@ -14023,9 +14008,10 @@ class CanvasManager {
14023
14008
  this.windowsSet = /* @__PURE__ */ new WeakSet();
14024
14009
  this.windows = [];
14025
14010
  this.shadowDoms = /* @__PURE__ */ new Set();
14026
- (_a2 = this.worker) == null ? void 0 : _a2.terminate();
14027
- this.worker = null;
14028
14011
  this.snapshotInProgressMap = /* @__PURE__ */ new Map();
14012
+ this.lastFingerprintMap = /* @__PURE__ */ new Map();
14013
+ this.snapshotCanvas = null;
14014
+ this.snapshotCtx = null;
14029
14015
  }
14030
14016
  freeze() {
14031
14017
  this.frozen = true;
@@ -14078,45 +14064,74 @@ class CanvasManager {
14078
14064
  resetShadowRoots() {
14079
14065
  this.shadowDoms = /* @__PURE__ */ new Set();
14080
14066
  }
14081
- initFPSWorker() {
14082
- const worker = new WorkerWrapper();
14083
- worker.onmessage = (e2) => {
14084
- const data = e2.data;
14085
- const { id } = data;
14086
- this.snapshotInProgressMap.set(id, false);
14087
- if (!("base64" in data)) return;
14088
- const { base64, type, width, height } = data;
14089
- this.mutationCb({
14067
+ /**
14068
+ * Encode one canvas frame (an ImageBitmap of the canvas) to a data blob on
14069
+ * the main thread, de-duplicating unchanged frames, and emit it as a canvas
14070
+ * mutation. Replaces the old blob-URL Worker, which crashed the renderer when
14071
+ * created inside sandboxed frames.
14072
+ */
14073
+ async snapshotImageBitmap(id, bitmap, width, height, dataURLOptions) {
14074
+ try {
14075
+ let offscreen = this.snapshotCanvas;
14076
+ if (!offscreen || offscreen.width !== width || offscreen.height !== height) {
14077
+ offscreen = new OffscreenCanvas(width, height);
14078
+ this.snapshotCanvas = offscreen;
14079
+ this.snapshotCtx = offscreen.getContext("2d");
14080
+ }
14081
+ const ctx = this.snapshotCtx;
14082
+ if (!ctx) return;
14083
+ ctx.clearRect(0, 0, width, height);
14084
+ ctx.drawImage(bitmap, 0, 0);
14085
+ const blob = await offscreen.convertToBlob(
14086
+ dataURLOptions
14087
+ );
14088
+ const arrayBuffer = await blob.arrayBuffer();
14089
+ const fingerprint = fnv1aHash(arrayBuffer);
14090
+ if (this.lastFingerprintMap.get(id) === fingerprint) return;
14091
+ this.lastFingerprintMap.set(id, fingerprint);
14092
+ this.emitCanvasSnapshot(
14090
14093
  id,
14091
- type: CanvasContext["2D"],
14092
- commands: [
14093
- {
14094
- property: "clearRect",
14095
- // wipe canvas
14096
- args: [0, 0, width, height]
14097
- },
14098
- {
14099
- property: "drawImage",
14100
- // draws (semi-transparent) image
14101
- args: [
14102
- {
14103
- rr_type: "ImageBitmap",
14104
- args: [
14105
- {
14106
- rr_type: "Blob",
14107
- data: [{ rr_type: "ArrayBuffer", base64 }],
14108
- type
14109
- }
14110
- ]
14111
- },
14112
- 0,
14113
- 0
14114
- ]
14115
- }
14116
- ]
14117
- });
14118
- };
14119
- return worker;
14094
+ encode(arrayBuffer),
14095
+ blob.type,
14096
+ width,
14097
+ height
14098
+ );
14099
+ } catch {
14100
+ } finally {
14101
+ bitmap.close();
14102
+ this.snapshotInProgressMap.set(id, false);
14103
+ }
14104
+ }
14105
+ emitCanvasSnapshot(id, base64, type, width, height) {
14106
+ this.mutationCb({
14107
+ id,
14108
+ type: CanvasContext["2D"],
14109
+ commands: [
14110
+ {
14111
+ property: "clearRect",
14112
+ // wipe canvas
14113
+ args: [0, 0, width, height]
14114
+ },
14115
+ {
14116
+ property: "drawImage",
14117
+ // draws (semi-transparent) image
14118
+ args: [
14119
+ {
14120
+ rr_type: "ImageBitmap",
14121
+ args: [
14122
+ {
14123
+ rr_type: "Blob",
14124
+ data: [{ rr_type: "ArrayBuffer", base64 }],
14125
+ type
14126
+ }
14127
+ ]
14128
+ },
14129
+ 0,
14130
+ 0
14131
+ ]
14132
+ }
14133
+ ]
14134
+ });
14120
14135
  }
14121
14136
  initCanvasFPSObserver() {
14122
14137
  let rafId;
@@ -14214,20 +14229,12 @@ class CanvasManager {
14214
14229
  context.clear(context.COLOR_BUFFER_BIT);
14215
14230
  }
14216
14231
  }
14217
- createImageBitmap(canvas).then((bitmap) => {
14218
- var _a3;
14219
- (_a3 = this.worker) == null ? void 0 : _a3.postMessage(
14220
- {
14221
- id,
14222
- bitmap,
14223
- width: canvas.width,
14224
- height: canvas.height,
14225
- dataURLOptions
14226
- },
14227
- [bitmap]
14228
- );
14229
- }).catch(() => {
14230
- this.snapshotInProgressMap.delete(id);
14232
+ const width = canvas.width;
14233
+ const height = canvas.height;
14234
+ createImageBitmap(canvas).then(
14235
+ (bitmap) => this.snapshotImageBitmap(id, bitmap, width, height, dataURLOptions)
14236
+ ).catch(() => {
14237
+ this.snapshotInProgressMap.set(id, false);
14231
14238
  });
14232
14239
  });
14233
14240
  }
@@ -15617,10 +15624,10 @@ function deserializeArg(imageMap, ctx, preload) {
15617
15624
  const blobContents = await Promise.all(
15618
15625
  arg.data.map(deserializeArg(imageMap, ctx, preload))
15619
15626
  );
15620
- const blob2 = new Blob(blobContents, {
15627
+ const blob = new Blob(blobContents, {
15621
15628
  type: arg.type
15622
15629
  });
15623
- return blob2;
15630
+ return blob;
15624
15631
  }
15625
15632
  } else if (Array.isArray(arg)) {
15626
15633
  const result2 = await Promise.all(