rnxsim 0.1.519 → 0.1.521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/cloud-client.ts +419 -287
- package/cli/cloud-dispatch.ts +2 -21
- package/cli/cloud-session.ts +31 -85
- package/cli/commands/box.ts +15 -11
- package/cli/commands/inspect.ts +34 -1
- package/cli/commands/platform.ts +184 -232
- package/cli/main.ts +10 -2
- package/cli/outbound-endpoints.ts +21 -6
- 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 +7 -2
- package/dist-lib/bridge-contract-input.mjs +7 -2
- 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 +18 -2
- package/dist-lib/cloud.mjs +18 -2
- 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 +112 -39
- 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 +44 -117
- 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 +30 -1
- package/dist-lib/menu.mjs +27 -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 +41 -4
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +138 -164
- package/dist-lib/swift.cjs +766 -24
- package/dist-lib/vite.cjs +103 -30
- package/package.json +1 -1
- package/scripts/dev-server-scanner.ts +72 -5
- package/src/bridge-contract-input.ts +10 -0
- package/src/bridge-contract.ts +5 -0
- package/src/cloud-contract.ts +7 -1
- package/src/cloud.ts +45 -6
- package/src/connect.ts +1 -1
- package/src/menu.ts +44 -0
- package/src/swift.ts +2 -0
- package/src/vite-plugin-one.ts +12 -0
- package/src/vite-plugin-swift.ts +141 -39
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.521 | (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;
|
|
@@ -320,37 +320,26 @@ function normalizeCloudOrigin(source) {
|
|
|
320
320
|
return parsed.origin;
|
|
321
321
|
}
|
|
322
322
|
function createCloudSession(input) {
|
|
323
|
+
const boxId = input.boxId?.trim() ?? "";
|
|
324
|
+
const boxToken = input.boxToken ?? "";
|
|
325
|
+
if (boxId === "" !== (boxToken === "")) {
|
|
326
|
+
throw new Error("cloud session names a box with both its id and its token");
|
|
327
|
+
}
|
|
323
328
|
const session = {
|
|
324
329
|
version: CLOUD_SESSION_VERSION,
|
|
325
330
|
service: "sim",
|
|
326
|
-
boxId: input.boxId.trim(),
|
|
327
|
-
boxToken: input.boxToken,
|
|
328
331
|
simId: input.simId.trim(),
|
|
329
332
|
apiOrigin: normalizeCloudOrigin(input.apiOrigin.trim()),
|
|
330
333
|
claimId: input.claimId.trim(),
|
|
331
334
|
token: input.token,
|
|
335
|
+
...input.streamUrl ? { streamUrl: input.streamUrl } : {},
|
|
332
336
|
...input.platform ? { platform: input.platform } : {},
|
|
333
337
|
...input.device?.trim() ? { device: input.device.trim() } : {},
|
|
334
|
-
...input.artifact ? { artifact: input.artifact } : {}
|
|
335
|
-
|
|
336
|
-
if (!session.boxId || !session.boxToken || !session.simId || !session.claimId || !session.token) {
|
|
337
|
-
throw new Error("cloud session requires box, simulator, origin, claim, and tokens");
|
|
338
|
-
}
|
|
339
|
-
return session;
|
|
340
|
-
}
|
|
341
|
-
function createCloudBoxSession(input) {
|
|
342
|
-
const session = {
|
|
343
|
-
version: CLOUD_SESSION_VERSION,
|
|
344
|
-
service: "box",
|
|
345
|
-
boxId: input.boxId.trim(),
|
|
346
|
-
boxToken: input.boxToken,
|
|
347
|
-
apiOrigin: normalizeCloudOrigin(input.apiOrigin.trim()),
|
|
348
|
-
...input.platform ? { platform: input.platform } : {},
|
|
349
|
-
...input.device?.trim() ? { device: input.device.trim() } : {},
|
|
350
|
-
...input.artifact ? { artifact: input.artifact } : {}
|
|
338
|
+
...input.artifact ? { artifact: input.artifact } : {},
|
|
339
|
+
...boxId && boxToken ? { boxId, boxToken } : {}
|
|
351
340
|
};
|
|
352
|
-
if (!session.
|
|
353
|
-
throw new Error("cloud
|
|
341
|
+
if (!session.simId || !session.claimId || !session.token) {
|
|
342
|
+
throw new Error("cloud session requires a simulator, an origin, a claim, and a token");
|
|
354
343
|
}
|
|
355
344
|
return session;
|
|
356
345
|
}
|
|
@@ -372,10 +361,8 @@ function parseCloudSession(encoded) {
|
|
|
372
361
|
if (!isRecord(parsed) || parsed.version !== CLOUD_SESSION_VERSION) {
|
|
373
362
|
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
374
363
|
}
|
|
375
|
-
const boxId = parsed.boxId;
|
|
376
|
-
const boxToken = parsed.boxToken;
|
|
377
364
|
const apiOrigin = parsed.apiOrigin;
|
|
378
|
-
if (typeof
|
|
365
|
+
if (typeof apiOrigin !== "string") {
|
|
379
366
|
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
380
367
|
}
|
|
381
368
|
const platform = parsed.platform === "ios" || parsed.platform === "android" ? parsed.platform : void 0;
|
|
@@ -384,17 +371,10 @@ function parseCloudSession(encoded) {
|
|
|
384
371
|
sha256: parsed.artifact.sha256,
|
|
385
372
|
bytes: typeof parsed.artifact.bytes === "number" ? parsed.artifact.bytes : void 0
|
|
386
373
|
} : void 0;
|
|
374
|
+
const streamUrl = typeof parsed.streamUrl === "string" ? parsed.streamUrl : void 0;
|
|
375
|
+
const boxId = typeof parsed.boxId === "string" ? parsed.boxId : void 0;
|
|
376
|
+
const boxToken = typeof parsed.boxToken === "string" ? parsed.boxToken : void 0;
|
|
387
377
|
try {
|
|
388
|
-
if (parsed.service === "box") {
|
|
389
|
-
return createCloudBoxSession({
|
|
390
|
-
boxId,
|
|
391
|
-
boxToken,
|
|
392
|
-
apiOrigin,
|
|
393
|
-
platform,
|
|
394
|
-
device,
|
|
395
|
-
artifact
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
378
|
const simId = parsed.simId;
|
|
399
379
|
const claimId = parsed.claimId;
|
|
400
380
|
const token = parsed.token;
|
|
@@ -402,15 +382,16 @@ function parseCloudSession(encoded) {
|
|
|
402
382
|
throw new Error("unreadable cloud session");
|
|
403
383
|
}
|
|
404
384
|
return createCloudSession({
|
|
405
|
-
boxId,
|
|
406
|
-
boxToken,
|
|
407
385
|
simId,
|
|
408
386
|
apiOrigin,
|
|
409
387
|
claimId,
|
|
410
388
|
token,
|
|
389
|
+
streamUrl,
|
|
411
390
|
platform,
|
|
412
391
|
device,
|
|
413
|
-
artifact
|
|
392
|
+
artifact,
|
|
393
|
+
boxId,
|
|
394
|
+
boxToken
|
|
414
395
|
});
|
|
415
396
|
} catch {
|
|
416
397
|
throw new Error(`${RNX_CLOUD_SESSION_ENV} is invalid`);
|
|
@@ -435,7 +416,8 @@ function failureSentence(text) {
|
|
|
435
416
|
}
|
|
436
417
|
if (!isRecord2(parsed)) return null;
|
|
437
418
|
if (isRecord2(parsed.error) && typeof parsed.error.message === "string") {
|
|
438
|
-
|
|
419
|
+
const code = typeof parsed.error.code === "string" && parsed.error.code ? ` [${parsed.error.code}]` : "";
|
|
420
|
+
return `${parsed.error.message}${code}`;
|
|
439
421
|
}
|
|
440
422
|
if (typeof parsed.message === "string") return parsed.message;
|
|
441
423
|
if (typeof parsed.error === "string") return parsed.error;
|
|
@@ -455,14 +437,6 @@ function responseError(status, text) {
|
|
|
455
437
|
function resolveCloudSessionForParsed(parsed) {
|
|
456
438
|
const session = readCloudSession();
|
|
457
439
|
if (!session) return null;
|
|
458
|
-
if (session.service === "box") {
|
|
459
|
-
if (parsed.simIdSource === "flag" && parsed.simId !== session.boxId) {
|
|
460
|
-
throw new Error(
|
|
461
|
-
`this shell is connected to box ${session.boxId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
return session;
|
|
465
|
-
}
|
|
466
440
|
if (parsed.simIdSource === "flag" && parsed.simId !== session.simId) {
|
|
467
441
|
throw new Error(
|
|
468
442
|
`this shell is connected to remote simulator ${session.simId}; ${parsed.simId ? `--sim ${parsed.simId}` : "the requested simulator"} is not available in this shell`
|
|
@@ -558,77 +532,10 @@ var CloudBridge = class {
|
|
|
558
532
|
close() {
|
|
559
533
|
}
|
|
560
534
|
};
|
|
561
|
-
var CloudBoxBridge = class {
|
|
562
|
-
constructor(session) {
|
|
563
|
-
this.session = session;
|
|
564
|
-
}
|
|
565
|
-
plane = "cloud";
|
|
566
|
-
async send(command, options) {
|
|
567
|
-
const id = (0, import_node_crypto.randomUUID)();
|
|
568
|
-
const payload = {};
|
|
569
|
-
for (const [key, value] of Object.entries(command)) {
|
|
570
|
-
if (key !== "id" && key !== "simId") payload[key] = value;
|
|
571
|
-
}
|
|
572
|
-
let response;
|
|
573
|
-
try {
|
|
574
|
-
response = await fetch(
|
|
575
|
-
`${this.session.apiOrigin}/v1/boxes/${encodeURIComponent(this.session.boxId)}/commands`,
|
|
576
|
-
{
|
|
577
|
-
method: "POST",
|
|
578
|
-
headers: {
|
|
579
|
-
authorization: `Bearer ${this.session.boxToken}`,
|
|
580
|
-
"content-type": "application/json"
|
|
581
|
-
},
|
|
582
|
-
body: JSON.stringify({ id, command: payload }),
|
|
583
|
-
...options?.timeoutMs ? { signal: AbortSignal.timeout(options.timeoutMs) } : {}
|
|
584
|
-
}
|
|
585
|
-
);
|
|
586
|
-
} catch (error) {
|
|
587
|
-
throw new Error(
|
|
588
|
-
`could not reach box ${this.session.boxId} at ${this.session.apiOrigin}: ${error instanceof Error ? error.message : String(error)}`
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
const text = await response.text();
|
|
592
|
-
if (!response.ok) throw responseError(response.status, text);
|
|
593
|
-
let parsed;
|
|
594
|
-
try {
|
|
595
|
-
parsed = JSON.parse(text);
|
|
596
|
-
} catch {
|
|
597
|
-
throw new Error("box command returned unreadable JSON");
|
|
598
|
-
}
|
|
599
|
-
if (!isRecord2(parsed) || parsed.id !== id) {
|
|
600
|
-
throw new Error("box command returned an invalid command receipt");
|
|
601
|
-
}
|
|
602
|
-
if (typeof parsed.error === "string" && parsed.error) throw new Error(parsed.error);
|
|
603
|
-
if (!Object.hasOwn(parsed, "result")) {
|
|
604
|
-
throw new Error("box command receipt has no result");
|
|
605
|
-
}
|
|
606
|
-
return parsed.result;
|
|
607
|
-
}
|
|
608
|
-
listSims() {
|
|
609
|
-
return Promise.reject(new Error("a box does not expose a local simulator list"));
|
|
610
|
-
}
|
|
611
|
-
focusSim() {
|
|
612
|
-
return Promise.reject(new Error("a box simulator has no browser window to focus"));
|
|
613
|
-
}
|
|
614
|
-
resolveReloadedSim() {
|
|
615
|
-
return Promise.resolve(null);
|
|
616
|
-
}
|
|
617
|
-
closeSim() {
|
|
618
|
-
return Promise.reject(new Error("close a box simulator with rnx box stop"));
|
|
619
|
-
}
|
|
620
|
-
claim() {
|
|
621
|
-
return Promise.reject(
|
|
622
|
-
new Error("a box simulator is held by its Box page and has nothing to claim")
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
close() {
|
|
626
|
-
}
|
|
627
|
-
};
|
|
628
535
|
function createCloudBridgeForParsed(parsed) {
|
|
629
536
|
const session = resolveCloudSessionForParsed(parsed);
|
|
630
537
|
if (!session) return null;
|
|
631
|
-
return
|
|
538
|
+
return new CloudBridge(session);
|
|
632
539
|
}
|
|
633
540
|
|
|
634
541
|
// cli/current-sim.ts
|
|
@@ -3060,7 +2967,7 @@ async function connect(options = {}) {
|
|
|
3060
2967
|
const bridge2 = createCloudBridgeForParsed(target);
|
|
3061
2968
|
if (!bridge2)
|
|
3062
2969
|
throw new SimConnectError("remote simulator session disappeared while connecting");
|
|
3063
|
-
return new SimClient(bridge2, cloud.
|
|
2970
|
+
return new SimClient(bridge2, cloud.simId, {
|
|
3064
2971
|
commandTimeoutMs: options.timeoutMs ?? 15e3
|
|
3065
2972
|
});
|
|
3066
2973
|
}
|
|
@@ -3922,17 +3829,37 @@ var import_node_child_process2 = require("node:child_process");
|
|
|
3922
3829
|
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
3923
3830
|
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
3924
3831
|
var import_node_util = require("node:util");
|
|
3832
|
+
|
|
3833
|
+
// ../sootsim-swift/toolchain.json
|
|
3834
|
+
var toolchain_default = {
|
|
3835
|
+
release: "swift-6.3-RELEASE",
|
|
3836
|
+
wasmSdkChecksum: "9fa4016ee632c7e9e906608ec3b55cf13dfc4dff44e47574c5af58064dc33fd9"
|
|
3837
|
+
};
|
|
3838
|
+
|
|
3839
|
+
// src/vite-plugin-swift.ts
|
|
3925
3840
|
var run = (0, import_node_util.promisify)(import_node_child_process2.execFile);
|
|
3926
3841
|
var TOOLCHAIN_BIN = import_node_path6.default.join(
|
|
3927
3842
|
import_node_os2.default.homedir(),
|
|
3928
|
-
|
|
3843
|
+
`Library/Developer/Toolchains/${toolchain_default.release}.xctoolchain/usr/bin`
|
|
3929
3844
|
);
|
|
3845
|
+
var WASM_SDK = `${toolchain_default.release}_wasm`;
|
|
3930
3846
|
|
|
3931
3847
|
// src/vite-plugin-one.ts
|
|
3932
3848
|
function rnxPlugin(options = {}) {
|
|
3933
3849
|
const prefix2 = options.prefix || "/__soot";
|
|
3934
3850
|
return {
|
|
3935
3851
|
name: "sootsim-one",
|
|
3852
|
+
// use-latest-callback ships a CJS main (module.exports, no default) with
|
|
3853
|
+
// an esm.mjs shim that re-imports it. react-native-bottom-tabs
|
|
3854
|
+
// default-imports it from source served live, so vite hands the browser
|
|
3855
|
+
// the raw CJS file and the import fails with 'does not provide an export
|
|
3856
|
+
// named default' before anything mounts. forcing it through dep
|
|
3857
|
+
// optimization lets esbuild's CJS interop answer the default import, and
|
|
3858
|
+
// every bare import of it (including the nested copy's) resolves to the
|
|
3859
|
+
// one pre-bundled instance.
|
|
3860
|
+
config() {
|
|
3861
|
+
return { optimizeDeps: { include: ["use-latest-callback"] } };
|
|
3862
|
+
},
|
|
3936
3863
|
configureServer(server) {
|
|
3937
3864
|
if (options.enabled === false) return;
|
|
3938
3865
|
const bundleUrl = options.bundleUrl || "/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.521 | (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.521 | (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.521 | (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,8 @@ __export(menu_exports, {
|
|
|
25
25
|
SOOTSIM_AMBIENT_GLOW_LABELS: () => SOOTSIM_AMBIENT_GLOW_LABELS,
|
|
26
26
|
SOOTSIM_AMBIENT_GLOW_LEVELS: () => SOOTSIM_AMBIENT_GLOW_LEVELS,
|
|
27
27
|
SOOTSIM_ENGINE_EVENT_NAME: () => SOOTSIM_ENGINE_EVENT_NAME,
|
|
28
|
+
SOOTSIM_HOME_SCREEN_VERSIONS: () => SOOTSIM_HOME_SCREEN_VERSIONS,
|
|
29
|
+
SOOTSIM_HOME_SCREEN_VERSION_LABELS: () => SOOTSIM_HOME_SCREEN_VERSION_LABELS,
|
|
28
30
|
SOOTSIM_SHELL_COMMAND_NAME: () => SOOTSIM_SHELL_COMMAND_NAME,
|
|
29
31
|
buildSootSimDeviceChoiceDefs: () => buildSootSimDeviceChoiceDefs,
|
|
30
32
|
buildSootSimMenuDefs: () => buildSootSimMenuDefs,
|
|
@@ -34,6 +36,7 @@ __export(menu_exports, {
|
|
|
34
36
|
getShortcutDocSections: () => getShortcutDocSections,
|
|
35
37
|
getShortcutDocSectionsFromDefs: () => getShortcutDocSectionsFromDefs,
|
|
36
38
|
isSootSimAmbientGlowLevel: () => isSootSimAmbientGlowLevel,
|
|
39
|
+
isSootSimHomeScreenVersion: () => isSootSimHomeScreenVersion,
|
|
37
40
|
matchesAccelerator: () => matchesAccelerator
|
|
38
41
|
});
|
|
39
42
|
module.exports = __toCommonJS(menu_exports);
|
|
@@ -60,6 +63,14 @@ var SOOTSIM_AMBIENT_GLOW_LABELS = {
|
|
|
60
63
|
soft: "Soft",
|
|
61
64
|
full: "Full"
|
|
62
65
|
};
|
|
66
|
+
var SOOTSIM_HOME_SCREEN_VERSIONS = ["ios26", "ios27"];
|
|
67
|
+
function isSootSimHomeScreenVersion(value) {
|
|
68
|
+
return value === "ios26" || value === "ios27";
|
|
69
|
+
}
|
|
70
|
+
var SOOTSIM_HOME_SCREEN_VERSION_LABELS = {
|
|
71
|
+
ios26: "iOS 26",
|
|
72
|
+
ios27: "iOS 27"
|
|
73
|
+
};
|
|
63
74
|
function buildSootSimMenuDefs(state, deviceChoices) {
|
|
64
75
|
return [
|
|
65
76
|
appMenu(),
|
|
@@ -393,6 +404,21 @@ function windowMenu(state) {
|
|
|
393
404
|
actionPayload: level
|
|
394
405
|
}))
|
|
395
406
|
},
|
|
407
|
+
// both eras stay selectable while the ios 27 home surfaces land one at a
|
|
408
|
+
// time, and the device's own os picks the starting value. the switch is
|
|
409
|
+
// the iPhone Duo's, so it is offered exactly where the Duo is.
|
|
410
|
+
...state.developmentMode ? [
|
|
411
|
+
{
|
|
412
|
+
label: "Home Screen",
|
|
413
|
+
items: SOOTSIM_HOME_SCREEN_VERSIONS.map((version) => ({
|
|
414
|
+
label: SOOTSIM_HOME_SCREEN_VERSION_LABELS[version],
|
|
415
|
+
type: "radio",
|
|
416
|
+
checked: state.homeScreenVersion === version,
|
|
417
|
+
action: "set-home-screen",
|
|
418
|
+
actionPayload: version
|
|
419
|
+
}))
|
|
420
|
+
}
|
|
421
|
+
] : [],
|
|
396
422
|
{
|
|
397
423
|
label: "Wireframe",
|
|
398
424
|
type: "checkbox",
|
|
@@ -604,6 +630,8 @@ function matchesAccelerator(event, accelerator) {
|
|
|
604
630
|
SOOTSIM_AMBIENT_GLOW_LABELS,
|
|
605
631
|
SOOTSIM_AMBIENT_GLOW_LEVELS,
|
|
606
632
|
SOOTSIM_ENGINE_EVENT_NAME,
|
|
633
|
+
SOOTSIM_HOME_SCREEN_VERSIONS,
|
|
634
|
+
SOOTSIM_HOME_SCREEN_VERSION_LABELS,
|
|
607
635
|
SOOTSIM_SHELL_COMMAND_NAME,
|
|
608
636
|
buildSootSimDeviceChoiceDefs,
|
|
609
637
|
buildSootSimMenuDefs,
|
|
@@ -613,5 +641,6 @@ function matchesAccelerator(event, accelerator) {
|
|
|
613
641
|
getShortcutDocSections,
|
|
614
642
|
getShortcutDocSectionsFromDefs,
|
|
615
643
|
isSootSimAmbientGlowLevel,
|
|
644
|
+
isSootSimHomeScreenVersion,
|
|
616
645
|
matchesAccelerator
|
|
617
646
|
});
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.521 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/public-brand.ts
|
|
4
4
|
var name = "rnx";
|
|
@@ -22,6 +22,14 @@ var SOOTSIM_AMBIENT_GLOW_LABELS = {
|
|
|
22
22
|
soft: "Soft",
|
|
23
23
|
full: "Full"
|
|
24
24
|
};
|
|
25
|
+
var SOOTSIM_HOME_SCREEN_VERSIONS = ["ios26", "ios27"];
|
|
26
|
+
function isSootSimHomeScreenVersion(value) {
|
|
27
|
+
return value === "ios26" || value === "ios27";
|
|
28
|
+
}
|
|
29
|
+
var SOOTSIM_HOME_SCREEN_VERSION_LABELS = {
|
|
30
|
+
ios26: "iOS 26",
|
|
31
|
+
ios27: "iOS 27"
|
|
32
|
+
};
|
|
25
33
|
function buildSootSimMenuDefs(state, deviceChoices) {
|
|
26
34
|
return [
|
|
27
35
|
appMenu(),
|
|
@@ -355,6 +363,21 @@ function windowMenu(state) {
|
|
|
355
363
|
actionPayload: level
|
|
356
364
|
}))
|
|
357
365
|
},
|
|
366
|
+
// both eras stay selectable while the ios 27 home surfaces land one at a
|
|
367
|
+
// time, and the device's own os picks the starting value. the switch is
|
|
368
|
+
// the iPhone Duo's, so it is offered exactly where the Duo is.
|
|
369
|
+
...state.developmentMode ? [
|
|
370
|
+
{
|
|
371
|
+
label: "Home Screen",
|
|
372
|
+
items: SOOTSIM_HOME_SCREEN_VERSIONS.map((version) => ({
|
|
373
|
+
label: SOOTSIM_HOME_SCREEN_VERSION_LABELS[version],
|
|
374
|
+
type: "radio",
|
|
375
|
+
checked: state.homeScreenVersion === version,
|
|
376
|
+
action: "set-home-screen",
|
|
377
|
+
actionPayload: version
|
|
378
|
+
}))
|
|
379
|
+
}
|
|
380
|
+
] : [],
|
|
358
381
|
{
|
|
359
382
|
label: "Wireframe",
|
|
360
383
|
type: "checkbox",
|
|
@@ -565,6 +588,8 @@ export {
|
|
|
565
588
|
SOOTSIM_AMBIENT_GLOW_LABELS,
|
|
566
589
|
SOOTSIM_AMBIENT_GLOW_LEVELS,
|
|
567
590
|
SOOTSIM_ENGINE_EVENT_NAME,
|
|
591
|
+
SOOTSIM_HOME_SCREEN_VERSIONS,
|
|
592
|
+
SOOTSIM_HOME_SCREEN_VERSION_LABELS,
|
|
568
593
|
SOOTSIM_SHELL_COMMAND_NAME,
|
|
569
594
|
buildSootSimDeviceChoiceDefs,
|
|
570
595
|
buildSootSimMenuDefs,
|
|
@@ -574,5 +599,6 @@ export {
|
|
|
574
599
|
getShortcutDocSections,
|
|
575
600
|
getShortcutDocSectionsFromDefs,
|
|
576
601
|
isSootSimAmbientGlowLevel,
|
|
602
|
+
isSootSimHomeScreenVersion,
|
|
577
603
|
matchesAccelerator
|
|
578
604
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.521 | (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.521 | (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.521 | (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.521 | (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.521 | (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.521 | (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.521 | (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.521 | (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;
|
|
@@ -826,12 +826,32 @@ function safeParseManifest(body) {
|
|
|
826
826
|
return null;
|
|
827
827
|
}
|
|
828
828
|
}
|
|
829
|
+
var localIconPathCache = /* @__PURE__ */ new Map();
|
|
830
|
+
var localIconProbeInFlight = /* @__PURE__ */ new Set();
|
|
831
|
+
function metroAssetPath(rawIcon) {
|
|
832
|
+
return `/assets/${rawIcon.replace(/^\.?\//, "")}`;
|
|
833
|
+
}
|
|
834
|
+
function staticAssetPath(rawIcon) {
|
|
835
|
+
return `/${rawIcon.replace(/^\.?\//, "")}`;
|
|
836
|
+
}
|
|
837
|
+
async function resolveLocalIconPath(hostname, port, rawIcon) {
|
|
838
|
+
const candidates = [metroAssetPath(rawIcon), staticAssetPath(rawIcon)];
|
|
839
|
+
for (const candidate of candidates) {
|
|
840
|
+
const res = await httpGet(hostname, port, candidate, "HEAD", ENRICH_TIMEOUT_MS);
|
|
841
|
+
if (res?.statusCode === 200) {
|
|
842
|
+
localIconPathCache.set(port, candidate);
|
|
843
|
+
portCache.delete(port);
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
829
848
|
function applyManifest(result, manifestRes, buildIconProxyUrl) {
|
|
830
849
|
if (!manifestRes) return result;
|
|
831
850
|
try {
|
|
832
851
|
const manifest = JSON.parse(manifestRes.body);
|
|
833
852
|
const client = manifest?.extra?.expoClient || manifest?.extra || {};
|
|
834
853
|
if (client.name) result.projectName = client.name;
|
|
854
|
+
if (typeof client.primaryColor === "string") result.primaryColor = client.primaryColor;
|
|
835
855
|
if (client.ios?.bundleIdentifier) result.bundleId = client.ios.bundleIdentifier;
|
|
836
856
|
if (result.framework === "metro" && client.sdkVersion) result.framework = "expo";
|
|
837
857
|
const rawLaunchUrl = manifest?.launchAsset?.url;
|
|
@@ -863,9 +883,9 @@ function applyManifest(result, manifestRes, buildIconProxyUrl) {
|
|
|
863
883
|
resolvedIconUrl = rawIcon;
|
|
864
884
|
}
|
|
865
885
|
} else {
|
|
866
|
-
const
|
|
867
|
-
const assetPath =
|
|
868
|
-
const localUrl = `${
|
|
886
|
+
const base = buildLoopbackProbeBaseUrl("http:", manifestRes.hostname, result.port);
|
|
887
|
+
const assetPath = localIconPathCache.get(result.port) ?? metroAssetPath(rawIcon);
|
|
888
|
+
const localUrl = `${base}${assetPath}`;
|
|
869
889
|
resolvedIconUrl = buildIconProxyUrl ? buildIconProxyUrl(localUrl) : localUrl;
|
|
870
890
|
}
|
|
871
891
|
if (resolvedIconUrl) {
|
|
@@ -890,7 +910,20 @@ function __applyManifestForTests(result, manifestBody, buildIconProxyUrl) {
|
|
|
890
910
|
var ENRICH_TIMEOUT_MS = 2e4;
|
|
891
911
|
var enrichmentCache = /* @__PURE__ */ new Map();
|
|
892
912
|
var enrichmentInFlight = /* @__PURE__ */ new Set();
|
|
913
|
+
function ensureLocalIconPathResolved(result) {
|
|
914
|
+
const rawIcon = result.iconPath;
|
|
915
|
+
if (!rawIcon) return;
|
|
916
|
+
if (rawIcon.startsWith("http://") || rawIcon.startsWith("https://")) return;
|
|
917
|
+
if (localIconPathCache.has(result.port)) return;
|
|
918
|
+
if (localIconProbeInFlight.has(result.port)) return;
|
|
919
|
+
localIconProbeInFlight.add(result.port);
|
|
920
|
+
const hostname = normalizeHostname(new URL(result.bundleUrl).hostname);
|
|
921
|
+
void resolveLocalIconPath(hostname, result.port, rawIcon).finally(
|
|
922
|
+
() => localIconProbeInFlight.delete(result.port)
|
|
923
|
+
);
|
|
924
|
+
}
|
|
893
925
|
function enrichWithManifest(result, buildIconProxyUrl) {
|
|
926
|
+
ensureLocalIconPathResolved(result);
|
|
894
927
|
if (result.projectName) return result;
|
|
895
928
|
const cached2 = enrichmentCache.get(result.port);
|
|
896
929
|
if (cached2) {
|
|
@@ -1129,6 +1162,9 @@ async function scanDevServers(opts = {}) {
|
|
|
1129
1162
|
for (const p of [...enrichmentCache.keys()]) {
|
|
1130
1163
|
if (!currentPorts.has(p)) enrichmentCache.delete(p);
|
|
1131
1164
|
}
|
|
1165
|
+
for (const p of [...localIconPathCache.keys()]) {
|
|
1166
|
+
if (!currentPorts.has(p)) localIconPathCache.delete(p);
|
|
1167
|
+
}
|
|
1132
1168
|
const results = [];
|
|
1133
1169
|
const toProbe = [];
|
|
1134
1170
|
for (const { port, pid } of processes) {
|
|
@@ -1142,6 +1178,7 @@ async function scanDevServers(opts = {}) {
|
|
|
1142
1178
|
knownNonExpo.delete(port);
|
|
1143
1179
|
knownOne.delete(port);
|
|
1144
1180
|
enrichmentCache.delete(port);
|
|
1181
|
+
localIconPathCache.delete(port);
|
|
1145
1182
|
}
|
|
1146
1183
|
toProbe.push({ port, pid });
|
|
1147
1184
|
}
|
package/dist-lib/sdk.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.521 | (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.521 | (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);
|