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