rnxsim 0.1.418 → 0.1.420
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/cli/cloud-client.ts +164 -12
- package/cli/cloud-dispatch.ts +7 -2
- package/cli/commands/box/checkout-plane.ts +78 -40
- package/cli/commands/inspect/core.ts +23 -14
- package/cli/commands/inspect/wait-ready.ts +2 -0
- package/cli/commands/platform.ts +30 -9
- package/cli/outbound-endpoints.ts +6 -0
- package/cli/self-invocation.ts +2 -2
- package/cli/shell-init.ts +1 -1
- package/cli/ws-bridge.ts +7 -5
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +1 -1
- package/dist-lib/bridge-contract-input.mjs +1 -1
- package/dist-lib/bridge-contract.cjs +7 -1
- package/dist-lib/bridge-contract.mjs +5 -1
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +6 -4
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +55 -28
- package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +14 -7
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +4 -3
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +9 -6
- package/dist-lib/sdk.cjs +6 -3
- package/dist-lib/sdk.mjs +6 -3
- package/dist-lib/skills.cjs +71 -36
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +9 -5
- package/src/bridge-contract.ts +3 -0
- package/src/dev-bundle-resolution.ts +6 -3
- package/src/dev-server-open.ts +3 -2
- package/src/host/bridge-host.ts +1 -1
- package/src/host/plane-host.ts +1 -1
- package/src/native-dev-bundle-url.ts +1 -1
- package/src/vite-plugin.ts +1 -1
package/dist-lib/sdk.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.420 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
|
|
6
6
|
// src/bridge-contract.ts
|
|
7
7
|
var SEMANTIC_READY_CONTENT_NODE_FLOOR = 100;
|
|
8
|
+
var PUBLIC_NO_NETWORK_MARKER = "public RNX Cloud simulators have no network";
|
|
9
|
+
var HEADLESS_TENANT_FETCH_HUNG_MARKER = "headless tenant fetch hung";
|
|
8
10
|
function readyProbeHasContent(probe) {
|
|
9
11
|
return probe.liveFrameActive || probe.targets > 0 || probe.nodes >= SEMANTIC_READY_CONTENT_NODE_FLOOR;
|
|
10
12
|
}
|
|
@@ -628,12 +630,13 @@ function shellEscape(value) {
|
|
|
628
630
|
}
|
|
629
631
|
function waitReadyReason(status) {
|
|
630
632
|
if (status.bridgeError) {
|
|
631
|
-
if (status.bridgeError.includes(
|
|
633
|
+
if (status.bridgeError.includes(HEADLESS_TENANT_FETCH_HUNG_MARKER) || status.bridgeError.includes(PUBLIC_NO_NETWORK_MARKER)) {
|
|
632
634
|
return status.bridgeError;
|
|
633
635
|
}
|
|
634
636
|
return `sim unreachable: ${status.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`rnx list\`, reopen with \`rnx open\`)`;
|
|
635
637
|
}
|
|
636
|
-
const
|
|
638
|
+
const waitingOnGuestFetch = status.externalReady === false && /https?:\/\//.test(status.externalStatus);
|
|
639
|
+
const base = status.externalError ? `guest app errored: ${status.externalError}` : waitingOnGuestFetch ? `waiting on a guest fetch: ${status.externalStatus}` : status.loadingText ? `still showing "${status.loadingText}"` : status.externalReady === false ? "guest app is still loading" : status.flag !== true && status.targets > 0 ? "native content is rendered but the ready signal has not settled" : status.flag !== true ? "guest app has not emitted sootsim:externalAppReady" : status.targets <= 0 ? "ready flag emitted but no visible app content is inspectable yet" : "node tree is still changing";
|
|
637
640
|
return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
|
|
638
641
|
}
|
|
639
642
|
async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
|
package/dist-lib/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.420 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -15006,7 +15006,7 @@ var init_optional_demo_registry = __esm({
|
|
|
15006
15006
|
});
|
|
15007
15007
|
|
|
15008
15008
|
// scripts/dev-server-scanner.ts
|
|
15009
|
-
function execGuarded(command, timeout, extra = {}) {
|
|
15009
|
+
async function execGuarded(command, timeout, extra = {}) {
|
|
15010
15010
|
let child;
|
|
15011
15011
|
const ran = new Promise((resolve7, reject) => {
|
|
15012
15012
|
child = (0, import_child_process.exec)(command, { encoding: "utf8", timeout, ...extra }, (err, stdout) => {
|
|
@@ -15014,16 +15014,20 @@ function execGuarded(command, timeout, extra = {}) {
|
|
|
15014
15014
|
else resolve7({ stdout });
|
|
15015
15015
|
});
|
|
15016
15016
|
});
|
|
15017
|
+
let deadlineTimer;
|
|
15017
15018
|
const deadline = new Promise((_resolve, reject) => {
|
|
15018
|
-
|
|
15019
|
+
deadlineTimer = setTimeout(() => {
|
|
15019
15020
|
child?.kill("SIGKILL");
|
|
15020
15021
|
const err = new Error(`\`${command}\` did not exit within ${timeout}ms`);
|
|
15021
15022
|
Object.assign(err, { killed: true });
|
|
15022
15023
|
reject(err);
|
|
15023
15024
|
}, timeout + EXEC_EXIT_GRACE_MS);
|
|
15024
|
-
timer.unref?.();
|
|
15025
15025
|
});
|
|
15026
|
-
|
|
15026
|
+
try {
|
|
15027
|
+
return await Promise.race([ran, deadline]);
|
|
15028
|
+
} finally {
|
|
15029
|
+
clearTimeout(deadlineTimer);
|
|
15030
|
+
}
|
|
15027
15031
|
}
|
|
15028
15032
|
async function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
15029
15033
|
try {
|
|
@@ -15085,7 +15089,6 @@ function httpGet(hostname, port, path20, method = "GET", timeout = TIMEOUT_MS, h
|
|
|
15085
15089
|
req.socket?.unref();
|
|
15086
15090
|
}, timeout);
|
|
15087
15091
|
const abandon = setTimeout(() => req.destroy(), BODY_TIMEOUT_MS);
|
|
15088
|
-
abandon.unref?.();
|
|
15089
15092
|
req.on("close", () => {
|
|
15090
15093
|
clearTimeout(giveUp);
|
|
15091
15094
|
clearTimeout(abandon);
|
|
@@ -18746,7 +18749,7 @@ function looksBinary(filePath, size) {
|
|
|
18746
18749
|
if (fd !== void 0) import_node_fs10.default.closeSync(fd);
|
|
18747
18750
|
}
|
|
18748
18751
|
}
|
|
18749
|
-
var import_node_child_process5, import_node_fs10, import_node_path10, CheckoutRequiresGitError, BINARY_SNIFF_BYTES, LIST_FILES_TIMEOUT_MS, CheckoutFilePlane;
|
|
18752
|
+
var import_node_child_process5, import_node_fs10, import_node_path10, CheckoutRequiresGitError, BINARY_SNIFF_BYTES, LIST_FILES_TIMEOUT_MS, LIST_FILES_ATTEMPTS, LIST_FILES_RETRY_MS, CheckoutFilePlane;
|
|
18750
18753
|
var init_checkout_plane = __esm({
|
|
18751
18754
|
"cli/commands/box/checkout-plane.ts"() {
|
|
18752
18755
|
"use strict";
|
|
@@ -18757,6 +18760,8 @@ var init_checkout_plane = __esm({
|
|
|
18757
18760
|
};
|
|
18758
18761
|
BINARY_SNIFF_BYTES = 8192;
|
|
18759
18762
|
LIST_FILES_TIMEOUT_MS = 1e4;
|
|
18763
|
+
LIST_FILES_ATTEMPTS = 3;
|
|
18764
|
+
LIST_FILES_RETRY_MS = 25;
|
|
18760
18765
|
CheckoutFilePlane = class {
|
|
18761
18766
|
root;
|
|
18762
18767
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -18774,33 +18779,55 @@ var init_checkout_plane = __esm({
|
|
|
18774
18779
|
index() {
|
|
18775
18780
|
return this.entries;
|
|
18776
18781
|
}
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
env: process.env
|
|
18791
|
-
});
|
|
18792
|
-
} catch (error) {
|
|
18793
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
18794
|
-
const killed = error instanceof Error && "signal" in error && error.signal === "SIGTERM";
|
|
18795
|
-
throw new CheckoutRequiresGitError(
|
|
18796
|
-
killed ? `git did not list the project's files in ${this.root} within ${this.listTimeoutMs / 1e3}s, so the box has no file set to serve. the checkout may be on a stalled filesystem, or this machine may be too loaded to start a subprocess.` : `could not list the project's files with git in ${this.root}: ${message}`
|
|
18797
|
-
);
|
|
18798
|
-
}
|
|
18782
|
+
listFiles() {
|
|
18783
|
+
const args = this.trackedOnly ? ["ls-files", "-z"] : ["ls-files", "-co", "--exclude-standard", "-z"];
|
|
18784
|
+
const stdout = (0, import_node_child_process5.execFileSync)("git", args, {
|
|
18785
|
+
cwd: this.root,
|
|
18786
|
+
encoding: "utf8",
|
|
18787
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
18788
|
+
timeout: this.listTimeoutMs,
|
|
18789
|
+
// stating the environment is not redundant here. bun 1.3.14 resolves
|
|
18790
|
+
// the binary for the synchronous form against the PATH it captured at
|
|
18791
|
+
// startup and ignores a later change to `process.env.PATH`, so without
|
|
18792
|
+
// this it runs a different git than every other call in the process.
|
|
18793
|
+
env: process.env
|
|
18794
|
+
});
|
|
18799
18795
|
if (stdout.length === 0) {
|
|
18800
18796
|
throw new CheckoutRequiresGitError(
|
|
18801
18797
|
`git listed no ${this.trackedOnly ? "tracked " : ""}files in ${this.root}. either the checkout contains no eligible files, or this machine could not read the child process's output.`
|
|
18802
18798
|
);
|
|
18803
18799
|
}
|
|
18800
|
+
return stdout;
|
|
18801
|
+
}
|
|
18802
|
+
async refresh() {
|
|
18803
|
+
let stdout = "";
|
|
18804
|
+
let lastFailure;
|
|
18805
|
+
for (let attempt = 1; attempt <= LIST_FILES_ATTEMPTS; attempt++) {
|
|
18806
|
+
try {
|
|
18807
|
+
stdout = this.listFiles();
|
|
18808
|
+
lastFailure = void 0;
|
|
18809
|
+
break;
|
|
18810
|
+
} catch (error) {
|
|
18811
|
+
if (error instanceof CheckoutRequiresGitError) {
|
|
18812
|
+
lastFailure = error;
|
|
18813
|
+
} else {
|
|
18814
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18815
|
+
const killed = error instanceof Error && "signal" in error && error.signal === "SIGTERM";
|
|
18816
|
+
lastFailure = new CheckoutRequiresGitError(
|
|
18817
|
+
killed ? `git did not list the project's files in ${this.root} within ${this.listTimeoutMs / 1e3}s, so the box has no file set to serve. the checkout may be on a stalled filesystem, or this machine may be too loaded to start a subprocess.` : `could not list the project's files with git in ${this.root}: ${message}`
|
|
18818
|
+
);
|
|
18819
|
+
}
|
|
18820
|
+
if (attempt < LIST_FILES_ATTEMPTS) {
|
|
18821
|
+
await new Promise(
|
|
18822
|
+
(resolve7) => setTimeout(resolve7, LIST_FILES_RETRY_MS * attempt)
|
|
18823
|
+
);
|
|
18824
|
+
}
|
|
18825
|
+
}
|
|
18826
|
+
}
|
|
18827
|
+
if (lastFailure) {
|
|
18828
|
+
lastFailure.message = `${lastFailure.message} (${LIST_FILES_ATTEMPTS} attempts)`;
|
|
18829
|
+
throw lastFailure;
|
|
18830
|
+
}
|
|
18804
18831
|
const next = /* @__PURE__ */ new Map();
|
|
18805
18832
|
const nextSniffed = /* @__PURE__ */ new Map();
|
|
18806
18833
|
for (const relative of stdout.split("\0")) {
|
|
@@ -22483,11 +22510,12 @@ function createBridge(wsPort, opts = {}) {
|
|
|
22483
22510
|
} catch {
|
|
22484
22511
|
}
|
|
22485
22512
|
ws.close();
|
|
22486
|
-
setTimeout(() => {
|
|
22513
|
+
const terminateGrace = setTimeout(() => {
|
|
22487
22514
|
if (ws.readyState !== import_ws3.WebSocket.CLOSED) {
|
|
22488
22515
|
ws.terminate();
|
|
22489
22516
|
}
|
|
22490
|
-
}, 250)
|
|
22517
|
+
}, 250);
|
|
22518
|
+
ws.once("close", () => clearTimeout(terminateGrace));
|
|
22491
22519
|
}
|
|
22492
22520
|
};
|
|
22493
22521
|
}
|
|
@@ -22695,12 +22723,14 @@ async function probeExpoManifest(normalizedBaseUrl, port) {
|
|
|
22695
22723
|
async (res) => res.ok ? { ok: true, body: await res.text() } : null,
|
|
22696
22724
|
() => void 0
|
|
22697
22725
|
);
|
|
22726
|
+
let probeDeadline;
|
|
22698
22727
|
const answered = await Promise.race([
|
|
22699
22728
|
pending,
|
|
22700
|
-
new Promise(
|
|
22701
|
-
|
|
22702
|
-
)
|
|
22729
|
+
new Promise((resolve7) => {
|
|
22730
|
+
probeDeadline = setTimeout(() => resolve7("timeout"), MANIFEST_PROBE_TIMEOUT_MS);
|
|
22731
|
+
})
|
|
22703
22732
|
]);
|
|
22733
|
+
clearTimeout(probeDeadline);
|
|
22704
22734
|
if (answered === "timeout" || answered === void 0) return { state: "no-answer" };
|
|
22705
22735
|
if (answered === null) return { state: "no-manifest" };
|
|
22706
22736
|
body = answered.body;
|
|
@@ -23324,9 +23354,12 @@ var init_app_splash = __esm({
|
|
|
23324
23354
|
});
|
|
23325
23355
|
|
|
23326
23356
|
// src/bridge-contract.ts
|
|
23357
|
+
var PUBLIC_NO_NETWORK_MARKER, HEADLESS_TENANT_FETCH_HUNG_MARKER;
|
|
23327
23358
|
var init_bridge_contract = __esm({
|
|
23328
23359
|
"src/bridge-contract.ts"() {
|
|
23329
23360
|
"use strict";
|
|
23361
|
+
PUBLIC_NO_NETWORK_MARKER = "public RNX Cloud simulators have no network";
|
|
23362
|
+
HEADLESS_TENANT_FETCH_HUNG_MARKER = "headless tenant fetch hung";
|
|
23330
23363
|
}
|
|
23331
23364
|
});
|
|
23332
23365
|
|
|
@@ -23707,12 +23740,13 @@ function layoutGetNativeEval(opts = {}) {
|
|
|
23707
23740
|
}
|
|
23708
23741
|
function waitReadyReason(status) {
|
|
23709
23742
|
if (status.bridgeError) {
|
|
23710
|
-
if (status.bridgeError.includes(
|
|
23743
|
+
if (status.bridgeError.includes(HEADLESS_TENANT_FETCH_HUNG_MARKER) || status.bridgeError.includes(PUBLIC_NO_NETWORK_MARKER)) {
|
|
23711
23744
|
return status.bridgeError;
|
|
23712
23745
|
}
|
|
23713
23746
|
return `sim unreachable: ${status.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`rnx list\`, reopen with \`rnx open\`)`;
|
|
23714
23747
|
}
|
|
23715
|
-
const
|
|
23748
|
+
const waitingOnGuestFetch = status.externalReady === false && /https?:\/\//.test(status.externalStatus);
|
|
23749
|
+
const base = status.externalError ? `guest app errored: ${status.externalError}` : waitingOnGuestFetch ? `waiting on a guest fetch: ${status.externalStatus}` : status.loadingText ? `still showing "${status.loadingText}"` : status.externalReady === false ? "guest app is still loading" : status.flag !== true && status.targets > 0 ? "native content is rendered but the ready signal has not settled" : status.flag !== true ? "guest app has not emitted sootsim:externalAppReady" : status.targets <= 0 ? "ready flag emitted but no visible app content is inspectable yet" : "node tree is still changing";
|
|
23716
23750
|
return !status.externalError && status.suppressedEntryError ? `${base} (suppressed entry error: ${status.suppressedEntryError})` : base;
|
|
23717
23751
|
}
|
|
23718
23752
|
async function inspectWaitReady(bridge, timeoutMs = 2e4, options = {}) {
|
|
@@ -23817,6 +23851,7 @@ var init_core = __esm({
|
|
|
23817
23851
|
"cli/commands/inspect/core.ts"() {
|
|
23818
23852
|
"use strict";
|
|
23819
23853
|
init_bridge_contract();
|
|
23854
|
+
init_bridge_contract();
|
|
23820
23855
|
LAYOUT_GET_NATIVE_EVAL = layoutGetNativeEval();
|
|
23821
23856
|
MERGED_CONSOLE_COUNT_EVAL = `(() => {
|
|
23822
23857
|
const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.420 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
package/package.json
CHANGED
|
@@ -53,7 +53,7 @@ const EXEC_EXIT_GRACE_MS = 2_000
|
|
|
53
53
|
* `/__server-scan` stops answering at all instead of answering "could not
|
|
54
54
|
* look". so we race the child against a real wall-clock deadline and reject
|
|
55
55
|
* with `killed`, which callers already read as could-not-look. */
|
|
56
|
-
function execGuarded(
|
|
56
|
+
async function execGuarded(
|
|
57
57
|
command: string,
|
|
58
58
|
timeout: number,
|
|
59
59
|
extra: { maxBuffer?: number } = {},
|
|
@@ -65,8 +65,9 @@ function execGuarded(
|
|
|
65
65
|
else resolve({ stdout })
|
|
66
66
|
})
|
|
67
67
|
})
|
|
68
|
+
let deadlineTimer: ReturnType<typeof setTimeout> | undefined
|
|
68
69
|
const deadline = new Promise<never>((_resolve, reject) => {
|
|
69
|
-
|
|
70
|
+
deadlineTimer = setTimeout(() => {
|
|
70
71
|
child?.kill('SIGKILL')
|
|
71
72
|
const err = new Error(`\`${command}\` did not exit within ${timeout}ms`)
|
|
72
73
|
// matches the shape `wasKilledByTimeout` reads off a real exec timeout, so
|
|
@@ -74,9 +75,13 @@ function execGuarded(
|
|
|
74
75
|
Object.assign(err, { killed: true })
|
|
75
76
|
reject(err)
|
|
76
77
|
}, timeout + EXEC_EXIT_GRACE_MS)
|
|
77
|
-
timer.unref?.()
|
|
78
78
|
})
|
|
79
|
-
|
|
79
|
+
try {
|
|
80
|
+
return await Promise.race([ran, deadline])
|
|
81
|
+
} finally {
|
|
82
|
+
// the race is settled, so drop the deadline rather than leaving it pending.
|
|
83
|
+
clearTimeout(deadlineTimer)
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
export interface DiscoveredServer {
|
|
@@ -234,7 +239,6 @@ function httpGet(
|
|
|
234
239
|
// the only thing that ever destroys a connection here. by BODY_TIMEOUT_MS a
|
|
235
240
|
// server has long since answered or died, so there is no live write to cut.
|
|
236
241
|
const abandon = setTimeout(() => req.destroy(), BODY_TIMEOUT_MS)
|
|
237
|
-
abandon.unref?.()
|
|
238
242
|
req.on('close', () => {
|
|
239
243
|
clearTimeout(giveUp)
|
|
240
244
|
clearTimeout(abandon)
|
package/src/bridge-contract.ts
CHANGED
|
@@ -231,6 +231,9 @@ export const SEMANTIC_READY_CONTENT_NODE_FLOOR = 100
|
|
|
231
231
|
export const SEMANTIC_READY_NODE_STABLE_MS = 750
|
|
232
232
|
export const SEMANTIC_READY_POLL_MS = 150
|
|
233
233
|
|
|
234
|
+
export const PUBLIC_NO_NETWORK_MARKER = 'public RNX Cloud simulators have no network'
|
|
235
|
+
export const HEADLESS_TENANT_FETCH_HUNG_MARKER = 'headless tenant fetch hung'
|
|
236
|
+
|
|
234
237
|
export function readyProbeHasContent(
|
|
235
238
|
probe: Pick<SemanticReadyProbe, 'nodes' | 'targets'> &
|
|
236
239
|
Partial<Pick<SemanticReadyProbe, 'liveFrameActive'>>,
|
|
@@ -179,12 +179,15 @@ async function probeExpoManifest(
|
|
|
179
179
|
async (res) => (res.ok ? { ok: true as const, body: await res.text() } : null),
|
|
180
180
|
() => undefined,
|
|
181
181
|
)
|
|
182
|
+
let probeDeadline: ReturnType<typeof setTimeout> | undefined
|
|
182
183
|
const answered = await Promise.race([
|
|
183
184
|
pending,
|
|
184
|
-
new Promise<'timeout'>((resolve) =>
|
|
185
|
-
setTimeout(() => resolve('timeout'), MANIFEST_PROBE_TIMEOUT_MS)
|
|
186
|
-
),
|
|
185
|
+
new Promise<'timeout'>((resolve) => {
|
|
186
|
+
probeDeadline = setTimeout(() => resolve('timeout'), MANIFEST_PROBE_TIMEOUT_MS)
|
|
187
|
+
}),
|
|
187
188
|
])
|
|
189
|
+
// the race is settled, so drop the deadline rather than leaving it pending.
|
|
190
|
+
clearTimeout(probeDeadline)
|
|
188
191
|
if (answered === 'timeout' || answered === undefined) return { state: 'no-answer' }
|
|
189
192
|
if (answered === null) return { state: 'no-manifest' }
|
|
190
193
|
body = answered.body
|
package/src/dev-server-open.ts
CHANGED
|
@@ -129,9 +129,11 @@ export function openRnxDesktopWhenMetroIsReady({
|
|
|
129
129
|
|
|
130
130
|
return new Promise((resolve) => {
|
|
131
131
|
let finished = false
|
|
132
|
+
let retryTimer: ReturnType<typeof setTimeout> | undefined
|
|
132
133
|
const finish = (opened: boolean) => {
|
|
133
134
|
if (finished) return
|
|
134
135
|
finished = true
|
|
136
|
+
clearTimeout(retryTimer)
|
|
135
137
|
scheduledMetroOpens.delete(key)
|
|
136
138
|
resolve(opened)
|
|
137
139
|
}
|
|
@@ -144,8 +146,7 @@ export function openRnxDesktopWhenMetroIsReady({
|
|
|
144
146
|
finish(false)
|
|
145
147
|
return
|
|
146
148
|
}
|
|
147
|
-
|
|
148
|
-
timer.unref()
|
|
149
|
+
retryTimer = setTimeout(check, intervalMs)
|
|
149
150
|
}
|
|
150
151
|
const check = () => {
|
|
151
152
|
const request = http.get(
|
package/src/host/bridge-host.ts
CHANGED
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
isFetchProxyRequestUrl,
|
|
50
50
|
} from './fetch-proxy-handler.ts'
|
|
51
51
|
import { openUrl as openUrlInBrowser, type OpenUrlOptions } from './open-url.ts'
|
|
52
|
-
import { PlaneHost } from './plane-host'
|
|
52
|
+
import { PlaneHost } from './plane-host.ts'
|
|
53
53
|
import {
|
|
54
54
|
handleReplacementModuleRequest,
|
|
55
55
|
isReplacementModuleRequestUrl,
|
package/src/host/plane-host.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import fs from 'node:fs'
|
|
19
19
|
import path from 'node:path'
|
|
20
20
|
import { dispatchPlaneCommand, indexVersion } from '@rnx/box/plane'
|
|
21
|
-
import { CheckoutFilePlane } from '../../cli/commands/box/checkout-plane'
|
|
21
|
+
import { CheckoutFilePlane } from '../../cli/commands/box/checkout-plane.ts'
|
|
22
22
|
import type { ProjectFilePlane } from '@rnx/box/plane'
|
|
23
23
|
import type { WebSocket } from 'ws'
|
|
24
24
|
|
package/src/vite-plugin.ts
CHANGED
|
@@ -511,7 +511,7 @@ export function workerBootChunkPlugin(closures: WorkerBootClosure[]): Plugin {
|
|
|
511
511
|
},
|
|
512
512
|
outputOptions(options) {
|
|
513
513
|
if (!closure) return null
|
|
514
|
-
return { ...options,
|
|
514
|
+
return { ...options, codeSplitting: false }
|
|
515
515
|
},
|
|
516
516
|
generateBundle(_options, bundle) {
|
|
517
517
|
if (!closure) return
|