Skip to content

Commit d8da2b9

Browse files
committed
Add: reload to profile for Fusebox
1 parent 33ecabe commit d8da2b9

File tree

7 files changed

+104
-29
lines changed

7 files changed

+104
-29
lines changed

packages/react-devtools-core/src/backend.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import type {
2323
import type {
2424
DevToolsHook,
2525
DevToolsHookSettings,
26+
ReloadAndProfileConfig,
27+
ReloadAndProfileConfigPersistence,
2628
} from 'react-devtools-shared/src/backend/types';
2729
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
2830

@@ -37,6 +39,7 @@ type ConnectOptions = {
3739
websocket?: ?WebSocket,
3840
onSettingsUpdated?: (settings: $ReadOnly<DevToolsHookSettings>) => void,
3941
getIsReloadAndProfileSupported?: () => boolean,
42+
reloadAndProfileConfigPersistence?: ReloadAndProfileConfigPersistence,
4043
};
4144

4245
let savedComponentFilters: Array<ComponentFilter> =
@@ -57,6 +60,7 @@ export function initialize(
5760
maybeSettingsOrSettingsPromise?:
5861
| DevToolsHookSettings
5962
| Promise<DevToolsHookSettings>,
63+
reloadAndProfileConfig: ReloadAndProfileConfig,
6064
) {
6165
installHook(window, maybeSettingsOrSettingsPromise);
6266
}
@@ -79,6 +83,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
7983
isAppActive = () => true,
8084
onSettingsUpdated,
8185
getIsReloadAndProfileSupported,
86+
reloadAndProfileConfigPersistence,
8287
} = options || {};
8388

8489
const protocol = useHttps ? 'wss' : 'ws';
@@ -172,7 +177,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
172177

173178
// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
174179
// $FlowFixMe[incompatible-call] found when upgrading Flow
175-
const agent = new Agent(bridge);
180+
const agent = new Agent(bridge, reloadAndProfileConfigPersistence);
176181
if (onSettingsUpdated != null) {
177182
agent.addListener('updateHookSettings', onSettingsUpdated);
178183
}
@@ -312,6 +317,7 @@ type ConnectWithCustomMessagingOptions = {
312317
resolveRNStyle?: ResolveNativeStyle,
313318
onSettingsUpdated?: (settings: $ReadOnly<DevToolsHookSettings>) => void,
314319
getIsReloadAndProfileSupported?: () => boolean,
320+
reloadAndProfileConfigPersistence?: ReloadAndProfileConfigPersistence,
315321
};
316322

