peachsim 0.1.1469 → 0.1.1481

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 (102) hide show
  1. package/cli/commands/control.ts +68 -42
  2. package/cli/commands/detox.ts +15 -10
  3. package/cli/commands/flow.ts +1 -2
  4. package/cli/commands/inspect/settling.ts +5 -1
  5. package/cli/commands/setup.ts +20 -13
  6. package/cli/commands/test.ts +2 -1
  7. package/cli/dev-build-freshness.ts +14 -14
  8. package/cli/drivers/playwright-sim-host.ts +7 -2
  9. package/cli/drivers/playwright.ts +6 -6
  10. package/cli/outbound-endpoints.ts +80 -6
  11. package/detox/index.ts +27 -14
  12. package/detox/matchers.ts +17 -6
  13. package/dist-lib/agent-daemon-client.cjs +1 -1
  14. package/dist-lib/agent-events.cjs +1 -1
  15. package/dist-lib/attached-projects.cjs +1 -1
  16. package/dist-lib/auth/shared-session.cjs +1 -1
  17. package/dist-lib/backend-origin.cjs +1 -1
  18. package/dist-lib/beta.cjs +1 -1
  19. package/dist-lib/beta.mjs +1 -1
  20. package/dist-lib/bridge-constants.cjs +1 -1
  21. package/dist-lib/bridge-contract-input.cjs +1 -1
  22. package/dist-lib/bridge-contract-input.mjs +1 -1
  23. package/dist-lib/bridge-contract.cjs +1 -1
  24. package/dist-lib/bridge-contract.mjs +1 -1
  25. package/dist-lib/bundle-channel.cjs +54 -15
  26. package/dist-lib/capture-contract.cjs +1 -1
  27. package/dist-lib/capture-contract.mjs +1 -1
  28. package/dist-lib/cloud-contract.cjs +1 -1
  29. package/dist-lib/cloud-contract.mjs +1 -1
  30. package/dist-lib/cloud-test-args.cjs +1 -1
  31. package/dist-lib/cloud-test-args.mjs +1 -1
  32. package/dist-lib/cloud.cjs +1 -1
  33. package/dist-lib/cloud.mjs +1 -1
  34. package/dist-lib/config.cjs +19 -3
  35. package/dist-lib/config.mjs +19 -3
  36. package/dist-lib/detox/index.cjs +125 -52
  37. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  38. package/dist-lib/expo-swift-bundle.cjs +30 -9
  39. package/dist-lib/expo-swift-metadata.cjs +18 -6
  40. package/dist-lib/expo-swift-metadata.mjs +18 -6
  41. package/dist-lib/home-paths.cjs +1 -1
  42. package/dist-lib/host/bridge-host.cjs +621 -390
  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 +46 -19
  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 +24 -6
  57. package/dist-lib/metro-production-bundle.mjs +22 -6
  58. package/dist-lib/metro.cjs +41 -18
  59. package/dist-lib/native-app-identity-project.cjs +1 -1
  60. package/dist-lib/native-app-identity-project.mjs +1 -1
  61. package/dist-lib/native-app-identity.cjs +19 -5
  62. package/dist-lib/native-app-identity.mjs +19 -5
  63. package/dist-lib/native-firebase-metadata.cjs +22 -7
  64. package/dist-lib/native-firebase-metadata.mjs +20 -7
  65. package/dist-lib/plist.cjs +1 -1
  66. package/dist-lib/plist.mjs +1 -1
  67. package/dist-lib/profiles.cjs +1 -1
  68. package/dist-lib/public-brand.cjs +1 -1
  69. package/dist-lib/react-native-host-modules.cjs +3 -1
  70. package/dist-lib/react-native-host-modules.mjs +3 -1
  71. package/dist-lib/scripts/dev-server-scanner.cjs +404 -279
  72. package/dist-lib/sdk.cjs +6 -2
  73. package/dist-lib/sdk.mjs +6 -2
  74. package/dist-lib/skills.cjs +757 -531
  75. package/dist-lib/swift-compile.cjs +7 -2
  76. package/dist-lib/swift-compile.mjs +7 -2
  77. package/dist-lib/swift-package.cjs +1 -1
  78. package/dist-lib/swift-package.mjs +1 -1
  79. package/dist-lib/swift-submit.cjs +1 -1
  80. package/dist-lib/swift-submit.mjs +1 -1
  81. package/dist-lib/swift-toolchain.cjs +1 -1
  82. package/dist-lib/swift.cjs +1 -1
  83. package/dist-lib/vite-swift.cjs +7 -2
  84. package/dist-lib/vite.cjs +1 -1
  85. package/dist-lib/worklet-executable.cjs +27 -7
  86. package/dist-lib/worklet-executable.mjs +27 -7
  87. package/package.json +1 -1
  88. package/scripts/dev-server-scanner.ts +493 -188
  89. package/src/admitted-mac-build.ts +12 -0
  90. package/src/bridge-constants.ts +5 -3
  91. package/src/bundleGlobalFooter.ts +26 -3
  92. package/src/config.ts +3 -2
  93. package/src/configured-bundle-producer.ts +2 -1
  94. package/src/expo-swift-host.ts +33 -7
  95. package/src/host/bridge-host.ts +34 -6
  96. package/src/metro-production-bundle.ts +11 -4
  97. package/src/native-app-identity.ts +3 -2
  98. package/src/native-firebase-metadata.ts +5 -3
  99. package/src/react-native-host-modules.ts +2 -0
  100. package/src/swift-compile.ts +5 -4
  101. package/src/worker-system-chunks.ts +61 -58
  102. package/src/worklet-executable.ts +38 -6
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (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;
@@ -1366,30 +1366,14 @@ var os = __toESM(require("node:os"), 1);
1366
1366
  var path = __toESM(require("node:path"), 1);
1367
1367
 
1368
1368
  // ../../scripts/lib/chromium-admission.ts
1369
- async function acquireChromiumAdmission(deps) {
1370
- const { fs: fs3, os: os2, path: path3, childProcess: childProcess2, label } = deps;
1369
+ function readChromiumQueue(deps, verified, own) {
1370
+ const { fs: fs3, os: os2, path: path3, childProcess: childProcess2 } = deps;
1371
1371
  const dir = path3.join(
1372
1372
  process.platform === "win32" ? os2.tmpdir() : "/tmp",
1373
1373
  "chromium-admission"
1374
1374
  );
1375
1375
  fs3.mkdirSync(dir, { recursive: true });
1376
- const limit = Math.max(2, Math.floor(os2.availableParallelism() / 3));
1377
- const startedAt = Math.round(Date.now() / 1e3 - process.uptime());
1378
- const name2 = `${process.pid}-${startedAt}-${Math.random().toString(36).slice(2, 10)}`;
1379
- const ticket = path3.join(dir, name2);
1380
- fs3.closeSync(fs3.openSync(ticket, "wx"));
1381
- let released = false;
1382
- const release = () => {
1383
- if (released) return;
1384
- released = true;
1385
- process.removeListener("exit", release);
1386
- try {
1387
- fs3.unlinkSync(ticket);
1388
- } catch {
1389
- }
1390
- };
1391
- process.on("exit", release);
1392
- const verified = /* @__PURE__ */ new Map();
1376
+ const limit = Math.max(2, Math.floor(os2.cpus().length / 3));
1393
1377
  const live = (entry) => {
1394
1378
  const match = /^(\d+)-(\d+)-/.exec(entry);
1395
1379
  if (!match) return false;
@@ -1413,29 +1397,50 @@ async function acquireChromiumAdmission(deps) {
1413
1397
  verified.set(entry, same);
1414
1398
  return same;
1415
1399
  };
1416
- let waited = false;
1417
- while (true) {
1418
- const tickets = [];
1419
- for (const entry of fs3.readdirSync(dir)) {
1420
- if (entry !== name2 && !live(entry)) {
1421
- try {
1422
- fs3.unlinkSync(path3.join(dir, entry));
1423
- } catch {
1424
- }
1425
- continue;
1426
- }
1400
+ const tickets = [];
1401
+ for (const entry of fs3.readdirSync(dir)) {
1402
+ if (entry !== own && !live(entry)) {
1427
1403
  try {
1428
- tickets.push({
1429
- entry,
1430
- created: fs3.statSync(path3.join(dir, entry), { bigint: true }).ctimeNs
1431
- });
1404
+ fs3.unlinkSync(path3.join(dir, entry));
1432
1405
  } catch {
1433
1406
  }
1407
+ continue;
1434
1408
  }
1435
- tickets.sort(
1436
- (a, b) => a.created === b.created ? a.entry < b.entry ? -1 : 1 : a.created < b.created ? -1 : 1
1437
- );
1438
- const rank = tickets.findIndex((t) => t.entry === name2);
1409
+ try {
1410
+ tickets.push({
1411
+ entry,
1412
+ created: fs3.statSync(path3.join(dir, entry), { bigint: true }).ctimeNs
1413
+ });
1414
+ } catch {
1415
+ }
1416
+ }
1417
+ tickets.sort(
1418
+ (a, b) => a.created === b.created ? a.entry < b.entry ? -1 : 1 : a.created < b.created ? -1 : 1
1419
+ );
1420
+ return { dir, limit, tickets: tickets.map((t) => t.entry) };
1421
+ }
1422
+ async function acquireChromiumAdmission(deps) {
1423
+ const { fs: fs3, path: path3, label, readQueue } = deps;
1424
+ const verified = /* @__PURE__ */ new Map();
1425
+ const startedAt = Math.round(Date.now() / 1e3 - process.uptime());
1426
+ const name2 = `${process.pid}-${startedAt}-${Math.random().toString(36).slice(2, 10)}`;
1427
+ const ticket = path3.join(readQueue(deps, verified, name2).dir, name2);
1428
+ fs3.closeSync(fs3.openSync(ticket, "wx"));
1429
+ let released = false;
1430
+ const release = () => {
1431
+ if (released) return;
1432
+ released = true;
1433
+ process.removeListener("exit", release);
1434
+ try {
1435
+ fs3.unlinkSync(ticket);
1436
+ } catch {
1437
+ }
1438
+ };
1439
+ process.on("exit", release);
1440
+ let waited = false;
1441
+ while (true) {
1442
+ const { limit, tickets } = readQueue(deps, verified, name2);
1443
+ const rank = tickets.indexOf(name2);
1439
1444
  if (rank < 0) {
1440
1445
  fs3.closeSync(fs3.openSync(ticket, "wx"));
1441
1446
  continue;
@@ -1446,7 +1451,7 @@ async function acquireChromiumAdmission(deps) {
1446
1451
  return release;
1447
1452
  }
1448
1453
  if (!waited) {
1449
- const holders = tickets.slice(0, limit).map((t) => t.entry.split("-")[0]);
1454
+ const holders = tickets.slice(0, limit).map((t) => t.split("-")[0]);
1450
1455
  process.stderr.write(
1451
1456
  `[chromium-admission] ${label}: ${limit} chromium launches already run on this machine (pids ${holders.join(" ")}), queued ${rank - limit + 1}
1452
1457
  `
@@ -1750,7 +1755,8 @@ async function launchReapedScoped(launch, readIdentity = processIdentity) {
1750
1755
  os,
1751
1756
  path,
1752
1757
  childProcess,
1753
- label: process.argv.slice(1, 3).join(" ")
1758
+ label: process.argv.slice(1, 3).join(" "),
1759
+ readQueue: readChromiumQueue
1754
1760
  });
1755
1761
  let browser;
1756
1762
  try {
@@ -2643,6 +2649,8 @@ async function automateWebViewFrames(context, names, helpers, tenantWorkers) {
2643
2649
  const browser = context.browser();
2644
2650
  if (!browser) throw new Error("webview automation needs the browser behind its context");
2645
2651
  const browserSession = await browser.newBrowserCDPSession();
2652
+ context.on("close", () => void browserSession.detach().catch(() => {
2653
+ }));
2646
2654
  const cookieOperations = helpers.cookieOperations();
2647
2655
  let nextNetworkDecision = 0;
2648
2656
  const byFrameId = /* @__PURE__ */ new Map();
@@ -4072,9 +4080,12 @@ ${WEBVIEW_FRAME_COLOR_SCHEME_SOURCE} var webKit = config.webKit || null;
4072
4080
  if (!lastEditable || !lastEditable.isConnected) return;
4073
4081
  var state = editorState(lastEditable);
4074
4082
  var candidate = payload.candidate;
4083
+ // a verbatim candidate still spells the word before the caret; an
4084
+ // empty-field prediction inserts into a still-empty editor.
4075
4085
  if (!candidate || state.selectionStart !== state.selectionEnd ||
4076
4086
  state.selectionEnd !== candidate.end || candidate.end !== state.text.length ||
4077
- state.text.slice(candidate.start, candidate.end) !== candidate.text) return;
4087
+ (candidate.start === candidate.end ? state.text.length !== 0 :
4088
+ state.text.slice(candidate.start, candidate.end) !== candidate.text)) return;
4078
4089
  if ('value' in lastEditable) lastEditable.setSelectionRange(candidate.start, candidate.end);
4079
4090
  else {
4080
4091
  var walker = document.createTreeWalker(lastEditable, NodeFilter.SHOW_TEXT);
@@ -8125,6 +8136,15 @@ var IOS_NAMED_FACES = [
8125
8136
  italic: false,
8126
8137
  metrics: SF_COMPACT_KEYCAP_METRICS
8127
8138
  },
8139
+ // no named instance carries the keycap grade at wght 400
8140
+ {
8141
+ family: SF_COMPACT_KEYCAP_FONT_FAMILY,
8142
+ postScript: ".SFCompact-LightG3-400",
8143
+ file: "sf-compact-keycaps-400.woff2",
8144
+ weight: 0,
8145
+ italic: false,
8146
+ metrics: { ...SF_COMPACT_KEYCAP_METRICS, capHeight: 1365, xHeight: 1049 }
8147
+ },
8128
8148
  {
8129
8149
  family: "Menlo",
8130
8150
  postScript: "Menlo-Regular",
@@ -8258,6 +8278,42 @@ var BOOT_FONT_URLS = [...BASE_FONT_URLS];
8258
8278
  var PLATFORM_FONT_FAMILIES = [DEFAULT_FONT_FAMILY, EMOJI_FONT_FAMILY];
8259
8279
  var _registeredFamilies = new Set(PLATFORM_FONT_FAMILIES);
8260
8280
 
8281
+ // ../peach-engine/src/engine/scroll-momentum-math.ts
8282
+ var IOS_STATUS_BAR_SCROLL_TO_TOP_RESPONSE_SECONDS = 0.6;
8283
+ var IOS_STATUS_BAR_SCROLL_TO_TOP_OMEGA = 2 * Math.PI / IOS_STATUS_BAR_SCROLL_TO_TOP_RESPONSE_SECONDS;
8284
+ var IOS_STATUS_BAR_SCROLL_TO_TOP_CONTROL_POINT_Y = Math.fround(0.2);
8285
+ var ANDROID_DECELERATION_RATE = Math.log(0.78) / Math.log(0.9);
8286
+ var ANDROID_FLING_INFLEXION = 0.35;
8287
+ var ANDROID_START_TENSION = 0.5;
8288
+ var ANDROID_END_TENSION = 1;
8289
+ var ANDROID_SPLINE_P1 = ANDROID_START_TENSION * ANDROID_FLING_INFLEXION;
8290
+ var ANDROID_SPLINE_P2 = 1 - ANDROID_END_TENSION * (1 - ANDROID_FLING_INFLEXION);
8291
+ var ANDROID_SPLINE_SAMPLES = 100;
8292
+ var ANDROID_PHYSICAL_COEFFICIENT = 9.80665 * 39.37 * 160 * 0.84;
8293
+ var ANDROID_SPLINE_POSITION = createAndroidSplinePosition();
8294
+ function createAndroidSplinePosition() {
8295
+ const position = Array.from({ length: ANDROID_SPLINE_SAMPLES + 1 }).fill(0);
8296
+ let xMin = 0;
8297
+ for (let i = 0; i < ANDROID_SPLINE_SAMPLES; i++) {
8298
+ const alpha = i / ANDROID_SPLINE_SAMPLES;
8299
+ let xMax = 1;
8300
+ let x = 0;
8301
+ let coefficient = 0;
8302
+ while (true) {
8303
+ x = xMin + (xMax - xMin) / 2;
8304
+ coefficient = 3 * x * (1 - x);
8305
+ const tx = coefficient * ((1 - x) * ANDROID_SPLINE_P1 + x * ANDROID_SPLINE_P2) + x * x * x;
8306
+ if (Math.abs(tx - alpha) < 1e-5) break;
8307
+ if (tx > alpha) xMax = x;
8308
+ else xMin = x;
8309
+ }
8310
+ position[i] = coefficient * ((1 - x) * ANDROID_START_TENSION + x) + x * x * x;
8311
+ }
8312
+ position[ANDROID_SPLINE_SAMPLES] = 1;
8313
+ return position;
8314
+ }
8315
+ var RESTING_FRAME_MS = 1e3 / 60;
8316
+
8261
8317
  // ../peach-engine/src/engine/scroll-platform.ts
8262
8318
  var IOS_SCROLL_AXIS_TANGENT = Math.sqrt(3);
8263
8319
  function scrollTouchSlop(platform, primaryDelta) {
@@ -9045,15 +9101,23 @@ var SootSimWaitForScrollAction = class {
9045
9101
  };
9046
9102
 
9047
9103
  // detox/matchers.ts
9104
+ function createMatcher(type, value) {
9105
+ if (typeof value === "string") return { type, value };
9106
+ return {
9107
+ type,
9108
+ value: value.source,
9109
+ regexFlags: value.flags.replace(/[^ims]/g, "") + "u"
9110
+ };
9111
+ }
9048
9112
  var by = {
9049
9113
  id(testID) {
9050
- return { type: "id", value: testID };
9114
+ return createMatcher("id", testID);
9051
9115
  },
9052
9116
  text(text) {
9053
- return { type: "text", value: text };
9117
+ return createMatcher("text", text);
9054
9118
  },
9055
9119
  label(accessibilityLabel) {
9056
- return { type: "label", value: accessibilityLabel };
9120
+ return createMatcher("label", accessibilityLabel);
9057
9121
  },
9058
9122
  type(nativeType) {
9059
9123
  return { type: "type", value: nativeType };
@@ -9692,13 +9756,21 @@ async function waitForSootsimIdle(page, maxMs = 3e3, strict = false, transitionS
9692
9756
  }
9693
9757
  async function findNodeByMatcher(matcher) {
9694
9758
  const page = getPage();
9695
- if (matcher.index !== void 0 || matcher.type === "text") {
9759
+ if (matcher.regexFlags !== void 0 || matcher.index !== void 0 || matcher.type === "text") {
9696
9760
  return page.evaluate(async (indexedMatcher) => {
9697
- const filter = indexedMatcher.type === "id" ? { hasId: indexedMatcher.value } : indexedMatcher.type === "text" ? { hasText: indexedMatcher.value } : indexedMatcher.type === "label" ? { hasLabel: indexedMatcher.value } : indexedMatcher.type === "role" ? { hasRole: indexedMatcher.value } : { type: indexedMatcher.value };
9761
+ const regex = indexedMatcher.regexFlags !== void 0 ? new RegExp(indexedMatcher.value, indexedMatcher.regexFlags) : null;
9762
+ const filter = regex ? {} : indexedMatcher.type === "id" ? { hasId: indexedMatcher.value } : indexedMatcher.type === "text" ? { hasText: indexedMatcher.value } : indexedMatcher.type === "label" ? { hasLabel: indexedMatcher.value } : indexedMatcher.type === "role" ? { hasRole: indexedMatcher.value } : { type: indexedMatcher.value };
9698
9763
  const results = await window.__sootsimTest.queryAll(filter);
9699
- const indexed = indexedMatcher.type === "text" ? results.filter(
9700
- (node) => (node.type === "text" || node.nodeId < 0) && node.text === indexedMatcher.value
9701
- ) : results;
9764
+ const indexed = results.filter((node) => {
9765
+ if (indexedMatcher.type === "text" && node.type !== "text" && node.nodeId >= 0)
9766
+ return false;
9767
+ if (!regex)
9768
+ return indexedMatcher.type !== "text" || node.text === indexedMatcher.value;
9769
+ const matches = (value) => typeof value === "string" && regex.test(value);
9770
+ if (indexedMatcher.type === "id") return matches(node.testID) || matches(node.id);
9771
+ if (indexedMatcher.type === "text") return matches(node.text);
9772
+ return matches(node.accessibilityLabel || (node.accessible ? node.text : null));
9773
+ });
9702
9774
  return indexed[indexedMatcher.index ?? 0] ?? null;
9703
9775
  }, matcher);
9704
9776
  }
@@ -10150,14 +10222,15 @@ function createSootSimElement(matcher) {
10150
10222
  async replaceText(text) {
10151
10223
  const page = getPage();
10152
10224
  const node = await findNodeByMatcher(matcher);
10153
- if (matcher.type === "id" && typeof node?.nodeId === "number" && node.nodeId >= 1073741824) {
10225
+ const resolvedId = node?.testID ?? node?.id;
10226
+ if (matcher.type === "id" && typeof resolvedId === "string" && typeof node?.nodeId === "number" && node.nodeId >= 1073741824) {
10154
10227
  const replaced = await page.evaluate(
10155
10228
  async ({ id, value: value2 }) => {
10156
10229
  const mainShell = window.SootSim?.bridges?.mainShell;
10157
10230
  if (typeof mainShell?.callTestBridge !== "function") return false;
10158
10231
  return mainShell.callTestBridge("replaceTextByTestId", id, value2);
10159
10232
  },
10160
- { id: matcher.value, value: text }
10233
+ { id: resolvedId, value: text }
10161
10234
  );
10162
10235
  if (replaced === true) return;
10163
10236
  }
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (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 __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (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;
@@ -1436,6 +1436,11 @@ var import_node_os = __toESM(require("node:os"), 1);
1436
1436
  var import_node_path2 = __toESM(require("node:path"), 1);
1437
1437
  var import_node_util2 = require("node:util");
1438
1438
 
1439
+ // src/admitted-mac-build.ts
1440
+ function admittedMacBuilderSlot(env = process.env) {
1441
+ return env.CONTRAST_REMOTE_BUILD === "mac" && env.REMOTE_MAC_SLOT_HELD === "1" && env.CONTRAST_HEAVY_ADMITTED === "1";
1442
+ }
1443
+
1439
1444
  // src/is-record.ts
1440
1445
  function isRecord(value) {
1441
1446
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -3745,7 +3750,7 @@ function compileSwiftProjectUnit(input, options) {
3745
3750
  };
3746
3751
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
3747
3752
  return serialize(root, async () => {
3748
- if (process.platform === "darwin" && process.env.TM_SESSION && !process.env.CONTRAST_REMOTE_BUILD && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3753
+ if (process.platform === "darwin" && process.env.TM_SESSION && !admittedMacBuilderSlot() && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3749
3754
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
3750
3755
  const output = import_node_path2.default.join(requestRoot, "output");
3751
3756
  const request = import_node_path2.default.join(requestRoot, "request.json");
@@ -9548,7 +9553,20 @@ ${[...new Set(units.map((unit) => unit.namespace))].map((namespace) => `import $
9548
9553
  }
9549
9554
  `;
9550
9555
  }
9551
- var failedCompilations = /* @__PURE__ */ new Map();
9556
+ function failureRecordPath(packagePath) {
9557
+ return `${packagePath}.failed.json`;
9558
+ }
9559
+ function readFailedCompilation(packagePath) {
9560
+ let record2;
9561
+ try {
9562
+ record2 = JSON.parse(import_node_fs15.default.readFileSync(failureRecordPath(packagePath), "utf8"));
9563
+ } catch {
9564
+ return null;
9565
+ }
9566
+ if (typeof record2 !== "object" || record2 === null || !("stamp" in record2) || !("diagnostic" in record2) || typeof record2.stamp !== "string" || typeof record2.diagnostic !== "string")
9567
+ return null;
9568
+ return { stamp: record2.stamp, diagnostic: record2.diagnostic };
9569
+ }
9552
9570
  async function compileExpoSwiftModules(root, base, publishArtifact) {
9553
9571
  const units = await collectExpoSwiftSources(root);
9554
9572
  if (!units) return null;
@@ -9584,12 +9602,12 @@ async function compileExpoSwiftModules(root, base, publishArtifact) {
9584
9602
  )
9585
9603
  );
9586
9604
  const stamp = sourceStamp(packagePath, module2.root);
9587
- const failed = failedCompilations.get(packagePath);
9605
+ const failed = readFailedCompilation(packagePath);
9588
9606
  if (failed?.stamp === stamp) {
9589
9607
  failures.set(unit.moduleId, failed.diagnostic);
9590
9608
  continue;
9591
9609
  }
9592
- failedCompilations.delete(packagePath);
9610
+ import_node_fs15.default.rmSync(failureRecordPath(packagePath), { force: true });
9593
9611
  stamps.set(unit, stamp);
9594
9612
  candidates.push(unit);
9595
9613
  }
@@ -9653,10 +9671,13 @@ let package = Package(name: "PeachExpo", targets: [${targets.map((name2) => `.ta
9653
9671
  throw error;
9654
9672
  const missing = error instanceof SwiftMissingModulesError;
9655
9673
  if ((sourceErrors.length && sourceErrors.length === errors.length || missing) && sourceStamp(packagePath, module2.root) === stamps.get(unit)) {
9656
- failedCompilations.set(packagePath, {
9657
- stamp: stamps.get(unit),
9658
- diagnostic: missing ? diagnostic : sourceErrors.join("\n")
9659
- });
9674
+ import_node_fs15.default.writeFileSync(
9675
+ failureRecordPath(packagePath),
9676
+ JSON.stringify({
9677
+ stamp: stamps.get(unit),
9678
+ diagnostic: missing ? diagnostic : sourceErrors.join("\n")
9679
+ })
9680
+ );
9660
9681
  }
9661
9682
  failures.set(
9662
9683
  unit.moduleId,
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (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 __defProp = Object.defineProperty;
@@ -30,10 +30,23 @@ __export(expoSwiftContract_exports, {
30
30
  module.exports = __toCommonJS(expoSwiftContract_exports);
31
31
 
32
32
  // src/bundleGlobalFooter.ts
33
+ function findBundleFooter(source, prefix) {
34
+ let end = source.length;
35
+ while (end > 0) {
36
+ const newline = source.lastIndexOf("\n", end - 1);
37
+ if (newline < 0) return -1;
38
+ const line = newline + 1;
39
+ if (source.startsWith(prefix, line)) return newline;
40
+ if (line !== end && !source.startsWith("globalThis.", line) && !source.startsWith("//", line)) {
41
+ return -1;
42
+ }
43
+ end = newline;
44
+ }
45
+ return -1;
46
+ }
33
47
  function readBundleGlobalFooter(source, name) {
34
48
  const prefix = `globalThis.${name}=`;
35
- const start = source.lastIndexOf(`
36
- ${prefix}`);
49
+ const start = findBundleFooter(source, prefix);
37
50
  if (start < 0) return null;
38
51
  const end = source.indexOf("\n", start + 1);
39
52
  const line = source.slice(start + 1, end < 0 ? void 0 : end);
@@ -44,8 +57,7 @@ ${prefix}`);
44
57
  }
45
58
  function insertBundleGlobalFooter(source, name, value) {
46
59
  const prefix = `globalThis.${name}=`;
47
- const start = source.lastIndexOf(`
48
- ${prefix}`);
60
+ const start = findBundleFooter(source, prefix);
49
61
  if (start >= 0) {
50
62
  readBundleGlobalFooter(source, name);
51
63
  const end = source.indexOf("\n", start + 1);
@@ -54,7 +66,7 @@ ${prefix}`);
54
66
  const json = JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
55
67
  const footer = `
56
68
  ${prefix}${json};`;
57
- const identity = source.lastIndexOf("\nglobalThis.__sootsimModulePaths=");
69
+ const identity = findBundleFooter(source, "globalThis.__sootsimModulePaths=");
58
70
  return identity < 0 ? source + footer : source.slice(0, identity) + footer + source.slice(identity);
59
71
  }
60
72
 
@@ -1,10 +1,23 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
 
3
3
  // src/bundleGlobalFooter.ts
4
+ function findBundleFooter(source, prefix) {
5
+ let end = source.length;
6
+ while (end > 0) {
7
+ const newline = source.lastIndexOf("\n", end - 1);
8
+ if (newline < 0) return -1;
9
+ const line = newline + 1;
10
+ if (source.startsWith(prefix, line)) return newline;
11
+ if (line !== end && !source.startsWith("globalThis.", line) && !source.startsWith("//", line)) {
12
+ return -1;
13
+ }
14
+ end = newline;
15
+ }
16
+ return -1;
17
+ }
4
18
  function readBundleGlobalFooter(source, name) {
5
19
  const prefix = `globalThis.${name}=`;
6
- const start = source.lastIndexOf(`
7
- ${prefix}`);
20
+ const start = findBundleFooter(source, prefix);
8
21
  if (start < 0) return null;
9
22
  const end = source.indexOf("\n", start + 1);
10
23
  const line = source.slice(start + 1, end < 0 ? void 0 : end);
@@ -15,8 +28,7 @@ ${prefix}`);
15
28
  }
16
29
  function insertBundleGlobalFooter(source, name, value) {
17
30
  const prefix = `globalThis.${name}=`;
18
- const start = source.lastIndexOf(`
19
- ${prefix}`);
31
+ const start = findBundleFooter(source, prefix);
20
32
  if (start >= 0) {
21
33
  readBundleGlobalFooter(source, name);
22
34
  const end = source.indexOf("\n", start + 1);
@@ -25,7 +37,7 @@ ${prefix}`);
25
37
  const json = JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
26
38
  const footer = `
27
39
  ${prefix}${json};`;
28
- const identity = source.lastIndexOf("\nglobalThis.__sootsimModulePaths=");
40
+ const identity = findBundleFooter(source, "globalThis.__sootsimModulePaths=");
29
41
  return identity < 0 ? source + footer : source.slice(0, identity) + footer + source.slice(identity);
30
42
  }
31
43
 
@@ -1,4 +1,4 @@
1
- /*! peach v0.1.1469 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
1
+ /*! peach v0.1.1481 | (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;