rnxsim 0.1.403 → 0.1.405
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/README.md +17 -4
- 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/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 +1 -1
- 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 +30 -6
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +186 -0
- package/dist-lib/metro-fingerprint-registry.mjs +156 -0
- package/dist-lib/metro-production-bundle.cjs +66 -17
- package/dist-lib/metro-production-bundle.mjs +62 -15
- package/dist-lib/metro.cjs +30 -6
- 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 +56 -24
- package/dist-lib/vite.cjs +1 -1
- package/package.json +8 -1
- package/src/metro-fingerprint-registry.ts +302 -0
- package/src/metro-plugin.ts +47 -4
- package/src/metro-production-bundle.ts +94 -16
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/*! rnx v0.1.405 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
+
|
|
3
|
+
// src/metro-fingerprint-registry.ts
|
|
4
|
+
var RNX_METRO_FINGERPRINT_SCHEMA_VERSION = 2;
|
|
5
|
+
var RNX_METRO_FINGERPRINT_POINTER_PATH = "/compile/metro-fingerprints.json";
|
|
6
|
+
var RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES = 16 * 1024;
|
|
7
|
+
var RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES = 8 * 1024 * 1024;
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function isSha256(value) {
|
|
12
|
+
return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
13
|
+
}
|
|
14
|
+
function readStringArray(value) {
|
|
15
|
+
if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string")) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const entries = [...value];
|
|
19
|
+
if (new Set(entries).size !== entries.length || entries.some((entry, index) => index > 0 && entries[index - 1] >= entry)) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return entries;
|
|
23
|
+
}
|
|
24
|
+
function parseRNXMetroFingerprintPointer(value) {
|
|
25
|
+
if (!isRecord(value)) return null;
|
|
26
|
+
const { schemaVersion, revision, integrity, bytes, payloadUrl } = value;
|
|
27
|
+
if (schemaVersion !== RNX_METRO_FINGERPRINT_SCHEMA_VERSION || !isSha256(revision) || !isSha256(integrity) || typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes < 1 || typeof payloadUrl !== "string" || payloadUrl.length === 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return { schemaVersion, revision, integrity, bytes, payloadUrl };
|
|
31
|
+
}
|
|
32
|
+
function parseRNXMetroFingerprintRegistry(value) {
|
|
33
|
+
if (!isRecord(value)) return null;
|
|
34
|
+
const { schemaVersion, revision } = value;
|
|
35
|
+
if (schemaVersion !== RNX_METRO_FINGERPRINT_SCHEMA_VERSION || !isSha256(revision) || !Array.isArray(value.atoms) || !Array.isArray(value.templates) || !isRecord(value.candidatesByFactoryDigest) || !isRecord(value.candidatesByDiscriminator)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const atoms = [];
|
|
39
|
+
for (const atomValue of value.atoms) {
|
|
40
|
+
if (!isRecord(atomValue)) return null;
|
|
41
|
+
const exports = readStringArray(atomValue.exports);
|
|
42
|
+
const literals = readStringArray(atomValue.literals);
|
|
43
|
+
if (typeof atomValue.key !== "string" || atomValue.key.length === 0 || !exports || !literals || typeof atomValue.dependencyArity !== "number" || !Number.isSafeInteger(atomValue.dependencyArity) || atomValue.dependencyArity < 0 || !isSha256(atomValue.factoryDigest)) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
atoms.push({
|
|
47
|
+
key: atomValue.key,
|
|
48
|
+
exports,
|
|
49
|
+
literals,
|
|
50
|
+
dependencyArity: atomValue.dependencyArity,
|
|
51
|
+
factoryDigest: atomValue.factoryDigest
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const templates = [];
|
|
55
|
+
for (const templateValue of value.templates) {
|
|
56
|
+
if (!isRecord(templateValue) || typeof templateValue.packageName !== "string" || templateValue.packageName.length === 0 || typeof templateValue.packageVersion !== "string" || templateValue.packageVersion.length === 0 || !isSha256(templateValue.sourceIntegrity) || typeof templateValue.profile !== "string" || templateValue.profile.length === 0 || templateValue.platform !== "ios" && templateValue.platform !== "android" || !Array.isArray(templateValue.nodes) || templateValue.nodes.length === 0 || !Array.isArray(templateValue.roots) || templateValue.roots.length === 0) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const nodes = [];
|
|
60
|
+
for (const nodeValue of templateValue.nodes) {
|
|
61
|
+
if (!isRecord(nodeValue) || typeof nodeValue.atom !== "number" || !Number.isSafeInteger(nodeValue.atom) || nodeValue.atom < 0 || nodeValue.atom >= atoms.length || !Array.isArray(nodeValue.internalDependencies) || nodeValue.landmarkPath !== void 0 && (typeof nodeValue.landmarkPath !== "string" || nodeValue.landmarkPath.length === 0)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const internalDependencies = [];
|
|
65
|
+
const positions = /* @__PURE__ */ new Set();
|
|
66
|
+
for (const edgeValue of nodeValue.internalDependencies) {
|
|
67
|
+
if (!isRecord(edgeValue) || typeof edgeValue.position !== "number" || !Number.isSafeInteger(edgeValue.position) || edgeValue.position < 0 || positions.has(edgeValue.position) || typeof edgeValue.node !== "number" || !Number.isSafeInteger(edgeValue.node) || edgeValue.node < 0 || edgeValue.node >= templateValue.nodes.length) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
positions.add(edgeValue.position);
|
|
71
|
+
internalDependencies.push({
|
|
72
|
+
position: edgeValue.position,
|
|
73
|
+
node: edgeValue.node
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
internalDependencies.sort((left, right) => left.position - right.position);
|
|
77
|
+
nodes.push({
|
|
78
|
+
atom: nodeValue.atom,
|
|
79
|
+
internalDependencies,
|
|
80
|
+
...typeof nodeValue.landmarkPath === "string" ? { landmarkPath: nodeValue.landmarkPath } : {}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const roots = [];
|
|
84
|
+
for (const rootValue of templateValue.roots) {
|
|
85
|
+
if (!isRecord(rootValue) || typeof rootValue.node !== "number" || !Number.isSafeInteger(rootValue.node) || rootValue.node < 0 || rootValue.node >= nodes.length || !nodes[rootValue.node].landmarkPath) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
roots.push({ node: rootValue.node });
|
|
89
|
+
}
|
|
90
|
+
templates.push({
|
|
91
|
+
packageName: templateValue.packageName,
|
|
92
|
+
packageVersion: templateValue.packageVersion,
|
|
93
|
+
sourceIntegrity: templateValue.sourceIntegrity,
|
|
94
|
+
profile: templateValue.profile,
|
|
95
|
+
platform: templateValue.platform,
|
|
96
|
+
nodes,
|
|
97
|
+
roots
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const candidatesByFactoryDigest = {};
|
|
101
|
+
for (const [factoryDigest, candidateValues] of Object.entries(
|
|
102
|
+
value.candidatesByFactoryDigest
|
|
103
|
+
)) {
|
|
104
|
+
if (!isSha256(factoryDigest) || !Array.isArray(candidateValues)) return null;
|
|
105
|
+
const candidates = [];
|
|
106
|
+
for (const candidateValue of candidateValues) {
|
|
107
|
+
if (!isRecord(candidateValue) || typeof candidateValue.template !== "number" || !Number.isSafeInteger(candidateValue.template) || candidateValue.template < 0 || candidateValue.template >= templates.length || typeof candidateValue.root !== "number" || !Number.isSafeInteger(candidateValue.root) || candidateValue.root < 0 || candidateValue.root >= templates[candidateValue.template].roots.length) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const template = templates[candidateValue.template];
|
|
111
|
+
const root = template.roots[candidateValue.root];
|
|
112
|
+
if (atoms[template.nodes[root.node].atom].factoryDigest !== factoryDigest) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
candidates.push({
|
|
116
|
+
template: candidateValue.template,
|
|
117
|
+
root: candidateValue.root
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
candidatesByFactoryDigest[factoryDigest] = candidates;
|
|
121
|
+
}
|
|
122
|
+
const candidatesByDiscriminator = {};
|
|
123
|
+
for (const [discriminator, candidateValues] of Object.entries(
|
|
124
|
+
value.candidatesByDiscriminator
|
|
125
|
+
)) {
|
|
126
|
+
if (!/^(?:e|l|ea|la|el|ela):[a-f0-9]{16}$/.test(discriminator)) return null;
|
|
127
|
+
if (!Array.isArray(candidateValues) || candidateValues.length === 0) return null;
|
|
128
|
+
const candidates = [];
|
|
129
|
+
for (const candidateValue of candidateValues) {
|
|
130
|
+
if (!isRecord(candidateValue) || typeof candidateValue.template !== "number" || !Number.isSafeInteger(candidateValue.template) || candidateValue.template < 0 || candidateValue.template >= templates.length || typeof candidateValue.root !== "number" || !Number.isSafeInteger(candidateValue.root) || candidateValue.root < 0 || candidateValue.root >= templates[candidateValue.template].roots.length) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
candidates.push({
|
|
134
|
+
template: candidateValue.template,
|
|
135
|
+
root: candidateValue.root
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
candidatesByDiscriminator[discriminator] = candidates;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
schemaVersion,
|
|
142
|
+
revision,
|
|
143
|
+
atoms,
|
|
144
|
+
templates,
|
|
145
|
+
candidatesByFactoryDigest,
|
|
146
|
+
candidatesByDiscriminator
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES,
|
|
151
|
+
RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES,
|
|
152
|
+
RNX_METRO_FINGERPRINT_POINTER_PATH,
|
|
153
|
+
RNX_METRO_FINGERPRINT_SCHEMA_VERSION,
|
|
154
|
+
parseRNXMetroFingerprintPointer,
|
|
155
|
+
parseRNXMetroFingerprintRegistry
|
|
156
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.405 | (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;
|
|
@@ -22,17 +22,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
22
22
|
// src/metro-production-bundle.ts
|
|
23
23
|
var metro_production_bundle_exports = {};
|
|
24
24
|
__export(metro_production_bundle_exports, {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
RNX_METRO_MODULE_IDENTITY_VERSION: () => RNX_METRO_MODULE_IDENTITY_VERSION,
|
|
26
|
+
appendRNXMetroModuleIdentityFooter: () => appendRNXMetroModuleIdentityFooter,
|
|
27
|
+
createRNXMetroModuleIdentityFooter: () => createRNXMetroModuleIdentityFooter,
|
|
27
28
|
detachRNXMetroSourceMapUrl: () => detachRNXMetroSourceMapUrl,
|
|
28
29
|
readRNXMetroBundleLayout: () => readRNXMetroBundleLayout,
|
|
29
30
|
readRNXMetroModuleIdentity: () => readRNXMetroModuleIdentity,
|
|
30
31
|
toRNXDevelopmentBundleUrl: () => toRNXDevelopmentBundleUrl,
|
|
31
32
|
toRNXProductionBundleUrl: () => toRNXProductionBundleUrl,
|
|
33
|
+
validateRNXMetroModuleIdentity: () => validateRNXMetroModuleIdentity,
|
|
32
34
|
validateRNXMetroModulePaths: () => validateRNXMetroModulePaths
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(metro_production_bundle_exports);
|
|
35
37
|
var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
|
|
38
|
+
var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
|
|
36
39
|
function toRNXProductionBundleUrl(bundleUrl) {
|
|
37
40
|
const relative = bundleUrl.startsWith("/");
|
|
38
41
|
const url = new URL(bundleUrl, "http://rnxsim.local");
|
|
@@ -59,13 +62,13 @@ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
|
|
|
59
62
|
if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
|
|
60
63
|
return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
|
|
61
64
|
}
|
|
62
|
-
function
|
|
63
|
-
const payload = JSON.stringify(
|
|
65
|
+
function createRNXMetroModuleIdentityFooter(identity) {
|
|
66
|
+
const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
|
|
64
67
|
return `
|
|
65
68
|
${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
|
|
66
69
|
}
|
|
67
|
-
function
|
|
68
|
-
const footer =
|
|
70
|
+
function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
|
|
71
|
+
const footer = createRNXMetroModuleIdentityFooter(identity);
|
|
69
72
|
const detached = detachRNXMetroSourceMapUrl(bundleText);
|
|
70
73
|
return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
|
|
71
74
|
${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
|
|
@@ -76,21 +79,55 @@ function readRNXMetroModuleIdentity(bundleText) {
|
|
|
76
79
|
const footerPrefix = `
|
|
77
80
|
${RNXSIM_METRO_MODULE_PATHS_PREFIX}`;
|
|
78
81
|
const footerStart = withoutMap.lastIndexOf(footerPrefix);
|
|
79
|
-
if (footerStart < 0
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (footerStart < 0) return null;
|
|
83
|
+
if (!withoutMap.endsWith(";")) {
|
|
84
|
+
throw new Error("Metro module identity footer is truncated");
|
|
85
|
+
}
|
|
86
|
+
let parsed;
|
|
87
|
+
try {
|
|
88
|
+
parsed = JSON.parse(withoutMap.slice(footerStart + footerPrefix.length, -1));
|
|
89
|
+
} catch {
|
|
90
|
+
throw new Error("Metro module identity footer is not valid JSON");
|
|
91
|
+
}
|
|
83
92
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
84
|
-
|
|
93
|
+
throw new Error("Metro module identity footer is malformed");
|
|
94
|
+
}
|
|
95
|
+
const version = Reflect.get(parsed, "version");
|
|
96
|
+
if (version === void 0) return null;
|
|
97
|
+
const identitySource = Reflect.get(parsed, "identitySource");
|
|
98
|
+
const parsedModulePaths = Reflect.get(parsed, "modulePaths");
|
|
99
|
+
const parsedLogicalSpecifiers = Reflect.get(parsed, "logicalSpecifiers");
|
|
100
|
+
if (version !== RNX_METRO_MODULE_IDENTITY_VERSION || identitySource !== "rnx-plugin" && identitySource !== "contrast-bundler" && identitySource !== "metro-source-map" || typeof parsedModulePaths !== "object" || parsedModulePaths === null || Array.isArray(parsedModulePaths) || typeof parsedLogicalSpecifiers !== "object" || parsedLogicalSpecifiers === null || Array.isArray(parsedLogicalSpecifiers)) {
|
|
101
|
+
throw new Error("Metro module identity footer is malformed");
|
|
85
102
|
}
|
|
86
103
|
const modulePaths = {};
|
|
87
|
-
for (const [moduleId, modulePath] of Object.entries(
|
|
88
|
-
if (typeof modulePath !== "string")
|
|
104
|
+
for (const [moduleId, modulePath] of Object.entries(parsedModulePaths)) {
|
|
105
|
+
if (typeof modulePath !== "string") {
|
|
106
|
+
throw new Error(`Metro module identity has an invalid path for ${moduleId}`);
|
|
107
|
+
}
|
|
89
108
|
modulePaths[moduleId] = modulePath;
|
|
90
109
|
}
|
|
110
|
+
const logicalSpecifiers = {};
|
|
111
|
+
for (const [moduleId, specifiers] of Object.entries(parsedLogicalSpecifiers)) {
|
|
112
|
+
if (!Array.isArray(specifiers) || specifiers.length === 0 || !specifiers.every(
|
|
113
|
+
(specifier) => typeof specifier === "string" && specifier.length > 0
|
|
114
|
+
)) {
|
|
115
|
+
throw new Error(`Metro module identity has invalid specifiers for ${moduleId}`);
|
|
116
|
+
}
|
|
117
|
+
const unique = [...new Set(specifiers)].sort(
|
|
118
|
+
(left, right) => left.localeCompare(right)
|
|
119
|
+
);
|
|
120
|
+
if (unique.length !== specifiers.length) {
|
|
121
|
+
throw new Error(`Metro module identity repeats a specifier for ${moduleId}`);
|
|
122
|
+
}
|
|
123
|
+
logicalSpecifiers[moduleId] = unique;
|
|
124
|
+
}
|
|
91
125
|
return {
|
|
92
126
|
source: withoutMap.slice(0, footerStart),
|
|
127
|
+
version,
|
|
128
|
+
identitySource,
|
|
93
129
|
modulePaths,
|
|
130
|
+
logicalSpecifiers,
|
|
94
131
|
sourceMappingUrl: detached.sourceMappingUrl
|
|
95
132
|
};
|
|
96
133
|
}
|
|
@@ -145,7 +182,7 @@ function readDefineTail(source, start, end) {
|
|
|
145
182
|
while (idEnd > start && /\s/.test(source[idEnd])) idEnd--;
|
|
146
183
|
if (source[idEnd] !== ",") return null;
|
|
147
184
|
let idStart = idEnd;
|
|
148
|
-
while (idStart > start && /[0-9a-fA-FxX
|
|
185
|
+
while (idStart > start && /[0-9a-fA-FxX.+-]/.test(source[idStart - 1])) idStart--;
|
|
149
186
|
const literal = source.slice(idStart, idEnd);
|
|
150
187
|
if (!/^-?(?:0[xXbBoO][0-9a-fA-F]+|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)$/.test(literal)) {
|
|
151
188
|
return null;
|
|
@@ -248,14 +285,26 @@ function validateRNXMetroModulePaths(source, modulePaths) {
|
|
|
248
285
|
}
|
|
249
286
|
}
|
|
250
287
|
}
|
|
288
|
+
function validateRNXMetroModuleIdentity(identity) {
|
|
289
|
+
validateRNXMetroModulePaths(identity.source, identity.modulePaths);
|
|
290
|
+
for (const moduleId of Object.keys(identity.logicalSpecifiers)) {
|
|
291
|
+
if (!Object.prototype.hasOwnProperty.call(identity.modulePaths, moduleId)) {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`Metro module identity has logical specifiers for unknown module ${moduleId}`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
251
298
|
// Annotate the CommonJS export names for ESM import in node:
|
|
252
299
|
0 && (module.exports = {
|
|
253
|
-
|
|
254
|
-
|
|
300
|
+
RNX_METRO_MODULE_IDENTITY_VERSION,
|
|
301
|
+
appendRNXMetroModuleIdentityFooter,
|
|
302
|
+
createRNXMetroModuleIdentityFooter,
|
|
255
303
|
detachRNXMetroSourceMapUrl,
|
|
256
304
|
readRNXMetroBundleLayout,
|
|
257
305
|
readRNXMetroModuleIdentity,
|
|
258
306
|
toRNXDevelopmentBundleUrl,
|
|
259
307
|
toRNXProductionBundleUrl,
|
|
308
|
+
validateRNXMetroModuleIdentity,
|
|
260
309
|
validateRNXMetroModulePaths
|
|
261
310
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.405 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/metro-production-bundle.ts
|
|
4
4
|
var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
|
|
5
|
+
var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
|
|
5
6
|
function toRNXProductionBundleUrl(bundleUrl) {
|
|
6
7
|
const relative = bundleUrl.startsWith("/");
|
|
7
8
|
const url = new URL(bundleUrl, "http://rnxsim.local");
|
|
@@ -28,13 +29,13 @@ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
|
|
|
28
29
|
if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
|
|
29
30
|
return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
|
|
30
31
|
}
|
|
31
|
-
function
|
|
32
|
-
const payload = JSON.stringify(
|
|
32
|
+
function createRNXMetroModuleIdentityFooter(identity) {
|
|
33
|
+
const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
|
|
33
34
|
return `
|
|
34
35
|
${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
|
|
35
36
|
}
|
|
36
|
-
function
|
|
37
|
-
const footer =
|
|
37
|
+
function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
|
|
38
|
+
const footer = createRNXMetroModuleIdentityFooter(identity);
|
|
38
39
|
const detached = detachRNXMetroSourceMapUrl(bundleText);
|
|
39
40
|
return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
|
|
40
41
|
${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
|
|
@@ -45,21 +46,55 @@ function readRNXMetroModuleIdentity(bundleText) {
|
|
|
45
46
|
const footerPrefix = `
|
|
46
47
|
${RNXSIM_METRO_MODULE_PATHS_PREFIX}`;
|
|
47
48
|
const footerStart = withoutMap.lastIndexOf(footerPrefix);
|
|
48
|
-
if (footerStart < 0
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
if (footerStart < 0) return null;
|
|
50
|
+
if (!withoutMap.endsWith(";")) {
|
|
51
|
+
throw new Error("Metro module identity footer is truncated");
|
|
52
|
+
}
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(withoutMap.slice(footerStart + footerPrefix.length, -1));
|
|
56
|
+
} catch {
|
|
57
|
+
throw new Error("Metro module identity footer is not valid JSON");
|
|
58
|
+
}
|
|
52
59
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
53
|
-
|
|
60
|
+
throw new Error("Metro module identity footer is malformed");
|
|
61
|
+
}
|
|
62
|
+
const version = Reflect.get(parsed, "version");
|
|
63
|
+
if (version === void 0) return null;
|
|
64
|
+
const identitySource = Reflect.get(parsed, "identitySource");
|
|
65
|
+
const parsedModulePaths = Reflect.get(parsed, "modulePaths");
|
|
66
|
+
const parsedLogicalSpecifiers = Reflect.get(parsed, "logicalSpecifiers");
|
|
67
|
+
if (version !== RNX_METRO_MODULE_IDENTITY_VERSION || identitySource !== "rnx-plugin" && identitySource !== "contrast-bundler" && identitySource !== "metro-source-map" || typeof parsedModulePaths !== "object" || parsedModulePaths === null || Array.isArray(parsedModulePaths) || typeof parsedLogicalSpecifiers !== "object" || parsedLogicalSpecifiers === null || Array.isArray(parsedLogicalSpecifiers)) {
|
|
68
|
+
throw new Error("Metro module identity footer is malformed");
|
|
54
69
|
}
|
|
55
70
|
const modulePaths = {};
|
|
56
|
-
for (const [moduleId, modulePath] of Object.entries(
|
|
57
|
-
if (typeof modulePath !== "string")
|
|
71
|
+
for (const [moduleId, modulePath] of Object.entries(parsedModulePaths)) {
|
|
72
|
+
if (typeof modulePath !== "string") {
|
|
73
|
+
throw new Error(`Metro module identity has an invalid path for ${moduleId}`);
|
|
74
|
+
}
|
|
58
75
|
modulePaths[moduleId] = modulePath;
|
|
59
76
|
}
|
|
77
|
+
const logicalSpecifiers = {};
|
|
78
|
+
for (const [moduleId, specifiers] of Object.entries(parsedLogicalSpecifiers)) {
|
|
79
|
+
if (!Array.isArray(specifiers) || specifiers.length === 0 || !specifiers.every(
|
|
80
|
+
(specifier) => typeof specifier === "string" && specifier.length > 0
|
|
81
|
+
)) {
|
|
82
|
+
throw new Error(`Metro module identity has invalid specifiers for ${moduleId}`);
|
|
83
|
+
}
|
|
84
|
+
const unique = [...new Set(specifiers)].sort(
|
|
85
|
+
(left, right) => left.localeCompare(right)
|
|
86
|
+
);
|
|
87
|
+
if (unique.length !== specifiers.length) {
|
|
88
|
+
throw new Error(`Metro module identity repeats a specifier for ${moduleId}`);
|
|
89
|
+
}
|
|
90
|
+
logicalSpecifiers[moduleId] = unique;
|
|
91
|
+
}
|
|
60
92
|
return {
|
|
61
93
|
source: withoutMap.slice(0, footerStart),
|
|
94
|
+
version,
|
|
95
|
+
identitySource,
|
|
62
96
|
modulePaths,
|
|
97
|
+
logicalSpecifiers,
|
|
63
98
|
sourceMappingUrl: detached.sourceMappingUrl
|
|
64
99
|
};
|
|
65
100
|
}
|
|
@@ -114,7 +149,7 @@ function readDefineTail(source, start, end) {
|
|
|
114
149
|
while (idEnd > start && /\s/.test(source[idEnd])) idEnd--;
|
|
115
150
|
if (source[idEnd] !== ",") return null;
|
|
116
151
|
let idStart = idEnd;
|
|
117
|
-
while (idStart > start && /[0-9a-fA-FxX
|
|
152
|
+
while (idStart > start && /[0-9a-fA-FxX.+-]/.test(source[idStart - 1])) idStart--;
|
|
118
153
|
const literal = source.slice(idStart, idEnd);
|
|
119
154
|
if (!/^-?(?:0[xXbBoO][0-9a-fA-F]+|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)$/.test(literal)) {
|
|
120
155
|
return null;
|
|
@@ -217,13 +252,25 @@ function validateRNXMetroModulePaths(source, modulePaths) {
|
|
|
217
252
|
}
|
|
218
253
|
}
|
|
219
254
|
}
|
|
255
|
+
function validateRNXMetroModuleIdentity(identity) {
|
|
256
|
+
validateRNXMetroModulePaths(identity.source, identity.modulePaths);
|
|
257
|
+
for (const moduleId of Object.keys(identity.logicalSpecifiers)) {
|
|
258
|
+
if (!Object.prototype.hasOwnProperty.call(identity.modulePaths, moduleId)) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`Metro module identity has logical specifiers for unknown module ${moduleId}`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
220
265
|
export {
|
|
221
|
-
|
|
222
|
-
|
|
266
|
+
RNX_METRO_MODULE_IDENTITY_VERSION,
|
|
267
|
+
appendRNXMetroModuleIdentityFooter,
|
|
268
|
+
createRNXMetroModuleIdentityFooter,
|
|
223
269
|
detachRNXMetroSourceMapUrl,
|
|
224
270
|
readRNXMetroBundleLayout,
|
|
225
271
|
readRNXMetroModuleIdentity,
|
|
226
272
|
toRNXDevelopmentBundleUrl,
|
|
227
273
|
toRNXProductionBundleUrl,
|
|
274
|
+
validateRNXMetroModuleIdentity,
|
|
228
275
|
validateRNXMetroModulePaths
|
|
229
276
|
};
|
package/dist-lib/metro.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.405 | (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;
|
|
@@ -412,6 +412,7 @@ exports.jsxDEV = exports.jsx`,
|
|
|
412
412
|
|
|
413
413
|
// src/metro-production-bundle.ts
|
|
414
414
|
var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
|
|
415
|
+
var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
|
|
415
416
|
function toRNXProductionBundleUrl(bundleUrl) {
|
|
416
417
|
const relative = bundleUrl.startsWith("/");
|
|
417
418
|
const url = new URL(bundleUrl, "http://rnxsim.local");
|
|
@@ -438,13 +439,13 @@ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
|
|
|
438
439
|
if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
|
|
439
440
|
return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
|
|
440
441
|
}
|
|
441
|
-
function
|
|
442
|
-
const payload = JSON.stringify(
|
|
442
|
+
function createRNXMetroModuleIdentityFooter(identity) {
|
|
443
|
+
const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
|
|
443
444
|
return `
|
|
444
445
|
${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
|
|
445
446
|
}
|
|
446
|
-
function
|
|
447
|
-
const footer =
|
|
447
|
+
function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
|
|
448
|
+
const footer = createRNXMetroModuleIdentityFooter(identity);
|
|
448
449
|
const detached = detachRNXMetroSourceMapUrl(bundleText);
|
|
449
450
|
return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
|
|
450
451
|
${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
|
|
@@ -675,7 +676,30 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
|
|
|
675
676
|
if (Object.keys(modulePaths).length !== dependencies.size) {
|
|
676
677
|
throw new Error("rnxsim: bundle module IDs were not unique");
|
|
677
678
|
}
|
|
678
|
-
|
|
679
|
+
const specifiersByModuleId = /* @__PURE__ */ new Map();
|
|
680
|
+
for (const module2 of dependencies.values()) {
|
|
681
|
+
for (const [dependencyKey, dependency] of module2.dependencies ?? []) {
|
|
682
|
+
const specifier = dependency.data?.name ?? dependencyKey;
|
|
683
|
+
if (specifier.length === 0 || specifier.startsWith(".") || specifier.startsWith("/") || typeof dependency.absolutePath !== "string") {
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
const moduleId = String(createModuleId(dependency.absolutePath));
|
|
687
|
+
if (!Object.prototype.hasOwnProperty.call(modulePaths, moduleId)) continue;
|
|
688
|
+
const found = specifiersByModuleId.get(moduleId);
|
|
689
|
+
if (found) found.add(specifier);
|
|
690
|
+
else specifiersByModuleId.set(moduleId, /* @__PURE__ */ new Set([specifier]));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
const logicalSpecifiers = Object.fromEntries(
|
|
694
|
+
[...specifiersByModuleId].sort(([left], [right]) => Number(left) - Number(right)).map(([moduleId, specifiers]) => [moduleId, [...specifiers].sort()])
|
|
695
|
+
);
|
|
696
|
+
const identity = {
|
|
697
|
+
version: RNX_METRO_MODULE_IDENTITY_VERSION,
|
|
698
|
+
identitySource: "rnx-plugin",
|
|
699
|
+
modulePaths,
|
|
700
|
+
logicalSpecifiers
|
|
701
|
+
};
|
|
702
|
+
return typeof result === "string" ? appendRNXMetroModuleIdentityFooter(result, identity) : { ...result, code: appendRNXMetroModuleIdentityFooter(result.code, identity) };
|
|
679
703
|
}
|
|
680
704
|
function withRNX(config, options = {}) {
|
|
681
705
|
if (!options.devServer && !options.open && !options.productionBundles && !options.developmentBundles) {
|
package/dist-lib/profiles.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.405 | (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.405 | (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.405 | (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.405 | (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.405 | (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.405 | (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.405 | (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);
|