stim 1.25.0 → 1.27.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 +1 -1
- package/dist/{acquire-artifact-zA4S7RHE.mjs → acquire-artifact-BKN2Yuhg.mjs} +2 -2
- package/dist/{act-BbHS3oV8.mjs → act-ROviTF_t.mjs} +415 -118
- package/dist/{activity-BpjwrQXU.mjs → activity-Cd-ysFes.mjs} +6 -7
- package/dist/{agent-device-usage-output-Bnkerfod.mjs → agent-device-usage-output-C5nCKWp9.mjs} +5 -5
- package/dist/{android-CNZgRC-4.mjs → android--HBgpvpW.mjs} +5 -5
- package/dist/{android-BGwuK3Mc.mjs → android-Cd6w7_qw.mjs} +134 -57
- package/dist/{android-saBeB4lr.mjs → android-Deb9X3_Y.mjs} +37 -15
- package/dist/{android-Cjcj8MCw.mjs → android-DriNoAVy.mjs} +99 -47
- package/dist/{android-cas-BVqh2Zep.mjs → android-cas-D5e6ecUg.mjs} +4 -4
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{android-project-CTYaETc0.d.mts → android-project-DUGMbq28.d.mts} +55 -1
- package/dist/api.d.mts +20 -7
- package/dist/api.mjs +42 -32
- package/dist/apk-signed-tail-BHQHx3Rm.mjs +142 -0
- package/dist/{artifact-Co8zixVx.mjs → artifact-0AGJYB9O.mjs} +28 -28
- package/dist/{artifact-DN8JNwqS.mjs → artifact-faemIZv5.mjs} +40 -30
- package/dist/{artifact-platform-CMRc0M_r.mjs → artifact-platform-BO2Uvk_A.mjs} +1 -1
- package/dist/{attempt-DW-mQqM7.mjs → attempt-ClyJlZPT.mjs} +4 -2
- package/dist/auto-placement-z-H5pJza.mjs +350 -0
- package/dist/{browser-web-CCgZsHmI.mjs → browser-web-slD8AvLp.mjs} +16 -17
- package/dist/{build-cache-CKCzxzxA.mjs → build-cache-gBJ-WKzA.mjs} +141 -37
- package/dist/{build-CAiw8Ezm.mjs → build-hS0QyFlQ.mjs} +38 -31
- package/dist/{build-plan-zCuHGlA8.mjs → build-plan-CBqYbzYM.mjs} +7 -6
- package/dist/{cache-manifest-BPXRONJz.mjs → cache-manifest-DEjqGGat.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{budget-HyShrIpL.mjs → ccache-BWTze1Ls.mjs} +634 -1514
- package/dist/{cdp-BG3FJCCx.mjs → cdp-C3svvXiE.mjs} +1 -1
- package/dist/{chrome-BvV8ssI3.mjs → chrome-DyDWurWG.mjs} +1 -1
- package/dist/{cli-C4w607Pz.mjs → cli-ftXDLto1.mjs} +24 -23
- package/dist/cli.mjs +1 -1
- package/dist/{client-BQsmyp_-.mjs → client-xsdxrhWA.mjs} +77 -116
- package/dist/collector-run.d.mts +10 -9
- package/dist/collector-run.mjs +42 -27
- package/dist/{command-output-BBvS1H6v.mjs → command-output-Dj-WT4BP.mjs} +1 -1
- package/dist/{config-BZhXY15H.mjs → config-Cn94Jc0g.mjs} +343 -18
- package/dist/{launch-DscF1QfM.mjs → dependencies-BGokZ-Ng.mjs} +330 -279
- package/dist/{dependency-state-BwNCYG5Q.mjs → dependency-state-C3OtgG94.mjs} +14 -7
- package/dist/{detached-entry-KmieOKgN.mjs → detached-entry-BPlSaCwC.mjs} +1 -1
- package/dist/{dev-client-CHoXXZeg.mjs → dev-client-BMca82xo.mjs} +2 -2
- package/dist/{device-F5-4z9ef.mjs → device-BJm0irrq.mjs} +16 -16
- package/dist/{device-capacity-ZYaRALv5.mjs → device-capacity-6LP7QsaA.mjs} +103 -25
- package/dist/device-host-worker.mjs +19 -21
- package/dist/{device-ios-DkHBrmvH.mjs → device-ios-534c14fz.mjs} +288 -28
- package/dist/{device-lease-run-ogEeJ62K.mjs → device-lease-run-DwsGfjUN.mjs} +5 -5
- package/dist/{device-pool-BIg8MU8l.mjs → device-pool-BnQqvs6o.mjs} +3 -3
- package/dist/{device-B9FqTBYW.mjs → device-tM41-TUq.mjs} +25 -24
- package/dist/{doctor-A_Nr_fDe.mjs → doctor-Dbx1ZpD2.mjs} +1 -1
- package/dist/{doctor-k3P3PizH.mjs → doctor-DyqE9n1J.mjs} +28 -16
- package/dist/{doctor-Bm8TVpGn.mjs → doctor-F-3VUUyN.mjs} +128 -35
- package/dist/{doctor-fingerprint-zlujA1Gs.mjs → doctor-fingerprint-o7ZI9YLn.mjs} +9 -3
- package/dist/doctor-fingerprint.mjs +1 -1
- package/dist/{doctor-watchman-BovI1y3-.mjs → doctor-watchman-CxDbyrrt.mjs} +5 -5
- package/dist/{eas-build-CyDKNTBP.mjs → eas-build-CjNSWmjo.mjs} +4 -4
- package/dist/eas-fallback-9fqb46kW.mjs +87 -0
- package/dist/{eas-session-ledger-BMCA1gdO.mjs → eas-session-ledger-DrP4OuuM.mjs} +6 -6
- package/dist/{error-diagnostics-B1Mj_-7h.mjs → error-diagnostics-snej9k4j.mjs} +51 -25
- package/dist/{exec-VFRpu1iA.mjs → exec-aULwtNly.mjs} +57 -6
- package/dist/{gc-eaz403W6.mjs → gc-BRwAY3qT.mjs} +2 -2
- package/dist/{gc-B9jcnmIk.mjs → gc-CGZ1Yg88.mjs} +218 -72
- package/dist/{guide-DR0K0xW9.mjs → guide-_rfEh_zM.mjs} +839 -222
- package/dist/{hosted-android-Bvb2-ZxD.mjs → hosted-android-BMKzUNnY.mjs} +4 -4
- package/dist/{hosted-client-rsRqysJc.mjs → hosted-client-D7Pk_Oo1.mjs} +13 -9
- package/dist/{hosted-logs-CWKGYWNX.mjs → hosted-logs-B1gqQuva.mjs} +18 -12
- package/dist/hosted-logs-sync-Dg3qrZmV.mjs +195 -0
- package/dist/{hosted-macos-d0pv9Tth.mjs → hosted-macos-B9w4H8hc.mjs} +6 -6
- package/dist/{hosted-native-BxTizGU2.mjs → hosted-native-CdgaiuyP.mjs} +17 -17
- package/dist/{idle-shutdown-BIyfl0Zj.mjs → idle-shutdown-Cbvo5KEh.mjs} +21 -9
- package/dist/{ios-BRVM8b0P.mjs → ios-B5HlVMhQ.mjs} +138 -55
- package/dist/{ios-Dvt97HgQ.mjs → ios-Bk4mWbtS.mjs} +8 -8
- package/dist/{ios-ENC4sRPA.mjs → ios-CsRVik64.mjs} +7 -1
- package/dist/{ios-BQzvJlzw.mjs → ios-E26qSpkb.mjs} +94 -11
- package/dist/{ios-device-CKSvk0bu.mjs → ios-device-C_QkIf1Z.mjs} +3 -3
- package/dist/{ios-device-B6HK951C.mjs → ios-device-CiBA-er9.mjs} +1 -1
- package/dist/{ios-project-DCUDo06I.mjs → ios-project-D8Jcy_br.mjs} +22 -9
- package/dist/{ios-signing-4c_qXvQm.mjs → ios-signing-BJzvDPfU.mjs} +2 -2
- package/dist/{ios-state-CT9nV5SP.mjs → ios-state-BZ03NFgF.mjs} +1 -1
- package/dist/{js-swap-Z9HbC4cj.mjs → js-swap-Dg2a945i.mjs} +8 -7
- package/dist/{launch-D0lPvFFu.mjs → launch-CRyBeNsA.mjs} +53 -44
- package/dist/lightened-BCsdAGj_.mjs +171 -0
- package/dist/{logs-BsIRre8x.mjs → logs-CC_-ZzEE.mjs} +10 -174
- package/dist/{logs-Crs9y34Z.mjs → logs-aJQb-RDg.mjs} +112 -38
- package/dist/{macos-CcUlJPMu.mjs → macos-BGmTpnv9.mjs} +1 -1
- package/dist/{macos-D477nfzH.mjs → macos-DlCBhMw5.mjs} +73 -39
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +30 -13
- package/dist/{metro-1pJgCX4U.mjs → metro-CvyD-xwe.mjs} +4 -4
- package/dist/{metro-gateway-Bp9gJQAN.mjs → metro-gateway-BnHdqMO_.mjs} +3 -4
- package/dist/{named-ports-BVbn8SvC.mjs → named-ports-BCyMWA6b.mjs} +3 -3
- package/dist/{native-android-BvMizJn1.mjs → native-android-DlpxCyOP.mjs} +17 -18
- package/dist/{native-gradle-artifact-inputs-BJscK4vN.mjs → native-gradle-artifact-inputs-C13qT7R_.mjs} +5 -5
- package/dist/{native-runtime-B9w_Qyz3.mjs → native-runtime-DqaIBO5w.mjs} +9 -9
- package/dist/{native-source-D-4Dh4JU.mjs → native-source-D1AzWiuP.mjs} +1 -1
- package/dist/{native-xcode-inputs-Cv4l-obn.mjs → native-xcode-inputs-B1W8SrxB.mjs} +3 -3
- package/dist/{native-xcode-ios-DGrg90hE.mjs → native-xcode-ios-QPP0Rm68.mjs} +17 -18
- package/dist/{ndjson-CgE_o3Dl.mjs → ndjson-Dy2W4vRa.mjs} +2 -2
- package/dist/offload-worker.d.mts +3 -1
- package/dist/offload-worker.mjs +34 -25
- package/dist/{operation-exec-CUZifp6Z.mjs → operation-exec-Dp4FuIGR.mjs} +1 -1
- package/dist/{ownership-jxxz-19m.mjs → ownership-Bx-0cku-.mjs} +3 -3
- package/dist/{page-CzEA_-5_.mjs → page-CQJlcj3x.mjs} +2 -2
- package/dist/{phone-reverses-CYb7RRAx.mjs → phone-reverses-C9yAaKEv.mjs} +18 -4
- package/dist/{placement-log-DjOXJRIH.mjs → placement-log-BXUbiZM6.mjs} +3 -3
- package/dist/{plan-placement-BqKgKHCi.mjs → plan-placement-UxnQjv5Z.mjs} +36 -10
- package/dist/{ports-DtS1Amb0.mjs → ports-uUrghqWN.mjs} +3 -3
- package/dist/prebuild-BDpToDgR.mjs +1246 -0
- package/dist/{project-BiC68mIp.mjs → project-DYj-HVx6.mjs} +17 -18
- package/dist/{pull-request-CbNlkFok.mjs → pull-request-BzLmzAIQ.mjs} +2 -2
- package/dist/pull-requests.mjs +1 -1
- package/dist/{react-native-android-DRYqoJc4.mjs → react-native-android-DDBccgJw.mjs} +56 -36
- package/dist/{react-native-build-CwZB-agu.mjs → react-native-build-DaK2IFyP.mjs} +9 -9
- package/dist/{react-native-doctor-BCrytK7h.mjs → react-native-doctor-B-Mw6DcR.mjs} +50 -9
- package/dist/{react-native-ios-Cr1buNFo.mjs → react-native-ios-DjYwUF9U.mjs} +45 -25
- package/dist/{recordings-BaoQ0t-J.mjs → recordings-C20iUZfp.mjs} +1 -1
- package/dist/{registration-CN6nlhcD.mjs → registration-BwCe64PH.mjs} +1 -1
- package/dist/{reload-Beftw2X3.mjs → reload-DJBeF_rC.mjs} +1 -1
- package/dist/{reload-FbSgMF8x.mjs → reload-fUdkH2_p.mjs} +16 -16
- package/dist/{remote-BuZj6AyU.mjs → remote-y6n99WMW.mjs} +22 -9
- package/dist/{result-CR2vk2cj.mjs → result-CTqBw2Te.mjs} +32 -21
- package/dist/{run-BtzE09Dl.mjs → run-DaCeNKRm.mjs} +3 -3
- package/dist/{selection-D5cxEl3t.mjs → selection-Bs8phwhN.mjs} +183 -62
- package/dist/{server-bare-CH9X0RLn.mjs → server-bare-BOh-iZEj.mjs} +2 -2
- package/dist/{server-command-CaBbDNU2.mjs → server-command-8CuA51Cv.mjs} +6 -6
- package/dist/{server-expo-Ck8EIidM.mjs → server-expo-ABQs2XFA.mjs} +4 -4
- package/dist/server-expo-Ba_Y21vB.mjs +2 -0
- package/dist/{settings-B5tCoq9N.mjs → settings-BDVI8Ivc.mjs} +331 -62
- package/dist/{settings-DzH9mGQZ.mjs → settings-CMHhQNwI.mjs} +24 -3
- package/dist/settings-payload-cm60Zhib.mjs +257 -0
- package/dist/settings-write-BdNRLlBn.mjs +185 -0
- package/dist/settings.schema.json +84 -39
- package/dist/{simslim-BjxszUAb.mjs → simslim-DCQwzoPy.mjs} +4 -3
- package/dist/{slot-launch-QeuJMlnJ.mjs → slot-launch-0l7RqSpr.mjs} +6 -6
- package/dist/{stage-D8xlRU2D.mjs → stage-F4cAfJGi.mjs} +2 -2
- package/dist/{start-C1JLjkNw.mjs → start-DcqnF9p8.mjs} +1 -1
- package/dist/{start-YMpNwLhh.mjs → start-DrPwER_2.mjs} +27 -23
- package/dist/{state-DMRNP7-4.mjs → state-BX1y5syV.mjs} +4 -5
- package/dist/{state-DPaM3u5K.mjs → state-CZxLyetD.mjs} +2 -3
- package/dist/{stats-CP7STzZw.mjs → stats-GxuCbles.mjs} +5 -5
- package/dist/{stats-report-n2U5plhk.mjs → stats-report-B86Cv7Uc.mjs} +1 -1
- package/dist/{status-Fect2w9R.mjs → status-7ULDEJ1e.mjs} +1 -1
- package/dist/{status-CRLiJ-O_.mjs → status-BfnK9pUd.mjs} +25 -26
- package/dist/{status-cNw6i0_t.mjs → status-Bj7ZYvvc.mjs} +1 -1
- package/dist/{status-watch-Bc2J4TZn.mjs → status-watch-BfabQn03.mjs} +5 -5
- package/dist/status-worker.mjs +1 -1
- package/dist/{stim-desktop-DS0mzR8U.mjs → stim-desktop-CbWo21kb.mjs} +2 -2
- package/dist/{stop-COP6PQqw.mjs → stop-CH79S3IZ.mjs} +5 -6
- package/dist/{stop-Db9Kh-UA.mjs → stop-D-EAr25B.mjs} +25 -22
- package/dist/{stop-Br7LKxBE.mjs → stop-x1Yu3He4.mjs} +2 -2
- package/dist/supervisor-run.d.mts +1 -0
- package/dist/supervisor-run.mjs +17 -18
- package/dist/{support-qKcbgmI5.mjs → support-Be0UeVZU.mjs} +10 -10
- package/dist/{support-Cxj9CmII.mjs → support-CNg_YsOk.mjs} +6 -6
- package/dist/{swiftpm-artifact-inputs-iY9fsmOc.mjs → swiftpm-artifact-inputs-uPqYvGBv.mjs} +4 -4
- package/dist/{swiftpm-macos-Bp_sn9P4.mjs → swiftpm-macos-Ch4YjY_A.mjs} +11 -12
- package/dist/toolchain-CbCG6C5Z.mjs +2413 -0
- package/dist/toolchain-JYAOquPg.mjs +2 -0
- package/dist/{trigger-CBMe2YLH.mjs → trigger-DMou-X7j.mjs} +3 -3
- package/dist/trigger-qp2ji5wE.mjs +2 -0
- package/dist/{warm-progress-BV3ZPmcY.mjs → warm-progress-C0RsbngN.mjs} +731 -728
- package/dist/{web-B4Yjyt1G.mjs → web-Cq_AQ4DK.mjs} +9 -10
- package/dist/web-Je6abcpz.mjs +2 -0
- package/dist/web-run.mjs +9 -9
- package/dist/windows-report.mjs +1 -1
- package/dist/{workspace-state-CPSp3mav.mjs → workspace-state-BjqdjnJR.mjs} +46 -8
- package/dist/{workspaces-C9w4aeXF.mjs → workspaces-DFbj07jp.mjs} +1801 -76
- package/dist/{worktree-CclFIe1Z.mjs → worktree-COAJ3-OD.mjs} +934 -511
- package/dist/{worktree-Ct9Gk3KL.mjs → worktree-JGUd_53L.mjs} +1 -1
- package/package.json +8 -8
- package/dist/ccache-h1FKhZeg.mjs +0 -143
- package/dist/created-devices-D2Aca-xu.mjs +0 -52
- package/dist/eas-fallback-gaZi-dJL.mjs +0 -381
- package/dist/hosted-ios-RtVcJH3u.mjs +0 -15
- package/dist/native-run-D5OJsGwA.mjs +0 -276
- package/dist/paths-DQtTgsBf.mjs +0 -42
- package/dist/prebuild-JUaqOLpc.mjs +0 -501
- package/dist/server-expo-C16Zf2k7.mjs +0 -2
- package/dist/settings-write-n0zwfohx.mjs +0 -360
- package/dist/toolchain-DB1aeqxO.mjs +0 -2
- package/dist/toolchain-VzLJzZ7O.mjs +0 -908
- package/dist/trigger-BLsHgAGR.mjs +0 -2
- package/dist/web-DS4UDWvf.mjs +0 -2
- package/dist/xcode-CiIIDnuD.mjs +0 -910
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { _ as loadConfig$1, p as getProject } from "./config-Cn94Jc0g.mjs";
|
|
2
|
+
import { m as peekBudget } from "./ccache-BWTze1Ls.mjs";
|
|
3
|
+
import { z as readHostMemoryPressureAsync } from "./ios-E26qSpkb.mjs";
|
|
4
|
+
import { _ as hostingMachines, o as namedBuildMachine, u as resolveBuildMachine } from "./selection-Bs8phwhN.mjs";
|
|
5
|
+
import { c as call, l as connectHost, p as requireHostedAppMode } from "./hosted-client-D7Pk_Oo1.mjs";
|
|
6
|
+
import { c as writeHostedNativeAsync, r as readHostedNative } from "./ios-state-BZ03NFgF.mjs";
|
|
7
|
+
import { i as prepareHostedNative } from "./hosted-native-CdgaiuyP.mjs";
|
|
8
|
+
import { l as peekDeviceSlots, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-6LP7QsaA.mjs";
|
|
9
|
+
import { ambientEnv } from "@stim-cli/core";
|
|
10
|
+
import { automaticMachineEnabled, isJsonObject, machineCapacity, mayRunHere, parseHostedChoice, parseHostedNativeOffer, prefersRemote } from "@stim-cli/core/state";
|
|
11
|
+
import { setTimeout } from "node:timers/promises";
|
|
12
|
+
//#region src/device-host/placement.ts
|
|
13
|
+
function local$1(code, reason, skipped = [], atCapacity = false) {
|
|
14
|
+
return {
|
|
15
|
+
kind: "local",
|
|
16
|
+
code,
|
|
17
|
+
reason,
|
|
18
|
+
skipped,
|
|
19
|
+
...atCapacity ? { atCapacity: true } : {}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function decideDevicePlacement(inputs) {
|
|
23
|
+
if ("sticky" in inputs) {
|
|
24
|
+
if ("machine" in inputs.sticky) {
|
|
25
|
+
const reason = `recorded session on ${inputs.sticky.machine}`;
|
|
26
|
+
return {
|
|
27
|
+
kind: "host",
|
|
28
|
+
code: "sticky",
|
|
29
|
+
reason,
|
|
30
|
+
machines: [{
|
|
31
|
+
machine: inputs.sticky.machine,
|
|
32
|
+
reason
|
|
33
|
+
}],
|
|
34
|
+
skipped: []
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
kind: "local",
|
|
39
|
+
code: "sticky",
|
|
40
|
+
reason: "this workspace's device runs here",
|
|
41
|
+
skipped: []
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const { platform, placement = "auto", here, offers, buildMachine, noWait, eas } = inputs;
|
|
45
|
+
const remoteFirst = prefersRemote(placement);
|
|
46
|
+
const { count, max, queued } = here.devices;
|
|
47
|
+
const room = max === 0 || count !== null && count < max;
|
|
48
|
+
const localEnabled = here.localEnabled !== false && mayRunHere(placement);
|
|
49
|
+
const cannotTake = !localEnabled || !room || queued > 0;
|
|
50
|
+
const atCapacity = count !== null && (!room || queued > 0);
|
|
51
|
+
const usage = max > 0 ? `${count} of ${max} devices in use` : `${count} devices in use, no device cap`;
|
|
52
|
+
const localReason = !mayRunHere(placement) ? "remote-only never runs here" : !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}`);
|
|
53
|
+
let hostsFull = false;
|
|
54
|
+
const nowhere = (code, reason, skipped = [], waiting = "") => {
|
|
55
|
+
if (!mayRunHere(placement)) return {
|
|
56
|
+
kind: "refused",
|
|
57
|
+
code: "pool-unavailable",
|
|
58
|
+
reason,
|
|
59
|
+
skipped,
|
|
60
|
+
...hostsFull ? { hostsFull: true } : {}
|
|
61
|
+
};
|
|
62
|
+
if (!localEnabled && !atCapacity) return {
|
|
63
|
+
kind: "refused",
|
|
64
|
+
code: "pool-unavailable",
|
|
65
|
+
reason,
|
|
66
|
+
skipped
|
|
67
|
+
};
|
|
68
|
+
if (!cannotTake || count === null) return local$1(code, reason + waiting, skipped);
|
|
69
|
+
if (eas?.usable) return {
|
|
70
|
+
kind: "eas",
|
|
71
|
+
code: "eas-fallback",
|
|
72
|
+
reason: `${reason}; EAS Simulator (remote.easFallback)`,
|
|
73
|
+
skipped
|
|
74
|
+
};
|
|
75
|
+
const why = eas ? [...skipped, {
|
|
76
|
+
machine: "eas",
|
|
77
|
+
code: eas.code,
|
|
78
|
+
reason: eas.reason
|
|
79
|
+
}] : skipped;
|
|
80
|
+
return localEnabled ? local$1(code, reason + waiting, why, true) : {
|
|
81
|
+
kind: "refused",
|
|
82
|
+
code: "pool-unavailable",
|
|
83
|
+
reason,
|
|
84
|
+
skipped: why,
|
|
85
|
+
atCapacity: true
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
if (!offers.length) return nowhere("no-remote-mac", "no remote machines configured; " + localReason);
|
|
89
|
+
if (localEnabled && count === null && !remoteFirst) return local$1("device-count-unknown", localReason);
|
|
90
|
+
if (!remoteFirst && !cannotTake && here.memoryPressure === "normal" && !here.budgetRefusal && here.loadPerCore < here.maxLoadPerCore) return local$1("this-mac-free", localReason);
|
|
91
|
+
const ceiling = (offer) => offer.resources.maxLoadPerCore ?? here.maxLoadPerCore;
|
|
92
|
+
const skipped = [];
|
|
93
|
+
const admitted = [];
|
|
94
|
+
offers.forEach((probe, index) => {
|
|
95
|
+
let reason = null;
|
|
96
|
+
let code = "unreachable";
|
|
97
|
+
if ("failure" in probe) reason = probe.failure;
|
|
98
|
+
else {
|
|
99
|
+
const { offer } = probe;
|
|
100
|
+
if (offer.declined !== null) [code, reason] = ["declined", `declined: ${offer.declined}`];
|
|
101
|
+
else if (offer.platform !== platform || !offer.choice) [code, reason] = ["no-matching-device", `no matching ${platform} device choice`];
|
|
102
|
+
else if (offer.resources.memoryPressure !== "normal") [code, reason] = ["memory", "host memory pressure unknown or elevated"];
|
|
103
|
+
else if (offer.capacity.available === 0) [code, reason] = ["no-capacity", "no hosted device capacity available"];
|
|
104
|
+
else if (offer.resources.loadPerCore !== null && offer.resources.loadPerCore >= ceiling(offer)) [code, reason] = ["load", `saturated: load ${offer.resources.loadPerCore.toFixed(1)}/core there, at or above ${ceiling(offer)}/core`];
|
|
105
|
+
else if (placement === "auto" && !cannotTake && offer.resources.loadPerCore === null) [code, reason] = ["load", "host load unknown while this machine has room"];
|
|
106
|
+
else admitted.push({
|
|
107
|
+
machine: probe.machine,
|
|
108
|
+
offer,
|
|
109
|
+
index
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (reason) skipped.push({
|
|
113
|
+
machine: probe.machine,
|
|
114
|
+
code,
|
|
115
|
+
reason
|
|
116
|
+
});
|
|
117
|
+
if (reason && ("offer" in probe ? [
|
|
118
|
+
"no-capacity",
|
|
119
|
+
"load",
|
|
120
|
+
"memory"
|
|
121
|
+
].includes(code) || code === "declined" && (probe.offer.capacity.available === 0 || probe.offer.resources.memoryPressure !== "normal") : false)) hostsFull = true;
|
|
122
|
+
});
|
|
123
|
+
admitted.sort((a, b) => Number(b.machine === buildMachine) - Number(a.machine === buildMachine) || a.index - b.index);
|
|
124
|
+
if (!admitted.length) return nowhere("no-host-admits", `${localReason}; no host admits`, skipped, localEnabled && cannotTake && !noWait ? "; waiting locally if needed" : "");
|
|
125
|
+
const machines = admitted.map(({ machine, offer }) => ({
|
|
126
|
+
machine,
|
|
127
|
+
reason: `${remoteFirst && !cannotTake ? `${placement} tries remote machines first` : localReason}; ${machine}${machine === buildMachine ? " is the explicit remote machine," : ""} load ${offer.resources.loadPerCore === null ? "unknown" : offer.resources.loadPerCore.toFixed(1) + "/core"}`
|
|
128
|
+
}));
|
|
129
|
+
return {
|
|
130
|
+
kind: "host",
|
|
131
|
+
code: "placed",
|
|
132
|
+
machines,
|
|
133
|
+
reason: machines[0].reason,
|
|
134
|
+
skipped
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/device-host/auto-placement.ts
|
|
139
|
+
const HOST_WAIT_POLL_MS = 5e3;
|
|
140
|
+
function refusalText(decision, waitedMs) {
|
|
141
|
+
return [
|
|
142
|
+
decision.reason,
|
|
143
|
+
...decision.skipped.map((each) => `${each.machine}: ${each.reason}`),
|
|
144
|
+
...waitedMs === null ? [] : [`waited ${Math.round(waitedMs / 1e3)}s for a remote machine with room`]
|
|
145
|
+
].join("; ");
|
|
146
|
+
}
|
|
147
|
+
async function probeHost(machine, platform, selectors, appMode, signal) {
|
|
148
|
+
let host;
|
|
149
|
+
const deadline = Date.now() + 3e3;
|
|
150
|
+
const cancel = () => host?.connection.close();
|
|
151
|
+
try {
|
|
152
|
+
host = await connectHost(machine, 3e3, true, signal);
|
|
153
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
154
|
+
signal?.throwIfAborted();
|
|
155
|
+
if (platform !== "macos") requireHostedAppMode(host, platform, appMode);
|
|
156
|
+
const offer = await call(host, "device-host.offer", {
|
|
157
|
+
platform,
|
|
158
|
+
...selectors
|
|
159
|
+
}, Math.max(1, deadline - Date.now()));
|
|
160
|
+
signal?.throwIfAborted();
|
|
161
|
+
const resources = isJsonObject(offer.resources) ? offer.resources : {};
|
|
162
|
+
const parsed = parseHostedNativeOffer({
|
|
163
|
+
...offer,
|
|
164
|
+
resources: {
|
|
165
|
+
...resources,
|
|
166
|
+
loadPerCore: resources.loadPerCore ?? 0
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
let choice = platform === "ios" ? offer.platform === "ios" ? parseHostedChoice(offer.choice) : null : parsed?.platform === platform ? parsed.choice : null;
|
|
170
|
+
if (choice && platform !== "macos" && ("runtime" in choice ? selectors.deviceType && selectors.deviceType !== choice.deviceType || selectors.runtime && selectors.runtime.replace(/^iOS /, "") !== choice.runtime.replace(/^iOS /, "") : "systemImage" in choice && (selectors.systemImage && selectors.systemImage !== choice.systemImage || selectors.deviceProfile && selectors.deviceProfile !== choice.deviceProfile))) choice = null;
|
|
171
|
+
if (!isJsonObject(offer.capacity) || offer.declined !== null && typeof offer.declined !== "string") throw new Error("unreadable device offer");
|
|
172
|
+
return {
|
|
173
|
+
probe: {
|
|
174
|
+
machine,
|
|
175
|
+
offer: {
|
|
176
|
+
platform,
|
|
177
|
+
choice,
|
|
178
|
+
declined: offer.declined,
|
|
179
|
+
capacity: { available: typeof offer.capacity.available === "number" ? offer.capacity.available : null },
|
|
180
|
+
resources: {
|
|
181
|
+
...typeof resources.maxLoadPerCore === "number" && Number.isFinite(resources.maxLoadPerCore) && resources.maxLoadPerCore > 0 ? { maxLoadPerCore: resources.maxLoadPerCore } : {},
|
|
182
|
+
loadPerCore: typeof resources.loadPerCore === "number" && Number.isFinite(resources.loadPerCore) && resources.loadPerCore >= 0 ? resources.loadPerCore : null,
|
|
183
|
+
memoryFreeBytes: typeof resources.memoryFreeBytes === "number" ? resources.memoryFreeBytes : 0,
|
|
184
|
+
memoryPressure: typeof resources.memoryPressure === "string" ? resources.memoryPressure : null
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
...choice && ("runtime" in choice || "systemImage" in choice) ? { target: {
|
|
189
|
+
host,
|
|
190
|
+
choice,
|
|
191
|
+
session: null
|
|
192
|
+
} } : {}
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
signal?.throwIfAborted();
|
|
196
|
+
return { probe: {
|
|
197
|
+
machine,
|
|
198
|
+
failure: error instanceof Error ? error.message : String(error)
|
|
199
|
+
} };
|
|
200
|
+
} finally {
|
|
201
|
+
signal?.removeEventListener("abort", cancel);
|
|
202
|
+
host?.connection.close();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function hosted(target, machine, code, reason, skipped = []) {
|
|
206
|
+
if (target) target.selection = {
|
|
207
|
+
selected: "auto",
|
|
208
|
+
reason
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
target,
|
|
212
|
+
placement: {
|
|
213
|
+
decision: "hosted",
|
|
214
|
+
machine,
|
|
215
|
+
reason
|
|
216
|
+
},
|
|
217
|
+
code,
|
|
218
|
+
skipped
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function local(code, reason, skipped = []) {
|
|
222
|
+
return {
|
|
223
|
+
target: null,
|
|
224
|
+
placement: {
|
|
225
|
+
decision: "local",
|
|
226
|
+
reason
|
|
227
|
+
},
|
|
228
|
+
code,
|
|
229
|
+
skipped
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function viaEas(code, reason, skipped) {
|
|
233
|
+
return {
|
|
234
|
+
target: null,
|
|
235
|
+
placement: {
|
|
236
|
+
decision: "eas",
|
|
237
|
+
machine: "eas",
|
|
238
|
+
reason
|
|
239
|
+
},
|
|
240
|
+
code,
|
|
241
|
+
skipped
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
async function automaticDevicePlacement({ root, slot, platform, placement = "auto", selectors, appMode, buildMachine, noWait, waitMs = DEFAULT_DEVICE_SLOT_WAIT_MS, onWait = () => {}, eas, signal, localSims }, { machines = () => hostingMachines(void 0, signal), read = readHostedNative, write = writeHostedNativeAsync, resume = prepareHostedNative, peek = () => peekDeviceSlots({
|
|
245
|
+
platform: platform === "macos" ? "ios" : platform,
|
|
246
|
+
project: getProject(root),
|
|
247
|
+
slot,
|
|
248
|
+
...localSims ? { sources: { sims: localSims } } : {}
|
|
249
|
+
}), capacity = machineCapacity, memory = () => readHostMemoryPressureAsync(void 0, void 0, signal), probe = probeHost, budget = (projectRoot) => peekBudget(projectRoot, {}, ambientEnv(), signal), now = Date.now, sleep = (ms) => setTimeout(ms, void 0, { signal }) } = {}) {
|
|
250
|
+
const recorded = platform === "macos" ? void 0 : read(root, platform, slot)[slot];
|
|
251
|
+
if (recorded && platform !== "macos") {
|
|
252
|
+
const target = await resume(recorded.machine, selectors, recorded, platform, true, appMode);
|
|
253
|
+
if (target) return {
|
|
254
|
+
target,
|
|
255
|
+
placement: {
|
|
256
|
+
decision: "hosted",
|
|
257
|
+
machine: recorded.machine,
|
|
258
|
+
reason: recorded.reason ?? decideDevicePlacement({ sticky: { machine: recorded.machine } }).reason
|
|
259
|
+
},
|
|
260
|
+
code: "sticky",
|
|
261
|
+
skipped: [],
|
|
262
|
+
sticky: true
|
|
263
|
+
};
|
|
264
|
+
await write(root, slot, null, platform);
|
|
265
|
+
}
|
|
266
|
+
const devices = platform === "macos" ? {
|
|
267
|
+
count: 0,
|
|
268
|
+
max: 0,
|
|
269
|
+
queued: 0,
|
|
270
|
+
localLive: false
|
|
271
|
+
} : peek();
|
|
272
|
+
if (devices.localLive && placement === "remote-only") throw Object.assign(/* @__PURE__ */ new Error(`This workspace's ${platform} device for slot ${slot} runs on this machine, and remote-only never runs here.`), {
|
|
273
|
+
code: "STIM_HOSTING_REFUSED",
|
|
274
|
+
remedy: "Run stim stop, then retry."
|
|
275
|
+
});
|
|
276
|
+
if (devices.localLive) return {
|
|
277
|
+
...local("sticky", decideDevicePlacement({ sticky: { local: true } }).reason),
|
|
278
|
+
sticky: true
|
|
279
|
+
};
|
|
280
|
+
const configured = await machines();
|
|
281
|
+
signal?.throwIfAborted();
|
|
282
|
+
if (configured === null) throw Object.assign(/* @__PURE__ */ new Error("remote.machines is invalid. Run stim guide settings and correct it."), { code: "STIM_HOSTING_REFUSED" });
|
|
283
|
+
const config = loadConfig$1();
|
|
284
|
+
const entries = configured.filter((machine) => automaticMachineEnabled("device", machine, config));
|
|
285
|
+
const preference = resolveBuildMachine(buildMachine, ambientEnv().STIM_REMOTE_BUILD, config?.remote?.build);
|
|
286
|
+
buildMachine = namedBuildMachine(preference) ? preference : void 0;
|
|
287
|
+
const load = capacity();
|
|
288
|
+
const here = {
|
|
289
|
+
localEnabled: automaticMachineEnabled("device", "local", config),
|
|
290
|
+
loadPerCore: load.loadPerCore,
|
|
291
|
+
maxLoadPerCore: load.maxLoadPerCore,
|
|
292
|
+
memoryPressure: await memory(),
|
|
293
|
+
devices,
|
|
294
|
+
budgetRefusal: await budget(root)
|
|
295
|
+
};
|
|
296
|
+
signal?.throwIfAborted();
|
|
297
|
+
const inputs = (offers) => ({
|
|
298
|
+
platform,
|
|
299
|
+
placement,
|
|
300
|
+
here,
|
|
301
|
+
offers,
|
|
302
|
+
buildMachine,
|
|
303
|
+
noWait
|
|
304
|
+
});
|
|
305
|
+
const notProbed = entries.map((machine) => ({
|
|
306
|
+
machine,
|
|
307
|
+
failure: "not probed"
|
|
308
|
+
}));
|
|
309
|
+
const waitStarted = now();
|
|
310
|
+
let announced = false;
|
|
311
|
+
let probes = [];
|
|
312
|
+
let offers = notProbed;
|
|
313
|
+
let decision;
|
|
314
|
+
for (;;) {
|
|
315
|
+
const early = decideDevicePlacement(inputs(notProbed));
|
|
316
|
+
probes = early.kind === "local" && early.skipped.length === 0 ? [] : await Promise.all(entries.map((machine) => probe(machine, platform, selectors, appMode, signal)));
|
|
317
|
+
offers = probes.length ? probes.map((each) => each.probe) : notProbed;
|
|
318
|
+
decision = decideDevicePlacement(inputs(offers));
|
|
319
|
+
if (decision.kind !== "refused" || !decision.hostsFull) break;
|
|
320
|
+
const waited = now() - waitStarted;
|
|
321
|
+
const immediate = noWait || waitMs <= 0;
|
|
322
|
+
if (immediate || waited >= waitMs) throw Object.assign(new Error(refusalText(decision, immediate ? null : waited)), {
|
|
323
|
+
code: "STIM_AT_CAPACITY",
|
|
324
|
+
remedy: `Wait for a remote machine in remote.machines to have room, ${platform === "macos" ? "retry later" : "retry with a longer --wait <seconds>"}, or select a placement that may run here.`
|
|
325
|
+
});
|
|
326
|
+
if (!announced) {
|
|
327
|
+
announced = true;
|
|
328
|
+
onWait(`remote-only waits up to ${Math.round(waitMs / 1e3)}s for a remote machine with room (${decision.skipped.map((each) => `${each.machine}: ${each.reason}`).join("; ")})`);
|
|
329
|
+
}
|
|
330
|
+
await sleep(Math.min(HOST_WAIT_POLL_MS, waitMs - waited));
|
|
331
|
+
signal?.throwIfAborted();
|
|
332
|
+
}
|
|
333
|
+
if ((decision.kind === "local" || decision.kind === "refused") && decision.atCapacity && eas && placement !== "remote-only") decision = decideDevicePlacement({
|
|
334
|
+
...inputs(offers),
|
|
335
|
+
eas: await eas()
|
|
336
|
+
});
|
|
337
|
+
if (decision.kind === "refused") throw Object.assign(new Error(refusalText(decision, null)), {
|
|
338
|
+
code: "STIM_HOSTING_REFUSED",
|
|
339
|
+
remedy: placement === "remote-only" ? entries.length === 0 ? "Add an approved Mac to remote.machines (stim guide settings), or select a placement that may run here." : "Wait for a remote machine in remote.machines to have room, check stim doctor for the ones that are unreachable or unapproved, or select a placement that may run here." : "Enable an available member in remote.devicePoolDisabled or select a machine explicitly."
|
|
340
|
+
});
|
|
341
|
+
if (decision.kind === "eas") return viaEas(decision.code, decision.reason, decision.skipped);
|
|
342
|
+
if (decision.kind === "local") return local(decision.code, decision.reason, decision.skipped);
|
|
343
|
+
const machine = decision.machines[0].machine;
|
|
344
|
+
return hosted(probes.find((each) => each.probe.machine === machine)?.target ?? null, machine, decision.code, decision.reason, decision.skipped);
|
|
345
|
+
}
|
|
346
|
+
function devicePlacementLine(placement, skipped) {
|
|
347
|
+
return `${placement.machine ?? "local"}, ${placement.reason}${placement.decision !== "hosted" && skipped.length ? "; " + skipped.map((each) => `${each.machine}: ${each.reason}`).join("; ") : ""}`;
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
350
|
+
export { devicePlacementLine as n, probeHost as r, automaticDevicePlacement as t };
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { D as ownership_claim_exports, S as process_identity_exports, c as throwIfCancelled, l as WorkspaceProcessCleanupError, s as cancelledError, t as getExecutor, u as withWorkspaceProcessLock } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import { p as getProject } from "./config-
|
|
4
|
-
import { l as phaseLine } from "./command-output-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { f as webLogFile, m as webSupervisorLogFile, o as readWebRecord, s as updateWebRecord } from "./state-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { o as resolveWorkspaceMetroPort } from "./start-YMpNwLhh.mjs";
|
|
1
|
+
import { D as ownership_claim_exports, S as process_identity_exports, c as throwIfCancelled, l as WorkspaceProcessCleanupError, s as cancelledError, t as getExecutor, u as withWorkspaceProcessLock } from "./exec-aULwtNly.mjs";
|
|
2
|
+
import { E as workspaceDir, k as workspaceLogsDir$1, l as withWorkspaceStateLockAsync, r as readWorkspaceState$1 } from "./workspace-state-BjqdjnJR.mjs";
|
|
3
|
+
import { p as getProject } from "./config-Cn94Jc0g.mjs";
|
|
4
|
+
import { l as phaseLine } from "./command-output-Dj-WT4BP.mjs";
|
|
5
|
+
import { N as metroPortSetting, a as SETTING_SHAPE_REMEDY, ct as webSettings } from "./settings-BDVI8Ivc.mjs";
|
|
6
|
+
import { b as isPackageResolvable, v as detectIsExpo } from "./project-DYj-HVx6.mjs";
|
|
7
|
+
import { d as resolveProjectMetro } from "./metro-CvyD-xwe.mjs";
|
|
8
|
+
import { c as readNdjsonGenerations$1 } from "./ndjson-Dy2W4vRa.mjs";
|
|
9
|
+
import { Wt as readMetroRecords } from "./ccache-BWTze1Ls.mjs";
|
|
10
|
+
import { f as webLogFile, m as webSupervisorLogFile, o as readWebRecord, s as updateWebRecord } from "./state-BX1y5syV.mjs";
|
|
11
|
+
import { b as resolveSupervisorTarget, lt as teardownBrowserHeld } from "./workspaces-DFbj07jp.mjs";
|
|
12
|
+
import { i as reserveBrowserPort, n as getNamedPort } from "./named-ports-BCyMWA6b.mjs";
|
|
13
|
+
import { n as sendToOwnedPage, t as liveWebRecord } from "./page-CQJlcj3x.mjs";
|
|
14
|
+
import { o as resolveWorkspaceMetroPort } from "./start-DrPwER_2.mjs";
|
|
16
15
|
import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
|
|
17
|
-
import { n as windowsLauncherArgs } from "./detached-entry-
|
|
18
|
-
import { a as findChrome, t as CHROME_INSTALL_REMEDY } from "./chrome-
|
|
16
|
+
import { n as windowsLauncherArgs } from "./detached-entry-BPlSaCwC.mjs";
|
|
17
|
+
import { a as findChrome, t as CHROME_INSTALL_REMEDY } from "./chrome-DyDWurWG.mjs";
|
|
19
18
|
import { randomUUID } from "node:crypto";
|
|
20
19
|
import { mkdirSync, openSync, statSync, watch } from "node:fs";
|
|
21
20
|
import { ambientEnv } from "@stim-cli/core";
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { c as throwIfCancelled, t as getExecutor, x as withDrainingCancellation } from "./exec-
|
|
2
|
-
import {
|
|
3
|
-
import { a as killOnAbort, c as gitQuiet, o as git, r as childEnvironment, s as gitAsync } from "./operation-exec-
|
|
4
|
-
import { m as defaultAndroidLayout } from "./settings-
|
|
5
|
-
import { r as register } from "./cache-manifest-
|
|
1
|
+
import { c as throwIfCancelled, t as getExecutor, x as withDrainingCancellation } from "./exec-aULwtNly.mjs";
|
|
2
|
+
import { y as sharedBuildCache } from "./workspace-state-BjqdjnJR.mjs";
|
|
3
|
+
import { a as killOnAbort, c as gitQuiet, o as git, r as childEnvironment, s as gitAsync } from "./operation-exec-Dp4FuIGR.mjs";
|
|
4
|
+
import { m as defaultAndroidLayout } from "./settings-BDVI8Ivc.mjs";
|
|
5
|
+
import { r as register } from "./cache-manifest-DEjqGGat.mjs";
|
|
6
|
+
import { r as writeSignedTail, t as computeSignedTail } from "./apk-signed-tail-BHQHx3Rm.mjs";
|
|
6
7
|
import { createHash } from "node:crypto";
|
|
7
8
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
9
|
import { join } from "node:path";
|
|
9
10
|
import { artifactIn, buildCacheKey, resolveArtifact, storeArtifactAsync } from "@stim-cli/core";
|
|
10
|
-
import {
|
|
11
|
+
import { trace } from "@stim-cli/core/state";
|
|
12
|
+
import { basename as basename$1, isAbsolute as isAbsolute$1, join as join$1, posix as posix$1, relative as relative$1, resolve as resolve$1, sep as sep$1 } from "path";
|
|
11
13
|
import { existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, rmSync as rmSync$1, statSync as statSync$1 } from "fs";
|
|
12
|
-
import { readdir, writeFile } from "node:fs/promises";
|
|
14
|
+
import { readdir, rename, rm, writeFile } from "node:fs/promises";
|
|
13
15
|
import { isDeepStrictEqual } from "util";
|
|
14
16
|
import * as expoFingerprint from "@expo/fingerprint";
|
|
15
17
|
import { loadConfigAsync } from "@expo/fingerprint/build/Config.js";
|
|
@@ -293,6 +295,58 @@ function androidProjectFingerprintOptions(projectRoot, layout, exists = existsSy
|
|
|
293
295
|
].map((dir) => `${moduleRel}/${dir}/**/*`)
|
|
294
296
|
};
|
|
295
297
|
}
|
|
298
|
+
const LOCKFILES = [
|
|
299
|
+
"pnpm-lock.yaml",
|
|
300
|
+
"yarn.lock",
|
|
301
|
+
"package-lock.json",
|
|
302
|
+
"bun.lock",
|
|
303
|
+
"bun.lockb"
|
|
304
|
+
];
|
|
305
|
+
/**
|
|
306
|
+
* The patches of a monorepo's install root, which @expo/fingerprint does not see: its patch sourcer reads only the
|
|
307
|
+
* app's own `patches/`, and its default preset hashes an installed package by name and version, so a patch applied
|
|
308
|
+
* from the workspace root would leave the key unchanged.
|
|
309
|
+
*/
|
|
310
|
+
function workspacePatchSources(projectRoot) {
|
|
311
|
+
let dir = resolve$1(projectRoot);
|
|
312
|
+
for (;;) {
|
|
313
|
+
if (LOCKFILES.some((name) => existsSync$1(join$1(dir, name)))) break;
|
|
314
|
+
const parent = resolve$1(dir, "..");
|
|
315
|
+
if (parent === dir || existsSync$1(join$1(dir, ".git"))) return [];
|
|
316
|
+
dir = parent;
|
|
317
|
+
}
|
|
318
|
+
const sources = ["patches", ".yarn/patches"].filter((name) => (name === "patches" ? dir !== resolve$1(projectRoot) : true) && existsSync$1(join$1(dir, name))).map((name) => ({
|
|
319
|
+
type: "dir",
|
|
320
|
+
filePath: relative$1(projectRoot, join$1(dir, name)).split(sep$1).join("/"),
|
|
321
|
+
reasons: ["workspacePatches"]
|
|
322
|
+
}));
|
|
323
|
+
const patched = pnpmPatchedDependencies(join$1(dir, "pnpm-lock.yaml"));
|
|
324
|
+
if (patched) sources.push({
|
|
325
|
+
type: "contents",
|
|
326
|
+
id: "pnpmPatchedDependencies",
|
|
327
|
+
contents: patched,
|
|
328
|
+
reasons: ["workspacePatches"]
|
|
329
|
+
});
|
|
330
|
+
return sources;
|
|
331
|
+
}
|
|
332
|
+
/** The lockfile's `patchedDependencies` block, which pnpm rewrites with each patch's hash wherever the patch lives. */
|
|
333
|
+
function pnpmPatchedDependencies(lockfile) {
|
|
334
|
+
let text;
|
|
335
|
+
try {
|
|
336
|
+
text = readFileSync$1(lockfile, "utf8");
|
|
337
|
+
} catch {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
const lines = text.split(/\r?\n/);
|
|
341
|
+
const start = lines.indexOf("patchedDependencies:");
|
|
342
|
+
if (start === -1) return null;
|
|
343
|
+
const block = [];
|
|
344
|
+
for (const line of lines.slice(start + 1)) {
|
|
345
|
+
if (line && !/^\s/.test(line)) break;
|
|
346
|
+
if (line.trim()) block.push(line.trim());
|
|
347
|
+
}
|
|
348
|
+
return block.length ? block.join("\n") : null;
|
|
349
|
+
}
|
|
296
350
|
/**
|
|
297
351
|
* The bundle output and, with `ios.projectPath` '.', the top-level entries that git ignores here for an iOS
|
|
298
352
|
* fingerprint, as the paths a build worker needs to ignore the same ones: it has no .git/info/exclude or global
|
|
@@ -319,7 +373,12 @@ async function fingerprintOptions(projectRoot, { platform, iosProjectPath = "ios
|
|
|
319
373
|
const ignoredAtAppRoot = (names) => new Set([...ignoredHere(names)].filter((name) => !trackedPaths.includes(name)));
|
|
320
374
|
const platforms = platform && FINGERPRINT_PLATFORMS.has(platform) ? { platforms: [platform] } : void 0;
|
|
321
375
|
const ios = platform === "ios" ? iosProjectFingerprintOptions(projectRoot, iosProjectPath, { ignored: (_, names) => ignoredAtAppRoot(names) }) : androidLayout?.custom ? androidProjectFingerprintOptions(projectRoot, androidLayout) : {};
|
|
322
|
-
|
|
376
|
+
const patches = workspacePatchSources(projectRoot);
|
|
377
|
+
if (ios.extraSources || patches.length) ios.extraSources = [
|
|
378
|
+
...(await loadConfigAsync(projectRoot, true))?.extraSources ?? [],
|
|
379
|
+
...ios.extraSources ?? [],
|
|
380
|
+
...patches
|
|
381
|
+
];
|
|
323
382
|
const bundleOutput = platform === "android" ? [] : [...ignoredHere(Object.keys(BUNDLE_OUTPUT_IGNORES), true)].map((path) => BUNDLE_OUTPUT_IGNORES[path]);
|
|
324
383
|
return {
|
|
325
384
|
...platforms,
|
|
@@ -333,26 +392,27 @@ async function fingerprintOptions(projectRoot, { platform, iosProjectPath = "ios
|
|
|
333
392
|
};
|
|
334
393
|
}
|
|
335
394
|
async function fingerprintProject(projectRoot, { createFingerprint = expoFingerprint.createFingerprintAsync, debug = false, ...target } = {}) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
395
|
+
return trace.spanAsync("fingerprint", async () => {
|
|
396
|
+
const options = await fingerprintOptions(projectRoot, target);
|
|
397
|
+
const result = await createFingerprint(projectRoot, debug ? {
|
|
398
|
+
...options,
|
|
399
|
+
debug
|
|
400
|
+
} : options);
|
|
401
|
+
const hash = result?.hash ?? null;
|
|
402
|
+
if (!hash) return null;
|
|
403
|
+
return {
|
|
404
|
+
hash,
|
|
405
|
+
sources: Array.isArray(result?.sources) ? result.sources : []
|
|
406
|
+
};
|
|
407
|
+
}, { platform: target.platform });
|
|
347
408
|
}
|
|
348
|
-
/** The env files @expo/env loads for the config
|
|
409
|
+
/** The env files @expo/env loads for the config: @expo/fingerprint 0.21 evaluates it in development mode. */
|
|
349
410
|
function expoEnvFiles(env = {}) {
|
|
350
411
|
if (/^(1|true)$/i.test(env.EXPO_NO_DOTENV ?? "")) return [];
|
|
351
|
-
const mode = env.NODE_ENV || "development";
|
|
352
412
|
return [
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
413
|
+
".env.development.local",
|
|
414
|
+
".env.local",
|
|
415
|
+
".env.development",
|
|
356
416
|
".env"
|
|
357
417
|
];
|
|
358
418
|
}
|
|
@@ -367,8 +427,8 @@ async function gitignoredFingerprintInputs(projectRoot, sources, target, { env,
|
|
|
367
427
|
if (sources.some((source) => source.type === "contents" && source.id === "expoConfig")) {
|
|
368
428
|
for (const name of expoEnvFiles(env)) if (lstatSync$1(join$1(projectRoot, name), { throwIfNoEntry: false })?.isFile()) found.add(name);
|
|
369
429
|
}
|
|
370
|
-
const top = realpathSync$1(await gitAsync(projectRoot, ["rev-parse", "--show-toplevel"], { signal }));
|
|
371
|
-
const base = realpathSync$1(projectRoot);
|
|
430
|
+
const top = realpathSync$1.native(await gitAsync(projectRoot, ["rev-parse", "--show-toplevel"], { signal }));
|
|
431
|
+
const base = realpathSync$1.native(projectRoot);
|
|
372
432
|
const pathspecs = sources.flatMap((source) => {
|
|
373
433
|
if (source.type === "contents" || inNodeModules(source.filePath)) return [];
|
|
374
434
|
const inRepo = relative$1(top, resolve$1(base, source.filePath));
|
|
@@ -457,6 +517,17 @@ async function storeBuild(platform, key, buildPath, rootOrOptions = {}) {
|
|
|
457
517
|
}),
|
|
458
518
|
overwrite: Boolean(options.overwrite),
|
|
459
519
|
writeMetadata: async (staging) => {
|
|
520
|
+
if (platform === "android" && buildPath.endsWith(".apk")) try {
|
|
521
|
+
const tail = await computeSignedTail(join$1(staging, basename$1(buildPath)), (file, args) => getExecutor().runFileAsync(file, args, {
|
|
522
|
+
timeoutMs: 12e4,
|
|
523
|
+
...env ? childEnvironment(env) : {},
|
|
524
|
+
onSpawn: killOnAbort(signal),
|
|
525
|
+
declareFor: options.context
|
|
526
|
+
}));
|
|
527
|
+
if (tail) await writeSignedTail(staging, tail);
|
|
528
|
+
} catch {
|
|
529
|
+
throwIfCancelled(signal, "build cache copy");
|
|
530
|
+
}
|
|
460
531
|
if (Array.isArray(options.sources)) try {
|
|
461
532
|
await writeFile(join$1(staging, SOURCES_FILE), JSON.stringify(options.sources.map(withoutContents)));
|
|
462
533
|
} catch {}
|
|
@@ -476,6 +547,25 @@ async function storeBuild(platform, key, buildPath, rootOrOptions = {}) {
|
|
|
476
547
|
throw error;
|
|
477
548
|
}
|
|
478
549
|
}
|
|
550
|
+
/** Removes a stored build by renaming its entry aside first, so no run sees a half-deleted entry. */
|
|
551
|
+
async function evictBuild(platform, key, root = sharedBuildCache()) {
|
|
552
|
+
const dir = entryDir(platform, key, root);
|
|
553
|
+
const evicted = `${dir}.evicted-${process.pid}`;
|
|
554
|
+
try {
|
|
555
|
+
await rm(evicted, {
|
|
556
|
+
recursive: true,
|
|
557
|
+
force: true
|
|
558
|
+
});
|
|
559
|
+
await rename(dir, evicted);
|
|
560
|
+
} catch {
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
await rm(evicted, {
|
|
564
|
+
recursive: true,
|
|
565
|
+
force: true
|
|
566
|
+
}).catch(() => {});
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
479
569
|
const PROVIDER_DOWNLOAD_DIR = "cache-provider";
|
|
480
570
|
function providerDownloadPath(workspacePath) {
|
|
481
571
|
return join$1(workspacePath, PROVIDER_DOWNLOAD_DIR);
|
|
@@ -588,6 +678,28 @@ function diffItemChange(item) {
|
|
|
588
678
|
reasons: sourceReasons(source)
|
|
589
679
|
};
|
|
590
680
|
}
|
|
681
|
+
/** The installed package a source path lies in: the name after its last `node_modules/`. */
|
|
682
|
+
function packageIn(path) {
|
|
683
|
+
return [...path.matchAll(/(?:^|\/)node_modules\/((?:@[^/]+\/)?[^/]+)/g)].at(-1)?.[1] ?? null;
|
|
684
|
+
}
|
|
685
|
+
/** A package that moved, such as a version bump of a pnpm store directory, is one change rather than a removal and an addition. */
|
|
686
|
+
function mergeMovedPackages(changes) {
|
|
687
|
+
const added = /* @__PURE__ */ new Map();
|
|
688
|
+
for (const change of changes) {
|
|
689
|
+
const pkg = change.change === "added" ? packageIn(change.name) : null;
|
|
690
|
+
if (pkg && !added.has(pkg)) added.set(pkg, change);
|
|
691
|
+
}
|
|
692
|
+
const moved = /* @__PURE__ */ new Set();
|
|
693
|
+
const kept = changes.filter((change) => {
|
|
694
|
+
const pkg = change.change === "removed" ? packageIn(change.name) : null;
|
|
695
|
+
const counterpart = pkg ? added.get(pkg) : void 0;
|
|
696
|
+
if (!counterpart || moved.has(counterpart)) return true;
|
|
697
|
+
moved.add(counterpart);
|
|
698
|
+
return false;
|
|
699
|
+
});
|
|
700
|
+
for (const change of moved) change.change = "changed";
|
|
701
|
+
return kept;
|
|
702
|
+
}
|
|
591
703
|
function compareSourceLists(previous, current) {
|
|
592
704
|
const previousByName = /* @__PURE__ */ new Map();
|
|
593
705
|
for (const source of previous) {
|
|
@@ -621,7 +733,7 @@ function compareSourceLists(previous, current) {
|
|
|
621
733
|
change: "removed",
|
|
622
734
|
reasons: before.reasons
|
|
623
735
|
});
|
|
624
|
-
return changes;
|
|
736
|
+
return mergeMovedPackages(changes);
|
|
625
737
|
}
|
|
626
738
|
function diffFingerprintSources({ previous, previousHash = null, current, differ = null }) {
|
|
627
739
|
if (typeof differ === "function") try {
|
|
@@ -633,16 +745,8 @@ function diffFingerprintSources({ previous, previousHash = null, current, differ
|
|
|
633
745
|
hash: current.hash
|
|
634
746
|
});
|
|
635
747
|
if (Array.isArray(items)) {
|
|
636
|
-
const changes = [];
|
|
637
748
|
const seen = /* @__PURE__ */ new Set();
|
|
638
|
-
|
|
639
|
-
const change = diffItemChange(item);
|
|
640
|
-
if (change !== null && !seen.has(change.name)) {
|
|
641
|
-
seen.add(change.name);
|
|
642
|
-
changes.push(change);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
return changes;
|
|
749
|
+
return mergeMovedPackages(items.map(diffItemChange).filter((change) => change !== null)).filter((change) => !seen.has(change.name) && Boolean(seen.add(change.name)));
|
|
646
750
|
}
|
|
647
751
|
} catch {}
|
|
648
752
|
return compareSourceLists(previous, current.sources);
|
|
@@ -750,4 +854,4 @@ function fingerprintDiffRecord({ changed, previousHash, hash }) {
|
|
|
750
854
|
};
|
|
751
855
|
}
|
|
752
856
|
//#endregion
|
|
753
|
-
export {
|
|
857
|
+
export { untrackedNativeFiles as A, resolveBuild as C, storedSources as D, storedAssetManifest as E, captureAssetManifest as M, compareAssetManifests as N, trackedFingerprintPaths as O, readAssetManifest as P, refingerprintAfterMutation as S, storedAppId as T, inputsChangedDuringBuild as _, configInputsChanged as a, providerDownloadPath as b, evictBuild as c, filesystemBuildCapability as d, fingerprintDiffRecord as f, ignoredFingerprintPaths as g, gitignoredFingerprintInputs as h, compareSourceLists as i, assetDiffReason as j, untrackedMissLine as k, expoConfigContents as l, fingerprintProject as m, buildCacheKey as n, diffFingerprintSources as o, fingerprintOptions as p, changedDuringBuildLine as r, entryDir as s, artifactIn as t, expoEnvFiles as u, packageIn as v, storeBuild as w, providerUploadOutcome as x, prepareProviderDownloadDir as y };
|