rnxsim 0.1.459 → 0.1.461
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/bridge-flow-runner.ts +43 -14
- package/cli/drivers/playwright-sim-host.ts +24 -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 +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/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 +12 -7
- 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 +1 -1
- 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 +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +46 -23
- package/dist-lib/vite.cjs +1 -1
- package/package.json +1 -1
- package/src/host/bridge-host.ts +14 -8
|
@@ -784,6 +784,11 @@ export class SootSimBridgeFlowRunner {
|
|
|
784
784
|
text: node.text || null,
|
|
785
785
|
absolutePosition: node.absolutePosition,
|
|
786
786
|
layout: node.layout,
|
|
787
|
+
// the engine's authoritative answer to "is this painted": layout
|
|
788
|
+
// bounds minus clipping and minus every frontward sibling, overlay
|
|
789
|
+
// and portal that fully covers it. visibility assertions read this,
|
|
790
|
+
// never the raw layout box.
|
|
791
|
+
visibleFrame: node.visibleFrame || null,
|
|
787
792
|
isTextInput: !!node.isTextInput,
|
|
788
793
|
}
|
|
789
794
|
})()`)
|
|
@@ -861,6 +866,8 @@ export class SootSimBridgeFlowRunner {
|
|
|
861
866
|
text: node.text || null,
|
|
862
867
|
absolutePosition: node.absolutePosition,
|
|
863
868
|
layout: node.layout,
|
|
869
|
+
// authoritative visibility, as in findElement above.
|
|
870
|
+
visibleFrame: node.visibleFrame || null,
|
|
864
871
|
isTextInput: !!node.isTextInput,
|
|
865
872
|
}
|
|
866
873
|
})()`)
|
|
@@ -1170,13 +1177,15 @@ export class SootSimBridgeFlowRunner {
|
|
|
1170
1177
|
}
|
|
1171
1178
|
await sleep(200)
|
|
1172
1179
|
}
|
|
1173
|
-
//
|
|
1174
|
-
//
|
|
1175
|
-
//
|
|
1176
|
-
//
|
|
1180
|
+
// report the geometry rather than a guess at the cause. a zero visibleFrame
|
|
1181
|
+
// says the node paints nothing; it cannot on its own separate scrolled-away
|
|
1182
|
+
// from painted-over, so print the frame and let the reader judge. a missing
|
|
1183
|
+
// node stays clearly distinct from a found one. the diff is one bridge call.
|
|
1177
1184
|
const found = await this.findElement(opts)
|
|
1185
|
+
const frame = found?.visibleFrame
|
|
1178
1186
|
const detail = found
|
|
1179
|
-
? ` (matched node at y=${Math.round(found.absolutePosition.y)} h=${Math.round(found.layout.height)}
|
|
1187
|
+
? ` (matched node at y=${Math.round(found.absolutePosition.y)} h=${Math.round(found.layout.height)}, ` +
|
|
1188
|
+
`visibleFrame ${JSON.stringify(frame ?? null)})`
|
|
1180
1189
|
: ' (no matching node in tree)'
|
|
1181
1190
|
throw new Error(`assertVisible: ${JSON.stringify(opts)} not visible${detail}`)
|
|
1182
1191
|
}
|
|
@@ -1192,13 +1201,32 @@ export class SootSimBridgeFlowRunner {
|
|
|
1192
1201
|
}
|
|
1193
1202
|
}
|
|
1194
1203
|
|
|
1204
|
+
// visibility is the engine's call, not a layout-bounds guess. the old test
|
|
1205
|
+
// here was a vertical band (`y + height > 0 && y < SCREEN_H`), so a node
|
|
1206
|
+
// sealed under an opaque overlay, pushed off the left or right edge, or
|
|
1207
|
+
// clipped to nothing by an ancestor all read as visible — a demo flow could
|
|
1208
|
+
// assert a button that no finger could reach. visibleFrame already carries
|
|
1209
|
+
// the clipped, occlusion-subtracted rect, and tap-target refuses a covered
|
|
1210
|
+
// node on the same basis, so assertions and taps now agree.
|
|
1195
1211
|
private async isElementVisible(opts: { id?: string; text?: string }) {
|
|
1196
1212
|
const element = await this.findElement(opts)
|
|
1197
|
-
return
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1213
|
+
if (!element) return false
|
|
1214
|
+
const frame = element.visibleFrame
|
|
1215
|
+
const usable =
|
|
1216
|
+
!!frame &&
|
|
1217
|
+
Number.isFinite(frame.width) &&
|
|
1218
|
+
Number.isFinite(frame.height) &&
|
|
1219
|
+
Number.isFinite(frame.area)
|
|
1220
|
+
if (!usable) {
|
|
1221
|
+
// absent or non-numeric geometry is unknown visibility, never "hidden".
|
|
1222
|
+
// returning false here would quietly hand assertNotVisible a pass it did
|
|
1223
|
+
// not earn, which is the same shape of false green this change removes.
|
|
1224
|
+
throw new Error(
|
|
1225
|
+
`authoritative visibility unavailable for ${JSON.stringify(opts)}: the engine ` +
|
|
1226
|
+
`returned visibleFrame ${JSON.stringify(frame ?? null)}`,
|
|
1227
|
+
)
|
|
1228
|
+
}
|
|
1229
|
+
return frame.width > 0 && frame.height > 0 && frame.area > 0
|
|
1202
1230
|
}
|
|
1203
1231
|
|
|
1204
1232
|
async inputText(text: string) {
|
|
@@ -2189,18 +2217,19 @@ export class SootSimBridgeFlowRunner {
|
|
|
2189
2217
|
}
|
|
2190
2218
|
|
|
2191
2219
|
// evaluate a `when:` predicate. returns true if the step should run.
|
|
2220
|
+
// `visible:` and `notVisible:` answer the same question assertVisible does,
|
|
2221
|
+
// so they read the engine's visibleFrame too. resolving them by mere presence
|
|
2222
|
+
// in the tree let a guarded step fire on a node painted over by an overlay.
|
|
2192
2223
|
private async evaluateWhen(when: NonNullable<MaestroStep['when']>): Promise<boolean> {
|
|
2193
2224
|
if (when.visible !== undefined) {
|
|
2194
2225
|
const opts =
|
|
2195
2226
|
typeof when.visible === 'string' ? { text: when.visible } : when.visible
|
|
2196
|
-
|
|
2197
|
-
return !!el
|
|
2227
|
+
return this.isElementVisible(opts)
|
|
2198
2228
|
}
|
|
2199
2229
|
if (when.notVisible !== undefined) {
|
|
2200
2230
|
const opts =
|
|
2201
2231
|
typeof when.notVisible === 'string' ? { text: when.notVisible } : when.notVisible
|
|
2202
|
-
|
|
2203
|
-
return !el
|
|
2232
|
+
return !(await this.isElementVisible(opts))
|
|
2204
2233
|
}
|
|
2205
2234
|
if (when.platform !== undefined) {
|
|
2206
2235
|
// rnx emulates iOS — match against the context's platform the way
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readBrowserCompositeCaptureRequest,
|
|
3
|
+
resolveBrowserCompositeCdpClip,
|
|
4
|
+
} from '../../../sootsim-engine/src/capture/browser-composite'
|
|
1
5
|
// the detached browser host, as CJS source.
|
|
2
6
|
//
|
|
3
7
|
// it resolves playwright from the absolute path the driver hands it, launches
|
|
@@ -66,6 +70,8 @@ const { existsSync, mkdtempSync, readdirSync, rmSync, unlinkSync } = require('fs
|
|
|
66
70
|
const { execSync } = require('child_process');
|
|
67
71
|
const { tmpdir } = require('os');
|
|
68
72
|
const { join } = require('path');
|
|
73
|
+
const readBrowserCompositeCaptureRequest = ${readBrowserCompositeCaptureRequest.toString()};
|
|
74
|
+
const resolveBrowserCompositeCdpClip = ${resolveBrowserCompositeCdpClip.toString()};
|
|
69
75
|
// chrome tree reaper — playwright's browser.close() and even SIGKILLing the
|
|
70
76
|
// root chrome process do NOT reliably take down the helper tree (gpu, renderer,
|
|
71
77
|
// network/storage utilities). they reparent to launchd/init and survive, each
|
|
@@ -422,6 +428,24 @@ const cleanupProfile = () => {
|
|
|
422
428
|
await context.exposeBinding('__sootsimHostClose', async () => {
|
|
423
429
|
await shutdown(0);
|
|
424
430
|
});
|
|
431
|
+
await context.exposeBinding('__sootsimHostCapture', async (source, value) => {
|
|
432
|
+
const request = readBrowserCompositeCaptureRequest(value);
|
|
433
|
+
const session = await source.page.context().newCDPSession(source.page);
|
|
434
|
+
try {
|
|
435
|
+
const result = await session.send('Page.captureScreenshot', {
|
|
436
|
+
format: 'png',
|
|
437
|
+
fromSurface: true,
|
|
438
|
+
captureBeyondViewport: true,
|
|
439
|
+
clip: resolveBrowserCompositeCdpClip(
|
|
440
|
+
request,
|
|
441
|
+
await session.send('Page.getLayoutMetrics'),
|
|
442
|
+
),
|
|
443
|
+
});
|
|
444
|
+
return 'data:image/png;base64,' + result.data;
|
|
445
|
+
} finally {
|
|
446
|
+
await session.detach();
|
|
447
|
+
}
|
|
448
|
+
});
|
|
425
449
|
const connectTimeoutMs = Number(process.env.SOOTSIM_PW_CONNECT_TIMEOUT_MS || 120000);
|
|
426
450
|
if (connectAckFile) {
|
|
427
451
|
connectAckPoll = setInterval(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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;
|
|
@@ -8732,7 +8732,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
8732
8732
|
inflightScan = null;
|
|
8733
8733
|
static SCAN_FRESH_MS = 2e3;
|
|
8734
8734
|
constructor(opts = {}) {
|
|
8735
|
-
this.preferredPort = opts.port
|
|
8735
|
+
this.preferredPort = opts.port ?? DEFAULT_SOOTSIM_BRIDGE_PORT;
|
|
8736
8736
|
this.port = this.preferredPort;
|
|
8737
8737
|
this.shouldWriteLockfile = opts.writeLockfile === true;
|
|
8738
8738
|
this.shouldWriteDevLockfile = opts.writeDevLockfile === true;
|
|
@@ -8782,9 +8782,9 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
8782
8782
|
for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
|
|
8783
8783
|
const candidate = this.preferredPort + attempt;
|
|
8784
8784
|
try {
|
|
8785
|
-
await this.bindOnce(candidate, options?.silent === true);
|
|
8786
|
-
this.effectivePort =
|
|
8787
|
-
this.port =
|
|
8785
|
+
const boundPort = await this.bindOnce(candidate, options?.silent === true);
|
|
8786
|
+
this.effectivePort = boundPort;
|
|
8787
|
+
this.port = boundPort;
|
|
8788
8788
|
this.startedAt = Date.now();
|
|
8789
8789
|
if (attempt > 0 && !options?.silent) {
|
|
8790
8790
|
process.stderr.write(
|
|
@@ -8793,7 +8793,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
8793
8793
|
);
|
|
8794
8794
|
}
|
|
8795
8795
|
this.afterBind();
|
|
8796
|
-
return
|
|
8796
|
+
return boundPort;
|
|
8797
8797
|
} catch (err) {
|
|
8798
8798
|
const e = err;
|
|
8799
8799
|
if (e?.code !== "EADDRINUSE") {
|
|
@@ -8829,6 +8829,11 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
8829
8829
|
server.once("error", onError);
|
|
8830
8830
|
server.listen(port, "127.0.0.1", () => {
|
|
8831
8831
|
if (settled) return;
|
|
8832
|
+
const address = server.address();
|
|
8833
|
+
if (!address || typeof address === "string") {
|
|
8834
|
+
onError(new Error("ws bridge has no bound TCP address"));
|
|
8835
|
+
return;
|
|
8836
|
+
}
|
|
8832
8837
|
settled = true;
|
|
8833
8838
|
server.removeListener("error", onError);
|
|
8834
8839
|
server.on("error", (err) => {
|
|
@@ -8844,7 +8849,7 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
|
|
|
8844
8849
|
this.wss?.emit("connection", ws, req);
|
|
8845
8850
|
});
|
|
8846
8851
|
});
|
|
8847
|
-
resolve5();
|
|
8852
|
+
resolve5(address.port);
|
|
8848
8853
|
});
|
|
8849
8854
|
});
|
|
8850
8855
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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.461 | (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.461 | (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/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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.461 | (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/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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.461 | (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.461 | (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.461 | (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/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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.461 | (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/skills.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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;
|
|
@@ -4005,7 +4005,7 @@ var init_supported_native_packages = __esm({
|
|
|
4005
4005
|
"@react-native-documents/viewer",
|
|
4006
4006
|
// seam
|
|
4007
4007
|
"@react-native-firebase/analytics",
|
|
4008
|
-
//
|
|
4008
|
+
// coverage
|
|
4009
4009
|
"@react-native-firebase/app",
|
|
4010
4010
|
// seam+coverage
|
|
4011
4011
|
"@react-native-firebase/auth",
|
|
@@ -4023,7 +4023,7 @@ var init_supported_native_packages = __esm({
|
|
|
4023
4023
|
"@react-native-masked-view/masked-view",
|
|
4024
4024
|
// preset+coverage
|
|
4025
4025
|
"@react-native-menu/menu",
|
|
4026
|
-
//
|
|
4026
|
+
// coverage
|
|
4027
4027
|
"@react-native-ml-kit/barcode-scanning",
|
|
4028
4028
|
// seam
|
|
4029
4029
|
"@react-native-picker/picker",
|
|
@@ -4059,7 +4059,7 @@ var init_supported_native_packages = __esm({
|
|
|
4059
4059
|
"@shopify/flash-list",
|
|
4060
4060
|
// coverage
|
|
4061
4061
|
"@shopify/react-native-performance",
|
|
4062
|
-
//
|
|
4062
|
+
// coverage
|
|
4063
4063
|
"@shopify/react-native-skia",
|
|
4064
4064
|
// preset+coverage
|
|
4065
4065
|
"@simform_solutions/react-native-audio-waveform",
|
|
@@ -4214,8 +4214,6 @@ var init_supported_native_packages = __esm({
|
|
|
4214
4214
|
// visual-proof+coverage
|
|
4215
4215
|
"expo-sensors",
|
|
4216
4216
|
// visual-proof
|
|
4217
|
-
"expo-share-extension",
|
|
4218
|
-
// seam
|
|
4219
4217
|
"expo-sharing",
|
|
4220
4218
|
// visual-proof
|
|
4221
4219
|
"expo-sms",
|
|
@@ -4228,8 +4226,6 @@ var init_supported_native_packages = __esm({
|
|
|
4228
4226
|
// visual-proof+coverage
|
|
4229
4227
|
"expo-sqlite",
|
|
4230
4228
|
// preset+coverage
|
|
4231
|
-
"expo-squircle-view",
|
|
4232
|
-
// seam
|
|
4233
4229
|
"expo-store-review",
|
|
4234
4230
|
// visual-proof+coverage
|
|
4235
4231
|
"expo-symbols",
|
|
@@ -4241,7 +4237,7 @@ var init_supported_native_packages = __esm({
|
|
|
4241
4237
|
"expo-testflight",
|
|
4242
4238
|
// seam+coverage
|
|
4243
4239
|
"expo-tracking-transparency",
|
|
4244
|
-
// visual-proof+
|
|
4240
|
+
// visual-proof+coverage
|
|
4245
4241
|
"expo-updates",
|
|
4246
4242
|
// preset+seam+coverage
|
|
4247
4243
|
"expo-video",
|
|
@@ -4396,8 +4392,6 @@ var init_supported_native_packages = __esm({
|
|
|
4396
4392
|
// coverage
|
|
4397
4393
|
"react-native-fast-secure-storage",
|
|
4398
4394
|
// seam+coverage
|
|
4399
|
-
"react-native-fast-squircle",
|
|
4400
|
-
// seam
|
|
4401
4395
|
"react-native-fast-trie",
|
|
4402
4396
|
// seam+coverage
|
|
4403
4397
|
"react-native-fbsdk-next",
|
|
@@ -27738,7 +27732,7 @@ var init_bridge_host = __esm({
|
|
|
27738
27732
|
inflightScan = null;
|
|
27739
27733
|
static SCAN_FRESH_MS = 2e3;
|
|
27740
27734
|
constructor(opts = {}) {
|
|
27741
|
-
this.preferredPort = opts.port
|
|
27735
|
+
this.preferredPort = opts.port ?? DEFAULT_SOOTSIM_BRIDGE_PORT;
|
|
27742
27736
|
this.port = this.preferredPort;
|
|
27743
27737
|
this.shouldWriteLockfile = opts.writeLockfile === true;
|
|
27744
27738
|
this.shouldWriteDevLockfile = opts.writeDevLockfile === true;
|
|
@@ -27788,9 +27782,9 @@ var init_bridge_host = __esm({
|
|
|
27788
27782
|
for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
|
|
27789
27783
|
const candidate = this.preferredPort + attempt;
|
|
27790
27784
|
try {
|
|
27791
|
-
await this.bindOnce(candidate, options?.silent === true);
|
|
27792
|
-
this.effectivePort =
|
|
27793
|
-
this.port =
|
|
27785
|
+
const boundPort = await this.bindOnce(candidate, options?.silent === true);
|
|
27786
|
+
this.effectivePort = boundPort;
|
|
27787
|
+
this.port = boundPort;
|
|
27794
27788
|
this.startedAt = Date.now();
|
|
27795
27789
|
if (attempt > 0 && !options?.silent) {
|
|
27796
27790
|
process.stderr.write(
|
|
@@ -27799,7 +27793,7 @@ var init_bridge_host = __esm({
|
|
|
27799
27793
|
);
|
|
27800
27794
|
}
|
|
27801
27795
|
this.afterBind();
|
|
27802
|
-
return
|
|
27796
|
+
return boundPort;
|
|
27803
27797
|
} catch (err) {
|
|
27804
27798
|
const e = err;
|
|
27805
27799
|
if (e?.code !== "EADDRINUSE") {
|
|
@@ -27835,6 +27829,11 @@ var init_bridge_host = __esm({
|
|
|
27835
27829
|
server.once("error", onError);
|
|
27836
27830
|
server.listen(port, "127.0.0.1", () => {
|
|
27837
27831
|
if (settled) return;
|
|
27832
|
+
const address = server.address();
|
|
27833
|
+
if (!address || typeof address === "string") {
|
|
27834
|
+
onError(new Error("ws bridge has no bound TCP address"));
|
|
27835
|
+
return;
|
|
27836
|
+
}
|
|
27838
27837
|
settled = true;
|
|
27839
27838
|
server.removeListener("error", onError);
|
|
27840
27839
|
server.on("error", (err) => {
|
|
@@ -27850,7 +27849,7 @@ var init_bridge_host = __esm({
|
|
|
27850
27849
|
this.wss?.emit("connection", ws, req);
|
|
27851
27850
|
});
|
|
27852
27851
|
});
|
|
27853
|
-
resolve9();
|
|
27852
|
+
resolve9(address.port);
|
|
27854
27853
|
});
|
|
27855
27854
|
});
|
|
27856
27855
|
}
|
|
@@ -35953,6 +35952,11 @@ var init_bridge_flow_runner = __esm({
|
|
|
35953
35952
|
text: node.text || null,
|
|
35954
35953
|
absolutePosition: node.absolutePosition,
|
|
35955
35954
|
layout: node.layout,
|
|
35955
|
+
// the engine's authoritative answer to "is this painted": layout
|
|
35956
|
+
// bounds minus clipping and minus every frontward sibling, overlay
|
|
35957
|
+
// and portal that fully covers it. visibility assertions read this,
|
|
35958
|
+
// never the raw layout box.
|
|
35959
|
+
visibleFrame: node.visibleFrame || null,
|
|
35956
35960
|
isTextInput: !!node.isTextInput,
|
|
35957
35961
|
}
|
|
35958
35962
|
})()`);
|
|
@@ -36025,6 +36029,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
36025
36029
|
text: node.text || null,
|
|
36026
36030
|
absolutePosition: node.absolutePosition,
|
|
36027
36031
|
layout: node.layout,
|
|
36032
|
+
// authoritative visibility, as in findElement above.
|
|
36033
|
+
visibleFrame: node.visibleFrame || null,
|
|
36028
36034
|
isTextInput: !!node.isTextInput,
|
|
36029
36035
|
}
|
|
36030
36036
|
})()`);
|
|
@@ -36245,7 +36251,8 @@ var init_bridge_flow_runner = __esm({
|
|
|
36245
36251
|
await sleep3(200);
|
|
36246
36252
|
}
|
|
36247
36253
|
const found = await this.findElement(opts);
|
|
36248
|
-
const
|
|
36254
|
+
const frame = found?.visibleFrame;
|
|
36255
|
+
const detail = found ? ` (matched node at y=${Math.round(found.absolutePosition.y)} h=${Math.round(found.layout.height)}, visibleFrame ${JSON.stringify(frame ?? null)})` : " (no matching node in tree)";
|
|
36249
36256
|
throw new Error(`assertVisible: ${JSON.stringify(opts)} not visible${detail}`);
|
|
36250
36257
|
}
|
|
36251
36258
|
async assertNotVisible(target) {
|
|
@@ -36256,9 +36263,24 @@ var init_bridge_flow_runner = __esm({
|
|
|
36256
36263
|
throw new Error(`assertNotVisible: ${JSON.stringify(opts)} IS visible${where}`);
|
|
36257
36264
|
}
|
|
36258
36265
|
}
|
|
36266
|
+
// visibility is the engine's call, not a layout-bounds guess. the old test
|
|
36267
|
+
// here was a vertical band (`y + height > 0 && y < SCREEN_H`), so a node
|
|
36268
|
+
// sealed under an opaque overlay, pushed off the left or right edge, or
|
|
36269
|
+
// clipped to nothing by an ancestor all read as visible — a demo flow could
|
|
36270
|
+
// assert a button that no finger could reach. visibleFrame already carries
|
|
36271
|
+
// the clipped, occlusion-subtracted rect, and tap-target refuses a covered
|
|
36272
|
+
// node on the same basis, so assertions and taps now agree.
|
|
36259
36273
|
async isElementVisible(opts) {
|
|
36260
36274
|
const element = await this.findElement(opts);
|
|
36261
|
-
|
|
36275
|
+
if (!element) return false;
|
|
36276
|
+
const frame = element.visibleFrame;
|
|
36277
|
+
const usable = !!frame && Number.isFinite(frame.width) && Number.isFinite(frame.height) && Number.isFinite(frame.area);
|
|
36278
|
+
if (!usable) {
|
|
36279
|
+
throw new Error(
|
|
36280
|
+
`authoritative visibility unavailable for ${JSON.stringify(opts)}: the engine returned visibleFrame ${JSON.stringify(frame ?? null)}`
|
|
36281
|
+
);
|
|
36282
|
+
}
|
|
36283
|
+
return frame.width > 0 && frame.height > 0 && frame.area > 0;
|
|
36262
36284
|
}
|
|
36263
36285
|
async inputText(text) {
|
|
36264
36286
|
if (!await this.waitForFocusedTextInput()) {
|
|
@@ -37041,16 +37063,17 @@ var init_bridge_flow_runner = __esm({
|
|
|
37041
37063
|
this.firstLaunchDone = true;
|
|
37042
37064
|
}
|
|
37043
37065
|
// evaluate a `when:` predicate. returns true if the step should run.
|
|
37066
|
+
// `visible:` and `notVisible:` answer the same question assertVisible does,
|
|
37067
|
+
// so they read the engine's visibleFrame too. resolving them by mere presence
|
|
37068
|
+
// in the tree let a guarded step fire on a node painted over by an overlay.
|
|
37044
37069
|
async evaluateWhen(when) {
|
|
37045
37070
|
if (when.visible !== void 0) {
|
|
37046
37071
|
const opts = typeof when.visible === "string" ? { text: when.visible } : when.visible;
|
|
37047
|
-
|
|
37048
|
-
return !!el;
|
|
37072
|
+
return this.isElementVisible(opts);
|
|
37049
37073
|
}
|
|
37050
37074
|
if (when.notVisible !== void 0) {
|
|
37051
37075
|
const opts = typeof when.notVisible === "string" ? { text: when.notVisible } : when.notVisible;
|
|
37052
|
-
|
|
37053
|
-
return !el;
|
|
37076
|
+
return !await this.isElementVisible(opts);
|
|
37054
37077
|
}
|
|
37055
37078
|
if (when.platform !== void 0) {
|
|
37056
37079
|
return when.platform.toLowerCase() === this.js.maestro.platform.toLowerCase();
|
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.461 | (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
package/src/host/bridge-host.ts
CHANGED
|
@@ -223,6 +223,7 @@ interface BridgeForwardedCommand {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
export interface BridgeHostOptions {
|
|
226
|
+
/** use 0 for an OS-assigned port; startAsync returns the bound address. */
|
|
226
227
|
port?: number
|
|
227
228
|
openUrl?: (url: string, options?: OpenUrlOptions) => Promise<void> | void
|
|
228
229
|
/** Contrast-specific excludes for the agent host's dev-server scan. passed
|
|
@@ -466,7 +467,7 @@ export class SootSimBridgeHost {
|
|
|
466
467
|
private static SCAN_FRESH_MS = 2000
|
|
467
468
|
|
|
468
469
|
constructor(opts: BridgeHostOptions = {}) {
|
|
469
|
-
this.preferredPort = opts.port
|
|
470
|
+
this.preferredPort = opts.port ?? DEFAULT_SOOTSIM_BRIDGE_PORT
|
|
470
471
|
this.port = this.preferredPort
|
|
471
472
|
// default off — callers that want the lockfile (rnx serve) opt in.
|
|
472
473
|
this.shouldWriteLockfile = opts.writeLockfile === true
|
|
@@ -537,9 +538,9 @@ export class SootSimBridgeHost {
|
|
|
537
538
|
for (let attempt = 0; attempt < this.portFallbackCount; attempt++) {
|
|
538
539
|
const candidate = this.preferredPort + attempt
|
|
539
540
|
try {
|
|
540
|
-
await this.bindOnce(candidate, options?.silent === true)
|
|
541
|
-
this.effectivePort =
|
|
542
|
-
this.port =
|
|
541
|
+
const boundPort = await this.bindOnce(candidate, options?.silent === true)
|
|
542
|
+
this.effectivePort = boundPort
|
|
543
|
+
this.port = boundPort
|
|
543
544
|
this.startedAt = Date.now()
|
|
544
545
|
if (attempt > 0 && !options?.silent) {
|
|
545
546
|
process.stderr.write(
|
|
@@ -547,7 +548,7 @@ export class SootSimBridgeHost {
|
|
|
547
548
|
)
|
|
548
549
|
}
|
|
549
550
|
this.afterBind()
|
|
550
|
-
return
|
|
551
|
+
return boundPort
|
|
551
552
|
} catch (err: unknown) {
|
|
552
553
|
const e = err as NodeJS.ErrnoException
|
|
553
554
|
if (e?.code !== 'EADDRINUSE') {
|
|
@@ -566,8 +567,8 @@ export class SootSimBridgeHost {
|
|
|
566
567
|
)
|
|
567
568
|
}
|
|
568
569
|
|
|
569
|
-
private bindOnce(port: number, _silent: boolean): Promise<
|
|
570
|
-
return new Promise<
|
|
570
|
+
private bindOnce(port: number, _silent: boolean): Promise<number> {
|
|
571
|
+
return new Promise<number>((resolve, reject) => {
|
|
571
572
|
const server = createServer((req, res) => this.handleHttpRequest(req, res))
|
|
572
573
|
let settled = false
|
|
573
574
|
|
|
@@ -589,6 +590,11 @@ export class SootSimBridgeHost {
|
|
|
589
590
|
// 127.0.0.1 explicitly to avoid the localhost-vs-::1 DNS coinflip.
|
|
590
591
|
server.listen(port, '127.0.0.1', () => {
|
|
591
592
|
if (settled) return
|
|
593
|
+
const address = server.address()
|
|
594
|
+
if (!address || typeof address === 'string') {
|
|
595
|
+
onError(new Error('ws bridge has no bound TCP address'))
|
|
596
|
+
return
|
|
597
|
+
}
|
|
592
598
|
settled = true
|
|
593
599
|
server.removeListener('error', onError)
|
|
594
600
|
server.on('error', (err) => {
|
|
@@ -603,7 +609,7 @@ export class SootSimBridgeHost {
|
|
|
603
609
|
this.wss?.emit('connection', ws, req)
|
|
604
610
|
})
|
|
605
611
|
})
|
|
606
|
-
resolve()
|
|
612
|
+
resolve(address.port)
|
|
607
613
|
})
|
|
608
614
|
})
|
|
609
615
|
}
|