peachsim 0.1.577 → 0.1.579
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/LICENSE +1 -1
- package/README.md +11 -9
- package/cli/app-catalog.ts +77 -0
- package/cli/app-fonts.ts +4 -20
- package/cli/app-splash.ts +2 -18
- package/cli/bridge-flow-runner.ts +505 -139
- package/cli/cloud-client.ts +1 -4
- package/cli/cloud-session.ts +1 -4
- package/cli/cloud-test-result-files.ts +3 -0
- package/cli/cloud-test-tunnel.ts +2 -5
- package/cli/command-registry.ts +2 -0
- package/cli/commands/agent.ts +149 -23
- package/cli/commands/assert.ts +1 -4
- package/cli/commands/box/peach-command.ts +62 -0
- package/cli/commands/box/plane-share.ts +0 -70
- package/cli/commands/box/rnx-command.ts +1 -60
- package/cli/commands/box/search-command.ts +14 -0
- package/cli/commands/box.ts +2 -2
- package/cli/commands/control.ts +121 -27
- package/cli/commands/cpu-profile.ts +23 -10
- package/cli/commands/daemon.ts +1 -9
- package/cli/commands/detox.ts +26 -18
- package/cli/commands/device.ts +129 -1
- package/cli/commands/film.ts +25 -16
- package/cli/commands/flow.ts +9 -2
- package/cli/commands/inspect/actions.ts +75 -1
- package/cli/commands/inspect/core.ts +81 -2
- package/cli/commands/inspect/describe.ts +2 -6
- package/cli/commands/inspect/env.ts +1 -1
- package/cli/commands/inspect/settling.ts +20 -3
- package/cli/commands/inspect/shared.ts +1 -4
- package/cli/commands/inspect/sleep.ts +1 -1
- package/cli/commands/inspect.ts +16 -49
- package/cli/commands/install-desktop.ts +8 -6
- package/cli/commands/login.ts +3 -5
- package/cli/commands/maestro-generate.ts +1 -4
- package/cli/commands/maestro.ts +38 -21
- package/cli/commands/no-bridge-hint.ts +0 -14
- package/cli/commands/permissions.ts +2 -2
- package/cli/commands/platform.ts +13 -6
- package/cli/commands/screenshot.ts +6 -1
- package/cli/commands/skills.ts +1 -1
- package/cli/commands/test.ts +6 -2
- package/cli/commands/three-mode.ts +162 -19
- package/cli/commands/upload.ts +3 -18
- package/cli/current-sim.ts +0 -1
- package/cli/desktop-companion.ts +40 -8
- package/cli/drivers/playwright-provisioning.ts +1 -4
- package/cli/flow-export.ts +1 -8
- package/cli/flow-session.ts +0 -4
- package/cli/hints.ts +1 -16
- package/cli/inspect-notice-state.ts +0 -4
- package/cli/main.ts +2 -4
- package/cli/outbound-endpoints.ts +1 -24
- package/cli/parse-args.ts +1 -2
- package/cli/rnx-in-process.ts +3 -1
- package/cli/run-rnx-core.ts +4 -2
- package/cli/run-rnx.ts +18 -10
- package/cli/send-to-box.ts +1 -4
- package/cli/telemetry.ts +1 -1
- package/cli/ws-bridge.ts +1 -5
- package/detox/gestures.ts +20 -6
- package/detox/index.ts +379 -123
- package/detox/navigation-lifecycle.ts +22 -13
- package/dist-lib/agent-daemon-client.cjs +21 -15
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +3 -17
- package/dist-lib/agent-sessions.cjs +5 -4
- package/dist-lib/attached-projects.cjs +1 -77
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +11 -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 -5
- package/dist-lib/bridge-contract-input.mjs +7 -5
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/bridge-contract.mjs +1 -1
- package/dist-lib/capture-contract.cjs +30 -7
- package/dist-lib/capture-contract.mjs +30 -7
- 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-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +17 -11
- package/dist-lib/cloud.mjs +17 -11
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +321 -122
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +427 -212
- package/dist-lib/host/fetch-proxy-handler.cjs +5 -28
- 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 +315 -58
- 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 +67 -31
- package/dist-lib/menu.mjs +64 -28
- package/dist-lib/metro-fingerprint-registry.cjs +8 -4
- package/dist-lib/metro-fingerprint-registry.mjs +6 -4
- package/dist-lib/metro-production-bundle.cjs +2 -2
- package/dist-lib/metro-production-bundle.mjs +2 -2
- package/dist-lib/metro.cjs +8 -4
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +7 -4
- 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 +3 -13
- package/dist-lib/scripts/dev-server-scanner.cjs +5 -17
- package/dist-lib/sdk.cjs +129 -10
- package/dist-lib/sdk.mjs +127 -10
- package/dist-lib/skills.cjs +1635 -1121
- package/dist-lib/swift-compile.cjs +277 -70
- package/dist-lib/swift-compile.mjs +275 -70
- package/dist-lib/swift-package.cjs +17 -5
- package/dist-lib/swift-package.mjs +15 -4
- package/dist-lib/swift-submit.cjs +32 -8
- package/dist-lib/swift-submit.mjs +29 -7
- package/dist-lib/swift.cjs +30912 -577
- package/dist-lib/vite-kotlin.cjs +356 -0
- package/dist-lib/vite-swift.cjs +1743 -0
- package/dist-lib/vite.cjs +208 -1039
- package/kotlin/README.md +18 -0
- package/kotlin/Sources/androidx/annotation/Keep.kt +4 -0
- package/kotlin/Sources/dev/onejs/one/OneNativeSourceDispatch.kt +7 -0
- package/kotlin/Sources/dev/onejs/one/source/OneModule.kt +4 -0
- package/kotlin/Sources/org/json/JSON.kt +244 -0
- package/kotlin/toolchain.json +19 -0
- package/package.json +14 -2
- package/scripts/dev-server-scanner.ts +0 -18
- package/scripts/optional-demo-registry.ts +0 -17
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-setup/SKILL.md +16 -0
- package/src/agent-daemon-client.ts +36 -22
- package/src/agent-identity.ts +0 -15
- package/src/agent-prompt.ts +12 -0
- package/src/attached-projects.ts +0 -72
- package/src/backend-origin.ts +10 -0
- package/src/bridge-contract-input.ts +2 -5
- package/src/bridge-contract.ts +2 -0
- package/src/capture-contract.ts +53 -11
- package/src/cloud.ts +4 -9
- package/src/dev-server-open.ts +0 -99
- package/src/home-paths.ts +2 -3
- package/src/host/agent-host.ts +82 -36
- package/src/host/bridge-host.ts +5 -11
- package/src/host/fetch-proxy-handler.ts +19 -43
- package/src/is-record.ts +4 -0
- package/src/menu.ts +82 -37
- package/src/metro-fingerprint-registry.ts +1 -4
- package/src/metro-production-bundle.ts +1 -1
- package/src/plist.ts +1 -4
- package/src/public-brand.ts +5 -3
- package/src/render-mode.ts +0 -12
- package/src/runtime-assets.ts +9 -2
- package/src/screenshots/compose.ts +7 -1
- package/src/screenshots/frame-compose.ts +21 -10
- package/src/screenshots/schema.ts +1 -4
- package/src/sim-client.ts +2 -4
- package/src/skills/builtin/maestro-test.ts +1 -4
- package/src/sleep.ts +4 -0
- package/src/swift-compile.ts +209 -47
- package/src/swift-icu.ts +140 -0
- package/src/swift-package.ts +26 -2
- package/src/swift-submit.ts +84 -4
- package/src/swift.ts +2 -0
- package/src/vite-plugin-kotlin.ts +376 -0
- package/src/vite-plugin-one.ts +224 -36
- package/src/vite-plugin-swift.ts +382 -96
- package/src/vite-plugin.ts +121 -134
- package/src/vite.d.ts +10 -0
- package/cli/resolve-assets.ts +0 -63
- package/src/rolldown-plugin-swift.ts +0 -244
- package/src/team-machine-prompt.ts +0 -73
|
@@ -1,20 +1,118 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.579 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/swift-compile.ts
|
|
4
|
-
import { execFile } from "node:child_process";
|
|
5
|
-
import { createHash } from "node:crypto";
|
|
4
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
5
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6
6
|
import {
|
|
7
7
|
existsSync,
|
|
8
8
|
mkdirSync,
|
|
9
|
-
readFileSync,
|
|
9
|
+
readFileSync as readFileSync2,
|
|
10
10
|
readdirSync,
|
|
11
11
|
realpathSync,
|
|
12
12
|
rmSync,
|
|
13
13
|
statSync,
|
|
14
14
|
writeFileSync
|
|
15
15
|
} from "node:fs";
|
|
16
|
+
import os from "node:os";
|
|
17
|
+
import path2 from "node:path";
|
|
18
|
+
import { promisify as promisify2 } from "node:util";
|
|
19
|
+
|
|
20
|
+
// src/swift-icu.ts
|
|
21
|
+
import { execFile } from "node:child_process";
|
|
22
|
+
import { createHash } from "node:crypto";
|
|
23
|
+
import { readFileSync } from "node:fs";
|
|
16
24
|
import path from "node:path";
|
|
17
25
|
import { promisify } from "node:util";
|
|
26
|
+
import { gzip } from "node:zlib";
|
|
27
|
+
var run = promisify(execFile);
|
|
28
|
+
var deflate = promisify(gzip);
|
|
29
|
+
var ARCHIVE = "wasi/lib_FoundationICU.a";
|
|
30
|
+
var MEMBER = "icu_packaged_data.cpp.obj";
|
|
31
|
+
var raw = /* @__PURE__ */ new Map();
|
|
32
|
+
var assets = /* @__PURE__ */ new Map();
|
|
33
|
+
function memo(cache, key, load2) {
|
|
34
|
+
let pending = cache.get(key);
|
|
35
|
+
if (!pending) {
|
|
36
|
+
pending = load2();
|
|
37
|
+
pending.catch(() => cache.delete(key));
|
|
38
|
+
cache.set(key, pending);
|
|
39
|
+
}
|
|
40
|
+
return pending;
|
|
41
|
+
}
|
|
42
|
+
function swiftIcuData(toolchainBin, release) {
|
|
43
|
+
return memo(raw, `${toolchainBin}\0${release}`, () => load(toolchainBin, release));
|
|
44
|
+
}
|
|
45
|
+
function swiftIcuAsset(toolchainBin, release) {
|
|
46
|
+
return memo(assets, `${toolchainBin}\0${release}`, async () => {
|
|
47
|
+
const zipped = await deflate(await swiftIcuData(toolchainBin, release));
|
|
48
|
+
return { sha256: createHash("sha256").update(zipped).digest("hex"), gzip: zipped };
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function load(toolchainBin, release) {
|
|
52
|
+
const { stdout } = await run(path.join(toolchainBin, "swift"), [
|
|
53
|
+
"sdk",
|
|
54
|
+
"configure",
|
|
55
|
+
"--show-configuration",
|
|
56
|
+
`${release}_wasm`,
|
|
57
|
+
"wasm32-unknown-wasip1"
|
|
58
|
+
]);
|
|
59
|
+
const resources = /^swiftStaticResourcesPath: (.+)$/m.exec(stdout)?.[1]?.trim();
|
|
60
|
+
if (!resources) throw new Error(`swift-icu: ${release}_wasm names no static resources`);
|
|
61
|
+
return Buffer.from(
|
|
62
|
+
icuSegment(archiveMember(readFileSync(path.join(resources, ARCHIVE)), MEMBER))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
function archiveMember(archive, name) {
|
|
66
|
+
if (archive.toString("latin1", 0, 8) !== "!<arch>\n")
|
|
67
|
+
throw new Error("swift-icu: not an ar archive");
|
|
68
|
+
let names = "";
|
|
69
|
+
for (let at = 8; at + 60 <= archive.length; ) {
|
|
70
|
+
const raw2 = archive.toString("latin1", at, at + 16).trimEnd();
|
|
71
|
+
const size = Number(archive.toString("latin1", at + 48, at + 58).trim());
|
|
72
|
+
const body = archive.subarray(at + 60, at + 60 + size);
|
|
73
|
+
if (raw2 === "//") names = body.toString("latin1");
|
|
74
|
+
const member = /^\/\d+$/.test(raw2) ? names.slice(Number(raw2.slice(1)), names.indexOf("/\n", Number(raw2.slice(1)))) : raw2.replace(/\/$/, "");
|
|
75
|
+
if (member === name) return body;
|
|
76
|
+
at += 60 + size + size % 2;
|
|
77
|
+
}
|
|
78
|
+
throw new Error(`swift-icu: ${name} is not in the sdk's icu archive`);
|
|
79
|
+
}
|
|
80
|
+
function icuSegment(object) {
|
|
81
|
+
let at = 8;
|
|
82
|
+
const leb = () => {
|
|
83
|
+
let result = 0;
|
|
84
|
+
let shift = 0;
|
|
85
|
+
let byte;
|
|
86
|
+
do {
|
|
87
|
+
byte = object[at++];
|
|
88
|
+
result += (byte & 127) * 2 ** shift;
|
|
89
|
+
shift += 7;
|
|
90
|
+
} while (byte & 128);
|
|
91
|
+
return result;
|
|
92
|
+
};
|
|
93
|
+
const found = [];
|
|
94
|
+
while (at < object.length) {
|
|
95
|
+
const id = object[at++];
|
|
96
|
+
const size = leb();
|
|
97
|
+
const end = at + size;
|
|
98
|
+
if (id === 11) {
|
|
99
|
+
for (let count = leb(); count > 0; count--) {
|
|
100
|
+
if (leb() !== 0) throw new Error("swift-icu: unexpected data segment kind");
|
|
101
|
+
at++;
|
|
102
|
+
leb();
|
|
103
|
+
at++;
|
|
104
|
+
const length = leb();
|
|
105
|
+
const bytes = object.subarray(at, at + length);
|
|
106
|
+
if (bytes[2] === 218 && bytes[3] === 39) found.push(bytes);
|
|
107
|
+
at += length;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
at = end;
|
|
111
|
+
}
|
|
112
|
+
if (found.length !== 1)
|
|
113
|
+
throw new Error(`swift-icu: expected one icu data segment, found ${found.length}`);
|
|
114
|
+
return found[0];
|
|
115
|
+
}
|
|
18
116
|
|
|
19
117
|
// src/swift-package.ts
|
|
20
118
|
function swiftManifestTargets(manifest) {
|
|
@@ -25,7 +123,8 @@ function swiftManifestTargets(manifest) {
|
|
|
25
123
|
while ((match = pattern.exec(code)) !== null) {
|
|
26
124
|
const executable = match[1] === "executableTarget";
|
|
27
125
|
let depth = 1;
|
|
28
|
-
|
|
126
|
+
const start = pattern.lastIndex;
|
|
127
|
+
let i = start;
|
|
29
128
|
let inString = false;
|
|
30
129
|
let escaped = false;
|
|
31
130
|
let flat = "";
|
|
@@ -54,26 +153,67 @@ function swiftManifestTargets(manifest) {
|
|
|
54
153
|
if (!name) continue;
|
|
55
154
|
const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
|
|
56
155
|
const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
57
|
-
|
|
156
|
+
const call = code.slice(start, i);
|
|
157
|
+
const languageMode = Number(
|
|
158
|
+
/\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
|
|
159
|
+
);
|
|
160
|
+
const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
|
|
161
|
+
targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
|
|
58
162
|
}
|
|
59
163
|
return targets;
|
|
60
164
|
}
|
|
165
|
+
function swiftPackagePartition(manifest) {
|
|
166
|
+
const targets = swiftManifestTargets(manifest);
|
|
167
|
+
return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
|
|
168
|
+
}
|
|
61
169
|
|
|
62
170
|
// src/swift-compile.ts
|
|
63
|
-
var
|
|
171
|
+
var run2 = promisify2(execFile2);
|
|
64
172
|
var WASM_TRIPLE = "wasm32-unknown-wasip1";
|
|
173
|
+
var cores = os.availableParallelism();
|
|
174
|
+
var BUILD_ENV = { ...process.env, BINARYEN_CORES: String(Math.min(4, cores)) };
|
|
175
|
+
var BUILD_JOBS = String(Math.max(1, Math.floor(cores / 2)));
|
|
65
176
|
function swiftModuleInputFiles(root) {
|
|
66
|
-
const files = [
|
|
177
|
+
const files = [
|
|
178
|
+
"Package.swift",
|
|
179
|
+
"scripts/contrast-app-Package.swift",
|
|
180
|
+
"toolchain.json"
|
|
181
|
+
];
|
|
67
182
|
const walk = (dir) => {
|
|
68
|
-
for (const entry of readdirSync(
|
|
183
|
+
for (const entry of readdirSync(path2.join(root, dir), { withFileTypes: true })) {
|
|
69
184
|
const relative = `${dir}/${entry.name}`;
|
|
70
185
|
if (entry.isDirectory()) walk(relative);
|
|
71
|
-
else if (entry.name
|
|
186
|
+
else if (/\.(swift|c|h)$/.test(entry.name)) files.push(relative);
|
|
72
187
|
}
|
|
73
188
|
};
|
|
74
189
|
walk("Sources");
|
|
75
190
|
return files.sort();
|
|
76
191
|
}
|
|
192
|
+
async function ensureMacroPlugins(moduleRoot, toolchainBin) {
|
|
193
|
+
const dir = path2.join(moduleRoot, ".build/host/RnxPreviewMacros");
|
|
194
|
+
const ext = process.platform === "darwin" ? "dylib" : "so";
|
|
195
|
+
const plugins = [
|
|
196
|
+
{
|
|
197
|
+
library: path2.join(dir, `libRnxPreviewMacros.${ext}`),
|
|
198
|
+
source: path2.join(moduleRoot, "Sources/RnxPreviewMacros/PreviewMacro.swift")
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
library: path2.join(dir, `libFoundationMacros.${ext}`),
|
|
202
|
+
source: path2.join(moduleRoot, "Sources/FoundationMacros/PredicateMacro.swift")
|
|
203
|
+
}
|
|
204
|
+
];
|
|
205
|
+
const stale = plugins.some(
|
|
206
|
+
({ library, source }) => !existsSync(library) || statSync(source).mtimeMs > statSync(library).mtimeMs
|
|
207
|
+
);
|
|
208
|
+
if (stale) {
|
|
209
|
+
await run2("sh", [
|
|
210
|
+
path2.join(moduleRoot, "scripts/build-preview-plugin.sh"),
|
|
211
|
+
toolchainBin,
|
|
212
|
+
plugins[0].library
|
|
213
|
+
]);
|
|
214
|
+
}
|
|
215
|
+
return plugins.map(({ library }) => library);
|
|
216
|
+
}
|
|
77
217
|
var linkedModuleDigests = /* @__PURE__ */ new Map();
|
|
78
218
|
function clearLinkedModuleDigests(root) {
|
|
79
219
|
if (root === void 0) linkedModuleDigests.clear();
|
|
@@ -81,9 +221,9 @@ function clearLinkedModuleDigests(root) {
|
|
|
81
221
|
}
|
|
82
222
|
function linkedModuleDigest(root) {
|
|
83
223
|
const files = swiftModuleInputFiles(root);
|
|
84
|
-
const stampHash =
|
|
224
|
+
const stampHash = createHash2("sha256");
|
|
85
225
|
for (const file of files) {
|
|
86
|
-
const stat = statSync(
|
|
226
|
+
const stat = statSync(path2.join(root, file), { bigint: true });
|
|
87
227
|
stampHash.update(file);
|
|
88
228
|
stampHash.update(
|
|
89
229
|
`${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}
|
|
@@ -93,11 +233,11 @@ function linkedModuleDigest(root) {
|
|
|
93
233
|
const stamp = stampHash.digest("hex");
|
|
94
234
|
const cached = linkedModuleDigests.get(root);
|
|
95
235
|
if (cached?.stamp === stamp) return cached.digest;
|
|
96
|
-
const hash =
|
|
236
|
+
const hash = createHash2("sha256");
|
|
97
237
|
for (const file of files) {
|
|
98
|
-
hash.update(
|
|
238
|
+
hash.update(createHash2("sha256").update(file).digest());
|
|
99
239
|
hash.update(
|
|
100
|
-
|
|
240
|
+
createHash2("sha256").update(readFileSync2(path2.join(root, file))).digest()
|
|
101
241
|
);
|
|
102
242
|
}
|
|
103
243
|
const digest = hash.digest();
|
|
@@ -106,7 +246,22 @@ function linkedModuleDigest(root) {
|
|
|
106
246
|
}
|
|
107
247
|
function compileTargets(input) {
|
|
108
248
|
const manifest = input.files["Package.swift"];
|
|
109
|
-
return manifest === void 0 ? [] :
|
|
249
|
+
return manifest === void 0 ? [] : swiftPackagePartition(manifest);
|
|
250
|
+
}
|
|
251
|
+
function withNativeSourceGlue(input, glue) {
|
|
252
|
+
const targets = compileTargets(input);
|
|
253
|
+
if (targets.length > 1) {
|
|
254
|
+
throw new Error("swift native modules need one SwiftPM target");
|
|
255
|
+
}
|
|
256
|
+
const targetPath = targets[0]?.path === "." ? "" : targets[0]?.path ?? "";
|
|
257
|
+
return {
|
|
258
|
+
...input,
|
|
259
|
+
files: {
|
|
260
|
+
...input.files,
|
|
261
|
+
[path2.posix.join(targetPath, "OneNativeSource.generated.swift")]: glue
|
|
262
|
+
},
|
|
263
|
+
oneModule: true
|
|
264
|
+
};
|
|
110
265
|
}
|
|
111
266
|
function swiftSiblingDependencies(files, targets) {
|
|
112
267
|
const names = new Set(targets.map((target) => target.name));
|
|
@@ -116,7 +271,9 @@ function swiftSiblingDependencies(files, targets) {
|
|
|
116
271
|
const deps = /* @__PURE__ */ new Set();
|
|
117
272
|
for (const [file, contents] of Object.entries(files)) {
|
|
118
273
|
if (file === "Package.swift" || !file.startsWith(prefix)) continue;
|
|
119
|
-
for (const match of contents.matchAll(
|
|
274
|
+
for (const match of contents.matchAll(
|
|
275
|
+
/^\s*(?:@\w+(?:\([^)]*\))?\s+)*import\s+(?:(?:typealias|struct|class|enum|protocol|let|var|func)\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm
|
|
276
|
+
)) {
|
|
120
277
|
if (names.has(match[1]) && match[1] !== target.name) deps.add(match[1]);
|
|
121
278
|
}
|
|
122
279
|
}
|
|
@@ -124,29 +281,32 @@ function swiftSiblingDependencies(files, targets) {
|
|
|
124
281
|
}
|
|
125
282
|
return siblings;
|
|
126
283
|
}
|
|
127
|
-
var
|
|
284
|
+
var ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")';
|
|
285
|
+
var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
|
|
286
|
+
var MULTI_MANIFEST_VERSION = 5;
|
|
128
287
|
function swiftArtifactHash(input, release, moduleRoot) {
|
|
129
|
-
const hash =
|
|
288
|
+
const hash = createHash2("sha256");
|
|
130
289
|
hash.update(`swift-compile/v1
|
|
131
290
|
${release}
|
|
132
291
|
`);
|
|
292
|
+
if (input.oneModule) hash.update("one-module\n");
|
|
133
293
|
hash.update(linkedModuleDigest(moduleRoot));
|
|
134
294
|
for (const file of Object.keys(input.files).sort()) {
|
|
135
|
-
hash.update(
|
|
136
|
-
hash.update(
|
|
295
|
+
hash.update(createHash2("sha256").update(file).digest());
|
|
296
|
+
hash.update(createHash2("sha256").update(input.files[file]).digest());
|
|
137
297
|
}
|
|
138
298
|
for (const base of Object.keys(input.resources ?? {}).sort()) {
|
|
139
|
-
hash.update(
|
|
299
|
+
hash.update(createHash2("sha256").update(base).digest());
|
|
140
300
|
hash.update(
|
|
141
|
-
|
|
301
|
+
createHash2("sha256").update(input.resources?.[base] ?? "").digest()
|
|
142
302
|
);
|
|
143
303
|
}
|
|
144
304
|
for (const name of Object.keys(input.images ?? {}).sort()) {
|
|
145
305
|
const image = input.images?.[name];
|
|
146
306
|
if (!image) continue;
|
|
147
|
-
hash.update(
|
|
148
|
-
hash.update(
|
|
149
|
-
hash.update(
|
|
307
|
+
hash.update(createHash2("sha256").update(name).digest());
|
|
308
|
+
hash.update(createHash2("sha256").update(image.file).digest());
|
|
309
|
+
hash.update(createHash2("sha256").update(image.data).digest());
|
|
150
310
|
}
|
|
151
311
|
const targets = compileTargets(input);
|
|
152
312
|
if (targets.length > 0) {
|
|
@@ -164,13 +324,15 @@ ${release}
|
|
|
164
324
|
return hash.digest("hex");
|
|
165
325
|
}
|
|
166
326
|
function emitSwiftPackageManifest(args) {
|
|
167
|
-
const { targets, siblings, moduleRoot } = args;
|
|
327
|
+
const { targets, siblings, moduleRoot, oneModule } = args;
|
|
168
328
|
const executable = targets.find((target) => target.executable);
|
|
169
329
|
if (!executable) throw new Error("swift-compile: no executable target to emit");
|
|
170
|
-
const swiftSettings = 'swiftSettings: [.swiftLanguageMode(.v5), .unsafeFlags(["-Osize"])]';
|
|
171
330
|
const stanza = (target) => {
|
|
331
|
+
const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
|
|
332
|
+
const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
|
|
172
333
|
const deps = [
|
|
173
334
|
'.product(name: "SwiftUI", package: "sootsim-swift")',
|
|
335
|
+
...oneModule ? [ONE_PRODUCT] : [],
|
|
174
336
|
...(siblings.get(target.name) ?? []).map((sibling) => `"${sibling}"`)
|
|
175
337
|
].join(", ");
|
|
176
338
|
const kind = target.executable ? ".executableTarget" : ".target";
|
|
@@ -192,7 +354,7 @@ function emitSwiftPackageManifest(args) {
|
|
|
192
354
|
].join("\n");
|
|
193
355
|
};
|
|
194
356
|
return [
|
|
195
|
-
"// swift-tools-version: 6.
|
|
357
|
+
"// swift-tools-version: 6.2",
|
|
196
358
|
"import PackageDescription",
|
|
197
359
|
"",
|
|
198
360
|
"// generated by swift-compile from the project package partition.",
|
|
@@ -207,42 +369,63 @@ function emitSwiftPackageManifest(args) {
|
|
|
207
369
|
""
|
|
208
370
|
].join("\n");
|
|
209
371
|
}
|
|
372
|
+
function syncSwiftTree(base, files) {
|
|
373
|
+
mkdirSync(base, { recursive: true });
|
|
374
|
+
const walk = (dir) => {
|
|
375
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
376
|
+
const full = path2.join(dir, entry.name);
|
|
377
|
+
if (dir === base && entry.name === ".build") continue;
|
|
378
|
+
if (entry.isDirectory()) walk(full);
|
|
379
|
+
else if (!files.has(full)) rmSync(full, { force: true });
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
walk(base);
|
|
383
|
+
for (const [full, contents] of files) {
|
|
384
|
+
if (existsSync(full) && readFileSync2(full, "utf8") === contents) continue;
|
|
385
|
+
mkdirSync(path2.dirname(full), { recursive: true });
|
|
386
|
+
writeFileSync(full, contents, "utf8");
|
|
387
|
+
}
|
|
388
|
+
}
|
|
210
389
|
function writeSwiftProject(layout, input, moduleRoot) {
|
|
211
390
|
const targets = compileTargets(input);
|
|
391
|
+
const files = /* @__PURE__ */ new Map();
|
|
212
392
|
if (targets.length === 0) {
|
|
213
|
-
rmSync(layout.sources, { recursive: true, force: true });
|
|
214
393
|
for (const [file, contents] of Object.entries(input.files)) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
writeFileSync(target, contents, "utf8");
|
|
394
|
+
if (file === "Package.swift") continue;
|
|
395
|
+
files.set(path2.join(layout.sources, file), contents);
|
|
218
396
|
}
|
|
219
|
-
|
|
220
|
-
|
|
397
|
+
let manifest = readFileSync2(
|
|
398
|
+
path2.join(moduleRoot, "scripts/contrast-app-Package.swift"),
|
|
221
399
|
"utf8"
|
|
222
400
|
).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
401
|
+
if (input.oneModule) {
|
|
402
|
+
const product = '.product(name: "CoreLocation", package: "sootsim-swift"),';
|
|
403
|
+
const flags = '"-Osize"';
|
|
404
|
+
if (!manifest.includes(product) || !manifest.includes(flags)) {
|
|
405
|
+
throw new Error(
|
|
406
|
+
"scripts/contrast-app-Package.swift lost the lines the One module links at"
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
manifest = manifest.replace(product, `${product}
|
|
410
|
+
${ONE_PRODUCT},`).replace(flags, `${flags}${ONE_IMPLICIT_FLAGS}`);
|
|
411
|
+
}
|
|
412
|
+
files.set(path2.join(layout.root, "Package.swift"), manifest);
|
|
413
|
+
} else {
|
|
414
|
+
for (const [file, contents] of Object.entries(input.files)) {
|
|
415
|
+
if (file === "Package.swift") continue;
|
|
416
|
+
files.set(path2.join(layout.root, file), contents);
|
|
417
|
+
}
|
|
418
|
+
files.set(
|
|
419
|
+
path2.join(layout.root, "Package.swift"),
|
|
420
|
+
emitSwiftPackageManifest({
|
|
421
|
+
targets,
|
|
422
|
+
siblings: swiftSiblingDependencies(input.files, targets),
|
|
423
|
+
moduleRoot,
|
|
424
|
+
oneModule: input.oneModule
|
|
425
|
+
})
|
|
426
|
+
);
|
|
236
427
|
}
|
|
237
|
-
|
|
238
|
-
path.join(layout.root, "Package.swift"),
|
|
239
|
-
emitSwiftPackageManifest({
|
|
240
|
-
targets,
|
|
241
|
-
siblings: swiftSiblingDependencies(input.files, targets),
|
|
242
|
-
moduleRoot
|
|
243
|
-
}),
|
|
244
|
-
"utf8"
|
|
245
|
-
);
|
|
428
|
+
syncSwiftTree(layout.root, files);
|
|
246
429
|
}
|
|
247
430
|
function streamText(value) {
|
|
248
431
|
if (typeof value === "string") return value.trim();
|
|
@@ -260,18 +443,24 @@ function outputOf(error) {
|
|
|
260
443
|
return error instanceof Error ? error.message : String(error);
|
|
261
444
|
}
|
|
262
445
|
function builtArtifact(layout) {
|
|
263
|
-
const binDir =
|
|
264
|
-
const
|
|
265
|
-
|
|
446
|
+
const binDir = path2.join(layout.root, ".build", WASM_TRIPLE, "release");
|
|
447
|
+
const manifest = readFileSync2(path2.join(layout.root, "Package.swift"), "utf8");
|
|
448
|
+
const executable = swiftManifestTargets(manifest).find((target) => target.executable);
|
|
449
|
+
if (executable === void 0) {
|
|
450
|
+
throw new Error("swift-compile: the written manifest names no executable target");
|
|
451
|
+
}
|
|
452
|
+
const file = path2.join(binDir, `${executable.name}.wasm`);
|
|
453
|
+
if (!existsSync(file)) {
|
|
454
|
+
const found = existsSync(binDir) ? readdirSync(binDir).filter((name) => name.endsWith(".wasm")).sort() : [];
|
|
266
455
|
throw new Error(
|
|
267
|
-
`swift-compile: the build produced ${
|
|
456
|
+
`swift-compile: the build produced no ${executable.name}.wasm (found: ${found.join(", ") || "none"})`
|
|
268
457
|
);
|
|
269
458
|
}
|
|
270
|
-
return
|
|
459
|
+
return file;
|
|
271
460
|
}
|
|
272
461
|
function projectDiagnostic(output, layout) {
|
|
273
462
|
const base = layout.multi ? layout.root : layout.sources;
|
|
274
|
-
const prefix = `${base}${
|
|
463
|
+
const prefix = `${base}${path2.sep}`;
|
|
275
464
|
return output.split("\n").map((line) => line.startsWith(prefix) ? line.slice(prefix.length) : line).join("\n").trim();
|
|
276
465
|
}
|
|
277
466
|
var ROOT_LOCKS = Symbol.for("peachsim.swiftCompile.rootLocks");
|
|
@@ -290,26 +479,30 @@ function serialize(root, work) {
|
|
|
290
479
|
function compileSwiftProjectUnit(input, options) {
|
|
291
480
|
mkdirSync(options.buildRoot, { recursive: true });
|
|
292
481
|
const root = realpathSync(options.buildRoot);
|
|
293
|
-
const moduleRoot =
|
|
482
|
+
const moduleRoot = path2.resolve(options.moduleRoot);
|
|
294
483
|
const layout = {
|
|
295
484
|
root,
|
|
296
|
-
sources:
|
|
485
|
+
sources: path2.join(root, "Sources", "App"),
|
|
297
486
|
multi: compileTargets(input).length > 0
|
|
298
487
|
};
|
|
299
488
|
const hash = swiftArtifactHash(input, options.release, moduleRoot);
|
|
300
489
|
return serialize(root, async () => {
|
|
301
490
|
writeSwiftProject(layout, input, moduleRoot);
|
|
302
|
-
const swift =
|
|
491
|
+
const swift = path2.join(options.toolchainBin, "swift");
|
|
303
492
|
if (!existsSync(swift)) {
|
|
304
493
|
throw new Error(
|
|
305
494
|
`swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
|
|
306
495
|
);
|
|
307
496
|
}
|
|
497
|
+
const macroPlugins = await ensureMacroPlugins(moduleRoot, options.toolchainBin);
|
|
498
|
+
const icu = swiftIcuAsset(options.toolchainBin, options.release);
|
|
308
499
|
try {
|
|
309
|
-
await
|
|
500
|
+
await run2(
|
|
310
501
|
swift,
|
|
311
502
|
[
|
|
312
503
|
"build",
|
|
504
|
+
"-j",
|
|
505
|
+
BUILD_JOBS,
|
|
313
506
|
"--package-path",
|
|
314
507
|
root,
|
|
315
508
|
"--swift-sdk",
|
|
@@ -317,14 +510,24 @@ function compileSwiftProjectUnit(input, options) {
|
|
|
317
510
|
"-c",
|
|
318
511
|
"release",
|
|
319
512
|
"-Xswiftc",
|
|
320
|
-
"-Osize"
|
|
513
|
+
"-Osize",
|
|
514
|
+
...macroPlugins.flatMap((plugin) => [
|
|
515
|
+
"-Xswiftc",
|
|
516
|
+
"-load-plugin-library",
|
|
517
|
+
"-Xswiftc",
|
|
518
|
+
plugin
|
|
519
|
+
])
|
|
321
520
|
],
|
|
322
|
-
{ maxBuffer: 64 * 1024 * 1024, timeout: options.timeoutMs }
|
|
521
|
+
{ env: BUILD_ENV, maxBuffer: 64 * 1024 * 1024, timeout: options.timeoutMs }
|
|
323
522
|
);
|
|
324
523
|
} catch (error) {
|
|
325
524
|
throw new Error(projectDiagnostic(outputOf(error), layout), { cause: error });
|
|
326
525
|
}
|
|
327
|
-
return {
|
|
526
|
+
return {
|
|
527
|
+
hash,
|
|
528
|
+
bytes: readFileSync2(builtArtifact(layout)),
|
|
529
|
+
icu: await icu
|
|
530
|
+
};
|
|
328
531
|
});
|
|
329
532
|
}
|
|
330
533
|
export {
|
|
@@ -334,6 +537,8 @@ export {
|
|
|
334
537
|
compileTargets,
|
|
335
538
|
emitSwiftPackageManifest,
|
|
336
539
|
swiftArtifactHash,
|
|
540
|
+
swiftIcuAsset,
|
|
337
541
|
swiftModuleInputFiles,
|
|
542
|
+
withNativeSourceGlue,
|
|
338
543
|
writeSwiftProject
|
|
339
544
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.579 | (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;
|
|
@@ -23,7 +23,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
23
23
|
var swift_package_exports = {};
|
|
24
24
|
__export(swift_package_exports, {
|
|
25
25
|
isSwiftManifestFile: () => isSwiftManifestFile,
|
|
26
|
-
swiftManifestTargets: () => swiftManifestTargets
|
|
26
|
+
swiftManifestTargets: () => swiftManifestTargets,
|
|
27
|
+
swiftPackagePartition: () => swiftPackagePartition
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(swift_package_exports);
|
|
29
30
|
function isSwiftManifestFile(file) {
|
|
@@ -38,7 +39,8 @@ function swiftManifestTargets(manifest) {
|
|
|
38
39
|
while ((match = pattern.exec(code)) !== null) {
|
|
39
40
|
const executable = match[1] === "executableTarget";
|
|
40
41
|
let depth = 1;
|
|
41
|
-
|
|
42
|
+
const start = pattern.lastIndex;
|
|
43
|
+
let i = start;
|
|
42
44
|
let inString = false;
|
|
43
45
|
let escaped = false;
|
|
44
46
|
let flat = "";
|
|
@@ -67,12 +69,22 @@ function swiftManifestTargets(manifest) {
|
|
|
67
69
|
if (!name) continue;
|
|
68
70
|
const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
|
|
69
71
|
const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
70
|
-
|
|
72
|
+
const call = code.slice(start, i);
|
|
73
|
+
const languageMode = Number(
|
|
74
|
+
/\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
|
|
75
|
+
);
|
|
76
|
+
const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
|
|
77
|
+
targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
|
|
71
78
|
}
|
|
72
79
|
return targets;
|
|
73
80
|
}
|
|
81
|
+
function swiftPackagePartition(manifest) {
|
|
82
|
+
const targets = swiftManifestTargets(manifest);
|
|
83
|
+
return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
|
|
84
|
+
}
|
|
74
85
|
// Annotate the CommonJS export names for ESM import in node:
|
|
75
86
|
0 && (module.exports = {
|
|
76
87
|
isSwiftManifestFile,
|
|
77
|
-
swiftManifestTargets
|
|
88
|
+
swiftManifestTargets,
|
|
89
|
+
swiftPackagePartition
|
|
78
90
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.579 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
|
|
3
3
|
// src/swift-package.ts
|
|
4
4
|
function isSwiftManifestFile(file) {
|
|
@@ -13,7 +13,8 @@ function swiftManifestTargets(manifest) {
|
|
|
13
13
|
while ((match = pattern.exec(code)) !== null) {
|
|
14
14
|
const executable = match[1] === "executableTarget";
|
|
15
15
|
let depth = 1;
|
|
16
|
-
|
|
16
|
+
const start = pattern.lastIndex;
|
|
17
|
+
let i = start;
|
|
17
18
|
let inString = false;
|
|
18
19
|
let escaped = false;
|
|
19
20
|
let flat = "";
|
|
@@ -42,11 +43,21 @@ function swiftManifestTargets(manifest) {
|
|
|
42
43
|
if (!name) continue;
|
|
43
44
|
const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
|
|
44
45
|
const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
45
|
-
|
|
46
|
+
const call = code.slice(start, i);
|
|
47
|
+
const languageMode = Number(
|
|
48
|
+
/\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
|
|
49
|
+
);
|
|
50
|
+
const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
|
|
51
|
+
targets.push({ name, path: targetPath, executable, languageMode, mainActorIsolation });
|
|
46
52
|
}
|
|
47
53
|
return targets;
|
|
48
54
|
}
|
|
55
|
+
function swiftPackagePartition(manifest) {
|
|
56
|
+
const targets = swiftManifestTargets(manifest);
|
|
57
|
+
return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
|
|
58
|
+
}
|
|
49
59
|
export {
|
|
50
60
|
isSwiftManifestFile,
|
|
51
|
-
swiftManifestTargets
|
|
61
|
+
swiftManifestTargets,
|
|
62
|
+
swiftPackagePartition
|
|
52
63
|
};
|