peachsim 0.1.570 → 0.1.571

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.
Files changed (79) hide show
  1. package/README.md +2 -2
  2. package/cli/bridge-flow-runner.ts +15 -7
  3. package/cli/cloud-dispatch.ts +1 -0
  4. package/cli/cloud-test-result-files.ts +97 -0
  5. package/cli/commands/maestro.ts +123 -31
  6. package/cli/commands/test.ts +161 -3
  7. package/cli/maestro-report.ts +3 -1
  8. package/cli/outbound-endpoints.ts +2 -0
  9. package/cli/run-registry.ts +2 -1
  10. package/detox/jest-preset.cjs +2 -2
  11. package/dist-lib/agent-daemon-client.cjs +1 -1
  12. package/dist-lib/agent-events.cjs +1 -1
  13. package/dist-lib/agent-identity.cjs +1 -1
  14. package/dist-lib/agent-sessions.cjs +1 -1
  15. package/dist-lib/attached-projects.cjs +1 -1
  16. package/dist-lib/auth/shared-session.cjs +1 -1
  17. package/dist-lib/backend-origin.cjs +1 -1
  18. package/dist-lib/beta.cjs +1 -1
  19. package/dist-lib/beta.mjs +1 -1
  20. package/dist-lib/bridge-constants.cjs +1 -1
  21. package/dist-lib/bridge-contract-input.cjs +1 -1
  22. package/dist-lib/bridge-contract-input.mjs +1 -1
  23. package/dist-lib/bridge-contract.cjs +1 -1
  24. package/dist-lib/bridge-contract.mjs +1 -1
  25. package/dist-lib/capture-contract.cjs +1 -1
  26. package/dist-lib/capture-contract.mjs +1 -1
  27. package/dist-lib/cli-constants.cjs +1 -1
  28. package/dist-lib/cloud-contract.cjs +1 -1
  29. package/dist-lib/cloud-contract.mjs +1 -1
  30. package/dist-lib/cloud-test-args.cjs +116 -0
  31. package/dist-lib/cloud-test-args.mjs +86 -0
  32. package/dist-lib/cloud.cjs +1 -1
  33. package/dist-lib/cloud.mjs +1 -1
  34. package/dist-lib/config.cjs +1 -1
  35. package/dist-lib/detox/index.cjs +1 -1
  36. package/dist-lib/detox/jest-preset.cjs +2 -2
  37. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  38. package/dist-lib/home-paths.cjs +1 -1
  39. package/dist-lib/host/bridge-host.cjs +16 -7
  40. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  41. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  42. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  43. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  44. package/dist-lib/host/websocket-proxy.cjs +1 -1
  45. package/dist-lib/index.cjs +16 -26
  46. package/dist-lib/jump-to-source-babel.cjs +1 -1
  47. package/dist-lib/jump-to-source-native.cjs +1 -1
  48. package/dist-lib/menu.cjs +1 -1
  49. package/dist-lib/menu.mjs +1 -1
  50. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  51. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  52. package/dist-lib/metro-production-bundle.cjs +1 -1
  53. package/dist-lib/metro-production-bundle.mjs +1 -1
  54. package/dist-lib/metro.cjs +1 -1
  55. package/dist-lib/profiles.cjs +1 -1
  56. package/dist-lib/public-brand.cjs +1 -1
  57. package/dist-lib/react-native-host-modules.cjs +1 -1
  58. package/dist-lib/react-native-host-modules.mjs +1 -1
  59. package/dist-lib/render-mode.cjs +1 -1
  60. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  61. package/dist-lib/sdk.cjs +1 -1
  62. package/dist-lib/sdk.mjs +1 -1
  63. package/dist-lib/skills.cjs +119 -106
  64. package/dist-lib/swift-compile.cjs +372 -0
  65. package/dist-lib/swift-compile.mjs +339 -0
  66. package/dist-lib/swift-package.cjs +78 -0
  67. package/dist-lib/swift-package.mjs +52 -0
  68. package/dist-lib/swift-submit.cjs +1 -1
  69. package/dist-lib/swift-submit.mjs +1 -1
  70. package/dist-lib/swift.cjs +1 -1
  71. package/dist-lib/vite.cjs +456 -138
  72. package/package.json +22 -1
  73. package/skills/rnx-test/SKILL.md +3 -3
  74. package/src/cloud-test-args.ts +100 -0
  75. package/src/rolldown-plugin-swift.ts +8 -7
  76. package/src/swift-compile.ts +359 -0
  77. package/src/swift-package.ts +69 -0
  78. package/src/swift-submit.ts +3 -2
  79. package/src/vite-plugin-swift.ts +103 -107
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.570 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.571 | (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;
@@ -40,7 +40,7 @@ __export(vite_plugin_one_exports, {
40
40
  });
41
41
  module.exports = __toCommonJS(vite_plugin_one_exports);
42
42
  var import_fs2 = __toESM(require("fs"), 1);
43
- var import_node_crypto3 = require("node:crypto");
43
+ var import_node_crypto4 = require("node:crypto");
44
44
  var import_path2 = __toESM(require("path"), 1);
45
45
 
46
46
  // src/bridge-constants.ts
@@ -713,10 +713,10 @@ function resolveRuntimeRootForHostname(hostname) {
713
713
  const version = runtimeVersionFromHostname(hostname);
714
714
  return version ? resolveInstalledRuntimeRoot(version) : null;
715
715
  }
716
- function resolveRuntimeRootForRequestHost(host) {
717
- if (!host) return resolveActiveRuntimeRoot();
716
+ function resolveRuntimeRootForRequestHost(host2) {
717
+ if (!host2) return resolveActiveRuntimeRoot();
718
718
  try {
719
- return resolveRuntimeRootForHostname(new URL(`http://${host}`).hostname);
719
+ return resolveRuntimeRootForHostname(new URL(`http://${host2}`).hostname);
720
720
  } catch {
721
721
  return null;
722
722
  }
@@ -757,12 +757,10 @@ function serveRuntimeFile(req, res, fullPath) {
757
757
  }
758
758
 
759
759
  // src/vite-plugin-swift.ts
760
- var import_node_child_process2 = require("node:child_process");
761
- var import_node_crypto2 = require("node:crypto");
762
- var import_node_fs3 = __toESM(require("node:fs"), 1);
760
+ var import_node_crypto3 = require("node:crypto");
761
+ var import_node_fs4 = __toESM(require("node:fs"), 1);
763
762
  var import_node_os2 = __toESM(require("node:os"), 1);
764
- var import_node_path4 = __toESM(require("node:path"), 1);
765
- var import_node_util = require("node:util");
763
+ var import_node_path5 = __toESM(require("node:path"), 1);
766
764
 
767
765
  // ../sootsim-swift/src/bundleAssets.ts
768
766
  var RASTER_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -797,13 +795,13 @@ function imagesetName(contentsPath) {
797
795
  if (!leaf.endsWith(".imageset")) return null;
798
796
  return leaf.slice(0, -".imageset".length) || null;
799
797
  }
800
- function isFlatResourceImage(path8) {
801
- return path8.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path8));
798
+ function isFlatResourceImage(path9) {
799
+ return path9.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path9));
802
800
  }
