@appsurify-testmap/rrweb-record 3.2.0-alpha.1 → 3.3.0-alpha.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.
@@ -13858,6 +13858,30 @@ function initNavigationObserver({
13858
13858
  handlers.push(restoreReplaceState);
13859
13859
  handlers.push(on("popstate", () => emitNavigation("popstate"), win));
13860
13860
  handlers.push(on("hashchange", () => emitNavigation("hashchange"), win));
13861
+ const useNavigationAPI = typeof sampling.navigation === "object" ? sampling.navigation.useNavigationAPI ?? true : true;
13862
+ if (useNavigationAPI && "navigation" in win) {
13863
+ try {
13864
+ const nav = win.navigation;
13865
+ const handler = (event) => {
13866
+ var _a2;
13867
+ const navEvent = event;
13868
+ if (navEvent.navigationType === "push" || navEvent.navigationType === "replace") {
13869
+ const destUrl = (_a2 = navEvent.destination) == null ? void 0 : _a2.url;
13870
+ if (destUrl && destUrl !== lastHref) {
13871
+ navigationCb({
13872
+ href: destUrl,
13873
+ oldHref: lastHref,
13874
+ navigationType: "navigate"
13875
+ });
13876
+ lastHref = destUrl;
13877
+ }
13878
+ }
13879
+ };
13880
+ nav.addEventListener("navigate", handler);
13881
+ handlers.push(() => nav.removeEventListener("navigate", handler));
13882
+ } catch {
13883
+ }
13884
+ }
13861
13885
  return callbackWrapper(() => {
13862
13886
  handlers.forEach((h) => h());
13863
13887
  });
@@ -15956,6 +15980,164 @@ class VisibilityManager {
15956
15980
  }
15957
15981
  }
15958
15982
  }
