Skip to content

Commit

Permalink
fix[react-devtools]: initialize bridge only after domain is ready
Browse files Browse the repository at this point in the history
  • Loading branch information
hoxyq committed Sep 5, 2024
1 parent a556d26 commit b8132fc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
26 changes: 15 additions & 11 deletions front_end/panels/react_devtools/ReactDevToolsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export class ReactDevToolsModel extends SDK.SDKModel.SDKModel<EventTypes> {
readonly #listeners: Set<ReactDevToolsTypes.WallListener> = new Set();
#initializeCalled: boolean = false;
#initialized: boolean = false;
#bridge: ReactDevToolsTypes.Bridge | null;
#store: ReactDevToolsTypes.Store | null;
#bridge: ReactDevToolsTypes.Bridge | null = null;
#store: ReactDevToolsTypes.Store | null = null;

constructor(target: SDK.Target.Target) {
super(target);
Expand All @@ -52,8 +52,6 @@ export class ReactDevToolsModel extends SDK.SDKModel.SDKModel<EventTypes> {
},
send: (event, payload): void => void this.#sendMessage({event, payload}),
};
this.#bridge = ReactDevTools.createBridge(this.#wall);
this.#store = ReactDevTools.createStore(this.#bridge);

const bindingsModel = target.model(ReactNativeModels.ReactDevToolsBindingsModel.ReactDevToolsBindingsModel);
if (bindingsModel == null) {
Expand Down Expand Up @@ -82,13 +80,16 @@ export class ReactDevToolsModel extends SDK.SDKModel.SDKModel<EventTypes> {
window.addEventListener('beforeunload', () => this.#bridge?.shutdown());
}

async ensureInitialized(): Promise<void> {
ensureInitialized(): void {
if (this.#initializeCalled) {
return;
}

this.#initializeCalled = true;
void this.#initialize();
}

async #initialize(): Promise<void> {
try {
const bindingsModel = this.#bindingsModel;
await bindingsModel.enable();
Expand All @@ -101,7 +102,7 @@ export class ReactDevToolsModel extends SDK.SDKModel.SDKModel<EventTypes> {
await bindingsModel.initializeDomain(ReactDevToolsModel.FUSEBOX_BINDING_NAMESPACE);

this.#initialized = true;
this.dispatchEventToListeners(Events.InitializationCompleted);
this.#finishInitializationAndNotify();
} catch (e) {
this.dispatchEventToListeners(Events.InitializationFailed, e.message);
}
Expand Down Expand Up @@ -152,17 +153,20 @@ export class ReactDevToolsModel extends SDK.SDKModel.SDKModel<EventTypes> {
throw new Error('ReactDevToolsModel failed to handle BackendExecutionContextCreated event: ReactDevToolsBindingsModel was null');
}

this.#bridge = ReactDevTools.createBridge(this.#wall);
this.#store = ReactDevTools.createStore(this.#bridge);

// This could happen if the app was reloaded while ReactDevToolsBindingsModel was initializing
if (!rdtBindingsModel.isEnabled()) {
void this.ensureInitialized();
this.ensureInitialized();
} else {
this.dispatchEventToListeners(Events.InitializationCompleted);
this.#finishInitializationAndNotify();
}
}

#finishInitializationAndNotify(): void {
this.#bridge = ReactDevTools.createBridge(this.#wall);
this.#store = ReactDevTools.createStore(this.#bridge);
this.dispatchEventToListeners(Events.InitializationCompleted);
}

#handleBackendExecutionContextUnavailable({data: errorMessage}: ReactDevToolsBindingsBackendExecutionContextUnavailableEvent): void {
this.dispatchEventToListeners(Events.InitializationFailed, errorMessage);
}
Expand Down
16 changes: 9 additions & 7 deletions front_end/panels/react_devtools/ReactDevToolsViewBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ export class ReactDevToolsViewBase extends UI.View.SimpleView implements
modelAdded(model: ReactDevToolsModel): void {
this.#model = model;

if (model.isInitialized()) {
// Already initialized from another rendered React DevTools view - render
// from initialized state
this.#renderDevToolsView();
}

model.addEventListener(
ReactDevToolsModelEvents.InitializationCompleted,
this.#handleInitializationCompleted,
Expand All @@ -117,7 +111,15 @@ export class ReactDevToolsViewBase extends UI.View.SimpleView implements
this.#handleBackendDestroyed,
this,
);
void model.ensureInitialized();

if (model.isInitialized()) {
// Already initialized from another rendered React DevTools panel - render
// from initialized state
this.#renderDevToolsView();
} else {
// Once initialized, it will emit InitializationCompleted event
model.ensureInitialized();
}
}

modelRemoved(model: ReactDevToolsModel): void {
Expand Down

0 comments on commit b8132fc

Please sign in to comment.