stim 1.1.0 → 1.3.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 +37 -0
- package/dist/{android-CC5bUer7.mjs → android-BW8i_YxU.mjs} +1 -1
- package/dist/android-BqVIJoG7.mjs +1368 -0
- package/dist/{android-DnZlT3aU.mjs → android-CqcW1hrP.mjs} +205 -58
- package/dist/{android-cas-DGlTStWu.mjs → android-cas-BR5YJBYv.mjs} +6 -6
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{app-install-oZIQRbdD.mjs → app-install-DIp9riNx.mjs} +29 -21
- package/dist/{build-slots-CgacA9zQ.mjs → build-slots-C3-R4XQr.mjs} +3 -3
- package/dist/{cache-manifest-oeH18ERr.mjs → cache-manifest-CXR-Y8pH.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +13 -13
- package/dist/collector-run.d.mts +4 -1
- package/dist/collector-run.mjs +36 -11
- package/dist/{config-D7uu8Gbq.mjs → config-CcefMY2Q.mjs} +94 -13
- package/dist/{deps-64wVnpZc.mjs → deps-Spz8ozgo.mjs} +2 -2
- package/dist/{dev-client-Bvky1hya.mjs → dev-client-BjisHDB5.mjs} +250 -10
- package/dist/{device-DJKv5Qej.mjs → device-BkiW-gkk.mjs} +19 -11
- package/dist/{device-lease-D-G3SgVe.mjs → device-lease-BJYybF-2.mjs} +107 -83
- package/dist/{device-pool-BlHXnYYs.mjs → device-pool-CPbLGfrB.mjs} +19 -13
- package/dist/{device-remote-CCgkG82J.mjs → device-remote-AkYCKS8U.mjs} +8 -8
- package/dist/{doctor-DlVxTtMq.mjs → doctor-Bmv86UUW.mjs} +18 -26
- package/dist/{doctor-BRF9aAJ3.mjs → doctor-fAMXC4vl.mjs} +10 -10
- package/dist/{error-diagnostics-B5IJwv3-.mjs → error-diagnostics-DHC31rXA.mjs} +65 -55
- package/dist/{exec-bsN9MJXb.mjs → exec-CyylIdq9.mjs} +4 -2
- package/dist/{gc-DhXdgSdt.mjs → gc-GGu-8ULN.mjs} +90 -67
- package/dist/{guide-DrhrDBo5.mjs → guide-92CPA21s.mjs} +414 -47
- package/dist/{ios-CK1Vrk6Q.mjs → ios-BSXFeO5H.mjs} +200 -59
- package/dist/{ios-BZxKPuqP.mjs → ios-Deh5js5V.mjs} +147 -40
- package/dist/{ios-device-CdSm0GDw.mjs → ios-device-CWOM_S44.mjs} +2 -2
- package/dist/{ios-device-CYbuRNXR.mjs → ios-device-D3pzTKQE.mjs} +1 -1
- package/dist/{logs-Dxoy16Qv.mjs → logs-DPNF4C9s.mjs} +9 -6
- package/dist/{logs-query-oqn47Ffx.mjs → logs-query-R-Cqc6Qv.mjs} +22 -5
- package/dist/{metro-B01H3EuD.mjs → metro-CORqXyTL.mjs} +3 -3
- package/dist/{ndjson-DcAtEx_K.mjs → ndjson-BZwI1NBv.mjs} +5 -2
- package/dist/{ownership-D8HmSv2E.mjs → ownership-8O073GIC.mjs} +3 -3
- package/dist/{ownership-B9QIdQOw.mjs → ownership-BpCKiRlQ.mjs} +4 -4
- package/dist/{ownership-claim-CeJLEpjD.mjs → ownership-claim-Bf2CAfw3.mjs} +4 -3
- package/dist/{project-COj6nzzh.mjs → project-fKmuIaMI.mjs} +2 -2
- package/dist/{reclaim-BPvN2HlP.mjs → reclaim-iW9Cad7k.mjs} +80 -73
- package/dist/{reload-DYZEBbZy.mjs → reload-DazHDSFA.mjs} +32 -24
- package/dist/{server-bare-BYHqEeyw.mjs → server-bare-DEzPZLvf.mjs} +7 -2
- package/dist/server-expo-44em5Pmg.mjs +2 -0
- package/dist/{server-expo-BEMr_m6p.mjs → server-expo-DizT4OMk.mjs} +5 -5
- package/dist/{settings-BSwrY4FZ.mjs → settings-DEJf6_kJ.mjs} +26 -5
- package/dist/slot-launch-cci0xvmC.mjs +19 -0
- package/dist/{start-ByCylYtB.mjs → start-mObjQH2W.mjs} +12 -12
- package/dist/{state-IYEY-zi8.mjs → state-B3XA2wp2.mjs} +9 -9
- package/dist/{stats-wqxPm7Tv.mjs → stats-BR-kwj0B.mjs} +1 -1
- package/dist/{stats-DZ4Q5J-7.mjs → stats-CaaQr4yN.mjs} +3 -3
- package/dist/{status-Dia0XTqG.mjs → status-BxQNqu9t.mjs} +86 -25
- package/dist/{stop-D6o5zAdm.mjs → stop-CrHGcjrV.mjs} +2 -2
- package/dist/{stop-BApyaF21.mjs → stop-DimGXEKY.mjs} +93 -42
- package/dist/supervisor-run.d.mts +1 -2
- package/dist/supervisor-run.mjs +5 -5
- package/dist/{remote-cache-DOi5-zLj.mjs → teardown-ClFp1Aax.mjs} +889 -830
- package/dist/{workspace-process-lock-CxOO9-pf.mjs → workspace-process-lock-3NcQnZ0X.mjs} +1 -1
- package/dist/{worktree-DxEmUI_n.mjs → worktree-DxTgN1CJ.mjs} +16 -16
- package/dist/{worktree-Dx3ZC5lS.mjs → worktree-Eq6TLH8N.mjs} +7 -3
- package/dist/{xcode-CDB6fytw.mjs → xcode-D7sAp-Zy.mjs} +256 -103
- package/package.json +5 -5
- package/shim/bundle-response.cjs +5 -0
- package/dist/android-xmyGBNy5.mjs +0 -665
- package/dist/build-lock-vE45ZzJZ.mjs +0 -645
- package/dist/server-expo-rb0k-0w7.mjs +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
3
3
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
5
|
import { join } from "node:path";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { o as parseNdjsonText } from "./ndjson-
|
|
3
|
-
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { o as parseNdjsonText } from "./ndjson-BZwI1NBv.mjs";
|
|
3
|
+
import { t as DEV_MENU_LAUNCH_ARGS } from "./ios-device-D3pzTKQE.mjs";
|
|
4
4
|
import { s as isAppLaunchError } from "./command-output-8wHMEde0.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { l as iosSimulatorFailureAdvice, p as listUserApps, w as uninstallIosApp } from "./ios-Deh5js5V.mjs";
|
|
6
6
|
import { closeSync, lstatSync, openSync, readFileSync, readSync, readdirSync } from "node:fs";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { join } from "node:path";
|
|
@@ -157,6 +157,10 @@ const IOS_DEV_MENU_OFF_KEYS = ["EXDevMenuShowsAtLaunch", "EXDevMenuShowFloatingA
|
|
|
157
157
|
const DEV_CLIENT_ONBOARDING_QUERY = "disableOnboarding=1";
|
|
158
158
|
const DEV_CLIENT_DISABLE_FAB_QUERY = "disableFab=1";
|
|
159
159
|
const ANDROID_DISABLE_AUTO_LAUNCH_EXTRA = "EXDevMenuDisableAutoLaunch";
|
|
160
|
+
function describeIosSimulatorFailure(error, exec) {
|
|
161
|
+
const detail = describe(error);
|
|
162
|
+
return error?.code === "ETIMEDOUT" ? `${detail}. ${iosSimulatorFailureAdvice(exec)}` : detail;
|
|
163
|
+
}
|
|
160
164
|
function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null, proveInstalled = true }, { exec = null, now = null } = {}) {
|
|
161
165
|
const e = exec || getExecutor();
|
|
162
166
|
const artifactStartedAt = now?.();
|
|
@@ -171,12 +175,15 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
171
175
|
"install",
|
|
172
176
|
udid,
|
|
173
177
|
appPath
|
|
174
|
-
]
|
|
178
|
+
], {
|
|
179
|
+
timeoutMs: 3e5,
|
|
180
|
+
killSignal: "SIGKILL"
|
|
181
|
+
});
|
|
175
182
|
} catch (err) {
|
|
176
183
|
return {
|
|
177
184
|
failed: true,
|
|
178
185
|
code: INSTALL_ERROR,
|
|
179
|
-
reason: `simctl install failed for ${appPath}: ${
|
|
186
|
+
reason: `simctl install failed for ${appPath}: ${describeIosSimulatorFailure(err, e)}`
|
|
180
187
|
};
|
|
181
188
|
}
|
|
182
189
|
const artifactFinishedAt = now?.();
|
|
@@ -193,7 +200,7 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
193
200
|
key,
|
|
194
201
|
"-bool",
|
|
195
202
|
"false"
|
|
196
|
-
]);
|
|
203
|
+
], { timeoutMs: 6e4 });
|
|
197
204
|
for (const key of iosSchemeApprovalKeys(bundleId, devClientScheme)) e.runFile("xcrun", [
|
|
198
205
|
"simctl",
|
|
199
206
|
"spawn",
|
|
@@ -204,12 +211,12 @@ function installIosApp({ udid, appPath, bundleId = null, devClientScheme = null,
|
|
|
204
211
|
key,
|
|
205
212
|
"-string",
|
|
206
213
|
bundleId
|
|
207
|
-
]);
|
|
214
|
+
], { timeoutMs: 6e4 });
|
|
208
215
|
} catch (err) {
|
|
209
216
|
return {
|
|
210
217
|
failed: true,
|
|
211
218
|
code: INSTALL_ERROR,
|
|
212
|
-
reason: `Installed ${bundleId}, but could not prepare the dev client: ${
|
|
219
|
+
reason: `Installed ${bundleId}, but could not prepare the dev client: ${describeIosSimulatorFailure(err, e)}`
|
|
213
220
|
};
|
|
214
221
|
}
|
|
215
222
|
const devClientPreparationDurationMs = now && preparationStartedAt !== void 0 ? now() - preparationStartedAt : void 0;
|
|
@@ -318,12 +325,12 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
318
325
|
bundleId,
|
|
319
326
|
"RCT_jsLocation",
|
|
320
327
|
jsLocationValue(metroPort)
|
|
321
|
-
]);
|
|
328
|
+
], { timeoutMs: 6e4 });
|
|
322
329
|
} catch (err) {
|
|
323
330
|
return {
|
|
324
331
|
failed: true,
|
|
325
332
|
code: LAUNCH_ERROR,
|
|
326
|
-
reason: `Could not point ${bundleId} at Metro port ${metroPort} (defaults write RCT_jsLocation): ${
|
|
333
|
+
reason: `Could not point ${bundleId} at Metro port ${metroPort} (defaults write RCT_jsLocation): ${describeIosSimulatorFailure(err, e)}`
|
|
327
334
|
};
|
|
328
335
|
}
|
|
329
336
|
if (devClientScheme) {
|
|
@@ -349,7 +356,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
349
356
|
"openurl",
|
|
350
357
|
udid,
|
|
351
358
|
url
|
|
352
|
-
]);
|
|
359
|
+
], { timeoutMs: 6e4 });
|
|
353
360
|
return {
|
|
354
361
|
ok: true,
|
|
355
362
|
mode: "openurl",
|
|
@@ -360,7 +367,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
360
367
|
return {
|
|
361
368
|
failed: true,
|
|
362
369
|
code: LAUNCH_ERROR,
|
|
363
|
-
reason: `simctl openurl ${url} failed: ${
|
|
370
|
+
reason: `simctl openurl ${url} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
364
371
|
};
|
|
365
372
|
}
|
|
366
373
|
}
|
|
@@ -377,7 +384,7 @@ function launchIosApp({ udid, bundleId, metroPort, devClientScheme = null, conso
|
|
|
377
384
|
return {
|
|
378
385
|
failed: true,
|
|
379
386
|
code: LAUNCH_ERROR,
|
|
380
|
-
reason: `simctl launch ${bundleId} failed: ${
|
|
387
|
+
reason: `simctl launch ${bundleId} failed: ${describeIosSimulatorFailure(err, e)}`
|
|
381
388
|
};
|
|
382
389
|
}
|
|
383
390
|
}
|
|
@@ -893,7 +900,7 @@ function nativeLaunchFailure({ readCrashes, since, platform, processAlive, mode,
|
|
|
893
900
|
waitedMs
|
|
894
901
|
} : null;
|
|
895
902
|
}
|
|
896
|
-
async function verifyLaunch({ logsDir, since, metroPort = null, platform = null, mode = null, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
|
|
903
|
+
async function verifyLaunch({ slot, logsDir, since, metroPort = null, platform = null, mode = null, requireBundleResponse, timeoutMs = VERIFY_TIMEOUT_MS, stabilityMs = STABILITY_WINDOW_MS, pollMs = VERIFY_POLL_MS, readRecords = null, readDeviceRecords = null, readClientRecords = null, readNativeCrashes = null, processAlive = null, onReadinessPending = null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) } = {}) {
|
|
897
904
|
const read = readRecords || (() => readMetroRecords(logsDir));
|
|
898
905
|
const readDevice = readDeviceRecords || (() => readNdjson(logsDir, "device.ndjson"));
|
|
899
906
|
const readClient = readClientRecords || (() => readNdjson(logsDir, "client.ndjson"));
|
|
@@ -908,9 +915,10 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
908
915
|
let runtimeStartedAt = null;
|
|
909
916
|
let nextCrashCheck = startedAt + 1e3;
|
|
910
917
|
while (true) {
|
|
911
|
-
const metroRecords = read().filter((record) => after(record, since));
|
|
912
|
-
const
|
|
913
|
-
const
|
|
918
|
+
const metroRecords = read().filter((record) => after(record, since) && (slot === void 0 || record.slot === slot));
|
|
919
|
+
const bundleRecords = metroRecords.filter((record) => !requireBundleResponse || String(record.event).startsWith("bundle_response_"));
|
|
920
|
+
const deviceRecords = readDevice().filter((record) => after(record, since) && (slot === void 0 || (record.slot ?? "default") === slot));
|
|
921
|
+
const clientRecords = readClient().filter((record) => after(record, since) && (slot === void 0 || record.slot === slot));
|
|
914
922
|
if (now() >= nextCrashCheck) {
|
|
915
923
|
nextCrashCheck = now() + 2e3;
|
|
916
924
|
const crash = nativeLaunchFailure({
|
|
@@ -924,14 +932,14 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
924
932
|
if (crash) return crash;
|
|
925
933
|
}
|
|
926
934
|
if (deliveryId === null) {
|
|
927
|
-
const request =
|
|
935
|
+
const request = bundleRecords.find((record) => record.event === "bundle_response_started" && typeof record.requestId === "string" && isBundleProof(record, since, platform));
|
|
928
936
|
if (request) {
|
|
929
937
|
deliveryId = request.requestId;
|
|
930
938
|
proof = null;
|
|
931
939
|
stabilityDeadline = null;
|
|
932
940
|
}
|
|
933
941
|
}
|
|
934
|
-
for (const record of
|
|
942
|
+
for (const record of bundleRecords) {
|
|
935
943
|
if (isBundleProof(record, since, platform)) activity = record;
|
|
936
944
|
const completed = deliveryId === null ? isBundleReadyProof(record, since, platform) : record.event === "bundle_response_finished" && record.requestId === deliveryId && isBundleProof(record, since, platform);
|
|
937
945
|
if (!proof && completed) {
|
|
@@ -960,7 +968,7 @@ async function verifyLaunch({ logsDir, since, metroPort = null, platform = null,
|
|
|
960
968
|
}
|
|
961
969
|
}
|
|
962
970
|
const ready = pendingAt !== null && signals.some((record) => Number(record.ts) >= pendingAt && Number(record.ts) <= readinessDeadline && appReadinessSignal(record, platform) === "ready");
|
|
963
|
-
const bundleErrors =
|
|
971
|
+
const bundleErrors = bundleRecords.filter((record) => isFatalLaunchError(record, platform) || deliveryId !== null && record.event === "bundle_response_failed" && record.requestId === deliveryId && isBundleProof(record, since, platform));
|
|
964
972
|
if (bundleErrors.length) {
|
|
965
973
|
const alive = processAlive ? processAlive() : null;
|
|
966
974
|
const fatalRecord = bundleErrors[bundleErrors.length - 1];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { u as getConfigDir } from "./config-
|
|
1
|
+
import { u as getConfigDir } from "./config-CcefMY2Q.mjs";
|
|
2
2
|
import { a as formatElapsed } from "./command-output-8wHMEde0.mjs";
|
|
3
|
-
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, s as isClaimRefusal } from "./ownership-claim-
|
|
3
|
+
import { d as readClaimSet, f as releaseClaim, h as tryAcquireClaim, s as isClaimRefusal } from "./ownership-claim-Bf2CAfw3.mjs";
|
|
4
4
|
import { readdirSync, statSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
//#region src/engine/build-slots.ts
|
|
@@ -77,7 +77,7 @@ function tryAcquireBuildSlot({ max, root = null, logFile = null }) {
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
function slotWaitingLine({ max, elapsedMs }) {
|
|
80
|
-
return `${"build".padEnd(11)} waiting for a build slot (all ${max} in use, ${formatElapsed(elapsedMs)} elapsed)`;
|
|
80
|
+
return `${"build".padEnd(11)} waiting for a build slot (all ${max} in use, ${formatElapsed(elapsedMs)} elapsed) -- stim guide lifecycle concurrency`;
|
|
81
81
|
}
|
|
82
82
|
async function acquireBuildSlot({ max, root = null, logFile = null, now = Date.now, out = () => {}, sleep = sleepAsync, intervalMs = SLOT_POLL_MS, progressMs = SLOT_PROGRESS_MS, ceilingMs = SLOT_CEILING_MS }) {
|
|
83
83
|
if (!max || max <= 0) return {
|
package/dist/cache-manifest.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-
|
|
1
|
+
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-CXR-Y8pH.mjs";
|
|
2
2
|
export { manifestPath, readManifest, register, registeredCaches, unregister };
|
package/dist/cli.mjs
CHANGED
|
@@ -3,19 +3,19 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
//#region bin/cli.ts
|
|
5
5
|
const commands = /* @__PURE__ */ new Map([
|
|
6
|
-
["doctor", () => import("./doctor-
|
|
7
|
-
["worktree", () => import("./worktree-
|
|
8
|
-
["start", () => import("./start-
|
|
9
|
-
["stop", () => import("./stop-
|
|
10
|
-
["ios", () => import("./ios-
|
|
11
|
-
["android", () => import("./android-
|
|
12
|
-
["reload", () => import("./reload-
|
|
13
|
-
["device", () => import("./device-
|
|
14
|
-
["logs", () => import("./logs-
|
|
15
|
-
["status", () => import("./status-
|
|
16
|
-
["stats", () => import("./stats-
|
|
17
|
-
["gc", () => import("./gc-
|
|
18
|
-
["guide", () => import("./guide-
|
|
6
|
+
["doctor", () => import("./doctor-fAMXC4vl.mjs")],
|
|
7
|
+
["worktree", () => import("./worktree-DxTgN1CJ.mjs")],
|
|
8
|
+
["start", () => import("./start-mObjQH2W.mjs")],
|
|
9
|
+
["stop", () => import("./stop-CrHGcjrV.mjs")],
|
|
10
|
+
["ios", () => import("./ios-BSXFeO5H.mjs")],
|
|
11
|
+
["android", () => import("./android-CqcW1hrP.mjs")],
|
|
12
|
+
["reload", () => import("./reload-DazHDSFA.mjs")],
|
|
13
|
+
["device", () => import("./device-BkiW-gkk.mjs")],
|
|
14
|
+
["logs", () => import("./logs-DPNF4C9s.mjs")],
|
|
15
|
+
["status", () => import("./status-BxQNqu9t.mjs")],
|
|
16
|
+
["stats", () => import("./stats-CaaQr4yN.mjs")],
|
|
17
|
+
["gc", () => import("./gc-GGu-8ULN.mjs")],
|
|
18
|
+
["guide", () => import("./guide-92CPA21s.mjs")]
|
|
19
19
|
]);
|
|
20
20
|
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
21
21
|
const program = new Command();
|
package/dist/collector-run.d.mts
CHANGED
|
@@ -4,6 +4,7 @@ import { ChildProcess as ChildProcess$1 } from "node:child_process";
|
|
|
4
4
|
//#region src/exec.d.ts
|
|
5
5
|
interface ExecOptions {
|
|
6
6
|
timeoutMs?: number;
|
|
7
|
+
killSignal?: NodeJS.Signals;
|
|
7
8
|
cwd?: string;
|
|
8
9
|
env?: Record<string, string>;
|
|
9
10
|
omitEnv?: readonly string[];
|
|
@@ -54,6 +55,7 @@ declare function readCollectors(root: string): Record<string, unknown>;
|
|
|
54
55
|
//#region src/collector/run.d.ts
|
|
55
56
|
declare const PLATFORMS: string[];
|
|
56
57
|
interface ParsedCollectorArgs {
|
|
58
|
+
slot?: string;
|
|
57
59
|
platform?: string;
|
|
58
60
|
root?: string;
|
|
59
61
|
udid?: string;
|
|
@@ -68,6 +70,7 @@ interface ParsedCollectorArgs {
|
|
|
68
70
|
}
|
|
69
71
|
declare function parseArgs(argv: string[]): ParsedCollectorArgs;
|
|
70
72
|
interface RunCollectorOptions {
|
|
73
|
+
slot?: string;
|
|
71
74
|
platform: string;
|
|
72
75
|
root: string;
|
|
73
76
|
udid?: string | null;
|
|
@@ -113,7 +116,7 @@ interface RunCollectorHandle {
|
|
|
113
116
|
startedAt: string;
|
|
114
117
|
pid: number | null;
|
|
115
118
|
}
|
|
116
|
-
declare function runCollector({ platform, root, udid, appName, appExecutable, bundleId, serial, packageName, physical, payloadUrl, startStream, resolvePid, pidTimeoutMs, pidOf, pidWatchMs, watchPid, resolveClockOffset, now, onExit, attachSignals, stderr }: RunCollectorOptions): Promise<RunCollectorHandle | null>;
|
|
119
|
+
declare function runCollector({ slot, platform, root, udid, appName, appExecutable, bundleId, serial, packageName, physical, payloadUrl, startStream, resolvePid, pidTimeoutMs, pidOf, pidWatchMs, watchPid, resolveClockOffset, now, onExit, attachSignals, stderr }: RunCollectorOptions): Promise<RunCollectorHandle | null>;
|
|
117
120
|
declare function main(argv?: string[]): Promise<void>;
|
|
118
121
|
//#endregion
|
|
119
122
|
export { PLATFORMS, ParsedCollectorArgs, RunCollectorHandle, RunCollectorOptions, main, parseArgs, readCollectors, registerCollector, runCollector, unregisterCollector };
|
package/dist/collector-run.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { T as captureProcessToken } from "./config-
|
|
3
|
-
import { r as createNdjsonWriter } from "./ndjson-
|
|
4
|
-
import { D as workspaceLogsDir } from "./state-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
+
import { I as deviceSlotKey, T as captureProcessToken, V as validateDeviceSlot } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { r as createNdjsonWriter } from "./ndjson-BZwI1NBv.mjs";
|
|
4
|
+
import { D as workspaceLogsDir } from "./state-B3XA2wp2.mjs";
|
|
5
5
|
import { t as createLineReader } from "./process-output-C7IlIzd7.mjs";
|
|
6
|
-
import { i as startIosDeviceConsole, r as parseDeviceConsoleLine } from "./ios-device-
|
|
7
|
-
import { a as unregisterCollector, i as registerCollector, r as readCollectors, t as collectorProcessTitle } from "./ownership-
|
|
8
|
-
import { a as watchAppPid, i as waitForAppPid, n as parseLogcatLine, r as startAndroidLogcat, t as androidClockOffset } from "./android-
|
|
6
|
+
import { i as startIosDeviceConsole, r as parseDeviceConsoleLine } from "./ios-device-D3pzTKQE.mjs";
|
|
7
|
+
import { a as unregisterCollector, i as registerCollector, r as readCollectors, t as collectorProcessTitle } from "./ownership-8O073GIC.mjs";
|
|
8
|
+
import { a as watchAppPid, i as waitForAppPid, n as parseLogcatLine, r as startAndroidLogcat, t as androidClockOffset } from "./android-BW8i_YxU.mjs";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { isAbsolute, join, resolve } from "node:path";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
@@ -193,6 +193,7 @@ function startIosLogStream({ udid, appName, executableName = null, spawnFn = nul
|
|
|
193
193
|
//#region src/collector/run.ts
|
|
194
194
|
const PLATFORMS = ["ios", "android"];
|
|
195
195
|
function parseArgs(argv) {
|
|
196
|
+
let slot;
|
|
196
197
|
let platform;
|
|
197
198
|
let root;
|
|
198
199
|
let udid;
|
|
@@ -205,6 +206,16 @@ function parseArgs(argv) {
|
|
|
205
206
|
let payloadUrl = null;
|
|
206
207
|
for (let i = 0; i < argv.length; i++) {
|
|
207
208
|
const arg = argv[i];
|
|
209
|
+
if (arg === "--slot") {
|
|
210
|
+
slot = argv[++i];
|
|
211
|
+
if (!slot) return { error: "--slot needs a name." };
|
|
212
|
+
try {
|
|
213
|
+
validateDeviceSlot(slot);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return { error: String(error.message) };
|
|
216
|
+
}
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
208
219
|
if (arg === "--platform") {
|
|
209
220
|
platform = argv[++i];
|
|
210
221
|
continue;
|
|
@@ -272,7 +283,8 @@ function parseArgs(argv) {
|
|
|
272
283
|
serial,
|
|
273
284
|
packageName,
|
|
274
285
|
physical,
|
|
275
|
-
payloadUrl
|
|
286
|
+
payloadUrl,
|
|
287
|
+
...slot ? { slot } : {}
|
|
276
288
|
};
|
|
277
289
|
}
|
|
278
290
|
const noopFlush = () => {};
|
|
@@ -281,7 +293,12 @@ function startMessage({ platform, physical, pid, appName, bundleId, udid, packag
|
|
|
281
293
|
if (!physical) return `device log collector pid ${pid} streaming ${appName} on ${udid}`;
|
|
282
294
|
return `device log collector pid ${pid} launching ${bundleId} on device ${udid} and streaming its console; subsystem, category and severity are not carried on hardware -- see \`stim guide logs\``;
|
|
283
295
|
}
|
|
284
|
-
async function runCollector({ platform, root, udid = null, appName = null, appExecutable = null, bundleId = null, serial = null, packageName = null, physical = false, payloadUrl = null, startStream = null, resolvePid = null, pidTimeoutMs = 3e4, pidOf = null, pidWatchMs = null, watchPid = watchAppPid, resolveClockOffset = androidClockOffset, now = Date.now, onExit = (code) => process.exit(code), attachSignals = true, stderr = (line) => console.error(line) }) {
|
|
296
|
+
async function runCollector({ slot = "default", platform, root, udid = null, appName = null, appExecutable = null, bundleId = null, serial = null, packageName = null, physical = false, payloadUrl = null, startStream = null, resolvePid = null, pidTimeoutMs = 3e4, pidOf = null, pidWatchMs = null, watchPid = watchAppPid, resolveClockOffset = androidClockOffset, now = Date.now, onExit = (code) => process.exit(code), attachSignals = true, stderr = (line) => console.error(line) }) {
|
|
297
|
+
const key = deviceSlotKey(platform, slot);
|
|
298
|
+
const attribution = slot === "default" ? {} : {
|
|
299
|
+
slot,
|
|
300
|
+
deviceId: udid ?? serial
|
|
301
|
+
};
|
|
285
302
|
const writer = createNdjsonWriter(join(workspaceLogsDir(root), "device.ndjson"));
|
|
286
303
|
const startedAt = new Date(now()).toISOString();
|
|
287
304
|
const processToken = captureProcessToken(process.pid);
|
|
@@ -299,6 +316,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
299
316
|
finished = true;
|
|
300
317
|
watcher?.stop();
|
|
301
318
|
if (physical && captured === 0 && !signalled) writer.write({
|
|
319
|
+
...attribution,
|
|
302
320
|
src: "device",
|
|
303
321
|
platform,
|
|
304
322
|
level: "warn",
|
|
@@ -306,6 +324,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
306
324
|
msg: `the device console produced no output for ${bundleId}; devicectl only connects the app's streams when it starts the app, and os_log below the info level never reaches them`
|
|
307
325
|
});
|
|
308
326
|
writer.write({
|
|
327
|
+
...attribution,
|
|
309
328
|
src: "device",
|
|
310
329
|
platform,
|
|
311
330
|
level,
|
|
@@ -313,7 +332,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
313
332
|
msg
|
|
314
333
|
});
|
|
315
334
|
try {
|
|
316
|
-
unregisterCollector(root,
|
|
335
|
+
unregisterCollector(root, key, process.pid, processToken);
|
|
317
336
|
} catch {}
|
|
318
337
|
const closed = writer.close();
|
|
319
338
|
if (closed.dropped > 0) stderr(`Stim collector: dropped ${closed.dropped} record(s); last error: ${describe(closed.lastError)}`);
|
|
@@ -327,7 +346,8 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
327
346
|
finish(0, "info", `device log collector received ${signal}; detaching`, "collector_stopped", { signalled: true });
|
|
328
347
|
});
|
|
329
348
|
try {
|
|
330
|
-
registerCollector(root,
|
|
349
|
+
registerCollector(root, key, {
|
|
350
|
+
...attribution,
|
|
331
351
|
pid: process.pid,
|
|
332
352
|
processToken,
|
|
333
353
|
startedAt
|
|
@@ -355,6 +375,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
355
375
|
pid = resolved.pid ?? null;
|
|
356
376
|
}
|
|
357
377
|
writer.write({
|
|
378
|
+
...attribution,
|
|
358
379
|
src: "device",
|
|
359
380
|
platform,
|
|
360
381
|
level: "info",
|
|
@@ -375,6 +396,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
375
396
|
const attach = (streamPid) => {
|
|
376
397
|
const clockOffsetMs = platform === "android" ? resolveClockOffset(serial, { now }) : null;
|
|
377
398
|
if (platform === "android") writer.write({
|
|
399
|
+
...attribution,
|
|
378
400
|
src: "device",
|
|
379
401
|
platform,
|
|
380
402
|
level: clockOffsetMs === null ? "warn" : "debug",
|
|
@@ -390,6 +412,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
390
412
|
if (!record) return;
|
|
391
413
|
captured++;
|
|
392
414
|
writer.write({
|
|
415
|
+
...attribution,
|
|
393
416
|
...record,
|
|
394
417
|
platform
|
|
395
418
|
});
|
|
@@ -420,6 +443,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
420
443
|
const errReader = createLineReader(physical ? onLine : (line) => {
|
|
421
444
|
const text = String(line).trimEnd();
|
|
422
445
|
if (text.trim()) writer.write({
|
|
446
|
+
...attribution,
|
|
423
447
|
src: "device",
|
|
424
448
|
platform,
|
|
425
449
|
level: "debug",
|
|
@@ -464,6 +488,7 @@ async function runCollector({ platform, root, udid = null, appName = null, appEx
|
|
|
464
488
|
killChild(child);
|
|
465
489
|
child = null;
|
|
466
490
|
writer.write({
|
|
491
|
+
...attribution,
|
|
467
492
|
src: "device",
|
|
468
493
|
platform,
|
|
469
494
|
level: "info",
|
|
@@ -1,9 +1,88 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
2
|
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, renameSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { dirname, isAbsolute, join, normalize } from "path";
|
|
5
5
|
import { withDirLock } from "@stim-cli/core";
|
|
6
6
|
import { capture, check, decode } from "unique-pid";
|
|
7
|
+
//#region src/device-slots.ts
|
|
8
|
+
const DEFAULT_DEVICE_SLOT = "default";
|
|
9
|
+
function validateDeviceSlot(slot = "default") {
|
|
10
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(slot) || [
|
|
11
|
+
"constructor",
|
|
12
|
+
"prototype",
|
|
13
|
+
"__proto__"
|
|
14
|
+
].includes(slot)) {
|
|
15
|
+
const error = /* @__PURE__ */ new Error("A device slot must be 1-64 letters, digits, underscores or hyphens, starting with a letter or digit.");
|
|
16
|
+
Object.assign(error, { code: "STIM_BAD_ARG" });
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
return slot;
|
|
20
|
+
}
|
|
21
|
+
function deviceSlotPlatforms(project, slot = DEFAULT_DEVICE_SLOT) {
|
|
22
|
+
validateDeviceSlot(slot);
|
|
23
|
+
if (slot === DEFAULT_DEVICE_SLOT) return project?.platforms;
|
|
24
|
+
return project?.deviceSlots && Object.hasOwn(project.deviceSlots, slot) ? project.deviceSlots[slot] : void 0;
|
|
25
|
+
}
|
|
26
|
+
function projectDeviceSlots(project) {
|
|
27
|
+
const slots = [{
|
|
28
|
+
slot: DEFAULT_DEVICE_SLOT,
|
|
29
|
+
platforms: project?.platforms ?? {}
|
|
30
|
+
}];
|
|
31
|
+
for (const [slot, platforms] of Object.entries(project?.deviceSlots ?? {})) {
|
|
32
|
+
validateDeviceSlot(slot);
|
|
33
|
+
if (slot === DEFAULT_DEVICE_SLOT) throw new Error("The default device slot must use the existing platforms record.");
|
|
34
|
+
if (!platforms || typeof platforms !== "object" || Array.isArray(platforms)) throw new Error(`Invalid device slot record: ${slot}`);
|
|
35
|
+
slots.push({
|
|
36
|
+
slot,
|
|
37
|
+
platforms
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return slots;
|
|
41
|
+
}
|
|
42
|
+
function assignSlotDevice(project, platform, device, slot = DEFAULT_DEVICE_SLOT) {
|
|
43
|
+
validateDeviceSlot(slot);
|
|
44
|
+
if (platform !== "ios" && platform !== "android") throw new Error(`Unknown device platform: ${platform}`);
|
|
45
|
+
if (slot === DEFAULT_DEVICE_SLOT) project.platforms = {
|
|
46
|
+
...project.platforms,
|
|
47
|
+
[platform]: device
|
|
48
|
+
};
|
|
49
|
+
else project.deviceSlots = {
|
|
50
|
+
...project.deviceSlots,
|
|
51
|
+
[slot]: {
|
|
52
|
+
...deviceSlotPlatforms(project, slot),
|
|
53
|
+
[platform]: device
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function removeSlotDevice(project, platform, slot = DEFAULT_DEVICE_SLOT) {
|
|
58
|
+
const platforms = deviceSlotPlatforms(project, slot);
|
|
59
|
+
if (!platforms) return;
|
|
60
|
+
delete platforms[platform];
|
|
61
|
+
if (slot !== DEFAULT_DEVICE_SLOT && Object.keys(platforms).length === 0) {
|
|
62
|
+
delete project.deviceSlots[slot];
|
|
63
|
+
if (Object.keys(project.deviceSlots).length === 0) delete project.deviceSlots;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function deviceSlotKey(platform, slot = "default") {
|
|
67
|
+
validateDeviceSlot(slot);
|
|
68
|
+
if (platform !== "ios" && platform !== "android") throw new Error(`Unknown device platform: ${platform}`);
|
|
69
|
+
return slot === "default" ? platform : `${platform}:${slot}`;
|
|
70
|
+
}
|
|
71
|
+
function parseDeviceSlotKey(key) {
|
|
72
|
+
const [platform, slot = "default", extra] = key.split(":");
|
|
73
|
+
if (platform !== "ios" && platform !== "android" || extra !== void 0) return null;
|
|
74
|
+
try {
|
|
75
|
+
validateDeviceSlot(slot);
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
if (key !== deviceSlotKey(platform, slot)) return null;
|
|
80
|
+
return {
|
|
81
|
+
platform,
|
|
82
|
+
slot
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
7
86
|
//#region src/fs-util.ts
|
|
8
87
|
function volumeRootFor(path) {
|
|
9
88
|
const m = normalize(String(path)).match(/^\/volumes\/([^/]+)/i);
|
|
@@ -266,31 +345,31 @@ function claimMetroPort(projectPath, port) {
|
|
|
266
345
|
return port;
|
|
267
346
|
});
|
|
268
347
|
}
|
|
269
|
-
function setDevice(projectPath, platform, deviceFields) {
|
|
348
|
+
function setDevice(projectPath, platform, deviceFields, slot = "default") {
|
|
270
349
|
requireAbsoluteProjectPath(projectPath);
|
|
271
350
|
withConfigLock(() => {
|
|
272
351
|
const cfg = ensureConfig();
|
|
273
352
|
if (!cfg.projects[projectPath]) throw new Error(`Project not registered: ${projectPath}`);
|
|
274
|
-
cfg.projects[projectPath]
|
|
275
|
-
cfg.projects[projectPath].platforms[platform] = deviceFields;
|
|
353
|
+
assignSlotDevice(cfg.projects[projectPath], platform, deviceFields, slot);
|
|
276
354
|
saveConfig(cfg);
|
|
277
355
|
});
|
|
278
356
|
}
|
|
279
|
-
function releaseAndroidConsolePort(projectPath, consolePort) {
|
|
357
|
+
function releaseAndroidConsolePort(projectPath, consolePort, slot = "default") {
|
|
280
358
|
return withConfigLock(() => {
|
|
281
359
|
const cfg = loadConfig();
|
|
282
|
-
const android = cfg?.projects?.[projectPath]?.
|
|
360
|
+
const android = deviceSlotPlatforms(cfg?.projects?.[projectPath], slot)?.android;
|
|
283
361
|
if (!cfg || !android || android.consolePort !== consolePort) return false;
|
|
284
362
|
delete android.consolePort;
|
|
285
363
|
saveConfig(cfg);
|
|
286
364
|
return true;
|
|
287
365
|
});
|
|
288
366
|
}
|
|
289
|
-
function clearDevice(projectPath, platform) {
|
|
367
|
+
function clearDevice(projectPath, platform, slot = "default") {
|
|
290
368
|
withConfigLock(() => {
|
|
291
369
|
const cfg = loadConfig();
|
|
292
|
-
|
|
293
|
-
|
|
370
|
+
const project = cfg?.projects?.[projectPath];
|
|
371
|
+
if (!cfg || !project) return;
|
|
372
|
+
removeSlotDevice(project, platform, slot);
|
|
294
373
|
saveConfig(cfg);
|
|
295
374
|
});
|
|
296
375
|
}
|
|
@@ -371,11 +450,13 @@ function allConsolePortsAndSerials({ isMounted = isOnMountedVolume } = {}) {
|
|
|
371
450
|
if (!cfg) return result;
|
|
372
451
|
for (const [path, proj] of Object.entries(cfg.projects || {})) {
|
|
373
452
|
if (!existsSync(path) && isMounted(path)) continue;
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
453
|
+
for (const { platforms } of projectDeviceSlots(proj)) {
|
|
454
|
+
const android = platforms.android;
|
|
455
|
+
if (typeof android?.consolePort === "number") result.androidConsolePorts.push(android.consolePort);
|
|
456
|
+
if (android?.serial && !android.avdName) result.androidPhysicalSerials.push(android.serial);
|
|
457
|
+
}
|
|
377
458
|
}
|
|
378
459
|
return result;
|
|
379
460
|
}
|
|
380
461
|
//#endregion
|
|
381
|
-
export { directorySize as A, withConfigLock as C, sameProcessRecord as D, inspectProcessIdentity as E, isOnMountedVolume as M, listMountedVolumes as N, waitForProcessExit as O, volumeRootFor as P, upsertProject as S, captureProcessToken as T, releaseAndroidConsolePort as _, clearSupervisor as a, setDevice as b, findEnclosingWorktreeRoot as c, getConfigPath as d, getProject as f, loadConfig as g, isPathPrefix as h, clearDevice as i, formatBytes as j, withDirLock as k, getConcurrencyLimits as l, getRepoSettings as m, allMetroPorts as n, configCorruptRepair as o, getProjectSettings as p, claimMetroPort as r, ensureConfig as s, allConsolePortsAndSerials as t, getConfigDir as u, removeProject as v, captureProcessIdentity as w, setSupervisor as x, saveConfig as y };
|
|
462
|
+
export { directorySize as A, removeSlotDevice as B, withConfigLock as C, sameProcessRecord as D, inspectProcessIdentity as E, assignSlotDevice as F, deviceSlotKey as I, deviceSlotPlatforms as L, isOnMountedVolume as M, listMountedVolumes as N, waitForProcessExit as O, volumeRootFor as P, parseDeviceSlotKey as R, upsertProject as S, captureProcessToken as T, validateDeviceSlot as V, releaseAndroidConsolePort as _, clearSupervisor as a, setDevice as b, findEnclosingWorktreeRoot as c, getConfigPath as d, getProject as f, loadConfig as g, isPathPrefix as h, clearDevice as i, formatBytes as j, withDirLock as k, getConcurrencyLimits as l, getRepoSettings as m, allMetroPorts as n, configCorruptRepair as o, getProjectSettings as p, claimMetroPort as r, ensureConfig as s, allConsolePortsAndSerials as t, getConfigDir as u, removeProject as v, captureProcessIdentity as w, setSupervisor as x, saveConfig as y, projectDeviceSlots as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
1
|
+
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
2
|
import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-C7IlIzd7.mjs";
|
|
3
|
-
import { f as startBuildHeartbeat, h as bundlerPin, r as HEARTBEAT_INTERVAL_MS } from "./xcode-
|
|
3
|
+
import { f as startBuildHeartbeat, h as bundlerPin, r as HEARTBEAT_INTERVAL_MS } from "./xcode-D7sAp-Zy.mjs";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|