stim 1.14.0 → 1.16.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.
Files changed (152) hide show
  1. package/README.md +2 -0
  2. package/dist/activity-BxwdD81S.mjs +609 -0
  3. package/dist/agent-device-usage-output-Dpih1Tfa.mjs +411 -0
  4. package/dist/{android-d6rGq1pA.mjs → android-B_NumVyQ.mjs} +169 -81
  5. package/dist/{android-LbPFRWVL.mjs → android-Ift4kVvt.mjs} +517 -413
  6. package/dist/android-cas-8U4DPqeR.mjs +167 -0
  7. package/dist/android-cas-compiler.mjs +2 -2
  8. package/dist/{android-XpvCrV7q.mjs → android-r2rBL8kV.mjs} +2 -2
  9. package/dist/{app-install-BpgSgkJj.mjs → app-install-CKWdbXIX.mjs} +128 -151
  10. package/dist/attempt-Bk2ouQVL.mjs +39 -0
  11. package/dist/budget-DjrURfQn.mjs +2700 -0
  12. package/dist/{build-plan-Dcr-3ie0.mjs → build-plan-DjeSb2Xl.mjs} +192 -653
  13. package/dist/build-slots-rUk77xqh.mjs +132 -0
  14. package/dist/{cache-manifest-C68QQ0ua.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
  15. package/dist/cache-manifest.mjs +1 -1
  16. package/dist/{chrome-BPCiC3ZX.mjs → chrome-BrcVWQyD.mjs} +1 -1
  17. package/dist/cli-BkYZ_6hy.mjs +51 -0
  18. package/dist/cli.mjs +6 -42
  19. package/dist/client-BTY686R6.mjs +1368 -0
  20. package/dist/collector-run.mjs +9 -195
  21. package/dist/{command-output-DVcpw6eE.mjs → command-output-DnJMdEY-.mjs} +1 -1
  22. package/dist/{config-lvc7d3C2.mjs → config-D0DbpZtM.mjs} +28 -29
  23. package/dist/{created-devices-CllH_8eb.mjs → created-devices-D5owjN4C.mjs} +2 -2
  24. package/dist/{dependency-state-DsT7aKeo.mjs → dependency-state-B6cMXZab.mjs} +2 -2
  25. package/dist/{deps-D9IcKqXS.mjs → deps-urbmfXig.mjs} +3 -3
  26. package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
  27. package/dist/dev-client-CroAIjjj.mjs +43 -0
  28. package/dist/{device-CjuuAJjQ.mjs → device-DZQjF7H5.mjs} +8 -7
  29. package/dist/device-capacity-BHwxNBlu.mjs +136 -0
  30. package/dist/device-host-worker.d.mts +1 -0
  31. package/dist/device-host-worker.mjs +964 -0
  32. package/dist/device-ios-BadmeL2V.mjs +381 -0
  33. package/dist/{device-lease-5c3WrVRm.mjs → device-lease-D-hLqx1b.mjs} +43 -36
  34. package/dist/{device-pool-BiyDyPP-.mjs → device-lease-run-CqjShqWW.mjs} +6 -126
  35. package/dist/device-pool-CUaEWMMm.mjs +125 -0
  36. package/dist/{device-remote-D87zEzaq.mjs → device-remote-D5WVWqOq.mjs} +69 -163
  37. package/dist/{doctor-x9pnU9fq.mjs → doctor-Cimf-gGB.mjs} +241 -103
  38. package/dist/{error-diagnostics-C5HzcwCW.mjs → error-diagnostics-B9L4Ae0x.mjs} +15 -18
  39. package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
  40. package/dist/{gc-ko6mUAYD.mjs → gc-Bqy4bjEu.mjs} +599 -108
  41. package/dist/{android-cas-iZK3DOCr.mjs → gradle-BsO1MdsH.mjs} +8 -294
  42. package/dist/{guide-6R0VNFqI.mjs → guide-B_uyKTxW.mjs} +2511 -239
  43. package/dist/{guide-status-BZrFPIA_.mjs → guide-status-CjEZMAD4.mjs} +3 -3
  44. package/dist/hosted-client-a-WmqE2L.mjs +197 -0
  45. package/dist/hosted-ios-CIWelIqf.mjs +220 -0
  46. package/dist/hosted-logs-D5g041Q3.mjs +187 -0
  47. package/dist/hosted-macos-BSZyIb3y.mjs +135 -0
  48. package/dist/idle-DYVymG92.mjs +1099 -0
  49. package/dist/idle-shutdown-CTsDnAde.mjs +122 -0
  50. package/dist/in-use-DvBw0Kxo.mjs +130 -0
  51. package/dist/{ios-BwDPrnYQ.mjs → ios-BaInn3sW.mjs} +201 -10
  52. package/dist/ios-Cr1h5gnO.mjs +189 -0
  53. package/dist/{ios-P1f5nm2n.mjs → ios-aq3QoGI3.mjs} +1159 -633
  54. package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
  55. package/dist/{ios-device-DGglU3E_.mjs → ios-device-FfCN_C8p.mjs} +12 -7
  56. package/dist/ios-state-DS5UpYTH.mjs +48 -0
  57. package/dist/{launch-verify-Deg4tB3Z.mjs → launch-verify-2DBRizjo.mjs} +5 -5
  58. package/dist/logs-CHEVK8zD.mjs +371 -0
  59. package/dist/machines-BIBUdhpj.mjs +265 -0
  60. package/dist/macos-CSYEAFmF.mjs +473 -0
  61. package/dist/macos-run.d.mts +5 -0
  62. package/dist/macos-run.mjs +2 -0
  63. package/dist/maintenance-run.d.mts +4 -0
  64. package/dist/maintenance-run.mjs +254 -0
  65. package/dist/{metro-CcEo8Fl8.mjs → metro-BeK1ZPz1.mjs} +20 -120
  66. package/dist/metro-gateway-BJ-rxQAB.mjs +84 -0
  67. package/dist/{named-ports-Blg8IxOh.mjs → named-ports-Bk_YXEmE.mjs} +6 -59
  68. package/dist/native-run-NaBrRFtQ.mjs +147 -0
  69. package/dist/{native-runtime-DjBHRg5m.mjs → native-runtime-DBzRnEKS.mjs} +9 -5
  70. package/dist/{ndjson-CDY9IkVC.mjs → ndjson-PclOIwVY.mjs} +2 -2
  71. package/dist/offload-worker.d.mts +122 -0
  72. package/dist/offload-worker.mjs +606 -0
  73. package/dist/{ownership-DyYDF5ww.mjs → ownership-DiA16AsN.mjs} +3 -2
  74. package/dist/ownership-hCkPzGmr.mjs +571 -0
  75. package/dist/{page-BHUzTDFt.mjs → page-QF_Ke10s.mjs} +7 -2
  76. package/dist/{ports-BguS83ex.mjs → ports-R2k4Knz3.mjs} +3 -3
  77. package/dist/prebuild-D2fsca_Z.mjs +213 -0
  78. package/dist/preview-DhVbvPAZ.mjs +318 -0
  79. package/dist/process-identity-BmRm1qV0.mjs +12 -0
  80. package/dist/{project-CWlvEaeN.mjs → project-Du91Ilvc.mjs} +74 -19
  81. package/dist/pull-request-pxnDCQzn.mjs +322 -0
  82. package/dist/pull-requests.d.mts +120 -0
  83. package/dist/pull-requests.mjs +2 -0
  84. package/dist/recordings-BIXOzVnr.mjs +37 -0
  85. package/dist/{reload-BiniwsSZ.mjs → reload-rM9jV1fz.mjs} +109 -24
  86. package/dist/{remote-cache-CcR6o6lI.mjs → remote-cache-C8-V13XN.mjs} +5 -5
  87. package/dist/run-f4vI6EnK.mjs +119 -0
  88. package/dist/{server-bare-DGfgyJ5J.mjs → server-bare-CpPGmnmO.mjs} +33 -15
  89. package/dist/server-expo-CVqO2c35.mjs +2 -0
  90. package/dist/{server-expo-BVuwQ65v.mjs → server-expo-MC0rHlOC.mjs} +8 -12
  91. package/dist/settings-BBpMcDbD.mjs +25 -0
  92. package/dist/{settings-B-fsC-Om.mjs → settings-ZkDzkzvB.mjs} +22 -10
  93. package/dist/settings-oTSkkNrM.mjs +1439 -0
  94. package/dist/settings.schema.json +845 -97
  95. package/dist/{simslim-DrDN4WuV.mjs → simslim-B8-7AoTI.mjs} +8 -132
  96. package/dist/{slot-launch-D5t8EiMf.mjs → slot-launch-B8VrHxn1.mjs} +11 -8
  97. package/dist/{spawn-claims-Drw_o-Fb.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
  98. package/dist/spawn-entry-jw19m8Nl.mjs +17 -0
  99. package/dist/stage-CzaiwFsI.mjs +143 -0
  100. package/dist/start-CX8Ig-U2.mjs +2 -0
  101. package/dist/{start-s4RXp1wy.mjs → start-ClDfwXa4.mjs} +116 -65
  102. package/dist/state-3DwSQIBK.mjs +41 -0
  103. package/dist/state-B4PQFXMW.d.mts +12 -0
  104. package/dist/{state-Dk9RVXI7.mjs → state-C1jB7Q8q.mjs} +70 -8
  105. package/dist/{state-DHqvsbqC.mjs → state-DcW6vOd_.mjs} +7 -4
  106. package/dist/stats-CEZ_i5je.mjs +77 -0
  107. package/dist/{status-BgAuxESg.mjs → status-BuvBFeII.mjs} +118 -20
  108. package/dist/{status-BsPAnfOI.mjs → status-Cs7VLg9D.mjs} +542 -283
  109. package/dist/status-DlKvVJBE.mjs +49 -0
  110. package/dist/stdout-reader-C8yjre1x.mjs +23 -0
  111. package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
  112. package/dist/stim-footprint.swift +32 -0
  113. package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
  114. package/dist/stop-B0Yxtmiy.mjs +48 -0
  115. package/dist/{stop-BzreOWJp.mjs → stop-Bffozsac.mjs} +83 -16
  116. package/dist/{stop-BWIF_6BK.mjs → stop-Dt_dM16A.mjs} +2 -2
  117. package/dist/stop-cause-CidxIqup.mjs +97 -0
  118. package/dist/supervisor-run.d.mts +43 -11
  119. package/dist/supervisor-run.mjs +363 -24
  120. package/dist/support-CAP8qDUF.mjs +316 -0
  121. package/dist/support-D4aYJniO.mjs +201 -0
  122. package/dist/teardown-CL6vDs2Y.mjs +727 -0
  123. package/dist/{xcode-Cp5KvK9x.mjs → toolchain-DkUflduf.mjs} +364 -14
  124. package/dist/trigger-Bemu8ytw.mjs +65 -0
  125. package/dist/trigger-CXts6qt1.mjs +2 -0
  126. package/dist/warm-progress-CpGv3Wb6.mjs +732 -0
  127. package/dist/{web-BsQs1WlO.mjs → web-DWUaMp8P.mjs} +37 -21
  128. package/dist/web-run.mjs +310 -13
  129. package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
  130. package/dist/workspace-state-B8-aJ1_5.mjs +371 -0
  131. package/dist/workspaces-BV4pdHFz.mjs +306 -0
  132. package/dist/{worktree-UrQWXSeb.mjs → worktree-K-xj9Db0.mjs} +625 -256
  133. package/dist/worktree-jnG8Iph5.mjs +2 -0
  134. package/package.json +10 -5
  135. package/shim/bundle-response.cjs +28 -12
  136. package/dist/activity-CYVDcrt3.mjs +0 -356
  137. package/dist/budget-CGDkhvv_.mjs +0 -1745
  138. package/dist/build-progress-DxKpwnaS.mjs +0 -247
  139. package/dist/idle-DXtx3RbX.mjs +0 -191
  140. package/dist/in-use-DlqBDKqY.mjs +0 -249
  141. package/dist/logs-Civ4gbBH.mjs +0 -486
  142. package/dist/merge-state-ytFQCeh4.mjs +0 -262
  143. package/dist/server-expo-DIHDhvGg.mjs +0 -2
  144. package/dist/settings-D61iNOsB.mjs +0 -629
  145. package/dist/start-Cetfvy8l.mjs +0 -2
  146. package/dist/stats-CFpFGlJV.mjs +0 -62
  147. package/dist/stats-CX1Z8Tca.mjs +0 -368
  148. package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
  149. package/dist/stop-cause-hjGBOZTG.mjs +0 -1231
  150. package/dist/worktree-BVrHsYZG.mjs +0 -752
  151. package/dist/worktree-CHWWvm5v.mjs +0 -2
  152. package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
@@ -0,0 +1,606 @@
1
+ import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
+ import { n as stripAnsi } from "./process-output-Fpl8PYi8.mjs";
3
+ import { D as fingerprintProject, M as refingerprintAfterMutation } from "./device-lease-D-hLqx1b.mjs";
4
+ import { T as CCACHE_UNAVAILABLE, d as buildIos, k as resolveCcache, o as workerToolchain, s as manifestDigest } from "./toolchain-DkUflduf.mjs";
5
+ import { t as logLines } from "./run-f4vI6EnK.mjs";
6
+ import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-urbmfXig.mjs";
7
+ import { n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-D2fsca_Z.mjs";
8
+ import { a as gradlewPath, i as buildAndroid, r as assembleTaskFor } from "./gradle-BsO1MdsH.mjs";
9
+ import { n as stageBundle, t as resolveBundleExtras } from "./stage-CzaiwFsI.mjs";
10
+ import { u as podAction } from "./support-D4aYJniO.mjs";
11
+ import { createHash } from "node:crypto";
12
+ import { chmodSync, constants, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
13
+ import { basename, dirname, join } from "node:path";
14
+ //#region src/offload/worker.ts
15
+ function emit(value) {
16
+ process.stdout.write(`${JSON.stringify(value)}\n`);
17
+ }
18
+ function note(phase, msg) {
19
+ emit({
20
+ type: "phase",
21
+ phase,
22
+ msg
23
+ });
24
+ }
25
+ function relayWriter(file) {
26
+ let written = 0;
27
+ return {
28
+ file,
29
+ write(record) {
30
+ written += 1;
31
+ emit({
32
+ type: "log",
33
+ record
34
+ });
35
+ return true;
36
+ },
37
+ close: () => ({
38
+ file,
39
+ written,
40
+ dropped: 0,
41
+ lastError: null
42
+ }),
43
+ get written() {
44
+ return written;
45
+ },
46
+ dropped: 0,
47
+ lastError: null
48
+ };
49
+ }
50
+ function blobPath(blobs, sha256) {
51
+ return join(blobs, sha256.slice(0, 2), sha256);
52
+ }
53
+ /** Whether every directory above `path` inside `root` is a real directory, so removing it cannot leave `root`. */
54
+ function realParents(root, path) {
55
+ let current = root;
56
+ for (const part of path.split("/").slice(0, -1)) {
57
+ current = join(current, part);
58
+ try {
59
+ if (!lstatSync(current).isDirectory()) return false;
60
+ } catch {
61
+ return false;
62
+ }
63
+ }
64
+ return true;
65
+ }
66
+ /** Makes every directory above `path` inside `root` a real directory, replacing a file or symlink in the way. */
67
+ function ensureParents(root, path) {
68
+ let current = root;
69
+ for (const part of path.split("/").slice(0, -1)) {
70
+ current = join(current, part);
71
+ let stat;
72
+ try {
73
+ stat = lstatSync(current);
74
+ } catch {
75
+ mkdirSync(current);
76
+ continue;
77
+ }
78
+ if (stat.isDirectory()) continue;
79
+ rmSync(current, { force: true });
80
+ mkdirSync(current);
81
+ }
82
+ }
83
+ /**
84
+ * Makes `src` hold exactly the manifest's files: a file the manifest names is rewritten unless this process
85
+ * wrote that same content there and nothing touched it since; a file that git would list as untracked and not
86
+ * ignored, and that the manifest does not name, is deleted, as is one the previous manifest named. Ignored
87
+ * files (dependencies, generated native projects) stay, and the fingerprint check covers them.
88
+ */
89
+ function materialize(job, src) {
90
+ const recordFile = join(job.area, "mirror.json");
91
+ let previous = {};
92
+ try {
93
+ previous = JSON.parse(readFileSync(recordFile, "utf8"));
94
+ } catch {}
95
+ mkdirSync(src, { recursive: true });
96
+ if (!existsSync(join(src, ".git"))) {
97
+ getExecutor().runFile("git", [
98
+ "init",
99
+ "--quiet",
100
+ src
101
+ ], { timeoutMs: 3e4 });
102
+ getExecutor().runFile("git", [
103
+ "-C",
104
+ src,
105
+ "config",
106
+ "core.excludesFile",
107
+ "/dev/null"
108
+ ], { timeoutMs: 3e4 });
109
+ }
110
+ const next = {};
111
+ const wanted = /* @__PURE__ */ new Set();
112
+ let written = 0;
113
+ for (const entry of job.manifest) {
114
+ wanted.add(entry.path);
115
+ const target = join(src, entry.path);
116
+ const known = previous[entry.path];
117
+ let stat = null;
118
+ try {
119
+ stat = lstatSync(target);
120
+ } catch {}
121
+ if (known && stat && known.sha256 === entry.sha256 && known.kind === entry.kind && stat.mtimeMs === known.mtimeMs && stat.size === known.size) {
122
+ next[entry.path] = known;
123
+ continue;
124
+ }
125
+ ensureParents(src, entry.path);
126
+ if (stat) rmSync(target, {
127
+ recursive: true,
128
+ force: true
129
+ });
130
+ const blob = blobPath(job.blobs, entry.sha256);
131
+ if (entry.kind === "link") symlinkSync(readFileSync(blob, "utf8"), target);
132
+ else {
133
+ copyFileSync(blob, target, constants.COPYFILE_FICLONE);
134
+ chmodSync(target, entry.kind === "exec" ? 493 : 420);
135
+ }
136
+ const after = lstatSync(target);
137
+ next[entry.path] = {
138
+ sha256: entry.sha256,
139
+ kind: entry.kind,
140
+ mtimeMs: after.mtimeMs,
141
+ size: after.size
142
+ };
143
+ written += 1;
144
+ }
145
+ const untracked = getExecutor().runFile("git", [
146
+ "-C",
147
+ src,
148
+ "ls-files",
149
+ "-z",
150
+ "-o",
151
+ "--exclude-standard"
152
+ ], {
153
+ untrimmed: true,
154
+ timeoutMs: 12e4
155
+ }).split("\0").filter(Boolean);
156
+ let removed = 0;
157
+ for (const path of /* @__PURE__ */ new Set([...untracked, ...Object.keys(previous)])) {
158
+ if (wanted.has(path) || !realParents(src, path)) continue;
159
+ try {
160
+ rmSync(join(src, path), { force: true });
161
+ removed += 1;
162
+ } catch {}
163
+ }
164
+ const tmp = `${recordFile}.${process.pid}.tmp`;
165
+ writeFileSync(tmp, JSON.stringify(next));
166
+ renameSync(tmp, recordFile);
167
+ return {
168
+ written,
169
+ removed
170
+ };
171
+ }
172
+ function lockfileOf(src) {
173
+ if (existsSync(join(src, "pnpm-lock.yaml"))) return {
174
+ file: "pnpm-lock.yaml",
175
+ command: "pnpm",
176
+ args: (pkg) => [
177
+ "install",
178
+ "--frozen-lockfile",
179
+ ...pkg ? ["--filter", `${pkg}...`] : []
180
+ ]
181
+ };
182
+ if (existsSync(join(src, "yarn.lock"))) return {
183
+ file: "yarn.lock",
184
+ command: "yarn",
185
+ args: () => ["install", "--frozen-lockfile"]
186
+ };
187
+ if (existsSync(join(src, "package-lock.json"))) return {
188
+ file: "package-lock.json",
189
+ command: "npm",
190
+ args: () => ["ci"]
191
+ };
192
+ return null;
193
+ }
194
+ /** Installs JavaScript dependencies when the lockfile, or the install command, changed since the last install. */
195
+ async function ensureDependencies(job, src) {
196
+ const lock = lockfileOf(src);
197
+ if (!lock) return;
198
+ const args = lock.args(job.packageName);
199
+ const lockfile = readFileSync(join(src, lock.file));
200
+ const digest = createHash("sha256").update(lockfile).update(JSON.stringify(args)).digest("hex");
201
+ const marker = join(job.area, "dependencies");
202
+ const installed = () => writeFileSync(join(job.area, "lockfile"), createHash("sha256").update(lockfile).digest("hex"));
203
+ if (existsSync(join(src, job.project, "node_modules")) && existsSync(marker)) {
204
+ if (readFileSync(marker, "utf8") === digest) return installed();
205
+ }
206
+ note("deps", `${lock.command} ${args.join(" ")}`);
207
+ const child = getExecutor().spawn(lock.command, args, {
208
+ cwd: src,
209
+ env: {
210
+ ...process.env,
211
+ CI: "1"
212
+ },
213
+ stdio: [
214
+ "ignore",
215
+ "pipe",
216
+ "pipe"
217
+ ]
218
+ });
219
+ const tail = [];
220
+ const keep = (chunk) => {
221
+ tail.push(...String(chunk).split("\n").filter(Boolean));
222
+ tail.splice(0, Math.max(0, tail.length - 5));
223
+ };
224
+ child.stdout?.on("data", keep);
225
+ child.stderr?.on("data", keep);
226
+ const code = await new Promise((resolve, reject) => {
227
+ child.on("error", reject);
228
+ child.on("exit", resolve);
229
+ });
230
+ if (code !== 0) throw new Error(`${lock.command} ${args.join(" ")} exited with ${code}: ${tail.join(" | ")}`);
231
+ writeFileSync(marker, digest);
232
+ installed();
233
+ }
234
+ /**
235
+ * The generic simulator destination compiles arm64 and x86_64, so the worker names one of its own iPhone
236
+ * simulators on the client's runtime. It is a build destination only: nothing boots or installs on it.
237
+ */
238
+ function destination(runtime) {
239
+ try {
240
+ const device = (JSON.parse(getExecutor().runFileQuiet("xcrun", [
241
+ "simctl",
242
+ "list",
243
+ "devices",
244
+ "available",
245
+ "-j"
246
+ ], { timeoutMs: 2e4 }) ?? "{}").devices?.[runtime] ?? []).find((each) => each.name.startsWith("iPhone"));
247
+ return device ? `id=${device.udid}` : null;
248
+ } catch {
249
+ return null;
250
+ }
251
+ }
252
+ async function sha256Of(path) {
253
+ const hash = createHash("sha256");
254
+ for await (const chunk of createReadStream(path)) hash.update(chunk);
255
+ return hash.digest("hex");
256
+ }
257
+ async function build(job) {
258
+ const timings = {
259
+ syncMs: 0,
260
+ depsMs: 0,
261
+ prebuildMs: 0,
262
+ podsMs: 0,
263
+ fingerprintMs: 0,
264
+ buildMs: 0,
265
+ packageMs: 0
266
+ };
267
+ const time = async (key, run) => {
268
+ const started = Date.now();
269
+ try {
270
+ return await run();
271
+ } finally {
272
+ timings[key] += Date.now() - started;
273
+ }
274
+ };
275
+ const failed = (code, message) => ({
276
+ ok: false,
277
+ code,
278
+ message,
279
+ timings
280
+ });
281
+ const src = join(job.area, "src");
282
+ const root = join(src, job.project);
283
+ const log = relayWriter(join(job.area, "build.ndjson"));
284
+ const mirrored = await time("syncMs", () => materialize(job, src));
285
+ const realSrc = realpathSync(src);
286
+ const realRoot = realpathSync(root);
287
+ if (realRoot !== realSrc && !realRoot.startsWith(`${realSrc}/`)) return failed("bad-project", `${job.project} leaves the checkout.`);
288
+ note("sync", `${job.manifest.length} files, ${mirrored.written} written, ${mirrored.removed} removed`);
289
+ let fingerprint;
290
+ let compiled;
291
+ if (job.platform === "macos") {
292
+ fingerprint = await time("fingerprintMs", () => manifestDigest(job.manifest));
293
+ if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the manifest there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint.slice(0, 12)}`);
294
+ compiled = await compileMacos(job, root, log, time);
295
+ if (!compiled.ok) return failed(compiled.code, compiled.message);
296
+ } else {
297
+ try {
298
+ await time("depsMs", () => ensureDependencies(job, src));
299
+ } catch (error) {
300
+ return failed("deps-failed", error.message);
301
+ }
302
+ const platform = job.platform;
303
+ const initial = await time("fingerprintMs", () => fingerprintProject(root, { platform }));
304
+ if (!initial) return failed("no-fingerprint", "The build machine could not fingerprint the project.");
305
+ const plan = planPrebuild(root, platform, {
306
+ isExpo: job.isExpo,
307
+ fingerprint: initial.hash,
308
+ sources: initial.sources
309
+ });
310
+ if (plan === "refuse") return failed("prebuild-refused", `${platform}/ is not generated by prebuild and does not match.`);
311
+ const mutations = [];
312
+ if (plan === "generate" || plan === "regenerate") {
313
+ note("prebuild", plan === "generate" ? `generating ${platform}/` : `regenerating ${platform}/ with --clean`);
314
+ recordPrebuild(root, platform, null);
315
+ const result = await time("prebuildMs", () => runPrebuild(root, platform, log, { clean: plan === "regenerate" }));
316
+ if (result?.failed) return failed("prebuild-failed", result.reason ?? "expo prebuild failed.");
317
+ mutations.push("prebuild");
318
+ }
319
+ if (platform === "ios") {
320
+ const podState = readPodState(root);
321
+ const pods = podAction(podState, podsAreStale(podState.lockText, podState.manifestText));
322
+ if (pods.install) {
323
+ note("pods", `${pods.reason ?? "Pods are stale"} -> pod install`);
324
+ const result = await time("podsMs", () => runPodInstall(root, log, { onHeartbeat: (line) => note("pods", line) }));
325
+ if (result?.failed) return failed("pods-failed", result.reason ?? "pod install failed.");
326
+ mutations.push("pods");
327
+ }
328
+ }
329
+ fingerprint = initial.hash;
330
+ if (mutations.length) {
331
+ const after = await time("fingerprintMs", () => refingerprintAfterMutation({
332
+ projectRoot: root,
333
+ platform,
334
+ previousHash: initial.hash
335
+ }));
336
+ if (!after) return failed("no-fingerprint", `No fingerprint after ${mutations.join(", ")}.`);
337
+ fingerprint = after.hash;
338
+ if (mutations.includes("prebuild")) recordPrebuild(root, platform, after.hash);
339
+ }
340
+ if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the checkout there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint.slice(0, 12)}`);
341
+ compiled = platform === "android" ? await compileAndroid(job, root, log, time) : await compileIos(job, root, log, time);
342
+ if (!compiled.ok) return failed(compiled.code, compiled.message);
343
+ const settled = await time("fingerprintMs", () => refingerprintAfterMutation({
344
+ projectRoot: root,
345
+ platform,
346
+ previousHash: fingerprint
347
+ }));
348
+ if (!settled || settled.moved) return failed("fingerprint-moved", "The inputs changed during the build there.");
349
+ }
350
+ const out = join(job.area, "out", job.job);
351
+ if (job.platform !== "macos") rmSync(out, {
352
+ recursive: true,
353
+ force: true
354
+ });
355
+ mkdirSync(out, { recursive: true });
356
+ const archive = join(out, "app.tgz");
357
+ const name = basename(compiled.path);
358
+ if (job.platform === "ios") cpSync(compiled.path, join(out, name), {
359
+ recursive: true,
360
+ verbatimSymlinks: true,
361
+ mode: constants.COPYFILE_FICLONE
362
+ });
363
+ await time("packageMs", () => getExecutor().runFileAsync("tar", [
364
+ "-czf",
365
+ archive,
366
+ "--options",
367
+ "gzip:compression-level=1",
368
+ "-C",
369
+ dirname(compiled.path),
370
+ name
371
+ ], { timeoutMs: 6e5 }));
372
+ const sha256 = await time("packageMs", () => sha256Of(archive));
373
+ return {
374
+ ok: true,
375
+ artifact: {
376
+ path: archive,
377
+ name,
378
+ size: statSync(archive).size,
379
+ sha256
380
+ },
381
+ fingerprint,
382
+ compilationCache: compiled.cache,
383
+ timings
384
+ };
385
+ }
386
+ async function compileMacos(job, root, log, time) {
387
+ const options = job.macos;
388
+ if (!options) return {
389
+ ok: false,
390
+ code: "bad-request",
391
+ message: "The job has no SwiftPM options."
392
+ };
393
+ const src = join(job.area, "src");
394
+ const scratch = join(job.area, "macos", job.project.replaceAll("/", "_") || "root");
395
+ const run = async (args, capture = false) => {
396
+ const child = getExecutor().spawn("swift", args, {
397
+ cwd: root,
398
+ stdio: [
399
+ "ignore",
400
+ "pipe",
401
+ "pipe"
402
+ ]
403
+ });
404
+ let stdout = "";
405
+ let firstError = null;
406
+ const tail = [];
407
+ const write = (msg) => {
408
+ const plain = stripAnsi(msg);
409
+ if (firstError === null && /\.swift:\d+:\d+: error:/.test(plain)) firstError = plain;
410
+ tail.push(plain);
411
+ if (tail.length > 3) tail.shift();
412
+ note("build", msg);
413
+ log.write({
414
+ src: "build",
415
+ platform: "macos",
416
+ level: "debug",
417
+ msg
418
+ });
419
+ };
420
+ child.stdout?.on("data", (chunk) => {
421
+ if (capture) stdout += chunk.toString("utf8");
422
+ });
423
+ if (child.stdout) logLines(child.stdout, write);
424
+ if (child.stderr) logLines(child.stderr, write);
425
+ await new Promise((done, reject) => {
426
+ child.once("error", reject);
427
+ child.once("close", (code) => code === 0 ? done() : reject(new Error(firstError ?? (tail.join(" | ") || `swift build failed (${code})`))));
428
+ });
429
+ return stdout.trim();
430
+ };
431
+ try {
432
+ const extras = resolveBundleExtras(src, src, options.resources, options.assetCatalog);
433
+ return await time("buildMs", async () => {
434
+ await run([
435
+ "build",
436
+ "-c",
437
+ "debug",
438
+ "--product",
439
+ options.product,
440
+ "--scratch-path",
441
+ scratch,
442
+ "--cache-path",
443
+ job.swiftpmCache
444
+ ]);
445
+ const bin = await run([
446
+ "build",
447
+ "-c",
448
+ "debug",
449
+ "--scratch-path",
450
+ scratch,
451
+ "--cache-path",
452
+ job.swiftpmCache,
453
+ "--show-bin-path"
454
+ ], true);
455
+ const bundle = join(job.area, "out", job.job, `${options.product}.app`);
456
+ stageBundle(root, options.product, options.infoPlist, bin, bundle, options.bundleId, extras);
457
+ return {
458
+ ok: true,
459
+ path: bundle,
460
+ cache: {}
461
+ };
462
+ });
463
+ } catch (error) {
464
+ return {
465
+ ok: false,
466
+ code: "swift-failed",
467
+ message: error.message
468
+ };
469
+ }
470
+ }
471
+ async function compileIos(job, root, log, time) {
472
+ const runtime = job.runtime ?? "";
473
+ const target = destination(runtime);
474
+ if (!target) return {
475
+ ok: false,
476
+ code: "no-runtime",
477
+ message: `There is no iPhone simulator on ${runtime} to build for.`
478
+ };
479
+ note("build", `xcodebuild for ${runtime}`);
480
+ const built = await time("buildMs", () => buildIos({
481
+ root,
482
+ destination: target,
483
+ logWriter: log,
484
+ ...job.scheme ? { scheme: job.scheme } : {},
485
+ ...job.configuration ? { configuration: job.configuration } : {},
486
+ ...job.optimizations ? { optimizations: job.optimizations } : {},
487
+ onHeartbeat: (line) => note("build", line),
488
+ onNote: (line) => note("build", line)
489
+ }));
490
+ if (!built.ok) {
491
+ const first = built.diagnostics[0]?.message;
492
+ return {
493
+ ok: false,
494
+ code: built.code,
495
+ message: first ?? (built.tail.slice(-3).join(" | ") || "xcodebuild failed.")
496
+ };
497
+ }
498
+ return {
499
+ ok: true,
500
+ path: built.appPath,
501
+ cache: built.compilationCache
502
+ };
503
+ }
504
+ /**
505
+ * Stops the Gradle daemons of this client's Gradle home. A daemon calls setsid, so it leaves the build's
506
+ * process group and would outlive the job and its claim.
507
+ */
508
+ function stopGradleDaemons(root, timeoutMs) {
509
+ const gradlew = gradlewPath(root);
510
+ if (!existsSync(gradlew)) return;
511
+ getExecutor().runFileQuiet(gradlew, ["--stop"], {
512
+ cwd: dirname(gradlew),
513
+ timeoutMs
514
+ });
515
+ }
516
+ /**
517
+ * Gradle reads `org.gradle.daemon.idletimeout` from the user home's gradle.properties, which overrides the
518
+ * project's, so the daemon exits after that idle time instead of Gradle's three hours.
519
+ */
520
+ function limitDaemonIdle(idleMs) {
521
+ const home = process.env.GRADLE_USER_HOME;
522
+ if (!home) return;
523
+ const file = join(home, "gradle.properties");
524
+ const wanted = `org.gradle.daemon.idletimeout=${idleMs}\n`;
525
+ try {
526
+ if (readFileSync(file, "utf8") === wanted) return;
527
+ } catch {}
528
+ mkdirSync(home, { recursive: true });
529
+ writeFileSync(file, wanted);
530
+ }
531
+ async function compileAndroid(job, root, log, time) {
532
+ const options = job.android;
533
+ if (!options) return {
534
+ ok: false,
535
+ code: "bad-request",
536
+ message: "The job has no Gradle options."
537
+ };
538
+ const idleMs = job.gradleDaemonIdleMs ?? 0;
539
+ const keepDaemon = idleMs > 0;
540
+ limitDaemonIdle(keepDaemon ? idleMs : 6e4);
541
+ const onNote = (line) => note("build", line);
542
+ const stop = () => {
543
+ stopGradleDaemons(root, 4e3);
544
+ process.exit(143);
545
+ };
546
+ process.once("SIGTERM", stop);
547
+ note("build", `gradle ${assembleTaskFor(options.variant)} for ${options.abi ?? "every ABI"}`);
548
+ try {
549
+ const built = await time("buildMs", () => buildAndroid({
550
+ root,
551
+ logWriter: log,
552
+ variant: options.variant,
553
+ abi: options.abi
554
+ }, {
555
+ buildCache: options.gradleBuildCache,
556
+ pch: options.pch,
557
+ compilerCacheDisabled: options.compilerCache === "none",
558
+ ccache: options.compilerCache === "ccache" ? resolveCcache({
559
+ root,
560
+ onNote
561
+ }) : null,
562
+ onHeartbeat: onNote,
563
+ onNote
564
+ }));
565
+ if (!built.ok) {
566
+ const first = built.diagnostics[0]?.message;
567
+ return {
568
+ ok: false,
569
+ code: built.code,
570
+ message: first ?? (built.lastLines.slice(-3).join(" | ") || built.reason)
571
+ };
572
+ }
573
+ return {
574
+ ok: true,
575
+ path: built.apkPath,
576
+ cache: built.ccache ?? CCACHE_UNAVAILABLE
577
+ };
578
+ } finally {
579
+ process.off("SIGTERM", stop);
580
+ if (!keepDaemon) stopGradleDaemons(root, 6e4);
581
+ }
582
+ }
583
+ async function main() {
584
+ const mode = process.argv[2];
585
+ if (mode === "offer") return emit(workerToolchain());
586
+ if (mode === "build") {
587
+ const chunks = [];
588
+ for await (const chunk of process.stdin) chunks.push(chunk);
589
+ return emit({
590
+ type: "result",
591
+ ...await build(JSON.parse(Buffer.concat(chunks).toString("utf8")))
592
+ });
593
+ }
594
+ process.stderr.write("usage: offload-worker offer | build < job.json\n");
595
+ process.exitCode = 2;
596
+ }
597
+ main().catch((error) => {
598
+ emit({
599
+ type: "result",
600
+ ok: false,
601
+ code: "worker-crashed",
602
+ message: String(error?.message ?? error)
603
+ });
604
+ });
605
+ //#endregion
606
+ export {};
@@ -1,5 +1,6 @@
1
- import { O as process_identity_exports } from "./config-lvc7d3C2.mjs";
2
- import { a as pidExists, b as writeWorkspaceState, h as readWorkspaceState, v as withWorkspaceStateLock } from "./metro-CcEo8Fl8.mjs";
1
+ import { t as process_identity_exports } from "./process-identity-BmRm1qV0.mjs";
2
+ import { o as pidExists } from "./metro-BeK1ZPz1.mjs";
3
+ import { c as writeWorkspaceState, o as withWorkspaceStateLock, r as readWorkspaceState } from "./workspace-state-B8-aJ1_5.mjs";
3
4
  import { realpathSync } from "node:fs";
4
5
  //#region src/collector/state.ts
5
6
  function collectorRoot(root) {