Skip to content

Commit b7a0a12

Browse files
nachooyaclaude
andcommitted
fix(runtime): don't overwrite native Event/EventTarget on web
The runtime's initialize hook unconditionally replaces globalThis.Event and globalThis.EventTarget with event-target-shim's classes. That's necessary on RN's JSC runtime (no DOM), but on web (RN Web running in a real browser) it stomps on the browser's native ctors. Safari's native EventTarget.dispatchEvent() does an internal brand check on its argument and throws TypeError: Argument 1 ('event') to EventTarget.dispatchEvent must be an instance of Event when a polyfill instance is dispatched on a native EventTarget — even though the polyfill mostly behaves like Event. That's enough to break any DOM-event-driven flow in the page; the visible casualty was FairPlay playback through @castlabs/react-native-prestoplay, where AppleEmeManager re-dispatches a synthetic `encrypted` event onto the <video> in response to `webkitneedkey` and Safari rejects it. Gate both assignments on whether a native ctor is already present so the polyfill only takes effect on platforms that genuinely lack one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 64a74d7 commit b7a0a12

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

packages/runtime/src/initialize.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@ import { getClient } from './client/index.js';
33
import { disableHMRWhenReady } from './disableHMRWhenReady.js';
44
import { setupJestMock } from './jest-mock.js';
55

6-
// Polyfill for EventTarget
6+
// Polyfill for EventTarget on runtimes that don't ship one (RN's JSC).
7+
// Do NOT overwrite when a native ctor already exists (RN Web / browsers):
8+
// Safari's EventTarget.dispatchEvent() does an internal brand check and
9+
// rejects polyfill instances with a TypeError, which breaks any
10+
// DOM-event-driven flow in the page — most visibly DRM (FairPlay) via
11+
// libraries that re-dispatch synthetic `encrypted` events.
712
const Shim = require('event-target-shim');
8-
globalThis.Event = Shim.Event;
9-
globalThis.EventTarget = Shim.EventTarget;
13+
if (typeof globalThis.Event !== 'function') {
14+
globalThis.Event = Shim.Event;
15+
}
16+
if (typeof globalThis.EventTarget !== 'function') {
17+
globalThis.EventTarget = Shim.EventTarget;
18+
}
1019

1120
// Setup jest mock to warn users about using Jest APIs
1221
setupJestMock();

0 commit comments

Comments
 (0)