peachsim 0.1.626 → 0.1.628
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/LICENSE +1 -1
- package/README.md +3 -2
- package/cli/bin.ts +6 -2
- package/cli/bridge-flow-runner.ts +79 -72
- package/cli/commands/box/bundle-plane.ts +7 -2
- package/cli/commands/box.ts +9 -2
- package/cli/commands/cleanup.ts +6 -6
- package/cli/commands/control.ts +36 -6
- package/cli/commands/detox.ts +25 -11
- package/cli/commands/flow.ts +20 -8
- package/cli/commands/inspect.ts +22 -37
- package/cli/commands/maestro-generate.ts +5 -12
- package/cli/commands/maestro.ts +16 -6
- package/cli/commands/mode.ts +11 -7
- package/cli/commands/platform.ts +1 -0
- package/cli/commands/report-issue.ts +1 -1
- package/cli/commands/setup.ts +16 -11
- package/cli/commands/show-touches-mode.ts +33 -0
- package/cli/commands/skills.ts +16 -0
- package/cli/commands/test.ts +22 -1
- package/cli/commands/upload.ts +18 -8
- package/cli/commands/welcome.ts +3 -3
- package/cli/drivers/playwright-sim-host.ts +16 -8
- package/cli/drivers/playwright.ts +8 -5
- package/cli/help-core.ts +9 -4
- package/cli/internal-child.ts +14 -2
- package/cli/levenshtein.ts +27 -0
- package/cli/main.ts +28 -18
- package/cli/run-rnx.ts +8 -4
- package/cli/ws-bridge.ts +3 -2
- package/detox/index.ts +234 -7
- package/dist-lib/agent-daemon-client.cjs +2 -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 +4 -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 +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +18 -8
- package/dist-lib/capture-contract.mjs +18 -8
- 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/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +170 -13
- package/dist-lib/dev-bundle-resolution.cjs +2 -2
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +280 -138
- 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 +62 -12
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/menu.cjs +7 -1
- package/dist-lib/menu.mjs +7 -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 +43 -4
- 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 +215 -28
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +431 -276
- package/dist-lib/swift-compile.cjs +1 -1
- package/dist-lib/swift-compile.mjs +1 -1
- package/dist-lib/swift-package.cjs +1 -1
- package/dist-lib/swift-package.mjs +1 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +14512 -14208
- package/dist-lib/vite-kotlin.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1 -1
- package/dist-lib/vite.cjs +44 -4
- package/install.mjs +16 -0
- package/install.sh +199 -0
- package/package.json +6 -1
- package/scripts/dev-server-scanner.ts +77 -46
- package/skills/contrast/SKILL.md +1 -1
- package/src/bridge-constants.ts +11 -0
- package/src/capture-contract.ts +40 -7
- package/src/dev-bundle-resolution.ts +1 -1
- package/src/host/bridge-host.ts +26 -137
- package/src/menu.ts +7 -0
- package/src/native-seam-manifest.ts +4 -16
- package/src/runtime-assets.ts +59 -2
- package/src/vite-plugin.ts +723 -25
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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;
|
|
@@ -973,6 +973,7 @@ function resolveSootsimBridgePort(input = {}) {
|
|
|
973
973
|
if (explicitPort !== null) return explicitPort;
|
|
974
974
|
return DEFAULT_SOOTSIM_BRIDGE_PORT + parsePortOffset(input.portOffset);
|
|
975
975
|
}
|
|
976
|
+
var AUTOMATION_SIM_IDLE_REAP_TTL_MS = 5 * 6e4;
|
|
976
977
|
|
|
977
978
|
// src/cli-constants.ts
|
|
978
979
|
var DEFAULT_SOOTSIM_SHELL_URL = "http://localhost:5173/";
|
|
@@ -1027,7 +1028,7 @@ function resolveDefaultDevBridgeLockfile() {
|
|
|
1027
1028
|
) ?? sameCheckout[0];
|
|
1028
1029
|
}
|
|
1029
1030
|
}
|
|
1030
|
-
return lockfiles.find((lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT) ??
|
|
1031
|
+
return lockfiles.find((lockfile) => lockfile.bridgePort === DEFAULT_SOOTSIM_BRIDGE_PORT) ?? null;
|
|
1031
1032
|
}
|
|
1032
1033
|
function resolveBridgeWorld() {
|
|
1033
1034
|
const homeDir = rnxHomeDir();
|
|
@@ -3155,13 +3156,18 @@ async function connect(options = {}) {
|
|
|
3155
3156
|
|
|
3156
3157
|
// src/capture-contract.ts
|
|
3157
3158
|
var RNX_SCREEN_CAPTURE_VERSION = 1;
|
|
3159
|
+
function isLiveRasterSource(node) {
|
|
3160
|
+
const source = node.props?.source;
|
|
3161
|
+
return node.type === "image" && !!source && typeof source === "object" && "uri" in source && typeof source.uri === "string" && source.uri.startsWith("live:");
|
|
3162
|
+
}
|
|
3158
3163
|
function selectRnxRasterNodeIds(tree) {
|
|
3159
3164
|
const nodesById = new Map(tree.nodes.map((node) => [node.nodeId, node]));
|
|
3160
3165
|
const unsupported = /* @__PURE__ */ new Set();
|
|
3161
3166
|
for (const node of tree.nodes) {
|
|
3162
|
-
const
|
|
3167
|
+
const liveVideo = isLiveRasterSource(node);
|
|
3168
|
+
const visibleFrame = liveVideo && node.visibleFrame && (node.visibleFrame.width <= 0 || node.visibleFrame.height <= 0) ? node.frame : node.visibleFrame ?? node.frame;
|
|
3163
3169
|
if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
|
|
3164
|
-
if (node.type === "masked-view" || node.type === "text" && typeof node.text === "string" && (new RegExp("\\p{Emoji_Presentation}", "u").test(node.text) || new RegExp("\\uFE0F|\\u200D|\\u20E3|\\p{Emoji_Modifier}|\\p{Regional_Indicator}", "u").test(
|
|
3170
|
+
if (node.type === "masked-view" || liveVideo || node.type === "text" && typeof node.text === "string" && (new RegExp("\\p{Emoji_Presentation}", "u").test(node.text) || new RegExp("\\uFE0F|\\u200D|\\u20E3|\\p{Emoji_Modifier}|\\p{Regional_Indicator}", "u").test(
|
|
3165
3171
|
node.text
|
|
3166
3172
|
)) || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0 || node.style._liquidGlassMaterialTint !== void 0) {
|
|
3167
3173
|
unsupported.add(node.nodeId);
|
|
@@ -3179,17 +3185,21 @@ function selectRnxRasterNodeIds(tree) {
|
|
|
3179
3185
|
}
|
|
3180
3186
|
const screenArea = tree.width * tree.height;
|
|
3181
3187
|
const maxLayerArea = screenArea * 0.25;
|
|
3182
|
-
const maxAtlasArea = screenArea * 0.5;
|
|
3183
3188
|
const candidates = [...unsupported].map((nodeId) => {
|
|
3184
3189
|
const node = nodesById.get(nodeId);
|
|
3185
|
-
|
|
3186
|
-
|
|
3190
|
+
if (!node) return null;
|
|
3191
|
+
const liveVideo = isLiveRasterSource(node);
|
|
3192
|
+
const frame = liveVideo && node.visibleFrame && (node.visibleFrame.width <= 0 || node.visibleFrame.height <= 0) ? node.frame : node.visibleFrame ?? node.frame;
|
|
3193
|
+
return frame ? { nodeId, area: frame.width * frame.height, liveVideo } : null;
|
|
3187
3194
|
}).filter(
|
|
3188
|
-
(candidate) => candidate !== null && candidate.area <= maxLayerArea
|
|
3189
|
-
).sort(
|
|
3195
|
+
(candidate) => candidate !== null && (candidate.liveVideo || candidate.area <= maxLayerArea)
|
|
3196
|
+
).sort(
|
|
3197
|
+
(left, right) => Number(right.liveVideo) - Number(left.liveVideo) || left.area - right.area || left.nodeId - right.nodeId
|
|
3198
|
+
);
|
|
3190
3199
|
const selected = /* @__PURE__ */ new Set();
|
|
3191
3200
|
let atlasArea = 0;
|
|
3192
3201
|
for (const candidate of candidates) {
|
|
3202
|
+
const maxAtlasArea = screenArea * (candidate.liveVideo ? 1 : 0.5);
|
|
3193
3203
|
if (atlasArea + candidate.area > maxAtlasArea) continue;
|
|
3194
3204
|
selected.add(candidate.nodeId);
|
|
3195
3205
|
atlasArea += candidate.area;
|
|
@@ -3270,6 +3280,7 @@ function rnxCaptureRasterRegions(capture) {
|
|
|
3270
3280
|
nodeId: node.nodeId,
|
|
3271
3281
|
parentNodeId: node.parentNodeId,
|
|
3272
3282
|
type: node.type,
|
|
3283
|
+
props: node.props,
|
|
3273
3284
|
text: node.text,
|
|
3274
3285
|
style: node.style.resolved,
|
|
3275
3286
|
layout: node.layout.local,
|
|
@@ -4002,7 +4013,11 @@ var MIME_TYPES = {
|
|
|
4002
4013
|
".woff": "font/woff",
|
|
4003
4014
|
".woff2": "font/woff2",
|
|
4004
4015
|
".mp3": "audio/mpeg",
|
|
4005
|
-
".wav": "audio/wav"
|
|
4016
|
+
".wav": "audio/wav",
|
|
4017
|
+
".mp4": "video/mp4",
|
|
4018
|
+
".m4v": "video/mp4",
|
|
4019
|
+
".mov": "video/quicktime",
|
|
4020
|
+
".webm": "video/webm"
|
|
4006
4021
|
};
|
|
4007
4022
|
var ROOT_RUNTIME_PATHS = [
|
|
4008
4023
|
"/assets/",
|
|
@@ -4016,7 +4031,7 @@ var ROOT_RUNTIME_PATHS = [
|
|
|
4016
4031
|
"/spike/",
|
|
4017
4032
|
"/test-wallpaper.jpg",
|
|
4018
4033
|
"/preview-sw.js",
|
|
4019
|
-
"/
|
|
4034
|
+
"/peach.svg",
|
|
4020
4035
|
"/bedrock-sqlite.wasm",
|
|
4021
4036
|
"/bedrock-sqlite.js",
|
|
4022
4037
|
"/sootsim/"
|
|
@@ -4100,7 +4115,42 @@ function serveRuntimeFile(req, res, fullPath) {
|
|
|
4100
4115
|
res.end();
|
|
4101
4116
|
return;
|
|
4102
4117
|
}
|
|
4103
|
-
|
|
4118
|
+
sendFileWithRanges(req, res, fullPath, stat.size, {});
|
|
4119
|
+
}
|
|
4120
|
+
function sendFileWithRanges(req, res, filePath, total, headers) {
|
|
4121
|
+
const head = (req?.method || "GET").toUpperCase() === "HEAD";
|
|
4122
|
+
const range = /^bytes=(\d*)-(\d*)$/.exec(req?.headers?.range || "");
|
|
4123
|
+
const invalid = range && range[1] && range[2] && Number(range[2]) < Number(range[1]);
|
|
4124
|
+
if (range && (range[1] || range[2]) && !invalid) {
|
|
4125
|
+
const [, startRaw, endRaw] = range;
|
|
4126
|
+
const start = startRaw ? Number(startRaw) : Math.max(0, total - Number(endRaw));
|
|
4127
|
+
const end = startRaw && endRaw ? Math.min(Number(endRaw), total - 1) : total - 1;
|
|
4128
|
+
if (start > end || start >= total) {
|
|
4129
|
+
res.writeHead(416, { ...headers, "Content-Range": `bytes */${total}` });
|
|
4130
|
+
res.end();
|
|
4131
|
+
return;
|
|
4132
|
+
}
|
|
4133
|
+
res.writeHead(206, {
|
|
4134
|
+
...headers,
|
|
4135
|
+
"Content-Range": `bytes ${start}-${end}/${total}`,
|
|
4136
|
+
"Accept-Ranges": "bytes",
|
|
4137
|
+
"Content-Length": String(end - start + 1)
|
|
4138
|
+
});
|
|
4139
|
+
if (head) res.end();
|
|
4140
|
+
else streamFile(res, import_fs3.default.createReadStream(filePath, { start, end }));
|
|
4141
|
+
return;
|
|
4142
|
+
}
|
|
4143
|
+
res.writeHead(200, {
|
|
4144
|
+
...headers,
|
|
4145
|
+
"Accept-Ranges": "bytes",
|
|
4146
|
+
"Content-Length": String(total)
|
|
4147
|
+
});
|
|
4148
|
+
if (head || total === 0) res.end();
|
|
4149
|
+
else streamFile(res, import_fs3.default.createReadStream(filePath, { start: 0, end: total - 1 }));
|
|
4150
|
+
}
|
|
4151
|
+
function streamFile(res, stream) {
|
|
4152
|
+
stream.on("error", (error) => res.destroy(error));
|
|
4153
|
+
stream.pipe(res);
|
|
4104
4154
|
}
|
|
4105
4155
|
|
|
4106
4156
|
// src/vite-plugin-one.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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/dist-lib/menu.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
|
@@ -404,6 +404,12 @@ function windowMenu(state) {
|
|
|
404
404
|
checked: state.showBezels,
|
|
405
405
|
action: "toggle-bezels"
|
|
406
406
|
},
|
|
407
|
+
{
|
|
408
|
+
label: "Show Touches",
|
|
409
|
+
type: "checkbox",
|
|
410
|
+
checked: state.showTouches,
|
|
411
|
+
action: "toggle-touches"
|
|
412
|
+
},
|
|
407
413
|
{
|
|
408
414
|
label: "Show Menu Bar",
|
|
409
415
|
type: "checkbox",
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/public-brand.ts
|
|
4
4
|
var name = "Peach";
|
|
@@ -363,6 +363,12 @@ function windowMenu(state) {
|
|
|
363
363
|
checked: state.showBezels,
|
|
364
364
|
action: "toggle-bezels"
|
|
365
365
|
},
|
|
366
|
+
{
|
|
367
|
+
label: "Show Touches",
|
|
368
|
+
type: "checkbox",
|
|
369
|
+
checked: state.showTouches,
|
|
370
|
+
action: "toggle-touches"
|
|
371
|
+
},
|
|
366
372
|
{
|
|
367
373
|
label: "Show Menu Bar",
|
|
368
374
|
type: "checkbox",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
package/dist-lib/metro.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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;
|
|
@@ -612,7 +612,11 @@ var MIME_TYPES = {
|
|
|
612
612
|
".woff": "font/woff",
|
|
613
613
|
".woff2": "font/woff2",
|
|
614
614
|
".mp3": "audio/mpeg",
|
|
615
|
-
".wav": "audio/wav"
|
|
615
|
+
".wav": "audio/wav",
|
|
616
|
+
".mp4": "video/mp4",
|
|
617
|
+
".m4v": "video/mp4",
|
|
618
|
+
".mov": "video/quicktime",
|
|
619
|
+
".webm": "video/webm"
|
|
616
620
|
};
|
|
617
621
|
var ROOT_RUNTIME_PATHS = [
|
|
618
622
|
"/assets/",
|
|
@@ -626,7 +630,7 @@ var ROOT_RUNTIME_PATHS = [
|
|
|
626
630
|
"/spike/",
|
|
627
631
|
"/test-wallpaper.jpg",
|
|
628
632
|
"/preview-sw.js",
|
|
629
|
-
"/
|
|
633
|
+
"/peach.svg",
|
|
630
634
|
"/bedrock-sqlite.wasm",
|
|
631
635
|
"/bedrock-sqlite.js",
|
|
632
636
|
"/sootsim/"
|
|
@@ -710,7 +714,42 @@ function serveRuntimeFile(req, res, fullPath) {
|
|
|
710
714
|
res.end();
|
|
711
715
|
return;
|
|
712
716
|
}
|
|
713
|
-
|
|
717
|
+
sendFileWithRanges(req, res, fullPath, stat.size, {});
|
|
718
|
+
}
|
|
719
|
+
function sendFileWithRanges(req, res, filePath, total, headers) {
|
|
720
|
+
const head = (req?.method || "GET").toUpperCase() === "HEAD";
|
|
721
|
+
const range = /^bytes=(\d*)-(\d*)$/.exec(req?.headers?.range || "");
|
|
722
|
+
const invalid = range && range[1] && range[2] && Number(range[2]) < Number(range[1]);
|
|
723
|
+
if (range && (range[1] || range[2]) && !invalid) {
|
|
724
|
+
const [, startRaw, endRaw] = range;
|
|
725
|
+
const start = startRaw ? Number(startRaw) : Math.max(0, total - Number(endRaw));
|
|
726
|
+
const end = startRaw && endRaw ? Math.min(Number(endRaw), total - 1) : total - 1;
|
|
727
|
+
if (start > end || start >= total) {
|
|
728
|
+
res.writeHead(416, { ...headers, "Content-Range": `bytes */${total}` });
|
|
729
|
+
res.end();
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
res.writeHead(206, {
|
|
733
|
+
...headers,
|
|
734
|
+
"Content-Range": `bytes ${start}-${end}/${total}`,
|
|
735
|
+
"Accept-Ranges": "bytes",
|
|
736
|
+
"Content-Length": String(end - start + 1)
|
|
737
|
+
});
|
|
738
|
+
if (head) res.end();
|
|
739
|
+
else streamFile(res, import_fs.default.createReadStream(filePath, { start, end }));
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
res.writeHead(200, {
|
|
743
|
+
...headers,
|
|
744
|
+
"Accept-Ranges": "bytes",
|
|
745
|
+
"Content-Length": String(total)
|
|
746
|
+
});
|
|
747
|
+
if (head || total === 0) res.end();
|
|
748
|
+
else streamFile(res, import_fs.default.createReadStream(filePath, { start: 0, end: total - 1 }));
|
|
749
|
+
}
|
|
750
|
+
function streamFile(res, stream) {
|
|
751
|
+
stream.on("error", (error) => res.destroy(error));
|
|
752
|
+
stream.pipe(res);
|
|
714
753
|
}
|
|
715
754
|
|
|
716
755
|
// src/metro-plugin.ts
|
package/dist-lib/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
package/dist-lib/render-mode.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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;
|
|
@@ -47,6 +47,161 @@ __export(dev_server_scanner_exports, {
|
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(dev_server_scanner_exports);
|
|
49
49
|
var import_child_process = require("child_process");
|
|
50
|
+
|
|
51
|
+
// ../contrast/src/runtime/process-group.ts
|
|
52
|
+
var import_node_child_process = require("node:child_process");
|
|
53
|
+
|
|
54
|
+
// ../contrast/src/sleep.ts
|
|
55
|
+
function sleep(ms) {
|
|
56
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ../contrast/src/runtime/process-group.ts
|
|
60
|
+
var GRACEFUL_TIMEOUT_MS = 3e3;
|
|
61
|
+
var FORCED_EXIT_TIMEOUT_MS = 1e3;
|
|
62
|
+
function signalProcessGroup(child, signal) {
|
|
63
|
+
if (!child.pid) return;
|
|
64
|
+
try {
|
|
65
|
+
process.kill(-child.pid, signal);
|
|
66
|
+
} catch {
|
|
67
|
+
try {
|
|
68
|
+
process.kill(child.pid, signal);
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function runningPids(pids) {
|
|
74
|
+
return pids.filter((pid) => {
|
|
75
|
+
try {
|
|
76
|
+
process.kill(pid, 0);
|
|
77
|
+
return true;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return error instanceof Error && "code" in error && error.code === "EPERM";
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function groupIsEmpty(pgid) {
|
|
84
|
+
try {
|
|
85
|
+
process.kill(-pgid, 0);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (!(error instanceof Error && "code" in error && error.code === "EPERM"))
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
const result = (0, import_node_child_process.spawnSync)("ps", ["-A", "-o", "pgid=,stat="], {
|
|
91
|
+
encoding: "utf8",
|
|
92
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
93
|
+
});
|
|
94
|
+
if (result.error || result.status !== 0) return false;
|
|
95
|
+
return !result.stdout.split("\n").some((line) => {
|
|
96
|
+
const [group, state] = line.trim().split(/\s+/);
|
|
97
|
+
return Number(group) === pgid && state !== void 0 && !state.startsWith("Z");
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async function waitForExit(pids, pgid, timeoutMs) {
|
|
101
|
+
const deadline = Date.now() + timeoutMs;
|
|
102
|
+
const gone = () => runningPids(pids).length === 0 && groupIsEmpty(pgid);
|
|
103
|
+
while (Date.now() < deadline) {
|
|
104
|
+
if (gone()) return true;
|
|
105
|
+
await sleep(50);
|
|
106
|
+
}
|
|
107
|
+
return gone();
|
|
108
|
+
}
|
|
109
|
+
async function terminateProcessGroup(child, signal = "SIGTERM", gracefulTimeoutMs = GRACEFUL_TIMEOUT_MS) {
|
|
110
|
+
if (!child.pid) {
|
|
111
|
+
try {
|
|
112
|
+
child.kill(signal);
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
signalProcessGroup(child, "SIGSTOP");
|
|
118
|
+
const descendants = /* @__PURE__ */ new Set();
|
|
119
|
+
let parents = [child.pid];
|
|
120
|
+
let inspectionError = null;
|
|
121
|
+
while (parents.length > 0) {
|
|
122
|
+
const result = (0, import_node_child_process.spawnSync)("pgrep", ["-P", parents.join(",")], {
|
|
123
|
+
encoding: "utf8",
|
|
124
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
125
|
+
});
|
|
126
|
+
if (result.error || result.status !== 0 && result.status !== 1) {
|
|
127
|
+
inspectionError = new Error(
|
|
128
|
+
`could not inspect descendants of processes ${parents.join(",")}: ${result.error?.message || result.stderr.trim() || `pgrep exited ${result.status}`}`
|
|
129
|
+
);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const next = [];
|
|
133
|
+
for (const line of result.stdout.split("\n")) {
|
|
134
|
+
const descendantPid = Number(line.trim());
|
|
135
|
+
if (Number.isInteger(descendantPid) && descendantPid > 1 && !descendants.has(descendantPid)) {
|
|
136
|
+
descendants.add(descendantPid);
|
|
137
|
+
next.push(descendantPid);
|
|
138
|
+
try {
|
|
139
|
+
process.kill(descendantPid, "SIGSTOP");
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
parents = next;
|
|
145
|
+
}
|
|
146
|
+
const pids = [child.pid, ...descendants];
|
|
147
|
+
const gracefulDeadline = Date.now() + gracefulTimeoutMs;
|
|
148
|
+
try {
|
|
149
|
+
process.kill(child.pid, signal);
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
signalProcessGroup(child, "SIGCONT");
|
|
153
|
+
for (const pid of descendants) {
|
|
154
|
+
try {
|
|
155
|
+
process.kill(pid, "SIGCONT");
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let rootExited = child.exitCode !== null || child.signalCode !== null;
|
|
160
|
+
if (!rootExited) {
|
|
161
|
+
rootExited = await new Promise((resolveExit) => {
|
|
162
|
+
const onExit = () => {
|
|
163
|
+
clearTimeout(deadlineTimer);
|
|
164
|
+
resolveExit(true);
|
|
165
|
+
};
|
|
166
|
+
const deadlineTimer = setTimeout(
|
|
167
|
+
() => {
|
|
168
|
+
child.removeListener("exit", onExit);
|
|
169
|
+
resolveExit(false);
|
|
170
|
+
},
|
|
171
|
+
Math.max(0, gracefulDeadline - Date.now())
|
|
172
|
+
);
|
|
173
|
+
child.once("exit", onExit);
|
|
174
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
175
|
+
child.removeListener("exit", onExit);
|
|
176
|
+
onExit();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (rootExited) {
|
|
181
|
+
signalProcessGroup(child, signal);
|
|
182
|
+
for (const pid of descendants) {
|
|
183
|
+
try {
|
|
184
|
+
process.kill(pid, signal);
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (await waitForExit(pids, child.pid, Math.max(0, gracefulDeadline - Date.now()))) {
|
|
190
|
+
if (inspectionError) throw inspectionError;
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
for (const pid of pids) {
|
|
194
|
+
try {
|
|
195
|
+
process.kill(pid, "SIGKILL");
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
signalProcessGroup(child, "SIGKILL");
|
|
200
|
+
await waitForExit(pids, child.pid, FORCED_EXIT_TIMEOUT_MS);
|
|
201
|
+
if (inspectionError) throw inspectionError;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// scripts/dev-server-scanner.ts
|
|
50
205
|
var import_promises2 = require("fs/promises");
|
|
51
206
|
var import_http = __toESM(require("http"), 1);
|
|
52
207
|
var import_net = __toESM(require("net"), 1);
|
|
@@ -522,29 +677,51 @@ function optionalDemoAppsSync() {
|
|
|
522
677
|
}
|
|
523
678
|
|
|
524
679
|
// scripts/dev-server-scanner.ts
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
680
|
+
function execGuarded(command, timeout, extra = {}) {
|
|
681
|
+
const maxBuffer = extra.maxBuffer ?? 1024 * 1024;
|
|
682
|
+
return new Promise((resolve2, reject) => {
|
|
683
|
+
const child = (0, import_child_process.spawn)("/bin/sh", ["-c", command], {
|
|
684
|
+
detached: true,
|
|
685
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
686
|
+
});
|
|
687
|
+
let stdout = "";
|
|
688
|
+
let settled = false;
|
|
689
|
+
let killing = false;
|
|
690
|
+
const settle = (err) => {
|
|
691
|
+
if (settled) return;
|
|
692
|
+
settled = true;
|
|
693
|
+
clearTimeout(deadline);
|
|
530
694
|
if (err) reject(err);
|
|
531
695
|
else resolve2({ stdout });
|
|
696
|
+
};
|
|
697
|
+
const killThenSettle = (err) => {
|
|
698
|
+
if (killing) return;
|
|
699
|
+
killing = true;
|
|
700
|
+
clearTimeout(deadline);
|
|
701
|
+
terminateProcessGroup(child, "SIGKILL", 0).finally(() => settle(err));
|
|
702
|
+
};
|
|
703
|
+
const deadline = setTimeout(() => {
|
|
704
|
+
killThenSettle(
|
|
705
|
+
Object.assign(new Error(`\`${command}\` did not exit within ${timeout}ms`), {
|
|
706
|
+
killed: true
|
|
707
|
+
})
|
|
708
|
+
);
|
|
709
|
+
}, timeout);
|
|
710
|
+
child.stdout.setEncoding("utf8");
|
|
711
|
+
child.stdout.on("data", (chunk) => {
|
|
712
|
+
stdout += chunk;
|
|
713
|
+
if (stdout.length > maxBuffer) {
|
|
714
|
+
killThenSettle(new Error(`\`${command}\` exceeded maxBuffer ${maxBuffer}`));
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
child.on("error", (err) => {
|
|
718
|
+
if (!killing) settle(err);
|
|
719
|
+
});
|
|
720
|
+
child.on("close", (code) => {
|
|
721
|
+
if (killing) return;
|
|
722
|
+
settle(code === 0 ? null : new Error(`\`${command}\` exited with ${code}`));
|
|
532
723
|
});
|
|
533
724
|
});
|
|
534
|
-
let deadlineTimer;
|
|
535
|
-
const deadline = new Promise((_resolve, reject) => {
|
|
536
|
-
deadlineTimer = setTimeout(() => {
|
|
537
|
-
child?.kill("SIGKILL");
|
|
538
|
-
const err = new Error(`\`${command}\` did not exit within ${timeout}ms`);
|
|
539
|
-
Object.assign(err, { killed: true });
|
|
540
|
-
reject(err);
|
|
541
|
-
}, timeout + EXEC_EXIT_GRACE_MS);
|
|
542
|
-
});
|
|
543
|
-
try {
|
|
544
|
-
return await Promise.race([ran, deadline]);
|
|
545
|
-
} finally {
|
|
546
|
-
clearTimeout(deadlineTimer);
|
|
547
|
-
}
|
|
548
725
|
}
|
|
549
726
|
var TIMEOUT_MS = 250;
|
|
550
727
|
var MANIFEST_TIMEOUT_MS = 1500;
|
|
@@ -579,6 +756,7 @@ async function tcpPing(port, timeout = TCP_GATE_MS) {
|
|
|
579
756
|
function httpGet(hostname, port, path, method = "GET", timeout = TIMEOUT_MS, headers = {}) {
|
|
580
757
|
return new Promise((resolve2) => {
|
|
581
758
|
let settled = false;
|
|
759
|
+
let killing = false;
|
|
582
760
|
const settle = (value) => {
|
|
583
761
|
if (settled) return;
|
|
584
762
|
settled = true;
|
|
@@ -657,6 +835,21 @@ async function discoverListeningProcesses(excludePorts = []) {
|
|
|
657
835
|
}
|
|
658
836
|
async function scanListeningProcesses(excludePorts = []) {
|
|
659
837
|
const excluded = new Set(excludePorts);
|
|
838
|
+
const listing = await listListenersShared();
|
|
839
|
+
if (listing.state === "could-not-look") return listing;
|
|
840
|
+
return {
|
|
841
|
+
state: "looked",
|
|
842
|
+
processes: listing.processes.filter((p) => acceptPort(p.port, excluded))
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
var inflightListing = null;
|
|
846
|
+
function listListenersShared() {
|
|
847
|
+
inflightListing ??= listListeners().finally(() => {
|
|
848
|
+
inflightListing = null;
|
|
849
|
+
});
|
|
850
|
+
return inflightListing;
|
|
851
|
+
}
|
|
852
|
+
async function listListeners() {
|
|
660
853
|
let timedOut = false;
|
|
661
854
|
try {
|
|
662
855
|
const { stdout } = await execGuarded(
|
|
@@ -668,11 +861,9 @@ async function scanListeningProcesses(excludePorts = []) {
|
|
|
668
861
|
const parts = line.trim().split(/\s+/);
|
|
669
862
|
if (parts.length < 9) continue;
|
|
670
863
|
const pid = Number(parts[1]);
|
|
671
|
-
const
|
|
672
|
-
const m = addr.match(/:(\d+)$/);
|
|
864
|
+
const m = parts[8].match(/:(\d+)$/);
|
|
673
865
|
if (!m) continue;
|
|
674
866
|
const port = Number(m[1]);
|
|
675
|
-
if (!acceptPort(port, excluded)) continue;
|
|
676
867
|
if (!seen.has(port)) seen.set(port, pid);
|
|
677
868
|
}
|
|
678
869
|
return {
|
|
@@ -694,7 +885,6 @@ async function scanListeningProcesses(excludePorts = []) {
|
|
|
694
885
|
if (!portMatch) continue;
|
|
695
886
|
const port = Number(portMatch[1]);
|
|
696
887
|
const pid = pidMatch ? Number(pidMatch[1]) : 0;
|
|
697
|
-
if (!acceptPort(port, excluded)) continue;
|
|
698
888
|
if (!seen.has(port)) seen.set(port, pid);
|
|
699
889
|
}
|
|
700
890
|
return {
|
|
@@ -705,10 +895,7 @@ async function scanListeningProcesses(excludePorts = []) {
|
|
|
705
895
|
if (wasKilledByTimeout(err)) timedOut = true;
|
|
706
896
|
}
|
|
707
897
|
if (timedOut) return { state: "could-not-look" };
|
|
708
|
-
return {
|
|
709
|
-
state: "looked",
|
|
710
|
-
processes: FALLBACK_PORTS.filter((p) => acceptPort(p.port, excluded))
|
|
711
|
-
};
|
|
898
|
+
return { state: "looked", processes: FALLBACK_PORTS };
|
|
712
899
|
}
|
|
713
900
|
async function discoverListeningPorts(excludePorts = []) {
|
|
714
901
|
const processes = await discoverListeningProcesses(excludePorts);
|
package/dist-lib/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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 __defProp = Object.defineProperty;
|
package/dist-lib/sdk.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.628 | (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);
|