mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Deduplicate pages by ID within each device (#42282)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42282 Changelog: [Internal] `inspector-proxy` now assumes each app will report pages with locally unique IDs. In order to simplify some upcoming logic changes in `inspector-proxy`, in this diff we begin to enforce the assumption that each app ( = platform-specific implementation of `InspectorPackagerConnection`) assigns a locally unique ID to each inspector page. The inspector proxy will silently drop page descriptors that have conflicting IDs, and log a message to `debug()`. NOTE: As an implementation detail, integrators may use `DEBUG=Metro:InspectorProxy` to see debug messages from `inspector-proxy`. Reviewed By: huntie Differential Revision: D50969752 fbshipit-source-id: a4e6faa91d97594fc5343ce4bee66233523cd175
This commit is contained in:
committed by
Facebook GitHub Bot
parent
67532e07ce
commit
8ac08c8d18
@@ -220,6 +220,45 @@ xdescribe('inspector proxy HTTP API', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('removes pages with duplicate IDs', async () => {
|
||||
const device1 = await createDeviceMock(
|
||||
`${serverRef.serverBaseWsUrl}/inspector/device?device=device1&name=foo&app=bar`,
|
||||
autoCleanup.signal,
|
||||
);
|
||||
try {
|
||||
device1.getPages.mockImplementation(() => [
|
||||
{
|
||||
app: 'bar-app',
|
||||
id: 'page1',
|
||||
title: 'bar-title',
|
||||
vm: 'bar-vm',
|
||||
},
|
||||
{
|
||||
app: 'bar-app-other',
|
||||
id: 'page1',
|
||||
title: 'bar-title-other',
|
||||
vm: 'bar-vm-other',
|
||||
},
|
||||
]);
|
||||
|
||||
jest.advanceTimersByTime(PAGES_POLLING_DELAY);
|
||||
|
||||
const json = await fetchJson<JsonPagesListResponse>(
|
||||
`${serverRef.serverBaseUrl}${endpoint}`,
|
||||
);
|
||||
|
||||
expect(json).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'device1-page1',
|
||||
title: 'bar-title-other',
|
||||
vm: 'bar-vm-other',
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
device1.close();
|
||||
}
|
||||
});
|
||||
|
||||
describe('HTTP vs HTTPS', () => {
|
||||
const secureServerRef = withServerForEachTest({
|
||||
logger: undefined,
|
||||
|
||||
@@ -68,8 +68,8 @@ export default class Device {
|
||||
// Stores socket connection between Inspector Proxy and device.
|
||||
#deviceSocket: WS;
|
||||
|
||||
// Stores last list of device's pages.
|
||||
#pages: $ReadOnlyArray<Page>;
|
||||
// Stores the most recent listing of device's pages, keyed by the `id` field.
|
||||
#pages: $ReadOnlyMap<string, Page>;
|
||||
|
||||
// Stores information about currently connected debugger (if any).
|
||||
#debuggerConnection: ?DebuggerInfo = null;
|
||||
@@ -106,7 +106,7 @@ export default class Device {
|
||||
this.#id = id;
|
||||
this.#name = name;
|
||||
this.#app = app;
|
||||
this.#pages = [];
|
||||
this.#pages = new Map();
|
||||
this.#deviceSocket = socket;
|
||||
this.#projectRoot = projectRoot;
|
||||
this.#deviceEventReporter = eventReporter
|
||||
@@ -166,9 +166,9 @@ export default class Device {
|
||||
vm: "don't use",
|
||||
app: this.#app,
|
||||
};
|
||||
return this.#pages.concat(reactNativeReloadablePage);
|
||||
return [...this.#pages.values(), reactNativeReloadablePage];
|
||||
} else {
|
||||
return this.#pages;
|
||||
return [...this.#pages.values()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,17 +302,33 @@ export default class Device {
|
||||
// locations).
|
||||
#handleMessageFromDevice(message: MessageFromDevice) {
|
||||
if (message.event === 'getPages') {
|
||||
this.#pages = message.payload;
|
||||
this.#pages = new Map(message.payload.map(page => [page.id, page]));
|
||||
if (message.payload.length !== this.#pages.size) {
|
||||
const duplicateIds = new Set<string>();
|
||||
const idsSeen = new Set<string>();
|
||||
for (const page of message.payload) {
|
||||
if (!idsSeen.has(page.id)) {
|
||||
idsSeen.add(page.id);
|
||||
} else {
|
||||
duplicateIds.add(page.id);
|
||||
}
|
||||
}
|
||||
debug(
|
||||
`Received duplicate page IDs from device: ${[...duplicateIds].join(
|
||||
', ',
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check if device have new React Native page.
|
||||
// There is usually no more than 2-3 pages per device so this operation
|
||||
// is not expensive.
|
||||
// TODO(hypuk): It is better for VM to send update event when new page is
|
||||
// created instead of manually checking this on every getPages result.
|
||||
for (let i = 0; i < this.#pages.length; ++i) {
|
||||
if (this.#pages[i].title.indexOf('React') >= 0) {
|
||||
if (this.#pages[i].id !== this.#lastConnectedReactNativePage?.id) {
|
||||
this.#newReactNativePage(this.#pages[i]);
|
||||
for (const page of this.#pages.values()) {
|
||||
if (page.title.indexOf('React') >= 0) {
|
||||
if (page.id !== this.#lastConnectedReactNativePage?.id) {
|
||||
this.#newReactNativePage(page);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user