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,12 +1,198 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { r as readWorkspaceState } from "./workspace-state-
|
|
5
|
-
import { existsSync, readlinkSync, realpathSync } from "fs";
|
|
1
|
+
import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-i8GDPwq9.mjs";
|
|
3
|
+
import { M as isOnMountedVolume, N as listMountedVolumes, _ as loadConfig, n as allMetroPorts, r as claimMetroPort, x as releaseMetroPort } from "./config-DC5jEtd1.mjs";
|
|
4
|
+
import { r as readWorkspaceState } from "./workspace-state-CR9X86xJ.mjs";
|
|
6
5
|
import { sep } from "path";
|
|
6
|
+
import { existsSync, readlinkSync, realpathSync } from "fs";
|
|
7
|
+
import { readFile } from "node:fs/promises";
|
|
7
8
|
import { request } from "http";
|
|
8
|
-
import { connect } from "net";
|
|
9
|
+
import { connect } from "node:net";
|
|
10
|
+
//#region src/listening-ports.ts
|
|
11
|
+
/**
|
|
12
|
+
* Returns occupied TCP ports across local interfaces. Rejects if listener inspection fails.
|
|
13
|
+
*/
|
|
14
|
+
async function readListeningPorts(platform = process.platform) {
|
|
15
|
+
switch (platform) {
|
|
16
|
+
case "darwin": return parseDarwinPorts(await readNetstat("/usr/sbin/netstat", [
|
|
17
|
+
"-anL",
|
|
18
|
+
"-p",
|
|
19
|
+
"tcp"
|
|
20
|
+
]));
|
|
21
|
+
case "linux": return parseLinuxPorts(await Promise.all([readFile("/proc/net/tcp", "utf8"), readFile("/proc/net/tcp6", "utf8").catch((error) => {
|
|
22
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
23
|
+
throw error;
|
|
24
|
+
})]));
|
|
25
|
+
case "win32": return parseWindowsPorts(await readNetstat("netstat", ["-an"]));
|
|
26
|
+
default: throw new Error(`TCP listener inspection is not supported on ${platform}.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const DARWIN_TITLE = "Current listen queue sizes (qlen/incqlen/maxqlen)";
|
|
30
|
+
const DARWIN_COLUMNS = /^Listen\s+Local Address$/;
|
|
31
|
+
const DARWIN_TABLE_CHANGE = /^Some tcp sockets may have been (?:created|deleted|created or deleted)\.?$/;
|
|
32
|
+
const DARWIN_LISTENER = /^\d+\/\d+\/\d+\s+\S+\.(?<port>\d+)$/;
|
|
33
|
+
function parseDarwinPorts(output) {
|
|
34
|
+
const ports = /* @__PURE__ */ new Set();
|
|
35
|
+
let title = false;
|
|
36
|
+
let columns = false;
|
|
37
|
+
for (const raw of output.split("\n")) {
|
|
38
|
+
const line = raw.trim();
|
|
39
|
+
if (line === DARWIN_TITLE) title = true;
|
|
40
|
+
else if (DARWIN_COLUMNS.test(line)) columns = true;
|
|
41
|
+
if (!line || line === DARWIN_TITLE || DARWIN_COLUMNS.test(line) || DARWIN_TABLE_CHANGE.test(line)) continue;
|
|
42
|
+
const listener = DARWIN_LISTENER.exec(line)?.groups;
|
|
43
|
+
if (!listener) throw new Error("Cannot parse the TCP listen table from netstat.");
|
|
44
|
+
addPort(ports, Number(listener.port));
|
|
45
|
+
}
|
|
46
|
+
if (!title || !columns) throw new Error("netstat printed no TCP listen table.");
|
|
47
|
+
return ports;
|
|
48
|
+
}
|
|
49
|
+
const LINUX_COLUMNS = /^\s*sl\s+local_address\s+rem(?:ote)?_address\s+st\s/;
|
|
50
|
+
const LINUX_TCP_STATE = /^[0-9A-F]{2}$/i;
|
|
51
|
+
const LINUX_LOCAL_ADDRESS = /^(?:[0-9A-F]{8}|[0-9A-F]{32}):(?<port>[0-9A-F]{4})$/i;
|
|
52
|
+
const LINUX_LISTEN_STATE = "0A";
|
|
53
|
+
function parseLinuxPorts(tables) {
|
|
54
|
+
const ports = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const table of tables) {
|
|
56
|
+
if (table === null) continue;
|
|
57
|
+
const [header, ...rows] = table.trim().split("\n");
|
|
58
|
+
if (!header || !LINUX_COLUMNS.test(header)) throw new Error("Cannot parse the TCP socket table from /proc/net.");
|
|
59
|
+
for (const raw of rows) {
|
|
60
|
+
const line = raw.trim();
|
|
61
|
+
if (!line) continue;
|
|
62
|
+
const [, localAddress, , state] = line.split(/\s+/);
|
|
63
|
+
if (!state || !LINUX_TCP_STATE.test(state)) throw new Error("Invalid TCP state in /proc/net.");
|
|
64
|
+
if (state.toUpperCase() !== LINUX_LISTEN_STATE) continue;
|
|
65
|
+
const listener = localAddress && LINUX_LOCAL_ADDRESS.exec(localAddress)?.groups;
|
|
66
|
+
if (!listener) throw new Error("Invalid TCP listener in /proc/net.");
|
|
67
|
+
addPort(ports, Number(`0x${listener.port}`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return ports;
|
|
71
|
+
}
|
|
72
|
+
const WINDOWS_COLUMNS = /^Proto\s/;
|
|
73
|
+
const WINDOWS_TCP_ROW = /^TCP\s+\S*:(?<localPort>\d+)\s+\S*:(?<remotePort>\d+)\s+\S/;
|
|
74
|
+
function parseWindowsPorts(output) {
|
|
75
|
+
const ports = /* @__PURE__ */ new Set();
|
|
76
|
+
let table = false;
|
|
77
|
+
for (const raw of output.split("\n")) {
|
|
78
|
+
const line = raw.trim();
|
|
79
|
+
if (WINDOWS_COLUMNS.test(line)) table = true;
|
|
80
|
+
const [protocol] = line.split(/\s+/, 1);
|
|
81
|
+
if (protocol !== "TCP") continue;
|
|
82
|
+
table = true;
|
|
83
|
+
const connection = WINDOWS_TCP_ROW.exec(line)?.groups;
|
|
84
|
+
if (!connection) throw new Error("Cannot parse the TCP connection table from netstat.");
|
|
85
|
+
if (Number(connection.remotePort) === 0) addPort(ports, Number(connection.localPort));
|
|
86
|
+
}
|
|
87
|
+
if (!table) throw new Error("netstat printed no TCP connection table.");
|
|
88
|
+
return ports;
|
|
89
|
+
}
|
|
90
|
+
function readNetstat(file, args) {
|
|
91
|
+
return getExecutor().runFileAsync(file, args, {
|
|
92
|
+
timeoutMs: 5e3,
|
|
93
|
+
rejectStderr: true,
|
|
94
|
+
env: { LC_ALL: "C" }
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function addPort(ports, port) {
|
|
98
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid TCP listener port.");
|
|
99
|
+
ports.add(port);
|
|
100
|
+
}
|
|
101
|
+
function addressPort(address) {
|
|
102
|
+
const colon = String(address ?? "").lastIndexOf(":");
|
|
103
|
+
return colon < 0 ? NaN : Number(String(address).slice(colon + 1));
|
|
104
|
+
}
|
|
105
|
+
function parseLsofListeners(out) {
|
|
106
|
+
const byPort = /* @__PURE__ */ new Map();
|
|
107
|
+
let pid = null;
|
|
108
|
+
for (const line of String(out ?? "").split("\n")) if (line.startsWith("p")) pid = parseInt(line.slice(1), 10);
|
|
109
|
+
else if (line.startsWith("n") && pid !== null && Number.isFinite(pid)) {
|
|
110
|
+
const port = addressPort(line.slice(1));
|
|
111
|
+
const pids = byPort.get(port) ?? [];
|
|
112
|
+
if (!pids.includes(pid)) pids.push(pid);
|
|
113
|
+
byPort.set(port, pids);
|
|
114
|
+
}
|
|
115
|
+
return byPort;
|
|
116
|
+
}
|
|
117
|
+
const PORT_INSPECTION_REMEDY = "Allow Stim to run netstat or lsof, or to connect to 127.0.0.1 and ::1, then retry. A metro.port pin skips the scan for Metro.";
|
|
118
|
+
var PortInspectionError = class extends Error {
|
|
119
|
+
code = "STIM_PORT_INSPECTION_FAILED";
|
|
120
|
+
reason;
|
|
121
|
+
constructor(reason) {
|
|
122
|
+
super(`${reason} ${PORT_INSPECTION_REMEDY}`);
|
|
123
|
+
this.reason = reason;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Returns the TCP ports lsof lists as listening, or null when lsof cannot list them.
|
|
128
|
+
*/
|
|
129
|
+
async function readLsofListeningPorts() {
|
|
130
|
+
try {
|
|
131
|
+
const out = await getExecutor().runFileAsync("lsof", [
|
|
132
|
+
"-nP",
|
|
133
|
+
"-iTCP",
|
|
134
|
+
"-sTCP:LISTEN",
|
|
135
|
+
"-Fpn"
|
|
136
|
+
], { timeoutMs: 5e3 });
|
|
137
|
+
return new Set([...parseLsofListeners(out).keys()].filter(Number.isInteger));
|
|
138
|
+
} catch (error) {
|
|
139
|
+
const result = error;
|
|
140
|
+
if (result.status === 1 && !String(result.stdout ?? "").trim() && !String(result.stderr ?? "").trim()) return /* @__PURE__ */ new Set();
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const IPV6_UNAVAILABLE = /* @__PURE__ */ new Set([
|
|
145
|
+
"EADDRNOTAVAIL",
|
|
146
|
+
"EAFNOSUPPORT",
|
|
147
|
+
"ENETUNREACH"
|
|
148
|
+
]);
|
|
149
|
+
/**
|
|
150
|
+
* Connects to a loopback port: `taken` when something accepts or the connect hangs, `free` when
|
|
151
|
+
* it is refused or IPv6 is unavailable, `unknown` for any other connect error.
|
|
152
|
+
*/
|
|
153
|
+
function probeLoopback(port, host, timeoutMs = 400) {
|
|
154
|
+
return new Promise((resolve) => {
|
|
155
|
+
const socket = connect({
|
|
156
|
+
port,
|
|
157
|
+
host
|
|
158
|
+
});
|
|
159
|
+
const done = (answer) => {
|
|
160
|
+
socket.removeAllListeners();
|
|
161
|
+
socket.destroy();
|
|
162
|
+
resolve(answer);
|
|
163
|
+
};
|
|
164
|
+
socket.setTimeout(timeoutMs);
|
|
165
|
+
socket.once("connect", () => done("taken"));
|
|
166
|
+
socket.once("timeout", () => done("taken"));
|
|
167
|
+
socket.once("error", (error) => {
|
|
168
|
+
const refused = error.code === "ECONNREFUSED" || host === "::1" && IPV6_UNAVAILABLE.has(error.code ?? "");
|
|
169
|
+
done(refused ? "free" : "unknown");
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
9
174
|
//#region src/ports.ts
|
|
175
|
+
/**
|
|
176
|
+
* Creates one lazy listener snapshot for an allocation attempt; discard the probe before retrying.
|
|
177
|
+
* When the native TCP table cannot be read, each port is checked with an lsof listener scan and
|
|
178
|
+
* loopback connects instead. Rejects with `PortInspectionError` only when none of them can answer.
|
|
179
|
+
*/
|
|
180
|
+
function createPortProbe() {
|
|
181
|
+
let snapshot;
|
|
182
|
+
let lsof;
|
|
183
|
+
return async (port) => {
|
|
184
|
+
const listening = await (snapshot ??= readListeningPorts().catch((error) => error instanceof Error ? error : new Error(String(error))));
|
|
185
|
+
if (!(listening instanceof Error)) return !listening.has(port);
|
|
186
|
+
const [listed, ipv4, ipv6] = await Promise.all([
|
|
187
|
+
lsof ??= readLsofListeningPorts(),
|
|
188
|
+
probeLoopback(port, "127.0.0.1"),
|
|
189
|
+
probeLoopback(port, "::1")
|
|
190
|
+
]);
|
|
191
|
+
if (listed?.has(port) || ipv4 === "taken" || ipv6 === "taken") return false;
|
|
192
|
+
if (listed || ipv4 === "free" && ipv6 === "free") return true;
|
|
193
|
+
throw new PortInspectionError(`Cannot tell whether TCP port ${port} is free: the TCP listener table failed (${listening.message.replace(/\s+/g, " ").trim()}), lsof could not list listeners, and a loopback connect failed.`);
|
|
194
|
+
};
|
|
195
|
+
}
|
|
10
196
|
function isMetroRunning(port) {
|
|
11
197
|
return new Promise((resolve) => {
|
|
12
198
|
const req = request({
|
|
@@ -29,25 +215,8 @@ function isMetroRunning(port) {
|
|
|
29
215
|
req.end();
|
|
30
216
|
});
|
|
31
217
|
}
|
|
32
|
-
function isPortFree(port, { timeoutMs = 400 } = {}) {
|
|
33
|
-
return new Promise((resolve) => {
|
|
34
|
-
const sock = connect({
|
|
35
|
-
port,
|
|
36
|
-
host: "127.0.0.1"
|
|
37
|
-
});
|
|
38
|
-
const done = (free) => {
|
|
39
|
-
sock.removeAllListeners();
|
|
40
|
-
sock.destroy();
|
|
41
|
-
resolve(free);
|
|
42
|
-
};
|
|
43
|
-
sock.setTimeout(timeoutMs);
|
|
44
|
-
sock.once("connect", () => done(false));
|
|
45
|
-
sock.once("error", () => done(true));
|
|
46
|
-
sock.once("timeout", () => done(false));
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
218
|
const FIRST_PORT = 8082;
|
|
50
|
-
async function computeNextPort(isFree =
|
|
219
|
+
async function computeNextPort(isFree = createPortProbe()) {
|
|
51
220
|
const taken = new Set(allMetroPorts());
|
|
52
221
|
for (let port = FIRST_PORT; port < 8282; port++) {
|
|
53
222
|
if (taken.has(port)) continue;
|
|
@@ -73,7 +242,7 @@ async function findReclaimablePort(excludeProjectPath, probe = isMetroRunning, {
|
|
|
73
242
|
for (const c of candidates) if (!await probe(c.port)) return c;
|
|
74
243
|
return null;
|
|
75
244
|
}
|
|
76
|
-
async function allocatePort(projectPath, probe = isMetroRunning, isFree =
|
|
245
|
+
async function allocatePort(projectPath, probe = isMetroRunning, isFree = createPortProbe()) {
|
|
77
246
|
const reclaim = await findReclaimablePort(projectPath, probe);
|
|
78
247
|
if (reclaim && await isFree(reclaim.port)) {
|
|
79
248
|
releaseMetroPort(reclaim.ownerPath, reclaim.port);
|
|
@@ -82,7 +251,7 @@ async function allocatePort(projectPath, probe = isMetroRunning, isFree = isPort
|
|
|
82
251
|
return computeNextPort(isFree);
|
|
83
252
|
}
|
|
84
253
|
const RESERVE_ATTEMPTS = 5;
|
|
85
|
-
async function reserveMetroPort(projectPath, probe = isMetroRunning, isFree
|
|
254
|
+
async function reserveMetroPort(projectPath, probe = isMetroRunning, isFree, pinned = null) {
|
|
86
255
|
if (pinned !== null) {
|
|
87
256
|
if (claimMetroPort(projectPath, pinned) !== null) return pinned;
|
|
88
257
|
throw new Error(`metro.port ${pinned} is already reserved by another workspace's Metro or named port.`);
|
|
@@ -116,10 +285,6 @@ function parseLsofPids(out) {
|
|
|
116
285
|
if (!out) return [];
|
|
117
286
|
return String(out).split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => Number.isFinite(n));
|
|
118
287
|
}
|
|
119
|
-
function addressPort(address) {
|
|
120
|
-
const colon = String(address ?? "").lastIndexOf(":");
|
|
121
|
-
return colon < 0 ? NaN : Number(String(address).slice(colon + 1));
|
|
122
|
-
}
|
|
123
288
|
function parseNetstatPids(out, port) {
|
|
124
289
|
const pids = [];
|
|
125
290
|
for (const line of String(out ?? "").split("\n")) {
|
|
@@ -147,18 +312,6 @@ function parseLsofCwd(out) {
|
|
|
147
312
|
function lsofOutput(args) {
|
|
148
313
|
return getExecutor().runFileAsync("lsof", args).catch((error) => typeof error?.stdout === "string" ? error.stdout : null);
|
|
149
314
|
}
|
|
150
|
-
function parseLsofListeners(out) {
|
|
151
|
-
const byPort = /* @__PURE__ */ new Map();
|
|
152
|
-
let pid = null;
|
|
153
|
-
for (const line of String(out ?? "").split("\n")) if (line.startsWith("p")) pid = parseInt(line.slice(1), 10);
|
|
154
|
-
else if (line.startsWith("n") && pid !== null && Number.isFinite(pid)) {
|
|
155
|
-
const port = addressPort(line.slice(1));
|
|
156
|
-
const pids = byPort.get(port) ?? [];
|
|
157
|
-
if (!pids.includes(pid)) pids.push(pid);
|
|
158
|
-
byPort.set(port, pids);
|
|
159
|
-
}
|
|
160
|
-
return byPort;
|
|
161
|
-
}
|
|
162
315
|
/**
|
|
163
316
|
* `listeningPids` for several ports with one lsof call. A port lsof could not be asked about is
|
|
164
317
|
* missing from the map.
|
|
@@ -306,4 +459,4 @@ function killMetroTree(leader, processToken) {
|
|
|
306
459
|
}
|
|
307
460
|
}
|
|
308
461
|
//#endregion
|
|
309
|
-
export { listeningPidsByPort as a,
|
|
462
|
+
export { listeningPidsByPort as a, processCwd as c, signalProcessTree as d, createPortProbe as f, PortInspectionError as g, PORT_INSPECTION_REMEDY as h, listeningPids as i, processCwds as l, reserveMetroPort as m, isInsideProject as n, parseNetstatPids as o, isMetroRunning as p, killMetroTree as r, pidExists as s, NOT_OURS_FOREIGN_CWD as t, resolveProjectMetro as u };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as process_identity_exports } from "./process-identity-
|
|
2
|
-
import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-
|
|
3
|
-
import {
|
|
4
|
-
import { randomBytes, randomUUID } from "node:crypto";
|
|
1
|
+
import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { a as updateWorkspaceState, r as readWorkspaceState$1 } from "./workspace-state-CR9X86xJ.mjs";
|
|
3
|
+
import { L as realIo } from "./client-CuUo8Nvg.mjs";
|
|
5
4
|
import { HOSTED_METRO_REQUESTS_KEY, findPeer, hostedMetroGateways, hostedMetroRequests, isJsonObject, parseMachine } from "@stim-cli/core/state";
|
|
5
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
6
6
|
import { isIP } from "node:net";
|
|
7
7
|
//#region src/device-host/metro-gateway.ts
|
|
8
8
|
function gatewayAddresses(credential, status) {
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
-
import { METRO_NAMED_CACHE_LAYOUT, metroCacheRoot, registerCache, sharedStoreRoot, tagSharedStore } from "@stim-cli/core";
|
|
4
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { METRO_NAMED_CACHE_LAYOUT, metroCacheRoot, registerCache, sharedStoreRoot, tagSharedStore } from "@stim-cli/core";
|
|
5
|
+
//#region src/supervisor/errors.ts
|
|
6
|
+
function supervisorError(code, message, remedy) {
|
|
7
|
+
const err = new Error(message);
|
|
8
|
+
err.code = code;
|
|
9
|
+
if (remedy) err.remedy = remedy;
|
|
10
|
+
return err;
|
|
11
|
+
}
|
|
12
|
+
function describeError(err) {
|
|
13
|
+
if (!err) return "unknown error";
|
|
14
|
+
const e = err;
|
|
15
|
+
const message = e.message || String(err);
|
|
16
|
+
return `${e.code ? `${e.code}: ` : ""}${message}${e.remedy ? ` Remedy: ${e.remedy}` : ""}`;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
5
19
|
//#region src/supervisor/metro-store.ts
|
|
6
20
|
function metroStoreName(root) {
|
|
7
21
|
try {
|
|
@@ -89,4 +103,4 @@ function expoMetroStoreEnv({ root, storeRoot, adapterPath, existingOverride }) {
|
|
|
89
103
|
};
|
|
90
104
|
}
|
|
91
105
|
//#endregion
|
|
92
|
-
export { metroStoreRoot as a, metroStoreConfirmedRoot as i, expoMetroConfigPath as n, registerMetroStore as o, expoMetroStoreEnv as r, appendCacheStore as t };
|
|
106
|
+
export { metroStoreRoot as a, supervisorError as c, metroStoreConfirmedRoot as i, expoMetroConfigPath as n, registerMetroStore as o, expoMetroStoreEnv as r, describeError as s, appendCacheStore as t };
|