rnxsim 0.1.433 → 0.1.435
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 +55 -13
- package/cli/commands/box.ts +89 -14
- package/cli/commands/inspect.ts +8 -1
- package/cli/outbound-endpoints.ts +5 -0
- package/cli/send-to-box.ts +112 -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 +5324 -1371
- 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 +298 -91
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +313 -104
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +7 -1
- package/dist-lib/menu.mjs +7 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +302 -95
- 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 +5006 -1441
- package/dist-lib/vite.cjs +298 -91
- package/package.json +2 -2
- package/src/bridge-contract.ts +6 -0
- package/src/host/bridge-host.ts +79 -0
- package/src/host/replacement-module-handler.ts +20 -96
- package/src/menu.ts +8 -0
package/dist-lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.435 | (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;
|
|
@@ -510,6 +510,15 @@ var import_react_native_host_modules = require("rnxsim/react-native-host-modules
|
|
|
510
510
|
// ../sootsim-engine/src/metro-fingerprint-registry-client.ts
|
|
511
511
|
var import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
|
|
512
512
|
|
|
513
|
+
// src/backend-origin.ts
|
|
514
|
+
function normalizeHostname(hostname) {
|
|
515
|
+
return hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
516
|
+
}
|
|
517
|
+
function isLoopbackHost(hostname) {
|
|
518
|
+
const normalized = normalizeHostname(hostname);
|
|
519
|
+
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "0.0.0.0" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
|
|
520
|
+
}
|
|
521
|
+
|
|
513
522
|
// src/cloud-contract.ts
|
|
514
523
|
var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
|
|
515
524
|
var RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES = 1024 * 1024;
|
|
@@ -573,15 +582,6 @@ var rnxPublicBrand = Object.freeze({
|
|
|
573
582
|
var import_node_async_hooks = require("node:async_hooks");
|
|
574
583
|
var sinks = new import_node_async_hooks.AsyncLocalStorage();
|
|
575
584
|
|
|
576
|
-
// src/backend-origin.ts
|
|
577
|
-
function normalizeHostname(hostname) {
|
|
578
|
-
return hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
579
|
-
}
|
|
580
|
-
function isLoopbackHost(hostname) {
|
|
581
|
-
const normalized = normalizeHostname(hostname);
|
|
582
|
-
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "0.0.0.0" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/.test(normalized);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
585
|
// cli/cloud-session.ts
|
|
586
586
|
var MAX_ENCODED_SESSION_BYTES = 32 * 1024;
|
|
587
587
|
var RNX_SHELL_UPDATE_PREFIX = "__RNX_SHELL_UPDATE_V1__";
|
|
@@ -611,8 +611,8 @@ function checkoutRoot(cwd) {
|
|
|
611
611
|
}
|
|
612
612
|
}
|
|
613
613
|
function pathContains(parent, child) {
|
|
614
|
-
const
|
|
615
|
-
return
|
|
614
|
+
const relative2 = import_node_path3.default.relative(parent, child);
|
|
615
|
+
return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${import_node_path3.default.sep}`) && !import_node_path3.default.isAbsolute(relative2);
|
|
616
616
|
}
|
|
617
617
|
function resolveDefaultDevBridgeLockfile() {
|
|
618
618
|
const lockfiles = liveDevBridgeLockfiles();
|
|
@@ -729,7 +729,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
729
729
|
const pending = /* @__PURE__ */ new Map();
|
|
730
730
|
const ws = new import_ws.WebSocket(bridgeWsUrl(wsPort));
|
|
731
731
|
const identity = getCliIdentity();
|
|
732
|
-
const ready = new Promise((
|
|
732
|
+
const ready = new Promise((resolve3, reject) => {
|
|
733
733
|
ws.on("open", () => {
|
|
734
734
|
try {
|
|
735
735
|
ws.send(
|
|
@@ -743,7 +743,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
743
743
|
);
|
|
744
744
|
} catch {
|
|
745
745
|
}
|
|
746
|
-
|
|
746
|
+
resolve3();
|
|
747
747
|
});
|
|
748
748
|
ws.on("error", (err) => {
|
|
749
749
|
const cause = err.message ? `: ${err.message}` : "";
|
|
@@ -812,7 +812,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
812
812
|
const sendOnce = async (defaultSimId) => {
|
|
813
813
|
await ready;
|
|
814
814
|
const id = nextId++;
|
|
815
|
-
return new Promise((
|
|
815
|
+
return new Promise((resolve3, reject) => {
|
|
816
816
|
const timeout = setTimeout(() => {
|
|
817
817
|
pending.delete(id);
|
|
818
818
|
reject(
|
|
@@ -824,7 +824,7 @@ function createBridge(wsPort, opts = {}) {
|
|
|
824
824
|
pending.set(id, {
|
|
825
825
|
resolve: (v) => {
|
|
826
826
|
clearTimeout(timeout);
|
|
827
|
-
|
|
827
|
+
resolve3(v);
|
|
828
828
|
},
|
|
829
829
|
reject: (e) => {
|
|
830
830
|
clearTimeout(timeout);
|
|
@@ -1914,7 +1914,7 @@ async function tapResolvedTarget(bridge, args) {
|
|
|
1914
1914
|
stablePolls: 2
|
|
1915
1915
|
});
|
|
1916
1916
|
} catch {
|
|
1917
|
-
await new Promise((
|
|
1917
|
+
await new Promise((resolve3) => setTimeout(resolve3, Math.min(120, remaining)));
|
|
1918
1918
|
}
|
|
1919
1919
|
}
|
|
1920
1920
|
return {
|
|
@@ -2171,7 +2171,7 @@ var SimResetError = class extends SimClientError {
|
|
|
2171
2171
|
}
|
|
2172
2172
|
};
|
|
2173
2173
|
function sleep(ms) {
|
|
2174
|
-
return new Promise((
|
|
2174
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
2175
2175
|
}
|
|
2176
2176
|
function decodePngDataUrl(dataUrl) {
|
|
2177
2177
|
if (typeof dataUrl !== "string" || !dataUrl.startsWith("data:image/png;base64,")) {
|
|
@@ -2884,23 +2884,290 @@ function launchRnxDesktop(bundleUrl, appName) {
|
|
|
2884
2884
|
// src/host/replacement-module-handler.ts
|
|
2885
2885
|
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
2886
2886
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2887
|
+
|
|
2888
|
+
// ../contrast-bundler/src/replacementModule.ts
|
|
2889
|
+
var import_dist = require("sucrase/dist/index.js");
|
|
2890
|
+
var import_parser = require("sucrase/dist/parser/index.js");
|
|
2891
|
+
var import_types = require("sucrase/dist/parser/tokenizer/types.js");
|
|
2892
|
+
|
|
2893
|
+
// ../contrast-bundler/src/posixPath.ts
|
|
2894
|
+
var sep = "/";
|
|
2895
|
+
var delimiter = ":";
|
|
2896
|
+
function isAbsolute(p) {
|
|
2897
|
+
return p.charCodeAt(0) === 47;
|
|
2898
|
+
}
|
|
2899
|
+
function normalizeSegments(parts, allowAboveRoot) {
|
|
2900
|
+
const out = [];
|
|
2901
|
+
for (const part of parts) {
|
|
2902
|
+
if (part === "" || part === ".") continue;
|
|
2903
|
+
if (part === "..") {
|
|
2904
|
+
if (out.length > 0 && out[out.length - 1] !== "..") out.pop();
|
|
2905
|
+
else if (allowAboveRoot) out.push("..");
|
|
2906
|
+
continue;
|
|
2907
|
+
}
|
|
2908
|
+
out.push(part);
|
|
2909
|
+
}
|
|
2910
|
+
return out;
|
|
2911
|
+
}
|
|
2912
|
+
function normalize(p) {
|
|
2913
|
+
if (p.length === 0) return ".";
|
|
2914
|
+
const absolute = isAbsolute(p);
|
|
2915
|
+
const trailingSlash = p.charCodeAt(p.length - 1) === 47;
|
|
2916
|
+
const segments = normalizeSegments(p.split("/"), !absolute);
|
|
2917
|
+
let joined = segments.join("/");
|
|
2918
|
+
if (joined.length === 0) {
|
|
2919
|
+
if (absolute) return "/";
|
|
2920
|
+
return trailingSlash ? "./" : ".";
|
|
2921
|
+
}
|
|
2922
|
+
if (trailingSlash) joined += "/";
|
|
2923
|
+
return absolute ? "/" + joined : joined;
|
|
2924
|
+
}
|
|
2925
|
+
function join2(...parts) {
|
|
2926
|
+
const present = parts.filter((part) => part.length > 0);
|
|
2927
|
+
if (present.length === 0) return ".";
|
|
2928
|
+
return normalize(present.join("/"));
|
|
2929
|
+
}
|
|
2930
|
+
function resolve2(...parts) {
|
|
2931
|
+
let resolved = "";
|
|
2932
|
+
let absolute = false;
|
|
2933
|
+
for (let i = parts.length - 1; i >= 0 && !absolute; i--) {
|
|
2934
|
+
const part = parts[i];
|
|
2935
|
+
if (part.length === 0) continue;
|
|
2936
|
+
resolved = resolved.length > 0 ? `${part}/${resolved}` : part;
|
|
2937
|
+
absolute = isAbsolute(part);
|
|
2938
|
+
}
|
|
2939
|
+
if (!absolute)
|
|
2940
|
+
throw new Error(
|
|
2941
|
+
`posixPath.resolve needs an absolute segment, got: ${parts.join(", ")}`
|
|
2942
|
+
);
|
|
2943
|
+
const normalized = normalizeSegments(resolved.split("/"), false).join("/");
|
|
2944
|
+
return normalized.length > 0 ? "/" + normalized : "/";
|
|
2945
|
+
}
|
|
2946
|
+
function dirname3(p) {
|
|
2947
|
+
const idx = p.lastIndexOf("/");
|
|
2948
|
+
if (idx < 0) return ".";
|
|
2949
|
+
if (idx === 0) return "/";
|
|
2950
|
+
return p.slice(0, idx);
|
|
2951
|
+
}
|
|
2952
|
+
function basename2(p, ext) {
|
|
2953
|
+
const idx = p.lastIndexOf("/");
|
|
2954
|
+
const base = idx < 0 ? p : p.slice(idx + 1);
|
|
2955
|
+
if (ext != null && ext.length < base.length && base.endsWith(ext)) {
|
|
2956
|
+
return base.slice(0, base.length - ext.length);
|
|
2957
|
+
}
|
|
2958
|
+
return base;
|
|
2959
|
+
}
|
|
2960
|
+
function extname(p) {
|
|
2961
|
+
const base = basename2(p);
|
|
2962
|
+
const idx = base.lastIndexOf(".");
|
|
2963
|
+
if (idx <= 0) return "";
|
|
2964
|
+
return base.slice(idx);
|
|
2965
|
+
}
|
|
2966
|
+
function relative(from, to) {
|
|
2967
|
+
if (from === to) return "";
|
|
2968
|
+
const fromParts = normalizeSegments(from.split("/"), false);
|
|
2969
|
+
const toParts = normalizeSegments(to.split("/"), false);
|
|
2970
|
+
let shared = 0;
|
|
2971
|
+
while (shared < fromParts.length && shared < toParts.length && fromParts[shared] === toParts[shared]) {
|
|
2972
|
+
shared++;
|
|
2973
|
+
}
|
|
2974
|
+
const up = new Array(fromParts.length - shared).fill("..");
|
|
2975
|
+
return [...up, ...toParts.slice(shared)].join("/");
|
|
2976
|
+
}
|
|
2977
|
+
var posix = {
|
|
2978
|
+
sep,
|
|
2979
|
+
delimiter,
|
|
2980
|
+
isAbsolute,
|
|
2981
|
+
normalize,
|
|
2982
|
+
join: join2,
|
|
2983
|
+
resolve: resolve2,
|
|
2984
|
+
dirname: dirname3,
|
|
2985
|
+
basename: basename2,
|
|
2986
|
+
extname,
|
|
2987
|
+
relative
|
|
2988
|
+
};
|
|
2989
|
+
var posixPath_default = { ...posix, posix };
|
|
2990
|
+
|
|
2991
|
+
// ../contrast-bundler/src/replacementModule.ts
|
|
2992
|
+
var REPLACEMENT_MODULE_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx"];
|
|
2993
|
+
var IMPORT_KEYWORD = import_types.TokenType["_import"];
|
|
2994
|
+
var EXPORT_KEYWORD = import_types.TokenType["_export"];
|
|
2995
|
+
var REACT_BRIDGE = "globalThis.__sootsim_react_bridge";
|
|
2996
|
+
var REACT_NATIVE_BRIDGE = "globalThis.__sootsim_components__";
|
|
2997
|
+
var PACKAGE_BRIDGES = "globalThis.__sootsim_config_package_modules";
|
|
2998
|
+
var JSX_RUNTIME_SPECIFIERS = /* @__PURE__ */ new Set(["react/jsx-runtime", "react/jsx-dev-runtime"]);
|
|
2999
|
+
function transformsFor(filePath) {
|
|
3000
|
+
switch (extname(filePath).toLowerCase()) {
|
|
2896
3001
|
case ".ts":
|
|
2897
|
-
return "
|
|
3002
|
+
return ["typescript"];
|
|
2898
3003
|
case ".tsx":
|
|
2899
|
-
return "
|
|
3004
|
+
return ["typescript", "jsx"];
|
|
3005
|
+
case ".js":
|
|
3006
|
+
case ".jsx":
|
|
3007
|
+
return ["jsx"];
|
|
2900
3008
|
default:
|
|
2901
|
-
|
|
3009
|
+
throw new Error(
|
|
3010
|
+
`replacement files must be ${REPLACEMENT_MODULE_EXTENSIONS.join(", ")}`
|
|
3011
|
+
);
|
|
2902
3012
|
}
|
|
2903
3013
|
}
|
|
3014
|
+
function unsupportedSpecifier(specifier) {
|
|
3015
|
+
return new Error(
|
|
3016
|
+
`replacement modules may only import react, react-native, and the packages rnx stubs for this app; '${specifier}' is none of those. vendor the code into the replacement file, or add the package to rnx.config so the simulator bridges it.`
|
|
3017
|
+
);
|
|
3018
|
+
}
|
|
3019
|
+
function bridgeDeclaration(name2, specifier) {
|
|
3020
|
+
const notReady = (what) => JSON.stringify(`[rnx] replacement ${what} bridge is not ready`);
|
|
3021
|
+
if (specifier === "react") {
|
|
3022
|
+
return `const ${name2} = ${REACT_BRIDGE}; if (!${name2}) throw new Error(${notReady("React")});`;
|
|
3023
|
+
}
|
|
3024
|
+
if (specifier === "react-native") {
|
|
3025
|
+
return `const ${name2} = ${REACT_NATIVE_BRIDGE}; if (!${name2}) throw new Error(${notReady("React Native")});`;
|
|
3026
|
+
}
|
|
3027
|
+
if (JSX_RUNTIME_SPECIFIERS.has(specifier)) {
|
|
3028
|
+
return `const ${name2} = (() => { const react = ${REACT_BRIDGE}; if (!react) throw new Error(${notReady("React")}); const jsx = (type, props, key) => react.createElement(type, key === undefined ? props : { ...props, key }); return { Fragment: react.Fragment, jsx, jsxs: jsx, jsxDEV: jsx }; })();`;
|
|
3029
|
+
}
|
|
3030
|
+
return `const ${name2} = (${PACKAGE_BRIDGES} || {})[${JSON.stringify(specifier)}]; if (!${name2}) throw new Error(${JSON.stringify(`[rnx] replacement package bridge ${specifier} is not ready`)});`;
|
|
3031
|
+
}
|
|
3032
|
+
var DEFAULT_INTEROP = "__rnxReplacementDefault";
|
|
3033
|
+
var DEFAULT_INTEROP_DECLARATION = `const ${DEFAULT_INTEROP} = (bridge) => (bridge && bridge.__esModule ? bridge.default : bridge);`;
|
|
3034
|
+
function compileReplacementModule(input) {
|
|
3035
|
+
const transformed = (0, import_dist.transform)(input.source, {
|
|
3036
|
+
transforms: transformsFor(input.filePath),
|
|
3037
|
+
filePath: input.filePath,
|
|
3038
|
+
// classic runtime, matching what the app's own Metro build does for a file
|
|
3039
|
+
// that has no automatic-runtime pragma: the file imports React itself.
|
|
3040
|
+
jsxRuntime: "classic",
|
|
3041
|
+
jsxPragma: "React.createElement",
|
|
3042
|
+
jsxFragmentPragma: "React.Fragment",
|
|
3043
|
+
production: true,
|
|
3044
|
+
sourceMapOptions: { compiledFilename: input.filePath }
|
|
3045
|
+
});
|
|
3046
|
+
const code = transformed.code;
|
|
3047
|
+
const sourceMap = transformed.sourceMap;
|
|
3048
|
+
if (!sourceMap) throw new Error("sucrase compiled the replacement with no source map");
|
|
3049
|
+
const { tokens } = (0, import_parser.parse)(code, false, false, false);
|
|
3050
|
+
const read = (token) => code.slice(token.start, token.end);
|
|
3051
|
+
const readSpecifier = (token) => {
|
|
3052
|
+
if (token.type !== import_types.TokenType.string) {
|
|
3053
|
+
throw new Error("replacement module import has no string specifier");
|
|
3054
|
+
}
|
|
3055
|
+
return code.slice(token.start + 1, token.end - 1);
|
|
3056
|
+
};
|
|
3057
|
+
const bridgeNames = /* @__PURE__ */ new Map();
|
|
3058
|
+
const declarations = [];
|
|
3059
|
+
let needsDefaultInterop = false;
|
|
3060
|
+
const bridgeFor = (specifier) => {
|
|
3061
|
+
const existing = bridgeNames.get(specifier);
|
|
3062
|
+
if (existing) return existing;
|
|
3063
|
+
const name2 = `__rnxReplacementBridge${bridgeNames.size}`;
|
|
3064
|
+
bridgeNames.set(specifier, name2);
|
|
3065
|
+
declarations.push(bridgeDeclaration(name2, specifier));
|
|
3066
|
+
return name2;
|
|
3067
|
+
};
|
|
3068
|
+
const edits = [];
|
|
3069
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
3070
|
+
const token = tokens[index];
|
|
3071
|
+
if (token.type === EXPORT_KEYWORD) {
|
|
3072
|
+
const after2 = tokens[index + 1];
|
|
3073
|
+
let fromAt = -1;
|
|
3074
|
+
if (after2?.type === import_types.TokenType.star) {
|
|
3075
|
+
fromAt = read(tokens[index + 2]) === "from" ? index + 2 : index + 4;
|
|
3076
|
+
} else if (after2?.type === import_types.TokenType.braceL) {
|
|
3077
|
+
let depth = 1;
|
|
3078
|
+
let cursor2 = index + 2;
|
|
3079
|
+
while (cursor2 < tokens.length && depth > 0) {
|
|
3080
|
+
if (tokens[cursor2].type === import_types.TokenType.braceL) depth++;
|
|
3081
|
+
else if (tokens[cursor2].type === import_types.TokenType.braceR) depth--;
|
|
3082
|
+
cursor2++;
|
|
3083
|
+
}
|
|
3084
|
+
fromAt = cursor2;
|
|
3085
|
+
}
|
|
3086
|
+
if (fromAt > 0 && tokens[fromAt] && read(tokens[fromAt]) === "from" && tokens[fromAt + 1]?.type === import_types.TokenType.string) {
|
|
3087
|
+
const specifier2 = readSpecifier(tokens[fromAt + 1]);
|
|
3088
|
+
throw new Error(
|
|
3089
|
+
`a replacement module cannot re-export from another module, and this one re-exports from '${specifier2}'. import what you need and export the binding.`
|
|
3090
|
+
);
|
|
3091
|
+
}
|
|
3092
|
+
continue;
|
|
3093
|
+
}
|
|
3094
|
+
if (token.type !== IMPORT_KEYWORD) continue;
|
|
3095
|
+
const after = tokens[index + 1];
|
|
3096
|
+
if (!after || after.type === import_types.TokenType.parenL || after.type === import_types.TokenType.dot) continue;
|
|
3097
|
+
const bindings = [];
|
|
3098
|
+
let cursor = index + 1;
|
|
3099
|
+
if (after.type !== import_types.TokenType.string) {
|
|
3100
|
+
while (cursor < tokens.length) {
|
|
3101
|
+
const clause = tokens[cursor];
|
|
3102
|
+
if (clause.type === import_types.TokenType.name && read(clause) === "from") break;
|
|
3103
|
+
if (clause.type === import_types.TokenType.comma) {
|
|
3104
|
+
cursor++;
|
|
3105
|
+
continue;
|
|
3106
|
+
}
|
|
3107
|
+
if (clause.type === import_types.TokenType.star) {
|
|
3108
|
+
bindings.push({ local: read(tokens[cursor + 2]), imported: null });
|
|
3109
|
+
cursor += 3;
|
|
3110
|
+
continue;
|
|
3111
|
+
}
|
|
3112
|
+
if (clause.type === import_types.TokenType.braceL) {
|
|
3113
|
+
cursor++;
|
|
3114
|
+
while (cursor < tokens.length && tokens[cursor].type !== import_types.TokenType.braceR) {
|
|
3115
|
+
if (tokens[cursor].type === import_types.TokenType.comma) {
|
|
3116
|
+
cursor++;
|
|
3117
|
+
continue;
|
|
3118
|
+
}
|
|
3119
|
+
const nameToken = tokens[cursor];
|
|
3120
|
+
const imported = nameToken.type === import_types.TokenType.string ? readSpecifier(nameToken) : read(nameToken);
|
|
3121
|
+
let local = imported;
|
|
3122
|
+
if (tokens[cursor + 1] && read(tokens[cursor + 1]) === "as") {
|
|
3123
|
+
local = read(tokens[cursor + 2]);
|
|
3124
|
+
cursor += 2;
|
|
3125
|
+
}
|
|
3126
|
+
bindings.push({ local, imported });
|
|
3127
|
+
cursor++;
|
|
3128
|
+
}
|
|
3129
|
+
cursor++;
|
|
3130
|
+
continue;
|
|
3131
|
+
}
|
|
3132
|
+
bindings.push({ local: read(clause), imported: "default" });
|
|
3133
|
+
cursor++;
|
|
3134
|
+
}
|
|
3135
|
+
cursor++;
|
|
3136
|
+
}
|
|
3137
|
+
const specifierToken = tokens[cursor];
|
|
3138
|
+
if (!specifierToken) throw new Error("replacement module import is unterminated");
|
|
3139
|
+
const specifier = readSpecifier(specifierToken);
|
|
3140
|
+
if (specifier !== "react" && specifier !== "react-native" && !JSX_RUNTIME_SPECIFIERS.has(specifier) && !input.runtimePackages.has(specifier)) {
|
|
3141
|
+
throw unsupportedSpecifier(specifier);
|
|
3142
|
+
}
|
|
3143
|
+
const bridge = bindings.length > 0 ? bridgeFor(specifier) : null;
|
|
3144
|
+
const replacement = bindings.map((binding) => {
|
|
3145
|
+
if (binding.imported === null) return `const ${binding.local} = ${bridge};`;
|
|
3146
|
+
if (binding.imported === "default") {
|
|
3147
|
+
needsDefaultInterop = true;
|
|
3148
|
+
return `const ${binding.local} = ${DEFAULT_INTEROP}(${bridge});`;
|
|
3149
|
+
}
|
|
3150
|
+
return `const ${binding.local} = ${bridge}[${JSON.stringify(binding.imported)}];`;
|
|
3151
|
+
}).join(" ");
|
|
3152
|
+
const start = token.start;
|
|
3153
|
+
const end = specifierToken.end;
|
|
3154
|
+
const newlines = code.slice(start, end).split("\n").length - 1;
|
|
3155
|
+
edits.push({ start, end, text: replacement + "\n".repeat(newlines) });
|
|
3156
|
+
}
|
|
3157
|
+
let out = code;
|
|
3158
|
+
for (const edit of edits.reverse()) {
|
|
3159
|
+
out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
|
|
3160
|
+
}
|
|
3161
|
+
if (needsDefaultInterop) declarations.unshift(DEFAULT_INTEROP_DECLARATION);
|
|
3162
|
+
const preamble = declarations.join(" ");
|
|
3163
|
+
return {
|
|
3164
|
+
code: preamble ? `${preamble} ${out}` : out,
|
|
3165
|
+
sourceMap: { ...sourceMap, sourcesContent: [input.source] }
|
|
3166
|
+
};
|
|
3167
|
+
}
|
|
3168
|
+
|
|
3169
|
+
// src/host/replacement-module-handler.ts
|
|
3170
|
+
var REPLACEMENT_MODULE_ROUTE = "/__sootsim-replacement-module";
|
|
2904
3171
|
function sendJavaScript(req, res, source) {
|
|
2905
3172
|
const origin = req.headers.origin;
|
|
2906
3173
|
let allowedOrigin;
|
|
@@ -2963,10 +3230,10 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
2963
3230
|
res.end("missing path param");
|
|
2964
3231
|
return true;
|
|
2965
3232
|
}
|
|
2966
|
-
const
|
|
2967
|
-
if (!
|
|
3233
|
+
const extension = import_node_path5.default.extname(targetPath).toLowerCase();
|
|
3234
|
+
if (!REPLACEMENT_MODULE_EXTENSIONS.some((allowed) => allowed === extension)) {
|
|
2968
3235
|
res.writeHead(400, { "Content-Type": "text/plain; charset=utf-8" });
|
|
2969
|
-
res.end(
|
|
3236
|
+
res.end(`replacement files must be ${REPLACEMENT_MODULE_EXTENSIONS.join(", ")}`);
|
|
2970
3237
|
return true;
|
|
2971
3238
|
}
|
|
2972
3239
|
if (!import_node_path5.default.isAbsolute(targetPath)) {
|
|
@@ -3004,81 +3271,23 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
3004
3271
|
}
|
|
3005
3272
|
}
|
|
3006
3273
|
try {
|
|
3007
|
-
const
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
format: "esm",
|
|
3012
|
-
platform: "browser",
|
|
3013
|
-
target: "es2022",
|
|
3014
|
-
jsx: "transform",
|
|
3015
|
-
jsxFactory: "React.createElement",
|
|
3016
|
-
jsxFragment: "React.Fragment",
|
|
3017
|
-
tsconfigRaw: { compilerOptions: { jsx: "react" } },
|
|
3018
|
-
sourcemap: "inline",
|
|
3019
|
-
logLevel: "silent",
|
|
3020
|
-
plugins: [
|
|
3021
|
-
{
|
|
3022
|
-
name: "sootsim-replacement-runtime",
|
|
3023
|
-
setup(runtimeBuild) {
|
|
3024
|
-
runtimeBuild.onResolve(
|
|
3025
|
-
{
|
|
3026
|
-
filter: /^(react|react-native|react\/jsx-runtime|react\/jsx-dev-runtime)$/
|
|
3027
|
-
},
|
|
3028
|
-
(args) => ({ path: args.path, namespace: "sootsim-replacement-runtime" })
|
|
3029
|
-
);
|
|
3030
|
-
runtimeBuild.onResolve(
|
|
3031
|
-
{ filter: /.*/ },
|
|
3032
|
-
(args) => runtimePackages.has(args.path) ? { path: args.path, namespace: "sootsim-replacement-runtime" } : void 0
|
|
3033
|
-
);
|
|
3034
|
-
runtimeBuild.onLoad(
|
|
3035
|
-
{ filter: /.*/, namespace: "sootsim-replacement-runtime" },
|
|
3036
|
-
(args) => {
|
|
3037
|
-
if (args.path === "react-native") {
|
|
3038
|
-
return {
|
|
3039
|
-
contents: `const bridge = globalThis.__sootsim_components__
|
|
3040
|
-
if (!bridge) throw new Error('[rnx] replacement React Native bridge is not ready')
|
|
3041
|
-
module.exports = bridge`,
|
|
3042
|
-
loader: "js"
|
|
3043
|
-
};
|
|
3044
|
-
}
|
|
3045
|
-
if (args.path === "react") {
|
|
3046
|
-
return {
|
|
3047
|
-
contents: `const bridge = globalThis.__sootsim_react_bridge
|
|
3048
|
-
if (!bridge) throw new Error('[rnx] replacement React bridge is not ready')
|
|
3049
|
-
module.exports = bridge`,
|
|
3050
|
-
loader: "js"
|
|
3051
|
-
};
|
|
3052
|
-
}
|
|
3053
|
-
if (args.path !== "react/jsx-runtime" && args.path !== "react/jsx-dev-runtime") {
|
|
3054
|
-
return {
|
|
3055
|
-
contents: `const packages = globalThis.__sootsim_config_package_modules
|
|
3056
|
-
const bridge = packages?.[${JSON.stringify(args.path)}]
|
|
3057
|
-
if (!bridge) throw new Error(${JSON.stringify(`[rnx] replacement package bridge ${args.path} is not ready`)})
|
|
3058
|
-
module.exports = bridge`,
|
|
3059
|
-
loader: "js"
|
|
3060
|
-
};
|
|
3061
|
-
}
|
|
3062
|
-
return {
|
|
3063
|
-
contents: `const React = globalThis.__sootsim_react_bridge
|
|
3064
|
-
if (!React) throw new Error('[rnx] replacement React bridge is not ready')
|
|
3065
|
-
exports.Fragment = React.Fragment
|
|
3066
|
-
exports.jsx = (type, props, key) => React.createElement(type, key === undefined ? props : { ...props, key })
|
|
3067
|
-
exports.jsxs = exports.jsx
|
|
3068
|
-
exports.jsxDEV = exports.jsx`,
|
|
3069
|
-
loader: "js"
|
|
3070
|
-
};
|
|
3071
|
-
}
|
|
3072
|
-
);
|
|
3073
|
-
}
|
|
3074
|
-
}
|
|
3075
|
-
]
|
|
3274
|
+
const compiled = compileReplacementModule({
|
|
3275
|
+
filePath: resolvedTargetPath,
|
|
3276
|
+
source: await import_promises.default.readFile(resolvedTargetPath, "utf8"),
|
|
3277
|
+
runtimePackages
|
|
3076
3278
|
});
|
|
3077
|
-
|
|
3279
|
+
const map = Buffer.from(JSON.stringify(compiled.sourceMap), "utf8").toString("base64");
|
|
3280
|
+
sendJavaScript(
|
|
3281
|
+
req,
|
|
3282
|
+
res,
|
|
3283
|
+
`${compiled.code}
|
|
3284
|
+
//# sourceMappingURL=data:application/json;base64,${map}
|
|
3285
|
+
`
|
|
3286
|
+
);
|
|
3078
3287
|
} catch (error) {
|
|
3079
3288
|
const message = error instanceof Error ? error.message : String(error);
|
|
3080
3289
|
res.writeHead(500, { "Content-Type": "text/plain; charset=utf-8" });
|
|
3081
|
-
res.end(`replacement
|
|
3290
|
+
res.end(`replacement compile failed: ${message}`);
|
|
3082
3291
|
}
|
|
3083
3292
|
return true;
|
|
3084
3293
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.435 | (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.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.435 | (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;
|
|
@@ -294,6 +294,12 @@ function debugMenu(state) {
|
|
|
294
294
|
checked: state.alwaysShowLiveWebViews,
|
|
295
295
|
action: "toggle-live-webviews"
|
|
296
296
|
},
|
|
297
|
+
{
|
|
298
|
+
label: "Send to Box Carries Sign-In",
|
|
299
|
+
type: "checkbox",
|
|
300
|
+
checked: state.sendToBoxCarryAuth,
|
|
301
|
+
action: "toggle-send-to-box-auth"
|
|
302
|
+
},
|
|
297
303
|
{ type: "separator" },
|
|
298
304
|
{
|
|
299
305
|
label: "Clear Cache and Reload",
|
package/dist-lib/menu.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.435 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/public-brand.ts
|
|
4
4
|
var name = "rnx";
|
|
@@ -256,6 +256,12 @@ function debugMenu(state) {
|
|
|
256
256
|
checked: state.alwaysShowLiveWebViews,
|
|
257
257
|
action: "toggle-live-webviews"
|
|
258
258
|
},
|
|
259
|
+
{
|
|
260
|
+
label: "Send to Box Carries Sign-In",
|
|
261
|
+
type: "checkbox",
|
|
262
|
+
checked: state.sendToBoxCarryAuth,
|
|
263
|
+
action: "toggle-send-to-box-auth"
|
|
264
|
+
},
|
|
259
265
|
{ type: "separator" },
|
|
260
266
|
{
|
|
261
267
|
label: "Clear Cache and Reload",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.435 | (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.435 | (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;
|