peachsim 0.1.1619 → 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 (140) hide show
  1. package/README.md +35 -5
  2. package/cli/app-fonts.ts +2 -1
  3. package/cli/bridge-flow-runner.ts +222 -175
  4. package/cli/cloud-client.ts +81 -48
  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 +74 -17
  11. package/cli/commands/record.ts +20 -15
  12. package/cli/commands/upload.ts +5 -1
  13. package/cli/dev-build-freshness.ts +37 -2
  14. package/cli/drivers/playwright-sim-host.ts +18 -6
  15. package/cli/maestro-accessibility.ts +53 -0
  16. package/cli/maestro-compare.ts +24 -0
  17. package/cli/outbound-endpoints.ts +27 -8
  18. package/cli/parent-pid.ts +0 -9
  19. package/cli/remote-simulators.ts +112 -0
  20. package/cli/remoteSimulatorContract.ts +21 -0
  21. package/detox/expectations.ts +5 -1
  22. package/detox/index.ts +133 -98
  23. package/detox/motion-change.cjs +37 -0
  24. package/detox/motion-change.d.cts +16 -0
  25. package/detox/navigation-lifecycle.ts +22 -4
  26. package/dist-lib/agent-daemon-client.cjs +3 -2
  27. package/dist-lib/agent-events.cjs +1 -1
  28. package/dist-lib/attached-projects.cjs +1 -1
  29. package/dist-lib/auth/shared-session.cjs +3 -2
  30. package/dist-lib/backend-origin.cjs +1 -1
  31. package/dist-lib/beta.cjs +1 -1
  32. package/dist-lib/beta.mjs +1 -1
  33. package/dist-lib/bridge-constants.cjs +1 -1
  34. package/dist-lib/bridge-contract-input.cjs +1 -1
  35. package/dist-lib/bridge-contract-input.mjs +1 -1
  36. package/dist-lib/bridge-contract.cjs +1 -1
  37. package/dist-lib/bridge-contract.mjs +1 -1
  38. package/dist-lib/bundle-channel.cjs +1528 -937
  39. package/dist-lib/capture-contract.cjs +1 -1
  40. package/dist-lib/capture-contract.mjs +1 -1
  41. package/dist-lib/cloud-contract.cjs +1 -1
  42. package/dist-lib/cloud-contract.mjs +1 -1
  43. package/dist-lib/cloud-test-args.cjs +1 -1
  44. package/dist-lib/cloud-test-args.mjs +1 -1
  45. package/dist-lib/cloud.cjs +4 -3
  46. package/dist-lib/cloud.mjs +4 -3
  47. package/dist-lib/config.cjs +5 -4
  48. package/dist-lib/config.mjs +5 -4
  49. package/dist-lib/detox/index.cjs +1021 -364
  50. package/dist-lib/dev-bundle-resolution.cjs +51 -23
  51. package/dist-lib/expo-swift-bundle.cjs +1351 -804
  52. package/dist-lib/expo-swift-metadata.cjs +5 -4
  53. package/dist-lib/expo-swift-metadata.mjs +5 -4
  54. package/dist-lib/home-paths.cjs +1 -1
  55. package/dist-lib/host/bridge-host.cjs +2475 -1343
  56. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  57. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  58. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  59. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  60. package/dist-lib/host/websocket-proxy.cjs +1 -1
  61. package/dist-lib/index.cjs +1269 -300
  62. package/dist-lib/jump-to-source-babel.cjs +1 -1
  63. package/dist-lib/jump-to-source-native.cjs +1 -1
  64. package/dist-lib/kotlin-host.cjs +1 -1
  65. package/dist-lib/menu.cjs +3 -2
  66. package/dist-lib/menu.mjs +3 -2
  67. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  68. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  69. package/dist-lib/metro-production-bundle.cjs +5 -4
  70. package/dist-lib/metro-production-bundle.mjs +5 -4
  71. package/dist-lib/metro.cjs +806 -398
  72. package/dist-lib/native-app-identity-project.cjs +729 -21
  73. package/dist-lib/native-app-identity-project.mjs +728 -21
  74. package/dist-lib/native-app-identity.cjs +232 -9
  75. package/dist-lib/native-app-identity.mjs +230 -8
  76. package/dist-lib/native-firebase-metadata.cjs +5 -4
  77. package/dist-lib/native-firebase-metadata.mjs +5 -4
  78. package/dist-lib/plist.cjs +1 -1
  79. package/dist-lib/plist.mjs +1 -1
  80. package/dist-lib/profiles.cjs +1 -1
  81. package/dist-lib/public-brand.cjs +3 -2
  82. package/dist-lib/react-native-host-modules.cjs +4 -1
  83. package/dist-lib/react-native-host-modules.mjs +4 -1
  84. package/dist-lib/scripts/dev-server-scanner.cjs +94 -28
  85. package/dist-lib/sdk.cjs +89 -24
  86. package/dist-lib/sdk.mjs +89 -24
  87. package/dist-lib/skills.cjs +4471 -2394
  88. package/dist-lib/swift-compile.cjs +336 -145
  89. package/dist-lib/swift-compile.mjs +350 -150
  90. package/dist-lib/swift-package.cjs +1 -1
  91. package/dist-lib/swift-package.mjs +1 -1
  92. package/dist-lib/swift-submit.cjs +1 -1
  93. package/dist-lib/swift-submit.mjs +1 -1
  94. package/dist-lib/swift-toolchain.cjs +1 -1
  95. package/dist-lib/swift.cjs +1 -1
  96. package/dist-lib/vite-swift.cjs +891 -557
  97. package/dist-lib/vite.cjs +68 -14
  98. package/dist-lib/worklet-executable.cjs +25 -2
  99. package/dist-lib/worklet-executable.mjs +25 -2
  100. package/package.json +2 -2
  101. package/scripts/dev-server-scanner.ts +33 -13
  102. package/src/admitted-mac-build.ts +34 -8
  103. package/src/android-app-identity.ts +146 -0
  104. package/src/android-autolinking.ts +75 -0
  105. package/src/android-string-value.ts +36 -0
  106. package/src/android-strings.ts +5 -36
  107. package/src/androidAutolinkingContract.ts +40 -0
  108. package/src/bundleGlobalFooter.ts +26 -7
  109. package/src/cloud.ts +2 -2
  110. package/src/codex-client.ts +3 -2
  111. package/src/dev-bundle-resolution.ts +58 -25
  112. package/src/expo-kotlin-host.ts +6 -36
  113. package/src/expo-swift-bundle.ts +17 -12
  114. package/src/expo-swift-host.ts +477 -173
  115. package/src/expoSwiftContract.ts +6 -0
  116. package/src/host/bridge-host.ts +7 -55
  117. package/src/host/staged-host-files.ts +29 -2
  118. package/src/installed-package-versions.ts +54 -14
  119. package/src/launchMetadataContract.ts +24 -0
  120. package/src/metro-plugin.ts +37 -42
  121. package/src/native-app-identity-project.ts +118 -3
  122. package/src/native-app-identity.ts +103 -11
  123. package/src/nitro-compile.ts +2 -5
  124. package/src/nitro-source.ts +147 -63
  125. package/src/process-group.ts +90 -60
  126. package/src/process-output.ts +0 -9
  127. package/src/public-brand.ts +1 -0
  128. package/src/react-native-host-modules.ts +3 -0
  129. package/src/sim-client.ts +6 -4
  130. package/src/swift-compile.ts +185 -31
  131. package/src/swift-distribution.lock.json +37 -11
  132. package/src/swift-distribution.ts +61 -9
  133. package/src/swift-host.ts +58 -27
  134. package/src/swift-objc-standin.ts +13 -0
  135. package/src/swift-standin-emit.ts +1 -1
  136. package/src/swift-standins.ts +17 -5
  137. package/src/vite-plugin.ts +8 -19
  138. package/src/worklet-executable.ts +30 -3
  139. package/src/worklets-babel.ts +35 -14
  140. package/src/xcode-project.ts +10 -0
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1619 | (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/v46
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) {
@@ -2143,9 +2369,14 @@ function compiledSwiftSources(files2, targets) {
2143
2369
  const orderedTargets = [...targets].sort((a, b) => b.path.length - a.path.length);
2144
2370
  for (const [file, contents] of Object.entries(files2)) {
2145
2371
  if (!file.endsWith(".swift")) continue;
2146
- const owner = orderedTargets.find(
2147
- (candidate) => candidate.path === "." || file.startsWith(`${candidate.path}/`)
2148
- );
2372
+ const owner = orderedTargets.find((candidate) => {
2373
+ const prefix = candidate.path === "." ? "" : `${candidate.path}/`;
2374
+ if (!file.startsWith(prefix)) return false;
2375
+ const relative = file.slice(prefix.length);
2376
+ return !candidate.exclude?.some(
2377
+ (excluded) => relative === excluded || relative.startsWith(`${excluded}/`)
2378
+ );
2379
+ });
2149
2380
  if (/(?:^|\/)Package(?:@swift-[\d.]+)?\.swift$/.test(file) && (!owner || /^Package(?:@swift-[\d.]+)?\.swift$/.test(file))) {
2150
2381
  compiled.set(file, contents);
2151
2382
  continue;
@@ -2175,11 +2406,53 @@ function compiledSwiftSources(files2, targets) {
2175
2406
  const sources = lifted.map(([, contents]) => contents);
2176
2407
  const extensions = objcExtensionMemberIndex(sources);
2177
2408
  const objc = objcIndex(sources);
2409
+ const rooted = objcRootedClasses(sources);
2178
2410
  for (const [file, contents] of lifted)
2179
- compiled.set(file, swiftSourceAsIOS(contents, extensions, objc));
2411
+ compiled.set(
2412
+ file,
2413
+ hideObjCClassesFromCxx(swiftSourceAsIOS(contents, extensions, objc), rooted)
2414
+ );
2180
2415
  }
2181
2416
  return compiled;
2182
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
+ }
2183
2456
  function lowerAnyObjectDoubleValue(source) {
2184
2457
  const masked = swiftCodeMask(source);
2185
2458
  const names = /* @__PURE__ */ new Set();
@@ -2601,11 +2874,39 @@ function objcIndex(sources) {
2601
2874
  /\b(?:var|let)\s+([A-Za-z_]\w*)/g
2602
2875
  ))
2603
2876
  variables.add(declared[1]);
2604
- const parents = requirements.size ? inheritedTypes(sources) : /* @__PURE__ */ new Map();
2877
+ const parents = inheritedTypes(sources);
2605
2878
  for (const [protocol, inherited] of sdkParents)
2606
2879
  parents.set(protocol, /* @__PURE__ */ new Set([...parents.get(protocol) ?? [], ...inherited]));
2607
2880
  const conformers = requirements.size ? conformingTypes(parents, new Set(requirements.keys())) : /* @__PURE__ */ new Map();
2608
- 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
+ };
2609
2910
  }
2610
2911
  function objcAliases(sources) {
2611
2912
  const declared = /* @__PURE__ */ new Map();
@@ -2852,7 +3153,7 @@ function lowerObjCOptionalRequirements(source, index) {
2852
3153
  }
2853
3154
  function lowerObjCRuntimeCalls(source, index) {
2854
3155
  const casts = source.includes("@convention(c)");
2855
- const classes = /\b(?:AnyClass|AnyObject)\b/.test(source);
3156
+ const classes = /\b(?:AnyClass|AnyObject)\b|\.\s*init\s*\(/.test(source);
2856
3157
  if (!casts && !classes) return source;
2857
3158
  const code = swiftCodeMask(source);
2858
3159
  const edits = [];
@@ -2882,11 +3183,24 @@ function lowerObjCRuntimeCalls(source, index) {
2882
3183
  if (classes) {
2883
3184
  const declarations = /* @__PURE__ */ new Map();
2884
3185
  for (const declared of code.matchAll(
2885
- /(?:\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
2886
3187
  )) {
2887
3188
  const name2 = declared[1] ?? declared[4] ?? declared[5];
2888
3189
  const list2 = declarations.get(name2) ?? [];
2889
- 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 });
2890
3204
  declarations.set(name2, list2);
2891
3205
  }
2892
3206
  for (const pattern of code.matchAll(/\b(?:let|var|for)\s*(?=\(|\.\s*\w+\s*\()/g)) {
@@ -2900,7 +3214,7 @@ function lowerObjCRuntimeCalls(source, index) {
2900
3214
  }
2901
3215
  for (const list2 of declarations.values()) list2.sort((a, b) => a.at - b.at);
2902
3216
  const braces = [...code.matchAll(/[{}]/g)].map((match) => match.index);
2903
- const receives = (name2, at, type) => {
3217
+ const receiverType = (name2, at) => {
2904
3218
  let innermost;
2905
3219
  for (const declared of declarations.get(name2) ?? []) {
2906
3220
  if (declared.at > at) break;
@@ -2908,17 +3222,31 @@ function lowerObjCRuntimeCalls(source, index) {
2908
3222
  if (at > from && at < to && (!innermost || from >= innermost.from))
2909
3223
  innermost = { from, type: declared.type };
2910
3224
  }
2911
- return innermost?.type === type;
3225
+ return innermost?.type;
2912
3226
  };
2913
3227
  let reached = -1;
2914
3228
  for (const call of code.matchAll(
2915
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
2916
3230
  )) {
2917
- if (call.index < reached || !(call[2] ? receives(call[2], call.index, "AnyObject") : receives(call[1], call.index, "AnyClass")))
2918
- 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;
2919
3236
  const open = call.index + call[0].length - 1;
2920
3237
  const shut = closingParen(code, open);
2921
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;
2922
3250
  const selector = objcSelectorName(
2923
3251
  call[3],
2924
3252
  passed.map(({ label }) => label),
@@ -3327,7 +3655,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3327
3655
  const targets = distribution && compileTargets(input).length === 0 ? [
3328
3656
  {
3329
3657
  name: "App",
3330
- path: import_node_path3.default.relative(layout.root, layout.sources),
3658
+ path: import_node_path5.default.relative(layout.root, layout.sources),
3331
3659
  executable: true,
3332
3660
  languageMode: 5,
3333
3661
  mainActorIsolation: false,
@@ -3336,7 +3664,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3336
3664
  ] : compileTargets(input);
3337
3665
  const files2 = /* @__PURE__ */ new Map();
3338
3666
  const native = /* @__PURE__ */ new Map();
3339
- 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");
3340
3668
  for (const target of targets) {
3341
3669
  const prefix = target.path === "." ? "" : `${target.path}/`;
3342
3670
  const entries = Object.entries(input.files).filter(
@@ -3359,7 +3687,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3359
3687
  if (producer && targets.some((value) => value.name === producer))
3360
3688
  producers.add(producer);
3361
3689
  const local = [
3362
- 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),
3363
3691
  `${includes}${include}`
3364
3692
  ].find((candidate) => input.files[candidate] !== void 0);
3365
3693
  if (local) {
@@ -3381,7 +3709,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3381
3709
  const late = units.filter(([file]) => consumers.get(file).size > 0);
3382
3710
  native.set(target.name, {
3383
3711
  path: target.path,
3384
- includeDirectory: import_node_path3.default.join(layout.root, includes),
3712
+ includeDirectory: import_node_path5.default.join(layout.root, includes),
3385
3713
  lateSources: late.map(([file]) => file.slice(prefix.length)),
3386
3714
  ...late.length > 0 ? {
3387
3715
  late: {
@@ -3398,7 +3726,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3398
3726
  ([file]) => file.startsWith(includes) && /\.(?:h|hpp|hh|hxx)$/.test(file) && consumers.get(file).size === 0
3399
3727
  );
3400
3728
  files2.set(
3401
- import_node_path3.default.join(layout.root, includes, "module.modulemap"),
3729
+ import_node_path5.default.join(layout.root, includes, "module.modulemap"),
3402
3730
  [
3403
3731
  `module ${target.name} {`,
3404
3732
  ...roots.map(
@@ -3410,14 +3738,14 @@ function writeSwiftProject(layout, input, moduleRoot) {
3410
3738
  ].join("\n")
3411
3739
  );
3412
3740
  }
3413
- if (native.size > 0) (0, import_node_fs3.mkdirSync)(headerDirectory, { recursive: true });
3414
- 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(
3415
3743
  swiftModuleInputFiles(moduleRoot).join("\n")
3416
3744
  );
3417
3745
  if (!distribution) {
3418
- 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")));
3419
3747
  }
3420
- const resourcePlan = (0, import_node_crypto2.createHash)("sha256").update(
3748
+ const resourcePlan = (0, import_node_crypto3.createHash)("sha256").update(
3421
3749
  JSON.stringify(
3422
3750
  resourceTargets.filter((target) => target.resources).map((target) => [
3423
3751
  target.name,
@@ -3442,10 +3770,10 @@ function writeSwiftProject(layout, input, moduleRoot) {
3442
3770
  if (targets.length === 0) {
3443
3771
  for (const [file, contents] of Object.entries(input.files)) {
3444
3772
  if (file === "Package.swift") continue;
3445
- 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);
3446
3774
  }
3447
- let manifest = (0, import_node_fs3.readFileSync)(
3448
- 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"),
3449
3777
  "utf8"
3450
3778
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
3451
3779
  const reactor = ` ${REACTOR_FLAG}`;
@@ -3489,21 +3817,21 @@ function writeSwiftProject(layout, input, moduleRoot) {
3489
3817
  manifest = manifest.replace(anchor, `${anchor}
3490
3818
  ${SPRITEKIT_PRODUCT},`);
3491
3819
  }
3492
- 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);
3493
3821
  } else {
3494
3822
  const base = layout.multi ? layout.root : layout.sources;
3495
3823
  const libraries = /* @__PURE__ */ new Map();
3496
3824
  for (const [target, data] of Object.entries(input.libraries ?? {})) {
3497
- 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`);
3498
3826
  files2.set(file, Buffer.from(data, "base64"));
3499
3827
  libraries.set(target, file);
3500
3828
  }
3501
3829
  for (const [file, contents] of Object.entries(input.files)) {
3502
3830
  if (file === "Package.swift") continue;
3503
- 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);
3504
3832
  }
3505
3833
  files2.set(
3506
- import_node_path3.default.join(layout.root, "Package.swift"),
3834
+ import_node_path5.default.join(layout.root, "Package.swift"),
3507
3835
  emitSwiftPackageManifest({
3508
3836
  targets,
3509
3837
  native,
@@ -3520,7 +3848,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
3520
3848
  spriteKit: importsSpriteKit(input.files),
3521
3849
  distribution: distribution ?? void 0,
3522
3850
  distributionLink: {
3523
- 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"),
3524
3852
  files: files2
3525
3853
  },
3526
3854
  libraries
@@ -3536,9 +3864,9 @@ function writeSwiftProject(layout, input, moduleRoot) {
3536
3864
  throw new Error(
3537
3865
  `swift resource target ${target.name} has no matching bundle assignment`
3538
3866
  );
3539
- 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;
3540
3868
  files2.set(
3541
- import_node_path3.default.join(directory, "ResourceBundleAccessor.generated.swift"),
3869
+ import_node_path5.default.join(directory, "ResourceBundleAccessor.generated.swift"),
3542
3870
  [
3543
3871
  "import Foundation",
3544
3872
  "",
@@ -3571,15 +3899,15 @@ function outputOf(error) {
3571
3899
  return error instanceof Error ? error.message : String(error);
3572
3900
  }
3573
3901
  function builtArtifact(layout) {
3574
- const binDir = import_node_path3.default.join(layout.root, ".build", WASM_TRIPLE, "release");
3575
- 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");
3576
3904
  const executable = swiftManifestTargets(manifest).find((target) => target.executable);
3577
3905
  if (executable === void 0) {
3578
3906
  throw new Error("swift-compile: the written manifest names no executable target");
3579
3907
  }
3580
- const file = import_node_path3.default.join(binDir, `${executable.name}.wasm`);
3581
- if (!(0, import_node_fs3.existsSync)(file)) {
3582
- 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() : [];
3583
3911
  throw new Error(
3584
3912
  `swift-compile: the build produced no ${executable.name}.wasm (found: ${found.join(", ") || "none"})`
3585
3913
  );
@@ -3588,7 +3916,7 @@ function builtArtifact(layout) {
3588
3916
  }
3589
3917
  function projectDiagnostic(output, layout, files2) {
3590
3918
  const base = layout.multi ? layout.root : layout.sources;
3591
- const prefix = `${base}${import_node_path3.default.sep}`;
3919
+ const prefix = `${base}${import_node_path5.default.sep}`;
3592
3920
  return designTimeDiagnostic(output, files2).split("\n").map((line) => line.startsWith(prefix) ? line.slice(prefix.length) : line).join("\n").trim();
3593
3921
  }
3594
3922
  function serialize(root, work, signal) {
@@ -3621,13 +3949,13 @@ function serialize(root, work, signal) {
3621
3949
  function readCompiledArtifact(directory, hash) {
3622
3950
  try {
3623
3951
  const receipt = JSON.parse(
3624
- (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")
3625
3953
  );
3626
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")
3627
3955
  return null;
3628
- const bytes = (0, import_node_fs3.readFileSync)(import_node_path3.default.join(directory, "app.wasm"));
3629
- const gzip2 = (0, import_node_fs3.readFileSync)(import_node_path3.default.join(directory, "icu.gz"));
3630
- 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)
3631
3959
  return null;
3632
3960
  return { hash, bytes, icu: { sha256: receipt.icu, gzip: gzip2 } };
3633
3961
  } catch (error) {
@@ -3637,25 +3965,25 @@ function readCompiledArtifact(directory, hash) {
3637
3965
  }
3638
3966
  }
3639
3967
  function saveCompiledArtifact(root, artifact) {
3640
- const directory = import_node_path3.default.join(root, "artifact");
3641
- (0, import_node_fs3.mkdirSync)(directory, { recursive: true });
3642
- 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-"));
3643
3971
  try {
3644
- (0, import_node_fs3.writeFileSync)(import_node_path3.default.join(pending, "app.wasm"), artifact.bytes);
3645
- (0, import_node_fs3.writeFileSync)(import_node_path3.default.join(pending, "icu.gz"), artifact.icu.gzip);
3646
- (0, import_node_fs3.writeFileSync)(
3647
- 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"),
3648
3976
  JSON.stringify({
3649
3977
  hash: artifact.hash,
3650
- 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"),
3651
3979
  icu: artifact.icu.sha256
3652
3980
  })
3653
3981
  );
3654
3982
  for (const file of ["app.wasm", "icu.gz", "artifact.json"]) {
3655
- (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));
3656
3984
  }
3657
3985
  } finally {
3658
- (0, import_node_fs3.rmSync)(pending, { recursive: true, force: true });
3986
+ (0, import_node_fs4.rmSync)(pending, { recursive: true, force: true });
3659
3987
  }
3660
3988
  }
3661
3989
  function retain(root, artifact) {
@@ -3670,42 +3998,54 @@ function retain(root, artifact) {
3670
3998
  }
3671
3999
  function compileSwiftProjectUnit(input, options) {
3672
4000
  options.signal?.throwIfAborted();
3673
- (0, import_node_fs3.mkdirSync)(options.buildRoot, { recursive: true });
3674
- const root = (0, import_node_fs3.realpathSync)(options.buildRoot);
3675
- 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);
3676
4004
  const layout = {
3677
4005
  root,
3678
- sources: import_node_path3.default.join(root, "Sources", "App"),
4006
+ sources: import_node_path5.default.join(root, "Sources", "App"),
3679
4007
  multi: compileTargets(input).length > 0
3680
4008
  };
3681
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");
3682
4013
  return serialize(
3683
4014
  root,
3684
4015
  async () => {
3685
4016
  const retained = retainedArtifacts.get(root)?.find((old) => old.hash === hash);
3686
- if (retained) return retain(root, retained);
3687
- const cached2 = readCompiledArtifact(import_node_path3.default.join(root, "artifact"), hash);
3688
- if (cached2) return retain(root, cached2);
3689
- 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)) {
3690
- const requestRoot = (0, import_node_fs3.mkdtempSync)(import_node_path3.default.join(root, ".builder-request-"));
3691
- const output = import_node_path3.default.join(requestRoot, "output");
3692
- const request = import_node_path3.default.join(requestRoot, "request.json");
3693
- (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)(
3694
4033
  request,
3695
4034
  JSON.stringify({
3696
4035
  input,
3697
4036
  hash,
3698
4037
  release: options.release,
3699
4038
  timeoutMs: options.timeoutMs,
3700
- 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)
3701
4040
  })
3702
4041
  );
3703
4042
  try {
3704
- 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");
3705
4045
  await runCompiler(
3706
4046
  "bun",
3707
4047
  [
3708
- import_node_path3.default.join(repo, "scripts/build/swift-project.ts"),
4048
+ import_node_path5.default.join(repo, "scripts/build/swift-project.ts"),
3709
4049
  "--request",
3710
4050
  request,
3711
4051
  "--output",
@@ -3729,18 +4069,21 @@ function compileSwiftProjectUnit(input, options) {
3729
4069
  );
3730
4070
  }
3731
4071
  saveCompiledArtifact(root, artifact2);
4072
+ saveCompiledArtifact(sharedRoot, artifact2);
4073
+ report("builder artifact verified");
3732
4074
  return retain(root, artifact2);
3733
4075
  } finally {
3734
- (0, import_node_fs3.rmSync)(requestRoot, { recursive: true, force: true });
4076
+ (0, import_node_fs4.rmSync)(requestRoot, { recursive: true, force: true });
3735
4077
  }
3736
4078
  }
3737
4079
  writeSwiftProject(layout, input, moduleRoot);
3738
- const swift = import_node_path3.default.join(options.toolchainBin, "swift");
3739
- 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)) {
3740
4082
  throw new Error(
3741
4083
  `swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
3742
4084
  );
3743
4085
  }
4086
+ report("preparing compiler plugins");
3744
4087
  const macroPlugins = await ensureMacroPlugins(
3745
4088
  moduleRoot,
3746
4089
  options.toolchainBin,
@@ -3780,8 +4123,8 @@ function compileSwiftProjectUnit(input, options) {
3780
4123
  // shipped host plugins resolve against the selected compiler's runtime.
3781
4124
  ...process.platform === "linux" ? {
3782
4125
  LD_LIBRARY_PATH: [
3783
- import_node_path3.default.resolve(options.toolchainBin, "../lib/swift/linux"),
3784
- 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"),
3785
4128
  process.env.LD_LIBRARY_PATH
3786
4129
  ].filter(Boolean).join(":")
3787
4130
  } : {}
@@ -3790,21 +4133,22 @@ function compileSwiftProjectUnit(input, options) {
3790
4133
  timeout: options.timeoutMs,
3791
4134
  signal: options.signal
3792
4135
  };
4136
+ report("compiling and linking Swift modules");
3793
4137
  try {
3794
- await runCompiler(swift, buildArgs, buildOptions);
4138
+ await runCompiler(swift, buildArgs, buildOptions, true);
3795
4139
  } catch (error) {
3796
4140
  const output = outputOf(error);
3797
- const moduleCache = import_node_path3.default.join(
4141
+ const moduleCache = import_node_path5.default.join(
3798
4142
  root,
3799
4143
  ".build",
3800
4144
  WASM_TRIPLE,
3801
4145
  "release",
3802
4146
  "ModuleCache"
3803
4147
  );
3804
- if (output.includes("was compiled with module cache path") && (0, import_node_fs3.existsSync)(moduleCache)) {
3805
- (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 });
3806
4150
  try {
3807
- await runCompiler(swift, buildArgs, buildOptions);
4151
+ await runCompiler(swift, buildArgs, buildOptions, true);
3808
4152
  } catch (retryError) {
3809
4153
  throw new Error(
3810
4154
  projectDiagnostic(outputOf(retryError), layout, input.files),
@@ -3821,25 +4165,28 @@ function compileSwiftProjectUnit(input, options) {
3821
4165
  }
3822
4166
  const artifact = {
3823
4167
  hash,
3824
- bytes: (0, import_node_fs3.readFileSync)(builtArtifact(layout)),
4168
+ bytes: (0, import_node_fs4.readFileSync)(builtArtifact(layout)),
3825
4169
  icu: await icu
3826
4170
  };
3827
4171
  saveCompiledArtifact(root, artifact);
4172
+ saveCompiledArtifact(sharedRoot, artifact);
4173
+ report("compiled artifact verified");
3828
4174
  return retain(root, artifact);
3829
4175
  },
3830
4176
  options.signal
3831
4177
  );
3832
4178
  }
3833
- 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;
3834
4180
  var init_swift_compile = __esm({
3835
4181
  "src/swift-compile.ts"() {
3836
4182
  "use strict";
3837
- import_node_child_process3 = require("node:child_process");
3838
- import_node_crypto2 = require("node:crypto");
3839
- import_node_fs3 = require("node:fs");
3840
- import_node_os2 = __toESM(require("node:os"), 1);
3841
- 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);
3842
4188
  init_admitted_mac_build();
4189
+ init_home_paths();
3843
4190
  init_process_group();
3844
4191
  init_swift_design_time();
3845
4192
  init_swift_distribution_contract();
@@ -3848,7 +4195,7 @@ var init_swift_compile = __esm({
3848
4195
  init_swiftContract();
3849
4196
  WASM_TRIPLE = "wasm32-unknown-wasip1";
3850
4197
  BUILD_JOBS = String(
3851
- 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)))
3852
4199
  );
3853
4200
  linkedModuleDigests = /* @__PURE__ */ new Map();
3854
4201
  OPTIONAL_FRAMEWORK_DEPENDENCIES = {
@@ -3941,6 +4288,7 @@ var init_swift_compile = __esm({
3941
4288
  MODIFIERS = /(?:^|\s)(public|open|internal|fileprivate|private|final|nonisolated|@MainActor)(?=\s)/g;
3942
4289
  OVERRIDE_FUNC = /^override((?:\s+(?:public|open|internal|fileprivate|private|final|nonisolated|dynamic|@\w+))*)\s+func\s+([A-Za-z_]\w*)\s*(<[^>{}]*>)?\s*\(/;
3943
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)$/;
3944
4292
  OBJC_PROTOCOL = /@objc\b(?:\s*\([^()]*\))?(?:\s+(?:@\w+(?:\([^()]*\))?|public|internal|fileprivate|private|package))*\s+protocol\s+([A-Za-z_]\w*)[^{]*\{/g;
3945
4293
  OBJC_PREPOSITIONS = /* @__PURE__ */ new Set([
3946
4294
  "above",
@@ -5408,156 +5756,188 @@ var init_product = __esm({
5408
5756
 
5409
5757
  // ../contrast-runtime-delivery/src/index.ts
5410
5758
  async function installVerifiedTarball(tarball) {
5411
- const { url, digest: digest2, destDir, installedMarker, label } = tarball;
5412
- const downloadDir = import_node_fs4.default.mkdtempSync(import_node_path4.default.join(import_node_os3.default.tmpdir(), "runtime-delivery-download-"));
5413
- const archivePath = import_node_path4.default.join(downloadDir, "archive");
5414
- import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(destDir), { recursive: true });
5415
- const tmpDir = import_node_fs4.default.mkdtempSync(
5416
- 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)}-`)
5417
5766
  );
5418
5767
  try {
5419
- await downloadToFile(url, archivePath);
5420
- 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
+ );
5421
5775
  if (actual !== digest2.value) {
5422
5776
  throw new Error(
5423
5777
  `${digest2.algorithm} mismatch for ${label}: expected ${digest2.value}, actual ${actual}`
5424
5778
  );
5425
5779
  }
5426
- if (new URL(url).pathname.endsWith(".zip")) await extractZip(archivePath, tmpDir);
5427
- else await extractTarball(archivePath, tmpDir, tarball.stripComponents ?? 0);
5428
- 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))) {
5429
5785
  throw new Error(`extracted tarball for ${label} is missing ${installedMarker}`);
5430
5786
  }
5431
5787
  tarball.verify?.(tmpDir);
5788
+ signal?.throwIfAborted();
5432
5789
  try {
5433
- import_node_fs4.default.renameSync(tmpDir, destDir);
5790
+ import_node_fs5.default.renameSync(tmpDir, destDir);
5434
5791
  } catch (err) {
5435
5792
  if (!isErrnoCode(err, "ENOTEMPTY", "EEXIST")) throw err;
5436
5793
  const aside = `${tmpDir}-replaced`;
5437
5794
  try {
5438
- import_node_fs4.default.renameSync(destDir, aside);
5795
+ import_node_fs5.default.renameSync(destDir, aside);
5439
5796
  } catch (moveErr) {
5440
5797
  if (!isErrnoCode(moveErr, "ENOENT")) throw moveErr;
5441
5798
  }
5442
5799
  try {
5443
- import_node_fs4.default.renameSync(tmpDir, destDir);
5800
+ import_node_fs5.default.renameSync(tmpDir, destDir);
5444
5801
  } catch (landErr) {
5445
- 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))) {
5446
5803
  throw landErr;
5447
5804
  }
5448
5805
  } finally {
5449
- import_node_fs4.default.rmSync(aside, { recursive: true, force: true });
5806
+ import_node_fs5.default.rmSync(aside, { recursive: true, force: true });
5450
5807
  }
5451
5808
  }
5452
5809
  } finally {
5453
- import_node_fs4.default.rmSync(tmpDir, { recursive: true, force: true });
5454
- 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 });
5455
5812
  }
5456
5813
  }
5457
5814
  function isErrnoCode(err, ...codes) {
5458
5815
  return err instanceof Error && "code" in err && codes.includes(String(err.code));
5459
5816
  }
5460
- async function downloadToFile(url, destPath) {
5461
- const res = await fetch(url);
5817
+ async function downloadToFile(url, destPath, signal) {
5818
+ const res = await fetch(url, { signal });
5462
5819
  if (!res.ok || !res.body) {
5463
5820
  throw new Error(`download failed: ${res.status} ${res.statusText} (${url})`);
5464
5821
  }
5465
- 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 });
5466
5823
  const tmp = `${destPath}.partial`;
5467
5824
  try {
5468
5825
  await (0, import_promises2.pipeline)(
5469
5826
  import_node_stream.Readable.fromWeb(res.body),
5470
- import_node_fs4.default.createWriteStream(tmp)
5827
+ import_node_fs5.default.createWriteStream(tmp),
5828
+ { signal }
5471
5829
  );
5472
- import_node_fs4.default.renameSync(tmp, destPath);
5830
+ signal?.throwIfAborted();
5831
+ import_node_fs5.default.renameSync(tmp, destPath);
5473
5832
  } catch (err) {
5474
5833
  try {
5475
- import_node_fs4.default.unlinkSync(tmp);
5834
+ import_node_fs5.default.unlinkSync(tmp);
5476
5835
  } catch {
5477
5836
  }
5478
5837
  throw err;
5479
5838
  }
5480
5839
  }
5481
- function digestFile(filePath, algorithm, encoding) {
5482
- return new Promise((resolve2, reject) => {
5483
- const hash = import_node_crypto3.default.createHash(algorithm);
5484
- const stream = import_node_fs4.default.createReadStream(filePath);
5485
- stream.on("data", (chunk) => hash.update(chunk));
5486
- stream.on("error", reject);
5487
- stream.on("end", () => resolve2(hash.digest(encoding)));
5488
- });
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);
5489
5844
  }
5490
- function extractZip(zipPath, destDir) {
5491
- return runExtractor("ditto", ["-x", "-k", zipPath, destDir]);
5845
+ function extractZip(zipPath, destDir, signal) {
5846
+ return runExtractor("ditto", ["-x", "-k", zipPath, destDir], signal);
5492
5847
  }
5493
- function extractTarball(tarPath, destDir, stripComponents) {
5848
+ function extractTarball(tarPath, destDir, stripComponents, signal) {
5494
5849
  const args = ["-xzf", tarPath, "-C", destDir];
5495
5850
  if (stripComponents > 0) args.push(`--strip-components=${stripComponents}`);
5496
- return runExtractor("tar", args);
5851
+ return runExtractor("tar", args, signal);
5497
5852
  }
5498
- function runExtractor(command, args) {
5499
- return new Promise((resolve2, reject) => {
5500
- const child = (0, import_node_child_process4.spawn)(command, args, {
5501
- 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(() => {
5502
5863
  });
5503
- child.on("error", reject);
5504
- child.on("exit", (code) => {
5505
- if (code === 0) resolve2();
5506
- 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();
5507
5883
  });
5508
- });
5884
+ } finally {
5885
+ signal?.removeEventListener("abort", abort);
5886
+ await stopping;
5887
+ }
5509
5888
  }
5510
- 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;
5511
5890
  var init_src = __esm({
5512
5891
  "../contrast-runtime-delivery/src/index.ts"() {
5513
5892
  "use strict";
5514
- import_node_child_process4 = require("node:child_process");
5515
- import_node_crypto3 = __toESM(require("node:crypto"), 1);
5516
- import_node_fs4 = __toESM(require("node:fs"), 1);
5517
- import_node_os3 = __toESM(require("node:os"), 1);
5518
- 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);
5519
5898
  import_node_stream = require("node:stream");
5520
5899
  import_promises2 = require("node:stream/promises");
5900
+ init_process_group();
5521
5901
  init_product();
5522
5902
  init_product();
5523
5903
  }
5524
5904
  });
5525
5905
 
5526
- // src/home-paths.ts
5527
- function rnxHomeDir() {
5528
- const override = process.env[PEACH_HOME_ENV];
5529
- if (override && override.length > 0) return import_node_path5.default.resolve(override);
5530
- return import_node_path5.default.join((0, import_node_os4.homedir)(), ".peach");
5531
- }
5532
- function electronDir() {
5533
- return import_node_path5.default.join(rnxHomeDir(), "electron");
5534
- }
5535
- function electronUserDataDir() {
5536
- return import_node_path5.default.join(electronDir(), "userData");
5537
- }
5538
- var import_node_os4, import_node_path5, PEACH_HOME_ENV, DAEMON_LOCKFILE_MAX_BYTES;
5539
- var init_home_paths = __esm({
5540
- "src/home-paths.ts"() {
5541
- "use strict";
5542
- import_node_os4 = require("node:os");
5543
- import_node_path5 = __toESM(require("node:path"), 1);
5544
- PEACH_HOME_ENV = "PEACH_HOME";
5545
- DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
5546
- }
5547
- });
5548
-
5549
5906
  // src/swift-distribution.lock.json
5550
5907
  var swift_distribution_lock_default;
5551
5908
  var init_swift_distribution_lock = __esm({
5552
5909
  "src/swift-distribution.lock.json"() {
5553
5910
  swift_distribution_lock_default = {
5554
- id: "64fd4ea71bc39e4f",
5911
+ id: "1fda1fb984f25758",
5555
5912
  release: "swift-6.4.0-RELEASE",
5556
- wasmSdkId: "swift-6.4.0-RELEASE_wasm-peach-dc9c8c67",
5557
- wasmSdkUrl: "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-dc9c8c67.artifactbundle.tar.gz",
5558
- wasmSdkChecksum: "5d38f795f516ccfef3d7ac869b447cdedcd82a35af9761a65b9f88924eb6a89a",
5559
- 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",
5560
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",
5561
5941
  "ExpoModulesCore",
5562
5942
  "_MapKit_SwiftUI",
5563
5943
  "PeachJSON",
@@ -5573,6 +5953,7 @@ var init_swift_distribution_lock = __esm({
5573
5953
  "PeachObjC",
5574
5954
  "UIKitCore",
5575
5955
  "PeachICU",
5956
+ "PeachCMark",
5576
5957
  "CoreImage",
5577
5958
  "QuartzCore",
5578
5959
  "CoreGraphics",
@@ -5603,6 +5984,7 @@ var init_swift_distribution_lock = __esm({
5603
5984
  "ActivityKit",
5604
5985
  "SwiftData",
5605
5986
  "UIKit",
5987
+ "React",
5606
5988
  "Combine",
5607
5989
  "PeachFoundationCombine",
5608
5990
  "AppIntents",
@@ -5684,6 +6066,7 @@ var init_swift_distribution_lock = __esm({
5684
6066
  systemVersion: ["string"],
5685
6067
  colorScheme: ["string:light", "string:dark"],
5686
6068
  semanticColors: ["object"],
6069
+ imageAssets: ["object"],
5687
6070
  locale: ["string"],
5688
6071
  dynamicTypeSize: [
5689
6072
  "string:xSmall",
@@ -5705,16 +6088,16 @@ var init_swift_distribution_lock = __esm({
5705
6088
  },
5706
6089
  hosts: {
5707
6090
  "darwin-arm64": {
5708
- sha256: "6b60bae2bc91957af3baee5e9cad44200f15ff3840d8e70afa5ddc63413d880f",
5709
- size: 58565898
6091
+ sha256: "6a3b956b13bcc76dbf0b55533088251e2ae29badcd5c8d66394a2459e0942a32",
6092
+ size: 63180761
5710
6093
  },
5711
6094
  "linux-x64": {
5712
- sha256: "d97e287ca5d7ea0d00dfc9db60be746aec35a9b7412299461ce0d5e77f38b7a8",
5713
- size: 58569694
6095
+ sha256: "37f26adff0a90c0647065b3c2e70bfdae05c84832b27add00915d441f2f79359",
6096
+ size: 63183751
5714
6097
  },
5715
6098
  "linux-arm64": {
5716
- sha256: "495fe6adc7cf1c8ec9fc8de3410c976e65a7ff051ca50ee3f6d0d3fee8aa2c5d",
5717
- size: 58567328
6099
+ sha256: "e329424d19ede87f4c9257de40f88220cdaff42bd82f1ab47616394ec7f32f35",
6100
+ size: 63181548
5718
6101
  }
5719
6102
  }
5720
6103
  };
@@ -5727,24 +6110,24 @@ function swiftCompilerRelease(release) {
5727
6110
  }
5728
6111
  function swiftToolchainBin(release) {
5729
6112
  if (process.platform === "darwin") {
5730
- const dirs = [import_node_os5.default.homedir(), "/"].map(
5731
- (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`)
5732
6115
  );
5733
- 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];
5734
6117
  }
5735
6118
  if (process.env.CONTRAST_SWIFT_TOOLCHAINS) {
5736
- 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");
5737
6120
  }
5738
- const image = import_node_path6.default.join("/opt/swift", release, "usr/bin");
5739
- if (import_node_fs5.default.existsSync(import_node_path6.default.join(image, "swift"))) return image;
5740
- 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;
5741
6124
  }
5742
6125
  function swiftToolchain(release, sdk) {
5743
6126
  const cached2 = verified.get(`${release}\0${sdk.wasmSdkId}`);
5744
6127
  if (cached2) return cached2;
5745
6128
  const bin = swiftToolchainBin(release);
5746
- const swift = import_node_path6.default.join(bin, "swift");
5747
- 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"], {
5748
6131
  encoding: "utf8",
5749
6132
  stdio: ["ignore", "pipe", "pipe"]
5750
6133
  }) : "";
@@ -5755,7 +6138,7 @@ function swiftToolchain(release, sdk) {
5755
6138
  ${swiftInstallSteps(release, sdk)}`
5756
6139
  );
5757
6140
  }
5758
- const sdks = (0, import_node_child_process5.execFileSync)(swift, ["sdk", "list"], {
6141
+ const sdks = (0, import_node_child_process6.execFileSync)(swift, ["sdk", "list"], {
5759
6142
  encoding: "utf8",
5760
6143
  stdio: ["ignore", "pipe", "pipe"]
5761
6144
  });
@@ -5790,22 +6173,23 @@ function swiftInstallSteps(release, wasmSdk) {
5790
6173
  ` ${sdk}`
5791
6174
  ].join("\n");
5792
6175
  }
5793
- 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;
5794
6177
  var init_swift_toolchain = __esm({
5795
6178
  "src/swift-toolchain.ts"() {
5796
6179
  "use strict";
5797
- import_node_child_process5 = require("node:child_process");
5798
- import_node_fs5 = __toESM(require("node:fs"), 1);
5799
- import_node_os5 = __toESM(require("node:os"), 1);
5800
- 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);
5801
6184
  verified = /* @__PURE__ */ new Map();
5802
6185
  }
5803
6186
  });
5804
6187
 
5805
6188
  // src/swift-distribution.ts
5806
- function swiftDistributionRoot() {
6189
+ async function swiftDistributionRoot(signal) {
6190
+ signal?.throwIfAborted();
5807
6191
  const endpoint = process.env[SWIFT_ENDPOINT_ENV]?.trim().replace(/\/+$/, "");
5808
- if (!endpoint) return Promise.resolve(null);
6192
+ if (!endpoint) return null;
5809
6193
  const lock = parseSwiftDistributionLock(swift_distribution_lock_default);
5810
6194
  const host2 = swiftDistributionHost(process.platform, process.arch);
5811
6195
  if (!host2) {
@@ -5814,16 +6198,19 @@ function swiftDistributionRoot() {
5814
6198
  );
5815
6199
  }
5816
6200
  swiftToolchain(lock.release, lock);
5817
- 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}`);
5818
6202
  let pending = installs.get(dir);
6203
+ if (pending?.controller.signal.aborted) pending = void 0;
5819
6204
  if (!pending) {
5820
- pending = (async () => {
5821
- 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))) {
5822
6208
  process.stderr.write(
5823
6209
  `peach: downloading Swift distribution ${lock.id} (${host2})\u2026
5824
6210
  `
5825
6211
  );
5826
6212
  await installVerifiedTarball({
6213
+ signal: controller.signal,
5827
6214
  url: `${endpoint}/${swiftDistributionKey(lock.id, host2)}`,
5828
6215
  digest: {
5829
6216
  algorithm: "sha256",
@@ -5840,17 +6227,52 @@ function swiftDistributionRoot() {
5840
6227
  throw new Error(`${dir} does not hold Swift distribution ${lock.id} (${host2})`);
5841
6228
  }
5842
6229
  return dir;
5843
- })();
5844
- pending.catch(() => installs.delete(dir));
6230
+ })().finally(() => {
6231
+ if (installs.get(dir)?.controller === controller) installs.delete(dir);
6232
+ });
6233
+ pending = { promise, controller, clients: 0 };
5845
6234
  installs.set(dir, pending);
5846
6235
  }
5847
- 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
+ }
5848
6268
  }
5849
6269
  async function resolveSwiftModule({
5850
- required = false
6270
+ required = false,
6271
+ signal
5851
6272
  } = {}) {
5852
- const checkout2 = import_node_path7.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift");
5853
- 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"))) {
5854
6276
  try {
5855
6277
  return { root: checkout2, ...swiftModuleToolchain(checkout2) };
5856
6278
  } catch (error) {
@@ -5858,22 +6280,22 @@ async function resolveSwiftModule({
5858
6280
  return null;
5859
6281
  }
5860
6282
  }
5861
- const root = await swiftDistributionRoot();
6283
+ const root = await swiftDistributionRoot(signal);
5862
6284
  return root ? { root, ...swiftModuleToolchain(root) } : null;
5863
6285
  }
5864
6286
  function swiftModuleToolchain(root) {
5865
- 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"));
5866
6288
  return {
5867
6289
  release: pin.release,
5868
6290
  toolchainBin: swiftToolchain(pin.release, swiftModuleSdk(root))
5869
6291
  };
5870
6292
  }
5871
- var import_node_fs6, import_node_path7, SWIFT_ENDPOINT_ENV, installs;
6293
+ var import_node_fs7, import_node_path8, SWIFT_ENDPOINT_ENV, installs;
5872
6294
  var init_swift_distribution = __esm({
5873
6295
  "src/swift-distribution.ts"() {
5874
6296
  "use strict";
5875
- import_node_fs6 = __toESM(require("node:fs"), 1);
5876
- 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);
5877
6299
  init_src();
5878
6300
  init_home_paths();
5879
6301
  init_swift_compile();
@@ -5906,8 +6328,8 @@ function imagesetFiles(images) {
5906
6328
  ];
5907
6329
  }).sort((a, b) => a.scale - b.scale);
5908
6330
  }
5909
- function flatScale(path20) {
5910
- const match = /@([23])x\.[^./]+$/.exec(path20);
6331
+ function flatScale(path21) {
6332
+ const match = /@([23])x\.[^./]+$/.exec(path21);
5911
6333
  return match ? Number(match[1]) : 1;
5912
6334
  }
5913
6335
  function providesNamespace(text4) {
@@ -5934,8 +6356,8 @@ function catalogEntryName(contentsPath, kind, readText) {
5934
6356
  }
5935
6357
  return segments.join("/");
5936
6358
  }
5937
- function isFlatResourceImage(path20) {
5938
- 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));
5939
6361
  }
5940
6362
  function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5941
6363
  const table = [];
@@ -5948,7 +6370,7 @@ function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5948
6370
  seen.set(bundlePath, names);
5949
6371
  return { bundlePath, names };
5950
6372
  };
5951
- const catalogs = paths.filter((path20) => baseOf(path20) === "Contents.json");
6373
+ const catalogs = paths.filter((path21) => baseOf(path21) === "Contents.json");
5952
6374
  for (const contentsPath of catalogs) {
5953
6375
  const name2 = catalogEntryName(contentsPath, ".imageset", readText);
5954
6376
  if (name2 === null) continue;
@@ -5976,13 +6398,13 @@ function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
5976
6398
  bundlePath
5977
6399
  });
5978
6400
  }
5979
- for (const path20 of paths) {
5980
- if (!isFlatResourceImage(path20)) continue;
5981
- const name2 = baseOf(path20).slice(0, -extOf(path20).length);
5982
- 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);
5983
6405
  if (name2 === "" || names.has(name2)) continue;
5984
6406
  names.add(name2);
5985
- table.push({ name: name2, file: path20, scale: flatScale(path20), bundlePath });
6407
+ table.push({ name: name2, file: path21, scale: flatScale(path21), bundlePath });
5986
6408
  }
5987
6409
  return table;
5988
6410
  }
@@ -6011,7 +6433,7 @@ function colorsetValue(color) {
6011
6433
  }
6012
6434
  function enumerateBundleColors(paths, readText) {
6013
6435
  const table = {};
6014
- for (const contentsPath of paths.filter((path20) => baseOf(path20) === "Contents.json")) {
6436
+ for (const contentsPath of paths.filter((path21) => baseOf(path21) === "Contents.json")) {
6015
6437
  const name2 = catalogEntryName(contentsPath, ".colorset", readText);
6016
6438
  if (name2 === null || name2 in table) continue;
6017
6439
  let colors;
@@ -6075,8 +6497,8 @@ function axisExtremes(points) {
6075
6497
  function pathBounds(d) {
6076
6498
  const xs = [];
6077
6499
  const ys = [];
6078
- for (const path20 of d)
6079
- (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) => {
6080
6502
  const [command, ...args] = segment2;
6081
6503
  if (command === "M" || command === "L") {
6082
6504
  xs.push(Number(args[0]));
@@ -6103,7 +6525,7 @@ function guide(svg, id, axis) {
6103
6525
  }
6104
6526
  function enumerateBundleSymbols(paths, readText, bundleForFile) {
6105
6527
  const table = {};
6106
- for (const contentsPath of paths.filter((path20) => baseOf(path20) === "Contents.json")) {
6528
+ for (const contentsPath of paths.filter((path21) => baseOf(path21) === "Contents.json")) {
6107
6529
  const name2 = catalogEntryName(contentsPath, ".symbolset", readText);
6108
6530
  if (name2 === null) continue;
6109
6531
  const bundle = bundleForFile(contentsPath);
@@ -6139,24 +6561,24 @@ function enumerateBundleSymbols(paths, readText, bundleForFile) {
6139
6561
  viewBox: "0 0 24 24",
6140
6562
  advance,
6141
6563
  box: [12 - advance / 2, 12 - tall / 2, advance, tall],
6142
- layers: d.map((path20) => ({
6143
- 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()
6144
6566
  }))
6145
6567
  };
6146
6568
  }
6147
6569
  return table;
6148
6570
  }
6149
- function isCopiedResource(path20) {
6150
- if (path20.split("/").some((segment2) => segment2.endsWith(".atlasc"))) return true;
6151
- const ext = extOf(path20);
6571
+ function isCopiedResource(path21) {
6572
+ if (path21.split("/").some((segment2) => segment2.endsWith(".atlasc"))) return true;
6573
+ const ext = extOf(path21);
6152
6574
  if (ext === ".json" || ext === ".xcstrings") return true;
6153
- 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));
6154
6576
  }
6155
6577
  function enumerateBundleResources(paths) {
6156
6578
  const found = [];
6157
6579
  const seen = /* @__PURE__ */ new Set();
6158
6580
  const ordered = [...paths].filter(
6159
- (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)
6160
6582
  ).sort((a, b) => {
6161
6583
  const aDepth = a.split("/").length;
6162
6584
  const bDepth = b.split("/").length;
@@ -6206,7 +6628,8 @@ var init_public_brand = __esm({
6206
6628
  packageName: "peachsim",
6207
6629
  commandName: "peach",
6208
6630
  domain: "peachsim.com",
6209
- origin: "https://peachsim.com"
6631
+ origin: "https://peachsim.com",
6632
+ boxOrigin: "https://rnx-box.contrast.dev"
6210
6633
  });
6211
6634
  rnxPublicBrand = peachPublicBrand;
6212
6635
  }
@@ -6222,14 +6645,14 @@ function sharedDesktopAuthAccounts(user) {
6222
6645
  function getBaseDir() {
6223
6646
  const explicit = process.env[SESSION_FILE_ENV];
6224
6647
  if (explicit?.trim()) {
6225
- 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));
6226
6649
  }
6227
6650
  return electronUserDataDir();
6228
6651
  }
6229
6652
  function getSharedDesktopAuthFilePath() {
6230
6653
  const explicit = process.env[SESSION_FILE_ENV];
6231
- if (explicit?.trim()) return (0, import_node_path8.resolve)(explicit);
6232
- 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");
6233
6656
  }
6234
6657
  function normalizeUser(input) {
6235
6658
  if (!input || typeof input !== "object") return null;
@@ -6279,26 +6702,26 @@ function normalizeSession(input) {
6279
6702
  }
6280
6703
  function readSharedDesktopAuthSession() {
6281
6704
  const filepath = getSharedDesktopAuthFilePath();
6282
- if (!(0, import_node_fs7.existsSync)(filepath)) return null;
6705
+ if (!(0, import_node_fs8.existsSync)(filepath)) return null;
6283
6706
  try {
6284
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)(filepath, "utf8"));
6707
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(filepath, "utf8"));
6285
6708
  const normalized = normalizeSession(parsed);
6286
6709
  if (!normalized) {
6287
- (0, import_node_fs7.rmSync)(filepath, { force: true });
6710
+ (0, import_node_fs8.rmSync)(filepath, { force: true });
6288
6711
  return null;
6289
6712
  }
6290
6713
  return normalized;
6291
6714
  } catch {
6292
- (0, import_node_fs7.rmSync)(filepath, { force: true });
6715
+ (0, import_node_fs8.rmSync)(filepath, { force: true });
6293
6716
  return null;
6294
6717
  }
6295
6718
  }
6296
- 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;
6297
6720
  var init_shared_session = __esm({
6298
6721
  "src/auth/shared-session.ts"() {
6299
6722
  "use strict";
6300
- import_node_fs7 = require("node:fs");
6301
- import_node_path8 = require("node:path");
6723
+ import_node_fs8 = require("node:fs");
6724
+ import_node_path9 = require("node:path");
6302
6725
  init_home_paths();
6303
6726
  init_public_brand();
6304
6727
  SESSION_VERSION = 1;
@@ -6685,94 +7108,6 @@ var init_ios_sdk_frameworks = __esm({
6685
7108
  }
6686
7109
  });
6687
7110
 
6688
- // src/swift-binary-modules.ts
6689
- function frameworkModules(paths) {
6690
- const modules = /* @__PURE__ */ new Set();
6691
- for (const file of paths) {
6692
- const segment2 = file.split("/").find((part) => part.endsWith(".framework"));
6693
- if (segment2) modules.add(segment2.slice(0, -".framework".length));
6694
- }
6695
- return [...modules].sort();
6696
- }
6697
- async function range(url, spec) {
6698
- const response = await fetch(url, {
6699
- headers: { range: `bytes=${spec}`, "accept-encoding": "identity" },
6700
- signal: AbortSignal.timeout(2e4)
6701
- });
6702
- const match = /^bytes (\d+)-\d+\/(\d+)$/.exec(
6703
- response.headers.get("content-range") ?? ""
6704
- );
6705
- if (response.status !== 206 || !match)
6706
- throw new Error(`${url} answered ${response.status} to a range request`);
6707
- return {
6708
- bytes: Buffer.from(await response.arrayBuffer()),
6709
- start: Number(match[1]),
6710
- total: Number(match[2])
6711
- };
6712
- }
6713
- async function zipEntries(url) {
6714
- const { total } = await range(url, "0-0");
6715
- const tail = await range(url, `${Math.max(0, total - 65558)}-${total - 1}`);
6716
- let end = tail.bytes.length - 22;
6717
- for (; end >= 0; end--)
6718
- if (tail.bytes.readUInt32LE(end) === 101010256 && end + 22 + tail.bytes.readUInt16LE(end + 20) === tail.bytes.length)
6719
- break;
6720
- if (end < 0) throw new Error(`${url} has no zip end record`);
6721
- let size = tail.bytes.readUInt32LE(end + 12);
6722
- let offset = tail.bytes.readUInt32LE(end + 16);
6723
- if (offset === 4294967295 || size === 4294967295) {
6724
- const locator = end - 20;
6725
- if (locator < 0 || tail.bytes.readUInt32LE(locator) !== 117853008)
6726
- throw new Error(`${url} has no zip64 locator`);
6727
- const recordAt = Number(tail.bytes.readBigUInt64LE(locator + 8));
6728
- const record4 = recordAt >= tail.start ? tail.bytes.subarray(recordAt - tail.start) : (await range(url, `${recordAt}-${recordAt + 55}`)).bytes;
6729
- size = Number(record4.readBigUInt64LE(40));
6730
- offset = Number(record4.readBigUInt64LE(48));
6731
- }
6732
- const directory = offset >= tail.start ? tail.bytes.subarray(offset - tail.start, offset - tail.start + size) : (await range(url, `${offset}-${offset + size - 1}`)).bytes;
6733
- const names = [];
6734
- for (let at = 0; at + 46 <= directory.length; ) {
6735
- if (directory.readUInt32LE(at) !== 33639248) break;
6736
- const nameLength = directory.readUInt16LE(at + 28);
6737
- names.push(directory.toString("utf8", at + 46, at + 46 + nameLength));
6738
- at += 46 + nameLength + directory.readUInt16LE(at + 30) + directory.readUInt16LE(at + 32);
6739
- }
6740
- return names;
6741
- }
6742
- function localEntries(dir) {
6743
- if (!import_node_fs8.default.existsSync(dir)) return [];
6744
- return import_node_fs8.default.readdirSync(dir, { withFileTypes: true }).filter((slice) => slice.isDirectory()).flatMap(
6745
- (slice) => import_node_fs8.default.readdirSync(import_node_path9.default.join(dir, slice.name)).map((entry) => `${slice.name}/${entry}`)
6746
- );
6747
- }
6748
- async function swiftBinaryModules(binary) {
6749
- if (!binary.url) return frameworkModules(localEntries(binary.dir));
6750
- const cached2 = import_node_path9.default.join(
6751
- cacheDir,
6752
- `${(0, import_node_crypto4.createHash)("sha256").update(`${binary.url}\0${binary.checksum ?? ""}`).digest("hex").slice(0, 32)}.json`
6753
- );
6754
- if (import_node_fs8.default.existsSync(cached2)) {
6755
- const value = JSON.parse(import_node_fs8.default.readFileSync(cached2, "utf8"));
6756
- if (Array.isArray(value) && value.every((name2) => typeof name2 === "string"))
6757
- return value;
6758
- }
6759
- const modules = frameworkModules(await zipEntries(binary.url));
6760
- import_node_fs8.default.mkdirSync(cacheDir, { recursive: true });
6761
- import_node_fs8.default.writeFileSync(cached2, JSON.stringify(modules));
6762
- return modules;
6763
- }
6764
- var import_node_crypto4, import_node_fs8, import_node_os6, import_node_path9, cacheDir;
6765
- var init_swift_binary_modules = __esm({
6766
- "src/swift-binary-modules.ts"() {
6767
- "use strict";
6768
- import_node_crypto4 = require("node:crypto");
6769
- import_node_fs8 = __toESM(require("node:fs"), 1);
6770
- import_node_os6 = __toESM(require("node:os"), 1);
6771
- import_node_path9 = __toESM(require("node:path"), 1);
6772
- cacheDir = import_node_path9.default.join(import_node_os6.default.tmpdir(), "peach-swift-binary-modules");
6773
- }
6774
- });
6775
-
6776
7111
  // src/swift-package-manifest.ts
6777
7112
  function swiftCommand() {
6778
7113
  return process.platform === "darwin" ? { file: "xcrun", args: ["swift"] } : { file: import_node_path10.default.join(swiftToolchainBin(swift_distribution_lock_default.release), "swift"), args: [] };
@@ -6788,7 +7123,7 @@ function dump(dir) {
6788
7123
  return { key: key2, raw: record3(JSON.parse(import_node_fs9.default.readFileSync(cached2, "utf8"))) };
6789
7124
  let output;
6790
7125
  try {
6791
- output = (0, import_node_child_process6.execFileSync)(
7126
+ output = (0, import_node_child_process7.execFileSync)(
6792
7127
  command.file,
6793
7128
  [
6794
7129
  ...command.args,
@@ -6975,11 +7310,11 @@ function swiftTargetFiles(manifest, target) {
6975
7310
  ];
6976
7311
  return included.flatMap(walk).filter((file) => !within(file, excluded)).sort();
6977
7312
  }
6978
- 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;
6979
7314
  var init_swift_package_manifest = __esm({
6980
7315
  "src/swift-package-manifest.ts"() {
6981
7316
  "use strict";
6982
- import_node_child_process6 = require("node:child_process");
7317
+ import_node_child_process7 = require("node:child_process");
6983
7318
  import_node_crypto5 = require("node:crypto");
6984
7319
  import_node_fs9 = __toESM(require("node:fs"), 1);
6985
7320
  import_node_os7 = __toESM(require("node:os"), 1);
@@ -7025,7 +7360,7 @@ function checkout(checkouts, identity, pin) {
7025
7360
  const dir = import_node_path11.default.join(checkouts, identity);
7026
7361
  const key2 = `${dir}\0${pin.revision}`;
7027
7362
  if (verified2.has(key2)) return dir;
7028
- 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], {
7029
7364
  encoding: "utf8",
7030
7365
  stdio: ["ignore", "pipe", "pipe"]
7031
7366
  }).trim();
@@ -7227,11 +7562,11 @@ function resolveSwiftPackages(options) {
7227
7562
  result.targets = [...targets.entries()].filter(([key2]) => reached.has(key2)).map(([, target]) => target);
7228
7563
  return result;
7229
7564
  }
7230
- 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;
7231
7566
  var init_swift_packages = __esm({
7232
7567
  "src/swift-packages.ts"() {
7233
7568
  "use strict";
7234
- import_node_child_process7 = require("node:child_process");
7569
+ import_node_child_process8 = require("node:child_process");
7235
7570
  import_node_fs10 = __toESM(require("node:fs"), 1);
7236
7571
  import_node_path11 = __toESM(require("node:path"), 1);
7237
7572
  init_swift_package();
@@ -8417,6 +8752,17 @@ function objcView(surface, toolchainBin, stdlib, cacheDir4, work) {
8417
8752
  const slash = include2.indexOf("/");
8418
8753
  if (slash > 0 && /^[A-Z]/.test(include2)) {
8419
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
+ }
8420
8766
  const root = import_node_path13.default.join(stubs, `${name2}.framework`);
8421
8767
  const header = import_node_path13.default.join(root, "Headers", include2.slice(slash + 1));
8422
8768
  import_node_fs13.default.mkdirSync(import_node_path13.default.dirname(header), { recursive: true });
@@ -8464,7 +8810,7 @@ function objcView(surface, toolchainBin, stdlib, cacheDir4, work) {
8464
8810
  for (let round = 0; ; round++) {
8465
8811
  import_node_fs13.default.rmSync(out, { recursive: true, force: true });
8466
8812
  import_node_fs13.default.mkdirSync(out, { recursive: true });
8467
- const run5 = (0, import_node_child_process8.spawnSync)(
8813
+ const run5 = (0, import_node_child_process9.spawnSync)(
8468
8814
  import_node_path13.default.join(toolchainBin, "swift-symbolgraph-extract"),
8469
8815
  [
8470
8816
  "-module-name",
@@ -8571,7 +8917,7 @@ function enumValues(graphs, surface, framework, toolchainBin, search, work) {
8571
8917
  if (flag === "-sdk") flags.push("-isysroot", dir);
8572
8918
  else flags.push(flag, dir);
8573
8919
  }
8574
- const run5 = (0, import_node_child_process8.spawnSync)(
8920
+ const run5 = (0, import_node_child_process9.spawnSync)(
8575
8921
  import_node_path13.default.join(toolchainBin, "clang"),
8576
8922
  [
8577
8923
  "-x",
@@ -8640,11 +8986,11 @@ function constantValue(node) {
8640
8986
  }
8641
8987
  return null;
8642
8988
  }
8643
- 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;
8644
8990
  var init_swift_objc_standin = __esm({
8645
8991
  "src/swift-objc-standin.ts"() {
8646
8992
  "use strict";
8647
- import_node_child_process8 = require("node:child_process");
8993
+ import_node_child_process9 = require("node:child_process");
8648
8994
  import_node_crypto6 = require("node:crypto");
8649
8995
  import_node_fs13 = __toESM(require("node:fs"), 1);
8650
8996
  import_node_path13 = __toESM(require("node:path"), 1);
@@ -8804,10 +9150,10 @@ function emitSwiftStandin(graphs, options) {
8804
9150
  owners.push(...physical.map(() => current));
8805
9151
  };
8806
9152
  const scoped = (body) => (symbol, ...rest) => {
8807
- const path20 = pathOf(symbol);
8808
- 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) });
8809
9155
  const previous = current;
8810
- current = path20;
9156
+ current = path21;
8811
9157
  try {
8812
9158
  body(symbol, ...rest);
8813
9159
  } finally {
@@ -8827,14 +9173,14 @@ function emitSwiftStandin(graphs, options) {
8827
9173
  const access = (symbol, openOwner) => symbol.accessLevel === "open" && openOwner ? "open" : "public";
8828
9174
  const emitMember = scoped(
8829
9175
  (member, indent, context) => {
8830
- const path20 = pathOf(member);
9176
+ const path21 = pathOf(member);
8831
9177
  if (TYPE_KINDS.has(member.kind.identifier)) {
8832
9178
  emitType(member, indent);
8833
9179
  return;
8834
9180
  }
8835
9181
  if (member.kind.identifier === "swift.enum.case") return;
8836
9182
  if (!MEMBER_KINDS.has(member.kind.identifier)) {
8837
- skipped.push({ path: path20, reason: `unhandled ${member.kind.identifier}` });
9183
+ skipped.push({ path: path21, reason: `unhandled ${member.kind.identifier}` });
8838
9184
  return;
8839
9185
  }
8840
9186
  const { 1: attrs, 2: rest } = LEADING_ATTRS.exec(text2(member));
@@ -8848,12 +9194,12 @@ function emitSwiftStandin(graphs, options) {
8848
9194
  const final = context.inClass && flags.has("final") ? "final " : "";
8849
9195
  const mutating = flags.has("mutating") ? "mutating " : flags.has("nonmutating") ? "nonmutating " : "";
8850
9196
  let core = `${flags.has("convenience") ? "convenience " : ""}${modifiers[2]}`;
8851
- 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 " : "";
8852
9198
  const head = `${indent}${attrs}${access(member, context.openOwner)} ${required ? "required " : ""}${final}${override}${mutating}`;
8853
- const measured = behavior.get(path20);
8854
- if (measured) used.add(path20);
9199
+ const measured = behavior.get(path21);
9200
+ if (measured) used.add(path21);
8855
9201
  const overloadBody = /\basync\b/.test(core) ? measured?.asyncBody : /\bResult</.test(core) ? measured?.resultBody : void 0;
8856
- const body = overloadBody ?? measured?.body ?? trap(path20);
9202
+ const body = overloadBody ?? measured?.body ?? trap(path21);
8857
9203
  switch (member.kind.identifier) {
8858
9204
  case "swift.property":
8859
9205
  case "swift.type.property":
@@ -8874,7 +9220,7 @@ function emitSwiftStandin(graphs, options) {
8874
9220
  return;
8875
9221
  }
8876
9222
  emit(
8877
- `${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)} }` : ""} }`
8878
9224
  );
8879
9225
  return;
8880
9226
  }
@@ -8927,7 +9273,7 @@ function emitSwiftStandin(graphs, options) {
8927
9273
  };
8928
9274
  const emitType = scoped(
8929
9275
  (symbol, indent) => {
8930
- const path20 = pathOf(symbol);
9276
+ const path21 = pathOf(symbol);
8931
9277
  const id = symbol.identifier.precise;
8932
9278
  const inner = `${indent} `;
8933
9279
  switch (symbol.kind.identifier) {
@@ -8939,10 +9285,10 @@ function emitSwiftStandin(graphs, options) {
8939
9285
  case "swift.class": {
8940
9286
  const shape = header(symbol, "class", indent);
8941
9287
  if (!shape)
8942
- return void skipped.push({ path: path20, reason: `unparsed class ${text2(symbol)}` });
8943
- 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);
8944
9290
  const blocked = classBlocked(id);
8945
- if (blocked) return void skipped.push({ path: path20, reason: blocked });
9291
+ if (blocked) return void skipped.push({ path: path21, reason: blocked });
8946
9292
  const ancestors = /* @__PURE__ */ new Set();
8947
9293
  for (let at = superId.get(id); at; at = superId.get(at))
8948
9294
  for (const name2 of conforms.get(at) ?? []) ancestors.add(name2);
@@ -8958,9 +9304,9 @@ function emitSwiftStandin(graphs, options) {
8958
9304
  `${indent}${shape.attrs}${open ? "open" : "public"} class ${shape.name}${shape.generics}${list2.length ? `: ${list2.join(", ")}` : ""}${selfConforming(shape.where)} {`
8959
9305
  );
8960
9306
  const members = membersOf(id);
8961
- const extra = options.behavior?.get(path20)?.members;
9307
+ const extra = options.behavior?.get(path21)?.members;
8962
9308
  if (extra) {
8963
- used.add(path20);
9309
+ used.add(path21);
8964
9310
  emit(`${inner}${extra}`);
8965
9311
  }
8966
9312
  for (const member of members)
@@ -9012,13 +9358,13 @@ function emitSwiftStandin(graphs, options) {
9012
9358
  continue;
9013
9359
  have.add(witnessKey(member));
9014
9360
  have.add(sideLeaf(member));
9015
- emitWitness(member, inner, path20);
9361
+ emitWitness(member, inner, path21);
9016
9362
  }
9017
9363
  }
9018
9364
  const coder = members.some((member) => leaf(member) === "init(coder:)");
9019
9365
  if (designated && !coder && externalRoot(id) !== "NSObject" && externalRoot(id) !== null)
9020
9366
  emit(
9021
- `${inner}public required init?(coder: NSCoder) { ${trap(`${path20}.init(coder:)`)} }`
9367
+ `${inner}public required init?(coder: NSCoder) { ${trap(`${path21}.init(coder:)`)} }`
9022
9368
  );
9023
9369
  emit(`${indent}}`);
9024
9370
  return;
@@ -9026,7 +9372,7 @@ function emitSwiftStandin(graphs, options) {
9026
9372
  case "swift.struct": {
9027
9373
  const shape = header(symbol, "struct", indent);
9028
9374
  if (!shape)
9029
- return void skipped.push({ path: path20, reason: `unparsed struct ${text2(symbol)}` });
9375
+ return void skipped.push({ path: path21, reason: `unparsed struct ${text2(symbol)}` });
9030
9376
  const members = membersOf(id);
9031
9377
  const raw2 = rawType(members);
9032
9378
  const list2 = inheritance(id);
@@ -9058,7 +9404,7 @@ function emitSwiftStandin(graphs, options) {
9058
9404
  case "swift.enum": {
9059
9405
  const shape = header(symbol, "enum", indent);
9060
9406
  if (!shape)
9061
- return void skipped.push({ path: path20, reason: `unparsed enum ${text2(symbol)}` });
9407
+ return void skipped.push({ path: path21, reason: `unparsed enum ${text2(symbol)}` });
9062
9408
  const members = membersOf(id);
9063
9409
  const raw2 = rawType(members);
9064
9410
  const cases = members.filter(
@@ -9067,7 +9413,7 @@ function emitSwiftStandin(graphs, options) {
9067
9413
  const missing = raw2 ? cases.filter((member) => !values.has(member.identifier.precise)) : [];
9068
9414
  if (raw2 && isObjC(symbol) && missing.length > 0)
9069
9415
  return void skipped.push({
9070
- path: path20,
9416
+ path: path21,
9071
9417
  reason: `no header value for ${missing.map(leaf).join(", ")}`
9072
9418
  });
9073
9419
  const list2 = inheritance(id, raw2 ?? void 0).filter(
@@ -9107,7 +9453,7 @@ function emitSwiftStandin(graphs, options) {
9107
9453
  const shape = header(symbol, "protocol", indent);
9108
9454
  if (!shape)
9109
9455
  return void skipped.push({
9110
- path: path20,
9456
+ path: path21,
9111
9457
  reason: `unparsed protocol ${text2(symbol)}`
9112
9458
  });
9113
9459
  const list2 = [...isObjC(symbol) ? ["AnyObject"] : [], ...inheritance(id)];
@@ -9132,7 +9478,7 @@ function emitSwiftStandin(graphs, options) {
9132
9478
  }
9133
9479
  emit(`${indent}}`);
9134
9480
  if (defaults.length > 0) {
9135
- emit(`${indent}extension ${path20} {`);
9481
+ emit(`${indent}extension ${path21} {`);
9136
9482
  for (const member of defaults) {
9137
9483
  const decl = text2(member);
9138
9484
  if (optional.has(member.identifier.precise) && member.kind.identifier === "swift.method" && !decl.replace(/\([^)]*\)/g, "").includes("->") && !/ async\b/.test(decl))
@@ -9178,7 +9524,7 @@ function emitSwiftStandin(graphs, options) {
9178
9524
  return init ? /rawValue:\s*([^)]+)\)/.exec(text2(init))?.[1]?.trim() ?? null : null;
9179
9525
  };
9180
9526
  const emitGlobal = scoped((symbol) => {
9181
- const path20 = pathOf(symbol);
9527
+ const path21 = pathOf(symbol);
9182
9528
  const kind = symbol.kind.identifier;
9183
9529
  if (kind === "swift.func" || kind === "swift.func.op" || kind === "swift.method" || kind === "swift.type.method") {
9184
9530
  const { 1: attrs, 2: rest } = LEADING_ATTRS.exec(text2(symbol));
@@ -9189,22 +9535,22 @@ function emitSwiftStandin(graphs, options) {
9189
9535
  if (fix && !/^(?:prefix|infix|postfix)\b/.test(spelled))
9190
9536
  spelled = `${fix} ${spelled}`;
9191
9537
  }
9192
- const measured = behavior.get(path20);
9193
- if (measured) used.add(path20);
9538
+ const measured = behavior.get(path21);
9539
+ if (measured) used.add(path21);
9194
9540
  const overloadBody = /\basync\b/.test(spelled) ? measured?.asyncBody : /\bResult</.test(spelled) ? measured?.resultBody : void 0;
9195
9541
  emit(
9196
- `${attrs}public ${spelled} { ${overloadBody ?? measured?.body ?? trap(path20)} }`
9542
+ `${attrs}public ${spelled} { ${overloadBody ?? measured?.body ?? trap(path21)} }`
9197
9543
  );
9198
9544
  } else if (kind === "swift.var") {
9199
9545
  const parsed = splitAccessors(text2(symbol).replace(/^let /, "var "));
9200
- const measured = behavior.get(path20);
9201
- if (measured) used.add(path20);
9202
- emit(`public ${parsed.decl} { ${measured?.body ?? trap(path20)} }`);
9203
- } 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}` });
9204
9550
  });
9205
9551
  const roots = [...byId.values()].filter((symbol) => !owner.has(symbol.identifier.precise) && !unavailable(symbol)).sort((a, b) => pathOf(a).localeCompare(pathOf(b)));
9206
9552
  for (const symbol of roots) {
9207
- const path20 = pathOf(symbol);
9553
+ const path21 = pathOf(symbol);
9208
9554
  if (TYPE_KINDS.has(symbol.kind.identifier)) emitType(symbol, "");
9209
9555
  else emitGlobal(symbol);
9210
9556
  }
@@ -9245,9 +9591,9 @@ function emitSwiftStandin(graphs, options) {
9245
9591
  ...imports.map((name2) => `import ${name2}`),
9246
9592
  ""
9247
9593
  ];
9248
- for (const path20 of behavior.keys())
9249
- if (!used.has(path20))
9250
- 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" });
9251
9597
  return {
9252
9598
  source: `${[...banner, ...lines].join("\n")}
9253
9599
  `,
@@ -9287,7 +9633,7 @@ var STANDIN_EMIT_VERSION, STANDIN_IMPORTS, TYPE_KINDS, MEMBER_KINDS, ACCESSOR_WO
9287
9633
  var init_swift_standin_emit = __esm({
9288
9634
  "src/swift-standin-emit.ts"() {
9289
9635
  "use strict";
9290
- STANDIN_EMIT_VERSION = "6";
9636
+ STANDIN_EMIT_VERSION = "7";
9291
9637
  STANDIN_IMPORTS = ["Foundation", "UIKit"];
9292
9638
  TYPE_KINDS = /* @__PURE__ */ new Set([
9293
9639
  "swift.class",
@@ -9334,7 +9680,7 @@ var init_swift_standin_emit = __esm({
9334
9680
  sideLeaf = (symbol) => `${symbol.kind.identifier.startsWith("swift.type.") ? "type" : "instance"}|leaf|${leaf(symbol)}`;
9335
9681
  isObjC = (symbol) => symbol.identifier.precise.startsWith("c:");
9336
9682
  synthesizedEquality = (symbol, conforms) => conforms.includes("Hashable") ? ["==(_:_:)", "hash(into:)", "hashValue"].includes(leaf(symbol)) : conforms.includes("Equatable") && leaf(symbol) === "==(_:_:)";
9337
- trap = (path20) => `fatalError("${path20} is a binary framework peach cannot run")`;
9683
+ trap = (path21) => `fatalError("${path21} is a binary framework peach cannot run")`;
9338
9684
  KEYWORDS = /* @__PURE__ */ new Set([
9339
9685
  "Type",
9340
9686
  "Protocol",
@@ -9376,7 +9722,7 @@ var init_swift_standin_emit = __esm({
9376
9722
 
9377
9723
  // src/swift-standins.ts
9378
9724
  function exec(file, args, cwd) {
9379
- return (0, import_node_child_process9.execFileSync)(file, args, {
9725
+ return (0, import_node_child_process10.execFileSync)(file, args, {
9380
9726
  cwd,
9381
9727
  encoding: "utf8",
9382
9728
  maxBuffer: 256 * 1024 * 1024,
@@ -9692,7 +10038,7 @@ function graphStandin(module2, graphs, values, wasm, binary, toolchain, work, be
9692
10038
  );
9693
10039
  }
9694
10040
  import_node_fs14.default.writeFileSync(file, source);
9695
- const check = (0, import_node_child_process9.spawnSync)(
10041
+ const check = (0, import_node_child_process10.spawnSync)(
9696
10042
  import_node_path14.default.join(toolchain.toolchainBin, "swiftc"),
9697
10043
  [
9698
10044
  "-typecheck",
@@ -10014,7 +10360,7 @@ function standinLibrary(binary, searchRoot) {
10014
10360
  if (!library) return null;
10015
10361
  const manifest = crateFor(searchRoot, library.slice("lib".length, -".a".length));
10016
10362
  if (!manifest) return null;
10017
- const result = (0, import_node_child_process9.spawnSync)(
10363
+ const result = (0, import_node_child_process10.spawnSync)(
10018
10364
  "cargo",
10019
10365
  [
10020
10366
  "build",
@@ -10076,7 +10422,7 @@ function sourceBinaryStandins(binary, toolchain, provided, behavior) {
10076
10422
  release: toolchain.release
10077
10423
  })
10078
10424
  );
10079
- (0, import_node_child_process9.execFileSync)(
10425
+ const build = (0, import_node_child_process10.spawnSync)(
10080
10426
  "bun",
10081
10427
  [
10082
10428
  import_node_path14.default.join(repo, "scripts/build/swift-standins-submit.ts"),
@@ -10087,11 +10433,20 @@ function sourceBinaryStandins(binary, toolchain, provided, behavior) {
10087
10433
  "--delivery-dir",
10088
10434
  delivery
10089
10435
  ],
10090
- { cwd: repo, stdio: "inherit" }
10091
- );
10092
- const receipt = JSON.parse(
10093
- import_node_fs14.default.readFileSync(import_node_path14.default.join(delivery, "standins.json"), "utf8")
10436
+ { cwd: repo, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }
10094
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"));
10095
10450
  if (!receipt || typeof receipt !== "object" || !("generation" in receipt) || receipt.generation !== generation || !("result" in receipt))
10096
10451
  throw new Error("Swift stand-in builder source differs from the caller");
10097
10452
  const result = receipt.result;
@@ -10204,7 +10559,7 @@ function binaryStandins(binary, toolchain, provided, behavior) {
10204
10559
  const work = import_node_fs14.default.mkdtempSync(import_node_path14.default.join(import_node_os8.default.tmpdir(), "peach-standin-"));
10205
10560
  let result;
10206
10561
  try {
10207
- 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) => {
10208
10563
  const dir = import_node_path14.default.join(work, surface.module);
10209
10564
  try {
10210
10565
  if (surface.kind === "c" && configured.has(surface.module))
@@ -10257,11 +10612,11 @@ function swiftStandins(binaries, toolchain, provided = /* @__PURE__ */ new Set()
10257
10612
  }
10258
10613
  return { standins, gaps };
10259
10614
  }
10260
- 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;
10261
10616
  var init_swift_standins = __esm({
10262
10617
  "src/swift-standins.ts"() {
10263
10618
  "use strict";
10264
- import_node_child_process9 = require("node:child_process");
10619
+ import_node_child_process10 = require("node:child_process");
10265
10620
  import_node_crypto7 = require("node:crypto");
10266
10621
  import_node_fs14 = __toESM(require("node:fs"), 1);
10267
10622
  import_node_os8 = __toESM(require("node:os"), 1);
@@ -10273,6 +10628,7 @@ var init_swift_standins = __esm({
10273
10628
  init_swift_standin_emit();
10274
10629
  TRIPLE = "wasm32-unknown-wasip1";
10275
10630
  cacheDir3 = import_node_path14.default.join(import_node_os8.default.homedir(), "builders/cache/peach-swift-standins");
10631
+ SWIFT_STANDINS_DIR = "__standins__";
10276
10632
  key = (...parts) => (0, import_node_crypto7.createHash)("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
10277
10633
  digests = /* @__PURE__ */ new Map();
10278
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() : [];
@@ -12286,20 +12642,20 @@ function targetSettings(ref, configuration, builtins, options = {}) {
12286
12642
  ...level(str(project.project.buildConfigurationList)),
12287
12643
  ...level(str(target.buildConfigurationList))
12288
12644
  ];
12289
- const resolving = /* @__PURE__ */ new Set();
12645
+ const resolving2 = /* @__PURE__ */ new Set();
12290
12646
  const valueAt = (key2, top) => {
12291
12647
  let at = top;
12292
12648
  while (at >= 0 && levels[at][key2] === void 0) at--;
12293
12649
  if (at < 0) return derived(key2);
12294
12650
  const marker = `${key2}@${at}`;
12295
- if (resolving.has(marker))
12651
+ if (resolving2.has(marker))
12296
12652
  throw new Error(`${str(target.name)} has a cyclic build setting ${key2}`);
12297
- resolving.add(marker);
12653
+ resolving2.add(marker);
12298
12654
  const value = expand(
12299
12655
  levels[at][key2],
12300
12656
  (name2) => name2 === "inherited" ? valueAt(key2, at - 1) : valueAt(name2, levels.length - 1)
12301
12657
  );
12302
- resolving.delete(marker);
12658
+ resolving2.delete(marker);
12303
12659
  return value;
12304
12660
  };
12305
12661
  const derived = (key2) => {
@@ -12610,6 +12966,16 @@ function readXcodeAppTarget(input, targetName, configurationName, options = {})
12610
12966
  const value = settings(key2);
12611
12967
  info[key2.slice("INFOPLIST_KEY_".length)] = value === "YES" ? true : value === "NO" ? false : value;
12612
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
+ }
12613
12979
  if (settings("INFOPLIST_KEY_UIApplicationSceneManifest_Generation") === "YES" && info.UIApplicationSceneManifest === void 0) {
12614
12980
  info.UIApplicationSceneManifest = {
12615
12981
  UIApplicationSupportsMultipleScenes: true,
@@ -12915,7 +13281,7 @@ function xcodeLayout(root) {
12915
13281
  for (const standin of standins)
12916
13282
  targets.push({
12917
13283
  name: standin.module,
12918
- 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),
12919
13285
  executable: false,
12920
13286
  resources: false,
12921
13287
  exclude: [],
@@ -13230,6 +13596,8 @@ function sourceStamp(packagePath, moduleRootOverride, hosted = false) {
13230
13596
  const hash = (0, import_node_crypto8.createHash)("sha256");
13231
13597
  hash.update(packagePath);
13232
13598
  hash.update(JSON.stringify(xcodeProjects.get(packagePath)?.behavior ?? {}));
13599
+ const libraries = projects.get(packagePath)?.libraries;
13600
+ if (libraries) hash.update(JSON.stringify(libraries));
13233
13601
  const projectInputs = new Set(packageFiles(packagePath));
13234
13602
  for (const file of [...projectInputs].sort()) {
13235
13603
  hash.update(import_node_path17.default.relative(packagePath, file));
@@ -13259,14 +13627,14 @@ function otherInputs(input) {
13259
13627
  function icuUrl(origin, artifact) {
13260
13628
  return "url" in artifact.icu ? artifact.icu.url : `${origin}${ICU_PATH}${artifact.icu.sha256}`;
13261
13629
  }
13262
- function standinLibraries(layout) {
13630
+ function standinLibraries(binaries, standins, rootDir) {
13263
13631
  const linked = /* @__PURE__ */ new Map();
13264
- for (const binary of layout.binaries) {
13265
- const modules = layout.standins.filter(
13632
+ for (const binary of binaries) {
13633
+ const modules = standins.filter(
13266
13634
  (standin) => standin.target === binary.target && `${standin.module}.c` in standin.files
13267
13635
  );
13268
13636
  if (modules.length === 0) continue;
13269
- const library = standinLibrary(binary, layout.app.rootDir);
13637
+ const library = standinLibrary(binary, rootDir);
13270
13638
  if (!library) continue;
13271
13639
  linked.set(library, modules);
13272
13640
  }
@@ -13293,14 +13661,14 @@ function packageSources(packagePath, linked = /* @__PURE__ */ new Set()) {
13293
13661
  files2["Package.swift"] = xcodeManifest(xcode);
13294
13662
  for (const standin of xcode.standins)
13295
13663
  for (const [file, text4] of Object.entries(standin.files))
13296
- 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.
13297
13665
  ` : text4;
13298
13666
  }
13299
13667
  return files2;
13300
13668
  }
13301
13669
  function packageSnapshot(project, entry) {
13302
13670
  const layout = xcodeLayout(project.packagePath);
13303
- const linked = layout ? standinLibraries(layout) : /* @__PURE__ */ new Map();
13671
+ const linked = layout ? standinLibraries(layout.binaries, layout.standins, layout.app.rootDir) : /* @__PURE__ */ new Map();
13304
13672
  const files2 = packageSources(project.packagePath, new Set([...linked.values()].flat()));
13305
13673
  const native = nativeSourceDescriptor(project.packagePath);
13306
13674
  return {
@@ -13319,13 +13687,16 @@ function packageSnapshot(project, entry) {
13319
13687
  files2
13320
13688
  ),
13321
13689
  native,
13322
- ...linked.size > 0 ? {
13323
- libraries: Object.fromEntries(
13324
- [...linked].map(([library, [first]]) => [
13325
- first.module,
13326
- import_node_fs16.default.readFileSync(library).toString("base64")
13327
- ])
13328
- )
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
+ }
13329
13700
  } : {},
13330
13701
  ...native ? {
13331
13702
  glue: readPackageFile(
@@ -13371,7 +13742,7 @@ async function compile(packagePath, stamp, moduleRootOverride, hosted, snapshot,
13371
13742
  };
13372
13743
  const moduleRoot = moduleRootOverride ?? linkedModuleRoots(packagePath).find(
13373
13744
  (root) => import_node_fs16.default.existsSync(import_node_path17.default.join(root, "toolchain.json"))
13374
- ) ?? await swiftDistributionRoot();
13745
+ ) ?? await swiftDistributionRoot(signal);
13375
13746
  if (!moduleRoot)
13376
13747
  return {
13377
13748
  ...await compileRemote(packagePath, snapshot, void 0, signal),
@@ -13591,19 +13962,30 @@ async function compileRemote(packagePath, snapshot, hosted, ownerSignal) {
13591
13962
  icu: { url: address.icuUrl }
13592
13963
  };
13593
13964
  }
13594
- function artifactFor(project, entry, moduleRoot) {
13595
- 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();
13596
13969
  const stamp = sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted));
13597
13970
  if (project.artifact?.stamp === stamp) return Promise.resolve(project.artifact);
13598
13971
  if (project.building) {
13599
13972
  const running = project.building;
13600
- if (running.stamp === stamp) return running.promise;
13601
- const again = () => artifactFor(project, entry, moduleRoot);
13602
- 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
+ });
13603
13985
  }
13604
13986
  const snapshot = packageSnapshot(project, entry);
13605
13987
  if (sourceStamp(project.packagePath, moduleRoot, Boolean(project.hosted)) !== stamp) {
13606
- return artifactFor(project, entry, moduleRoot);
13988
+ return artifactFor(project, entry, moduleRoot, signal);
13607
13989
  }
13608
13990
  const compiled = project.artifact?.compiled;
13609
13991
  if (project.artifact && compiled && compiled.module === moduleStamp(project.packagePath, moduleRoot, false)) {
@@ -13620,7 +14002,7 @@ function artifactFor(project, entry, moduleRoot) {
13620
14002
  moduleRoot,
13621
14003
  project.hosted,
13622
14004
  snapshot,
13623
- project.signal
14005
+ signal
13624
14006
  ).then(
13625
14007
  (artifact) => {
13626
14008
  project.artifact = artifact;
@@ -13637,12 +14019,12 @@ function artifactFor(project, entry, moduleRoot) {
13637
14019
  }
13638
14020
  );
13639
14021
  const fresh = promise.then(
13640
- (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)
13641
14023
  );
13642
- project.building = { stamp, promise: fresh };
14024
+ project.building = { stamp, promise: fresh, signal };
13643
14025
  return fresh;
13644
14026
  }
13645
- 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;
13646
14028
  var init_swift_host = __esm({
13647
14029
  "src/swift-host.ts"() {
13648
14030
  "use strict";
@@ -13685,7 +14067,6 @@ var init_swift_host = __esm({
13685
14067
  XCODE_APP_DIR = "__app__";
13686
14068
  XCODE_FRAMEWORKS_DIR = "__frameworks__";
13687
14069
  XCODE_PACKAGES_DIR = "__packages__";
13688
- XCODE_STANDINS_DIR = "__standins__";
13689
14070
  CHECKOUTS_PREFIX = `${REMOTE_CHECKOUTS.split(import_node_path17.default.sep).join(import_node_path17.default.posix.sep)}/`;
13690
14071
  HOSTED_LIMITS = {
13691
14072
  resources: MAX_SWIFT_COMPILE_RESOURCES,
@@ -13733,7 +14114,8 @@ var init_swift_host = __esm({
13733
14114
  });
13734
14115
 
13735
14116
  // src/expo-swift-host.ts
13736
- async function collectExpoSwiftSources(appRoot) {
14117
+ async function collectExpoSwiftSources(appRoot, signal) {
14118
+ signal?.throwIfAborted();
13737
14119
  appRoot = import_node_fs17.default.realpathSync(appRoot);
13738
14120
  const appRequire = (0, import_node_module.createRequire)(import_node_path18.default.join(appRoot, "package.json"));
13739
14121
  let autolinker;
@@ -13757,7 +14139,7 @@ async function collectExpoSwiftSources(appRoot) {
13757
14139
  appRoot,
13758
14140
  "--json"
13759
14141
  ],
13760
- { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv }
14142
+ { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv, signal }
13761
14143
  )
13762
14144
  )
13763
14145
  );
@@ -13797,6 +14179,7 @@ async function collectExpoSwiftSources(appRoot) {
13797
14179
  throw new Error(`duplicate local Expo Swift module ${namespace}`);
13798
14180
  namespacesSeen.add(namespace);
13799
14181
  const files2 = {};
14182
+ const frameworks = /* @__PURE__ */ new Set();
13800
14183
  const classes = [];
13801
14184
  for (const module2 of modules) {
13802
14185
  const className = typeof module2 === "string" ? module2 : module2 && typeof module2 === "object" ? Reflect.get(module2, "class") : null;
@@ -13809,19 +14192,41 @@ async function collectExpoSwiftSources(appRoot) {
13809
14192
  });
13810
14193
  }
13811
14194
  const ios = import_node_path18.default.join(canonical, "ios");
13812
- if (import_node_fs17.default.lstatSync(ios).isSymbolicLink())
13813
- throw new Error(`Expo Swift source directory is a symlink: ${ios}`);
13814
- 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);
13815
14214
  for (const child of import_node_fs17.default.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
13816
14215
  const file = import_node_path18.default.join(dir, child.name);
13817
- if (child.isSymbolicLink())
13818
- throw new Error(`Expo Swift source is a symlink: ${file}`);
13819
- if (child.isDirectory()) {
13820
- 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);
13821
14223
  continue;
13822
14224
  }
13823
- if (!child.name.endsWith(".swift")) continue;
13824
- 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;
13825
14230
  bytes += size;
13826
14231
  fileCount++;
13827
14232
  if (fileCount > MAX_SWIFT_COMPILE_FILES - 2 || bytes > MAX_SWIFT_COMPILE_SOURCE_BYTES)
@@ -13830,7 +14235,7 @@ async function collectExpoSwiftSources(appRoot) {
13830
14235
  // through the underlying module; these source units have no clang pod.
13831
14236
  `import UIKit
13832
14237
  #sourceLocation(file: ${JSON.stringify(file)}, line: 1)
13833
- ${import_node_fs17.default.readFileSync(file, "utf8")}`;
14238
+ ${import_node_fs17.default.readFileSync(source, "utf8")}`;
13834
14239
  }
13835
14240
  };
13836
14241
  walk2(ios);
@@ -13839,7 +14244,8 @@ ${import_node_fs17.default.readFileSync(file, "utf8")}`;
13839
14244
  namespace,
13840
14245
  moduleId: `${namespace}.${module2.name}`,
13841
14246
  classes: [module2.registration],
13842
- files: swiftSourceClosure(files2, [module2.name])
14247
+ files: swiftSourceClosure(files2, [module2.name]),
14248
+ frameworks: [...frameworks]
13843
14249
  };
13844
14250
  unit.files[EXPO_SWIFT_ENTRY] = expoEntry([unit]);
13845
14251
  units.push(unit);
@@ -13875,17 +14281,36 @@ ${import_node_fs17.default.readFileSync(file, "utf8")}`;
13875
14281
  if (namespace === unit.namespace) continue;
13876
14282
  const dependency = byNamespace.get(namespace);
13877
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
+ ];
13878
14290
  for (const [name2, source] of Object.entries(allFiles)) {
13879
14291
  if (name2.startsWith(`Sources/${namespace}/`)) unit.files[name2] = source;
13880
14292
  }
13881
14293
  }
13882
- unit.files["Package.swift"] = `// swift-tools-version: 6.0
13883
- import PackageDescription
13884
- 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")])
13885
- `;
14294
+ unit.files["Package.swift"] = expoManifest(unit.files);
13886
14295
  }
13887
14296
  return units;
13888
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
+ }
13889
14314
  function expoEntry(units) {
13890
14315
  return `import SwiftUI
13891
14316
  import ExpoModulesCore
@@ -13915,152 +14340,312 @@ function readFailedCompilation(packagePath) {
13915
14340
  }
13916
14341
  if (typeof record4 !== "object" || record4 === null || !("stamp" in record4) || !("diagnostic" in record4) || typeof record4.stamp !== "string" || typeof record4.diagnostic !== "string")
13917
14342
  return null;
14343
+ if ("retryAt" in record4 && (typeof record4.retryAt !== "number" || !Number.isFinite(record4.retryAt) || record4.retryAt <= Date.now()))
14344
+ return null;
13918
14345
  return { stamp: record4.stamp, diagnostic: record4.diagnostic };
13919
14346
  }
13920
- async function compileExpoSwiftModules(root, base, publishArtifact) {
13921
- const units = await collectExpoSwiftSources(root);
13922
- if (!units) return null;
13923
- const module2 = await resolveSwiftModule();
13924
- if (!module2 && publishArtifact)
13925
- throw new Error("No local Swift toolchain or distribution is available");
13926
- const result = {
13927
- namespaces: units.map((unit) => unit.moduleId),
13928
- modules: [],
13929
- failures: []
13930
- };
13931
- if (!module2) {
13932
- for (const unit of units)
13933
- result.failures.push({
13934
- namespace: unit.moduleId,
13935
- diagnostic: "No local Swift toolchain or distribution is available"
13936
- });
13937
- return result;
13938
- }
13939
- const key2 = (0, import_node_crypto9.createHash)("sha256").update(import_node_fs17.default.realpathSync(root)).digest("hex");
13940
- const failures = /* @__PURE__ */ new Map();
13941
- const candidates = [];
13942
- const stamps = /* @__PURE__ */ new Map();
13943
- for (const unit of units) {
13944
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
13945
- syncSwiftTree(
13946
- packagePath,
13947
- new Map(
13948
- Object.entries(unit.files).map(([name2, source]) => [
13949
- import_node_path18.default.join(packagePath, name2),
13950
- source
13951
- ])
13952
- )
13953
- );
13954
- const stamp = sourceStamp(packagePath, module2.root);
13955
- const failed = readFailedCompilation(packagePath);
13956
- if (failed?.stamp === stamp) {
13957
- failures.set(unit.moduleId, failed.diagnostic);
13958
- continue;
13959
- }
13960
- import_node_fs17.default.rmSync(failureRecordPath(packagePath), { force: true });
13961
- stamps.set(unit, stamp);
13962
- candidates.push(unit);
13963
- }
13964
- const link = async (linked2) => {
13965
- const files2 = Object.assign(
13966
- {},
13967
- ...linked2.map((unit) => unit.files)
13968
- );
13969
- files2[EXPO_SWIFT_ENTRY] = expoEntry(linked2);
13970
- const targets = [
13971
- ...new Set(
13972
- Object.keys(files2).flatMap((name2) => {
13973
- const match = /^Sources\/([^/]+)\//.exec(name2);
13974
- return match && match[1] !== "PeachExpoApp" ? [match[1]] : [];
13975
- })
13976
- )
13977
- ];
13978
- files2["Package.swift"] = `// swift-tools-version: 6.0
13979
- import PackageDescription
13980
- 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")])
13981
- `;
13982
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, "linked-app");
13983
- syncSwiftTree(
13984
- packagePath,
13985
- new Map(
13986
- Object.entries(files2).map(([name2, source]) => [
13987
- import_node_path18.default.join(packagePath, name2),
13988
- source
13989
- ])
13990
- )
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(", ")}`
13991
14367
  );
13992
- return artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
13993
- };
13994
- let linked = candidates;
13995
- let artifact;
13996
- if (linked.length) {
13997
- try {
13998
- artifact = await link(linked);
13999
- } catch (linkError) {
14000
- linked = [];
14001
- for (const unit of candidates) {
14002
- const packagePath = import_node_path18.default.join(import_node_os10.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
14003
- try {
14004
- await artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
14005
- linked.push(unit);
14006
- } catch (error) {
14007
- const diagnostic = error instanceof Error ? error.message : String(error);
14008
- const appPaths = Object.values(unit.files).flatMap((source) => {
14009
- const match = /^#sourceLocation\(file: (".*"), line: 1\)$/m.exec(source);
14010
- if (!match) return [];
14011
- const file = JSON.parse(match[1]);
14012
- return typeof file === "string" ? [file] : [];
14013
- });
14014
- const errors = diagnostic.match(/^.+:\d+(?::\d+)?: error:.*$/gm) ?? [];
14015
- const sourceErrors = errors.filter(
14016
- (line) => appPaths.some((file) => line.startsWith(`${file}:`)) && !/external macro implementation type|failed to load library plugin/.test(
14017
- line
14018
- )
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}`)
14019
14458
  );
14020
- if (publishArtifact && (sourceErrors.length === 0 || sourceErrors.length !== errors.length) && !(error instanceof SwiftMissingModulesError))
14021
- throw error;
14022
- const missing = error instanceof SwiftMissingModulesError;
14023
- if ((sourceErrors.length && sourceErrors.length === errors.length || missing) && sourceStamp(packagePath, module2.root) === stamps.get(unit)) {
14024
- import_node_fs17.default.writeFileSync(
14025
- failureRecordPath(packagePath),
14026
- JSON.stringify({
14027
- stamp: stamps.get(unit),
14028
- diagnostic: missing ? diagnostic : sourceErrors.join("\n")
14029
- })
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
14030
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
+ }
14031
14607
  }
14032
- failures.set(
14033
- unit.moduleId,
14034
- sourceErrors.length ? sourceErrors.join("\n") : diagnostic
14035
- );
14608
+ if (linked.length === candidates.length) throw linkError;
14609
+ if (linked.length) artifact = await link(linked);
14036
14610
  }
14037
14611
  }
14038
- if (linked.length === candidates.length) throw linkError;
14039
- if (linked.length) artifact = await link(linked);
14040
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);
14041
14642
  }
14042
- for (const unit of units) {
14043
- const diagnostic = failures.get(unit.moduleId);
14044
- if (diagnostic !== void 0)
14045
- result.failures.push({ namespace: unit.moduleId, diagnostic });
14046
- }
14047
- if (artifact) {
14048
- await publishArtifact?.(artifact);
14049
- result.modules.push({
14050
- namespaces: linked.map((unit) => unit.moduleId),
14051
- url: `${base}/__peach/swift/${artifact.hash}.wasm`,
14052
- hash: artifact.hash,
14053
- icuUrl: icuUrl(base, artifact),
14054
- rootId: `${key2}/Expo`
14055
- });
14056
- }
14057
- return result;
14058
14643
  }
14059
- 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;
14060
14645
  var init_expo_swift_host = __esm({
14061
14646
  "src/expo-swift-host.ts"() {
14062
14647
  "use strict";
14063
- import_node_child_process10 = require("node:child_process");
14648
+ import_node_child_process11 = require("node:child_process");
14064
14649
  import_node_crypto9 = require("node:crypto");
14065
14650
  import_node_fs17 = __toESM(require("node:fs"), 1);
14066
14651
  import_node_module = require("node:module");
@@ -14069,13 +14654,17 @@ var init_expo_swift_host = __esm({
14069
14654
  import_node_util2 = require("node:util");
14070
14655
  init_internal_child();
14071
14656
  init_backend_origin();
14657
+ init_swift_binary_modules();
14072
14658
  init_swift_compile();
14073
14659
  init_swift_distribution();
14074
14660
  init_swift_host();
14661
+ init_swift_standins();
14075
14662
  init_swift_submit();
14076
- run2 = (0, import_node_util2.promisify)(import_node_child_process10.execFile);
14663
+ run2 = (0, import_node_util2.promisify)(import_node_child_process11.execFile);
14077
14664
  scriptEnv = { ...process.env, [RNX_FORKED_SCRIPT_ENV]: "1" };
14078
14665
  EXPO_SWIFT_ENTRY = "Sources/PeachExpoApp/PeachExpoEntry.swift";
14666
+ ExpoSwiftLinkRefusal = class extends Error {
14667
+ };
14079
14668
  }
14080
14669
  });
14081
14670
 
@@ -14086,20 +14675,25 @@ __export(expo_swift_bundle_exports, {
14086
14675
  });
14087
14676
  async function buildExpoSwiftBundle(appRoot) {
14088
14677
  const assets2 = [];
14089
- const metadata = await compileExpoSwiftModules(appRoot, "", async (artifact) => {
14090
- assets2.push({
14091
- path: `__peach/swift/${artifact.hash}.wasm`,
14092
- bytes: artifact.bytes,
14093
- contentType: "application/wasm"
14094
- });
14095
- if ("gzip" in artifact.icu) {
14678
+ const metadata = await compileExpoSwiftModules(
14679
+ appRoot,
14680
+ "",
14681
+ async (artifact, signal) => {
14682
+ signal.throwIfAborted();
14096
14683
  assets2.push({
14097
- path: `__peach/swift-icu/${artifact.icu.sha256}`,
14098
- bytes: artifact.icu.gzip,
14099
- contentType: "application/gzip"
14684
+ path: `__peach/swift/${artifact.hash}.wasm`,
14685
+ bytes: artifact.bytes,
14686
+ contentType: "application/wasm"
14100
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
+ }
14101
14695
  }
14102
- });
14696
+ );
14103
14697
  if (!metadata) return null;
14104
14698
  return { metadata, assets: assets2 };
14105
14699
  }
@@ -14110,6 +14704,78 @@ var init_expo_swift_bundle = __esm({
14110
14704
  }
14111
14705
  });
14112
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
+
14113
14779
  // cli/standalone.ts
14114
14780
  var IS_STANDALONE;
14115
14781
  var init_standalone = __esm({
@@ -14122,45 +14788,45 @@ var init_standalone = __esm({
14122
14788
  // src/kotlin-module.ts
14123
14789
  function peachKotlinModuleRoot() {
14124
14790
  if (!IS_STANDALONE)
14125
- 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");
14126
14792
  if (installedRoot) return installedRoot;
14127
14793
  const files2 = __PEACH_BUNDLED_KOTLIN__;
14128
14794
  const digest2 = (0, import_node_crypto10.createHash)("sha256").update(JSON.stringify(files2)).digest("hex");
14129
- const parent = import_node_path19.default.join(rnxHomeDir(), "kotlin", "modules");
14130
- const root = import_node_path19.default.join(parent, digest2);
14131
- import_node_fs18.default.mkdirSync(parent, { recursive: true });
14132
- if (!import_node_fs18.default.existsSync(root)) {
14133
- 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-"));
14134
14800
  try {
14135
14801
  for (const [name2, contents] of Object.entries(files2)) {
14136
- const file = import_node_path19.default.join(pending, name2);
14137
- import_node_fs18.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
14138
- 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);
14139
14805
  }
14140
14806
  try {
14141
- import_node_fs18.default.renameSync(pending, root);
14807
+ import_node_fs19.default.renameSync(pending, root);
14142
14808
  } catch (error) {
14143
14809
  if (!isRecord(error) || error.code !== "EEXIST" && error.code !== "ENOTEMPTY")
14144
14810
  throw error;
14145
14811
  }
14146
14812
  } finally {
14147
- import_node_fs18.default.rmSync(pending, { recursive: true, force: true });
14813
+ import_node_fs19.default.rmSync(pending, { recursive: true, force: true });
14148
14814
  }
14149
14815
  }
14150
14816
  for (const [name2, contents] of Object.entries(files2)) {
14151
- 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)
14152
14818
  throw new Error(`packaged Kotlin module differs from this CLI: ${name2}`);
14153
14819
  }
14154
14820
  installedRoot = root;
14155
14821
  return root;
14156
14822
  }
14157
- 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;
14158
14824
  var init_kotlin_module = __esm({
14159
14825
  "src/kotlin-module.ts"() {
14160
14826
  "use strict";
14161
14827
  import_node_crypto10 = require("node:crypto");
14162
- import_node_fs18 = __toESM(require("node:fs"), 1);
14163
- 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);
14164
14830
  import_node_url2 = require("node:url");
14165
14831
  init_standalone();
14166
14832
  init_home_paths();
@@ -14265,7 +14931,7 @@ __export(kotlin_host_exports, {
14265
14931
  });
14266
14932
  function readToolchain(moduleRoot) {
14267
14933
  const parsed = JSON.parse(
14268
- 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")
14269
14935
  );
14270
14936
  const download = (value) => {
14271
14937
  if (!isRecord(value) || typeof value.url !== "string" || typeof value.sha256 !== "string")
@@ -14306,43 +14972,43 @@ function readToolchain(moduleRoot) {
14306
14972
  };
14307
14973
  }
14308
14974
  function kotlinHome() {
14309
- return import_node_path20.default.join(rnxHomeDir(), "kotlin");
14975
+ return import_node_path21.default.join(rnxHomeDir(), "kotlin");
14310
14976
  }
14311
14977
  async function fetchVerified(download, target) {
14312
- if (import_node_fs19.default.existsSync(target)) return;
14978
+ if (import_node_fs20.default.existsSync(target)) return;
14313
14979
  const response = await fetch(download.url);
14314
14980
  if (!response.ok) throw new Error(`${download.url} answered ${response.status}`);
14315
14981
  const bytes = Buffer.from(await response.arrayBuffer());
14316
14982
  const digest2 = (0, import_node_crypto11.createHash)("sha256").update(bytes).digest("hex");
14317
14983
  if (digest2 !== download.sha256)
14318
14984
  throw new Error(`${download.url} has sha256 ${digest2}, expected ${download.sha256}`);
14319
- 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 });
14320
14986
  const partial = `${target}.${process.pid}.partial`;
14321
- import_node_fs19.default.writeFileSync(partial, bytes);
14322
- import_node_fs19.default.renameSync(partial, target);
14987
+ import_node_fs20.default.writeFileSync(partial, bytes);
14988
+ import_node_fs20.default.renameSync(partial, target);
14323
14989
  }
14324
14990
  function ensureToolchain(toolchain) {
14325
14991
  const key2 = JSON.stringify(toolchain);
14326
14992
  const pending = toolchains.get(key2);
14327
14993
  if (pending) return pending;
14328
14994
  const ready = (async () => {
14329
- const dir = import_node_path20.default.join(kotlinHome(), toolchain.compiler.version);
14330
- const kotlinc = import_node_path20.default.join(dir, "kotlinc", "bin", "kotlinc-wasm");
14331
- if (!import_node_fs19.default.existsSync(kotlinc)) {
14332
- 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");
14333
14999
  await fetchVerified(toolchain.compiler, zip);
14334
- await run3("unzip", ["-q", "-o", zip, "-d", dir]);
14335
- import_node_fs19.default.rmSync(zip);
15000
+ await run4("unzip", ["-q", "-o", zip, "-d", dir]);
15001
+ import_node_fs20.default.rmSync(zip);
14336
15002
  }
14337
- const java = process.env.JAVA_HOME ? import_node_path20.default.join(process.env.JAVA_HOME, "bin", "java") : "java";
14338
- 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(() => {
14339
15005
  throw new Error(
14340
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"}`
14341
15007
  );
14342
15008
  });
14343
- 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")];
14344
15010
  for (const library of toolchain.libraries) {
14345
- const target = import_node_path20.default.join(dir, library.name);
15011
+ const target = import_node_path21.default.join(dir, library.name);
14346
15012
  await fetchVerified(library, target);
14347
15013
  libraries.push(target);
14348
15014
  }
@@ -14355,11 +15021,11 @@ function ensureToolchain(toolchain) {
14355
15021
  return ready;
14356
15022
  }
14357
15023
  function appKotlinLanguage(root) {
14358
- const reactNative = import_node_path20.default.dirname(
14359
- (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")
14360
15026
  );
14361
- const versions = import_node_fs19.default.readFileSync(
14362
- 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"),
14363
15029
  "utf8"
14364
15030
  );
14365
15031
  const match = /^kotlin\s*=\s*"(\d+)\.(\d+)/m.exec(versions);
@@ -14370,9 +15036,9 @@ function appKotlinLanguage(root) {
14370
15036
  function kotlinSources(root, skip = SKIP_DIRS) {
14371
15037
  const sources = [];
14372
15038
  const walk2 = (dir) => {
14373
- 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 })) {
14374
15040
  if (entry.name.startsWith(".") || skip.has(entry.name)) continue;
14375
- const full = import_node_path20.default.join(dir, entry.name);
15041
+ const full = import_node_path21.default.join(dir, entry.name);
14376
15042
  if (entry.isDirectory()) walk2(full);
14377
15043
  else if (entry.isFile() && entry.name.endsWith(".kt")) sources.push(full);
14378
15044
  }
@@ -14382,51 +15048,51 @@ function kotlinSources(root, skip = SKIP_DIRS) {
14382
15048
  }
14383
15049
  function kotlinPlatformSources(moduleRoot, usesCompose) {
14384
15050
  return ["Sources", "JniPlatformSources", "JniSources"].flatMap(
14385
- (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(
14386
15052
  (file) => usesCompose ? !file.endsWith("/androidx/annotation/CallSuper.kt") : !file.endsWith("/OneNativeSourceViewDispatch.kt")
14387
15053
  )
14388
15054
  );
14389
15055
  }
14390
15056
  function ensureCompilerPlugin(kotlinc, plugin) {
14391
- const cache = import_node_path20.default.join(kotlinHome(), "compiler-plugins");
14392
- const out = import_node_path20.default.join(cache, plugin.hash);
14393
- 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);
14394
15060
  const pending = compilerPlugins.get(plugin.hash);
14395
15061
  if (pending) return pending;
14396
15062
  const build = (async () => {
14397
- import_node_fs19.default.mkdirSync(cache, { recursive: true });
14398
- const work = import_node_fs19.default.mkdtempSync(import_node_path20.default.join(cache, `${plugin.hash}-`));
14399
- 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");
14400
15066
  try {
14401
15067
  const sources = [];
14402
15068
  for (const { name: name2, bytes } of plugin.files) {
14403
- const target = import_node_path20.default.join(work, "sources", name2);
14404
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(target), { recursive: true });
14405
- 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);
14406
15072
  if (name2.endsWith(".kt")) sources.push(target);
14407
15073
  }
14408
- await run3(
14409
- 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"),
14410
15076
  [
14411
15077
  "-cp",
14412
- 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"),
14413
15079
  ...sources,
14414
15080
  "-d",
14415
15081
  classes
14416
15082
  ],
14417
15083
  { maxBuffer: 16 * 1024 * 1024 }
14418
15084
  );
14419
- const service = import_node_path20.default.join(classes, COMPILER_PLUGIN_SERVICE);
14420
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(service), { recursive: true });
14421
- 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);
14422
15088
  try {
14423
- import_node_fs19.default.renameSync(classes, out);
15089
+ import_node_fs20.default.renameSync(classes, out);
14424
15090
  } catch (error) {
14425
- if (!import_node_fs19.default.existsSync(out)) throw error;
15091
+ if (!import_node_fs20.default.existsSync(out)) throw error;
14426
15092
  }
14427
15093
  return out;
14428
15094
  } finally {
14429
- import_node_fs19.default.rmSync(work, { recursive: true, force: true });
15095
+ import_node_fs20.default.rmSync(work, { recursive: true, force: true });
14430
15096
  }
14431
15097
  })().finally(() => compilerPlugins.delete(plugin.hash));
14432
15098
  compilerPlugins.set(plugin.hash, build);
@@ -14480,7 +15146,7 @@ function entrySource(ids) {
14480
15146
  ].join("\n");
14481
15147
  }
14482
15148
  function buildsDir() {
14483
- return import_node_path20.default.join(kotlinHome(), "builds");
15149
+ return import_node_path21.default.join(kotlinHome(), "builds");
14484
15150
  }
14485
15151
  async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14486
15152
  const { kotlinSourceId, nativeSourceContract, renderKotlinSourceGlue } = await import("vxrn/native-source-contract");
@@ -14493,7 +15159,7 @@ async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14493
15159
  const viewIds = [];
14494
15160
  let usesCompose = false;
14495
15161
  for (const file of sources) {
14496
- const source = import_node_fs19.default.readFileSync(file, "utf8");
15162
+ const source = import_node_fs20.default.readFileSync(file, "utf8");
14497
15163
  if (/\bandroidx\.compose\./.test(source)) usesCompose = true;
14498
15164
  const contract = nativeSourceContract(file, source);
14499
15165
  if (contract.modules.length === 0 && contract.views.length === 0) continue;
@@ -14506,9 +15172,9 @@ async function kotlinArtifact(root, moduleRoot, origin, target = "app") {
14506
15172
  if (viewIds.length > 0) generated["PeachViews.kt"] = viewsSource(viewIds);
14507
15173
  const shims = kotlinPlatformSources(moduleRoot, usesCompose);
14508
15174
  if (target === "jni")
14509
- 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()));
14510
15176
  if (viewIds.length > 0)
14511
- shims.push(...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")));
15177
+ shims.push(...kotlinSources(import_node_path21.default.join(moduleRoot, "ComposeSources")));
14512
15178
  return compileKotlin(
14513
15179
  { root, moduleRoot, toolchain, language, sources, generated, shims, usesCompose },
14514
15180
  origin
@@ -14578,23 +15244,23 @@ function readExpoTypes(output) {
14578
15244
  function scanExpoTypes(toolchain, script, sources) {
14579
15245
  const candidates = sources.filter(
14580
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(
14581
- import_node_fs19.default.readFileSync(file, "utf8")
15247
+ import_node_fs20.default.readFileSync(file, "utf8")
14582
15248
  )
14583
15249
  );
14584
15250
  if (candidates.length === 0) return Promise.resolve([]);
14585
15251
  const digest2 = (0, import_node_crypto11.createHash)("sha256").update(JSON.stringify(toolchain.compiler));
14586
15252
  for (const file of [script, ...candidates])
14587
- 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`);
14588
15254
  const key2 = digest2.digest("hex");
14589
15255
  let scan = expoTypeScans.get(key2);
14590
15256
  if (!scan) {
14591
15257
  scan = (async () => {
14592
15258
  const { kotlinc } = await ensureToolchain(toolchain);
14593
- const { stdout } = await run3(
14594
- 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"),
14595
15261
  [
14596
15262
  "-cp",
14597
- 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"),
14598
15264
  "-script",
14599
15265
  script,
14600
15266
  ...candidates
@@ -14671,7 +15337,7 @@ function expoTypeSources(files2) {
14671
15337
  )
14672
15338
  ];
14673
15339
  if (edits.length > 0 || views.length > 0) {
14674
- 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");
14675
15341
  for (const { range: range2, owner, field } of edits.sort((a, b) => b.range[0] - a.range[0]))
14676
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])}`;
14677
15343
  if (views.length > 0) {
@@ -14687,7 +15353,7 @@ function expoTypeSources(files2) {
14687
15353
  `${file.package ? `${file.package}.` : ""}peachExpoViews${index}()`
14688
15354
  );
14689
15355
  }
14690
- const name2 = `PeachExpoSource_${index}_${import_node_path20.default.basename(file.file)}`;
15356
+ const name2 = `PeachExpoSource_${index}_${import_node_path21.default.basename(file.file)}`;
14691
15357
  generated[name2] = text4;
14692
15358
  origins[name2] = file.file;
14693
15359
  }
@@ -14710,19 +15376,19 @@ async function expoKotlinArtifact(root, moduleRoot, origin, modules) {
14710
15376
  const language = appKotlinLanguage(root);
14711
15377
  const scanned = await scanExpoTypes(
14712
15378
  toolchain,
14713
- import_node_path20.default.join(moduleRoot, "tools/expo-types.main.kts"),
15379
+ import_node_path21.default.join(moduleRoot, "tools/expo-types.main.kts"),
14714
15380
  modules.sources
14715
15381
  );
14716
15382
  const usesCompose = scanned.some((file) => file.views.length > 0) || modules.sources.some(
14717
- (file) => /\bandroidx\.compose\./.test(import_node_fs19.default.readFileSync(file, "utf8"))
15383
+ (file) => /\bandroidx\.compose\./.test(import_node_fs20.default.readFileSync(file, "utf8"))
14718
15384
  );
14719
15385
  const shims = [
14720
15386
  ...kotlinPlatformSources(moduleRoot, usesCompose),
14721
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ExpoSources"), /* @__PURE__ */ new Set()),
14722
- ...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()),
14723
15389
  ...usesCompose ? [
14724
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")),
14725
- ...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())
14726
15392
  ] : []
14727
15393
  ];
14728
15394
  const types = expoTypeSources(scanned);
@@ -14866,9 +15532,9 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
14866
15532
  };
14867
15533
  const shims = [
14868
15534
  ...kotlinPlatformSources(moduleRoot, true),
14869
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "ComposeSources")),
14870
- ...kotlinSources(import_node_path20.default.join(moduleRoot, "AppSources"), /* @__PURE__ */ new Set()),
14871
- ...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())
14872
15538
  ];
14873
15539
  return compileKotlin(
14874
15540
  {
@@ -14883,7 +15549,7 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
14883
15549
  viewModels: {
14884
15550
  file: "PeachAppEntry.kt",
14885
15551
  render: appEntry,
14886
- 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")
14887
15553
  }
14888
15554
  },
14889
15555
  origin
@@ -14928,7 +15594,7 @@ function appResourceSources(app) {
14928
15594
  entries: app.drawables.map((drawable) => ({
14929
15595
  name: drawable.name,
14930
15596
  init: `listOf(
14931
- ${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")}
14932
15598
  )`
14933
15599
  }))
14934
15600
  },
@@ -14992,7 +15658,7 @@ function drawableInit(drawable, file) {
14992
15658
  if (drawable.kind === "xml") return `PeachDrawable.Xml(${where})`;
14993
15659
  if (drawable.kind === "bitmap")
14994
15660
  return `PeachDrawable.Bitmap(${where}, ${drawable.ninePatch}, ${literal(
14995
- import_node_fs19.default.readFileSync(drawable.file).toString("base64")
15661
+ import_node_fs20.default.readFileSync(drawable.file).toString("base64")
14996
15662
  )})`;
14997
15663
  const vector = drawable.vector;
14998
15664
  const float = (value) => `${value}f`;
@@ -15053,15 +15719,15 @@ async function compileKotlin(input, origin) {
15053
15719
  usesCompose,
15054
15720
  viewModels
15055
15721
  } = input;
15056
- const compilerRoot = import_node_path20.default.join(moduleRoot, "CompilerSources");
15722
+ const compilerRoot = import_node_path21.default.join(moduleRoot, "CompilerSources");
15057
15723
  const compilerFiles = [
15058
15724
  ...kotlinSources(compilerRoot, /* @__PURE__ */ new Set()).map(
15059
- (file) => import_node_path20.default.relative(compilerRoot, file)
15725
+ (file) => import_node_path21.default.relative(compilerRoot, file)
15060
15726
  ),
15061
15727
  COMPILER_PLUGIN_SERVICE
15062
15728
  ].map((name2) => ({
15063
15729
  name: name2,
15064
- 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))
15065
15731
  }));
15066
15732
  const compilerDigest = (0, import_node_crypto11.createHash)("sha256").update(
15067
15733
  JSON.stringify({ format: 1, compiler: toolchain.compiler })
@@ -15071,15 +15737,15 @@ async function compileKotlin(input, origin) {
15071
15737
  const plugin = { hash: compilerDigest.digest("hex"), files: compilerFiles };
15072
15738
  const inputs = [...shims, ...sources].map((file) => ({
15073
15739
  file,
15074
- bytes: import_node_fs19.default.readFileSync(file)
15740
+ bytes: import_node_fs20.default.readFileSync(file)
15075
15741
  }));
15076
15742
  const digest2 = (0, import_node_crypto11.createHash)("sha256");
15077
15743
  digest2.update(
15078
15744
  JSON.stringify({ format: BUILD_FORMAT, toolchain, language, plugin: plugin.hash })
15079
15745
  );
15080
15746
  for (const { file, bytes } of inputs)
15081
- digest2.update(import_node_path20.default.relative(root, file)).update("\0").update(bytes).update("\0");
15082
- 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));
15083
15749
  for (const [name2, text4] of Object.entries(generated))
15084
15750
  digest2.update(`${name2}\0${text4}\0`);
15085
15751
  const hash = digest2.digest("hex").slice(0, 24);
@@ -15087,8 +15753,8 @@ async function compileKotlin(input, origin) {
15087
15753
  url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`,
15088
15754
  hash
15089
15755
  };
15090
- const out = import_node_path20.default.join(buildsDir(), hash);
15091
- 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;
15092
15758
  const pending = builds.get(hash);
15093
15759
  if (pending) return pending;
15094
15760
  const build = (async () => {
@@ -15096,29 +15762,29 @@ async function compileKotlin(input, origin) {
15096
15762
  const { kotlinc } = ready;
15097
15763
  const compilerPlugin = await ensureCompilerPlugin(kotlinc, plugin);
15098
15764
  const libraries = [...ready.libraries];
15099
- const composeRuntime = import_node_path20.default.join(
15765
+ const composeRuntime = import_node_path21.default.join(
15100
15766
  kotlinHome(),
15101
15767
  toolchain.compiler.version,
15102
15768
  toolchain.composeRuntime.name
15103
15769
  );
15104
15770
  if (usesCompose) {
15105
15771
  for (const library of toolchain.composeLibraries) {
15106
- 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);
15107
15773
  await fetchVerified(library, target);
15108
15774
  libraries.push(target);
15109
15775
  }
15110
15776
  await fetchVerified(toolchain.composeRuntime, composeRuntime);
15111
15777
  }
15112
- import_node_fs19.default.mkdirSync(buildsDir(), { recursive: true });
15113
- const work = import_node_fs19.default.mkdtempSync(import_node_path20.default.join(buildsDir(), `${hash}-`));
15114
- const generatedDir = import_node_path20.default.join(work, "generated");
15115
- 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);
15116
15782
  for (const [name2, text4] of Object.entries(generated))
15117
- 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);
15118
15784
  const compiledSources = inputs.map(({ file, bytes }, index) => {
15119
- const target = import_node_path20.default.join(work, "sources", String(index), import_node_path20.default.basename(file));
15120
- import_node_fs19.default.mkdirSync(import_node_path20.default.dirname(target), { recursive: true });
15121
- 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);
15122
15788
  return { file, target };
15123
15789
  });
15124
15790
  const common = [
@@ -15127,15 +15793,15 @@ async function compileKotlin(input, origin) {
15127
15793
  "-Xallow-kotlin-package",
15128
15794
  "-Xwasm-target=js",
15129
15795
  "-libraries",
15130
- libraries.join(import_node_path20.default.delimiter)
15796
+ libraries.join(import_node_path21.default.delimiter)
15131
15797
  ];
15132
- const compileKlib = (outputDir) => run3(
15798
+ const compileKlib = (outputDir) => run4(
15133
15799
  kotlinc,
15134
15800
  [
15135
15801
  ...common,
15136
15802
  `-Xplugin=${compilerPlugin}`,
15137
15803
  ...usesCompose ? [
15138
- `-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")}`
15139
15805
  ] : [],
15140
15806
  "-language-version",
15141
15807
  language,
@@ -15148,7 +15814,7 @@ async function compileKotlin(input, origin) {
15148
15814
  "-ir-output-name",
15149
15815
  "app",
15150
15816
  ...compiledSources.map(({ target }) => target),
15151
- ...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))
15152
15818
  ],
15153
15819
  { maxBuffer: 16 * 1024 * 1024 }
15154
15820
  );
@@ -15156,49 +15822,49 @@ async function compileKotlin(input, origin) {
15156
15822
  if (viewModels && inputs.some(
15157
15823
  ({ file, bytes }) => sources.includes(file) && bytes.includes("ViewModel")
15158
15824
  )) {
15159
- await compileKlib(import_node_path20.default.join(work, "abi"));
15160
- const { stdout } = await run3(
15161
- 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"),
15162
15828
  [
15163
15829
  "-cp",
15164
- 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"),
15165
15831
  "-script",
15166
15832
  viewModels.script,
15167
- import_node_path20.default.join(work, "abi")
15833
+ import_node_path21.default.join(work, "abi")
15168
15834
  ],
15169
15835
  { maxBuffer: 64 * 1024 * 1024 }
15170
15836
  );
15171
- import_node_fs19.default.writeFileSync(
15172
- import_node_path20.default.join(generatedDir, viewModels.file),
15837
+ import_node_fs20.default.writeFileSync(
15838
+ import_node_path21.default.join(generatedDir, viewModels.file),
15173
15839
  viewModels.render(viewModelClasses(readAbiClasses(stdout)))
15174
15840
  );
15175
15841
  }
15176
- await compileKlib(import_node_path20.default.join(work, "klib"));
15177
- await run3(
15842
+ await compileKlib(import_node_path21.default.join(work, "klib"));
15843
+ await run4(
15178
15844
  kotlinc,
15179
15845
  [
15180
15846
  ...common,
15181
15847
  "-nowarn",
15182
- `-Xinclude=${import_node_path20.default.join(work, "klib")}`,
15848
+ `-Xinclude=${import_node_path21.default.join(work, "klib")}`,
15183
15849
  "-Xir-produce-js",
15184
15850
  "-ir-output-dir",
15185
- import_node_path20.default.join(work, "js"),
15851
+ import_node_path21.default.join(work, "js"),
15186
15852
  "-ir-output-name",
15187
15853
  "app"
15188
15854
  ],
15189
15855
  { maxBuffer: 16 * 1024 * 1024 }
15190
15856
  );
15191
15857
  if (usesCompose) {
15192
- await run3("unzip", [
15858
+ await run4("unzip", [
15193
15859
  "-q",
15194
15860
  "-j",
15195
15861
  composeRuntime,
15196
15862
  "skiko.mjs",
15197
15863
  "-d",
15198
- import_node_path20.default.join(work, "js")
15864
+ import_node_path21.default.join(work, "js")
15199
15865
  ]);
15200
- const skikoPath = import_node_path20.default.join(work, "js", "skiko.mjs");
15201
- 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"), {
15202
15868
  ecmaVersion: "latest",
15203
15869
  sourceType: "module"
15204
15870
  });
@@ -15221,7 +15887,7 @@ async function compileKotlin(input, origin) {
15221
15887
  "GL",
15222
15888
  ...bindings
15223
15889
  ];
15224
- import_node_fs19.default.writeFileSync(
15890
+ import_node_fs20.default.writeFileSync(
15225
15891
  skikoPath,
15226
15892
  [
15227
15893
  "const runtime = globalThis.__peachKotlinSkiko;",
@@ -15235,10 +15901,10 @@ async function compileKotlin(input, origin) {
15235
15901
  if (usesCompose) {
15236
15902
  for (const library of toolchain.composeJsLibraries) {
15237
15903
  let imported = false;
15238
- 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"))) {
15239
15905
  if (!file.endsWith(".mjs")) continue;
15240
- const target = import_node_path20.default.join(work, "js", file);
15241
- 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");
15242
15908
  let next = source;
15243
15909
  for (const quote of ["'", '"'])
15244
15910
  next = next.replaceAll(
@@ -15246,29 +15912,29 @@ async function compileKotlin(input, origin) {
15246
15912
  `from ${quote}./${library.file}${quote}`
15247
15913
  );
15248
15914
  if (next === source) continue;
15249
- import_node_fs19.default.writeFileSync(target, next);
15915
+ import_node_fs20.default.writeFileSync(target, next);
15250
15916
  imported = true;
15251
15917
  }
15252
15918
  if (!imported) continue;
15253
- const archive = import_node_path20.default.join(
15919
+ const archive = import_node_path21.default.join(
15254
15920
  kotlinHome(),
15255
15921
  toolchain.compiler.version,
15256
15922
  library.name
15257
15923
  );
15258
15924
  await fetchVerified(library, archive);
15259
- const { stdout } = await run3("tar", ["-xOf", archive, library.archiveEntry], {
15925
+ const { stdout } = await run4("tar", ["-xOf", archive, library.archiveEntry], {
15260
15926
  maxBuffer: 16 * 1024 * 1024
15261
15927
  });
15262
- 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);
15263
15929
  }
15264
15930
  }
15265
15931
  } catch (error) {
15266
- import_node_fs19.default.rmSync(work, { recursive: true, force: true });
15932
+ import_node_fs20.default.rmSync(work, { recursive: true, force: true });
15267
15933
  let output = isRecord(error) ? `${String(error.stderr ?? "")}${String(error.stdout ?? "")}` : "";
15268
15934
  for (const [name2, source] of Object.entries(origins))
15269
- output = output.replaceAll(import_node_path20.default.join(generatedDir, name2), source);
15935
+ output = output.replaceAll(import_node_path21.default.join(generatedDir, name2), source);
15270
15936
  for (const { file, target } of compiledSources)
15271
- 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);
15272
15938
  throw new Error(
15273
15939
  `kotlin compile failed:
15274
15940
  ${output.trim() || (error instanceof Error ? error.message : String(error))}`
@@ -15277,9 +15943,9 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15277
15943
  const seams = [
15278
15944
  ["process.release.name", "process.release?.name"]
15279
15945
  ];
15280
- 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"));
15281
15947
  if (js.some(
15282
- (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.")
15283
15949
  ))
15284
15950
  seams.push([
15285
15951
  "(typeof(window) !== 'undefined' && window != null && typeof(window.addEventListener) === 'function') ? window : null",
@@ -15288,12 +15954,12 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15288
15954
  for (const [from, to] of seams) {
15289
15955
  let patched = 0;
15290
15956
  for (const file of js) {
15291
- const target = import_node_path20.default.join(work, "js", file);
15292
- 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");
15293
15959
  const next = text4.replaceAll(from, to);
15294
15960
  if (next !== text4) {
15295
15961
  patched++;
15296
- import_node_fs19.default.writeFileSync(target, next);
15962
+ import_node_fs20.default.writeFileSync(target, next);
15297
15963
  }
15298
15964
  }
15299
15965
  if (patched === 0)
@@ -15302,10 +15968,10 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15302
15968
  );
15303
15969
  }
15304
15970
  try {
15305
- import_node_fs19.default.renameSync(work, out);
15971
+ import_node_fs20.default.renameSync(work, out);
15306
15972
  } catch (error) {
15307
- if (!import_node_fs19.default.existsSync(import_node_path20.default.join(out, "js", "app.wasm"))) throw error;
15308
- 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 });
15309
15975
  }
15310
15976
  return artifact;
15311
15977
  })().finally(() => builds.delete(hash));
@@ -15313,24 +15979,24 @@ ${output.trim() || (error instanceof Error ? error.message : String(error))}`
15313
15979
  return build;
15314
15980
  }
15315
15981
  function kotlinArtifactFiles(hash) {
15316
- const dir = import_node_path20.default.join(buildsDir(), hash, "js");
15317
- return import_node_fs19.default.readdirSync(dir).sort().map((name2) => {
15318
- 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)];
15319
15985
  if (!contentType) throw new Error(`unexpected kotlin artifact file ${name2}`);
15320
- 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 };
15321
15987
  });
15322
15988
  }
15323
15989
  function serveKotlinArtifact(pathname, res) {
15324
15990
  if (!pathname.startsWith(KOTLIN_ARTIFACT_PREFIX)) return false;
15325
15991
  const [hash, file, ...rest] = pathname.slice(KOTLIN_ARTIFACT_PREFIX.length).split("/");
15326
- 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;
15327
15993
  if (!hash || !/^[0-9a-f]+$/.test(hash) || !file || rest.length > 0 || !type || file.includes("..")) {
15328
15994
  res.statusCode = 404;
15329
15995
  res.end("not a kotlin artifact");
15330
15996
  return true;
15331
15997
  }
15332
- const target = import_node_path20.default.join(buildsDir(), hash, "js", file);
15333
- 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)) {
15334
16000
  res.statusCode = 404;
15335
16001
  res.end(`kotlin artifact ${hash}/${file} was not built`);
15336
16002
  return true;
@@ -15338,7 +16004,7 @@ function serveKotlinArtifact(pathname, res) {
15338
16004
  res.setHeader("access-control-allow-origin", "*");
15339
16005
  res.setHeader("content-type", type);
15340
16006
  res.setHeader("cache-control", "public, max-age=31536000, immutable");
15341
- res.end(import_node_fs19.default.readFileSync(target));
16007
+ res.end(import_node_fs20.default.readFileSync(target));
15342
16008
  return true;
15343
16009
  }
15344
16010
  async function serveKotlinRequest(pathname, res, app) {
@@ -15355,22 +16021,22 @@ async function serveKotlinRequest(pathname, res, app) {
15355
16021
  }
15356
16022
  return true;
15357
16023
  }
15358
- 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;
15359
16025
  var init_kotlin_host = __esm({
15360
16026
  "src/kotlin-host.ts"() {
15361
16027
  "use strict";
15362
- import_node_child_process11 = require("node:child_process");
16028
+ import_node_child_process13 = require("node:child_process");
15363
16029
  import_node_crypto11 = require("node:crypto");
15364
- import_node_fs19 = __toESM(require("node:fs"), 1);
15365
- import_node_module2 = require("node:module");
15366
- import_node_path20 = __toESM(require("node:path"), 1);
15367
- 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");
15368
16034
  import_acorn2 = require("acorn");
15369
16035
  init_home_paths();
15370
16036
  init_is_record();
15371
16037
  init_kotlin_view_models();
15372
16038
  init_kotlin_module();
15373
- run3 = (0, import_node_util3.promisify)(import_node_child_process11.execFile);
16039
+ run4 = (0, import_node_util4.promisify)(import_node_child_process13.execFile);
15374
16040
  KOTLIN_ARTIFACT_PREFIX = "/__peach/kotlin-artifact/";
15375
16041
  toolchains = /* @__PURE__ */ new Map();
15376
16042
  SKIP_DIRS = /* @__PURE__ */ new Set([
@@ -15412,41 +16078,17 @@ var init_kotlin_host = __esm({
15412
16078
 
15413
16079
  // src/expo-kotlin-host.ts
15414
16080
  async function collectExpoKotlinModules(appRoot) {
15415
- appRoot = import_node_fs20.default.realpathSync(appRoot);
15416
- let autolinker;
15417
- try {
15418
- autolinker = (0, import_node_module3.createRequire)(import_node_path21.default.join(appRoot, "package.json")).resolve(
15419
- "expo-modules-autolinking/package.json"
15420
- );
15421
- } catch (error) {
15422
- if (isRecord(error) && error.code === "MODULE_NOT_FOUND") return null;
15423
- throw error;
15424
- }
15425
- const { stdout } = await run4(
15426
- process.execPath,
15427
- [
15428
- import_node_path21.default.join(import_node_path21.default.dirname(autolinker), "bin/expo-modules-autolinking.js"),
15429
- "resolve",
15430
- "--platform",
15431
- "android",
15432
- "--project-root",
15433
- appRoot,
15434
- "--json"
15435
- ],
15436
- { timeout: 3e4, maxBuffer: 8 * 1024 * 1024, env: scriptEnv2 }
15437
- );
15438
- const resolved = JSON.parse(stdout);
15439
- if (!isRecord(resolved) || !Array.isArray(resolved.modules))
15440
- throw new Error("invalid Expo Android resolution");
16081
+ const modules = await resolveExpoAndroidAutolinking(appRoot);
15441
16082
  const result = { modules: [], sources: [] };
15442
- for (const entry of resolved.modules) {
15443
- 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))
15444
16086
  throw new Error("invalid Expo Android module entry");
15445
16087
  for (const project of entry.projects) {
15446
16088
  if (!isRecord(project) || typeof project.sourceDir !== "string" || !Array.isArray(project.modules))
15447
16089
  throw new Error("invalid Expo Android project");
15448
- const sourceDir = import_node_fs20.default.realpathSync(project.sourceDir);
15449
- 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;
15450
16092
  if (project.modules.length === 0) continue;
15451
16093
  for (const module2 of project.modules) {
15452
16094
  if (!isRecord(module2) || typeof module2.classifier !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)+$/.test(
@@ -15456,9 +16098,9 @@ async function collectExpoKotlinModules(appRoot) {
15456
16098
  result.modules.push({ classifier: module2.classifier, name: module2.name });
15457
16099
  }
15458
16100
  const walk2 = (dir) => {
15459
- if (!import_node_fs20.default.existsSync(dir)) return;
15460
- for (const child of import_node_fs20.default.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
15461
- 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);
15462
16104
  if (child.isSymbolicLink())
15463
16105
  throw new Error(`Expo Kotlin source is a symlink: ${file}`);
15464
16106
  if (child.isDirectory()) walk2(file);
@@ -15467,8 +16109,8 @@ async function collectExpoKotlinModules(appRoot) {
15467
16109
  else if (child.name.endsWith(".kt")) result.sources.push(file);
15468
16110
  }
15469
16111
  };
15470
- walk2(import_node_path21.default.join(sourceDir, "src", "main", "java"));
15471
- 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"));
15472
16114
  }
15473
16115
  }
15474
16116
  return result.modules.length === 0 ? null : result;
@@ -15502,21 +16144,16 @@ async function compileExpoKotlinModules(root, origin) {
15502
16144
  };
15503
16145
  }
15504
16146
  }
15505
- 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;
15506
16148
  var init_expo_kotlin_host = __esm({
15507
16149
  "src/expo-kotlin-host.ts"() {
15508
16150
  "use strict";
15509
- import_node_child_process12 = require("node:child_process");
15510
- import_node_fs20 = __toESM(require("node:fs"), 1);
15511
- import_node_module3 = require("node:module");
15512
- import_node_path21 = __toESM(require("node:path"), 1);
15513
- import_node_util4 = require("node:util");
15514
- 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();
15515
16154
  init_backend_origin();
15516
16155
  init_is_record();
15517
16156
  init_kotlin_module();
15518
- run4 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
15519
- scriptEnv2 = { ...process.env, [RNX_FORKED_SCRIPT_ENV]: "1" };
15520
16157
  }
15521
16158
  });
15522
16159
 
@@ -15562,56 +16199,8 @@ var import_node_vm = require("node:vm");
15562
16199
  init_process_group();
15563
16200
  init_backend_origin();
15564
16201
 
15565
- // src/bundleGlobalFooter.ts
15566
- function findBundleFooter(source, prefix) {
15567
- let end = source.length;
15568
- while (end > 0) {
15569
- const newline = source.lastIndexOf("\n", end - 1);
15570
- if (newline < 0) return -1;
15571
- const line = newline + 1;
15572
- if (source.startsWith(prefix, line)) return newline;
15573
- if (line !== end && !source.startsWith("globalThis.", line) && !source.startsWith("//", line)) {
15574
- return -1;
15575
- }
15576
- end = newline;
15577
- }
15578
- return -1;
15579
- }
15580
- function readFooter(source, prefix, suffix, name2) {
15581
- const start = findBundleFooter(source, prefix);
15582
- if (start < 0) return null;
15583
- const end = source.indexOf("\n", start + 1);
15584
- const line = source.slice(start + 1, end < 0 ? void 0 : end);
15585
- if (!line.endsWith(suffix)) throw new Error(`${name2} footer is truncated`);
15586
- const value = JSON.parse(
15587
- line.slice(prefix.length, suffix ? -suffix.length : void 0)
15588
- );
15589
- if (value === null) throw new Error(`${name2} footer has no metadata`);
15590
- return value;
15591
- }
15592
- function detachFooter(source, prefix, suffix, name2) {
15593
- const start = findBundleFooter(source, prefix);
15594
- if (start < 0) return { source, value: null };
15595
- const value = readFooter(source, prefix, suffix, name2);
15596
- const end = source.indexOf("\n", start + 1);
15597
- return { source: source.slice(0, start) + (end < 0 ? "" : source.slice(end)), value };
15598
- }
15599
- function insertBundleGlobalFooter(source, name2, value) {
15600
- return insertFooter(source, `globalThis.${name2}=`, ";", name2, value);
15601
- }
15602
- function insertBundleMetadataFooter(source, name2, value) {
15603
- return insertFooter(source, `// peach.${name2}=`, "", name2, value);
15604
- }
15605
- function insertFooter(source, prefix, suffix, name2, value) {
15606
- source = detachFooter(source, prefix, suffix, name2).source;
15607
- const json = JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
15608
- const footer = `
15609
- ${prefix}${json}${suffix}`;
15610
- const identity = findBundleFooter(source, "globalThis.__sootsimModulePaths=");
15611
- return identity < 0 ? source + footer : source.slice(0, identity) + footer + source.slice(identity);
15612
- }
15613
-
15614
16202
  // src/expoKotlinContract.ts
16203
+ init_bundleGlobalFooter();
15615
16204
  function record(value) {
15616
16205
  return value !== null && typeof value === "object" && !Array.isArray(value);
15617
16206
  }
@@ -15649,6 +16238,7 @@ function insertExpoKotlinFooter(source, metadata) {
15649
16238
  }
15650
16239
 
15651
16240
  // src/expoSwiftContract.ts
16241
+ init_bundleGlobalFooter();
15652
16242
  function record2(value) {
15653
16243
  return value !== null && typeof value === "object" && !Array.isArray(value);
15654
16244
  }
@@ -15682,6 +16272,7 @@ function insertExpoSwiftFooter(source, metadata) {
15682
16272
  }
15683
16273
 
15684
16274
  // src/nitroContract.ts
16275
+ init_bundleGlobalFooter();
15685
16276
  function readNitroMetadata(value) {
15686
16277
  if (value === null || value === void 0) return null;
15687
16278
  if (typeof value !== "object" || Array.isArray(value) || Reflect.get(value, "platform") !== "ios")
@@ -15801,17 +16392,17 @@ function prepareChannel({
15801
16392
  }
15802
16393
  }
15803
16394
  const identity = (0, import_node_crypto12.createHash)("sha256").update(bundle).update(icon);
15804
- for (const [path20, bytes] of [...files2].sort(
16395
+ for (const [path21, bytes] of [...files2].sort(
15805
16396
  ([a], [b]) => a < b ? -1 : a > b ? 1 : 0
15806
16397
  )) {
15807
- identity.update(JSON.stringify([path20, digest(bytes)]));
16398
+ identity.update(JSON.stringify([path21, digest(bytes)]));
15808
16399
  }
15809
16400
  if (native) identity.update(JSON.stringify(native.metadata));
15810
16401
  if (nitro) identity.update(JSON.stringify(nitro.metadata));
15811
16402
  const releaseKey = `${prefix}/peach/releases/${identity.digest("hex")}`;
15812
16403
  const assetBaseUrl = `${origin.origin}/${releaseKey}/`;
15813
16404
  const directories = new Set(
15814
- [...files2.keys()].map((path20) => path20.slice(0, path20.lastIndexOf("/")))
16405
+ [...files2.keys()].map((path21) => path21.slice(0, path21.lastIndexOf("/")))
15815
16406
  );
15816
16407
  let locations = 0;
15817
16408
  let source = new TextDecoder("utf-8", { fatal: true }).decode(bundle).replace(
@@ -15819,12 +16410,12 @@ function prepareChannel({
15819
16410
  /("?httpServerLocation"?\s*:\s*)(?:"((?:[^"\\]|\\.)*)"|`([^`\\$]*)`)/g,
15820
16411
  (match, property, quoted, template) => {
15821
16412
  const location = quoted === void 0 ? template : JSON.parse(`"${quoted}"`);
15822
- const path20 = packagedAssetDirectory(location);
15823
- if (!directories.has(path20)) {
16413
+ const path21 = packagedAssetDirectory(location);
16414
+ if (!directories.has(path21)) {
15824
16415
  throw new Error(`bundle asset location has no packaged files: ${location}`);
15825
16416
  }
15826
16417
  locations++;
15827
- return `${property}${JSON.stringify(new URL(path20, assetBaseUrl).href)}`;
16418
+ return `${property}${JSON.stringify(new URL(path21, assetBaseUrl).href)}`;
15828
16419
  }
15829
16420
  );
15830
16421
  if (assets2.length && !locations)
@@ -15887,10 +16478,10 @@ function prepareChannel({
15887
16478
  contentType: "application/javascript"
15888
16479
  },
15889
16480
  { key: `${releaseKey}/icon.png`, bytes: icon, contentType: "image/png" },
15890
- ...[...files2].map(([path20, bytes]) => ({
15891
- key: `${releaseKey}/${path20}`,
16481
+ ...[...files2].map(([path21, bytes]) => ({
16482
+ key: `${releaseKey}/${path21}`,
15892
16483
  bytes,
15893
- contentType: nativeAssets.get(path20)?.contentType ?? {
16484
+ contentType: nativeAssets.get(path21)?.contentType ?? {
15894
16485
  png: "image/png",
15895
16486
  jpg: "image/jpeg",
15896
16487
  jpeg: "image/jpeg",
@@ -15899,7 +16490,7 @@ function prepareChannel({
15899
16490
  ttf: "font/ttf",
15900
16491
  otf: "font/otf",
15901
16492
  wav: "audio/wav"
15902
- }[path20.split(".").pop()] ?? "application/octet-stream"
16493
+ }[path21.split(".").pop()] ?? "application/octet-stream"
15903
16494
  }))
15904
16495
  ];
15905
16496
  return { platform, key: `${prefix}/${channelKey(platform)}`, metadata, objects };
@@ -15939,7 +16530,7 @@ async function publishBundleChannel(release, { put, fetchObject = fetch }) {
15939
16530
  }
15940
16531
  async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios", "android"], assertRunning = () => {
15941
16532
  } } = {}) {
15942
- const { readFileSync: readFileSync5 } = await import("node:fs");
16533
+ const { readFileSync: readFileSync6 } = await import("node:fs");
15943
16534
  const { basename: basename2 } = await import("node:path");
15944
16535
  const snapshots = [];
15945
16536
  for (const platform of platforms) {
@@ -15960,27 +16551,27 @@ async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios
15960
16551
  const directory = packagedAssetDirectory(asset.httpServerLocation);
15961
16552
  if (asset.files) {
15962
16553
  for (const file of asset.files) {
15963
- const path20 = `${directory}/${basename2(file)}`;
15964
- 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));
15965
16556
  }
15966
16557
  continue;
15967
16558
  }
15968
16559
  for (const scale of asset.scales) {
15969
16560
  const file = `${asset.name}${scale === 1 ? "" : `@${scale}x`}.${asset.type}`;
15970
- const path20 = `${directory}/${file}`;
15971
- if (assets2.has(path20)) continue;
16561
+ const path21 = `${directory}/${file}`;
16562
+ if (assets2.has(path21)) continue;
15972
16563
  const response = await fetch(
15973
16564
  `${origin}${asset.httpServerLocation}/${file}?platform=${platform}&hash=${asset.hash}`
15974
16565
  );
15975
16566
  if (!response.ok)
15976
- throw new Error(`dev server asset ${path20} failed: ${response.status}`);
15977
- 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()));
15978
16569
  }
15979
16570
  }
15980
16571
  snapshots.push({
15981
16572
  platform,
15982
16573
  bundle,
15983
- assets: [...assets2].map(([path20, bytes]) => ({ path: path20, bytes })),
16574
+ assets: [...assets2].map(([path21, bytes]) => ({ path: path21, bytes })),
15984
16575
  ...platform === "ios" ? {
15985
16576
  expoSwift: await (await Promise.resolve().then(() => (init_expo_swift_bundle(), expo_swift_bundle_exports))).buildExpoSwiftBundle(projectRoot)
15986
16577
  } : {
@@ -15992,7 +16583,7 @@ async function snapshotDevServerBundles(origin, projectRoot, { platforms = ["ios
15992
16583
  }
15993
16584
  async function snapshotOneDevBundle(projectRoot, env = {}) {
15994
16585
  const { spawn: spawn4 } = await import("node:child_process");
15995
- const { readFileSync: readFileSync5 } = await import("node:fs");
16586
+ const { readFileSync: readFileSync6 } = await import("node:fs");
15996
16587
  const { createServer } = await import("node:net");
15997
16588
  const { dirname: dirname2, join: join3 } = await import("node:path");
15998
16589
  const { createRequire: createRequire4 } = await import("node:module");
@@ -16001,7 +16592,7 @@ async function snapshotOneDevBundle(projectRoot, env = {}) {
16001
16592
  );
16002
16593
  const oneBin = join3(
16003
16594
  dirname2(onePackage),
16004
- JSON.parse(readFileSync5(onePackage, "utf8")).bin.one
16595
+ JSON.parse(readFileSync6(onePackage, "utf8")).bin.one
16005
16596
  );
16006
16597
  const port = await new Promise((resolve2, reject) => {
16007
16598
  const server = createServer().listen(0, "127.0.0.1", () => {