peachsim 0.1.637 → 0.1.639

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 (94) hide show
  1. package/README.md +8 -5
  2. package/cli/bridge-flow-runner.ts +442 -14
  3. package/cli/command-registry.ts +1 -0
  4. package/cli/commands/control.ts +42 -5
  5. package/cli/commands/inspect/core.ts +93 -24
  6. package/cli/commands/maestro.ts +2 -2
  7. package/cli/commands/serve.ts +13 -1
  8. package/cli/commands/swift.ts +326 -0
  9. package/cli/drivers/playwright-provisioning.ts +8 -16
  10. package/cli/drivers/playwright-sim-host.ts +3 -0
  11. package/cli/drivers/playwright.ts +1 -0
  12. package/cli/internal-child.ts +51 -8
  13. package/cli/main.ts +11 -0
  14. package/cli/outbound-endpoints.ts +5 -1
  15. package/dist-lib/agent-daemon-client.cjs +1 -1
  16. package/dist-lib/agent-events.cjs +1 -1
  17. package/dist-lib/agent-identity.cjs +1 -1
  18. package/dist-lib/agent-sessions.cjs +1 -1
  19. package/dist-lib/attached-projects.cjs +1 -1
  20. package/dist-lib/auth/shared-session.cjs +1 -1
  21. package/dist-lib/backend-origin.cjs +1 -1
  22. package/dist-lib/beta.cjs +1 -1
  23. package/dist-lib/beta.mjs +1 -1
  24. package/dist-lib/bridge-constants.cjs +1 -1
  25. package/dist-lib/bridge-contract-input.cjs +3 -2
  26. package/dist-lib/bridge-contract-input.mjs +3 -2
  27. package/dist-lib/bridge-contract.cjs +1 -1
  28. package/dist-lib/bridge-contract.mjs +1 -1
  29. package/dist-lib/capture-contract.cjs +1 -1
  30. package/dist-lib/capture-contract.mjs +1 -1
  31. package/dist-lib/cli-constants.cjs +1 -1
  32. package/dist-lib/cloud-contract.cjs +1 -1
  33. package/dist-lib/cloud-contract.mjs +1 -1
  34. package/dist-lib/cloud-test-args.cjs +1 -1
  35. package/dist-lib/cloud-test-args.mjs +1 -1
  36. package/dist-lib/cloud.cjs +1 -1
  37. package/dist-lib/cloud.mjs +1 -1
  38. package/dist-lib/config.cjs +1 -1
  39. package/dist-lib/detox/index.cjs +1 -1
  40. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  41. package/dist-lib/home-paths.cjs +1 -1
  42. package/dist-lib/host/bridge-host.cjs +4 -2
  43. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  44. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  45. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  46. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  47. package/dist-lib/host/websocket-proxy.cjs +1 -1
  48. package/dist-lib/index.cjs +88 -23
  49. package/dist-lib/jump-to-source-babel.cjs +1 -1
  50. package/dist-lib/jump-to-source-native.cjs +1 -1
  51. package/dist-lib/kotlin-host.cjs +1 -1
  52. package/dist-lib/menu.cjs +1 -1
  53. package/dist-lib/menu.mjs +1 -1
  54. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  55. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  56. package/dist-lib/metro-production-bundle.cjs +1 -1
  57. package/dist-lib/metro-production-bundle.mjs +1 -1
  58. package/dist-lib/metro.cjs +1 -1
  59. package/dist-lib/native-app-identity.cjs +1 -1
  60. package/dist-lib/native-app-identity.mjs +1 -1
  61. package/dist-lib/profiles.cjs +1 -1
  62. package/dist-lib/public-brand.cjs +1 -1
  63. package/dist-lib/react-native-host-modules.cjs +1 -1
  64. package/dist-lib/react-native-host-modules.mjs +1 -1
  65. package/dist-lib/render-mode.cjs +1 -1
  66. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  67. package/dist-lib/sdk.cjs +78 -20
  68. package/dist-lib/sdk.mjs +77 -20
  69. package/dist-lib/skills.cjs +441 -94
  70. package/dist-lib/swift-compile.cjs +89 -7
  71. package/dist-lib/swift-compile.mjs +89 -7
  72. package/dist-lib/swift-package.cjs +1 -1
  73. package/dist-lib/swift-package.mjs +1 -1
  74. package/dist-lib/swift-submit.cjs +89 -8
  75. package/dist-lib/swift-submit.mjs +78 -8
  76. package/dist-lib/swift.cjs +16 -33220
  77. package/dist-lib/vite-swift.cjs +510 -253
  78. package/dist-lib/vite.cjs +13 -4
  79. package/package.json +1 -1
  80. package/skills/contrast/SKILL.md +1 -0
  81. package/src/assetCatalogContract.ts +16 -0
  82. package/src/bridge-contract-input.ts +3 -2
  83. package/src/bridge-contract.ts +8 -0
  84. package/src/host/bridge-host.ts +5 -5
  85. package/src/metro-runtime-source.ts +15 -0
  86. package/src/native-seam-manifest.ts +4 -6
  87. package/src/swift-compile.ts +105 -9
  88. package/src/swift-guest.ts +51 -0
  89. package/src/swift-host.ts +900 -0
  90. package/src/swift-submit.ts +97 -6
  91. package/src/swift.ts +36 -8
  92. package/src/swiftContract.ts +52 -0
  93. package/src/vite-plugin-one.ts +4 -3
  94. package/src/vite-plugin-swift.ts +43 -755
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -321,7 +321,7 @@ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
321
321
  var MULTI_MANIFEST_VERSION = 5;