317323
export function connectWithCustomMessagingProtocol({
@@ -322,6 +328,7 @@ export function connectWithCustomMessagingProtocol({
322328
resolveRNStyle,
323329
onSettingsUpdated,
324330
getIsReloadAndProfileSupported,
331+
reloadAndProfileConfigPersistence,
325332
}: ConnectWithCustomMessagingOptions): Function {
326333
const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
327334
if (hook == null) {
@@ -358,7 +365,7 @@ export function connectWithCustomMessagingProtocol({
358365
bridge.send('overrideComponentFilters', savedComponentFilters);
359366
}
360367

361-
const agent = new Agent(bridge);
368+
const agent = new Agent(bridge, reloadAndProfileConfigPersistence);
362369
if (onSettingsUpdated != null) {
363370
agent.addListener('updateHookSettings', onSettingsUpdated);
364371
}

packages/react-devtools-fusebox/src/frontend.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ export type Bridge = {
1919
};
2020
export type Store = Object;
2121
export type BrowserTheme = 'dark' | 'light';
22+
export type Config = {
23+
supportsReloadAndProfile?: boolean,
24+
};
2225

2326
export function createBridge(wall: Wall): Bridge;
24-
export function createStore(bridge: Bridge): Store;
27+
export function createStore(bridge: Bridge, config?: Config): Store;
2528

2629
export type Source = {
2730
sourceURL: string,

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {attach as attachFlight} from 'react-devtools-shared/src/backend/flight/r
1818
import {attach as attachFiber} from 'react-devtools-shared/src/backend/fiber/renderer';
1919
import {attach as attachLegacy} from 'react-devtools-shared/src/backend/legacy/renderer';
2020
import {hasAssignedBackend} from 'react-devtools-shared/src/backend/utils';
21+
import type {ReloadAndProfileConfig} from './backend/types';
2122

2223
// this is the backend that is compatible with all older React versions
2324
function isMatchingRender(version: string): boolean {
@@ -29,6 +30,7 @@ export default function attachRenderer(
2930
id: RendererID,
3031
renderer: ReactRenderer,
3132
global: Object,
33+
reloadAndProfileConfig?: ReloadAndProfileConfig,
3234
): RendererInterface | void {
3335
// only attach if the renderer is compatible with the current version of the backend
3436
if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
@@ -48,7 +50,13 @@ export default function attachRenderer(
4850
renderer.currentDispatcherRef != null
4951
) {
5052
// react-reconciler v16+
51-
rendererInterface = attachFiber(hook, id, renderer, global);
53+
rendererInterface = attachFiber(
54+
hook,
55+
id,
56+
renderer,
57+
global,
58+
reloadAndProfileConfig,
59+
);
5260
} else if (renderer.ComponentTree) {
5361
// react-dom v15
5462
rendererInterface = attachLegacy(hook, id, renderer, global);

packages/react-devtools-shared/src/backend/agent.js

+53-14
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import type {
3636
RendererID,
3737
RendererInterface,
3838
DevToolsHookSettings,
39+
ReloadAndProfileConfigPersistence,
40+
ReloadAndProfileConfig,
3941
} from './types';
4042
import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
4143
import {isReactNativeEnvironment} from './utils';
@@ -159,21 +161,27 @@ export default class Agent extends EventEmitter<{
159161
_persistedSelection: PersistedSelection | null = null;
160162
_persistedSelectionMatch: PathMatch | null = null;
161163
_traceUpdatesEnabled: boolean = false;
164+
_reloadAndProfileConfigPersistence: ReloadAndProfileConfigPersistence;
162165

163-
constructor(bridge: BackendBridge) {
166+
constructor(
167+
bridge: BackendBridge,
168+
reloadAndProfileConfigPersistence?: ReloadAndProfileConfigPersistence = defaultReloadAndProfileConfigSetters,
169+
) {
164170
super();
165171

166-
if (
167-
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
168-
) {
172+
this._reloadAndProfileConfigPersistence = reloadAndProfileConfigPersistence;
173+
const {getReloadAndProfileConfig, setReloadAndProfileConfig} =
174+
reloadAndProfileConfigPersistence;
175+
const reloadAndProfileConfig = getReloadAndProfileConfig();
176+
if (reloadAndProfileConfig.shouldReloadAndProfile) {
169177
this._recordChangeDescriptions =
170-
sessionStorageGetItem(
171-
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
172-
) === 'true';
178+
reloadAndProfileConfig.recordChangeDescriptions;
173179
this._isProfiling = true;
174180

175-
sessionStorageRemoveItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY);
176-
sessionStorageRemoveItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY);
181+
setReloadAndProfileConfig({
182+
shouldReloadAndProfile: false,
183+
recordChangeDescriptions: false,
184+
});
177185
}
178186

179187
const persistedSelectionString = sessionStorageGetItem(
@@ -671,11 +679,10 @@ export default class Agent extends EventEmitter<{
671679

672680
reloadAndProfile: (recordChangeDescriptions: boolean) => void =
673681
recordChangeDescriptions => {
674-
sessionStorageSetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY, 'true');
675-
sessionStorageSetItem(
676-
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
677-
recordChangeDescriptions ? 'true' : 'false',
678-
);
682+
this._reloadAndProfileConfigPersistence.setReloadAndProfileConfig({
683+
shouldReloadAndProfile: true,
684+
recordChangeDescriptions,
685+
});
679686

680687
// This code path should only be hit if the shell has explicitly told the Store that it supports profiling.
681688
// In that case, the shell must also listen for this specific message to know when it needs to reload the app.
@@ -956,3 +963,35 @@ export default class Agent extends EventEmitter<{
956963
}
957964
};
958965
}
966+
967+
const defaultReloadAndProfileConfigSetters: ReloadAndProfileConfigPersistence =
968+
{
969+
setReloadAndProfileConfig({
970+
shouldReloadAndProfile,
971+
recordChangeDescriptions,
972+
}): void {
973+
if (shouldReloadAndProfile != null) {
974+
sessionStorageSetItem(
975+
SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
976+
shouldReloadAndProfile ? 'true' : 'false',
977+
);
978+
}
979+
if (recordChangeDescriptions != null) {
980+
sessionStorageSetItem(
981+
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
982+
recordChangeDescriptions ? 'true' : 'false',
983+
);
984+
}
985+
},
986+
getReloadAndProfileConfig(): ReloadAndProfileConfig {
987+
return {
988+
shouldReloadAndProfile:
989+
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) ===
990+
'true',
991+
recordChangeDescriptions:
992+
sessionStorageGetItem(
993+
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
994+
) === 'true',
995+
};
996+
},
997+
};

packages/react-devtools-shared/src/backend/fiber/renderer.js

+6-10
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import {
4242
utfEncodeString,
4343
filterOutLocationComponentFilters,
4444
} from 'react-devtools-shared/src/utils';
45-
import {sessionStorageGetItem} from 'react-devtools-shared/src/storage';
4645
import {
4746
formatConsoleArgumentsToSingleString,
4847
gt,
@@ -61,8 +60,6 @@ import {
6160
__DEBUG__,
6261
PROFILING_FLAG_BASIC_SUPPORT,
6362
PROFILING_FLAG_TIMELINE_SUPPORT,
64-
SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
65-
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
6663
TREE_OPERATION_ADD,
6764
TREE_OPERATION_REMOVE,
6865
TREE_OPERATION_REORDER_CHILDREN,
@@ -106,6 +103,7 @@ import {
106103
supportsOwnerStacks,
107104
supportsConsoleTasks,
108105
} from './DevToolsFiberComponentStack';
106+
import type {ReloadAndProfileConfig} from '../types';
109107

110108
// $FlowFixMe[method-unbinding]
111109
const toString = Object.prototype.toString;
@@ -851,6 +849,7 @@ export function attach(
851849
rendererID: number,
852850
renderer: ReactRenderer,
853851
global: Object,
852+
reloadAndProfileConfig?: ReloadAndProfileConfig,
854853
): RendererInterface {
855854
// Newer versions of the reconciler package also specific reconciler version.
856855
// If that version number is present, use it.
@@ -5199,13 +5198,10 @@ export function attach(
51995198
}
52005199

52015200
// Automatically start profiling so that we don't miss timing info from initial "mount".
5202-
if (
5203-
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
5204-
) {
5205-
startProfiling(
5206-
sessionStorageGetItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY) ===
5207-
'true',
5208-
);
5201+
if (reloadAndProfileConfig?.shouldReloadAndProfile) {
5202+
const shouldRecordChangeDescriptions =
5203+
reloadAndProfileConfig.recordChangeDescriptions;
5204+
startProfiling(shouldRecordChangeDescriptions);
52095205
}
52105206

52115207
function getNearestFiber(devtoolsInstance: DevToolsInstance): null | Fiber {

packages/react-devtools-shared/src/backend/types.js

+14
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,20 @@ export type DevToolsBackend = {
485485
setupNativeStyleEditor?: SetupNativeStyleEditor,
486486
};
487487

488+
export type ReloadAndProfileConfig = {
489+
shouldReloadAndProfile: boolean,
490+
recordChangeDescriptions: boolean,
491+
};
492+
493+
// Linter doesn't speak Flow's `Partial` type
494+
// eslint-disable-next-line no-undef
495+
type PartialReloadAndProfileConfig = Partial<ReloadAndProfileConfig>;
496+
497+
export type ReloadAndProfileConfigPersistence = {
498+
setReloadAndProfileConfig: (config: PartialReloadAndProfileConfig) => void,
499+
getReloadAndProfileConfig: () => ReloadAndProfileConfig,
500+
};
501+
488502
export type DevToolsHook = {
489503
listeners: {[key: string]: Array<Handler>, ...},
490504
rendererInterfaces: Map<RendererID, RendererInterface>,

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
RendererInterface,
1717
DevToolsBackend,
1818
DevToolsHookSettings,
19+
ReloadAndProfileConfig,
1920
} from './backend/types';
2021

2122
import {
@@ -54,6 +55,7 @@ export function installHook(
5455
maybeSettingsOrSettingsPromise?:
5556
| DevToolsHookSettings
5657
| Promise<DevToolsHookSettings>,
58+
reloadAndProfileConfig?: ReloadAndProfileConfig,
5759
): DevToolsHook | null {
5860
if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
5961
return null;
@@ -207,7 +209,13 @@ export function installHook(
207209
reactBuildType,
208210
});
209211

210-
const rendererInterface = attachRenderer(hook, id, renderer, target);
212+
const rendererInterface = attachRenderer(
213+
hook,
214+
id,
215+
renderer,
216+
target,
217+
reloadAndProfileConfig,
218+
);
211219
if (rendererInterface != null) {
212220
hook.rendererInterfaces.set(id, rendererInterface);
213221
hook.emit('renderer-attached', {id, rendererInterface});

0 commit comments

Comments
 (0)