Skip to content

fix(record): port rrweb 2.0.1 WebKit MutationObserver fix#3737

Open
arnohillen wants to merge 3 commits into
mainfrom
ahillen/rrweb-sync-webkit-mutationobserver
Open

fix(record): port rrweb 2.0.1 WebKit MutationObserver fix#3737
arnohillen wants to merge 3 commits into
mainfrom
ahillen/rrweb-sync-webkit-mutationobserver

Conversation

@arnohillen

Copy link
Copy Markdown
Contributor

Problem

I reviewed upstream rrweb's releases (rrweb-io/rrweb) against our vendored fork (packages/rrweb/*, @posthog/rrweb). The fork's upstream baseline is rrweb@2.0.0-alpha.18; upstream has since cut 2.0.0 and 2.0.1.

The headline of 2.0.0 is a packaging/dist restructure (split plugin packages, new @rrweb/browser-client, new file extensions) that we already do our own incompatible way (our @posthog/rrweb-* workspace split + property mangling + custom vite build), so adopting it would fight our build. Stripping out docs/CI/browser-client noise, the only functional code change upstream landed after our baseline is the 2.0.1 WebKit fix.

That fix matters: on WebKit/Safari, when a 3rd-party library has monkey-patched the page, rrweb grabs a pristine MutationObserver constructor from a throwaway iframe to avoid the tainted one. WebKit tears down a detached iframe's ScriptExecutionContext, so the observer built from it silently stops delivering mutations once we remove the iframe (webkit.org/b/179224) — i.e. no DOM mutations get recorded on affected Safari pages.

Changes

