9
10
import Agent from './agent';
11
12
-import {attach as attachFiber} from './fiber/renderer';
13
-import {attach as attachFlight} from './flight/renderer';
14
-import {attach as attachLegacy} from './legacy/renderer';
15
-
16
-import {hasAssignedBackend} from './utils';
17
-
18
-import type {DevToolsHook, ReactRenderer, RendererInterface} from './types';
19
-
20
-// this is the backend that is compatible with all older React versions
21
-function isMatchingRender(version: string): boolean {
22
- return !hasAssignedBackend(version);
23
-}
12
+import type {DevToolsHook, RendererID, RendererInterface} from './types';
13
14
export type InitBackend = typeof initBackend;
15
23
return () => {};
24
}
25
26
+ function registerRendererInterface(
27
+ id: RendererID,
28
+ rendererInterface: RendererInterface,
29
+ ) {
30
+ agent.registerRendererInterface(id, rendererInterface);
31
+
32
+ // Now that the Store and the renderer interface are connected,
33
+ // it's time to flush the pending operation codes to the frontend.
34
+ rendererInterface.flushInitialOperations();
35
+ }
36
+
37
const subs = [
38
hook.sub(
39
'renderer-attached',
40
({
41
id,
42
- renderer,
42
rendererInterface,
43
}: {
44
id: number,
46
- renderer: ReactRenderer,
45
rendererInterface: RendererInterface,
48
- ...
46
}) => {
50
- agent.setRendererInterface(id, rendererInterface);
51
-
52
- // Now that the Store and the renderer interface are connected,
53
- // it's time to flush the pending operation codes to the frontend.
54
- rendererInterface.flushInitialOperations();
47
+ registerRendererInterface(id, rendererInterface);
48
},
49
),
57
-
58
- hook.sub('unsupported-renderer-version', (id: number) => {
59
- agent.onUnsupportedRenderer(id);
50
+ hook.sub('unsupported-renderer-version', () => {
51
+ agent.onUnsupportedRenderer();
52
}),
53
54
hook.sub('fastRefreshScheduled', agent.onFastRefreshScheduled),
58
// TODO Add additional subscriptions required for profiling mode
59
];
60
69
- const attachRenderer = (id: number, renderer: ReactRenderer) => {
70
- // only attach if the renderer is compatible with the current version of the backend
71
- if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
72
- return;
73
- }
74
- let rendererInterface = hook.rendererInterfaces.get(id);
75
-
76
- // Inject any not-yet-injected renderers (if we didn't reload-and-profile)
77
- if (rendererInterface == null) {
78
- if (typeof renderer.getCurrentComponentInfo === 'function') {
79
- // react-flight/client
80
- rendererInterface = attachFlight(hook, id, renderer, global);
81
- } else if (
82
- // v16-19
83
- typeof renderer.findFiberByHostInstance === 'function' ||
84
- // v16.8+
85
- renderer.currentDispatcherRef != null
86
- ) {
87
- // react-reconciler v16+
88
- rendererInterface = attachFiber(hook, id, renderer, global);
89
- } else if (renderer.ComponentTree) {
90
- // react-dom v15
91
- rendererInterface = attachLegacy(hook, id, renderer, global);
92
- } else {
93
- // Older react-dom or other unsupported renderer version
94
- }
95
-
96
- if (rendererInterface != null) {
97
- hook.rendererInterfaces.set(id, rendererInterface);
98
- }
61
+ agent.addListener('getIfHasUnsupportedRendererVersion', () => {
62
+ if (hook.hasUnsupportedRendererAttached) {
63
+ agent.onUnsupportedRenderer();
64
}
100
-
101
- // Notify the DevTools frontend about new renderers.
102
- // This includes any that were attached early (via __REACT_DEVTOOLS_ATTACH__).
103
- if (rendererInterface != null) {
104
- hook.emit('renderer-attached', {
105
- id,
106
- renderer,
107
- rendererInterface,
108
- });
109
- } else {
110
- hook.emit('unsupported-renderer-version', id);
111
- }
112
- };
113
-
114
- // Connect renderers that have already injected themselves.
115
- hook.renderers.forEach((renderer, id) => {
116
- attachRenderer(id, renderer);
65
});
66
119
- // Connect any new renderers that injected themselves.
120
- subs.push(
121
- hook.sub(
122
- 'renderer',
123
- ({id, renderer}: {id: number, renderer: ReactRenderer, ...}) => {
124
- attachRenderer(id, renderer);
125
- },
126
- ),
127
- );
67
+ hook.rendererInterfaces.forEach((rendererInterface, id) => {
68
+ registerRendererInterface(id, rendererInterface);
69
+ });
70
71
hook.emit('react-devtools', agent);
72
hook.reactDevtoolsAgent = agent;
73
+
74
const onAgentShutdown = () => {
75
subs.forEach(fn => fn());
76
hook.rendererInterfaces.forEach(rendererInterface => {