rnxsim 0.1.543 → 0.1.545
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/commands/control.ts +8 -2
- package/cli/commands/inspect/wait-selector.ts +12 -2
- package/cli/outbound-endpoints.ts +5 -0
- 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 +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +93 -2
- package/dist-lib/capture-contract.mjs +92 -2
- 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.cjs +1 -1
- package/dist-lib/cloud.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 +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +29 -14
- 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 +93 -2
- 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 +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 +1 -1
- 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 +30 -14
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +30 -15
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +40 -13
- package/src/capture-contract.ts +143 -2
- package/src/index.ts +3 -0
package/cli/commands/control.ts
CHANGED
|
@@ -425,14 +425,20 @@ async function resolveConnectionInputForCli(target: string): Promise<ResolvedDev
|
|
|
425
425
|
try {
|
|
426
426
|
return await resolveConnectionInput(normalized)
|
|
427
427
|
} catch (error) {
|
|
428
|
-
if (
|
|
428
|
+
if (
|
|
429
|
+
!(error instanceof Error) ||
|
|
430
|
+
!error.message.startsWith('could not resolve a native bundle')
|
|
431
|
+
) {
|
|
429
432
|
throw error
|
|
430
433
|
}
|
|
431
434
|
lastError = error
|
|
432
435
|
}
|
|
433
436
|
await sleep(DEV_BUNDLE_RESOLVE_INTERVAL_MS)
|
|
434
437
|
}
|
|
435
|
-
throw
|
|
438
|
+
throw (
|
|
439
|
+
lastError ??
|
|
440
|
+
new Error('could not resolve a native bundle for ' + normalized + ' after retrying.')
|
|
441
|
+
)
|
|
436
442
|
}
|
|
437
443
|
|
|
438
444
|
function getShellRoutePrefix(pathname: string): string {
|
|
@@ -19,13 +19,23 @@ export async function runWaitSelectorSubcommand(opts: {
|
|
|
19
19
|
const testId = positional[1]
|
|
20
20
|
if (!testId) {
|
|
21
21
|
console.error(
|
|
22
|
-
inspectUsage(
|
|
22
|
+
inspectUsage(
|
|
23
|
+
'selector',
|
|
24
|
+
'<testid> [--max-ms 5000 | --timeout 5000] [--gone] [--structural]',
|
|
25
|
+
),
|
|
23
26
|
)
|
|
24
27
|
rnxExit(1)
|
|
25
28
|
}
|
|
29
|
+
// the wait budget. `--max-ms` names it, and `--timeout` (the global
|
|
30
|
+
// per-command budget) means the same thing for a command whose whole job is
|
|
31
|
+
// to wait — without this it parsed away and the wait silently stayed at 5s,
|
|
32
|
+
// reporting a false timeout.
|
|
26
33
|
const maxMsIdx = args.indexOf('--max-ms')
|
|
34
|
+
const budgetIdx = maxMsIdx >= 0 ? maxMsIdx : args.indexOf('--timeout')
|
|
27
35
|
const timeoutMs =
|
|
28
|
-
|
|
36
|
+
budgetIdx >= 0 && args[budgetIdx + 1]
|
|
37
|
+
? Math.max(100, Number(args[budgetIdx + 1]))
|
|
38
|
+
: 5000
|
|
29
39
|
const gone = args.includes('--gone')
|
|
30
40
|
const structural = args.includes('--structural')
|
|
31
41
|
|
|
@@ -277,6 +277,11 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
|
|
|
277
277
|
{ category: 'contrast_user_action', count: 1 },
|
|
278
278
|
'packages/rnx-cloud-box/src/box-do.ts :: fetch :: `${origin}/api/v1/rnx/sessions/internal/${encodeURIComponent()}`':
|
|
279
279
|
{ category: 'contrast_user_action', count: 1 },
|
|
280
|
+
// stop and delete authorize the caller against the account before any
|
|
281
|
+
// teardown. the account service owns the verdict on a key, its scope and the
|
|
282
|
+
// account it names; no project content is sent.
|
|
283
|
+
'packages/rnx-cloud-box/src/box-do.ts :: fetch :: `${origin}/api/v1/rnx/sessions?accountId=${encodeURIComponent()}&kind=box&status=running`':
|
|
284
|
+
{ category: 'contrast_user_action', count: 1 },
|
|
280
285
|
// the Cloudflare Worker forwards the already-authenticated request to the
|
|
281
286
|
// selected Durable Object in the same service.
|
|
282
287
|
'packages/rnx-cloud-box/src/worker.ts :: fetch :: request': {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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.545 | (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.545 | (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.545 | (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.545 | (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.545 | (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/beta.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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/beta.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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.545 | (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.545 | (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;
|
|
@@ -25,6 +25,7 @@ __export(capture_contract_exports, {
|
|
|
25
25
|
RNX_SCREEN_CAPTURE_VERSION: () => RNX_SCREEN_CAPTURE_VERSION,
|
|
26
26
|
isRnxCaptureRegionAtlas: () => isRnxCaptureRegionAtlas,
|
|
27
27
|
isRnxScreenCapture: () => isRnxScreenCapture,
|
|
28
|
+
packRnxCaptureRegions: () => packRnxCaptureRegions,
|
|
28
29
|
rnxCaptureRasterRegions: () => rnxCaptureRasterRegions,
|
|
29
30
|
rnxRasterFrames: () => rnxRasterFrames,
|
|
30
31
|
selectRnxRasterNodeIds: () => selectRnxRasterNodeIds
|
|
@@ -138,6 +139,95 @@ function rnxCaptureRasterRegions(capture) {
|
|
|
138
139
|
return frame ? [{ key: String(nodeId), nodeId, frame }] : [];
|
|
139
140
|
});
|
|
140
141
|
}
|
|
142
|
+
function packRnxCaptureRegions(regions, pixelRatio, surface) {
|
|
143
|
+
const physical = regions.map((region) => {
|
|
144
|
+
const left = Math.floor(region.frame.x * pixelRatio);
|
|
145
|
+
const top = Math.floor(region.frame.y * pixelRatio);
|
|
146
|
+
const right = Math.ceil((region.frame.x + region.frame.width) * pixelRatio);
|
|
147
|
+
const bottom = Math.ceil((region.frame.y + region.frame.height) * pixelRatio);
|
|
148
|
+
if (left < 0 || top < 0 || right > surface.pixelWidth || bottom > surface.pixelHeight || right <= left || bottom <= top) {
|
|
149
|
+
throw new Error(`capture region ${region.key} is outside the app surface`);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
key: region.key,
|
|
153
|
+
nodeId: region.nodeId,
|
|
154
|
+
frame: {
|
|
155
|
+
x: left / pixelRatio,
|
|
156
|
+
y: top / pixelRatio,
|
|
157
|
+
width: (right - left) / pixelRatio,
|
|
158
|
+
height: (bottom - top) / pixelRatio
|
|
159
|
+
},
|
|
160
|
+
sourceX: left,
|
|
161
|
+
sourceY: top,
|
|
162
|
+
pixelWidth: right - left,
|
|
163
|
+
pixelHeight: bottom - top
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
const largestWidth = Math.max(...physical.map((region) => region.pixelWidth));
|
|
167
|
+
const totalArea = physical.reduce(
|
|
168
|
+
(area, region) => area + region.pixelWidth * region.pixelHeight,
|
|
169
|
+
0
|
|
170
|
+
);
|
|
171
|
+
if (totalArea > 4194304) {
|
|
172
|
+
throw new Error("capture region pixels exceed the atlas budget");
|
|
173
|
+
}
|
|
174
|
+
const candidates = [
|
|
175
|
+
largestWidth,
|
|
176
|
+
Math.max(largestWidth, Math.ceil(Math.sqrt(totalArea))),
|
|
177
|
+
Math.max(largestWidth, surface.pixelWidth),
|
|
178
|
+
4096
|
|
179
|
+
];
|
|
180
|
+
const ordered = [...physical].sort(
|
|
181
|
+
(left, right) => right.pixelHeight - left.pixelHeight || right.pixelWidth - left.pixelWidth || left.key.localeCompare(right.key)
|
|
182
|
+
);
|
|
183
|
+
let best = null;
|
|
184
|
+
for (const candidate of [...new Set(candidates)]) {
|
|
185
|
+
if (candidate > 4096) continue;
|
|
186
|
+
let x = 0;
|
|
187
|
+
let y = 0;
|
|
188
|
+
let rowHeight = 0;
|
|
189
|
+
let usedWidth = 0;
|
|
190
|
+
const packed = [];
|
|
191
|
+
for (const region of ordered) {
|
|
192
|
+
if (x > 0 && x + region.pixelWidth > candidate) {
|
|
193
|
+
y += rowHeight;
|
|
194
|
+
x = 0;
|
|
195
|
+
rowHeight = 0;
|
|
196
|
+
}
|
|
197
|
+
packed.push({ ...region, atlasX: x, atlasY: y });
|
|
198
|
+
x += region.pixelWidth;
|
|
199
|
+
rowHeight = Math.max(rowHeight, region.pixelHeight);
|
|
200
|
+
usedWidth = Math.max(usedWidth, x);
|
|
201
|
+
}
|
|
202
|
+
const height2 = y + rowHeight;
|
|
203
|
+
if (height2 > 4096 || usedWidth * height2 > 4194304) continue;
|
|
204
|
+
const result = { width: usedWidth, height: height2, regions: packed };
|
|
205
|
+
if (!best || result.width * result.height < best.width * best.height) best = result;
|
|
206
|
+
}
|
|
207
|
+
if (!best) throw new Error("capture regions cannot fit in one bounded atlas");
|
|
208
|
+
const width = best.width / pixelRatio;
|
|
209
|
+
const height = best.height / pixelRatio;
|
|
210
|
+
return {
|
|
211
|
+
width,
|
|
212
|
+
height,
|
|
213
|
+
pixelWidth: best.width,
|
|
214
|
+
pixelHeight: best.height,
|
|
215
|
+
regions: best.regions,
|
|
216
|
+
atlasRegions: best.regions.map((region) => ({
|
|
217
|
+
key: region.key,
|
|
218
|
+
nodeId: region.nodeId,
|
|
219
|
+
frame: region.frame,
|
|
220
|
+
// a region flush with the far edge is anchored to the logical edge so
|
|
221
|
+
// its source never runs past the atlas by a rounding hair
|
|
222
|
+
source: {
|
|
223
|
+
x: region.atlasX + region.pixelWidth === best.width ? width - region.frame.width : region.atlasX / pixelRatio,
|
|
224
|
+
y: region.atlasY + region.pixelHeight === best.height ? height - region.frame.height : region.atlasY / pixelRatio,
|
|
225
|
+
width: region.frame.width,
|
|
226
|
+
height: region.frame.height
|
|
227
|
+
}
|
|
228
|
+
}))
|
|
229
|
+
};
|
|
230
|
+
}
|
|
141
231
|
function captureRecord(value) {
|
|
142
232
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
143
233
|
}
|
|
@@ -193,7 +283,7 @@ function isRnxScreenCapture(value) {
|
|
|
193
283
|
return captureRecord(tree.viewport) && captureInteger(tree.viewport.width) && tree.viewport.width > 0 && captureInteger(tree.viewport.height) && tree.viewport.height > 0 && captureInteger(tree.rootNodeId) && (tree.commitRevision === void 0 || captureInteger(tree.commitRevision)) && Array.isArray(tree.nodes) && tree.nodes.every(captureNode) && (visual === void 0 || visual.kind === "png" && (visual.producer === "headless-cpu-app-surface" || visual.producer === "browser-compositor-app-surface") && typeof visual.dataUri === "string" && visual.dataUri.startsWith("data:image/png;base64,") && captureInteger(visual.pixelWidth) && visual.pixelWidth > 0 && captureInteger(visual.pixelHeight) && visual.pixelHeight > 0);
|
|
194
284
|
}
|
|
195
285
|
function isRnxCaptureRegionAtlas(value) {
|
|
196
|
-
if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
|
|
286
|
+
if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" && value.producer !== "browser-compositor-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
|
|
197
287
|
return false;
|
|
198
288
|
}
|
|
199
289
|
const scale = value.pixelWidth / value.width;
|
|
@@ -214,6 +304,7 @@ function isRnxCaptureRegionAtlas(value) {
|
|
|
214
304
|
RNX_SCREEN_CAPTURE_VERSION,
|
|
215
305
|
isRnxCaptureRegionAtlas,
|
|
216
306
|
isRnxScreenCapture,
|
|
307
|
+
packRnxCaptureRegions,
|
|
217
308
|
rnxCaptureRasterRegions,
|
|
218
309
|
rnxRasterFrames,
|
|
219
310
|
selectRnxRasterNodeIds
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/capture-contract.ts
|
|
4
4
|
var RNX_SCREEN_CAPTURE_VERSION = 1;
|
|
@@ -109,6 +109,95 @@ function rnxCaptureRasterRegions(capture) {
|
|
|
109
109
|
return frame ? [{ key: String(nodeId), nodeId, frame }] : [];
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
+
function packRnxCaptureRegions(regions, pixelRatio, surface) {
|
|
113
|
+
const physical = regions.map((region) => {
|
|
114
|
+
const left = Math.floor(region.frame.x * pixelRatio);
|
|
115
|
+
const top = Math.floor(region.frame.y * pixelRatio);
|
|
116
|
+
const right = Math.ceil((region.frame.x + region.frame.width) * pixelRatio);
|
|
117
|
+
const bottom = Math.ceil((region.frame.y + region.frame.height) * pixelRatio);
|
|
118
|
+
if (left < 0 || top < 0 || right > surface.pixelWidth || bottom > surface.pixelHeight || right <= left || bottom <= top) {
|
|
119
|
+
throw new Error(`capture region ${region.key} is outside the app surface`);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
key: region.key,
|
|
123
|
+
nodeId: region.nodeId,
|
|
124
|
+
frame: {
|
|
125
|
+
x: left / pixelRatio,
|
|
126
|
+
y: top / pixelRatio,
|
|
127
|
+
width: (right - left) / pixelRatio,
|
|
128
|
+
height: (bottom - top) / pixelRatio
|
|
129
|
+
},
|
|
130
|
+
sourceX: left,
|
|
131
|
+
sourceY: top,
|
|
132
|
+
pixelWidth: right - left,
|
|
133
|
+
pixelHeight: bottom - top
|
|
134
|
+
};
|
|
135
|
+
});
|
|
136
|
+
const largestWidth = Math.max(...physical.map((region) => region.pixelWidth));
|
|
137
|
+
const totalArea = physical.reduce(
|
|
138
|
+
(area, region) => area + region.pixelWidth * region.pixelHeight,
|
|
139
|
+
0
|
|
140
|
+
);
|
|
141
|
+
if (totalArea > 4194304) {
|
|
142
|
+
throw new Error("capture region pixels exceed the atlas budget");
|
|
143
|
+
}
|
|
144
|
+
const candidates = [
|
|
145
|
+
largestWidth,
|
|
146
|
+
Math.max(largestWidth, Math.ceil(Math.sqrt(totalArea))),
|
|
147
|
+
Math.max(largestWidth, surface.pixelWidth),
|
|
148
|
+
4096
|
|
149
|
+
];
|
|
150
|
+
const ordered = [...physical].sort(
|
|
151
|
+
(left, right) => right.pixelHeight - left.pixelHeight || right.pixelWidth - left.pixelWidth || left.key.localeCompare(right.key)
|
|
152
|
+
);
|
|
153
|
+
let best = null;
|
|
154
|
+
for (const candidate of [...new Set(candidates)]) {
|
|
155
|
+
if (candidate > 4096) continue;
|
|
156
|
+
let x = 0;
|
|
157
|
+
let y = 0;
|
|
158
|
+
let rowHeight = 0;
|
|
159
|
+
let usedWidth = 0;
|
|
160
|
+
const packed = [];
|
|
161
|
+
for (const region of ordered) {
|
|
162
|
+
if (x > 0 && x + region.pixelWidth > candidate) {
|
|
163
|
+
y += rowHeight;
|
|
164
|
+
x = 0;
|
|
165
|
+
rowHeight = 0;
|
|
166
|
+
}
|
|
167
|
+
packed.push({ ...region, atlasX: x, atlasY: y });
|
|
168
|
+
x += region.pixelWidth;
|
|
169
|
+
rowHeight = Math.max(rowHeight, region.pixelHeight);
|
|
170
|
+
usedWidth = Math.max(usedWidth, x);
|
|
171
|
+
}
|
|
172
|
+
const height2 = y + rowHeight;
|
|
173
|
+
if (height2 > 4096 || usedWidth * height2 > 4194304) continue;
|
|
174
|
+
const result = { width: usedWidth, height: height2, regions: packed };
|
|
175
|
+
if (!best || result.width * result.height < best.width * best.height) best = result;
|
|
176
|
+
}
|
|
177
|
+
if (!best) throw new Error("capture regions cannot fit in one bounded atlas");
|
|
178
|
+
const width = best.width / pixelRatio;
|
|
179
|
+
const height = best.height / pixelRatio;
|
|
180
|
+
return {
|
|
181
|
+
width,
|
|
182
|
+
height,
|
|
183
|
+
pixelWidth: best.width,
|
|
184
|
+
pixelHeight: best.height,
|
|
185
|
+
regions: best.regions,
|
|
186
|
+
atlasRegions: best.regions.map((region) => ({
|
|
187
|
+
key: region.key,
|
|
188
|
+
nodeId: region.nodeId,
|
|
189
|
+
frame: region.frame,
|
|
190
|
+
// a region flush with the far edge is anchored to the logical edge so
|
|
191
|
+
// its source never runs past the atlas by a rounding hair
|
|
192
|
+
source: {
|
|
193
|
+
x: region.atlasX + region.pixelWidth === best.width ? width - region.frame.width : region.atlasX / pixelRatio,
|
|
194
|
+
y: region.atlasY + region.pixelHeight === best.height ? height - region.frame.height : region.atlasY / pixelRatio,
|
|
195
|
+
width: region.frame.width,
|
|
196
|
+
height: region.frame.height
|
|
197
|
+
}
|
|
198
|
+
}))
|
|
199
|
+
};
|
|
200
|
+
}
|
|
112
201
|
function captureRecord(value) {
|
|
113
202
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
114
203
|
}
|
|
@@ -164,7 +253,7 @@ function isRnxScreenCapture(value) {
|
|
|
164
253
|
return captureRecord(tree.viewport) && captureInteger(tree.viewport.width) && tree.viewport.width > 0 && captureInteger(tree.viewport.height) && tree.viewport.height > 0 && captureInteger(tree.rootNodeId) && (tree.commitRevision === void 0 || captureInteger(tree.commitRevision)) && Array.isArray(tree.nodes) && tree.nodes.every(captureNode) && (visual === void 0 || visual.kind === "png" && (visual.producer === "headless-cpu-app-surface" || visual.producer === "browser-compositor-app-surface") && typeof visual.dataUri === "string" && visual.dataUri.startsWith("data:image/png;base64,") && captureInteger(visual.pixelWidth) && visual.pixelWidth > 0 && captureInteger(visual.pixelHeight) && visual.pixelHeight > 0);
|
|
165
254
|
}
|
|
166
255
|
function isRnxCaptureRegionAtlas(value) {
|
|
167
|
-
if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
|
|
256
|
+
if (!captureRecord(value) || value.kind !== "png-atlas" || value.producer !== "headless-cpu-app-surface" && value.producer !== "browser-compositor-app-surface" || typeof value.dataUri !== "string" || !value.dataUri.startsWith("data:image/png;base64,") || !captureNumber(value.width) || value.width <= 0 || !captureNumber(value.height) || value.height <= 0 || !captureInteger(value.pixelWidth) || value.pixelWidth <= 0 || !captureInteger(value.pixelHeight) || value.pixelHeight <= 0 || !Array.isArray(value.regions) || value.regions.length === 0 || value.regions.length > 256) {
|
|
168
257
|
return false;
|
|
169
258
|
}
|
|
170
259
|
const scale = value.pixelWidth / value.width;
|
|
@@ -184,6 +273,7 @@ export {
|
|
|
184
273
|
RNX_SCREEN_CAPTURE_VERSION,
|
|
185
274
|
isRnxCaptureRegionAtlas,
|
|
186
275
|
isRnxScreenCapture,
|
|
276
|
+
packRnxCaptureRegions,
|
|
187
277
|
rnxCaptureRasterRegions,
|
|
188
278
|
rnxRasterFrames,
|
|
189
279
|
selectRnxRasterNodeIds
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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/cloud.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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/cloud.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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);
|
package/dist-lib/config.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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/detox/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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/home-paths.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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;
|
|
@@ -5098,7 +5098,7 @@ async function resolveLocalIconPath(hostname, port, rawIcon) {
|
|
|
5098
5098
|
const res = await httpGet(hostname, port, candidate, "HEAD", ENRICH_TIMEOUT_MS);
|
|
5099
5099
|
if (res?.statusCode === 200) {
|
|
5100
5100
|
localIconPathCache.set(port, candidate);
|
|
5101
|
-
|
|
5101
|
+
invalidatePortCache(port);
|
|
5102
5102
|
return;
|
|
5103
5103
|
}
|
|
5104
5104
|
}
|
|
@@ -5220,7 +5220,7 @@ async function fetchManifestEnrichment(result, buildIconProxyUrl) {
|
|
|
5220
5220
|
iconPath: parsed.iconPath,
|
|
5221
5221
|
bundleId: parsed.bundleId
|
|
5222
5222
|
});
|
|
5223
|
-
|
|
5223
|
+
invalidatePortCache(result.port);
|
|
5224
5224
|
}
|
|
5225
5225
|
var knownNonPatched = /* @__PURE__ */ new Set();
|
|
5226
5226
|
var knownNonExpo = /* @__PURE__ */ new Set();
|
|
@@ -5260,16 +5260,19 @@ async function probePort(port, buildIconProxyUrl, listeningProcess) {
|
|
|
5260
5260
|
const framework = launchUrl2.includes(
|
|
5261
5261
|
"/one/metro-entry.bundle"
|
|
5262
5262
|
) ? "one" : "expo";
|
|
5263
|
-
return
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5263
|
+
return enrichWithManifest(
|
|
5264
|
+
applyManifest(
|
|
5265
|
+
{
|
|
5266
|
+
port,
|
|
5267
|
+
framework,
|
|
5268
|
+
bundleUrl: withRuntimeConfig(port, launchUrl2, owner.cwd),
|
|
5269
|
+
hmrUrl: `${buildLoopbackProbeBaseUrl("ws:", probeHostname, port)}/hot`,
|
|
5270
|
+
lastSeen: Date.now(),
|
|
5271
|
+
...owner
|
|
5272
|
+
},
|
|
5273
|
+
manifestRes,
|
|
5274
|
+
buildIconProxyUrl
|
|
5275
|
+
),
|
|
5273
5276
|
buildIconProxyUrl
|
|
5274
5277
|
);
|
|
5275
5278
|
}
|
|
@@ -5347,6 +5350,11 @@ function isSootSimSelfServer(server) {
|
|
|
5347
5350
|
return false;
|
|
5348
5351
|
}
|
|
5349
5352
|
var portCache = /* @__PURE__ */ new Map();
|
|
5353
|
+
var portCacheInvalidatedAt = /* @__PURE__ */ new Map();
|
|
5354
|
+
function invalidatePortCache(port) {
|
|
5355
|
+
portCache.delete(port);
|
|
5356
|
+
portCacheInvalidatedAt.set(port, Date.now());
|
|
5357
|
+
}
|
|
5350
5358
|
var NEGATIVE_CACHE_TTL_MS = 3e4;
|
|
5351
5359
|
var WEAK_RESULT_CACHE_TTL_MS = 1500;
|
|
5352
5360
|
function isWeakCachedResult(result) {
|
|
@@ -5401,6 +5409,9 @@ async function scanDevServers(opts = {}) {
|
|
|
5401
5409
|
for (const p of [...localIconPathCache.keys()]) {
|
|
5402
5410
|
if (!currentPorts.has(p)) localIconPathCache.delete(p);
|
|
5403
5411
|
}
|
|
5412
|
+
for (const p of [...portCacheInvalidatedAt.keys()]) {
|
|
5413
|
+
if (!currentPorts.has(p)) portCacheInvalidatedAt.delete(p);
|
|
5414
|
+
}
|
|
5404
5415
|
const results = [];
|
|
5405
5416
|
const toProbe = [];
|
|
5406
5417
|
for (const { port, pid } of processes) {
|
|
@@ -5419,12 +5430,16 @@ async function scanDevServers(opts = {}) {
|
|
|
5419
5430
|
toProbe.push({ port, pid });
|
|
5420
5431
|
}
|
|
5421
5432
|
if (toProbe.length > 0) {
|
|
5433
|
+
const scanStartedAt = Date.now();
|
|
5422
5434
|
const probed = await Promise.all(
|
|
5423
5435
|
toProbe.map((p) => probePort(p.port, opts.buildIconProxyUrl, p))
|
|
5424
5436
|
);
|
|
5425
5437
|
probed.forEach((result, i) => {
|
|
5426
5438
|
const { port, pid } = toProbe[i];
|
|
5427
|
-
|
|
5439
|
+
const invalidatedAt = portCacheInvalidatedAt.get(port) ?? 0;
|
|
5440
|
+
if (pid !== 0 && invalidatedAt < scanStartedAt) {
|
|
5441
|
+
portCache.set(port, { pid, result, cachedAt: Date.now() });
|
|
5442
|
+
}
|
|
5428
5443
|
if (result) results.push(result);
|
|
5429
5444
|
});
|
|
5430
5445
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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.545 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/host/fetch-proxy-overrides.ts
|
|
4
4
|
var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.545 | (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.545 | (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;
|