peachsim 0.1.1620 → 0.1.1625

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 (138) hide show
  1. package/README.md +35 -5
  2. package/cli/app-fonts.ts +2 -1
  3. package/cli/bridge-flow-runner.ts +184 -113
  4. package/cli/cloud-client.ts +68 -57
  5. package/cli/commands/box/search-command.ts +3 -2
  6. package/cli/commands/box.ts +10 -29
  7. package/cli/commands/control.ts +108 -43
  8. package/cli/commands/inspect/settling.ts +57 -20
  9. package/cli/commands/maestro-compare.ts +11 -32
  10. package/cli/commands/platform.ts +71 -36
  11. package/cli/commands/upload.ts +5 -1
  12. package/cli/dev-build-freshness.ts +37 -2
  13. package/cli/drivers/playwright-sim-host.ts +6 -5
  14. package/cli/maestro-accessibility.ts +53 -0
  15. package/cli/maestro-compare.ts +24 -0
  16. package/cli/outbound-endpoints.ts +22 -5
  17. package/cli/parent-pid.ts +0 -9
  18. package/cli/remote-simulators.ts +112 -0
  19. package/cli/remoteSimulatorContract.ts +21 -0
  20. package/detox/expectations.ts +5 -1
  21. package/detox/index.ts +133 -98
  22. package/detox/motion-change.cjs +37 -0
  23. package/detox/motion-change.d.cts +16 -0
  24. package/detox/navigation-lifecycle.ts +22 -4
  25. package/dist-lib/agent-daemon-client.cjs +3 -2
  26. package/dist-lib/agent-events.cjs +1 -1
  27. package/dist-lib/attached-projects.cjs +1 -1
  28. package/dist-lib/auth/shared-session.cjs +3 -2
  29. package/dist-lib/backend-origin.cjs +1 -1
  30. package/dist-lib/beta.cjs +1 -1
  31. package/dist-lib/beta.mjs +1 -1
  32. package/dist-lib/bridge-constants.cjs +1 -1
  33. package/dist-lib/bridge-contract-input.cjs +1 -1
  34. package/dist-lib/bridge-contract-input.mjs +1 -1
  35. package/dist-lib/bridge-contract.cjs +1 -1
  36. package/dist-lib/bridge-contract.mjs +1 -1
  37. package/dist-lib/bundle-channel.cjs +1520 -934
  38. package/dist-lib/capture-contract.cjs +1 -1
  39. package/dist-lib/capture-contract.mjs +1 -1
  40. package/dist-lib/cloud-contract.cjs +1 -1
  41. package/dist-lib/cloud-contract.mjs +1 -1
  42. package/dist-lib/cloud-test-args.cjs +1 -1
  43. package/dist-lib/cloud-test-args.mjs +1 -1
  44. package/dist-lib/cloud.cjs +3 -2
  45. package/dist-lib/cloud.mjs +3 -2
  46. package/dist-lib/config.cjs +5 -4
  47. package/dist-lib/config.mjs +5 -4
  48. package/dist-lib/detox/index.cjs +1021 -364
  49. package/dist-lib/dev-bundle-resolution.cjs +51 -23
  50. package/dist-lib/expo-swift-bundle.cjs +1343 -801
  51. package/dist-lib/expo-swift-metadata.cjs +5 -4
  52. package/dist-lib/expo-swift-metadata.mjs +5 -4
  53. package/dist-lib/home-paths.cjs +1 -1
  54. package/dist-lib/host/bridge-host.cjs +2468 -1341
  55. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  56. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  57. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  58. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  59. package/dist-lib/host/websocket-proxy.cjs +1 -1
  60. package/dist-lib/index.cjs +1262 -300
  61. package/dist-lib/jump-to-source-babel.cjs +1 -1
  62. package/dist-lib/jump-to-source-native.cjs +1 -1
  63. package/dist-lib/kotlin-host.cjs +1 -1
  64. package/dist-lib/menu.cjs +3 -2
  65. package/dist-lib/menu.mjs +3 -2
  66. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  67. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  68. package/dist-lib/metro-production-bundle.cjs +5 -4
  69. package/dist-lib/metro-production-bundle.mjs +5 -4
  70. package/dist-lib/metro.cjs +799 -398
  71. package/dist-lib/native-app-identity-project.cjs +728 -22
  72. package/dist-lib/native-app-identity-project.mjs +727 -22
  73. package/dist-lib/native-app-identity.cjs +224 -9
  74. package/dist-lib/native-app-identity.mjs +222 -8
  75. package/dist-lib/native-firebase-metadata.cjs +5 -4
  76. package/dist-lib/native-firebase-metadata.mjs +5 -4
  77. package/dist-lib/plist.cjs +1 -1
  78. package/dist-lib/plist.mjs +1 -1
  79. package/dist-lib/profiles.cjs +1 -1
  80. package/dist-lib/public-brand.cjs +3 -2
  81. package/dist-lib/react-native-host-modules.cjs +4 -1
  82. package/dist-lib/react-native-host-modules.mjs +4 -1
  83. package/dist-lib/scripts/dev-server-scanner.cjs +94 -28
  84. package/dist-lib/sdk.cjs +89 -24
  85. package/dist-lib/sdk.mjs +89 -24
  86. package/dist-lib/skills.cjs +4391 -2350
  87. package/dist-lib/swift-compile.cjs +328 -142
  88. package/dist-lib/swift-compile.mjs +342 -147
  89. package/dist-lib/swift-package.cjs +1 -1
  90. package/dist-lib/swift-package.mjs +1 -1
  91. package/dist-lib/swift-submit.cjs +1 -1
  92. package/dist-lib/swift-submit.mjs +1 -1
  93. package/dist-lib/swift-toolchain.cjs +1 -1
  94. package/dist-lib/swift.cjs +1 -1
  95. package/dist-lib/vite-swift.cjs +888 -559
  96. package/dist-lib/vite.cjs +68 -14
  97. package/dist-lib/worklet-executable.cjs +25 -2
  98. package/dist-lib/worklet-executable.mjs +25 -2
  99. package/package.json +2 -2
  100. package/scripts/dev-server-scanner.ts +33 -13
  101. package/src/admitted-mac-build.ts +34 -8
  102. package/src/android-app-identity.ts +146 -0
  103. package/src/android-autolinking.ts +75 -0
  104. package/src/android-string-value.ts +36 -0
  105. package/src/android-strings.ts +5 -36
  106. package/src/androidAutolinkingContract.ts +40 -0
  107. package/src/bundleGlobalFooter.ts +26 -7
  108. package/src/codex-client.ts +3 -2
  109. package/src/dev-bundle-resolution.ts +58 -25
  110. package/src/expo-kotlin-host.ts +6 -36
  111. package/src/expo-swift-bundle.ts +17 -12
  112. package/src/expo-swift-host.ts +477 -173
  113. package/src/expoSwiftContract.ts +6 -0
  114. package/src/host/bridge-host.ts +7 -55
  115. package/src/host/staged-host-files.ts +29 -2
  116. package/src/installed-package-versions.ts +54 -14
  117. package/src/launchMetadataContract.ts +24 -0
  118. package/src/metro-plugin.ts +37 -42
  119. package/src/native-app-identity-project.ts +116 -3
  120. package/src/native-app-identity.ts +86 -11
  121. package/src/nitro-compile.ts +2 -5
  122. package/src/nitro-source.ts +147 -63
  123. package/src/process-group.ts +90 -60
  124. package/src/process-output.ts +0 -9
  125. package/src/public-brand.ts +1 -0
  126. package/src/react-native-host-modules.ts +3 -0
  127. package/src/sim-client.ts +6 -4
  128. package/src/swift-compile.ts +176 -28
  129. package/src/swift-distribution.lock.json +37 -11
  130. package/src/swift-distribution.ts +61 -9
  131. package/src/swift-host.ts +58 -27
  132. package/src/swift-objc-standin.ts +13 -0
  133. package/src/swift-standin-emit.ts +1 -1
  134. package/src/swift-standins.ts +17 -5
  135. package/src/vite-plugin.ts +8 -19
  136. package/src/worklet-executable.ts +30 -3
  137. package/src/worklets-babel.ts +35 -14
  138. package/src/xcode-project.ts +10 -0
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1620 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1625 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -36,6 +36,51 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
 
38
38
  // src/process-group.ts
39
+ function listProcessChildren(parents, timeoutMs = 3e3) {
40
+ if (parents.some((pid) => !Number.isInteger(pid) || pid <= 1))
41
+ throw new Error("process inspection requires valid parent pids");
42
+ if (parents.length === 0) return [];
43
+ const deadline = Date.now() + timeoutMs;
44
+ let children;
45
+ if (process.platform === "linux") {
46
+ const lists = [];
47
+ for (const parent of parents) {
48
+ try {
49
+ const tasks = `/proc/${parent}/task`;
50
+ for (const thread of (0, import_node_fs.readdirSync)(tasks)) {
51
+ if (Date.now() >= deadline)
52
+ throw new Error("process descendant inspection exceeded its deadline");
53
+ try {
54
+ lists.push((0, import_node_fs.readFileSync)(`${tasks}/${thread}/children`, "utf8"));
55
+ } catch (error) {
56
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
57
+ throw error;
58
+ }
59
+ }
60
+ } catch (error) {
61
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
62
+ throw error;
63
+ }
64
+ }
65
+ children = lists.join(" ");
66
+ } else {
67
+ const result = (0, import_node_child_process.spawnSync)("pgrep", ["-P", parents.join(",")], {
68
+ encoding: "utf8",
69
+ stdio: ["ignore", "pipe", "pipe"],
70
+ timeout: Math.max(1, timeoutMs),
71
+ killSignal: "SIGKILL"
72
+ });
73
+ if (result.error || result.status !== 0 && result.status !== 1) {
74
+ throw new Error(
75
+ `could not inspect descendants of processes ${parents.join(",")}: ${result.error?.message || result.stderr.trim() || `pgrep exited ${result.status}`}`
76
+ );
77
+ }
78
+ children = result.stdout;
79
+ }
80
+ return [...new Set(children.trim().split(/\s+/).map(Number))].filter(
81
+ (pid) => Number.isInteger(pid) && pid > 1 && !parents.includes(pid)
82
+ );
83
+ }
39
84
  function signalProcessGroup(child, signal) {
40
85
  if (!child.pid) return;
41
86
  try {
@@ -123,36 +168,35 @@ pid ${rootPid}
123
168
  }
124
169
  };
125
170
  }
