@absolutejs/absolute 0.20.0-beta.51 → 0.20.0-beta.53
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +327 -106
- package/dist/mobile/index.js +284 -103
- package/dist/mobile/index.js.map +3 -3
- package/dist/mobile/remoteMacAgentEntry.js +85 -85
- package/dist/src/mobile/remoteMacProtocol.d.ts +46 -3
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-Ul3n0I/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-Ul3n0I/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-Ul3n0I/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/cli/index.js
CHANGED
|
@@ -5957,7 +5957,7 @@ import {
|
|
|
5957
5957
|
resolve as resolvePath,
|
|
5958
5958
|
sep as sep5
|
|
5959
5959
|
} from "path";
|
|
5960
|
-
var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TIMEOUT_MS = 2000, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () => join15(homedir4(), ".absolutejs", "mobile", "remote-macs.json"), emptyStore = () => ({
|
|
5960
|
+
var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TIMEOUT_MS = 2000, REMOTE_RELEASE_LEASE_HEARTBEAT_MS = 15000, REMOTE_RELEASE_LEASE_STALE_SECONDS = 120, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () => join15(homedir4(), ".absolutejs", "mobile", "remote-macs.json"), emptyStore = () => ({
|
|
5961
5961
|
format: PROFILE_FORMAT,
|
|
5962
5962
|
profiles: {}
|
|
5963
5963
|
}), loadStore = async (path = defaultProfilePath()) => {
|
|
@@ -6142,7 +6142,111 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6142
6142
|
remoteProjectRoot: posix.join(profile.workspaceRoot, "projects", projectIdentity(projectRoot, config.appId), "current"),
|
|
6143
6143
|
xcodebuild: "remote:xcodebuild",
|
|
6144
6144
|
xcrun: "remote:xcrun"
|
|
6145
|
-
}),
|
|
6145
|
+
}), releaseLeasePath = (project) => posix.join(posix.dirname(project.remoteProjectRoot), ".release-lease"), acquireAbsoluteRemoteMacReleaseLease = async (project, options = {}) => {
|
|
6146
|
+
options.signal?.throwIfAborted();
|
|
6147
|
+
const token = randomUUID4();
|
|
6148
|
+
const path = releaseLeasePath(project);
|
|
6149
|
+
const stalePath = `${path}.stale-${token}`;
|
|
6150
|
+
const staleSeconds = options.staleSeconds ?? REMOTE_RELEASE_LEASE_STALE_SECONDS;
|
|
6151
|
+
if (!Number.isSafeInteger(staleSeconds) || staleSeconds < 30)
|
|
6152
|
+
throw new TypeError("Remote Mac release lease expiry must be at least 30 seconds.");
|
|
6153
|
+
const owner = JSON.stringify({
|
|
6154
|
+
acquiredAt: new Date().toISOString(),
|
|
6155
|
+
appId: project.config.appId,
|
|
6156
|
+
host: process.env.HOSTNAME ?? "unknown",
|
|
6157
|
+
pid: process.pid,
|
|
6158
|
+
token
|
|
6159
|
+
});
|
|
6160
|
+
const script = [
|
|
6161
|
+
"set -eu",
|
|
6162
|
+
"umask 077",
|
|
6163
|
+
`mkdir -p ${shellQuote(posix.dirname(path))}`,
|
|
6164
|
+
`if mkdir ${shellQuote(path)} 2>/dev/null; then status=ACQUIRED; else now=$(date +%s); modified=$(stat -f %m ${shellQuote(path)} 2>/dev/null || printf '0'); age=$((now-modified)); if [ "$age" -le ${staleSeconds} ]; then printf 'BUSY\\n'; cat ${shellQuote(posix.join(path, "owner.json"))} 2>/dev/null || true; exit 73; fi; if mv ${shellQuote(path)} ${shellQuote(stalePath)} 2>/dev/null && mkdir ${shellQuote(path)} 2>/dev/null; then status=RECOVERED; rm -rf ${shellQuote(stalePath)}; else printf 'BUSY\\n'; exit 73; fi; fi`,
|
|
6165
|
+
`printf '%s\\n' ${shellQuote(token)} > ${shellQuote(posix.join(path, "token"))}`,
|
|
6166
|
+
`printf '%s\\n' ${shellQuote(owner)} > ${shellQuote(posix.join(path, "owner.json"))}`,
|
|
6167
|
+
`touch ${shellQuote(path)}`,
|
|
6168
|
+
`printf '%s\\n' "$status"`
|
|
6169
|
+
].join("; ");
|
|
6170
|
+
const capture = options.transport?.capture ?? defaultTransport.capture;
|
|
6171
|
+
const result = await capture([
|
|
6172
|
+
...absoluteRemoteMacSshBase(project.profile),
|
|
6173
|
+
"/bin/sh -lc",
|
|
6174
|
+
shellQuote(script)
|
|
6175
|
+
]);
|
|
6176
|
+
if (result.exitCode !== 0) {
|
|
6177
|
+
if (result.exitCode === 73 || result.stdout.startsWith("BUSY"))
|
|
6178
|
+
throw new Error(`Remote Mac ${project.profile.name} is already building ${project.config.appId}. Wait for that release to finish; a crashed lease recovers automatically after ${staleSeconds} seconds.${result.stdout.split(`
|
|
6179
|
+
`).slice(1).join(" ").trim() ? ` Owner: ${result.stdout.split(`
|
|
6180
|
+
`).slice(1).join(" ").trim()}` : ""}`);
|
|
6181
|
+
requireRemoteSuccess(result, "Remote Mac release lease acquisition");
|
|
6182
|
+
}
|
|
6183
|
+
const recovered = result.stdout.trim().split(/\r?\n/u).at(-1) === "RECOVERED";
|
|
6184
|
+
const runOwned = async (action) => {
|
|
6185
|
+
const ownedScript = `test -f ${shellQuote(posix.join(path, "token"))} && ` + `test "$(cat ${shellQuote(posix.join(path, "token"))})" = ${shellQuote(token)} && ${action}`;
|
|
6186
|
+
const owned = await capture([
|
|
6187
|
+
...absoluteRemoteMacSshBase(project.profile),
|
|
6188
|
+
"/bin/sh -lc",
|
|
6189
|
+
shellQuote(ownedScript)
|
|
6190
|
+
]);
|
|
6191
|
+
requireRemoteSuccess(owned, "Remote Mac release lease ownership check");
|
|
6192
|
+
};
|
|
6193
|
+
return {
|
|
6194
|
+
path,
|
|
6195
|
+
recovered,
|
|
6196
|
+
token,
|
|
6197
|
+
heartbeat: () => runOwned(`touch ${shellQuote(path)}`),
|
|
6198
|
+
release: () => runOwned(`rm -rf ${shellQuote(path)}`)
|
|
6199
|
+
};
|
|
6200
|
+
}, inspectAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
6201
|
+
const root = profile.workspaceRoot;
|
|
6202
|
+
const script = [
|
|
6203
|
+
"set -eu",
|
|
6204
|
+
`mkdir -p ${shellQuote(root)}`,
|
|
6205
|
+
`bytes=$(du -sk ${shellQuote(root)} 2>/dev/null | awk '{print $1 * 1024}')`,
|
|
6206
|
+
`projects=$(find ${shellQuote(posix.join(root, "projects"))} -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')`,
|
|
6207
|
+
`agents=$(find ${shellQuote(posix.join(root, "agents"))} -mindepth 2 -maxdepth 2 -type d 2>/dev/null | wc -l | tr -d ' ')`,
|
|
6208
|
+
`leases=$(find ${shellQuote(posix.join(root, "projects"))} -mindepth 2 -maxdepth 2 -type d -name .release-lease 2>/dev/null | wc -l | tr -d ' ')`,
|
|
6209
|
+
`printf '%s\\n%s\\n%s\\n%s\\n' "${"$"}{bytes:-0}" "${"$"}{projects:-0}" "${"$"}{agents:-0}" "${"$"}{leases:-0}"`
|
|
6210
|
+
].join("; ");
|
|
6211
|
+
const result = await (transport?.capture ?? defaultTransport.capture)([
|
|
6212
|
+
...absoluteRemoteMacSshBase(profile),
|
|
6213
|
+
"/bin/sh -lc",
|
|
6214
|
+
shellQuote(script)
|
|
6215
|
+
]);
|
|
6216
|
+
const [bytes, projectCount, agentCount, leaseCount] = requireRemoteSuccess(result, "Remote Mac workspace inspection").split(/\r?\n/u).map(Number);
|
|
6217
|
+
if ([bytes, projectCount, agentCount, leaseCount].some((value) => typeof value !== "number" || !Number.isSafeInteger(value) || value < 0))
|
|
6218
|
+
throw new TypeError("Remote Mac returned invalid workspace statistics.");
|
|
6219
|
+
return {
|
|
6220
|
+
agentCount: agentCount ?? 0,
|
|
6221
|
+
bytes: bytes ?? 0,
|
|
6222
|
+
leaseCount: leaseCount ?? 0,
|
|
6223
|
+
profile: profile.name,
|
|
6224
|
+
projectCount: projectCount ?? 0,
|
|
6225
|
+
workspaceRoot: root
|
|
6226
|
+
};
|
|
6227
|
+
}, cleanAbsoluteRemoteMacWorkspace = async (profile, transport) => {
|
|
6228
|
+
const root = profile.workspaceRoot;
|
|
6229
|
+
const projects = posix.join(root, "projects");
|
|
6230
|
+
const script = [
|
|
6231
|
+
"set -eu",
|
|
6232
|
+
`mkdir -p ${shellQuote(root)}`,
|
|
6233
|
+
`project_staging=$(find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
6234
|
+
`mobile_staging=$(find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -print 2>/dev/null | wc -l | tr -d ' ')`,
|
|
6235
|
+
`count=$((project_staging+mobile_staging))`,
|
|
6236
|
+
`find ${shellQuote(projects)} -mindepth 2 -maxdepth 2 -type d \\( -name '.incoming-*' -o -name '.previous' -o -name '.release-lease.stale-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
6237
|
+
`find ${shellQuote(projects)} -type d \\( -path '*/current/.absolutejs/mobile/.ios-build-*' -o -path '*/current/.absolutejs/mobile/.ios-stage-*' -o -path '*/current/.absolutejs/mobile/*.incoming-*' \\) -mtime +0 -prune -exec rm -rf {} + 2>/dev/null || true`,
|
|
6238
|
+
`printf '%s\\n' "$count"`
|
|
6239
|
+
].join("; ");
|
|
6240
|
+
const result = await (transport?.capture ?? defaultTransport.capture)([
|
|
6241
|
+
...absoluteRemoteMacSshBase(profile),
|
|
6242
|
+
"/bin/sh -lc",
|
|
6243
|
+
shellQuote(script)
|
|
6244
|
+
]);
|
|
6245
|
+
const removed = Number(requireRemoteSuccess(result, "Remote Mac workspace cleanup"));
|
|
6246
|
+
if (!Number.isSafeInteger(removed) || removed < 0)
|
|
6247
|
+
throw new TypeError("Remote Mac returned an invalid cleanup result.");
|
|
6248
|
+
return { profile: profile.name, removed, workspaceRoot: root };
|
|
6249
|
+
}, installAbsoluteRemoteMacAgent = async (project) => {
|
|
6146
6250
|
const artifact = await materializeAbsoluteRemoteMacAgent(project.projectRoot);
|
|
6147
6251
|
const directory = posix.join(project.profile.workspaceRoot, "agents", `protocol-${ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION}`, artifact.sha256);
|
|
6148
6252
|
const remotePath = posix.join(directory, "agent.js");
|
|
@@ -6291,13 +6395,16 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6291
6395
|
"."
|
|
6292
6396
|
]
|
|
6293
6397
|
};
|
|
6294
|
-
}, syncAbsoluteRemoteMacProject = async (project) => {
|
|
6398
|
+
}, syncAbsoluteRemoteMacProject = async (project, options = {}) => {
|
|
6399
|
+
options.signal?.throwIfAborted();
|
|
6295
6400
|
const commands = absoluteRemoteProjectSyncCommands(project);
|
|
6296
6401
|
const archive = Bun.spawn(commands.tar, {
|
|
6402
|
+
signal: options.signal,
|
|
6297
6403
|
stderr: "pipe",
|
|
6298
6404
|
stdout: "pipe"
|
|
6299
6405
|
});
|
|
6300
6406
|
const upload = Bun.spawn(commands.remote, {
|
|
6407
|
+
signal: options.signal,
|
|
6301
6408
|
stderr: "pipe",
|
|
6302
6409
|
stdin: archive.stdout,
|
|
6303
6410
|
stdout: "pipe"
|
|
@@ -6342,13 +6449,16 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6342
6449
|
],
|
|
6343
6450
|
tar: ["tar", "-cf", "-", "-C", project.config.bundleDirectory, "."]
|
|
6344
6451
|
};
|
|
6345
|
-
}, syncAbsoluteRemoteMacReleaseInputs = async (project) => {
|
|
6452
|
+
}, syncAbsoluteRemoteMacReleaseInputs = async (project, options = {}) => {
|
|
6453
|
+
options.signal?.throwIfAborted();
|
|
6346
6454
|
const commands = absoluteRemoteReleaseInputSyncCommands(project);
|
|
6347
6455
|
const archive = Bun.spawn(commands.tar, {
|
|
6456
|
+
signal: options.signal,
|
|
6348
6457
|
stderr: "pipe",
|
|
6349
6458
|
stdout: "pipe"
|
|
6350
6459
|
});
|
|
6351
6460
|
const upload = Bun.spawn(commands.remote, {
|
|
6461
|
+
signal: options.signal,
|
|
6352
6462
|
stderr: "pipe",
|
|
6353
6463
|
stdin: archive.stdout,
|
|
6354
6464
|
stdout: "pipe"
|
|
@@ -6440,114 +6550,176 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
6440
6550
|
}
|
|
6441
6551
|
}, buildAbsoluteRemoteIosRelease = async (options) => {
|
|
6442
6552
|
const startedAt = performance.now();
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6553
|
+
options.signal?.throwIfAborted();
|
|
6554
|
+
const operation2 = new AbortController;
|
|
6555
|
+
const abort = () => operation2.abort(options.signal?.reason ?? new Error("Remote iOS release cancelled."));
|
|
6556
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
6557
|
+
let lease;
|
|
6558
|
+
const leaseStartedAt = performance.now();
|
|
6559
|
+
try {
|
|
6560
|
+
lease = await (options.acquireLease ?? ((project, signal) => acquireAbsoluteRemoteMacReleaseLease(project, {
|
|
6561
|
+
signal,
|
|
6562
|
+
transport: options.transport
|
|
6563
|
+
})))(options.project, operation2.signal);
|
|
6564
|
+
} catch (error) {
|
|
6565
|
+
options.signal?.removeEventListener("abort", abort);
|
|
6566
|
+
throw error;
|
|
6567
|
+
}
|
|
6568
|
+
options.log?.(`${lease.recovered ? "Recovered stale" : "Acquired"} Remote Mac release lease for ${options.project.config.appId}.`);
|
|
6569
|
+
const leaseDuration = performance.now() - leaseStartedAt;
|
|
6447
6570
|
options.onPhaseTiming?.({
|
|
6448
|
-
durationMs:
|
|
6449
|
-
phase: "remote-release-
|
|
6571
|
+
durationMs: leaseDuration,
|
|
6572
|
+
phase: "remote-release-lease"
|
|
6450
6573
|
});
|
|
6451
|
-
|
|
6452
|
-
const
|
|
6453
|
-
|
|
6454
|
-
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
6455
|
-
const remoteCommand = [
|
|
6456
|
-
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
6457
|
-
"&&",
|
|
6458
|
-
"exec",
|
|
6459
|
-
shellQuote(options.project.profile.bunPath),
|
|
6460
|
-
shellQuote(agent.remotePath),
|
|
6461
|
-
"--release-ios",
|
|
6462
|
-
"--mobile-config",
|
|
6463
|
-
shellQuote(encodedConfig),
|
|
6464
|
-
...options.allowUnsigned ? ["--unsigned"] : [],
|
|
6465
|
-
...options.prepareBuildNumber ? ["--request-build-number"] : [],
|
|
6466
|
-
...options.developmentTeam ? ["--development-team", shellQuote(options.developmentTeam)] : []
|
|
6467
|
-
].join(" ");
|
|
6468
|
-
const process2 = (options.transport?.spawn ?? defaultTransport.spawn)([
|
|
6469
|
-
...absoluteRemoteMacSshBase(options.project.profile),
|
|
6470
|
-
"/bin/sh -lc",
|
|
6471
|
-
shellQuote(remoteCommand)
|
|
6472
|
-
], {});
|
|
6473
|
-
let failure;
|
|
6474
|
-
let metadata;
|
|
6475
|
-
const responses = [];
|
|
6476
|
-
const stdoutDone = consumeLines2(process2.stdout, (line) => {
|
|
6477
|
-
if (!line.startsWith(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX))
|
|
6574
|
+
let heartbeat;
|
|
6575
|
+
const heartbeatTimer = setInterval(() => {
|
|
6576
|
+
if (heartbeat)
|
|
6478
6577
|
return;
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6578
|
+
heartbeat = lease.heartbeat().catch((error) => operation2.abort(error)).finally(() => {
|
|
6579
|
+
heartbeat = undefined;
|
|
6580
|
+
});
|
|
6581
|
+
}, REMOTE_RELEASE_LEASE_HEARTBEAT_MS);
|
|
6582
|
+
heartbeatTimer.unref();
|
|
6583
|
+
try {
|
|
6584
|
+
const syncStartedAt = performance.now();
|
|
6585
|
+
if (options.syncProject)
|
|
6586
|
+
await options.syncProject(options.project);
|
|
6587
|
+
else
|
|
6588
|
+
await syncAbsoluteRemoteMacProject(options.project, {
|
|
6589
|
+
signal: operation2.signal
|
|
6590
|
+
});
|
|
6591
|
+
operation2.signal.throwIfAborted();
|
|
6592
|
+
if (options.syncReleaseInputs)
|
|
6593
|
+
await options.syncReleaseInputs(options.project);
|
|
6594
|
+
else
|
|
6595
|
+
await syncAbsoluteRemoteMacReleaseInputs(options.project, {
|
|
6596
|
+
signal: operation2.signal
|
|
6597
|
+
});
|
|
6598
|
+
operation2.signal.throwIfAborted();
|
|
6599
|
+
const syncDuration = performance.now() - syncStartedAt;
|
|
6600
|
+
options.onPhaseTiming?.({
|
|
6601
|
+
durationMs: syncDuration,
|
|
6602
|
+
phase: "remote-release-sync"
|
|
6603
|
+
});
|
|
6604
|
+
const agentStartedAt = performance.now();
|
|
6605
|
+
const agent = await (options.installAgent ?? installAbsoluteRemoteMacAgent)(options.project);
|
|
6606
|
+
operation2.signal.throwIfAborted();
|
|
6607
|
+
const agentDuration = performance.now() - agentStartedAt;
|
|
6608
|
+
const encodedConfig = Buffer.from(JSON.stringify(portableMobileConfig(options.project))).toString("base64url");
|
|
6609
|
+
const remoteCommand = [
|
|
6610
|
+
`cd ${shellQuote(options.project.remoteProjectRoot)}`,
|
|
6611
|
+
"&&",
|
|
6612
|
+
"exec",
|
|
6613
|
+
shellQuote(options.project.profile.bunPath),
|
|
6614
|
+
shellQuote(agent.remotePath),
|
|
6615
|
+
"--release-ios",
|
|
6616
|
+
"--mobile-config",
|
|
6617
|
+
shellQuote(encodedConfig),
|
|
6618
|
+
...options.allowUnsigned ? ["--unsigned"] : [],
|
|
6619
|
+
...options.prepareBuildNumber ? ["--request-build-number"] : [],
|
|
6620
|
+
...options.developmentTeam ? ["--development-team", shellQuote(options.developmentTeam)] : []
|
|
6621
|
+
].join(" ");
|
|
6622
|
+
const process2 = (options.transport?.spawn ?? defaultTransport.spawn)([
|
|
6623
|
+
...absoluteRemoteMacSshBase(options.project.profile),
|
|
6624
|
+
"/bin/sh -lc",
|
|
6625
|
+
shellQuote(remoteCommand)
|
|
6626
|
+
], { signal: operation2.signal });
|
|
6627
|
+
const killOnAbort = () => process2.kill();
|
|
6628
|
+
operation2.signal.addEventListener("abort", killOnAbort, { once: true });
|
|
6629
|
+
let failure;
|
|
6630
|
+
let metadata;
|
|
6631
|
+
const responses = [];
|
|
6632
|
+
const stdoutDone = consumeLines2(process2.stdout, (line) => {
|
|
6633
|
+
if (!line.startsWith(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX))
|
|
6634
|
+
return;
|
|
6635
|
+
try {
|
|
6636
|
+
const event = JSON.parse(line.slice(ABSOLUTE_REMOTE_MAC_EVENT_PREFIX.length));
|
|
6637
|
+
if (event.v !== ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION)
|
|
6638
|
+
throw new Error("Remote Mac protocol version mismatch.");
|
|
6639
|
+
if (event.type === "log")
|
|
6640
|
+
options.log?.(event.message);
|
|
6641
|
+
if (event.type === "timing") {
|
|
6642
|
+
const durationMs = Reflect.get(event, "durationMs");
|
|
6643
|
+
const phase = Reflect.get(event, "phase");
|
|
6644
|
+
if (typeof durationMs === "number" && typeof phase === "string")
|
|
6645
|
+
options.onPhaseTiming?.({ durationMs, phase });
|
|
6646
|
+
}
|
|
6647
|
+
if (event.type === "fatal")
|
|
6648
|
+
failure = new Error(event.error);
|
|
6649
|
+
if (event.type === "release")
|
|
6650
|
+
metadata = requireAbsoluteIosReleaseMetadata(event.metadata);
|
|
6651
|
+
if (event.type === "build-number-request") {
|
|
6652
|
+
if (!options.prepareBuildNumber || !/^[a-f0-9]{64}$/u.test(event.buildIdentity) || !event.id)
|
|
6653
|
+
throw new TypeError("Remote Mac requested an invalid iOS build number.");
|
|
6654
|
+
responses.push(options.prepareBuildNumber(event.buildIdentity).then(async (buildNumber) => {
|
|
6655
|
+
if (!Number.isSafeInteger(buildNumber) || buildNumber < 1)
|
|
6656
|
+
throw new TypeError("iOS release publisher returned an invalid build number.");
|
|
6657
|
+
process2.stdin.write(`${JSON.stringify({ buildNumber, command: "build-number", id: event.id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
6502
6658
|
`);
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6659
|
+
for (let attempt = 0;attempt < REMOTE_STDIN_FLUSH_ATTEMPTS; attempt++) {
|
|
6660
|
+
try {
|
|
6661
|
+
await process2.stdin.flush();
|
|
6662
|
+
break;
|
|
6663
|
+
} catch {
|
|
6664
|
+
await Promise.resolve();
|
|
6665
|
+
}
|
|
6509
6666
|
}
|
|
6510
|
-
}
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
}
|
|
6667
|
+
}).catch((error) => {
|
|
6668
|
+
failure = error instanceof Error ? error : new Error("Failed to allocate an iOS build number.");
|
|
6669
|
+
process2.kill();
|
|
6670
|
+
return;
|
|
6671
|
+
}));
|
|
6672
|
+
}
|
|
6673
|
+
} catch (error) {
|
|
6674
|
+
failure = error instanceof Error ? error : new Error("Remote Mac emitted an invalid release event.");
|
|
6675
|
+
process2.kill();
|
|
6676
|
+
}
|
|
6677
|
+
});
|
|
6678
|
+
const stderrDone = consumeLines2(process2.stderr, (line) => options.log?.(`[remote] ${line}`));
|
|
6679
|
+
const exitCode = await process2.exited;
|
|
6680
|
+
operation2.signal.removeEventListener("abort", killOnAbort);
|
|
6681
|
+
try {
|
|
6682
|
+
process2.stdin.end();
|
|
6683
|
+
} catch {}
|
|
6684
|
+
await Promise.all([stdoutDone, stderrDone, ...responses]);
|
|
6685
|
+
operation2.signal.throwIfAborted();
|
|
6686
|
+
if (failure)
|
|
6687
|
+
throw failure;
|
|
6688
|
+
if (exitCode !== 0)
|
|
6689
|
+
throw new Error(`Remote iOS release agent exited with status ${exitCode}.`);
|
|
6690
|
+
if (!metadata)
|
|
6691
|
+
throw new Error("Remote iOS release agent did not return an IPA.");
|
|
6692
|
+
const downloadStartedAt = performance.now();
|
|
6693
|
+
const release = await (options.retrieveRelease ?? retrieveAbsoluteRemoteIosRelease)(options.project, metadata, options.outputDirectory);
|
|
6694
|
+
const downloadDuration = performance.now() - downloadStartedAt;
|
|
6695
|
+
options.onPhaseTiming?.({
|
|
6696
|
+
durationMs: downloadDuration,
|
|
6697
|
+
phase: "remote-release-download"
|
|
6698
|
+
});
|
|
6699
|
+
options.log?.(`Remote Mac ${options.project.profile.name} built and verified iOS release ${metadata.releaseId} in ${(performance.now() - startedAt).toFixed(2)}ms (agent ${agent.uploaded ? "uploaded" : "cache hit"}).`);
|
|
6700
|
+
return {
|
|
6701
|
+
...release,
|
|
6702
|
+
timings: {
|
|
6703
|
+
"remote-agent": agentDuration,
|
|
6704
|
+
"remote-release-download": downloadDuration,
|
|
6705
|
+
"remote-release-lease": leaseDuration,
|
|
6706
|
+
"remote-release-sync": syncDuration,
|
|
6707
|
+
total: performance.now() - startedAt
|
|
6516
6708
|
}
|
|
6709
|
+
};
|
|
6710
|
+
} finally {
|
|
6711
|
+
clearInterval(heartbeatTimer);
|
|
6712
|
+
await heartbeat?.catch(() => {
|
|
6713
|
+
return;
|
|
6714
|
+
});
|
|
6715
|
+
options.signal?.removeEventListener("abort", abort);
|
|
6716
|
+
try {
|
|
6717
|
+
await lease.release();
|
|
6718
|
+
options.log?.("Released Remote Mac release lease.");
|
|
6517
6719
|
} catch (error) {
|
|
6518
|
-
|
|
6519
|
-
process2.kill();
|
|
6520
|
-
}
|
|
6521
|
-
});
|
|
6522
|
-
const stderrDone = consumeLines2(process2.stderr, (line) => options.log?.(`[remote] ${line}`));
|
|
6523
|
-
const exitCode = await process2.exited;
|
|
6524
|
-
try {
|
|
6525
|
-
process2.stdin.end();
|
|
6526
|
-
} catch {}
|
|
6527
|
-
await Promise.all([stdoutDone, stderrDone, ...responses]);
|
|
6528
|
-
if (failure)
|
|
6529
|
-
throw failure;
|
|
6530
|
-
if (exitCode !== 0)
|
|
6531
|
-
throw new Error(`Remote iOS release agent exited with status ${exitCode}.`);
|
|
6532
|
-
if (!metadata)
|
|
6533
|
-
throw new Error("Remote iOS release agent did not return an IPA.");
|
|
6534
|
-
const downloadStartedAt = performance.now();
|
|
6535
|
-
const release = await (options.retrieveRelease ?? retrieveAbsoluteRemoteIosRelease)(options.project, metadata, options.outputDirectory);
|
|
6536
|
-
const downloadDuration = performance.now() - downloadStartedAt;
|
|
6537
|
-
options.onPhaseTiming?.({
|
|
6538
|
-
durationMs: downloadDuration,
|
|
6539
|
-
phase: "remote-release-download"
|
|
6540
|
-
});
|
|
6541
|
-
options.log?.(`Remote Mac ${options.project.profile.name} built and verified iOS release ${metadata.releaseId} in ${(performance.now() - startedAt).toFixed(2)}ms (agent ${agent.uploaded ? "uploaded" : "cache hit"}).`);
|
|
6542
|
-
return {
|
|
6543
|
-
...release,
|
|
6544
|
-
timings: {
|
|
6545
|
-
"remote-agent": agentDuration,
|
|
6546
|
-
"remote-release-download": downloadDuration,
|
|
6547
|
-
"remote-release-sync": syncDuration,
|
|
6548
|
-
total: performance.now() - startedAt
|
|
6720
|
+
options.log?.(`Remote Mac release lease cleanup failed and will recover after expiry: ${error instanceof Error ? error.message : String(error)}`);
|
|
6549
6721
|
}
|
|
6550
|
-
}
|
|
6722
|
+
}
|
|
6551
6723
|
}, startAbsoluteRemoteExpoIosDevSession = async (options) => {
|
|
6552
6724
|
const session = await startAbsoluteRemoteDevSession({
|
|
6553
6725
|
certificateAuthorityPath: options.certificateAuthorityPath,
|
|
@@ -18403,6 +18575,10 @@ console.log(\`
|
|
|
18403
18575
|
const resolvedOutdir = resolve36(outdir ?? "dist");
|
|
18404
18576
|
await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
|
|
18405
18577
|
}, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
|
|
18578
|
+
rmSync7(join47(resolvedOutdir, "node_modules"), {
|
|
18579
|
+
force: true,
|
|
18580
|
+
recursive: true
|
|
18581
|
+
});
|
|
18406
18582
|
const configuredPrerenderPort = env5.COMPILE_PORT === undefined ? Number(env5.PORT) : Number(env5.COMPILE_PORT);
|
|
18407
18583
|
const prerenderPort = configuredPrerenderPort > 0 ? configuredPrerenderPort : await findFreePort();
|
|
18408
18584
|
killStaleProcesses(prerenderPort);
|
|
@@ -22247,6 +22423,32 @@ var NOT_FOUND4 = -1, isRecord17 = (value) => typeof value === "object" && value
|
|
|
22247
22423
|
});
|
|
22248
22424
|
console.log(`Paired remote Mac ${profile.name} (${profile.xcodeVersion}) and selected it as the default iOS development host.`);
|
|
22249
22425
|
}, listRemoteMacs = async (args) => {
|
|
22426
|
+
if (args[0] === "inspect") {
|
|
22427
|
+
const requested = args[1]?.startsWith("-") ? undefined : args[1];
|
|
22428
|
+
const profile = await getAbsoluteRemoteMacProfile(requested, remoteProfilePath());
|
|
22429
|
+
if (!profile)
|
|
22430
|
+
throw new TypeError("No Remote Mac is selected. Pair one before inspecting its workspace.");
|
|
22431
|
+
const inspection = await inspectAbsoluteRemoteMacWorkspace(profile);
|
|
22432
|
+
console.log(args.includes("--json") ? JSON.stringify(inspection, null, 2) : [
|
|
22433
|
+
`Remote Mac: ${inspection.profile}`,
|
|
22434
|
+
`Workspace: ${inspection.workspaceRoot}`,
|
|
22435
|
+
`Cache: ${(inspection.bytes / 1048576).toFixed(1)} MiB across ${inspection.projectCount} project(s) and ${inspection.agentCount} agent artifact(s)`,
|
|
22436
|
+
`Active release leases: ${inspection.leaseCount}`
|
|
22437
|
+
].join(`
|
|
22438
|
+
`));
|
|
22439
|
+
return;
|
|
22440
|
+
}
|
|
22441
|
+
if (args[0] === "clean") {
|
|
22442
|
+
if (!args.includes("--yes"))
|
|
22443
|
+
throw new TypeError("Remote Mac cleanup requires --yes. It removes only abandoned staging directories older than one day.");
|
|
22444
|
+
const requested = args[1]?.startsWith("-") ? undefined : args[1];
|
|
22445
|
+
const profile = await getAbsoluteRemoteMacProfile(requested, remoteProfilePath());
|
|
22446
|
+
if (!profile)
|
|
22447
|
+
throw new TypeError("No Remote Mac is selected. Pair one before cleaning its workspace.");
|
|
22448
|
+
const result2 = await cleanAbsoluteRemoteMacWorkspace(profile);
|
|
22449
|
+
console.log(`Removed ${result2.removed} abandoned Remote Mac staging director${result2.removed === 1 ? "y" : "ies"}; project caches, releases, and active leases were retained.`);
|
|
22450
|
+
return;
|
|
22451
|
+
}
|
|
22250
22452
|
const result = await listAbsoluteRemoteMacProfiles(remoteProfilePath());
|
|
22251
22453
|
if (args.includes("--json")) {
|
|
22252
22454
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -22744,6 +22946,18 @@ Mobile release security and compliance checks failed.`);
|
|
|
22744
22946
|
...options.prepareBuildNumber === undefined ? {} : { prepareBuildNumber: options.prepareBuildNumber },
|
|
22745
22947
|
projectRoot: options.projectRoot
|
|
22746
22948
|
});
|
|
22949
|
+
}, listenForRemoteReleaseCancellation = (cancellation) => {
|
|
22950
|
+
if (!cancellation)
|
|
22951
|
+
return () => {
|
|
22952
|
+
return;
|
|
22953
|
+
};
|
|
22954
|
+
const cancel = () => cancellation.abort(new Error("Remote iOS release interrupted."));
|
|
22955
|
+
process.once("SIGINT", cancel);
|
|
22956
|
+
process.once("SIGTERM", cancel);
|
|
22957
|
+
return () => {
|
|
22958
|
+
process.removeListener("SIGINT", cancel);
|
|
22959
|
+
process.removeListener("SIGTERM", cancel);
|
|
22960
|
+
};
|
|
22747
22961
|
}, buildIos = async (args, prepareBuildNumber) => {
|
|
22748
22962
|
const configPath2 = valueAfter(args, "--config");
|
|
22749
22963
|
const { mobile, projectRoot } = await loadMobile(configPath2);
|
|
@@ -22758,10 +22972,15 @@ Mobile release security and compliance checks failed.`);
|
|
|
22758
22972
|
if (process.platform !== "darwin" && !remoteProfile)
|
|
22759
22973
|
throw new TypeError("iOS release builds require macOS or a paired Remote Mac. Run `absolute mobile pair mac <name> <user@host>`.");
|
|
22760
22974
|
let success = false;
|
|
22975
|
+
const cancellation = remoteProfile ? new AbortController : undefined;
|
|
22976
|
+
let stopListeningForCancellation = () => {
|
|
22977
|
+
return;
|
|
22978
|
+
};
|
|
22761
22979
|
try {
|
|
22762
22980
|
if (!remoteProfile && mobile.engine === "capacitor")
|
|
22763
22981
|
await repairAbsoluteIosDevSession(projectRoot);
|
|
22764
22982
|
await start(mobileBuildServerEntry(args), valueAfter(args, "--web-outdir"), configPath2, { prepareOnly: true });
|
|
22983
|
+
stopListeningForCancellation = listenForRemoteReleaseCancellation(cancellation);
|
|
22765
22984
|
const release = remoteProfile ? await buildAbsoluteRemoteIosRelease({
|
|
22766
22985
|
allowUnsigned: args.includes("--unsigned"),
|
|
22767
22986
|
developmentTeam: process.env.ABSOLUTE_IOS_DEVELOPMENT_TEAM,
|
|
@@ -22778,7 +22997,8 @@ Mobile release security and compliance checks failed.`);
|
|
|
22778
22997
|
});
|
|
22779
22998
|
},
|
|
22780
22999
|
...prepareBuildNumber === undefined ? {} : { prepareBuildNumber },
|
|
22781
|
-
project: createAbsoluteRemoteIosDevProject(mobile, projectRoot, remoteProfile)
|
|
23000
|
+
project: createAbsoluteRemoteIosDevProject(mobile, projectRoot, remoteProfile),
|
|
23001
|
+
signal: cancellation?.signal
|
|
22782
23002
|
}) : await buildLocalIosRelease({
|
|
22783
23003
|
args,
|
|
22784
23004
|
mobile,
|
|
@@ -22792,6 +23012,7 @@ Mobile release security and compliance checks failed.`);
|
|
|
22792
23012
|
console.log(`Metadata: ${join56(release.releaseRoot, "release.json")}`);
|
|
22793
23013
|
return release;
|
|
22794
23014
|
} finally {
|
|
23015
|
+
stopListeningForCancellation();
|
|
22795
23016
|
sendTelemetryEvent("mobile:ios-release-build", {
|
|
22796
23017
|
durationMs: Math.round(performance.now() - startedAt),
|
|
22797
23018
|
engine: mobile.engine,
|
|
@@ -23718,7 +23939,7 @@ Emulator setup verification:`);
|
|
|
23718
23939
|
await publishIos(args.slice(2));
|
|
23719
23940
|
return;
|
|
23720
23941
|
}
|
|
23721
|
-
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
23942
|
+
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [inspect [name] [--json] | clean [name] --yes | --json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
23722
23943
|
};
|
|
23723
23944
|
var init_mobile = __esm(() => {
|
|
23724
23945
|
init_dependencies();
|