15983
+ const DEFAULT_SETTLE_TIMEOUT = 150;
15984
+ const DEFAULT_MAX_WAIT = 5e3;
15985
+ const DEFAULT_DEBOUNCE = 100;
15986
+ class NavigationManager {
15987
+ constructor(options) {
15988
+ __publicField(this, "frozen", false);
15989
+ __publicField(this, "locked", false);
15990
+ __publicField(this, "disabled", false);
15991
+ __publicField(this, "settleTimeout");
15992
+ __publicField(this, "maxWait");
15993
+ __publicField(this, "debounceMs");
15994
+ __publicField(this, "settlingObserver", null);
15995
+ __publicField(this, "debounceTimer", null);
15996
+ __publicField(this, "settleCheckTimer", null);
15997
+ __publicField(this, "maxWaitTimer", null);
15998
+ __publicField(this, "lastMutationTime", 0);
15999
+ __publicField(this, "pendingNavigation", null);
16000
+ __publicField(this, "doc");
16001
+ __publicField(this, "onSnapshot");
16002
+ const { doc, config, onSnapshot } = options;
16003
+ this.doc = doc;
16004
+ this.onSnapshot = callbackWrapper(onSnapshot);
16005
+ this.settleTimeout = config.settleTimeout ?? DEFAULT_SETTLE_TIMEOUT;
16006
+ this.maxWait = config.maxWait ?? DEFAULT_MAX_WAIT;
16007
+ this.debounceMs = config.debounce ?? DEFAULT_DEBOUNCE;
16008
+ }
16009
+ handleNavigation(data) {
16010
+ if (this.disabled) return;
16011
+ if (this.locked) return;
16012
+ this.cancelTimers();
16013
+ this.disconnectSettlingObserver();
16014
+ this.pendingNavigation = data;
16015
+ if (this.frozen) {
16016
+ return;
16017
+ }
16018
+ this.startDebounce();
16019
+ }
16020
+ cancelPending() {
16021
+ this.cancelTimers();
16022
+ this.disconnectSettlingObserver();
16023
+ this.pendingNavigation = null;
16024
+ }
16025
+ freeze() {
16026
+ this.frozen = true;
16027
+ this.cancelTimers();
16028
+ this.disconnectSettlingObserver();
16029
+ }
16030
+ unfreeze() {
16031
+ this.frozen = false;
16032
+ if (this.pendingNavigation && !this.locked && !this.disabled) {
16033
+ this.startDebounce();
16034
+ }
16035
+ }
16036
+ lock() {
16037
+ this.locked = true;
16038
+ this.cancelTimers();
16039
+ this.disconnectSettlingObserver();
16040
+ }
16041
+ unlock() {
16042
+ this.locked = false;
16043
+ this.pendingNavigation = null;
16044
+ }
16045
+ unsetFrozen() {
16046
+ this.frozen = false;
16047
+ }
16048
+ reset() {
16049
+ this.cancelTimers();
16050
+ this.disconnectSettlingObserver();
16051
+ this.pendingNavigation = null;
16052
+ this.frozen = false;
16053
+ this.locked = false;
16054
+ }
16055
+ destroy() {
16056
+ this.reset();
16057
+ this.disabled = true;
16058
+ }
16059
+ startDebounce() {
16060
+ this.debounceTimer = setTimeout(() => {
16061
+ this.debounceTimer = null;
16062
+ this.startDOMSettling();
16063
+ }, this.debounceMs);
16064
+ }
16065
+ startDOMSettling() {
16066
+ if (this.frozen || this.locked || this.disabled) return;
16067
+ this.lastMutationTime = performance.now();
16068
+ const ObserverCtor = mutationObserverCtor();
16069
+ this.settlingObserver = new ObserverCtor(() => {
16070
+ this.lastMutationTime = performance.now();
16071
+ if (this.settleCheckTimer !== null) {
16072
+ clearTimeout(this.settleCheckTimer);
16073
+ }
16074
+ this.settleCheckTimer = setTimeout(
16075
+ () => this.checkSettled(),
16076
+ this.settleTimeout
16077
+ );
16078
+ });
16079
+ this.settlingObserver.observe(this.doc, {
16080
+ childList: true,
16081
+ subtree: true,
16082
+ attributes: true,
16083
+ characterData: true
16084
+ });
16085
+ this.settleCheckTimer = setTimeout(
16086
+ () => this.checkSettled(),
16087
+ this.settleTimeout
16088
+ );
16089
+ this.maxWaitTimer = setTimeout(() => {
16090
+ this.maxWaitTimer = null;
16091
+ this.completeSettling();
16092
+ }, this.maxWait);
16093
+ }
16094
+ checkSettled() {
16095
+ this.settleCheckTimer = null;
16096
+ const elapsed = performance.now() - this.lastMutationTime;
16097
+ if (elapsed >= this.settleTimeout) {
16098
+ this.completeSettling();
16099
+ } else {
16100
+ this.settleCheckTimer = setTimeout(
16101
+ () => this.checkSettled(),
16102
+ this.settleTimeout - elapsed
16103
+ );
16104
+ }
16105
+ }
16106
+ completeSettling() {
16107
+ if (this.frozen || this.locked || this.disabled) return;
16108
+ if (!this.pendingNavigation) return;
16109
+ this.cancelTimers();
16110
+ this.disconnectSettlingObserver();
16111
+ this.pendingNavigation = null;
16112
+ requestAnimationFrame(() => {
16113
+ requestAnimationFrame(() => {
16114
+ if (!this.frozen && !this.locked && !this.disabled) {
16115
+ this.onSnapshot(true);
16116
+ }
16117
+ });
16118
+ });
16119
+ }
16120
+ cancelTimers() {
16121
+ if (this.debounceTimer !== null) {
16122
+ clearTimeout(this.debounceTimer);
16123
+ this.debounceTimer = null;
16124
+ }
16125
+ if (this.settleCheckTimer !== null) {
16126
+ clearTimeout(this.settleCheckTimer);
16127
+ this.settleCheckTimer = null;
16128
+ }
16129
+ if (this.maxWaitTimer !== null) {
16130
+ clearTimeout(this.maxWaitTimer);
16131
+ this.maxWaitTimer = null;
16132
+ }
16133
+ }
16134
+ disconnectSettlingObserver() {
16135
+ if (this.settlingObserver) {
16136
+ this.settlingObserver.disconnect();
16137
+ this.settlingObserver = null;
16138
+ }
16139
+ }
16140
+ }
15959
16141
  class StylesheetManager {
15960
16142
  constructor(options) {
15961
16143
  __publicField(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
@@ -16039,43 +16221,13 @@ class ProcessedNodeManager {
16039
16221
  destroy() {
16040
16222
  }
16041
16223
  }
16042
- const version$1 = "3.1.1-alpha.3";
16224
+ const version$1 = "3.3.0-alpha.1";
16043
16225
  let wrappedEmit;
16044
16226
  let takeFullSnapshot$1;
16045
16227
  let canvasManager;
16046
16228
  let recording = false;
16047
16229
  const customEventQueue = [];
16048
16230
  let flushCustomEventQueue$1;
16049
- function waitForDOMStabilization(win) {
16050
- const maxWaitMs = 5e3;
16051
- return new Promise((resolve2) => {
16052
- const captureAfterPaint = () => {
16053
- requestAnimationFrame(() => {
16054
- requestAnimationFrame(() => {
16055
- resolve2();
16056
- });
16057
- });
16058
- };
16059
- const safeResolve = /* @__PURE__ */ (() => {
16060
- let called = false;
16061
- return () => {
16062
- if (!called) {
16063
- called = true;
16064
- captureAfterPaint();
16065
- }
16066
- };
16067
- })();
16068
- if (["interactive", "complete"].includes(win.document.readyState)) {
16069
- safeResolve();
16070
- } else {
16071
- win.addEventListener("DOMContentLoaded", safeResolve, { once: true });
16072
- win.addEventListener("load", safeResolve, { once: true });
16073
- setTimeout(() => {
16074
- safeResolve();
16075
- }, maxWaitMs);
16076
- }
16077
- });
16078
- }
16079
16231
  try {
16080
16232
  if (Array.from([1], (x2) => x2 * 2)[0] !== 2) {
16081
16233
  const cleanFrame = document.createElement("iframe");
@@ -16208,6 +16360,7 @@ function record(options = {}) {
16208
16360
  checkoutDebounceTimer = null;
16209
16361
  checkoutPending = false;
16210
16362
  checkoutFreezeTimestamp = null;
16363
+ navigationManager == null ? void 0 : navigationManager.cancelPending();
16211
16364
  takeFullSnapshot$1(true);
16212
16365
  mutationBuffers.forEach((buf) => {
16213
16366
  buf.resetBuffers();
@@ -16216,6 +16369,9 @@ function record(options = {}) {
16216
16369
  if (visibilityManager) {
16217
16370
  visibilityManager.unsetFrozen();
16218
16371
  }
16372
+ if (navigationManager) {
16373
+ navigationManager.unsetFrozen();
16374
+ }
16219
16375
  };
16220
16376
  wrappedEmit = (r2, isCheckout) => {
16221
16377
  var _a2;
@@ -16225,6 +16381,7 @@ function record(options = {}) {
16225
16381
  if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && !checkoutPending && e2.type !== EventType.FullSnapshot && !(e2.type === EventType.IncrementalSnapshot && e2.data.source === IncrementalSource.Mutation)) {
16226
16382
  mutationBuffers.forEach((buf) => buf.unfreeze());
16227
16383
  visibilityManager == null ? void 0 : visibilityManager.unfreeze();
16384
+ navigationManager == null ? void 0 : navigationManager.unfreeze();
16228
16385
  }
16229
16386
  if (inEmittingFrame) {
16230
16387
  emit == null ? void 0 : emit(eventProcessor(e2), isCheckout);
@@ -16434,6 +16591,7 @@ function record(options = {}) {
16434
16591
  shadowDomManager.init();
16435
16592
  mutationBuffers.forEach((buf) => buf.lock());
16436
16593
  visibilityManager == null ? void 0 : visibilityManager.lock();
16594
+ navigationManager == null ? void 0 : navigationManager.lock();
16437
16595
  const node2 = snapshot(document, {
16438
16596
  mirror,
16439
16597
  blockClass,
@@ -16485,6 +16643,7 @@ function record(options = {}) {
16485
16643
  );
16486
16644
  mutationBuffers.forEach((buf) => buf.unlock());
16487
16645
  visibilityManager == null ? void 0 : visibilityManager.unlock();
16646
+ navigationManager == null ? void 0 : navigationManager.unlock();
16488
16647
  if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)
16489
16648
  stylesheetManager.adoptStyleSheets(
16490
16649
  document.adoptedStyleSheets,
@@ -16497,6 +16656,31 @@ function record(options = {}) {
16497
16656
  }
16498
16657
  customEventQueue.length = 0;
16499
16658
  };
16659
+ let navigationManager;
16660
+ const navigationSampling = sampling.navigation;
16661
+ if (navigationSampling !== false) {
16662
+ const navConfig = typeof navigationSampling === "object" ? navigationSampling : {};
16663
+ navigationManager = new NavigationManager({
16664
+ doc: document,
16665
+ config: navConfig,
16666
+ onSnapshot: (isCheckout) => {
16667
+ if (checkoutPending) {
16668
+ if (checkoutDebounceTimer) {
16669
+ clearTimeout(checkoutDebounceTimer);
16670
+ checkoutDebounceTimer = null;
16671
+ }
16672
+ checkoutPending = false;
16673
+ checkoutFreezeTimestamp = null;
16674
+ mutationBuffers.forEach((buf) => {
16675
+ buf.resetBuffers();
16676
+ buf.unsetFrozen();
16677
+ });
16678
+ visibilityManager == null ? void 0 : visibilityManager.unsetFrozen();
16679
+ }
16680
+ takeFullSnapshot$1(isCheckout);
16681
+ }
16682
+ });
16683
+ }
16500
16684
  try {
16501
16685
  const handlers = [];
16502
16686
  const observe = (doc) => {
@@ -16527,14 +16711,11 @@ function record(options = {}) {
16527
16711
  }
16528
16712
  }),
16529
16713
  navigationCb: (navData) => {
16530
- console.debug(
16531
- `[${nowTimestamp()}] [rrweb:record/navigation] 🧭 Navigation detected:`,
16532
- navData.navigationType,
16533
- navData.oldHref,
16534
- "→",
16535
- navData.href
16536
- );
16537
- takeFullSnapshot$1(true);
16714
+ if (navigationManager) {
16715
+ navigationManager.handleNavigation(navData);
16716
+ } else {
16717
+ takeFullSnapshot$1(true);
16718
+ }
16538
16719
  },
16539
16720
  inputCb: (v2) => wrappedEmit({
16540
16721
  type: EventType.IncrementalSnapshot,
@@ -16653,23 +16834,6 @@ function record(options = {}) {
16653
16834
  flushCustomEventQueue$1();
16654
16835
  }
16655
16836
  };
16656
- const runInit = async () => {
16657
- if (flushCustomEvent === "before") {
16658
- flushCustomEventQueue$1();
16659
- }
16660
- if (recordAfter === "DOMContentStabilized") {
16661
- console.debug(`[${nowTimestamp()}] [rrweb:record] 🟢 Waiting for DOM stabilization...`);
16662
- await waitForDOMStabilization(window);
16663
- console.debug(`[${nowTimestamp()}] [rrweb:record] ✅ DOM stabilized, starting recording`);
16664
- }
16665
- console.debug(`[${nowTimestamp()}] [rrweb:record] ✅ Init dom and takeFullSnapshot `);
16666
- takeFullSnapshot$1();
16667
- handlers.push(observe(document));
16668
- recording = true;
16669
- if (flushCustomEvent === "after") {
16670
- flushCustomEventQueue$1();
16671
- }
16672
- };
16673
16837
  if (document.readyState === "interactive" || document.readyState === "complete") {
16674
16838
  init();
16675
16839
  } else {
@@ -16703,6 +16867,7 @@ function record(options = {}) {
16703
16867
  }
16704
16868
  flushCustomEventQueue$1();
16705
16869
  handlers.forEach((h) => h());
16870
+ navigationManager == null ? void 0 : navigationManager.destroy();
16706
16871
  processedNodeManager.destroy();
16707
16872
  recording = false;
16708
16873
  unregisterErrorHandler();