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,276 +0,0 @@
|
|
|
1
|
-
import { _ as loadConfig$1, g as isPathPrefix, l as findEnclosingWorktreeRoot, p as getProject } from "./config-D0DbpZtM.mjs";
|
|
2
|
-
import { U as webSettings, gt as repoRoot, z as settingValueAt } from "./settings-Cfd-0r2d.mjs";
|
|
3
|
-
import { existsSync, readFileSync, readdirSync, realpathSync } from "fs";
|
|
4
|
-
import { basename, dirname, join, resolve } from "path";
|
|
5
|
-
import { findProjectRoot, findProjectRoot as findProjectRoot$1 } from "@stim-cli/core/state";
|
|
6
|
-
//#region src/workspace/project.ts
|
|
7
|
-
/**
|
|
8
|
-
* The realpath of `name`'s package.json in the nearest `node_modules` at or above `projectRoot`.
|
|
9
|
-
* Unlike `require.resolve`, it ignores `NODE_PATH`, which pnpm's bin shims point at the workspace's
|
|
10
|
-
* hidden hoist directory holding every member's dependencies.
|
|
11
|
-
*/
|
|
12
|
-
function resolvePackageJson(projectRoot, name) {
|
|
13
|
-
for (let dir = resolve(projectRoot);; dir = dirname(dir)) {
|
|
14
|
-
const candidate = join(dir, "node_modules", name, "package.json");
|
|
15
|
-
if (existsSync(candidate)) return realpathSync(candidate);
|
|
16
|
-
if (dirname(dir) === dir) return null;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function isPackageResolvable(projectRoot, name) {
|
|
20
|
-
return resolvePackageJson(projectRoot, name) !== null;
|
|
21
|
-
}
|
|
22
|
-
function projectShortcut(path, proj) {
|
|
23
|
-
if (proj?.label) return proj.label;
|
|
24
|
-
const rootPath = findEnclosingWorktreeRoot(path);
|
|
25
|
-
if (rootPath && rootPath !== path) return `${projectShortcut(rootPath, getProject(rootPath))}/${path.split("/").pop() || path}`;
|
|
26
|
-
return path.split("/").pop() || path;
|
|
27
|
-
}
|
|
28
|
-
function ownedDeviceLabel(projectPath) {
|
|
29
|
-
const app = realpathSync(projectPath);
|
|
30
|
-
const root = repoRoot(app);
|
|
31
|
-
const appLabel = basename(app);
|
|
32
|
-
if (!root) return appLabel;
|
|
33
|
-
const worktreeLabel = basename(realpathSync(root));
|
|
34
|
-
return worktreeLabel === appLabel ? appLabel : `${worktreeLabel}-${appLabel}`;
|
|
35
|
-
}
|
|
36
|
-
const NO_PROJECT_REFUSAL = {
|
|
37
|
-
code: "STIM_NO_PROJECT",
|
|
38
|
-
message: "Not in a React Native project (no package.json found).",
|
|
39
|
-
remedy: "Run this from the app directory -- the one holding package.json."
|
|
40
|
-
};
|
|
41
|
-
function findServerWorkspace(startDir) {
|
|
42
|
-
const nearest = findProjectRoot(startDir);
|
|
43
|
-
if (!nearest) return null;
|
|
44
|
-
if (existsSync(join(nearest, "Package.swift"))) return {
|
|
45
|
-
root: nearest,
|
|
46
|
-
from: null
|
|
47
|
-
};
|
|
48
|
-
if (appProjectProblem(nearest)?.kind !== "not-an-app") return {
|
|
49
|
-
root: nearest,
|
|
50
|
-
from: null
|
|
51
|
-
};
|
|
52
|
-
if (Object.keys(getProject(nearest)?.ports ?? {}).length) return {
|
|
53
|
-
root: nearest,
|
|
54
|
-
from: null
|
|
55
|
-
};
|
|
56
|
-
const top = repoRoot(nearest);
|
|
57
|
-
if (!top) return {
|
|
58
|
-
root: nearest,
|
|
59
|
-
from: null
|
|
60
|
-
};
|
|
61
|
-
const worktree = expandedRealpath(top);
|
|
62
|
-
const apps = Object.keys(loadConfig$1()?.projects ?? {}).filter((path) => {
|
|
63
|
-
if (path === nearest || !isPathPrefix(worktree, expandedRealpath(path)) || appProjectProblem(path) !== null) return false;
|
|
64
|
-
const owner = repoRoot(path);
|
|
65
|
-
return owner !== null && expandedRealpath(owner) === worktree;
|
|
66
|
-
});
|
|
67
|
-
return apps.length === 1 ? {
|
|
68
|
-
root: apps[0],
|
|
69
|
-
from: nearest
|
|
70
|
-
} : {
|
|
71
|
-
root: nearest,
|
|
72
|
-
from: null
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function findCommandWorkspace(startDir, note = (line) => console.error(line)) {
|
|
76
|
-
const workspace = findServerWorkspace(startDir);
|
|
77
|
-
if (workspace?.from) note(`Using the Stim workspace ${workspace.root}: ${workspace.from} is not a React Native or Expo app.`);
|
|
78
|
-
return workspace?.root ?? null;
|
|
79
|
-
}
|
|
80
|
-
function expandedRealpath(path) {
|
|
81
|
-
try {
|
|
82
|
-
return realpathSync.native(path);
|
|
83
|
-
} catch {
|
|
84
|
-
return resolve(path);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function loadPackageJson(projectRoot) {
|
|
88
|
-
const p = join(projectRoot, "package.json");
|
|
89
|
-
if (!existsSync(p)) return {
|
|
90
|
-
pkg: null,
|
|
91
|
-
parseError: null
|
|
92
|
-
};
|
|
93
|
-
try {
|
|
94
|
-
return {
|
|
95
|
-
pkg: JSON.parse(readFileSync(p, "utf-8")),
|
|
96
|
-
parseError: null
|
|
97
|
-
};
|
|
98
|
-
} catch (error) {
|
|
99
|
-
return {
|
|
100
|
-
pkg: null,
|
|
101
|
-
parseError: error?.message || String(error)
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function readPackageJson(projectRoot) {
|
|
106
|
-
return loadPackageJson(projectRoot).pkg;
|
|
107
|
-
}
|
|
108
|
-
const APP_DEPENDENCIES = ["react-native", "expo"];
|
|
109
|
-
function declaresAppDependency(pkg) {
|
|
110
|
-
if (!pkg || typeof pkg !== "object") return false;
|
|
111
|
-
const { dependencies, devDependencies } = pkg;
|
|
112
|
-
const deps = {
|
|
113
|
-
...dependencies,
|
|
114
|
-
...devDependencies
|
|
115
|
-
};
|
|
116
|
-
return APP_DEPENDENCIES.some((name) => name in deps);
|
|
117
|
-
}
|
|
118
|
-
function appProjectProblem(projectRoot) {
|
|
119
|
-
const file = join(projectRoot, "package.json");
|
|
120
|
-
const { pkg, parseError } = loadPackageJson(projectRoot);
|
|
121
|
-
if (parseError) return {
|
|
122
|
-
kind: "unreadable",
|
|
123
|
-
message: `${file} is not valid JSON (${parseError}), so Stim cannot tell whether this is a React Native or Expo app.`,
|
|
124
|
-
remedy: `Fix the JSON in ${file} -- an unfinished edit or a merge conflict leaves it unparseable -- then run the command again.`
|
|
125
|
-
};
|
|
126
|
-
if (declaresAppDependency(pkg)) return null;
|
|
127
|
-
return {
|
|
128
|
-
kind: "not-an-app",
|
|
129
|
-
message: `${file} depends on neither react-native nor expo, so this is not a React Native or Expo app.`,
|
|
130
|
-
remedy: "Run this from the app directory -- the one whose package.json depends on react-native or expo -- or from that directory inside a worktree."
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
function detectIsExpo(projectRoot) {
|
|
134
|
-
const pkg = readPackageJson(projectRoot);
|
|
135
|
-
const iosScript = pkg?.scripts?.ios;
|
|
136
|
-
if (typeof iosScript === "string") {
|
|
137
|
-
if (/\bexpo\s+run:ios\b/.test(iosScript)) return true;
|
|
138
|
-
if (/\breact-native\s+run-ios\b/.test(iosScript)) return false;
|
|
139
|
-
}
|
|
140
|
-
if (!pkg) return false;
|
|
141
|
-
const hasExpoDep = "expo" in {
|
|
142
|
-
...pkg.dependencies,
|
|
143
|
-
...pkg.devDependencies
|
|
144
|
-
};
|
|
145
|
-
const resolvable = () => isPackageResolvable(projectRoot, "expo");
|
|
146
|
-
if (!hasExpoDep && !resolvable()) return false;
|
|
147
|
-
const appJson = readAppJson(projectRoot);
|
|
148
|
-
if (appJson?.expo) return true;
|
|
149
|
-
const text = readAppConfigText(projectRoot);
|
|
150
|
-
if (text && /\b(?:from\s+['"]expo['"]|expo\/config|ExpoConfig)\b/.test(text)) return true;
|
|
151
|
-
if (hasExpoDep && resolvable()) return true;
|
|
152
|
-
if (looksLikeExpoConfig(appJson)) return true;
|
|
153
|
-
if (podfileUsesExpoModules(projectRoot)) return true;
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
function detectTutorial(appJson) {
|
|
157
|
-
const extra = appJson?.expo?.extra;
|
|
158
|
-
const version = typeof extra === "object" && extra !== null ? extra.stimTutorial : null;
|
|
159
|
-
return typeof version === "number" && Number.isInteger(version) && version > 0 ? { version } : void 0;
|
|
160
|
-
}
|
|
161
|
-
function detectPlatforms(root, settings) {
|
|
162
|
-
const platforms = /* @__PURE__ */ new Set();
|
|
163
|
-
const product = settingValueAt(settings, "macos.product");
|
|
164
|
-
const infoPlist = settingValueAt(settings, "macos.infoPlist");
|
|
165
|
-
if (existsSync(join(root, "Package.swift")) && product && infoPlist) platforms.add("macos");
|
|
166
|
-
if (webSettings(settings).url !== null) platforms.add("web");
|
|
167
|
-
const pkg = readPackageJson(root);
|
|
168
|
-
const deps = {
|
|
169
|
-
...pkg?.dependencies,
|
|
170
|
-
...pkg?.devDependencies
|
|
171
|
-
};
|
|
172
|
-
if (detectIsExpo(root)) {
|
|
173
|
-
const appJson = readAppJson(root);
|
|
174
|
-
const config = appJson?.expo ?? appJson;
|
|
175
|
-
const text = readAppConfigText(root);
|
|
176
|
-
const explicit = (text ? literalPlatforms(text) : null) ?? config?.platforms;
|
|
177
|
-
if (Array.isArray(explicit)) {
|
|
178
|
-
for (const platform of explicit) if (platform === "ios" || platform === "android" || platform === "web") platforms.add(platform);
|
|
179
|
-
} else {
|
|
180
|
-
platforms.add("ios");
|
|
181
|
-
platforms.add("android");
|
|
182
|
-
if ("react-native-web" in deps || isPackageResolvable(root, "react-native-web")) platforms.add("web");
|
|
183
|
-
}
|
|
184
|
-
} else if (declaresAppDependency(pkg)) {
|
|
185
|
-
let ios = [];
|
|
186
|
-
try {
|
|
187
|
-
ios = readdirSync(join(root, "ios"));
|
|
188
|
-
} catch {}
|
|
189
|
-
if (ios.some((name) => name.endsWith(".xcodeproj") || name.endsWith(".xcworkspace"))) platforms.add("ios");
|
|
190
|
-
if ([
|
|
191
|
-
"build.gradle",
|
|
192
|
-
"build.gradle.kts",
|
|
193
|
-
"settings.gradle",
|
|
194
|
-
"settings.gradle.kts"
|
|
195
|
-
].some((name) => existsSync(join(root, "android", name)))) platforms.add("android");
|
|
196
|
-
}
|
|
197
|
-
return [
|
|
198
|
-
"ios",
|
|
199
|
-
"android",
|
|
200
|
-
"macos",
|
|
201
|
-
"web"
|
|
202
|
-
].filter((platform) => platforms.has(platform));
|
|
203
|
-
}
|
|
204
|
-
function literalPlatforms(text) {
|
|
205
|
-
const tokens = text.match(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|[A-Za-z_$][\w$]*|[^\s]/g)?.filter((token) => !token.startsWith("//") && !token.startsWith("/*")) ?? [];
|
|
206
|
-
let open = 0;
|
|
207
|
-
const index = tokens.findIndex((token, i) => {
|
|
208
|
-
if (token === "[") open++;
|
|
209
|
-
else if (token === "]") open--;
|
|
210
|
-
return open === 0 && (token === "platforms" || token === "\"platforms\"" || token === "'platforms'") && tokens[i + 1] === ":";
|
|
211
|
-
});
|
|
212
|
-
if (index < 0 || tokens[index + 2] !== "[") return null;
|
|
213
|
-
const platforms = [];
|
|
214
|
-
let i = index + 3;
|
|
215
|
-
while (tokens[i] !== "]") {
|
|
216
|
-
const value = tokens[i]?.match(/^(['"])([a-z]+)\1$/)?.[2];
|
|
217
|
-
if (value === void 0) return null;
|
|
218
|
-
platforms.push(value);
|
|
219
|
-
i++;
|
|
220
|
-
if (tokens[i] === ",") i++;
|
|
221
|
-
else if (tokens[i] !== "]") return null;
|
|
222
|
-
}
|
|
223
|
-
return tokens[i + 1] === "," || tokens[i + 1] === "}" ? platforms : null;
|
|
224
|
-
}
|
|
225
|
-
function looksLikeExpoConfig(appJson) {
|
|
226
|
-
if (!appJson || typeof appJson !== "object" || Array.isArray(appJson)) return false;
|
|
227
|
-
if (appJson.expo) return true;
|
|
228
|
-
if ([
|
|
229
|
-
"slug",
|
|
230
|
-
"plugins",
|
|
231
|
-
"sdkVersion",
|
|
232
|
-
"experiments",
|
|
233
|
-
"runtimeVersion",
|
|
234
|
-
"updates",
|
|
235
|
-
"buildCacheProvider",
|
|
236
|
-
"assetBundlePatterns",
|
|
237
|
-
"splash",
|
|
238
|
-
"orientation",
|
|
239
|
-
"userInterfaceStyle"
|
|
240
|
-
].some((key) => appJson[key] !== void 0)) return true;
|
|
241
|
-
return Boolean(appJson.extra && typeof appJson.extra === "object" && appJson.extra.eas);
|
|
242
|
-
}
|
|
243
|
-
function podfileUsesExpoModules(projectRoot) {
|
|
244
|
-
const p = join(projectRoot, "ios", "Podfile");
|
|
245
|
-
if (!existsSync(p)) return false;
|
|
246
|
-
try {
|
|
247
|
-
return /^[^#\n]*use_expo_modules!/m.test(readFileSync(p, "utf-8"));
|
|
248
|
-
} catch {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function readAppJson(projectRoot) {
|
|
253
|
-
const p = join(projectRoot, "app.json");
|
|
254
|
-
if (!existsSync(p)) return null;
|
|
255
|
-
try {
|
|
256
|
-
return JSON.parse(readFileSync(p, "utf-8"));
|
|
257
|
-
} catch {
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
function readAppConfigText(projectRoot) {
|
|
262
|
-
for (const name of [
|
|
263
|
-
"app.config.js",
|
|
264
|
-
"app.config.ts",
|
|
265
|
-
"app.config.cjs",
|
|
266
|
-
"app.config.mjs"
|
|
267
|
-
]) {
|
|
268
|
-
const p = join(projectRoot, name);
|
|
269
|
-
if (existsSync(p)) try {
|
|
270
|
-
return readFileSync(p, "utf-8");
|
|
271
|
-
} catch {}
|
|
272
|
-
}
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
|
-
//#endregion
|
|
276
|
-
export { detectTutorial as a, findServerWorkspace as c, projectShortcut as d, readAppConfigText as f, detectPlatforms as i, isPackageResolvable as l, resolvePackageJson as m, appProjectProblem as n, findCommandWorkspace as o, readAppJson as p, detectIsExpo as r, findProjectRoot$1 as s, NO_PROJECT_REFUSAL as t, ownedDeviceLabel as u };
|
package/dist/state-BKa8wNN5.mjs
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { B as parseDeviceSlotKey, R as deviceSlotKey } from "./config-D0DbpZtM.mjs";
|
|
2
|
-
import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
3
|
-
import { C as workspaceStateFile, a as updateWorkspaceState, h as supervisorPidFile, o as withWorkspaceStateLock, r as readWorkspaceState, t as clearWorkspaceStateKey } from "./workspace-state-DqcCbpE7.mjs";
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { dirname } from "node:path";
|
|
6
|
-
//#region src/supervisor/state.ts
|
|
7
|
-
const MODE_BARE = "bare-inproc";
|
|
8
|
-
const MODE_EXPO = "expo-child";
|
|
9
|
-
function readMetroTunnel(root) {
|
|
10
|
-
const record = readWorkspaceState(root)?.metroTunnel;
|
|
11
|
-
if (!record || typeof record !== "object") return null;
|
|
12
|
-
const kind = record.kind;
|
|
13
|
-
const url = record.url;
|
|
14
|
-
if (typeof url !== "string" || url.length === 0) return null;
|
|
15
|
-
if (kind === "expo") return {
|
|
16
|
-
kind: "expo",
|
|
17
|
-
url
|
|
18
|
-
};
|
|
19
|
-
if (kind === "managed") {
|
|
20
|
-
const provider = record.provider;
|
|
21
|
-
const pid = record.pid;
|
|
22
|
-
const port = record.port;
|
|
23
|
-
const startedAt = record.startedAt;
|
|
24
|
-
const processToken = record.processToken;
|
|
25
|
-
const logFile = record.logFile;
|
|
26
|
-
if (provider !== "ngrok" && provider !== "cloudflared" && provider !== "tailscale" || typeof pid !== "number" || typeof port !== "number") return null;
|
|
27
|
-
return {
|
|
28
|
-
kind: "managed",
|
|
29
|
-
provider,
|
|
30
|
-
pid,
|
|
31
|
-
url,
|
|
32
|
-
port,
|
|
33
|
-
startedAt: typeof startedAt === "string" ? startedAt : "",
|
|
34
|
-
processToken: typeof processToken === "string" && processToken.length > 0 ? processToken : null,
|
|
35
|
-
...typeof logFile === "string" && logFile.length > 0 ? { logFile } : {}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
function parseWorkspaceLaunchRecord(value) {
|
|
41
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
42
|
-
const record = value;
|
|
43
|
-
if (typeof record.appId !== "string" || record.appId.length === 0) return null;
|
|
44
|
-
if (typeof record.deviceId !== "string" || record.deviceId.length === 0) return null;
|
|
45
|
-
if (record.metroPort !== null && typeof record.metroPort !== "number") return null;
|
|
46
|
-
if (typeof record.release !== "boolean") return null;
|
|
47
|
-
if (typeof record.launchedAt !== "string") return null;
|
|
48
|
-
return record;
|
|
49
|
-
}
|
|
50
|
-
function readWorkspaceLaunches(root) {
|
|
51
|
-
const launches = readWorkspaceState(root)?.launches;
|
|
52
|
-
if (!launches || typeof launches !== "object" || Array.isArray(launches)) return {};
|
|
53
|
-
const records = {};
|
|
54
|
-
for (const [key, value] of Object.entries(launches)) {
|
|
55
|
-
const record = parseWorkspaceLaunchRecord(value);
|
|
56
|
-
if (parseDeviceSlotKey(key) && record) records[key] = record;
|
|
57
|
-
}
|
|
58
|
-
return records;
|
|
59
|
-
}
|
|
60
|
-
function writeWorkspaceLaunch(root, platform, record, slot = "default") {
|
|
61
|
-
updateWorkspaceState(root, (state) => {
|
|
62
|
-
const launches = state.launches && typeof state.launches === "object" ? state.launches : {};
|
|
63
|
-
return {
|
|
64
|
-
...state,
|
|
65
|
-
launches: {
|
|
66
|
-
...launches,
|
|
67
|
-
[deviceSlotKey(platform, slot)]: record
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
function clearWorkspaceLaunches(root, slot) {
|
|
73
|
-
updateWorkspaceState(root, (state) => {
|
|
74
|
-
if (!state.launches || typeof state.launches !== "object") return state;
|
|
75
|
-
const launches = { ...state.launches };
|
|
76
|
-
delete launches[deviceSlotKey("ios", slot)];
|
|
77
|
-
delete launches[deviceSlotKey("android", slot)];
|
|
78
|
-
return {
|
|
79
|
-
...state,
|
|
80
|
-
launches
|
|
81
|
-
};
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
function readRemoteSession(root) {
|
|
85
|
-
const record = readWorkspaceState(root)?.remoteDevice;
|
|
86
|
-
if (!record || typeof record !== "object") return null;
|
|
87
|
-
const id = record.sessionId;
|
|
88
|
-
if (typeof id !== "string" || id.length === 0) return null;
|
|
89
|
-
const platform = record.platform;
|
|
90
|
-
const startedAt = record.startedAt;
|
|
91
|
-
const webPreviewUrl = record.webPreviewUrl;
|
|
92
|
-
const deviceType = record.deviceType;
|
|
93
|
-
return {
|
|
94
|
-
platform: platform === "ios" || platform === "android" ? platform : null,
|
|
95
|
-
sessionId: id,
|
|
96
|
-
startedAt: typeof startedAt === "string" ? startedAt : null,
|
|
97
|
-
webPreviewUrl: typeof webPreviewUrl === "string" && webPreviewUrl.length > 0 ? webPreviewUrl : null,
|
|
98
|
-
deviceType: typeof deviceType === "string" && deviceType.length > 0 ? deviceType : null
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
function readRemoteSessionId(root) {
|
|
102
|
-
return readRemoteSession(root)?.sessionId ?? null;
|
|
103
|
-
}
|
|
104
|
-
function clearRemoteSession(root, expectedSessionId) {
|
|
105
|
-
clearWorkspaceStateKey(root, "remoteDevice", (value) => {
|
|
106
|
-
if (typeof value !== "object" || value === null) return false;
|
|
107
|
-
return value.sessionId === expectedSessionId;
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function clearWorkspaceSupervisor(root, expected) {
|
|
111
|
-
return withWorkspaceStateLock(root, () => {
|
|
112
|
-
const current = readWorkspaceState(root)?.supervisor;
|
|
113
|
-
if (current && expected !== void 0 && !(0, process_identity_exports.sameProcessRecord)(current, expected)) return false;
|
|
114
|
-
clearWorkspaceStateKey(root, "supervisor", () => true);
|
|
115
|
-
clearExpoMetroTunnel(root);
|
|
116
|
-
if (expected === void 0 || readPidFile(root) === expected?.pid) rmSync(supervisorPidFile(root), { force: true });
|
|
117
|
-
return true;
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
function clearExpoMetroTunnel(root) {
|
|
121
|
-
clearWorkspaceStateKey(root, "metroTunnel", (value) => {
|
|
122
|
-
return typeof value === "object" && value !== null && value.kind === "expo";
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
function clearManagedMetroTunnel(root, expected) {
|
|
126
|
-
if (!existsSync(workspaceStateFile(root))) return true;
|
|
127
|
-
return clearWorkspaceStateKey(root, "metroTunnel", (value) => {
|
|
128
|
-
if (typeof value !== "object" || value === null) return false;
|
|
129
|
-
const record = value;
|
|
130
|
-
return record.kind === "managed" && record.provider === expected.provider && record.pid === expected.pid && record.url === expected.url && record.port === expected.port && record.startedAt === expected.startedAt && (record.processToken ?? null) === (expected.processToken ?? null) && (record.logFile ?? null) === (expected.logFile ?? null);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function writePidFile(root, pid) {
|
|
134
|
-
const file = supervisorPidFile(root);
|
|
135
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
136
|
-
writeFileSync(file, `${pid}\n`);
|
|
137
|
-
return file;
|
|
138
|
-
}
|
|
139
|
-
function readPidFile(root) {
|
|
140
|
-
try {
|
|
141
|
-
const pid = parseInt(readFileSync(supervisorPidFile(root), "utf-8").trim(), 10);
|
|
142
|
-
return Number.isFinite(pid) ? pid : null;
|
|
143
|
-
} catch {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
//#endregion
|
|
148
|
-
export { clearRemoteSession as a, readMetroTunnel as c, readRemoteSessionId as d, readWorkspaceLaunches as f, clearManagedMetroTunnel as i, readPidFile as l, writeWorkspaceLaunch as m, MODE_EXPO as n, clearWorkspaceLaunches as o, writePidFile as p, clearExpoMetroTunnel as r, clearWorkspaceSupervisor as s, MODE_BARE as t, readRemoteSession as u };
|
package/dist/stop-BIiM49EY.mjs
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
2
|
-
import { c as writeWorkspaceState, v as workspaceDir } from "./workspace-state-DqcCbpE7.mjs";
|
|
3
|
-
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-2mNzOlaB.mjs";
|
|
4
|
-
import { a as requiredMacosRecord, i as macosRuntimeClaim } from "./state-DyaNTgfR.mjs";
|
|
5
|
-
import { n as stopHostedMacos } from "./hosted-macos-DcxKjtfH.mjs";
|
|
6
|
-
import { readMacosRecord } from "@stim-cli/core/state";
|
|
7
|
-
//#region src/macos/stop.ts
|
|
8
|
-
async function stopProcess(record) {
|
|
9
|
-
if (!record) return;
|
|
10
|
-
for (const signal of ["SIGTERM", "SIGKILL"]) {
|
|
11
|
-
const identity = (0, process_identity_exports.inspectProcessIdentity)(record);
|
|
12
|
-
if (identity === "gone" || identity === "different") return;
|
|
13
|
-
if (identity !== "same") throw Object.assign(/* @__PURE__ */ new Error(`Cannot verify macOS owner pid ${record.pid}; no signal was sent.`), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
|
|
14
|
-
process.kill(record.pid, signal);
|
|
15
|
-
if (await (0, process_identity_exports.waitForProcessExit)(record, 5e3)) return;
|
|
16
|
-
}
|
|
17
|
-
throw new Error(`Owned macOS process ${record.pid} did not exit.`);
|
|
18
|
-
}
|
|
19
|
-
async function stopMacosAppHeld(root) {
|
|
20
|
-
const record = requiredMacosRecord(root);
|
|
21
|
-
if (!record) return false;
|
|
22
|
-
await stopProcess(record.supervisor);
|
|
23
|
-
await stopProcess(readMacosRecord(root)?.app ?? record.app);
|
|
24
|
-
const claims = (0, ownership_claim_exports.readClaimSet)(macosRuntimeClaim(root));
|
|
25
|
-
if (claims.unresolved.length || claims.live.length) throw Object.assign(/* @__PURE__ */ new Error("The macOS runtime claim cannot be released; inspect its recorded owner before cleanup."), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
/** Stops the workspace's app here, or its session on the hosting Mac, which must confirm the session stopped. */
|
|
29
|
-
function stopMacosApp(root) {
|
|
30
|
-
const stop = async () => {
|
|
31
|
-
const record = requiredMacosRecord(root);
|
|
32
|
-
if (!record?.host) return stopMacosAppHeld(root);
|
|
33
|
-
await stopHostedMacos(root, record.host);
|
|
34
|
-
const { host: _host, hostLaunched: _launched, ...stopped } = record;
|
|
35
|
-
writeWorkspaceState(root, { macos: {
|
|
36
|
-
...stopped,
|
|
37
|
-
supervisor: void 0
|
|
38
|
-
} });
|
|
39
|
-
return true;
|
|
40
|
-
};
|
|
41
|
-
return withWorkspaceProcessLock(workspaceDir(root), "macos-launch", stop, {
|
|
42
|
-
external: true,
|
|
43
|
-
waitMs: 0,
|
|
44
|
-
ownerPurpose: "stop macOS app"
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { stopMacosAppHeld as n, stopMacosApp as t };
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
2
|
-
import { c as writeWorkspaceState, t as clearWorkspaceStateKey, x as workspaceLogsDir$1 } from "./workspace-state-DqcCbpE7.mjs";
|
|
3
|
-
import { r as createNdjsonWriter } from "./ndjson-PclOIwVY.mjs";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { LOG_ROTATE_BYTES } from "@stim-cli/core";
|
|
6
|
-
import { DEV_SERVER_STOP_REQUEST_KEY, readDevServerStop, readDevServerStopRequest } from "@stim-cli/core/state";
|
|
7
|
-
//#region src/supervisor/stop-cause.ts
|
|
8
|
-
function requestDevServerStop(root, processToken, requester) {
|
|
9
|
-
if (!processToken) return;
|
|
10
|
-
try {
|
|
11
|
-
writeWorkspaceState(root, { [DEV_SERVER_STOP_REQUEST_KEY]: {
|
|
12
|
-
processToken,
|
|
13
|
-
by: requester.by,
|
|
14
|
-
pid: process.pid,
|
|
15
|
-
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16
|
-
...requester.workspace ? { workspace: requester.workspace } : {}
|
|
17
|
-
} });
|
|
18
|
-
} catch {}
|
|
19
|
-
}
|
|
20
|
-
function withdrawDevServerStopRequest(root, processToken) {
|
|
21
|
-
if (!processToken) return;
|
|
22
|
-
try {
|
|
23
|
-
clearWorkspaceStateKey(root, DEV_SERVER_STOP_REQUEST_KEY, (value) => {
|
|
24
|
-
return readDevServerStopRequest({ [DEV_SERVER_STOP_REQUEST_KEY]: value })?.processToken === processToken;
|
|
25
|
-
});
|
|
26
|
-
} catch {}
|
|
27
|
-
}
|
|
28
|
-
function devServerStopRecord(trigger, request, at) {
|
|
29
|
-
if (request) return {
|
|
30
|
-
reason: "requested",
|
|
31
|
-
at,
|
|
32
|
-
by: request.by,
|
|
33
|
-
byPid: request.pid,
|
|
34
|
-
...request.workspace ? { byWorkspace: request.workspace } : {}
|
|
35
|
-
};
|
|
36
|
-
return trigger.kind === "signal" ? {
|
|
37
|
-
reason: "signal",
|
|
38
|
-
at,
|
|
39
|
-
signal: trigger.signal
|
|
40
|
-
} : {
|
|
41
|
-
reason: "server-exited",
|
|
42
|
-
at,
|
|
43
|
-
mode: trigger.mode,
|
|
44
|
-
code: trigger.code,
|
|
45
|
-
signal: trigger.signal
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function describeDevServerStop(record) {
|
|
49
|
-
if (record.reason === "idle") return `idle for ${record.idleMinutes} minutes (metro.idleStopMinutes)`;
|
|
50
|
-
if (record.reason === "requested") return `stop requested by ${record.by} (pid ${record.byPid}${record.byWorkspace ? ` in ${record.byWorkspace}` : ""})`;
|
|
51
|
-
if (record.reason === "signal") return `received ${record.signal} with no Stim stop request recorded, so it likely came from outside Stim`;
|
|
52
|
-
const detail = record.signal ? `signal ${record.signal}` : `exit code ${record.code ?? "unknown"}`;
|
|
53
|
-
const expoSignal = record.mode === "expo-child" && record.code === 0 ? "; Expo CLI also exits 0 on SIGTERM, and no Stim stop request was recorded" : "";
|
|
54
|
-
return `the ${record.mode} dev server exited unexpectedly (${detail})${expoSignal}`;
|
|
55
|
-
}
|
|
56
|
-
function devServerStopLevel(record) {
|
|
57
|
-
if (record.reason === "server-exited") return "error";
|
|
58
|
-
return record.reason === "signal" ? "warn" : "info";
|
|
59
|
-
}
|
|
60
|
-
/** The log line for a recorded supervisor whose process is proven gone, or null while it may still run. */
|
|
61
|
-
function vanishedSupervisorMessage(record) {
|
|
62
|
-
if (!record || typeof record.pid !== "number") return null;
|
|
63
|
-
const identity = (0, process_identity_exports.inspectProcessIdentity)(record);
|
|
64
|
-
if (identity !== "gone" && identity !== "different") return null;
|
|
65
|
-
const started = typeof record.startedAt === "string" ? ` (started ${record.startedAt})` : "";
|
|
66
|
-
return `supervisor pid ${record.pid}${started} ${VANISHED}`;
|
|
67
|
-
}
|
|
68
|
-
const VANISHED = "is gone and recorded no cause: usually SIGKILL, a crash or a machine restart";
|
|
69
|
-
function logVanishedSupervisor(root, record) {
|
|
70
|
-
const msg = vanishedSupervisorMessage(record);
|
|
71
|
-
if (!msg) return;
|
|
72
|
-
const writer = createNdjsonWriter(join(workspaceLogsDir$1(root), "metro.ndjson"), { maxBytes: LOG_ROTATE_BYTES });
|
|
73
|
-
writer.write({
|
|
74
|
-
src: "metro",
|
|
75
|
-
level: "warn",
|
|
76
|
-
event: "supervisor_vanished",
|
|
77
|
-
msg
|
|
78
|
-
});
|
|
79
|
-
writer.close();
|
|
80
|
-
}
|
|
81
|
-
/** The recorded stop, else a vanished supervisor when status proved the recorded one gone. */
|
|
82
|
-
function metroLastStop(state, supervisor) {
|
|
83
|
-
const recorded = readDevServerStop(state);
|
|
84
|
-
if (recorded) return recorded;
|
|
85
|
-
if (supervisor?.status !== "stale" || typeof supervisor.pid !== "number") return null;
|
|
86
|
-
const startedAt = typeof supervisor.startedAt === "string" ? supervisor.startedAt : null;
|
|
87
|
-
return {
|
|
88
|
-
reason: "vanished",
|
|
89
|
-
pid: supervisor.pid,
|
|
90
|
-
startedAt
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function describeMetroLastStop(stop) {
|
|
94
|
-
return stop.reason === "vanished" ? `supervisor pid ${stop.pid} ${VANISHED}` : describeDevServerStop(stop);
|
|
95
|
-
}
|
|
96
|
-
//#endregion
|
|
97
|
-
export { logVanishedSupervisor as a, vanishedSupervisorMessage as c, devServerStopRecord as i, withdrawDevServerStopRequest as l, describeMetroLastStop as n, metroLastStop as o, devServerStopLevel as r, requestDevServerStop as s, describeDevServerStop as t };
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-CaErVv7t.mjs";
|
|
2
|
-
//#region src/watchman.ts
|
|
3
|
-
/** Runs one watchman command with `--no-spawn`, so Stim never starts a daemon, and parses its JSON answer. */
|
|
4
|
-
const runWatchman = async (args, timeoutMs) => JSON.parse(await getExecutor().runFileAsync("watchman", ["--no-spawn", ...args], { timeoutMs }));
|
|
5
|
-
function parseWatchRoots(payload) {
|
|
6
|
-
const roots = payload?.roots;
|
|
7
|
-
if (!Array.isArray(roots)) return null;
|
|
8
|
-
return roots.filter((root) => typeof root === "string");
|
|
9
|
-
}
|
|
10
|
-
function parseSubscriberNames(payload) {
|
|
11
|
-
if (!payload || typeof payload !== "object" || "error" in payload) return null;
|
|
12
|
-
const subscribers = payload.subscribers;
|
|
13
|
-
if (subscribers === void 0) return [];
|
|
14
|
-
if (!Array.isArray(subscribers)) return null;
|
|
15
|
-
const names = [];
|
|
16
|
-
for (const subscriber of subscribers) {
|
|
17
|
-
const name = subscriber?.info?.name;
|
|
18
|
-
if (typeof name !== "string") return null;
|
|
19
|
-
names.push(name);
|
|
20
|
-
}
|
|
21
|
-
return names;
|
|
22
|
-
}
|
|
23
|
-
function parseTriggerCount(payload) {
|
|
24
|
-
const triggers = payload?.triggers;
|
|
25
|
-
return Array.isArray(triggers) ? triggers.length : null;
|
|
26
|
-
}
|
|
27
|
-
function parseWatchmanPid(payload) {
|
|
28
|
-
const pid = payload?.pid;
|
|
29
|
-
return typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
30
|
-
}
|
|
31
|
-
/** The connected clients in a `debug-status` answer, or null when the answer does not list them. */
|
|
32
|
-
function parseWatchmanClients(payload) {
|
|
33
|
-
if (!payload || typeof payload !== "object" || "error" in payload) return null;
|
|
34
|
-
const clients = payload.clients;
|
|
35
|
-
if (!Array.isArray(clients)) return null;
|
|
36
|
-
const parsed = [];
|
|
37
|
-
for (const client of clients) {
|
|
38
|
-
const peer = client?.peer;
|
|
39
|
-
if (typeof peer?.pid !== "number") return null;
|
|
40
|
-
parsed.push({
|
|
41
|
-
pid: peer.pid,
|
|
42
|
-
name: typeof peer.name === "string" ? peer.name : null
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
return parsed;
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { parseWatchmanPid as a, parseWatchmanClients as i, parseTriggerCount as n, runWatchman as o, parseWatchRoots as r, parseSubscriberNames as t };
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { n as ownership_claim_exports } from "./process-identity-BmRm1qV0.mjs";
|
|
2
|
-
import { n as declareSpawnsOn, o as stopDeclaringSpawnsOn } from "./spawn-claims-D0XfSe8u.mjs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { setTimeout } from "node:timers/promises";
|
|
5
|
-
//#region src/engine/workspace-process-lock.ts
|
|
6
|
-
const DEFAULT_WAIT_MS = 6e4;
|
|
7
|
-
const POLL_MS = 25;
|
|
8
|
-
function workspaceProcessLockError(err) {
|
|
9
|
-
const code = err?.code;
|
|
10
|
-
if (code === "STIM_LOCK_REFUSED") return "refused";
|
|
11
|
-
if (code === "STIM_LOCK_TIMEOUT") return "timeout";
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
function workspaceProcessLockPath(root, name, external) {
|
|
15
|
-
return external ? join(root, `${name}.lock`) : join(root, ".stim", `${name}.lock`);
|
|
16
|
-
}
|
|
17
|
-
async function withWorkspaceProcessLock(root, name, fn, { now = Date.now, signal, sleep = (ms) => setTimeout(ms, void 0, { signal }), waitMs = DEFAULT_WAIT_MS, ownerPurpose, details = {}, onHeld, rejectOwnerPurposes = [], external = false, declareSpawns = false } = {}) {
|
|
18
|
-
const path = workspaceProcessLockPath(root, name, external);
|
|
19
|
-
const deadline = now() + waitMs;
|
|
20
|
-
for (;;) {
|
|
21
|
-
signal?.throwIfAborted();
|
|
22
|
-
const attempt = (0, ownership_claim_exports.tryAcquireClaim)({
|
|
23
|
-
root: path,
|
|
24
|
-
mode: "exclusive",
|
|
25
|
-
label: `${name} lock`,
|
|
26
|
-
details: ownerPurpose ? {
|
|
27
|
-
...details,
|
|
28
|
-
purpose: ownerPurpose
|
|
29
|
-
} : details
|
|
30
|
-
});
|
|
31
|
-
if (attempt.pending) (0, ownership_claim_exports.releaseClaim)(attempt.pending);
|
|
32
|
-
if (attempt.acquired) {
|
|
33
|
-
if (declareSpawns) declareSpawnsOn(attempt.acquired);
|
|
34
|
-
try {
|
|
35
|
-
return await fn(attempt.acquired);
|
|
36
|
-
} finally {
|
|
37
|
-
stopDeclaringSpawnsOn(attempt.acquired);
|
|
38
|
-
(0, ownership_claim_exports.releaseClaim)(attempt.acquired);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const holder = attempt.held ?? attempt.waitingFor?.[0];
|
|
42
|
-
const purpose = holder?.details.purpose;
|
|
43
|
-
if (typeof purpose === "string" && rejectOwnerPurposes.includes(purpose)) {
|
|
44
|
-
const error = /* @__PURE__ */ new Error(`The ${name} lock at ${path} is held for ${purpose}.`);
|
|
45
|
-
error.code = "STIM_LOCK_REFUSED";
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
if (holder && onHeld) await onHeld(holder);
|
|
49
|
-
if (now() >= deadline) {
|
|
50
|
-
const error = /* @__PURE__ */ new Error(`Timed out waiting for the ${name} lock at ${path}.`);
|
|
51
|
-
error.code = "STIM_LOCK_TIMEOUT";
|
|
52
|
-
throw error;
|
|
53
|
-
}
|
|
54
|
-
await sleep(POLL_MS);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
//#endregion
|
|
58
|
-
export { workspaceProcessLockError as n, workspaceProcessLockPath as r, withWorkspaceProcessLock as t };
|