stim 0.0.0 → 1.1.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/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/android-CC5bUer7.mjs +204 -0
- package/dist/android-DnZlT3aU.mjs +2279 -0
- package/dist/android-cas-DGlTStWu.mjs +1078 -0
- package/dist/android-cas-compiler.d.mts +1 -0
- package/dist/android-cas-compiler.mjs +71 -0
- package/dist/android-xmyGBNy5.mjs +665 -0
- package/dist/app-install-oZIQRbdD.mjs +1141 -0
- package/dist/build-lock-vE45ZzJZ.mjs +645 -0
- package/dist/build-slots-CgacA9zQ.mjs +152 -0
- package/dist/cache-manifest-oeH18ERr.mjs +66 -0
- package/dist/cache-manifest.d.mts +27 -0
- package/dist/cache-manifest.mjs +2 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +40 -0
- package/dist/collector-run.d.mts +119 -0
- package/dist/collector-run.mjs +541 -0
- package/dist/command-output-8wHMEde0.mjs +289 -0
- package/dist/config-D7uu8Gbq.mjs +381 -0
- package/dist/deps-64wVnpZc.mjs +435 -0
- package/dist/dev-client-Bvky1hya.mjs +557 -0
- package/dist/device-DJKv5Qej.mjs +250 -0
- package/dist/device-lease-D-G3SgVe.mjs +335 -0
- package/dist/device-pool-BlHXnYYs.mjs +408 -0
- package/dist/device-remote-CCgkG82J.mjs +1209 -0
- package/dist/doctor-BRF9aAJ3.mjs +530 -0
- package/dist/doctor-DlVxTtMq.mjs +1137 -0
- package/dist/error-diagnostics-B5IJwv3-.mjs +636 -0
- package/dist/errors-B6W7FkxQ.mjs +15 -0
- package/dist/exec-bsN9MJXb.mjs +63 -0
- package/dist/gc-DhXdgSdt.mjs +1651 -0
- package/dist/guide-DrhrDBo5.mjs +4319 -0
- package/dist/ios-BZxKPuqP.mjs +382 -0
- package/dist/ios-CK1Vrk6Q.mjs +2721 -0
- package/dist/ios-device-CYbuRNXR.mjs +81 -0
- package/dist/ios-device-CdSm0GDw.mjs +413 -0
- package/dist/logs-Dxoy16Qv.mjs +176 -0
- package/dist/logs-query-oqn47Ffx.mjs +273 -0
- package/dist/metro-B01H3EuD.mjs +184 -0
- package/dist/metro-store-CDDZHtPl.mjs +92 -0
- package/dist/ndjson-DcAtEx_K.mjs +131 -0
- package/dist/ndjson-DvHSsNU9.d.mts +16 -0
- package/dist/ownership-B9QIdQOw.mjs +475 -0
- package/dist/ownership-D8HmSv2E.mjs +60 -0
- package/dist/ownership-claim-CeJLEpjD.mjs +569 -0
- package/dist/process-output-C7IlIzd7.mjs +40 -0
- package/dist/project-COj6nzzh.mjs +243 -0
- package/dist/reclaim-BPvN2HlP.mjs +347 -0
- package/dist/reload-DYZEBbZy.mjs +332 -0
- package/dist/remote-cache-DOi5-zLj.mjs +934 -0
- package/dist/server-bare-BYHqEeyw.mjs +352 -0
- package/dist/server-expo-BEMr_m6p.mjs +312 -0
- package/dist/server-expo-rb0k-0w7.mjs +2 -0
- package/dist/settings-BSwrY4FZ.mjs +687 -0
- package/dist/spawn-entry-nCE6m770.mjs +14 -0
- package/dist/start-ByCylYtB.mjs +822 -0
- package/dist/state-IYEY-zi8.mjs +268 -0
- package/dist/stats-DZ4Q5J-7.mjs +62 -0
- package/dist/stats-wqxPm7Tv.mjs +307 -0
- package/dist/status-Dia0XTqG.mjs +363 -0
- package/dist/stop-BApyaF21.mjs +591 -0
- package/dist/stop-D6o5zAdm.mjs +3 -0
- package/dist/supervisor-run.d.mts +84 -0
- package/dist/supervisor-run.mjs +210 -0
- package/dist/workspace-process-lock-CxOO9-pf.mjs +47 -0
- package/dist/worktree-Dx3ZC5lS.mjs +539 -0
- package/dist/worktree-DxEmUI_n.mjs +1322 -0
- package/dist/xcode-CDB6fytw.mjs +1705 -0
- package/package.json +61 -8
- package/shim/android-cas-pch.cmake +35 -0
- package/shim/android-cas.gradle +29 -0
- package/shim/android-cas.toolchain.cmake +12 -0
- package/shim/android-optimizations.gradle +30 -0
- package/shim/bundle-response.cjs +46 -0
- package/shim/bundle-response.d.cts +5 -0
- package/shim/expo-metro-config.cjs +188 -0
- package/shim/metro-cache-generation.cjs +20 -0
- package/shim/metro-cache-generation.d.cts +5 -0
- package/skill/SKILL.md +14 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { T as captureProcessToken, a as clearSupervisor, x as setSupervisor } from "./config-D7uu8Gbq.mjs";
|
|
2
|
+
import { r as createNdjsonWriter } from "./ndjson-DcAtEx_K.mjs";
|
|
3
|
+
import { D as workspaceLogsDir, _ as writeWorkspaceState, h as writePidFile, l as readPidFile, m as withWorkspaceStateLock, n as MODE_EXPO, p as readWorkspaceState, r as clearExpoMetroTunnel, s as clearWorkspaceSupervisor, t as MODE_BARE } from "./state-IYEY-zi8.mjs";
|
|
4
|
+
import { i as detectIsExpo } from "./project-COj6nzzh.mjs";
|
|
5
|
+
import { t as describeError } from "./errors-B6W7FkxQ.mjs";
|
|
6
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
7
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
//#region src/supervisor/run.ts
|
|
10
|
+
function parseArgs(argv) {
|
|
11
|
+
let root;
|
|
12
|
+
let port;
|
|
13
|
+
let tunnel = false;
|
|
14
|
+
for (let i = 0; i < argv.length; i++) {
|
|
15
|
+
const arg = argv[i];
|
|
16
|
+
if (arg === "--root") {
|
|
17
|
+
root = argv[++i];
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (arg === "--port") {
|
|
21
|
+
port = argv[++i];
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (arg === "--tunnel") {
|
|
25
|
+
tunnel = true;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
return { error: `Unknown supervisor argument "${arg}". Usage: run.js --root <path> --port <n> [--tunnel]` };
|
|
29
|
+
}
|
|
30
|
+
if (!root) return { error: "Missing --root. Usage: run.js --root <path> --port <n> [--tunnel]" };
|
|
31
|
+
if (!isAbsolute(root)) return { error: `--root must be an absolute path, got "${root}".` };
|
|
32
|
+
const parsedPort = Number(port);
|
|
33
|
+
if (!Number.isInteger(parsedPort) || parsedPort <= 0 || parsedPort > 65535) return { error: `--port must be a TCP port number, got "${port}".` };
|
|
34
|
+
return {
|
|
35
|
+
root: resolve(root),
|
|
36
|
+
port: parsedPort,
|
|
37
|
+
tunnel
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function runSupervisor({ root, port, tunnel = false, isExpo = detectIsExpo, startBare = null, startExpo = null, now = Date.now, onExit = (code) => process.exit(code), attachSignals = true, stderr = (line) => console.error(line) }) {
|
|
41
|
+
root = realpathSync(root);
|
|
42
|
+
const logsDir = workspaceLogsDir(root);
|
|
43
|
+
const writer = createNdjsonWriter(join(logsDir, "metro.ndjson"));
|
|
44
|
+
const mode = isExpo(root) ? MODE_EXPO : MODE_BARE;
|
|
45
|
+
const startedAt = new Date(now()).toISOString();
|
|
46
|
+
const processToken = captureProcessToken(process.pid);
|
|
47
|
+
if (!processToken) {
|
|
48
|
+
stderr("Stim supervisor: could not capture process identity; refusing to start an unmanaged server.");
|
|
49
|
+
writer.close();
|
|
50
|
+
onExit(1);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const record = {
|
|
54
|
+
pid: process.pid,
|
|
55
|
+
processToken,
|
|
56
|
+
port,
|
|
57
|
+
mode,
|
|
58
|
+
startedAt
|
|
59
|
+
};
|
|
60
|
+
clearExpoMetroTunnel(root);
|
|
61
|
+
writePidFile(root, process.pid);
|
|
62
|
+
writeWorkspaceState(root, { supervisor: record });
|
|
63
|
+
try {
|
|
64
|
+
setSupervisor(root, record);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
writer.write({
|
|
67
|
+
src: "metro",
|
|
68
|
+
level: "warn",
|
|
69
|
+
event: "supervisor_registration_failed",
|
|
70
|
+
msg: `Could not record the supervisor in the global config: ${describeError(err)}`
|
|
71
|
+
});
|
|
72
|
+
stderr(`Stim supervisor: global registration failed: ${describeError(err)}`);
|
|
73
|
+
}
|
|
74
|
+
writer.write({
|
|
75
|
+
src: "metro",
|
|
76
|
+
level: "info",
|
|
77
|
+
event: "supervisor_started",
|
|
78
|
+
msg: `supervisor pid ${process.pid} starting the ${mode} dev server on port ${port} for ${root}`
|
|
79
|
+
});
|
|
80
|
+
let stopping = false;
|
|
81
|
+
const finish = (code, event, level, msg) => {
|
|
82
|
+
writer.write({
|
|
83
|
+
src: "metro",
|
|
84
|
+
level,
|
|
85
|
+
event,
|
|
86
|
+
msg
|
|
87
|
+
});
|
|
88
|
+
try {
|
|
89
|
+
clearSupervisor(root, record);
|
|
90
|
+
} catch {}
|
|
91
|
+
try {
|
|
92
|
+
clearWorkspaceSupervisor(root, record);
|
|
93
|
+
} catch {}
|
|
94
|
+
const closed = writer.close();
|
|
95
|
+
if (closed.dropped > 0) stderr(`Stim supervisor: dropped ${closed.dropped} log record(s); last error: ${describeError(closed.lastError)}`);
|
|
96
|
+
onExit(code);
|
|
97
|
+
};
|
|
98
|
+
let server;
|
|
99
|
+
try {
|
|
100
|
+
server = await (mode === "expo-child" ? startExpo || (await import("./server-expo-rb0k-0w7.mjs")).startExpoServer : startBare || (await import("./server-bare-BYHqEeyw.mjs")).startBareServer)({
|
|
101
|
+
root,
|
|
102
|
+
port,
|
|
103
|
+
logsDir,
|
|
104
|
+
writer,
|
|
105
|
+
tunnel,
|
|
106
|
+
onTunnelUrl: (url) => {
|
|
107
|
+
try {
|
|
108
|
+
withWorkspaceStateLock(root, () => {
|
|
109
|
+
if (readWorkspaceState(root)?.supervisor?.processToken === processToken) writeWorkspaceState(root, { metroTunnel: {
|
|
110
|
+
kind: "expo",
|
|
111
|
+
url
|
|
112
|
+
} });
|
|
113
|
+
});
|
|
114
|
+
} catch (err) {
|
|
115
|
+
stderr(`Stim supervisor: could not record the Expo tunnel URL: ${describeError(err)}`);
|
|
116
|
+
}
|
|
117
|
+
writer.write({
|
|
118
|
+
src: "metro",
|
|
119
|
+
level: "info",
|
|
120
|
+
event: "expo_tunnel_ready",
|
|
121
|
+
msg: `Expo tunnel ready: ${url}`
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
} catch (err) {
|
|
126
|
+
stderr(`Stim supervisor: failed to start the ${mode} dev server: ${describeError(err)}`);
|
|
127
|
+
finish(1, "supervisor_failed", "fatal", `failed to start the ${mode} dev server: ${describeError(err)}`);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const readyServer = server;
|
|
131
|
+
if (readyServer.serverPid) withWorkspaceStateLock(root, () => {
|
|
132
|
+
if (readWorkspaceState(root)?.supervisor?.processToken === processToken) writeWorkspaceState(root, { supervisor: {
|
|
133
|
+
...record,
|
|
134
|
+
serverPid: readyServer.serverPid
|
|
135
|
+
} });
|
|
136
|
+
});
|
|
137
|
+
writer.write({
|
|
138
|
+
src: "metro",
|
|
139
|
+
level: "info",
|
|
140
|
+
event: "server_started",
|
|
141
|
+
msg: `${mode} dev server listening on port ${port}`
|
|
142
|
+
});
|
|
143
|
+
const shutdown = async (code, event, msg) => {
|
|
144
|
+
if (stopping) return;
|
|
145
|
+
stopping = true;
|
|
146
|
+
try {
|
|
147
|
+
await readyServer.close();
|
|
148
|
+
} catch (err) {
|
|
149
|
+
writer.write({
|
|
150
|
+
src: "metro",
|
|
151
|
+
level: "warn",
|
|
152
|
+
event: "server_close_failed",
|
|
153
|
+
msg: describeError(err)
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
finish(code, event, code === 0 ? "info" : "error", msg);
|
|
157
|
+
};
|
|
158
|
+
readyServer.onExit?.((info) => {
|
|
159
|
+
if (stopping) return;
|
|
160
|
+
const detail = info?.signal ? `signal ${info.signal}` : `exit code ${info?.code ?? "unknown"}`;
|
|
161
|
+
shutdown(1, "supervisor_stopped", `the ${mode} dev server exited unexpectedly (${detail}); shutting the supervisor down`);
|
|
162
|
+
});
|
|
163
|
+
if (attachSignals) for (const signal of ["SIGTERM", "SIGINT"]) process.on(signal, () => {
|
|
164
|
+
shutdown(0, "supervisor_stopped", `received ${signal}; stopping the ${mode} dev server`);
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
mode,
|
|
168
|
+
server,
|
|
169
|
+
shutdown,
|
|
170
|
+
startedAt
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async function main(argv = process.argv.slice(2)) {
|
|
174
|
+
const parsed = parseArgs(argv);
|
|
175
|
+
if (parsed.error) {
|
|
176
|
+
console.error(`Stim supervisor: ${parsed.error}`);
|
|
177
|
+
process.exit(2);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const root = parsed.root;
|
|
181
|
+
if (!existsSync(root)) {
|
|
182
|
+
console.error(`Stim supervisor: --root ${root} does not exist.`);
|
|
183
|
+
process.exit(2);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
process.chdir(root);
|
|
188
|
+
} catch {}
|
|
189
|
+
process.title = "stim-supervisor";
|
|
190
|
+
await runSupervisor({
|
|
191
|
+
root,
|
|
192
|
+
port: parsed.port,
|
|
193
|
+
tunnel: parsed.tunnel ?? false
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function invokedDirectly() {
|
|
197
|
+
const entry = process.argv[1];
|
|
198
|
+
if (!entry) return false;
|
|
199
|
+
try {
|
|
200
|
+
return resolve(entry) === fileURLToPath(import.meta.url);
|
|
201
|
+
} catch {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (invokedDirectly()) main().catch((err) => {
|
|
206
|
+
console.error(`Stim supervisor: ${describeError(err)}`);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
});
|
|
209
|
+
//#endregion
|
|
210
|
+
export { MODE_BARE, MODE_EXPO, clearExpoMetroTunnel, clearWorkspaceSupervisor, main, parseArgs, readPidFile, readWorkspaceState, runSupervisor, withWorkspaceStateLock, writePidFile, writeWorkspaceState };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { f as releaseClaim, h as tryAcquireClaim } from "./ownership-claim-CeJLEpjD.mjs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
//#region src/engine/workspace-process-lock.ts
|
|
4
|
+
const DEFAULT_WAIT_MS = 6e4;
|
|
5
|
+
const POLL_MS = 25;
|
|
6
|
+
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
|
+
function workspaceProcessLockError(err) {
|
|
8
|
+
const code = err?.code;
|
|
9
|
+
if (code === "STIM_LOCK_REFUSED") return "refused";
|
|
10
|
+
if (code === "STIM_LOCK_TIMEOUT") return "timeout";
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
function lockPath(root, name, external) {
|
|
14
|
+
return external ? join(root, `${name}.lock`) : join(root, ".stim", `${name}.lock`);
|
|
15
|
+
}
|
|
16
|
+
async function withWorkspaceProcessLock(root, name, fn, { now = Date.now, sleep = defaultSleep, waitMs = DEFAULT_WAIT_MS, ownerPurpose, rejectOwnerPurposes = [], external = false } = {}) {
|
|
17
|
+
const path = lockPath(root, name, external);
|
|
18
|
+
const deadline = now() + waitMs;
|
|
19
|
+
for (;;) {
|
|
20
|
+
const attempt = tryAcquireClaim({
|
|
21
|
+
root: path,
|
|
22
|
+
mode: "exclusive",
|
|
23
|
+
label: `${name} lock`,
|
|
24
|
+
details: ownerPurpose ? { purpose: ownerPurpose } : {}
|
|
25
|
+
});
|
|
26
|
+
if (attempt.pending) releaseClaim(attempt.pending);
|
|
27
|
+
if (attempt.acquired) try {
|
|
28
|
+
return await fn();
|
|
29
|
+
} finally {
|
|
30
|
+
releaseClaim(attempt.acquired);
|
|
31
|
+
}
|
|
32
|
+
const purpose = (attempt.held ?? attempt.waitingFor?.[0])?.details.purpose;
|
|
33
|
+
if (typeof purpose === "string" && rejectOwnerPurposes.includes(purpose)) {
|
|
34
|
+
const error = /* @__PURE__ */ new Error(`The ${name} lock at ${path} is held for ${purpose}.`);
|
|
35
|
+
error.code = "STIM_LOCK_REFUSED";
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
if (now() >= deadline) {
|
|
39
|
+
const error = /* @__PURE__ */ new Error(`Timed out waiting for the ${name} lock at ${path}.`);
|
|
40
|
+
error.code = "STIM_LOCK_TIMEOUT";
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
await sleep(POLL_MS);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { workspaceProcessLockError as n, withWorkspaceProcessLock as t };
|