@screeb/rrweb 1.0.21 → 2.1.6-screeb.1

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/README.md CHANGED
@@ -1,66 +1,91 @@
1
- <p align="center">
2
- <img width="100px" height="100px" src="https://www.rrweb.io/favicon.png">
3
- </p>
4
- <p align="center">
5
- <a href="https://www.rrweb.io/" style="font-weight: bold">Try rrweb</a>
6
- </p>
7
-
8
1
  # rrweb
9
2
 
10
- **This is a simpler version of the [original rrweb README](../../README.md) within this rrweb subpackage**
3
+ ## Overview
4
+
5
+ > **Deprecated.** `rrweb` is kept for backward compatibility only. New projects should depend on [@rrweb/record](packages/record/) and [@rrweb/replay](packages/replay/) directly, or use [@rrweb/all](packages/all/) for a single convenience import. Moving to these entrypoints lets us slim down and eventually remove this package.
6
+
7
+ rrweb refers to 'record and replay the web', a tool for recording and replaying users' interactions on the web.
8
+
9
+ In most production setups, the recorder and replayer are deployed to different pages/apps. Use [@rrweb/record](packages/record/) on recorded pages and [@rrweb/replay](packages/replay/) (or [rrweb-player](packages/rrweb-player/) to include UI) on replay pages.
11
10
 
12
- [中文文档](../../README.zh_CN.md)
11
+ | Use case | Package choice |
12
+ | ----------------------------------------------- | --------------------------------- |
13
+ | Most apps (explicit record/replay dependencies) | `@rrweb/record` + `@rrweb/replay` |
14
+ | Single import for record, replay + packer | `@rrweb/all` |
13
15
 
14
- rrweb refers to 'record and replay the web', which is a tool for recording and replaying users' interactions on the web.
16
+ ### Dev Note
15
17
 
16
- ## Guide
18
+ As this was the original rrweb package, typescript code for both @rrweb/record and @rrweb/replay still lives in src/record and src/replay in this package. These will be refactored into their respective packages in due course, but for now this package is the principal one for both record and replay related PRs. See [Contributing to rrweb](../../CONTRIBUTING.md) for more info.
17
19
 
18
- [**📚 Read the rrweb guide here. 📚**](../../guide.md)
20
+ ## Installation
19
21
 
20
- [**🍳 Recipes 🍳**](../../docs/recipes/index.md)
22
+ ### 1) Bundler / npm (Recommended)
21
23
 
22
- ## Project Structure
24
+ For new projects:
23
25
 
