Skip to content

Commit cbc4d40

Browse files
authored
Typecheck React DevTools extension main script (facebook#35519)
1 parent db71391 commit cbc4d40

File tree

3 files changed

+64
-36
lines changed

3 files changed

+64
-36
lines changed

packages/react-devtools-extensions/src/main/index.js

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
/* global chrome */
2-
2+
/** @flow */
3+
4+
import type {RootType} from 'react-dom/src/client/ReactDOMRoot';
5+
import type {FrontendBridge, Message} from 'react-devtools-shared/src/bridge';
6+
import type {
7+
TabID,
8+
ViewElementSource,
9+
} from 'react-devtools-shared/src/devtools/views/DevTools';
310
import type {SourceSelection} from 'react-devtools-shared/src/devtools/views/Editor/EditorPane';
11+
import type {Element} from 'react-devtools-shared/src/frontend/types';
412

513
import {createElement} from 'react';
614
import {flushSync} from 'react-dom';
@@ -51,9 +59,9 @@ const hookNamesModuleLoaderFunction = () => resolvedParseHookNames;
5159
function createBridge() {
5260
bridge = new Bridge({
5361
listen(fn) {
54-
const bridgeListener = message => fn(message);
62+
const bridgeListener = (message: Message) => fn(message);
5563
// Store the reference so that we unsubscribe from the same object.
56-
const portOnMessage = port.onMessage;
64+
const portOnMessage = ((port: any): ExtensionPort).onMessage;
5765
portOnMessage.addListener(bridgeListener);
5866

5967
lastSubscribedBridgeListener = bridgeListener;
@@ -71,7 +79,7 @@ function createBridge() {
7179

7280
bridge.addListener('reloadAppForProfiling', () => {
7381
localStorageSetItem(LOCAL_STORAGE_SUPPORTS_PROFILING_KEY, 'true');
74-
evalInInspectedWindow('reload', []);
82+
evalInInspectedWindow('reload', [], () => {});
7583
});
7684

7785
bridge.addListener(
@@ -176,14 +184,20 @@ function createBridgeAndStore() {
176184
// Otherwise, the Store may miss important initial tree op codes.
177185
injectBackendManager(chrome.devtools.inspectedWindow.tabId);
178186

179-
const viewAttributeSourceFunction = (id, path) => {
187+
const viewAttributeSourceFunction = (
188+
id: Element['id'],
189+
path: Array<string | number>,
190+
) => {
180191
const rendererID = store.getRendererIDForElement(id);
181192
if (rendererID != null) {
182193
viewAttributeSource(rendererID, id, path);
183194
}
184195
};
185196

186-
const viewElementSourceFunction = (source, symbolicatedSource) => {
197+
const viewElementSourceFunction: ViewElementSource = (
198+
source,
199+
symbolicatedSource,
200+
) => {
187201
const [, sourceURL, line, column] = symbolicatedSource
188202
? symbolicatedSource
189203
: source;
@@ -198,7 +212,7 @@ function createBridgeAndStore() {
198212

199213
root = createRoot(document.createElement('div'));
200214

201-
render = (overrideTab = mostRecentOverrideTab) => {
215+
render = (overrideTab: TabID | null = mostRecentOverrideTab) => {
202216
mostRecentOverrideTab = overrideTab;
203217

204218
root.render(
@@ -227,7 +241,9 @@ function createBridgeAndStore() {
227241
};
228242
}
229243

230-
function ensureInitialHTMLIsCleared(container) {
244+
function ensureInitialHTMLIsCleared(
245+
container: HTMLElement & {_hasInitialHTMLBeenCleared?: boolean},
246+
) {
231247
if (container._hasInitialHTMLBeenCleared) {
232248
return;
233249
}
@@ -397,13 +413,6 @@ function createSourcesEditorPanel() {
397413
logEvent({event_name: 'selected-editor-pane'});
398414
}
399415
});
400-
401-
createdPane.onShown.addListener(() => {
402-
bridge.emit('extensionEditorPaneShown');
403-
});
404-
createdPane.onHidden.addListener(() => {
405-
bridge.emit('extensionEditorPaneHidden');
406-
});
407416
});
408417
}
409418

@@ -479,10 +488,10 @@ function performInTabNavigationCleanup() {
479488
// Do not clean mostRecentOverrideTab on purpose, so we remember last opened
480489
// React DevTools tab, when user does in-tab navigation
481490

482-
store = null;
483-
bridge = null;
484-
render = null;
485-
root = null;
491+
store = (null: $FlowFixMe);
492+
bridge = (null: $FlowFixMe);
493+
render = (null: $FlowFixMe);
494+
root = (null: $FlowFixMe);
486495
}
487496

488497
function performFullCleanup() {
@@ -504,18 +513,18 @@ function performFullCleanup() {
504513
componentsPortalContainer = null;
505514
profilerPortalContainer = null;
506515
suspensePortalContainer = null;
507-
root = null;
516+
root = (null: $FlowFixMe);
508517

509518
mostRecentOverrideTab = null;
510-
store = null;
511-
bridge = null;
512-
render = null;
519+
store = (null: $FlowFixMe);
520+
bridge = (null: $FlowFixMe);
521+
render = (null: $FlowFixMe);
513522

514523
port?.disconnect();
515-
port = null;
524+
port = (null: $FlowFixMe);
516525
}
517526

518-
function connectExtensionPort() {
527+
function connectExtensionPort(): void {
519528
if (port) {
520529
throw new Error('DevTools port was already connected');
521530
}
@@ -539,7 +548,7 @@ function connectExtensionPort() {
539548
// so, when we call `port.disconnect()` from this script,
540549
// this should not trigger this callback and port reconnection
541550
port.onDisconnect.addListener(() => {
542-
port = null;
551+
port = (null: $FlowFixMe);
543552
connectExtensionPort();
544553
});
545554
}
@@ -593,9 +602,9 @@ function mountReactDevToolsWhenReactHasLoaded() {
593602
);
594603
}
595604

596-
let bridge = null;
605+
let bridge: FrontendBridge = (null: $FlowFixMe);
597606
let lastSubscribedBridgeListener = null;
598-
let store = null;
607+
let store: Store = (null: $FlowFixMe);
599608

600609
let profilingData = null;
601610

@@ -610,13 +619,28 @@ let suspensePortalContainer = null;
610619
let editorPortalContainer = null;
611620
let inspectedElementPortalContainer = null;
612621

613-
let mostRecentOverrideTab = null;
614-
let render = null;
615-
let root = null;
622+
let mostRecentOverrideTab: null | TabID = null;
623+
let render: (overrideTab?: TabID) => void = (null: $FlowFixMe);
624+
let root: RootType = (null: $FlowFixMe);
616625

617626
let currentSelectedSource: null | SourceSelection = null;
618627

619-
let port = null;
628+
type ExtensionEvent = {
629+
addListener(callback: (message: Message, port: ExtensionPort) => void): void,
630+
removeListener(
631+
callback: (message: Message, port: ExtensionPort) => void,
632+
): void,
633+
};
634+
635+
/** https://developer.chrome.com/docs/extensions/reference/api/runtime#type-Port */
636+
type ExtensionPort = {
637+
onDisconnect: ExtensionEvent,
638+
onMessage: ExtensionEvent,
639+
postMessage(message: mixed, transferable?: Array<mixed>): void,
640+
disconnect(): void,
641+
};
642+
643+
let port: ExtensionPort = (null: $FlowFixMe);
620644

621645
// In case when multiple navigation events emitted in a short period of time
622646
// This debounced callback primarily used to avoid mounting React DevTools multiple times, which results
@@ -649,7 +673,7 @@ connectExtensionPort();
649673

650674
mountReactDevToolsWhenReactHasLoaded();
651675

652-
function onThemeChanged(themeName) {
676+
function onThemeChanged() {
653677
// Rerender with the new theme
654678
render();
655679
}

packages/react-devtools-shared/src/Logger.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ export type LoggerEvent =
6363
+value: any,
6464
...
6565
},
66-
};
66+
}
67+
| {
68+
+event_name: 'selected-editor-pane',
69+
}
70+
| {+event_name: 'selected-inspected-element-pane'};
6771

6872
export type LogFunction = LoggerEvent => void | Promise<void>;
6973

packages/react-devtools-shared/src/bridge.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export const currentBridgeProtocol: BridgeProtocol =
7474

7575
type ElementAndRendererID = {id: number, rendererID: RendererID};
7676

77-
type Message = {
77+
export type Message = {
7878
event: string,
7979
payload: any,
8080
};
@@ -239,7 +239,7 @@ export type BackendEvents = {
239239
type StartProfilingParams = ProfilingSettings;
240240
type ReloadAndProfilingParams = ProfilingSettings;
241241

242-
type FrontendEvents = {
242+
export type FrontendEvents = {
243243
clearErrorsAndWarnings: [{rendererID: RendererID}],
244244
clearErrorsForElementID: [ElementAndRendererID],
245245
clearHostInstanceHighlight: [],

0 commit comments

Comments
 (0)