stim 1.17.2 → 1.19.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/README.md +50 -1
- package/dist/{activity-IRvJY_ru.mjs → activity-BSw0x84R.mjs} +4 -4
- package/dist/{agent-device-usage-output-BK41vnzN.mjs → agent-device-usage-output-Bjxu_VmX.mjs} +8 -8
- package/dist/{android-B9yaNKwa.mjs → android-BXc6BmEi.mjs} +658 -404
- package/dist/{android-B_YNZy61.mjs → android-BdQC6zs1.mjs} +9 -9
- package/dist/android-BvV1gGdN.mjs +4 -0
- package/dist/{android-DE4v59Mb.mjs → android-DE5g_5gv.mjs} +2 -2
- package/dist/{android-cas-ZFpjJBL_.mjs → android-cas-C87geAg-.mjs} +5 -5
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/api-DIf_s86s.mjs +150 -0
- package/dist/api-run.d.mts +1 -0
- package/dist/api-run.mjs +145 -0
- package/dist/api.d.mts +218 -0
- package/dist/api.mjs +2 -0
- package/dist/{app-install-VPkI5WEg.mjs → app-install-CFI4ptUL.mjs} +33 -13
- package/dist/{attempt-Bk2ouQVL.mjs → attempt-DW-mQqM7.mjs} +14 -4
- package/dist/{web-Dl0KSRHf.mjs → browser-web-CDhqQxhv.mjs} +138 -176
- package/dist/{budget-DfcgFdQB.mjs → budget-Dz-kyXLv.mjs} +1391 -58
- package/dist/build-facts-B87vo-Im.d.mts +142 -0
- package/dist/{cache-manifest-DnUHBJaU.mjs → cache-manifest-DiwKSyv9.mjs} +3 -3
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BrcVWQyD.mjs → chrome-BTUOo8p2.mjs} +1 -1
- package/dist/cli-C9Zvgbdc.mjs +68 -0
- package/dist/cli.mjs +1 -1
- package/dist/{client-SvBdgObD.mjs → client-CuUo8Nvg.mjs} +381 -49
- package/dist/collector-run.d.mts +6 -0
- package/dist/collector-run.mjs +9 -9
- package/dist/{command-output-CDAIFD-8.mjs → command-output-Bt8ygHE7.mjs} +2 -2
- package/dist/{config-D0DbpZtM.mjs → config-DC5jEtd1.mjs} +9 -5
- package/dist/{created-devices-CpvzBL25.mjs → created-devices-D0s26Hx5.mjs} +2 -2
- package/dist/{dependency-state-CLcBHH2M.mjs → dependency-state-DKaS1OM9.mjs} +2 -2
- package/dist/{detached-entry-CiTEgMR1.mjs → detached-entry-pB_IPfV4.mjs} +1 -1
- package/dist/{dev-client-B-XC4uRH.mjs → dev-client-CDY_zAmD.mjs} +2 -2
- package/dist/{device-C8IOoJPv.mjs → device-BHw0WlHl.mjs} +8 -8
- package/dist/{device-capacity-ZC4XSZ4R.mjs → device-capacity-BoN1jQkO.mjs} +25 -14
- package/dist/device-host-worker.mjs +19 -19
- package/dist/{gradle-dJpre3Yn.mjs → device-ios-B2ruohE-.mjs} +661 -107
- package/dist/{device-lease-DpoS36_u.mjs → device-lease-Cu7PtQpZ.mjs} +9 -9
- package/dist/{device-lease-run-B8YltIH_.mjs → device-lease-run-D38SnZtt.mjs} +4 -4
- package/dist/{device-pool-3o7s5lo4.mjs → device-pool-CP4rAsHx.mjs} +3 -3
- package/dist/{device-remote-hFSkpfQu.mjs → device-remote-B5GiUifk.mjs} +15 -16
- package/dist/{doctor-CFv1fCrF.mjs → doctor-PRJH94v6.mjs} +61 -34
- package/dist/doctor-watchman-wZhyTdp4.mjs +259 -0
- package/dist/{error-diagnostics-C-NMnhrk.mjs → error-diagnostics--v5HGOU0.mjs} +11 -11
- package/dist/{exec-CaErVv7t.mjs → exec-i8GDPwq9.mjs} +93 -6
- package/dist/{gc-DEmkg3Xh.mjs → gc-CyHMcKcn.mjs} +25 -471
- package/dist/{guide-CSmhMTf8.mjs → guide-dRaQJJk9.mjs} +681 -507
- package/dist/{hosted-android-E1Heoqnv.mjs → hosted-android-Bs7fytj7.mjs} +3 -3
- package/dist/{hosted-client-Bp4knSwu.mjs → hosted-client-C5G4h_OJ.mjs} +2 -2
- package/dist/{hosted-ios-BnbeYOUD.mjs → hosted-ios-Bik035eL.mjs} +1 -1
- package/dist/{hosted-logs-OcgIBvCT.mjs → hosted-logs-CI9Az9a4.mjs} +9 -9
- package/dist/{hosted-macos-DcxKjtfH.mjs → hosted-macos-DABm3ScO.mjs} +5 -5
- package/dist/{hosted-native-1Ebbig4w.mjs → hosted-native-DbV2aUVw.mjs} +13 -9
- package/dist/{idle-shutdown-IGyNV8Cr.mjs → idle-shutdown-DYiMBn34.mjs} +7 -8
- package/dist/{ios-DSfnPfse.mjs → ios-BWbHFZVz.mjs} +19 -7
- package/dist/{ios-Cr1h5gnO.mjs → ios-DCrkgXEM.mjs} +1 -1
- package/dist/ios-DYUr9LGc.mjs +8 -0
- package/dist/ios-ITYno9rO.mjs +2241 -0
- package/dist/{ios-device-pAN4t54-.mjs → ios-device-CJ_ZOGky.mjs} +3 -3
- package/dist/{ios-device-Ee7sDXfp.mjs → ios-device-CrW8aMb5.mjs} +1 -1
- package/dist/{ios-state-8L3lgum6.mjs → ios-state-By0XuLTQ.mjs} +1 -1
- package/dist/{launch-verify-lTnWZikR.mjs → launch-verify-DCveSE6d.mjs} +5 -5
- package/dist/{logs-BAaS7gS2.mjs → logs-Bao1HOMy.mjs} +13 -13
- package/dist/{macos-BIRQS90f.mjs → macos-ciyBdTY5.mjs} +194 -132
- package/dist/macos-nIOATJmR.mjs +2 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +349 -47
- package/dist/manifest-CX0d1IkZ.mjs +148 -0
- package/dist/{metro-g8NqiJp-.mjs → metro-DI2AjPF_.mjs} +196 -43
- package/dist/{metro-gateway-C-ijGI2F.mjs → metro-gateway-BxpJLIwh.mjs} +4 -4
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-BAHFcJm6.mjs} +16 -2
- package/dist/{build-plan-BDsSi09V.mjs → miss-reason-CjQCOKqq.mjs} +207 -249
- package/dist/{named-ports-C8m8EQs2.mjs → named-ports-B4iWH4E-.mjs} +70 -8
- package/dist/{native-runtime-BEK171xQ.mjs → native-runtime-BGxsbfny.mjs} +6 -6
- package/dist/{ndjson-PclOIwVY.mjs → ndjson-LGZAMsqa.mjs} +8 -4
- package/dist/offload-worker.d.mts +3 -45
- package/dist/offload-worker.mjs +11 -11
- package/dist/{ownership-DyRQru0q.mjs → ownership-EB0ySdGK.mjs} +3 -3
- package/dist/{page-QF_Ke10s.mjs → page-Bv9s2KwY.mjs} +1 -1
- package/dist/placement-log-Dxe34rJm.mjs +88 -0
- package/dist/plan-placement-BVY59qa8.mjs +290 -0
- package/dist/{ports-4nYqxPWC.mjs → ports-ByPc0_97.mjs} +3 -3
- package/dist/{prebuild-D7RUMkwN.mjs → prebuild-BKJ3wJI1.mjs} +5 -5
- package/dist/preview-BbSottmO.mjs +986 -0
- package/dist/{rolldown-runtime-BsOwBuO_.mjs → process-identity-Biv3arCO.mjs} +11 -1
- package/dist/project-B5eQ1USs.mjs +612 -0
- package/dist/{pull-request-pxnDCQzn.mjs → pull-request-IHNdMnG8.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-ios-BMh2i25I.mjs +2 -0
- package/dist/react-native-ios-CSpIxexZ.mjs +2083 -0
- package/dist/{recordings-BNgsD1Tr.mjs → recordings-Bv8McZN4.mjs} +1 -1
- package/dist/{reload-DcRxj3qG.mjs → reload-rAPdqeRR.mjs} +14 -15
- package/dist/{remote-cache-Ci4DQYYj.mjs → remote-cache-N3hAEaAL.mjs} +5 -5
- package/dist/{run-CkE9y0nc.mjs → run-lAkle1-c.mjs} +5 -5
- package/dist/{server-bare-BkrSxSsZ.mjs → server-bare-CkIjnegq.mjs} +5 -6
- package/dist/server-expo-DGsdUGX2.mjs +2 -0
- package/dist/{server-expo-CHTyXD0G.mjs → server-expo-n3tUi3Em.mjs} +5 -6
- package/dist/{settings-SR9OmW9h.mjs → settings-2am7TSxp.mjs} +5 -5
- package/dist/{settings-Cfd-0r2d.mjs → settings-CxgngUZk.mjs} +116 -103
- package/dist/{settings-BBpMcDbD.mjs → settings-Djl-mpjX.mjs} +1 -1
- package/dist/settings.schema.json +198 -9
- package/dist/{simslim-BWNrc3M3.mjs → simslim-D9LkJxIO.mjs} +7 -7
- package/dist/{slot-launch-DmjBmpQV.mjs → slot-launch-HV_KtPIw.mjs} +6 -6
- package/dist/{spawn-claims-D0XfSe8u.mjs → spawn-claims-Kqiifsk2.mjs} +1 -1
- package/dist/{spawn-entry-jw19m8Nl.mjs → spawn-entry-Dcb7sDUz.mjs} +1 -0
- package/dist/{stage-CzaiwFsI.mjs → stage-BgaZJVZY.mjs} +14 -3
- package/dist/{start-AlfCPRVU.mjs → start-D8NbxNBb.mjs} +1 -1
- package/dist/{start-DUz3mYdb.mjs → start-DtxthMfI.mjs} +34 -27
- package/dist/{state-PeQiJuIu.mjs → state-D2KtnALG.mjs} +4 -4
- package/dist/{state-DyaNTgfR.mjs → state-Tp4uImDS.mjs} +5 -3
- package/dist/{state-B4PQFXMW.d.mts → state-lKh8shBp.d.mts} +2 -3
- package/dist/{stats-Bq4fJOdB.mjs → stats-8EJ5ivFT.mjs} +6 -6
- package/dist/{status-DlKvVJBE.mjs → status-BEeL6IKz.mjs} +6 -4
- package/dist/{status-BA2pehwf.mjs → status-BOyp0CUl.mjs} +31 -34
- package/dist/{stim-desktop-Cnz8CPnl.mjs → stim-desktop-C65jk_q2.mjs} +1 -1
- package/dist/{stim-installations-QMEI32v1.mjs → stim-installations-DbmUjsLv.mjs} +1 -1
- package/dist/stop-D0UIpZuh.mjs +72 -0
- package/dist/{stop-zF1y04f2.mjs → stop-DRipAg-e.mjs} +2 -2
- package/dist/{stop-DQIasgKp.mjs → stop-zDlknFoz.mjs} +79 -33
- package/dist/supervisor-run.d.mts +24 -22
- package/dist/supervisor-run.mjs +21 -22
- package/dist/{support-CsJNVfOc.mjs → support-CNqYkV0y.mjs} +7 -7
- package/dist/{support-WvD__tSV.mjs → support-DsNaFg6D.mjs} +5 -5
- package/dist/swiftpm-macos-aJzPAj1t.mjs +119 -0
- package/dist/{toolchain-DNyR3NPq.mjs → toolchain-C3xSoyUl.mjs} +475 -269
- package/dist/{trigger-Bemu8ytw.mjs → trigger-CAhmG-4s.mjs} +6 -6
- package/dist/trigger-CoalsMTV.mjs +2 -0
- package/dist/{warm-progress-DF4JRvYI.mjs → warm-progress-pFLB2e6P.mjs} +135 -38
- package/dist/{status-CzS4bPO9.mjs → watchman-BL1IdOtq.mjs} +75 -7
- package/dist/web-DFpFeZu5.mjs +2 -0
- package/dist/web-DbbrPUn0.mjs +127 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-DqcCbpE7.mjs → workspace-state-CR9X86xJ.mjs} +3 -3
- package/dist/{ownership-BMLqyBgJ.mjs → workspaces-Djb2gfi9.mjs} +661 -23
- package/dist/{worktree-Be_7NLKy.mjs → worktree-BL4M1rhB.mjs} +252 -50
- package/dist/{worktree-j3IcFAI5.mjs → worktree-DV-A0LNL.mjs} +1 -1
- package/package.json +10 -5
- package/shim/bundle-response.cjs +2 -1
- package/shim/bundle-response.d.cts +1 -1
- package/shim/expo-metro-config.cjs +1 -1
- package/dist/build-progress-D0WkjCPd.mjs +0 -1036
- package/dist/build-slots-41v_d2x9.mjs +0 -142
- package/dist/cli-CYXb29oE.mjs +0 -51
- package/dist/deps-iKw0eD4P.mjs +0 -438
- package/dist/device-ios-C2Um-XUR.mjs +0 -412
- package/dist/errors-B6W7FkxQ.mjs +0 -15
- package/dist/guide-status-Du-ZQ3FD.mjs +0 -125
- package/dist/idle-BXG__1BA.mjs +0 -176
- package/dist/in-use-CvGOUn-x.mjs +0 -130
- package/dist/ios-BJ4XUSe1.mjs +0 -3867
- package/dist/native-run-D1Q56rAD.mjs +0 -158
- package/dist/preview-B-g9d7kV.mjs +0 -318
- package/dist/process-identity-BmRm1qV0.mjs +0 -12
- package/dist/project-D47Rh0ly.mjs +0 -276
- package/dist/server-expo-CeakhI8P.mjs +0 -2
- package/dist/state-BKa8wNN5.mjs +0 -148
- package/dist/stop-BIiM49EY.mjs +0 -48
- package/dist/stop-cause-rhmGfwvt.mjs +0 -97
- package/dist/trigger-CXts6qt1.mjs +0 -2
- package/dist/watchman-APYjXSQa.mjs +0 -48
- package/dist/workspace-process-lock-2mNzOlaB.mjs +0 -58
- package/dist/workspaces-Bcib97-6.mjs +0 -306
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as ownership_claim_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
1
|
+
import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
|
|
4
3
|
import { r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { o as
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { A as
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { t as
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { t as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { t as reconcileSimSlim } from "./simslim-
|
|
28
|
-
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { l as phaseLine } from "./command-output-Bt8ygHE7.mjs";
|
|
5
|
+
import { D as withConfigLock$1, H as projectDeviceSlots, _ as loadConfig$1, a as clearDevice, b as releaseAndroidConsolePort, i as clearAndroidBootPending, k as acquireAvdClaim, p as getProject, t as allConsolePortsAndSerials, w as setDevice, z as deviceSlotPlatforms } from "./config-DC5jEtd1.mjs";
|
|
6
|
+
import { d as sharedBuildCache } from "./workspace-state-CR9X86xJ.mjs";
|
|
7
|
+
import { E as readMetroTunnel, O as readRemoteSession, o as ownedDeviceLabel } from "./project-B5eQ1USs.mjs";
|
|
8
|
+
import { Ct as removeTemporaryEntry, J as planMetroReach, St as makeTemporaryDirectory, a as androidAvdConfigSetting, c as androidDataPartitionSizeGbSetting, q as detectProviders, rt as gitCommonDirOnDisk } from "./settings-CxgngUZk.mjs";
|
|
9
|
+
import { s as pidExists } from "./metro-DI2AjPF_.mjs";
|
|
10
|
+
import { s as peekBudget } from "./budget-Dz-kyXLv.mjs";
|
|
11
|
+
import { A as teardownParkedAvd, D as teardownOwnedAvd } from "./workspaces-Djb2gfi9.mjs";
|
|
12
|
+
import { C as diffFingerprintSources, I as storedSources } from "./device-lease-Cu7PtQpZ.mjs";
|
|
13
|
+
import { A as listAvds, B as ownedAvdSystemImage, E as getAvdNameForSerial, F as ownedAvdDeviceProfile, J as resolveOwnedAvdSerial, L as ownedAvdMatchesConfiguration, O as listAdbDevices, P as nextConsolePort, R as ownedAvdName, W as pickDefaultSystemImage, b as createOwnedAvd, f as assertOwnedAvdStopped, ft as parkedMaxSetting, g as avdPoolConfiguration, j as listInstalledSystemImages, n as OWNED_AVD_CONFIG_DEFAULTS, pt as readParked, st as adoptParked, t as DEFAULT_AVD_DEVICE_PROFILE, tt as waitForBoot, ut as isLegacyDeletionClaim, v as bootAndroidEmulator, y as configureNewOwnedAvd } from "./android-BdQC6zs1.mjs";
|
|
14
|
+
import { M as readHostMemoryPressure, d as listAllIosSims } from "./ios-BWbHFZVz.mjs";
|
|
15
|
+
import { E as namedBuildMachine, N as hostingMachines, k as resolveBuildMachine } from "./client-CuUo8Nvg.mjs";
|
|
16
|
+
import { t as clearDeviceIdleShutdown } from "./idle-shutdown-DYiMBn34.mjs";
|
|
17
|
+
import { i as countLiveOwnedDevices, n as DeviceAdmissionRefusal, p as withDeviceBootAdmission, s as peekDeviceSlots } from "./device-capacity-BoN1jQkO.mjs";
|
|
18
|
+
import { E as startBuildHeartbeat, O as tailLines, h as HEARTBEAT_INTERVAL_MS } from "./toolchain-C3xSoyUl.mjs";
|
|
19
|
+
import { t as cleanLine } from "./server-expo-n3tUi3Em.mjs";
|
|
20
|
+
import { a as call, o as connectHost } from "./hosted-client-C5G4h_OJ.mjs";
|
|
21
|
+
import { r as readHostedNative, s as writeHostedNative } from "./ios-state-By0XuLTQ.mjs";
|
|
22
|
+
import { n as prepareHostedNative } from "./hosted-native-DbV2aUVw.mjs";
|
|
23
|
+
import { f as resolveEasCliBin, s as isEasAuthFailureText } from "./remote-cache-N3hAEaAL.mjs";
|
|
24
|
+
import { i as ensureOwnedIosDevice, r as ensureIosBooted } from "./device-ios-B2ruohE-.mjs";
|
|
25
|
+
import { _ as MIN_EAS_CLI_SIMULATOR_VERSION, g as MIN_EAS_CLI_DEVICE_VERSION, s as readInstalledEasCliVersion, v as easCliSupport } from "./device-remote-B5GiUifk.mjs";
|
|
26
|
+
import { t as reconcileSimSlim } from "./simslim-D9LkJxIO.mjs";
|
|
29
27
|
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
30
28
|
import { basename, dirname, join, relative } from "node:path";
|
|
31
|
-
import { LAST_BUILD_KEYS, isJsonObject, loadConfig, machineCapacity, parseHostedChoice, parseHostedNativeOffer, readWorkspaceState } from "@stim-cli/core/state";
|
|
32
|
-
import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
|
|
33
|
-
import { captureProcessIdentity } from "@stim-cli/core/process-identity";
|
|
29
|
+
import { LAST_BUILD_KEYS, automaticMachineEnabled, isJsonObject, loadConfig, machineCapacity, parseHostedChoice, parseHostedNativeOffer, readWorkspaceState } from "@stim-cli/core/state";
|
|
34
30
|
import chalk from "chalk";
|
|
35
31
|
import { isDeepStrictEqual } from "node:util";
|
|
32
|
+
import { claimRemoveCommand, clearClaimChild, markClaimChildPending, processGroupAlive, releaseClaim, setClaimChild } from "@stim-cli/core/ownership-claim";
|
|
33
|
+
import { captureProcessIdentity } from "@stim-cli/core/process-identity";
|
|
34
|
+
import { randomUUID } from "node:crypto";
|
|
36
35
|
import * as expoFingerprint from "@expo/fingerprint";
|
|
37
|
-
import { resolveTieredBuild } from "@stim-cli/cache";
|
|
38
36
|
import { request } from "node:http";
|
|
39
37
|
//#region src/device-host/placement.ts
|
|
40
|
-
function local$1(reason, skipped = []) {
|
|
38
|
+
function local$1(code, reason, skipped = [], atCapacity = false) {
|
|
41
39
|
return {
|
|
42
40
|
kind: "local",
|
|
41
|
+
code,
|
|
43
42
|
reason,
|
|
44
|
-
skipped
|
|
43
|
+
skipped,
|
|
44
|
+
...atCapacity ? { atCapacity: true } : {}
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
function decideDevicePlacement(inputs) {
|
|
@@ -50,6 +50,7 @@ function decideDevicePlacement(inputs) {
|
|
|
50
50
|
const reason = `recorded session on ${inputs.sticky.machine}`;
|
|
51
51
|
return {
|
|
52
52
|
kind: "host",
|
|
53
|
+
code: "sticky",
|
|
53
54
|
reason,
|
|
54
55
|
machines: [{
|
|
55
56
|
machine: inputs.sticky.machine,
|
|
@@ -60,30 +61,62 @@ function decideDevicePlacement(inputs) {
|
|
|
60
61
|
}
|
|
61
62
|
return {
|
|
62
63
|
kind: "local",
|
|
64
|
+
code: "sticky",
|
|
63
65
|
reason: "this workspace's device runs here",
|
|
64
66
|
skipped: []
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
|
-
const { platform, here, offers, buildMachine, noWait } = inputs;
|
|
69
|
+
const { platform, here, offers, buildMachine, noWait, eas } = inputs;
|
|
68
70
|
const { count, max, queued } = here.devices;
|
|
69
|
-
const
|
|
71
|
+
const room = max === 0 || count !== null && count < max;
|
|
72
|
+
const localEnabled = here.localEnabled !== false;
|
|
73
|
+
const cannotTake = !localEnabled || !room || queued > 0;
|
|
74
|
+
const atCapacity = count !== null && (!room || queued > 0);
|
|
70
75
|
const usage = max > 0 ? `${count} of ${max} devices in use` : `${count} devices in use, no device cap`;
|
|
71
|
-
const localReason = count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
const localReason = !localEnabled ? "local is disabled in remote.devicePoolDisabled" : count === null ? "cannot tell how many devices run here; local boot admission decides" : cannotTake ? `${usage}${queued ? `, ${queued} runs queued ahead` : ""}` : here.budgetRefusal ?? (here.memoryPressure !== "normal" ? `host memory pressure ${here.memoryPressure ?? "unknown"} here` : `load ${here.loadPerCore.toFixed(1)}/core here, ${usage}`);
|
|
77
|
+
const nowhere = (code, reason, skipped = [], waiting = "") => {
|
|
78
|
+
if (!localEnabled && !atCapacity) return {
|
|
79
|
+
kind: "refused",
|
|
80
|
+
code: "pool-unavailable",
|
|
81
|
+
reason,
|
|
82
|
+
skipped
|
|
83
|
+
};
|
|
84
|
+
if (!cannotTake || count === null) return local$1(code, reason + waiting, skipped);
|
|
85
|
+
if (eas?.usable) return {
|
|
86
|
+
kind: "eas",
|
|
87
|
+
code: "eas-fallback",
|
|
88
|
+
reason: `${reason}; EAS Simulator (remote.easFallback)`,
|
|
89
|
+
skipped
|
|
90
|
+
};
|
|
91
|
+
const why = eas ? [...skipped, {
|
|
92
|
+
machine: "eas",
|
|
93
|
+
code: eas.code,
|
|
94
|
+
reason: eas.reason
|
|
95
|
+
}] : skipped;
|
|
96
|
+
return localEnabled ? local$1(code, reason + waiting, why, true) : {
|
|
97
|
+
kind: "refused",
|
|
98
|
+
code: "pool-unavailable",
|
|
99
|
+
reason,
|
|
100
|
+
skipped: why,
|
|
101
|
+
atCapacity: true
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
if (!offers.length) return nowhere("no-remote-mac", "no remote Macs configured; " + localReason);
|
|
105
|
+
if (localEnabled && count === null) return local$1("device-count-unknown", localReason);
|
|
106
|
+
if (!cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1("this-mac-free", localReason);
|
|
75
107
|
const skipped = [];
|
|
76
108
|
const admitted = [];
|
|
77
109
|
offers.forEach((probe, index) => {
|
|
78
110
|
let reason = null;
|
|
111
|
+
let code = "unreachable";
|
|
79
112
|
if ("failure" in probe) reason = probe.failure;
|
|
80
113
|
else {
|
|
81
114
|
const { offer } = probe;
|
|
82
|
-
if (offer.declined !== null) reason = `declined: ${offer.declined}
|
|
83
|
-
else if (offer.platform !== platform || !offer.choice) reason = `no matching ${platform} device choice
|
|
84
|
-
else if (offer.resources.memoryPressure !== "normal") reason = "host memory pressure unknown or elevated";
|
|
85
|
-
else if (offer.capacity.available === 0) reason = "no hosted device capacity available";
|
|
86
|
-
else if (!cannotTake && (offer.resources.loadPerCore === null || offer.resources.loadPerCore >= here.loadPerCore)) reason = offer.resources.loadPerCore === null ? "host load unknown while this Mac has room" : "host is not less loaded than this Mac";
|
|
115
|
+
if (offer.declined !== null) [code, reason] = ["declined", `declined: ${offer.declined}`];
|
|
116
|
+
else if (offer.platform !== platform || !offer.choice) [code, reason] = ["no-matching-device", `no matching ${platform} device choice`];
|
|
117
|
+
else if (offer.resources.memoryPressure !== "normal") [code, reason] = ["memory", "host memory pressure unknown or elevated"];
|
|
118
|
+
else if (offer.capacity.available === 0) [code, reason] = ["no-capacity", "no hosted device capacity available"];
|
|
119
|
+
else if (!cannotTake && (offer.resources.loadPerCore === null || offer.resources.loadPerCore >= here.loadPerCore)) [code, reason] = ["load", offer.resources.loadPerCore === null ? "host load unknown while this Mac has room" : "host is not less loaded than this Mac"];
|
|
87
120
|
else admitted.push({
|
|
88
121
|
machine: probe.machine,
|
|
89
122
|
offer,
|
|
@@ -92,17 +125,19 @@ function decideDevicePlacement(inputs) {
|
|
|
92
125
|
}
|
|
93
126
|
if (reason) skipped.push({
|
|
94
127
|
machine: probe.machine,
|
|
128
|
+
code,
|
|
95
129
|
reason
|
|
96
130
|
});
|
|
97
131
|
});
|
|
98
132
|
admitted.sort((a, b) => Number(b.machine === buildMachine) - Number(a.machine === buildMachine) || (a.offer.resources.loadPerCore ?? Infinity) - (b.offer.resources.loadPerCore ?? Infinity) || b.offer.resources.memoryFreeBytes - a.offer.resources.memoryFreeBytes || a.index - b.index);
|
|
99
|
-
if (!admitted.length) return
|
|
133
|
+
if (!admitted.length) return nowhere("no-host-admits", `${localReason}; no host admits`, skipped, localEnabled && cannotTake && !noWait ? "; waiting locally if needed" : "");
|
|
100
134
|
const machines = admitted.map(({ machine, offer }) => ({
|
|
101
135
|
machine,
|
|
102
136
|
reason: `${localReason}; ${machine}${machine === buildMachine ? " is the explicit remote Mac," : ""} load ${offer.resources.loadPerCore === null ? "unknown" : offer.resources.loadPerCore.toFixed(1) + "/core"}`
|
|
103
137
|
}));
|
|
104
138
|
return {
|
|
105
139
|
kind: "host",
|
|
140
|
+
code: "placed",
|
|
106
141
|
machines,
|
|
107
142
|
reason: machines[0].reason,
|
|
108
143
|
skipped
|
|
@@ -160,7 +195,7 @@ async function probeHost(machine, platform, selectors) {
|
|
|
160
195
|
host?.connection.close();
|
|
161
196
|
}
|
|
162
197
|
}
|
|
163
|
-
function hosted(target, reason, skipped = []) {
|
|
198
|
+
function hosted(target, code, reason, skipped = []) {
|
|
164
199
|
target.selection = {
|
|
165
200
|
selected: "auto",
|
|
166
201
|
reason
|
|
@@ -172,20 +207,34 @@ function hosted(target, reason, skipped = []) {
|
|
|
172
207
|
machine: target.host.machine,
|
|
173
208
|
reason
|
|
174
209
|
},
|
|
210
|
+
code,
|
|
175
211
|
skipped
|
|
176
212
|
};
|
|
177
213
|
}
|
|
178
|
-
function local(reason, skipped = []) {
|
|
214
|
+
function local(code, reason, skipped = []) {
|
|
179
215
|
return {
|
|
180
216
|
target: null,
|
|
181
217
|
placement: {
|
|
182
218
|
decision: "local",
|
|
183
219
|
reason
|
|
184
220
|
},
|
|
221
|
+
code,
|
|
185
222
|
skipped
|
|
186
223
|
};
|
|
187
224
|
}
|
|
188
|
-
|
|
225
|
+
function viaEas(code, reason, skipped) {
|
|
226
|
+
return {
|
|
227
|
+
target: null,
|
|
228
|
+
placement: {
|
|
229
|
+
decision: "eas",
|
|
230
|
+
machine: "eas",
|
|
231
|
+
reason
|
|
232
|
+
},
|
|
233
|
+
code,
|
|
234
|
+
skipped
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
async function automaticDevicePlacement({ root, slot, platform, selectors, buildMachine, noWait, eas }, { machines = hostingMachines, read = readHostedNative, write = writeHostedNative, resume = prepareHostedNative, peek = () => peekDeviceSlots({
|
|
189
238
|
platform,
|
|
190
239
|
project: getProject(root),
|
|
191
240
|
slot
|
|
@@ -200,6 +249,7 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, build
|
|
|
200
249
|
machine: recorded.machine,
|
|
201
250
|
reason: recorded.reason ?? decideDevicePlacement({ sticky: { machine: recorded.machine } }).reason
|
|
202
251
|
},
|
|
252
|
+
code: "sticky",
|
|
203
253
|
skipped: [],
|
|
204
254
|
sticky: true
|
|
205
255
|
};
|
|
@@ -207,48 +257,134 @@ async function automaticDevicePlacement({ root, slot, platform, selectors, build
|
|
|
207
257
|
}
|
|
208
258
|
const devices = peek();
|
|
209
259
|
if (devices.localLive) return {
|
|
210
|
-
...local(decideDevicePlacement({ sticky: { local: true } }).reason),
|
|
260
|
+
...local("sticky", decideDevicePlacement({ sticky: { local: true } }).reason),
|
|
211
261
|
sticky: true
|
|
212
262
|
};
|
|
213
|
-
const
|
|
214
|
-
if (
|
|
215
|
-
const
|
|
263
|
+
const configured = machines();
|
|
264
|
+
if (configured === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
|
|
265
|
+
const config = loadConfig$1();
|
|
266
|
+
const entries = configured.filter((machine) => automaticMachineEnabled("device", machine, config));
|
|
267
|
+
const preference = resolveBuildMachine(buildMachine, process.env.STIM_REMOTE_BUILD, config?.remote?.build);
|
|
216
268
|
buildMachine = namedBuildMachine(preference) ? preference : void 0;
|
|
217
269
|
const load = capacity();
|
|
218
270
|
const here = {
|
|
271
|
+
localEnabled: automaticMachineEnabled("device", "local", config),
|
|
219
272
|
loadPerCore: load.loadPerCore,
|
|
220
273
|
maxLoadPerCore: load.maxLoadPerCore,
|
|
221
274
|
memoryPressure: memory(),
|
|
222
275
|
devices,
|
|
223
276
|
budgetRefusal: await budget(root)
|
|
224
277
|
};
|
|
225
|
-
const
|
|
278
|
+
const inputs = (offers) => ({
|
|
226
279
|
platform,
|
|
227
280
|
here,
|
|
228
|
-
offers
|
|
229
|
-
machine,
|
|
230
|
-
failure: "not probed"
|
|
231
|
-
})),
|
|
281
|
+
offers,
|
|
232
282
|
buildMachine,
|
|
233
283
|
noWait
|
|
234
284
|
});
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
285
|
+
const notProbed = entries.map((machine) => ({
|
|
286
|
+
machine,
|
|
287
|
+
failure: "not probed"
|
|
288
|
+
}));
|
|
289
|
+
const early = decideDevicePlacement(inputs(notProbed));
|
|
290
|
+
const probes = early.kind === "local" && early.skipped.length === 0 ? [] : await Promise.all(entries.map((machine) => probe(machine, platform, selectors)));
|
|
291
|
+
const offers = probes.length ? probes.map((each) => each.probe) : notProbed;
|
|
292
|
+
let decision = decideDevicePlacement(inputs(offers));
|
|
293
|
+
if ((decision.kind === "local" || decision.kind === "refused") && decision.atCapacity && eas) decision = decideDevicePlacement({
|
|
294
|
+
...inputs(offers),
|
|
295
|
+
eas: await eas()
|
|
243
296
|
});
|
|
244
|
-
if (decision.kind === "
|
|
297
|
+
if (decision.kind === "refused") throw Object.assign(new Error(devicePlacementLine({
|
|
298
|
+
decision: "local",
|
|
299
|
+
reason: decision.reason
|
|
300
|
+
}, decision.skipped)), {
|
|
301
|
+
code: "STIM_HOSTING_REFUSED",
|
|
302
|
+
remedy: "Enable an available member in remote.devicePoolDisabled or select a machine explicitly."
|
|
303
|
+
});
|
|
304
|
+
if (decision.kind === "eas") return viaEas(decision.code, decision.reason, decision.skipped);
|
|
305
|
+
if (decision.kind === "local") return local(decision.code, decision.reason, decision.skipped);
|
|
245
306
|
const target = probes.find((each) => each.probe.machine === decision.machines[0].machine).target;
|
|
246
|
-
return hosted(target, decision.reason, decision.skipped);
|
|
307
|
+
return hosted(target, decision.code, decision.reason, decision.skipped);
|
|
247
308
|
}
|
|
248
309
|
function devicePlacementLine(placement, skipped) {
|
|
249
310
|
return `${placement.machine ?? "local"}, ${placement.reason}${placement.decision !== "hosted" && skipped.length ? "; " + skipped.map((each) => `${each.machine}: ${each.reason}`).join("; ") : ""}`;
|
|
250
311
|
}
|
|
251
312
|
//#endregion
|
|
313
|
+
//#region src/engine/eas-fallback.ts
|
|
314
|
+
const AVAILABILITY_TIMEOUT_MS = 3e4;
|
|
315
|
+
function unusable(code, reason) {
|
|
316
|
+
return {
|
|
317
|
+
usable: false,
|
|
318
|
+
code,
|
|
319
|
+
reason
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
/** Reads `eas simulator:availability --json`: `{"available": true, ...}` on stdout, or a failure on stderr. */
|
|
323
|
+
function parseSimulatorAvailability(outcome) {
|
|
324
|
+
if ("failure" in outcome) {
|
|
325
|
+
if (outcome.timedOut) return unusable("eas-unavailable", "eas simulator:availability timed out");
|
|
326
|
+
const detail = outcome.failure.split("\n").map((line) => line.trim()).find((line) => line && !/is now available\.$|^(To upgrade|npm install|Proceeding with|\(node:|\(Use `node)/.test(line));
|
|
327
|
+
if (isEasAuthFailureText(outcome.failure)) return unusable("eas-logged-out", "eas-cli is not logged in (run eas login or set EXPO_TOKEN)");
|
|
328
|
+
return unusable("eas-unavailable", `eas simulator:availability failed${detail ? `: ${detail}` : ""}`);
|
|
329
|
+
}
|
|
330
|
+
let data = null;
|
|
331
|
+
try {
|
|
332
|
+
data = JSON.parse(outcome.stdout.slice(outcome.stdout.indexOf("{")));
|
|
333
|
+
} catch {}
|
|
334
|
+
if (typeof data !== "object" || data === null || typeof data.available !== "boolean") return unusable("eas-unavailable", "eas simulator:availability printed no availability");
|
|
335
|
+
return data.available ? { usable: true } : unusable("eas-not-enabled", "EAS Simulator is not enabled for this EAS account");
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Whether this run could use an EAS Simulator the way `--remote eas` does, without starting a session or a build.
|
|
339
|
+
* Each refusal names what `--remote eas` would refuse later, so automatic placement falls through instead.
|
|
340
|
+
*/
|
|
341
|
+
async function checkEasFallback({ root, platform, slot, release, isExpo, tunnelMode, publicUrl, deviceTypeFlag, localOnlyFlags, env = process.env, resolveBin = resolveEasCliBin, readVersion = readInstalledEasCliVersion, onPath = (bin) => getExecutor().findExecutable(bin) !== null, readTunnel = readMetroTunnel, readSession = readRemoteSession, metroPort = () => getProject(root)?.metroPort ?? null, availability = async (bin) => {
|
|
342
|
+
try {
|
|
343
|
+
return { stdout: await getExecutor().runFileAsync(bin, [
|
|
344
|
+
"simulator:availability",
|
|
345
|
+
"--json",
|
|
346
|
+
"--non-interactive"
|
|
347
|
+
], {
|
|
348
|
+
cwd: root,
|
|
349
|
+
timeoutMs: AVAILABILITY_TIMEOUT_MS
|
|
350
|
+
}) };
|
|
351
|
+
} catch (error) {
|
|
352
|
+
const err = error;
|
|
353
|
+
return {
|
|
354
|
+
failure: String(err.stderr || err.message || error),
|
|
355
|
+
timedOut: err.code === "ETIMEDOUT"
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
} }) {
|
|
359
|
+
if (slot !== "default") return unusable("eas-named-slot", `an EAS Simulator takes only the default slot, not ${slot}`);
|
|
360
|
+
if (localOnlyFlags.length) return unusable("eas-local-flags", `${localOnlyFlags.join(" and ")} applies only to a ${platform} device on a Mac`);
|
|
361
|
+
const session = readSession(root);
|
|
362
|
+
if (session && session.platform !== platform) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.platform ?? "another platform"}`);
|
|
363
|
+
if (session && deviceTypeFlag?.trim() && session.deviceType !== deviceTypeFlag.trim()) return unusable("eas-session-busy", `this workspace's EAS Simulator session ${session.sessionId} runs ${session.deviceType ?? "the model EAS chose"}, not ${deviceTypeFlag.trim()}`);
|
|
364
|
+
if (!onPath("agent-device")) return unusable("eas-no-agent-device", "agent-device is not on PATH");
|
|
365
|
+
const bin = resolveBin(root);
|
|
366
|
+
if (!bin) return unusable("eas-no-cli", "eas-cli is not installed for this project or on PATH");
|
|
367
|
+
const versionOutput = readVersion(bin.file, root);
|
|
368
|
+
const minimum = platform === "ios" && deviceTypeFlag?.trim() ? MIN_EAS_CLI_DEVICE_VERSION : MIN_EAS_CLI_SIMULATOR_VERSION;
|
|
369
|
+
const { supported, version } = easCliSupport(versionOutput, minimum);
|
|
370
|
+
if (!supported) return unusable("eas-cli-too-old", `eas-cli ${version ?? "(unknown version)"} is older than ${minimum}`);
|
|
371
|
+
if (!release) {
|
|
372
|
+
const mode = tunnelMode ?? "auto";
|
|
373
|
+
if (mode === "off") return unusable("eas-metro-unreachable", "metro.tunnel is off, so an EAS Simulator cannot reach Metro");
|
|
374
|
+
const plan = planMetroReach({
|
|
375
|
+
mode,
|
|
376
|
+
metroPort: metroPort() ?? "unknown",
|
|
377
|
+
publicUrl: env["STIM_METRO_PUBLIC_URL"]?.trim() || publicUrl,
|
|
378
|
+
isExpo,
|
|
379
|
+
available: detectProviders(onPath, mode)
|
|
380
|
+
});
|
|
381
|
+
if ("failed" in plan) return unusable("eas-metro-unreachable", plan.failed);
|
|
382
|
+
if ("start" in plan && plan.start === "tailscale") return unusable("eas-metro-unreachable", "metro.tunnel is tailscale, which an EAS Simulator cannot reach");
|
|
383
|
+
if ("expoTunnel" in plan && readTunnel(root)?.kind !== "expo") return unusable("eas-metro-unreachable", "Metro has no Expo tunnel; run stim start --remote first");
|
|
384
|
+
}
|
|
385
|
+
return parseSimulatorAvailability(await availability(bin.file));
|
|
386
|
+
}
|
|
387
|
+
//#endregion
|
|
252
388
|
//#region src/engine/metro-warmup.ts
|
|
253
389
|
const WARMUP_TIMEOUT_MS = 6e4;
|
|
254
390
|
async function requestLocal(url, platform, prefetch) {
|
|
@@ -891,7 +1027,7 @@ async function ensureAndroidBooted({ device, deviceSlotWait, projectPath, slot,
|
|
|
891
1027
|
function didSetUpDevice(device, remote) {
|
|
892
1028
|
return remote ? void 0 : Boolean(device.setup || device.booting);
|
|
893
1029
|
}
|
|
894
|
-
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 }) {
|
|
1030
|
+
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 }) {
|
|
895
1031
|
clearDeviceIdleShutdown(projectPath, platform, slot);
|
|
896
1032
|
if (slot && slot !== "default") label = `${label}-${slot}`;
|
|
897
1033
|
const record = deviceSlotPlatforms(project, slot)?.[platform] ?? null;
|
|
@@ -905,7 +1041,8 @@ async function ensureOwnedDevice({ platform, project, projectPath, slot, setting
|
|
|
905
1041
|
flags,
|
|
906
1042
|
note,
|
|
907
1043
|
out,
|
|
908
|
-
reconcileIosSimulator
|
|
1044
|
+
reconcileIosSimulator,
|
|
1045
|
+
simSnapshot
|
|
909
1046
|
});
|
|
910
1047
|
return ensureOwnedAndroidDevice({
|
|
911
1048
|
record,
|
|
@@ -1603,183 +1740,4 @@ function fingerprintErrorMissReason(message) {
|
|
|
1603
1740
|
};
|
|
1604
1741
|
}
|
|
1605
1742
|
//#endregion
|
|
1606
|
-
|
|
1607
|
-
const DISCARD = {
|
|
1608
|
-
file: "",
|
|
1609
|
-
written: 0,
|
|
1610
|
-
dropped: 0,
|
|
1611
|
-
lastError: null,
|
|
1612
|
-
write: () => true,
|
|
1613
|
-
close: () => ({
|
|
1614
|
-
file: "",
|
|
1615
|
-
written: 0,
|
|
1616
|
-
dropped: 0,
|
|
1617
|
-
lastError: null
|
|
1618
|
-
})
|
|
1619
|
-
};
|
|
1620
|
-
async function providerHit({ root, platform, cacheKey, providerConfig }, deps) {
|
|
1621
|
-
if (!providerConfig) return null;
|
|
1622
|
-
let destinationDir;
|
|
1623
|
-
try {
|
|
1624
|
-
destinationDir = makeTemporaryDirectory(root, "stim-plan-");
|
|
1625
|
-
} catch (error) {
|
|
1626
|
-
deps.note(chalk.yellow(phaseLine("cache", `provider not checked: ${error?.message || error}`)));
|
|
1627
|
-
return null;
|
|
1628
|
-
}
|
|
1629
|
-
try {
|
|
1630
|
-
const found = await resolveTieredBuild({
|
|
1631
|
-
local: {
|
|
1632
|
-
resolve: () => null,
|
|
1633
|
-
store: () => null
|
|
1634
|
-
},
|
|
1635
|
-
loadProvider: () => deps.loadCacheProvider({
|
|
1636
|
-
projectRoot: root,
|
|
1637
|
-
config: providerConfig
|
|
1638
|
-
}),
|
|
1639
|
-
target: {
|
|
1640
|
-
projectRoot: root,
|
|
1641
|
-
platform,
|
|
1642
|
-
key: cacheKey
|
|
1643
|
-
},
|
|
1644
|
-
destinationDir,
|
|
1645
|
-
warn: (_code, message) => deps.note(chalk.yellow(phaseLine("cache", message)))
|
|
1646
|
-
});
|
|
1647
|
-
return found ? found.providerName ?? "the cache provider" : null;
|
|
1648
|
-
} finally {
|
|
1649
|
-
removeTemporaryEntry(destinationDir);
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
async function expoRemoteHit(lookup, deps) {
|
|
1653
|
-
if (!lookup.expoRemote) return null;
|
|
1654
|
-
const { root, platform, isExpo, fingerprint } = lookup;
|
|
1655
|
-
const loaded = await deps.loadProjectProvider(root, { isExpo });
|
|
1656
|
-
if (loaded?.unavailable) {
|
|
1657
|
-
deps.note(chalk.yellow(phaseLine("cache", `provider not usable: ${loaded.unavailable}`)));
|
|
1658
|
-
return null;
|
|
1659
|
-
}
|
|
1660
|
-
if (!loaded?.provider) return null;
|
|
1661
|
-
const name = loaded.name ?? "the build cache provider";
|
|
1662
|
-
if (name === "eas") {
|
|
1663
|
-
const auth = deps.checkEasAuth({
|
|
1664
|
-
projectRoot: root,
|
|
1665
|
-
owner: loaded.owner || null
|
|
1666
|
-
});
|
|
1667
|
-
const authNote = easAuthNote(auth);
|
|
1668
|
-
if (authNote) deps.note(chalk.yellow(phaseLine("cache", authNote)));
|
|
1669
|
-
if (auth?.code === "logged-out") return null;
|
|
1670
|
-
}
|
|
1671
|
-
const hit = await deps.resolveRemote({
|
|
1672
|
-
provider: loaded.provider,
|
|
1673
|
-
platform,
|
|
1674
|
-
projectRoot: root,
|
|
1675
|
-
fingerprintHash: fingerprint,
|
|
1676
|
-
runOptions: lookup.expoRemote.runOptions,
|
|
1677
|
-
logWriter: DISCARD
|
|
1678
|
-
});
|
|
1679
|
-
if (hit?.timedOut) deps.note(chalk.yellow(phaseLine("cache", `${name} did not answer; counted as a miss`)));
|
|
1680
|
-
else if (hit?.failed) deps.note(chalk.yellow(phaseLine("cache", `${name} could not be used: ${hit.failed}`)));
|
|
1681
|
-
return hit?.appPath ? name : null;
|
|
1682
|
-
}
|
|
1683
|
-
async function planCachedBuild(lookup, deps) {
|
|
1684
|
-
const { root, platform, isExpo, fingerprint, sources, cacheKey, cachePolicy } = lookup;
|
|
1685
|
-
let cacheHit = false;
|
|
1686
|
-
let provider = null;
|
|
1687
|
-
if (cachePolicy.read) {
|
|
1688
|
-
if (artifactIn(entryDir(platform, cacheKey))) cacheHit = "local";
|
|
1689
|
-
else {
|
|
1690
|
-
provider = (cachePolicy.remote ? await providerHit(lookup, deps) : null) ?? await expoRemoteHit(lookup, deps);
|
|
1691
|
-
if (provider) cacheHit = "remote";
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
let prebuild = null;
|
|
1695
|
-
let refusal = null;
|
|
1696
|
-
let missReason;
|
|
1697
|
-
if (!cacheHit) {
|
|
1698
|
-
prebuild = deps.planPrebuild(root, platform, {
|
|
1699
|
-
isExpo,
|
|
1700
|
-
fingerprint,
|
|
1701
|
-
sources
|
|
1702
|
-
});
|
|
1703
|
-
if (prebuild === "refuse") refusal = staleNativeDirRefusal(platform);
|
|
1704
|
-
else if (cachePolicy.read) missReason = predictBuildMiss({
|
|
1705
|
-
root,
|
|
1706
|
-
platform,
|
|
1707
|
-
current: {
|
|
1708
|
-
hash: fingerprint,
|
|
1709
|
-
sources
|
|
1710
|
-
},
|
|
1711
|
-
prebuild: prebuild === "generate" || prebuild === "regenerate" ? prebuild : null
|
|
1712
|
-
});
|
|
1713
|
-
}
|
|
1714
|
-
return planPayload(lookup, {
|
|
1715
|
-
fingerprint,
|
|
1716
|
-
cacheKey,
|
|
1717
|
-
cacheHit,
|
|
1718
|
-
provider,
|
|
1719
|
-
cacheSkipped: !cachePolicy.read,
|
|
1720
|
-
prebuild,
|
|
1721
|
-
...missReason ? { missReason } : {},
|
|
1722
|
-
refusal
|
|
1723
|
-
});
|
|
1724
|
-
}
|
|
1725
|
-
function planPayload({ platform, slot, projectKey }, found) {
|
|
1726
|
-
const { refusal, missReason, ...rest } = found;
|
|
1727
|
-
const outcome = refusal ? null : found.cacheHit ? "hit" : "cold";
|
|
1728
|
-
const estimate = outcome ? estimateBuild(readStats$1().record?.history?.[projectKey], platform, outcome) : {
|
|
1729
|
-
expectedMs: null,
|
|
1730
|
-
basis: 0
|
|
1731
|
-
};
|
|
1732
|
-
return {
|
|
1733
|
-
platform,
|
|
1734
|
-
...slot === "default" ? {} : { slot },
|
|
1735
|
-
...rest,
|
|
1736
|
-
outcome,
|
|
1737
|
-
expectedMs: estimate.expectedMs,
|
|
1738
|
-
basis: estimate.basis,
|
|
1739
|
-
...missReason ? { missReason } : {},
|
|
1740
|
-
...refusal ? { refusal } : {}
|
|
1741
|
-
};
|
|
1742
|
-
}
|
|
1743
|
-
function cacheLine(plan) {
|
|
1744
|
-
if (plan.refusal) return `the build would refuse with ${plan.refusal.code}`;
|
|
1745
|
-
if (plan.cacheHit === "local") return "local cache hit";
|
|
1746
|
-
if (plan.cacheHit === "remote") return `remote cache hit (${plan.provider})`;
|
|
1747
|
-
return `${plan.cacheSkipped ? "cache reads are off" : "cache miss"}: compiles${plan.prebuild === "generate" || plan.prebuild === "regenerate" ? `, ${plan.prebuild}s the native dir` : ""}`;
|
|
1748
|
-
}
|
|
1749
|
-
function printPlan(plan, json) {
|
|
1750
|
-
if (json) {
|
|
1751
|
-
console.log(JSON.stringify(plan));
|
|
1752
|
-
return;
|
|
1753
|
-
}
|
|
1754
|
-
const slot = plan.slot ? ` [${plan.slot}]` : "";
|
|
1755
|
-
console.log(phaseLine("plan", `${plan.platform}${slot} ${shortHash(plan.fingerprint)} -> ${cacheLine(plan)}`));
|
|
1756
|
-
if (plan.missReason) console.log(phaseLine("cache", `miss: ${plan.missReason.summary}`));
|
|
1757
|
-
if (plan.refusal) {
|
|
1758
|
-
console.log(phaseLine("error", plan.refusal.message));
|
|
1759
|
-
console.log(phaseLine("remedy", plan.refusal.remedy));
|
|
1760
|
-
return;
|
|
1761
|
-
}
|
|
1762
|
-
console.log(phaseLine("expect", plan.expectedMs === null ? `unknown: no ${plan.outcome} run of this project is recorded yet` : `~${formatDuration(plan.expectedMs)} (median of ${plural(plan.basis, `${plan.outcome} run`)})`));
|
|
1763
|
-
}
|
|
1764
|
-
function refusePlan({ code, message, remedy }, json, lines = []) {
|
|
1765
|
-
console.error(chalk.red(phaseLine("error", message)));
|
|
1766
|
-
for (const line of lines) console.error(chalk.dim(phaseLine("", line)));
|
|
1767
|
-
console.error(chalk.dim(phaseLine("remedy", remedy)));
|
|
1768
|
-
console.error(chalk.red(phaseLine("failed", code)));
|
|
1769
|
-
if (json) console.log(JSON.stringify({
|
|
1770
|
-
code,
|
|
1771
|
-
message,
|
|
1772
|
-
remedy
|
|
1773
|
-
}));
|
|
1774
|
-
process.exitCode = 1;
|
|
1775
|
-
}
|
|
1776
|
-
const PLAN_ONLY_REMEDY = "Drop the flag to plan the owned simulator or emulator build, or run the command without --plan.";
|
|
1777
|
-
function planFlagRefusal(flag) {
|
|
1778
|
-
return {
|
|
1779
|
-
code: "STIM_BAD_ARG",
|
|
1780
|
-
message: `${flag} does not apply to --plan, which predicts the next local build without choosing a device.`,
|
|
1781
|
-
remedy: PLAN_ONLY_REMEDY
|
|
1782
|
-
};
|
|
1783
|
-
}
|
|
1784
|
-
//#endregion
|
|
1785
|
-
export { AvdRecoveryError as _, refusePlan as a, devicePlacementLine as b, skippedMissReason as c, refreshUpdatesManifestFile as d, swapJsBundle as f, AvdBootError as g, ensureOwnedDevice as h, printPlan as i, UPDATES_MANIFEST_NAME as l, ensureBooted as m, planFlagRefusal as n, explainBuildMiss as o, didSetUpDevice as p, planPayload as r, fingerprintErrorMissReason as s, planCachedBuild as t, detectEntryFile as u, warmMetro as v, automaticDevicePlacement as y };
|
|
1743
|
+
export { devicePlacementLine as _, UPDATES_MANIFEST_NAME as a, swapJsBundle as c, ensureOwnedDevice as d, AvdBootError as f, automaticDevicePlacement as g, checkEasFallback as h, skippedMissReason as i, didSetUpDevice as l, warmMetro as m, fingerprintErrorMissReason as n, detectEntryFile as o, AvdRecoveryError as p, predictBuildMiss as r, refreshUpdatesManifestFile as s, explainBuildMiss as t, ensureBooted as u, probeHost as v };
|