main
js 102 lines 2.67 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import Agent from './agent';
11
12 import type {DevToolsHook, RendererID, RendererInterface} from './types';
13
14 export type InitBackend = typeof initBackend;
15
16 export function initBackend(
17 hook: DevToolsHook,
18 agent: Agent,
19 global: Object,
20 isReloadAndProfileSupported: boolean,
21 ): () => void {
22 if (hook == null) {
23 // DevTools didn't get injected into this page (maybe b'c of the contentType).
24 return () => {};
25 }
26
27 function registerRendererInterface(
28 id: RendererID,
29 rendererInterface: RendererInterface,
30 ) {
31 agent.registerRendererInterface(id, rendererInterface);
32
33 // Now that the Store and the renderer interface are connected,
34 // it's time to flush the pending operation codes to the frontend.
35 rendererInterface.flushInitialOperations();
36 }
37
38 const subs = [
39 hook.sub(
40 'renderer-attached',
41 ({
42 id,
43 rendererInterface,
44 }: {
45 id: number,
46 rendererInterface: RendererInterface,
47 }) => {
48 registerRendererInterface(id, rendererInterface);
49 },
50 ),
51 hook.sub('unsupported-renderer-version', () => {
52 agent.onUnsupportedRenderer();
53 }),
54
55 hook.sub('fastRefreshScheduled', agent.onFastRefreshScheduled),
56 hook.sub('operations', agent.onHookOperations),
57 hook.sub('traceUpdates', agent.onTraceUpdates),
58 hook.sub('settingsInitialized', agent.onHookSettings),
59
60 // TODO Add additional subscriptions required for profiling mode
61 ];
62
63 agent.addListener('getIfHasUnsupportedRendererVersion', () => {
64 if (hook.hasUnsupportedRendererAttached) {
65 agent.onUnsupportedRenderer();
66 }
67 });
68
69 hook.rendererInterfaces.forEach((rendererInterface, id) => {
70 registerRendererInterface(id, rendererInterface);
71 });
72
73 hook.emit('react-devtools', agent);
74 hook.reactDevtoolsAgent = agent;
75
76 const onAgentShutdown = () => {
77 subs.forEach(fn => fn());
78 hook.rendererInterfaces.forEach(rendererInterface => {
79 rendererInterface.cleanup();
80 });
81 hook.reactDevtoolsAgent = null;
82 };
83
84 // Agent's event listeners are cleaned up by Agent in `shutdown` implementation.
85 agent.addListener('shutdown', onAgentShutdown);
86 agent.addListener('updateHookSettings', settings => {
87 hook.settings = settings;
88 });
89 agent.addListener('getHookSettings', () => {
90 if (hook.settings != null) {
91 agent.onHookSettings(hook.settings);
92 }
93 });
94
95 if (isReloadAndProfileSupported) {
96 agent.onReloadAndProfileSupportedByHost();
97 }
98
99 return () => {
100 subs.forEach(fn => fn());
101 };
102 }