stim 1.19.0 → 1.20.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 +20 -3
- package/dist/{activity-BSw0x84R.mjs → activity-BrGh9EAI.mjs} +3 -3
- package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-DVyv_hWj.mjs} +7 -7
- package/dist/android-0vv-OruW.mjs +6 -0
- package/dist/android-Brx6EKvJ.mjs +1258 -0
- package/dist/{android-BdQC6zs1.mjs → android-BsYNR81W.mjs} +103 -45
- package/dist/{android-DE5g_5gv.mjs → android-CK3fpEyZ.mjs} +2 -2
- package/dist/{android-cas-C87geAg-.mjs → android-cas-DCAuXryb.mjs} +9 -5
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/api-run.mjs +159 -8
- package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
- package/dist/api.d.mts +98 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-CFI4ptUL.mjs → app-install-0LgaQRT7.mjs} +9 -8
- package/dist/artifact-CnC0mfov.mjs +807 -0
- package/dist/artifact-DClXJNWx.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{browser-web-CDhqQxhv.mjs → browser-web-CzBmhmgs.mjs} +19 -19
- package/dist/{budget-Dz-kyXLv.mjs → budget-BONq9vXY.mjs} +3101 -3062
- package/dist/build-BixRI6sB.mjs +462 -0
- package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
- package/dist/build-plan-CP0tckNU.mjs +553 -0
- package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{manifest-CX0d1IkZ.mjs → ccache-CjHQ5F8g.mjs} +13 -19
- package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-C9Zvgbdc.mjs → cli-B2R8wH1F.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-CuUo8Nvg.mjs → client-BLy1Pw2V.mjs} +89 -307
- package/dist/collector-run.d.mts +4 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-Bt8ygHE7.mjs → command-output-BjPN99ZB.mjs} +2 -2
- package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
- package/dist/{created-devices-D0s26Hx5.mjs → created-devices-HU_DAb_Q.mjs} +7 -6
- package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CDY_zAmD.mjs → dev-client-ClATaJoH.mjs} +2 -2
- package/dist/{device-BHw0WlHl.mjs → device-B7lsC0K1.mjs} +8 -8
- package/dist/device-DVCwAFlX.mjs +727 -0
- package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-Ca_ke1LE.mjs} +13 -14
- package/dist/device-host-worker.mjs +38 -18
- package/dist/device-ios-CRUqPxKw.mjs +413 -0
- package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-DHOBXGgS.mjs} +135 -22
- package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-CvDeHTkG.mjs} +4 -4
- package/dist/{device-pool-CP4rAsHx.mjs → device-pool-L2-5GxMy.mjs} +3 -3
- package/dist/{device-remote-B5GiUifk.mjs → device-remote-Bmg42063.mjs} +17 -68
- package/dist/doctor-C2MSuMMg.mjs +515 -0
- package/dist/{doctor-PRJH94v6.mjs → doctor-DPAqhVCK.mjs} +333 -744
- package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-CB4NnVZm.mjs} +13 -12
- package/dist/{simslim-D9LkJxIO.mjs → eas-build-Dw_ec2Km.mjs} +6 -152
- package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DZlC-Fq3.mjs} +57 -4
- package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-Du7I_GuY.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
- package/dist/{gc-CyHMcKcn.mjs → gc-PWp34zGb.mjs} +21 -20
- package/dist/{device-ios-B2ruohE-.mjs → gradle-C2OEKCCI.mjs} +21 -650
- package/dist/{guide-dRaQJJk9.mjs → guide-Dai9lphv.mjs} +504 -117
- package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-DQ-Agsd8.mjs} +5 -5
- package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client-Io01s5By.mjs} +9 -3
- package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-DIxFnYp-.mjs} +3 -3
- package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-DP-ABU_M.mjs} +8 -8
- package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-Aziw9T_9.mjs} +7 -6
- package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-BdAQi21M.mjs} +17 -14
- package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DdMqoSUB.mjs} +7 -7
- package/dist/{ios-DYUr9LGc.mjs → ios-BZ9dg2Fr.mjs} +8 -7
- package/dist/{ios-BWbHFZVz.mjs → ios-CXLIUxXJ.mjs} +180 -24
- package/dist/ios-CZuv6gRv.mjs +1112 -0
- package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BreZOpM0.mjs} +3 -3
- package/dist/ios-project-B9drt_aY.mjs +197 -0
- package/dist/{ios-state-By0XuLTQ.mjs → ios-state-CjrL2qv-.mjs} +1 -1
- package/dist/js-swap-C8icNYIY.mjs +432 -0
- package/dist/launch-DxH0THLP.mjs +745 -0
- package/dist/{react-native-ios-CSpIxexZ.mjs → launch-YrbqaIFj.mjs} +59 -612
- package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-BzRdbuO1.mjs} +26 -7
- package/dist/{logs-Bao1HOMy.mjs → logs-DHaRNfg7.mjs} +11 -11
- package/dist/macos-C0iljhsN.mjs +2 -0
- package/dist/{macos-ciyBdTY5.mjs → macos-V_3Ui7g4.mjs} +42 -50
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-DI2AjPF_.mjs → metro-D_j9sN-B.mjs} +18 -5
- package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BBJldOdi.mjs} +2 -2
- package/dist/miss-reason-BPAzZS0r.mjs +238 -0
- package/dist/{named-ports-B4iWH4E-.mjs → named-ports-C2lvoPsb.mjs} +3 -3
- package/dist/native-android-lHzaew7r.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-BRmWL7ru.mjs} +9 -8
- package/dist/native-xcode-inputs-eutS19jU.mjs +307 -0
- package/dist/native-xcode-ios-DP3cHLwu.mjs +434 -0
- package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
- package/dist/offload-worker.d.mts +41 -7
- package/dist/offload-worker.mjs +409 -74
- package/dist/{ownership-EB0ySdGK.mjs → ownership-DXzMMSx6.mjs} +2 -2
- package/dist/{placement-log-Dxe34rJm.mjs → placement-log-reFbjqEr.mjs} +1 -1
- package/dist/plan-BDk2AeY_.mjs +260 -0
- package/dist/plan-placement-D_YYlE6N.mjs +73 -0
- package/dist/{ports-ByPc0_97.mjs → ports-jzvAJXXL.mjs} +3 -3
- package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-Bw44QxVh.mjs} +4 -4
- package/dist/{preview-BbSottmO.mjs → preview-BaBJ72Al.mjs} +50 -32
- package/dist/project-B8_duAzW.mjs +1067 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-android-chm1DMlA.mjs +921 -0
- package/dist/react-native-build-oAw6gQeW.mjs +239 -0
- package/dist/react-native-doctor-DYXoh-6I.mjs +78 -0
- package/dist/react-native-ios-SCTK_CT5.mjs +595 -0
- package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-rAPdqeRR.mjs → reload-D34GkY78.mjs} +17 -13
- package/dist/remote-BU9UyhCJ.mjs +192 -0
- package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-Bsts6f6Y.mjs} +5 -5
- package/dist/result-BDoRk1k3.mjs +186 -0
- package/dist/{run-lAkle1-c.mjs → run-qvff78hv.mjs} +3 -3
- package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
- package/dist/server-command-7XIKlWtO.mjs +69 -0
- package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CsYu2aKL.mjs} +107 -82
- package/dist/server-expo-DV43vep4.mjs +2 -0
- package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
- package/dist/{settings-2am7TSxp.mjs → settings-CT3E71-i.mjs} +6 -6
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +84 -0
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-B9hn96wd.mjs} +6 -6
- package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/start-CbQCSnXQ.mjs +2 -0
- package/dist/{start-DtxthMfI.mjs → start-CdvcTaXr.mjs} +97 -68
- package/dist/{state-Tp4uImDS.mjs → state-Boo0IMJq.mjs} +1 -1
- package/dist/{state-D2KtnALG.mjs → state-DI84A-uu.mjs} +29 -10
- package/dist/{stats-8EJ5ivFT.mjs → stats-BIIDrjA8.mjs} +5 -5
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-BOyp0CUl.mjs → status-DARMkc9q.mjs} +81 -293
- package/dist/status-watch-DvmI3SmN.mjs +296 -0
- package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-DRipAg-e.mjs → stop-CCZS-C9m.mjs} +2 -2
- package/dist/{stop-D0UIpZuh.mjs → stop-WQPQHLuy.mjs} +5 -5
- package/dist/{stop-zDlknFoz.mjs → stop-iNemHsJC.mjs} +21 -20
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-DsNaFg6D.mjs → support-CnE_SIjt.mjs} +17 -7
- package/dist/{support-CNqYkV0y.mjs → support-DCco5fut.mjs} +61 -8
- package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-afeNUExW.mjs} +5 -5
- package/dist/tailnet-CoJUb2tB.mjs +265 -0
- package/dist/toolchain-BIupIro1.mjs +2 -0
- package/dist/{toolchain-C3xSoyUl.mjs → toolchain-DqyDXs30.mjs} +206 -53
- package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-C3ASD6z5.mjs} +6 -6
- package/dist/{watchman-BL1IdOtq.mjs → watchman-CQl51YZu.mjs} +6 -6
- package/dist/{web-DbbrPUn0.mjs → web-B3eldHFH.mjs} +9 -13
- package/dist/web-BLXpOe6b.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CSIFuuDa.mjs} +33 -33
- package/dist/{workspaces-Djb2gfi9.mjs → workspaces-D2xSHBDY.mjs} +1260 -1258
- package/dist/{worktree-BL4M1rhB.mjs → worktree-BxDqaTev.mjs} +84 -48
- package/dist/worktree-q7_OZNY0.mjs +2 -0
- package/package.json +8 -6
- package/shim/native-android.gradle +101 -0
- package/dist/android-BXc6BmEi.mjs +0 -3732
- package/dist/android-BvV1gGdN.mjs +0 -4
- package/dist/ios-ITYno9rO.mjs +0 -2241
- package/dist/macos-nIOATJmR.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
- package/dist/plan-placement-BVY59qa8.mjs +0 -290
- package/dist/project-B5eQ1USs.mjs +0 -612
- package/dist/react-native-ios-BMh2i25I.mjs +0 -2
- package/dist/server-expo-DGsdUGX2.mjs +0 -2
- package/dist/start-D8NbxNBb.mjs +0 -2
- package/dist/trigger-CoalsMTV.mjs +0 -2
- package/dist/web-DFpFeZu5.mjs +0 -2
- package/dist/worktree-DV-A0LNL.mjs +0 -2
|
@@ -1,15 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { Q as settingShapeErrors, a as SETTING_SHAPE_REMEDY, b as iosProjectDirSettingError, nt as unknownSettingKeys, p as cacheProviderSettingError, y as iosProjectDirSetting } from "./settings-Bbztm4oV.mjs";
|
|
2
|
+
import { w as workspaceLogsDir } from "./workspace-state-CSIFuuDa.mjs";
|
|
3
|
+
import { h as shortUdid, l as phaseLine } from "./command-output-BjPN99ZB.mjs";
|
|
4
|
+
import { p as resolveOptimizations } from "./errors-DzkMYh8Q.mjs";
|
|
5
|
+
import { y as resolveBuildPlacement } from "./client-BLy1Pw2V.mjs";
|
|
6
|
+
import { j as parseIosSimulatorApp } from "./ios-CXLIUxXJ.mjs";
|
|
7
|
+
import { F as describeDiagnostic } from "./toolchain-DqyDXs30.mjs";
|
|
8
|
+
import { d as unknownIosDeviceTypeRefusal, f as unknownIosRuntimeRefusal, o as layerNote, t as DEFAULT_DEVICE_SLOT_WAIT_MS } from "./device-capacity-Ca_ke1LE.mjs";
|
|
9
|
+
import { l as parseDeviceWait } from "./device-lease-run-CvDeHTkG.mjs";
|
|
10
|
+
import { t as IosDeviceMismatchError } from "./device-ios-CRUqPxKw.mjs";
|
|
8
11
|
import { basename, join } from "node:path";
|
|
9
12
|
import chalk from "chalk";
|
|
10
13
|
function buildLogFile(root) {
|
|
11
14
|
return join(workspaceLogsDir(root), `build-ios.ndjson`);
|
|
12
15
|
}
|
|
16
|
+
function iosProjectPathError(settings, root, isExpo) {
|
|
17
|
+
const error = iosProjectDirSettingError(settings, root);
|
|
18
|
+
if (error || !iosProjectDirSetting(settings, root).custom || !isExpo()) return error;
|
|
19
|
+
return "ios.projectPath applies to bare React Native apps only: expo prebuild generates and builds ios/. Remove it for this Expo app.";
|
|
20
|
+
}
|
|
21
|
+
function resolveIosBuildSetup(remoteBuild, settings, warn) {
|
|
22
|
+
const [shapeError, ...lines] = settingShapeErrors(settings);
|
|
23
|
+
if (shapeError) return {
|
|
24
|
+
ok: false,
|
|
25
|
+
failure: {
|
|
26
|
+
code: "STIM_BAD_ARG",
|
|
27
|
+
message: shapeError,
|
|
28
|
+
lines,
|
|
29
|
+
remedy: SETTING_SHAPE_REMEDY
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const placement = resolveBuildPlacement(remoteBuild);
|
|
33
|
+
if (placement.failure) return {
|
|
34
|
+
ok: false,
|
|
35
|
+
failure: {
|
|
36
|
+
...placement.failure,
|
|
37
|
+
setup: true
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
let optimizations;
|
|
41
|
+
try {
|
|
42
|
+
optimizations = resolveOptimizations(settings);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
failure: {
|
|
47
|
+
code: "STIM_BAD_ARG",
|
|
48
|
+
message: error.message,
|
|
49
|
+
remedy: SETTING_SHAPE_REMEDY
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
for (const key of unknownSettingKeys(settings)) warn("setting", `Warning: setting "${key}" is not read by Stim and will be ignored.`);
|
|
54
|
+
const cacheProviderError = cacheProviderSettingError(settings);
|
|
55
|
+
if (cacheProviderError) warn("cache", `${cacheProviderError} Using the local cache.`);
|
|
56
|
+
return {
|
|
57
|
+
ok: true,
|
|
58
|
+
buildMachine: placement.selected,
|
|
59
|
+
optimizations
|
|
60
|
+
};
|
|
61
|
+
}
|
|
13
62
|
const MAX_PRINTED_DIAGNOSTICS = 6;
|
|
14
63
|
function deviceLabel(device, udid) {
|
|
15
64
|
const name = device?.deviceName || device?.name || null;
|
|
@@ -32,6 +81,10 @@ function iosConfigurationSetting(settings) {
|
|
|
32
81
|
function resolveConfiguration(flag, settings) {
|
|
33
82
|
return (typeof flag === "string" && flag.trim() !== "" ? flag.trim() : null) || iosConfigurationSetting(settings);
|
|
34
83
|
}
|
|
84
|
+
function resolveSchemeSelection({ scheme, easProfile }, settings) {
|
|
85
|
+
if (typeof scheme === "string" || easProfile !== void 0) return scheme ?? void 0;
|
|
86
|
+
return iosStringSetting(settings, "scheme") ?? void 0;
|
|
87
|
+
}
|
|
35
88
|
function iosStringSetting(settings, key) {
|
|
36
89
|
const ios = settings?.["ios"];
|
|
37
90
|
if (!ios || typeof ios !== "object" || Array.isArray(ios)) return null;
|
|
@@ -223,4 +276,4 @@ function createIosDeviceWaitRun(stats, progress, signal) {
|
|
|
223
276
|
};
|
|
224
277
|
}
|
|
225
278
|
//#endregion
|
|
226
|
-
export {
|
|
279
|
+
export { xcodeFailureReport as S, resolveIosWait as _, deviceModelRefusal as a, resolveSimulatorAppFlag as b, iosProjectPathError as c, ownedSimFailure as d, podAction as f, resolveIosBuildSetup as g, resolveDeviceType as h, deviceLabel as i, iosProviderRunOptions as l, resolveConfiguration as m, buildLogFile as n, deviceShortName as o, printDiagnostics as p, createIosDeviceWaitRun as r, iosConfigurationSetting as s, appNameFromPath as t, isReleaseConfiguration as u, resolveRuntime as v, simulatorBuildArch as x, resolveSchemeSelection as y };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import {
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { Et as repoRoot } from "./settings-Bbztm4oV.mjs";
|
|
3
3
|
import { a as spawnDeclared } from "./spawn-claims-Kqiifsk2.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { i as validateInfoPlist, n as setBundleName, r as stageBundle, t as resolveBundleExtras } from "./stage-
|
|
6
|
-
import { t as logLines } from "./run-
|
|
4
|
+
import { s as macosToolchain } from "./toolchain-DqyDXs30.mjs";
|
|
5
|
+
import { i as validateInfoPlist, n as setBundleName, r as stageBundle, t as resolveBundleExtras } from "./stage-BNKKdDNc.mjs";
|
|
6
|
+
import { t as logLines } from "./run-qvff78hv.mjs";
|
|
7
7
|
import { existsSync, realpathSync } from "node:fs";
|
|
8
8
|
import { join, relative, resolve } from "node:path";
|
|
9
9
|
//#region src/integrations/swiftpm-macos.ts
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { t as getExecutor } from "./exec-B81Qodjn.mjs";
|
|
2
|
+
import { a as updateWorkspaceState, r as readWorkspaceState$1, t as clearWorkspaceStateKey, x as workspaceDir } from "./workspace-state-CSIFuuDa.mjs";
|
|
3
|
+
import { a as formatElapsed } from "./command-output-BjPN99ZB.mjs";
|
|
4
|
+
import { i as signalDeclaredSpawns, r as refuseDeclaredSpawns, t as allowDeclaredSpawns } from "./spawn-claims-Kqiifsk2.mjs";
|
|
5
|
+
import { a as withWorkspaceProcessLock } from "./named-ports-C2lvoPsb.mjs";
|
|
6
|
+
import { endpoint, findPeer as findPeer$1, isJsonObject, parseMachine, parseMachine as parseMachine$1, pinnedEndpoint } from "@stim-cli/core/state";
|
|
7
|
+
import { WebSocket } from "ws";
|
|
8
|
+
//#region src/engine/native-run.ts
|
|
9
|
+
const NATIVE_RUN_LOCK = "native-run";
|
|
10
|
+
const NATIVE_RUN_WAIT_MS = 18e5;
|
|
11
|
+
const WAIT_HEARTBEAT_MS = 3e4;
|
|
12
|
+
const CANCEL_REQUEST_KEY = "nativeRunCancel";
|
|
13
|
+
function nativeRunHolder(holder) {
|
|
14
|
+
const { command, platform, slot } = holder.details;
|
|
15
|
+
return {
|
|
16
|
+
command: typeof command === "string" ? command : null,
|
|
17
|
+
platform: typeof platform === "string" ? platform : null,
|
|
18
|
+
slot: typeof slot === "string" ? slot : "default"
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function describeNativeRunHolder(holder, now) {
|
|
22
|
+
const { command, slot } = nativeRunHolder(holder);
|
|
23
|
+
const started = Date.parse(holder.startedAt);
|
|
24
|
+
const facts = [`pid ${holder.owner.pid}`];
|
|
25
|
+
if (Number.isFinite(started)) facts.push(`running for ${formatElapsed(now - started)}`);
|
|
26
|
+
if (command === null) return `another Stim run (${facts.join(", ")})`;
|
|
27
|
+
if (command === "build") return `an artifact build (${facts.join(", ")})`;
|
|
28
|
+
return `\`stim ${command}${slot === "default" ? "" : ` --slot ${slot}`}\` (${facts.join(", ")})`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Report a wait on the native-run lock: one line as soon as a holder is seen, a line for each new
|
|
32
|
+
* holder, and a heartbeat every WAIT_HEARTBEAT_MS while the same holder keeps it.
|
|
33
|
+
*/
|
|
34
|
+
function nativeRunWaitNotice({ write, now = Date.now, describe = describeNativeRunHolder }) {
|
|
35
|
+
let claimId = null;
|
|
36
|
+
let lastAt = 0;
|
|
37
|
+
return (holder, firstLine) => {
|
|
38
|
+
const at = now();
|
|
39
|
+
if (holder.claimId !== claimId) {
|
|
40
|
+
claimId = holder.claimId;
|
|
41
|
+
lastAt = at;
|
|
42
|
+
write(firstLine ?? `waiting for ${describe(holder, at)} in this workspace to finish`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (at - lastAt < WAIT_HEARTBEAT_MS) return;
|
|
46
|
+
lastAt = at;
|
|
47
|
+
write(`still waiting for ${describe(holder, at)}`);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* What `stop` does about the run holding the native-run lock. A build is interrupted only when the stop
|
|
52
|
+
* leaves it nothing to deploy to: the whole workspace stops, the build targets the stopped slot, or the
|
|
53
|
+
* stopped slot is the workspace's only device. A build for another slot that stays is left running and
|
|
54
|
+
* the stop proceeds without the lock. Only an owner whose identity is proven live is signalled.
|
|
55
|
+
*/
|
|
56
|
+
function decideStopAction({ stopSlot, holder, ownerIdentity, deviceSlots }) {
|
|
57
|
+
if (holder.command === "macos" || holder.command === "build") {
|
|
58
|
+
if (stopSlot !== void 0) return { action: "proceed" };
|
|
59
|
+
return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
|
|
60
|
+
}
|
|
61
|
+
if (holder.command !== "ios" && holder.command !== "android") return { action: "wait" };
|
|
62
|
+
if (!(stopSlot === void 0 || holder.slot === stopSlot || deviceSlots.includes(stopSlot) && deviceSlots.every((slot) => slot === stopSlot))) return { action: "proceed" };
|
|
63
|
+
return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
|
|
64
|
+
}
|
|
65
|
+
function requestNativeRunCancel(root, claimId, pid = process.pid) {
|
|
66
|
+
updateWorkspaceState(root, (state) => ({
|
|
67
|
+
...state,
|
|
68
|
+
[CANCEL_REQUEST_KEY]: {
|
|
69
|
+
claimId,
|
|
70
|
+
pid,
|
|
71
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
72
|
+
}
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
function cancelRequestFor(root, claimId) {
|
|
76
|
+
const request = readWorkspaceState$1(root)?.[CANCEL_REQUEST_KEY];
|
|
77
|
+
if (request?.claimId !== claimId || typeof request.pid !== "number") return null;
|
|
78
|
+
return { pid: request.pid };
|
|
79
|
+
}
|
|
80
|
+
function clearNativeRunCancel(root, claimId) {
|
|
81
|
+
try {
|
|
82
|
+
clearWorkspaceStateKey(root, CANCEL_REQUEST_KEY, (value) => value?.claimId === claimId);
|
|
83
|
+
} catch {}
|
|
84
|
+
}
|
|
85
|
+
let cancelled = null;
|
|
86
|
+
let cancellationSignal;
|
|
87
|
+
/** The active native run aborts this signal when it is cancelled. */
|
|
88
|
+
function runCancellationSignal() {
|
|
89
|
+
return cancellationSignal;
|
|
90
|
+
}
|
|
91
|
+
/** Why this process's native run was cancelled, or null while it was not. */
|
|
92
|
+
function runCancellation() {
|
|
93
|
+
return cancelled;
|
|
94
|
+
}
|
|
95
|
+
function cancelledFailure(platform, { code, message }) {
|
|
96
|
+
if (cancelled === null) return null;
|
|
97
|
+
return {
|
|
98
|
+
code: "STIM_CANCELLED",
|
|
99
|
+
message: `The ${platform} run was ${cancelled} before it finished.`,
|
|
100
|
+
remedy: `Run \`stim ${platform}\` again when you want the app on a device.`,
|
|
101
|
+
lines: [`it stopped at ${code ?? "an unfinished step"}${message ? `: ${message}` : ""}`]
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function cancelOnInterrupt({ root, claim, write, exit, controller }) {
|
|
105
|
+
let signals = 0;
|
|
106
|
+
const onInterrupt = () => {
|
|
107
|
+
signals += 1;
|
|
108
|
+
if (signals > 1) {
|
|
109
|
+
exit(130);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const request = cancelRequestFor(root, claim.claimId);
|
|
113
|
+
cancelled = request ? `cancelled by \`stim stop\` (pid ${request.pid})` : "cancelled by an interrupt";
|
|
114
|
+
controller.abort();
|
|
115
|
+
refuseDeclaredSpawns(`the run was ${cancelled}`);
|
|
116
|
+
const signalled = signalDeclaredSpawns("SIGINT");
|
|
117
|
+
write(signalled > 0 ? `${cancelled}; stopping the running build tool` : request ? `${cancelled}; stopping before the next build tool or install` : cancelled);
|
|
118
|
+
if (signalled === 0 && !request) exit(130);
|
|
119
|
+
};
|
|
120
|
+
process.on("SIGINT", onInterrupt);
|
|
121
|
+
return () => {
|
|
122
|
+
process.off("SIGINT", onInterrupt);
|
|
123
|
+
allowDeclaredSpawns();
|
|
124
|
+
clearNativeRunCancel(root, claim.claimId);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Run an `ios`, `android` or `macos` invocation under the workspace's native-run lock: the claim records the
|
|
129
|
+
* command, platform and slot, and a wait for another holder is reported on `write`. The first SIGINT
|
|
130
|
+
* forwards the interrupt to the running declared build tool; a run `stim stop` cancelled between build
|
|
131
|
+
* tools starts no further one; a terminal interrupt with no build tool running, or a second SIGINT, exits
|
|
132
|
+
* with 130 at once.
|
|
133
|
+
*/
|
|
134
|
+
function withNativeBuildRun(root, details, fn, { write, exit = (code) => process.exit(code) }) {
|
|
135
|
+
const notice = nativeRunWaitNotice({ write });
|
|
136
|
+
return withWorkspaceProcessLock(workspaceDir(root), NATIVE_RUN_LOCK, async (claim) => {
|
|
137
|
+
cancelled = null;
|
|
138
|
+
const controller = new AbortController();
|
|
139
|
+
cancellationSignal = controller.signal;
|
|
140
|
+
const dispose = cancelOnInterrupt({
|
|
141
|
+
root,
|
|
142
|
+
claim,
|
|
143
|
+
write,
|
|
144
|
+
exit,
|
|
145
|
+
controller
|
|
146
|
+
});
|
|
147
|
+
try {
|
|
148
|
+
return await fn(claim);
|
|
149
|
+
} finally {
|
|
150
|
+
dispose();
|
|
151
|
+
cancellationSignal = void 0;
|
|
152
|
+
}
|
|
153
|
+
}, {
|
|
154
|
+
external: true,
|
|
155
|
+
waitMs: NATIVE_RUN_WAIT_MS,
|
|
156
|
+
declareSpawns: true,
|
|
157
|
+
details: { ...details },
|
|
158
|
+
onHeld: (holder) => notice(holder)
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/offload/tailnet.ts
|
|
163
|
+
const MAC_APP_TAILSCALE = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
|
164
|
+
const HELLO_TIMEOUT_MS = 1e4;
|
|
165
|
+
function isLapsed(credential) {
|
|
166
|
+
return credential.state === "pending" && !!credential.expiresAt && Date.parse(credential.expiresAt) <= Date.now();
|
|
167
|
+
}
|
|
168
|
+
function markApproved(credential) {
|
|
169
|
+
const { expiresAt: _expiresAt, ...rest } = credential;
|
|
170
|
+
return {
|
|
171
|
+
...rest,
|
|
172
|
+
state: "approved"
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function pendingReport(credential) {
|
|
176
|
+
return {
|
|
177
|
+
state: "pending",
|
|
178
|
+
...credential.expiresAt ? { expiresAt: credential.expiresAt } : {}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function lapsedLine(machine, credential) {
|
|
182
|
+
return `${machine} did not approve this Mac before the request lapsed at ${credential.expiresAt}.`;
|
|
183
|
+
}
|
|
184
|
+
function requestedLine(credential) {
|
|
185
|
+
return `Requested at ${credential.requestedAt}${credential.expiresAt ? `; the request lapses at ${credential.expiresAt}` : ""}.`;
|
|
186
|
+
}
|
|
187
|
+
function parseTailscaleStatus(output) {
|
|
188
|
+
try {
|
|
189
|
+
const status = JSON.parse(output);
|
|
190
|
+
return isJsonObject(status) && status.BackendState === "Running" ? status : null;
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function tailscaleStatus() {
|
|
196
|
+
for (const binary of ["tailscale", MAC_APP_TAILSCALE]) {
|
|
197
|
+
const output = getExecutor().runFileQuiet(binary, ["status", "--json"], { timeoutMs: 5e3 });
|
|
198
|
+
if (output !== null) return parseTailscaleStatus(output);
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
async function tailscaleStatusAsync() {
|
|
203
|
+
for (const binary of ["tailscale", MAC_APP_TAILSCALE]) {
|
|
204
|
+
let output;
|
|
205
|
+
try {
|
|
206
|
+
output = await getExecutor().runFileAsync(binary, ["status", "--json"], { timeoutMs: 5e3 });
|
|
207
|
+
} catch {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
return parseTailscaleStatus(output);
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
function hello({ url, servername, host }, auth) {
|
|
215
|
+
return new Promise((resolve) => {
|
|
216
|
+
const socket = new WebSocket(url, {
|
|
217
|
+
handshakeTimeout: HELLO_TIMEOUT_MS,
|
|
218
|
+
servername,
|
|
219
|
+
headers: { Host: host }
|
|
220
|
+
});
|
|
221
|
+
const done = (reply) => {
|
|
222
|
+
clearTimeout(timer);
|
|
223
|
+
socket.removeAllListeners();
|
|
224
|
+
socket.on("error", () => {});
|
|
225
|
+
socket.close();
|
|
226
|
+
resolve(reply);
|
|
227
|
+
};
|
|
228
|
+
const timer = setTimeout(() => done({ failed: "no reply in time" }), HELLO_TIMEOUT_MS);
|
|
229
|
+
socket.on("open", () => {
|
|
230
|
+
socket.send(JSON.stringify({
|
|
231
|
+
id: 1,
|
|
232
|
+
method: "hello",
|
|
233
|
+
params: {
|
|
234
|
+
protocol: 1,
|
|
235
|
+
client: {
|
|
236
|
+
name: "stim",
|
|
237
|
+
version: "1"
|
|
238
|
+
},
|
|
239
|
+
auth
|
|
240
|
+
}
|
|
241
|
+
}));
|
|
242
|
+
});
|
|
243
|
+
socket.on("message", (data) => {
|
|
244
|
+
let message;
|
|
245
|
+
try {
|
|
246
|
+
message = JSON.parse(String(data));
|
|
247
|
+
} catch {
|
|
248
|
+
message = null;
|
|
249
|
+
}
|
|
250
|
+
if (isJsonObject(message) && ("result" in message || "error" in message)) return done(message);
|
|
251
|
+
done({ failed: "the reply was not a hello result" });
|
|
252
|
+
});
|
|
253
|
+
socket.on("error", (error) => done({ failed: error.message }));
|
|
254
|
+
socket.on("close", () => done({ failed: "the connection closed before a reply" }));
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
const realIo = {
|
|
258
|
+
status: tailscaleStatus,
|
|
259
|
+
hello
|
|
260
|
+
};
|
|
261
|
+
async function pinnedEndpoint$1(credential, status = tailscaleStatusAsync) {
|
|
262
|
+
return pinnedEndpoint(credential, parseMachine(credential.machine) ? await status() : null);
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
export { withNativeBuildRun as S, nativeRunHolder as _, markApproved as a, runCancellation as b, pinnedEndpoint$1 as c, NATIVE_RUN_LOCK as d, NATIVE_RUN_WAIT_MS as f, describeNativeRunHolder as g, decideStopAction as h, lapsedLine as i, realIo as l, clearNativeRunCancel as m, findPeer$1 as n, parseMachine$1 as o, cancelledFailure as p, isLapsed as r, pendingReport as s, endpoint as t, requestedLine as u, nativeRunWaitNotice as v, runCancellationSignal as x, requestNativeRunCancel as y };
|