@highlight-run/rrweb 2.0.0-lambda.7 → 2.0.0-lambda.9

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
@@ -1875,6 +1875,7 @@ function requireStringifier$1() {
1875
1875
  hasRequiredStringifier$1 = 1;
1876
1876
  const STYLE_TAG = /(<)(\/?style\b)/gi;
1877
1877
  const COMMENT_OPEN = /(<)(!--)/g;
1878
+ const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
1878
1879
  function escapeHTMLInCSS(str) {
1879
1880
  if (typeof str !== "string") return str;
1880
1881
  if (!str.includes("<")) return str;
@@ -1900,12 +1901,13 @@ function requireStringifier$1() {
1900
1901
  function atruleStart(str, node2) {
1901
1902
  let name = "@" + node2.name;
1902
1903
  let params = node2.params ? str.rawValue(node2, "params") : "";
1903
- if (typeof node2.raws.afterName !== "undefined") {
1904
- name += node2.raws.afterName;
1905
- } else if (params) {
1906
- name += " ";
1904
+ let afterName = node2.raws.afterName;
1905
+ if (typeof afterName === "undefined") {
1906
+ afterName = params ? " " : "";
1907
+ } else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
1908
+ afterName = " ";
1907
1909
  }
1908
- return name + params;
1910
+ return name + afterName + params;
1909
1911
  }
1910
1912
  function pushBody(str, stack, node2) {
1911
1913
  let nodes = node2.nodes;
@@ -1917,10 +1919,15 @@ function requireStringifier$1() {
1917
1919
  let semicolon = str.raw(node2, "semicolon");
1918
1920
  let isDocument = node2.type === "document";
1919
1921
  for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
1922
+ let child = nodes[i2];
1923
+ let childSemicolon = last !== i2 || semicolon;
1924
+ if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
1925
+ childSemicolon = true;
1926
+ }
1920
1927
  stack.push({
1921
1928
  document: isDocument,
1922
- node: nodes[i2],
1923
- semicolon: last !== i2 || semicolon
1929
+ node: child,
1930
+ semicolon: childSemicolon
1924
1931
  });
1925
1932
  }
1926
1933
  }
@@ -2211,6 +2218,9 @@ function requireStringifier$1() {
2211
2218
  return value;
2212
2219
  }
2213
2220
  root(node2) {
2221
+ if (node2.source && node2.source.input.hasBOM) {
2222
+ this.builder("\uFEFF", node2, "start");
2223
+ }
2214
2224
  this.body(node2);
2215
2225
  if (node2.raws.after) {
2216
2226
  let after = node2.raws.after;
@@ -3283,15 +3293,12 @@ function requirePreviousMap$1() {
3283
3293
  }
3284
3294
  loadFile(path, cssFile, trusted) {
3285
3295
  if (!trusted && !this.unsafeMap) {
3286
- if (!/\.map$/i.test(path)) {
3296
+ if (!/\.map$/i.test(path)) return void 0;
3297
+ if (!cssFile) return void 0;
3298
+ let rel = relative(dirname(cssFile), path);
3299
+ if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
3287
3300
  return void 0;
3288
3301
  }
3289
- if (cssFile) {
3290
- let relativePath = relative(dirname(cssFile), path);
3291
- if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
3292
- return void 0;
3293
- }
3294
- }
3295
3302
  }
3296
3303
  this.root = dirname(path);
3297
3304
  if (existsSync(path)) {
@@ -3663,6 +3670,7 @@ function requireList$1() {
3663
3670
  return list.split(string, spaces);
3664
3671
  },
3665
3672
  split(string, separators, last) {
3673
+ if (!string) return [];
3666
3674
  let array = [];
3667
3675
  let current = "";
3668
3676
  let split = false;
@@ -4949,11 +4957,16 @@ var hasRequiredWarning$1;
4949
4957
  function requireWarning$1() {
4950
4958
  if (hasRequiredWarning$1) return warning$1;
4951
4959
  hasRequiredWarning$1 = 1;
4960
+ let Container = requireContainer$1();
4961
+ let { my } = requireSymbols$1();
4952
4962
  class Warning {
4953
4963
  constructor(text, opts = {}) {
4954
4964
  this.type = "warning";
4955
4965
  this.text = text;
4956
4966
  if (opts.node && opts.node.source) {
4967
+ if (!opts.node[my]) {
4968
+ Container.rebuild(opts.node);
4969
+ }
4957
4970
  let range = opts.node.rangeBy(opts);
4958
4971
  this.line = range.start.line;
4959
4972
  this.column = range.start.column;
@@ -5463,14 +5476,19 @@ function requireLazyResult$1() {
5463
5476
  }
5464
5477
  if (visit2.iterator !== 0) {
5465
5478
  let iterator = visit2.iterator;
5479
+ if (visit2.descending) {
5480
+ visit2.descending = false;
5481
+ node2.indexes[iterator] += 1;
5482
+ }
5466
5483
  let child;
5467
5484
  while (child = node2.nodes[node2.indexes[iterator]]) {
5468
- node2.indexes[iterator] += 1;
5469
5485
  if (!child[isClean]) {
5470
5486
  child[isClean] = true;
5487
+ visit2.descending = true;
5471
5488
  stack.push(toStack(child));
5472
5489
  return;
5473
5490
  }
5491
+ node2.indexes[iterator] += 1;
5474
5492
  }
5475
5493
  visit2.iterator = 0;
5476
5494
  delete node2.indexes[iterator];
@@ -5500,12 +5518,16 @@ function requireLazyResult$1() {
5500
5518
  let visitNode = visit2.node;
5501
5519
  if (visit2.iterator !== 0) {
5502
5520
  let iterator = visit2.iterator;
5521
+ if (visit2.descending) {
5522
+ visit2.descending = false;
5523
+ visitNode.indexes[iterator] += 1;
5524
+ }
5503
5525
  let child;
5504
5526
  let descended = false;
5505
5527
  while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
5506
- visitNode.indexes[iterator] += 1;
5507
5528
  if (!child[isClean]) {
5508
5529
  child[isClean] = true;
5530
+ visit2.descending = true;
5509
5531
  stack.push({
5510
5532
  eventIndex: 0,
5511
5533
  events: getEvents(child),
@@ -5515,6 +5537,7 @@ function requireLazyResult$1() {
5515
5537
  descended = true;
5516
5538
  break;
5517
5539
  }
5540
+ visitNode.indexes[iterator] += 1;
5518
5541
  }
5519
5542
  if (descended) continue;
5520
5543
  visit2.iterator = 0;
@@ -5677,7 +5700,7 @@ function requireProcessor$1() {
5677
5700
  let Root = requireRoot$1();
5678
5701
  class Processor {
5679
5702
  constructor(plugins = []) {
5680
- this.version = "8.5.19";
5703
+ this.version = "8.5.25";
5681
5704
  this.plugins = this.normalize(plugins);
5682
5705
  }
5683
5706
  normalize(plugins) {
@@ -6544,6 +6567,7 @@ function requireStringifier() {
6544
6567
  hasRequiredStringifier = 1;
6545
6568
  const STYLE_TAG = /(<)(\/?style\b)/gi;
6546
6569
  const COMMENT_OPEN = /(<)(!--)/g;
6570
+ const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
6547
6571
  function escapeHTMLInCSS(str) {
6548
6572
  if (typeof str !== "string") return str;
6549
6573
  if (!str.includes("<")) return str;
@@ -6569,12 +6593,13 @@ function requireStringifier() {
6569
6593
  function atruleStart(str, node2) {
6570
6594
  let name = "@" + node2.name;
6571
6595
  let params = node2.params ? str.rawValue(node2, "params") : "";
6572
- if (typeof node2.raws.afterName !== "undefined") {
6573
- name += node2.raws.afterName;
6574
- } else if (params) {
6575
- name += " ";
6596
+ let afterName = node2.raws.afterName;
6597
+ if (typeof afterName === "undefined") {
6598
+ afterName = params ? " " : "";
6599
+ } else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
6600
+ afterName = " ";
6576
6601
  }
6577
- return name + params;
6602
+ return name + afterName + params;
6578
6603
  }
6579
6604
  function pushBody(str, stack, node2) {
6580
6605
  let nodes = node2.nodes;
@@ -6586,10 +6611,15 @@ function requireStringifier() {
6586
6611
  let semicolon = str.raw(node2, "semicolon");
6587
6612
  let isDocument = node2.type === "document";
6588
6613
  for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
6614
+ let child = nodes[i2];
6615
+ let childSemicolon = last !== i2 || semicolon;
6616
+ if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
6617
+ childSemicolon = true;
6618
+ }
6589
6619
  stack.push({
6590
6620
  document: isDocument,
6591
- node: nodes[i2],
6592
- semicolon: last !== i2 || semicolon
6621
+ node: child,
6622
+ semicolon: childSemicolon
6593
6623
  });
6594
6624
  }
6595
6625
  }
@@ -6880,6 +6910,9 @@ function requireStringifier() {
6880
6910
  return value;
6881
6911
  }
6882
6912
  root(node2) {
6913
+ if (node2.source && node2.source.input.hasBOM) {
6914
+ this.builder("\uFEFF", node2, "start");
6915
+ }
6883
6916
  this.body(node2);
6884
6917
  if (node2.raws.after) {
6885
6918
  let after = node2.raws.after;
@@ -7952,15 +7985,12 @@ function requirePreviousMap() {
7952
7985
  }
7953
7986
  loadFile(path, cssFile, trusted) {
7954
7987
  if (!trusted && !this.unsafeMap) {
7955
- if (!/\.map$/i.test(path)) {
7988
+ if (!/\.map$/i.test(path)) return void 0;
7989
+ if (!cssFile) return void 0;
7990
+ let rel = relative(dirname(cssFile), path);
7991
+ if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
7956
7992
  return void 0;
7957
7993
  }
7958
- if (cssFile) {
7959
- let relativePath = relative(dirname(cssFile), path);
7960
- if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
7961
- return void 0;
7962
- }
7963
- }
7964
7994
  }
7965
7995
  this.root = dirname(path);
7966
7996
  if (existsSync(path)) {
@@ -8332,6 +8362,7 @@ function requireList() {
8332
8362
  return list.split(string, spaces);
8333
8363
  },
8334
8364
  split(string, separators, last) {
8365
+ if (!string) return [];
8335
8366
  let array = [];
8336
8367
  let current = "";
8337
8368
  let split = false;
@@ -9618,11 +9649,16 @@ var hasRequiredWarning;
9618
9649
  function requireWarning() {
9619
9650
  if (hasRequiredWarning) return warning;
9620
9651
  hasRequiredWarning = 1;
9652
+ let Container = requireContainer();
9653
+ let { my } = requireSymbols();
9621
9654
  class Warning {
9622
9655
  constructor(text, opts = {}) {
9623
9656
  this.type = "warning";
9624
9657
  this.text = text;
9625
9658
  if (opts.node && opts.node.source) {
9659
+ if (!opts.node[my]) {
9660
+ Container.rebuild(opts.node);
9661
+ }
9626
9662
  let range = opts.node.rangeBy(opts);
9627
9663
  this.line = range.start.line;
9628
9664
  this.column = range.start.column;
@@ -10132,14 +10168,19 @@ function requireLazyResult() {
10132
10168
  }
10133
10169
  if (visit2.iterator !== 0) {
10134
10170
  let iterator = visit2.iterator;
10171
+ if (visit2.descending) {
10172
+ visit2.descending = false;
10173
+ node2.indexes[iterator] += 1;
10174
+ }
10135
10175
  let child;
10136
10176
  while (child = node2.nodes[node2.indexes[iterator]]) {
10137
- node2.indexes[iterator] += 1;
10138
10177
  if (!child[isClean]) {
10139
10178
  child[isClean] = true;
10179
+ visit2.descending = true;
10140
10180
  stack.push(toStack(child));
10141
10181
  return;
10142
10182
  }
10183
+ node2.indexes[iterator] += 1;
10143
10184
  }
10144
10185
  visit2.iterator = 0;
10145
10186
  delete node2.indexes[iterator];
@@ -10169,12 +10210,16 @@ function requireLazyResult() {
10169
10210
  let visitNode = visit2.node;
10170
10211
  if (visit2.iterator !== 0) {
10171
10212
  let iterator = visit2.iterator;
10213
+ if (visit2.descending) {
10214
+ visit2.descending = false;
10215
+ visitNode.indexes[iterator] += 1;
10216
+ }
10172
10217
  let child;
10173
10218
  let descended = false;
10174
10219
  while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
10175
- visitNode.indexes[iterator] += 1;
10176
10220
  if (!child[isClean]) {
10177
10221
  child[isClean] = true;
10222
+ visit2.descending = true;
10178
10223
  stack.push({
10179
10224
  eventIndex: 0,
10180
10225
  events: getEvents(child),
@@ -10184,6 +10229,7 @@ function requireLazyResult() {
10184
10229
  descended = true;
10185
10230
  break;
10186
10231
  }
10232
+ visitNode.indexes[iterator] += 1;
10187
10233
  }
10188
10234
  if (descended) continue;
10189
10235
  visit2.iterator = 0;
@@ -10346,7 +10392,7 @@ function requireProcessor() {
10346
10392
  let Root = requireRoot();
10347
10393
  class Processor {
10348
10394
  constructor(plugins = []) {
10349
- this.version = "8.5.19";
10395
+ this.version = "8.5.25";
10350
10396
  this.plugins = this.normalize(plugins);
10351
10397
  }
10352
10398
  normalize(plugins) {
@@ -13628,66 +13674,142 @@ function getIdAndStyleId(sheet, mirror2, styleMirror) {
13628
13674
  id
13629
13675
  };
13630
13676
  }
13631
- function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetManager }, { win }) {
13677
+ function restorePatchedMethod(target, key, ours, restoreTo) {
13678
+ if (target[key] === ours) {
13679
+ target[key] = restoreTo;
13680
+ }
13681
+ }
13682
+ const MAX_CSSOM_REPATCH_ATTEMPTS = 5;
13683
+ function initStyleSheetObserver({
13684
+ styleSheetRuleCb,
13685
+ mirror: mirror2,
13686
+ stylesheetManager,
13687
+ doc,
13688
+ styleSheetResyncInterval
13689
+ }, { win }) {
13632
13690
  if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
13633
13691
  return () => {
13634
13692
  };
13635
13693
  }
13636
- const insertRule = win.CSSStyleSheet.prototype.insertRule;
13637
- win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
13694
+ const reportedRuleCounts = /* @__PURE__ */ new WeakMap();
13695
+ const unreconcilableSheets = /* @__PURE__ */ new WeakSet();
13696
+ let probing = false;
13697
+ let probeInsertObserved = false;
13698
+ let probeDeleteObserved = false;
13699
+ let probeSheet;
13700
+ let stopped = false;
13701
+ let insideInsertRule = false;
13702
+ let insideDeleteRule = false;
13703
+ const noteReportedRules = (sheet, delta) => {
13704
+ const state = reportedRuleCounts.get(sheet);
13705
+ if (state) {
13706
+ state.reported = Math.max(0, state.reported + delta);
13707
+ state.everSeen = Math.max(state.everSeen, state.reported);
13708
+ }
13709
+ };
13710
+ const patchInsertRule = (target) => new Proxy(target, {
13638
13711
  apply: callbackWrapper(
13639
- (target, thisArg, argumentsList) => {
13712
+ (nativeFn, thisArg, argumentsList) => {
13713
+ if (probing) {
13714
+ probeInsertObserved = true;
13715
+ return nativeFn.apply(thisArg, argumentsList);
13716
+ }
13717
+ if (stopped || insideInsertRule) {
13718
+ return nativeFn.apply(thisArg, argumentsList);
13719
+ }
13640
13720
  const [rule2, index2] = argumentsList;
13641
13721
  const { id, styleId } = getIdAndStyleId(
13642
13722
  thisArg,
13643
13723
  mirror2,
13644
13724
  stylesheetManager.styleMirror
13645
13725
  );
13646
- if (id && id !== -1 || styleId && styleId !== -1) {
13726
+ const reported = id && id !== -1 || styleId && styleId !== -1;
13727
+ if (reported) {
13647
13728
  styleSheetRuleCb({
13648
13729
  id,
13649
13730
  styleId,
13650
13731
  adds: [{ rule: rule2, index: index2 }]
13651
13732
  });
13652
13733
  }
13653
- return target.apply(thisArg, argumentsList);
13734
+ insideInsertRule = true;
13735
+ let result2;
13736
+ try {
13737
+ result2 = nativeFn.apply(thisArg, argumentsList);
13738
+ } finally {
13739
+ insideInsertRule = false;
13740
+ }
13741
+ if (reported) {
13742
+ noteReportedRules(thisArg, 1);
13743
+ }
13744
+ return result2;
13654
13745
  }
13655
13746
  )
13656
13747
  });
13657
- win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {
13658
- const rule2 = `${selector} { ${styleBlock} }`;
13659
- return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
13660
- };
13661
- const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
13662
- win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
13748
+ const patchDeleteRule = (target) => new Proxy(target, {
13663
13749
  apply: callbackWrapper(
13664
- (target, thisArg, argumentsList) => {
13750
+ (nativeFn, thisArg, argumentsList) => {
13751
+ if (probing) {
13752
+ probeDeleteObserved = true;
13753
+ return nativeFn.apply(thisArg, argumentsList);
13754
+ }
13755
+ if (stopped || insideDeleteRule) {
13756
+ return nativeFn.apply(thisArg, argumentsList);
13757
+ }
13665
13758
  const [index2] = argumentsList;
13666
13759
  const { id, styleId } = getIdAndStyleId(
13667
13760
  thisArg,
13668
13761
  mirror2,
13669
13762
  stylesheetManager.styleMirror
13670
13763
  );
13671
- if (id && id !== -1 || styleId && styleId !== -1) {
13764
+ const reported = id && id !== -1 || styleId && styleId !== -1;
13765
+ if (reported) {
13672
13766
  styleSheetRuleCb({
13673
13767
  id,
13674
13768
  styleId,
13675
13769
  removes: [{ index: index2 }]
13676
13770
  });
13677
13771
  }
13678
- return target.apply(thisArg, argumentsList);
13772
+ insideDeleteRule = true;
13773
+ let result2;
13774
+ try {
13775
+ result2 = nativeFn.apply(thisArg, argumentsList);
13776
+ } finally {
13777
+ insideDeleteRule = false;
13778
+ }
13779
+ if (reported) {
13780
+ noteReportedRules(thisArg, -1);
13781
+ }
13782
+ return result2;
13679
13783
  }
13680
13784
  )
13681
13785
  });
13682
- win.CSSStyleSheet.prototype.removeRule = function(index2) {
13786
+ const insertRule = win.CSSStyleSheet.prototype.insertRule;
13787
+ let insertRuleProxy = patchInsertRule(insertRule);
13788
+ let restoreInsertRuleTo = insertRule;
13789
+ win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
13790
+ const addRule = win.CSSStyleSheet.prototype.addRule;
13791
+ const addRuleShim = function(selector, styleBlock, index2 = this.cssRules.length) {
13792
+ const rule2 = `${selector} { ${styleBlock} }`;
13793
+ return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
13794
+ };
13795
+ win.CSSStyleSheet.prototype.addRule = addRuleShim;
13796
+ const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
13797
+ let deleteRuleProxy = patchDeleteRule(deleteRule);
13798
+ let restoreDeleteRuleTo = deleteRule;
13799
+ win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
13800
+ const removeRule = win.CSSStyleSheet.prototype.removeRule;
13801
+ const removeRuleShim = function(index2) {
13683
13802
  return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
13684
13803
  };
13804
+ win.CSSStyleSheet.prototype.removeRule = removeRuleShim;
13685
13805
  let replace;
13806
+ let replaceProxy;
13686
13807
  if (win.CSSStyleSheet.prototype.replace) {
13687
13808
  replace = win.CSSStyleSheet.prototype.replace;
13688
- win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
13809
+ replaceProxy = new Proxy(replace, {
13689
13810
  apply: callbackWrapper(
13690
13811
  (target, thisArg, argumentsList) => {
13812
+ if (stopped) return target.apply(thisArg, argumentsList);
13691
13813
  const [text] = argumentsList;
13692
13814
  const { id, styleId } = getIdAndStyleId(
13693
13815
  thisArg,
@@ -13705,13 +13827,16 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13705
13827
  }
13706
13828
  )
13707
13829
  });
13830
+ win.CSSStyleSheet.prototype.replace = replaceProxy;
13708
13831
  }
13709
13832
  let replaceSync;
13833
+ let replaceSyncProxy;
13710
13834
  if (win.CSSStyleSheet.prototype.replaceSync) {
13711
13835
  replaceSync = win.CSSStyleSheet.prototype.replaceSync;
13712
- win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
13836
+ replaceSyncProxy = new Proxy(replaceSync, {
13713
13837
  apply: callbackWrapper(
13714
13838
  (target, thisArg, argumentsList) => {
13839
+ if (stopped) return target.apply(thisArg, argumentsList);
13715
13840
  const [text] = argumentsList;
13716
13841
  const { id, styleId } = getIdAndStyleId(
13717
13842
  thisArg,
@@ -13729,6 +13854,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13729
13854
  }
13730
13855
  )
13731
13856
  });
13857
+ win.CSSStyleSheet.prototype.replaceSync = replaceSyncProxy;
13732
13858
  }
13733
13859
  const supportedNestedCSSRuleTypes = {};
13734
13860
  if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
@@ -13745,6 +13871,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13745
13871
  }
13746
13872
  }
13747
13873
  const unmodifiedFunctions = {};
13874
+ const nestedProxies = {};
13748
13875
  Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
13749
13876
  unmodifiedFunctions[typeKey] = {
13750
13877
  // eslint-disable-next-line @typescript-eslint/unbound-method
@@ -13752,11 +13879,13 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13752
13879
  // eslint-disable-next-line @typescript-eslint/unbound-method
13753
13880
  deleteRule: type.prototype.deleteRule
13754
13881
  };
13755
- type.prototype.insertRule = new Proxy(
13882
+ nestedProxies[typeKey] = {};
13883
+ nestedProxies[typeKey].insertRule = new Proxy(
13756
13884
  unmodifiedFunctions[typeKey].insertRule,
13757
13885
  {
13758
13886
  apply: callbackWrapper(
13759
13887
  (target, thisArg, argumentsList) => {
13888
+ if (stopped) return target.apply(thisArg, argumentsList);
13760
13889
  const [rule2, index2] = argumentsList;
13761
13890
  const { id, styleId } = getIdAndStyleId(
13762
13891
  thisArg.parentStyleSheet,
@@ -13784,11 +13913,12 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13784
13913
  )
13785
13914
  }
13786
13915
  );
13787
- type.prototype.deleteRule = new Proxy(
13916
+ nestedProxies[typeKey].deleteRule = new Proxy(
13788
13917
  unmodifiedFunctions[typeKey].deleteRule,
13789
13918
  {
13790
13919
  apply: callbackWrapper(
13791
13920
  (target, thisArg, argumentsList) => {
13921
+ if (stopped) return target.apply(thisArg, argumentsList);
13792
13922
  const [index2] = argumentsList;
13793
13923
  const { id, styleId } = getIdAndStyleId(
13794
13924
  thisArg.parentStyleSheet,
@@ -13809,15 +13939,148 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
13809
13939
  )
13810
13940
  }
13811
13941
  );
13942
+ type.prototype.insertRule = nestedProxies[typeKey].insertRule;
13943
+ type.prototype.deleteRule = nestedProxies[typeKey].deleteRule;
13812
13944
  });
13945
+ const captureIsHealthy = () => {
13946
+ probing = true;
13947
+ probeInsertObserved = false;
13948
+ probeDeleteObserved = false;
13949
+ try {
13950
+ const probe = probeSheet ?? (probeSheet = new win.CSSStyleSheet());
13951
+ probe.insertRule(":root {}", 0);
13952
+ probe.deleteRule(0);
13953
+ } catch (error) {
13954
+ return {
13955
+ insertRule: win.CSSStyleSheet.prototype.insertRule === insertRuleProxy,
13956
+ deleteRule: win.CSSStyleSheet.prototype.deleteRule === deleteRuleProxy
13957
+ };
13958
+ } finally {
13959
+ probing = false;
13960
+ }
13961
+ return {
13962
+ insertRule: probeInsertObserved,
13963
+ deleteRule: probeDeleteObserved
13964
+ };
13965
+ };
13966
+ let repatchAttempts = 0;
13967
+ const repatch = (health) => {
13968
+ if (repatchAttempts >= MAX_CSSOM_REPATCH_ATTEMPTS) return;
13969
+ repatchAttempts += 1;
13970
+ if (!health.insertRule) {
13971
+ restoreInsertRuleTo = win.CSSStyleSheet.prototype.insertRule;
13972
+ insertRuleProxy = patchInsertRule(restoreInsertRuleTo);
13973
+ win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
13974
+ }
13975
+ if (!health.deleteRule) {
13976
+ restoreDeleteRuleTo = win.CSSStyleSheet.prototype.deleteRule;
13977
+ deleteRuleProxy = patchDeleteRule(restoreDeleteRuleTo);
13978
+ win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
13979
+ }
13980
+ };
13981
+ const resyncCssomStyleSheets = (trusted) => {
13982
+ for (let i2 = 0; i2 < doc.styleSheets.length; i2++) {
13983
+ const sheet = doc.styleSheets[i2];
13984
+ if (unreconcilableSheets.has(sheet)) continue;
13985
+ const owner = sheet.ownerNode;
13986
+ if (!owner || toLowerCase(owner.nodeName) !== "style") continue;
13987
+ if ((owner.textContent || "").trim().length) continue;
13988
+ const id = mirror2.getId(owner);
13989
+ if (!id || id === -1) continue;
13990
+ let rules2;
13991
+ try {
13992
+ rules2 = sheet.cssRules;
13993
+ } catch (error) {
13994
+ continue;
13995
+ }
13996
+ const live = rules2.length;
13997
+ let state = reportedRuleCounts.get(sheet);
13998
+ if (!state) {
13999
+ if (Array.from(rules2).some((rule2) => isCSSImportRule(rule2))) {
14000
+ unreconcilableSheets.add(sheet);
14001
+ continue;
14002
+ }
14003
+ state = { reported: live, everSeen: live };
14004
+ reportedRuleCounts.set(sheet, state);
14005
+ if (trusted) continue;
14006
+ replaceReplayerCopy(id, state, rules2);
14007
+ continue;
14008
+ }
14009
+ state.everSeen = Math.max(state.everSeen, live);
14010
+ if (live === state.reported) continue;
14011
+ if (live > state.reported) {
14012
+ const adds = [];
14013
+ for (let index2 = state.reported; index2 < live; index2++) {
14014
+ adds.push({ rule: rules2[index2].cssText, index: index2 });
14015
+ }
14016
+ styleSheetRuleCb({ id, adds });
14017
+ state.reported = live;
14018
+ } else {
14019
+ replaceReplayerCopy(id, state, rules2);
14020
+ }
14021
+ }
14022
+ };
14023
+ function replaceReplayerCopy(id, state, rules2) {
14024
+ const removes = [];
14025
+ for (let index2 = state.everSeen - 1; index2 >= 0; index2--) {
14026
+ removes.push({ index: index2 });
14027
+ }
14028
+ if (removes.length) styleSheetRuleCb({ id, removes });
14029
+ styleSheetRuleCb({
14030
+ id,
14031
+ adds: Array.from(rules2, (rule2, index2) => ({
14032
+ rule: rule2.cssText,
14033
+ index: index2
14034
+ }))
14035
+ });
14036
+ state.reported = rules2.length;
14037
+ state.everSeen = rules2.length;
14038
+ }
14039
+ let resyncTimer;
14040
+ if (styleSheetResyncInterval > 0) {
14041
+ resyncTimer = win.setInterval(
14042
+ callbackWrapper(() => {
14043
+ const health = captureIsHealthy();
14044
+ const healthy = health.insertRule && health.deleteRule;
14045
+ if (!healthy) repatch(health);
14046
+ resyncCssomStyleSheets(healthy);
14047
+ }),
14048
+ styleSheetResyncInterval
14049
+ );
14050
+ }
13813
14051
  return callbackWrapper(() => {
13814
- win.CSSStyleSheet.prototype.insertRule = insertRule;
13815
- win.CSSStyleSheet.prototype.deleteRule = deleteRule;
13816
- replace && (win.CSSStyleSheet.prototype.replace = replace);
13817
- replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);
14052
+ if (resyncTimer !== void 0) win.clearInterval(resyncTimer);
14053
+ stopped = true;
14054
+ const proto = win.CSSStyleSheet.prototype;
14055
+ restorePatchedMethod(
14056
+ proto,
14057
+ "insertRule",
14058
+ insertRuleProxy,
14059
+ restoreInsertRuleTo
14060
+ );
14061
+ restorePatchedMethod(
14062
+ proto,
14063
+ "deleteRule",
14064
+ deleteRuleProxy,
14065
+ restoreDeleteRuleTo
14066
+ );
14067
+ restorePatchedMethod(proto, "addRule", addRuleShim, addRule);
14068
+ restorePatchedMethod(proto, "removeRule", removeRuleShim, removeRule);
14069
+ replaceProxy && restorePatchedMethod(proto, "replace", replaceProxy, replace);
14070
+ replaceSyncProxy && restorePatchedMethod(proto, "replaceSync", replaceSyncProxy, replaceSync);
13818
14071
  Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
13819
- type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
13820
- type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
14072
+ restorePatchedMethod(
14073
+ type.prototype,
14074
+ "insertRule",
14075
+ nestedProxies[typeKey].insertRule,
14076
+ unmodifiedFunctions[typeKey].insertRule
14077
+ );
14078
+ restorePatchedMethod(
14079
+ type.prototype,
14080
+ "deleteRule",
14081
+ nestedProxies[typeKey].deleteRule,
14082
+ unmodifiedFunctions[typeKey].deleteRule
14083
+ );
13821
14084
  });
13822
14085
  });
13823
14086
  }
@@ -15585,6 +15848,7 @@ function record(options = {}) {
15585
15848
  keepIframeSrcFn = () => false,
15586
15849
  privacySetting = "default",
15587
15850
  ignoreCSSAttributes = /* @__PURE__ */ new Set([]),
15851
+ styleSheetResyncInterval = 2e3,
15588
15852
  errorHandler: errorHandler2,
15589
15853
  logger
15590
15854
  } = options;
@@ -15963,6 +16227,7 @@ function record(options = {}) {
15963
16227
  processedNodeManager,
15964
16228
  canvasManager,
15965
16229
  ignoreCSSAttributes,
16230
+ styleSheetResyncInterval,
15966
16231
  privacySetting,
15967
16232
  plugins: ((_a3 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a3.map((p) => ({
15968
16233
  observer: p.observer,
@@ -16849,12 +17114,36 @@ function variableListFor(ctx, ctor) {
16849
17114
  }
16850
17115
  return contextMap.get(ctor);
16851
17116
  }
16852
- function deserializeArg(imageMap, ctx, preload) {
17117
+ const canvasArgConstructors = /* @__PURE__ */ new Set([
17118
+ "Int8Array",
17119
+ "Int16Array",
17120
+ "Int32Array",
17121
+ "Uint8Array",
17122
+ "Uint8ClampedArray",
17123
+ "Uint16Array",
17124
+ "Uint32Array",
17125
+ "Float32Array",
17126
+ "Float64Array",
17127
+ "DataView",
17128
+ "ImageData",
17129
+ // normally serialized as base64, but reachable in `args` form through
17130
+ // recordings made by older clients and through nested `DataView` args.
17131
+ "ArrayBuffer",
17132
+ // wraps nested args in recordings made by older clients — see the
17133
+ // `preloadAllImages` tests for the shape.
17134
+ "Array"
17135
+ ]);
17136
+ function deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist = false) {
16853
17137
  return async (arg) => {
16854
17138
  if (arg && typeof arg === "object" && "rr_type" in arg) {
16855
17139
  if (preload) preload.isUnchanged = false;
16856
17140
  if (arg.rr_type === "ImageBitmap" && "args" in arg) {
16857
- const args = await deserializeArg(imageMap, ctx, preload)(arg.args);
17141
+ const args = await deserializeArg(
17142
+ imageMap,
17143
+ ctx,
17144
+ preload,
17145
+ enforceCanvasArgAllowlist
17146
+ )(arg.args);
16858
17147
  return await createImageBitmap.apply(null, args);
16859
17148
  } else if ("index" in arg) {
16860
17149
  if (preload || ctx === null) return arg;
@@ -16862,10 +17151,18 @@ function deserializeArg(imageMap, ctx, preload) {
16862
17151
  return variableListFor(ctx, name)[index2];
16863
17152
  } else if ("args" in arg) {
16864
17153
  const { rr_type: name, args } = arg;
17154
+ if (enforceCanvasArgAllowlist && !canvasArgConstructors.has(name)) {
17155
+ console.warn(
17156
+ `[replayer] refusing to construct canvas arg of unknown type: ${name}`
17157
+ );
17158
+ return null;
17159
+ }
16865
17160
  const ctor = window[name];
16866
17161
  return new ctor(
16867
17162
  ...await Promise.all(
16868
- args.map(deserializeArg(imageMap, ctx, preload))
17163
+ args.map(
17164
+ deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
17165
+ )
16869
17166
  )
16870
17167
  );
16871
17168
  } else if ("base64" in arg) {
@@ -16882,7 +17179,9 @@ function deserializeArg(imageMap, ctx, preload) {
16882
17179
  }
16883
17180
  } else if ("data" in arg && arg.rr_type === "Blob") {
16884
17181
  const blobContents = await Promise.all(
16885
- arg.data.map(deserializeArg(imageMap, ctx, preload))
17182
+ arg.data.map(
17183
+ deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
17184
+ )
16886
17185
  );
16887
17186
  const blob2 = new Blob(blobContents, {
16888
17187
  type: arg.type
@@ -16891,7 +17190,9 @@ function deserializeArg(imageMap, ctx, preload) {
16891
17190
  }
16892
17191
  } else if (Array.isArray(arg)) {
16893
17192
  const result2 = await Promise.all(
16894
- arg.map(deserializeArg(imageMap, ctx, preload))
17193
+ arg.map(
17194
+ deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
17195
+ )
16895
17196
  );
16896
17197
  return result2;
16897
17198
  }
@@ -16932,7 +17233,8 @@ async function webglMutation({
16932
17233
  target,
16933
17234
  type,
16934
17235
  imageMap,
16935
- errorHandler: errorHandler2
17236
+ errorHandler: errorHandler2,
17237
+ enforceCanvasArgAllowlist
16936
17238
  }) {
16937
17239
  try {
16938
17240
  const ctx = getContext(target, type);
@@ -16943,7 +17245,9 @@ async function webglMutation({
16943
17245
  }
16944
17246
  const original = ctx[mutation.property];
16945
17247
  const args = await Promise.all(
16946
- mutation.args.map(deserializeArg(imageMap, ctx))
17248
+ mutation.args.map(
17249
+ deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
17250
+ )
16947
17251
  );
16948
17252
  const result2 = original.apply(ctx, args);
16949
17253
  saveToWebGLVarMap(ctx, result2);
@@ -16958,7 +17262,8 @@ async function canvasMutation$1({
16958
17262
  mutations,
16959
17263
  target,
16960
17264
  imageMap,
16961
- errorHandler: errorHandler2
17265
+ errorHandler: errorHandler2,
17266
+ enforceCanvasArgAllowlist
16962
17267
  }) {
16963
17268
  const ctx = target.getContext("2d");
16964
17269
  if (!ctx) {
@@ -16968,7 +17273,11 @@ async function canvasMutation$1({
16968
17273
  wrapCanvasContextDrawImage(ctx);
16969
17274
  const mutationArgsPromises = mutations.map(
16970
17275
  async (mutation) => {
16971
- return Promise.all(mutation.args.map(deserializeArg(imageMap, ctx)));
17276
+ return Promise.all(
17277
+ mutation.args.map(
17278
+ deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
17279
+ )
17280
+ );
16972
17281
  }
16973
17282
  );
16974
17283
  const args = await Promise.all(mutationArgsPromises);
@@ -16998,7 +17307,8 @@ async function canvasMutation({
16998
17307
  target,
16999
17308
  imageMap,
17000
17309
  canvasEventMap,
17001
- errorHandler: errorHandler2
17310
+ errorHandler: errorHandler2,
17311
+ enforceCanvasArgAllowlist
17002
17312
  }) {
17003
17313
  try {
17004
17314
  const precomputedMutation = canvasEventMap.get(event) || mutation;
@@ -17011,7 +17321,8 @@ async function canvasMutation({
17011
17321
  type: mutation.type,
17012
17322
  target,
17013
17323
  imageMap,
17014
- errorHandler: errorHandler2
17324
+ errorHandler: errorHandler2,
17325
+ enforceCanvasArgAllowlist
17015
17326
  });
17016
17327
  }
17017
17328
  return;
@@ -17021,7 +17332,8 @@ async function canvasMutation({
17021
17332
  mutations: commands,
17022
17333
  target,
17023
17334
  imageMap,
17024
- errorHandler: errorHandler2
17335
+ errorHandler: errorHandler2,
17336
+ enforceCanvasArgAllowlist
17025
17337
  });
17026
17338
  } catch (error) {
17027
17339
  errorHandler2(mutation, error);
@@ -17464,6 +17776,7 @@ class Replayer {
17464
17776
  insertStyleRules: [],
17465
17777
  triggerFocus: true,
17466
17778
  UNSAFE_replayCanvas: false,
17779
+ enforceCanvasArgAllowlist: false,
17467
17780
  pauseAnimation: true,
17468
17781
  mouseTail: defaultMouseTailConfig,
17469
17782
  useVirtualDom: true,
@@ -17492,7 +17805,8 @@ class Replayer {
17492
17805
  target,
17493
17806
  imageMap: this.imageMap,
17494
17807
  canvasEventMap: this.canvasEventMap,
17495
- errorHandler: this.warnCanvasMutationFailed.bind(this)
17808
+ errorHandler: this.warnCanvasMutationFailed.bind(this),
17809
+ enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
17496
17810
  });
17497
17811
  },
17498
17812
  applyInput: this.applyInput.bind(this),
@@ -18204,7 +18518,14 @@ class Replayer {
18204
18518
  const commands = await Promise.all(
18205
18519
  data.commands.map(async (c2) => {
18206
18520
  const args = await Promise.all(
18207
- c2.args.map(deserializeArg(this.imageMap, null, status))
18521
+ c2.args.map(
18522
+ deserializeArg(
18523
+ this.imageMap,
18524
+ null,
18525
+ status,
18526
+ this.config.enforceCanvasArgAllowlist
18527
+ )
18528
+ )
18208
18529
  );
18209
18530
  return { ...c2, args };
18210
18531
  })
@@ -18213,7 +18534,14 @@ class Replayer {
18213
18534
  this.canvasEventMap.set(event, { ...data, commands });
18214
18535
  } else {
18215
18536
  const args = await Promise.all(
18216
- data.args.map(deserializeArg(this.imageMap, null, status))
18537
+ data.args.map(
18538
+ deserializeArg(
18539
+ this.imageMap,
18540
+ null,
18541
+ status,
18542
+ this.config.enforceCanvasArgAllowlist
18543
+ )
18544
+ )
18217
18545
  );
18218
18546
  if (status.isUnchanged === false)
18219
18547
  this.canvasEventMap.set(event, { ...data, args });
@@ -18426,7 +18754,8 @@ class Replayer {
18426
18754
  target,
18427
18755
  imageMap: this.imageMap,
18428
18756
  canvasEventMap: this.canvasEventMap,
18429
- errorHandler: this.warnCanvasMutationFailed.bind(this)
18757
+ errorHandler: this.warnCanvasMutationFailed.bind(this),
18758
+ enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
18430
18759
  });
18431
18760
  }
18432
18761
  break;
@@ -19149,18 +19478,529 @@ class Replayer {
19149
19478
  this.config.logger.log(REPLAY_CONSOLE_PREFIX, ...args);
19150
19479
  }
19151
19480
  }
19481
+ const RRWEB_EMBEDDED_CHANNEL = "rrweb-embedded";
19482
+ const RRWEB_EMBEDDED_PROTOCOL_VERSION = 1;
19483
+ const SERIALIZABLE_CONFIG_KEYS = [
19484
+ "speed",
19485
+ "maxSpeed",
19486
+ "loadTimeout",
19487
+ "skipInactive",
19488
+ "inactivePeriodThreshold",
19489
+ "showWarning",
19490
+ "showDebug",
19491
+ "blockClass",
19492
+ "liveMode",
19493
+ "insertStyleRules",
19494
+ "triggerFocus",
19495
+ "UNSAFE_replayCanvas",
19496
+ "enforceCanvasArgAllowlist",
19497
+ "cspContent",
19498
+ "pauseAnimation",
19499
+ "mouseTail",
19500
+ "useVirtualDom",
19501
+ "inactiveThreshold",
19502
+ "inactiveSkipTime"
19503
+ ];
19504
+ function pickSerializableConfig(config) {
19505
+ const out = {};
19506
+ if (config && typeof config === "object") {
19507
+ for (const key of SERIALIZABLE_CONFIG_KEYS) {
19508
+ const value = config[key];
19509
+ if (value !== void 0 && typeof value !== "function") {
19510
+ out[key] = value;
19511
+ }
19512
+ }
19513
+ }
19514
+ return out;
19515
+ }
19516
+ function wrap(message) {
19517
+ return {
19518
+ channel: RRWEB_EMBEDDED_CHANNEL,
19519
+ version: RRWEB_EMBEDDED_PROTOCOL_VERSION,
19520
+ message
19521
+ };
19522
+ }
19523
+ function isEnvelope(data) {
19524
+ if (!data || typeof data !== "object") return false;
19525
+ const e2 = data;
19526
+ return e2.channel === RRWEB_EMBEDDED_CHANNEL && e2.version === RRWEB_EMBEDDED_PROTOCOL_VERSION && !!e2.message && typeof e2.message === "object" && typeof e2.message.type === "string";
19527
+ }
19528
+ const PAYLOAD_EVENTS = /* @__PURE__ */ new Set([
19529
+ ReplayerEvents.Resize,
19530
+ ReplayerEvents.EventCast,
19531
+ ReplayerEvents.CustomEvent
19532
+ ]);
19533
+ class EmbeddedReplayerHost {
19534
+ constructor(options = {}) {
19535
+ __publicField(this, "root");
19536
+ __publicField(this, "parentWindow");
19537
+ __publicField(this, "timeUpdateIntervalMs");
19538
+ __publicField(this, "expectedParentOrigin");
19539
+ __publicField(this, "replayer", null);
19540
+ __publicField(this, "playing", false);
19541
+ __publicField(this, "timer", null);
19542
+ __publicField(this, "started", false);
19543
+ /**
19544
+ * Last layout the parent asked for. Retained because each `Replayer` builds
19545
+ * its own wrapper element, so a re-init would otherwise drop the scaling and
19546
+ * render the replay at 1:1 in the corner.
19547
+ */
19548
+ __publicField(this, "layout", null);
19549
+ __publicField(this, "onMessage", (event) => {
19550
+ if (event.source !== this.parentWindow) return;
19551
+ if (this.expectedParentOrigin === null) return;
19552
+ if (event.origin !== this.expectedParentOrigin) return;
19553
+ if (!isEnvelope(event.data)) return;
19554
+ try {
19555
+ this.handle(event.data.message);
19556
+ } catch (err) {
19557
+ this.post({
19558
+ type: "error",
19559
+ message: err instanceof Error ? err.message : String(err)
19560
+ });
19561
+ }
19562
+ });
19563
+ this.root = options.root ?? document.body;
19564
+ this.parentWindow = options.parentWindow ?? window.parent;
19565
+ this.timeUpdateIntervalMs = options.timeUpdateIntervalMs ?? 50;
19566
+ this.expectedParentOrigin = options.expectedParentOrigin ?? new URLSearchParams(location.search).get("parentOrigin") ?? null;
19567
+ }
19568
+ /** Install the message listener and announce readiness to the parent. */
19569
+ start() {
19570
+ if (this.started) return;
19571
+ this.started = true;
19572
+ if (this.expectedParentOrigin === null) {
19573
+ console.warn(
19574
+ "[rrweb-embedded] no parentOrigin configured; all incoming messages will be ignored"
19575
+ );
19576
+ }
19577
+ window.addEventListener("message", this.onMessage);
19578
+ this.post({ type: "ready" });
19579
+ }
19580
+ /** Tear everything down (also invoked on a `destroy` command). */
19581
+ stop() {
19582
+ var _a2;
19583
+ window.removeEventListener("message", this.onMessage);
19584
+ this.setPlaying(false);
19585
+ (_a2 = this.replayer) == null ? void 0 : _a2.destroy();
19586
+ this.replayer = null;
19587
+ this.started = false;
19588
+ }
19589
+ handle(command) {
19590
+ var _a2, _b, _c, _d, _e, _f, _g;
19591
+ switch (command.type) {
19592
+ case "ping":
19593
+ this.post({ type: "ready" });
19594
+ return;
19595
+ case "init":
19596
+ this.init(command.events, command.config, command.autoplay);
19597
+ return;
19598
+ case "play":
19599
+ (_a2 = this.replayer) == null ? void 0 : _a2.play(command.timeOffset ?? 0);
19600
+ this.setPlaying(true);
19601
+ return;
19602
+ case "pause":
19603
+ (_b = this.replayer) == null ? void 0 : _b.pause(command.timeOffset);
19604
+ this.setPlaying(false);
19605
+ this.postTime();
19606
+ return;
19607
+ case "resume":
19608
+ (_c = this.replayer) == null ? void 0 : _c.resume(command.timeOffset ?? 0);
19609
+ this.setPlaying(true);
19610
+ return;
19611
+ case "setLayout":
19612
+ this.layout = {
19613
+ scale: command.scale,
19614
+ anchor: command.anchor ?? "center"
19615
+ };
19616
+ this.applyLayout();
19617
+ this.postDimensions();
19618
+ return;
19619
+ case "setConfig":
19620
+ (_d = this.replayer) == null ? void 0 : _d.setConfig(pickSerializableConfig(command.config));
19621
+ return;
19622
+ case "replaceEvents":
19623
+ if (this.replayer) {
19624
+ this.replayer.replaceEvents(command.events);
19625
+ this.postInitialized();
19626
+ }
19627
+ return;
19628
+ case "addEvent":
19629
+ (_e = this.replayer) == null ? void 0 : _e.addEvent(command.event);
19630
+ return;
19631
+ case "enableInteract":
19632
+ (_f = this.replayer) == null ? void 0 : _f.enableInteract();
19633
+ return;
19634
+ case "disableInteract":
19635
+ (_g = this.replayer) == null ? void 0 : _g.disableInteract();
19636
+ return;
19637
+ case "destroy":
19638
+ this.stop();
19639
+ return;
19640
+ }
19641
+ }
19642
+ init(events, config, autoplay) {
19643
+ if (this.replayer) {
19644
+ this.setPlaying(false);
19645
+ this.replayer.destroy();
19646
+ }
19647
+ const replayerConfig = {
19648
+ ...pickSerializableConfig(config),
19649
+ root: this.root
19650
+ };
19651
+ this.replayer = new Replayer(events, replayerConfig);
19652
+ this.wireEvents(this.replayer);
19653
+ this.applyLayout();
19654
+ this.postInitialized();
19655
+ this.postDimensions();
19656
+ if (autoplay) {
19657
+ this.replayer.play(0);
19658
+ this.setPlaying(true);
19659
+ }
19660
+ }
19661
+ /**
19662
+ * Translate the parent's layout intent into styles on the replay wrapper.
19663
+ *
19664
+ * Mirrors what an embedder would otherwise apply from its own stylesheet:
19665
+ * `transform-origin: top left` with `left: 50%` to center horizontally, and
19666
+ * either `top: 50%` + a -50% Y translate to center vertically, or `top: 0`
19667
+ * with no Y translate to anchor at the top edge.
19668
+ */
19669
+ applyLayout() {
19670
+ var _a2;
19671
+ const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
19672
+ if (!wrapper || !this.layout) return;
19673
+ const { scale, anchor } = this.layout;
19674
+ const top = anchor === "top";
19675
+ wrapper.style.position = "absolute";
19676
+ wrapper.style.transformOrigin = "top left";
19677
+ wrapper.style.left = "50%";
19678
+ wrapper.style.top = top ? "0" : "50%";
19679
+ wrapper.style.transform = top ? `scale(${scale}) translate(-50%, 0)` : `scale(${scale}) translate(-50%, -50%)`;
19680
+ }
19681
+ /** Report the wrapper's rendered geometry; the parent cannot measure it. */
19682
+ postDimensions() {
19683
+ var _a2;
19684
+ const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
19685
+ if (!wrapper) return;
19686
+ const rect = wrapper.getBoundingClientRect();
19687
+ this.post({
19688
+ type: "dimensions",
19689
+ width: rect.width,
19690
+ height: rect.height,
19691
+ top: rect.top,
19692
+ left: rect.left
19693
+ });
19694
+ }
19695
+ /** Push the stable getters (metadata, activity intervals) to the parent. */
19696
+ postInitialized() {
19697
+ if (!this.replayer) return;
19698
+ this.post({
19699
+ type: "initialized",
19700
+ metadata: this.replayer.getMetaData(),
19701
+ activityIntervals: this.replayer.getActivityIntervals()
19702
+ });
19703
+ }
19704
+ wireEvents(replayer) {
19705
+ for (const name of Object.values(ReplayerEvents)) {
19706
+ replayer.on(name, (payload) => {
19707
+ if (name === ReplayerEvents.Finish) {
19708
+ this.setPlaying(false);
19709
+ this.postTime();
19710
+ }
19711
+ if (name === ReplayerEvents.Resize) {
19712
+ this.postDimensions();
19713
+ }
19714
+ this.post(
19715
+ PAYLOAD_EVENTS.has(name) && payload !== void 0 ? { type: "replayer-event", event: name, payload } : { type: "replayer-event", event: name }
19716
+ );
19717
+ });
19718
+ }
19719
+ }
19720
+ /* --- current-time telemetry ------------------------------------------- */
19721
+ setPlaying(playing) {
19722
+ if (this.playing === playing) return;
19723
+ this.playing = playing;
19724
+ if (playing) this.startTimePump();
19725
+ else this.stopTimePump();
19726
+ }
19727
+ startTimePump() {
19728
+ if (this.timer !== null) return;
19729
+ this.timer = setInterval(() => this.postTime(), this.timeUpdateIntervalMs);
19730
+ }
19731
+ /**
19732
+ * Push the current playback position across the bridge.
19733
+ *
19734
+ * The parent cannot read the position synchronously — it lives in this realm
19735
+ * behind an origin boundary — so the client's `getCurrentTime()` is only ever
19736
+ * as fresh as the last push. While playing, the pump keeps it current. When
19737
+ * playback stops the pump stops too, so the last pumped value would be up to
19738
+ * one interval stale; callers that seek from it (`play(getCurrentTime())` to
19739
+ * resume) would drift backwards. Pausing and finishing therefore push one
19740
+ * final, settled value.
19741
+ */
19742
+ postTime() {
19743
+ if (!this.replayer) return;
19744
+ this.post({ type: "time", currentTime: this.replayer.getCurrentTime() });
19745
+ }
19746
+ stopTimePump() {
19747
+ if (this.timer !== null) {
19748
+ clearInterval(this.timer);
19749
+ this.timer = null;
19750
+ }
19751
+ }
19752
+ post(message) {
19753
+ this.parentWindow.postMessage(
19754
+ wrap(message),
19755
+ this.expectedParentOrigin ?? "*"
19756
+ );
19757
+ }
19758
+ }
19759
+ function startEmbeddedReplayerHost(options) {
19760
+ const host2 = new EmbeddedReplayerHost(options);
19761
+ host2.start();
19762
+ return host2;
19763
+ }
19764
+ class EmbeddedReplayerClient {
19765
+ constructor(iframe, options = {}) {
19766
+ __publicField(this, "iframe");
19767
+ __publicField(this, "hostOrigin");
19768
+ __publicField(this, "listeners", /* @__PURE__ */ new Map());
19769
+ __publicField(this, "metadata", null);
19770
+ __publicField(this, "activityIntervals", []);
19771
+ __publicField(this, "dimensions", null);
19772
+ __publicField(this, "lastCurrentTime", 0);
19773
+ __publicField(this, "ready", false);
19774
+ __publicField(this, "readyResolvers", []);
19775
+ __publicField(this, "disposed", false);
19776
+ /**
19777
+ * Commands issued before the host handshakes. A command posted while the
19778
+ * iframe is still on its initial `about:blank` (which carries the PARENT's
19779
+ * origin) is rejected by the browser as an origin mismatch and lost — the
19780
+ * viewer calls `setLayout` on mount, well before the host boots. Buffer until
19781
+ * `ready`, then flush; by then the frame is on the host origin.
19782
+ */
19783
+ __publicField(this, "pending", []);
19784
+ __publicField(this, "onMessage", (event) => {
19785
+ if (event.source !== this.iframe.contentWindow) return;
19786
+ if (!isEnvelope(event.data)) return;
19787
+ this.handle(event.data.message);
19788
+ });
19789
+ this.iframe = iframe;
19790
+ this.hostOrigin = options.hostOrigin ?? "*";
19791
+ window.addEventListener("message", this.onMessage);
19792
+ this.probe();
19793
+ }
19794
+ /** Resolves once the host iframe has loaded and announced readiness. */
19795
+ whenReady() {
19796
+ if (this.ready) return Promise.resolve();
19797
+ return new Promise((resolve) => this.readyResolvers.push(resolve));
19798
+ }
19799
+ /* --- commands --------------------------------------------------------- */
19800
+ init(events, config, autoplay = false) {
19801
+ this.send({ type: "init", events, config, autoplay });
19802
+ }
19803
+ play(timeOffset) {
19804
+ this.send({ type: "play", timeOffset });
19805
+ }
19806
+ pause(timeOffset) {
19807
+ this.send({ type: "pause", timeOffset });
19808
+ }
19809
+ resume(timeOffset) {
19810
+ this.send({ type: "resume", timeOffset });
19811
+ }
19812
+ setConfig(config) {
19813
+ this.send({ type: "setConfig", config });
19814
+ }
19815
+ /**
19816
+ * Scale and position the replay. Compute `scale` from your own container size
19817
+ * and the recorded viewport, as you would when driving a local `Replayer`;
19818
+ * the host applies it, since the wrapper element is not reachable from here.
19819
+ * The layout is retained across re-inits.
19820
+ */
19821
+ setLayout(scale, anchor) {
19822
+ this.send({ type: "setLayout", scale, anchor });
19823
+ }
19824
+ replaceEvents(events) {
19825
+ this.send({ type: "replaceEvents", events });
19826
+ }
19827
+ addEvent(event) {
19828
+ this.send({ type: "addEvent", event });
19829
+ }
19830
+ enableInteract() {
19831
+ this.send({ type: "enableInteract" });
19832
+ }
19833
+ disableInteract() {
19834
+ this.send({ type: "disableInteract" });
19835
+ }
19836
+ /** Tear down: destroys the host replayer and detaches the listener. */
19837
+ destroy() {
19838
+ if (this.disposed) return;
19839
+ this.disposed = true;
19840
+ try {
19841
+ this.send({ type: "destroy" });
19842
+ } finally {
19843
+ window.removeEventListener("message", this.onMessage);
19844
+ this.listeners.clear();
19845
+ }
19846
+ }
19847
+ /* --- event surface ---------------------------------------------------- */
19848
+ on(event, listener) {
19849
+ let set = this.listeners.get(event);
19850
+ if (!set) {
19851
+ set = /* @__PURE__ */ new Set();
19852
+ this.listeners.set(event, set);
19853
+ }
19854
+ set.add(listener);
19855
+ }
19856
+ off(event, listener) {
19857
+ var _a2;
19858
+ (_a2 = this.listeners.get(event)) == null ? void 0 : _a2.delete(listener);
19859
+ }
19860
+ /* --- getters ---------------------------------------------------------- */
19861
+ // Cached getters mirroring the local Replayer's synchronous ones. Metadata
19862
+ // and activity intervals arrive on `initialized` (re-sent on replaceEvents);
19863
+ // current time is streamed by the host while playing.
19864
+ /** Last-known current time (pushed by the host while playing). */
19865
+ getCurrentTime() {
19866
+ return this.lastCurrentTime;
19867
+ }
19868
+ getMetaData() {
19869
+ return this.metadata;
19870
+ }
19871
+ getActivityIntervals() {
19872
+ return this.activityIntervals;
19873
+ }
19874
+ /**
19875
+ * Rendered geometry of the replay, in the host document's coordinate space —
19876
+ * the cross-origin stand-in for `replayer.wrapper.getBoundingClientRect()`.
19877
+ * Null until the host has reported it (listen for `'dimensions'`).
19878
+ */
19879
+ getDimensions() {
19880
+ return this.dimensions;
19881
+ }
19882
+ /* --- internals -------------------------------------------------------- */
19883
+ send(command) {
19884
+ if (!this.ready) {
19885
+ this.pending.push(command);
19886
+ return;
19887
+ }
19888
+ this.postToHost(command);
19889
+ }
19890
+ postToHost(command) {
19891
+ const target = this.iframe.contentWindow;
19892
+ if (!target) return;
19893
+ target.postMessage(wrap(command), this.hostOrigin);
19894
+ }
19895
+ flushPending() {
19896
+ const queued = this.pending;
19897
+ this.pending = [];
19898
+ queued.forEach((command) => this.postToHost(command));
19899
+ }
19900
+ /** Data-free handshake probe; see the note in the constructor. */
19901
+ probe() {
19902
+ var _a2;
19903
+ (_a2 = this.iframe.contentWindow) == null ? void 0 : _a2.postMessage(wrap({ type: "ping" }), "*");
19904
+ }
19905
+ handle(message) {
19906
+ switch (message.type) {
19907
+ case "ready":
19908
+ this.ready = true;
19909
+ this.flushPending();
19910
+ this.readyResolvers.forEach((r2) => r2());
19911
+ this.readyResolvers = [];
19912
+ return;
19913
+ case "initialized":
19914
+ this.metadata = message.metadata;
19915
+ this.activityIntervals = message.activityIntervals;
19916
+ this.emit("initialized", message.metadata);
19917
+ return;
19918
+ case "replayer-event":
19919
+ this.emit(message.event, message.payload);
19920
+ return;
19921
+ case "time":
19922
+ this.lastCurrentTime = message.currentTime;
19923
+ this.emit("time", message.currentTime);
19924
+ return;
19925
+ case "dimensions":
19926
+ this.dimensions = {
19927
+ width: message.width,
19928
+ height: message.height,
19929
+ top: message.top,
19930
+ left: message.left
19931
+ };
19932
+ this.emit("dimensions", this.dimensions);
19933
+ return;
19934
+ case "error":
19935
+ this.emit("error", message.message);
19936
+ return;
19937
+ }
19938
+ }
19939
+ emit(event, payload) {
19940
+ var _a2;
19941
+ (_a2 = this.listeners.get(event)) == null ? void 0 : _a2.forEach((listener) => listener(payload));
19942
+ }
19943
+ }
19944
+ function originOf(url) {
19945
+ try {
19946
+ return new URL(url).origin;
19947
+ } catch {
19948
+ return "'self'";
19949
+ }
19950
+ }
19951
+ function buildHostDocument(options) {
19952
+ const scriptOrigin = originOf(options.scriptUrl);
19953
+ const styleSources = [
19954
+ "'unsafe-inline'",
19955
+ scriptOrigin,
19956
+ ...options.extraStyleSources ?? []
19957
+ ].join(" ");
19958
+ const csp = [
19959
+ `default-src 'none'`,
19960
+ `script-src ${scriptOrigin}`,
19961
+ `style-src ${styleSources}`,
19962
+ `img-src * data: blob:`,
19963
+ `font-src * data:`,
19964
+ `media-src * data: blob:`,
19965
+ `frame-src *`,
19966
+ `connect-src 'none'`,
19967
+ `worker-src 'none'`
19968
+ ].join("; ");
19969
+ const styleTag = options.styleUrl ? `<link rel="stylesheet" href="${escapeAttr(options.styleUrl)}">` : "";
19970
+ return `<!DOCTYPE html>
19971
+ <html>
19972
+ <head>
19973
+ <meta charset="utf-8">
19974
+ <meta http-equiv="Content-Security-Policy" content="${escapeAttr(csp)}">
19975
+ <style>html,body{margin:0;padding:0;height:100%;overflow:hidden;background:transparent}</style>
19976
+ ${styleTag}
19977
+ <script type="module" src="${escapeAttr(options.scriptUrl)}"><\/script>
19978
+ </head>
19979
+ <body></body>
19980
+ </html>`;
19981
+ }
19982
+ function escapeAttr(value) {
19983
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
19984
+ }
19152
19985
  const { addCustomEvent } = record;
19153
19986
  const { freezePage } = record;
19154
19987
  const { takeFullSnapshot } = record;
19988
+ exports.EmbeddedReplayerClient = EmbeddedReplayerClient;
19989
+ exports.EmbeddedReplayerHost = EmbeddedReplayerHost;
19155
19990
  exports.EventType = EventType;
19156
19991
  exports.IncrementalSource = IncrementalSource;
19157
19992
  exports.MouseInteractions = MouseInteractions;
19993
+ exports.RRWEB_EMBEDDED_CHANNEL = RRWEB_EMBEDDED_CHANNEL;
19994
+ exports.RRWEB_EMBEDDED_PROTOCOL_VERSION = RRWEB_EMBEDDED_PROTOCOL_VERSION;
19158
19995
  exports.Replayer = Replayer;
19159
19996
  exports.ReplayerEvents = ReplayerEvents;
19160
19997
  exports.addCustomEvent = addCustomEvent;
19998
+ exports.buildHostDocument = buildHostDocument;
19161
19999
  exports.canvasMutation = canvasMutation;
19162
20000
  exports.freezePage = freezePage;
20001
+ exports.pickSerializableConfig = pickSerializableConfig;
19163
20002
  exports.record = record;
20003
+ exports.startEmbeddedReplayerHost = startEmbeddedReplayerHost;
19164
20004
  exports.takeFullSnapshot = takeFullSnapshot;
19165
20005
  exports.utils = utils;
19166
20006
  //# sourceMappingURL=rrweb.cjs.map