Skip to content

Commit

Permalink
Add: reload to profile for Fusebox
Browse files Browse the repository at this point in the history
  • Loading branch information
EdmondChuiHW committed Sep 26, 2024
1 parent 33ecabe commit d8da2b9
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 29 deletions.
11 changes: 9 additions & 2 deletions packages/react-devtools-core/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import type {
import type {
DevToolsHook,
DevToolsHookSettings,
ReloadAndProfileConfig,
ReloadAndProfileConfigPersistence,
} from 'react-devtools-shared/src/backend/types';
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';

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

let savedComponentFilters: Array<ComponentFilter> =
Expand All @@ -57,6 +60,7 @@ export function initialize(
maybeSettingsOrSettingsPromise?:
| DevToolsHookSettings
| Promise<DevToolsHookSettings>,
reloadAndProfileConfig: ReloadAndProfileConfig,
) {
installHook(window, maybeSettingsOrSettingsPromise);
}
Expand All @@ -79,6 +83,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
isAppActive = () => true,
onSettingsUpdated,
getIsReloadAndProfileSupported,
reloadAndProfileConfigPersistence,
} = options || {};

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

// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
// $FlowFixMe[incompatible-call] found when upgrading Flow
const agent = new Agent(bridge);
const agent = new Agent(bridge, reloadAndProfileConfigPersistence);
if (onSettingsUpdated != null) {
agent.addListener('updateHookSettings', onSettingsUpdated);
}
Expand Down Expand Up @@ -312,6 +317,7 @@ type ConnectWithCustomMessagingOptions = {
resolveRNStyle?: ResolveNativeStyle,
onSettingsUpdated?: (settings: $ReadOnly<DevToolsHookSettings>) => void,
getIsReloadAndProfileSupported?: () => boolean,
reloadAndProfileConfigPersistence?: ReloadAndProfileConfigPersistence,
};

