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/src/capture-contract.ts
CHANGED
|
@@ -318,6 +318,146 @@ export function rnxCaptureRasterRegions(
|
|
|
318
318
|
})
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
+
/** a region request snapped to the surface pixel grid and placed in the atlas */
|
|
322
|
+
export interface RnxPackedCaptureRegion extends RnxCaptureRegionRequest {
|
|
323
|
+
/** top-left of the region on the app surface, in pixels */
|
|
324
|
+
sourceX: number
|
|
325
|
+
sourceY: number
|
|
326
|
+
pixelWidth: number
|
|
327
|
+
pixelHeight: number
|
|
328
|
+
/** top-left of the region inside the atlas, in pixels */
|
|
329
|
+
atlasX: number
|
|
330
|
+
atlasY: number
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export interface RnxPackedCaptureAtlas {
|
|
334
|
+
/** logical atlas dimensions; pixel dimensions are these times the pixel ratio */
|
|
335
|
+
width: number
|
|
336
|
+
height: number
|
|
337
|
+
pixelWidth: number
|
|
338
|
+
pixelHeight: number
|
|
339
|
+
regions: RnxPackedCaptureRegion[]
|
|
340
|
+
/** the wire regions a producer publishes beside the encoded atlas */
|
|
341
|
+
atlasRegions: RnxCaptureAtlasRegion[]
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// the bounded selective-layer atlas every producer ships: regions snapped to
|
|
345
|
+
// whole surface pixels, shelf-packed into the smallest of a few candidate
|
|
346
|
+
// widths, and mapped back to logical atlas coordinates. one packer for the
|
|
347
|
+
// headless renderer (which draws isolated subtrees into the slots) and the
|
|
348
|
+
// browser producer (which crops them out of a screen-sized screenshot), so a
|
|
349
|
+
// consumer never learns which one made the artifact from the layout.
|
|
350
|
+
export function packRnxCaptureRegions(
|
|
351
|
+
regions: readonly RnxCaptureRegionRequest[],
|
|
352
|
+
pixelRatio: number,
|
|
353
|
+
surface: { pixelWidth: number; pixelHeight: number },
|
|
354
|
+
): RnxPackedCaptureAtlas {
|
|
355
|
+
const physical = regions.map((region) => {
|
|
356
|
+
const left = Math.floor(region.frame.x * pixelRatio)
|
|
357
|
+
const top = Math.floor(region.frame.y * pixelRatio)
|
|
358
|
+
const right = Math.ceil((region.frame.x + region.frame.width) * pixelRatio)
|
|
359
|
+
const bottom = Math.ceil((region.frame.y + region.frame.height) * pixelRatio)
|
|
360
|
+
if (
|
|
361
|
+
left < 0 ||
|
|
362
|
+
top < 0 ||
|
|
363
|
+
right > surface.pixelWidth ||
|
|
364
|
+
bottom > surface.pixelHeight ||
|
|
365
|
+
right <= left ||
|
|
366
|
+
bottom <= top
|
|
367
|
+
) {
|
|
368
|
+
throw new Error(`capture region ${region.key} is outside the app surface`)
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
key: region.key,
|
|
372
|
+
nodeId: region.nodeId,
|
|
373
|
+
frame: {
|
|
374
|
+
x: left / pixelRatio,
|
|
375
|
+
y: top / pixelRatio,
|
|
376
|
+
width: (right - left) / pixelRatio,
|
|
377
|
+
height: (bottom - top) / pixelRatio,
|
|
378
|
+
},
|
|
379
|
+
sourceX: left,
|
|
380
|
+
sourceY: top,
|
|
381
|
+
pixelWidth: right - left,
|
|
382
|
+
pixelHeight: bottom - top,
|
|
383
|
+
}
|
|
384
|
+
})
|
|
385
|
+
const largestWidth = Math.max(...physical.map((region) => region.pixelWidth))
|
|
386
|
+
const totalArea = physical.reduce(
|
|
387
|
+
(area, region) => area + region.pixelWidth * region.pixelHeight,
|
|
388
|
+
0,
|
|
389
|
+
)
|
|
390
|
+
if (totalArea > 4_194_304) {
|
|
391
|
+
throw new Error('capture region pixels exceed the atlas budget')
|
|
392
|
+
}
|
|
393
|
+
const candidates = [
|
|
394
|
+
largestWidth,
|
|
395
|
+
Math.max(largestWidth, Math.ceil(Math.sqrt(totalArea))),
|
|
396
|
+
Math.max(largestWidth, surface.pixelWidth),
|
|
397
|
+
4_096,
|
|
398
|
+
]
|
|
399
|
+
const ordered = [...physical].sort(
|
|
400
|
+
(left, right) =>
|
|
401
|
+
right.pixelHeight - left.pixelHeight ||
|
|
402
|
+
right.pixelWidth - left.pixelWidth ||
|
|
403
|
+
left.key.localeCompare(right.key),
|
|
404
|
+
)
|
|
405
|
+
let best: { width: number; height: number; regions: RnxPackedCaptureRegion[] } | null =
|
|
406
|
+
null
|
|
407
|
+
for (const candidate of [...new Set(candidates)]) {
|
|
408
|
+
if (candidate > 4_096) continue
|
|
409
|
+
let x = 0
|
|
410
|
+
let y = 0
|
|
411
|
+
let rowHeight = 0
|
|
412
|
+
let usedWidth = 0
|
|
413
|
+
const packed: RnxPackedCaptureRegion[] = []
|
|
414
|
+
for (const region of ordered) {
|
|
415
|
+
if (x > 0 && x + region.pixelWidth > candidate) {
|
|
416
|
+
y += rowHeight
|
|
417
|
+
x = 0
|
|
418
|
+
rowHeight = 0
|
|
419
|
+
}
|
|
420
|
+
packed.push({ ...region, atlasX: x, atlasY: y })
|
|
421
|
+
x += region.pixelWidth
|
|
422
|
+
rowHeight = Math.max(rowHeight, region.pixelHeight)
|
|
423
|
+
usedWidth = Math.max(usedWidth, x)
|
|
424
|
+
}
|
|
425
|
+
const height = y + rowHeight
|
|
426
|
+
if (height > 4_096 || usedWidth * height > 4_194_304) continue
|
|
427
|
+
const result = { width: usedWidth, height, regions: packed }
|
|
428
|
+
if (!best || result.width * result.height < best.width * best.height) best = result
|
|
429
|
+
}
|
|
430
|
+
if (!best) throw new Error('capture regions cannot fit in one bounded atlas')
|
|
431
|
+
const width = best.width / pixelRatio
|
|
432
|
+
const height = best.height / pixelRatio
|
|
433
|
+
return {
|
|
434
|
+
width,
|
|
435
|
+
height,
|
|
436
|
+
pixelWidth: best.width,
|
|
437
|
+
pixelHeight: best.height,
|
|
438
|
+
regions: best.regions,
|
|
439
|
+
atlasRegions: best.regions.map((region) => ({
|
|
440
|
+
key: region.key,
|
|
441
|
+
nodeId: region.nodeId,
|
|
442
|
+
frame: region.frame,
|
|
443
|
+
// a region flush with the far edge is anchored to the logical edge so
|
|
444
|
+
// its source never runs past the atlas by a rounding hair
|
|
445
|
+
source: {
|
|
446
|
+
x:
|
|
447
|
+
region.atlasX + region.pixelWidth === best.width
|
|
448
|
+
? width - region.frame.width
|
|
449
|
+
: region.atlasX / pixelRatio,
|
|
450
|
+
y:
|
|
451
|
+
region.atlasY + region.pixelHeight === best.height
|
|
452
|
+
? height - region.frame.height
|
|
453
|
+
: region.atlasY / pixelRatio,
|
|
454
|
+
width: region.frame.width,
|
|
455
|
+
height: region.frame.height,
|
|
456
|
+
},
|
|
457
|
+
})),
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
321
461
|
export interface RnxCaptureAtlasRegion extends RnxCaptureRegionRequest {
|
|
322
462
|
/** source rectangle inside the packed atlas, in logical atlas coordinates */
|
|
323
463
|
source: RnxCaptureRect
|
|
@@ -325,7 +465,7 @@ export interface RnxCaptureAtlasRegion extends RnxCaptureRegionRequest {
|
|
|
325
465
|
|
|
326
466
|
export interface RnxCaptureRegionAtlas {
|
|
327
467
|
kind: 'png-atlas'
|
|
328
|
-
producer: 'headless-cpu-app-surface'
|
|
468
|
+
producer: 'headless-cpu-app-surface' | 'browser-compositor-app-surface'
|
|
329
469
|
dataUri: string
|
|
330
470
|
/** logical atlas dimensions; the encoded PNG uses pixelWidth × pixelHeight */
|
|
331
471
|
width: number
|
|
@@ -533,7 +673,8 @@ export function isRnxCaptureRegionAtlas(value: unknown): value is RnxCaptureRegi
|
|
|
533
673
|
if (
|
|
534
674
|
!captureRecord(value) ||
|
|
535
675
|
value.kind !== 'png-atlas' ||
|
|
536
|
-
value.producer !== 'headless-cpu-app-surface'
|
|
676
|
+
(value.producer !== 'headless-cpu-app-surface' &&
|
|
677
|
+
value.producer !== 'browser-compositor-app-surface') ||
|
|
537
678
|
typeof value.dataUri !== 'string' ||
|
|
538
679
|
!value.dataUri.startsWith('data:image/png;base64,') ||
|
|
539
680
|
!captureNumber(value.width) ||
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export {
|
|
|
39
39
|
isRnxCaptureRegionAtlas,
|
|
40
40
|
isRnxScreenCapture,
|
|
41
41
|
rnxCaptureRasterRegions,
|
|
42
|
+
packRnxCaptureRegions,
|
|
42
43
|
rnxRasterFrames,
|
|
43
44
|
RNX_SCREEN_CAPTURE_VERSION,
|
|
44
45
|
selectRnxRasterNodeIds,
|
|
@@ -54,6 +55,8 @@ export {
|
|
|
54
55
|
type RnxCaptureSource,
|
|
55
56
|
type RnxCaptureStyleTokenBinding,
|
|
56
57
|
type RnxCaptureTextLine,
|
|
58
|
+
type RnxPackedCaptureAtlas,
|
|
59
|
+
type RnxPackedCaptureRegion,
|
|
57
60
|
type RnxCaptureTextSegment,
|
|
58
61
|
type RnxCaptureTree,
|
|
59
62
|
type RnxCaptureVisualEvidence,
|