803
801
  function enumerateBundleImages(paths, readText) {
804
802
  const table = [];
805
803
  const seen = /* @__PURE__ */ new Set();
806
- const catalogs = paths.filter((path8) => baseOf(path8) === "Contents.json");
804
+ const catalogs = paths.filter((path9) => baseOf(path9) === "Contents.json");
807
805
  for (const contentsPath of catalogs) {
808
806
  const name = imagesetName(contentsPath);
809
807
  if (name === null || seen.has(name)) continue;
@@ -823,12 +821,12 @@ function enumerateBundleImages(paths, readText) {
823
821
  seen.add(name);
824
822
  table.push({ name, file: `${dir}/${file}` });
825
823
  }
826
- for (const path8 of paths) {
827
- if (!isFlatResourceImage(path8)) continue;
828
- const name = baseOf(path8).slice(0, -extOf(path8).length);
824
+ for (const path9 of paths) {
825
+ if (!isFlatResourceImage(path9)) continue;
826
+ const name = baseOf(path9).slice(0, -extOf(path9).length);
829
827
  if (name === "" || seen.has(name)) continue;
830
828
  seen.add(name);
831
- table.push({ name, file: path8 });
829
+ table.push({ name, file: path9 });
832
830
  }
833
831
  return table;
834
832
  }
@@ -836,7 +834,7 @@ function enumerateBundleJson(paths) {
836
834
  const found = [];
837
835
  const seen = /* @__PURE__ */ new Set();
838
836
  const ordered = [...paths].filter(
839
- (path8) => path8.split("/").includes("Resources") && path8.split("/").every((segment) => segment !== "" && segment !== "..") && extOf(path8) === ".json"
837
+ (path9) => path9.split("/").includes("Resources") && path9.split("/").every((segment) => segment !== "" && segment !== "..") && extOf(path9) === ".json"
840
838
  ).sort((a, b) => {
841
839
  const aDepth = a.split("/").length;
842
840
  const bDepth = b.split("/").length;
@@ -860,20 +858,322 @@ function swiftEntryModuleEsm(args) {
860
858
  ].join("\n");
861
859
  }
862
860
 
863
- // ../sootsim-swift/toolchain.json
864
- var toolchain_default = {
865
- release: "swift-6.3-RELEASE",
866
- wasmSdkChecksum: "9fa4016ee632c7e9e906608ec3b55cf13dfc4dff44e47574c5af58064dc33fd9"
867
- };
861
+ // src/swift-compile.ts
862
+ var import_node_child_process2 = require("node:child_process");
863
+ var import_node_crypto2 = require("node:crypto");
864
+ var import_node_fs3 = require("node:fs");
865
+ var import_node_path4 = __toESM(require("node:path"), 1);
866
+ var import_node_util = require("node:util");
868
867
 
869
- // src/vite-plugin-swift.ts
868
+ // src/swift-package.ts
869
+ function swiftManifestTargets(manifest) {
870
+ const code = manifest.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
871
+ const targets = [];
872
+ const pattern = /\.(executableTarget|target)\s*\(/g;
873
+ let match;
874
+ while ((match = pattern.exec(code)) !== null) {
875
+ const executable = match[1] === "executableTarget";
876
+ let depth = 1;
877
+ let i = pattern.lastIndex;
878
+ let inString = false;
879
+ let escaped = false;
880
+ let flat = "";
881
+ while (i < code.length && depth > 0) {
882
+ const ch = code[i];
883
+ if (inString) {
884
+ if (escaped) escaped = false;
885
+ else if (ch === "\\") escaped = true;
886
+ else if (ch === '"') inString = false;
887
+ if (depth === 1) flat += ch;
888
+ } else if (ch === '"') {
889
+ inString = true;
890
+ if (depth === 1) flat += ch;
891
+ } else if (ch === "(") {
892
+ depth++;
893
+ if (depth === 1) flat += ch;
894
+ } else if (ch === ")") {
895
+ depth--;
896
+ if (depth >= 1) flat += ch;
897
+ } else if (depth === 1) {
898
+ flat += ch;
899
+ }
900
+ i++;
901
+ }
902
+ const name = /\bname\s*:\s*"([^"]+)"/.exec(flat)?.[1];
903
+ if (!name) continue;
904
+ const rawPath = /\bpath\s*:\s*"([^"]*)"/.exec(flat)?.[1];
905
+ const targetPath = rawPath == null || rawPath === "" ? `Sources/${name}` : rawPath.replace(/^\.\//, "").replace(/\/+$/, "");
906
+ targets.push({ name, path: targetPath, executable });
907
+ }
908
+ return targets;
909
+ }
910
+
911
+ // src/swift-compile.ts
870
912
  var run = (0, import_node_util.promisify)(import_node_child_process2.execFile);
871
- var TOOLCHAIN_BIN = import_node_path4.default.join(
872
- import_node_os2.default.homedir(),
873
- `Library/Developer/Toolchains/${toolchain_default.release}.xctoolchain/usr/bin`
874
- );
875
- var WASM_SDK = `${toolchain_default.release}_wasm`;
876
913
  var WASM_TRIPLE = "wasm32-unknown-wasip1";
914
+ function swiftModuleInputFiles(root) {
915
+ const files = ["Package.swift", "scripts/contrast-app-Package.swift"];
916
+ const walk = (dir) => {
917
+ for (const entry of (0, import_node_fs3.readdirSync)(import_node_path4.default.join(root, dir), { withFileTypes: true })) {
918
+ const relative2 = `${dir}/${entry.name}`;
919
+ if (entry.isDirectory()) walk(relative2);
920
+ else if (entry.name.endsWith(".swift")) files.push(relative2);
921
+ }
922
+ };
923
+ walk("Sources");
924
+ return files.sort();
925
+ }
926
+ var linkedModuleDigests = /* @__PURE__ */ new Map();
927
+ function linkedModuleDigest(root) {
928
+ const files = swiftModuleInputFiles(root);
929
+ const stampHash = (0, import_node_crypto2.createHash)("sha256");
930
+ for (const file of files) {
931
+ const stat = (0, import_node_fs3.statSync)(import_node_path4.default.join(root, file), { bigint: true });
932
+ stampHash.update(file);
933
+ stampHash.update(
934
+ `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}
935
+ `
936
+ );
937
+ }
938
+ const stamp = stampHash.digest("hex");
939
+ const cached = linkedModuleDigests.get(root);
940
+ if (cached?.stamp === stamp) return cached.digest;
941
+ const hash = (0, import_node_crypto2.createHash)("sha256");
942
+ for (const file of files) {
943
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
944
+ hash.update(
945
+ (0, import_node_crypto2.createHash)("sha256").update((0, import_node_fs3.readFileSync)(import_node_path4.default.join(root, file))).digest()
946
+ );
947
+ }
948
+ const digest = hash.digest();
949
+ linkedModuleDigests.set(root, { stamp, digest });
950
+ return digest;
951
+ }
952
+ function compileTargets(input) {
953
+ const manifest = input.files["Package.swift"];
954
+ return manifest === void 0 ? [] : swiftManifestTargets(manifest);
955
+ }
956
+ function swiftSiblingDependencies(files, targets) {
957
+ const names = new Set(targets.map((target) => target.name));
958
+ const siblings = /* @__PURE__ */ new Map();
959
+ for (const target of targets) {
960
+ const prefix = `${target.path}/`;
961
+ const deps = /* @__PURE__ */ new Set();
962
+ for (const [file, contents] of Object.entries(files)) {
963
+ if (file === "Package.swift" || !file.startsWith(prefix)) continue;
964
+ for (const match of contents.matchAll(/^\s*import\s+([A-Za-z_][A-Za-z0-9_]*)/gm)) {
965
+ if (names.has(match[1]) && match[1] !== target.name) deps.add(match[1]);
966
+ }
967
+ }
968
+ siblings.set(target.name, [...deps].sort());
969
+ }
970
+ return siblings;
971
+ }
972
+ var MULTI_MANIFEST_VERSION = 1;
973
+ function swiftArtifactHash(input, release, moduleRoot) {
974
+ const hash = (0, import_node_crypto2.createHash)("sha256");
975
+ hash.update(`swift-compile/v1
976
+ ${release}
977
+ `);
978
+ hash.update(linkedModuleDigest(moduleRoot));
979
+ for (const file of Object.keys(input.files).sort()) {
980
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
981
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(input.files[file]).digest());
982
+ }
983
+ for (const base of Object.keys(input.resources ?? {}).sort()) {
984
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(base).digest());
985
+ hash.update(
986
+ (0, import_node_crypto2.createHash)("sha256").update(input.resources?.[base] ?? "").digest()
987
+ );
988
+ }
989
+ for (const name of Object.keys(input.images ?? {}).sort()) {
990
+ const image = input.images?.[name];
991
+ if (!image) continue;
992
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(name).digest());
993
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(image.file).digest());
994
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(image.data).digest());
995
+ }
996
+ const targets = compileTargets(input);
997
+ if (targets.length > 0) {
998
+ hash.update(`swift-multi/v${MULTI_MANIFEST_VERSION}
999
+ `);
1000
+ hash.update(
1001
+ JSON.stringify({
1002
+ targets,
1003
+ siblings: [...swiftSiblingDependencies(input.files, targets)].sort(
1004
+ (a, b) => String(a) < String(b) ? -1 : String(a) > String(b) ? 1 : 0
1005
+ )
1006
+ })
1007
+ );
1008
+ }
1009
+ return hash.digest("hex");
1010
+ }
1011
+ function emitSwiftPackageManifest(args) {
1012
+ const { targets, siblings, moduleRoot } = args;
1013
+ const executable = targets.find((target) => target.executable);
1014
+ if (!executable) throw new Error("swift-compile: no executable target to emit");
1015
+ const swiftSettings = 'swiftSettings: [.swiftLanguageMode(.v5), .unsafeFlags(["-Osize"])]';
1016
+ const stanza = (target) => {
1017
+ const deps = [
1018
+ '.product(name: "SwiftUI", package: "sootsim-swift")',
1019
+ ...(siblings.get(target.name) ?? []).map((sibling) => `"${sibling}"`)
1020
+ ].join(", ");
1021
+ const kind = target.executable ? ".executableTarget" : ".target";
1022
+ const link = target.executable ? `,
1023
+ linkerSettings: [
1024
+ .unsafeFlags([
1025
+ "-Xclang-linker", "-mexec-model=reactor",
1026
+ "-Xlinker", "--export-if-defined=__main_argc_argv",
1027
+ ]),
1028
+ .unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),
1029
+ ]` : "";
1030
+ return [
1031
+ ` ${kind}(`,
1032
+ ` name: "${target.name}",`,
1033
+ ` dependencies: [${deps}],`,
1034
+ ` path: "${target.path}",`,
1035
+ ` ${swiftSettings}${link}`,
1036
+ ` ),`
1037
+ ].join("\n");
1038
+ };
1039
+ return [
1040
+ "// swift-tools-version: 6.0",
1041
+ "import PackageDescription",
1042
+ "",
1043
+ "// generated by swift-compile from the project package partition.",
1044
+ "let package = Package(",
1045
+ ' name: "app",',
1046
+ ` products: [.executable(name: "${executable.name}", targets: ["${executable.name}"])],`,
1047
+ ` dependencies: [.package(path: "${moduleRoot}")],`,
1048
+ " targets: [",
1049
+ ...targets.map(stanza),
1050
+ " ]",
1051
+ ")",
1052
+ ""
1053
+ ].join("\n");
1054
+ }
1055
+ function writeSwiftProject(layout, input, moduleRoot) {
1056
+ const targets = compileTargets(input);
1057
+ if (targets.length === 0) {
1058
+ (0, import_node_fs3.rmSync)(layout.sources, { recursive: true, force: true });
1059
+ for (const [file, contents] of Object.entries(input.files)) {
1060
+ const target = import_node_path4.default.join(layout.sources, file);
1061
+ (0, import_node_fs3.mkdirSync)(import_node_path4.default.dirname(target), { recursive: true });
1062
+ (0, import_node_fs3.writeFileSync)(target, contents, "utf8");
1063
+ }
1064
+ const manifest = (0, import_node_fs3.readFileSync)(
1065
+ import_node_path4.default.join(moduleRoot, "scripts/contrast-app-Package.swift"),
1066
+ "utf8"
1067
+ ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
1068
+ (0, import_node_fs3.writeFileSync)(import_node_path4.default.join(layout.root, "Package.swift"), manifest, "utf8");
1069
+ return;
1070
+ }
1071
+ (0, import_node_fs3.mkdirSync)(layout.root, { recursive: true });
1072
+ for (const child of (0, import_node_fs3.readdirSync)(layout.root)) {
1073
+ if (child === ".build") continue;
1074
+ (0, import_node_fs3.rmSync)(import_node_path4.default.join(layout.root, child), { recursive: true, force: true });
1075
+ }
1076
+ for (const [file, contents] of Object.entries(input.files)) {
1077
+ if (file === "Package.swift") continue;
1078
+ const target = import_node_path4.default.join(layout.root, file);
1079
+ (0, import_node_fs3.mkdirSync)(import_node_path4.default.dirname(target), { recursive: true });
1080
+ (0, import_node_fs3.writeFileSync)(target, contents, "utf8");
1081
+ }
1082
+ (0, import_node_fs3.writeFileSync)(
1083
+ import_node_path4.default.join(layout.root, "Package.swift"),
1084
+ emitSwiftPackageManifest({
1085
+ targets,
1086
+ siblings: swiftSiblingDependencies(input.files, targets),
1087
+ moduleRoot
1088
+ }),
1089
+ "utf8"
1090
+ );
1091
+ }
1092
+ function streamText(value) {
1093
+ if (typeof value === "string") return value.trim();
1094
+ if (Buffer.isBuffer(value)) return value.toString("utf8").trim();
1095
+ return "";
1096
+ }
1097
+ function outputOf(error) {
1098
+ if (error && typeof error === "object") {
1099
+ const streams = [
1100
+ streamText(Reflect.get(error, "stdout")),
1101
+ streamText(Reflect.get(error, "stderr"))
1102
+ ].filter(Boolean);
1103
+ if (streams.length > 0) return streams.join("\n");
1104
+ }
1105
+ return error instanceof Error ? error.message : String(error);
1106
+ }
1107
+ function builtArtifact(layout) {
1108
+ const binDir = import_node_path4.default.join(layout.root, ".build", WASM_TRIPLE, "release");
1109
+ const artifacts = (0, import_node_fs3.existsSync)(binDir) ? (0, import_node_fs3.readdirSync)(binDir).filter((name) => name.endsWith(".wasm")).sort() : [];
1110
+ if (artifacts.length !== 1) {
1111
+ throw new Error(
1112
+ `swift-compile: the build produced ${artifacts.length} wasm artifacts; exactly one executable is the app`
1113
+ );
1114
+ }
1115
+ return import_node_path4.default.join(binDir, artifacts[0]);
1116
+ }
1117
+ function projectDiagnostic(output, layout) {
1118
+ const base = layout.multi ? layout.root : layout.sources;
1119
+ const prefix = `${base}${import_node_path4.default.sep}`;
1120
+ return output.split("\n").map((line) => line.startsWith(prefix) ? line.slice(prefix.length) : line).join("\n").trim();
1121
+ }
1122
+ var ROOT_LOCKS = Symbol.for("peachsim.swiftCompile.rootLocks");
1123
+ var host = globalThis;
1124
+ var rootLocks = host[ROOT_LOCKS] ??= /* @__PURE__ */ new Map();
1125
+ function serialize(root, work) {
1126
+ const current = rootLocks.get(root) ?? Promise.resolve();
1127
+ const next = current.then(work, work);
1128
+ rootLocks.set(
1129
+ root,
1130
+ next.catch(() => {
1131
+ })
1132
+ );
1133
+ return next;
1134
+ }
1135
+ function compileSwiftProjectUnit(input, options) {
1136
+ (0, import_node_fs3.mkdirSync)(options.buildRoot, { recursive: true });
1137
+ const root = (0, import_node_fs3.realpathSync)(options.buildRoot);
1138
+ const moduleRoot = import_node_path4.default.resolve(options.moduleRoot);
1139
+ const layout = {
1140
+ root,
1141
+ sources: import_node_path4.default.join(root, "Sources", "App"),
1142
+ multi: compileTargets(input).length > 0
1143
+ };
1144
+ const hash = swiftArtifactHash(input, options.release, moduleRoot);
1145
+ return serialize(root, async () => {
1146
+ writeSwiftProject(layout, input, moduleRoot);
1147
+ const swift = import_node_path4.default.join(options.toolchainBin, "swift");
1148
+ if (!(0, import_node_fs3.existsSync)(swift)) {
1149
+ throw new Error(
1150
+ `swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
1151
+ );
1152
+ }
1153
+ try {
1154
+ await run(
1155
+ swift,
1156
+ [
1157
+ "build",
1158
+ "--package-path",
1159
+ root,
1160
+ "--swift-sdk",
1161
+ `${options.release}_wasm`,
1162
+ "-c",
1163
+ "release",
1164
+ "-Xswiftc",
1165
+ "-Osize"
1166
+ ],
1167
+ { maxBuffer: 64 * 1024 * 1024, timeout: options.timeoutMs }
1168
+ );
1169
+ } catch (error) {
1170
+ throw new Error(projectDiagnostic(outputOf(error), layout), { cause: error });
1171
+ }
1172
+ return { hash, bytes: (0, import_node_fs3.readFileSync)(builtArtifact(layout)) };
1173
+ });
1174
+ }
1175
+
1176
+ // src/vite-plugin-swift.ts
877
1177
  var ARTIFACT_PATH = "/__rnx/swift/";
878
1178
  var RESOURCE_PATH = "/__rnx/swift-res/";
879
1179
  var VIRTUAL_PREFIX = "\0rnx-swift:";
@@ -894,11 +1194,11 @@ function projectFor(packagePath) {
894
1194
  function sourceFiles(root) {
895
1195
  const found = [];
896
1196
  const walk = (dir) => {
897
- for (const entry of import_node_fs3.default.readdirSync(dir, { withFileTypes: true })) {
1197
+ for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true })) {
898
1198
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
899
- const full = import_node_path4.default.join(dir, entry.name);
1199
+ const full = import_node_path5.default.join(dir, entry.name);
900
1200
  if (entry.isDirectory()) {
901
- if (full !== root && import_node_fs3.default.existsSync(import_node_path4.default.join(full, "Package.swift"))) continue;
1201
+ if (full !== root && import_node_fs4.default.existsSync(import_node_path5.default.join(full, "Package.swift"))) continue;
902
1202
  walk(full);
903
1203
  } else if (entry.name.endsWith(".swift")) found.push(full);
904
1204
  }
@@ -909,12 +1209,12 @@ function sourceFiles(root) {
909
1209
  function resourceCandidateFiles(root) {
910
1210
  const found = [];
911
1211
  const walk = (dir) => {
912
- for (const entry of import_node_fs3.default.readdirSync(dir, { withFileTypes: true })) {
1212
+ for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true })) {
913
1213
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === ".build")
914
1214
  continue;
915
- const full = import_node_path4.default.join(dir, entry.name);
1215
+ const full = import_node_path5.default.join(dir, entry.name);
916
1216
  if (entry.isDirectory()) {
917
- if (full !== root && import_node_fs3.default.existsSync(import_node_path4.default.join(full, "Package.swift"))) continue;
1217
+ if (full !== root && import_node_fs4.default.existsSync(import_node_path5.default.join(full, "Package.swift"))) continue;
918
1218
  walk(full);
919
1219
  } else {
920
1220
  found.push(full);
@@ -937,19 +1237,20 @@ var RESOURCE_CONTENT_TYPES = {
937
1237
  function buildSwiftResourceTable(project, baseUrl) {
938
1238
  const absolute = resourceCandidateFiles(project.packagePath);
939
1239
  const relative2 = absolute.map(
940
- (file) => import_node_path4.default.relative(project.packagePath, file).split(import_node_path4.default.sep).join(import_node_path4.default.posix.sep)
1240
+ (file) => import_node_path5.default.relative(project.packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep)
941
1241
  );
942
1242
  const byRelative = new Map(absolute.map((file, index) => [relative2[index], file]));
943
1243
  const found = enumerateBundleImages(relative2, (candidate) => {
944
1244
  const file = byRelative.get(candidate);
945
- if (!file || import_node_path4.default.basename(file) !== "Contents.json") return null;
1245
+ if (!file || import_node_path5.default.basename(file) !== "Contents.json") return null;
946
1246
  try {
947
- return import_node_fs3.default.readFileSync(file, "utf8");
1247
+ return import_node_fs4.default.readFileSync(file, "utf8");
948
1248
  } catch {
949
1249
  return null;
950
1250
  }
951
1251
  });
952
1252
  const table = {};
1253
+ const images = {};
953
1254
  const watched = [];
954
1255
  const registered = /* @__PURE__ */ new Map();
955
1256
  for (const { name, file } of found) {
@@ -957,27 +1258,31 @@ function buildSwiftResourceTable(project, baseUrl) {
957
1258
  if (!disk) continue;
958
1259
  let bytes;
959
1260
  try {
960
- bytes = import_node_fs3.default.readFileSync(disk);
1261
+ bytes = import_node_fs4.default.readFileSync(disk);
961
1262
  } catch {
962
1263
  continue;
963
1264
  }
964
- const hash = (0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex").slice(0, 16);
965
- const ext = import_node_path4.default.posix.extname(file).toLowerCase();
1265
+ const hash = (0, import_node_crypto3.createHash)("sha256").update(bytes).digest("hex").slice(0, 16);
1266
+ const ext = import_node_path5.default.posix.extname(file).toLowerCase();
966
1267
  table[name] = `${baseUrl}${RESOURCE_PATH}${hash}${ext}`;
1268
+ images[name] = {
1269
+ file: import_node_path5.default.posix.basename(file),
1270
+ data: bytes.toString("base64")
1271
+ };
967
1272
  watched.push(file);
968
1273
  const contents = file.replace(/\/[^/]+$/, "/Contents.json");
969
1274
  if (byRelative.has(contents)) watched.push(contents);
970
1275
  registered.set(`${hash}${ext}`, disk);
971
1276
  }
972
1277
  project.resourceFiles = registered;
973
- return { table, watched };
1278
+ return { table, images, watched };
974
1279
  }
975
1280
  var BUNDLE_MAX_FILES = 128;
976
1281
  var BUNDLE_MAX_FILE_BYTES = 2 * 1024 * 1024;
977
1282
  var BUNDLE_MAX_TOTAL_BYTES = 8 * 1024 * 1024;
978
1283
  function buildSwiftBundleFiles(packagePath) {
979
1284
  const relative2 = resourceCandidateFiles(packagePath).map(
980
- (file) => import_node_path4.default.relative(packagePath, file).split(import_node_path4.default.sep).join(import_node_path4.default.posix.sep)
1285
+ (file) => import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep)
981
1286
  );
982
1287
  const files = {};
983
1288
  const watched = [];
@@ -987,7 +1292,7 @@ function buildSwiftBundleFiles(packagePath) {
987
1292
  watched.push(file);
988
1293
  let bytes;
989
1294
  try {
990
- bytes = import_node_fs3.default.readFileSync(import_node_path4.default.join(packagePath, ...file.split("/")));
1295
+ bytes = import_node_fs4.default.readFileSync(import_node_path5.default.join(packagePath, ...file.split("/")));
991
1296
  } catch {
992
1297
  continue;
993
1298
  }
@@ -1011,8 +1316,8 @@ function serveSwiftResource(project, key) {
1011
1316
  if (!disk) return null;
1012
1317
  try {
1013
1318
  return {
1014
- bytes: import_node_fs3.default.readFileSync(disk),
1015
- contentType: RESOURCE_CONTENT_TYPES[import_node_path4.default.extname(disk).toLowerCase()] ?? "application/octet-stream"
1319
+ bytes: import_node_fs4.default.readFileSync(disk),
1320
+ contentType: RESOURCE_CONTENT_TYPES[import_node_path5.default.extname(disk).toLowerCase()] ?? "application/octet-stream"
1016
1321
  };
1017
1322
  } catch {
1018
1323
  return null;
@@ -1021,32 +1326,53 @@ function serveSwiftResource(project, key) {
1021
1326
  function linkedModuleRoots(packagePath) {
1022
1327
  let manifest;
1023
1328
  try {
1024
- manifest = import_node_fs3.default.readFileSync(import_node_path4.default.join(packagePath, "Package.swift"), "utf8");
1329
+ manifest = import_node_fs4.default.readFileSync(import_node_path5.default.join(packagePath, "Package.swift"), "utf8");
1025
1330
  } catch {
1026
1331
  return [];
1027
1332
  }
1028
1333
  const roots = /* @__PURE__ */ new Set();
1029
1334
  const dependency = /\.package\(\s*path:\s*"([^"]+)"\s*\)/g;
1030
1335
  for (const match of manifest.replace(/^\s*\/\/.*$/gm, "").matchAll(dependency)) {
1031
- const root = import_node_path4.default.resolve(packagePath, match[1]);
1032
- if (import_node_fs3.default.existsSync(import_node_path4.default.join(root, "Package.swift"))) roots.add(root);
1336
+ const root = import_node_path5.default.resolve(packagePath, match[1]);
1337
+ if (import_node_fs4.default.existsSync(import_node_path5.default.join(root, "Package.swift"))) roots.add(root);
1033
1338
  }
1034
1339
  return [...roots].sort();
1035
1340
  }
1036
1341
  function sourceStamp(packagePath) {
1037
- const hash = (0, import_node_crypto2.createHash)("sha256");
1038
- for (const root of [packagePath, ...linkedModuleRoots(packagePath)]) {
1039
- hash.update(root);
1040
- for (const file of sourceFiles(root).sort()) {
1041
- hash.update(import_node_path4.default.relative(root, file));
1042
- hash.update(String(import_node_fs3.default.statSync(file).mtimeMs));
1342
+ const hash = (0, import_node_crypto3.createHash)("sha256");
1343
+ hash.update(packagePath);
1344
+ const projectInputs = /* @__PURE__ */ new Set([
1345
+ import_node_path5.default.join(packagePath, "Package.swift"),
1346
+ ...sourceFiles(packagePath),
1347
+ ...buildSwiftBundleFiles(packagePath).watched.map(
1348
+ (file) => import_node_path5.default.join(packagePath, ...file.split(import_node_path5.default.posix.sep))
1349
+ ),
1350
+ ...buildSwiftResourceTable(projectFor(packagePath), "").watched.map(
1351
+ (file) => import_node_path5.default.join(packagePath, ...file.split(import_node_path5.default.posix.sep))
1352
+ )
1353
+ ]);
1354
+ for (const file of [...projectInputs].sort()) {
1355
+ hash.update(import_node_path5.default.relative(packagePath, file));
1356
+ hash.update(String(import_node_fs4.default.statSync(file).mtimeMs));
1357
+ }
1358
+ const moduleRoot = linkedModuleRoots(packagePath).find(
1359
+ (root) => import_node_fs4.default.existsSync(import_node_path5.default.join(root, "toolchain.json"))
1360
+ );
1361
+ if (moduleRoot) {
1362
+ hash.update(moduleRoot);
1363
+ for (const relative2 of [
1364
+ ...swiftModuleInputFiles(moduleRoot),
1365
+ "toolchain.json"
1366
+ ].sort()) {
1367
+ hash.update(relative2);
1368
+ hash.update(String(import_node_fs4.default.statSync(import_node_path5.default.join(moduleRoot, relative2)).mtimeMs));
1043
1369
  }
1044
1370
  }
1045
1371
  return hash.digest("hex").slice(0, 16);
1046
1372
  }
1047
1373
  function entryRootId(packagePath, file) {
1048
- const relative2 = import_node_path4.default.relative(packagePath, file).split(import_node_path4.default.sep).join(import_node_path4.default.posix.sep);
1049
- return `${import_node_path4.default.basename(packagePath)}${import_node_path4.default.posix.sep}${relative2}`;
1374
+ const relative2 = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
1375
+ return `${import_node_path5.default.basename(packagePath)}${import_node_path5.default.posix.sep}${relative2}`;
1050
1376
  }
1051
1377
  function serverOrigin() {
1052
1378
  const address = devServer?.httpServer?.address();
@@ -1057,70 +1383,60 @@ function serverOrigin() {
1057
1383
  function artifactUrl(project, artifact) {
1058
1384
  return `${serverOrigin()}${ARTIFACT_PATH}${artifact.hash}.wasm`;
1059
1385
  }
1060
- function builtArtifact(packagePath) {
1061
- const binDir = import_node_path4.default.join(packagePath, ".build", WASM_TRIPLE, "release");
1062
- const artifacts = import_node_fs3.default.existsSync(binDir) ? import_node_fs3.default.readdirSync(binDir).filter((name) => name.endsWith(".wasm")).sort() : [];
1063
- if (artifacts.length !== 1) {
1064
- throw new Error(
1065
- `swift project ${packagePath} built ${artifacts.length} wasm artifacts; exactly one executable is the app`
1066
- );
1386
+ function compileInput(packagePath, entry) {
1387
+ const files = {};
1388
+ for (const file of sourceFiles(packagePath)) {
1389
+ const relative2 = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
1390
+ files[relative2] = import_node_fs4.default.readFileSync(file, "utf8");
1067
1391
  }
1068
- return import_node_path4.default.join(binDir, artifacts[0]);
1069
- }
1070
- function streamText(value) {
1071
- if (typeof value === "string") return value.trim();
1072
- if (Buffer.isBuffer(value)) return value.toString("utf8").trim();
1073
- return "";
1392
+ const manifest = import_node_path5.default.join(packagePath, "Package.swift");
1393
+ if (import_node_fs4.default.existsSync(manifest)) files["Package.swift"] = import_node_fs4.default.readFileSync(manifest, "utf8");
1394
+ const resources = buildSwiftBundleFiles(packagePath).files;
1395
+ const images = buildSwiftResourceTable(projectFor(packagePath), "").images;
1396
+ return {
1397
+ files,
1398
+ resources,
1399
+ images,
1400
+ entry
1401
+ };
1074
1402
  }
1075
- async function compile(packagePath, stamp) {
1076
- const swift = import_node_path4.default.join(TOOLCHAIN_BIN, "swift");
1077
- if (!import_node_fs3.default.existsSync(swift)) {
1403
+ async function compile(packagePath, entry, stamp) {
1404
+ const moduleRoot = linkedModuleRoots(packagePath).find(
1405
+ (root) => import_node_fs4.default.existsSync(import_node_path5.default.join(root, "toolchain.json"))
1406
+ );
1407
+ if (!moduleRoot) {
1078
1408
  throw new Error(
1079
- `no swift.org toolchain at ${TOOLCHAIN_BIN}. install it and the ${WASM_SDK} sdk; see packages/sootsim-swift/README.md`
1409
+ `swift project ${packagePath} has no linked rnx SwiftUI package with toolchain.json`
1080
1410
  );
1081
1411
  }
1082
- try {
1083
- await run(
1084
- swift,
1085
- [
1086
- "build",
1087
- "--package-path",
1088
- packagePath,
1089
- "--swift-sdk",
1090
- WASM_SDK,
1091
- "-c",
1092
- "release",
1093
- "-Xswiftc",
1094
- "-Osize"
1095
- ],
1096
- { maxBuffer: 64 * 1024 * 1024 }
1097
- );
1098
- } catch (error) {
1099
- const streams = error && typeof error === "object" ? [
1100
- streamText(Reflect.get(error, "stdout")),
1101
- streamText(Reflect.get(error, "stderr"))
1102
- ].filter(Boolean) : [];
1103
- const detail = streams.length > 0 ? streams.join("\n") : error instanceof Error ? error.message : String(error);
1104
- throw new Error(`swift build failed for ${packagePath}
1105
- ${detail}`);
1412
+ const toolchain = JSON.parse(
1413
+ import_node_fs4.default.readFileSync(import_node_path5.default.join(moduleRoot, "toolchain.json"), "utf8")
1414
+ );
1415
+ const release = toolchain && typeof toolchain === "object" ? Reflect.get(toolchain, "release") : void 0;
1416
+ if (typeof release !== "string") {
1417
+ throw new Error(`swift toolchain manifest at ${moduleRoot} has no release`);
1106
1418
  }
1107
- const bytes = import_node_fs3.default.readFileSync(builtArtifact(packagePath));
1108
- return {
1109
- hash: (0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex").slice(0, 16),
1110
- bytes,
1111
- stamp
1112
- };
1419
+ const artifact = await compileSwiftProjectUnit(compileInput(packagePath, entry), {
1420
+ buildRoot: process.env.CONTRAST_SWIFT_BUILD_ROOT ?? import_node_path5.default.join(import_node_os2.default.tmpdir(), "contrast-swift-build"),
1421
+ moduleRoot,
1422
+ release,
1423
+ toolchainBin: import_node_path5.default.join(
1424
+ import_node_os2.default.homedir(),
1425
+ `Library/Developer/Toolchains/${release}.xctoolchain/usr/bin`
1426
+ )
1427
+ });
1428
+ return { ...artifact, stamp };
1113
1429
  }
1114
- function artifactFor(project) {
1430
+ function artifactFor(project, entry) {
1115
1431
  const stamp = sourceStamp(project.packagePath);
1116
1432
  if (project.artifact?.stamp === stamp) return Promise.resolve(project.artifact);
1117
1433
  if (project.building) {
1118
1434
  const running = project.building;
1119
1435
  if (running.stamp === stamp) return running.promise;
1120
- const again = () => artifactFor(project);
1436
+ const again = () => artifactFor(project, entry);
1121
1437
  return running.promise.then(again, again);
1122
1438
  }
1123
- const promise = compile(project.packagePath, stamp).then(
1439
+ const promise = compile(project.packagePath, entry, stamp).then(
1124
1440
  (artifact) => {
1125
1441
  project.artifact = artifact;
1126
1442
  project.building = null;
@@ -1135,12 +1451,12 @@ function artifactFor(project) {
1135
1451
  return promise;
1136
1452
  }
1137
1453
  function packageFor(file) {
1138
- let dir = import_node_path4.default.dirname(file);
1454
+ let dir = import_node_path5.default.dirname(file);
1139
1455
  const stop = devServer?.config.root;
1140
1456
  for (; ; ) {
1141
- if (import_node_fs3.default.existsSync(import_node_path4.default.join(dir, "Package.swift"))) return dir;
1142
- if (stop !== void 0 && dir === stop || import_node_path4.default.dirname(dir) === dir) break;
1143
- dir = import_node_path4.default.dirname(dir);
1457
+ if (import_node_fs4.default.existsSync(import_node_path5.default.join(dir, "Package.swift"))) return dir;
1458
+ if (stop !== void 0 && dir === stop || import_node_path5.default.dirname(dir) === dir) break;
1459
+ dir = import_node_path5.default.dirname(dir);
1144
1460
  }
1145
1461
  throw new Error(
1146
1462
  `no Package.swift above ${file}${stop === void 0 ? "" : ` (searched up to ${stop})`}; a .swift import needs a swiftpm package like the one in packages/sootsim-swift/example`
@@ -1164,16 +1480,18 @@ function swiftPlugin(options = {}) {
1164
1480
  async load(id) {
1165
1481
  if (!id.startsWith(VIRTUAL_PREFIX)) return null;
1166
1482
  const file = id.slice(VIRTUAL_PREFIX.length);
1167
- if (!import_node_fs3.default.existsSync(file)) throw new Error(`swift source ${file} no longer exists`);
1483
+ if (!import_node_fs4.default.existsSync(file)) throw new Error(`swift source ${file} no longer exists`);
1168
1484
  const packagePath = options.packagePath ?? packageFor(file);
1169
1485
  const project = projectFor(packagePath);
1486
+ const entry = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
1170
1487
  for (const source of sourceFiles(packagePath)) this.addWatchFile(source);
1488
+ this.addWatchFile(import_node_path5.default.join(packagePath, "Package.swift"));
1171
1489
  for (const root of linkedModuleRoots(packagePath)) {
1172
1490
  for (const source of sourceFiles(root)) this.addWatchFile(source);
1173
1491
  }
1174
1492
  let artifact;
1175
1493
  try {
1176
- artifact = await artifactFor(project);
1494
+ artifact = await artifactFor(project, entry);
1177
1495
  } catch (error) {
1178
1496
  if (!project.artifact) throw error;
1179
1497
  this.warn(error instanceof Error ? error.message : String(error));
@@ -1184,7 +1502,7 @@ function swiftPlugin(options = {}) {
1184
1502
  const built = buildSwiftResourceTable(project, serverOrigin());
1185
1503
  resources = built.table;
1186
1504
  for (const watched of built.watched) {
1187
- this.addWatchFile(import_node_path4.default.join(packagePath, ...watched.split(import_node_path4.default.posix.sep)));
1505
+ this.addWatchFile(import_node_path5.default.join(packagePath, ...watched.split(import_node_path5.default.posix.sep)));
1188
1506
  }
1189
1507
  } catch (error) {
1190
1508
  this.warn(
@@ -1196,7 +1514,7 @@ function swiftPlugin(options = {}) {
1196
1514
  const packed = buildSwiftBundleFiles(packagePath);
1197
1515
  bundleFiles = packed.files;
1198
1516
  for (const watched of packed.watched) {
1199
- this.addWatchFile(import_node_path4.default.join(packagePath, ...watched.split(import_node_path4.default.posix.sep)));
1517
+ this.addWatchFile(import_node_path5.default.join(packagePath, ...watched.split(import_node_path5.default.posix.sep)));
1200
1518
  }
1201
1519
  if (packed.skipped.length > 0) {
1202
1520
  this.warn(
@@ -1255,8 +1573,8 @@ function swiftPlugin(options = {}) {
1255
1573
  }
1256
1574
 
1257
1575
  // src/rolldown-plugin-swift.ts
1258
- var import_node_fs4 = __toESM(require("node:fs"), 1);
1259
- var import_node_path5 = __toESM(require("node:path"), 1);
1576
+ var import_node_fs5 = __toESM(require("node:fs"), 1);
1577
+ var import_node_path6 = __toESM(require("node:path"), 1);
1260
1578
 
1261
1579
  // src/swift-submit.ts
1262
1580
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
@@ -1330,15 +1648,15 @@ function projectFor2(packagePath) {
1330
1648
  function packageFiles(root) {
1331
1649
  const found = [];
1332
1650
  const walk = (dir) => {
1333
- for (const entry of import_node_fs4.default.readdirSync(dir, { withFileTypes: true })) {
1651
+ for (const entry of import_node_fs5.default.readdirSync(dir, { withFileTypes: true })) {
1334
1652
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === ".build")
1335
1653
  continue;
1336
- const full = import_node_path5.default.join(dir, entry.name);
1654
+ const full = import_node_path6.default.join(dir, entry.name);
1337
1655
  if (entry.isDirectory()) {
1338
- if (full !== root && import_node_fs4.default.existsSync(import_node_path5.default.join(full, "Package.swift"))) continue;
1656
+ if (full !== root && import_node_fs5.default.existsSync(import_node_path6.default.join(full, "Package.swift"))) continue;
1339
1657
  walk(full);
1340
1658
  } else {
1341
- found.push(import_node_path5.default.relative(root, full).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep));
1659
+ found.push(import_node_path6.default.relative(root, full).split(import_node_path6.default.sep).join(import_node_path6.default.posix.sep));
1342
1660
  }
1343
1661
  }
1344
1662
  };
@@ -1349,8 +1667,8 @@ function sourceFiles2(packagePath) {
1349
1667
  const files = {};
1350
1668
  for (const relative2 of packageFiles(packagePath)) {
1351
1669
  if (!relative2.endsWith(".swift")) continue;
1352
- files[relative2] = import_node_fs4.default.readFileSync(
1353
- import_node_path5.default.join(packagePath, ...relative2.split("/")),
1670
+ files[relative2] = import_node_fs5.default.readFileSync(
1671
+ import_node_path6.default.join(packagePath, ...relative2.split("/")),
1354
1672
  "utf8"
1355
1673
  );
1356
1674
  }
@@ -1358,20 +1676,20 @@ function sourceFiles2(packagePath) {
1358
1676
  }
1359
1677
  function bundlePack(packagePath) {
1360
1678
  const relative2 = packageFiles(packagePath);
1361
- const disk = (file) => import_node_path5.default.join(packagePath, ...file.split("/"));
1679
+ const disk = (file) => import_node_path6.default.join(packagePath, ...file.split("/"));
1362
1680
  const resources = {};
1363
1681
  const watched = [];
1364
1682
  for (const { base, file } of enumerateBundleJson(relative2)) {
1365
- resources[base] = import_node_fs4.default.readFileSync(disk(file)).toString("base64");
1683
+ resources[base] = import_node_fs5.default.readFileSync(disk(file)).toString("base64");
1366
1684
  watched.push(file);
1367
1685
  }
1368
1686
  const images = {};
1369
1687
  const byRelative = new Map(relative2.map((file) => [file, disk(file)]));
1370
1688
  for (const { name, file } of enumerateBundleImages(relative2, (candidate) => {
1371
1689
  const absolute = byRelative.get(candidate);
1372
- if (!absolute || import_node_path5.default.basename(absolute) !== "Contents.json") return null;
1690
+ if (!absolute || import_node_path6.default.basename(absolute) !== "Contents.json") return null;
1373
1691
  try {
1374
- return import_node_fs4.default.readFileSync(absolute, "utf8");
1692
+ return import_node_fs5.default.readFileSync(absolute, "utf8");
1375
1693
  } catch {
1376
1694
  return null;
1377
1695
  }
@@ -1379,19 +1697,19 @@ function bundlePack(packagePath) {
1379
1697
  const absolute = byRelative.get(file);
1380
1698
  if (!absolute) continue;
1381
1699
  images[name] = {
1382
- file: import_node_path5.default.posix.basename(file),
1383
- data: import_node_fs4.default.readFileSync(absolute).toString("base64")
1700
+ file: import_node_path6.default.posix.basename(file),
1701
+ data: import_node_fs5.default.readFileSync(absolute).toString("base64")
1384
1702
  };
1385
1703
  watched.push(file);
1386
1704
  }
1387
1705
  return { resources, images, watched };
1388
1706
  }
1389
1707
  function packageFor2(file, stop) {
1390
- let dir = import_node_path5.default.dirname(file);
1708
+ let dir = import_node_path6.default.dirname(file);
1391
1709
  for (; ; ) {
1392
- if (import_node_fs4.default.existsSync(import_node_path5.default.join(dir, "Package.swift"))) return dir;
1393
- if (stop !== void 0 && dir === stop || import_node_path5.default.dirname(dir) === dir) break;
1394
- dir = import_node_path5.default.dirname(dir);
1710
+ if (import_node_fs5.default.existsSync(import_node_path6.default.join(dir, "Package.swift"))) return dir;
1711
+ if (stop !== void 0 && dir === stop || import_node_path6.default.dirname(dir) === dir) break;
1712
+ dir = import_node_path6.default.dirname(dir);
1395
1713
  }
1396
1714
  throw new Error(
1397
1715
  `no Package.swift above ${file}; a .swift import needs a swiftpm package like the one in packages/sootsim-swift/example`
@@ -1420,17 +1738,17 @@ function swiftRemotePlugin(options) {
1420
1738
  async load(id) {
1421
1739
  if (!id.startsWith(VIRTUAL_PREFIX2)) return null;
1422
1740
  const file = id.slice(VIRTUAL_PREFIX2.length);
1423
- if (!import_node_fs4.default.existsSync(file)) throw new Error(`swift source ${file} no longer exists`);
1741
+ if (!import_node_fs5.default.existsSync(file)) throw new Error(`swift source ${file} no longer exists`);
1424
1742
  const packagePath = options.packagePath ?? packageFor2(file);
1425
1743
  const project = projectFor2(packagePath);
1426
1744
  const files = sourceFiles2(packagePath);
1427
- const entry = import_node_path5.default.relative(packagePath, file).split(import_node_path5.default.sep).join(import_node_path5.default.posix.sep);
1745
+ const entry = import_node_path6.default.relative(packagePath, file).split(import_node_path6.default.sep).join(import_node_path6.default.posix.sep);
1428
1746
  for (const source of Object.keys(files)) {
1429
- this.addWatchFile(import_node_path5.default.join(packagePath, ...source.split("/")));
1747
+ this.addWatchFile(import_node_path6.default.join(packagePath, ...source.split("/")));
1430
1748
  }
1431
1749
  const pack = bundlePack(packagePath);
1432
1750
  for (const watched of pack.watched) {
1433
- this.addWatchFile(import_node_path5.default.join(packagePath, ...watched.split("/")));
1751
+ this.addWatchFile(import_node_path6.default.join(packagePath, ...watched.split("/")));
1434
1752
  }
1435
1753
  try {
1436
1754
  project.address = await compileSwiftProject(
@@ -1474,7 +1792,7 @@ function rnxPlugin(options = {}) {
1474
1792
  if (options.enabled === false) return;
1475
1793
  const bundleUrl = options.bundleUrl || "/node_modules/one/metro-entry.bundle?platform=ios&dev=true&minify=false";
1476
1794
  const appName = resolveRnxDesktopAppName(options.open, server.config.root);
1477
- const replacementToken = (0, import_node_crypto3.randomUUID)();
1795
+ const replacementToken = (0, import_node_crypto4.randomUUID)();
1478
1796
  const configuredPort = server.config.server.port || 8081;
1479
1797
  const listeningPort = () => {
1480
1798
  const address = server.httpServer?.address();