stim 1.9.0 → 1.10.1
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/dist/{android-_y4Ohi5z.mjs → android-787HhP5w.mjs} +119 -29
- package/dist/{android-BPGizezh.mjs → android-Bu4mbDzc.mjs} +168 -95
- package/dist/{android-DEgo4oCo.mjs → android-DPov-fv2.mjs} +2 -2
- package/dist/{android-cas-eiExNLf7.mjs → android-cas-CITmIeWY.mjs} +9 -8
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{app-install-Uf3a83Tv.mjs → app-install-Cfmqr3TQ.mjs} +2 -2
- package/dist/budget-nDCEwtJv.mjs +620 -0
- package/dist/build-progress-BXx-ZBe4.mjs +512 -0
- package/dist/{cache-manifest-Dg7OnMrp.mjs → cache-manifest-Pubfp8wV.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +16 -16
- package/dist/collector-run.d.mts +5 -1
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-gByVmIjy.mjs → command-output-D5z2_bcF.mjs} +1 -1
- package/dist/{config-Cp9lM3wX.mjs → config-BEq0Qw_a.mjs} +14 -131
- package/dist/{dependency-state-Bq5DcLGn.mjs → dependency-state-r9UesA9a.mjs} +2 -2
- package/dist/{deps-Cip5vUm1.mjs → deps-DP4eWqea.mjs} +3 -3
- package/dist/{detached-entry-KEu0_AXL.mjs → detached-entry-DJHoca49.mjs} +1 -1
- package/dist/{dev-client-HyqISM0h.mjs → dev-client-DExzPiOa.mjs} +137 -250
- package/dist/{device-D4U-xLty.mjs → device-Czh5kO8A.mjs} +7 -7
- package/dist/{build-lock-DPXPLgTc.mjs → device-lease-CbEaIk7b.mjs} +370 -12
- package/dist/{device-pool-CnTAz8X1.mjs → device-pool-BBWLAr55.mjs} +4 -4
- package/dist/{device-remote-AQ5rQPqr.mjs → device-remote-powUHdbK.mjs} +547 -468
- package/dist/{doctor-B_Ei3bZu.mjs → doctor-CmqK1LcQ.mjs} +58 -22
- package/dist/{error-diagnostics-Vfz83GCF.mjs → error-diagnostics-xxWKNO3-.mjs} +11 -12
- package/dist/{exec-jIAlgilk.mjs → exec-DK8KaVHK.mjs} +3 -2
- package/dist/{gc-Ckw8RQHi.mjs → gc-zCDpmdHU.mjs} +500 -1114
- package/dist/{guide-BiAbhs1J.mjs → guide-DwmaD_Wa.mjs} +882 -528
- package/dist/guide-status-CWvti2Lg.mjs +125 -0
- package/dist/idle--jn7pBNe.mjs +157 -0
- package/dist/in-use-CNIWU-r-.mjs +245 -0
- package/dist/{ios-BL2NFckr.mjs → ios-COGcGEcN.mjs} +39 -65
- package/dist/{ios-BzUJWk1K.mjs → ios-CbdqTqOc.mjs} +130 -89
- package/dist/{ios-device-DPsSm0v_.mjs → ios-device-BiOsSVzd.mjs} +1 -1
- package/dist/{ios-device-D972i9wf.mjs → ios-device-DNjPXBnb.mjs} +3 -3
- package/dist/{launch-verify-Q_OtW1Rf.mjs → launch-verify-BhgkYAws.mjs} +5 -5
- package/dist/{logs-CI9NQSK7.mjs → logs-MARIy6m9.mjs} +9 -9
- package/dist/{metro-DrLHaMn2.mjs → metro-BWLOJ_Wr.mjs} +116 -10
- package/dist/{named-ports-CmLQSIRj.mjs → named-ports-DiTfSz6p.mjs} +4 -4
- package/dist/{ndjson-9uFNRwfe.mjs → ndjson-CDY9IkVC.mjs} +3 -56
- package/dist/{ndjson-DvHSsNU9.d.mts → ndjson-Du3j0AQ9.d.mts} +1 -0
- package/dist/ownership-BfPNRf3-.mjs +1180 -0
- package/dist/{ownership-D15Op8vN.mjs → ownership-D2xbLVoz.mjs} +2 -3
- package/dist/{ports-BNKoWVWZ.mjs → ports-CLSSFOuz.mjs} +3 -3
- package/dist/{project-DS112DYB.mjs → project-BXZzOABt.mjs} +2 -2
- package/dist/{reload-ZNJUo1pl.mjs → reload-CymyF6Kk.mjs} +9 -10
- package/dist/{server-bare-DWkkcIxV.mjs → server-bare-DVbb7kXH.mjs} +1 -1
- package/dist/{server-expo-B_lctBR3.mjs → server-expo-BvOCeakp.mjs} +4 -4
- package/dist/server-expo-DBVTdult.mjs +2 -0
- package/dist/{settings-D030k0t4.mjs → settings-DOugPlPz.mjs} +16 -428
- package/dist/{settings-BKNh5rl4.mjs → settings-EWYNwe72.mjs} +16 -14
- package/dist/settings.schema.json +75 -0
- package/dist/{simslim-B_LsGLuJ.mjs → simslim-DZUxzsjq.mjs} +182 -5
- package/dist/{slot-launch-DU9A-gYw.mjs → slot-launch-Dk4oTREM.mjs} +4 -4
- package/dist/{spawn-claims-Dn3C_N6w.mjs → spawn-claims-CUleC2cM.mjs} +1 -1
- package/dist/{start-DYkkKF0s.mjs → start-RbmFPeZ7.mjs} +147 -98
- package/dist/start-qWapeB4W.mjs +2 -0
- package/dist/{state-NcJzMEBF.mjs → state-WGdIbi_d.mjs} +2 -2
- package/dist/{stats-DG9e66Rz.mjs → stats-BAgJaLA4.mjs} +1 -1
- package/dist/{stats-B63-JVAY.mjs → stats-DBYJ5bxL.mjs} +4 -4
- package/dist/status-Dr4fRkym.mjs +216 -0
- package/dist/{status-S6ehL4Ui.mjs → status-Zp8kvexe.mjs} +63 -231
- package/dist/{guide-status-BAMVU0ZA.mjs → stim-installations-CINXy_su.mjs} +3 -124
- package/dist/{stop-T1R-cZRz.mjs → stop-DI4BG4Os.mjs} +2 -2
- package/dist/{stop-BO28HGqF.mjs → stop-DcEv5sk-.mjs} +22 -18
- package/dist/supervisor-run.d.mts +11 -2
- package/dist/supervisor-run.mjs +185 -17
- package/dist/{workspace-process-lock-DWaiRD0e.mjs → workspace-process-lock-BXA96myD.mjs} +2 -2
- package/dist/workspaces-wrH6dXfu.mjs +1003 -0
- package/dist/{worktree-LGB-UwgG.mjs → worktree-Bd4dRvx7.mjs} +40 -122
- package/dist/{worktree-R_cUlE7s.mjs → worktree-BlizKDpZ.mjs} +143 -18
- package/dist/{worktree-DKhSF0UX.mjs → worktree-DEG2o9F8.mjs} +1 -1
- package/dist/{xcode-BZqyxh3e.mjs → xcode-B2tBkf0m.mjs} +9 -158
- package/package.json +6 -5
- package/dist/build-progress-CVqkfPC6.mjs +0 -188
- package/dist/device-lease-Crs-HkJY.mjs +0 -366
- package/dist/logs-query-Cqma3WIu.mjs +0 -298
- package/dist/ownership-DCQPuWEc.mjs +0 -489
- package/dist/public-http-probe-CyMDrQ3c.mjs +0 -61
- package/dist/server-expo-CeILEu86.mjs +0 -2
- package/dist/sim-pool-KaIsp2Ft.mjs +0 -723
- package/dist/spawn-entry-nCE6m770.mjs +0 -14
- package/dist/workspace-state-DF2gCFhx.mjs +0 -169
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { k as ownership_claim_exports, u as getConfigDir } from "./config-
|
|
2
|
-
import { t as getExecutor } from "./exec-
|
|
3
|
-
import { r as register } from "./cache-manifest-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
1
|
+
import { B as parseDeviceSlotKey, R as deviceSlotKey, W as validateDeviceSlot, k as ownership_claim_exports, u as getConfigDir } from "./config-BEq0Qw_a.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-DK8KaVHK.mjs";
|
|
3
|
+
import { r as register } from "./cache-manifest-Pubfp8wV.mjs";
|
|
4
|
+
import { P as withDirLock, S as sharedBuildCache, _ as withWorkspaceStateLock, m as readWorkspaceState, p as clearWorkspaceStateKeys, y as writeWorkspaceState } from "./metro-BWLOJ_Wr.mjs";
|
|
5
|
+
import { r as stopDeclaringSpawnsOn, t as declareSpawnsOn } from "./spawn-claims-CUleC2cM.mjs";
|
|
6
|
+
import { a as formatElapsed, i as formatDuration, m as shortHash } from "./command-output-D5z2_bcF.mjs";
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
9
9
|
import { join } from "path";
|
|
10
10
|
import { buildCacheKey, resolveArtifact, storeArtifact } from "@stim-cli/core";
|
|
11
11
|
import { join as join$1 } from "node:path";
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
12
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
13
13
|
import * as expoFingerprint from "@expo/fingerprint";
|
|
14
14
|
import { buildUploadTimeoutMs } from "@stim-cli/cache";
|
|
15
15
|
const ASSET_MANIFEST_FILE = "assets-manifest.json";
|
|
@@ -425,7 +425,7 @@ function fingerprintDiffRecord({ changed, previousHash, hash }) {
|
|
|
425
425
|
}
|
|
426
426
|
//#endregion
|
|
427
427
|
//#region src/engine/build-lock.ts
|
|
428
|
-
const LOCK_SUFFIX = ".lock";
|
|
428
|
+
const LOCK_SUFFIX$1 = ".lock";
|
|
429
429
|
const WAIT_POLL_MS = 1e3;
|
|
430
430
|
const WAIT_PROGRESS_MS = 3e4;
|
|
431
431
|
const WAIT_CEILING_MS = 54e5;
|
|
@@ -439,7 +439,7 @@ function buildLocksDir() {
|
|
|
439
439
|
return join$1(getConfigDir(), "build-locks");
|
|
440
440
|
}
|
|
441
441
|
function buildLockPath(platform, key) {
|
|
442
|
-
return join$1(buildLocksDir(), `${segment(platform)}-${segment(key)}${LOCK_SUFFIX}`);
|
|
442
|
+
return join$1(buildLocksDir(), `${segment(platform)}-${segment(key)}${LOCK_SUFFIX$1}`);
|
|
443
443
|
}
|
|
444
444
|
function label(platform) {
|
|
445
445
|
return `${platform} build`;
|
|
@@ -510,7 +510,7 @@ function listBuildLocks() {
|
|
|
510
510
|
}
|
|
511
511
|
const locks = [];
|
|
512
512
|
for (const name of names) {
|
|
513
|
-
if (!name.endsWith(LOCK_SUFFIX)) continue;
|
|
513
|
+
if (!name.endsWith(LOCK_SUFFIX$1)) continue;
|
|
514
514
|
const path = join$1(dir, name);
|
|
515
515
|
try {
|
|
516
516
|
if (!statSync(path).isDirectory()) continue;
|
|
@@ -696,5 +696,363 @@ async function waitForSharedBuild({ platform, key, fingerprint, root, logFile, c
|
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
698
|
}
|
|
699
|
+
const DEFAULT_LEASE_MS = 3e5;
|
|
700
|
+
const LEASE_SUFFIX = ".json";
|
|
701
|
+
const LOCK_SUFFIX = ".lock";
|
|
702
|
+
const DURATION = /^[1-9][0-9]*(s|m)$/;
|
|
703
|
+
function deviceLocksDir() {
|
|
704
|
+
return join$1(getConfigDir(), "device-locks");
|
|
705
|
+
}
|
|
706
|
+
function leaseStem(platform, id) {
|
|
707
|
+
return `${segment(platform)}-${segment(id)}`;
|
|
708
|
+
}
|
|
709
|
+
function deviceLeasePath(platform, id) {
|
|
710
|
+
return join$1(deviceLocksDir(), `${leaseStem(platform, id)}${LEASE_SUFFIX}`);
|
|
711
|
+
}
|
|
712
|
+
function deviceLeaseLockPath(platform, id) {
|
|
713
|
+
return join$1(deviceLocksDir(), `${leaseStem(platform, id)}${LOCK_SUFFIX}`);
|
|
714
|
+
}
|
|
715
|
+
const fileLeaseIo = {
|
|
716
|
+
withHolderLock: withWorkspaceStateLock,
|
|
717
|
+
now: () => Date.now(),
|
|
718
|
+
readLease(path) {
|
|
719
|
+
try {
|
|
720
|
+
return readFileSync(path, "utf-8");
|
|
721
|
+
} catch {
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
writeLease(path, body) {
|
|
726
|
+
mkdirSync(deviceLocksDir(), { recursive: true });
|
|
727
|
+
const tmp = `${path}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
728
|
+
writeFileSync(tmp, body);
|
|
729
|
+
try {
|
|
730
|
+
renameSync(tmp, path);
|
|
731
|
+
} catch (error) {
|
|
732
|
+
rmSync(tmp, { force: true });
|
|
733
|
+
throw error;
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
removeLease(path) {
|
|
737
|
+
rmSync(path, { force: true });
|
|
738
|
+
},
|
|
739
|
+
listLeaseNames() {
|
|
740
|
+
try {
|
|
741
|
+
return readdirSync(deviceLocksDir());
|
|
742
|
+
} catch {
|
|
743
|
+
return [];
|
|
744
|
+
}
|
|
745
|
+
},
|
|
746
|
+
withLeaseLock(lockPath, fn) {
|
|
747
|
+
return withDirLock(lockPath, fn, { ensureParent: () => mkdirSync(deviceLocksDir(), { recursive: true }) });
|
|
748
|
+
},
|
|
749
|
+
readHolder(root) {
|
|
750
|
+
return parseWorkspaceLeases(readWorkspaceState(root)?.deviceLeases);
|
|
751
|
+
},
|
|
752
|
+
writeHolder(root, leases) {
|
|
753
|
+
if (Object.keys(leases).length === 0) clearWorkspaceStateKeys(root, ["deviceLeases"]);
|
|
754
|
+
else writeWorkspaceState(root, { deviceLeases: leases });
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
function text(value) {
|
|
758
|
+
return typeof value === "string" && value.trim() !== "" ? value : null;
|
|
759
|
+
}
|
|
760
|
+
function isPlatform(value) {
|
|
761
|
+
return value === "ios" || value === "android";
|
|
762
|
+
}
|
|
763
|
+
function parseLease(raw) {
|
|
764
|
+
if (typeof raw !== "string") return null;
|
|
765
|
+
let parsed;
|
|
766
|
+
try {
|
|
767
|
+
parsed = JSON.parse(raw);
|
|
768
|
+
} catch {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
772
|
+
const entry = parsed;
|
|
773
|
+
if (entry.version !== 1 || !isPlatform(entry.platform)) return null;
|
|
774
|
+
const id = text(entry.id);
|
|
775
|
+
const holder = text(entry.holder);
|
|
776
|
+
const token = text(entry.token);
|
|
777
|
+
const expiresAt = text(entry.expiresAt);
|
|
778
|
+
if (!id || !holder || !token || !expiresAt || !Number.isFinite(Date.parse(expiresAt))) return null;
|
|
779
|
+
if (entry.slot !== void 0) {
|
|
780
|
+
if (typeof entry.slot !== "string") return null;
|
|
781
|
+
try {
|
|
782
|
+
validateDeviceSlot(entry.slot);
|
|
783
|
+
} catch {
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
return {
|
|
788
|
+
version: 1,
|
|
789
|
+
...typeof entry.slot === "string" ? { slot: entry.slot } : {},
|
|
790
|
+
platform: entry.platform,
|
|
791
|
+
id,
|
|
792
|
+
deviceName: text(entry.deviceName),
|
|
793
|
+
holder,
|
|
794
|
+
token,
|
|
795
|
+
grantedAt: text(entry.grantedAt),
|
|
796
|
+
expiresAt
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
function parseWorkspaceLeases(value) {
|
|
800
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
801
|
+
const leases = {};
|
|
802
|
+
for (const [platform, entry] of Object.entries(value)) {
|
|
803
|
+
if (!parseDeviceSlotKey(platform) || !entry || typeof entry !== "object") continue;
|
|
804
|
+
const record = entry;
|
|
805
|
+
const id = text(record.id);
|
|
806
|
+
const token = text(record.token);
|
|
807
|
+
if (!id || !token) continue;
|
|
808
|
+
leases[platform] = {
|
|
809
|
+
id,
|
|
810
|
+
token,
|
|
811
|
+
kind: record.kind === "run" ? "run" : "declared"
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
return leases;
|
|
815
|
+
}
|
|
816
|
+
function leaseIsExpired(lease, now) {
|
|
817
|
+
return Date.parse(lease.expiresAt) <= now;
|
|
818
|
+
}
|
|
819
|
+
function parseLeaseDuration(value) {
|
|
820
|
+
const raw = String(value ?? "").trim();
|
|
821
|
+
const match = DURATION.exec(raw);
|
|
822
|
+
if (!match) return { error: `--for must be a whole number of seconds or minutes, such as 90s or 5m (got "${raw}").` };
|
|
823
|
+
const ms = Number(raw.slice(0, -1)) * (match[1] === "s" ? 1e3 : 6e4);
|
|
824
|
+
if (ms < 1e4 || ms > 18e5) return { error: `--for must be between 10s and 30m (got "${raw}").` };
|
|
825
|
+
return { ms };
|
|
826
|
+
}
|
|
827
|
+
function listLeaseFiles(io = fileLeaseIo) {
|
|
828
|
+
const dir = deviceLocksDir();
|
|
829
|
+
const entries = [];
|
|
830
|
+
for (const name of io.listLeaseNames().toSorted()) {
|
|
831
|
+
if (!name.endsWith(LEASE_SUFFIX)) continue;
|
|
832
|
+
const path = join$1(dir, name);
|
|
833
|
+
const lease = parseLease(io.readLease(path));
|
|
834
|
+
const stem = name.slice(0, -5);
|
|
835
|
+
const cut = stem.indexOf("-");
|
|
836
|
+
entries.push({
|
|
837
|
+
path,
|
|
838
|
+
name,
|
|
839
|
+
platform: lease?.platform ?? (cut > 0 ? stem.slice(0, cut) : stem),
|
|
840
|
+
id: lease?.id ?? (cut > 0 ? stem.slice(cut + 1) : null),
|
|
841
|
+
lease
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
return entries;
|
|
845
|
+
}
|
|
846
|
+
function writeLease(lease, io) {
|
|
847
|
+
io.writeLease(deviceLeasePath(lease.platform, lease.id), `${JSON.stringify(lease, null, 2)}\n`);
|
|
848
|
+
return lease;
|
|
849
|
+
}
|
|
850
|
+
function takeLease({ root, platform, slot = "default", id, deviceName = null, kind, durationMs = DEFAULT_LEASE_MS }, io = fileLeaseIo) {
|
|
851
|
+
return withHolderLock(io, root, () => {
|
|
852
|
+
const key = deviceSlotKey(platform, slot);
|
|
853
|
+
const previous = io.readHolder(root)[key];
|
|
854
|
+
if (previous && previous.id !== id) releaseHeld(root, platform, previous, io, slot);
|
|
855
|
+
for (const entry of listLeaseFiles(io)) {
|
|
856
|
+
const other = entry.lease;
|
|
857
|
+
if (!other || other.platform !== platform || other.holder !== root || (other.slot ?? "default") !== slot || other.id === id) continue;
|
|
858
|
+
releaseByRoot(root, platform, other.id, io);
|
|
859
|
+
}
|
|
860
|
+
const declared = previous?.kind === "declared" && previous.id === id;
|
|
861
|
+
const path = deviceLeasePath(platform, id);
|
|
862
|
+
const result = io.withLeaseLock(deviceLeaseLockPath(platform, id), () => {
|
|
863
|
+
const now = io.now();
|
|
864
|
+
const raw = io.readLease(path);
|
|
865
|
+
const current = parseLease(raw);
|
|
866
|
+
if (raw !== null && !current) return {
|
|
867
|
+
status: "unreadable",
|
|
868
|
+
path
|
|
869
|
+
};
|
|
870
|
+
const asked = now + durationMs;
|
|
871
|
+
if (current && !leaseIsExpired(current, now)) {
|
|
872
|
+
if (current.holder !== root || (current.slot ?? "default") !== slot) return {
|
|
873
|
+
status: "held",
|
|
874
|
+
lease: current
|
|
875
|
+
};
|
|
876
|
+
const floor = declared && kind === "run" ? Math.max(asked, Date.parse(current.expiresAt)) : asked;
|
|
877
|
+
return {
|
|
878
|
+
status: "set",
|
|
879
|
+
lease: writeLease({
|
|
880
|
+
...current,
|
|
881
|
+
deviceName: deviceName ?? current.deviceName,
|
|
882
|
+
expiresAt: new Date(floor).toISOString()
|
|
883
|
+
}, io)
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
const expiresAt = new Date(asked).toISOString();
|
|
887
|
+
return {
|
|
888
|
+
status: "taken",
|
|
889
|
+
lease: writeLease({
|
|
890
|
+
version: 1,
|
|
891
|
+
...slot === "default" ? {} : { slot },
|
|
892
|
+
platform,
|
|
893
|
+
id,
|
|
894
|
+
deviceName,
|
|
895
|
+
holder: root,
|
|
896
|
+
token: randomBytes(12).toString("hex"),
|
|
897
|
+
grantedAt: new Date(now).toISOString(),
|
|
898
|
+
expiresAt
|
|
899
|
+
}, io)
|
|
900
|
+
};
|
|
901
|
+
});
|
|
902
|
+
if (result.status === "taken" || result.status === "set") {
|
|
903
|
+
const recorded = result.status === "set" && declared ? "declared" : kind;
|
|
904
|
+
io.writeHolder(root, {
|
|
905
|
+
...io.readHolder(root),
|
|
906
|
+
[key]: {
|
|
907
|
+
id,
|
|
908
|
+
token: result.lease.token,
|
|
909
|
+
kind: recorded
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
return result;
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
function raiseLease({ root, platform, slot = "default", minMs }, io = fileLeaseIo) {
|
|
917
|
+
const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
918
|
+
if (!record) return { status: "none" };
|
|
919
|
+
const path = deviceLeasePath(platform, record.id);
|
|
920
|
+
return io.withLeaseLock(deviceLeaseLockPath(platform, record.id), () => {
|
|
921
|
+
const current = parseLease(io.readLease(path));
|
|
922
|
+
if (!current || current.token !== record.token) return {
|
|
923
|
+
status: "lost",
|
|
924
|
+
lease: current
|
|
925
|
+
};
|
|
926
|
+
const floor = io.now() + minMs;
|
|
927
|
+
if (Date.parse(current.expiresAt) >= floor) return {
|
|
928
|
+
status: "raised",
|
|
929
|
+
lease: current
|
|
930
|
+
};
|
|
931
|
+
return {
|
|
932
|
+
status: "raised",
|
|
933
|
+
lease: writeLease({
|
|
934
|
+
...current,
|
|
935
|
+
expiresAt: new Date(floor).toISOString()
|
|
936
|
+
}, io)
|
|
937
|
+
};
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
function summarize(lease) {
|
|
941
|
+
return {
|
|
942
|
+
platform: lease.platform,
|
|
943
|
+
id: lease.id,
|
|
944
|
+
deviceName: lease.deviceName,
|
|
945
|
+
expiresAt: lease.expiresAt
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
function releaseHeld(root, platform, record, io, slot = "default") {
|
|
949
|
+
const key = deviceSlotKey(platform, slot);
|
|
950
|
+
const path = deviceLeasePath(platform, record.id);
|
|
951
|
+
const released = io.withLeaseLock(deviceLeaseLockPath(platform, record.id), () => {
|
|
952
|
+
const current = parseLease(io.readLease(path));
|
|
953
|
+
if (!current || current.token !== record.token) return null;
|
|
954
|
+
io.removeLease(path);
|
|
955
|
+
return current;
|
|
956
|
+
});
|
|
957
|
+
const held = io.readHolder(root);
|
|
958
|
+
if (held[key]?.token === record.token) {
|
|
959
|
+
delete held[key];
|
|
960
|
+
io.writeHolder(root, held);
|
|
961
|
+
}
|
|
962
|
+
return released;
|
|
963
|
+
}
|
|
964
|
+
function releaseByRoot(root, platform, id, io) {
|
|
965
|
+
const path = deviceLeasePath(platform, id);
|
|
966
|
+
return io.withLeaseLock(deviceLeaseLockPath(platform, id), () => {
|
|
967
|
+
const current = parseLease(io.readLease(path));
|
|
968
|
+
if (!current || current.holder !== root) return null;
|
|
969
|
+
io.removeLease(path);
|
|
970
|
+
return current;
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
function releaseRunLease({ root, platform, slot = "default" }, io = fileLeaseIo) {
|
|
974
|
+
return withHolderLock(io, root, () => {
|
|
975
|
+
const record = io.readHolder(root)[deviceSlotKey(platform, slot)];
|
|
976
|
+
if (!record || record.kind !== "run") return null;
|
|
977
|
+
const released = releaseHeld(root, platform, record, io, slot);
|
|
978
|
+
return released ? summarize(released) : null;
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
function releaseWorkspaceLeases(root, { platform = null, slot = null } = {}, io = fileLeaseIo) {
|
|
982
|
+
return withHolderLock(io, root, () => {
|
|
983
|
+
const released = [];
|
|
984
|
+
for (const [name, record] of Object.entries(io.readHolder(root))) {
|
|
985
|
+
const parsed = parseDeviceSlotKey(name);
|
|
986
|
+
if (!parsed || platform && parsed.platform !== platform || slot !== null && parsed.slot !== slot) continue;
|
|
987
|
+
const lease = releaseHeld(root, parsed.platform, record, io, parsed.slot);
|
|
988
|
+
if (lease) released.push(summarize(lease));
|
|
989
|
+
}
|
|
990
|
+
for (const entry of listLeaseFiles(io)) {
|
|
991
|
+
const lease = entry.lease;
|
|
992
|
+
if (!lease || lease.holder !== root) continue;
|
|
993
|
+
if (platform && lease.platform !== platform) continue;
|
|
994
|
+
if (slot !== null && (lease.slot ?? "default") !== slot) continue;
|
|
995
|
+
const byRoot = releaseByRoot(root, lease.platform, lease.id, io);
|
|
996
|
+
if (byRoot) released.push(summarize(byRoot));
|
|
997
|
+
}
|
|
998
|
+
return released;
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
function removeExpiredLease(entry, io = fileLeaseIo) {
|
|
1002
|
+
const lease = entry.lease;
|
|
1003
|
+
if (!lease) return false;
|
|
1004
|
+
return io.withLeaseLock(deviceLeaseLockPath(lease.platform, lease.id), () => {
|
|
1005
|
+
const current = parseLease(io.readLease(entry.path));
|
|
1006
|
+
if (!current || !leaseIsExpired(current, io.now())) return false;
|
|
1007
|
+
io.removeLease(entry.path);
|
|
1008
|
+
return true;
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
function selectPoolDevice({ candidates, leases, held = null, now }) {
|
|
1012
|
+
const ordered = candidates.toSorted((a, b) => {
|
|
1013
|
+
const left = a.id.toLowerCase();
|
|
1014
|
+
const right = b.id.toLowerCase();
|
|
1015
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
1016
|
+
});
|
|
1017
|
+
if (held) {
|
|
1018
|
+
const mine = ordered.find((candidate) => candidate.id === held);
|
|
1019
|
+
return mine ? {
|
|
1020
|
+
status: "selected",
|
|
1021
|
+
candidate: mine
|
|
1022
|
+
} : {
|
|
1023
|
+
status: "held-disconnected",
|
|
1024
|
+
id: held
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
const preferred = ordered.filter((candidate) => !candidate.fallback);
|
|
1028
|
+
const pool = preferred.length > 0 ? preferred : ordered;
|
|
1029
|
+
if (pool.length === 0) return { status: "none" };
|
|
1030
|
+
const byId = new Map(leases.map((lease) => [lease.id, lease]));
|
|
1031
|
+
const free = (candidate) => {
|
|
1032
|
+
const lease = byId.get(candidate.id);
|
|
1033
|
+
return !lease || leaseIsExpired(lease, now);
|
|
1034
|
+
};
|
|
1035
|
+
const holders = [];
|
|
1036
|
+
for (const candidate of pool) {
|
|
1037
|
+
if (free(candidate)) return {
|
|
1038
|
+
status: "selected",
|
|
1039
|
+
candidate
|
|
1040
|
+
};
|
|
1041
|
+
const lease = byId.get(candidate.id);
|
|
1042
|
+
holders.push({
|
|
1043
|
+
id: lease.id,
|
|
1044
|
+
holder: lease.holder,
|
|
1045
|
+
expiresAt: lease.expiresAt
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
return {
|
|
1049
|
+
status: "busy",
|
|
1050
|
+
holders,
|
|
1051
|
+
spare: ordered.filter((candidate) => candidate.fallback && free(candidate)).map((candidate) => candidate.id)
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
function withHolderLock(io, root, fn) {
|
|
1055
|
+
return io.withHolderLock ? io.withHolderLock(root, fn) : fn();
|
|
1056
|
+
}
|
|
699
1057
|
//#endregion
|
|
700
|
-
export {
|
|
1058
|
+
export { resolveBuild as A, fingerprintDiffRecord as C, providerDownloadPath as D, prepareProviderDownloadDir as E, assetDiffReason as F, captureAssetManifest as I, compareAssetManifests as L, storedAssetManifest as M, untrackedMissLine as N, providerUploadOutcome as O, untrackedNativeFiles as P, readAssetManifest as R, filesystemBuildCapability as S, fingerprintProject as T, waitForBuild as _, parseLease as a, describeFingerprintMiss as b, raiseLease as c, removeExpiredLease as d, selectPoolDevice as f, releaseBuildLock as g, listBuildLocks as h, listLeaseFiles as i, storeBuild as j, refingerprintAfterMutation as k, releaseRunLease as l, acquireBuildLock as m, fileLeaseIo as n, parseLeaseDuration as o, takeLease as p, leaseIsExpired as r, parseWorkspaceLeases as s, deviceLeasePath as t, releaseWorkspaceLeases as u, waitForSharedBuild as v, fingerprintDiffSuffix as w, diffFingerprintSources as x, buildCacheKey as y };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as formatElapsed, r as clockTime } from "./command-output-
|
|
3
|
-
import { a as
|
|
4
|
-
import { a as
|
|
1
|
+
import { R as deviceSlotKey } from "./config-BEq0Qw_a.mjs";
|
|
2
|
+
import { a as formatElapsed, r as clockTime } from "./command-output-D5z2_bcF.mjs";
|
|
3
|
+
import { a as parseLease, c as raiseLease, f as selectPoolDevice, l as releaseRunLease, n as fileLeaseIo, p as takeLease, r as leaseIsExpired, t as deviceLeasePath } from "./device-lease-CbEaIk7b.mjs";
|
|
4
|
+
import { a as VERIFY_TIMEOUT_MS, p as APP_READINESS_TIMEOUT_MS } from "./launch-verify-BhgkYAws.mjs";
|
|
5
5
|
//#region src/engine/device-lease-run.ts
|
|
6
6
|
const LEASE_STEP_FLOOR_MS = 6e4;
|
|
7
7
|
const DEBUG_VERIFY_STEP_MS = VERIFY_TIMEOUT_MS + APP_READINESS_TIMEOUT_MS;
|