Ported rrweb-io/rrweb#1854, reconciled against our diverged fork:

  • @posthog/rrweb-utils (getUntaintedPrototype): on Safari, keep the untainted-prototype iframe attached (hidden via display:none, tagged rr-block + __rrwebUntaintedMutationObserver so it isn't serialized into snapshots) instead of removing it. mutationObserverCtor() now returns [ctor, cleanup].
  • @posthog/rrweb (initMutationObserver / initObservers): thread the iframeCleanup through and invoke it on observer teardown so we don't leak the iframe.
  • Non-Safari behavior is unchanged (iframe still removed immediately; cleanup is a no-op).

Adapted to our fork's shape: our initMutationObserver returns an object ({ observer, buffer }) rather than upstream's tuple, so shadow-dom-manager needs no change (it just ignores the extra iframeCleanup field). Deliberately not porting the upstream WebKit Docker/CI test harness (Dockerfile.webkit-test, vitest.config.webkit.ts) — that's a separate CI infrastructure decision.

Typecheck + eslint clean on both packages.

Release info Sub-libraries affected

Libraries affected

  • posthog-js (web)

(Changeset bumps posthog-js, @posthog/rrweb, @posthog/rrweb-utils as patch.)

Checklist

  • Tests for new code — source-only port; the upstream regression test needs a WebKit CI runner we don't have wired up. Open to adding a Chromium-safe variant if wanted.
  • Accounted for the impact of any changes across different platforms — Safari-gated; non-Safari path byte-for-byte equivalent.
  • Accounted for backwards compatibility — mutationObserverCtor signature changed but it has a single internal caller; no external dom.mutationObserver( consumers.
  • Took care not to unnecessarily increase the bundle size — a few lines, Safari-gated.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Scope was deliberately narrowed from "sync all rrweb updates": a literal full merge of alpha.18 → 2.0.1 (65 commits) would drag in upstream's 2.0.0 packaging restructure which conflicts with our custom build/mangling. The genuine functional delta since our baseline is just the 2.0.1 WebKit MutationObserver fix, which this PR ports.

Made with Cursor

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
posthog-example-next-app-router Ready Ready Preview Jun 7, 2026 6:27pm
posthog-js Ready Ready Preview Jun 7, 2026 6:27pm
posthog-nextjs-config Ready Ready Preview Jun 7, 2026 6:27pm

Request Review

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor
⚠️ Changeset declares `posthog-js` but no source files in that package changed

This is informational — the PR is not blocked. Click the triangle above to collapse, or push a fix and this comment will auto-delete.

Declared in a changeset but no source files modified:

  • posthog-js

Double-check this is intentional — for example, releasing a previously-merged change.

Changesets in this PR:

  • @posthog/rrweb — patch
  • @posthog/rrweb-utils — patch
  • posthog-js — patch

@greptile-apps

greptile-apps Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/rrweb/utils/src/index.ts:134
**Stale cache after cleanup breaks a stop-then-restart recording session on Safari**

`untaintedBasePrototype[key]` is never cleared when `iframeCleanup` is called. On the next call to `getUntaintedPrototype('MutationObserver')` (line 72–73) the cache returns the constructor from the now-removed iframe whose `ScriptExecutionContext` WebKit has already torn down — the exact silent-breakage this PR is fixing. Any workflow that stops and restarts session recording on the same page (e.g. idle-pause / resume) will reproduce the original bug on Safari.

```suggestion
      untaintedBaseIframeCleanup[key] = () => {
        iframeEl.remove();
        // Clear the cached prototype so a subsequent recording session creates a
        // fresh iframe rather than reusing a constructor from a torn-down context.
        delete untaintedBasePrototype[key];
        delete untaintedBaseIframeCleanup[key];
      };
```

Reviews (1): Last reviewed commit: "fix(record): port rrweb 2.0.1 WebKit Mut..." | Re-trigger Greptile

// rr-block prevents rrweb from serializing this iframe in later snapshots
iframeEl.classList.add('rr-block');
iframeEl.setAttribute('__rrwebUntaintedMutationObserver', '');
untaintedBaseIframeCleanup[key] = () => iframeEl.remove();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stale cache after cleanup breaks a stop-then-restart recording session on Safari

untaintedBasePrototype[key] is never cleared when iframeCleanup is called. On the next call to getUntaintedPrototype('MutationObserver') (line 72–73) the cache returns the constructor from the now-removed iframe whose ScriptExecutionContext WebKit has already torn down — the exact silent-breakage this PR is fixing. Any workflow that stops and restarts session recording on the same page (e.g. idle-pause / resume) will reproduce the original bug on Safari.

Suggested change
untaintedBaseIframeCleanup[key] = () => iframeEl.remove();
untaintedBaseIframeCleanup[key] = () => {
iframeEl.remove();
// Clear the cached prototype so a subsequent recording session creates a
// fresh iframe rather than reusing a constructor from a torn-down context.
delete untaintedBasePrototype[key];
delete untaintedBaseIframeCleanup[key];
};
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/rrweb/utils/src/index.ts
Line: 134

Comment:
**Stale cache after cleanup breaks a stop-then-restart recording session on Safari**

`untaintedBasePrototype[key]` is never cleared when `iframeCleanup` is called. On the next call to `getUntaintedPrototype('MutationObserver')` (line 72–73) the cache returns the constructor from the now-removed iframe whose `ScriptExecutionContext` WebKit has already torn down — the exact silent-breakage this PR is fixing. Any workflow that stops and restarts session recording on the same page (e.g. idle-pause / resume) will reproduce the original bug on Safari.

```suggestion
      untaintedBaseIframeCleanup[key] = () => {
        iframeEl.remove();
        // Clear the cached prototype so a subsequent recording session creates a
        // fresh iframe rather than reusing a constructor from a torn-down context.
        delete untaintedBasePrototype[key];
        delete untaintedBaseIframeCleanup[key];
      };
```

How can I resolve this? If you propose a fix, please make it concise.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Size Change: +25.6 kB (+0.15%)

Total Size: 16.7 MB

Filename Size Change
packages/browser/dist/all-external-dependencies.js 267 kB +277 B (+0.1%)
packages/browser/dist/array.full.js 439 kB +283 B (+0.06%)
packages/browser/dist/array.full.no-********.js 514 kB +283 B (+0.06%)
packages/browser/dist/lazy-********.js 156 kB +281 B (+0.18%)
packages/browser/dist/module.full.js 442 kB +283 B (+0.06%)
packages/browser/dist/module.full.no-********.js 517 kB +283 B (+0.05%)
packages/browser/dist/posthog-********.js 156 kB +277 B (+0.18%)
packages/browser/dist/recorder-v2.js 103 kB +277 B (+0.27%)
packages/browser/dist/recorder.js 103 kB +277 B (+0.27%)
packages/browser/dist/rrweb.js 284 kB +680 B (+0.24%)
packages/rrweb/all/dist/rrweb-all.cjs 623 kB +1.37 kB (+0.22%)
packages/rrweb/all/dist/rrweb-all.js 622 kB +1.37 kB (+0.22%)
packages/rrweb/all/dist/rrweb-all.umd.cjs 625 kB +1.37 kB (+0.22%)
packages/rrweb/all/dist/rrweb-all.umd.min.cjs 295 kB +683 B (+0.23%)
packages/rrweb/record/dist/rrweb-record.cjs 183 kB +617 B (+0.34%)
packages/rrweb/record/dist/rrweb-record.js 183 kB +617 B (+0.34%)
packages/rrweb/record/dist/rrweb-record.umd.cjs 184 kB +617 B (+0.34%)
packages/rrweb/record/dist/rrweb-record.umd.min.cjs 87.7 kB +285 B (+0.33%)
packages/rrweb/replay/dist/rrweb-replay.cjs 442 kB +1.13 kB (+0.26%)
packages/rrweb/replay/dist/rrweb-replay.js 442 kB +1.13 kB (+0.26%)
packages/rrweb/replay/dist/rrweb-replay.umd.cjs 444 kB +1.13 kB (+0.25%)
packages/rrweb/replay/dist/rrweb-replay.umd.min.cjs 210 kB +597 B (+0.28%)
packages/rrweb/rrdom/dist/rrdom.cjs 174 kB +373 B (+0.21%)
packages/rrweb/rrdom/dist/rrdom.js 174 kB +373 B (+0.22%)
packages/rrweb/rrdom/dist/rrdom.umd.cjs 176 kB +373 B (+0.21%)
packages/rrweb/rrdom/dist/rrdom.umd.min.cjs 81 kB +199 B (+0.25%)
packages/rrweb/rrweb-snapshot/dist/record.umd.cjs 55.6 kB +419 B (+0.76%)
packages/rrweb/rrweb-snapshot/dist/record.umd.min.cjs 26.5 kB +197 B (+0.75%)
packages/rrweb/rrweb-snapshot/dist/replay.umd.cjs 161 kB +419 B (+0.26%)
packages/rrweb/rrweb-snapshot/dist/replay.umd.min.cjs 74.2 kB +197 B (+0.27%)
packages/rrweb/rrweb-snapshot/dist/rrweb-********.umd.cjs 220 kB +419 B (+0.19%)
packages/rrweb/rrweb-snapshot/dist/rrweb-********.umd.min.cjs 92.7 kB +197 B (+0.21%)
packages/rrweb/rrweb-snapshot/dist/types-********.cjs 18.6 kB +373 B (+2.04%)
packages/rrweb/rrweb-snapshot/dist/types-********.umd.cjs 19.2 kB +371 B (+1.98%)
packages/rrweb/rrweb-snapshot/dist/types-********.umd.min.cjs 9.5 kB +197 B (+2.12%)
packages/rrweb/rrweb-snapshot/dist/types-********.js 0 B -17.8 kB (removed) 🏆
packages/rrweb/rrweb/dist/rrweb.cjs 606 kB +1.37 kB (+0.23%)
packages/rrweb/rrweb/dist/rrweb.js 606 kB +1.37 kB (+0.23%)
packages/rrweb/rrweb/dist/rrweb.umd.cjs 606 kB +1.37 kB (+0.23%)
packages/rrweb/rrweb/dist/rrweb.umd.min.cjs 286 kB +683 B (+0.24%)
packages/rrweb/utils/dist/rrweb-utils.cjs 7.05 kB +641 B (+10%) ⚠️
packages/rrweb/utils/dist/rrweb-utils.js 6.56 kB +610 B (+10.26%) ⚠️
packages/rrweb/utils/dist/rrweb-utils.umd.cjs 7.46 kB +641 B (+9.4%) 🔍
packages/rrweb/utils/dist/rrweb-utils.umd.min.cjs 3.81 kB +307 B (+8.75%) 🔍
packages/rrweb/rrweb-snapshot/dist/types-DcjM1e-R.js 18.2 kB +18.2 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
packages/ai/dist/anthropic/index.cjs 26.2 kB 0 B
packages/ai/dist/anthropic/index.mjs 25.9 kB 0 B
packages/ai/dist/gemini/index.cjs 34.6 kB 0 B
packages/ai/dist/gemini/index.mjs 34.5 kB 0 B
packages/ai/dist/index.cjs 178 kB 0 B
packages/ai/dist/index.mjs 177 kB 0 B
packages/ai/dist/langchain/index.cjs 47.9 kB 0 B
packages/ai/dist/langchain/index.mjs 47.3 kB 0 B
packages/ai/dist/openai-agents/index.cjs 25.5 kB 0 B
packages/ai/dist/openai-agents/index.mjs 25.4 kB 0 B
packages/ai/dist/openai/index.cjs 55.7 kB 0 B
packages/ai/dist/openai/index.mjs 55.4 kB 0 B
packages/ai/dist/otel/index.cjs 6.59 kB 0 B
packages/ai/dist/otel/index.mjs 6.47 kB 0 B
packages/ai/dist/vercel/index.cjs 44.8 kB 0 B
packages/ai/dist/vercel/index.mjs 44.7 kB 0 B
packages/browser/dist/array.full.es5.js 354 kB 0 B
packages/browser/dist/array.js 195 kB 0 B
packages/browser/dist/array.no-********.js 214 kB 0 B
packages/browser/dist/conversations.js 67.3 kB 0 B
packages/browser/dist/crisp-chat-integration.js 1.97 kB 0 B
packages/browser/dist/customizations.full.js 18.8 kB 0 B
packages/browser/dist/dead-clicks-autocapture.js 14.3 kB 0 B
packages/browser/dist/default-extensions.js 193 kB 0 B
packages/browser/dist/element-inference.js 5.69 kB 0 B
packages/browser/dist/exception-autocapture.js 11.8 kB 0 B
packages/browser/dist/extension-bundles.js 107 kB 0 B
packages/browser/dist/external-scripts-loader.js 3.13 kB 0 B
packages/browser/dist/intercom-integration.js 2.03 kB 0 B
packages/browser/dist/logs.js 40.6 kB 0 B
packages/browser/dist/main.js 200 kB 0 B
packages/browser/dist/module.js 199 kB 0 B
packages/browser/dist/module.no-********.js 218 kB 0 B
packages/browser/dist/module.slim.js 105 kB 0 B
packages/browser/dist/module.slim.no-********.js 111 kB 0 B
packages/browser/dist/product-tours-preview.js 76.4 kB 0 B
packages/browser/dist/product-tours.js 115 kB 0 B
packages/browser/dist/rrweb-plugin-console-record.js 6.67 kB 0 B
packages/browser/dist/rrweb-types.js 2.28 kB 0 B
packages/browser/dist/surveys-preview.js 76.3 kB 0 B
packages/browser/dist/surveys.js 94.7 kB 0 B
packages/browser/dist/tracing-headers.js 3.36 kB 0 B
packages/browser/dist/web-vitals-with-attribution.js 11.8 kB 0 B
packages/browser/dist/web-vitals.js 6.39 kB 0 B
packages/browser/react/dist/esm/index.js 21.2 kB 0 B
packages/browser/react/dist/esm/slim/index.js 17.6 kB 0 B
packages/browser/react/dist/esm/surveys/index.js 4.68 kB 0 B
packages/browser/react/dist/umd/index.js 24.5 kB 0 B
packages/browser/react/dist/umd/slim/index.js 20.4 kB 0 B
packages/browser/react/dist/umd/surveys/index.js 5.45 kB 0 B
packages/convex/dist/client/feature-flags/crypto.js 461 B 0 B
packages/convex/dist/client/feature-flags/evaluator.js 16.5 kB 0 B
packages/convex/dist/client/feature-flags/index.js 196 B 0 B
packages/convex/dist/client/feature-flags/match-********.js 14.8 kB 0 B
packages/convex/dist/client/feature-flags/types.js 44 B 0 B
packages/convex/dist/client/index.js 14.7 kB 0 B
packages/convex/dist/component/_generated/api.js 712 B 0 B
packages/convex/dist/component/_generated/component.js 212 B 0 B
packages/convex/dist/component/_generated/dataModel.js 230 B 0 B
packages/convex/dist/component/_generated/server.js 3.74 kB 0 B
packages/convex/dist/component/convex.config.js 1.11 kB 0 B
packages/convex/dist/component/crons.js 1.4 kB 0 B
packages/convex/dist/component/lib.js 21.4 kB 0 B
packages/convex/dist/component/schema.js 694 B 0 B
packages/convex/dist/component/version.js 68 B 0 B
packages/core/dist/cookie.js 5.34 kB 0 B
packages/core/dist/cookie.mjs 3.12 kB 0 B
packages/core/dist/error-tracking/chunk-ids.js 2.54 kB 0 B
packages/core/dist/error-tracking/chunk-ids.mjs 1.31 kB 0 B
packages/core/dist/error-tracking/coercers/dom-exception-coercer.js 2.3 kB 0 B
packages/core/dist/error-tracking/coercers/dom-exception-coercer.mjs 993 B 0 B
packages/core/dist/error-tracking/coercers/error-coercer.js 2.02 kB 0 B
packages/core/dist/error-tracking/coercers/error-coercer.mjs 794 B 0 B
packages/core/dist/error-tracking/coercers/error-event-coercer.js 1.76 kB 0 B
packages/core/dist/error-tracking/coercers/error-event-coercer.mjs 513 B 0 B
packages/core/dist/error-tracking/coercers/event-coercer.js 1.82 kB 0 B
packages/core/dist/error-tracking/coercers/event-coercer.mjs 548 B 0 B
packages/core/dist/error-tracking/coercers/index.js 6.79 kB 0 B
packages/core/dist/error-tracking/coercers/index.mjs 326 B 0 B
packages/core/dist/error-tracking/coercers/object-coercer.js 3.46 kB 0 B
packages/core/dist/error-tracking/coercers/object-coercer.mjs 2.07 kB 0 B
packages/core/dist/error-tracking/coercers/primitive-coercer.js 1.67 kB 0 B
packages/core/dist/error-tracking/coercers/primitive-coercer.mjs 419 B 0 B
packages/core/dist/error-tracking/coercers/promise-rejection-event.js 2.59 kB 0 B
packages/core/dist/error-tracking/coercers/promise-rejection-event.mjs 1.25 kB 0 B
packages/core/dist/error-tracking/coercers/string-coercer.js 2.01 kB 0 B
packages/core/dist/error-tracking/coercers/string-coercer.mjs 820 B 0 B
packages/core/dist/error-tracking/coercers/utils.js 2.06 kB 0 B
packages/core/dist/error-tracking/coercers/utils.mjs 716 B 0 B
packages/core/dist/error-tracking/error-properties-builder.js 5.56 kB 0 B
packages/core/dist/error-tracking/error-properties-builder.mjs 4.23 kB 0 B
packages/core/dist/error-tracking/exception-steps.js 6.87 kB 0 B
packages/core/dist/error-tracking/exception-steps.mjs 4.71 kB 0 B
packages/core/dist/error-tracking/index.js 4.74 kB 0 B
packages/core/dist/error-tracking/index.mjs 191 B 0 B
packages/core/dist/error-tracking/parsers/base.js 1.83 kB 0 B
packages/core/dist/error-tracking/parsers/base.mjs 464 B 0 B
packages/core/dist/error-tracking/parsers/chrome.js 2.73 kB 0 B
packages/core/dist/error-tracking/parsers/chrome.mjs 1.32 kB 0 B
packages/core/dist/error-tracking/parsers/gecko.js 2.47 kB 0 B
packages/core/dist/error-tracking/parsers/gecko.mjs 1.13 kB 0 B
packages/core/dist/error-tracking/parsers/index.js 4.75 kB 0 B
packages/core/dist/error-tracking/parsers/index.mjs 2.1 kB 0 B
packages/core/dist/error-tracking/parsers/node.js 3.94 kB 0 B
packages/core/dist/error-tracking/parsers/node.mjs 2.68 kB 0 B
packages/core/dist/error-tracking/parsers/opera.js 2.26 kB 0 B
packages/core/dist/error-tracking/parsers/opera.mjs 746 B 0 B
packages/core/dist/error-tracking/parsers/safari.js 1.88 kB 0 B
packages/core/dist/error-tracking/parsers/safari.mjs 574 B 0 B
packages/core/dist/error-tracking/parsers/winjs.js 1.72 kB 0 B
packages/core/dist/error-tracking/parsers/winjs.mjs 426 B 0 B
packages/core/dist/error-tracking/types.js 1.33 kB 0 B
packages/core/dist/error-tracking/types.mjs 131 B 0 B
packages/core/dist/error-tracking/utils.js 1.8 kB 0 B
packages/core/dist/error-tracking/utils.mjs 604 B 0 B
packages/core/dist/eventemitter.js 1.78 kB 0 B
packages/core/dist/eventemitter.mjs 571 B 0 B
packages/core/dist/featureFlagUtils.js 6.8 kB 0 B
packages/core/dist/featureFlagUtils.mjs 4.32 kB 0 B
packages/core/dist/gzip.js 5.72 kB 0 B
packages/core/dist/gzip.mjs 3.84 kB 0 B
packages/core/dist/index.js 13.6 kB 0 B
packages/core/dist/index.mjs 1.31 kB 0 B
packages/core/dist/logs/index.js 9.47 kB 0 B
packages/core/dist/logs/index.mjs 7.87 kB 0 B
packages/core/dist/logs/logs-utils.js 5.96 kB 0 B
packages/core/dist/logs/logs-utils.mjs 3.99 kB 0 B
packages/core/dist/logs/types.js 603 B 0 B
packages/core/dist/logs/types.mjs 0 B 0 B 🆕
packages/core/dist/posthog-core-stateless.js 34.6 kB 0 B
packages/core/dist/posthog-core-stateless.mjs 31.7 kB 0 B
packages/core/dist/posthog-core.js 41.8 kB 0 B
packages/core/dist/posthog-core.mjs 36.8 kB 0 B
packages/core/dist/surveys/events.js 4.21 kB 0 B
packages/core/dist/surveys/events.mjs 1.99 kB 0 B
packages/core/dist/surveys/index.js 4.57 kB 0 B
packages/core/dist/surveys/index.mjs 894 B 0 B
packages/core/dist/surveys/translations.js 9.4 kB 0 B
packages/core/dist/surveys/translations.mjs 7.03 kB 0 B
packages/core/dist/surveys/validation.js 3.06 kB 0 B
packages/core/dist/surveys/validation.mjs 1.51 kB 0 B
packages/core/dist/testing/index.js 2.93 kB 0 B
packages/core/dist/testing/index.mjs 79 B 0 B
packages/core/dist/testing/PostHogCoreTestClient.js 3.15 kB 0 B
packages/core/dist/testing/PostHogCoreTestClient.mjs 1.74 kB 0 B
packages/core/dist/testing/test-utils.js 2.83 kB 0 B
packages/core/dist/testing/test-utils.mjs 1.15 kB 0 B
packages/core/dist/tracing-headers.js 3.38 kB 0 B
packages/core/dist/tracing-headers.mjs 2.08 kB 0 B
packages/core/dist/types.js 9.62 kB 0 B
packages/core/dist/types.mjs 7.07 kB 0 B
packages/core/dist/utils/bot-detection.js 3.28 kB 0 B
packages/core/dist/utils/bot-detection.mjs 1.95 kB 0 B
packages/core/dist/utils/bucketed-rate-limiter.js 3 kB 0 B
packages/core/dist/utils/bucketed-rate-limiter.mjs 1.62 kB 0 B
packages/core/dist/utils/index.js 11.9 kB 0 B
packages/core/dist/utils/index.mjs 1.98 kB 0 B
packages/core/dist/utils/logger.js 2.58 kB 0 B
packages/core/dist/utils/logger.mjs 1.29 kB 0 B
packages/core/dist/utils/number-utils.js 3.32 kB 0 B
packages/core/dist/utils/number-utils.mjs 1.68 kB 0 B
packages/core/dist/utils/promise-queue.js 2 kB 0 B
packages/core/dist/utils/promise-queue.mjs 768 B 0 B
packages/core/dist/utils/string-utils.js 2.73 kB 0 B
packages/core/dist/utils/string-utils.mjs 1.09 kB 0 B
packages/core/dist/utils/type-utils.js 7.04 kB 0 B
packages/core/dist/utils/type-utils.mjs 3.11 kB 0 B
packages/core/dist/utils/user-agent-utils.js 17.4 kB 0 B
packages/core/dist/utils/user-agent-utils.mjs 13.9 kB 0 B
packages/core/dist/vendor/uuidv7.js 8.29 kB 0 B
packages/core/dist/vendor/uuidv7.mjs 6.72 kB 0 B
packages/mcp/dist/index.js 1.29 kB 0 B
packages/mcp/dist/index.mjs 61 B 0 B
packages/mcp/dist/version.js 1.21 kB 0 B
packages/mcp/dist/version.mjs 46 B 0 B
packages/next/dist/app/PostHogProvider.js 3.33 kB 0 B
packages/next/dist/client/ClientPostHogProvider.js 1.76 kB 0 B
packages/next/dist/client/hooks.js 172 B 0 B
packages/next/dist/client/PostHogPageView.js 1.76 kB 0 B
packages/next/dist/index.client.js 401 B 0 B
packages/next/dist/index.edge.js 447 B 0 B
packages/next/dist/index.js 444 B 0 B
packages/next/dist/index.react-server.js 420 B 0 B
packages/next/dist/middleware/postHogMiddleware.js 3.7 kB 0 B
packages/next/dist/pages.client.js 502 B 0 B
packages/next/dist/pages.edge.js 570 B 0 B
packages/next/dist/pages.js 414 B 0 B
packages/next/dist/pages/getServerSidePostHog.js 1.99 kB 0 B
packages/next/dist/pages/PostHogPageView.js 1.32 kB 0 B
packages/next/dist/pages/PostHogProvider.js 1.61 kB 0 B
packages/next/dist/server/getPostHog.js 2.79 kB 0 B
packages/next/dist/server/nodeClientCache.js 1.31 kB 0 B
packages/next/dist/shared/browser.js 195 B 0 B
packages/next/dist/shared/config.js 2.08 kB 0 B
packages/next/dist/shared/constants.js 201 B 0 B
packages/next/dist/shared/cookie.js 540 B 0 B
packages/next/dist/shared/identity.js 264 B 0 B
packages/next/dist/shared/tracing-headers.js 2.18 kB 0 B
packages/nextjs-config/dist/config.js 5.82 kB 0 B
packages/nextjs-config/dist/config.mjs 4.34 kB 0 B
packages/nextjs-config/dist/index.js 2.24 kB 0 B
packages/nextjs-config/dist/index.mjs 30 B 0 B
packages/nextjs-config/dist/utils.js 2.94 kB 0 B
packages/nextjs-config/dist/utils.mjs 826 B 0 B
packages/node/dist/client.js 46.7 kB 0 B
packages/node/dist/client.mjs 44.3 kB 0 B
packages/node/dist/entrypoints/index.edge.js 3.85 kB 0 B
packages/node/dist/entrypoints/index.edge.mjs 720 B 0 B
packages/node/dist/entrypoints/index.node.js 5.67 kB 0 B
packages/node/dist/entrypoints/index.node.mjs 1.25 kB 0 B
packages/node/dist/entrypoints/nestjs.js 2.31 kB 0 B
packages/node/dist/entrypoints/nestjs.mjs 42 B 0 B
packages/node/dist/experimental.js 870 B 0 B
packages/node/dist/experimental.mjs 267 B 0 B
packages/node/dist/exports.js 6.75 kB 0 B
packages/node/dist/exports.mjs 582 B 0 B
packages/node/dist/extensions/context/context.js 2.13 kB 0 B
packages/node/dist/extensions/context/context.mjs 863 B 0 B
packages/node/dist/extensions/context/types.js 603 B 0 B
packages/node/dist/extensions/context/types.mjs 0 B 0 B 🆕
packages/node/dist/extensions/error-tracking/autocapture.js 2.66 kB 0 B
packages/node/dist/extensions/error-tracking/autocapture.mjs 1.24 kB 0 B
packages/node/dist/extensions/error-tracking/index.js 4.15 kB 0 B
packages/node/dist/extensions/error-tracking/index.mjs 2.88 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/context-lines.node.js 8.81 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs 7.15 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/module.node.js 2.78 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/module.node.mjs 1.45 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/relative-path.node.js 1.97 kB 0 B
packages/node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs 624 B 0 B
packages/node/dist/extensions/express.js 4.6 kB 0 B
packages/node/dist/extensions/express.mjs 2.49 kB 0 B
packages/node/dist/extensions/feature-flags/cache.js 603 B 0 B
packages/node/dist/extensions/feature-flags/cache.mjs 0 B 0 B 🆕
packages/node/dist/extensions/feature-flags/crypto.js 1.57 kB 0 B
packages/node/dist/extensions/feature-flags/crypto.mjs 395 B 0 B
packages/node/dist/extensions/feature-flags/feature-flags.js 40.6 kB 0 B
packages/node/dist/extensions/feature-flags/feature-flags.mjs 38.5 kB 0 B
packages/node/dist/extensions/nestjs.js 5 kB 0 B
packages/node/dist/extensions/nestjs.mjs 2.9 kB 0 B
packages/node/dist/extensions/sentry-integration.js 4.66 kB 0 B
packages/node/dist/extensions/sentry-integration.mjs 3.17 kB 0 B
packages/node/dist/extensions/tracing-headers.js 3.31 kB 0 B
packages/node/dist/extensions/tracing-headers.mjs 1.53 kB 0 B
packages/node/dist/feature-flag-evaluations.js 5.97 kB 0 B
packages/node/dist/feature-flag-evaluations.mjs 4.63 kB 0 B
packages/node/dist/storage-memory.js 1.52 kB 0 B
packages/node/dist/storage-memory.mjs 297 B 0 B
packages/node/dist/types.js 1.43 kB 0 B
packages/node/dist/types.mjs 224 B 0 B
packages/node/dist/version.js 1.21 kB 0 B
packages/node/dist/version.mjs 46 B 0 B
packages/nuxt/dist/module.mjs 5.29 kB 0 B
packages/nuxt/dist/runtime/composables/useFeatureFlagEnabled.js 566 B 0 B
packages/nuxt/dist/runtime/composables/useFeatureFlagPayload.js 690 B 0 B
packages/nuxt/dist/runtime/composables/useFeatureFlagVariantKey.js 591 B 0 B
packages/nuxt/dist/runtime/composables/usePostHog.js 128 B 0 B
packages/nuxt/dist/runtime/nitro-plugin.js 1.08 kB 0 B
packages/nuxt/dist/runtime/vue-plugin.js 1.14 kB 0 B
packages/plugin-utils/dist/cli.js 3.14 kB 0 B
packages/plugin-utils/dist/cli.mjs 1.64 kB 0 B
packages/plugin-utils/dist/config.js 3.07 kB 0 B
packages/plugin-utils/dist/config.mjs 1.83 kB 0 B
packages/plugin-utils/dist/index.js 4.3 kB 0 B
packages/plugin-utils/dist/index.mjs 217 B 0 B
packages/plugin-utils/dist/spawn-local.js 2.17 kB 0 B
packages/plugin-utils/dist/spawn-local.mjs 918 B 0 B
packages/plugin-utils/dist/utils.js 3.27 kB 0 B
packages/plugin-utils/dist/utils.mjs 1.3 kB 0 B
packages/react-native/dist/autocapture.js 5.05 kB 0 B
packages/react-native/dist/error-tracking/index.js 5.77 kB 0 B
packages/react-native/dist/error-tracking/utils.js 2.58 kB 0 B
packages/react-native/dist/frameworks/wix-navigation.js 1.3 kB 0 B
packages/react-native/dist/hooks/useFeatureFlag.js 1.7 kB 0 B
packages/react-native/dist/hooks/useFeatureFlagResult.js 963 B 0 B
packages/react-native/dist/hooks/useFeatureFlags.js 921 B 0 B
packages/react-native/dist/hooks/useNavigationTracker.js 2.45 kB 0 B
packages/react-native/dist/hooks/usePostHog.js 544 B 0 B
packages/react-native/dist/hooks/utils.js 988 B 0 B
packages/react-native/dist/index.js 4.33 kB 0 B
packages/react-native/dist/logs-********.js 3.32 kB 0 B
packages/react-native/dist/native-deps.js 8.77 kB 0 B
packages/react-native/dist/optional/OptionalAsyncStorage.js 299 B 0 B
packages/react-native/dist/optional/OptionalExpoApplication.js 377 B 0 B
packages/react-native/dist/optional/OptionalExpoDevice.js 347 B 0 B
packages/react-native/dist/optional/OptionalExpoFileSystem.js 386 B 0 B
packages/react-native/dist/optional/OptionalExpoFileSystemLegacy.js 423 B 0 B
packages/react-native/dist/optional/OptionalExpoLocalization.js 383 B 0 B
packages/react-native/dist/optional/OptionalReactNativeDeviceInfo.js 415 B 0 B
packages/react-native/dist/optional/OptionalReactNativeLocalize.js 303 B 0 B
packages/react-native/dist/optional/OptionalReactNativeNavigation.js 415 B 0 B
packages/react-native/dist/optional/OptionalReactNativeNavigationWix.js 443 B 0 B
packages/react-native/dist/optional/OptionalReactNativeSafeArea.js 644 B 0 B
packages/react-native/dist/optional/OptionalReactNativeSvg.js 872 B 0 B
packages/react-native/dist/optional/OptionalSessionReplay.js 455 B 0 B
packages/react-native/dist/posthog-rn.js 47.6 kB 0 B
packages/react-native/dist/PostHogContext.js 329 B 0 B
packages/react-native/dist/PostHogErrorBoundary.js 3.19 kB 0 B
packages/react-native/dist/PostHogMaskView.js 1.68 kB 0 B
packages/react-native/dist/PostHogProvider.js 4.55 kB 0 B
packages/react-native/dist/storage.js 5.76 kB 0 B
packages/react-native/dist/surveys/components/BottomSection.js 1.51 kB 0 B
packages/react-native/dist/surveys/components/Cancel.js 968 B 0 B
packages/react-native/dist/surveys/components/ConfirmationMessage.js 1.71 kB 0 B
packages/react-native/dist/surveys/components/QuestionHeader.js 1.43 kB 0 B
packages/react-native/dist/surveys/components/QuestionTypes.js 13.4 kB 0 B
packages/react-native/dist/surveys/components/SurveyModal.js 6.33 kB 0 B
packages/react-native/dist/surveys/components/Surveys.js 6.58 kB 0 B
packages/react-native/dist/surveys/getActiveMatchingSurveys.js 2.64 kB 0 B
packages/react-native/dist/surveys/icons.js 10 kB 0 B
packages/react-native/dist/surveys/index.js 600 B 0 B
packages/react-native/dist/surveys/PostHogSurveyProvider.js 6.28 kB 0 B
packages/react-native/dist/surveys/safeStyleSheet.js 418 B 0 B
packages/react-native/dist/surveys/survey-translations.js 1.11 kB 0 B
packages/react-native/dist/surveys/surveys-utils.js 14.2 kB 0 B
packages/react-native/dist/surveys/useActivatedSurveys.js 3.67 kB 0 B
packages/react-native/dist/surveys/useSurveyStorage.js 2.16 kB 0 B
packages/react-native/dist/tooling/expoconfig.js 4.16 kB 0 B
packages/react-native/dist/tooling/metroconfig.js 2.32 kB 0 B
packages/react-native/dist/tooling/posthogMetroSerializer.js 4.86 kB 0 B
packages/react-native/dist/tooling/utils.js 4.05 kB 0 B
packages/react-native/dist/tooling/vendor/expo/expoconfig.js 70 B 0 B
packages/react-native/dist/tooling/vendor/metro/countLines.js 237 B 0 B
packages/react-native/dist/tooling/vendor/metro/utils.js 3.35 kB 0 B
packages/react-native/dist/types.js 70 B 0 B
packages/react-native/dist/utils.js 1.14 kB 0 B
packages/react-native/dist/version.js 131 B 0 B
packages/react/dist/esm/index.js 21.2 kB 0 B
packages/react/dist/esm/slim/index.js 17.6 kB 0 B
packages/react/dist/esm/surveys/index.js 4.68 kB 0 B
packages/react/dist/umd/index.js 24.5 kB 0 B
packages/react/dist/umd/slim/index.js 20.4 kB 0 B
packages/react/dist/umd/surveys/index.js 5.45 kB 0 B
packages/rollup-plugin/dist/index.js 2.44 kB 0 B
packages/rrweb/packer/dist/base-********.js 18.2 kB 0 B
packages/rrweb/packer/dist/base-********.cjs 18.3 kB 0 B
packages/rrweb/packer/dist/base-********.umd.cjs 18.7 kB 0 B
packages/rrweb/packer/dist/base-********.umd.min.cjs 9.5 kB 0 B
packages/rrweb/packer/dist/pack.cjs 347 B 0 B
packages/rrweb/packer/dist/pack.js 285 B 0 B
packages/rrweb/packer/dist/pack.umd.cjs 1.63 kB 0 B
packages/rrweb/packer/dist/pack.umd.min.cjs 1.11 kB 0 B
packages/rrweb/packer/dist/packer.cjs 257 B 0 B
packages/rrweb/packer/dist/packer.js 136 B 0 B
packages/rrweb/packer/dist/packer.umd.cjs 662 B 0 B
packages/rrweb/packer/dist/packer.umd.min.cjs 626 B 0 B
packages/rrweb/packer/dist/unpack.cjs 769 B 0 B
packages/rrweb/packer/dist/unpack.js 702 B 0 B
packages/rrweb/packer/dist/unpack.umd.cjs 1.17 kB 0 B
packages/rrweb/packer/dist/unpack.umd.min.cjs 955 B 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.cjs 37.6 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.js 37.5 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.umd.cjs 38 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.umd.min.cjs 22.2 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.cjs 34.3 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.js 34.2 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.umd.cjs 34.7 kB 0 B
packages/rrweb/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.umd.min.cjs 20.5 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.cjs 14.9 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js 14.8 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.umd.cjs 15.4 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.umd.min.cjs 7.33 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.cjs 5.01 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.js 4.9 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.umd.cjs 5.44 kB 0 B
packages/rrweb/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.umd.min.cjs 2.64 kB 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.cjs 681 B 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.js 548 B 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.umd.cjs 1.12 kB 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.umd.min.cjs 829 B 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.cjs 933 B 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.js 820 B 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.umd.cjs 1.37 kB 0 B
packages/rrweb/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.umd.min.cjs 968 B 0 B
packages/rrweb/rrdom-nodejs/dist/rrdom-nodejs.cjs 150 kB 0 B
packages/rrweb/rrdom-nodejs/dist/rrdom-nodejs.js 149 kB 0 B
packages/rrweb/rrdom-nodejs/dist/rrdom-nodejs.umd.cjs 152 kB 0 B
packages/rrweb/rrdom-nodejs/dist/rrdom-nodejs.umd.min.cjs 70.8 kB 0 B
packages/rrweb/rrweb-snapshot/dist/record.cjs 33.9 kB 0 B
packages/rrweb/rrweb-snapshot/dist/record.js 32.8 kB 0 B
packages/rrweb/rrweb-snapshot/dist/replay.cjs 138 kB 0 B
packages/rrweb/rrweb-snapshot/dist/replay.js 137 kB 0 B
packages/rrweb/rrweb-snapshot/dist/rrweb-********.cjs 2.27 kB 0 B
packages/rrweb/rrweb-snapshot/dist/rrweb-********.js 1.42 kB 0 B
packages/rrweb/types/dist/rrweb-types.cjs 5.64 kB 0 B
packages/rrweb/types/dist/rrweb-types.js 5.38 kB 0 B
packages/rrweb/types/dist/rrweb-types.umd.cjs 6.04 kB 0 B
packages/rrweb/types/dist/rrweb-types.umd.min.cjs 2.8 kB 0 B
packages/types/dist/capture-log.js 603 B 0 B
packages/types/dist/capture-log.mjs 0 B 0 B 🆕
packages/types/dist/capture.js 603 B 0 B
packages/types/dist/capture.mjs 0 B 0 B 🆕
packages/types/dist/common.js 603 B 0 B
packages/types/dist/common.mjs 0 B 0 B 🆕
packages/types/dist/feature-flags.js 603 B 0 B
packages/types/dist/feature-flags.mjs 0 B 0 B 🆕
packages/types/dist/index.js 603 B 0 B
packages/types/dist/index.mjs 0 B 0 B 🆕
packages/types/dist/posthog-config.js 603 B 0 B
packages/types/dist/posthog-config.mjs 0 B 0 B 🆕
packages/types/dist/posthog.js 603 B 0 B
packages/types/dist/posthog.mjs 0 B 0 B 🆕
packages/types/dist/request.js 603 B 0 B
packages/types/dist/request.mjs 0 B 0 B 🆕
packages/types/dist/segment.js 603 B 0 B
packages/types/dist/segment.mjs 0 B 0 B 🆕
packages/types/dist/session-recording.js 603 B 0 B
packages/types/dist/session-recording.mjs 0 B 0 B 🆕
packages/types/dist/survey.js 603 B 0 B
packages/types/dist/survey.mjs 0 B 0 B 🆕
packages/types/dist/toolbar.js 603 B 0 B
packages/types/dist/toolbar.mjs 0 B 0 B 🆕
packages/types/dist/tree-shakeable.js 603 B 0 B
packages/types/dist/tree-shakeable.mjs 0 B 0 B 🆕
packages/web/dist/index.cjs 13.9 kB 0 B
packages/web/dist/index.mjs 13.8 kB 0 B
packages/webpack-plugin/dist/config.js 1.47 kB 0 B
packages/webpack-plugin/dist/config.mjs 480 B 0 B
packages/webpack-plugin/dist/index.js 5.38 kB 0 B
packages/webpack-plugin/dist/index.mjs 2.04 kB 0 B
tooling/changelog/dist/index.js 3.31 kB 0 B
tooling/rollup-utils/dist/index.js 1.17 kB 0 B

compressed-size-action

arnohillen and others added 2 commits June 7, 2026 18:29
Sync the only functional upstream change since the fork's baseline
(rrweb@2.0.0-alpha.18): rrweb-io/rrweb#1854. WebKit/Safari tears down a
detached iframe's ScriptExecutionContext, so the pristine MutationObserver
rrweb pulls from a throwaway iframe (to dodge 3rd-party monkey-patching)
silently stopped delivering mutations once the iframe was removed, halting
DOM recording on affected Safari pages. Keep that iframe attached on Safari
(hidden, rr-block-tagged) and tear it down via a cleanup wired through
initMutationObserver's teardown.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rebase onto main. Export cleanupUntaintedIframe instead of threading
iframeCleanup through initMutationObserver. Add unit and puppeteer tests
for monkey-patched MutationObserver recording.

Co-authored-by: Cursor <cursoragent@cursor.com>
@arnohillen arnohillen force-pushed the ahillen/rrweb-sync-webkit-mutationobserver branch from addc9ee to 1082c45 Compare June 7, 2026 17:32
Comment on lines 142 to 143
return defaultPrototype;
} finally {
if (iframeEl.parentNode) {
document.body.removeChild(iframeEl);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory leak: The catch block doesn't clean up the iframe that was appended at line 115. The old code had a finally block that removed the iframe in all cases. Now if an exception is thrown after appendChild (line 115) but before the cleanup function is stored (line 135), the iframe will leak on Safari. Even on non-Safari browsers, if an exception occurs between line 115 and line 137, the iframe leaks.

Fix:

catch {
  iframeEl.remove();
  return defaultPrototype;
}
Suggested change
return defaultPrototype;
} finally {
if (iframeEl.parentNode) {
document.body.removeChild(iframeEl);
}
}
iframeEl.remove();
return defaultPrototype;
}

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Cover stop/start recording, iframe cleanup after teardown, and mixed
attribute/child-list mutations under a hijacked MutationObserver.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment on lines +149 to +150
untaintedBaseIframeCleanup[key]?.();
delete untaintedBaseIframeCleanup[key];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must-fix: this removes the iframe but never evicts untaintedBasePrototype[key]. Since getUntaintedPrototype early-returns the cached prototype, the next record() on Safari hands back a constructor bound to the now-removed iframe — so mutations record on the first session only and every later start/stop (SPA reinit, reset(), stop/restart) records nothing, the exact bug this PR fixes, one cycle later.

Suggested change
untaintedBaseIframeCleanup[key]?.();
delete untaintedBaseIframeCleanup[key];
untaintedBaseIframeCleanup[key]?.();
delete untaintedBaseIframeCleanup[key];
delete untaintedBasePrototype[key];

Comment on lines +49 to +50
utils.cleanupUntaintedIframe();
expect(document.querySelector('iframe')).toBeNull();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stops at one ctor → cleanup, so nothing here catches the bug above. Add a second mutationObserverCtor() after cleanup and assert a fresh iframe.rr-block is re-created — that fails today (the cached prototype is never evicted) and passes once it is.

@github-actions

Copy link
Copy Markdown
Contributor

This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, post a comment or remove the stale label – otherwise this will be closed in another week.

@github-actions github-actions Bot added the stale label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants