peachsim 0.1.646 → 0.1.648

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 (70) hide show
  1. package/cli/desktop-companion.ts +48 -8
  2. package/cli/drivers/electron.ts +1 -3
  3. package/dist-lib/agent-daemon-client.cjs +1 -1
  4. package/dist-lib/agent-events.cjs +1 -1
  5. package/dist-lib/agent-identity.cjs +1 -1
  6. package/dist-lib/agent-sessions.cjs +1 -1
  7. package/dist-lib/attached-projects.cjs +1 -1
  8. package/dist-lib/auth/shared-session.cjs +1 -1
  9. package/dist-lib/backend-origin.cjs +1 -1
  10. package/dist-lib/beta.cjs +1 -1
  11. package/dist-lib/beta.mjs +1 -1
  12. package/dist-lib/bridge-constants.cjs +1 -1
  13. package/dist-lib/bridge-contract-input.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.mjs +1 -1
  15. package/dist-lib/bridge-contract.cjs +1 -1
  16. package/dist-lib/bridge-contract.mjs +1 -1
  17. package/dist-lib/capture-contract.cjs +1 -1
  18. package/dist-lib/capture-contract.mjs +1 -1
  19. package/dist-lib/cli-constants.cjs +1 -1
  20. package/dist-lib/cloud-contract.cjs +1 -1
  21. package/dist-lib/cloud-contract.mjs +1 -1
  22. package/dist-lib/cloud-test-args.cjs +1 -1
  23. package/dist-lib/cloud-test-args.mjs +1 -1
  24. package/dist-lib/cloud.cjs +1 -1
  25. package/dist-lib/cloud.mjs +1 -1
  26. package/dist-lib/config.cjs +1 -1
  27. package/dist-lib/detox/index.cjs +1 -1
  28. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  29. package/dist-lib/home-paths.cjs +1 -1
  30. package/dist-lib/host/bridge-host.cjs +1 -1
  31. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  32. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  33. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  34. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  35. package/dist-lib/host/websocket-proxy.cjs +1 -1
  36. package/dist-lib/index.cjs +1 -1
  37. package/dist-lib/jump-to-source-babel.cjs +1 -1
  38. package/dist-lib/jump-to-source-native.cjs +1 -1
  39. package/dist-lib/kotlin-host.cjs +1 -1
  40. package/dist-lib/menu.cjs +1 -1
  41. package/dist-lib/menu.mjs +1 -1
  42. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  43. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  44. package/dist-lib/metro-production-bundle.cjs +1 -1
  45. package/dist-lib/metro-production-bundle.mjs +1 -1
  46. package/dist-lib/metro.cjs +1 -1
  47. package/dist-lib/native-app-identity.cjs +1 -1
  48. package/dist-lib/native-app-identity.mjs +1 -1
  49. package/dist-lib/profiles.cjs +1 -1
  50. package/dist-lib/public-brand.cjs +1 -1
  51. package/dist-lib/react-native-host-modules.cjs +1 -1
  52. package/dist-lib/react-native-host-modules.mjs +1 -1
  53. package/dist-lib/render-mode.cjs +1 -1
  54. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  55. package/dist-lib/sdk.cjs +1 -1
  56. package/dist-lib/sdk.mjs +1 -1
  57. package/dist-lib/skills.cjs +24 -8
  58. package/dist-lib/swift-compile.cjs +15 -3
  59. package/dist-lib/swift-compile.mjs +15 -3
  60. package/dist-lib/swift-package.cjs +1 -1
  61. package/dist-lib/swift-package.mjs +1 -1
  62. package/dist-lib/swift-submit.cjs +2 -2
  63. package/dist-lib/swift-submit.mjs +2 -2
  64. package/dist-lib/swift.cjs +1 -1
  65. package/dist-lib/vite-swift.cjs +1067 -1052
  66. package/dist-lib/vite.cjs +1 -1
  67. package/package.json +1 -1
  68. package/src/swift-compile.ts +31 -7
  69. package/src/swift-submit.ts +3 -1
  70. package/src/vite-plugin-swift.ts +10 -6
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.646 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.648 | (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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.646",
3
+ "version": "0.1.648",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for peach.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -229,9 +229,10 @@ export function swiftArtifactHash(
229
229
  moduleRoot: string,
230
230
  ): string {
231
231
  const hash = createHash('sha256')
232
- // v5: a target declaring resources gets SwiftPM's Bundle.module accessor
233
- // (v4: sources compile through swiftSourceAsIOS)
234
- hash.update(`swift-compile/v5\n${release}\n`)
232
+ // v6: app and scene delegate classes compile final
233
+ // (v5: a target declaring resources gets SwiftPM's Bundle.module accessor;
234
+ // v4: sources compile through swiftSourceAsIOS)
235
+ hash.update(`swift-compile/v6\n${release}\n`)
235
236
  if (input.oneModule) hash.update('one-module\n')
236
237
  hash.update(linkedModuleDigest(moduleRoot))
237
238
  for (const file of Object.keys(input.files).sort()) {
@@ -361,11 +362,19 @@ function syncSwiftTree(base: string, files: Map<string, string>): void {
361
362
  // `@objcMembers` `@ObjCMembers`, `@IBAction` `@ObjC` padded, and `#selector(`
362
363
  // `#Selector(`: the module's macros that expose a method to selector dispatch
363
364
  // (plans/peach/uikit-shell.md, gate B). all keep their width except an
364
- // explicit `@objc(name:)`, whose name becomes a string argument.
365
+ // explicit `@objc(name:)`, whose name becomes a string argument, and a
366
+ // delegate class that becomes final (below).
365
367
  const DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/
366
368
  const OS_IOS = /\bos\(\s*iOS\s*\)/g
367
369
  const OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/
368
370
  const SELECTOR = /^#selector\b/
371
+ // uikit makes app and scene delegates from their class through the objc
372
+ // runtime; here their protocols require init(), which a non-final class
373
+ // meets only with a required one. a class declaring one of them that is
374
+ // neither final nor open becomes final, and subclassing it fails to
375
+ // compile naming itself.
376
+ const DELEGATE_CLASS =
377
+ /^class\s+[A-Za-z_]\w*\s*(?:<[^>{]*>)?\s*:[^{]*\b(?:UIApplicationDelegate|UISceneDelegate|UIWindowSceneDelegate)\b[^{]*\{/
369
378
  export function swiftSourceAsIOS(source: string): string {
370
379
  const { lineStarts, tokens } = swiftCodeScan(source)
371
380
  let offset = 0
@@ -382,7 +391,15 @@ export function swiftSourceAsIOS(source: string): string {
382
391
  let out = ''
383
392
  let copied = 0
384
393
  for (const at of tokens) {
385
- const rest = conditioned.slice(at, at + 200)
394
+ const rest = conditioned.slice(at, at + 400)
395
+ if (rest.startsWith('class')) {
396
+ const modifiers = conditioned.slice(conditioned.lastIndexOf('\n', at - 1) + 1, at)
397
+ if (DELEGATE_CLASS.test(rest) && !/\b(?:final|open)\b/.test(modifiers)) {
398
+ out += `${conditioned.slice(copied, at)}final `
399
+ copied = at
400
+ }
401
+ continue
402
+ }
386
403
  const selector = SELECTOR.exec(rest)
387
404
  const match = selector ?? OBJC_ATTRIBUTE.exec(rest)
388
405
  if (!match) continue
@@ -398,8 +415,8 @@ export function swiftSourceAsIOS(source: string): string {
398
415
  return out + conditioned.slice(copied)
399
416
  }
400
417
 
401
- // the offsets of the lines that begin in code, and of every `@` and `#` that
402
- // stands in code (an interpolation's code included), from a scan of Swift's
418
+ // the offsets of the lines that begin in code, and of every `@`, `#` and
419
+ // `class` keyword that stands in code (an interpolation's code included), from a scan of Swift's
403
420
  // lexical contexts: nested block comments, line comments, string literals (single and
404
421
  // multiline, raw with any number of #, interpolations holding code and
405
422
  // strings of their own) and #/ /# regex literals. a bare /regex/ literal
@@ -487,6 +504,13 @@ function swiftCodeScan(source: string): { lineStarts: Set<number>; tokens: numbe
487
504
  if (top.parens === 0 && stack.length > 1) stack.pop()
488
505
  else top.parens--
489
506
  i++
507
+ } else if (
508
+ source.startsWith('class', i) &&
509
+ !/[\w$]/.test(source[i - 1] ?? '') &&
510
+ !/[\w$]/.test(source[i + 5] ?? '')
511
+ ) {
512
+ tokens.push(i)
513
+ i += 5
490
514
  } else {
491
515
  if (char === '@') tokens.push(i)
492
516
  i++
@@ -44,8 +44,10 @@ export const MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024
44
44
  * `peach.icu_data_v1` (`packages/sootsim-swift/src/icuData.ts`). a request
45
45
  * without one comes from before this field, a host that is 0.
46
46
  * 2: scroll anchors carry numeric unit coordinates to the kit.
47
+ * 3: the host provides `rnx.measure_text`, UIKitCore's synchronous text
48
+ * measure (`packages/sootsim-swift/src/mount.tsx`).
47
49
  */
48
- export const SWIFT_HOST_ABI = 2
50
+ export const SWIFT_HOST_ABI = 3
49
51
 
50
52
  export interface SwiftImageUpload {
51
53
  /** the raster file picked for the asset (has the extension). */
@@ -2,6 +2,7 @@
2
2
  import fs from 'node:fs'
3
3
  import path from 'node:path'
4
4
  import { swiftEntryModuleEsm } from '../../sootsim-swift/src/entryModule'
5
+ import { swiftModuleInputFiles } from './swift-compile'
5
6
  import {
6
7
  artifactFor,
7
8
  entryRootId,
@@ -133,12 +134,15 @@ export function swiftPlugin(options: SwiftPluginOptions = {}): Plugin {
133
134
  this.addWatchFile(source)
134
135
  this.addWatchFile(path.join(packagePath, 'Package.swift'))
135
136
  // an edit to the linked SwiftUI module rebuilds the artifact without
136
- // touching the project's own sources, so those files gate the reload
137
- // too: the new hash in the emitted module is what tells the mount it
138
- // is looking at a different app.
139
- for (const root of linkedModuleRoots(packagePath)) {
140
- for (const source of sourceFiles(root)) this.addWatchFile(source)
141
- }
137
+ // touching the project's own sources, so the module inputs the source
138
+ // stamp hashes gate the reload too. the module is never uploaded, so
139
+ // the compile service's source caps do not apply to it.
140
+ const moduleRoot = linkedModuleRoots(packagePath).find((root) =>
141
+ fs.existsSync(path.join(root, 'toolchain.json')),
142
+ )
143
+ if (moduleRoot)
144
+ for (const relative of swiftModuleInputFiles(moduleRoot))
145
+ this.addWatchFile(path.join(moduleRoot, relative))
142
146
  let artifact: SwiftArtifact
143
147
  try {
144
148
  artifact = await artifactFor(project, entry)