@@ -16,6 +16,7 @@ import {COMPACT_VERSION_NAME} from 'react-devtools-extensions/src/utils';
16
16
import { getIsReloadAndProfileSupported } from 'react-devtools-shared/src/utils' ;
17
17
18
18
let welcomeHasInitialized = false ;
19
+ const requiredBackends = new Set < string > ( ) ;
19
20
20
21
function welcome ( event : $FlowFixMe ) {
21
22
if (
@@ -49,8 +50,6 @@ function welcome(event: $FlowFixMe) {
49
50
setup ( window . __REACT_DEVTOOLS_GLOBAL_HOOK__ ) ;
50
51
}
51
52
52
- window . addEventListener ( 'message' , welcome ) ;
53
-
54
53
function setup ( hook : ?DevToolsHook ) {
55
54
// this should not happen, but Chrome can be weird sometimes
56
55
if ( hook == null ) {
@@ -71,20 +70,27 @@ function setup(hook: ?DevToolsHook) {
71
70
updateRequiredBackends ( ) ;
72
71
73
72
// register renderers that inject themselves later.
74
- hook . sub ( 'renderer' , ( { renderer} ) => {
73
+ const unsubscribeRendererListener = hook . sub ( 'renderer' , ( { renderer} ) => {
75
74
registerRenderer ( renderer , hook ) ;
76
75
updateRequiredBackends ( ) ;
77
76
} ) ;
78
77
79
78
// listen for backend installations.
80
- hook . sub ( 'devtools-backend-installed' , version => {
81
- activateBackend ( version , hook ) ;
82
- updateRequiredBackends ( ) ;
79
+ const unsubscribeBackendInstallationListener = hook . sub (
80
+ 'devtools-backend-installed' ,
81
+ version => {
82
+ activateBackend ( version , hook ) ;
83
+ updateRequiredBackends ( ) ;
84
+ } ,
85
+ ) ;
86
+
87
+ const unsubscribeShutdownListener : ( ) => void = hook . sub ( 'shutdown' , ( ) => {
88
+ unsubscribeRendererListener ( ) ;
89
+ unsubscribeBackendInstallationListener ( ) ;
90
+ unsubscribeShutdownListener ( ) ;
83
91
} ) ;
84
92
}
85
93
86
- const requiredBackends = new Set < string > ( ) ;
87
-
88
94
function registerRenderer ( renderer : ReactRenderer , hook : DevToolsHook ) {
89
95
let version = renderer . reconcilerVersion || renderer . version ;
90
96
if ( ! hasAssignedBackend ( version ) ) {
@@ -139,6 +145,7 @@ function activateBackend(version: string, hook: DevToolsHook) {
139
145
// If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
140
146
// and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
141
147
hook . emit ( 'shutdown' ) ;
148
+ delete window . __REACT_DEVTOOLS_BACKEND_MANAGER_INJECTED__ ;
142
149
} ) ;
143
150
144
151
initBackend ( hook , agent , window , getIsReloadAndProfileSupported ( ) ) ;
@@ -178,3 +185,13 @@ function updateRequiredBackends() {
178
185
'*' ,
179
186
) ;
180
187
}
188
+
189
+ /*
190
+ * Make sure this is executed only once in case Frontend is reloaded multiple times while Backend is initializing
191
+ * We can't use `reactDevToolsAgent` field on a global Hook object, because it only cleaned up after both Frontend and Backend initialized
192
+ */
193
+ if ( ! window . __REACT_DEVTOOLS_BACKEND_MANAGER_INJECTED__ ) {
194
+ window . __REACT_DEVTOOLS_BACKEND_MANAGER_INJECTED__ = true ;
195
+
196
+ window . addEventListener ( 'message' , welcome ) ;
197
+ }
0 commit comments