stim 1.2.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 +30 -0
- package/dist/android-BqVIJoG7.mjs +1368 -0
- package/dist/{android-Bcmev2s2.mjs → android-CqcW1hrP.mjs} +148 -56
- package/dist/{android-cas-D6HPZ6UQ.mjs → android-cas-BR5YJBYv.mjs} +5 -5
- package/dist/{app-install-NFxUahnH.mjs → app-install-DIp9riNx.mjs} +6 -6
- package/dist/{build-slots-D0b6sJyo.mjs → build-slots-C3-R4XQr.mjs} +2 -2
- package/dist/{cache-manifest-Cu4_Znw9.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 +3 -1
- package/dist/collector-run.mjs +33 -8
- package/dist/{config-CMtIaTk9.mjs → config-CcefMY2Q.mjs} +93 -12
- package/dist/{deps-BLBsTNDS.mjs → deps-Spz8ozgo.mjs} +1 -1
- package/dist/{dev-client-RpvXxCXV.mjs → dev-client-BjisHDB5.mjs} +186 -9
- package/dist/{device-CoCPmazS.mjs → device-BkiW-gkk.mjs} +19 -11
- package/dist/{device-lease-Dpik41RY.mjs → device-lease-BJYybF-2.mjs} +107 -83
- package/dist/{device-pool-B5pEVa3t.mjs → device-pool-CPbLGfrB.mjs} +18 -12
- package/dist/{device-remote-E81KAdXf.mjs → device-remote-AkYCKS8U.mjs} +7 -7
- package/dist/{doctor-CqPeMsSm.mjs → doctor-Bmv86UUW.mjs} +11 -12
- package/dist/{doctor-D_CX7ib5.mjs → doctor-fAMXC4vl.mjs} +4 -4
- package/dist/{error-diagnostics-Dw8Gn3yw.mjs → error-diagnostics-DHC31rXA.mjs} +62 -52
- package/dist/{gc-B7KkDinF.mjs → gc-GGu-8ULN.mjs} +66 -57
- package/dist/{guide-BS2Xc24o.mjs → guide-92CPA21s.mjs} +196 -13
- package/dist/{ios-B7KLgIp5.mjs → ios-BSXFeO5H.mjs} +183 -54
- package/dist/{ios-D1h1Di39.mjs → ios-Deh5js5V.mjs} +78 -40
- package/dist/{ios-device-xNt0Lg6v.mjs → ios-device-CWOM_S44.mjs} +1 -1
- package/dist/{logs-DcX9AvRF.mjs → logs-DPNF4C9s.mjs} +9 -6
- package/dist/{logs-query-oqn47Ffx.mjs → logs-query-R-Cqc6Qv.mjs} +22 -5
- package/dist/{metro-COslRK_F.mjs → metro-CORqXyTL.mjs} +2 -2
- package/dist/{ndjson-DcAtEx_K.mjs → ndjson-BZwI1NBv.mjs} +5 -2
- package/dist/{ownership-CGPart6T.mjs → ownership-8O073GIC.mjs} +3 -3
- package/dist/{ownership-CYOyqxUo.mjs → ownership-BpCKiRlQ.mjs} +3 -3
- package/dist/{ownership-claim-7zRxxTfZ.mjs → ownership-claim-Bf2CAfw3.mjs} +4 -3
- package/dist/{project-BBTVABUz.mjs → project-fKmuIaMI.mjs} +2 -2
- package/dist/{reclaim-C5Jmuahx.mjs → reclaim-iW9Cad7k.mjs} +80 -74
- package/dist/{reload-Z8nKifAk.mjs → reload-DazHDSFA.mjs} +32 -24
- package/dist/{server-bare-DEk37Mz2.mjs → server-bare-DEzPZLvf.mjs} +2 -2
- package/dist/server-expo-44em5Pmg.mjs +2 -0
- package/dist/{server-expo-C3ktAwUG.mjs → server-expo-DizT4OMk.mjs} +4 -4
- package/dist/{settings-DwU1_U_q.mjs → settings-DEJf6_kJ.mjs} +2 -2
- package/dist/slot-launch-cci0xvmC.mjs +19 -0
- package/dist/{start-BrY4EuIg.mjs → start-mObjQH2W.mjs} +11 -11
- package/dist/{state-CZ-ER-8d.mjs → state-B3XA2wp2.mjs} +9 -9
- package/dist/{stats-BCWEVLrM.mjs → stats-BR-kwj0B.mjs} +1 -1
- package/dist/{stats-BsF15Bti.mjs → stats-CaaQr4yN.mjs} +3 -3
- package/dist/{status-DFI1Hfpg.mjs → status-BxQNqu9t.mjs} +55 -24
- package/dist/{stop-B7DR4awK.mjs → stop-CrHGcjrV.mjs} +2 -2
- package/dist/{stop-Btg770vV.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-DDmJ1Roq.mjs → teardown-ClFp1Aax.mjs} +887 -888
- package/dist/{workspace-process-lock-BKfdys1q.mjs → workspace-process-lock-3NcQnZ0X.mjs} +1 -1
- package/dist/{worktree-BPTbI-LN.mjs → worktree-DxTgN1CJ.mjs} +12 -12
- package/dist/{worktree-C79xx_kM.mjs → worktree-Eq6TLH8N.mjs} +1 -1
- package/dist/{xcode-DeKCribl.mjs → xcode-D7sAp-Zy.mjs} +82 -56
- package/package.json +5 -5
- package/dist/android-K63_0UfF.mjs +0 -727
- package/dist/build-lock-BsVoLDaq.mjs +0 -645
- package/dist/server-expo-Drd7ksHu.mjs +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { k as withDirLock, u as getConfigDir } from "./config-
|
|
2
|
-
import { _ as writeWorkspaceState, o as clearWorkspaceStateKeys, p as readWorkspaceState } from "./state-
|
|
3
|
-
import {
|
|
1
|
+
import { I as deviceSlotKey, R as parseDeviceSlotKey, V as validateDeviceSlot, k as withDirLock, u as getConfigDir } from "./config-CcefMY2Q.mjs";
|
|
2
|
+
import { _ as writeWorkspaceState, m as withWorkspaceStateLock, o as clearWorkspaceStateKeys, p as readWorkspaceState } from "./state-B3XA2wp2.mjs";
|
|
3
|
+
import { H as segment } from "./android-BqVIJoG7.mjs";
|
|
4
4
|
import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { randomBytes } from "node:crypto";
|
|
6
6
|
import { join } from "node:path";
|
|
@@ -21,6 +21,7 @@ function deviceLeaseLockPath(platform, id) {
|
|
|
21
21
|
return join(deviceLocksDir(), `${leaseStem(platform, id)}${LOCK_SUFFIX}`);
|
|
22
22
|
}
|
|
23
23
|
const fileLeaseIo = {
|
|
24
|
+
withHolderLock: withWorkspaceStateLock,
|
|
24
25
|
now: () => Date.now(),
|
|
25
26
|
readLease(path) {
|
|
26
27
|
try {
|
|
@@ -83,8 +84,17 @@ function parseLease(raw) {
|
|
|
83
84
|
const token = text(entry.token);
|
|
84
85
|
const expiresAt = text(entry.expiresAt);
|
|
85
86
|
if (!id || !holder || !token || !expiresAt || !Number.isFinite(Date.parse(expiresAt))) return null;
|
|
87
|
+
if (entry.slot !== void 0) {
|
|
88
|
+
if (typeof entry.slot !== "string") return null;
|
|
89
|
+
try {
|
|
90
|
+
validateDeviceSlot(entry.slot);
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
86
95
|
return {
|
|
87
96
|
version: 1,
|
|
97
|
+
...typeof entry.slot === "string" ? { slot: entry.slot } : {},
|
|
88
98
|
platform: entry.platform,
|
|
89
99
|
id,
|
|
90
100
|
deviceName: text(entry.deviceName),
|
|
@@ -98,7 +108,7 @@ function parseWorkspaceLeases(value) {
|
|
|
98
108
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
99
109
|
const leases = {};
|
|
100
110
|
for (const [platform, entry] of Object.entries(value)) {
|
|
101
|
-
if (!
|
|
111
|
+
if (!parseDeviceSlotKey(platform) || !entry || typeof entry !== "object") continue;
|
|
102
112
|
const record = entry;
|
|
103
113
|
const id = text(record.id);
|
|
104
114
|
const token = text(record.token);
|
|
@@ -145,70 +155,74 @@ function writeLease(lease, io) {
|
|
|
145
155
|
io.writeLease(deviceLeasePath(lease.platform, lease.id), `${JSON.stringify(lease, null, 2)}\n`);
|
|
146
156
|
return lease;
|
|
147
157
|
}
|
|
148
|
-
function takeLease({ root, platform, id, deviceName = null, kind, durationMs = DEFAULT_LEASE_MS }, io = fileLeaseIo) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (current && !leaseIsExpired(current, now)) {
|
|
168
|
-
if (current.holder !== root) return {
|
|
169
|
-
status: "held",
|
|
170
|
-
lease: current
|
|
158
|
+
function takeLease({ root, platform, slot = "default", id, deviceName = null, kind, durationMs = DEFAULT_LEASE_MS }, io = fileLeaseIo) {
|
|
159
|
+
return withHolderLock(io, root, () => {
|
|
160
|
+
const key = deviceSlotKey(platform, slot);
|
|
161
|
+
const previous = io.readHolder(root)[key];
|
|
162
|
+
if (previous && previous.id !== id) releaseHeld(root, platform, previous, io, slot);
|
|
163
|
+
for (const entry of listLeaseFiles(io)) {
|
|
164
|
+
const other = entry.lease;
|
|
165
|
+
if (!other || other.platform !== platform || other.holder !== root || (other.slot ?? "default") !== slot || other.id === id) continue;
|
|
166
|
+
releaseByRoot(root, platform, other.id, io);
|
|
167
|
+
}
|
|
168
|
+
const declared = previous?.kind === "declared" && previous.id === id;
|
|
169
|
+
const path = deviceLeasePath(platform, id);
|
|
170
|
+
const result = io.withLeaseLock(deviceLeaseLockPath(platform, id), () => {
|
|
171
|
+
const now = io.now();
|
|
172
|
+
const raw = io.readLease(path);
|
|
173
|
+
const current = parseLease(raw);
|
|
174
|
+
if (raw !== null && !current) return {
|
|
175
|
+
status: "unreadable",
|
|
176
|
+
path
|
|
171
177
|
};
|
|
172
|
-
const
|
|
178
|
+
const asked = now + durationMs;
|
|
179
|
+
if (current && !leaseIsExpired(current, now)) {
|
|
180
|
+
if (current.holder !== root || (current.slot ?? "default") !== slot) return {
|
|
181
|
+
status: "held",
|
|
182
|
+
lease: current
|
|
183
|
+
};
|
|
184
|
+
const floor = declared && kind === "run" ? Math.max(asked, Date.parse(current.expiresAt)) : asked;
|
|
185
|
+
return {
|
|
186
|
+
status: "set",
|
|
187
|
+
lease: writeLease({
|
|
188
|
+
...current,
|
|
189
|
+
deviceName: deviceName ?? current.deviceName,
|
|
190
|
+
expiresAt: new Date(floor).toISOString()
|
|
191
|
+
}, io)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const expiresAt = new Date(asked).toISOString();
|
|
173
195
|
return {
|
|
174
|
-
status: "
|
|
196
|
+
status: "taken",
|
|
175
197
|
lease: writeLease({
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
198
|
+
version: 1,
|
|
199
|
+
...slot === "default" ? {} : { slot },
|
|
200
|
+
platform,
|
|
201
|
+
id,
|
|
202
|
+
deviceName,
|
|
203
|
+
holder: root,
|
|
204
|
+
token: randomBytes(12).toString("hex"),
|
|
205
|
+
grantedAt: new Date(now).toISOString(),
|
|
206
|
+
expiresAt
|
|
179
207
|
}, io)
|
|
180
208
|
};
|
|
209
|
+
});
|
|
210
|
+
if (result.status === "taken" || result.status === "set") {
|
|
211
|
+
const recorded = result.status === "set" && declared ? "declared" : kind;
|
|
212
|
+
io.writeHolder(root, {
|
|
213
|
+
...io.readHolder(root),
|
|
214
|
+
[key]: {
|
|
215
|
+
id,
|
|
216
|
+
token: result.lease.token,
|
|
217
|
+
kind: recorded
|
|
218
|
+
}
|
|
219
|
+
});
|
|
181
220
|
}
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
status: "taken",
|
|
185
|
-
lease: writeLease({
|
|
186
|
-
version: 1,
|
|
187
|
-
platform,
|
|
188
|
-
id,
|
|
189
|
-
deviceName,
|
|
190
|
-
holder: root,
|
|
191
|
-
token: randomBytes(12).toString("hex"),
|
|
192
|
-
grantedAt: new Date(now).toISOString(),
|
|
193
|
-
expiresAt
|
|
194
|
-
}, io)
|
|
195
|
-
};
|
|
221
|
+
return result;
|
|
196
222
|
});
|
|
197
|
-
if (result.status === "taken" || result.status === "set") {
|
|
198
|
-
const recorded = result.status === "set" && declared ? "declared" : kind;
|
|
199
|
-
io.writeHolder(root, {
|
|
200
|
-
...io.readHolder(root),
|
|
201
|
-
[platform]: {
|
|
202
|
-
id,
|
|
203
|
-
token: result.lease.token,
|
|
204
|
-
kind: recorded
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
return result;
|
|
209
223
|
}
|
|
210
|
-
function raiseLease({ root, platform, minMs }, io = fileLeaseIo) {
|
|
211
|
-
const record = io.readHolder(root)[platform];
|
|
224
|
+
function raiseLease({ root, platform, slot = "default", minMs }, io = fileLeaseIo) {
|
|
225
|
+
const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
212
226
|
if (!record) return { status: "none" };
|
|
213
227
|
const path = deviceLeasePath(platform, record.id);
|
|
214
228
|
return io.withLeaseLock(deviceLeaseLockPath(platform, record.id), () => {
|
|
@@ -239,7 +253,8 @@ function summarize(lease) {
|
|
|
239
253
|
expiresAt: lease.expiresAt
|
|
240
254
|
};
|
|
241
255
|
}
|
|
242
|
-
function releaseHeld(root, platform, record, io) {
|
|
256
|
+
function releaseHeld(root, platform, record, io, slot = "default") {
|
|
257
|
+
const key = deviceSlotKey(platform, slot);
|
|
243
258
|
const path = deviceLeasePath(platform, record.id);
|
|
244
259
|
const released = io.withLeaseLock(deviceLeaseLockPath(platform, record.id), () => {
|
|
245
260
|
const current = parseLease(io.readLease(path));
|
|
@@ -248,8 +263,8 @@ function releaseHeld(root, platform, record, io) {
|
|
|
248
263
|
return current;
|
|
249
264
|
});
|
|
250
265
|
const held = io.readHolder(root);
|
|
251
|
-
if (held[
|
|
252
|
-
delete held[
|
|
266
|
+
if (held[key]?.token === record.token) {
|
|
267
|
+
delete held[key];
|
|
253
268
|
io.writeHolder(root, held);
|
|
254
269
|
}
|
|
255
270
|
return released;
|
|
@@ -263,27 +278,33 @@ function releaseByRoot(root, platform, id, io) {
|
|
|
263
278
|
return current;
|
|
264
279
|
});
|
|
265
280
|
}
|
|
266
|
-
function releaseRunLease({ root, platform }, io = fileLeaseIo) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
281
|
+
function releaseRunLease({ root, platform, slot = "default" }, io = fileLeaseIo) {
|
|
282
|
+
return withHolderLock(io, root, () => {
|
|
283
|
+
const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
284
|
+
if (!record || record.kind !== "run") return null;
|
|
285
|
+
const released = releaseHeld(root, platform, record, io, slot);
|
|
286
|
+
return released ? summarize(released) : null;
|
|
287
|
+
});
|
|
271
288
|
}
|
|
272
|
-
function releaseWorkspaceLeases(root, { platform = null } = {}, io = fileLeaseIo) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
289
|
+
function releaseWorkspaceLeases(root, { platform = null, slot = null } = {}, io = fileLeaseIo) {
|
|
290
|
+
return withHolderLock(io, root, () => {
|
|
291
|
+
const released = [];
|
|
292
|
+
for (const [name, record] of Object.entries(io.readHolder(root))) {
|
|
293
|
+
const parsed = parseDeviceSlotKey(name);
|
|
294
|
+
if (!parsed || platform && parsed.platform !== platform || slot !== null && parsed.slot !== slot) continue;
|
|
295
|
+
const lease = releaseHeld(root, parsed.platform, record, io, parsed.slot);
|
|
296
|
+
if (lease) released.push(summarize(lease));
|
|
297
|
+
}
|
|
298
|
+
for (const entry of listLeaseFiles(io)) {
|
|
299
|
+
const lease = entry.lease;
|
|
300
|
+
if (!lease || lease.holder !== root) continue;
|
|
301
|
+
if (platform && lease.platform !== platform) continue;
|
|
302
|
+
if (slot !== null && (lease.slot ?? "default") !== slot) continue;
|
|
303
|
+
const byRoot = releaseByRoot(root, lease.platform, lease.id, io);
|
|
304
|
+
if (byRoot) released.push(summarize(byRoot));
|
|
305
|
+
}
|
|
306
|
+
return released;
|
|
307
|
+
});
|
|
287
308
|
}
|
|
288
309
|
function removeExpiredLease(entry, io = fileLeaseIo) {
|
|
289
310
|
const lease = entry.lease;
|
|
@@ -331,5 +352,8 @@ function selectPoolDevice({ candidates, leases, held = null, now }) {
|
|
|
331
352
|
holders
|
|
332
353
|
};
|
|
333
354
|
}
|
|
355
|
+
function withHolderLock(io, root, fn) {
|
|
356
|
+
return io.withHolderLock ? io.withHolderLock(root, fn) : fn();
|
|
357
|
+
}
|
|
334
358
|
//#endregion
|
|
335
359
|
export { parseLease as a, releaseRunLease as c, selectPoolDevice as d, takeLease as f, listLeaseFiles as i, releaseWorkspaceLeases as l, fileLeaseIo as n, parseLeaseDuration as o, leaseIsExpired as r, raiseLease as s, deviceLeasePath as t, removeExpiredLease as u };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { I as deviceSlotKey } from "./config-CcefMY2Q.mjs";
|
|
1
2
|
import { a as formatElapsed, r as clockTime } from "./command-output-8wHMEde0.mjs";
|
|
2
|
-
import { A as APP_READINESS_TIMEOUT_MS, l as VERIFY_TIMEOUT_MS } from "./app-install-
|
|
3
|
-
import { a as parseLease, c as releaseRunLease, d as selectPoolDevice, f as takeLease, n as fileLeaseIo, r as leaseIsExpired, s as raiseLease, t as deviceLeasePath } from "./device-lease-
|
|
3
|
+
import { A as APP_READINESS_TIMEOUT_MS, l as VERIFY_TIMEOUT_MS } from "./app-install-DIp9riNx.mjs";
|
|
4
|
+
import { a as parseLease, c as releaseRunLease, d as selectPoolDevice, f as takeLease, n as fileLeaseIo, r as leaseIsExpired, s as raiseLease, t as deviceLeasePath } from "./device-lease-BJYybF-2.mjs";
|
|
4
5
|
//#region src/engine/device-lease-run.ts
|
|
5
6
|
const LEASE_STEP_FLOOR_MS = 6e4;
|
|
6
7
|
const DEBUG_VERIFY_STEP_MS = VERIFY_TIMEOUT_MS + APP_READINESS_TIMEOUT_MS;
|
|
@@ -101,7 +102,7 @@ function lostRefusal(holder, expiresAt, now) {
|
|
|
101
102
|
lease: null
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
function runLease({ root, platform, kind, expiresAt, io = fileLeaseIo }) {
|
|
105
|
+
function runLease({ root, platform, slot = "default", kind, expiresAt, io = fileLeaseIo }) {
|
|
105
106
|
const handle = {
|
|
106
107
|
kind,
|
|
107
108
|
expiresAt,
|
|
@@ -115,6 +116,7 @@ function runLease({ root, platform, kind, expiresAt, io = fileLeaseIo }) {
|
|
|
115
116
|
const result = raiseLease({
|
|
116
117
|
root,
|
|
117
118
|
platform,
|
|
119
|
+
slot,
|
|
118
120
|
minMs: leaseStepMs(boundMs)
|
|
119
121
|
}, io);
|
|
120
122
|
if (result.status === "raised") {
|
|
@@ -137,7 +139,8 @@ function runLease({ root, platform, kind, expiresAt, io = fileLeaseIo }) {
|
|
|
137
139
|
if (handle.kind === null) return;
|
|
138
140
|
releaseRunLease({
|
|
139
141
|
root,
|
|
140
|
-
platform
|
|
142
|
+
platform,
|
|
143
|
+
slot
|
|
141
144
|
}, io);
|
|
142
145
|
},
|
|
143
146
|
facts() {
|
|
@@ -173,7 +176,7 @@ function releaseLeaseOnSignal(release, { on = (signal, handler) => {
|
|
|
173
176
|
installed.length = 0;
|
|
174
177
|
};
|
|
175
178
|
}
|
|
176
|
-
async function waitForDevice({ root, platform, id, idLabel, waitSeconds, noWait = false, appId = null, holderAppId = () => null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo, deadline, lastLine }) {
|
|
179
|
+
async function waitForDevice({ root, platform, slot = "default", id, idLabel, waitSeconds, noWait = false, appId = null, holderAppId = () => null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo, deadline, lastLine }) {
|
|
177
180
|
const path = deviceLeasePath(platform, id);
|
|
178
181
|
for (;;) {
|
|
179
182
|
const raw = io.readLease(path);
|
|
@@ -183,7 +186,7 @@ async function waitForDevice({ root, platform, id, idLabel, waitSeconds, noWait
|
|
|
183
186
|
refusal: unreadableRefusal(path)
|
|
184
187
|
};
|
|
185
188
|
if (!current || leaseIsExpired(current, now())) return { status: "free" };
|
|
186
|
-
if (current.holder === root) return {
|
|
189
|
+
if (current.holder === root && (current.slot ?? "default") === slot) return {
|
|
187
190
|
status: "ours",
|
|
188
191
|
lease: current
|
|
189
192
|
};
|
|
@@ -210,8 +213,8 @@ async function waitForDevice({ root, platform, id, idLabel, waitSeconds, noWait
|
|
|
210
213
|
await sleep(DEVICE_WAIT_POLL_MS);
|
|
211
214
|
}
|
|
212
215
|
}
|
|
213
|
-
async function acquireRunLease({ root, platform, id, deviceName = null, idLabel, waitSeconds, noWait, installBoundMs, appId = null, holderAppId = () => null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo }) {
|
|
214
|
-
const recorded = io.readHolder(root)[platform];
|
|
216
|
+
async function acquireRunLease({ root, platform, slot = "default", id, deviceName = null, idLabel, waitSeconds, noWait, installBoundMs, appId = null, holderAppId = () => null, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo }) {
|
|
217
|
+
const recorded = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
215
218
|
let held = recorded;
|
|
216
219
|
if (recorded && recorded.id !== id) {
|
|
217
220
|
const other = parseLease(io.readLease(deviceLeasePath(platform, recorded.id)));
|
|
@@ -234,6 +237,7 @@ async function acquireRunLease({ root, platform, id, deviceName = null, idLabel,
|
|
|
234
237
|
const raised = raiseLease({
|
|
235
238
|
root,
|
|
236
239
|
platform,
|
|
240
|
+
slot,
|
|
237
241
|
minMs: leaseStepMs(installBoundMs)
|
|
238
242
|
}, io);
|
|
239
243
|
if (raised.status === "raised") return {
|
|
@@ -245,6 +249,7 @@ async function acquireRunLease({ root, platform, id, deviceName = null, idLabel,
|
|
|
245
249
|
const outcome = await waitForDevice({
|
|
246
250
|
root,
|
|
247
251
|
platform,
|
|
252
|
+
slot,
|
|
248
253
|
id,
|
|
249
254
|
idLabel,
|
|
250
255
|
waitSeconds,
|
|
@@ -267,6 +272,7 @@ async function acquireRunLease({ root, platform, id, deviceName = null, idLabel,
|
|
|
267
272
|
const taken = takeLease({
|
|
268
273
|
root,
|
|
269
274
|
platform,
|
|
275
|
+
slot,
|
|
270
276
|
id,
|
|
271
277
|
deviceName,
|
|
272
278
|
kind: "run",
|
|
@@ -285,8 +291,8 @@ async function acquireRunLease({ root, platform, id, deviceName = null, idLabel,
|
|
|
285
291
|
}
|
|
286
292
|
//#endregion
|
|
287
293
|
//#region src/engine/device-pool.ts
|
|
288
|
-
function heldPoolId(root, platform, now, io = fileLeaseIo) {
|
|
289
|
-
const record = io.readHolder(root)[platform];
|
|
294
|
+
function heldPoolId(root, platform, now, io = fileLeaseIo, slot = "default") {
|
|
295
|
+
const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
290
296
|
if (!record) return null;
|
|
291
297
|
const lease = parseLease(io.readLease(deviceLeasePath(platform, record.id)));
|
|
292
298
|
if (!lease || lease.token !== record.token || leaseIsExpired(lease, now)) return null;
|
|
@@ -352,8 +358,8 @@ function poolBusyRefusal(holders, leases, unreadable, now, waitSeconds) {
|
|
|
352
358
|
}
|
|
353
359
|
};
|
|
354
360
|
}
|
|
355
|
-
async function selectFromPool({ root, platform, idLabel, list, noCandidates, waitSeconds, deadline, noWait = false, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo }) {
|
|
356
|
-
const held = heldPoolId(root, platform, now(), io);
|
|
361
|
+
async function selectFromPool({ root, platform, slot = "default", idLabel, list, noCandidates, waitSeconds, deadline, noWait = false, now = Date.now, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), warn = () => {}, io = fileLeaseIo }) {
|
|
362
|
+
const held = heldPoolId(root, platform, now(), io, slot);
|
|
357
363
|
const until = deadline ?? now() + waitSeconds * 1e3;
|
|
358
364
|
let lastLine = null;
|
|
359
365
|
for (;;) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { k as withDirLock, u as getConfigDir } from "./config-
|
|
3
|
-
import { D as workspaceLogsDir, O as workspaceName, T as workspaceDir, a as clearRemoteSession, c as readMetroTunnel, k as workspaceStateFile, u as readRemoteSession } from "./state-
|
|
4
|
-
import { r as pidExists } from "./metro-
|
|
5
|
-
import { z as planMetroReach } from "./settings-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { k as withDirLock, u as getConfigDir } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { D as workspaceLogsDir, O as workspaceName, T as workspaceDir, a as clearRemoteSession, c as readMetroTunnel, k as workspaceStateFile, u as readRemoteSession } from "./state-B3XA2wp2.mjs";
|
|
4
|
+
import { r as pidExists } from "./metro-CORqXyTL.mjs";
|
|
5
|
+
import { z as planMetroReach } from "./settings-DEJf6_kJ.mjs";
|
|
6
|
+
import { t as withWorkspaceProcessLock } from "./workspace-process-lock-3NcQnZ0X.mjs";
|
|
7
|
+
import { T as readMetroRecords, a as LAUNCH_ERROR, b as isBundleProof, p as devClientDeepLink, r as INSTALL_ERROR } from "./app-install-DIp9riNx.mjs";
|
|
8
|
+
import { S as sanitizeDeviceLabel } from "./ios-Deh5js5V.mjs";
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
11
11
|
import { homedir } from "node:os";
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { g as loadConfig, l as getConcurrencyLimits, o as configCorruptRepair } from "./config-
|
|
3
|
-
import { b as sharedBuildCache, w as workspaceDerivedData } from "./state-
|
|
4
|
-
import { S as makeTemporaryDirectory, a as dirtyFingerprintFiles, f as listWorktrees, g as repoRoot, s as gitCommonDir, w as temporaryRoot, x as filesystemDevice } from "./worktree-
|
|
5
|
-
import { i as detectIsExpo, t as appProjectProblem } from "./project-
|
|
6
|
-
import { d as resolveEasCliBin, i as checkEasAuth$1, l as ownerFromConfig, u as providerFromConfig, v as POOL_SETTING_REMEDY, x as parkedMaxSetting } from "./remote-cache-DDmJ1Roq.mjs";
|
|
7
|
-
import { A as resolveSettings, E as remoteAndroidSetting, I as unknownSettingKeys, M as settingOrigin, N as settingShapeErrors, O as remoteIosSetting, P as settingsLayers, U as resolveOptimizations, V as compilerCacheFallbackMessage, a as SETTING_SHAPE_REMEDY, i as SETTINGS_WITH_RESOLVE_TIME_FALLBACK, n as PATH_SETTINGS, v as iosSimSlimProfileSetting, w as projectOptimizations, y as mergeSettingsLayers } from "./settings-DwU1_U_q.mjs";
|
|
2
|
+
import { g as loadConfig, l as getConcurrencyLimits, o as configCorruptRepair } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { b as sharedBuildCache, w as workspaceDerivedData } from "./state-B3XA2wp2.mjs";
|
|
4
|
+
import { S as makeTemporaryDirectory, a as dirtyFingerprintFiles, f as listWorktrees, g as repoRoot, s as gitCommonDir, w as temporaryRoot, x as filesystemDevice } from "./worktree-Eq6TLH8N.mjs";
|
|
5
|
+
import { i as detectIsExpo, t as appProjectProblem } from "./project-fKmuIaMI.mjs";
|
|
8
6
|
import { d as quotedPath, u as plural } from "./command-output-8wHMEde0.mjs";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
7
|
+
import { B as listBuildLocks, Z as fingerprintProject, q as diffFingerprintSources, y as listAdbDevices } from "./android-BqVIJoG7.mjs";
|
|
8
|
+
import { A as resolveSettings, E as remoteAndroidSetting, I as unknownSettingKeys, M as settingOrigin, N as settingShapeErrors, O as remoteIosSetting, P as settingsLayers, U as resolveOptimizations, V as compilerCacheFallbackMessage, a as SETTING_SHAPE_REMEDY, i as SETTINGS_WITH_RESOLVE_TIME_FALLBACK, n as PATH_SETTINGS, v as iosSimSlimProfileSetting, w as projectOptimizations, y as mergeSettingsLayers } from "./settings-DEJf6_kJ.mjs";
|
|
9
|
+
import { a as POOL_SETTING_REMEDY, b as providerFromConfig, c as parkedMaxSetting, m as checkEasAuth$1, x as resolveEasCliBin, y as ownerFromConfig } from "./teardown-ClFp1Aax.mjs";
|
|
10
|
+
import { E as readHostMemoryPressure, T as hostMemoryPressureAdvice, u as listAllIosSims } from "./ios-Deh5js5V.mjs";
|
|
11
|
+
import { n as listBuildSlots } from "./build-slots-C3-R4XQr.mjs";
|
|
12
|
+
import { E as simslimIsOnPath, S as liveOwnedDeviceCount, a as ccacheEnabled, g as podInstallCommand } from "./xcode-D7sAp-Zy.mjs";
|
|
13
|
+
import { d as projectCmakeLauncher, i as apkOutputsDir, r as resolveAndroidCompilerCache, t as readAndroidCasToolchain } from "./android-cas-BR5YJBYv.mjs";
|
|
15
14
|
import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, rmSync } from "node:fs";
|
|
16
15
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
17
16
|
import { existsSync as existsSync$1, lstatSync as lstatSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, rmSync as rmSync$1 } from "fs";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { g as repoRoot } from "./worktree-
|
|
3
|
-
import { a as findProjectRoot } from "./project-
|
|
2
|
+
import { g as repoRoot } from "./worktree-Eq6TLH8N.mjs";
|
|
3
|
+
import { a as findProjectRoot } from "./project-fKmuIaMI.mjs";
|
|
4
4
|
import { l as phaseLine } from "./command-output-8wHMEde0.mjs";
|
|
5
|
-
import { s as detectXcodeMajor } from "./xcode-
|
|
6
|
-
import { c as repairCxxLauncherState, n as detectFingerprintParity, r as detectLinkedLibraryGitMetadata, s as runDoctor } from "./doctor-
|
|
5
|
+
import { s as detectXcodeMajor } from "./xcode-D7sAp-Zy.mjs";
|
|
6
|
+
import { c as repairCxxLauncherState, n as detectFingerprintParity, r as detectLinkedLibraryGitMetadata, s as runDoctor } from "./doctor-Bmv86UUW.mjs";
|
|
7
7
|
import { accessSync, constants, realpathSync, statSync } from "node:fs";
|
|
8
8
|
import { InvalidArgumentError } from "commander";
|
|
9
9
|
import { delimiter, join, resolve } from "node:path";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { f as getProject, k as withDirLock } from "./config-
|
|
3
|
-
import { f as readWorkspaceLaunches, p as readWorkspaceState } from "./state-
|
|
2
|
+
import { I as deviceSlotKey, L as deviceSlotPlatforms, f as getProject, k as withDirLock } from "./config-CcefMY2Q.mjs";
|
|
3
|
+
import { f as readWorkspaceLaunches, p as readWorkspaceState } from "./state-B3XA2wp2.mjs";
|
|
4
4
|
import { n as deviceConsoleLevel } from "./ios-device-D3pzTKQE.mjs";
|
|
5
|
-
import { i as resolveProjectMetro } from "./metro-
|
|
5
|
+
import { i as resolveProjectMetro } from "./metro-CORqXyTL.mjs";
|
|
6
6
|
import { n as parseLogcatLine, t as androidClockOffset } from "./android-BW8i_YxU.mjs";
|
|
7
7
|
import { _ as launchErrorPreview } from "./command-output-8wHMEde0.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { c as readLogRecords, t as attachExpoErrorContext } from "./logs-query-
|
|
8
|
+
import { n as androidHome } from "./android-BqVIJoG7.mjs";
|
|
9
|
+
import { a as parseLease, n as fileLeaseIo, t as deviceLeasePath } from "./device-lease-BJYybF-2.mjs";
|
|
10
|
+
import { c as readLogRecords, t as attachExpoErrorContext } from "./logs-query-R-Cqc6Qv.mjs";
|
|
11
11
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
13
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
@@ -333,14 +333,18 @@ function captureNativeCrashes(target, logsDir) {
|
|
|
333
333
|
if (text) records = parseAndroidCrashes(text, target, offset).map((record) => symbolicateAndroid(record, target.root, deadline));
|
|
334
334
|
}
|
|
335
335
|
} catch {}
|
|
336
|
-
for (const record of records)
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
336
|
+
for (const record of records) {
|
|
337
|
+
if (target.slot && target.slot !== "default") record.slot = target.slot;
|
|
338
|
+
try {
|
|
339
|
+
const key = createHash("sha256").update(JSON.stringify([
|
|
340
|
+
record.slot,
|
|
341
|
+
record.deviceId,
|
|
342
|
+
record.incident ?? record.deviceTs,
|
|
343
|
+
record.rawReport
|
|
344
|
+
])).digest("hex");
|
|
345
|
+
writeDiagnosticOnce(join(logsDir, `native-crash-${key}.ndjson`), `${JSON.stringify(record)}\n`);
|
|
346
|
+
} catch {}
|
|
347
|
+
}
|
|
344
348
|
return records;
|
|
345
349
|
}
|
|
346
350
|
function printNativeCrashReport(target, logsDir, emit, remote) {
|
|
@@ -350,45 +354,51 @@ function printNativeCrashReport(target, logsDir, emit, remote) {
|
|
|
350
354
|
function captureWorkspaceCrashes(root, logsDir) {
|
|
351
355
|
const attempts = readLogRecords(logsDir).filter((record) => record.event === "launch_attempt");
|
|
352
356
|
const launches = readWorkspaceLaunches(root);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
"
|
|
377
|
-
|
|
378
|
-
|
|
357
|
+
const latest = /* @__PURE__ */ new Map();
|
|
358
|
+
for (const attempt of attempts) if (attempt.platform === "ios" || attempt.platform === "android") latest.set(deviceSlotKey(attempt.platform, String(attempt.slot ?? "default")), attempt);
|
|
359
|
+
for (const [key, attempt] of latest) {
|
|
360
|
+
const platform = attempt.platform;
|
|
361
|
+
const slot = String(attempt.slot ?? "default");
|
|
362
|
+
try {
|
|
363
|
+
if (!attempt || attempt.remote) continue;
|
|
364
|
+
const { deviceId, appId } = attempt;
|
|
365
|
+
const since = attempt.ts;
|
|
366
|
+
const until = Date.now();
|
|
367
|
+
if (typeof deviceId !== "string" || typeof appId !== "string" || typeof since !== "number" || !Number.isFinite(since)) continue;
|
|
368
|
+
if (attempt.physical) {
|
|
369
|
+
const holder = fileLeaseIo.readHolder(root)[key];
|
|
370
|
+
const lease = parseLease(fileLeaseIo.readLease(deviceLeasePath(platform, deviceId)));
|
|
371
|
+
if (holder?.id !== deviceId || !lease || lease.platform !== platform || lease.id !== deviceId || lease.holder !== root || lease.token !== holder.token || Date.parse(lease.expiresAt) <= until || !lease.grantedAt || !Number.isFinite(Date.parse(lease.grantedAt)) || Date.parse(lease.grantedAt) > since) continue;
|
|
372
|
+
} else {
|
|
373
|
+
const launch = launches[key];
|
|
374
|
+
if (!launch || launch.deviceId !== deviceId || launch.appId !== appId || Date.parse(launch.launchedAt) !== since) continue;
|
|
375
|
+
const configured = deviceSlotPlatforms(getProject(root), slot)?.[platform];
|
|
376
|
+
if (!configured?.owned) continue;
|
|
377
|
+
if (platform === "ios" && configured.deviceUdid !== deviceId) continue;
|
|
378
|
+
if (platform === "android") {
|
|
379
|
+
if (!configured.avdName) continue;
|
|
380
|
+
if (getExecutor().runFileQuiet("adb", [
|
|
381
|
+
"-s",
|
|
382
|
+
deviceId,
|
|
383
|
+
"emu",
|
|
384
|
+
"avd",
|
|
385
|
+
"name"
|
|
386
|
+
], { timeoutMs: 2e3 })?.split("\n")[0]?.trim() !== configured.avdName) continue;
|
|
387
|
+
}
|
|
379
388
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
389
|
+
captureNativeCrashes({
|
|
390
|
+
root,
|
|
391
|
+
slot,
|
|
392
|
+
platform,
|
|
393
|
+
deviceId,
|
|
394
|
+
appId,
|
|
395
|
+
since: Number(since),
|
|
396
|
+
until,
|
|
397
|
+
physical: attempt?.physical === true,
|
|
398
|
+
appPath: attempt?.appPath ?? readWorkspaceState(root)?.lastBuild?.appPath
|
|
399
|
+
}, logsDir);
|
|
400
|
+
} catch {}
|
|
401
|
+
}
|
|
392
402
|
}
|
|
393
403
|
//#endregion
|
|
394
404
|
//#region src/error-symbolication.ts
|