322
322
  function swiftArtifactHash(input, release, moduleRoot) {
323
323
  const hash = (0, import_node_crypto2.createHash)("sha256");
324
- hash.update(`swift-compile/v2
324
+ hash.update(`swift-compile/v3
325
325
  ${release}
326
326
  `);
327
327
  if (input.oneModule) hash.update("one-module\n");
@@ -421,13 +421,95 @@ function syncSwiftTree(base, files) {
421
421
  (0, import_node_fs2.writeFileSync)(full, contents, "utf8");
422
422
  }
423
423
  }
424
- var CONDITION_LINE = /^([ \t]*#(?:if|elseif)\b)(.*)$/gm;
424
+ var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
425
425
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
426
426
  function swiftSourceAsIOS(source) {
427
- return source.replace(
428
- CONDITION_LINE,
429
- (_, directive, condition) => directive + condition.replace(OS_IOS, (match) => "true".padEnd(match.length))
430
- );
427
+ const code = swiftCodeLineStarts(source);
428
+ let offset = 0;
429
+ return source.split("\n").map((line) => {
430
+ const start = offset;
431
+ offset += line.length + 1;
432
+ if (!code.has(start) || !DIRECTIVE.test(line)) return line;
433
+ return line.replace(OS_IOS, (match) => "true".padEnd(match.length));
434
+ }).join("\n");
435
+ }
436
+ function swiftCodeLineStarts(source) {
437
+ const starts = /* @__PURE__ */ new Set();
438
+ const stack = [{ kind: "code", parens: 0 }];
439
+ const hashesAt = (at) => {
440
+ let end = at;
441
+ while (source[end] === "#") end++;
442
+ return end - at;
443
+ };
444
+ const closes = (at, hashes) => source.startsWith("#".repeat(hashes), at);
445
+ let i = 0;
446
+ while (i < source.length) {
447
+ const top = stack[stack.length - 1];
448
+ if ((i === 0 || source[i - 1] === "\n") && top.kind === "code" && stack.length === 1)
449
+ starts.add(i);
450
+ const char = source[i];
451
+ if (top.kind === "block") {
452
+ if (source.startsWith("/*", i)) {
453
+ top.depth++;
454
+ i += 2;
455
+ } else if (source.startsWith("*/", i)) {
456
+ if (--top.depth === 0) stack.pop();
457
+ i += 2;
458
+ } else i++;
459
+ continue;
460
+ }
461
+ if (top.kind === "string") {
462
+ if (char === "\\" && closes(i + 1, top.hashes)) {
463
+ const after = i + 1 + top.hashes;
464
+ if (source[after] === "(") {
465
+ stack.push({ kind: "code", parens: 0 });
466
+ i = after + 1;
467
+ } else i = after + 1;
468
+ continue;
469
+ }
470
+ const quote = top.multiline ? '"""' : '"';
471
+ if (source.startsWith(quote, i) && closes(i + quote.length, top.hashes)) {
472
+ stack.pop();
473
+ i += quote.length + top.hashes;
474
+ } else i++;
475
+ continue;
476
+ }
477
+ if (top.kind === "regex") {
478
+ if (char === "/" && closes(i + 1, top.hashes)) {
479
+ stack.pop();
480
+ i += 1 + top.hashes;
481
+ } else i++;
482
+ continue;
483
+ }
484
+ if (source.startsWith("//", i)) {
485
+ const end = source.indexOf("\n", i);
486
+ i = end === -1 ? source.length : end;
487
+ } else if (source.startsWith("/*", i)) {
488
+ stack.push({ kind: "block", depth: 1 });
489
+ i += 2;
490
+ } else if (char === '"' || char === "#") {
491
+ const hashes = hashesAt(i);
492
+ const at = i + hashes;
493
+ if (source.startsWith('"""', at)) {
494
+ stack.push({ kind: "string", hashes, multiline: true });
495
+ i = at + 3;
496
+ } else if (source[at] === '"') {
497
+ stack.push({ kind: "string", hashes, multiline: false });
498
+ i = at + 1;
499
+ } else if (hashes > 0 && source[at] === "/") {
500
+ stack.push({ kind: "regex", hashes });
501
+ i = at + 1;
502
+ } else i = Math.max(at, i + 1);
503
+ } else if (char === "(") {
504
+ top.parens++;
505
+ i++;
506
+ } else if (char === ")") {
507
+ if (top.parens === 0 && stack.length > 1) stack.pop();
508
+ else top.parens--;
509
+ i++;
510
+ } else i++;
511
+ }
512
+ return starts;
431
513
  }
432
514
  var compiledSource = (file, contents) => file.endsWith(".swift") ? swiftSourceAsIOS(contents) : contents;
433
515
  function writeSwiftProject(layout, input, moduleRoot) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2 } from "node:child_process";
@@ -286,7 +286,7 @@ var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
286
286
  var MULTI_MANIFEST_VERSION = 5;
287
287
  function swiftArtifactHash(input, release, moduleRoot) {
288
288
  const hash = createHash2("sha256");
289
- hash.update(`swift-compile/v2
289
+ hash.update(`swift-compile/v3
290
290
  ${release}
291
291
  `);
292
292
  if (input.oneModule) hash.update("one-module\n");
@@ -386,13 +386,95 @@ function syncSwiftTree(base, files) {
386
386
  writeFileSync(full, contents, "utf8");
387
387
  }
388
388
  }
389
- var CONDITION_LINE = /^([ \t]*#(?:if|elseif)\b)(.*)$/gm;
389
+ var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
390
390
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
391
391
  function swiftSourceAsIOS(source) {
392
- return source.replace(
393
- CONDITION_LINE,
394
- (_, directive, condition) => directive + condition.replace(OS_IOS, (match) => "true".padEnd(match.length))
395
- );
392
+ const code = swiftCodeLineStarts(source);
393
+ let offset = 0;
394
+ return source.split("\n").map((line) => {
395
+ const start = offset;
396
+ offset += line.length + 1;
397
+ if (!code.has(start) || !DIRECTIVE.test(line)) return line;
398
+ return line.replace(OS_IOS, (match) => "true".padEnd(match.length));
399
+ }).join("\n");
400
+ }
401
+ function swiftCodeLineStarts(source) {
402
+ const starts = /* @__PURE__ */ new Set();
403
+ const stack = [{ kind: "code", parens: 0 }];
404
+ const hashesAt = (at) => {
405
+ let end = at;
406
+ while (source[end] === "#") end++;
407
+ return end - at;
408
+ };
409
+ const closes = (at, hashes) => source.startsWith("#".repeat(hashes), at);
410
+ let i = 0;
411
+ while (i < source.length) {
412
+ const top = stack[stack.length - 1];
413
+ if ((i === 0 || source[i - 1] === "\n") && top.kind === "code" && stack.length === 1)
414
+ starts.add(i);
415
+ const char = source[i];
416
+ if (top.kind === "block") {
417
+ if (source.startsWith("/*", i)) {
418
+ top.depth++;
419
+ i += 2;
420
+ } else if (source.startsWith("*/", i)) {
421
+ if (--top.depth === 0) stack.pop();
422
+ i += 2;
423
+ } else i++;
424
+ continue;
425
+ }
426
+ if (top.kind === "string") {
427
+ if (char === "\\" && closes(i + 1, top.hashes)) {
428
+ const after = i + 1 + top.hashes;
429
+ if (source[after] === "(") {
430
+ stack.push({ kind: "code", parens: 0 });
431
+ i = after + 1;
432
+ } else i = after + 1;
433
+ continue;
434
+ }
435
+ const quote = top.multiline ? '"""' : '"';
436
+ if (source.startsWith(quote, i) && closes(i + quote.length, top.hashes)) {
437
+ stack.pop();
438
+ i += quote.length + top.hashes;
439
+ } else i++;
440
+ continue;
441
+ }
442
+ if (top.kind === "regex") {
443
+ if (char === "/" && closes(i + 1, top.hashes)) {
444
+ stack.pop();
445
+ i += 1 + top.hashes;
446
+ } else i++;
447
+ continue;
448
+ }
449
+ if (source.startsWith("//", i)) {
450
+ const end = source.indexOf("\n", i);
451
+ i = end === -1 ? source.length : end;
452
+ } else if (source.startsWith("/*", i)) {
453
+ stack.push({ kind: "block", depth: 1 });
454
+ i += 2;
455
+ } else if (char === '"' || char === "#") {
456
+ const hashes = hashesAt(i);
457
+ const at = i + hashes;
458
+ if (source.startsWith('"""', at)) {
459
+ stack.push({ kind: "string", hashes, multiline: true });
460
+ i = at + 3;
461
+ } else if (source[at] === '"') {
462
+ stack.push({ kind: "string", hashes, multiline: false });
463
+ i = at + 1;
464
+ } else if (hashes > 0 && source[at] === "/") {
465
+ stack.push({ kind: "regex", hashes });
466
+ i = at + 1;
467
+ } else i = Math.max(at, i + 1);
468
+ } else if (char === "(") {
469
+ top.parens++;
470
+ i++;
471
+ } else if (char === ")") {
472
+ if (top.parens === 0 && stack.length > 1) stack.pop();
473
+ else top.parens--;
474
+ i++;
475
+ } else i++;
476
+ }
477
+ return starts;
396
478
  }
397
479
  var compiledSource = (file, contents) => file.endsWith(".swift") ? swiftSourceAsIOS(contents) : contents;
398
480
  function writeSwiftProject(layout, input, moduleRoot) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -22,15 +22,36 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/swift-submit.ts
23
23
  var swift_submit_exports = {};
24
24
  __export(swift_submit_exports, {
25
+ MAX_SWIFT_COMPILE_FILES: () => MAX_SWIFT_COMPILE_FILES,
26
+ MAX_SWIFT_COMPILE_IMAGES: () => MAX_SWIFT_COMPILE_IMAGES,
27
+ MAX_SWIFT_COMPILE_IMAGE_BYTES: () => MAX_SWIFT_COMPILE_IMAGE_BYTES,
28
+ MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES: () => MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES,
29
+ MAX_SWIFT_COMPILE_RESOURCES: () => MAX_SWIFT_COMPILE_RESOURCES,
30
+ MAX_SWIFT_COMPILE_RESOURCE_BYTES: () => MAX_SWIFT_COMPILE_RESOURCE_BYTES,
31
+ MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES: () => MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES,
32
+ MAX_SWIFT_COMPILE_SOURCE_BYTES: () => MAX_SWIFT_COMPILE_SOURCE_BYTES,
25
33
  SWIFT_COMPILE_PATH: () => SWIFT_COMPILE_PATH,
34
+ SWIFT_HMR_PATH: () => SWIFT_HMR_PATH,
26
35
  SWIFT_HOST_ABI: () => SWIFT_HOST_ABI,
36
+ SWIFT_PACKAGE_PATH: () => SWIFT_PACKAGE_PATH,
27
37
  compileSwiftProject: () => compileSwiftProject,
28
38
  httpSwiftCompileSubmit: () => httpSwiftCompileSubmit,
39
+ isSwiftNativeModules: () => isSwiftNativeModules,
29
40
  swiftNativeEntry: () => swiftNativeEntry
30
41
  });
31
42
  module.exports = __toCommonJS(swift_submit_exports);
32
43
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
33
- var SWIFT_HOST_ABI = 1;
44
+ var SWIFT_PACKAGE_PATH = "/__peach/swift-package/";
45
+ var SWIFT_HMR_PATH = "/__peach/swift-hmr";
46
+ var MAX_SWIFT_COMPILE_FILES = 256;
47
+ var MAX_SWIFT_COMPILE_SOURCE_BYTES = 2 * 1024 * 1024;
48
+ var MAX_SWIFT_COMPILE_RESOURCES = 128;
49
+ var MAX_SWIFT_COMPILE_RESOURCE_BYTES = 2 * 1024 * 1024;
50
+ var MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES = 8 * 1024 * 1024;
51
+ var MAX_SWIFT_COMPILE_IMAGES = 128;
52
+ var MAX_SWIFT_COMPILE_IMAGE_BYTES = 4 * 1024 * 1024;
53
+ var MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024;
54
+ var SWIFT_HOST_ABI = 2;
34
55
  var POLL_INTERVAL_MS = 1500;
35
56
  function swiftNativeEntry(native, file) {
36
57
  return {
@@ -51,6 +72,7 @@ function httpSwiftCompileSubmit(context) {
51
72
  try {
52
73
  response = await fetch(url, {
53
74
  method: "POST",
75
+ signal: context.signal,
54
76
  headers: {
55
77
  "content-type": "application/json",
56
78
  ...authorization ? { authorization } : {}
@@ -73,30 +95,78 @@ function httpSwiftCompileSubmit(context) {
73
95
  `contrast-bundler: the swift compile for ${work.entry} answered ${response.status}${detail ? `: ${detail}` : ""}`
74
96
  );
75
97
  }
76
- return await response.json();
98
+ const outcome = await response.json();
99
+ if (!isSwiftCompileOutcome(outcome)) {
100
+ throw new Error("swift compile: the service returned invalid artifact metadata");
101
+ }
102
+ return outcome;
77
103
  };
78
104
  }
105
+ function isRecord(value) {
106
+ return typeof value === "object" && value !== null && !Array.isArray(value);
107
+ }
108
+ function isSwiftNativeModules(value) {
109
+ return isRecord(value) && typeof value.packageId === "string" && typeof value.hash === "string" && isRecord(value.files) && isRecord(value.modules) && [...Object.values(value.files), ...Object.values(value.modules)].every(
110
+ (names) => Array.isArray(names) && names.every((name) => typeof name === "string")
111
+ ) && Array.isArray(value.defaultViewFiles) && value.defaultViewFiles.every((file) => typeof file === "string");
112
+ }
113
+ function isSwiftCompileOutcome(value) {
114
+ if (!isRecord(value)) return false;
115
+ switch (value.status) {
116
+ case "published":
117
+ return typeof value.artifactUrl === "string" && typeof value.icuUrl === "string" && typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash) && (value.imageUrls === void 0 || isRecord(value.imageUrls) && Object.values(value.imageUrls).every((url) => typeof url === "string")) && (value.native === void 0 || isSwiftNativeModules(value.native));
118
+ case "compiling":
119
+ return typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash);
120
+ case "refused":
121
+ case "failed":
122
+ return typeof value.detail === "string";
123
+ default:
124
+ return false;
125
+ }
126
+ }
127
+ function compileAssetUrl(value, origin) {
128
+ const url = new URL(value, origin);
129
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.origin !== new URL(origin).origin) {
130
+ throw new Error("swift compile: artifact address escapes the compile origin");
131
+ }
132
+ return url.href;
133
+ }
79
134
  function resolveImageUrls(urls, origin) {
80
135
  const resolved = {};
81
136
  for (const [name, url] of Object.entries(urls)) {
82
- resolved[name] = new URL(url, origin).href;
137
+ resolved[name] = compileAssetUrl(url, origin);
83
138
  }
84
139
  return resolved;
85
140
  }
86
- async function compileSwiftProject(submit, work, origin) {
141
+ async function compileSwiftProject(submit, work, origin, signal) {
87
142
  while (true) {
143
+ signal?.throwIfAborted();
88
144
  const outcome = await submit(work);
89
145
  switch (outcome.status) {
90
146
  case "published":
91
147
  return {
92
- url: new URL(outcome.artifactUrl, origin).href,
148
+ url: compileAssetUrl(outcome.artifactUrl, origin),
93
149
  hash: outcome.hash,
94
- icuUrl: new URL(outcome.icuUrl, origin).href,
150
+ icuUrl: compileAssetUrl(outcome.icuUrl, origin),
95
151
  ...outcome.imageUrls === void 0 ? {} : { imageUrls: resolveImageUrls(outcome.imageUrls, origin) },
96
152
  ...outcome.native === void 0 ? {} : { native: outcome.native }
97
153
  };
98
154
  case "compiling":
99
- await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
155
+ await new Promise((resolve, reject) => {
156
+ const finish = () => {
157
+ signal?.removeEventListener("abort", abort);
158
+ resolve();
159
+ };
160
+ const timer = setTimeout(finish, POLL_INTERVAL_MS);
161
+ const abort = () => {
162
+ clearTimeout(timer);
163
+ signal?.removeEventListener("abort", abort);
164
+ const reason = signal?.reason;
165
+ reject(reason instanceof Error ? reason : new Error(String(reason)));
166
+ };
167
+ signal?.addEventListener("abort", abort, { once: true });
168
+ if (signal?.aborted) abort();
169
+ });
100
170
  continue;
101
171
  case "refused":
102
172
  case "failed":
@@ -108,9 +178,20 @@ async function compileSwiftProject(submit, work, origin) {
108
178
  }
109
179
  // Annotate the CommonJS export names for ESM import in node:
110
180
  0 && (module.exports = {
181
+ MAX_SWIFT_COMPILE_FILES,
182
+ MAX_SWIFT_COMPILE_IMAGES,
183
+ MAX_SWIFT_COMPILE_IMAGE_BYTES,
184
+ MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES,
185
+ MAX_SWIFT_COMPILE_RESOURCES,
186
+ MAX_SWIFT_COMPILE_RESOURCE_BYTES,
187
+ MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES,
188
+ MAX_SWIFT_COMPILE_SOURCE_BYTES,
111
189
  SWIFT_COMPILE_PATH,
190
+ SWIFT_HMR_PATH,
112
191
  SWIFT_HOST_ABI,
192
+ SWIFT_PACKAGE_PATH,
113
193
  compileSwiftProject,
114
194
  httpSwiftCompileSubmit,
195
+ isSwiftNativeModules,
115
196
  swiftNativeEntry
116
197
  });
@@ -1,8 +1,18 @@
1
- /*! rnx v0.1.637 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.639 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-submit.ts
4
4
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
5
- var SWIFT_HOST_ABI = 1;
5
+ var SWIFT_PACKAGE_PATH = "/__peach/swift-package/";
6
+ var SWIFT_HMR_PATH = "/__peach/swift-hmr";
7
+ var MAX_SWIFT_COMPILE_FILES = 256;
8
+ var MAX_SWIFT_COMPILE_SOURCE_BYTES = 2 * 1024 * 1024;
9
+ var MAX_SWIFT_COMPILE_RESOURCES = 128;
10
+ var MAX_SWIFT_COMPILE_RESOURCE_BYTES = 2 * 1024 * 1024;
11
+ var MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES = 8 * 1024 * 1024;
12
+ var MAX_SWIFT_COMPILE_IMAGES = 128;
13
+ var MAX_SWIFT_COMPILE_IMAGE_BYTES = 4 * 1024 * 1024;
14
+ var MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024;
15
+ var SWIFT_HOST_ABI = 2;
6
16
  var POLL_INTERVAL_MS = 1500;
7
17
  function swiftNativeEntry(native, file) {
8
18
  return {
@@ -23,6 +33,7 @@ function httpSwiftCompileSubmit(context) {
23
33
  try {
24
34
  response = await fetch(url, {
25
35
  method: "POST",
36
+ signal: context.signal,
26
37
  headers: {
27
38
  "content-type": "application/json",
28
39
  ...authorization ? { authorization } : {}
@@ -45,30 +56,78 @@ function httpSwiftCompileSubmit(context) {
45
56
  `contrast-bundler: the swift compile for ${work.entry} answered ${response.status}${detail ? `: ${detail}` : ""}`
46
57
  );
47
58
  }
48
- return await response.json();
59
+ const outcome = await response.json();
60
+ if (!isSwiftCompileOutcome(outcome)) {
61
+ throw new Error("swift compile: the service returned invalid artifact metadata");
62
+ }
63
+ return outcome;
49
64
  };
50
65
  }
66
+ function isRecord(value) {
67
+ return typeof value === "object" && value !== null && !Array.isArray(value);
68
+ }
69
+ function isSwiftNativeModules(value) {
70
+ return isRecord(value) && typeof value.packageId === "string" && typeof value.hash === "string" && isRecord(value.files) && isRecord(value.modules) && [...Object.values(value.files), ...Object.values(value.modules)].every(
71
+ (names) => Array.isArray(names) && names.every((name) => typeof name === "string")
72
+ ) && Array.isArray(value.defaultViewFiles) && value.defaultViewFiles.every((file) => typeof file === "string");
73
+ }
74
+ function isSwiftCompileOutcome(value) {
75
+ if (!isRecord(value)) return false;
76
+ switch (value.status) {
77
+ case "published":
78
+ return typeof value.artifactUrl === "string" && typeof value.icuUrl === "string" && typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash) && (value.imageUrls === void 0 || isRecord(value.imageUrls) && Object.values(value.imageUrls).every((url) => typeof url === "string")) && (value.native === void 0 || isSwiftNativeModules(value.native));
79
+ case "compiling":
80
+ return typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash);
81
+ case "refused":
82
+ case "failed":
83
+ return typeof value.detail === "string";
84
+ default:
85
+ return false;
86
+ }
87
+ }
88
+ function compileAssetUrl(value, origin) {
89
+ const url = new URL(value, origin);
90
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.origin !== new URL(origin).origin) {
91
+ throw new Error("swift compile: artifact address escapes the compile origin");
92
+ }
93
+ return url.href;
94
+ }
51
95
  function resolveImageUrls(urls, origin) {
52
96
  const resolved = {};
53
97
  for (const [name, url] of Object.entries(urls)) {
54
- resolved[name] = new URL(url, origin).href;
98
+ resolved[name] = compileAssetUrl(url, origin);
55
99
  }
56
100
  return resolved;
57
101
  }
58
- async function compileSwiftProject(submit, work, origin) {
102
+ async function compileSwiftProject(submit, work, origin, signal) {
59
103
  while (true) {
104
+ signal?.throwIfAborted();
60
105
  const outcome = await submit(work);
61
106
  switch (outcome.status) {
62
107
  case "published":
63
108
  return {
64
- url: new URL(outcome.artifactUrl, origin).href,
109
+ url: compileAssetUrl(outcome.artifactUrl, origin),
65
110
  hash: outcome.hash,
66
- icuUrl: new URL(outcome.icuUrl, origin).href,
111
+ icuUrl: compileAssetUrl(outcome.icuUrl, origin),
67
112
  ...outcome.imageUrls === void 0 ? {} : { imageUrls: resolveImageUrls(outcome.imageUrls, origin) },
68
113
  ...outcome.native === void 0 ? {} : { native: outcome.native }
69
114
  };
70
115
  case "compiling":
71
- await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
116
+ await new Promise((resolve, reject) => {
117
+ const finish = () => {
118
+ signal?.removeEventListener("abort", abort);
119
+ resolve();
120
+ };
121
+ const timer = setTimeout(finish, POLL_INTERVAL_MS);
122
+ const abort = () => {
123
+ clearTimeout(timer);
124
+ signal?.removeEventListener("abort", abort);
125
+ const reason = signal?.reason;
126
+ reject(reason instanceof Error ? reason : new Error(String(reason)));
127
+ };
128
+ signal?.addEventListener("abort", abort, { once: true });
129
+ if (signal?.aborted) abort();
130
+ });
72
131
  continue;
73
132
  case "refused":
74
133
  case "failed":
@@ -79,9 +138,20 @@ async function compileSwiftProject(submit, work, origin) {
79
138
  }
80
139
  }
81
140
  export {
141
+ MAX_SWIFT_COMPILE_FILES,
142
+ MAX_SWIFT_COMPILE_IMAGES,
143
+ MAX_SWIFT_COMPILE_IMAGE_BYTES,
144
+ MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES,
145
+ MAX_SWIFT_COMPILE_RESOURCES,
146
+ MAX_SWIFT_COMPILE_RESOURCE_BYTES,
147
+ MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES,
148
+ MAX_SWIFT_COMPILE_SOURCE_BYTES,
82
149
  SWIFT_COMPILE_PATH,
150
+ SWIFT_HMR_PATH,
83
151
  SWIFT_HOST_ABI,
152
+ SWIFT_PACKAGE_PATH,
84
153
  compileSwiftProject,
85
154
  httpSwiftCompileSubmit,
155
+ isSwiftNativeModules,
86
156
  swiftNativeEntry
87
157
  };