stim 1.3.1 → 1.4.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 +13 -0
- package/dist/{android-CT-PkXUh.mjs → android-BTR1KTMP.mjs} +197 -114
- package/dist/{android-hMj83VpN.mjs → android-BkM4qTaN.mjs} +65 -72
- package/dist/{android-cas-DXorPCi_.mjs → android-cas-BjLRZyks.mjs} +15 -12
- package/dist/{app-install-DIp9riNx.mjs → app-install--PAocWvq.mjs} +2 -2
- package/dist/{build-slots-C4AouyNz.mjs → build-slots-D6sDzOe-.mjs} +7 -8
- package/dist/{cache-manifest-CXR-Y8pH.mjs → cache-manifest-D02TpYjA.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +14 -13
- package/dist/collector-run.mjs +4 -4
- package/dist/{command-output-8wHMEde0.mjs → command-output-BuIb_ZOI.mjs} +1 -4
- package/dist/{config-CcefMY2Q.mjs → config-6vdGngKa.mjs} +51 -51
- package/dist/dependency-state-BMirHEPD.mjs +76 -0
- package/dist/{deps-0Yt0Inly.mjs → deps-Ck4wuTwa.mjs} +1 -1
- package/dist/{dev-client-VfSZNLT4.mjs → dev-client-Cd0v7iZk.mjs} +12 -12
- package/dist/{device-Bbv45Z9Z.mjs → device-CKXLnRRb.mjs} +7 -7
- package/dist/{xcode-xnxyvJkD.mjs → device-CMDFzx7C.mjs} +208 -967
- package/dist/{device-lease-CJwK7OZr.mjs → device-lease-DDJr85OK.mjs} +3 -3
- package/dist/{device-pool-CcBNTvM7.mjs → device-pool-DJvbIBGW.mjs} +4 -4
- package/dist/{device-remote-DAA0Zm6Z.mjs → device-remote-CMfHhoc8.mjs} +7 -6
- package/dist/{doctor-B4EITgQB.mjs → doctor-B_mfURdt.mjs} +536 -114
- package/dist/{error-diagnostics-DwhNBFDU.mjs → error-diagnostics-_VmkqRZo.mjs} +7 -6
- package/dist/{gc-BRu62v4o.mjs → gc-0AyxmECv.mjs} +61 -27
- package/dist/{guide-D95E0u3i.mjs → guide-CGxdmQ0K.mjs} +126 -7
- package/dist/{ios-DAju3TVy.mjs → ios-CtmGLx3X.mjs} +2667 -2607
- package/dist/{ios-device-CWOM_S44.mjs → ios-device-DJOi9FR5.mjs} +1 -1
- package/dist/{logs-CAdwW6c2.mjs → logs-BF3qPA7w.mjs} +5 -5
- package/dist/metro-DFLmaVz8.mjs +99 -0
- package/dist/named-ports-BO7Zpjp0.mjs +137 -0
- package/dist/{ownership-8O073GIC.mjs → ownership-BvSpZVBk.mjs} +5 -5
- package/dist/{ownership-DXcol4oU.mjs → ownership-C08Yzrp7.mjs} +6 -6
- package/dist/ports-BiKqP92J.mjs +39 -0
- package/dist/ports-ClqG8GPt.mjs +90 -0
- package/dist/{project-fKmuIaMI.mjs → project-CBFCwnN5.mjs} +2 -2
- package/dist/{reclaim-CUmwucWG.mjs → reclaim-DpDVo-AP.mjs} +20 -13
- package/dist/{reload-CWpXoOgN.mjs → reload-ByTqg6ZI.mjs} +8 -8
- package/dist/rolldown-runtime-BsOwBuO_.mjs +30 -0
- package/dist/{server-bare-DEzPZLvf.mjs → server-bare-Buk-k8tI.mjs} +3 -6
- package/dist/{server-expo-DizT4OMk.mjs → server-expo-D4P7iTvf.mjs} +3 -3
- package/dist/server-expo-Dho5Raiw.mjs +2 -0
- package/dist/{settings-DEJf6_kJ.mjs → settings-DwfltIXQ.mjs} +2 -2
- package/dist/{slot-launch-CZklomj6.mjs → slot-launch-DeKen9e5.mjs} +4 -4
- package/dist/{start-B5G4NjiA.mjs → start-BpKUHcU_.mjs} +15 -13
- package/dist/state-CDbvmZdt.mjs +131 -0
- package/dist/{stats-BR-kwj0B.mjs → stats-C59QLKm2.mjs} +1 -1
- package/dist/{stats-CaaQr4yN.mjs → stats-k5qMjyxo.mjs} +4 -4
- package/dist/{status-CI9clRSb.mjs → status-Y2ij3dm6.mjs} +12 -11
- package/dist/{stop-CjlgDk0a.mjs → stop-_P2OQwmZ.mjs} +15 -14
- package/dist/{stop-CQhffpmX.mjs → stop-vKmmxhea.mjs} +2 -2
- package/dist/supervisor-run.d.mts +3 -27
- package/dist/supervisor-run.mjs +7 -6
- package/dist/{teardown--gESs9ck.mjs → teardown-KsPpvldq.mjs} +148 -109
- package/dist/{workspace-process-lock-IBj1Towr.mjs → workspace-process-lock-UEIrvZMJ.mjs} +4 -4
- package/dist/workspace-state-Do1e2mOH.mjs +146 -0
- package/dist/{worktree-DtQGO9-s.mjs → worktree-BvcAIMdJ.mjs} +24 -25
- package/dist/{worktree-Eq6TLH8N.mjs → worktree-DWNx4tUg.mjs} +32 -2
- package/dist/xcode-D9tVItl-.mjs +860 -0
- package/package.json +7 -7
- package/dist/doctor-BueDfLYG.mjs +0 -530
- package/dist/metro-CORqXyTL.mjs +0 -184
- package/dist/ownership-claim-BtPtJVmq.mjs +0 -584
- package/dist/server-expo-44em5Pmg.mjs +0 -2
- package/dist/state-B3XA2wp2.mjs +0 -268
package/dist/metro-CORqXyTL.mjs
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { E as inspectProcessIdentity, M as isOnMountedVolume, N as listMountedVolumes, g as loadConfig, n as allMetroPorts, r as claimMetroPort, v as removeProject } from "./config-CcefMY2Q.mjs";
|
|
3
|
-
import { p as readWorkspaceState } from "./state-B3XA2wp2.mjs";
|
|
4
|
-
import { existsSync, readlinkSync, realpathSync } from "fs";
|
|
5
|
-
import { sep } from "path";
|
|
6
|
-
import { request } from "http";
|
|
7
|
-
import { connect } from "net";
|
|
8
|
-
//#region src/ports.ts
|
|
9
|
-
function isMetroRunning(port) {
|
|
10
|
-
return new Promise((resolve) => {
|
|
11
|
-
const req = request({
|
|
12
|
-
hostname: "localhost",
|
|
13
|
-
port,
|
|
14
|
-
path: "/status",
|
|
15
|
-
timeout: 2e3
|
|
16
|
-
}, (res) => {
|
|
17
|
-
let data = "";
|
|
18
|
-
res.on("data", (chunk) => {
|
|
19
|
-
data += chunk;
|
|
20
|
-
});
|
|
21
|
-
res.on("end", () => resolve(data.includes("packager-status:running")));
|
|
22
|
-
});
|
|
23
|
-
req.on("error", () => resolve(false));
|
|
24
|
-
req.on("timeout", () => {
|
|
25
|
-
req.destroy();
|
|
26
|
-
resolve(false);
|
|
27
|
-
});
|
|
28
|
-
req.end();
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function isPortFree(port, { timeoutMs = 400 } = {}) {
|
|
32
|
-
return new Promise((resolve) => {
|
|
33
|
-
const sock = connect({
|
|
34
|
-
port,
|
|
35
|
-
host: "127.0.0.1"
|
|
36
|
-
});
|
|
37
|
-
const done = (free) => {
|
|
38
|
-
sock.removeAllListeners();
|
|
39
|
-
sock.destroy();
|
|
40
|
-
resolve(free);
|
|
41
|
-
};
|
|
42
|
-
sock.setTimeout(timeoutMs);
|
|
43
|
-
sock.once("connect", () => done(false));
|
|
44
|
-
sock.once("error", () => done(true));
|
|
45
|
-
sock.once("timeout", () => done(false));
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
const FIRST_PORT = 8082;
|
|
49
|
-
async function computeNextPort(isFree = isPortFree) {
|
|
50
|
-
const taken = new Set(allMetroPorts());
|
|
51
|
-
for (let port = FIRST_PORT; port < 8282; port++) {
|
|
52
|
-
if (taken.has(port)) continue;
|
|
53
|
-
if (await isFree(port)) return port;
|
|
54
|
-
}
|
|
55
|
-
throw new Error(`Found no free Metro port between ${FIRST_PORT} and 8281. Free one up, or stop a stale bundler (\`stim status\`, \`stim stop <port>\`).`);
|
|
56
|
-
}
|
|
57
|
-
async function findReclaimablePort(excludeProjectPath, probe = isMetroRunning, { isMounted = isOnMountedVolume, mountedVolumes } = {}) {
|
|
58
|
-
const cfg = loadConfig();
|
|
59
|
-
if (!cfg?.projects) return null;
|
|
60
|
-
const mounted = mountedVolumes || listMountedVolumes();
|
|
61
|
-
const candidates = [];
|
|
62
|
-
for (const [path, proj] of Object.entries(cfg.projects)) {
|
|
63
|
-
if (path === excludeProjectPath) continue;
|
|
64
|
-
if (existsSync(path)) continue;
|
|
65
|
-
if (!isMounted(path, mounted)) continue;
|
|
66
|
-
if (typeof proj.metroPort === "number") candidates.push({
|
|
67
|
-
port: proj.metroPort,
|
|
68
|
-
ownerPath: path
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
for (const c of candidates) if (!await probe(c.port)) return c;
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
async function allocatePort(projectPath, probe = isMetroRunning, isFree = isPortFree) {
|
|
75
|
-
const reclaim = await findReclaimablePort(projectPath, probe);
|
|
76
|
-
if (reclaim && await isFree(reclaim.port)) {
|
|
77
|
-
removeProject(reclaim.ownerPath);
|
|
78
|
-
return reclaim.port;
|
|
79
|
-
}
|
|
80
|
-
return computeNextPort(isFree);
|
|
81
|
-
}
|
|
82
|
-
const RESERVE_ATTEMPTS = 5;
|
|
83
|
-
async function reserveMetroPort(projectPath, probe = isMetroRunning, isFree = isPortFree) {
|
|
84
|
-
for (let attempt = 0; attempt < RESERVE_ATTEMPTS; attempt++) {
|
|
85
|
-
const port = await allocatePort(projectPath, probe, isFree);
|
|
86
|
-
const claimed = claimMetroPort(projectPath, port);
|
|
87
|
-
if (claimed !== null) return claimed;
|
|
88
|
-
}
|
|
89
|
-
throw new Error(`Could not reserve a Metro port after ${RESERVE_ATTEMPTS} attempts: another Stim run claimed each one first. Retry.`);
|
|
90
|
-
}
|
|
91
|
-
//#endregion
|
|
92
|
-
//#region src/metro.ts
|
|
93
|
-
/**
|
|
94
|
-
* True when some process with this pid exists right now. It cannot tell a recycled pid from the
|
|
95
|
-
* process that first held it, so it is only valid for a pid this run spawned and still holds a
|
|
96
|
-
* handle on. For a pid read from a record on disk, decide with `inspectProcessIdentity` on that
|
|
97
|
-
* record's process token, or take an ownership claim (`ownership-claim.ts`): this answer would keep
|
|
98
|
-
* a dead holder's record looking live until some unrelated process exits.
|
|
99
|
-
*/
|
|
100
|
-
function pidExists(pid) {
|
|
101
|
-
if (!Number.isSafeInteger(pid) || pid <= 0) return false;
|
|
102
|
-
try {
|
|
103
|
-
process.kill(pid, 0);
|
|
104
|
-
return true;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
return error.code !== "ESRCH";
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function parseLsofPids(out) {
|
|
110
|
-
if (!out) return [];
|
|
111
|
-
return String(out).split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => Number.isFinite(n));
|
|
112
|
-
}
|
|
113
|
-
function parseLsofCwd(out) {
|
|
114
|
-
if (!out) return null;
|
|
115
|
-
const lines = String(out).split("\n");
|
|
116
|
-
const idx = lines.findIndex((l) => l === "fcwd");
|
|
117
|
-
if (idx === -1) return null;
|
|
118
|
-
const nLine = lines.slice(idx + 1).find((l) => l.startsWith("n"));
|
|
119
|
-
return nLine ? nLine.slice(1) : null;
|
|
120
|
-
}
|
|
121
|
-
function processCwd(pid) {
|
|
122
|
-
if (process.platform === "linux") try {
|
|
123
|
-
return readlinkSync(`/proc/${pid}/cwd`);
|
|
124
|
-
} catch {}
|
|
125
|
-
return parseLsofCwd(getExecutor().runQuiet(`lsof -a -p ${pid} -d cwd -Fn`));
|
|
126
|
-
}
|
|
127
|
-
function canonicalPath(path) {
|
|
128
|
-
try {
|
|
129
|
-
return realpathSync(path);
|
|
130
|
-
} catch {
|
|
131
|
-
return path;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function isInsideProject(cwd, projectPath) {
|
|
135
|
-
if (!cwd || !projectPath) return false;
|
|
136
|
-
const a = canonicalPath(cwd);
|
|
137
|
-
const b = canonicalPath(projectPath);
|
|
138
|
-
return a === b || a.startsWith(b.endsWith(sep) ? b : b + sep);
|
|
139
|
-
}
|
|
140
|
-
const NOT_OURS_UNRESPONSIVE = "unresponsive";
|
|
141
|
-
const NOT_OURS_UNREADABLE_CWD = "unreadable-cwd";
|
|
142
|
-
const NOT_OURS_FOREIGN_CWD = "foreign-cwd";
|
|
143
|
-
async function resolveProjectMetro(port, projectPath, { probe = isMetroRunning } = {}) {
|
|
144
|
-
const pid = parseLsofPids(getExecutor().runQuiet(`lsof -nP -iTCP:${port} -sTCP:LISTEN -t`))[0];
|
|
145
|
-
if (pid === void 0) return { missing: true };
|
|
146
|
-
if (!await probe(port)) return {
|
|
147
|
-
notOurs: `pid ${pid} on port ${port} does not answer Metro's /status`,
|
|
148
|
-
kind: NOT_OURS_UNRESPONSIVE,
|
|
149
|
-
pid
|
|
150
|
-
};
|
|
151
|
-
const cwd = processCwd(pid);
|
|
152
|
-
if (!cwd) return {
|
|
153
|
-
notOurs: `pid ${pid} on port ${port}: working directory could not be read`,
|
|
154
|
-
kind: NOT_OURS_UNREADABLE_CWD,
|
|
155
|
-
pid
|
|
156
|
-
};
|
|
157
|
-
if (!isInsideProject(cwd, projectPath)) return {
|
|
158
|
-
notOurs: `pid ${pid} on port ${port} runs from ${cwd}, outside ${projectPath}`,
|
|
159
|
-
kind: NOT_OURS_FOREIGN_CWD,
|
|
160
|
-
pid
|
|
161
|
-
};
|
|
162
|
-
const supervisor = readWorkspaceState(canonicalPath(projectPath))?.supervisor;
|
|
163
|
-
const owned = supervisor?.port === port && inspectProcessIdentity(supervisor) === "same";
|
|
164
|
-
return { metro: {
|
|
165
|
-
pid,
|
|
166
|
-
leader: owned ? supervisor.pid : pid,
|
|
167
|
-
cwd,
|
|
168
|
-
...owned ? { processToken: supervisor.processToken } : {}
|
|
169
|
-
} };
|
|
170
|
-
}
|
|
171
|
-
function killMetroTree(leader, processToken) {
|
|
172
|
-
if (!leader || leader === process.pid || inspectProcessIdentity({
|
|
173
|
-
pid: leader,
|
|
174
|
-
processToken
|
|
175
|
-
}) !== "same") return false;
|
|
176
|
-
try {
|
|
177
|
-
process.kill(-leader, "SIGTERM");
|
|
178
|
-
return true;
|
|
179
|
-
} catch {
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
//#endregion
|
|
184
|
-
export { isMetroRunning as a, resolveProjectMetro as i, killMetroTree as n, reserveMetroPort as o, pidExists as r, NOT_OURS_FOREIGN_CWD as t };
|