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,332 @@
|
|
|
1
|
+
import { f as getProject } from "./config-D7uu8Gbq.mjs";
|
|
2
|
+
import { f as readWorkspaceLaunches } from "./state-IYEY-zi8.mjs";
|
|
3
|
+
import { a as findProjectRoot } from "./project-COj6nzzh.mjs";
|
|
4
|
+
import { i as resolveProjectMetro } from "./metro-B01H3EuD.mjs";
|
|
5
|
+
import { l as phaseLine } from "./command-output-8wHMEde0.mjs";
|
|
6
|
+
import { u as androidAppProcess, y as iosAppProcess } from "./app-install-oZIQRbdD.mjs";
|
|
7
|
+
import { b as resolveOwnedIosSim } from "./ios-BZxKPuqP.mjs";
|
|
8
|
+
import { A as resolveOwnedAvdSerial } from "./android-xmyGBNy5.mjs";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import { WebSocket } from "ws";
|
|
11
|
+
//#region src/engine/reload.ts
|
|
12
|
+
const METRO_TIMEOUT_MS = 2e3;
|
|
13
|
+
function describe$1(error) {
|
|
14
|
+
return error instanceof Error ? error.message : String(error);
|
|
15
|
+
}
|
|
16
|
+
const ROLE_NAMES = {
|
|
17
|
+
ios: "iOS",
|
|
18
|
+
android: "Android"
|
|
19
|
+
};
|
|
20
|
+
function peerQuery(metadata) {
|
|
21
|
+
if (typeof metadata === "string") return new URLSearchParams(metadata);
|
|
22
|
+
if (!metadata || typeof metadata !== "object") return null;
|
|
23
|
+
const query = new URLSearchParams();
|
|
24
|
+
for (const [key, value] of Object.entries(metadata)) if (typeof value === "string") query.set(key, value);
|
|
25
|
+
return query;
|
|
26
|
+
}
|
|
27
|
+
function peerMatches(query, role, appId) {
|
|
28
|
+
if (role === "ios") return query.get("role")?.toLowerCase() === "ios";
|
|
29
|
+
return query.get("app") === appId;
|
|
30
|
+
}
|
|
31
|
+
function reloadThroughMetro(port, { role, appId, timeoutMs = METRO_TIMEOUT_MS }) {
|
|
32
|
+
const roleName = ROLE_NAMES[role];
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
const requestId = `stim-reload-${process.pid}-${Date.now()}`;
|
|
35
|
+
const socket = new WebSocket(`ws://127.0.0.1:${port}/message`);
|
|
36
|
+
let settled = false;
|
|
37
|
+
const finish = (result) => {
|
|
38
|
+
if (settled) return;
|
|
39
|
+
settled = true;
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
socket.close();
|
|
42
|
+
resolve(result);
|
|
43
|
+
};
|
|
44
|
+
const timer = setTimeout(() => finish({
|
|
45
|
+
failed: true,
|
|
46
|
+
unreachable: true,
|
|
47
|
+
reason: `Metro did not answer on port ${port}.`
|
|
48
|
+
}), timeoutMs);
|
|
49
|
+
socket.once("open", () => {
|
|
50
|
+
socket.send(JSON.stringify({
|
|
51
|
+
version: 2,
|
|
52
|
+
method: "getpeers",
|
|
53
|
+
target: "server",
|
|
54
|
+
id: requestId
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
socket.on("message", (data) => {
|
|
58
|
+
let message;
|
|
59
|
+
try {
|
|
60
|
+
message = JSON.parse(data.toString());
|
|
61
|
+
} catch {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (message.id !== requestId) return;
|
|
65
|
+
if (message.result && typeof message.result === "object") {
|
|
66
|
+
const entries = Object.entries(message.result);
|
|
67
|
+
const peers = entries.length;
|
|
68
|
+
const rolePeers = entries.filter(([, metadata]) => {
|
|
69
|
+
const query = peerQuery(metadata);
|
|
70
|
+
return query ? peerMatches(query, role, appId) : false;
|
|
71
|
+
});
|
|
72
|
+
if (rolePeers.length === 0) {
|
|
73
|
+
socket.send(JSON.stringify({
|
|
74
|
+
version: 2,
|
|
75
|
+
method: "reload"
|
|
76
|
+
}));
|
|
77
|
+
const others = peers === 0 ? " Nothing at all is connected to it, so the broadcast Stim sent anyway reached nothing." : ` Metro has ${peers} other connected client${peers === 1 ? "" : "s"}, and Stim broadcast a reload to them in case one is this app unmatched.`;
|
|
78
|
+
finish({
|
|
79
|
+
failed: true,
|
|
80
|
+
noPeer: true,
|
|
81
|
+
peers,
|
|
82
|
+
reason: `No ${roleName} React Native app is connected to Metro on port ${port}.${others}`
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
for (const [id] of rolePeers) socket.send(JSON.stringify({
|
|
87
|
+
version: 2,
|
|
88
|
+
method: "reload",
|
|
89
|
+
target: id
|
|
90
|
+
}));
|
|
91
|
+
finish({
|
|
92
|
+
ok: true,
|
|
93
|
+
peers,
|
|
94
|
+
targets: rolePeers.length
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
socket.send(JSON.stringify({
|
|
99
|
+
version: 2,
|
|
100
|
+
method: "reload"
|
|
101
|
+
}));
|
|
102
|
+
finish({
|
|
103
|
+
ok: true,
|
|
104
|
+
broadcast: true
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
socket.once("error", (error) => finish({
|
|
108
|
+
failed: true,
|
|
109
|
+
unreachable: true,
|
|
110
|
+
reason: `Metro reload failed: ${describe$1(error)}`
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/commands/reload.ts
|
|
116
|
+
const DEFAULT_DEPS = {
|
|
117
|
+
findProjectRoot,
|
|
118
|
+
getProject,
|
|
119
|
+
readLaunches: readWorkspaceLaunches,
|
|
120
|
+
resolveIos: resolveOwnedIosSim,
|
|
121
|
+
resolveAndroid: resolveOwnedAvdSerial,
|
|
122
|
+
iosProcess: iosAppProcess,
|
|
123
|
+
androidProcess: androidAppProcess,
|
|
124
|
+
resolveMetro: resolveProjectMetro,
|
|
125
|
+
reloadMetro: reloadThroughMetro
|
|
126
|
+
};
|
|
127
|
+
function failure(code, message, remedy) {
|
|
128
|
+
return {
|
|
129
|
+
code,
|
|
130
|
+
message,
|
|
131
|
+
remedy
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function describe(error) {
|
|
135
|
+
return error instanceof Error ? error.message : String(error);
|
|
136
|
+
}
|
|
137
|
+
function processFailure(platform, record, d) {
|
|
138
|
+
const process = platform === "ios" ? d.iosProcess(record.deviceId, record.appId) : d.androidProcess(record.deviceId, record.appId);
|
|
139
|
+
if (process === void 0) {
|
|
140
|
+
const probe = platform === "ios" ? `xcrun simctl spawn ${record.deviceId} launchctl list` : `adb -s ${record.deviceId} shell pidof ${record.appId}`;
|
|
141
|
+
return failure("STIM_RELOAD_PROBE_FAILED", `Stim could not determine whether ${record.appId} is running on ${record.deviceId}.`, `Run \`${probe}\` and retry when the device tool responds.`);
|
|
142
|
+
}
|
|
143
|
+
if (process === null) return failure("STIM_RELOAD_STOPPED", `${record.appId} is not running on ${record.deviceId}.`, `Run \`stim ${platform}\` to launch it.`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
function inspectTarget(platform, record, project, d) {
|
|
147
|
+
if (platform === "ios") {
|
|
148
|
+
const configured = project.platforms?.ios;
|
|
149
|
+
if (!configured?.owned || configured.deviceUdid !== record.deviceId) return {
|
|
150
|
+
platform,
|
|
151
|
+
error: failure("STIM_RELOAD_UNOWNED", `The recorded iOS launch on ${record.deviceId} is not this workspace's current owned simulator.`, "Run `stim ios` to launch the app on this workspace's owned simulator.")
|
|
152
|
+
};
|
|
153
|
+
let resolved;
|
|
154
|
+
try {
|
|
155
|
+
resolved = d.resolveIos(record.deviceId);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
return {
|
|
158
|
+
platform,
|
|
159
|
+
error: failure("STIM_RELOAD_PROBE_FAILED", `Stim could not inspect iOS simulator ${record.deviceId}: ${describe(error)}`, "Run `xcrun simctl list devices` and retry when simctl responds.")
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (!resolved.sim || resolved.sim.state !== "Booted") return {
|
|
163
|
+
platform,
|
|
164
|
+
error: failure("STIM_RELOAD_STOPPED", `The recorded iOS app is not running on a booted owned simulator.`, "Run `stim ios` to boot, install, and launch it.")
|
|
165
|
+
};
|
|
166
|
+
const stopped = processFailure(platform, record, d);
|
|
167
|
+
if (stopped) return {
|
|
168
|
+
platform,
|
|
169
|
+
error: stopped
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
platform,
|
|
173
|
+
record,
|
|
174
|
+
deviceName: resolved.sim.name
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const configured = project.platforms?.android;
|
|
178
|
+
if (!configured?.owned || !configured.avdName) return {
|
|
179
|
+
platform,
|
|
180
|
+
error: failure("STIM_RELOAD_UNOWNED", `The recorded Android launch on ${record.deviceId} is not this workspace's current owned emulator.`, "Run `stim android` to launch the app on this workspace's owned emulator.")
|
|
181
|
+
};
|
|
182
|
+
let resolved;
|
|
183
|
+
try {
|
|
184
|
+
resolved = d.resolveAndroid(configured.avdName);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
return {
|
|
187
|
+
platform,
|
|
188
|
+
error: failure("STIM_RELOAD_PROBE_FAILED", `Stim could not inspect Android emulator ${configured.avdName}: ${describe(error)}`, "Run `adb devices` and retry when adb responds.")
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
if (!resolved.serial || resolved.serial !== record.deviceId) return {
|
|
192
|
+
platform,
|
|
193
|
+
error: failure("STIM_RELOAD_STOPPED", `The recorded Android app is not running on this workspace's owned emulator.`, "Run `stim android` to boot, install, and launch it.")
|
|
194
|
+
};
|
|
195
|
+
const stopped = processFailure(platform, record, d);
|
|
196
|
+
if (stopped) return {
|
|
197
|
+
platform,
|
|
198
|
+
error: stopped
|
|
199
|
+
};
|
|
200
|
+
return {
|
|
201
|
+
platform,
|
|
202
|
+
record,
|
|
203
|
+
deviceName: configured.avdName
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function isTargetFailure(value) {
|
|
207
|
+
return "error" in value;
|
|
208
|
+
}
|
|
209
|
+
async function runReload({ root, platform = null, deps = {} }) {
|
|
210
|
+
const d = {
|
|
211
|
+
...DEFAULT_DEPS,
|
|
212
|
+
...deps
|
|
213
|
+
};
|
|
214
|
+
const project = d.getProject(root);
|
|
215
|
+
if (!project) return {
|
|
216
|
+
ok: false,
|
|
217
|
+
error: failure("STIM_NO_PROJECT", `No Stim environment is registered for ${root}.`, "Run `stim start` first.")
|
|
218
|
+
};
|
|
219
|
+
const launches = d.readLaunches(root);
|
|
220
|
+
const inspected = (platform ? [platform] : ["ios", "android"]).flatMap((candidate) => {
|
|
221
|
+
const record = launches[candidate];
|
|
222
|
+
return record ? [inspectTarget(candidate, record, project, d)] : [];
|
|
223
|
+
});
|
|
224
|
+
const live = inspected.filter((target) => !isTargetFailure(target));
|
|
225
|
+
if (live.length > 1) return {
|
|
226
|
+
ok: false,
|
|
227
|
+
error: failure("STIM_RELOAD_AMBIGUOUS", "Both the iOS and Android apps are running.", "Choose one with `stim reload ios` or `stim reload android`.")
|
|
228
|
+
};
|
|
229
|
+
if (live.length === 0) return {
|
|
230
|
+
ok: false,
|
|
231
|
+
error: inspected.find(isTargetFailure)?.error ?? failure("STIM_RELOAD_STOPPED", platform ? `No ${platform} app launch is recorded for this workspace.` : "No live app launch is recorded.", platform ? `Run \`stim ${platform}\` first.` : "Run `stim ios` or `stim android` first.")
|
|
232
|
+
};
|
|
233
|
+
const target = live[0];
|
|
234
|
+
if (target.record.release) return {
|
|
235
|
+
ok: false,
|
|
236
|
+
error: failure("STIM_RELOAD_RELEASE", `${target.record.appId} was launched with an embedded release bundle.`, `Run \`stim ${target.platform}\` with a Debug configuration or variant before reloading JavaScript.`)
|
|
237
|
+
};
|
|
238
|
+
const port = target.record.metroPort;
|
|
239
|
+
if (!port || project.metroPort !== port) return {
|
|
240
|
+
ok: false,
|
|
241
|
+
error: failure("STIM_NO_METRO", `The launch does not point at this workspace's current Metro reservation.`, "Run `stim start`, then launch the app again.")
|
|
242
|
+
};
|
|
243
|
+
if (!(await d.resolveMetro(port, root)).metro) return {
|
|
244
|
+
ok: false,
|
|
245
|
+
error: failure("STIM_NO_METRO", `Port ${port} is not serving this workspace's Metro.`, "Run `stim start`, then retry.")
|
|
246
|
+
};
|
|
247
|
+
const stopped = processFailure(target.platform, target.record, d);
|
|
248
|
+
if (stopped) return {
|
|
249
|
+
ok: false,
|
|
250
|
+
error: stopped
|
|
251
|
+
};
|
|
252
|
+
const reloaded = await d.reloadMetro(port, {
|
|
253
|
+
role: target.platform,
|
|
254
|
+
appId: target.record.appId
|
|
255
|
+
});
|
|
256
|
+
if (!reloaded.ok) {
|
|
257
|
+
const stoppedAfterMetro = processFailure(target.platform, target.record, d);
|
|
258
|
+
if (stoppedAfterMetro) return {
|
|
259
|
+
ok: false,
|
|
260
|
+
error: stoppedAfterMetro
|
|
261
|
+
};
|
|
262
|
+
const snapshot = `agent-device snapshot -i --platform ${target.platform} --${target.platform === "ios" ? "udid" : "serial"} ${target.record.deviceId}`;
|
|
263
|
+
const relaunch = `agent-device open ${target.record.appId} --platform ${target.platform} --${target.platform === "ios" ? "udid" : "serial"} ${target.record.deviceId} --metro-port ${port} --relaunch`;
|
|
264
|
+
const firstBundle = target.platform === "ios" ? " If it stays unreachable, an error in the first bundle leaves iOS without a packager connection at all, and no retry will make it a peer." : "";
|
|
265
|
+
const device = `reload from the device in your existing automation session: run \`${snapshot}\`, then press the error screen's Reload button, or open the dev menu and press Reload when no error screen is showing. Only when neither is reachable, run \`${relaunch}\`; that restarts the app and loses in-memory state. Keep your existing --session flag, verify the expected UI afterward, and do not create another session.`;
|
|
266
|
+
const remedy = reloaded.unreachable ? `Metro is registered for this workspace but did not answer on port ${port}, so nothing is known about ${target.record.appId}. Run \`stim reload ${target.platform}\` again. If it keeps timing out, run \`stim doctor\` to check the dev server before touching the app.` : `Metro reports no peer for ${target.record.appId} right now. Stim broadcast a reload anyway, so check the expected UI on ${target.record.deviceId} first -- it may already have recovered. If not, the app reconnects every 2 seconds, so run \`stim reload ${target.platform}\` once more.${firstBundle} Then ${device}`;
|
|
267
|
+
return {
|
|
268
|
+
ok: false,
|
|
269
|
+
error: failure("STIM_RELOAD_FAILED", reloaded.reason, remedy)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const strategy = reloaded.broadcast ? "metro-broadcast" : "metro-websocket";
|
|
273
|
+
return {
|
|
274
|
+
ok: true,
|
|
275
|
+
facts: {
|
|
276
|
+
platform: target.platform,
|
|
277
|
+
deviceId: target.record.deviceId,
|
|
278
|
+
deviceName: target.deviceName,
|
|
279
|
+
appId: target.record.appId,
|
|
280
|
+
metroPort: port,
|
|
281
|
+
strategy,
|
|
282
|
+
targets: reloaded.targets ?? null
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function registerReload(program, deps = {}) {
|
|
287
|
+
program.command("reload [platform]").description("Request a JavaScript reload in this workspace's live app without observing completion. Specify ios or android when both are live.").option("--json", "Emit the reload facts as one JSON line").action(async (value, opts) => {
|
|
288
|
+
if (value !== void 0 && value !== "ios" && value !== "android") {
|
|
289
|
+
const error = failure("STIM_BAD_ARG", `Unknown reload platform ${JSON.stringify(value)}.`, "Use ios or android.");
|
|
290
|
+
if (opts.json) console.log(JSON.stringify(error));
|
|
291
|
+
else {
|
|
292
|
+
console.error(chalk.red(phaseLine("error", `${error.code}: ${error.message}`)));
|
|
293
|
+
if (error.remedy) console.error(phaseLine("remedy", error.remedy));
|
|
294
|
+
}
|
|
295
|
+
process.exitCode = 1;
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const root = (deps.findProjectRoot ?? DEFAULT_DEPS.findProjectRoot)(process.cwd());
|
|
299
|
+
if (!root) {
|
|
300
|
+
const error = failure("STIM_NO_PROJECT", "Not inside a project (no package.json found above the current directory).", null);
|
|
301
|
+
if (opts.json) console.log(JSON.stringify(error));
|
|
302
|
+
else console.error(chalk.red(phaseLine("error", `${error.code}: ${error.message}`)));
|
|
303
|
+
process.exitCode = 1;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const result = await runReload({
|
|
307
|
+
root,
|
|
308
|
+
platform: value ?? null,
|
|
309
|
+
deps
|
|
310
|
+
});
|
|
311
|
+
if (!result.ok) {
|
|
312
|
+
if (opts.json) console.log(JSON.stringify(result.error));
|
|
313
|
+
else {
|
|
314
|
+
console.error(chalk.red(phaseLine("error", `${result.error.code}: ${result.error.message}`)));
|
|
315
|
+
if (result.error.remedy) console.error(phaseLine("remedy", result.error.remedy));
|
|
316
|
+
}
|
|
317
|
+
process.exitCode = 1;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (opts.json) console.log(JSON.stringify(result.facts));
|
|
321
|
+
else {
|
|
322
|
+
const facts = result.facts;
|
|
323
|
+
const scope = facts.strategy === "metro-broadcast" ? ` This Metro cannot name its connected apps, so the reload request was broadcast to all of them and Stim cannot confirm ${facts.appId} was one. Check the expected UI on ${facts.deviceId}; if nothing changed, reload from the app's own error screen or dev menu.` : facts.targets && facts.targets > 1 ? ` ${facts.targets} devices are running this app on that Metro and the reload request addressed all of them, not only ${facts.deviceId}.` : "";
|
|
324
|
+
console.log(`Reload requested for ${facts.appId} on ${facts.deviceName} (${facts.deviceId}) via ${facts.strategy}; ${facts.platform} Metro port ${facts.metroPort}.${scope} Completion is not observed; verify the expected UI and run stim logs --errors.`);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
function reloadCommand(program) {
|
|
329
|
+
registerReload(program);
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
export { reloadCommand as default, registerReload, runReload };
|