126
- function runningPids(pids) {
127
- return pids.filter((pid) => {
171
+ function processesHaveExited(pids, pgid) {
172
+ const mayExist = [-pgid, ...pids].some((target) => {
128
173
  try {
129
- process.kill(pid, 0);
174
+ process.kill(target, 0);
130
175
  return true;
131
176
  } catch (error) {
132
- return error instanceof Error && "code" in error && error.code === "EPERM";
177
+ return !(error instanceof Error && "code" in error && error.code === "ESRCH");
133
178
  }
134
179
  });
135
- }
136
- function groupIsEmpty(pgid) {
137
- try {
138
- process.kill(-pgid, 0);
139
- } catch (error) {
140
- if (!(error instanceof Error && "code" in error && error.code === "EPERM"))
141
- return true;
142
- }
143
- const result = (0, import_node_child_process.spawnSync)("ps", ["-A", "-o", "pgid=,stat="], {
180
+ if (!mayExist) return true;
181
+ const result = (0, import_node_child_process.spawnSync)("ps", ["-A", "-o", "pid=,pgid=,stat="], {
144
182
  encoding: "utf8",
145
- stdio: ["ignore", "pipe", "pipe"]
183
+ stdio: ["ignore", "pipe", "pipe"],
184
+ timeout: FORCED_EXIT_TIMEOUT_MS,
185
+ killSignal: "SIGKILL"
146
186
  });
147
187
  if (result.error || result.status !== 0) return false;
188
+ const knownPids = new Set(pids);
148
189
  return !result.stdout.split("\n").some((line) => {
149
- const [group, state] = line.trim().split(/\s+/);
150
- return Number(group) === pgid && state !== void 0 && !state.startsWith("Z");
190
+ const [pid, group, state] = line.trim().split(/\s+/);
191
+ return (Number(group) === pgid || knownPids.has(Number(pid))) && state !== void 0 && !state.startsWith("Z");
151
192
  });
152
193
  }
194
+ function groupIsEmpty(pgid) {
195
+ return processesHaveExited([], pgid);
196
+ }
153
197
  async function waitForExit(pids, pgid, timeoutMs) {
154
198
  const deadline = Date.now() + timeoutMs;
155
- const gone = () => runningPids(pids).length === 0 && groupIsEmpty(pgid);
199
+ const gone = () => processesHaveExited(pids, pgid);
156
200
  while (Date.now() < deadline) {
157
201
  if (gone()) return true;
158
202
  await (0, import_promises.setTimeout)(50);
@@ -185,22 +229,16 @@ async function terminateProcessGroup(child, signal = "SIGTERM", gracefulTimeoutM
185
229
  inspectionError = new Error("process descendant inspection exceeded its deadline");
186
230
  break;
187
231
  }
188
- const result = (0, import_node_child_process.spawnSync)("pgrep", ["-P", parents.join(",")], {
189
- encoding: "utf8",
190
- stdio: ["ignore", "pipe", "pipe"],
191
- timeout: remaining,
192
- killSignal: "SIGKILL"
193
- });
194
- if (result.error || result.status !== 0 && result.status !== 1) {
195
- inspectionError = new Error(
196
- `could not inspect descendants of processes ${parents.join(",")}: ${result.error?.message || result.stderr.trim() || `pgrep exited ${result.status}`}`
197
- );
232
+ let children;
233
+ try {
234
+ children = listProcessChildren(parents, remaining);
235
+ } catch (error) {
236
+ inspectionError = new Error(`could not inspect descendants: ${String(error)}`);
198
237
  break;
199
238
  }
200
239
  const next = [];
201
- for (const line of result.stdout.split("\n")) {
202
- const descendantPid = Number(line.trim());
203
- if (Number.isInteger(descendantPid) && descendantPid > 1 && !descendants.has(descendantPid)) {
240
+ for (const descendantPid of children) {
241
+ if (!descendants.has(descendantPid)) {
204
242
  freeze.record(descendantPid);
205
243
  descendants.add(descendantPid);
206
244
  next.push(descendantPid);
@@ -326,6 +364,61 @@ var init_backend_origin = __esm({
326
364
  }
327
365
  });
328
366
 
367
+ // src/bundleGlobalFooter.ts
368
+ function findBundleFooter(source, prefix) {
369
+ let end = source.length;
370
+ while (end > 0) {
371
+ const newline = source.lastIndexOf("\n", end - 1);
372
+ if (newline < 0) return -1;
373
+ const line = newline + 1;
374
+ if (source.startsWith(prefix, line)) return newline;
375
+ if (!isFooterBlockLine(source, line, end)) return -1;
376
+ end = newline;
377
+ }
378
+ return -1;
379
+ }
380
+ function isFooterBlockLine(source, line, end) {
381
+ return line === end || source.startsWith("globalThis.", line) || source.startsWith("//", line);
382
+ }
383
+ function readFooter(source, prefix, suffix, name2) {
384
+ const start = findBundleFooter(source, prefix);
385
+ if (start < 0) return null;
386
+ const end = source.indexOf("\n", start + 1);
387
+ const line = source.slice(start + 1, end < 0 ? void 0 : end);
388
+ if (!line.endsWith(suffix)) throw new Error(`${name2} footer is truncated`);
389
+ const value = JSON.parse(
390
+ line.slice(prefix.length, suffix ? -suffix.length : void 0)
391
+ );
392
+ if (value === null) throw new Error(`${name2} footer has no metadata`);
393
+ return value;
394
+ }
395
+ function detachFooter(source, prefix, suffix, name2) {
396
+ const start = findBundleFooter(source, prefix);
397
+ if (start < 0) return { source, value: null };
398
+ const value = readFooter(source, prefix, suffix, name2);
399
+ const end = source.indexOf("\n", start + 1);
400
+ return { source: source.slice(0, start) + (end < 0 ? "" : source.slice(end)), value };
401
+ }
402
+ function insertBundleGlobalFooter(source, name2, value) {
403
+ return insertFooter(source, `globalThis.${name2}=`, ";", name2, value);
404
+ }
405
+ function insertBundleMetadataFooter(source, name2, value) {
406
+ return insertFooter(source, `// peach.${name2}=`, "", name2, value);
407
+ }
408
+ function insertFooter(source, prefix, suffix, name2, value) {
409
+ source = detachFooter(source, prefix, suffix, name2).source;
410
+ const json = JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
411
+ const footer = `
412
+ ${prefix}${json}${suffix}`;
413
+ const identity = findBundleFooter(source, "globalThis.__sootsimModulePaths=");
414
+ return identity < 0 ? source + footer : source.slice(0, identity) + footer + source.slice(identity);
415
+ }
416
+ var init_bundleGlobalFooter = __esm({
417
+ "src/bundleGlobalFooter.ts"() {
418
+ "use strict";
419
+ }
420
+ });
421
+
329
422
  // cli/internal-child.ts
330
423
  var RNX_FORKED_SCRIPT_ENV;
331
424
  var init_internal_child = __esm({
@@ -335,13 +428,146 @@ var init_internal_child = __esm({
335
428
  }
336
429
  });
337
430
 
431
+ // src/swift-binary-modules.ts
432
+ function frameworkModules(paths) {
433
+ const modules = /* @__PURE__ */ new Set();
434
+ for (const file of paths) {
435
+ const segment2 = file.split("/").find((part) => part.endsWith(".framework"));
436
+ if (segment2) modules.add(segment2.slice(0, -".framework".length));
437
+ }
438
+ return [...modules].sort();
439
+ }
440
+ async function range(url, spec) {
441
+ const response = await fetch(url, {
442
+ headers: { range: `bytes=${spec}`, "accept-encoding": "identity" },
443
+ signal: AbortSignal.timeout(2e4)
444
+ });
445
+ const match = /^bytes (\d+)-\d+\/(\d+)$/.exec(
446
+ response.headers.get("content-range") ?? ""
447
+ );
448
+ if (response.status !== 206 || !match)
449
+ throw new Error(`${url} answered ${response.status} to a range request`);
450
+ return {
451
+ bytes: Buffer.from(await response.arrayBuffer()),
452
+ start: Number(match[1]),
453
+ total: Number(match[2])
454
+ };
455
+ }
456
+ async function zipEntries(url) {
457
+ const { total } = await range(url, "0-0");
458
+ const tail = await range(url, `${Math.max(0, total - 65558)}-${total - 1}`);
459
+ let end = tail.bytes.length - 22;
460
+ for (; end >= 0; end--)
461
+ if (tail.bytes.readUInt32LE(end) === 101010256 && end + 22 + tail.bytes.readUInt16LE(end + 20) === tail.bytes.length)
462
+ break;
463
+ if (end < 0) throw new Error(`${url} has no zip end record`);
464
+ let size = tail.bytes.readUInt32LE(end + 12);
465
+ let offset = tail.bytes.readUInt32LE(end + 16);
466
+ if (offset === 4294967295 || size === 4294967295) {
467
+ const locator = end - 20;
468
+ if (locator < 0 || tail.bytes.readUInt32LE(locator) !== 117853008)
469
+ throw new Error(`${url} has no zip64 locator`);
470
+ const recordAt = Number(tail.bytes.readBigUInt64LE(locator + 8));
471
+ const record4 = recordAt >= tail.start ? tail.bytes.subarray(recordAt - tail.start) : (await range(url, `${recordAt}-${recordAt + 55}`)).bytes;
472
+ size = Number(record4.readBigUInt64LE(40));
473
+ offset = Number(record4.readBigUInt64LE(48));
474
+ }
475
+ const directory = offset >= tail.start ? tail.bytes.subarray(offset - tail.start, offset - tail.start + size) : (await range(url, `${offset}-${offset + size - 1}`)).bytes;
476
+ const names = [];
477
+ for (let at = 0; at + 46 <= directory.length; ) {
478
+ if (directory.readUInt32LE(at) !== 33639248) break;
479
+ const nameLength = directory.readUInt16LE(at + 28);
480
+ names.push(directory.toString("utf8", at + 46, at + 46 + nameLength));
481
+ at += 46 + nameLength + directory.readUInt16LE(at + 30) + directory.readUInt16LE(at + 32);
482
+ }
483
+ return names;
484
+ }
485
+ function localEntries(dir) {
486
+ if (!import_node_fs2.default.existsSync(dir)) return [];
487
+ return import_node_fs2.default.readdirSync(dir, { withFileTypes: true }).filter((slice) => slice.isDirectory()).flatMap(
488
+ (slice) => import_node_fs2.default.readdirSync(import_node_path2.default.join(dir, slice.name)).map((entry) => `${slice.name}/${entry}`)
489
+ );
490
+ }
491
+ async function swiftBinaryModules(binary) {
492
+ if (!binary.url) return frameworkModules(localEntries(binary.dir));
493
+ const cached2 = import_node_path2.default.join(
494
+ cacheDir,
495
+ `${(0, import_node_crypto.createHash)("sha256").update(`${binary.url}\0${binary.checksum ?? ""}`).digest("hex").slice(0, 32)}.json`
496
+ );
497
+ if (import_node_fs2.default.existsSync(cached2)) {
498
+ const value = JSON.parse(import_node_fs2.default.readFileSync(cached2, "utf8"));
499
+ if (Array.isArray(value) && value.every((name2) => typeof name2 === "string"))
500
+ return value;
501
+ }
502
+ const modules = frameworkModules(await zipEntries(binary.url));
503
+ import_node_fs2.default.mkdirSync(cacheDir, { recursive: true });
504
+ import_node_fs2.default.writeFileSync(cached2, JSON.stringify(modules));
505
+ return modules;
506
+ }
507
+ var import_node_crypto, import_node_fs2, import_node_os2, import_node_path2, cacheDir;
508
+ var init_swift_binary_modules = __esm({
509
+ "src/swift-binary-modules.ts"() {
510
+ "use strict";
511
+ import_node_crypto = require("node:crypto");
512
+ import_node_fs2 = __toESM(require("node:fs"), 1);
513
+ import_node_os2 = __toESM(require("node:os"), 1);
514
+ import_node_path2 = __toESM(require("node:path"), 1);
515
+ cacheDir = import_node_path2.default.join(import_node_os2.default.tmpdir(), "peach-swift-binary-modules");
516
+ }
517
+ });
518
+
338
519
  // src/admitted-mac-build.ts
520
+ function windowAdmission() {
521
+ const result = (0, import_node_child_process2.spawnSync)("tm", ["window", "ancestor", "--json"], {
522
+ encoding: "utf8",
523
+ stdio: ["ignore", "pipe", "inherit"]
524
+ });
525
+ if (result.error) throw result.error;
526
+ if (result.status === 1) return null;
527
+ if (result.status !== 0) throw new Error(`tm window ancestor exited ${result.status}`);
528
+ const entry = JSON.parse(result.stdout);
529
+ if (entry.kind === "external")
530
+ return { kind: "external", name: entry.name ?? "", cores: null };
531
+ if (entry.kind !== "heavy" && entry.kind !== "quiet")
532
+ throw new Error(`tm window ancestor returned kind ${entry.kind}`);
533
+ return {
534
+ kind: entry.kind,
535
+ cores: entry.cores && entry.cores > 0 ? entry.cores : null,
536
+ scopes: entry.scopes ?? []
537
+ };
538
+ }
339
539
  function admittedMacBuilderSlot(env = process.env) {
340
- return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
540
+ if (process.platform !== "darwin" || env.REMOTE_MAC_SLOT_HELD !== "1") return false;
541
+ return windowAdmission() !== null;
341
542
  }
543
+ var import_node_child_process2;
342
544
  var init_admitted_mac_build = __esm({
343
545
  "src/admitted-mac-build.ts"() {
344
546
  "use strict";
547
+ import_node_child_process2 = require("node:child_process");
548
+ }
549
+ });
550
+
551
+ // src/home-paths.ts
552
+ function rnxHomeDir() {
553
+ const override = process.env[PEACH_HOME_ENV];
554
+ if (override && override.length > 0) return import_node_path3.default.resolve(override);
555
+ return import_node_path3.default.join((0, import_node_os3.homedir)(), ".peach");
556
+ }
557
+ function electronDir() {
558
+ return import_node_path3.default.join(rnxHomeDir(), "electron");
559
+ }
560
+ function electronUserDataDir() {
561
+ return import_node_path3.default.join(electronDir(), "userData");
562
+ }
563
+ var import_node_os3, import_node_path3, PEACH_HOME_ENV, DAEMON_LOCKFILE_MAX_BYTES;
564
+ var init_home_paths = __esm({
565
+ "src/home-paths.ts"() {
566
+ "use strict";
567
+ import_node_os3 = require("node:os");
568
+ import_node_path3 = __toESM(require("node:path"), 1);
569
+ PEACH_HOME_ENV = "PEACH_HOME";
570
+ DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
345
571
  }
346
572
  });
347
573
 
@@ -700,9 +926,9 @@ function originalColumn(line, column) {
700
926
  }
701
927
  function designTimeDiagnostic(output, files2) {
702
928
  const rewritten = /* @__PURE__ */ new Map();
703
- const linesOf = (path20) => {
929
+ const linesOf = (path21) => {
704
930
  const file = Object.keys(files2).find(
705
- (name2) => name2.endsWith(".swift") && (path20 === name2 || path20.endsWith(`/${name2}`))
931
+ (name2) => name2.endsWith(".swift") && (path21 === name2 || path21.endsWith(`/${name2}`))
706
932
  );
707
933
  if (file === void 0) return null;
708
934
  let lines = rewritten.get(file);
@@ -876,12 +1102,12 @@ function swiftIcuData(toolchainBin, sdk) {
876
1102
  function swiftIcuAsset(toolchainBin, sdk) {
877
1103
  return memo(assets, `${toolchainBin}\0${sdk}`, async () => {
878
1104
  const zipped = await deflate(await swiftIcuData(toolchainBin, sdk));
879
- return { sha256: (0, import_node_crypto.createHash)("sha256").update(zipped).digest("hex"), gzip: zipped };
1105
+ return { sha256: (0, import_node_crypto2.createHash)("sha256").update(zipped).digest("hex"), gzip: zipped };
880
1106
  });
881
1107
  }
882
1108
  async function load(toolchainBin, sdk) {
883
- const swift = import_node_path2.default.join(toolchainBin, "swift");
884
- if (!(0, import_node_fs2.existsSync)(swift))
1109
+ const swift = import_node_path4.default.join(toolchainBin, "swift");
1110
+ if (!(0, import_node_fs3.existsSync)(swift))
885
1111
  throw new Error(`swift-icu: no swift at ${swift} for the ${sdk} SDK's icu data`);
886
1112
  const { stdout: listed } = await run(swift, ["sdk", "list"]);
887
1113
  if (!listed.split("\n").some((line) => line.trim() === sdk))
@@ -896,7 +1122,7 @@ async function load(toolchainBin, sdk) {
896
1122
  const resources = /^swiftStaticResourcesPath: (.+)$/m.exec(stdout)?.[1]?.trim();
897
1123
  if (!resources) throw new Error(`swift-icu: ${sdk} names no static resources`);
898
1124
  return Buffer.from(
899
- icuSegment(archiveMember((0, import_node_fs2.readFileSync)(import_node_path2.default.join(resources, ARCHIVE)), MEMBER))
1125
+ icuSegment(archiveMember((0, import_node_fs3.readFileSync)(import_node_path4.default.join(resources, ARCHIVE)), MEMBER))
900
1126
  );
901
1127
  }
902
1128
  function archiveMember(archive, name2) {
@@ -950,17 +1176,17 @@ function icuSegment(object) {
950
1176
  throw new Error(`swift-icu: expected one icu data segment, found ${found.length}`);
951
1177
  return found[0];
952
1178
  }
953
- var import_node_child_process2, import_node_crypto, import_node_fs2, import_node_path2, import_node_util, import_node_zlib, run, deflate, ARCHIVE, MEMBER, raw, assets;
1179
+ var import_node_child_process3, import_node_crypto2, import_node_fs3, import_node_path4, import_node_util, import_node_zlib, run, deflate, ARCHIVE, MEMBER, raw, assets;
954
1180
  var init_swift_icu = __esm({
955
1181
  "src/swift-icu.ts"() {
956
1182
  "use strict";
957
- import_node_child_process2 = require("node:child_process");
958
- import_node_crypto = require("node:crypto");
959
- import_node_fs2 = require("node:fs");
960
- import_node_path2 = __toESM(require("node:path"), 1);
1183
+ import_node_child_process3 = require("node:child_process");
1184
+ import_node_crypto2 = require("node:crypto");
1185
+ import_node_fs3 = require("node:fs");
1186
+ import_node_path4 = __toESM(require("node:path"), 1);
961
1187
  import_node_util = require("node:util");
962
1188
  import_node_zlib = require("node:zlib");
963
- run = (0, import_node_util.promisify)(import_node_child_process2.execFile);
1189
+ run = (0, import_node_util.promisify)(import_node_child_process3.execFile);
964
1190
  deflate = (0, import_node_util.promisify)(import_node_zlib.gzip);
965
1191
  ARCHIVE = "wasi/lib_FoundationICU.a";
966
1192
  MEMBER = "icu_packaged_data.cpp.obj";
@@ -1261,7 +1487,7 @@ var init_swiftContract = __esm({
1261
1487
  async function runCompiler(command, args, options, stream = false) {
1262
1488
  const { signal } = options;
1263
1489
  signal?.throwIfAborted();
1264
- const child = (0, import_node_child_process3.spawn)(command, args, {
1490
+ const child = (0, import_node_child_process4.spawn)(command, args, {
1265
1491
  cwd: options.cwd,
1266
1492
  env: options.env,
1267
1493
  detached: true,
@@ -1325,12 +1551,12 @@ async function runCompiler(command, args, options, stream = false) {
1325
1551
  }
1326
1552
  }
1327
1553
  function swiftDistributionAt(root) {
1328
- const file = import_node_path3.default.join(root, SWIFT_DISTRIBUTION_MANIFEST);
1329
- if (!(0, import_node_fs3.existsSync)(file)) return null;
1330
- return parseSwiftDistributionManifest(JSON.parse((0, import_node_fs3.readFileSync)(file, "utf8")));
1554
+ const file = import_node_path5.default.join(root, SWIFT_DISTRIBUTION_MANIFEST);
1555
+ if (!(0, import_node_fs4.existsSync)(file)) return null;
1556
+ return parseSwiftDistributionManifest(JSON.parse((0, import_node_fs4.readFileSync)(file, "utf8")));
1331
1557
  }
1332
1558
  function swiftModuleSdk(root) {
1333
- const pin = swiftDistributionAt(root) ?? JSON.parse((0, import_node_fs3.readFileSync)(import_node_path3.default.join(root, "toolchain.json"), "utf8"));
1559
+ const pin = swiftDistributionAt(root) ?? JSON.parse((0, import_node_fs4.readFileSync)(import_node_path5.default.join(root, "toolchain.json"), "utf8"));
1334
1560
  if (!pin || typeof pin !== "object" || typeof Reflect.get(pin, "wasmSdkId") !== "string" || typeof Reflect.get(pin, "wasmSdkUrl") !== "string" || typeof Reflect.get(pin, "wasmSdkChecksum") !== "string")
1335
1561
  throw new Error(`${root} pins no wasm SDK id, url and checksum`);
1336
1562
  return {
@@ -1352,7 +1578,7 @@ function swiftModuleInputFiles(root) {
1352
1578
  "toolchain.json"
1353
1579
  ];
1354
1580
  const walk2 = (dir) => {
1355
- for (const entry of (0, import_node_fs3.readdirSync)(import_node_path3.default.join(root, dir), {
1581
+ for (const entry of (0, import_node_fs4.readdirSync)(import_node_path5.default.join(root, dir), {
1356
1582
  withFileTypes: true
1357
1583
  })) {
1358
1584
  const relative = `${dir}/${entry.name}`;
@@ -1370,29 +1596,29 @@ function swiftMacroPlugins(moduleRoot) {
1370
1596
  const distribution = swiftDistributionAt(moduleRoot);
1371
1597
  if (distribution)
1372
1598
  return {
1373
- libraries: distribution.plugins.map((plugin) => import_node_path3.default.join(moduleRoot, plugin)),
1599
+ libraries: distribution.plugins.map((plugin) => import_node_path5.default.join(moduleRoot, plugin)),
1374
1600
  stale: false
1375
1601
  };
1376
- const dir = import_node_path3.default.join(moduleRoot, ".build/host/RnxPreviewMacros");
1602
+ const dir = import_node_path5.default.join(moduleRoot, ".build/host/RnxPreviewMacros");
1377
1603
  const release = JSON.parse(
1378
- (0, import_node_fs3.readFileSync)(import_node_path3.default.join(moduleRoot, "toolchain.json"), "utf8")
1604
+ (0, import_node_fs4.readFileSync)(import_node_path5.default.join(moduleRoot, "toolchain.json"), "utf8")
1379
1605
  ).release;
1380
- const compilerStamp = import_node_path3.default.join(dir, "compiler-release");
1606
+ const compilerStamp = import_node_path5.default.join(dir, "compiler-release");
1381
1607
  const ext = process.platform === "darwin" ? "dylib" : "so";
1382
1608
  const plugins = [
1383
1609
  {
1384
- library: import_node_path3.default.join(dir, `libRnxPreviewMacros.${ext}`),
1385
- source: import_node_path3.default.join(moduleRoot, "Sources/RnxPreviewMacros/PreviewMacro.swift")
1610
+ library: import_node_path5.default.join(dir, `libRnxPreviewMacros.${ext}`),
1611
+ source: import_node_path5.default.join(moduleRoot, "Sources/RnxPreviewMacros/PreviewMacro.swift")
1386
1612
  },
1387
1613
  {
1388
- library: import_node_path3.default.join(dir, `libFoundationMacros.${ext}`),
1389
- source: import_node_path3.default.join(moduleRoot, "Sources/FoundationMacros/PredicateMacro.swift")
1614
+ library: import_node_path5.default.join(dir, `libFoundationMacros.${ext}`),
1615
+ source: import_node_path5.default.join(moduleRoot, "Sources/FoundationMacros/PredicateMacro.swift")
1390
1616
  }
1391
1617
  ];
1392
1618
  return {
1393
1619
  libraries: plugins.map(({ library }) => library),
1394
- stale: !(0, import_node_fs3.existsSync)(compilerStamp) || (0, import_node_fs3.readFileSync)(compilerStamp, "utf8").trim() !== release || plugins.some(
1395
- ({ library, source }) => !(0, import_node_fs3.existsSync)(library) || (0, import_node_fs3.statSync)(source).mtimeMs > (0, import_node_fs3.statSync)(library).mtimeMs
1620
+ stale: !(0, import_node_fs4.existsSync)(compilerStamp) || (0, import_node_fs4.readFileSync)(compilerStamp, "utf8").trim() !== release || plugins.some(
1621
+ ({ library, source }) => !(0, import_node_fs4.existsSync)(library) || (0, import_node_fs4.statSync)(source).mtimeMs > (0, import_node_fs4.statSync)(library).mtimeMs
1396
1622
  )
1397
1623
  };
1398
1624
  }
@@ -1402,14 +1628,14 @@ async function ensureMacroPlugins(moduleRoot, toolchainBin, release, signal) {
1402
1628
  await runCompiler(
1403
1629
  "sh",
1404
1630
  [
1405
- import_node_path3.default.join(moduleRoot, "scripts/build-preview-plugin.sh"),
1631
+ import_node_path5.default.join(moduleRoot, "scripts/build-preview-plugin.sh"),
1406
1632
  toolchainBin,
1407
1633
  libraries[0]
1408
1634
  ],
1409
1635
  { signal }
1410
1636
  );
1411
- (0, import_node_fs3.writeFileSync)(
1412
- import_node_path3.default.join(import_node_path3.default.dirname(libraries[0]), "compiler-release"),
1637
+ (0, import_node_fs4.writeFileSync)(
1638
+ import_node_path5.default.join(import_node_path5.default.dirname(libraries[0]), "compiler-release"),
1413
1639
  `${release}
1414
1640
  `
1415
1641
  );
@@ -1418,9 +1644,9 @@ async function ensureMacroPlugins(moduleRoot, toolchainBin, release, signal) {
1418
1644
  }
1419
1645
  function swiftModuleDigest(root) {
1420
1646
  const files2 = swiftModuleInputFiles(root);
1421
- const stampHash = (0, import_node_crypto2.createHash)("sha256");
1647
+ const stampHash = (0, import_node_crypto3.createHash)("sha256");
1422
1648
  for (const file of files2) {
1423
- const stat = (0, import_node_fs3.statSync)(import_node_path3.default.join(root, file), { bigint: true });
1649
+ const stat = (0, import_node_fs4.statSync)(import_node_path5.default.join(root, file), { bigint: true });
1424
1650
  stampHash.update(file);
1425
1651
  stampHash.update(
1426
1652
  `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}
@@ -1430,11 +1656,11 @@ function swiftModuleDigest(root) {
1430
1656
  const stamp = stampHash.digest("hex");
1431
1657
  const cached2 = linkedModuleDigests.get(root);
1432
1658
  if (cached2?.stamp === stamp) return cached2.digest;
1433
- const hash = (0, import_node_crypto2.createHash)("sha256");
1659
+ const hash = (0, import_node_crypto3.createHash)("sha256");
1434
1660
  for (const file of files2) {
1435
- hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
1661
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(file).digest());
1436
1662
  hash.update(
1437
- (0, import_node_crypto2.createHash)("sha256").update((0, import_node_fs3.readFileSync)(import_node_path3.default.join(root, file))).digest()
1663
+ (0, import_node_crypto3.createHash)("sha256").update((0, import_node_fs4.readFileSync)(import_node_path5.default.join(root, file))).digest()
1438
1664
  );
1439
1665
  }
1440
1666
  const digest2 = hash.digest();
@@ -1455,7 +1681,7 @@ function withNativeSourceGlue(input, glue) {
1455
1681
  ...input,
1456
1682
  files: {
1457
1683
  ...input.files,
1458
- [import_node_path3.default.posix.join(targetPath, "OneNativeSource.generated.swift")]: glue
1684
+ [import_node_path5.default.posix.join(targetPath, "OneNativeSource.generated.swift")]: glue
1459
1685
  },
1460
1686
  oneModule: true
1461
1687
  };
@@ -1534,7 +1760,7 @@ function swiftImportNames(contents, available) {
1534
1760
  function swiftPeachModules(moduleRoot) {
1535
1761
  const distribution = swiftDistributionAt(moduleRoot);
1536
1762
  return distribution ? distribution.modules : [
1537
- ...(0, import_node_fs3.readFileSync)(import_node_path3.default.join(moduleRoot, "Package.swift"), "utf8").matchAll(
1763
+ ...(0, import_node_fs4.readFileSync)(import_node_path5.default.join(moduleRoot, "Package.swift"), "utf8").matchAll(
1538
1764
  /\.(?:target|systemLibrary)\(\s*name:\s*"([^"]+)"/g
1539
1765
  )
1540
1766
  ].map((match) => match[1]);
@@ -1544,8 +1770,8 @@ function swiftSdkPaths(moduleRoot, toolchainBin) {
1544
1770
  const key2 = `${toolchainBin}\0${sdk}`;
1545
1771
  const cached2 = sdkPaths.get(key2);
1546
1772
  if (cached2) return cached2;
1547
- const configuration = (0, import_node_child_process3.execFileSync)(
1548
- import_node_path3.default.join(toolchainBin, "swift"),
1773
+ const configuration = (0, import_node_child_process4.execFileSync)(
1774
+ import_node_path5.default.join(toolchainBin, "swift"),
1549
1775
  ["sdk", "configure", "--show-configuration", sdk, "wasm32-unknown-wasip1"],
1550
1776
  { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
1551
1777
  );
@@ -1568,14 +1794,14 @@ function swiftAvailableModules(moduleRoot, toolchainBin) {
1568
1794
  if (cached2) return cached2;
1569
1795
  const modules = new Set(swiftPeachModules(moduleRoot));
1570
1796
  const { resources } = swiftSdkPaths(moduleRoot, toolchainBin);
1571
- for (const entry of (0, import_node_fs3.readdirSync)(import_node_path3.default.join(resources, "wasi"))) {
1797
+ for (const entry of (0, import_node_fs4.readdirSync)(import_node_path5.default.join(resources, "wasi"))) {
1572
1798
  if (entry.endsWith(".swiftmodule"))
1573
1799
  modules.add(entry.slice(0, -".swiftmodule".length));
1574
1800
  }
1575
- for (const entry of (0, import_node_fs3.readdirSync)(resources)) {
1576
- const map = import_node_path3.default.join(resources, entry, "module.modulemap");
1577
- if (!(0, import_node_fs3.existsSync)(map)) continue;
1578
- for (const match of (0, import_node_fs3.readFileSync)(map, "utf8").matchAll(/^module\s+([A-Za-z_]\w*)/gm))
1801
+ for (const entry of (0, import_node_fs4.readdirSync)(resources)) {
1802
+ const map = import_node_path5.default.join(resources, entry, "module.modulemap");
1803
+ if (!(0, import_node_fs4.existsSync)(map)) continue;
1804
+ for (const match of (0, import_node_fs4.readFileSync)(map, "utf8").matchAll(/^module\s+([A-Za-z_]\w*)/gm))
1579
1805
  modules.add(match[1]);
1580
1806
  }
1581
1807
  availableModules.set(key2, modules);
@@ -1617,39 +1843,39 @@ function swiftTargetDependencies(files2, targets) {
1617
1843
  return siblings;
1618
1844
  }
1619
1845
  function swiftArtifactHash(input, release, moduleRoot) {
1620
- const hash = (0, import_node_crypto2.createHash)("sha256");
1621
- hash.update(`swift-compile/v47
1846
+ const hash = (0, import_node_crypto3.createHash)("sha256");
1847
+ hash.update(`swift-compile/v49
1622
1848
  ${release}
1623
1849
  `);
1624
1850
  if (input.oneModule) hash.update("one-module\n");
1625
1851
  hash.update(swiftModuleDigest(moduleRoot));
1626
1852
  for (const file of Object.keys(input.files).sort()) {
1627
- hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
1628
- hash.update((0, import_node_crypto2.createHash)("sha256").update(input.files[file]).digest());
1853
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(file).digest());
1854
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(input.files[file]).digest());
1629
1855
  }
1630
1856
  for (const file of Object.keys(input.metalSources ?? {}).sort()) {
1631
1857
  hash.update("metal-source\n");
1632
- hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
1858
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(file).digest());
1633
1859
  hash.update(
1634
- (0, import_node_crypto2.createHash)("sha256").update(input.metalSources?.[file] ?? "").digest()
1860
+ (0, import_node_crypto3.createHash)("sha256").update(input.metalSources?.[file] ?? "").digest()
1635
1861
  );
1636
1862
  }
1637
1863
  for (const base of Object.keys(input.resources ?? {}).sort()) {
1638
- hash.update((0, import_node_crypto2.createHash)("sha256").update(base).digest());
1864
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(base).digest());
1639
1865
  hash.update(
1640
- (0, import_node_crypto2.createHash)("sha256").update(input.resources?.[base] ?? "").digest()
1866
+ (0, import_node_crypto3.createHash)("sha256").update(input.resources?.[base] ?? "").digest()
1641
1867
  );
1642
1868
  }
1643
1869
  for (const name2 of Object.keys(input.images ?? {}).sort()) {
1644
1870
  const image = input.images?.[name2];
1645
1871
  if (!image) continue;
1646
- hash.update((0, import_node_crypto2.createHash)("sha256").update(name2).digest());
1647
- hash.update((0, import_node_crypto2.createHash)("sha256").update(image.file).digest());
1648
- hash.update((0, import_node_crypto2.createHash)("sha256").update(image.data).digest());
1872
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(name2).digest());
1873
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(image.file).digest());
1874
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(image.data).digest());
1649
1875
  }
1650
1876
  for (const file of [...new Set(input.resourcePaths ?? [])].sort()) {
1651
1877
  hash.update("resource-path\n");
1652
- hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
1878
+ hash.update((0, import_node_crypto3.createHash)("sha256").update(file).digest());
1653
1879
  }
1654
1880
  hash.update(
1655
1881
  JSON.stringify(
@@ -1661,7 +1887,7 @@ ${release}
1661
1887
  ${target}
1662
1888
  `);
1663
1889
  hash.update(
1664
- (0, import_node_crypto2.createHash)("sha256").update(input.libraries?.[target] ?? "").digest()
1890
+ (0, import_node_crypto3.createHash)("sha256").update(input.libraries?.[target] ?? "").digest()
1665
1891
  );
1666
1892
  }
1667
1893
  const targets = compileTargets(input);
@@ -1704,21 +1930,21 @@ function emitSwiftPackageManifest(args) {
1704
1930
  distributionLink.files.set(
1705
1931
  distributionLink.path,
1706
1932
  objects.map(
1707
- (object) => `"${import_node_path3.default.join(moduleRoot, object).replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`
1933
+ (object) => `"${import_node_path5.default.join(moduleRoot, object).replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`
1708
1934
  ).join("\n") + "\n"
1709
1935
  );
1710
1936
  }
1711
- const overlayRoot = import_node_path3.default.join(
1937
+ const overlayRoot = import_node_path5.default.join(
1712
1938
  moduleRoot,
1713
1939
  distribution ? "modules" : "cross-import-overlays"
1714
1940
  );
1715
- const overlayFlags = (0, import_node_fs3.readdirSync)(overlayRoot, { encoding: "utf8", recursive: true }).filter((file) => file.endsWith(".swiftoverlay")).sort((left, right) => left.localeCompare(right)).flatMap((file) => [
1941
+ const overlayFlags = (0, import_node_fs4.readdirSync)(overlayRoot, { encoding: "utf8", recursive: true }).filter((file) => file.endsWith(".swiftoverlay")).sort((left, right) => left.localeCompare(right)).flatMap((file) => [
1716
1942
  "-Xfrontend",
1717
1943
  "-swift-module-cross-import",
1718
1944
  "-Xfrontend",
1719
- import_node_path3.default.basename(import_node_path3.default.dirname(file), ".swiftcrossimport"),
1945
+ import_node_path5.default.basename(import_node_path5.default.dirname(file), ".swiftcrossimport"),
1720
1946
  "-Xfrontend",
1721
- import_node_path3.default.join(overlayRoot, file)
1947
+ import_node_path5.default.join(overlayRoot, file)
1722
1948
  ]).map((flag) => `, ${JSON.stringify(flag)}`).join("");
1723
1949
  const executable = targets.find((target) => target.executable);
1724
1950
  if (!executable) throw new Error("swift-compile: no executable target to emit");
@@ -1726,14 +1952,14 @@ function emitSwiftPackageManifest(args) {
1726
1952
  const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
1727
1953
  const interoperability = target.cxxInterop ? " .interoperabilityMode(.Cxx)," : "";
1728
1954
  const defines = (target.defines ?? []).map((name2) => ` .define(${JSON.stringify(name2)}),`).join("");
1729
- const imports = distribution ? `, "-I", ${JSON.stringify(import_node_path3.default.join(moduleRoot, "modules"))}` : "";
1955
+ const imports = distribution ? `, "-I", ${JSON.stringify(import_node_path5.default.join(moduleRoot, "modules"))}` : "";
1730
1956
  const native = args.native?.get(target.name);
1731
1957
  const nativeImports = (siblings.get(target.name) ?? []).filter((name2) => args.native?.has(name2)).map(
1732
1958
  (name2) => `, "-Xfrontend", "-import-module", "-Xfrontend", ${JSON.stringify(swiftTargetModuleName(name2))}`
1733
1959
  ).join("");
1734
1960
  const header = args.headerDirectory && [...args.native?.values() ?? []].some(
1735
1961
  (value) => value.late?.producers.includes(target.name)
1736
- ) ? `, "-emit-objc-header-path", ${JSON.stringify(import_node_path3.default.join(args.headerDirectory, `${target.name}-Swift.h`))}` : "";
1962
+ ) ? `, "-emit-objc-header-path", ${JSON.stringify(import_node_path5.default.join(args.headerDirectory, `${target.name}-Swift.h`))}` : "";
1737
1963
  const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation}${interoperability}${defines} .unsafeFlags(["-Osize", "-Xfrontend", "-enable-cross-import-overlays"${overlayFlags}${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}${imports}${nativeImports}${header}])]`;
1738
1964
  const deps = [
1739
1965
  ...target.executable ? [...args.native?.values() ?? []].flatMap(
@@ -1798,21 +2024,21 @@ function emitSwiftPackageManifest(args) {
1798
2024
  ].join("\n");
1799
2025
  }
1800
2026
  function syncSwiftTree(base, files2) {
1801
- (0, import_node_fs3.mkdirSync)(base, { recursive: true });
2027
+ (0, import_node_fs4.mkdirSync)(base, { recursive: true });
1802
2028
  const walk2 = (dir) => {
1803
- for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
1804
- const full = import_node_path3.default.join(dir, entry.name);
2029
+ for (const entry of (0, import_node_fs4.readdirSync)(dir, { withFileTypes: true })) {
2030
+ const full = import_node_path5.default.join(dir, entry.name);
1805
2031
  if (dir === base && entry.name === ".build") continue;
1806
2032
  if (entry.isDirectory()) walk2(full);
1807
- else if (!files2.has(full)) (0, import_node_fs3.rmSync)(full, { force: true });
2033
+ else if (!files2.has(full)) (0, import_node_fs4.rmSync)(full, { force: true });
1808
2034
  }
1809
2035
  };
1810
2036
  walk2(base);
1811
2037
  for (const [full, contents] of files2) {
1812
- if ((0, import_node_fs3.existsSync)(full) && (typeof contents === "string" ? (0, import_node_fs3.readFileSync)(full, "utf8") === contents : (0, import_node_fs3.readFileSync)(full).equals(contents)))
2038
+ if ((0, import_node_fs4.existsSync)(full) && (typeof contents === "string" ? (0, import_node_fs4.readFileSync)(full, "utf8") === contents : (0, import_node_fs4.readFileSync)(full).equals(contents)))
1813
2039
  continue;
1814
- (0, import_node_fs3.mkdirSync)(import_node_path3.default.dirname(full), { recursive: true });
1815
- (0, import_node_fs3.writeFileSync)(full, contents);
2040
+ (0, import_node_fs4.mkdirSync)(import_node_path5.default.dirname(full), { recursive: true });
2041
+ (0, import_node_fs4.writeFileSync)(full, contents);
1816
2042
  }
1817
2043
  }
1818
2044
  function splitTopLevel(text4) {
@@ -2180,11 +2406,53 @@ function compiledSwiftSources(files2, targets) {
2180
2406
  const sources = lifted.map(([, contents]) => contents);
2181
2407
  const extensions = objcExtensionMemberIndex(sources);
2182
2408
  const objc = objcIndex(sources);
2409
+ const rooted = objcRootedClasses(sources);
2183
2410
  for (const [file, contents] of lifted)
2184
- compiled.set(file, swiftSourceAsIOS(contents, extensions, objc));
2411
+ compiled.set(
2412
+ file,
2413
+ hideObjCClassesFromCxx(swiftSourceAsIOS(contents, extensions, objc), rooted)
2414
+ );
2185
2415
  }
2186
2416
  return compiled;
2187
2417
  }
2418
+ function objcRootedClasses(sources) {
2419
+ const bases = /* @__PURE__ */ new Map();
2420
+ for (const source of sources)
2421
+ for (const match of swiftCodeMask(source).matchAll(
2422
+ /\bclass\s+(?!(?:func|var|let|subscript)\b)([A-Za-z_]\w*)\s*(?:<[^>{]*>)?\s*:\s*(?:[A-Za-z_]\w*\.)*([A-Za-z_]\w*)/g
2423
+ ))
2424
+ bases.set(match[1], match[2]);
2425
+ const rooted = /* @__PURE__ */ new Set();
2426
+ for (const name2 of bases.keys()) {
2427
+ const seen = /* @__PURE__ */ new Set([name2]);
2428
+ let base = bases.get(name2);
2429
+ while (bases.has(base) && !seen.has(base)) {
2430
+ seen.add(base);
2431
+ base = bases.get(base);
2432
+ }
2433
+ if (!bases.has(base) && APPLE_CLASS.test(base) && !APPLE_PROTOCOL.test(base) && !(base in SDK_OBJC_OPTIONAL))
2434
+ rooted.add(name2);
2435
+ }
2436
+ return rooted;
2437
+ }
2438
+ function hideObjCClassesFromCxx(source, rooted) {
2439
+ if (rooted.size === 0) return source;
2440
+ const code = swiftCodeMask(source);
2441
+ const starts = [];
2442
+ let depth = 0;
2443
+ for (const match of code.matchAll(
2444
+ /[{}]|\bclass\s+(?!(?:func|var|let|subscript)\b)([A-Za-z_]\w*)/g
2445
+ )) {
2446
+ if (match[0] === "{") depth++;
2447
+ else if (match[0] === "}") depth--;
2448
+ else if (depth === 0 && rooted.has(match[1]))
2449
+ starts.push(declarationStart(code, match.index, 0));
2450
+ }
2451
+ let out = source;
2452
+ for (const at of starts.reverse())
2453
+ out = `${out.slice(0, at)}@_expose(!Cxx) ${out.slice(at)}`;
2454
+ return out;
2455
+ }
2188
2456
  function lowerAnyObjectDoubleValue(source) {
2189
2457
  const masked = swiftCodeMask(source);
2190
2458
  const names = /* @__PURE__ */ new Set();
@@ -2606,11 +2874,39 @@ function objcIndex(sources) {
2606
2874
  /\b(?:var|let)\s+([A-Za-z_]\w*)/g
2607
2875
  ))
2608
2876
  variables.add(declared[1]);
2609
- const parents = requirements.size ? inheritedTypes(sources) : /* @__PURE__ */ new Map();
2877
+ const parents = inheritedTypes(sources);
2610
2878
  for (const [protocol, inherited] of sdkParents)
2611
2879
  parents.set(protocol, /* @__PURE__ */ new Set([...parents.get(protocol) ?? [], ...inherited]));
2612
2880
  const conformers = requirements.size ? conformingTypes(parents, new Set(requirements.keys())) : /* @__PURE__ */ new Map();
2613
- return { requirements, conformers, callable, variables, aliases, typeMethods };
2881
+ const protocols = /* @__PURE__ */ new Set();
2882
+ const initializers = /* @__PURE__ */ new Set();
2883
+ for (const source of sources) {
2884
+ if (!/\bprotocol\b/.test(source)) continue;
2885
+ const code = swiftCodeMask(source);
2886
+ const braces = [...code.matchAll(/[{}]/g)].map((match) => match.index);
2887
+ for (const protocol of code.matchAll(/\bprotocol\s+([A-Za-z_]\w*)[^{}]*\{/g)) {
2888
+ const name2 = protocol[1];
2889
+ protocols.add(name2);
2890
+ const open = protocol.index + protocol[0].length - 1;
2891
+ if (/\binit\s*[?!]?\s*\(/.test(code.slice(open + 1, closingBrace(code, braces, open))))
2892
+ initializers.add(name2);
2893
+ }
2894
+ }
2895
+ const rooted = conformingTypes(parents, /* @__PURE__ */ new Set(["NSObject"]));
2896
+ const initialized = conformingTypes(parents, initializers);
2897
+ const nsObjectTypes = /* @__PURE__ */ new Set([
2898
+ "NSObject",
2899
+ ...[...protocols].filter((name2) => rooted.has(name2) && !initialized.has(name2))
2900
+ ]);
2901
+ return {
2902
+ requirements,
2903
+ conformers,
2904
+ callable,
2905
+ variables,
2906
+ aliases,
2907
+ typeMethods,
2908
+ nsObjectTypes
2909
+ };
2614
2910
  }
2615
2911
  function objcAliases(sources) {
2616
2912
  const declared = /* @__PURE__ */ new Map();
@@ -2857,7 +3153,7 @@ function lowerObjCOptionalRequirements(source, index) {
2857
3153
  }
2858
3154
  function lowerObjCRuntimeCalls(source, index) {
2859
3155
  const casts = source.includes("@convention(c)");
2860
- const classes = /\b(?:AnyClass|AnyObject)\b/.test(source);
3156
+ const classes = /\b(?:AnyClass|AnyObject)\b|\.\s*init\s*\(/.test(source);
2861
3157
  if (!casts && !classes) return source;
2862
3158
  const code = swiftCodeMask(source);
2863
3159
  const edits = [];
@@ -2887,11 +3183,24 @@ function lowerObjCRuntimeCalls(source, index) {
2887
3183
  if (classes) {
2888
3184
  const declarations = /* @__PURE__ */ new Map();
2889
3185
  for (const declared of code.matchAll(
2890
- /(?:\b(?:let|var)\s+|[(,]\s*(?:[A-Za-z_]\w*\s+)?)([A-Za-z_]\w*)\s*:\s*(?:([A-Z]\w*(?:\.\w+)*)\s*([?!])?|[[(])|\b(?:let|var|for)\s+([A-Za-z_]\w*)\b(?!\s*:)|[{,]\s*([A-Za-z_]\w*)\s+in\b/g
3186
+ /(?:\b(?:let|var)\s+|[(,]\s*(?:[A-Za-z_]\w*\s+)?)([A-Za-z_]\w*)\s*:\s*(?:(?:any\s+)?([A-Z]\w*(?:\.\w+)*)\s*([?!])?|[[(])|\b(?:let|var|for)\s+([A-Za-z_]\w*)\b(?!\s*:)|[{,]\s*([A-Za-z_]\w*)\s+in\b/g
2891
3187
  )) {
2892
3188
  const name2 = declared[1] ?? declared[4] ?? declared[5];
2893
3189
  const list2 = declarations.get(name2) ?? [];
2894
- list2.push({ at: declared.index, type: declared[3] ? "" : declared[2] ?? "" });
3190
+ let type = declared[3] ? "" : declared[2] ?? "";
3191
+ if (!type && declared[4]) {
3192
+ const lookup = /^\s*=\s*NSClassFromString\s*\(/.exec(
3193
+ code.slice(declared.index + declared[0].length)
3194
+ );
3195
+ if (lookup) {
3196
+ const open = declared.index + declared[0].length + lookup[0].length - 1;
3197
+ type = /^\s*as\?\s*([A-Za-z_]\w*(?:\.\w+)*\.Type)\b/.exec(
3198
+ code.slice(closingParen(code, open) + 1)
3199
+ )?.[1] ?? "";
3200
+ }
3201
+ }
3202
+ const resolved = type.endsWith(".Type") ? `${resolveAliases(type.slice(0, -5), index.aliases)}.Type` : resolveAliases(type, index.aliases);
3203
+ list2.push({ at: declared.index, type: resolved });
2895
3204
  declarations.set(name2, list2);
2896
3205
  }
2897
3206
  for (const pattern of code.matchAll(/\b(?:let|var|for)\s*(?=\(|\.\s*\w+\s*\()/g)) {
@@ -2905,7 +3214,7 @@ function lowerObjCRuntimeCalls(source, index) {
2905
3214
  }
2906
3215
  for (const list2 of declarations.values()) list2.sort((a, b) => a.at - b.at);
2907
3216
  const braces = [...code.matchAll(/[{}]/g)].map((match) => match.index);
2908
- const receives = (name2, at, type) => {
3217
+ const receiverType = (name2, at) => {
2909
3218
  let innermost;
2910
3219
  for (const declared of declarations.get(name2) ?? []) {
2911
3220
  if (declared.at > at) break;
@@ -2913,17 +3222,31 @@ function lowerObjCRuntimeCalls(source, index) {
2913
3222
  if (at > from && at < to && (!innermost || from >= innermost.from))
2914
3223
  innermost = { from, type: declared.type };
2915
3224
  }
2916
- return innermost?.type === type;
3225
+ return innermost?.type;
2917
3226
  };
2918
3227
  let reached = -1;
2919
3228
  for (const call of code.matchAll(
2920
3229
  /(?<![\w.])((?:type\s*\(\s*of\s*:\s*([A-Za-z_]\w*)\s*\))|[A-Za-z_]\w*)\s*\.\s*([A-Za-z_]\w*)\s*\(/g
2921
3230
  )) {
2922
- if (call.index < reached || !(call[2] ? receives(call[2], call.index, "AnyObject") : receives(call[1], call.index, "AnyClass")))
2923
- continue;
3231
+ if (call.index < reached) continue;
3232
+ const type = receiverType(call[2] ?? call[1], call.index);
3233
+ const constructed = call[2] ? type : type?.replace(/\.Type$/, "");
3234
+ const constructs = call[3] === "init" && constructed && (call[2] || type?.endsWith(".Type")) && index.nsObjectTypes.has(constructed.replace(/^Foundation\./, ""));
3235
+ if (!constructs && type !== (call[2] ? "AnyObject" : "AnyClass")) continue;
2924
3236
  const open = call.index + call[0].length - 1;
2925
3237
  const shut = closingParen(code, open);
2926
3238
  const passed = callArguments(source, code, open, shut);
3239
+ if (constructs && passed.length === 0) {
3240
+ const result2 = constructed.replace(/^Foundation\./, "") === "NSObject" ? constructed : `any ${constructed}`;
3241
+ edits.push([
3242
+ call.index,
3243
+ shut + 1 - call.index,
3244
+ `_objcNSObjectDefaultInit(${call[1]}, returning: (${result2}).self)`
3245
+ ]);
3246
+ reached = shut + 1;
3247
+ continue;
3248
+ }
3249
+ if (type !== (call[2] ? "AnyObject" : "AnyClass")) continue;
2927
3250
  const selector = objcSelectorName(
2928
3251
  call[3],
2929
3252
  passed.map(({ label }) => label),
@@ -3332,7 +3655,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3332
3655
  const targets = distribution && compileTargets(input).length === 0 ? [
3333
3656
  {
3334
3657
  name: "App",
3335
- path: import_node_path3.default.relative(layout.root, layout.sources),
3658
+ path: import_node_path5.default.relative(layout.root, layout.sources),
3336
3659
  executable: true,
3337
3660
  languageMode: 5,
3338
3661
  mainActorIsolation: false,
@@ -3341,7 +3664,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3341
3664
  ] : compileTargets(input);
3342
3665
  const files2 = /* @__PURE__ */ new Map();
3343
3666
  const native = /* @__PURE__ */ new Map();
3344
- const headerDirectory = import_node_path3.default.join(layout.root, ".build", "peach-cxx-headers");
3667
+ const headerDirectory = import_node_path5.default.join(layout.root, ".build", "peach-cxx-headers");
3345
3668
  for (const target of targets) {
3346
3669
  const prefix = target.path === "." ? "" : `${target.path}/`;
3347
3670
  const entries = Object.entries(input.files).filter(
@@ -3364,7 +3687,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3364
3687
  if (producer && targets.some((value) => value.name === producer))
3365
3688
  producers.add(producer);
3366
3689
  const local = [
3367
- import_node_path3.default.posix.join(import_node_path3.default.posix.dirname(file), include),
3690
+ import_node_path5.default.posix.join(import_node_path5.default.posix.dirname(file), include),
3368
3691
  `${includes}${include}`
3369
3692
  ].find((candidate) => input.files[candidate] !== void 0);
3370
3693
  if (local) {
@@ -3386,7 +3709,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3386
3709
  const late = units.filter(([file]) => consumers.get(file).size > 0);
3387
3710
  native.set(target.name, {
3388
3711
  path: target.path,
3389
- includeDirectory: import_node_path3.default.join(layout.root, includes),
3712
+ includeDirectory: import_node_path5.default.join(layout.root, includes),
3390
3713
  lateSources: late.map(([file]) => file.slice(prefix.length)),
3391
3714
  ...late.length > 0 ? {
3392
3715
  late: {
@@ -3403,7 +3726,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3403
3726
  ([file]) => file.startsWith(includes) && /\.(?:h|hpp|hh|hxx)$/.test(file) && consumers.get(file).size === 0
3404
3727
  );
3405
3728
  files2.set(
3406
- import_node_path3.default.join(layout.root, includes, "module.modulemap"),
3729
+ import_node_path5.default.join(layout.root, includes, "module.modulemap"),
3407
3730
  [
3408
3731
  `module ${target.name} {`,
3409
3732
  ...roots.map(
@@ -3415,14 +3738,14 @@ function writeSwiftProject(layout, input, moduleRoot) {
3415
3738
  ].join("\n")
3416
3739
  );
3417
3740
  }
3418
- if (native.size > 0) (0, import_node_fs3.mkdirSync)(headerDirectory, { recursive: true });
3419
- const modulePlan = (0, import_node_crypto2.createHash)("sha256").update(
3741
+ if (native.size > 0) (0, import_node_fs4.mkdirSync)(headerDirectory, { recursive: true });
3742
+ const modulePlan = (0, import_node_crypto3.createHash)("sha256").update(
3420
3743
  swiftModuleInputFiles(moduleRoot).join("\n")
3421
3744
  );
3422
3745
  if (!distribution) {
3423
- modulePlan.update((0, import_node_fs3.readFileSync)(import_node_path3.default.join(moduleRoot, "Package.swift")));
3746
+ modulePlan.update((0, import_node_fs4.readFileSync)(import_node_path5.default.join(moduleRoot, "Package.swift")));
3424
3747
  }
3425
- const resourcePlan = (0, import_node_crypto2.createHash)("sha256").update(
3748
+ const resourcePlan = (0, import_node_crypto3.createHash)("sha256").update(
3426
3749
  JSON.stringify(
3427
3750
  resourceTargets.filter((target) => target.resources).map((target) => [
3428
3751
  target.name,
@@ -3447,10 +3770,10 @@ function writeSwiftProject(layout, input, moduleRoot) {
3447
3770
  if (targets.length === 0) {
3448
3771
  for (const [file, contents] of Object.entries(input.files)) {
3449
3772
  if (file === "Package.swift") continue;
3450
- files2.set(import_node_path3.default.join(layout.sources, file), compiled.get(file) ?? contents);
3773
+ files2.set(import_node_path5.default.join(layout.sources, file), compiled.get(file) ?? contents);
3451
3774
  }
3452
- let manifest = (0, import_node_fs3.readFileSync)(
3453
- import_node_path3.default.join(moduleRoot, "scripts/contrast-app-Package.swift"),
3775
+ let manifest = (0, import_node_fs4.readFileSync)(
3776
+ import_node_path5.default.join(moduleRoot, "scripts/contrast-app-Package.swift"),
3454
3777
  "utf8"
3455
3778
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
3456
3779
  const reactor = ` ${REACTOR_FLAG}`;
@@ -3494,21 +3817,21 @@ function writeSwiftProject(layout, input, moduleRoot) {
3494
3817
  manifest = manifest.replace(anchor, `${anchor}
3495
3818
  ${SPRITEKIT_PRODUCT},`);
3496
3819
  }
3497
- files2.set(import_node_path3.default.join(layout.root, "Package.swift"), manifest + moduleFiles);
3820
+ files2.set(import_node_path5.default.join(layout.root, "Package.swift"), manifest + moduleFiles);
3498
3821
  } else {
3499
3822
  const base = layout.multi ? layout.root : layout.sources;
3500
3823
  const libraries = /* @__PURE__ */ new Map();
3501
3824
  for (const [target, data] of Object.entries(input.libraries ?? {})) {
3502
- const file = import_node_path3.default.join(layout.root, ".peach-libraries", `lib${target}.a`);
3825
+ const file = import_node_path5.default.join(layout.root, ".peach-libraries", `lib${target}.a`);
3503
3826
  files2.set(file, Buffer.from(data, "base64"));
3504
3827
  libraries.set(target, file);
3505
3828
  }
3506
3829
  for (const [file, contents] of Object.entries(input.files)) {
3507
3830
  if (file === "Package.swift") continue;
3508
- files2.set(import_node_path3.default.join(base, file), compiled.get(file) ?? contents);
3831
+ files2.set(import_node_path5.default.join(base, file), compiled.get(file) ?? contents);
3509
3832
  }
3510
3833
  files2.set(
3511
- import_node_path3.default.join(layout.root, "Package.swift"),
3834
+ import_node_path5.default.join(layout.root, "Package.swift"),
3512
3835
  emitSwiftPackageManifest({
3513
3836
  targets,
3514
3837
  native,
@@ -3525,7 +3848,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3525
3848
  spriteKit: importsSpriteKit(input.files),
3526
3849
  distribution: distribution ?? void 0,
3527
3850
  distributionLink: {
3528
- path: import_node_path3.default.join(layout.root, ".peach-distribution-objects.rsp"),
3851
+ path: import_node_path5.default.join(layout.root, ".peach-distribution-objects.rsp"),
3529
3852
  files: files2
3530
3853
  },
3531
3854
  libraries
@@ -3541,9 +3864,9 @@ function writeSwiftProject(layout, input, moduleRoot) {
3541
3864
  throw new Error(
3542
3865
  `swift resource target ${target.name} has no matching bundle assignment`
3543
3866
  );
3544
- const directory = layout.multi ? import_node_path3.default.join(layout.root, target.path) : layout.sources;
3867
+ const directory = layout.multi ? import_node_path5.default.join(layout.root, target.path) : layout.sources;
3545
3868
  files2.set(
3546
- import_node_path3.default.join(directory, "ResourceBundleAccessor.generated.swift"),
3869
+ import_node_path5.default.join(directory, "ResourceBundleAccessor.generated.swift"),
3547
3870
  [
3548
3871
  "import Foundation",
3549
3872
  "",
@@ -3576,15 +3899,15 @@ function outputOf(error) {
3576
3899
  return error instanceof Error ? error.message : String(error);
3577
3900
  }
3578
3901
  function builtArtifact(layout) {
3579
- const binDir = import_node_path3.default.join(layout.root, ".build", WASM_TRIPLE, "release");
3580
- const manifest = (0, import_node_fs3.readFileSync)(import_node_path3.default.join(layout.root, "Package.swift"), "utf8");
3902
+ const binDir = import_node_path5.default.join(layout.root, ".build", WASM_TRIPLE, "release");
3903
+ const manifest = (0, import_node_fs4.readFileSync)(import_node_path5.default.join(layout.root, "Package.swift"), "utf8");
3581
3904
  const executable = swiftManifestTargets(manifest).find((target) => target.executable);
3582
3905
  if (executable === void 0) {
3583
3906
  throw new Error("swift-compile: the written manifest names no executable target");
3584
3907
  }
3585
- const file = import_node_path3.default.join(binDir, `${executable.name}.wasm`);
3586
- if (!(0, import_node_fs3.existsSync)(file)) {
3587
- const found = (0, import_node_fs3.existsSync)(binDir) ? (0, import_node_fs3.readdirSync)(binDir).filter((name2) => name2.endsWith(".wasm")).sort() : [];
3908
+ const file = import_node_path5.default.join(binDir, `${executable.name}.wasm`);
3909
+ if (!(0, import_node_fs4.existsSync)(file)) {
3910
+ const found = (0, import_node_fs4.existsSync)(binDir) ? (0, import_node_fs4.readdirSync)(binDir).filter((name2) => name2.endsWith(".wasm")).sort() : [];
3588
3911
  throw new Error(
3589
3912
  `swift-compile: the build produced no ${executable.name}.wasm (found: ${found.join(", ") || "none"})`
3590
3913
  );
@@ -3593,7 +3916,7 @@ function builtArtifact(layout) {
3593
3916
  }
3594
3917
  function projectDiagnostic(output, layout, files2) {
3595
3918
  const base = layout.multi ? layout.root : layout.sources;
3596
- const prefix = `${base}${import_node_path3.default.sep}`;
3919
+ const prefix = `${base}${import_node_path5.default.sep}`;
3597
3920
  return designTimeDiagnostic(output, files2).split("\n").map((line) => line.startsWith(prefix) ? line.slice(prefix.length) : line).join("\n").trim();
3598
3921
  }
3599
3922
  function serialize(root, work, signal) {
@@ -3626,13 +3949,13 @@ function serialize(root, work, signal) {
3626
3949
  function readCompiledArtifact(directory, hash) {
3627
3950
  try {
3628
3951
  const receipt = JSON.parse(
3629
- (0, import_node_fs3.readFileSync)(import_node_path3.default.join(directory, "artifact.json"), "utf8")
3952
+ (0, import_node_fs4.readFileSync)(import_node_path5.default.join(directory, "artifact.json"), "utf8")
3630
3953
  );
3631
3954
  if (!receipt || typeof receipt !== "object" || !("hash" in receipt) || receipt.hash !== hash || !("icu" in receipt) || typeof receipt.icu !== "string" || !("wasm" in receipt) || typeof receipt.wasm !== "string")
3632
3955
  return null;
3633
- const bytes = (0, import_node_fs3.readFileSync)(import_node_path3.default.join(directory, "app.wasm"));
3634
- const gzip2 = (0, import_node_fs3.readFileSync)(import_node_path3.default.join(directory, "icu.gz"));
3635
- if ((0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex") !== receipt.wasm || (0, import_node_crypto2.createHash)("sha256").update(gzip2).digest("hex") !== receipt.icu || bytes.length < 8 || bytes.readUInt32LE(0) !== 1836278016 || bytes.readUInt32LE(4) !== 1)
3956
+ const bytes = (0, import_node_fs4.readFileSync)(import_node_path5.default.join(directory, "app.wasm"));
3957
+ const gzip2 = (0, import_node_fs4.readFileSync)(import_node_path5.default.join(directory, "icu.gz"));
3958
+ if ((0, import_node_crypto3.createHash)("sha256").update(bytes).digest("hex") !== receipt.wasm || (0, import_node_crypto3.createHash)("sha256").update(gzip2).digest("hex") !== receipt.icu || bytes.length < 8 || bytes.readUInt32LE(0) !== 1836278016 || bytes.readUInt32LE(4) !== 1)
3636
3959
  return null;
3637
3960
  return { hash, bytes, icu: { sha256: receipt.icu, gzip: gzip2 } };
3638
3961
  } catch (error) {
@@ -3642,25 +3965,25 @@ function readCompiledArtifact(directory, hash) {
3642
3965
  }
3643
3966
  }
3644
3967
  function saveCompiledArtifact(root, artifact) {
3645
- const directory = import_node_path3.default.join(root, "artifact");
3646
- (0, import_node_fs3.mkdirSync)(directory, { recursive: true });
3647
- const pending = (0, import_node_fs3.mkdtempSync)(import_node_path3.default.join(root, ".artifact-"));
3968
+ const directory = import_node_path5.default.join(root, "artifact");
3969
+ (0, import_node_fs4.mkdirSync)(directory, { recursive: true });
3970
+ const pending = (0, import_node_fs4.mkdtempSync)(import_node_path5.default.join(root, ".artifact-"));
3648
3971
  try {
3649
- (0, import_node_fs3.writeFileSync)(import_node_path3.default.join(pending, "app.wasm"), artifact.bytes);
3650
- (0, import_node_fs3.writeFileSync)(import_node_path3.default.join(pending, "icu.gz"), artifact.icu.gzip);
3651
- (0, import_node_fs3.writeFileSync)(
3652
- import_node_path3.default.join(pending, "artifact.json"),
3972
+ (0, import_node_fs4.writeFileSync)(import_node_path5.default.join(pending, "app.wasm"), artifact.bytes);
3973
+ (0, import_node_fs4.writeFileSync)(import_node_path5.default.join(pending, "icu.gz"), artifact.icu.gzip);
3974
+ (0, import_node_fs4.writeFileSync)(
3975
+ import_node_path5.default.join(pending, "artifact.json"),
3653
3976
  JSON.stringify({
3654
3977
  hash: artifact.hash,
3655
- wasm: (0, import_node_crypto2.createHash)("sha256").update(artifact.bytes).digest("hex"),
3978
+ wasm: (0, import_node_crypto3.createHash)("sha256").update(artifact.bytes).digest("hex"),
3656
3979
  icu: artifact.icu.sha256
3657
3980
  })
3658
3981
  );
3659
3982
  for (const file of ["app.wasm", "icu.gz", "artifact.json"]) {
3660
- (0, import_node_fs3.renameSync)(import_node_path3.default.join(pending, file), import_node_path3.default.join(directory, file));
3983
+ (0, import_node_fs4.renameSync)(import_node_path5.default.join(pending, file), import_node_path5.default.join(directory, file));
3661
3984
  }
3662
3985
  } finally {
3663
- (0, import_node_fs3.rmSync)(pending, { recursive: true, force: true });
3986
+ (0, import_node_fs4.rmSync)(pending, { recursive: true, force: true });
3664
3987
  }
3665
3988
  }
3666
3989
  function retain(root, artifact) {
@@ -3675,42 +3998,54 @@ function retain(root, artifact) {
3675
3998
  }
3676
3999
  function compileSwiftProjectUnit(input, options) {
3677
4000
  options.signal?.throwIfAborted();
3678
- (0, import_node_fs3.mkdirSync)(options.buildRoot, { recursive: true });
3679
- const root = (0, import_node_fs3.realpathSync)(options.buildRoot);
3680
- const moduleRoot = import_node_path3.default.resolve(options.moduleRoot);
4001
+ (0, import_node_fs4.mkdirSync)(options.buildRoot, { recursive: true });
4002
+ const root = (0, import_node_fs4.realpathSync)(options.buildRoot);
4003
+ const moduleRoot = import_node_path5.default.resolve(options.moduleRoot);
3681
4004
  const layout = {
3682
4005
  root,
3683
- sources: import_node_path3.default.join(root, "Sources", "App"),
4006
+ sources: import_node_path5.default.join(root, "Sources", "App"),
3684
4007
  multi: compileTargets(input).length > 0
3685
4008
  };
3686
4009
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
4010
+ const sharedRoot = import_node_path5.default.join(rnxHomeDir(), "cache", "swift-projects", hash);
4011
+ const report = (message) => console.error(`[swift-project ${hash.slice(0, 16)}] ${message}`);
4012
+ report("checking verified artifacts");
3687
4013
  return serialize(
3688
4014
  root,
3689
4015
  async () => {
3690
4016
  const retained = retainedArtifacts.get(root)?.find((old) => old.hash === hash);
3691
- if (retained) return retain(root, retained);
3692
- const cached2 = readCompiledArtifact(import_node_path3.default.join(root, "artifact"), hash);
3693
- if (cached2) return retain(root, cached2);
3694
- if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === import_node_path3.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3695
- const requestRoot = (0, import_node_fs3.mkdtempSync)(import_node_path3.default.join(root, ".builder-request-"));
3696
- const output = import_node_path3.default.join(requestRoot, "output");
3697
- const request = import_node_path3.default.join(requestRoot, "request.json");
3698
- (0, import_node_fs3.writeFileSync)(
4017
+ if (retained) {
4018
+ report("reusing memory artifact");
4019
+ return retain(root, retained);
4020
+ }
4021
+ const cached2 = readCompiledArtifact(import_node_path5.default.join(sharedRoot, "artifact"), hash);
4022
+ const previous = cached2 ?? readCompiledArtifact(import_node_path5.default.join(root, "artifact"), hash);
4023
+ if (previous) {
4024
+ if (!cached2) saveCompiledArtifact(sharedRoot, previous);
4025
+ report("reusing verified disk artifact");
4026
+ return retain(root, previous);
4027
+ }
4028
+ if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === import_node_path5.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
4029
+ const requestRoot = (0, import_node_fs4.mkdtempSync)(import_node_path5.default.join(root, ".builder-request-"));
4030
+ const output = import_node_path5.default.join(requestRoot, "output");
4031
+ const request = import_node_path5.default.join(requestRoot, "request.json");
4032
+ (0, import_node_fs4.writeFileSync)(
3699
4033
  request,
3700
4034
  JSON.stringify({
3701
4035
  input,
3702
4036
  hash,
3703
4037
  release: options.release,
3704
4038
  timeoutMs: options.timeoutMs,
3705
- buildKey: (0, import_node_crypto2.createHash)("sha256").update(root).digest("hex").slice(0, 32)
4039
+ buildKey: (0, import_node_crypto3.createHash)("sha256").update(root).digest("hex").slice(0, 32)
3706
4040
  })
3707
4041
  );
3708
4042
  try {
3709
- const repo = import_node_path3.default.resolve(moduleRoot, "../..");
4043
+ const repo = import_node_path5.default.resolve(moduleRoot, "../..");
4044
+ report("requesting builder admission or cached result");
3710
4045
  await runCompiler(
3711
4046
  "bun",
3712
4047
  [
3713
- import_node_path3.default.join(repo, "scripts/build/swift-project.ts"),
4048
+ import_node_path5.default.join(repo, "scripts/build/swift-project.ts"),
3714
4049
  "--request",
3715
4050
  request,
3716
4051
  "--output",
@@ -3734,18 +4069,21 @@ function compileSwiftProjectUnit(input, options) {
3734
4069
  );
3735
4070
  }
3736
4071
  saveCompiledArtifact(root, artifact2);
4072
+ saveCompiledArtifact(sharedRoot, artifact2);
4073
+ report("builder artifact verified");
3737
4074
  return retain(root, artifact2);
3738
4075
  } finally {
3739
- (0, import_node_fs3.rmSync)(requestRoot, { recursive: true, force: true });
4076
+ (0, import_node_fs4.rmSync)(requestRoot, { recursive: true, force: true });
3740
4077
  }
3741
4078
  }
3742
4079
  writeSwiftProject(layout, input, moduleRoot);
3743
- const swift = import_node_path3.default.join(options.toolchainBin, "swift");
3744
- if (!(0, import_node_fs3.existsSync)(swift)) {
4080
+ const swift = import_node_path5.default.join(options.toolchainBin, "swift");
4081
+ if (!(0, import_node_fs4.existsSync)(swift)) {
3745
4082
  throw new Error(
3746
4083
  `swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
3747
4084
  );
3748
4085
  }
4086
+ report("preparing compiler plugins");
3749
4087
  const macroPlugins = await ensureMacroPlugins(
3750
4088
  moduleRoot,
3751
4089
  options.toolchainBin,
@@ -3785,8 +4123,8 @@ function compileSwiftProjectUnit(input, options) {
3785
4123
  // shipped host plugins resolve against the selected compiler's runtime.
3786
4124
  ...process.platform === "linux" ? {
3787
4125
  LD_LIBRARY_PATH: [
3788
- import_node_path3.default.resolve(options.toolchainBin, "../lib/swift/linux"),
3789
- import_node_path3.default.resolve(options.toolchainBin, "../lib/swift/host"),
4126
+ import_node_path5.default.resolve(options.toolchainBin, "../lib/swift/linux"),
4127
+ import_node_path5.default.resolve(options.toolchainBin, "../lib/swift/host"),
3790
4128
  process.env.LD_LIBRARY_PATH
3791
4129
  ].filter(Boolean).join(":")
3792
4130
  } : {}
@@ -3795,21 +4133,22 @@ function compileSwiftProjectUnit(input, options) {
3795
4133
  timeout: options.timeoutMs,
3796
4134
  signal: options.signal
3797
4135
  };
4136
+ report("compiling and linking Swift modules");
3798
4137
  try {
3799
- await runCompiler(swift, buildArgs, buildOptions);
4138
+ await runCompiler(swift, buildArgs, buildOptions, true);
3800
4139
  } catch (error) {
3801
4140
  const output = outputOf(error);
3802
- const moduleCache = import_node_path3.default.join(
4141
+ const moduleCache = import_node_path5.default.join(
3803
4142
  root,
3804
4143
  ".build",
3805
4144
  WASM_TRIPLE,
3806
4145
  "release",
3807
4146
  "ModuleCache"
3808
4147
  );
3809
- if (output.includes("was compiled with module cache path") && (0, import_node_fs3.existsSync)(moduleCache)) {
3810
- (0, import_node_fs3.rmSync)(moduleCache, { recursive: true, force: true });
4148
+ if (output.includes("was compiled with module cache path") && (0, import_node_fs4.existsSync)(moduleCache)) {
4149
+ (0, import_node_fs4.rmSync)(moduleCache, { recursive: true, force: true });
3811
4150
  try {
3812
- await runCompiler(swift, buildArgs, buildOptions);
4151
+ await runCompiler(swift, buildArgs, buildOptions, true);
3813
4152
  } catch (retryError) {
3814
4153
  throw new Error(
3815
4154
  projectDiagnostic(outputOf(retryError), layout, input.files),
@@ -3826,25 +4165,28 @@ function compileSwiftProjectUnit(input, options) {
3826
4165
  }
3827
4166
  const artifact = {
3828
4167
  hash,
3829
- bytes: (0, import_node_fs3.readFileSync)(builtArtifact(layout)),
4168
+ bytes: (0, import_node_fs4.readFileSync)(builtArtifact(layout)),
3830
4169
  icu: await icu
3831
4170
  };
3832
4171
  saveCompiledArtifact(root, artifact);
4172
+ saveCompiledArtifact(sharedRoot, artifact);
4173
+ report("compiled artifact verified");
3833
4174
  return retain(root, artifact);
3834
4175
  },
3835
4176
  options.signal
3836
4177
  );
3837
4178
  }
3838
- var import_node_child_process3, import_node_crypto2, import_node_fs3, import_node_os2, import_node_path3, WASM_TRIPLE, BUILD_JOBS, linkedModuleDigests, OPTIONAL_FRAMEWORK_DEPENDENCIES, OPTIONAL_FRAMEWORKS, SWIFT_IMPORT, sdkPaths, availableModules, ONE_PRODUCT, SPRITEKIT_PRODUCT, importsSpriteKit, FOUNDATION_IMPLICIT_MODULES, FOUNDATION_IMPLICIT_FLAGS, ONE_IMPLICIT_FLAGS, EXECUTABLE_LINK_FLAGS, REACTOR_FLAG, MULTI_MANIFEST_VERSION, DIRECTIVE, OS_IOS, OBJC_ATTRIBUTE, SELECTOR, PROTOCOL_NAME, KEY_PATH, TYPE_AFTER_ATTRIBUTE, DELEGATE_CLASS, REUSABLE_INIT, REUSABLE_VIEW_BASES, CLASS_BASE, FRAME_INIT, APPLE_CLASS, EXTENSION_DECL, CLASS_DECL, MODIFIERS, OVERRIDE_FUNC, OVERRIDE_VAR, OBJC_PROTOCOL, OBJC_PREPOSITIONS, DECLARATION_MODIFIERS, optionalResult, SDK_OBJC_OPTIONAL, IMP_CONVENTION, ROOT_LOCKS, host, rootLocks, retainedArtifacts;
4179
+ var import_node_child_process4, import_node_crypto3, import_node_fs4, import_node_os4, import_node_path5, WASM_TRIPLE, BUILD_JOBS, linkedModuleDigests, OPTIONAL_FRAMEWORK_DEPENDENCIES, OPTIONAL_FRAMEWORKS, SWIFT_IMPORT, sdkPaths, availableModules, ONE_PRODUCT, SPRITEKIT_PRODUCT, importsSpriteKit, FOUNDATION_IMPLICIT_MODULES, FOUNDATION_IMPLICIT_FLAGS, ONE_IMPLICIT_FLAGS, EXECUTABLE_LINK_FLAGS, REACTOR_FLAG, MULTI_MANIFEST_VERSION, DIRECTIVE, OS_IOS, OBJC_ATTRIBUTE, SELECTOR, PROTOCOL_NAME, KEY_PATH, TYPE_AFTER_ATTRIBUTE, DELEGATE_CLASS, REUSABLE_INIT, REUSABLE_VIEW_BASES, CLASS_BASE, FRAME_INIT, APPLE_CLASS, EXTENSION_DECL, CLASS_DECL, MODIFIERS, OVERRIDE_FUNC, OVERRIDE_VAR, APPLE_PROTOCOL, OBJC_PROTOCOL, OBJC_PREPOSITIONS, DECLARATION_MODIFIERS, optionalResult, SDK_OBJC_OPTIONAL, IMP_CONVENTION, ROOT_LOCKS, host, rootLocks, retainedArtifacts;
3839
4180
  var init_swift_compile = __esm({
3840
4181
  "src/swift-compile.ts"() {
3841
4182
  "use strict";
3842
- import_node_child_process3 = require("node:child_process");
3843
- import_node_crypto2 = require("node:crypto");
3844
- import_node_fs3 = require("node:fs");
3845
- import_node_os2 = __toESM(require("node:os"), 1);
3846
- import_node_path3 = __toESM(require("node:path"), 1);
4183
+ import_node_child_process4 = require("node:child_process");
4184
+ import_node_crypto3 = require("node:crypto");
4185
+ import_node_fs4 = require("node:fs");
4186
+ import_node_os4 = __toESM(require("node:os"), 1);
4187
+ import_node_path5 = __toESM(require("node:path"), 1);
3847
4188
  init_admitted_mac_build();
4189
+ init_home_paths();
3848
4190
  init_process_group();
3849
4191
  init_swift_design_time();
3850
4192
  init_swift_distribution_contract();
@@ -3853,7 +4195,7 @@ var init_swift_compile = __esm({
3853
4195
  init_swiftContract();
3854
4196
  WASM_TRIPLE = "wasm32-unknown-wasip1";
3855
4197
  BUILD_JOBS = String(
3856
- Math.min(4, Math.max(1, Math.floor(import_node_os2.default.availableParallelism() / 2)))
4198
+ Math.min(4, Math.max(1, Math.floor(import_node_os4.default.availableParallelism() / 2)))
3857
4199
  );
3858
4200
  linkedModuleDigests = /* @__PURE__ */ new Map();
3859
4201
  OPTIONAL_FRAMEWORK_DEPENDENCIES = {
@@ -3946,6 +4288,7 @@ var init_swift_compile = __esm({
3946
4288
  MODIFIERS = /(?:^|\s)(public|open|internal|fileprivate|private|final|nonisolated|@MainActor)(?=\s)/g;
3947
4289
  OVERRIDE_FUNC = /^override((?:\s+(?:public|open|internal|fileprivate|private|final|nonisolated|dynamic|@\w+))*)\s+func\s+([A-Za-z_]\w*)\s*(<[^>{}]*>)?\s*\(/;
3948
4290
  OVERRIDE_VAR = /^override((?:\s+(?:public|open|internal|fileprivate|private|final|nonisolated|dynamic|@\w+))*)\s+var\s+([A-Za-z_]\w*)\s*:\s*([^{=]+?)\s*\{/;
4291
+ APPLE_PROTOCOL = /^NS(?:Mutable)?Copying$|^NS(?:Secure)?Coding$|^NSLocking$|^NSFastEnumeration$|^NSObjectProtocol$|(?:Delegate|DataSource)$/;
3949
4292
  OBJC_PROTOCOL = /@objc\b(?:\s*\([^()]*\))?(?:\s+(?:@\w+(?:\([^()]*\))?|public|internal|fileprivate|private|package))*\s+protocol\s+([A-Za-z_]\w*)[^{]*\{/g;
3950
4293
  OBJC_PREPOSITIONS = /* @__PURE__ */ new Set([
3951
4294
  "above",
@@ -5413,156 +5756,188 @@ var init_product = __esm({
5413
5756
 
5414
5757
  // ../contrast-runtime-delivery/src/index.ts
5415
5758
  async function installVerifiedTarball(tarball) {
5416
- const { url, digest: digest2, destDir, installedMarker, label } = tarball;
5417
- const downloadDir = import_node_fs4.default.mkdtempSync(import_node_path4.default.join(import_node_os3.default.tmpdir(), "runtime-delivery-download-"));
5418
- const archivePath = import_node_path4.default.join(downloadDir, "archive");
5419
- import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(destDir), { recursive: true });
5420
- const tmpDir = import_node_fs4.default.mkdtempSync(
5421
- import_node_path4.default.join(import_node_path4.default.dirname(destDir), `.installing-${import_node_path4.default.basename(destDir)}-`)
5759
+ const { url, digest: digest2, destDir, installedMarker, label, signal } = tarball;
5760
+ signal?.throwIfAborted();
5761
+ const downloadDir = import_node_fs5.default.mkdtempSync(import_node_path6.default.join(import_node_os5.default.tmpdir(), "runtime-delivery-download-"));
5762
+ const archivePath = import_node_path6.default.join(downloadDir, "archive");
5763
+ import_node_fs5.default.mkdirSync(import_node_path6.default.dirname(destDir), { recursive: true });
5764
+ const tmpDir = import_node_fs5.default.mkdtempSync(
5765
+ import_node_path6.default.join(import_node_path6.default.dirname(destDir), `.installing-${import_node_path6.default.basename(destDir)}-`)
5422
5766
  );
5423
5767
  try {
5424
- await downloadToFile(url, archivePath);
5425
- const actual = await digestFile(archivePath, digest2.algorithm, digest2.encoding);
5768
+ await downloadToFile(url, archivePath, signal);
5769
+ const actual = await digestFile(
5770
+ archivePath,
5771
+ digest2.algorithm,
5772
+ digest2.encoding,
5773
+ signal
5774
+ );
5426
5775
  if (actual !== digest2.value) {
5427
5776
  throw new Error(
5428
5777
  `${digest2.algorithm} mismatch for ${label}: expected ${digest2.value}, actual ${actual}`
5429
5778
  );
5430
5779
  }
5431
- if (new URL(url).pathname.endsWith(".zip")) await extractZip(archivePath, tmpDir);
5432
- else await extractTarball(archivePath, tmpDir, tarball.stripComponents ?? 0);
5433
- if (!import_node_fs4.default.existsSync(import_node_path4.default.join(tmpDir, installedMarker))) {
5780
+ if (new URL(url).pathname.endsWith(".zip"))
5781
+ await extractZip(archivePath, tmpDir, signal);
5782
+ else await extractTarball(archivePath, tmpDir, tarball.stripComponents ?? 0, signal);
5783
+ signal?.throwIfAborted();
5784
+ if (!import_node_fs5.default.existsSync(import_node_path6.default.join(tmpDir, installedMarker))) {
5434
5785
  throw new Error(`extracted tarball for ${label} is missing ${installedMarker}`);
5435
5786
  }
5436
5787
  tarball.verify?.(tmpDir);
5788
+ signal?.throwIfAborted();
5437
5789
  try {
5438
- import_node_fs4.default.renameSync(tmpDir, destDir);
5790
+ import_node_fs5.default.renameSync(tmpDir, destDir);
5439
5791
  } catch (err) {
5440
5792
  if (!isErrnoCode(err, "ENOTEMPTY", "EEXIST")) throw err;
5441
5793
  const aside = `${tmpDir}-replaced`;
5442
5794
  try {
5443
- import_node_fs4.default.renameSync(destDir, aside);
5795
+ import_node_fs5.default.renameSync(destDir, aside);
5444
5796
  } catch (moveErr) {
5445
5797
  if (!isErrnoCode(moveErr, "ENOENT")) throw moveErr;
5446
5798
  }
5447
5799
  try {
5448
- import_node_fs4.default.renameSync(tmpDir, destDir);
5800
+ import_node_fs5.default.renameSync(tmpDir, destDir);
5449
5801
  } catch (landErr) {
5450
- if (!isErrnoCode(landErr, "ENOTEMPTY", "EEXIST") || !import_node_fs4.default.existsSync(import_node_path4.default.join(destDir, installedMarker))) {
5802
+ if (!isErrnoCode(landErr, "ENOTEMPTY", "EEXIST") || !import_node_fs5.default.existsSync(import_node_path6.default.join(destDir, installedMarker))) {
5451
5803
  throw landErr;
5452
5804
  }
5453
5805
  } finally {
5454
- import_node_fs4.default.rmSync(aside, { recursive: true, force: true });
5806
+ import_node_fs5.default.rmSync(aside, { recursive: true, force: true });
5455
5807
  }
5456
5808
  }
5457
5809
  } finally {
5458
- import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
5459
- import_node_fs4.default.rmSync(downloadDir, { recursive: true, force: true });
5810
+ import_node_fs5.default.rmSync(tmpDir, { recursive: true, force: true });
5811
+ import_node_fs5.default.rmSync(downloadDir, { recursive: true, force: true });
5460
5812
  }
5461
5813
  }
5462
5814
  function isErrnoCode(err, ...codes) {
5463
5815
  return err instanceof Error && "code" in err && codes.includes(String(err.code));
5464
5816
  }
5465
- async function downloadToFile(url, destPath) {
5466
- const res = await fetch(url);
5817
+ async function downloadToFile(url, destPath, signal) {
5818
+ const res = await fetch(url, { signal });
5467
5819
  if (!res.ok || !res.body) {
5468
5820
  throw new Error(`download failed: ${res.status} ${res.statusText} (${url})`);
5469
5821
  }
5470
- import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(destPath), { recursive: true });
5822
+ import_node_fs5.default.mkdirSync(import_node_path6.default.dirname(destPath), { recursive: true });
5471
5823
  const tmp = `${destPath}.partial`;
5472
5824
  try {
5473
5825
  await (0, import_promises2.pipeline)(
5474
5826
  import_node_stream.Readable.fromWeb(res.body),
5475
- import_node_fs4.default.createWriteStream(tmp)
5827
+ import_node_fs5.default.createWriteStream(tmp),
5828
+ { signal }
5476
5829
  );
5477
- import_node_fs4.default.renameSync(tmp, destPath);
5830
+ signal?.throwIfAborted();
5831
+ import_node_fs5.default.renameSync(tmp, destPath);
5478
5832
  } catch (err) {
5479
5833
  try {
5480
- import_node_fs4.default.unlinkSync(tmp);
5834
+ import_node_fs5.default.unlinkSync(tmp);
5481
5835
  } catch {
5482
5836
  }
5483
5837
  throw err;
5484
5838
  }
5485
5839
  }
5486
- function digestFile(filePath, algorithm, encoding) {
5487
- return new Promise((resolve2, reject) => {
5488
- const hash = import_node_crypto3.default.createHash(algorithm);
5489
- const stream = import_node_fs4.default.createReadStream(filePath);
5490
- stream.on("data", (chunk) => hash.update(chunk));
5491
- stream.on("error", reject);
5492
- stream.on("end", () => resolve2(hash.digest(encoding)));
5493
- });
5840
+ async function digestFile(filePath, algorithm, encoding, signal) {
5841
+ const hash = import_node_crypto4.default.createHash(algorithm);
5842
+ await (0, import_promises2.pipeline)(import_node_fs5.default.createReadStream(filePath), hash, { signal });
5843
+ return hash.digest(encoding);
5494
5844
  }
5495
- function extractZip(zipPath, destDir) {
5496
- return runExtractor("ditto", ["-x", "-k", zipPath, destDir]);
5845
+ function extractZip(zipPath, destDir, signal) {
5846
+ return runExtractor("ditto", ["-x", "-k", zipPath, destDir], signal);
5497
5847
  }
5498
- function extractTarball(tarPath, destDir, stripComponents) {
5848
+ function extractTarball(tarPath, destDir, stripComponents, signal) {
5499
5849
  const args = ["-xzf", tarPath, "-C", destDir];
5500
5850
  if (stripComponents > 0) args.push(`--strip-components=${stripComponents}`);
5501
- return runExtractor("tar", args);
5851
+ return runExtractor("tar", args, signal);
5502
5852
  }
5503
- function runExtractor(command, args) {
5504
- return new Promise((resolve2, reject) => {
5505
- const child = (0, import_node_child_process4.spawn)(command, args, {
5506
- stdio: ["ignore", "inherit", "inherit"]
5853
+ async function runExtractor(command, args, signal) {
5854
+ signal?.throwIfAborted();
5855
+ const child = (0, import_node_child_process5.spawn)(command, args, {
5856
+ stdio: ["ignore", "inherit", "inherit"],
5857
+ detached: process.platform !== "win32"
5858
+ });
5859
+ let stopping;
5860
+ const abort = () => {
5861
+ stopping ??= terminateProcessGroup(child, "SIGKILL", 0);
5862
+ void stopping.catch(() => {
5507
5863
  });
5508
- child.on("error", reject);
5509
- child.on("exit", (code) => {
5510
- if (code === 0) resolve2();
5511
- else reject(new Error(`${command} exited with code ${code}`));
5864
+ };
5865
+ try {
5866
+ await new Promise((resolve2, reject) => {
5867
+ let failure2;
5868
+ child.on("error", (error) => {
5869
+ failure2 = error;
5870
+ });
5871
+ child.on("close", (code) => {
5872
+ if (signal?.aborted) {
5873
+ const reason = signal.reason;
5874
+ reject(
5875
+ reason instanceof Error ? reason : new Error("Extraction canceled", { cause: reason })
5876
+ );
5877
+ } else if (failure2) reject(failure2);
5878
+ else if (code === 0) resolve2();
5879
+ else reject(new Error(`${command} exited with code ${code}`));
5880
+ });
5881
+ signal?.addEventListener("abort", abort, { once: true });
5882
+ if (signal?.aborted) abort();
5512
5883
  });
5513
- });
5884
+ } finally {
5885
+ signal?.removeEventListener("abort", abort);
5886
+ await stopping;
5887
+ }
5514
5888
  }
5515
- var import_node_child_process4, import_node_crypto3, import_node_fs4, import_node_os3, import_node_path4, import_node_stream, import_promises2;
5889
+ var import_node_child_process5, import_node_crypto4, import_node_fs5, import_node_os5, import_node_path6, import_node_stream, import_promises2;
5516
5890
  var init_src = __esm({
5517
5891
  "../contrast-runtime-delivery/src/index.ts"() {
5518
5892
  "use strict";
5519
- import_node_child_process4 = require("node:child_process");
5520
- import_node_crypto3 = __toESM(require("node:crypto"), 1);
5521
- import_node_fs4 = __toESM(require("node:fs"), 1);
5522
- import_node_os3 = __toESM(require("node:os"), 1);
5523
- import_node_path4 = __toESM(require("node:path"), 1);
5893
+ import_node_child_process5 = require("node:child_process");
5894
+ import_node_crypto4 = __toESM(require("node:crypto"), 1);
5895
+ import_node_fs5 = __toESM(require("node:fs"), 1);
5896
+ import_node_os5 = __toESM(require("node:os"), 1);
5897
+ import_node_path6 = __toESM(require("node:path"), 1);
5524
5898
  import_node_stream = require("node:stream");
5525
5899
  import_promises2 = require("node:stream/promises");
5900
+ init_process_group();
5526
5901
  init_product();
5527
5902
  init_product();
5528
5903
  }
5529
5904
  });
5530
5905
 
5531
- // src/home-paths.ts
5532
- function rnxHomeDir() {
5533
- const override = process.env[PEACH_HOME_ENV];
5534
- if (override && override.length > 0) return import_node_path5.default.resolve(override);
5535
- return import_node_path5.default.join((0, import_node_os4.homedir)(), ".peach");
5536
- }
5537
- function electronDir() {
5538
- return import_node_path5.default.join(rnxHomeDir(), "electron");
5539
- }
5540
- function electronUserDataDir() {
5541
- return import_node_path5.default.join(electronDir(), "userData");
5542
- }
5543
- var import_node_os4, import_node_path5, PEACH_HOME_ENV, DAEMON_LOCKFILE_MAX_BYTES;
5544
- var init_home_paths = __esm({
5545
- "src/home-paths.ts"() {
5546
- "use strict";
5547
- import_node_os4 = require("node:os");
5548
- import_node_path5 = __toESM(require("node:path"), 1);
5549
- PEACH_HOME_ENV = "PEACH_HOME";
5550
- DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
5551
- }
5552
- });
5553
-
5554
5906
  // src/swift-distribution.lock.json
5555
5907
  var swift_distribution_lock_default;
5556
5908
  var init_swift_distribution_lock = __esm({
5557
5909
  "src/swift-distribution.lock.json"() {
5558
5910
  swift_distribution_lock_default = {
5559
- id: "64fd4ea71bc39e4f",
5911
+ id: "1fda1fb984f25758",
5560
5912
  release: "swift-6.4.0-RELEASE",
5561
- wasmSdkId: "swift-6.4.0-RELEASE_wasm-peach-dc9c8c67",
5562
- wasmSdkUrl: "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-dc9c8c67.artifactbundle.tar.gz",
5563
- wasmSdkChecksum: "5d38f795f516ccfef3d7ac869b447cdedcd82a35af9761a65b9f88924eb6a89a",
5564
- source: "77fbca997182e53ceb1944e27d8689f469f632c5",
5913
+ wasmSdkId: "swift-6.4.0-RELEASE_wasm-peach-34b989c2",
5914
+ wasmSdkUrl: "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-34b989c2.artifactbundle.tar.gz",
5915
+ wasmSdkChecksum: "1598ac9d063e07b20aa6232acb03c7147c9a94abf989d51f1e55688eb4aba854",
5916
+ source: "078b4f63d3734871dc1fbea898005e2ef95a73cb",
5565
5917
  targets: [
5918
+ "System",
5919
+ "_LocationEssentials",
5920
+ "GeoToolbox",
5921
+ "DataDetection",
5922
+ "Accessibility",
5923
+ "Contacts",
5924
+ "CoreML",
5925
+ "EventKit",
5926
+ "CloudKit",
5927
+ "IOSurface",
5928
+ "OpenGLES",
5929
+ "ContactsUI",
5930
+ "CoreLocationUI",
5931
+ "MediaPlayer",
5932
+ "MusicKit",
5933
+ "RealityKit",
5934
+ "SecureElementCredential",
5935
+ "Social",
5936
+ "Speech",
5937
+ "Vision",
5938
+ "VisionKit",
5939
+ "WorkoutKit",
5940
+ "_PassKit_SwiftUI",
5566
5941
  "ExpoModulesCore",
5567
5942
  "_MapKit_SwiftUI",
5568
5943
  "PeachJSON",
@@ -5578,6 +5953,7 @@ var init_swift_distribution_lock = __esm({
5578
5953
  "PeachObjC",
5579
5954
  "UIKitCore",
5580
5955
  "PeachICU",
5956
+ "PeachCMark",
5581
5957
  "CoreImage",
5582
5958
  "QuartzCore",
5583
5959
  "CoreGraphics",
@@ -5608,6 +5984,7 @@ var init_swift_distribution_lock = __esm({
5608
5984
  "ActivityKit",
5609
5985
  "SwiftData",
5610
5986
  "UIKit",
5987
+ "React",
5611
5988
  "Combine",
5612
5989
  "PeachFoundationCombine",
5613
5990
  "AppIntents",
@@ -5689,6 +6066,7 @@ var init_swift_distribution_lock = __esm({
5689
6066
  systemVersion: ["string"],
5690
6067
  colorScheme: ["string:light", "string:dark"],
5691
6068
  semanticColors: ["object"],
6069
+ imageAssets: ["object"],
5692
6070
  locale: ["string"],
5693
6071
  dynamicTypeSize: [
5694
6072
  "string:xSmall",
@@ -5710,16 +6088,16 @@ var init_swift_distribution_lock = __esm({
5710
6088
  },
5711
6089
  hosts: {
5712
6090
  "darwin-arm64": {
5713
- sha256: "6b60bae2bc91957af3baee5e9cad44200f15ff3840d8e70afa5ddc63413d880f",
5714
- size: 58565898
6091
+ sha256: "6a3b956b13bcc76dbf0b55533088251e2ae29badcd5c8d66394a2459e0942a32",
6092
+ size: 63180761
5715
6093
  },
5716
6094
  "linux-x64": {
5717
- sha256: "d97e287ca5d7ea0d00dfc9db60be746aec35a9b7412299461ce0d5e77f38b7a8",
5718
- size: 58569694
6095
+ sha256: "37f26adff0a90c0647065b3c2e70bfdae05c84832b27add00915d441f2f79359",
6096
+ size: 63183751
5719
6097
  },
5720
6098
  "linux-arm64": {
5721
- sha256: "495fe6adc7cf1c8ec9fc8de3410c976e65a7ff051ca50ee3f6d0d3fee8aa2c5d",
5722
- size: 58567328
6099
+ sha256: "e329424d19ede87f4c9257de40f88220cdaff42bd82f1ab47616394ec7f32f35",
6100
+ size: 63181548
5723
6101
  }
5724
6102
  }
5725
6103
  };
@@ -5732,24 +6110,24 @@ function swiftCompilerRelease(release) {
5732
6110
  }
5733
6111
  function swiftToolchainBin(release) {
5734
6112
  if (process.platform === "darwin") {
5735
- const dirs = [import_node_os5.default.homedir(), "/"].map(
5736
- (base) => import_node_path6.default.join(base, `Library/Developer/Toolchains/${release}.xctoolchain/usr/bin`)
6113
+ const dirs = [import_node_os6.default.homedir(), "/"].map(
6114
+ (base) => import_node_path7.default.join(base, `Library/Developer/Toolchains/${release}.xctoolchain/usr/bin`)
5737
6115
  );
5738
- return dirs.find((dir) => import_node_fs5.default.existsSync(import_node_path6.default.join(dir, "swift"))) ?? dirs[0];
6116
+ return dirs.find((dir) => import_node_fs6.default.existsSync(import_node_path7.default.join(dir, "swift"))) ?? dirs[0];
5739
6117
  }
5740
6118
  if (process.env.CONTRAST_SWIFT_TOOLCHAINS) {
5741
- return import_node_path6.default.join(process.env.CONTRAST_SWIFT_TOOLCHAINS, release, "usr/bin");
6119
+ return import_node_path7.default.join(process.env.CONTRAST_SWIFT_TOOLCHAINS, release, "usr/bin");
5742
6120
  }
5743
- const image = import_node_path6.default.join("/opt/swift", release, "usr/bin");
5744
- if (import_node_fs5.default.existsSync(import_node_path6.default.join(image, "swift"))) return image;
5745
- return (process.env.PATH ?? "").split(import_node_path6.default.delimiter).find((dir) => dir && import_node_fs5.default.existsSync(import_node_path6.default.join(dir, "swift"))) ?? image;
6121
+ const image = import_node_path7.default.join("/opt/swift", release, "usr/bin");
6122
+ if (import_node_fs6.default.existsSync(import_node_path7.default.join(image, "swift"))) return image;
6123
+ return (process.env.PATH ?? "").split(import_node_path7.default.delimiter).find((dir) => dir && import_node_fs6.default.existsSync(import_node_path7.default.join(dir, "swift"))) ?? image;
5746
6124
  }
5747
6125
  function swiftToolchain(release, sdk) {
5748
6126
  const cached2 = verified.get(`${release}\0${sdk.wasmSdkId}`);
5749
6127
  if (cached2) return cached2;
5750
6128
  const bin = swiftToolchainBin(release);
5751
- const swift = import_node_path6.default.join(bin, "swift");
5752
- const version = import_node_fs5.default.existsSync(swift) ? (0, import_node_child_process5.execFileSync)(swift, ["--version"], {
6129
+ const swift = import_node_path7.default.join(bin, "swift");
6130
+ const version = import_node_fs6.default.existsSync(swift) ? (0, import_node_child_process6.execFileSync)(swift, ["--version"], {
5753
6131
  encoding: "utf8",
5754
6132
  stdio: ["ignore", "pipe", "pipe"]
5755
6133
  }) : "";
@@ -5760,7 +6138,7 @@ function swiftToolchain(release, sdk) {
5760
6138
  ${swiftInstallSteps(release, sdk)}`
5761
6139
  );
5762
6140
  }
5763
- const sdks = (0, import_node_child_process5.execFileSync)(swift, ["sdk", "list"], {
6141
+ const sdks = (0, import_node_child_process6.execFileSync)(swift, ["sdk", "list"], {
5764
6142
  encoding: "utf8",
5765
6143
  stdio: ["ignore", "pipe", "pipe"]
5766
6144
  });
@@ -5795,22 +6173,23 @@ function swiftInstallSteps(release, wasmSdk) {
5795
6173
  ` ${sdk}`
5796
6174
  ].join("\n");
5797
6175
  }
5798
- var import_node_child_process5, import_node_fs5, import_node_os5, import_node_path6, verified;
6176
+ var import_node_child_process6, import_node_fs6, import_node_os6, import_node_path7, verified;
5799
6177
  var init_swift_toolchain = __esm({
5800
6178
  "src/swift-toolchain.ts"() {
5801
6179
  "use strict";
5802
- import_node_child_process5 = require("node:child_process");
5803
- import_node_fs5 = __toESM(require("node:fs"), 1);
5804
- import_node_os5 = __toESM(require("node:os"), 1);
5805
- import_node_path6 = __toESM(require("node:path"), 1);
6180
+ import_node_child_process6 = require("node:child_process");
6181
+ import_node_fs6 = __toESM(require("node:fs"), 1);
6182
+ import_node_os6 = __toESM(require("node:os"), 1);
6183
+ import_node_path7 = __toESM(require("node:path"), 1);
5806
6184
  verified = /* @__PURE__ */ new Map();
5807
6185
  }
5808
6186
  });
5809
6187
 
5810
6188
  // src/swift-distribution.ts
5811
- function swiftDistributionRoot() {
6189
+ async function swiftDistributionRoot(signal) {
6190
+ signal?.throwIfAborted();
5812
6191
  const endpoint = process.env[SWIFT_ENDPOINT_ENV]?.trim().replace(/\/+$/, "");
5813
- if (!endpoint) return Promise.resolve(null);
6192
+ if (!endpoint) return null;
5814
6193
  const lock = parseSwiftDistributionLock(swift_distribution_lock_default);
5815
6194
  const host2 = swiftDistributionHost(process.platform, process.arch);
5816
6195
  if (!host2) {
@@ -5819,16 +6198,19 @@ function swiftDistributionRoot() {
5819
6198
  );
5820
6199
  }
5821
6200
  swiftToolchain(lock.release, lock);
5822
- const dir = import_node_path7.default.join(rnxHomeDir(), "swift", `${lock.id}-${host2}`);
6201
+ const dir = import_node_path8.default.join(rnxHomeDir(), "swift", `${lock.id}-${host2}`);
5823
6202
  let pending = installs.get(dir);
6203
+ if (pending?.controller.signal.aborted) pending = void 0;
5824
6204
  if (!pending) {
5825
- pending = (async () => {
5826
- if (!import_node_fs6.default.existsSync(import_node_path7.default.join(dir, SWIFT_DISTRIBUTION_MANIFEST))) {
6205
+ const controller = new AbortController();
6206
+ const promise = (async () => {
6207
+ if (!import_node_fs7.default.existsSync(import_node_path8.default.join(dir, SWIFT_DISTRIBUTION_MANIFEST))) {
5827
6208
  process.stderr.write(
5828
6209
  `peach: downloading Swift distribution ${lock.id} (${host2})\u2026
5829
6210
  `
5830
6211
  );
5831
6212
  await installVerifiedTarball({
6213
+ signal: controller.signal,
5832
6214
  url: `${endpoint}/${swiftDistributionKey(lock.id, host2)}`,
5833
6215
  digest: {
5834
6216
  algorithm: "sha256",
@@ -5845,17 +6227,52 @@ function swiftDistributionRoot() {
5845
6227
  throw new Error(`${dir} does not hold Swift distribution ${lock.id} (${host2})`);
5846
6228
  }
5847
6229
  return dir;
5848
- })();
5849
- pending.catch(() => installs.delete(dir));
6230
+ })().finally(() => {
6231
+ if (installs.get(dir)?.controller === controller) installs.delete(dir);
6232
+ });
6233
+ pending = { promise, controller, clients: 0 };
5850
6234
  installs.set(dir, pending);
5851
6235
  }
5852
- return pending;
6236
+ const current = pending;
6237
+ current.clients++;
6238
+ let released = false;
6239
+ const release = () => {
6240
+ if (released) return;
6241
+ released = true;
6242
+ if (--current.clients === 0) current.controller.abort(signal?.reason);
6243
+ };
6244
+ let abort;
6245
+ try {
6246
+ const root = await new Promise((resolve2, reject) => {
6247
+ abort = () => {
6248
+ release();
6249
+ const reason = signal?.reason;
6250
+ const error = reason instanceof Error ? reason : new Error("Swift distribution installation canceled", { cause: reason });
6251
+ if (current.clients > 0) reject(error);
6252
+ else
6253
+ current.promise.then(
6254
+ () => reject(error),
6255
+ () => reject(error)
6256
+ );
6257
+ };
6258
+ signal?.addEventListener("abort", abort, { once: true });
6259
+ current.promise.then(resolve2, reject);
6260
+ if (signal?.aborted) abort();
6261
+ });
6262
+ signal?.throwIfAborted();
6263
+ return root;
6264
+ } finally {
6265
+ if (abort) signal?.removeEventListener("abort", abort);
6266
+ release();
6267
+ }
5853
6268
  }
5854
6269
  async function resolveSwiftModule({
5855
- required = false
6270
+ required = false,
6271
+ signal
5856
6272
  } = {}) {
5857
- const checkout2 = import_node_path7.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift");
5858
- if (import_node_fs6.default.existsSync(import_node_path7.default.join(checkout2, "toolchain.json"))) {
6273
+ signal?.throwIfAborted();
6274
+ const checkout2 = import_node_path8.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift");
6275
+ if (import_node_fs7.default.existsSync(import_node_path8.default.join(checkout2, "toolchain.json"))) {
5859
6276
  try {
5860
6277
  return { root: checkout2, ...swiftModuleToolchain(checkout2) };
5861
6278
  } catch (error) {
@@ -5863,22 +6280,22 @@ async function resolveSwiftModule({
5863
6280
  return null;
5864
6281
  }
5865
6282
  }
5866
- const root = await swiftDistributionRoot();
6283
+ const root = await swiftDistributionRoot(signal);
5867
6284
  return root ? { root, ...swiftModuleToolchain(root) } : null;
5868
6285
  }
5869
6286
  function swiftModuleToolchain(root) {
5870
- const pin = swiftDistributionAt(root) ?? JSON.parse(import_node_fs6.default.readFileSync(import_node_path7.default.join(root, "toolchain.json"), "utf8"));
6287
+ const pin = swiftDistributionAt(root) ?? JSON.parse(import_node_fs7.default.readFileSync(import_node_path8.default.join(root, "toolchain.json"), "utf8"));
5871
6288
  return {
5872
6289
  release: pin.release,
5873
6290
  toolchainBin: swiftToolchain(pin.release, swiftModuleSdk(root))
5874
6291
  };
5875
6292
  }
5876
- var import_node_fs6, import_node_path7, SWIFT_ENDPOINT_ENV, installs;
6293
+ var import_node_fs7, import_node_path8, SWIFT_ENDPOINT_ENV, installs;
5877
6294
  var init_swift_distribution = __esm({
5878
6295
  "src/swift-distribution.ts"() {
5879
6296
  "use strict";
5880
- import_node_fs6 = __toESM(require("node:fs"), 1);
5881
- import_node_path7 = __toESM(require("node:path"), 1);
6297
+ import_node_fs7 = __toESM(require("node:fs"), 1);
6298
+ import_node_path8 = __toESM(require("node:path"), 1);
5882
6299
  init_src();
5883
6300
  init_home_paths();
5884
6301
  init_swift_compile();
@@ -5911,8 +6328,8 @@ function imagesetFiles(images) {
5911
6328
  ];
5912
6329
  }).sort((a, b) => a.scale - b.scale);
5913
6330
  }
5914
- function flatScale(path20) {
5915
- const match = /@([23])x\.[^./]+$/.exec(path20);
6331
+ function flatScale(path21) {
6332
+ const match = /@([23])x\.[^./]+$/.exec(path21);
5916
6333
  return match ? Number(match[1]) : 1;
5917
6334
  }
5918
6335
  function providesNamespace(text4) {
@@ -5939,8 +6356,8 @@ function catalogEntryName(contentsPath, kind, readText) {
5939
6356
  }
5940
6357
  return segments.join("/");
5941
6358
  }
5942
- function isFlatResourceImage(path20) {
5943
- return path20.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path20));
6359
+ function isFlatResourceImage(path21) {
6360
+ return path21.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path21));
5944
6361
  }
5945
6362
  function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5946
6363
  const table = [];
@@ -5953,7 +6370,7 @@ function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5953
6370
  seen.set(bundlePath, names);
5954
6371
  return { bundlePath, names };
5955
6372
  };
5956
- const catalogs = paths.filter((path20) => baseOf(path20) === "Contents.json");
6373
+ const catalogs = paths.filter((path21) => baseOf(path21) === "Contents.json");
5957
6374
  for (const contentsPath of catalogs) {
5958
6375
  const name2 = catalogEntryName(contentsPath, ".imageset", readText);
5959
6376
  if (name2 === null) continue;
@@ -5981,13 +6398,13 @@ function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5981
6398
  bundlePath
5982
6399
  });
5983
6400
  }
5984
- for (const path20 of paths) {
5985
- if (!isFlatResourceImage(path20)) continue;
5986
- const name2 = baseOf(path20).slice(0, -extOf(path20).length);
5987
- const { bundlePath, names } = namesFor(path20);
6401
+ for (const path21 of paths) {
6402
+ if (!isFlatResourceImage(path21)) continue;
6403
+ const name2 = baseOf(path21).slice(0, -extOf(path21).length);
6404
+ const { bundlePath, names } = namesFor(path21);
5988
6405
  if (name2 === "" || names.has(name2)) continue;
5989
6406
  names.add(name2);
5990
- table.push({ name: name2, file: path20, scale: flatScale(path20), bundlePath });
6407
+ table.push({ name: name2, file: path21, scale: flatScale(path21), bundlePath });
5991
6408
  }
5992
6409
  return table;
5993
6410
  }
@@ -6016,7 +6433,7 @@ function colorsetValue(color) {
6016
6433
  }
6017
6434
  function enumerateBundleColors(paths, readText) {
6018
6435
  const table = {};
6019
- for (const contentsPath of paths.filter((path20) => baseOf(path20) === "Contents.json")) {
6436
+ for (const contentsPath of paths.filter((path21) => baseOf(path21) === "Contents.json")) {
6020
6437
  const name2 = catalogEntryName(contentsPath, ".colorset", readText);
6021
6438
  if (name2 === null || name2 in table) continue;
6022
6439
  let colors;
@@ -6080,8 +6497,8 @@ function axisExtremes(points) {
6080
6497
  function pathBounds(d) {
6081
6498
  const xs = [];
6082
6499
  const ys = [];
6083
- for (const path20 of d)
6084
- (0, import_svgpath.default)(path20).abs().unshort().unarc().iterate((segment2, _index, x, y) => {
6500
+ for (const path21 of d)
6501
+ (0, import_svgpath.default)(path21).abs().unshort().unarc().iterate((segment2, _index, x, y) => {
6085
6502
  const [command, ...args] = segment2;
6086
6503
  if (command === "M" || command === "L") {
6087
6504
  xs.push(Number(args[0]));
@@ -6108,7 +6525,7 @@ function guide(svg, id, axis) {
6108
6525
  }
6109
6526
  function enumerateBundleSymbols(paths, readText, bundleForFile) {
6110
6527
  const table = {};
6111
- for (const contentsPath of paths.filter((path20) => baseOf(path20) === "Contents.json")) {
6528
+ for (const contentsPath of paths.filter((path21) => baseOf(path21) === "Contents.json")) {
6112
6529
  const name2 = catalogEntryName(contentsPath, ".symbolset", readText);
6113
6530
  if (name2 === null) continue;
6114
6531
  const bundle = bundleForFile(contentsPath);
@@ -6144,24 +6561,24 @@ function enumerateBundleSymbols(paths, readText, bundleForFile) {
6144
6561
  viewBox: "0 0 24 24",
6145
6562
  advance,
6146
6563
  box: [12 - advance / 2, 12 - tall / 2, advance, tall],
6147
- layers: d.map((path20) => ({
6148
- d: (0, import_svgpath.default)(path20).abs().scale(scale).translate(translateX, translateY).round(3).toString()
6564
+ layers: d.map((path21) => ({
6565
+ d: (0, import_svgpath.default)(path21).abs().scale(scale).translate(translateX, translateY).round(3).toString()
6149
6566
  }))
6150
6567
  };
6151
6568
  }
6152
6569
  return table;
6153
6570
  }
6154
- function isCopiedResource(path20) {
6155
- if (path20.split("/").some((segment2) => segment2.endsWith(".atlasc"))) return true;
6156
- const ext = extOf(path20);
6571
+ function isCopiedResource(path21) {
6572
+ if (path21.split("/").some((segment2) => segment2.endsWith(".atlasc"))) return true;
6573
+ const ext = extOf(path21);
6157
6574
  if (ext === ".json" || ext === ".xcstrings") return true;
6158
- return !RASTER_EXTENSIONS.has(ext) && !COMPILED_EXTENSIONS.has(ext) && !path20.split("/").some((segment2) => NESTED_BUNDLE_DIR.test(segment2));
6575
+ return !RASTER_EXTENSIONS.has(ext) && !COMPILED_EXTENSIONS.has(ext) && !path21.split("/").some((segment2) => NESTED_BUNDLE_DIR.test(segment2));
6159
6576
  }
6160
6577
  function enumerateBundleResources(paths) {
6161
6578
  const found = [];
6162
6579
  const seen = /* @__PURE__ */ new Set();
6163
6580
  const ordered = [...paths].filter(
6164
- (path20) => path20.split("/").includes("Resources") && path20.split("/").every((segment2) => segment2 !== "" && segment2 !== "..") && isCopiedResource(path20)
6581
+ (path21) => path21.split("/").includes("Resources") && path21.split("/").every((segment2) => segment2 !== "" && segment2 !== "..") && isCopiedResource(path21)
6165
6582
  ).sort((a, b) => {
6166
6583
  const aDepth = a.split("/").length;
6167
6584
  const bDepth = b.split("/").length;
@@ -6211,7 +6628,8 @@ var init_public_brand = __esm({
6211
6628
  packageName: "peachsim",
6212
6629
  commandName: "peach",
6213
6630
  domain: "peachsim.com",
6214
- origin: "https://peachsim.com"
6631
+ origin: "https://peachsim.com",
6632
+ boxOrigin: "https://rnx-box.contrast.dev"
6215
6633
  });
6216
6634
  rnxPublicBrand = peachPublicBrand;
6217
6635
  }
@@ -6227,14 +6645,14 @@ function sharedDesktopAuthAccounts(user) {
6227
6645
  function getBaseDir() {
6228
6646
  const explicit = process.env[SESSION_FILE_ENV];
6229
6647
  if (explicit?.trim()) {
6230
- return (0, import_node_path8.dirname)((0, import_node_path8.resolve)(explicit));
6648
+ return (0, import_node_path9.dirname)((0, import_node_path9.resolve)(explicit));
6231
6649
  }
6232
6650
  return electronUserDataDir();
6233
6651
  }
6234
6652
  function getSharedDesktopAuthFilePath() {
6235
6653
  const explicit = process.env[SESSION_FILE_ENV];
6236
- if (explicit?.trim()) return (0, import_node_path8.resolve)(explicit);
6237
- return (0, import_node_path8.join)(getBaseDir(), "desktop-auth.json");
6654
+ if (explicit?.trim()) return (0, import_node_path9.resolve)(explicit);
6655
+ return (0, import_node_path9.join)(getBaseDir(), "desktop-auth.json");
6238
6656
  }
6239
6657
  function normalizeUser(input) {
6240
6658
  if (!input || typeof input !== "object") return null;
@@ -6284,26 +6702,26 @@ function normalizeSession(input) {
6284
6702
  }
6285
6703
  function readSharedDesktopAuthSession() {
6286
6704
  const filepath = getSharedDesktopAuthFilePath();
6287
- if (!(0, import_node_fs7.existsSync)(filepath)) return null;
6705
+ if (!(0, import_node_fs8.existsSync)(filepath)) return null;
6288
6706
  try {
6289
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)(filepath, "utf8"));
6707
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(filepath, "utf8"));
6290
6708
  const normalized = normalizeSession(parsed);
6291
6709
  if (!normalized) {
6292
- (0, import_node_fs7.rmSync)(filepath, { force: true });
6710
+ (0, import_node_fs8.rmSync)(filepath, { force: true });
6293
6711
  return null;
6294
6712
  }
6295
6713
  return normalized;
6296
6714
  } catch {
6297
- (0, import_node_fs7.rmSync)(filepath, { force: true });
6715
+ (0, import_node_fs8.rmSync)(filepath, { force: true });
6298
6716
  return null;
6299
6717
  }
6300
6718
  }
6301
- var import_node_fs7, import_node_path8, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
6719
+ var import_node_fs8, import_node_path9, SESSION_VERSION, SESSION_FILE_ENV, DEFAULT_ORIGIN;
6302
6720
  var init_shared_session = __esm({
6303
6721
  "src/auth/shared-session.ts"() {
6304
6722
  "use strict";
6305
- import_node_fs7 = require("node:fs");
6306
- import_node_path8 = require("node:path");
6723
+ import_node_fs8 = require("node:fs");
6724
+ import_node_path9 = require("node:path");
6307
6725
  init_home_paths();
6308
6726
  init_public_brand();
6309
6727
  SESSION_VERSION = 1;
@@ -6690,94 +7108,6 @@ var init_ios_sdk_frameworks = __esm({
6690
7108
  }
6691
7109
  });
6692
7110
 
6693
- // src/swift-binary-modules.ts
6694
- function frameworkModules(paths) {
6695
- const modules = /* @__PURE__ */ new Set();
6696
- for (const file of paths) {
6697
- const segment2 = file.split("/").find((part) => part.endsWith(".framework"));
6698
- if (segment2) modules.add(segment2.slice(0, -".framework".length));
6699
- }
6700
- return [...modules].sort();
6701
- }
6702
- async function range(url, spec) {
6703
- const response = await fetch(url, {
6704
- headers: { range: `bytes=${spec}`, "accept-encoding": "identity" },
6705
- signal: AbortSignal.timeout(2e4)
6706
- });
6707
- const match = /^bytes (\d+)-\d+\/(\d+)$/.exec(
6708
- response.headers.get("content-range") ?? ""
6709
- );
6710
- if (response.status !== 206 || !match)
6711
- throw new Error(`${url} answered ${response.status} to a range request`);
6712
- return {
6713
- bytes: Buffer.from(await response.arrayBuffer()),
6714
- start: Number(match[1]),
6715
- total: Number(match[2])
6716
- };
6717
- }
6718
- async function zipEntries(url) {
6719
- const { total } = await range(url, "0-0");
6720
- const tail = await range(url, `${Math.max(0, total - 65558)}-${total - 1}`);
6721
- let end = tail.bytes.length - 22;
6722
- for (; end >= 0; end--)
6723
- if (tail.bytes.readUInt32LE(end) === 101010256 && end + 22 + tail.bytes.readUInt16LE(end + 20) === tail.bytes.length)
6724
- break;
6725
- if (end < 0) throw new Error(`${url} has no zip end record`);
6726
- let size = tail.bytes.readUInt32LE(end + 12);
6727
- let offset = tail.bytes.readUInt32LE(end + 16);
6728
- if (offset === 4294967295 || size === 4294967295) {
6729
- const locator = end - 20;
6730
- if (locator < 0 || tail.bytes.readUInt32LE(locator) !== 117853008)
6731
- throw new Error(`${url} has no zip64 locator`);
6732
- const recordAt = Number(tail.bytes.readBigUInt64LE(locator + 8));
6733
- const record4 = recordAt >= tail.start ? tail.bytes.subarray(recordAt - tail.start) : (await range(url, `${recordAt}-${recordAt + 55}`)).bytes;
6734
- size = Number(record4.readBigUInt64LE(40));
6735
- offset = Number(record4.readBigUInt64LE(48));
6736
- }
6737
- const directory = offset >= tail.start ? tail.bytes.subarray(offset - tail.start, offset - tail.start + size) : (await range(url, `${offset}-${offset + size - 1}`)).bytes;
6738
- const names = [];
6739
- for (let at = 0; at + 46 <= directory.length; ) {
6740
- if (directory.readUInt32LE(at) !== 33639248) break;
6741
- const nameLength = directory.readUInt16LE(at + 28);
6742
- names.push(directory.toString("utf8", at + 46, at + 46 + nameLength));
6743
- at += 46 + nameLength + directory.readUInt16LE(at + 30) + directory.readUInt16LE(at + 32);
6744
- }
6745
- return names;
6746
- }
6747
- function localEntries(dir) {
6748
- if (!import_node_fs8.default.existsSync(dir)) return [];
6749
- return import_node_fs8.default.readdirSync(dir, { withFileTypes: true }).filter((slice) => slice.isDirectory()).flatMap(
6750
- (slice) => import_node_fs8.default.readdirSync(import_node_path9.default.join(dir, slice.name)).map((entry) => `${slice.name}/${entry}`)
6751
- );
6752
- }
6753
- async function swiftBinaryModules(binary) {
6754
- if (!binary.url) return frameworkModules(localEntries(binary.dir));
6755
- const cached2 = import_node_path9.default.join(
6756
- cacheDir,
6757
- `${(0, import_node_crypto4.createHash)("sha256").update(`${binary.url}\0${binary.checksum ?? ""}`).digest("hex").slice(0, 32)}.json`
6758
- );
6759
- if (import_node_fs8.default.existsSync(cached2)) {
6760
- const value = JSON.parse(import_node_fs8.default.readFileSync(cached2, "utf8"));
6761
- if (Array.isArray(value) && value.every((name2) => typeof name2 === "string"))
6762
- return value;
6763
- }
6764
- const modules = frameworkModules(await zipEntries(binary.url));
6765
- import_node_fs8.default.mkdirSync(cacheDir, { recursive: true });
6766
- import_node_fs8.default.writeFileSync(cached2, JSON.stringify(modules));
6767
- return modules;
6768
- }
6769
- var import_node_crypto4, import_node_fs8, import_node_os6, import_node_path9, cacheDir;
6770
- var init_swift_binary_modules = __esm({
6771
- "src/swift-binary-modules.ts"() {
6772
- "use strict";
6773
- import_node_crypto4 = require("node:crypto");
6774
- import_node_fs8 = __toESM(require("node:fs"), 1);
6775
- import_node_os6 = __toESM(require("node:os"), 1);
6776
- import_node_path9 = __toESM(require("node:path"), 1);
6777
- cacheDir = import_node_path9.default.join(import_node_os6.default.tmpdir(), "peach-swift-binary-modules");
6778
- }
6779
- });
6780
-
6781
7111
  // src/swift-package-manifest.ts
6782
7112
  function swiftCommand() {
6783
7113
  return process.platform === "darwin" ? { file: "xcrun", args: ["swift"] } : { file: import_node_path10.default.join(swiftToolchainBin(swift_distribution_lock_default.release), "swift"), args: [] };
@@ -6793,7 +7123,7 @@ function dump(dir) {
6793
7123
  return { key: key2, raw: record3(JSON.parse(import_node_fs9.default.readFileSync(cached2, "utf8"))) };
6794
7124
  let output;
6795
7125
  try {
6796
- output = (0, import_node_child_process6.execFileSync)(
7126
+ output = (0, import_node_child_process7.execFileSync)(
6797
7127
  command.file,
6798
7128
  [
6799
7129
  ...command.args,
@@ -6980,11 +7310,11 @@ function swiftTargetFiles(manifest, target) {
6980
7310
  ];
6981
7311
  return included.flatMap(walk).filter((file) => !within(file, excluded)).sort();
6982
7312
  }
6983
- var import_node_child_process6, import_node_crypto5, import_node_fs9, import_node_os7, import_node_path10, TARGET_TYPES, isTargetType, record3, array, string, cacheDir2, evaluated, within;
7313
+ var import_node_child_process7, import_node_crypto5, import_node_fs9, import_node_os7, import_node_path10, TARGET_TYPES, isTargetType, record3, array, string, cacheDir2, evaluated, within;
6984
7314
  var init_swift_package_manifest = __esm({
6985
7315
  "src/swift-package-manifest.ts"() {
6986
7316
  "use strict";
6987
- import_node_child_process6 = require("node:child_process");
7317
+ import_node_child_process7 = require("node:child_process");
6988
7318
  import_node_crypto5 = require("node:crypto");
6989
7319
  import_node_fs9 = __toESM(require("node:fs"), 1);
6990
7320
  import_node_os7 = __toESM(require("node:os"), 1);
@@ -7030,7 +7360,7 @@ function checkout(checkouts, identity, pin) {
7030
7360
  const dir = import_node_path11.default.join(checkouts, identity);
7031
7361
  const key2 = `${dir}\0${pin.revision}`;
7032
7362
  if (verified2.has(key2)) return dir;
7033
- const git = (...args) => (0, import_node_child_process7.execFileSync)("git", ["-C", dir, ...args], {
7363
+ const git = (...args) => (0, import_node_child_process8.execFileSync)("git", ["-C", dir, ...args], {
7034
7364
  encoding: "utf8",
7035
7365
  stdio: ["ignore", "pipe", "pipe"]
7036
7366
  }).trim();
@@ -7232,11 +7562,11 @@ function resolveSwiftPackages(options) {
7232
7562
  result.targets = [...targets.entries()].filter(([key2]) => reached.has(key2)).map(([, target]) => target);
7233
7563
  return result;
7234
7564
  }
7235
- var import_node_child_process7, import_node_fs10, import_node_path11, REMOTE_CHECKOUTS, UNSUPPORTED_NATIVE, BINARY, blocker, verified2;
7565
+ var import_node_child_process8, import_node_fs10, import_node_path11, REMOTE_CHECKOUTS, UNSUPPORTED_NATIVE, BINARY, blocker, verified2;
7236
7566
  var init_swift_packages = __esm({
7237
7567
  "src/swift-packages.ts"() {
7238
7568
  "use strict";
7239
- import_node_child_process7 = require("node:child_process");
7569
+ import_node_child_process8 = require("node:child_process");
7240
7570
  import_node_fs10 = __toESM(require("node:fs"), 1);
7241
7571
  import_node_path11 = __toESM(require("node:path"), 1);
7242
7572
  init_swift_package();
@@ -8422,6 +8752,17 @@ function objcView(surface, toolchainBin, stdlib, cacheDir4, work) {
8422
8752
  const slash = include2.indexOf("/");
8423
8753
  if (slash > 0 && /^[A-Z]/.test(include2)) {
8424
8754
  const name2 = include2.slice(0, slash);
8755
+ const umbrella = `${name2}/${name2}.h`;
8756
+ if (Object.hasOwn(
8757
+ IOS_SDK_HEADERS,
8758
+ `System/Library/Frameworks/${name2}.framework/Headers/${name2}.h`
8759
+ )) {
8760
+ const header2 = import_node_path13.default.join(stubIncludes, include2);
8761
+ import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(header2), { recursive: true });
8762
+ import_node_fs13.default.writeFileSync(header2, `#import <${umbrella}>
8763
+ `);
8764
+ return true;
8765
+ }
8425
8766
  const root = import_node_path13.default.join(stubs, `${name2}.framework`);
8426
8767
  const header = import_node_path13.default.join(root, "Headers", include2.slice(slash + 1));
8427
8768
  import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(header), { recursive: true });
@@ -8469,7 +8810,7 @@ function objcView(surface, toolchainBin, stdlib, cacheDir4, work) {
8469
8810
  for (let round = 0; ; round++) {
8470
8811
  import_node_fs13.default.rmSync(out, { recursive: true, force: true });
8471
8812
  import_node_fs13.default.mkdirSync(out, { recursive: true });
8472
- const run5 = (0, import_node_child_process8.spawnSync)(
8813
+ const run5 = (0, import_node_child_process9.spawnSync)(
8473
8814
  import_node_path13.default.join(toolchainBin, "swift-symbolgraph-extract"),
8474
8815
  [
8475
8816
  "-module-name",
@@ -8576,7 +8917,7 @@ function enumValues(graphs, surface, framework, toolchainBin, search, work) {
8576
8917
  if (flag === "-sdk") flags.push("-isysroot", dir);
8577
8918
  else flags.push(flag, dir);
8578
8919
  }
8579
- const run5 = (0, import_node_child_process8.spawnSync)(
8920
+ const run5 = (0, import_node_child_process9.spawnSync)(
8580
8921
  import_node_path13.default.join(toolchainBin, "clang"),
8581
8922
  [
8582
8923
  "-x",
@@ -8645,11 +8986,11 @@ function constantValue(node) {
8645
8986
  }
8646
8987
  return null;
8647
8988
  }
8648
- var import_node_child_process8, import_node_crypto6, import_node_fs13, import_node_path13, ROUNDS, IOS_SDK_ID, headerFiles, MISSING_IMPORT;
8989
+ var import_node_child_process9, import_node_crypto6, import_node_fs13, import_node_path13, ROUNDS, IOS_SDK_ID, headerFiles, MISSING_IMPORT;
8649
8990
  var init_swift_objc_standin = __esm({
8650
8991
  "src/swift-objc-standin.ts"() {
8651
8992
  "use strict";
8652
- import_node_child_process8 = require("node:child_process");
8993
+ import_node_child_process9 = require("node:child_process");
8653
8994
  import_node_crypto6 = require("node:crypto");
8654
8995
  import_node_fs13 = __toESM(require("node:fs"), 1);
8655
8996
  import_node_path13 = __toESM(require("node:path"), 1);
@@ -8809,10 +9150,10 @@ function emitSwiftStandin(graphs, options) {
8809
9150
  owners.push(...physical.map(() => current));
8810
9151
  };
8811
9152
  const scoped = (body) => (symbol, ...rest) => {
8812
- const path20 = pathOf(symbol);
8813
- if (omit.has(path20)) return void skipped.push({ path: path20, reason: omit.get(path20) });
9153
+ const path21 = pathOf(symbol);
9154
+ if (omit.has(path21)) return void skipped.push({ path: path21, reason: omit.get(path21) });
8814
9155
  const previous = current;
8815
- current = path20;
9156
+ current = path21;
8816
9157
  try {
8817
9158
  body(symbol, ...rest);
8818
9159
  } finally {
@@ -8832,14 +9173,14 @@ function emitSwiftStandin(graphs, options) {
8832
9173
  const access = (symbol, openOwner) => symbol.accessLevel === "open" && openOwner ? "open" : "public";
8833
9174
  const emitMember = scoped(
8834
9175
  (member, indent, context) => {
8835
- const path20 = pathOf(member);
9176
+ const path21 = pathOf(member);
8836
9177
  if (TYPE_KINDS.has(member.kind.identifier)) {
8837
9178
  emitType(member, indent);
8838
9179
  return;
8839
9180
  }
8840
9181
  if (member.kind.identifier === "swift.enum.case") return;
8841
9182
  if (!MEMBER_KINDS.has(member.kind.identifier)) {
8842
- skipped.push({ path: path20, reason: `unhandled ${member.kind.identifier}` });
9183
+ skipped.push({ path: path21, reason: `unhandled ${member.kind.identifier}` });
8843
9184
  return;
8844
9185
  }
8845
9186
  const { 1: attrs, 2: rest } = LEADING_ATTRS.exec(text2(member));
@@ -8853,12 +9194,12 @@ function emitSwiftStandin(graphs, options) {
8853
9194
  const final = context.inClass && flags.has("final") ? "final " : "";
8854
9195
  const mutating = flags.has("mutating") ? "mutating " : flags.has("nonmutating") ? "nonmutating " : "";
8855
9196
  let core = `${flags.has("convenience") ? "convenience " : ""}${modifiers[2]}`;
8856
- const override = context.inClass && !options.plain?.has(path20) && (flags.has("override") || overrides.has(member.identifier.precise) || options.forcedOverride?.has(path20) || isObjC(member) && path20.endsWith(".init()")) ? "override " : "";
9197
+ const override = context.inClass && !options.plain?.has(path21) && (flags.has("override") || overrides.has(member.identifier.precise) || options.forcedOverride?.has(path21) || isObjC(member) && path21.endsWith(".init()")) ? "override " : "";
8857
9198
  const head = `${indent}${attrs}${access(member, context.openOwner)} ${required ? "required " : ""}${final}${override}${mutating}`;
8858
- const measured = behavior.get(path20);
8859
- if (measured) used.add(path20);
9199
+ const measured = behavior.get(path21);
9200
+ if (measured) used.add(path21);
8860
9201
  const overloadBody = /\basync\b/.test(core) ? measured?.asyncBody : /\bResult</.test(core) ? measured?.resultBody : void 0;
8861
- const body = overloadBody ?? measured?.body ?? trap(path20);
9202
+ const body = overloadBody ?? measured?.body ?? trap(path21);
8862
9203
  switch (member.kind.identifier) {
8863
9204
  case "swift.property":
8864
9205
  case "swift.type.property":
@@ -8879,7 +9220,7 @@ function emitSwiftStandin(graphs, options) {
8879
9220
  return;
8880
9221
  }
8881
9222
  emit(
8882
- `${head}${computed} { get${effects} { ${body} }${settable && !effects ? ` ${parsed.nonmutating ? "nonmutating " : ""}set { ${measured?.set ?? trap(path20)} }` : ""} }`
9223
+ `${head}${computed} { get${effects} { ${body} }${settable && !effects ? ` ${parsed.nonmutating ? "nonmutating " : ""}set { ${measured?.set ?? trap(path21)} }` : ""} }`
8883
9224
  );
8884
9225
  return;
8885
9226
  }
@@ -8932,7 +9273,7 @@ function emitSwiftStandin(graphs, options) {
8932
9273
  };
8933
9274
  const emitType = scoped(
8934
9275
  (symbol, indent) => {
8935
- const path20 = pathOf(symbol);
9276
+ const path21 = pathOf(symbol);
8936
9277
  const id = symbol.identifier.precise;
8937
9278
  const inner = `${indent} `;
8938
9279
  switch (symbol.kind.identifier) {
@@ -8944,10 +9285,10 @@ function emitSwiftStandin(graphs, options) {
8944
9285
  case "swift.class": {
8945
9286
  const shape = header(symbol, "class", indent);
8946
9287
  if (!shape)
8947
- return void skipped.push({ path: path20, reason: `unparsed class ${text2(symbol)}` });
8948
- const parent = options.superclasses?.get(path20) ?? superclass.get(id);
9288
+ return void skipped.push({ path: path21, reason: `unparsed class ${text2(symbol)}` });
9289
+ const parent = options.superclasses?.get(path21) ?? superclass.get(id);
8949
9290
  const blocked = classBlocked(id);
8950
- if (blocked) return void skipped.push({ path: path20, reason: blocked });
9291
+ if (blocked) return void skipped.push({ path: path21, reason: blocked });
8951
9292
  const ancestors = /* @__PURE__ */ new Set();
8952
9293
  for (let at = superId.get(id); at; at = superId.get(at))
8953
9294
  for (const name2 of conforms.get(at) ?? []) ancestors.add(name2);
@@ -8963,9 +9304,9 @@ function emitSwiftStandin(graphs, options) {
8963
9304
  `${indent}${shape.attrs}${open ? "open" : "public"} class ${shape.name}${shape.generics}${list2.length ? `: ${list2.join(", ")}` : ""}${selfConforming(shape.where)} {`
8964
9305
  );
8965
9306
  const members = membersOf(id);
8966
- const extra = options.behavior?.get(path20)?.members;
9307
+ const extra = options.behavior?.get(path21)?.members;
8967
9308
  if (extra) {
8968
- used.add(path20);
9309
+ used.add(path21);
8969
9310
  emit(`${inner}${extra}`);
8970
9311
  }
8971
9312
  for (const member of members)
@@ -9017,13 +9358,13 @@ function emitSwiftStandin(graphs, options) {
9017
9358
  continue;
9018
9359
  have.add(witnessKey(member));
9019
9360
  have.add(sideLeaf(member));
9020
- emitWitness(member, inner, path20);
9361
+ emitWitness(member, inner, path21);
9021
9362
  }
9022
9363
  }
9023
9364
  const coder = members.some((member) => leaf(member) === "init(coder:)");
9024
9365
  if (designated && !coder && externalRoot(id) !== "NSObject" && externalRoot(id) !== null)
9025
9366
  emit(
9026
- `${inner}public required init?(coder: NSCoder) { ${trap(`${path20}.init(coder:)`)} }`
9367
+ `${inner}public required init?(coder: NSCoder) { ${trap(`${path21}.init(coder:)`)} }`
9027
9368
  );
9028
9369
  emit(`${indent}}`);
9029
9370
  return;
@@ -9031,7 +9372,7 @@ function emitSwiftStandin(graphs, options) {
9031
9372
  case "swift.struct": {
9032
9373
  const shape = header(symbol, "struct", indent);
9033
9374
  if (!shape)
9034
- return void skipped.push({ path: path20, reason: `unparsed struct ${text2(symbol)}` });
9375
+ return void skipped.push({ path: path21, reason: `unparsed struct ${text2(symbol)}` });
9035
9376
  const members = membersOf(id);
9036
9377
  const raw2 = rawType(members);
9037
9378
  const list2 = inheritance(id);
@@ -9063,7 +9404,7 @@ function emitSwiftStandin(graphs, options) {
9063
9404
  case "swift.enum": {
9064
9405
  const shape = header(symbol, "enum", indent);
9065
9406
  if (!shape)
9066
- return void skipped.push({ path: path20, reason: `unparsed enum ${text2(symbol)}` });
9407
+ return void skipped.push({ path: path21, reason: `unparsed enum ${text2(symbol)}` });
9067
9408
  const members = membersOf(id);
9068
9409
  const raw2 = rawType(members);
9069
9410
  const cases = members.filter(
@@ -9072,7 +9413,7 @@ function emitSwiftStandin(graphs, options) {
9072
9413
  const missing = raw2 ? cases.filter((member) => !values.has(member.identifier.precise)) : [];
9073
9414
  if (raw2 && isObjC(symbol) && missing.length > 0)
9074
9415
  return void skipped.push({
9075
- path: path20,
9416
+ path: path21,
9076
9417
  reason: `no header value for ${missing.map(leaf).join(", ")}`
9077
9418
  });
9078
9419
  const list2 = inheritance(id, raw2 ?? void 0).filter(
@@ -9112,7 +9453,7 @@ function emitSwiftStandin(graphs, options) {
9112
9453
  const shape = header(symbol, "protocol", indent);
9113
9454
  if (!shape)
9114
9455
  return void skipped.push({
9115
- path: path20,
9456
+ path: path21,
9116
9457
  reason: `unparsed protocol ${text2(symbol)}`
9117
9458
  });
9118
9459
  const list2 = [...isObjC(symbol) ? ["AnyObject"] : [], ...inheritance(id)];
@@ -9137,7 +9478,7 @@ function emitSwiftStandin(graphs, options) {
9137
9478
  }
9138
9479
  emit(`${indent}}`);
9139
9480
  if (defaults.length > 0) {
9140
- emit(`${indent}extension ${path20} {`);
9481
+ emit(`${indent}extension ${path21} {`);
9141
9482
  for (const member of defaults) {
9142
9483
  const decl = text2(member);
9143
9484
  if (optional.has(member.identifier.precise) && member.kind.identifier === "swift.method" && !decl.replace(/\([^)]*\)/g, "").includes("->") && !/ async\b/.test(decl))
@@ -9183,7 +9524,7 @@ function emitSwiftStandin(graphs, options) {
9183
9524
  return init ? /rawValue:\s*([^)]+)\)/.exec(text2(init))?.[1]?.trim() ?? null : null;
9184
9525
  };
9185
9526
  const emitGlobal = scoped((symbol) => {
9186
- const path20 = pathOf(symbol);
9527
+ const path21 = pathOf(symbol);
9187
9528
  const kind = symbol.kind.identifier;
9188
9529
  if (kind === "swift.func" || kind === "swift.func.op" || kind === "swift.method" || kind === "swift.type.method") {
9189
9530
  const { 1: attrs, 2: rest } = LEADING_ATTRS.exec(text2(symbol));
@@ -9194,22 +9535,22 @@ function emitSwiftStandin(graphs, options) {
9194
9535
  if (fix && !/^(?:prefix|infix|postfix)\b/.test(spelled))
9195
9536
  spelled = `${fix} ${spelled}`;
9196
9537
  }
9197
- const measured = behavior.get(path20);
9198
- if (measured) used.add(path20);
9538
+ const measured = behavior.get(path21);
9539
+ if (measured) used.add(path21);
9199
9540
  const overloadBody = /\basync\b/.test(spelled) ? measured?.asyncBody : /\bResult</.test(spelled) ? measured?.resultBody : void 0;
9200
9541
  emit(
9201
- `${attrs}public ${spelled} { ${overloadBody ?? measured?.body ?? trap(path20)} }`
9542
+ `${attrs}public ${spelled} { ${overloadBody ?? measured?.body ?? trap(path21)} }`
9202
9543
  );
9203
9544
  } else if (kind === "swift.var") {
9204
9545
  const parsed = splitAccessors(text2(symbol).replace(/^let /, "var "));
9205
- const measured = behavior.get(path20);
9206
- if (measured) used.add(path20);
9207
- emit(`public ${parsed.decl} { ${measured?.body ?? trap(path20)} }`);
9208
- } else skipped.push({ path: path20, reason: `unhandled top-level ${kind}` });
9546
+ const measured = behavior.get(path21);
9547
+ if (measured) used.add(path21);
9548
+ emit(`public ${parsed.decl} { ${measured?.body ?? trap(path21)} }`);
9549
+ } else skipped.push({ path: path21, reason: `unhandled top-level ${kind}` });
9209
9550
  });
9210
9551
  const roots = [...byId.values()].filter((symbol) => !owner.has(symbol.identifier.precise) && !unavailable(symbol)).sort((a, b) => pathOf(a).localeCompare(pathOf(b)));
9211
9552
  for (const symbol of roots) {
9212
- const path20 = pathOf(symbol);
9553
+ const path21 = pathOf(symbol);
9213
9554
  if (TYPE_KINDS.has(symbol.kind.identifier)) emitType(symbol, "");
9214
9555
  else emitGlobal(symbol);
9215
9556
  }
@@ -9250,9 +9591,9 @@ function emitSwiftStandin(graphs, options) {
9250
9591
  ...imports.map((name2) => `import ${name2}`),
9251
9592
  ""
9252
9593
  ];
9253
- for (const path20 of behavior.keys())
9254
- if (!used.has(path20))
9255
- skipped.push({ path: path20, reason: "behavior names no emitted declaration" });
9594
+ for (const path21 of behavior.keys())
9595
+ if (!used.has(path21))
9596
+ skipped.push({ path: path21, reason: "behavior names no emitted declaration" });
9256
9597
  return {
9257
9598
  source: `${[...banner, ...lines].join("\n")}
9258
9599
  `,
@@ -9292,7 +9633,7 @@ var STANDIN_EMIT_VERSION, STANDIN_IMPORTS, TYPE_KINDS, MEMBER_KINDS, ACCESSOR_WO
9292
9633
  var init_swift_standin_emit = __esm({
9293
9634
  "src/swift-standin-emit.ts"() {
9294
9635
  "use strict";
9295
- STANDIN_EMIT_VERSION = "6";
9636
+ STANDIN_EMIT_VERSION = "7";
9296
9637
  STANDIN_IMPORTS = ["Foundation", "UIKit"];
9297
9638
  TYPE_KINDS = /* @__PURE__ */ new Set([
9298
9639
  "swift.class",
@@ -9339,7 +9680,7 @@ var init_swift_standin_emit = __esm({
9339
9680
  sideLeaf = (symbol) => `${symbol.kind.identifier.startsWith("swift.type.") ? "type" : "instance"}|leaf|${leaf(symbol)}`;
9340
9681
  isObjC = (symbol) => symbol.identifier.precise.startsWith("c:");
9341
9682
  synthesizedEquality = (symbol, conforms) => conforms.includes("Hashable") ? ["==(_:_:)", "hash(into:)", "hashValue"].includes(leaf(symbol)) : conforms.includes("Equatable") && leaf(symbol) === "==(_:_:)";
9342
- trap = (path20) => `fatalError("${path20} is a binary framework peach cannot run")`;
9683
+ trap = (path21) => `fatalError("${path21} is a binary framework peach cannot run")`;
9343
9684
  KEYWORDS = /* @__PURE__ */ new Set([
9344
9685
  "Type",
9345
9686
  "Protocol",
@@ -9381,7 +9722,7 @@ var init_swift_standin_emit = __esm({
9381
9722
 
9382
9723
  // src/swift-standins.ts
9383
9724
  function exec(file, args, cwd) {
9384
- return (0, import_node_child_process9.execFileSync)(file, args, {
9725
+ return (0, import_node_child_process10.execFileSync)(file, args, {
9385
9726
  cwd,
9386
9727
  encoding: "utf8",
9387
9728
  maxBuffer: 256 * 1024 * 1024,
@@ -9697,7 +10038,7 @@ function graphStandin(module2, graphs, values, wasm, binary, toolchain, work, be
9697
10038
  );
9698
10039
  }
9699
10040
  import_node_fs14.default.writeFileSync(file, source);
9700
- const check = (0, import_node_child_process9.spawnSync)(
10041
+ const check = (0, import_node_child_process10.spawnSync)(
9701
10042
  import_node_path14.default.join(toolchain.toolchainBin, "swiftc"),
9702
10043
  [
9703
10044
  "-typecheck",
@@ -10019,7 +10360,7 @@ function standinLibrary(binary, searchRoot) {
10019
10360
  if (!library) return null;
10020
10361
  const manifest = crateFor(searchRoot, library.slice("lib".length, -".a".length));
10021
10362
  if (!manifest) return null;
10022
- const result = (0, import_node_child_process9.spawnSync)(
10363
+ const result = (0, import_node_child_process10.spawnSync)(
10023
10364
  "cargo",
10024
10365
  [
10025
10366
  "build",
@@ -10081,7 +10422,7 @@ function sourceBinaryStandins(binary, toolchain, provided, behavior) {
10081
10422
  release: toolchain.release
10082
10423
  })
10083
10424
  );
10084
- (0, import_node_child_process9.execFileSync)(
10425
+ const build = (0, import_node_child_process10.spawnSync)(
10085
10426
  "bun",
10086
10427
  [
10087
10428
  import_node_path14.default.join(repo, "scripts/build/swift-standins-submit.ts"),
@@ -10092,11 +10433,20 @@ function sourceBinaryStandins(binary, toolchain, provided, behavior) {
10092
10433
  "--delivery-dir",
10093
10434
  delivery
10094
10435
  ],
10095
- { cwd: repo, stdio: "inherit" }
10096
- );
10097
- const receipt = JSON.parse(
10098
- import_node_fs14.default.readFileSync(import_node_path14.default.join(delivery, "standins.json"), "utf8")
10436
+ { cwd: repo, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }
10099
10437
  );
10438
+ if (build.stdout) process.stdout.write(build.stdout);
10439
+ if (build.stderr) process.stderr.write(build.stderr);
10440
+ if (build.error || build.status !== 0)
10441
+ throw new Error(
10442
+ `source stand-in build for ${binary.target} failed (${build.error?.message ?? build.signal ?? `exit ${build.status}`}): ${build.stderr?.trim().slice(-4e3) || build.stdout?.trim().slice(-4e3) || "builder returned no diagnostic"}`
10443
+ );
10444
+ const output = import_node_path14.default.join(delivery, "standins.json");
10445
+ if (!import_node_fs14.default.existsSync(output))
10446
+ throw new Error(
10447
+ `source stand-in builder returned no standins.json for ${binary.target}`
10448
+ );
10449
+ const receipt = JSON.parse(import_node_fs14.default.readFileSync(output, "utf8"));
10100
10450
  if (!receipt || typeof receipt !== "object" || !("generation" in receipt) || receipt.generation !== generation || !("result" in receipt))
10101
10451
  throw new Error("Swift stand-in builder source differs from the caller");
10102
10452
  const result = receipt.result;
@@ -10209,7 +10559,7 @@ function binaryStandins(binary, toolchain, provided, behavior) {
10209
10559
  const work = import_node_fs14.default.mkdtempSync(import_node_path14.default.join(import_node_os8.default.tmpdir(), "peach-standin-"));
10210
10560
  let result;
10211
10561
  try {
10212
- result = process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && toolchain.moduleRoot === import_node_path14.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(toolchain.moduleRoot) ? sourceBinaryStandins(binary, toolchain, provided, behavior) : found.map((surface) => {
10562
+ result = process.platform === "darwin" && process.env.TM_EXEC_BUILD_PLATFORM !== "mac" && process.env.TM_SESSION && process.env.CI !== "true" && toolchain.moduleRoot === import_node_path14.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(toolchain.moduleRoot) ? sourceBinaryStandins(binary, toolchain, provided, behavior) : found.map((surface) => {
10213
10563
  const dir = import_node_path14.default.join(work, surface.module);
10214
10564
  try {
10215
10565
  if (surface.kind === "c" && configured.has(surface.module))
@@ -10262,11 +10612,11 @@ function swiftStandins(binaries, toolchain, provided = /* @__PURE__ */ new Set()
10262
10612
  }
10263
10613
  return { standins, gaps };
10264
10614
  }
10265
- var import_node_child_process9, import_node_crypto7, import_node_fs14, import_node_os8, import_node_path14, TRIPLE, cacheDir3, key, digests, files, OBJC, identChar, RUST_TARGET, UNSEARCHED, built;
10615
+ var import_node_child_process10, import_node_crypto7, import_node_fs14, import_node_os8, import_node_path14, TRIPLE, cacheDir3, SWIFT_STANDINS_DIR, key, digests, files, OBJC, identChar, RUST_TARGET, UNSEARCHED, built;
10266
10616
  var init_swift_standins = __esm({
10267
10617
  "src/swift-standins.ts"() {
10268
10618
  "use strict";
10269
- import_node_child_process9 = require("node:child_process");
10619
+ import_node_child_process10 = require("node:child_process");
10270
10620
  import_node_crypto7 = require("node:crypto");
10271
10621
  import_node_fs14 = __toESM(require("node:fs"), 1);
10272
10622
  import_node_os8 = __toESM(require("node:os"), 1);
@@ -10278,6 +10628,7 @@ var init_swift_standins = __esm({
10278
10628
  init_swift_standin_emit();
10279
10629
  TRIPLE = "wasm32-unknown-wasip1";
10280
10630
  cacheDir3 = import_node_path14.default.join(import_node_os8.default.homedir(), "builders/cache/peach-swift-standins");
10631
+ SWIFT_STANDINS_DIR = "__standins__";
10281
10632
  key = (...parts) => (0, import_node_crypto7.createHash)("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
10282
10633
  digests = /* @__PURE__ */ new Map();
10283
10634
  files = (dir, test) => import_node_fs14.default.existsSync(dir) ? import_node_fs14.default.readdirSync(dir, { recursive: true, encoding: "utf8" }).filter((file) => test(import_node_path14.default.basename(file))).sort() : [];
@@ -12291,20 +12642,20 @@ function targetSettings(ref, configuration, builtins, options = {}) {
12291
12642
  ...level(str(project.project.buildConfigurationList)),
12292
12643
  ...level(str(target.buildConfigurationList))
12293
12644
  ];
12294
- const resolving = /* @__PURE__ */ new Set();
12645
+ const resolving2 = /* @__PURE__ */ new Set();
12295
12646
  const valueAt = (key2, top) => {
12296
12647
  let at = top;
12297
12648
  while (at >= 0 && levels[at][key2] === void 0) at--;
12298
12649
  if (at < 0) return derived(key2);
12299
12650
  const marker = `${key2}@${at}`;
12300
- if (resolving.has(marker))
12651
+ if (resolving2.has(marker))
12301
12652
  throw new Error(`${str(target.name)} has a cyclic build setting ${key2}`);
12302
- resolving.add(marker);
12653
+ resolving2.add(marker);
12303
12654
  const value = expand(
12304
12655
  levels[at][key2],
12305
12656
  (name2) => name2 === "inherited" ? valueAt(key2, at - 1) : valueAt(name2, levels.length - 1)
12306
12657
  );
12307
- resolving.delete(marker);
12658
+ resolving2.delete(marker);
12308
12659
  return value;
12309
12660
  };
12310
12661
  const derived = (key2) => {
@@ -12615,6 +12966,16 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
12615
12966
  const value = settings(key2);
12616
12967
  info[key2.slice("INFOPLIST_KEY_".length)] = value === "YES" ? true : value === "NO" ? false : value;
12617
12968
  }
12969
+ if (settings("GENERATE_INFOPLIST_FILE") === "YES") {
12970
+ const versions = {
12971
+ CFBundleShortVersionString: "MARKETING_VERSION",
12972
+ CFBundleVersion: "CURRENT_PROJECT_VERSION"
12973
+ };
12974
+ for (const [key2, setting] of Object.entries(versions)) {
12975
+ const value = settings(setting);
12976
+ if (info[key2] === void 0 && value) info[key2] = value;
12977
+ }
12978
+ }
12618
12979
  if (settings("INFOPLIST_KEY_UIApplicationSceneManifest_Generation") === "YES" && info.UIApplicationSceneManifest === void 0) {
12619
12980
  info.UIApplicationSceneManifest = {
12620
12981
  UIApplicationSupportsMultipleScenes: true,
@@ -12920,7 +13281,7 @@ function xcodeLayout(root) {
12920
13281
  for (const standin of standins)
12921
13282
  targets.push({
12922
13283
  name: standin.module,
12923
- path: import_node_path17.default.posix.join(XCODE_STANDINS_DIR, standin.module),
13284
+ path: import_node_path17.default.posix.join(SWIFT_STANDINS_DIR, standin.module),
12924
13285
  executable: false,
12925
13286
  resources: false,
12926
13287
  exclude: [],
@@ -13235,6 +13596,8 @@ function sourceStamp(packagePath, moduleRootOverride, hosted = false) {
13235
13596
  const hash = (0, import_node_crypto8.createHash)("sha256");
13236
13597
  hash.update(packagePath);
13237
13598
  hash.update(JSON.stringify(xcodeProjects.get(packagePath)?.behavior ?? {}));
13599
+ const libraries = projects.get(packagePath)?.libraries;
13600
+ if (libraries) hash.update(JSON.stringify(libraries));
13238
13601
  const projectInputs = new Set(packageFiles(packagePath));
13239
13602
  for (const file of [...projectInputs].sort()) {
13240
13603
  hash.update(import_node_path17.default.relative(packagePath, file));
@@ -13264,14 +13627,14 @@ function otherInputs(input) {
13264
13627
  function icuUrl(origin, artifact) {
13265
13628
  return "url" in artifact.icu ? artifact.icu.url : `${origin}${ICU_PATH}${artifact.icu.sha256}`;
13266
13629
  }
13267
- function standinLibraries(layout) {
13630
+ function standinLibraries(binaries, standins, rootDir) {
13268
13631
  const linked = /* @__PURE__ */ new Map();
13269
- for (const binary of layout.binaries) {
13270
- const modules = layout.standins.filter(
13632
+ for (const binary of binaries) {
13633
+ const modules = standins.filter(
13271
13634
  (standin) => standin.target === binary.target && `${standin.module}.c` in standin.files
13272
13635
  );
13273
13636
  if (modules.length === 0) continue;
13274
- const library = standinLibrary(binary, layout.app.rootDir);
13637
+ const library = standinLibrary(binary, rootDir);
13275
13638
  if (!library) continue;
13276
13639
  linked.set(library, modules);
13277
13640
  }
@@ -13298,14 +13661,14 @@ function packageSources(packagePath, linked = /* @__PURE__ */ new Set()) {
13298
13661
  files2["Package.swift"] = xcodeManifest(xcode);
13299
13662
  for (const standin of xcode.standins)
13300
13663
  for (const [file, text4] of Object.entries(standin.files))
13301
- files2[import_node_path17.default.posix.join(XCODE_STANDINS_DIR, standin.module, file)] = linked.has(standin) && file === `${standin.module}.c` ? `// ${standin.target}'s WebAssembly library defines ${standin.module}'s functions.
13664
+ files2[import_node_path17.default.posix.join(SWIFT_STANDINS_DIR, standin.module, file)] = linked.has(standin) && file === `${standin.module}.c` ? `// ${standin.target}'s WebAssembly library defines ${standin.module}'s functions.
13302
13665
  ` : text4;
13303
13666
  }
13304
13667
  return files2;
13305
13668
  }
13306
13669
  function packageSnapshot(project, entry) {
13307
13670
  const layout = xcodeLayout(project.packagePath);
13308
- const linked = layout ? standinLibraries(layout) : /* @__PURE__ */ new Map();
13671
+ const linked = layout ? standinLibraries(layout.binaries, layout.standins, layout.app.rootDir) : /* @__PURE__ */ new Map();
13309
13672
  const files2 = packageSources(project.packagePath, new Set([...linked.values()].flat()));
13310
13673
  const native = nativeSourceDescriptor(project.packagePath);
13311
13674
  return {
@@ -13324,13 +13687,16 @@ function packageSnapshot(project, entry) {
13324
13687
  files2
13325
13688
  ),
13326
13689
  native,
13327
- ...linked.size > 0 ? {
13328
- libraries: Object.fromEntries(
13329
- [...linked].map(([library, [first]]) => [
13330
- first.module,
13331
- import_node_fs16.default.readFileSync(library).toString("base64")
13332
- ])
13333
- )
13690
+ ...linked.size > 0 || project.libraries ? {
13691
+ libraries: {
13692
+ ...project.libraries,
13693
+ ...Object.fromEntries(
13694
+ [...linked].map(([library, [first]]) => [
13695
+ first.module,
13696
+ import_node_fs16.default.readFileSync(library).toString("base64")
13697
+ ])
13698
+ )
13699
+ }
13334
13700
  } : {},
13335
13701
  ...native ? {
13336
13702
  glue: readPackageFile(
@@ -13376,7 +13742,7 @@ async function compile(packagePath, stamp, moduleRootOverride, hosted, snapshot,
13376
13742
  };
13377
13743
  const moduleRoot = moduleRootOverride ?? linkedModuleRoots(packagePath).find(
13378
13744
  (root) => import_node_fs16.default.existsSync(import_node_path17.default.join(root, "toolchain.json"))
13379
- ) ?? await swiftDistributionRoot();
13745
+ ) ?? await swiftDistributionRoot(signal);
13380
13746
  if (!moduleRoot)
13381
13747
  return {
13382
13748
  ...await compileRemote(packagePath, snapshot, void 0, signal),
@@ -13596,19 +13962,30 @@ async function compileRemote(packagePath, snapshot, hosted, ownerSignal) {
13596
13962
  icu: { url: address.icuUrl }
13597
13963
  };
13598
13964
  }
13599
- function artifactFor(project, entry, moduleRoot) {
13600
- project.signal?.throwIfAborted();
13965
+ function artifactFor(project, entry, moduleRoot, signal = project.signal) {
13966
+ if (project.signal && signal !== project.signal)
13967
+ signal = signal ? AbortSignal.any([project.signal, signal]) : project.signal;
13968
+ signal?.throwIfAborted();
13601
13969
  const stamp = sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted));
13602
13970
  if (project.artifact?.stamp === stamp) return Promise.resolve(project.artifact);
13603
13971
  if (project.building) {
13604
13972
  const running = project.building;
13605
- if (running.stamp === stamp) return running.promise;
13606
- const again = () => artifactFor(project, entry, moduleRoot);
13607
- return running.promise.then(again, again);
13973
+ if (running.stamp === stamp && running.signal === signal) return running.promise;
13974
+ const again = () => artifactFor(project, entry, moduleRoot, signal);
13975
+ const queued = running.promise.then(again, again);
13976
+ if (!signal) return queued;
13977
+ return new Promise((resolve2, reject) => {
13978
+ const stop = () => reject(
13979
+ signal.reason instanceof Error ? signal.reason : new Error("Swift compilation canceled", { cause: signal.reason })
13980
+ );
13981
+ signal.addEventListener("abort", stop, { once: true });
13982
+ if (signal.aborted) stop();
13983
+ queued.then(resolve2, reject).finally(() => signal.removeEventListener("abort", stop));
13984
+ });
13608
13985
  }
13609
13986
  const snapshot = packageSnapshot(project, entry);
13610
13987
  if (sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) !== stamp) {
13611
- return artifactFor(project, entry, moduleRoot);
13988
+ return artifactFor(project, entry, moduleRoot, signal);
13612
13989
  }
13613
13990
  const compiled = project.artifact?.compiled;
13614
13991
  if (project.artifact && compiled && compiled.module === moduleStamp(project.packagePath, moduleRoot, false)) {
@@ -13625,7 +14002,7 @@ function artifactFor(project, entry, moduleRoot) {
13625
14002
  moduleRoot,
13626
14003
  project.hosted,
13627
14004
  snapshot,
13628
- project.signal
14005
+ signal
13629
14006
  ).then(
13630
14007
  (artifact) => {
13631
14008
  project.artifact = artifact;
@@ -13642,12 +14019,12 @@ function artifactFor(project, entry, moduleRoot) {
13642
14019
  }
13643
14020
  );
13644
14021
  const fresh = promise.then(
13645
- (artifact) => sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) === artifact.stamp ? artifact : artifactFor(project, entry, moduleRoot)
14022
+ (artifact) => sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) === artifact.stamp ? artifact : artifactFor(project, entry, moduleRoot, signal)
13646
14023
  );
13647
- project.building = { stamp, promise: fresh };
14024
+ project.building = { stamp, promise: fresh, signal };
13648
14025
  return fresh;
13649
14026
  }
13650
- var import_node_crypto8, import_node_fs16, import_node_os9, import_node_path17, RESOURCE_PATH, ICU_PATH, SKIP_SOURCE_DIRS, NATIVE_DESCRIPTOR, NATIVE_GLUE, SwiftMissingModulesError, projects, xcodeProjects, XCODE_APP_DIR, XCODE_FRAMEWORKS_DIR, XCODE_PACKAGES_DIR, XCODE_STANDINS_DIR, CHECKOUTS_PREFIX, HOSTED_LIMITS, LOCAL_LIMITS, inputLimits, RESOURCE_CONTENT_TYPES, API_GAP_PATTERNS, IOS_SDK_FRAMEWORKS;
14027
+ var import_node_crypto8, import_node_fs16, import_node_os9, import_node_path17, RESOURCE_PATH, ICU_PATH, SKIP_SOURCE_DIRS, NATIVE_DESCRIPTOR, NATIVE_GLUE, SwiftMissingModulesError, projects, xcodeProjects, XCODE_APP_DIR, XCODE_FRAMEWORKS_DIR, XCODE_PACKAGES_DIR, CHECKOUTS_PREFIX, HOSTED_LIMITS, LOCAL_LIMITS, inputLimits, RESOURCE_CONTENT_TYPES, API_GAP_PATTERNS, IOS_SDK_FRAMEWORKS;
13651
14028
  var init_swift_host = __esm({
13652
14029
  "src/swift-host.ts"() {
13653
14030
  "use strict";
@@ -13690,7 +14067,6 @@ var init_swift_host = __esm({
13690
14067
  XCODE_APP_DIR = "__app__";
13691
14068
  XCODE_FRAMEWORKS_DIR = "__frameworks__";
13692
14069
  XCODE_PACKAGES_DIR = "__packages__";
13693
- XCODE_STANDINS_DIR = "__standins__";
13694
14070
  CHECKOUTS_PREFIX = `${REMOTE_CHECKOUTS.split(import_node_path17.default.sep).join(import_node_path17.default.posix.sep)}/`;
13695
14071
  HOSTED_LIMITS = {
13696
14072
  resources: MAX_SWIFT_COMPILE_RESOURCES,
@@ -13738,7 +14114,8 @@ var init_swift_host = __esm({
13738
14114
  });
13739
14115
 
13740
14116
  // src/expo-swift-host.ts
13741
- async function collectExpoSwiftSources(appRoot) {
14117
+ async function collectExpoSwiftSources(appRoot, signal) {
14118
+ signal?.throwIfAborted();
13742
14119
  appRoot = import_node_fs17.default.realpathSync(appRoot);
13743
14120
  const appRequire = (0, import_node_module.createRequire)(import_node_path18.default.join(appRoot, "package.json"));
13744
14121
  let autolinker;
@@ -13762,7 +14139,7 @@ async function collectExpoSwiftSources(appRoot) {
13762
14139
  appRoot,
13763
14140
  "--json"
13764
14141
  ],
13765
- { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv }
14142
+ { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv, signal }
13766
14143
  )
13767
14144
  )
13768
14145
  );
@@ -13802,6 +14179,7 @@ async function collectExpoSwiftSources(appRoot) {
13802
14179
  throw new Error(`duplicate local Expo Swift module ${namespace}`);
13803
14180
  namespacesSeen.add(namespace);
13804
14181
  const files2 = {};
14182
+ const frameworks = /* @__PURE__ */ new Set();
13805
14183
  const classes = [];
13806
14184
  for (const module2 of modules) {
13807
14185
  const className = typeof module2 === "string" ? module2 : module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
@@ -13814,19 +14192,41 @@ async function collectExpoSwiftSources(appRoot) {
13814
14192
  });
13815
14193
  }
13816
14194
  const ios = import_node_path18.default.join(canonical, "ios");
13817
- if (import_node_fs17.default.lstatSync(ios).isSymbolicLink())
13818
- throw new Error(`Expo Swift source directory is a symlink: ${ios}`);
13819
- const walk2 = (dir) => {
14195
+ const directories = /* @__PURE__ */ new Set();
14196
+ const sources = /* @__PURE__ */ new Set();
14197
+ const resolveSource = (file) => {
14198
+ let target;
14199
+ try {
14200
+ target = import_node_fs17.default.realpathSync(file);
14201
+ } catch (cause) {
14202
+ throw new Error(`Cannot resolve Expo Swift source: ${file}`, { cause });
14203
+ }
14204
+ const relative = import_node_path18.default.relative(canonical, target);
14205
+ if (relative === ".." || relative.startsWith(`..${import_node_path18.default.sep}`) || import_node_path18.default.isAbsolute(relative))
14206
+ throw new Error(`Expo Swift source escapes module root: ${file} -> ${target}`);
14207
+ return target;
14208
+ };
14209
+ const walk2 = (dir, binary = false) => {
14210
+ signal?.throwIfAborted();
14211
+ const directory = resolveSource(dir);
14212
+ if (directories.has(directory)) return;
14213
+ directories.add(directory);
13820
14214
  for (const child of import_node_fs17.default.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
13821
14215
  const file = import_node_path18.default.join(dir, child.name);
13822
- if (child.isSymbolicLink())
13823
- throw new Error(`Expo Swift source is a symlink: ${file}`);
13824
- if (child.isDirectory()) {
13825
- if (!child.name.startsWith(".") && child.name !== "build") walk2(file);
14216
+ const linked = child.isSymbolicLink() ? resolveSource(file) : null;
14217
+ const target = linked ? import_node_fs17.default.statSync(linked) : child;
14218
+ if (target.isDirectory()) {
14219
+ const framework = /\.(xcframework|framework)$/.test(child.name);
14220
+ if (framework && !binary) frameworks.add(linked ?? resolveSource(file));
14221
+ if (!child.name.startsWith(".") && child.name !== "build")
14222
+ walk2(file, binary || framework);
13826
14223
  continue;
13827
14224
  }
13828
- if (!child.name.endsWith(".swift")) continue;
13829
- const size = import_node_fs17.default.statSync(file).size;
14225
+ if (!target.isFile() || !child.name.endsWith(".swift")) continue;
14226
+ const source = linked ?? resolveSource(file);
14227
+ if (sources.has(source)) continue;
14228
+ sources.add(source);
14229
+ const size = import_node_fs17.default.statSync(source).size;
13830
14230
  bytes += size;
13831
14231
  fileCount++;
13832
14232
  if (fileCount > MAX_SWIFT_COMPILE_FILES - 2 || bytes > MAX_SWIFT_COMPILE_SOURCE_BYTES)
@@ -13835,7 +14235,7 @@ async function collectExpoSwiftSources(appRoot) {
13835
14235
  // through the underlying module; these source units have no clang pod.
13836
14236
  `import UIKit
13837
14237
  #sourceLocation(file: ${JSON.stringify(file)}, line: 1)
13838
- ${import_node_fs17.default.readFileSync(file, "utf8")}`;
14238
+ ${import_node_fs17.default.readFileSync(source, "utf8")}`;
13839
14239
  }
13840
14240
  };
13841
14241
  walk2(ios);
@@ -13844,7 +14244,8 @@ ${import_node_fs17.default.readFileSync(file, "utf8")}`;
13844
14244
  namespace,
13845
14245
  moduleId: `${namespace}.${module2.name}`,
13846
14246
  classes: [module2.registration],
13847
- files: swiftSourceClosure(files2, [module2.name])
14247
+ files: swiftSourceClosure(files2, [module2.name]),
14248
+ frameworks: [...frameworks]
13848
14249
  };
13849
14250
  unit.files[EXPO_SWIFT_ENTRY] = expoEntry([unit]);
13850
14251
  units.push(unit);
@@ -13880,17 +14281,36 @@ ${import_node_fs17.default.readFileSync(file, "utf8")}`;
13880
14281
  if (namespace === unit.namespace) continue;
13881
14282
  const dependency = byNamespace.get(namespace);
13882
14283
  if (!dependency) throw new Error(`missing local Swift namespace ${namespace}`);
14284
+ unit.frameworks = [
14285
+ .../* @__PURE__ */ new Set([
14286
+ ...unit.frameworks,
14287
+ ...dependency.flatMap((item) => item.frameworks)
14288
+ ])
14289
+ ];
13883
14290
  for (const [name2, source] of Object.entries(allFiles)) {
13884
14291
  if (name2.startsWith(`Sources/${namespace}/`)) unit.files[name2] = source;
13885
14292
  }
13886
14293
  }
13887
- unit.files["Package.swift"] = `// swift-tools-version: 6.0
13888
- import PackageDescription
13889
- let package = Package(name: "PeachExpo", targets: [${[...included].map((name2) => `.target(name: ${JSON.stringify(name2)}, path: ${JSON.stringify(`Sources/${name2}`)})`).join(", ")}, .executableTarget(name: "PeachExpoApp", path: "Sources/PeachExpoApp")])
13890
- `;
14294
+ unit.files["Package.swift"] = expoManifest(unit.files);
13891
14295
  }
13892
14296
  return units;
13893
14297
  }
14298
+ function expoManifest(files2, generation = "") {
14299
+ const targets = /* @__PURE__ */ new Map();
14300
+ for (const file of Object.keys(files2)) {
14301
+ const match = /^(Sources|__standins__)\/([^/]+)\//.exec(file);
14302
+ if (!match || match[2] === "PeachExpoApp") continue;
14303
+ const dir = `${match[1]}/${match[2]}`;
14304
+ if (targets.has(match[2]) && targets.get(match[2]) !== dir)
14305
+ throw new Error(`duplicate Expo Swift compile target ${match[2]}`);
14306
+ targets.set(match[2], dir);
14307
+ }
14308
+ return `// swift-tools-version: 6.0
14309
+ import PackageDescription
14310
+ let package = Package(name: "PeachExpo", targets: [${[...targets].map(([name2, dir]) => `.target(name: ${JSON.stringify(name2)}, path: ${JSON.stringify(dir)}${dir.startsWith(`${SWIFT_STANDINS_DIR}/`) ? ", swiftSettings: [.swiftLanguageMode(.v5)]" : ""})`).join(", ")}, .executableTarget(name: "PeachExpoApp", path: "Sources/PeachExpoApp")])
14311
+ // stand-in inputs: ${generation}
14312
+ `;
14313
+ }
13894
14314
  function expoEntry(units) {
13895
14315
  return `import SwiftUI
13896
14316
  import ExpoModulesCore
@@ -13920,152 +14340,312 @@ function readFailedCompilation(packagePath) {
13920
14340
  }
13921
14341
  if (typeof record4 !== "object" || record4 === null || !("stamp" in record4) || !("diagnostic" in record4) || typeof record4.stamp !== "string" || typeof record4.diagnostic !== "string")
13922
14342
  return null;
14343
+ if ("retryAt" in record4 && (typeof record4.retryAt !== "number" || !Number.isFinite(record4.retryAt) || record4.retryAt <= Date.now()))
14344
+ return null;
13923
14345
  return { stamp: record4.stamp, diagnostic: record4.diagnostic };
13924
14346
  }
13925
- async function compileExpoSwiftModules(root, base, publishArtifact) {
13926
- const units = await collectExpoSwiftSources(root);
13927
- if (!units) return null;
13928
- const module2 = await resolveSwiftModule();
13929
- if (!module2 && publishArtifact)
13930
- throw new Error("No local Swift toolchain or distribution is available");
13931
- const result = {
13932
- namespaces: units.map((unit) => unit.moduleId),
13933
- modules: [],
13934
- failures: []
13935
- };
13936
- if (!module2) {
13937
- for (const unit of units)
13938
- result.failures.push({
13939
- namespace: unit.moduleId,
13940
- diagnostic: "No local Swift toolchain or distribution is available"
13941
- });
13942
- return result;
13943
- }
13944
- const key2 = (0, import_node_crypto9.createHash)("sha256").update(import_node_fs17.default.realpathSync(root)).digest("hex");
13945
- const failures = /* @__PURE__ */ new Map();
13946
- const candidates = [];
13947
- const stamps = /* @__PURE__ */ new Map();
13948
- for (const unit of units) {
13949
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
13950
- syncSwiftTree(
13951
- packagePath,
13952
- new Map(
13953
- Object.entries(unit.files).map(([name2, source]) => [
13954
- import_node_path18.default.join(packagePath, name2),
13955
- source
13956
- ])
13957
- )
13958
- );
13959
- const stamp = sourceStamp(packagePath, module2.root);
13960
- const failed = readFailedCompilation(packagePath);
13961
- if (failed?.stamp === stamp) {
13962
- failures.set(unit.moduleId, failed.diagnostic);
13963
- continue;
13964
- }
13965
- import_node_fs17.default.rmSync(failureRecordPath(packagePath), { force: true });
13966
- stamps.set(unit, stamp);
13967
- candidates.push(unit);
13968
- }
13969
- const link = async (linked2) => {
13970
- const files2 = Object.assign(
13971
- {},
13972
- ...linked2.map((unit) => unit.files)
13973
- );
13974
- files2[EXPO_SWIFT_ENTRY] = expoEntry(linked2);
13975
- const targets = [
13976
- ...new Set(
13977
- Object.keys(files2).flatMap((name2) => {
13978
- const match = /^Sources\/([^/]+)\//.exec(name2);
13979
- return match && match[1] !== "PeachExpoApp" ? [match[1]] : [];
13980
- })
13981
- )
13982
- ];
13983
- files2["Package.swift"] = `// swift-tools-version: 6.0
13984
- import PackageDescription
13985
- let package = Package(name: "PeachExpo", targets: [${targets.map((name2) => `.target(name: ${JSON.stringify(name2)}, path: ${JSON.stringify(`Sources/${name2}`)})`).join(", ")}, .executableTarget(name: "PeachExpoApp", path: "Sources/PeachExpoApp")])
13986
- `;
13987
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, "linked-app");
13988
- syncSwiftTree(
13989
- packagePath,
13990
- new Map(
13991
- Object.entries(files2).map(([name2, source]) => [
13992
- import_node_path18.default.join(packagePath, name2),
13993
- source
13994
- ])
13995
- )
14347
+ async function compileExpoSwiftModules(root, base, publishArtifact, options = {}) {
14348
+ const timeoutMs = options.timeoutMs ?? 6e5;
14349
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647)
14350
+ throw new Error("Expo Swift preparation timeout must be between 1 and 2147483647ms");
14351
+ const controller = new AbortController();
14352
+ const signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
14353
+ const started = performance.now();
14354
+ const report = (message) => console.error(`[expo-swift ${Math.round(performance.now() - started)}ms] ${message}`);
14355
+ const timer = setTimeout(
14356
+ () => controller.abort(new Error(`Expo Swift preparation exceeded ${timeoutMs}ms`)),
14357
+ timeoutMs
14358
+ );
14359
+ try {
14360
+ signal.throwIfAborted();
14361
+ report(`discovering app-owned modules (budget ${timeoutMs}ms): ${root}`);
14362
+ const units = await collectExpoSwiftSources(root, signal);
14363
+ signal.throwIfAborted();
14364
+ if (!units) return null;
14365
+ report(
14366
+ `preparing ${units.length} modules: ${units.map((unit) => unit.moduleId).join(", ")}`
13996
14367
  );
13997
- return artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
13998
- };
13999
- let linked = candidates;
14000
- let artifact;
14001
- if (linked.length) {
14002
- try {
14003
- artifact = await link(linked);
14004
- } catch (linkError) {
14005
- linked = [];
14006
- for (const unit of candidates) {
14007
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
14008
- try {
14009
- await artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
14010
- linked.push(unit);
14011
- } catch (error) {
14012
- const diagnostic = error instanceof Error ? error.message : String(error);
14013
- const appPaths = Object.values(unit.files).flatMap((source) => {
14014
- const match = /^#sourceLocation\(file: (".*"), line: 1\)$/m.exec(source);
14015
- if (!match) return [];
14016
- const file = JSON.parse(match[1]);
14017
- return typeof file === "string" ? [file] : [];
14018
- });
14019
- const errors = diagnostic.match(/^.+:\d+(?::\d+)?: error:.*$/gm) ?? [];
14020
- const sourceErrors = errors.filter(
14021
- (line) => appPaths.some((file) => line.startsWith(`${file}:`)) && !/external macro implementation type|failed to load library plugin/.test(
14022
- line
14023
- )
14368
+ const module2 = await resolveSwiftModule({ signal });
14369
+ signal.throwIfAborted();
14370
+ if (!module2 && publishArtifact)
14371
+ throw new Error("No local Swift toolchain or distribution is available");
14372
+ const result = {
14373
+ namespaces: units.map((unit) => unit.moduleId),
14374
+ modules: [],
14375
+ failures: []
14376
+ };
14377
+ if (!module2) {
14378
+ for (const unit of units)
14379
+ result.failures.push({
14380
+ namespace: unit.moduleId,
14381
+ diagnostic: "No local Swift toolchain or distribution is available"
14382
+ });
14383
+ return result;
14384
+ }
14385
+ const key2 = (0, import_node_crypto9.createHash)("sha256").update(import_node_fs17.default.realpathSync(root)).digest("hex");
14386
+ const failures = /* @__PURE__ */ new Map();
14387
+ const failureRecords = /* @__PURE__ */ new Map();
14388
+ const candidates = [];
14389
+ const stamps = /* @__PURE__ */ new Map();
14390
+ const generations = /* @__PURE__ */ new Map();
14391
+ const gaps = /* @__PURE__ */ new Map();
14392
+ const libraries = /* @__PURE__ */ new Map();
14393
+ for (const unit of units) {
14394
+ signal.throwIfAborted();
14395
+ if (unit.frameworks.length > 0) {
14396
+ const provided = new Set(swiftPeachModules(module2.root));
14397
+ const available = swiftAvailableModules(module2.root, module2.toolchainBin);
14398
+ const binaries = await Promise.all(
14399
+ unit.frameworks.map(async (dir) => {
14400
+ const binary = {
14401
+ target: import_node_path18.default.basename(dir).replace(/\.(xcframework|framework)$/, ""),
14402
+ source: dir,
14403
+ url: null,
14404
+ checksum: null,
14405
+ dir,
14406
+ reached: true
14407
+ };
14408
+ return {
14409
+ binary,
14410
+ modules: dir.endsWith(".framework") ? [binary.target] : await swiftBinaryModules(binary)
14411
+ };
14412
+ })
14413
+ );
14414
+ const importedAvailable = /* @__PURE__ */ new Set([
14415
+ ...available,
14416
+ ...units.map((item) => item.namespace),
14417
+ ...binaries.flatMap((item) => item.modules)
14418
+ ]);
14419
+ const imports = new Set(
14420
+ Object.values(unit.files).flatMap(
14421
+ (source) => swiftImportNames(source, importedAvailable)
14422
+ )
14423
+ );
14424
+ const reached = binaries.filter((item) => item.modules.some((name2) => imports.has(name2))).map((item) => item.binary);
14425
+ if (reached.length > 0) {
14426
+ const toolchain = {
14427
+ moduleRoot: module2.root,
14428
+ release: module2.release,
14429
+ toolchainBin: module2.toolchainBin
14430
+ };
14431
+ const generation = standinGenerationInputs(reached, toolchain);
14432
+ const built2 = swiftStandins(reached, toolchain, provided);
14433
+ const linkedLibraries = standinLibraries(reached, built2.standins, root);
14434
+ const linkedStandins = new Set([...linkedLibraries.values()].flat());
14435
+ for (const standin of built2.standins)
14436
+ for (const [name2, source] of Object.entries(standin.files)) {
14437
+ const file = `${SWIFT_STANDINS_DIR}/${standin.module}/${name2}`;
14438
+ const text4 = linkedStandins.has(standin) && name2 === `${standin.module}.c` ? `// ${standin.target}'s WebAssembly library defines ${standin.module}'s functions.
14439
+ ` : source;
14440
+ if (file in unit.files && unit.files[file] !== text4)
14441
+ throw new Error(`conflicting Expo Swift binary source ${file}`);
14442
+ unit.files[file] = text4;
14443
+ }
14444
+ if (linkedLibraries.size > 0)
14445
+ libraries.set(
14446
+ unit,
14447
+ Object.fromEntries(
14448
+ [...linkedLibraries].map(([library, [first]]) => [
14449
+ first.module,
14450
+ import_node_fs17.default.readFileSync(library).toString("base64")
14451
+ ])
14452
+ )
14453
+ );
14454
+ generations.set(unit, generation);
14455
+ gaps.set(
14456
+ unit,
14457
+ [...built2.gaps].map(([name2, reason]) => `${name2}: no stand-in: ${reason}`)
14024
14458
  );
14025
- if (publishArtifact && (sourceErrors.length === 0 || sourceErrors.length !== errors.length) && !(error instanceof SwiftMissingModulesError))
14026
- throw error;
14027
- const missing = error instanceof SwiftMissingModulesError;
14028
- if ((sourceErrors.length && sourceErrors.length === errors.length || missing) && sourceStamp(packagePath, module2.root) === stamps.get(unit)) {
14029
- import_node_fs17.default.writeFileSync(
14030
- failureRecordPath(packagePath),
14031
- JSON.stringify({
14032
- stamp: stamps.get(unit),
14033
- diagnostic: missing ? diagnostic : sourceErrors.join("\n")
14034
- })
14459
+ unit.files["Package.swift"] = expoManifest(unit.files, generation);
14460
+ }
14461
+ }
14462
+ const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
14463
+ syncSwiftTree(
14464
+ packagePath,
14465
+ new Map(
14466
+ Object.entries(unit.files).map(([name2, source]) => [
14467
+ import_node_path18.default.join(packagePath, name2),
14468
+ source
14469
+ ])
14470
+ )
14471
+ );
14472
+ projectFor(packagePath).libraries = libraries.get(unit);
14473
+ const stamp = sourceStamp(packagePath, module2.root);
14474
+ const failed = readFailedCompilation(packagePath);
14475
+ if (failed?.stamp === stamp) {
14476
+ failures.set(unit.moduleId, failed.diagnostic);
14477
+ continue;
14478
+ }
14479
+ import_node_fs17.default.rmSync(failureRecordPath(packagePath), { force: true });
14480
+ stamps.set(unit, stamp);
14481
+ candidates.push(unit);
14482
+ }
14483
+ const link = async (linked2) => {
14484
+ const files2 = {};
14485
+ for (const unit of linked2)
14486
+ for (const [name2, source] of Object.entries(unit.files)) {
14487
+ if (name2.startsWith(`${SWIFT_STANDINS_DIR}/`) && name2 in files2 && files2[name2] !== source)
14488
+ throw new Error(`conflicting Expo Swift binary source ${name2}`);
14489
+ files2[name2] = source;
14490
+ }
14491
+ files2[EXPO_SWIFT_ENTRY] = expoEntry(linked2);
14492
+ files2["Package.swift"] = expoManifest(
14493
+ files2,
14494
+ linked2.map((unit) => generations.get(unit) ?? "").join(",")
14495
+ );
14496
+ const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, "linked-app");
14497
+ syncSwiftTree(
14498
+ packagePath,
14499
+ new Map(
14500
+ Object.entries(files2).map(([name2, source]) => [
14501
+ import_node_path18.default.join(packagePath, name2),
14502
+ source
14503
+ ])
14504
+ )
14505
+ );
14506
+ const linkedLibraries = /* @__PURE__ */ new Map();
14507
+ for (const unit of linked2)
14508
+ for (const [name2, library] of Object.entries(libraries.get(unit) ?? {})) {
14509
+ if (linkedLibraries.has(name2) && linkedLibraries.get(name2) !== library)
14510
+ throw new Error(`conflicting Expo Swift binary libraries for ${name2}`);
14511
+ linkedLibraries.set(name2, library);
14512
+ }
14513
+ projectFor(packagePath).libraries = linkedLibraries.size > 0 ? Object.fromEntries(linkedLibraries) : void 0;
14514
+ signal.throwIfAborted();
14515
+ const stamp = sourceStamp(packagePath, module2.root);
14516
+ const refused = readFailedCompilation(packagePath);
14517
+ if (refused?.stamp === stamp) {
14518
+ report("reusing recent link refusal");
14519
+ throw new ExpoSwiftLinkRefusal(refused.diagnostic);
14520
+ }
14521
+ import_node_fs17.default.rmSync(failureRecordPath(packagePath), { force: true });
14522
+ report(`linking ${linked2.map((unit) => unit.moduleId).join(", ")}`);
14523
+ try {
14524
+ return await artifactFor(
14525
+ projectFor(packagePath),
14526
+ EXPO_SWIFT_ENTRY,
14527
+ module2.root,
14528
+ signal
14529
+ );
14530
+ } catch (error) {
14531
+ signal.throwIfAborted();
14532
+ const diagnostic = error instanceof Error ? error.message : String(error);
14533
+ if (error instanceof SwiftMissingModulesError || /^.+:\d+(?::\d+)?: error:|^(?:ld(?:\.lld)?|wasm-ld): error:/m.test(diagnostic))
14534
+ throw error;
14535
+ if (sourceStamp(packagePath, module2.root) === stamp)
14536
+ failureRecords.set(packagePath, {
14537
+ stamp,
14538
+ diagnostic,
14539
+ retryAt: Date.now() + 6e4
14540
+ });
14541
+ throw new ExpoSwiftLinkRefusal(diagnostic, { cause: error });
14542
+ }
14543
+ };
14544
+ let linked = candidates;
14545
+ let artifact;
14546
+ if (linked.length) {
14547
+ try {
14548
+ artifact = await link(linked);
14549
+ } catch (linkError) {
14550
+ signal.throwIfAborted();
14551
+ if (linkError instanceof ExpoSwiftLinkRefusal) {
14552
+ if (publishArtifact) throw linkError;
14553
+ for (const unit of candidates) failures.set(unit.moduleId, linkError.message);
14554
+ linked = [];
14555
+ } else {
14556
+ report("linked build failed; isolating module diagnostics");
14557
+ linked = [];
14558
+ for (const unit of candidates) {
14559
+ const packagePath = import_node_path18.default.join(
14560
+ import_node_os10.default.tmpdir(),
14561
+ "peach-expo-swift",
14562
+ key2,
14563
+ unit.moduleId
14035
14564
  );
14565
+ try {
14566
+ signal.throwIfAborted();
14567
+ report(`checking ${unit.moduleId}`);
14568
+ await artifactFor(
14569
+ projectFor(packagePath),
14570
+ EXPO_SWIFT_ENTRY,
14571
+ module2.root,
14572
+ signal
14573
+ );
14574
+ linked.push(unit);
14575
+ } catch (error) {
14576
+ signal.throwIfAborted();
14577
+ const diagnostic = [
14578
+ error instanceof Error ? error.message : String(error),
14579
+ ...gaps.get(unit) ?? []
14580
+ ].join("\n");
14581
+ const appPaths = Object.values(unit.files).flatMap((source) => {
14582
+ const match = /^#sourceLocation\(file: (".*"), line: 1\)$/m.exec(source);
14583
+ if (!match) return [];
14584
+ const file = JSON.parse(match[1]);
14585
+ return typeof file === "string" ? [file] : [];
14586
+ });
14587
+ const errors = diagnostic.match(/^.+:\d+(?::\d+)?: error:.*$/gm) ?? [];
14588
+ const sourceErrors = errors.filter(
14589
+ (line) => appPaths.some((file) => line.startsWith(`${file}:`)) && !/external macro implementation type|failed to load library plugin/.test(
14590
+ line
14591
+ )
14592
+ );
14593
+ if (publishArtifact && (sourceErrors.length === 0 || sourceErrors.length !== errors.length) && !(error instanceof SwiftMissingModulesError))
14594
+ throw error;
14595
+ const missing = error instanceof SwiftMissingModulesError;
14596
+ if ((sourceErrors.length && sourceErrors.length === errors.length || missing) && sourceStamp(packagePath, module2.root) === stamps.get(unit)) {
14597
+ failureRecords.set(packagePath, {
14598
+ stamp: stamps.get(unit),
14599
+ diagnostic: missing ? diagnostic : sourceErrors.join("\n")
14600
+ });
14601
+ }
14602
+ failures.set(
14603
+ unit.moduleId,
14604
+ sourceErrors.length ? sourceErrors.join("\n") : diagnostic
14605
+ );
14606
+ }
14036
14607
  }
14037
- failures.set(
14038
- unit.moduleId,
14039
- sourceErrors.length ? sourceErrors.join("\n") : diagnostic
14040
- );
14608
+ if (linked.length === candidates.length) throw linkError;
14609
+ if (linked.length) artifact = await link(linked);
14041
14610
  }
14042
14611
  }
14043
- if (linked.length === candidates.length) throw linkError;
14044
- if (linked.length) artifact = await link(linked);
14045
14612
  }
14613
+ for (const unit of units) {
14614
+ const diagnostic = failures.get(unit.moduleId);
14615
+ if (diagnostic !== void 0)
14616
+ result.failures.push({ namespace: unit.moduleId, diagnostic });
14617
+ }
14618
+ if (artifact) {
14619
+ signal.throwIfAborted();
14620
+ await publishArtifact?.(artifact, signal);
14621
+ result.modules.push({
14622
+ namespaces: linked.map((unit) => unit.moduleId),
14623
+ url: `${base}/__peach/swift/${artifact.hash}.wasm`,
14624
+ hash: artifact.hash,
14625
+ icuUrl: icuUrl(base, artifact),
14626
+ rootId: `${key2}/Expo`
14627
+ });
14628
+ }
14629
+ signal.throwIfAborted();
14630
+ for (const [packagePath, record4] of failureRecords)
14631
+ import_node_fs17.default.writeFileSync(failureRecordPath(packagePath), JSON.stringify(record4));
14632
+ report(
14633
+ `ready: ${result.modules.length} artifact, ${result.failures.length} unavailable modules`
14634
+ );
14635
+ return result;
14636
+ } catch (error) {
14637
+ const failure2 = signal.aborted ? signal.reason : error;
14638
+ report(`failed: ${failure2 instanceof Error ? failure2.message : String(failure2)}`);
14639
+ throw failure2;
14640
+ } finally {
14641
+ clearTimeout(timer);
14046
14642
  }
14047
- for (const unit of units) {
14048
- const diagnostic = failures.get(unit.moduleId);
14049
- if (diagnostic !== void 0)
14050
- result.failures.push({ namespace: unit.moduleId, diagnostic });
14051
- }
14052
- if (artifact) {
14053
- await publishArtifact?.(artifact);
14054
- result.modules.push({
14055
- namespaces: linked.map((unit) => unit.moduleId),
14056
- url: `${base}/__peach/swift/${artifact.hash}.wasm`,
14057
- hash: artifact.hash,
14058
- icuUrl: icuUrl(base, artifact),
14059
- rootId: `${key2}/Expo`
14060
- });
14061
- }
14062
- return result;
14063
14643
  }
14064
- var import_node_child_process10, import_node_crypto9, import_node_fs17, import_node_module, import_node_os10, import_node_path18, import_node_util2, run2, scriptEnv, EXPO_SWIFT_ENTRY;
14644
+ var import_node_child_process11, import_node_crypto9, import_node_fs17, import_node_module, import_node_os10, import_node_path18, import_node_util2, run2, scriptEnv, EXPO_SWIFT_ENTRY, ExpoSwiftLinkRefusal;
14065
14645
  var init_expo_swift_host = __esm({
14066
14646
  "src/expo-swift-host.ts"() {
14067
14647
  "use strict";
14068
- import_node_child_process10 = require("node:child_process");
14648
+ import_node_child_process11 = require("node:child_process");
14069
14649
  import_node_crypto9 = require("node:crypto");
14070
14650
  import_node_fs17 = __toESM(require("node:fs"), 1);
14071
14651
  import_node_module = require("node:module");
@@ -14074,13 +14654,17 @@ var init_expo_swift_host = __esm({
14074
14654
  import_node_util2 = require("node:util");
14075
14655
  init_internal_child();
14076
14656
  init_backend_origin();
14657
+ init_swift_binary_modules();
14077
14658
  init_swift_compile();
14078
14659
  init_swift_distribution();
14079
14660
  init_swift_host();
14661
+ init_swift_standins();
14080
14662
  init_swift_submit();
14081
- run2 = (0, import_node_util2.promisify)(import_node_child_process10.execFile);
14663
+ run2 = (0, import_node_util2.promisify)(import_node_child_process11.execFile);
14082
14664
  scriptEnv = { ...process.env, [RNX_FORKED_SCRIPT_ENV]: "1" };
14083
14665
  EXPO_SWIFT_ENTRY = "Sources/PeachExpoApp/PeachExpoEntry.swift";
14666
+ ExpoSwiftLinkRefusal = class extends Error {
14667
+ };
14084
14668
  }
14085
14669
  });
14086
14670
 
@@ -14091,20 +14675,25 @@ __export(expo_swift_bundle_exports, {
14091
14675
  });
14092
14676
  async function buildExpoSwiftBundle(appRoot) {
14093
14677
  const assets2 = [];
14094
- const metadata = await compileExpoSwiftModules(appRoot, "", async (artifact) => {
14095
- assets2.push({
14096
- path: `__peach/swift/${artifact.hash}.wasm`,
14097
- bytes: artifact.bytes,
14098
- contentType: "application/wasm"
14099
- });
14100
- if ("gzip" in artifact.icu) {
14678
+ const metadata = await compileExpoSwiftModules(
14679
+ appRoot,
14680
+ "",
14681
+ async (artifact, signal) => {
14682
+ signal.throwIfAborted();
14101
14683
  assets2.push({
14102
- path: `__peach/swift-icu/${artifact.icu.sha256}`,
14103
- bytes: artifact.icu.gzip,
14104
- contentType: "application/gzip"
14684
+ path: `__peach/swift/${artifact.hash}.wasm`,
14685
+ bytes: artifact.bytes,
14686
+ contentType: "application/wasm"
14105
14687
  });
14688
+ if ("gzip" in artifact.icu) {
14689
+ assets2.push({
14690
+ path: `__peach/swift-icu/${artifact.icu.sha256}`,
14691
+ bytes: artifact.icu.gzip,
14692
+ contentType: "application/gzip"
14693
+ });
14694
+ }
14106
14695
  }
14107
- });
14696
+ );
14108
14697
  if (!metadata) return null;
14109
14698
  return { metadata, assets: assets2 };
14110
14699
  }
@@ -14115,6 +14704,78 @@ var init_expo_swift_bundle = __esm({
14115
14704
  }
14116
14705
  });
14117
14706
 
14707
+ // src/androidAutolinkingContract.ts
14708
+ var init_androidAutolinkingContract = __esm({
14709
+ "src/androidAutolinkingContract.ts"() {
14710
+ "use strict";
14711
+ init_bundleGlobalFooter();
14712
+ }
14713
+ });
14714
+
14715
+ // src/android-autolinking.ts
14716
+ async function resolveExpoAndroidAutolinking(appRoot) {
14717
+ const root = import_node_fs18.default.realpathSync(appRoot);
14718
+ const existing = resolving.get(root);
14719
+ if (existing) return existing;
14720
+ const pending = resolveAndroidModules(root);
14721
+ resolving.set(root, pending);
14722
+ try {
14723
+ return await pending;
14724
+ } finally {
14725
+ if (resolving.get(root) === pending) resolving.delete(root);
14726
+ }
14727
+ }
14728
+ async function resolveAndroidModules(appRoot) {
14729
+ let autolinker;
14730
+ try {
14731
+ autolinker = (0, import_node_module2.createRequire)(import_node_path19.default.join(appRoot, "package.json")).resolve(
14732
+ "expo-modules-autolinking/package.json"
14733
+ );
14734
+ } catch (error) {
14735
+ if (isRecord(error) && error.code === "MODULE_NOT_FOUND") return [];
14736
+ throw error;
14737
+ }
14738
+ const { stdout } = await run3(
14739
+ process.execPath,
14740
+ [
14741
+ import_node_path19.default.join(import_node_path19.default.dirname(autolinker), "bin/expo-modules-autolinking.js"),
14742
+ "resolve",
14743
+ "--platform",
14744
+ "android",
14745
+ "--project-root",
14746
+ appRoot,
14747
+ "--json"
14748
+ ],
14749
+ {
14750
+ timeout: 3e4,
14751
+ maxBuffer: 8 * 1024 * 1024,
14752
+ env: { ...process.env, [RNX_FORKED_SCRIPT_ENV]: "1" }
14753
+ }
14754
+ );
14755
+ const resolved = JSON.parse(stdout);
14756
+ if (!isRecord(resolved) || !Array.isArray(resolved.modules))
14757
+ throw new Error("invalid Expo Android autolinking result");
14758
+ if (!resolved.modules.every(isRecord))
14759
+ throw new Error("invalid Expo Android autolinking entry");
14760
+ return resolved.modules;
14761
+ }
14762
+ var import_node_child_process12, import_node_fs18, import_node_module2, import_node_path19, import_node_util3, run3, resolving;
14763
+ var init_android_autolinking = __esm({
14764
+ "src/android-autolinking.ts"() {
14765
+ "use strict";
14766
+ import_node_child_process12 = require("node:child_process");
14767
+ import_node_fs18 = __toESM(require("node:fs"), 1);
14768
+ import_node_module2 = require("node:module");
14769
+ import_node_path19 = __toESM(require("node:path"), 1);
14770
+ import_node_util3 = require("node:util");
14771
+ init_internal_child();
14772
+ init_androidAutolinkingContract();
14773
+ init_is_record();
14774
+ run3 = (0, import_node_util3.promisify)(import_node_child_process12.execFile);
14775
+ resolving = /* @__PURE__ */ new Map();
14776
+ }
14777
+ });
14778
+
14118
14779
  // cli/standalone.ts
14119
14780
  var IS_STANDALONE;
14120
14781
  var init_standalone = __esm({
@@ -14127,45 +14788,45 @@ var init_standalone = __esm({
14127
14788
  // src/kotlin-module.ts
14128
14789
  function peachKotlinModuleRoot() {
14129
14790
  if (!IS_STANDALONE)
14130
- return import_node_path19.default.resolve(import_node_path19.default.dirname((0, import_node_url2.fileURLToPath)(__sootsim_import_meta_url)), "..", "kotlin");
14791
+ return import_node_path20.default.resolve(import_node_path20.default.dirname((0, import_node_url2.fileURLToPath)(__sootsim_import_meta_url)), "..", "kotlin");
14131
14792
  if (installedRoot) return installedRoot;
14132
14793
  const files2 = __PEACH_BUNDLED_KOTLIN__;
14133
14794
  const digest2 = (0, import_node_crypto10.createHash)("sha256").update(JSON.stringify(files2)).digest("hex");
14134
- const parent = import_node_path19.default.join(rnxHomeDir(), "kotlin", "modules");
14135
- const root = import_node_path19.default.join(parent, digest2);
14136
- import_node_fs18.default.mkdirSync(parent, { recursive: true });
14137
- if (!import_node_fs18.default.existsSync(root)) {
14138
- const pending = import_node_fs18.default.mkdtempSync(import_node_path19.default.join(parent, ".install-"));
14795
+ const parent = import_node_path20.default.join(rnxHomeDir(), "kotlin", "modules");
14796
+ const root = import_node_path20.default.join(parent, digest2);
14797
+ import_node_fs19.default.mkdirSync(parent, { recursive: true });
14798
+ if (!import_node_fs19.default.existsSync(root)) {
14799
+ const pending = import_node_fs19.default.mkdtempSync(import_node_path20.default.join(parent, ".install-"));
14139
14800
  try {
14140
14801
  for (const [name2, contents] of Object.entries(files2)) {
14141
- const file = import_node_path19.default.join(pending, name2);
14142
- import_node_fs18.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
14143
- import_node_fs18.default.writeFileSync(file, contents);
14802
+ const file = import_node_path20.default.join(pending, name2);
14803
+ import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
14804
+ import_node_fs19.default.writeFileSync(file, contents);
14144
14805
  }
14145
14806
  try {
14146
- import_node_fs18.default.renameSync(pending, root);
14807
+ import_node_fs19.default.renameSync(pending, root);
14147
14808
  } catch (error) {
14148
14809
  if (!isRecord(error) || error.code !== "EEXIST" && error.code !== "ENOTEMPTY")
14149
14810
  throw error;
14150
14811
  }
14151
14812
  } finally {
14152
- import_node_fs18.default.rmSync(pending, { recursive: true, force: true });
14813
+ import_node_fs19.default.rmSync(pending, { recursive: true, force: true });
14153
14814
  }
14154
14815
  }
14155
14816
  for (const [name2, contents] of Object.entries(files2)) {
14156
- if (import_node_fs18.default.readFileSync(import_node_path19.default.join(root, name2), "utf8") !== contents)
14817
+ if (import_node_fs19.default.readFileSync(import_node_path20.default.join(root, name2), "utf8") !== contents)
14157
14818
  throw new Error(`packaged Kotlin module differs from this CLI: ${name2}`);
14158
14819
  }
14159
14820
  installedRoot = root;
14160
14821
  return root;
14161
14822
  }
14162
- var import_node_crypto10, import_node_fs18, import_node_path19, import_node_url2, installedRoot;
14823
+ var import_node_crypto10, import_node_fs19, import_node_path20, import_node_url2, installedRoot;
14163
14824
  var init_kotlin_module = __esm({
14164
14825
  "src/kotlin-module.ts"() {
14165
14826
  "use strict";
14166
14827
  import_node_crypto10 = require("node:crypto");
14167
- import_node_fs18 = __toESM(require("node:fs"), 1);
14168
- import_node_path19 = __toESM(require("node:path"), 1);
14828
+ import_node_fs19 = __toESM(require("node:fs"), 1);
14829
+ import_node_path20 = __toESM(require("node:path"), 1);
14169
14830
  import_node_url2 = require("node:url");
14170
14831
  init_standalone();
14171
14832
  init_home_paths();
@@ -14270,7 +14931,7 @@ __export(kotlin_host_exports, {
14270
14931
  });
14271
14932
  function readToolchain(moduleRoot) {
14272
14933
  const parsed = JSON.parse(
14273
- import_node_fs19.default.readFileSync(import_node_path20.default.join(moduleRoot, "toolchain.json"), "utf8")
14934
+ import_node_fs20.default.readFileSync(import_node_path21.default.join(moduleRoot, "toolchain.json"), "utf8")
14274
14935
  );
14275
14936
  const download = (value) => {
14276
14937
  if (!isRecord(value) || typeof value.url !== "string" || typeof value.sha256 !== "string")
@@ -14311,43 +14972,43 @@ function readToolchain(moduleRoot) {
14311
14972
  };
14312
14973
  }
14313
14974
  function kotlinHome() {
14314
- return import_node_path20.default.join(rnxHomeDir(), "kotlin");
14975
+ return import_node_path21.default.join(rnxHomeDir(), "kotlin");
14315
14976
  }
14316
14977
  async function fetchVerified(download, target) {
14317
- if (import_node_fs19.default.existsSync(target)) return;
14978
+ if (import_node_fs20.default.existsSync(target)) return;
14318
14979
  const response = await fetch(download.url);
14319
14980
  if (!response.ok) throw new Error(`${download.url} answered ${response.status}`);
14320
14981
  const bytes = Buffer.from(await response.arrayBuffer());
14321
14982
  const digest2 = (0, import_node_crypto11.createHash)("sha256").update(bytes).digest("hex");
14322
14983
  if (digest2 !== download.sha256)
14323
14984
  throw new Error(`${download.url} has sha256 ${digest2}, expected ${download.sha256}`);
14324
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(target), { recursive: true });
14985
+ import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(target), { recursive: true });
14325
14986
  const partial = `${target}.${process.pid}.partial`;
14326
- import_node_fs19.default.writeFileSync(partial, bytes);
14327
- import_node_fs19.default.renameSync(partial, target);
14987
+ import_node_fs20.default.writeFileSync(partial, bytes);
14988
+ import_node_fs20.default.renameSync(partial, target);
14328
14989
  }
14329
14990
  function ensureToolchain(toolchain) {
14330
14991
  const key2 = JSON.stringify(toolchain);
14331
14992
  const pending = toolchains.get(key2);
14332
14993
  if (pending) return pending;
14333
14994
  const ready = (async () => {
14334
- const dir = import_node_path20.default.join(kotlinHome(), toolchain.compiler.version);
14335
- const kotlinc = import_node_path20.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
14336
- if (!import_node_fs19.default.existsSync(kotlinc)) {
14337
- const zip = import_node_path20.default.join(dir, "kotlin-compiler.zip");
14995
+ const dir = import_node_path21.default.join(kotlinHome(), toolchain.compiler.version);
14996
+ const kotlinc = import_node_path21.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
14997
+ if (!import_node_fs20.default.existsSync(kotlinc)) {
14998
+ const zip = import_node_path21.default.join(dir, "kotlin-compiler.zip");
14338
14999
  await fetchVerified(toolchain.compiler, zip);
14339
- await run3("unzip", ["-q", "-o", zip, "-d", dir]);
14340
- import_node_fs19.default.rmSync(zip);
15000
+ await run4("unzip", ["-q", "-o", zip, "-d", dir]);
15001
+ import_node_fs20.default.rmSync(zip);
14341
15002
  }
14342
- const java = process.env.JAVA_HOME ? import_node_path20.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
14343
- await run3(java, ["-version"]).catch(() => {
15003
+ const java = process.env.JAVA_HOME ? import_node_path21.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
15004
+ await run4(java, ["-version"]).catch(() => {
14344
15005
  throw new Error(
14345
15006
  `Kotlin in Peach compiles with kotlinc, which needs a Java runtime (17 or newer, as android builds use); ${process.env.JAVA_HOME ? `JAVA_HOME ${process.env.JAVA_HOME} has none` : "set JAVA_HOME or put java on PATH"}`
14346
15007
  );
14347
15008
  });
14348
- const libraries = [import_node_path20.default.join(dir, "kotlinc", "lib", "kotlin-stdlib-wasm-js.klib")];
15009
+ const libraries = [import_node_path21.default.join(dir, "kotlinc", "lib", "kotlin-stdlib-wasm-js.klib")];
14349
15010
  for (const library of toolchain.libraries) {
14350
- const target = import_node_path20.default.join(dir, library.name);
15011
+ const target = import_node_path21.default.join(dir, library.name);
14351
15012
  await fetchVerified(library, target);
14352
15013
  libraries.push(target);
14353
15014
  }
@@ -14360,11 +15021,11 @@ function ensureToolchain(toolchain) {
14360
15021
  return ready;
14361
15022
  }
14362
15023
  function appKotlinLanguage(root) {
14363
- const reactNative = import_node_path20.default.dirname(
14364
- (0, import_node_module2.createRequire)(import_node_path20.default.join(root, "package.json")).resolve("react-native/package.json")
15024
+ const reactNative = import_node_path21.default.dirname(
15025
+ (0, import_node_module3.createRequire)(import_node_path21.default.join(root, "package.json")).resolve("react-native/package.json")
14365
15026
  );
14366
- const versions = import_node_fs19.default.readFileSync(
14367
- import_node_path20.default.join(reactNative, "gradle", "libs.versions.toml"),
15027
+ const versions = import_node_fs20.default.readFileSync(
15028
+ import_node_path21.default.join(reactNative, "gradle", "libs.versions.toml"),
14368
15029
  "utf8"
14369
15030
  );
14370
15031
  const match = /^kotlin\s*=\s*"(\d+)\.(\d+)/m.exec(versions);
@@ -14375,9 +15036,9 @@ function appKotlinLanguage(root) {
14375
15036
  function kotlinSources(root, skip = SKIP_DIRS) {
14376
15037
  const sources = [];
14377
15038
  const walk2 = (dir) => {
14378
- for (const entry of import_node_fs19.default.readdirSync(dir, { withFileTypes: true })) {
15039
+ for (const entry of import_node_fs20.default.readdirSync(dir, { withFileTypes: true })) {
14379
15040
  if (entry.name.startsWith(".") || skip.has(entry.name)) continue;
14380
- const full = import_node_path20.default.join(dir, entry.name);
15041
+ const full = import_node_path21.default.join(dir, entry.name);
14381
15042
  if (entry.isDirectory()) walk2(full);
14382
15043
  else if (entry.isFile() && entry.name.endsWith(".kt")) sources.push(full);
14383
15044
  }
@@ -14387,51 +15048,51 @@ function kotlinSources(root, skip = SKIP_DIRS) {
14387
15048
  }
14388
15049
  function kotlinPlatformSources(moduleRoot, usesCompose) {
14389
15050
  return ["Sources", "JniPlatformSources", "JniSources"].flatMap(
14390
- (directory) => kotlinSources(import_node_path20.default.join(moduleRoot, directory), /* @__PURE__ */ new Set()).filter(
15051
+ (directory) => kotlinSources(import_node_path21.default.join(moduleRoot, directory), /* @__PURE__ */ new Set()).filter(
14391
15052
  (file) => usesCompose ? !file.endsWith("/androidx/annotation/CallSuper.kt") : !file.endsWith("/OneNativeSourceViewDispatch.kt")
14392
15053
  )
14393
15054
  );
14394
15055
  }
14395
15056
  function ensureCompilerPlugin(kotlinc, plugin) {
14396
- const cache = import_node_path20.default.join(kotlinHome(), "compiler-plugins");
14397
- const out = import_node_path20.default.join(cache, plugin.hash);
14398
- if (import_node_fs19.default.existsSync(out)) return Promise.resolve(out);
15057
+ const cache = import_node_path21.default.join(kotlinHome(), "compiler-plugins");
15058
+ const out = import_node_path21.default.join(cache, plugin.hash);
15059
+ if (import_node_fs20.default.existsSync(out)) return Promise.resolve(out);
14399
15060
  const pending = compilerPlugins.get(plugin.hash);
14400
15061
  if (pending) return pending;
14401
15062
  const build = (async () => {
14402
- import_node_fs19.default.mkdirSync(cache, { recursive: true });
14403
- const work = import_node_fs19.default.mkdtempSync(import_node_path20.default.join(cache, `${plugin.hash}-`));
14404
- const classes = import_node_path20.default.join(work, "classes");
15063
+ import_node_fs20.default.mkdirSync(cache, { recursive: true });
15064
+ const work = import_node_fs20.default.mkdtempSync(import_node_path21.default.join(cache, `${plugin.hash}-`));
15065
+ const classes = import_node_path21.default.join(work, "classes");
14405
15066
  try {
14406
15067
  const sources = [];
14407
15068
  for (const { name: name2, bytes } of plugin.files) {
14408
- const target = import_node_path20.default.join(work, "sources", name2);
14409
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(target), { recursive: true });
14410
- import_node_fs19.default.writeFileSync(target, bytes);
15069
+ const target = import_node_path21.default.join(work, "sources", name2);
15070
+ import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(target), { recursive: true });
15071
+ import_node_fs20.default.writeFileSync(target, bytes);
14411
15072
  if (name2.endsWith(".kt")) sources.push(target);
14412
15073
  }
14413
- await run3(
14414
- import_node_path20.default.join(import_node_path20.default.dirname(kotlinc), "kotlinc"),
15074
+ await run4(
15075
+ import_node_path21.default.join(import_node_path21.default.dirname(kotlinc), "kotlinc"),
14415
15076
  [
14416
15077
  "-cp",
14417
- import_node_path20.default.resolve(import_node_path20.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
15078
+ import_node_path21.default.resolve(import_node_path21.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
14418
15079
  ...sources,
14419
15080
  "-d",
14420
15081
  classes
14421
15082
  ],
14422
15083
  { maxBuffer: 16 * 1024 * 1024 }
14423
15084
  );
14424
- const service = import_node_path20.default.join(classes, COMPILER_PLUGIN_SERVICE);
14425
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(service), { recursive: true });
14426
- import_node_fs19.default.copyFileSync(import_node_path20.default.join(work, "sources", COMPILER_PLUGIN_SERVICE), service);
15085
+ const service = import_node_path21.default.join(classes, COMPILER_PLUGIN_SERVICE);
15086
+ import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(service), { recursive: true });
15087
+ import_node_fs20.default.copyFileSync(import_node_path21.default.join(work, "sources", COMPILER_PLUGIN_SERVICE), service);
14427
15088
  try {
14428
- import_node_fs19.default.renameSync(classes, out);
15089
+ import_node_fs20.default.renameSync(classes, out);
14429
15090
  } catch (error) {
14430
- if (!import_node_fs19.default.existsSync(out)) throw error;
15091
+ if (!import_node_fs20.default.existsSync(out)) throw error;
14431
15092
  }
14432
15093
  return out;
14433
15094
  } finally {
14434
- import_node_fs19.default.rmSync(work, { recursive: true, force: true });
15095
+ import_node_fs20.default.rmSync(work, { recursive: true, force: true });
14435
15096
  }
14436
15097
  })().finally(() => compilerPlugins.delete(plugin.hash));
14437
15098
  compilerPlugins.set(plugin.hash, build);
@@ -14485,7 +15146,7 @@ function entrySource(ids) {
14485
15146
  ].join("\n");
14486
15147
  }
14487
15148
  function buildsDir() {
14488
- return import_node_path20.default.join(kotlinHome(), "builds");
15149
+ return import_node_path21.default.join(kotlinHome(), "builds");
14489
15150
  }
14490
15151
  async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14491
15152
  const { kotlinSourceId, nativeSourceContract, renderKotlinSourceGlue } = await import("vxrn/native-source-contract");
@@ -14498,7 +15159,7 @@ async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14498
15159
  const viewIds = [];
14499
15160
  let usesCompose = false;
14500
15161
  for (const file of sources) {
14501
- const source = import_node_fs19.default.readFileSync(file, "utf8");
15162
+ const source = import_node_fs20.default.readFileSync(file, "utf8");
14502
15163
  if (/\bandroidx\.compose\./.test(source)) usesCompose = true;
14503
15164
  const contract = nativeSourceContract(file, source);
14504
15165
  if (contract.modules.length === 0 && contract.views.length === 0) continue;
@@ -14511,9 +15172,9 @@ async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14511
15172
  if (viewIds.length > 0) generated["PeachViews.kt"] = viewsSource(viewIds);
14512
15173
  const shims = kotlinPlatformSources(moduleRoot, usesCompose);
14513
15174
  if (target === "jni")
14514
- shims.push(...kotlinSources(import_node_path20.default.join(moduleRoot, "JniTransportSources"), /* @__PURE__ */ new Set()));
15175
+ shims.push(...kotlinSources(import_node_path21.default.join(moduleRoot, "JniTransportSources"), /* @__PURE__ */ new Set()));
14515
15176
  if (viewIds.length > 0)
14516
- shims.push(...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")));
15177
+ shims.push(...kotlinSources(import_node_path21.default.join(moduleRoot, "ComposeSources")));
14517
15178
  return compileKotlin(
14518
15179
  { root, moduleRoot, toolchain, language, sources, generated, shims, usesCompose },
14519
15180
  origin
@@ -14583,23 +15244,23 @@ function readExpoTypes(output) {
14583
15244
  function scanExpoTypes(toolchain, script, sources) {
14584
15245
  const candidates = sources.filter(
14585
15246
  (file) => /\bRecord\b|\benum\s+class\b|\bExpoComposeView\b|\bExpoView\b|\bComposeProps\b|:\s*(?:[A-Za-z0-9_.]+\.)?(?:View|FrameLayout|LinearLayout|ViewGroup)\b/.test(
14586
- import_node_fs19.default.readFileSync(file, "utf8")
15247
+ import_node_fs20.default.readFileSync(file, "utf8")
14587
15248
  )
14588
15249
  );
14589
15250
  if (candidates.length === 0) return Promise.resolve([]);
14590
15251
  const digest2 = (0, import_node_crypto11.createHash)("sha256").update(JSON.stringify(toolchain.compiler));
14591
15252
  for (const file of [script, ...candidates])
14592
- digest2.update(`${file}\0${import_node_fs19.default.readFileSync(file, "utf8")}\0`);
15253
+ digest2.update(`${file}\0${import_node_fs20.default.readFileSync(file, "utf8")}\0`);
14593
15254
  const key2 = digest2.digest("hex");
14594
15255
  let scan = expoTypeScans.get(key2);
14595
15256
  if (!scan) {
14596
15257
  scan = (async () => {
14597
15258
  const { kotlinc } = await ensureToolchain(toolchain);
14598
- const { stdout } = await run3(
14599
- import_node_path20.default.join(import_node_path20.default.dirname(kotlinc), "kotlinc"),
15259
+ const { stdout } = await run4(
15260
+ import_node_path21.default.join(import_node_path21.default.dirname(kotlinc), "kotlinc"),
14600
15261
  [
14601
15262
  "-cp",
14602
- import_node_path20.default.resolve(import_node_path20.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
15263
+ import_node_path21.default.resolve(import_node_path21.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
14603
15264
  "-script",
14604
15265
  script,
14605
15266
  ...candidates
@@ -14676,7 +15337,7 @@ function expoTypeSources(files2) {
14676
15337
  )
14677
15338
  ];
14678
15339
  if (edits.length > 0 || views.length > 0) {
14679
- let text4 = import_node_fs19.default.readFileSync(file.file, "utf8").replaceAll("\r\n", "\n");
15340
+ let text4 = import_node_fs20.default.readFileSync(file.file, "utf8").replaceAll("\r\n", "\n");
14680
15341
  for (const { range: range2, owner, field } of edits.sort((a, b) => b.range[0] - a.range[0]))
14681
15342
  text4 = `${text4.slice(0, range2[0])}dev.peach.expo.PeachExpoTypes.initial(${owner}::class, ${literal(field.key)}, ${field.required}) { ${text4.slice(range2[0], range2[1])} }${text4.slice(range2[1])}`;
14682
15343
  if (views.length > 0) {
@@ -14692,7 +15353,7 @@ function expoTypeSources(files2) {
14692
15353
  `${file.package ? `${file.package}.` : ""}peachExpoViews${index}()`
14693
15354
  );
14694
15355
  }
14695
- const name2 = `PeachExpoSource_${index}_${import_node_path20.default.basename(file.file)}`;
15356
+ const name2 = `PeachExpoSource_${index}_${import_node_path21.default.basename(file.file)}`;
14696
15357
  generated[name2] = text4;
14697
15358
  origins[name2] = file.file;
14698
15359
  }
@@ -14715,19 +15376,19 @@ async function expoKotlinArtifact(root, moduleRoot, origin, modules) {
14715
15376
  const language = appKotlinLanguage(root);
14716
15377
  const scanned = await scanExpoTypes(
14717
15378
  toolchain,
14718
- import_node_path20.default.join(moduleRoot, "tools/expo-types.main.kts"),
15379
+ import_node_path21.default.join(moduleRoot, "tools/expo-types.main.kts"),
14719
15380
  modules.sources
14720
15381
  );
14721
15382
  const usesCompose = scanned.some((file) => file.views.length > 0) || modules.sources.some(
14722
- (file) => /\bandroidx\.compose\./.test(import_node_fs19.default.readFileSync(file, "utf8"))
15383
+ (file) => /\bandroidx\.compose\./.test(import_node_fs20.default.readFileSync(file, "utf8"))
14723
15384
  );
14724
15385
  const shims = [
14725
15386
  ...kotlinPlatformSources(moduleRoot, usesCompose),
14726
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ExpoSources"), /* @__PURE__ */ new Set()),
14727
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "AndroidViewSources"), /* @__PURE__ */ new Set()),
15387
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "ExpoSources"), /* @__PURE__ */ new Set()),
15388
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "AndroidViewSources"), /* @__PURE__ */ new Set()),
14728
15389
  ...usesCompose ? [
14729
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")),
14730
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ExpoComposeSources"), /* @__PURE__ */ new Set())
15390
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "ComposeSources")),
15391
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "ExpoComposeSources"), /* @__PURE__ */ new Set())
14731
15392
  ] : []
14732
15393
  ];
14733
15394
  const types = expoTypeSources(scanned);
@@ -14871,9 +15532,9 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
14871
15532
  };
14872
15533
  const shims = [
14873
15534
  ...kotlinPlatformSources(moduleRoot, true),
14874
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")),
14875
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "AppSources"), /* @__PURE__ */ new Set()),
14876
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "AndroidViewSources"), /* @__PURE__ */ new Set())
15535
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "ComposeSources")),
15536
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "AppSources"), /* @__PURE__ */ new Set()),
15537
+ ...kotlinSources(import_node_path21.default.join(moduleRoot, "AndroidViewSources"), /* @__PURE__ */ new Set())
14877
15538
  ];
14878
15539
  return compileKotlin(
14879
15540
  {
@@ -14888,7 +15549,7 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
14888
15549
  viewModels: {
14889
15550
  file: "PeachAppEntry.kt",
14890
15551
  render: appEntry,
14891
- script: import_node_path20.default.join(moduleRoot, "tools/abi-classes.main.kts")
15552
+ script: import_node_path21.default.join(moduleRoot, "tools/abi-classes.main.kts")
14892
15553
  }
14893
15554
  },
14894
15555
  origin
@@ -14933,7 +15594,7 @@ function appResourceSources(app) {
14933
15594
  entries: app.drawables.map((drawable) => ({
14934
15595
  name: drawable.name,
14935
15596
  init: `listOf(
14936
- ${drawable.files.map((file) => drawableInit(file, import_node_path20.default.relative(app.moduleDir, file.file))).join(",\n")}
15597
+ ${drawable.files.map((file) => drawableInit(file, import_node_path21.default.relative(app.moduleDir, file.file))).join(",\n")}
14937
15598
  )`
14938
15599
  }))
14939
15600
  },
@@ -14997,7 +15658,7 @@ function drawableInit(drawable, file) {
14997
15658
  if (drawable.kind === "xml") return `PeachDrawable.Xml(${where})`;
14998
15659
  if (drawable.kind === "bitmap")
14999
15660
  return `PeachDrawable.Bitmap(${where}, ${drawable.ninePatch}, ${literal(
15000
- import_node_fs19.default.readFileSync(drawable.file).toString("base64")
15661
+ import_node_fs20.default.readFileSync(drawable.file).toString("base64")
15001
15662
  )})`;
15002
15663
  const vector = drawable.vector;
15003
15664
  const float = (value) => `${value}f`;
@@ -15058,15 +15719,15 @@ async function compileKotlin(input, origin) {
15058
15719
  usesCompose,
15059
15720
  viewModels
15060
15721
  } = input;
15061
- const compilerRoot = import_node_path20.default.join(moduleRoot, "CompilerSources");
15722
+ const compilerRoot = import_node_path21.default.join(moduleRoot, "CompilerSources");
15062
15723
  const compilerFiles = [
15063
15724
  ...kotlinSources(compilerRoot, /* @__PURE__ */ new Set()).map(
15064
- (file) => import_node_path20.default.relative(compilerRoot, file)
15725
+ (file) => import_node_path21.default.relative(compilerRoot, file)
15065
15726
  ),
15066
15727
  COMPILER_PLUGIN_SERVICE
15067
15728
  ].map((name2) => ({
15068
15729
  name: name2,
15069
- bytes: import_node_fs19.default.readFileSync(import_node_path20.default.join(compilerRoot, name2))
15730
+ bytes: import_node_fs20.default.readFileSync(import_node_path21.default.join(compilerRoot, name2))
15070
15731
  }));
15071
15732
  const compilerDigest = (0, import_node_crypto11.createHash)("sha256").update(
15072
15733
  JSON.stringify({ format: 1, compiler: toolchain.compiler })
@@ -15076,15 +15737,15 @@ async function compileKotlin(input, origin) {
15076
15737
  const plugin = { hash: compilerDigest.digest("hex"), files: compilerFiles };
15077
15738
  const inputs = [...shims, ...sources].map((file) => ({
15078
15739
  file,
15079
- bytes: import_node_fs19.default.readFileSync(file)
15740
+ bytes: import_node_fs20.default.readFileSync(file)
15080
15741
  }));
15081
15742
  const digest2 = (0, import_node_crypto11.createHash)("sha256");
15082
15743
  digest2.update(
15083
15744
  JSON.stringify({ format: BUILD_FORMAT, toolchain, language, plugin: plugin.hash })
15084
15745
  );
15085
15746
  for (const { file, bytes } of inputs)
15086
- digest2.update(import_node_path20.default.relative(root, file)).update("\0").update(bytes).update("\0");
15087
- if (viewModels) digest2.update(import_node_fs19.default.readFileSync(viewModels.script));
15747
+ digest2.update(import_node_path21.default.relative(root, file)).update("\0").update(bytes).update("\0");
15748
+ if (viewModels) digest2.update(import_node_fs20.default.readFileSync(viewModels.script));
15088
15749
  for (const [name2, text4] of Object.entries(generated))
15089
15750
  digest2.update(`${name2}\0${text4}\0`);
15090
15751
  const hash = digest2.digest("hex").slice(0, 24);
@@ -15092,8 +15753,8 @@ async function compileKotlin(input, origin) {
15092
15753
  url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`,
15093
15754
  hash
15094
15755
  };
15095
- const out = import_node_path20.default.join(buildsDir(), hash);
15096
- if (import_node_fs19.default.existsSync(import_node_path20.default.join(out, "js", "app.wasm"))) return artifact;
15756
+ const out = import_node_path21.default.join(buildsDir(), hash);
15757
+ if (import_node_fs20.default.existsSync(import_node_path21.default.join(out, "js", "app.wasm"))) return artifact;
15097
15758
  const pending = builds.get(hash);
15098
15759
  if (pending) return pending;
15099
15760
  const build = (async () => {
@@ -15101,29 +15762,29 @@ async function compileKotlin(input, origin) {
15101
15762
  const { kotlinc } = ready;
15102
15763
  const compilerPlugin = await ensureCompilerPlugin(kotlinc, plugin);
15103
15764
  const libraries = [...ready.libraries];
15104
- const composeRuntime = import_node_path20.default.join(
15765
+ const composeRuntime = import_node_path21.default.join(
15105
15766
  kotlinHome(),
15106
15767
  toolchain.compiler.version,
15107
15768
  toolchain.composeRuntime.name
15108
15769
  );
15109
15770
  if (usesCompose) {
15110
15771
  for (const library of toolchain.composeLibraries) {
15111
- const target = import_node_path20.default.join(kotlinHome(), toolchain.compiler.version, library.name);
15772
+ const target = import_node_path21.default.join(kotlinHome(), toolchain.compiler.version, library.name);
15112
15773
  await fetchVerified(library, target);
15113
15774
  libraries.push(target);
15114
15775
  }
15115
15776
  await fetchVerified(toolchain.composeRuntime, composeRuntime);
15116
15777
  }
15117
- import_node_fs19.default.mkdirSync(buildsDir(), { recursive: true });
15118
- const work = import_node_fs19.default.mkdtempSync(import_node_path20.default.join(buildsDir(), `${hash}-`));
15119
- const generatedDir = import_node_path20.default.join(work, "generated");
15120
- import_node_fs19.default.mkdirSync(generatedDir);
15778
+ import_node_fs20.default.mkdirSync(buildsDir(), { recursive: true });
15779
+ const work = import_node_fs20.default.mkdtempSync(import_node_path21.default.join(buildsDir(), `${hash}-`));
15780
+ const generatedDir = import_node_path21.default.join(work, "generated");
15781
+ import_node_fs20.default.mkdirSync(generatedDir);
15121
15782
  for (const [name2, text4] of Object.entries(generated))
15122
- import_node_fs19.default.writeFileSync(import_node_path20.default.join(generatedDir, name2), text4);
15783
+ import_node_fs20.default.writeFileSync(import_node_path21.default.join(generatedDir, name2), text4);
15123
15784
  const compiledSources = inputs.map(({ file, bytes }, index) => {
15124
- const target = import_node_path20.default.join(work, "sources", String(index), import_node_path20.default.basename(file));
15125
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(target), { recursive: true });
15126
- import_node_fs19.default.writeFileSync(target, bytes);
15785
+ const target = import_node_path21.default.join(work, "sources", String(index), import_node_path21.default.basename(file));
15786
+ import_node_fs20.default.mkdirSync(import_node_path21.default.dirname(target), { recursive: true });
15787
+ import_node_fs20.default.writeFileSync(target, bytes);
15127
15788
  return { file, target };
15128
15789
  });
15129
15790
  const common = [
@@ -15132,15 +15793,15 @@ async function compileKotlin(input, origin) {
15132
15793
  "-Xallow-kotlin-package",
15133
15794
  "-Xwasm-target=js",
15134
15795
  "-libraries",
15135
- libraries.join(import_node_path20.default.delimiter)
15796
+ libraries.join(import_node_path21.default.delimiter)
15136
15797
  ];
15137
- const compileKlib = (outputDir) => run3(
15798
+ const compileKlib = (outputDir) => run4(
15138
15799
  kotlinc,
15139
15800
  [
15140
15801
  ...common,
15141
15802
  `-Xplugin=${compilerPlugin}`,
15142
15803
  ...usesCompose ? [
15143
- `-Xplugin=${import_node_path20.default.resolve(import_node_path20.default.dirname(kotlinc), "../lib/compose-compiler-plugin.jar")}`
15804
+ `-Xplugin=${import_node_path21.default.resolve(import_node_path21.default.dirname(kotlinc), "../lib/compose-compiler-plugin.jar")}`
15144
15805
  ] : [],
15145
15806
  "-language-version",
15146
15807
  language,
@@ -15153,7 +15814,7 @@ async function compileKotlin(input, origin) {
15153
15814
  "-ir-output-name",
15154
15815
  "app",
15155
15816
  ...compiledSources.map(({ target }) => target),
15156
- ...Object.keys(generated).map((name2) => import_node_path20.default.join(generatedDir, name2))
15817
+ ...Object.keys(generated).map((name2) => import_node_path21.default.join(generatedDir, name2))
15157
15818
  ],
15158
15819
  { maxBuffer: 16 * 1024 * 1024 }
15159
15820
  );
@@ -15161,49 +15822,49 @@ async function compileKotlin(input, origin) {
15161
15822
  if (viewModels && inputs.some(
15162
15823
  ({ file, bytes }) => sources.includes(file) && bytes.includes("ViewModel")
15163
15824
  )) {
15164
- await compileKlib(import_node_path20.default.join(work, "abi"));
15165
- const { stdout } = await run3(
15166
- import_node_path20.default.join(import_node_path20.default.dirname(kotlinc), "kotlinc"),
15825
+ await compileKlib(import_node_path21.default.join(work, "abi"));
15826
+ const { stdout } = await run4(
15827
+ import_node_path21.default.join(import_node_path21.default.dirname(kotlinc), "kotlinc"),
15167
15828
  [
15168
15829
  "-cp",
15169
- import_node_path20.default.resolve(import_node_path20.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
15830
+ import_node_path21.default.resolve(import_node_path21.default.dirname(kotlinc), "../lib/kotlin-compiler.jar"),
15170
15831
  "-script",
15171
15832
  viewModels.script,
15172
- import_node_path20.default.join(work, "abi")
15833
+ import_node_path21.default.join(work, "abi")
15173
15834
  ],
15174
15835
  { maxBuffer: 64 * 1024 * 1024 }
15175
15836
  );
15176
- import_node_fs19.default.writeFileSync(
15177
- import_node_path20.default.join(generatedDir, viewModels.file),
15837
+ import_node_fs20.default.writeFileSync(
15838
+ import_node_path21.default.join(generatedDir, viewModels.file),
15178
15839
  viewModels.render(viewModelClasses(readAbiClasses(stdout)))
15179
15840
  );
15180
15841
  }
15181
- await compileKlib(import_node_path20.default.join(work, "klib"));
15182
- await run3(
15842
+ await compileKlib(import_node_path21.default.join(work, "klib"));
15843
+ await run4(
15183
15844
  kotlinc,
15184
15845
  [
15185
15846
  ...common,
15186
15847
  "-nowarn",
15187
- `-Xinclude=${import_node_path20.default.join(work, "klib")}`,
15848
+ `-Xinclude=${import_node_path21.default.join(work, "klib")}`,
15188
15849
  "-Xir-produce-js",
15189
15850
  "-ir-output-dir",
15190
- import_node_path20.default.join(work, "js"),
15851
+ import_node_path21.default.join(work, "js"),
15191
15852
  "-ir-output-name",
15192
15853
  "app"
15193
15854
  ],
15194
15855
  { maxBuffer: 16 * 1024 * 1024 }
15195
15856
  );
15196
15857
  if (usesCompose) {
15197
- await run3("unzip", [
15858
+ await run4("unzip", [
15198
15859
  "-q",
15199
15860
  "-j",
15200
15861
  composeRuntime,
15201
15862
  "skiko.mjs",
15202
15863
  "-d",
15203
- import_node_path20.default.join(work, "js")
15864
+ import_node_path21.default.join(work, "js")
15204
15865
  ]);
15205
- const skikoPath = import_node_path20.default.join(work, "js", "skiko.mjs");
15206
- const upstream = (0, import_acorn2.parse)(import_node_fs19.default.readFileSync(skikoPath, "utf8"), {
15866
+ const skikoPath = import_node_path21.default.join(work, "js", "skiko.mjs");
15867
+ const upstream = (0, import_acorn2.parse)(import_node_fs20.default.readFileSync(skikoPath, "utf8"), {
15207
15868
  ecmaVersion: "latest",
15208
15869
  sourceType: "module"
15209
15870
  });
@@ -15226,7 +15887,7 @@ async function compileKotlin(input, origin) {
15226
15887
  "GL",
15227
15888
  ...bindings
15228
15889
  ];
15229
- import_node_fs19.default.writeFileSync(
15890
+ import_node_fs20.default.writeFileSync(
15230
15891
  skikoPath,
15231
15892
  [
15232
15893
  "const runtime = globalThis.__peachKotlinSkiko;",
@@ -15240,10 +15901,10 @@ async function compileKotlin(input, origin) {
15240
15901
  if (usesCompose) {
15241
15902
  for (const library of toolchain.composeJsLibraries) {
15242
15903
  let imported = false;
15243
- for (const file of import_node_fs19.default.readdirSync(import_node_path20.default.join(work, "js"))) {
15904
+ for (const file of import_node_fs20.default.readdirSync(import_node_path21.default.join(work, "js"))) {
15244
15905
  if (!file.endsWith(".mjs")) continue;
15245
- const target = import_node_path20.default.join(work, "js", file);
15246
- const source = import_node_fs19.default.readFileSync(target, "utf8");
15906
+ const target = import_node_path21.default.join(work, "js", file);
15907
+ const source = import_node_fs20.default.readFileSync(target, "utf8");
15247
15908
  let next = source;
15248
15909
  for (const quote of ["'", '"'])
15249
15910
  next = next.replaceAll(
@@ -15251,29 +15912,29 @@ async function compileKotlin(input, origin) {
15251
15912
  `from ${quote}./${library.file}${quote}`
15252
15913
  );
15253
15914
  if (next === source) continue;
15254
- import_node_fs19.default.writeFileSync(target, next);
15915
+ import_node_fs20.default.writeFileSync(target, next);
15255
15916
  imported = true;
15256
15917
  }
15257
15918
  if (!imported) continue;
15258
- const archive = import_node_path20.default.join(
15919
+ const archive = import_node_path21.default.join(
15259
15920
  kotlinHome(),
15260
15921
  toolchain.compiler.version,
15261
15922
  library.name
15262
15923
  );
15263
15924
  await fetchVerified(library, archive);
15264
- const { stdout } = await run3("tar", ["-xOf", archive, library.archiveEntry], {
15925
+ const { stdout } = await run4("tar", ["-xOf", archive, library.archiveEntry], {
15265
15926
  maxBuffer: 16 * 1024 * 1024
15266
15927
  });
15267
- import_node_fs19.default.writeFileSync(import_node_path20.default.join(work, "js", library.file), stdout);
15928
+ import_node_fs20.default.writeFileSync(import_node_path21.default.join(work, "js", library.file), stdout);
15268
15929
  }
15269
15930
  }
15270
15931
  } catch (error) {
15271
- import_node_fs19.default.rmSync(work, { recursive: true, force: true });
15932
+ import_node_fs20.default.rmSync(work, { recursive: true, force: true });
15272
15933
  let output = isRecord(error) ? `${String(error.stderr ?? "")}${String(error.stdout ?? "")}` : "";
15273
15934
  for (const [name2, source] of Object.entries(origins))
15274
- output = output.replaceAll(import_node_path20.default.join(generatedDir, name2), source);
15935
+ output = output.replaceAll(import_node_path21.default.join(generatedDir, name2), source);
15275
15936
  for (const { file, target } of compiledSources)
15276
- output = output.replaceAll(target, file).replaceAll(import_node_path20.default.relative(process.cwd(), target), file);
15937
+ output = output.replaceAll(target, file).replaceAll(import_node_path21.default.relative(process.cwd(), target), file);
15277
15938
  throw new Error(
15278
15939
  `kotlin compile failed:
15279
15940
  ${output.trim() || (error instanceof Error ? error.message : String(error))}`
@@ -15282,9 +15943,9 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15282
15943
  const seams = [
15283
15944
  ["process.release.name", "process.release?.name"]
15284
15945
  ];
15285
- const js = import_node_fs19.default.readdirSync(import_node_path20.default.join(work, "js")).filter((file) => file.endsWith(".mjs"));
15946
+ const js = import_node_fs20.default.readdirSync(import_node_path21.default.join(work, "js")).filter((file) => file.endsWith(".mjs"));
15286
15947
  if (js.some(
15287
- (file) => import_node_fs19.default.readFileSync(import_node_path20.default.join(work, "js", file), "utf8").includes("'kotlinx.coroutines.")
15948
+ (file) => import_node_fs20.default.readFileSync(import_node_path21.default.join(work, "js", file), "utf8").includes("'kotlinx.coroutines.")
15288
15949
  ))
15289
15950
  seams.push([
15290
15951
  "(typeof(window) !== 'undefined' && window != null && typeof(window.addEventListener) === 'function') ? window : null",
@@ -15293,12 +15954,12 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15293
15954
  for (const [from, to] of seams) {
15294
15955
  let patched = 0;
15295
15956
  for (const file of js) {
15296
- const target = import_node_path20.default.join(work, "js", file);
15297
- const text4 = import_node_fs19.default.readFileSync(target, "utf8");
15957
+ const target = import_node_path21.default.join(work, "js", file);
15958
+ const text4 = import_node_fs20.default.readFileSync(target, "utf8");
15298
15959
  const next = text4.replaceAll(from, to);
15299
15960
  if (next !== text4) {
15300
15961
  patched++;
15301
- import_node_fs19.default.writeFileSync(target, next);
15962
+ import_node_fs20.default.writeFileSync(target, next);
15302
15963
  }
15303
15964
  }
15304
15965
  if (patched === 0)
@@ -15307,10 +15968,10 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15307
15968
  );
15308
15969
  }
15309
15970
  try {
15310
- import_node_fs19.default.renameSync(work, out);
15971
+ import_node_fs20.default.renameSync(work, out);
15311
15972
  } catch (error) {
15312
- if (!import_node_fs19.default.existsSync(import_node_path20.default.join(out, "js", "app.wasm"))) throw error;
15313
- import_node_fs19.default.rmSync(work, { recursive: true, force: true });
15973
+ if (!import_node_fs20.default.existsSync(import_node_path21.default.join(out, "js", "app.wasm"))) throw error;
15974
+ import_node_fs20.default.rmSync(work, { recursive: true, force: true });
15314
15975
  }
15315
15976
  return artifact;
15316
15977
  })().finally(() => builds.delete(hash));
@@ -15318,24 +15979,24 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15318
15979
  return build;
15319
15980
  }
15320
15981
  function kotlinArtifactFiles(hash) {
15321
- const dir = import_node_path20.default.join(buildsDir(), hash, "js");
15322
- return import_node_fs19.default.readdirSync(dir).sort().map((name2) => {
15323
- const contentType = CONTENT_TYPES[import_node_path20.default.extname(name2)];
15982
+ const dir = import_node_path21.default.join(buildsDir(), hash, "js");
15983
+ return import_node_fs20.default.readdirSync(dir).sort().map((name2) => {
15984
+ const contentType = CONTENT_TYPES[import_node_path21.default.extname(name2)];
15324
15985
  if (!contentType) throw new Error(`unexpected kotlin artifact file ${name2}`);
15325
- return { name: name2, bytes: import_node_fs19.default.readFileSync(import_node_path20.default.join(dir, name2)), contentType };
15986
+ return { name: name2, bytes: import_node_fs20.default.readFileSync(import_node_path21.default.join(dir, name2)), contentType };
15326
15987
  });
15327
15988
  }
15328
15989
  function serveKotlinArtifact(pathname, res) {
15329
15990
  if (!pathname.startsWith(KOTLIN_ARTIFACT_PREFIX)) return false;
15330
15991
  const [hash, file, ...rest] = pathname.slice(KOTLIN_ARTIFACT_PREFIX.length).split("/");
15331
- const type = file ? CONTENT_TYPES[import_node_path20.default.extname(file)] : void 0;
15992
+ const type = file ? CONTENT_TYPES[import_node_path21.default.extname(file)] : void 0;
15332
15993
  if (!hash || !/^[0-9a-f]+$/.test(hash) || !file || rest.length > 0 || !type || file.includes("..")) {
15333
15994
  res.statusCode = 404;
15334
15995
  res.end("not a kotlin artifact");
15335
15996
  return true;
15336
15997
  }
15337
- const target = import_node_path20.default.join(buildsDir(), hash, "js", file);
15338
- if (!import_node_fs19.default.existsSync(target)) {
15998
+ const target = import_node_path21.default.join(buildsDir(), hash, "js", file);
15999
+ if (!import_node_fs20.default.existsSync(target)) {
15339
16000
  res.statusCode = 404;
15340
16001
  res.end(`kotlin artifact ${hash}/${file} was not built`);
15341
16002
  return true;
@@ -15343,7 +16004,7 @@ function serveKotlinArtifact(pathname, res) {
15343
16004
  res.setHeader("access-control-allow-origin", "*");
15344
16005
  res.setHeader("content-type", type);
15345
16006
  res.setHeader("cache-control", "public, max-age=31536000, immutable");
15346
- res.end(import_node_fs19.default.readFileSync(target));
16007
+ res.end(import_node_fs20.default.readFileSync(target));
15347
16008
  return true;
15348
16009
  }
15349
16010
  async function serveKotlinRequest(pathname, res, app) {
@@ -15360,22 +16021,22 @@ async function serveKotlinRequest(pathname, res, app) {
15360
16021
  }
15361
16022
  return true;
15362
16023
  }
15363
- var import_node_child_process11, import_node_crypto11, import_node_fs19, import_node_module2, import_node_path20, import_node_util3, import_acorn2, run3, KOTLIN_ARTIFACT_PREFIX, toolchains, SKIP_DIRS, compilerPlugins, COMPILER_PLUGIN_SERVICE, BUILD_FORMAT, builds, expoTypeScans, argb, escapes, literal, CONTENT_TYPES, KOTLIN_PACKAGE_PATH;
16024
+ var import_node_child_process13, import_node_crypto11, import_node_fs20, import_node_module3, import_node_path21, import_node_util4, import_acorn2, run4, KOTLIN_ARTIFACT_PREFIX, toolchains, SKIP_DIRS, compilerPlugins, COMPILER_PLUGIN_SERVICE, BUILD_FORMAT, builds, expoTypeScans, argb, escapes, literal, CONTENT_TYPES, KOTLIN_PACKAGE_PATH;
15364
16025
  var init_kotlin_host = __esm({
15365
16026
  "src/kotlin-host.ts"() {
15366
16027
  "use strict";
15367
- import_node_child_process11 = require("node:child_process");
16028
+ import_node_child_process13 = require("node:child_process");
15368
16029
  import_node_crypto11 = require("node:crypto");
15369
- import_node_fs19 = __toESM(require("node:fs"), 1);
15370
- import_node_module2 = require("node:module");
15371
- import_node_path20 = __toESM(require("node:path"), 1);
15372
- import_node_util3 = require("node:util");
16030
+ import_node_fs20 = __toESM(require("node:fs"), 1);
16031
+ import_node_module3 = require("node:module");
16032
+ import_node_path21 = __toESM(require("node:path"), 1);
16033
+ import_node_util4 = require("node:util");
15373
16034
  import_acorn2 = require("acorn");
15374
16035
  init_home_paths();
15375
16036
  init_is_record();
15376
16037
  init_kotlin_view_models();
15377
16038
  init_kotlin_module();
15378
- run3 = (0, import_node_util3.promisify)(import_node_child_process11.execFile);
16039
+ run4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
15379
16040
  KOTLIN_ARTIFACT_PREFIX = "/__peach/kotlin-artifact/";
15380
16041
  toolchains = /* @__PURE__ */ new Map();
15381
16042
  SKIP_DIRS = /* @__PURE__ */ new Set([
@@ -15417,41 +16078,17 @@ var init_kotlin_host = __esm({
15417
16078
 
15418
16079
  // src/expo-kotlin-host.ts
15419
16080
  async function collectExpoKotlinModules(appRoot) {
15420
- appRoot = import_node_fs20.default.realpathSync(appRoot);
15421
- let autolinker;
15422
- try {
15423
- autolinker = (0, import_node_module3.createRequire)(import_node_path21.default.join(appRoot, "package.json")).resolve(
15424
- "expo-modules-autolinking/package.json"
15425
- );
15426
- } catch (error) {
15427
- if (isRecord(error) && error.code === "MODULE_NOT_FOUND") return null;
15428
- throw error;
15429
- }
15430
- const { stdout } = await run4(
15431
- process.execPath,
15432
- [
15433
- import_node_path21.default.join(import_node_path21.default.dirname(autolinker), "bin/expo-modules-autolinking.js"),
15434
- "resolve",
15435
- "--platform",
15436
- "android",
15437
- "--project-root",
15438
- appRoot,
15439
- "--json"
15440
- ],
15441
- { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv2 }
15442
- );
15443
- const resolved = JSON.parse(stdout);
15444
- if (!isRecord(resolved) || !Array.isArray(resolved.modules))
15445
- throw new Error("invalid Expo Android resolution");
16081
+ const modules = await resolveExpoAndroidAutolinking(appRoot);
15446
16082
  const result = { modules: [], sources: [] };
15447
- for (const entry of resolved.modules) {
15448
- if (!isRecord(entry) || !Array.isArray(entry.projects))
16083
+ for (const entry of modules) {
16084
+ if (entry.projects === void 0) continue;
16085
+ if (!Array.isArray(entry.projects))
15449
16086
  throw new Error("invalid Expo Android module entry");
15450
16087
  for (const project of entry.projects) {
15451
16088
  if (!isRecord(project) || typeof project.sourceDir !== "string" || !Array.isArray(project.modules))
15452
16089
  throw new Error("invalid Expo Android project");
15453
- const sourceDir = import_node_fs20.default.realpathSync(project.sourceDir);
15454
- if (sourceDir.split(import_node_path21.default.sep).includes("node_modules")) continue;
16090
+ const sourceDir = import_node_fs21.default.realpathSync(project.sourceDir);
16091
+ if (sourceDir.split(import_node_path22.default.sep).includes("node_modules")) continue;
15455
16092
  if (project.modules.length === 0) continue;
15456
16093
  for (const module2 of project.modules) {
15457
16094
  if (!isRecord(module2) || typeof module2.classifier !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)+$/.test(
@@ -15461,9 +16098,9 @@ async function collectExpoKotlinModules(appRoot) {
15461
16098
  result.modules.push({ classifier: module2.classifier, name: module2.name });
15462
16099
  }
15463
16100
  const walk2 = (dir) => {
15464
- if (!import_node_fs20.default.existsSync(dir)) return;
15465
- for (const child of import_node_fs20.default.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
15466
- const file = import_node_path21.default.join(dir, child.name);
16101
+ if (!import_node_fs21.default.existsSync(dir)) return;
16102
+ for (const child of import_node_fs21.default.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
16103
+ const file = import_node_path22.default.join(dir, child.name);
15467
16104
  if (child.isSymbolicLink())
15468
16105
  throw new Error(`Expo Kotlin source is a symlink: ${file}`);
15469
16106
  if (child.isDirectory()) walk2(file);
@@ -15472,8 +16109,8 @@ async function collectExpoKotlinModules(appRoot) {
15472
16109
  else if (child.name.endsWith(".kt")) result.sources.push(file);
15473
16110
  }
15474
16111
  };
15475
- walk2(import_node_path21.default.join(sourceDir, "src", "main", "java"));
15476
- walk2(import_node_path21.default.join(sourceDir, "src", "main", "kotlin"));
16112
+ walk2(import_node_path22.default.join(sourceDir, "src", "main", "java"));
16113
+ walk2(import_node_path22.default.join(sourceDir, "src", "main", "kotlin"));
15477
16114
  }
15478
16115
  }
15479
16116
  return result.modules.length === 0 ? null : result;
@@ -15507,21 +16144,16 @@ async function compileExpoKotlinModules(root, origin) {
15507
16144
  };
15508
16145
  }
15509
16146
  }
15510
- var import_node_child_process12, import_node_fs20, import_node_module3, import_node_path21, import_node_util4, run4, scriptEnv2;
16147
+ var import_node_fs21, import_node_path22;
15511
16148
  var init_expo_kotlin_host = __esm({
15512
16149
  "src/expo-kotlin-host.ts"() {
15513
16150
  "use strict";
15514
- import_node_child_process12 = require("node:child_process");
15515
- import_node_fs20 = __toESM(require("node:fs"), 1);
15516
- import_node_module3 = require("node:module");
15517
- import_node_path21 = __toESM(require("node:path"), 1);
15518
- import_node_util4 = require("node:util");
15519
- init_internal_child();
16151
+ import_node_fs21 = __toESM(require("node:fs"), 1);
16152
+ import_node_path22 = __toESM(require("node:path"), 1);
16153
+ init_android_autolinking();
15520
16154
  init_backend_origin();
15521
16155
  init_is_record();
15522
16156
  init_kotlin_module();
15523
- run4 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
15524
- scriptEnv2 = { ...process.env, [RNX_FORKED_SCRIPT_ENV]: "1" };
15525
16157
  }
15526
16158
  });
15527
16159
 
@@ -15567,56 +16199,8 @@ var import_node_vm = require("node:vm");
15567
16199
  init_process_group();
15568
16200
  init_backend_origin();
15569
16201
 
15570
- // src/bundleGlobalFooter.ts
15571
- function findBundleFooter(source, prefix) {
15572
- let end = source.length;
15573
- while (end > 0) {
15574
- const newline = source.lastIndexOf("\n", end - 1);
15575
- if (newline < 0) return -1;
15576
- const line = newline + 1;
15577
- if (source.startsWith(prefix, line)) return newline;
15578
- if (line !== end && !source.startsWith("globalThis.", line) && !source.startsWith("//", line)) {
15579
- return -1;
15580
- }
15581
- end = newline;
15582
- }
15583
- return -1;
15584
- }
15585
- function readFooter(source, prefix, suffix, name2) {
15586
- const start = findBundleFooter(source, prefix);
15587
- if (start < 0) return null;
15588
- const end = source.indexOf("\n", start + 1);
15589
- const line = source.slice(start + 1, end < 0 ? void 0 : end);
15590
- if (!line.endsWith(suffix)) throw new Error(`${name2} footer is truncated`);
15591
- const value = JSON.parse(
15592
- line.slice(prefix.length, suffix ? -suffix.length : void 0)
15593
- );
15594
- if (value === null) throw new Error(`${name2} footer has no metadata`);
15595
- return value;
15596
- }
15597
- function detachFooter(source, prefix, suffix, name2) {
15598
- const start = findBundleFooter(source, prefix);
15599
- if (start < 0) return { source, value: null };
15600
- const value = readFooter(source, prefix, suffix, name2);
15601
- const end = source.indexOf("\n", start + 1);
15602
- return { source: source.slice(0, start) + (end < 0 ? "" : source.slice(end)), value };
15603
- }
15604
- function insertBundleGlobalFooter(source, name2, value) {
15605
- return insertFooter(source, `globalThis.${name2}=`, ";", name2, value);
15606
- }
15607
- function insertBundleMetadataFooter(source, name2, value) {
15608
- return insertFooter(source, `// peach.${name2}=`, "", name2, value);
15609
- }
15610
- function insertFooter(source, prefix, suffix, name2, value) {
15611
- source = detachFooter(source, prefix, suffix, name2).source;
15612
- const json = JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
15613
- const footer = `
15614
- ${prefix}${json}${suffix}`;
15615
- const identity = findBundleFooter(source, "globalThis.__sootsimModulePaths=");
15616
- return identity < 0 ? source + footer : source.slice(0, identity) + footer + source.slice(identity);
15617
- }
15618
-
15619
16202
  // src/expoKotlinContract.ts
16203
+ init_bundleGlobalFooter();
15620
16204
  function record(value) {
15621
16205
  return value !== null && typeof value === "object" && !Array.isArray(value);
15622
16206
  }
@@ -15654,6 +16238,7 @@ function insertExpoKotlinFooter(source, metadata) {
15654
16238
  }
15655
16239
 
15656
16240
  // src/expoSwiftContract.ts
16241
+ init_bundleGlobalFooter();
15657
16242
  function record2(value) {
15658
16243
  return value !== null && typeof value === "object" && !Array.isArray(value);
15659
16244
  }
@@ -15687,6 +16272,7 @@ function insertExpoSwiftFooter(source, metadata) {
15687
16272
  }
15688
16273
 
15689
16274
  // src/nitroContract.ts
16275
+ init_bundleGlobalFooter();
15690
16276
  function readNitroMetadata(value) {
15691
16277
  if (value === null || value === void 0) return null;
15692
16278
  if (typeof value !== "object" || Array.isArray(value) || Reflect.get(value, "platform") !== "ios")
@@ -15806,17 +16392,17 @@ function prepareChannel({
15806
16392
  }
15807
16393
  }
15808
16394
  const identity = (0, import_node_crypto12.createHash)("sha256").update(bundle).update(icon);
15809
- for (const [path20, bytes] of [...files2].sort(
16395
+ for (const [path21, bytes] of [...files2].sort(
15810
16396
  ([a], [b]) => a < b ? -1 : a > b ? 1 : 0
15811
16397
  )) {
15812
- identity.update(JSON.stringify([path20, digest(bytes)]));
16398
+ identity.update(JSON.stringify([path21, digest(bytes)]));
15813
16399
  }
15814
16400
  if (native) identity.update(JSON.stringify(native.metadata));
15815
16401
  if (nitro) identity.update(JSON.stringify(nitro.metadata));
15816
16402
  const releaseKey = `${prefix}/peach/releases/${identity.digest("hex")}`;
15817
16403
  const assetBaseUrl = `${origin.origin}/${releaseKey}/`;
15818
16404
  const directories = new Set(
15819
- [...files2.keys()].map((path20) => path20.slice(0, path20.lastIndexOf("/")))
16405
+ [...files2.keys()].map((path21) => path21.slice(0, path21.lastIndexOf("/")))
15820
16406
  );
15821
16407
  let locations = 0;
15822
16408
  let source = new TextDecoder("utf-8", { fatal: true }).decode(bundle).replace(
@@ -15824,12 +16410,12 @@ function prepareChannel({
15824
16410
  /("?httpServerLocation"?\s*:\s*)(?:"((?:[^"\\]|\\.)*)"|`([^`\\$]*)`)/g,
15825
16411
  (match, property, quoted, template) => {
15826
16412
  const location = quoted === void 0 ? template : JSON.parse(`"${quoted}"`);
15827
- const path20 = packagedAssetDirectory(location);
15828
- if (!directories.has(path20)) {
16413
+ const path21 = packagedAssetDirectory(location);
16414
+ if (!directories.has(path21)) {
15829
16415
  throw new Error(`bundle asset location has no packaged files: ${location}`);
15830
16416
  }
15831
16417
  locations++;
15832
- return `${property}${JSON.stringify(new URL(path20, assetBaseUrl).href)}`;
16418
+ return `${property}${JSON.stringify(new URL(path21, assetBaseUrl).href)}`;
15833
16419
  }
15834
16420
  );
15835
16421
  if (assets2.length && !locations)
@@ -15892,10 +16478,10 @@ function prepareChannel({
15892
16478
  contentType: "application/javascript"
15893
16479
  },
15894
16480
  { key: `${releaseKey}/icon.png`, bytes: icon, contentType: "image/png" },
15895
- ...[...files2].map(([path20, bytes]) => ({
15896
- key: `${releaseKey}/${path20}`,
16481
+ ...[...files2].map(([path21, bytes]) => ({
16482
+ key: `${releaseKey}/${path21}`,
15897
16483
  bytes,
15898
- contentType: nativeAssets.get(path20)?.contentType ?? {
16484
+ contentType: nativeAssets.get(path21)?.contentType ?? {
15899
16485
  png: "image/png",
15900
16486
  jpg: "image/jpeg",
15901
16487
  jpeg: "image/jpeg",
@@ -15904,7 +16490,7 @@ function prepareChannel({
15904
16490
  ttf: "font/ttf",
15905
16491
  otf: "font/otf",
15906
16492
  wav: "audio/wav"
15907
- }[path20.split(".").pop()] ?? "application/octet-stream"
16493
+ }[path21.split(".").pop()] ?? "application/octet-stream"
15908
16494
  }))
15909
16495
  ];
15910
16496
  return { platform, key: `${prefix}/${channelKey(platform)}`, metadata, objects };
@@ -15944,7 +16530,7 @@ async function publishBundleChannel(release, { put, fetchObject = fetch }) {
15944
16530
  }
15945
16531
  async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios", "android"], assertRunning = () => {
15946
16532
  } } = {}) {
15947
- const { readFileSync: readFileSync5 } = await import("node:fs");
16533
+ const { readFileSync: readFileSync6 } = await import("node:fs");
15948
16534
  const { basename: basename2 } = await import("node:path");
15949
16535
  const snapshots = [];
15950
16536
  for (const platform of platforms) {
@@ -15965,27 +16551,27 @@ async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios
15965
16551
  const directory = packagedAssetDirectory(asset.httpServerLocation);
15966
16552
  if (asset.files) {
15967
16553
  for (const file of asset.files) {
15968
- const path20 = `${directory}/${basename2(file)}`;
15969
- if (!assets2.has(path20)) assets2.set(path20, readFileSync5(file));
16554
+ const path21 = `${directory}/${basename2(file)}`;
16555
+ if (!assets2.has(path21)) assets2.set(path21, readFileSync6(file));
15970
16556
  }
15971
16557
  continue;
15972
16558
  }
15973
16559
  for (const scale of asset.scales) {
15974
16560
  const file = `${asset.name}${scale === 1 ? "" : `@${scale}x`}.${asset.type}`;
15975
- const path20 = `${directory}/${file}`;
15976
- if (assets2.has(path20)) continue;
16561
+ const path21 = `${directory}/${file}`;
16562
+ if (assets2.has(path21)) continue;
15977
16563
  const response = await fetch(
15978
16564
  `${origin}${asset.httpServerLocation}/${file}?platform=${platform}&hash=${asset.hash}`
15979
16565
  );
15980
16566
  if (!response.ok)
15981
- throw new Error(`dev server asset ${path20} failed: ${response.status}`);
15982
- assets2.set(path20, Buffer.from(await response.arrayBuffer()));
16567
+ throw new Error(`dev server asset ${path21} failed: ${response.status}`);
16568
+ assets2.set(path21, Buffer.from(await response.arrayBuffer()));
15983
16569
  }
15984
16570
  }
15985
16571
  snapshots.push({
15986
16572
  platform,
15987
16573
  bundle,
15988
- assets: [...assets2].map(([path20, bytes]) => ({ path: path20, bytes })),
16574
+ assets: [...assets2].map(([path21, bytes]) => ({ path: path21, bytes })),
15989
16575
  ...platform === "ios" ? {
15990
16576
  expoSwift: await (await Promise.resolve().then(() => (init_expo_swift_bundle(), expo_swift_bundle_exports))).buildExpoSwiftBundle(projectRoot)
15991
16577
  } : {
@@ -15997,7 +16583,7 @@ async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios
15997
16583
  }
15998
16584
  async function snapshotOneDevBundle(projectRoot, env = {}) {
15999
16585
  const { spawn: spawn4 } = await import("node:child_process");
16000
- const { readFileSync: readFileSync5 } = await import("node:fs");
16586
+ const { readFileSync: readFileSync6 } = await import("node:fs");
16001
16587
  const { createServer } = await import("node:net");
16002
16588
  const { dirname: dirname2, join: join3 } = await import("node:path");
16003
16589
  const { createRequire: createRequire4 } = await import("node:module");
@@ -16006,7 +16592,7 @@ async function snapshotOneDevBundle(projectRoot, env = {}) {
16006
16592
  );
16007
16593
  const oneBin = join3(
16008
16594
  dirname2(onePackage),
16009
- JSON.parse(readFileSync5(onePackage, "utf8")).bin.one
16595
+ JSON.parse(readFileSync6(onePackage, "utf8")).bin.one
16010
16596
  );
16011
16597
  const port = await new Promise((resolve2, reject) => {
16012
16598
  const server = createServer().listen(0, "127.0.0.1", () => {