From 486874a1bec2094b0e197f9d43f3eabf5114b9c1 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Thu, 19 Dec 2024 14:56:27 +0100 Subject: [PATCH] fix: update device filtering logic to select inspectable device for SDK 52 (#266) * fix: update device filtering logic to select inspectable device for SDK 52 * chore: clean up code and resolve patch-package issue --- patches/jest-snapshot+28.1.3.patch | 2 +- src/expo/__tests__/bundler.test.ts | 51 +----------------------------- src/expo/bundler.ts | 29 ++++++++--------- src/expoDebuggers.ts | 22 +++++-------- 4 files changed, 23 insertions(+), 81 deletions(-) diff --git a/patches/jest-snapshot+28.1.3.patch b/patches/jest-snapshot+28.1.3.patch index d11a4e4c..a612f0f8 100644 --- a/patches/jest-snapshot+28.1.3.patch +++ b/patches/jest-snapshot+28.1.3.patch @@ -29,4 +29,4 @@ index a3d3b05..69f0132 100644 + const keys = [ ['resolveSnapshotPath', 'function'], - ['resolveTestPath', 'function'], + ['resolveTestPath', 'function'], \ No newline at end of file diff --git a/src/expo/__tests__/bundler.test.ts b/src/expo/__tests__/bundler.test.ts index 929a2e02..e910f515 100644 --- a/src/expo/__tests__/bundler.test.ts +++ b/src/expo/__tests__/bundler.test.ts @@ -1,11 +1,10 @@ import { expect } from 'chai'; import { mockDevice } from '../../__tests__/utils/debugging'; -import { stubFetch, withFetchError, withFetchResponse } from '../../__tests__/utils/fetch'; +import { stubFetch } from '../../__tests__/utils/fetch'; import { type InspectableDevice, fetchDevicesToInspect, - fetchDevicesToInspectFromUnknownWorkflow, findDeviceByName, inferDevicePlatform, } from '../bundler'; @@ -59,54 +58,6 @@ describe('fetchDevicesToInspect', () => { }); }); -describe('fetchDevicesToInspectFromUnknownWorkflow', () => { - it('fetches devices from modern and classic bundler addresses', async () => { - using fetch = stubFetch(); - - await fetchDevicesToInspectFromUnknownWorkflow({ host }); - - expect(fetch).to.be.calledWith(`http://${host}:19000/json/list`); - expect(fetch).to.be.calledWith(`http://${host}:8081/json/list`); - }); - - it('returns devices from modern bundler address', async () => { - const device = mockDevice({ deviceName: 'iPhone 7 Pro' }); - using fetch = stubFetch(); - - withFetchError(fetch.withArgs(`http://${host}:19000/json/list`)); - withFetchResponse(fetch.withArgs(`http://${host}:8081/json/list`), [device]); - - const devices = await fetchDevicesToInspectFromUnknownWorkflow({ host }); - - expect(devices).to.deep.equal([device]); - }); - - it('returns devices from classic bundler address', async () => { - const device = mockDevice({ deviceName: 'Pixel 7 Pro' }); - using fetch = stubFetch(); - - withFetchResponse(fetch.withArgs(`http://${host}:19000/json/list`), [device]); - withFetchError(fetch.withArgs(`http://${host}:8081/json/list`)); - - const devices = await fetchDevicesToInspectFromUnknownWorkflow({ host }); - - expect(devices).to.deep.equal([device]); - }); - - it('prioritizes modern bundler address', async () => { - const iphone = mockDevice({ deviceName: 'iPhone 15 Pro' }); - const android = mockDevice({ deviceName: 'Pixel 7 Pro' }); - using fetch = stubFetch(); - - withFetchResponse(fetch.withArgs(`http://${host}:19000/json/list`), [iphone]); - withFetchResponse(fetch.withArgs(`http://${host}:8081/json/list`), [android]); - - const devices = await fetchDevicesToInspectFromUnknownWorkflow({ host }); - - expect(devices).to.deep.equal([android]); - }); -}); - describe('findDeviceByName', () => { it('returns first device by its name', () => { const target = mockDevice({ deviceName: 'iPhone 15 Pro', id: 'page1' }); diff --git a/src/expo/bundler.ts b/src/expo/bundler.ts index 5501fa01..6cbd03be 100644 --- a/src/expo/bundler.ts +++ b/src/expo/bundler.ts @@ -34,30 +34,27 @@ function getDeviceNames(devices: InspectableDevice[]) { .filter((deviceName, index, self) => self.indexOf(deviceName) === index); } -export async function fetchDevicesToInspect({ host, port }: { host: string; port: string }) { +/** Fetch a list of all devices to inspect, filtered by known inspectable targets */ +export async function fetchDevicesToInspect({ + host = '127.0.0.1', + port = '8081', +}: { + host?: string; + port?: string; +}) { return await fetch(`http://${host}:${port}/json/list`) .then((response) => (response.ok ? response.json() : Promise.reject(response))) .then((devices: InspectableDevice[]): InspectableDevice[] => devices - .filter((device) => device.title === INSPECTABLE_DEVICE_TITLE) + .filter( + (device) => + device.title === INSPECTABLE_DEVICE_TITLE || // SDK <51 + device.reactNative?.capabilities?.nativePageReloads === true // SDK 52+ + ) .filter(uniqueBy((device) => device?.reactNative?.logicalDeviceId ?? device.deviceName)) ); } -/** Attempt to fetch from both `19000` and `8081`, return the data when one of these works */ -export async function fetchDevicesToInspectFromUnknownWorkflow({ host }: { host: string }) { - const [classic, modern] = await Promise.allSettled([ - fetchDevicesToInspect({ host, port: '19000' }), - fetchDevicesToInspect({ host, port: '8081' }), - ]); - - // Prefer data from modern Expo (dev clients) - if (modern.status === 'fulfilled') return modern.value; - if (classic.status === 'fulfilled') return classic.value; - - throw new Error(`No bundler found at ${host} on ports 19000 or 8081`); -} - export function findDeviceByName(devices: InspectableDevice[], deviceName: string) { return devices.find((devices) => getDeviceName(devices) === deviceName); } diff --git a/src/expoDebuggers.ts b/src/expoDebuggers.ts index ad031f4c..b588412c 100644 --- a/src/expoDebuggers.ts +++ b/src/expoDebuggers.ts @@ -1,12 +1,7 @@ import fs from 'fs'; import vscode from 'vscode'; -import { - fetchDevicesToInspect, - askDeviceByName, - inferDevicePlatform, - fetchDevicesToInspectFromUnknownWorkflow, -} from './expo/bundler'; +import { fetchDevicesToInspect, askDeviceByName, inferDevicePlatform } from './expo/bundler'; import { ExpoProjectCache, ExpoProject, @@ -249,15 +244,14 @@ async function waitForDevice(config: ExpoDebugConfig) { async function pickDevice(config: ExpoDebugConfig) { const bundlerHost = config.bundlerHost ?? '127.0.0.1'; + const bundlerPort = config.bundlerPort ?? '8081'; - // Either fetch from user-specified port, or try both `19000` and `8081`. - const devices = config.bundlerPort - ? await fetchDevicesToInspect({ host: bundlerHost, port: config.bundlerPort }).catch(() => { - throw new Error(`waiting for bundler on ${config.bundlerHost}:${config.bundlerPort}...`); - }) - : await fetchDevicesToInspectFromUnknownWorkflow({ host: bundlerHost }).catch(() => { - throw new Error(`waiting for bundler on ${config.bundlerHost}...`); - }); + const devices = await fetchDevicesToInspect({ + host: bundlerHost, + port: bundlerPort, + }).catch(() => { + throw new Error(`waiting for bundler on ${bundlerHost}:${bundlerPort}...`); + }); if (devices.length === 1) { log('Picking only device available:', devices[0].deviceName);