export function connectWithCustomMessagingProtocol({
Expand All @@ -322,6 +328,7 @@ export function connectWithCustomMessagingProtocol({
resolveRNStyle,
onSettingsUpdated,
getIsReloadAndProfileSupported,
reloadAndProfileConfigPersistence,
}: ConnectWithCustomMessagingOptions): Function {
const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
if (hook == null) {
Expand Down Expand Up @@ -358,7 +365,7 @@ export function connectWithCustomMessagingProtocol({
bridge.send('overrideComponentFilters', savedComponentFilters);
}

const agent = new Agent(bridge);
const agent = new Agent(bridge, reloadAndProfileConfigPersistence);
if (onSettingsUpdated != null) {
agent.addListener('updateHookSettings', onSettingsUpdated);
}
Expand Down
5 changes: 4 additions & 1 deletion packages/react-devtools-fusebox/src/frontend.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ export type Bridge = {
};
export type Store = Object;
export type BrowserTheme = 'dark' | 'light';
export type Config = {
supportsReloadAndProfile?: boolean,
};

export function createBridge(wall: Wall): Bridge;
export function createStore(bridge: Bridge): Store;
export function createStore(bridge: Bridge, config?: Config): Store;

export type Source = {
sourceURL: string,
Expand Down
10 changes: 9 additions & 1 deletion packages/react-devtools-shared/src/attachRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {attach as attachFlight} from 'react-devtools-shared/src/backend/flight/r
import {attach as attachFiber} from 'react-devtools-shared/src/backend/fiber/renderer';
import {attach as attachLegacy} from 'react-devtools-shared/src/backend/legacy/renderer';
import {hasAssignedBackend} from 'react-devtools-shared/src/backend/utils';
import type {ReloadAndProfileConfig} from './backend/types';

// this is the backend that is compatible with all older React versions
function isMatchingRender(version: string): boolean {
Expand All @@ -29,6 +30,7 @@ export default function attachRenderer(
id: RendererID,
renderer: ReactRenderer,
global: Object,
reloadAndProfileConfig?: ReloadAndProfileConfig,
): RendererInterface | void {
// only attach if the renderer is compatible with the current version of the backend
if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
Expand All @@ -48,7 +50,13 @@ export default function attachRenderer(
renderer.currentDispatcherRef != null
) {
// react-reconciler v16+
rendererInterface = attachFiber(hook, id, renderer, global);
rendererInterface = attachFiber(
hook,
id,
renderer,
global,
reloadAndProfileConfig,
);
} else if (renderer.ComponentTree) {
// react-dom v15
rendererInterface = attachLegacy(hook, id, renderer, global);
Expand Down
67 changes: 53 additions & 14 deletions packages/react-devtools-shared/src/backend/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import type {
RendererID,
RendererInterface,
DevToolsHookSettings,
ReloadAndProfileConfigPersistence,
ReloadAndProfileConfig,
} from './types';
import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
import {isReactNativeEnvironment} from './utils';
Expand Down Expand Up @@ -159,21 +161,27 @@ export default class Agent extends EventEmitter<{
_persistedSelection: PersistedSelection | null = null;
_persistedSelectionMatch: PathMatch | null = null;
_traceUpdatesEnabled: boolean = false;
_reloadAndProfileConfigPersistence: ReloadAndProfileConfigPersistence;

constructor(bridge: BackendBridge) {
constructor(
bridge: BackendBridge,
reloadAndProfileConfigPersistence?: ReloadAndProfileConfigPersistence = defaultReloadAndProfileConfigSetters,
) {
super();

if (
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
) {
this._reloadAndProfileConfigPersistence = reloadAndProfileConfigPersistence;
const {getReloadAndProfileConfig, setReloadAndProfileConfig} =
reloadAndProfileConfigPersistence;
const reloadAndProfileConfig = getReloadAndProfileConfig();
if (reloadAndProfileConfig.shouldReloadAndProfile) {
this._recordChangeDescriptions =
sessionStorageGetItem(
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
) === 'true';
reloadAndProfileConfig.recordChangeDescriptions;
this._isProfiling = true;

sessionStorageRemoveItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY);
sessionStorageRemoveItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY);
setReloadAndProfileConfig({
shouldReloadAndProfile: false,
recordChangeDescriptions: false,
});
}

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

reloadAndProfile: (recordChangeDescriptions: boolean) => void =
recordChangeDescriptions => {
sessionStorageSetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY, 'true');
sessionStorageSetItem(
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
recordChangeDescriptions ? 'true' : 'false',
);
this._reloadAndProfileConfigPersistence.setReloadAndProfileConfig({
shouldReloadAndProfile: true,
recordChangeDescriptions,
});

// This code path should only be hit if the shell has explicitly told the Store that it supports profiling.
// In that case, the shell must also listen for this specific message to know when it needs to reload the app.
Expand Down Expand Up @@ -956,3 +963,35 @@ export default class Agent extends EventEmitter<{
}
};
}

const defaultReloadAndProfileConfigSetters: ReloadAndProfileConfigPersistence =
{
setReloadAndProfileConfig({
shouldReloadAndProfile,
recordChangeDescriptions,
}): void {
if (shouldReloadAndProfile != null) {
sessionStorageSetItem(
SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
shouldReloadAndProfile ? 'true' : 'false',
);
}
if (recordChangeDescriptions != null) {
sessionStorageSetItem(
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
recordChangeDescriptions ? 'true' : 'false',
);
}
},
getReloadAndProfileConfig(): ReloadAndProfileConfig {
return {
shouldReloadAndProfile:
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) ===
'true',
recordChangeDescriptions:
sessionStorageGetItem(
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
) === 'true',
};
},
};
16 changes: 6 additions & 10 deletions packages/react-devtools-shared/src/backend/fiber/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import {
utfEncodeString,
filterOutLocationComponentFilters,
} from 'react-devtools-shared/src/utils';
import {sessionStorageGetItem} from 'react-devtools-shared/src/storage';
import {
formatConsoleArgumentsToSingleString,
gt,
Expand All @@ -61,8 +60,6 @@ import {
__DEBUG__,
PROFILING_FLAG_BASIC_SUPPORT,
PROFILING_FLAG_TIMELINE_SUPPORT,
SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY,
TREE_OPERATION_ADD,
TREE_OPERATION_REMOVE,
TREE_OPERATION_REORDER_CHILDREN,
Expand Down Expand Up @@ -106,6 +103,7 @@ import {
supportsOwnerStacks,
supportsConsoleTasks,
} from './DevToolsFiberComponentStack';
import type {ReloadAndProfileConfig} from '../types';

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

// Automatically start profiling so that we don't miss timing info from initial "mount".
if (
sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true'
) {
startProfiling(
sessionStorageGetItem(SESSION_STORAGE_RECORD_CHANGE_DESCRIPTIONS_KEY) ===
'true',
);
if (reloadAndProfileConfig?.shouldReloadAndProfile) {
const shouldRecordChangeDescriptions =
reloadAndProfileConfig.recordChangeDescriptions;
startProfiling(shouldRecordChangeDescriptions);
}

function getNearestFiber(devtoolsInstance: DevToolsInstance): null | Fiber {
Expand Down
14 changes: 14 additions & 0 deletions packages/react-devtools-shared/src/backend/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,20 @@ export type DevToolsBackend = {
setupNativeStyleEditor?: SetupNativeStyleEditor,
};

export type ReloadAndProfileConfig = {
shouldReloadAndProfile: boolean,
recordChangeDescriptions: boolean,
};

// Linter doesn't speak Flow's `Partial` type
// eslint-disable-next-line no-undef
type PartialReloadAndProfileConfig = Partial<ReloadAndProfileConfig>;

export type ReloadAndProfileConfigPersistence = {
setReloadAndProfileConfig: (config: PartialReloadAndProfileConfig) => void,
getReloadAndProfileConfig: () => ReloadAndProfileConfig,
};

export type DevToolsHook = {
listeners: {[key: string]: Array<Handler>, ...},
rendererInterfaces: Map<RendererID, RendererInterface>,
Expand Down
10 changes: 9 additions & 1 deletion packages/react-devtools-shared/src/hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
RendererInterface,
DevToolsBackend,
DevToolsHookSettings,
ReloadAndProfileConfig,
} from './backend/types';

import {
Expand Down Expand Up @@ -54,6 +55,7 @@ export function installHook(
maybeSettingsOrSettingsPromise?:
| DevToolsHookSettings
| Promise<DevToolsHookSettings>,
reloadAndProfileConfig?: ReloadAndProfileConfig,
): DevToolsHook | null {
if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
return null;
Expand Down Expand Up @@ -207,7 +209,13 @@ export function installHook(
reactBuildType,
});

const rendererInterface = attachRenderer(hook, id, renderer, target);
const rendererInterface = attachRenderer(
hook,
id,
renderer,
target,
reloadAndProfileConfig,
);
if (rendererInterface != null) {
hook.rendererInterfaces.set(id, rendererInterface);
hook.emit('renderer-attached', {id, rendererInterface});
Expand Down

0 comments on commit d8da2b9

Please sign in to comment.