mirror of
https://github.com/facebook/react.git
synced 2026-02-24 20:53:03 +00:00
The old version of prettier we were using didn't support the Flow syntax to access properties in a type using `SomeType['prop']`. This updates `prettier` and `rollup-plugin-prettier` to the latest versions. I added the prettier config `arrowParens: "avoid"` to reduce the diff size as the default has changed in Prettier 2.0. The largest amount of changes comes from function expressions now having a space. This doesn't have an option to preserve the old behavior, so we have to update this.
164 lines
4.3 KiB
JavaScript
164 lines
4.3 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
import type {ReactContext, RefObject} from 'shared/ReactTypes';
|
|
|
|
import * as React from 'react';
|
|
import {
|
|
createContext,
|
|
useContext,
|
|
useMemo,
|
|
useRef,
|
|
useState,
|
|
useSyncExternalStore,
|
|
} from 'react';
|
|
import {StoreContext} from 'react-devtools-shared/src/devtools/views/context';
|
|
|
|
import type {
|
|
HorizontalScrollStateChangeCallback,
|
|
TimelineData,
|
|
SearchRegExpStateChangeCallback,
|
|
ViewState,
|
|
ReactEventInfo,
|
|
} from './types';
|
|
|
|
export type Context = {
|
|
file: File | null,
|
|
inMemoryTimelineData: Array<TimelineData> | null,
|
|
isTimelineSupported: boolean,
|
|
searchInputContainerRef: RefObject,
|
|
setFile: (file: File | null) => void,
|
|
viewState: ViewState,
|
|
selectEvent: ReactEventInfo => void,
|
|
selectedEvent: ReactEventInfo,
|
|
};
|
|
|
|
const TimelineContext: ReactContext<Context> = createContext<Context>(
|
|
((null: any): Context),
|
|
);
|
|
TimelineContext.displayName = 'TimelineContext';
|
|
|
|
type Props = {
|
|
children: React$Node,
|
|
};
|
|
|
|
function TimelineContextController({children}: Props): React.Node {
|
|
const searchInputContainerRef = useRef(null);
|
|
const [file, setFile] = useState<string | null>(null);
|
|
|
|
const store = useContext(StoreContext);
|
|
|
|
const isTimelineSupported = useSyncExternalStore<boolean>(
|
|
function subscribe(callback) {
|
|
store.addListener('rootSupportsTimelineProfiling', callback);
|
|
return function unsubscribe() {
|
|
store.removeListener('rootSupportsTimelineProfiling', callback);
|
|
};
|
|
},
|
|
function getState() {
|
|
return store.rootSupportsTimelineProfiling;
|
|
},
|
|
);
|
|
|
|
const inMemoryTimelineData = useSyncExternalStore<Array<TimelineData> | null>(
|
|
function subscribe(callback) {
|
|
store.profilerStore.addListener('isProcessingData', callback);
|
|
store.profilerStore.addListener('profilingData', callback);
|
|
return function unsubscribe() {
|
|
store.profilerStore.removeListener('isProcessingData', callback);
|
|
store.profilerStore.removeListener('profilingData', callback);
|
|
};
|
|
},
|
|
function getState() {
|
|
return store.profilerStore.profilingData?.timelineData || null;
|
|
},
|
|
);
|
|
|
|
// Recreate view state any time new profiling data is imported.
|
|
const viewState = useMemo<ViewState>(() => {
|
|
const horizontalScrollStateChangeCallbacks: Set<HorizontalScrollStateChangeCallback> =
|
|
new Set();
|
|
const searchRegExpStateChangeCallbacks: Set<SearchRegExpStateChangeCallback> =
|
|
new Set();
|
|
|
|
const horizontalScrollState = {
|
|
offset: 0,
|
|
length: 0,
|
|
};
|
|
|
|
const state: ViewState = {
|
|
horizontalScrollState,
|
|
onHorizontalScrollStateChange: callback => {
|
|
horizontalScrollStateChangeCallbacks.add(callback);
|
|
},
|
|
onSearchRegExpStateChange: callback => {
|
|
searchRegExpStateChangeCallbacks.add(callback);
|
|
},
|
|
searchRegExp: null,
|
|
updateHorizontalScrollState: scrollState => {
|
|
if (
|
|
horizontalScrollState.offset === scrollState.offset &&
|
|
horizontalScrollState.length === scrollState.length
|
|
) {
|
|
return;
|
|
}
|
|
|
|
horizontalScrollState.offset = scrollState.offset;
|
|
horizontalScrollState.length = scrollState.length;
|
|
|
|
horizontalScrollStateChangeCallbacks.forEach(callback => {
|
|
callback(scrollState);
|
|
});
|
|
},
|
|
updateSearchRegExpState: (searchRegExp: RegExp | null) => {
|
|
state.searchRegExp = searchRegExp;
|
|
|
|
searchRegExpStateChangeCallbacks.forEach(callback => {
|
|
callback(searchRegExp);
|
|
});
|
|
},
|
|
viewToMutableViewStateMap: new Map(),
|
|
};
|
|
|
|
return state;
|
|
}, [file]);
|
|
|
|
const [selectedEvent, selectEvent] = useState<ReactEventInfo | null>(null);
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
file,
|
|
inMemoryTimelineData,
|
|
isTimelineSupported,
|
|
searchInputContainerRef,
|
|
setFile,
|
|
viewState,
|
|
selectEvent,
|
|
selectedEvent,
|
|
}),
|
|
[
|
|
file,
|
|
inMemoryTimelineData,
|
|
isTimelineSupported,
|
|
setFile,
|
|
viewState,
|
|
selectEvent,
|
|
selectedEvent,
|
|
],
|
|
);
|
|
|
|
return (
|
|
<TimelineContext.Provider value={value}>
|
|
{children}
|
|
</TimelineContext.Provider>
|
|
);
|
|
}
|
|
|
|
export {TimelineContext, TimelineContextController};
|