stim 1.29.0 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acquire-artifact-C2DKfenN.mjs → acquire-artifact-P84h3ssa.mjs} +1 -1
- package/dist/{act-CrTcskiE.mjs → act-lcOIEy32.mjs} +18 -18
- package/dist/{activity-BR5oHSO5.mjs → activity-Dw4N_RFe.mjs} +4 -4
- package/dist/{agent-device-usage-output-W0x4SoC7.mjs → agent-device-usage-output-Boie2yB-.mjs} +4 -4
- package/dist/{android-CLU_MMnb.mjs → android-BeeC15Ve.mjs} +1 -1
- package/dist/{android-l616dRP1.mjs → android-DhiWSOFU.mjs} +47 -43
- package/dist/{android-BHKgeOuq.mjs → android-DsEj2CCs.mjs} +65 -35
- package/dist/{android-BPmCmyAy.mjs → android-aIuJZoDu.mjs} +5 -5
- package/dist/{android-cas-BH6K12__.mjs → android-cas-CbumHXIq.mjs} +4 -4
- package/dist/api.mjs +26 -26
- package/dist/{apk-signed-tail-B-wKoF_8.mjs → apk-signed-tail-B9Usseps.mjs} +2 -2
- package/dist/{artifact-Dm9ScLrh.mjs → artifact-Cr34-Yyy.mjs} +12 -12
- package/dist/{artifact-DHuFYfhD.mjs → artifact-ta3xA0c4.mjs} +12 -12
- package/dist/{auto-placement-C8sJsyMN.mjs → auto-placement-DtTRG0rk.mjs} +12 -12
- package/dist/{browser-web-_tQTbQUs.mjs → browser-web-DuULNZrS.mjs} +11 -11
- package/dist/{build-DtCU9Kim.mjs → build-BpFFbdXD.mjs} +22 -22
- package/dist/{build-cache-BGwTsIEa.mjs → build-cache-BsKim4V7.mjs} +4 -4
- package/dist/{build-plan-CWyjMPKo.mjs → build-plan-DH1rT11x.mjs} +6 -6
- package/dist/{cache-manifest-evF_zJ9U.mjs → cache-manifest-CfiEny4T.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-DsDkdP72.mjs → ccache-DVDO2ocE.mjs} +16 -16
- package/dist/{cli-3fjOg-Oc.mjs → cli-C0jjwTuM.mjs} +18 -18
- package/dist/cli.mjs +1 -1
- package/dist/{client-BTUH8TF1.mjs → client-DhJOvSvh.mjs} +4 -4
- package/dist/collector-run.mjs +4 -4
- package/dist/{command-output-DjCsmzLZ.mjs → command-output-VrXd6qPX.mjs} +1 -1
- package/dist/{config-AbUjIBOQ.mjs → config-D5qNWJEP.mjs} +2 -2
- package/dist/{dependencies-CHNqX6Pr.mjs → dependencies-DIU-5rnG.mjs} +38 -37
- package/dist/{dependency-state-CPKAKCZ8.mjs → dependency-state-DZVln1P9.mjs} +1 -1
- package/dist/{dev-client-CROrxj1x.mjs → dev-client-DeAg0fso.mjs} +2 -2
- package/dist/device-C2WsPgFt.mjs +761 -0
- package/dist/device-DuNLOlR6.mjs +175 -0
- package/dist/{device-Bmm5qjM-.mjs → device-android-BjhH0Ru3.mjs} +39 -200
- package/dist/{device-capacity-B2ChA-bz.mjs → device-capacity-Du5wBTNJ.mjs} +175 -76
- package/dist/device-host-worker.mjs +49 -36
- package/dist/{device-ios-CYzivd31.mjs → device-ios-CUYUhSYO.mjs} +27 -17
- package/dist/{device-lease-run-qRq_2W2V.mjs → device-lease-run-CHXQEn-7.mjs} +4 -4
- package/dist/{device-pool-CrmiE4_x.mjs → device-pool-kUHO7MHO.mjs} +3 -3
- package/dist/{device-provision-CK2XiEp1.mjs → device-provision-e7bKS7lx.mjs} +8 -8
- package/dist/{doctor-BO_kaFWX.mjs → doctor-B6kIVgU9.mjs} +1 -1
- package/dist/{doctor-Cp4-HN1f.mjs → doctor-BGcsAgAV.mjs} +15 -15
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-Dr3C1iXV.mjs → doctor-hva3sd9f.mjs} +37 -26
- package/dist/{doctor-watchman-CJr2aXXv.mjs → doctor-watchman-DJY550yz.mjs} +4 -4
- package/dist/{eas-build-D-9HmGZS.mjs → eas-build-CBFgseh1.mjs} +2 -2
- package/dist/{eas-fallback-Cemt2GVL.mjs → eas-fallback-DFXdz4d6.mjs} +4 -4
- package/dist/{eas-session-ledger-B0KLZx5m.mjs → eas-session-ledger-aFBLTZr2.mjs} +19 -6
- package/dist/{error-diagnostics-CV_1RoEH.mjs → error-diagnostics-CCsq_3uG.mjs} +8 -8
- package/dist/{gc-CKHqL4aS.mjs → gc-B0K4d_PL.mjs} +17 -17
- package/dist/{gc-DjXwQXHK.mjs → gc-DASUa3Z_.mjs} +2 -2
- package/dist/{guide-CeRlWVsS.mjs → guide-Civo5-zV.mjs} +178 -28
- package/dist/{hosted-android-DI_vvv7U.mjs → hosted-android-CH1Sm4wo.mjs} +3 -3
- package/dist/{hosted-client-CgoxdU9j.mjs → hosted-client-5ur3YpxY.mjs} +36 -12
- package/dist/{hosted-logs-C-4INmkn.mjs → hosted-logs-BYg4yeti.mjs} +6 -6
- package/dist/{hosted-logs-sync-Bf5s02fi.mjs → hosted-logs-sync-BPe8xnMu.mjs} +7 -11
- package/dist/{hosted-macos-Doh85YUM.mjs → hosted-macos-BagT0Gn3.mjs} +5 -5
- package/dist/{hosted-native-DvZENAL-.mjs → hosted-native-kaR4nUHk.mjs} +9 -8
- package/dist/{idle-shutdown-BM37gMfU.mjs → idle-shutdown-BWHQ7mQG.mjs} +6 -6
- package/dist/{ios-CNDH6fNF.mjs → ios-BKR-Dq46.mjs} +8 -8
- package/dist/{ios-CoMCWfub.mjs → ios-CdAV4-1E.mjs} +4 -4
- package/dist/{ios-UM_dManb.mjs → ios-DUL68MI5.mjs} +33 -32
- package/dist/{ios-device-L1-pota_.mjs → ios-device-Dz8gFZ0K.mjs} +1 -1
- package/dist/{ios-project-DJYptOCh.mjs → ios-project-Br1tVYWX.mjs} +7 -7
- package/dist/{ios-state-Ce_dystM.mjs → ios-state-BEIJRJ7P.mjs} +1 -1
- package/dist/{js-swap-BthE4kZC.mjs → js-swap-BfG8XpyS.mjs} +4 -4
- package/dist/{launch-D798aSm8.mjs → launch-CrGndh8T.mjs} +19 -19
- package/dist/{lightened-vSxkstg6.mjs → lightened-DZ9Ip0T3.mjs} +4 -4
- package/dist/{logs-CilPftm3.mjs → logs-C-hfMsxK.mjs} +7 -6
- package/dist/{logs-BND8MiBq.mjs → logs-DpIKWT3A.mjs} +7 -7
- package/dist/{macos-BOQrKYeJ.mjs → macos-DNmKwfDy.mjs} +1 -1
- package/dist/{macos-CxUi9xcE.mjs → macos-DZ9ZSolN.mjs} +19 -19
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +5 -5
- package/dist/{metro-BMQHczcf.mjs → metro-mKHEMO-a.mjs} +2 -2
- package/dist/{metro-request-BtF7ox53.mjs → metro-request-RDhyx85c.mjs} +1 -1
- package/dist/{named-ports-DcktE2Pw.mjs → named-ports-B0hCk2v-.mjs} +2 -2
- package/dist/{native-android-BkhrCjdX.mjs → native-android-DExhFqR6.mjs} +16 -16
- package/dist/{native-gradle-artifact-inputs-Cw4P6Gyr.mjs → native-gradle-artifact-inputs-Bcmbdc23.mjs} +3 -3
- package/dist/{native-runtime-DyH2gkXK.mjs → native-runtime-D4qgnjK_.mjs} +6 -6
- package/dist/{native-xcode-inputs-DV8jr3kJ.mjs → native-xcode-inputs-EWma1lXh.mjs} +2 -2
- package/dist/{native-xcode-ios-DdpPG2iT.mjs → native-xcode-ios-Y6rzmWTc.mjs} +15 -15
- package/dist/offload-worker.mjs +19 -19
- package/dist/{ownership-Dtz9G5Gl.mjs → ownership-CCfiBfOP.mjs} +2 -2
- package/dist/{phone-reverses-DZRad8HT.mjs → phone-reverses-Drj5QQCh.mjs} +4 -4
- package/dist/{placement-log-CoN6xrjY.mjs → placement-log-CFT8SnlS.mjs} +1 -1
- package/dist/{plan-placement-7sHuqR-r.mjs → plan-placement-DhKCH_wF.mjs} +6 -6
- package/dist/{ports-VQSAPZhl.mjs → ports-BNtJ5DCj.mjs} +3 -3
- package/dist/{prebuild-Bqp0LFGN.mjs → prebuild-D0hvmO4j.mjs} +9 -9
- package/dist/{project-D1n0K4yg.mjs → project-DCLkDM8C.mjs} +15 -15
- package/dist/{react-native-android-FQ-yX3Mv.mjs → react-native-android-Dp7vctEA.mjs} +24 -24
- package/dist/{react-native-build-D58bIqV9.mjs → react-native-build-vK2lFYfN.mjs} +7 -7
- package/dist/{react-native-doctor-AkUH2aca.mjs → react-native-doctor-BtWzwZHU.mjs} +9 -8
- package/dist/{react-native-ios-Dmsv8j7T.mjs → react-native-ios-DW1Ax3Yv.mjs} +16 -15
- package/dist/{recordings-CHMaF73C.mjs → recordings-BWnIlhZH.mjs} +1 -1
- package/dist/{reload-BV0nD-k9.mjs → reload-B-d7-CsI.mjs} +14 -14
- package/dist/{reload-CDKEzzaf.mjs → reload-BS_ntVV_.mjs} +1 -1
- package/dist/{remote-C8xyslUa.mjs → remote-DScVlaMz.mjs} +8 -8
- package/dist/{result-9fqcJ90W.mjs → result-Epkl6gyG.mjs} +16 -16
- package/dist/{run-BQAmrohh.mjs → run-2CHAJ9Oj.mjs} +1 -1
- package/dist/{selection-D1ZDzHFX.mjs → selection-C95m--1_.mjs} +3 -3
- package/dist/{server-bare-CEQdB_F4.mjs → server-bare-CFyVFZXJ.mjs} +1 -1
- package/dist/{server-command-RlS-Kl4a.mjs → server-command-B1gDRJB2.mjs} +4 -4
- package/dist/{server-expo-bB1VV2k-.mjs → server-expo-CP4dURQp.mjs} +2 -2
- package/dist/server-expo-D3k9mvP8.mjs +2 -0
- package/dist/{settings-D776ygML.mjs → settings-C6UTYW2K.mjs} +1 -1
- package/dist/{settings-BcVCcAT5.mjs → settings-CjTRNCi3.mjs} +2 -2
- package/dist/{settings-payload-_aatELz2.mjs → settings-payload-zf5EnCTg.mjs} +4 -4
- package/dist/{settings-write-CkTVGQ4O.mjs → settings-write-Fe0K6BeC.mjs} +5 -5
- package/dist/settings.schema.json +45 -3
- package/dist/{simslim-CbpHERcv.mjs → simslim-93xmPh-d.mjs} +1 -1
- package/dist/{slot-launch-Dbgfh8gc.mjs → slot-launch-B4MHzVX2.mjs} +6 -6
- package/dist/{stage-BuHuRj1y.mjs → stage-DDrnM0CY.mjs} +1 -1
- package/dist/{start-Cr-c3Xhq.mjs → start-BXl5tkv8.mjs} +1 -1
- package/dist/{start-Dlv4XXTP.mjs → start-LSwIFlBv.mjs} +10 -10
- package/dist/{state-D5ZxwCGJ.mjs → state-CM_HvvkS.mjs} +2 -2
- package/dist/{state-C2AUjjhg.mjs → state-CiflgxTP.mjs} +1 -1
- package/dist/{stats-D5c-uIBp.mjs → stats-EgpYD536.mjs} +4 -4
- package/dist/{status-D6PBK6_-.mjs → status-BLDvhatv.mjs} +26 -25
- package/dist/{status-DbQv--Yb.mjs → status-DBMD7ZQT.mjs} +1 -1
- package/dist/{status-CK7ZoEhV.mjs → status-GQ-JqvRi.mjs} +1 -1
- package/dist/{status-watch-okrpea4i.mjs → status-watch-BwG4lJ1q.mjs} +4 -4
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-CYXLFpFS.mjs → stim-desktop-1XxET4S8.mjs} +1 -1
- package/dist/{stop-CHtAiv79.mjs → stop-4SAV_RR8.mjs} +2 -2
- package/dist/{stop-uRQ-zYcl.mjs → stop-BfNhzvXO.mjs} +4 -4
- package/dist/{stop-p9uSKuGE.mjs → stop-WyrZQuX6.mjs} +15 -15
- package/dist/supervisor-run.mjs +13 -13
- package/dist/{support-PFyTkrnr.mjs → support-Cffz6_Ft.mjs} +15 -11
- package/dist/{support-BMpQIug0.mjs → support-Cs24xRQa.mjs} +9 -9
- package/dist/{swiftpm-artifact-inputs-Cddq6jN2.mjs → swiftpm-artifact-inputs-yp8D5LE4.mjs} +1 -1
- package/dist/{swiftpm-macos-BSj9iZlI.mjs → swiftpm-macos-D0CzQtpp.mjs} +8 -8
- package/dist/toolchain-BEra9AIX.mjs +2 -0
- package/dist/{toolchain-CLGnEUgT.mjs → toolchain-CGdgD4x4.mjs} +19 -11
- package/dist/{warm-progress--KkkBBaq.mjs → warm-progress-_aTMvkIH.mjs} +3 -3
- package/dist/{web-xlVssjQf.mjs → web-BE89ONcc.mjs} +8 -8
- package/dist/web-DQPxvFVD.mjs +2 -0
- package/dist/web-run.mjs +4 -4
- package/dist/{workspace-state-DGwkPXwq.mjs → workspace-state-3bF4TB8P.mjs} +2 -2
- package/dist/{workspaces-CvSYD_78.mjs → workspaces-BNEyJ1B_.mjs} +15 -12
- package/dist/{worktree-CaQBf6kh.mjs → worktree-BTrii9e_.mjs} +24 -24
- package/dist/{worktree-DTOIohFe.mjs → worktree-DB3Ypdj6.mjs} +1 -1
- package/package.json +7 -7
- package/dist/device-BvpasThQ.mjs +0 -297
- package/dist/server-expo-BVV9qy31.mjs +0 -2
- package/dist/toolchain-B-mzR9Rh.mjs +0 -2
- package/dist/web-BxSo493O.mjs +0 -2
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { U as deviceSlotPlatforms } from "./config-D5qNWJEP.mjs";
|
|
2
|
+
import { s as ownedDeviceLabel } from "./project-DCLkDM8C.mjs";
|
|
3
|
+
import { x as configureNewOwnedAvd } from "./android-DsEj2CCs.mjs";
|
|
4
|
+
import { c as pidExists } from "./metro-mKHEMO-a.mjs";
|
|
5
|
+
import { pt as teardownOwnedAvd } from "./workspaces-BNEyJ1B_.mjs";
|
|
6
|
+
import { h as tailLines } from "./activity-Dw4N_RFe.mjs";
|
|
7
|
+
import "./ios-CdAV4-1E.mjs";
|
|
8
|
+
import { t as clearDeviceIdleShutdown } from "./idle-shutdown-BWHQ7mQG.mjs";
|
|
9
|
+
import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-CUYUhSYO.mjs";
|
|
10
|
+
import { t as reconcileSimSlim } from "./simslim-93xmPh-d.mjs";
|
|
11
|
+
import { n as ensureAndroidBooted, r as ensureOwnedAndroidDevice, t as ANDROID_BOOT_TIMEOUT_MS } from "./device-android-BjhH0Ru3.mjs";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
14
|
+
import { rotatedLogPath } from "@stim-cli/core";
|
|
15
|
+
import { acceptsShape, settingDefinition } from "@stim-cli/core/state";
|
|
16
|
+
import { request } from "node:http";
|
|
17
|
+
//#region src/engine/metro-warmup.ts
|
|
18
|
+
const WARMUP_TIMEOUT_MS = 6e4;
|
|
19
|
+
async function requestLocal(url, platform, prefetch) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
const req = request(url, { headers: {
|
|
22
|
+
accept: "application/json",
|
|
23
|
+
"expo-platform": platform,
|
|
24
|
+
"x-stim-metro-warmup": "1"
|
|
25
|
+
} });
|
|
26
|
+
const timer = setTimeout(() => req.destroy(), WARMUP_TIMEOUT_MS);
|
|
27
|
+
timer.unref();
|
|
28
|
+
req.on("socket", (socket) => socket.unref());
|
|
29
|
+
req.on("error", () => resolve(null));
|
|
30
|
+
req.on("close", () => {
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
resolve(null);
|
|
33
|
+
});
|
|
34
|
+
req.on("response", (res) => {
|
|
35
|
+
let body = "";
|
|
36
|
+
res.setEncoding("utf8");
|
|
37
|
+
res.on("data", (chunk) => {
|
|
38
|
+
if (!prefetch) body += chunk;
|
|
39
|
+
});
|
|
40
|
+
res.on("error", () => resolve(null));
|
|
41
|
+
res.on("end", () => resolve(res.statusCode === 200 ? body : null));
|
|
42
|
+
});
|
|
43
|
+
req.end();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const ENTRY_EXTENSIONS = [
|
|
47
|
+
"",
|
|
48
|
+
".js",
|
|
49
|
+
".jsx",
|
|
50
|
+
".ts",
|
|
51
|
+
".tsx"
|
|
52
|
+
];
|
|
53
|
+
function entryExists(bundlePath, root) {
|
|
54
|
+
const entry = decodeURIComponent(bundlePath.replace(/\.bundle\/*$/, ""));
|
|
55
|
+
if (entry.startsWith("/.expo/")) return true;
|
|
56
|
+
for (let dir = resolve(root);; dir = dirname(dir)) {
|
|
57
|
+
const file = resolve(dir, `.${entry}`);
|
|
58
|
+
if (file.startsWith(dir + sep) && ENTRY_EXTENSIONS.some((ext) => existsSync(file + ext))) return true;
|
|
59
|
+
if (dirname(dir) === dir) return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function recordedBundleUrl(logsDir, root, platform) {
|
|
63
|
+
const setting = settingDefinition(`metro.warmupUrl.${platform}`);
|
|
64
|
+
if (!logsDir || !root || !setting) return null;
|
|
65
|
+
const log = join(logsDir, "metro.ndjson");
|
|
66
|
+
for (const file of [log, rotatedLogPath(log)]) for (const line of (tailLines(file) ?? []).toReversed()) try {
|
|
67
|
+
const record = JSON.parse(line);
|
|
68
|
+
if (record?.event === "bundle_response_started" && record.platform === platform && acceptsShape(setting, record.url) && entryExists(new URL(record.url, "http://localhost").pathname, root)) return record.url;
|
|
69
|
+
} catch {}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
async function warmMetro({ port, platform, isExpo, appId, bundleUrl, logsDir, root }) {
|
|
73
|
+
try {
|
|
74
|
+
const origin = `http://127.0.0.1:${port}`;
|
|
75
|
+
if (await requestLocal(new URL("/_stim/metro-warmup", origin), platform, false) !== "ready") return;
|
|
76
|
+
const url = new URL("/index.bundle", origin);
|
|
77
|
+
url.search = new URLSearchParams({
|
|
78
|
+
platform,
|
|
79
|
+
dev: "true",
|
|
80
|
+
lazy: "true",
|
|
81
|
+
minify: "false",
|
|
82
|
+
...platform === "ios" ? { inlineSourceMap: "false" } : {},
|
|
83
|
+
modulesOnly: "false",
|
|
84
|
+
runModule: "true",
|
|
85
|
+
excludeSource: "true",
|
|
86
|
+
sourcePaths: "url-server",
|
|
87
|
+
...appId ? { app: appId } : {}
|
|
88
|
+
}).toString();
|
|
89
|
+
bundleUrl ||= recordedBundleUrl(logsDir, root, platform);
|
|
90
|
+
if (!bundleUrl && isExpo) {
|
|
91
|
+
const body = await requestLocal(new URL(origin), platform, false);
|
|
92
|
+
if (body === null) return;
|
|
93
|
+
const manifest = JSON.parse(body);
|
|
94
|
+
bundleUrl = manifest.launchAsset?.url ?? manifest.bundleUrl;
|
|
95
|
+
if (typeof bundleUrl !== "string") return;
|
|
96
|
+
}
|
|
97
|
+
if (bundleUrl) {
|
|
98
|
+
const bundle = new URL(bundleUrl, origin);
|
|
99
|
+
url.pathname = bundle.pathname;
|
|
100
|
+
url.search = bundle.search;
|
|
101
|
+
}
|
|
102
|
+
await requestLocal(url, platform, true);
|
|
103
|
+
} catch {}
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/engine/device.ts
|
|
107
|
+
/**
|
|
108
|
+
* Whether `ensureOwnedDevice` created, adopted or started booting the device, rather than finding it booted.
|
|
109
|
+
* Undefined for a remote device, which those functions do not describe.
|
|
110
|
+
*/
|
|
111
|
+
function didSetUpDevice(device, remote) {
|
|
112
|
+
return remote ? void 0 : Boolean(device.setup || device.booting);
|
|
113
|
+
}
|
|
114
|
+
async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim, simSnapshot }) {
|
|
115
|
+
await clearDeviceIdleShutdown(projectPath, platform, slot);
|
|
116
|
+
if (slot && slot !== "default") label = `${label}-${slot}`;
|
|
117
|
+
const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
|
|
118
|
+
if (platform === "ios") return ensureOwnedIosDevice({
|
|
119
|
+
record,
|
|
120
|
+
projectPath,
|
|
121
|
+
slot,
|
|
122
|
+
settingsRoot,
|
|
123
|
+
label,
|
|
124
|
+
settings,
|
|
125
|
+
flags,
|
|
126
|
+
note,
|
|
127
|
+
out,
|
|
128
|
+
reconcileIosSimulator,
|
|
129
|
+
simSnapshot
|
|
130
|
+
});
|
|
131
|
+
return ensureOwnedAndroidDevice({
|
|
132
|
+
record,
|
|
133
|
+
projectPath,
|
|
134
|
+
slot,
|
|
135
|
+
settingsRoot,
|
|
136
|
+
label,
|
|
137
|
+
settings,
|
|
138
|
+
flags,
|
|
139
|
+
note,
|
|
140
|
+
out,
|
|
141
|
+
logFile,
|
|
142
|
+
alive,
|
|
143
|
+
configureAvd,
|
|
144
|
+
teardownAvd
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const BOOT_POLL_MS = 500;
|
|
148
|
+
async function ensureBooted({ platform, device, simulatorApp, timeoutMs, pollMs = BOOT_POLL_MS, out = () => {}, logFile = null, alive = pidExists, projectPath, slot, deviceSlotWait }) {
|
|
149
|
+
if (platform === "ios") return ensureIosBooted({
|
|
150
|
+
device,
|
|
151
|
+
projectPath,
|
|
152
|
+
slot,
|
|
153
|
+
deviceSlotWait,
|
|
154
|
+
simulatorApp,
|
|
155
|
+
timeoutMs: timeoutMs ?? 6e5,
|
|
156
|
+
pollMs,
|
|
157
|
+
out
|
|
158
|
+
});
|
|
159
|
+
if (platform === "android") return ensureAndroidBooted({
|
|
160
|
+
device,
|
|
161
|
+
deviceSlotWait,
|
|
162
|
+
projectPath,
|
|
163
|
+
slot,
|
|
164
|
+
timeoutMs: timeoutMs ?? ANDROID_BOOT_TIMEOUT_MS,
|
|
165
|
+
out,
|
|
166
|
+
logFile,
|
|
167
|
+
alive
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
failed: true,
|
|
171
|
+
reason: `Unknown platform "${platform}".`
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
export { warmMetro as i, ensureBooted as n, ensureOwnedDevice as r, didSetUpDevice as t };
|
|
@@ -1,117 +1,19 @@
|
|
|
1
1
|
import { D as ownership_claim_exports, t as getExecutor } from "./exec-aULwtNly.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { l as phaseLine } from "./command-output-
|
|
4
|
-
import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-CoMCWfub.mjs";
|
|
11
|
-
import { g as withDeviceBootAdmission, n as DeviceAdmissionRefusal, o as countLiveOwnedDevicesFrom } from "./device-capacity-B2ChA-bz.mjs";
|
|
12
|
-
import { t as clearDeviceIdleShutdown } from "./idle-shutdown-BM37gMfU.mjs";
|
|
13
|
-
import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-CYzivd31.mjs";
|
|
14
|
-
import { t as reconcileSimSlim } from "./simslim-CbpHERcv.mjs";
|
|
2
|
+
import { K as projectDeviceSlots, M as acquireAvdClaim, O as withConfigLock, T as setDevice, U as deviceSlotPlatforms, a as clearDevice, i as clearAndroidBootPending, k as withConfigLockAsync, t as allConsolePortsAndSerials, v as loadConfig, x as releaseAndroidConsolePort } from "./config-D5qNWJEP.mjs";
|
|
3
|
+
import { l as phaseLine } from "./command-output-VrXd6qPX.mjs";
|
|
4
|
+
import { l as androidDataPartitionSizeGbSetting, o as androidAvdConfigSetting } from "./settings-C6UTYW2K.mjs";
|
|
5
|
+
import { A as getAvdNameForSerialAsync, G as ownedAvdName, H as ownedAvdDeviceProfile, J as ownedAvdSystemImage, P as listAdbDevicesAsync, Q as pickDefaultSystemImage, R as listAvdsAsync, S as createOwnedAvd, V as nextConsolePort, W as ownedAvdMatchesConfiguration, _ as avdPoolConfiguration, b as bootAndroidEmulator, bt as parkedMaxSetting, ht as adoptParked, it as resolveOwnedAvdSerialAsync, n as OWNED_AVD_CONFIG_DEFAULTS, p as assertOwnedAvdStoppedAsync, t as DEFAULT_AVD_DEVICE_PROFILE, ut as waitForBoot, vt as isLegacyDeletionClaim, xt as readParked, z as listInstalledSystemImages } from "./android-DsEj2CCs.mjs";
|
|
6
|
+
import { c as pidExists } from "./metro-mKHEMO-a.mjs";
|
|
7
|
+
import { gt as teardownParkedAvd, pt as teardownOwnedAvd } from "./workspaces-BNEyJ1B_.mjs";
|
|
8
|
+
import { B as reportMemoryCulprits, L as memoryCulpritsUnderAsync, R as readHostMemoryPressure, V as memoryCulpritAdvice, f as listAllIosSimsAsync } from "./ios-CdAV4-1E.mjs";
|
|
9
|
+
import { _ as withDeviceBootAdmission, n as DeviceAdmissionRefusal, s as countLiveOwnedDevicesFrom } from "./device-capacity-Du5wBTNJ.mjs";
|
|
15
10
|
import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
|
|
16
11
|
import { randomUUID } from "node:crypto";
|
|
17
12
|
import { existsSync } from "node:fs";
|
|
18
13
|
import { isDeepStrictEqual } from "node:util";
|
|
19
|
-
import { dirname, join, resolve, sep } from "node:path";
|
|
20
|
-
import { rotatedLogPath } from "@stim-cli/core";
|
|
21
|
-
import { acceptsShape, settingDefinition } from "@stim-cli/core/state";
|
|
22
|
-
import { request } from "node:http";
|
|
23
14
|
import { fileURLToPath } from "node:url";
|
|
24
15
|
import { captureProcessIdentity } from "@stim-cli/core/process-identity";
|
|
25
16
|
import chalk from "chalk";
|
|
26
|
-
//#region src/engine/metro-warmup.ts
|
|
27
|
-
const WARMUP_TIMEOUT_MS = 6e4;
|
|
28
|
-
async function requestLocal(url, platform, prefetch) {
|
|
29
|
-
return new Promise((resolve) => {
|
|
30
|
-
const req = request(url, { headers: {
|
|
31
|
-
accept: "application/json",
|
|
32
|
-
"expo-platform": platform,
|
|
33
|
-
"x-stim-metro-warmup": "1"
|
|
34
|
-
} });
|
|
35
|
-
const timer = setTimeout(() => req.destroy(), WARMUP_TIMEOUT_MS);
|
|
36
|
-
timer.unref();
|
|
37
|
-
req.on("socket", (socket) => socket.unref());
|
|
38
|
-
req.on("error", () => resolve(null));
|
|
39
|
-
req.on("close", () => {
|
|
40
|
-
clearTimeout(timer);
|
|
41
|
-
resolve(null);
|
|
42
|
-
});
|
|
43
|
-
req.on("response", (res) => {
|
|
44
|
-
let body = "";
|
|
45
|
-
res.setEncoding("utf8");
|
|
46
|
-
res.on("data", (chunk) => {
|
|
47
|
-
if (!prefetch) body += chunk;
|
|
48
|
-
});
|
|
49
|
-
res.on("error", () => resolve(null));
|
|
50
|
-
res.on("end", () => resolve(res.statusCode === 200 ? body : null));
|
|
51
|
-
});
|
|
52
|
-
req.end();
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
const ENTRY_EXTENSIONS = [
|
|
56
|
-
"",
|
|
57
|
-
".js",
|
|
58
|
-
".jsx",
|
|
59
|
-
".ts",
|
|
60
|
-
".tsx"
|
|
61
|
-
];
|
|
62
|
-
function entryExists(bundlePath, root) {
|
|
63
|
-
const entry = decodeURIComponent(bundlePath.replace(/\.bundle\/*$/, ""));
|
|
64
|
-
if (entry.startsWith("/.expo/")) return true;
|
|
65
|
-
for (let dir = resolve(root);; dir = dirname(dir)) {
|
|
66
|
-
const file = resolve(dir, `.${entry}`);
|
|
67
|
-
if (file.startsWith(dir + sep) && ENTRY_EXTENSIONS.some((ext) => existsSync(file + ext))) return true;
|
|
68
|
-
if (dirname(dir) === dir) return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function recordedBundleUrl(logsDir, root, platform) {
|
|
72
|
-
const setting = settingDefinition(`metro.warmupUrl.${platform}`);
|
|
73
|
-
if (!logsDir || !root || !setting) return null;
|
|
74
|
-
const log = join(logsDir, "metro.ndjson");
|
|
75
|
-
for (const file of [log, rotatedLogPath(log)]) for (const line of (tailLines(file) ?? []).toReversed()) try {
|
|
76
|
-
const record = JSON.parse(line);
|
|
77
|
-
if (record?.event === "bundle_response_started" && record.platform === platform && acceptsShape(setting, record.url) && entryExists(new URL(record.url, "http://localhost").pathname, root)) return record.url;
|
|
78
|
-
} catch {}
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
async function warmMetro({ port, platform, isExpo, appId, bundleUrl, logsDir, root }) {
|
|
82
|
-
try {
|
|
83
|
-
const origin = `http://127.0.0.1:${port}`;
|
|
84
|
-
if (await requestLocal(new URL("/_stim/metro-warmup", origin), platform, false) !== "ready") return;
|
|
85
|
-
const url = new URL("/index.bundle", origin);
|
|
86
|
-
url.search = new URLSearchParams({
|
|
87
|
-
platform,
|
|
88
|
-
dev: "true",
|
|
89
|
-
lazy: "true",
|
|
90
|
-
minify: "false",
|
|
91
|
-
...platform === "ios" ? { inlineSourceMap: "false" } : {},
|
|
92
|
-
modulesOnly: "false",
|
|
93
|
-
runModule: "true",
|
|
94
|
-
excludeSource: "true",
|
|
95
|
-
sourcePaths: "url-server",
|
|
96
|
-
...appId ? { app: appId } : {}
|
|
97
|
-
}).toString();
|
|
98
|
-
bundleUrl ||= recordedBundleUrl(logsDir, root, platform);
|
|
99
|
-
if (!bundleUrl && isExpo) {
|
|
100
|
-
const body = await requestLocal(new URL(origin), platform, false);
|
|
101
|
-
if (body === null) return;
|
|
102
|
-
const manifest = JSON.parse(body);
|
|
103
|
-
bundleUrl = manifest.launchAsset?.url ?? manifest.bundleUrl;
|
|
104
|
-
if (typeof bundleUrl !== "string") return;
|
|
105
|
-
}
|
|
106
|
-
if (bundleUrl) {
|
|
107
|
-
const bundle = new URL(bundleUrl, origin);
|
|
108
|
-
url.pathname = bundle.pathname;
|
|
109
|
-
url.search = bundle.search;
|
|
110
|
-
}
|
|
111
|
-
await requestLocal(url, platform, true);
|
|
112
|
-
} catch {}
|
|
113
|
-
}
|
|
114
|
-
//#endregion
|
|
115
17
|
//#region src/engine/android-avd-setup.ts
|
|
116
18
|
var AvdBootError = class extends Error {
|
|
117
19
|
remedy;
|
|
@@ -122,12 +24,12 @@ var AvdBootError = class extends Error {
|
|
|
122
24
|
};
|
|
123
25
|
var AvdRecoveryError = class extends AvdBootError {};
|
|
124
26
|
function findOtherOwner(avdName, projectPath, selectedSlot = "default") {
|
|
125
|
-
for (const [path, project] of Object.entries(loadConfig
|
|
27
|
+
for (const [path, project] of Object.entries(loadConfig()?.projects ?? {})) if (projectDeviceSlots(project).some(({ slot, platforms }) => (path !== projectPath || slot !== selectedSlot) && platforms.android?.avdName?.toLowerCase() === avdName.toLowerCase())) return path;
|
|
126
28
|
return null;
|
|
127
29
|
}
|
|
128
30
|
async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, systemImage, deviceProfile, configuration, configure, teardown = teardownOwnedAvd }) {
|
|
129
|
-
const { claim, reservation, previous, avdName } = await withConfigLockAsync
|
|
130
|
-
const previous = deviceSlotPlatforms(loadConfig
|
|
31
|
+
const { claim, reservation, previous, avdName } = await withConfigLockAsync(() => {
|
|
32
|
+
const previous = deviceSlotPlatforms(loadConfig()?.projects?.[projectPath], slot)?.android;
|
|
131
33
|
if (previous?.avdName && previous.avdName !== previousAvdName) throw new Error(`Another Stim run assigned AVD ${previous.avdName} to this workspace. Retry to use it.`);
|
|
132
34
|
if (readParked("android").some((entry) => entry.name === ownedAvdName(label)) || findOtherOwner(ownedAvdName(label), projectPath, slot)) label = `${label}-${randomUUID().slice(0, 8)}`;
|
|
133
35
|
const avdName = ownedAvdName(label);
|
|
@@ -152,7 +54,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
152
54
|
throw error;
|
|
153
55
|
}
|
|
154
56
|
});
|
|
155
|
-
const currentRecord = () => deviceSlotPlatforms(loadConfig
|
|
57
|
+
const currentRecord = () => deviceSlotPlatforms(loadConfig()?.projects?.[projectPath], slot)?.android;
|
|
156
58
|
const assertReservation = () => {
|
|
157
59
|
if (readParked("android").some((entry) => entry.name === avdName)) throw new Error(`AVD ${avdName} was parked by another Stim run. Retry to adopt it safely.`);
|
|
158
60
|
const owner = findOtherOwner(avdName, projectPath, slot);
|
|
@@ -163,8 +65,14 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
163
65
|
throw new Error(`AVD ${current?.avdName ?? avdName} ${state} by another concurrent Stim run. Retry after that run finishes so the recorded device is resolved safely.`);
|
|
164
66
|
}
|
|
165
67
|
};
|
|
68
|
+
const releaseReservation = () => withConfigLockAsync(() => {
|
|
69
|
+
if (!isDeepStrictEqual(currentRecord(), reservation)) return;
|
|
70
|
+
if (previous) setDevice(projectPath, "android", previous, slot);
|
|
71
|
+
else clearDevice(projectPath, "android", slot, avdName);
|
|
72
|
+
});
|
|
166
73
|
let prepared;
|
|
167
74
|
let child;
|
|
75
|
+
let spawnAttempted = false;
|
|
168
76
|
const creationRunning = () => child?.pid !== void 0 && processGroupAlive(child.pid);
|
|
169
77
|
let configurationFailure;
|
|
170
78
|
try {
|
|
@@ -173,6 +81,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
173
81
|
systemImage,
|
|
174
82
|
deviceProfile,
|
|
175
83
|
spawn: (...args) => {
|
|
84
|
+
spawnAttempted = true;
|
|
176
85
|
markClaimChildPending(claim);
|
|
177
86
|
child = getExecutor().spawn(...args);
|
|
178
87
|
if (child.pid !== void 0) {
|
|
@@ -196,10 +105,13 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
196
105
|
};
|
|
197
106
|
} catch (error) {
|
|
198
107
|
const message = String(error?.message || error);
|
|
199
|
-
if (!message.includes("already exists"))
|
|
108
|
+
if (!message.includes("already exists")) {
|
|
109
|
+
if (!spawnAttempted) await releaseReservation();
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
200
112
|
try {
|
|
201
113
|
if (!(await listAvdsAsync()).includes(avdName)) throw new AvdRecoveryError(`AVD ${avdName} already exists on disk but is not listed by the emulator. ${message}`, "Run `npx stim gc` to inspect orphaned owned AVDs, then `npx stim gc --delete` to reclaim those safe to delete. Retry `stim android` after cleanup; keep any AVD that GC cannot verify.", error);
|
|
202
|
-
await withConfigLockAsync
|
|
114
|
+
await withConfigLockAsync(assertReservation);
|
|
203
115
|
const resolved = await resolveOwnedAvdSerialAsync(avdName);
|
|
204
116
|
if (resolved.missing || resolved.notOwned) throw new Error(`AVD ${avdName} could not be verified for recovery. Retry after checking its registration.`, { cause: error });
|
|
205
117
|
if (!resolved.serial) await assertOwnedAvdStoppedAsync(avdName);
|
|
@@ -214,11 +126,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
214
126
|
} : {}
|
|
215
127
|
};
|
|
216
128
|
} catch (recoveryError) {
|
|
217
|
-
await
|
|
218
|
-
if (!isDeepStrictEqual(currentRecord(), reservation)) return;
|
|
219
|
-
if (previous) setDevice(projectPath, "android", previous, slot);
|
|
220
|
-
else clearDevice(projectPath, "android", slot, avdName);
|
|
221
|
-
});
|
|
129
|
+
await releaseReservation();
|
|
222
130
|
if (recoveryError instanceof AvdRecoveryError) throw recoveryError;
|
|
223
131
|
throw new AvdRecoveryError(`Could not recover owned AVD ${avdName}: ${String(recoveryError?.message || recoveryError)}`, "Inspect `npx stim status` and `adb devices`. Wait for any other Stim run using this AVD to finish, then retry `stim android`. Keep the AVD and its process locks while its state is unverified.", recoveryError);
|
|
224
132
|
}
|
|
@@ -228,7 +136,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
228
136
|
} catch (error) {
|
|
229
137
|
configurationFailure = { error };
|
|
230
138
|
}
|
|
231
|
-
if (!configurationFailure) await withConfigLockAsync
|
|
139
|
+
if (!configurationFailure) await withConfigLockAsync(() => {
|
|
232
140
|
assertReservation();
|
|
233
141
|
setDevice(projectPath, "android", {
|
|
234
142
|
avdName,
|
|
@@ -258,7 +166,7 @@ async function prepareOwnedAvd({ projectPath, slot, label, previousAvdName, syst
|
|
|
258
166
|
slot,
|
|
259
167
|
expectedRecord: reservation
|
|
260
168
|
},
|
|
261
|
-
onRemoved: () => withConfigLockAsync
|
|
169
|
+
onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
|
|
262
170
|
});
|
|
263
171
|
const orphan = cleanup.status === "failed" || cleanup.status === "skipped" ? ` The owned AVD remains tracked for cleanup (${cleanup.reason || cleanup.status}); fix the cause, then retry or run \`stim gc --delete\`.` : "";
|
|
264
172
|
throw new Error(`Created owned AVD ${avdName}, but could not configure its AVD settings: ${String(error?.message || error)}${orphan}`, { cause: error });
|
|
@@ -286,7 +194,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
|
|
|
286
194
|
slot,
|
|
287
195
|
expectedRecord: record
|
|
288
196
|
},
|
|
289
|
-
onRemoved: () => withConfigLockAsync
|
|
197
|
+
onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
|
|
290
198
|
});
|
|
291
199
|
if (cleanup.status === "failed" || cleanup.status === "skipped") throw new AvdRecoveryError(`Owned AVD ${record.avdName} has incomplete setup and could not be deleted (${cleanup.reason || cleanup.status}). Fix the cause, then retry; Stim kept the device record for cleanup.`, "Wait for any active AVD operation to finish. If the refusal names an unresolved claim, inspect its creator and native processes before removing only that claim. Retry `stim android` to reconcile the incomplete device.");
|
|
292
200
|
record = null;
|
|
@@ -304,7 +212,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
|
|
|
304
212
|
slot,
|
|
305
213
|
expectedRecord: record
|
|
306
214
|
},
|
|
307
|
-
onRemoved: () => withConfigLockAsync
|
|
215
|
+
onRemoved: () => withConfigLockAsync(() => clearDevice(projectPath, "android", slot, avdName))
|
|
308
216
|
});
|
|
309
217
|
if (cleanup.status === "failed" || cleanup.status === "skipped") throw new AvdRecoveryError(`Owned AVD ${avdName} never finished a boot, but could not be deleted to create one on ${requestedImage} (${cleanup.reason || cleanup.status}). Stim kept the device record.`, "Fix the cause, then retry, or pass `--slot <name>` to create the requested emulator beside it.");
|
|
310
218
|
out(phaseLine("device", `deleted ${avdName}, which never finished a boot, to create one on ${requestedImage}`));
|
|
@@ -329,7 +237,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
|
|
|
329
237
|
owned: true,
|
|
330
238
|
deviceName: record.deviceName ?? record.avdName
|
|
331
239
|
};
|
|
332
|
-
await withConfigLockAsync
|
|
240
|
+
await withConfigLockAsync(() => setDevice(projectPath, "android", updated, slot));
|
|
333
241
|
return {
|
|
334
242
|
...updated,
|
|
335
243
|
systemImage: ownedAvdSystemImage(record.avdName),
|
|
@@ -469,7 +377,7 @@ async function ensureOwnedAndroidDevice({ record, projectPath, slot, settingsRoo
|
|
|
469
377
|
deviceProfile: created.deviceProfile
|
|
470
378
|
};
|
|
471
379
|
}
|
|
472
|
-
function claimAndroidConsolePort({ projectPath, slot, avdName, deviceName, livePorts = [], metadata }, { lock = withConfigLock
|
|
380
|
+
function claimAndroidConsolePort({ projectPath, slot, avdName, deviceName, livePorts = [], metadata }, { lock = withConfigLock, recordedPorts = () => allConsolePortsAndSerials().androidConsolePorts, record = setDevice } = {}) {
|
|
473
381
|
return lock(() => {
|
|
474
382
|
const consolePort = nextConsolePort([...recordedPorts(), ...livePorts]);
|
|
475
383
|
const claim = {
|
|
@@ -495,7 +403,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
|
|
|
495
403
|
key: avdName
|
|
496
404
|
}, async () => {
|
|
497
405
|
const livePorts = await liveAndroidConsolePorts();
|
|
498
|
-
const claim = await withConfigLockAsync
|
|
406
|
+
const claim = await withConfigLockAsync(() => claimAndroidConsolePort({
|
|
499
407
|
projectPath,
|
|
500
408
|
slot,
|
|
501
409
|
avdName,
|
|
@@ -518,7 +426,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
|
|
|
518
426
|
if (result.failed) throw new AvdBootError(result.reason, result.remedy);
|
|
519
427
|
const running = await getAvdNameForSerialAsync(serial);
|
|
520
428
|
if (running && running !== avdName) throw new Error(`${serial} is running AVD ${running}, not this workspace's owned AVD ${avdName}; refusing to use it.`);
|
|
521
|
-
await withConfigLockAsync
|
|
429
|
+
await withConfigLockAsync(() => clearAndroidBootPending(projectPath, avdName, slot));
|
|
522
430
|
await muteBootedEmulator(serial, avdName, out);
|
|
523
431
|
const { bootPending: _booted, ...booted } = claim;
|
|
524
432
|
return {
|
|
@@ -527,7 +435,7 @@ async function bootOwnedAvdOnFreshPort({ avdName, deviceSlotWait, metadata, proj
|
|
|
527
435
|
setup: true
|
|
528
436
|
};
|
|
529
437
|
} catch (error) {
|
|
530
|
-
await withConfigLockAsync
|
|
438
|
+
await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
|
|
531
439
|
throw error;
|
|
532
440
|
}
|
|
533
441
|
}, {
|
|
@@ -670,7 +578,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
670
578
|
};
|
|
671
579
|
const avdName = device.avdName;
|
|
672
580
|
const booted = async (result) => {
|
|
673
|
-
if (!result.failed) await withConfigLockAsync
|
|
581
|
+
if (!result.failed) await withConfigLockAsync(() => clearAndroidBootPending(projectPath, avdName, slot));
|
|
674
582
|
return result;
|
|
675
583
|
};
|
|
676
584
|
if (resolved.serial) return booted(await waitForAndroidBoot({
|
|
@@ -686,7 +594,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
686
594
|
}));
|
|
687
595
|
const boot = async () => {
|
|
688
596
|
const livePorts = await liveAndroidConsolePorts();
|
|
689
|
-
const claim = await withConfigLockAsync
|
|
597
|
+
const claim = await withConfigLockAsync(() => claimAndroidConsolePort({
|
|
690
598
|
projectPath,
|
|
691
599
|
slot,
|
|
692
600
|
avdName,
|
|
@@ -701,7 +609,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
701
609
|
try {
|
|
702
610
|
pid = await bootAndroidEmulator(avdName, claim.consolePort, { logFile });
|
|
703
611
|
} catch (e) {
|
|
704
|
-
await withConfigLockAsync
|
|
612
|
+
await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
|
|
705
613
|
return {
|
|
706
614
|
failed: true,
|
|
707
615
|
reason: `Could not start emulator for AVD ${avdName}: ${e?.message || e}`
|
|
@@ -714,7 +622,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
714
622
|
alive,
|
|
715
623
|
out
|
|
716
624
|
});
|
|
717
|
-
if (result.failed) await withConfigLockAsync
|
|
625
|
+
if (result.failed) await withConfigLockAsync(() => releaseAndroidConsolePort(projectPath, claim.consolePort, slot));
|
|
718
626
|
else await muteBootedEmulator(serial, avdName, out);
|
|
719
627
|
return booted(result);
|
|
720
628
|
};
|
|
@@ -739,73 +647,4 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
739
647
|
}
|
|
740
648
|
}
|
|
741
649
|
//#endregion
|
|
742
|
-
|
|
743
|
-
/**
|
|
744
|
-
* Whether `ensureOwnedDevice` created, adopted or started booting the device, rather than finding it booted.
|
|
745
|
-
* Undefined for a remote device, which those functions do not describe.
|
|
746
|
-
*/
|
|
747
|
-
function didSetUpDevice(device, remote) {
|
|
748
|
-
return remote ? void 0 : Boolean(device.setup || device.booting);
|
|
749
|
-
}
|
|
750
|
-
async function ensureOwnedDevice({ platform, project, projectPath, slot, settingsRoot = projectPath, label = ownedDeviceLabel(projectPath), settings, flags = {}, note = () => {}, out = () => {}, logFile = null, alive = pidExists, configureAvd = configureNewOwnedAvd, teardownAvd = teardownOwnedAvd, reconcileIosSimulator = reconcileSimSlim, simSnapshot }) {
|
|
751
|
-
await clearDeviceIdleShutdown(projectPath, platform, slot);
|
|
752
|
-
if (slot && slot !== "default") label = `${label}-${slot}`;
|
|
753
|
-
const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
|
|
754
|
-
if (platform === "ios") return ensureOwnedIosDevice({
|
|
755
|
-
record,
|
|
756
|
-
projectPath,
|
|
757
|
-
slot,
|
|
758
|
-
settingsRoot,
|
|
759
|
-
label,
|
|
760
|
-
settings,
|
|
761
|
-
flags,
|
|
762
|
-
note,
|
|
763
|
-
out,
|
|
764
|
-
reconcileIosSimulator,
|
|
765
|
-
simSnapshot
|
|
766
|
-
});
|
|
767
|
-
return ensureOwnedAndroidDevice({
|
|
768
|
-
record,
|
|
769
|
-
projectPath,
|
|
770
|
-
slot,
|
|
771
|
-
settingsRoot,
|
|
772
|
-
label,
|
|
773
|
-
settings,
|
|
774
|
-
flags,
|
|
775
|
-
note,
|
|
776
|
-
out,
|
|
777
|
-
logFile,
|
|
778
|
-
alive,
|
|
779
|
-
configureAvd,
|
|
780
|
-
teardownAvd
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
const BOOT_POLL_MS = 500;
|
|
784
|
-
async function ensureBooted({ platform, device, simulatorApp, timeoutMs, pollMs = BOOT_POLL_MS, out = () => {}, logFile = null, alive = pidExists, projectPath, slot, deviceSlotWait }) {
|
|
785
|
-
if (platform === "ios") return ensureIosBooted({
|
|
786
|
-
device,
|
|
787
|
-
projectPath,
|
|
788
|
-
slot,
|
|
789
|
-
deviceSlotWait,
|
|
790
|
-
simulatorApp,
|
|
791
|
-
timeoutMs: timeoutMs ?? 6e5,
|
|
792
|
-
pollMs,
|
|
793
|
-
out
|
|
794
|
-
});
|
|
795
|
-
if (platform === "android") return ensureAndroidBooted({
|
|
796
|
-
device,
|
|
797
|
-
deviceSlotWait,
|
|
798
|
-
projectPath,
|
|
799
|
-
slot,
|
|
800
|
-
timeoutMs: timeoutMs ?? ANDROID_BOOT_TIMEOUT_MS,
|
|
801
|
-
out,
|
|
802
|
-
logFile,
|
|
803
|
-
alive
|
|
804
|
-
});
|
|
805
|
-
return {
|
|
806
|
-
failed: true,
|
|
807
|
-
reason: `Unknown platform "${platform}".`
|
|
808
|
-
};
|
|
809
|
-
}
|
|
810
|
-
//#endregion
|
|
811
|
-
export { AvdRecoveryError as a, AvdBootError as i, ensureBooted as n, warmMetro as o, ensureOwnedDevice as r, didSetUpDevice as t };
|
|
650
|
+
export { AvdBootError as a, muteBootedEmulator as i, ensureAndroidBooted as n, AvdRecoveryError as o, ensureOwnedAndroidDevice as r, ANDROID_BOOT_TIMEOUT_MS as t };
|