Skip to content

Commit

Permalink
fix: update device filtering logic to select inspectable device for S…
Browse files Browse the repository at this point in the history
…DK 52 (#266)

* fix: update device filtering logic to select inspectable device for SDK 52

* chore: clean up code and resolve patch-package issue
  • Loading branch information
byCedric authored Dec 19, 2024
1 parent 89a2c99 commit 486874a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 81 deletions.
2 changes: 1 addition & 1 deletion patches/jest-snapshot+28.1.3.patch
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ index a3d3b05..69f0132 100644
+
const keys = [
['resolveSnapshotPath', 'function'],
['resolveTestPath', 'function'],
['resolveTestPath', 'function'],
51 changes: 1 addition & 50 deletions src/expo/__tests__/bundler.test.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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' });
Expand Down
29 changes: 13 additions & 16 deletions src/expo/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
22 changes: 8 additions & 14 deletions src/expoDebuggers.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 486874a

Please sign in to comment.