24
- **[rrweb](https://github.com/rrweb-io/rrweb)** mainly includes two funtions:
26
+ ```shell
27
+ npm install @rrweb/record @rrweb/replay
28
+ ```
25
29
 
26
- - **Record**: The record function is used to record all the mutations in the DOM
27
- - **Replay**: The replay function is to replay the recorded mutations one by one according to the corresponding timestamp.
30
+ ```js
31
+ import { record } from '@rrweb/record';
32
+ import { Replayer } from '@rrweb/replay';
33
+ import '@rrweb/replay/dist/style.css';
34
+ ```
28
35
 
29
- ## Roadmap
36
+ Convenience single-package option:
30
37
 
31
- - storage engine: do deduplication on a large number of rrweb sessions
32
- - compact mutation data in common patterns
33
- - provide plugins via the new plugin API, including:
34
- - XHR plugin
35
- - fetch plugin
36
- - GraphQL plugin
37
- - ...
38
+ ```shell
39
+ npm install @rrweb/all
40
+ ```
38
41
 
39
- ## Internal Design
42
+ ```js
43
+ import { record, Replayer, pack, unpack } from '@rrweb/all';
44
+ import '@rrweb/all/dist/style.css';
45
+ ```
40
46
 
41
- - [serialization](../../docs/serialization.md)
42
- - [incremental snapshot](../../docs/observer.md)
43
- - [replay](../../docs/replay.md)
44
- - [sandbox](../../docs/sandbox.md)
47
+ Legacy compatibility package:
45
48
 
46
- ## Contribute Guide
49
+ ```shell
50
+ npm install rrweb
51
+ ```
47
52
 
48
- Since we want the record and replay sides to share a strongly typed data structure, rrweb is developed with typescript which provides stronger type support.
53
+ ```js
54
+ import { record, Replayer } from 'rrweb';
55
+ import 'rrweb/dist/style.css';
56
+ ```
49
57
 
50
- [Typescript handbook](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html)
58
+ ### 2) Browser Without Bundler (ESM)
51
59
 
52
- 1. Fork this repository.
53
- 2. Run `yarn install` in the root to install required dependencies for all sub-packages (note: `npm install` is _not_ recommended).
54
- 3. Run `yarn dev` in the root to get auto-building for all the sub-packages whenever you modify anything.
55
- 4. Navigate to one of the sub-packages (in the `packages` folder) where you'd like to make a change.
56
- 5. Patch the code and run `yarn test` to run the tests, make sure they pass before you commit anything.
57
- 6. Push the code and create a pull request.
60
+ ```html
61
+ <link
62
+ rel="stylesheet"
63
+ href="https://cdn.rrweb.com/replay/current/dist/style.css"
64
+ />
65
+ <script type="module">
66
+ import { record } from 'https://cdn.rrweb.com/record/current/dist/record.js';
67
+ import { Replayer } from 'https://cdn.rrweb.com/replay/current/dist/replay.js';
68
+ </script>
69
+ ```
58
70
 
59
- Protip: You can run `yarn test` in the root folder to run all the tests.
71
+ Use `current` for the latest stable release, or pin exact versions such as
72
+ `https://cdn.rrweb.com/record/2.0.0/dist/record.js` and
73
+ `https://cdn.rrweb.com/replay/2.0.0/dist/replay.js` for immutable
74
+ production URLs.
60
75
 
61
- In addition to adding integration tests and unit tests, rrweb also provides a REPL testing tool.
76
+ ### 3) Legacy Direct `<script>` Include (UMD fallback)
62
77
 
63
- [Using the REPL tool](../../guide.md#REPL-tool)
78
+ Use this only for compatibility with non-module environments; modern browsers
79
+ support the ESM method above.
80
+
81
+ ```html
82
+ <link
83
+ rel="stylesheet"
84
+ href="https://cdn.rrweb.com/replay/current/dist/style.css"
85
+ />
86
+ <script src="https://cdn.rrweb.com/record/current/dist/record.umd.cjs"></script>
87
+ <script src="https://cdn.rrweb.com/replay/current/dist/replay.umd.cjs"></script>
88
+ ```
64
89
 
65
90
  ## Sponsors
66
91
 
@@ -171,12 +196,12 @@ In addition to adding integration tests and unit tests, rrweb also provides a RE
171
196
  <tr>
172
197
  <td align="center">
173
198
  <a href="http://www.smartx.com/" target="_blank">
174
- <img width="195px" src="https://www.rrweb.io/logos/smartx.png">
199
+ <img width="195px" src="https://raw.githubusercontent.com/rrweb-io/web/HEAD/static/logos/smartx.png" alt="SmartX">
175
200
  </a>
176
201
  </td>
177
202
  <td align="center">
178
203
  <a href="https://posthog.com?utm_source=rrweb&utm_medium=sponsorship&utm_campaign=open-source-sponsorship" target="_blank">
179
- <img width="195px" src="https://www.rrweb.io/logos/posthog.png">
204
+ <img width="195px" src="https://rrweb.com/posthog.png" alt="PostHog">
180
205
  </a>
181
206
  </td>
182
207
  <td align="center">
@@ -190,7 +215,39 @@ In addition to adding integration tests and unit tests, rrweb also provides a RE
190
215
  </a>
191
216
  </td>
192
217
  </tr>
193
- <tr>
218
+ <tr>
219
+ <td align="center">
220
+ <a href="https://sentry.io" target="_blank">
221
+ <img width="195px" src="https://rrweb.com/sentry.png" alt="Sentry">
222
+ </a>
223
+ </td>
224
+ <td align="center">
225
+ <a href="https://www.pendo.io" target="_blank">
226
+ <img width="195px" src="https://rrweb.com/pendo.png" alt="Pendo">
227
+ </a>
228
+ </td>
229
+ <td align="center">
230
+ <a href="https://mixpanel.com" target="_blank">
231
+ <img width="195px" src="https://rrweb.com/mixpanel.png" alt="Mixpanel">
232
+ </a>
233
+ </td>
234
+ <td align="center">
235
+ <a href="https://www.datadoghq.com" target="_blank">
236
+ <img width="195px" src="https://rrweb.com/datadog.png" alt="Datadog">
237
+ </a>
238
+ </td>
239
+ </tr>
240
+ <tr>
241
+ <td align="center">
242
+ <a href="https://amplitude.com" target="_blank">
243
+ <img width="195px" src="https://rrweb.com/amplitude.png" alt="Amplitude">
244
+ </a>
245
+ </td>
246
+ <td align="center">
247
+ <a href="https://newrelic.com" target="_blank">
248
+ <img width="195px" src="https://rrweb.com/new%20relic.png" alt="New Relic">
249
+ </a>
250
+ </td>
194
251
  <td align="center">
195
252
  <a href="https://cux.io" target="_blank">
196
253
  <img style="padding: 8px" alt="The first ever UX automation tool" width="195px" src="https://cux.io/cux-logo.svg">
@@ -201,6 +258,8 @@ In addition to adding integration tests and unit tests, rrweb also provides a RE
201
258
  <img style="padding: 8px" alt="Remote Access & Co-Browsing" width="195px" src="https://remsupp.com/images/logo.png">
202
259
  </a>
203
260
  </td>
261
+ </tr>
262
+ <tr>
204
263
  <td align="center">
205
264
  <a href="https://highlight.io" target="_blank">
206
265
  <img style="padding: 8px" alt="The open source, fullstack Monitoring Platform." width="195px" src="https://github.com/highlight/highlight/raw/main/highlight.io/public/images/logo.png">
@@ -208,11 +267,9 @@ In addition to adding integration tests and unit tests, rrweb also provides a RE
208
267
  </td>
209
268
  <td align="center">
210
269
  <a href="https://analyzee.io" target="_blank">
211
- <img style="padding: 8px" alt="Comprehensive data analytics platform that empowers businesses to gain valuable insights and make data-driven decisions." width="195px" src="https://cdn.analyzee.io/assets/analyzee-logo.png">
270
+ <img style="padding: 8px" alt="Comprehensive data analytics platform that empowers businesses to gain valuable insights and make data-driven decisions." width="195px" src="https://analyzee.io/img/analyzee-main-logo.webp">
212
271
  </a>
213
272
  </td>
214
- </tr>
215
- <tr>
216
273
  <td align="center">
217
274
  <a href="https://requestly.io" target="_blank">
218
275
  <img style="padding: 8px" alt="Intercept, Modify, Record & Replay HTTP Requests." width="195px" src="https://github.com/requestly/requestly/assets/16779465/652552db-c867-44cb-9bb5-94a2026e04ca">
@@ -223,6 +280,8 @@ In addition to adding integration tests and unit tests, rrweb also provides a RE
223
280
  <img style="padding: 8px" alt="In-app bug reporting & customer feedback platform." width="195px" src="https://assets-global.website-files.com/6506f3f29c68b1724807619d/6506f56010237164c6306591_GleapLogo.svg">
224
281
  </a>
225
282
  </td>
283
+ </tr>
284
+ <tr>
226
285
  <td align="center">
227
286
  <a href="https://uxwizz.com" target="_blank">
228
287
  <img style="padding: 8px" alt="Self-hosted website analytics with heatmaps and session recordings." width="195px" src="https://github.com/UXWizz/public-files/raw/main/assets/logo.png">
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-bitmap-data-url-worker-IJpC7g_b.js","sources":["../../../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 '@rrweb/types';\n\nconst lastBlobMap: Map<number, string> = new Map();\nconst transparentBlobMap: Map<string, string> = new Map();\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\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 const offscreen = new OffscreenCanvas(width, height);\n const ctx = offscreen.getContext('2d')!;\n\n ctx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await offscreen.convertToBlob(dataURLOptions); // takes a while\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer); // cpu intensive\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 (!lastBlobMap.has(id) && (await transparentBase64) === base64) {\n lastBlobMap.set(id, base64);\n return worker.postMessage({ id });\n }\n\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id }); // unchanged\n worker.postMessage({\n id,\n type,\n base64,\n width,\n height,\n });\n lastBlobMap.set(id, base64);\n } else {\n return worker.postMessage({ id: e.data.id });\n }\n};\n"],"names":["i"],"mappings":";;AAKA,MAAI,QAAQ;AAEZ,MAAI,SAAS,OAAO,eAAe,cAAc,CAAA,IAAK,IAAI,WAAW,GAAG;AACxE,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,WAAO,MAAM,WAAW,CAAC,CAAC,IAAI;AAAA,EAClC;AACA,MAAI,SAAS,SAAU,aAAa;AAChC,QAAI,QAAQ,IAAI,WAAW,WAAW,GAAGA,IAAG,MAAM,MAAM,QAAQ,SAAS;AACzE,SAAKA,KAAI,GAAGA,KAAI,KAAKA,MAAK,GAAG;AACzB,gBAAU,MAAM,MAAMA,EAAC,KAAK,CAAC;AAC7B,gBAAU,OAAQ,MAAMA,EAAC,IAAI,MAAM,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAC3D,gBAAU,OAAQ,MAAMA,KAAI,CAAC,IAAI,OAAO,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAChE,gBAAU,MAAM,MAAMA,KAAI,CAAC,IAAI,EAAE;AAAA,IACzC;AACI,QAAI,MAAM,MAAM,GAAG;AACf,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IAC1D,WACa,MAAM,MAAM,GAAG;AACpB,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IAC1D;AACI,WAAO;AAAA,EACX;ACnBA,QAAM,kCAAuC,IAAI;AACjD,QAAM,yCAA8C,IAAI;AAiBxD,iBAAe,sBACb,OACA,QACA,gBACiB;AACjB,UAAM,KAAK,GAAG,KAAK,IAAI,MAAM;AAC7B,QAAI,qBAAqB,YAAY;AACnC,UAAI,mBAAmB,IAAI,EAAE,EAAU,QAAA,mBAAmB,IAAI,EAAE;AAChE,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AACnD,gBAAU,WAAW,IAAI;AACzB,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACnD,YAAA,cAAc,MAAM,KAAK,YAAY;AACrC,YAAA,SAAS,OAAO,WAAW;AACd,yBAAA,IAAI,IAAI,MAAM;AAC1B,aAAA;AAAA,IAAA,OACF;AACE,aAAA;AAAA,IAAA;AAAA,EAEX;AAGA,QAAM,SAA2C;AAGjD,SAAO,YAAY,eAAgB,GAAG;AACpC,QAAI,qBAAqB,YAAY;AACnC,YAAM,EAAE,IAAI,QAAQ,OAAO,QAAQ,eAAA,IAAmB,EAAE;AAExD,YAAM,oBAAoB;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AAC7C,YAAA,MAAM,UAAU,WAAW,IAAI;AAEjC,UAAA,UAAU,QAAQ,GAAG,CAAC;AAC1B,aAAO,MAAM;AACb,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACzD,YAAM,OAAO,KAAK;AACZ,YAAA,cAAc,MAAM,KAAK,YAAY;AACrC,YAAA,SAAS,OAAO,WAAW;AAIjC,UAAI,CAAC,YAAY,IAAI,EAAE,KAAM,MAAM,sBAAuB,QAAQ;AACpD,oBAAA,IAAI,IAAI,MAAM;AAC1B,eAAO,OAAO,YAAY,EAAE,IAAI;AAAA,MAAA;AAG9B,UAAA,YAAY,IAAI,EAAE,MAAM,eAAe,OAAO,YAAY,EAAE,IAAI;AACpE,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACW,kBAAA,IAAI,IAAI,MAAM;AAAA,IAAA,OACrB;AACL,aAAO,OAAO,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI;AAAA,IAAA;AAAA,EAE/C;;","x_google_ignoreList":[0]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-bitmap-data-url-worker-IJpC7g_b.js","sources":["../../../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 '@rrweb/types';\n\nconst lastBlobMap: Map<number, string> = new Map();\nconst transparentBlobMap: Map<string, string> = new Map();\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\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 const offscreen = new OffscreenCanvas(width, height);\n const ctx = offscreen.getContext('2d')!;\n\n ctx.drawImage(bitmap, 0, 0);\n bitmap.close();\n const blob = await offscreen.convertToBlob(dataURLOptions); // takes a while\n const type = blob.type;\n const arrayBuffer = await blob.arrayBuffer();\n const base64 = encode(arrayBuffer); // cpu intensive\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 (!lastBlobMap.has(id) && (await transparentBase64) === base64) {\n lastBlobMap.set(id, base64);\n return worker.postMessage({ id });\n }\n\n if (lastBlobMap.get(id) === base64) return worker.postMessage({ id }); // unchanged\n worker.postMessage({\n id,\n type,\n base64,\n width,\n height,\n });\n lastBlobMap.set(id, base64);\n } else {\n return worker.postMessage({ id: e.data.id });\n }\n};\n"],"names":["i"],"mappings":";;AAKA,MAAI,QAAQ;AAEZ,MAAI,SAAS,OAAO,eAAe,cAAc,CAAA,IAAK,IAAI,WAAW,GAAG;AACxE,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,WAAO,MAAM,WAAW,CAAC,CAAC,IAAI;AAAA,EAClC;AACA,MAAI,SAAS,SAAU,aAAa;AAChC,QAAI,QAAQ,IAAI,WAAW,WAAW,GAAGA,IAAG,MAAM,MAAM,QAAQ,SAAS;AACzE,SAAKA,KAAI,GAAGA,KAAI,KAAKA,MAAK,GAAG;AACzB,gBAAU,MAAM,MAAMA,EAAC,KAAK,CAAC;AAC7B,gBAAU,OAAQ,MAAMA,EAAC,IAAI,MAAM,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAC3D,gBAAU,OAAQ,MAAMA,KAAI,CAAC,IAAI,OAAO,IAAM,MAAMA,KAAI,CAAC,KAAK,CAAE;AAChE,gBAAU,MAAM,MAAMA,KAAI,CAAC,IAAI,EAAE;AAAA,IACzC;AACI,QAAI,MAAM,MAAM,GAAG;AACf,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IAC1D,WACa,MAAM,MAAM,GAAG;AACpB,eAAS,OAAO,UAAU,GAAG,OAAO,SAAS,CAAC,IAAI;AAAA,IAC1D;AACI,WAAO;AAAA,EACX;ACnBA,QAAM,kCAAuC,IAAI;AACjD,QAAM,yCAA8C,IAAI;AAiBxD,iBAAe,sBACb,OACA,QACA,gBACiB;AACjB,UAAM,KAAK,GAAG,KAAK,IAAI,MAAM;AAC7B,QAAI,qBAAqB,YAAY;AACnC,UAAI,mBAAmB,IAAI,EAAE,EAAU,QAAA,mBAAmB,IAAI,EAAE;AAChE,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AACnD,gBAAU,WAAW,IAAI;AACzB,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACnD,YAAA,cAAc,MAAM,KAAK,YAAY;AACrC,YAAA,SAAS,OAAO,WAAW;AACd,yBAAA,IAAI,IAAI,MAAM;AAC1B,aAAA;AAAA,IAAA,OACF;AACE,aAAA;AAAA,IAAA;AAAA,EAEX;AAGA,QAAM,SAA2C;AAGjD,SAAO,YAAY,eAAgB,GAAG;AACpC,QAAI,qBAAqB,YAAY;AACnC,YAAM,EAAE,IAAI,QAAQ,OAAO,QAAQ,eAAA,IAAmB,EAAE;AAExD,YAAM,oBAAoB;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AAC7C,YAAA,MAAM,UAAU,WAAW,IAAI;AAEjC,UAAA,UAAU,QAAQ,GAAG,CAAC;AAC1B,aAAO,MAAM;AACb,YAAM,OAAO,MAAM,UAAU,cAAc,cAAc;AACzD,YAAM,OAAO,KAAK;AACZ,YAAA,cAAc,MAAM,KAAK,YAAY;AACrC,YAAA,SAAS,OAAO,WAAW;AAIjC,UAAI,CAAC,YAAY,IAAI,EAAE,KAAM,MAAM,sBAAuB,QAAQ;AACpD,oBAAA,IAAI,IAAI,MAAM;AAC1B,eAAO,OAAO,YAAY,EAAE,IAAI;AAAA,MAAA;AAG9B,UAAA,YAAY,IAAI,EAAE,MAAM,eAAe,OAAO,YAAY,EAAE,IAAI;AACpE,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACW,kBAAA,IAAI,IAAI,MAAM;AAAA,IAAA,OACrB;AACL,aAAO,OAAO,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI;AAAA,IAAA;AAAA,EAE/C;;","x_google_ignoreList":[0]}