peachsim 0.1.2180 → 0.1.2185

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 (106) hide show
  1. package/cli/commands/shell-url.ts +28 -22
  2. package/cli/outbound-endpoints.ts +11 -1
  3. package/dist-lib/agent-daemon-client.cjs +1 -1
  4. package/dist-lib/agent-events.cjs +1 -1
  5. package/dist-lib/attached-projects.cjs +1 -1
  6. package/dist-lib/auth/shared-session.cjs +1 -1
  7. package/dist-lib/backend-origin.cjs +1 -1
  8. package/dist-lib/beta.cjs +1 -1
  9. package/dist-lib/beta.mjs +1 -1
  10. package/dist-lib/bridge-constants.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.mjs +1 -1
  13. package/dist-lib/bridge-contract.cjs +1 -1
  14. package/dist-lib/bridge-contract.mjs +1 -1
  15. package/dist-lib/bundle-channel.cjs +457 -96
  16. package/dist-lib/capture-contract.cjs +1 -1
  17. package/dist-lib/capture-contract.mjs +1 -1
  18. package/dist-lib/cloud-contract.cjs +1 -1
  19. package/dist-lib/cloud-contract.mjs +1 -1
  20. package/dist-lib/cloud-test-args.cjs +1 -1
  21. package/dist-lib/cloud-test-args.mjs +1 -1
  22. package/dist-lib/cloud.cjs +1 -1
  23. package/dist-lib/cloud.mjs +1 -1
  24. package/dist-lib/config.cjs +1 -1
  25. package/dist-lib/config.mjs +1 -1
  26. package/dist-lib/detox/index.cjs +1 -1
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/expo-swift-bundle.cjs +352 -58
  29. package/dist-lib/expo-swift-metadata.cjs +1 -1
  30. package/dist-lib/expo-swift-metadata.mjs +1 -1
  31. package/dist-lib/home-paths.cjs +1 -1
  32. package/dist-lib/host/bridge-host.cjs +415 -85
  33. package/dist-lib/host/fetch-proxy-handler.cjs +7 -4
  34. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  36. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  37. package/dist-lib/host/websocket-proxy.cjs +1 -1
  38. package/dist-lib/index.cjs +7 -4
  39. package/dist-lib/jump-to-source-babel.cjs +1 -1
  40. package/dist-lib/jump-to-source-native.cjs +1 -1
  41. package/dist-lib/kotlin-host.cjs +1 -1
  42. package/dist-lib/menu.cjs +1 -1
  43. package/dist-lib/menu.mjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  45. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  46. package/dist-lib/metro-production-bundle.cjs +1 -1
  47. package/dist-lib/metro-production-bundle.mjs +1 -1
  48. package/dist-lib/metro.cjs +7 -4
  49. package/dist-lib/native-app-identity-project.cjs +6 -3
  50. package/dist-lib/native-app-identity-project.mjs +6 -3
  51. package/dist-lib/native-app-identity.cjs +1 -1
  52. package/dist-lib/native-app-identity.mjs +1 -1
  53. package/dist-lib/native-firebase-metadata.cjs +1 -1
  54. package/dist-lib/native-firebase-metadata.mjs +1 -1
  55. package/dist-lib/pdfium-raster.cjs +1 -1
  56. package/dist-lib/pdfium-raster.mjs +1 -1
  57. package/dist-lib/plist.cjs +1 -1
  58. package/dist-lib/plist.mjs +1 -1
  59. package/dist-lib/profiles.cjs +1 -1
  60. package/dist-lib/public-brand.cjs +1 -1
  61. package/dist-lib/public-origins-lib-esm.json +25 -24
  62. package/dist-lib/public-origins-lib.json +63 -53
  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/reap-browser.cjs +1 -1
  66. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  67. package/dist-lib/sdk.cjs +1 -1
  68. package/dist-lib/sdk.mjs +1 -1
  69. package/dist-lib/skills.cjs +447 -93
  70. package/dist-lib/swift-compile.cjs +13 -4
  71. package/dist-lib/swift-compile.mjs +13 -4
  72. package/dist-lib/swift-package.cjs +26 -1
  73. package/dist-lib/swift-package.mjs +25 -1
  74. package/dist-lib/swift-submit.cjs +2 -2
  75. package/dist-lib/swift-submit.mjs +2 -2
  76. package/dist-lib/swift-toolchain.cjs +1 -1
  77. package/dist-lib/swift.cjs +1 -1
  78. package/dist-lib/vite-swift.cjs +298 -27
  79. package/dist-lib/vite.cjs +7 -4
  80. package/dist-lib/worklet-executable.cjs +1 -1
  81. package/dist-lib/worklet-executable.mjs +1 -1
  82. package/dist-types/packages/peach-engine/src/render-worker/map-command-channel.d.ts +14 -0
  83. package/package.json +1 -1
  84. package/sdk/ios/System/Library/Frameworks/ActivityKit.framework/Headers/ActivityKit.h +1 -0
  85. package/sdk/ios/System/Library/Frameworks/ActivityKit.framework/Modules/module.modulemap +4 -0
  86. package/sdk/ios/usr/lib/swift/ActivityKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +14 -0
  87. package/sdk/ios/usr/lib/swift/CoreGraphics.swiftmodule/arm64-apple-ios-simulator.swiftinterface +14 -0
  88. package/sdk/ios/usr/lib/swift/Dispatch.swiftmodule/arm64-apple-ios-simulator.swiftinterface +3 -0
  89. package/sdk/ios/usr/lib/swift/Foundation.swiftmodule/arm64-apple-ios-simulator.swiftinterface +147 -16
  90. package/sdk/ios/usr/lib/swift/UIKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +5 -0
  91. package/src/expo-native-workspace.ts +19 -21
  92. package/src/expo-swift-bundle.ts +6 -1
  93. package/src/expo-swift-host.ts +35 -6
  94. package/src/expoSwiftContract.ts +3 -0
  95. package/src/native-bundles.ts +30 -10
  96. package/src/one-sdk/source.ts +10 -4
  97. package/src/one-sdk-bundle.ts +56 -24
  98. package/src/swift-compile.ts +3 -1
  99. package/src/swift-interface-bodies.ts +165 -0
  100. package/src/swift-objc-standin.ts +73 -13
  101. package/src/swift-package.ts +26 -0
  102. package/src/swift-source-pods.ts +27 -4
  103. package/src/swift-standin-emit.ts +30 -3
  104. package/src/swift-standins.ts +75 -12
  105. package/src/swift-submit.ts +2 -1
  106. package/src/wasm-optimize.ts +11 -1
@@ -0,0 +1,14 @@
1
+ // swift-interface-format-version: 1.0
2
+ // swift-module-flags: -target arm64-apple-ios16.0-simulator -enable-objc-interop -enable-library-evolution -module-name ActivityKit
3
+ @_exported import ActivityKit
4
+ import Foundation
5
+ import Swift
6
+ import _Concurrency
7
+ public protocol ActivityAttributes : Swift.Decodable, Swift.Encodable {
8
+ associatedtype ContentState : Swift.Decodable, Swift.Encodable, Swift.Hashable
9
+ }
10
+ @available(iOS 16.1, *)
11
+ public struct Activity<Attributes> where Attributes : ActivityKit.ActivityAttributes {
12
+ public let id: Swift.String
13
+ public let attributes: Attributes
14
+ }
@@ -6,3 +6,17 @@ import Swift
6
6
  public init()
7
7
  public init(_ value: Swift.Double)
8
8
  }
9
+ extension CoreGraphics.CGPoint {
10
+ public static let zero: CoreGraphics.CGPoint
11
+ }
12
+ extension CoreGraphics.CGSize {
13
+ public static let zero: CoreGraphics.CGSize
14
+ }
15
+ extension CoreGraphics.CGVector {
16
+ public static let zero: CoreGraphics.CGVector
17
+ }
18
+ extension CoreGraphics.CGRect {
19
+ public static let zero: CoreGraphics.CGRect
20
+ public static let null: CoreGraphics.CGRect
21
+ public static let infinite: CoreGraphics.CGRect
22
+ }
@@ -3,3 +3,6 @@
3
3
  @_exported import Dispatch
4
4
  import Swift
5
5
  @_objcRuntimeName(_TtC8Dispatch17_DispatchWorkItem) public class DispatchWorkItem {}
6
+ extension Dispatch.DispatchQueue {
7
+ public class var main: Dispatch.DispatchQueue { get }
8
+ }
@@ -5,27 +5,137 @@
5
5
  @_exported import CoreGraphics
6
6
  import Swift
7
7
  import _Concurrency
8
- public struct URL {}
8
+ public struct URL : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
9
+ public static func == (a: Foundation.URL, b: Foundation.URL) -> Swift.Bool
10
+ public func hash(into hasher: inout Swift.Hasher)
11
+ public func encode(to encoder: any Swift.Encoder) throws
12
+ public init(from decoder: any Swift.Decoder) throws
13
+ public var description: Swift.String { get }
14
+ }
9
15
  public struct Data {
10
16
  public typealias ReadingOptions = Foundation.NSData.ReadingOptions
11
17
  public typealias WritingOptions = Foundation.NSData.WritingOptions
12
18
  public typealias SearchOptions = Foundation.NSData.SearchOptions
19
+ public typealias Index = Swift.Int
20
+ }
21
+ public struct Date : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
22
+ public init()
23
+ public static var now: Foundation.Date { get }
24
+ public static let distantPast: Foundation.Date
25
+ public static let distantFuture: Foundation.Date
26
+ public static func == (a: Foundation.Date, b: Foundation.Date) -> Swift.Bool
27
+ public func hash(into hasher: inout Swift.Hasher)
28
+ public func encode(to encoder: any Swift.Encoder) throws
29
+ public init(from decoder: any Swift.Decoder) throws
30
+ public static func < (a: Foundation.Date, b: Foundation.Date) -> Swift.Bool
31
+ public var description: Swift.String { get }
32
+ }
33
+ public struct DateComponents : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
34
+ public static func == (a: Foundation.DateComponents, b: Foundation.DateComponents) -> Swift.Bool
35
+ public func hash(into hasher: inout Swift.Hasher)
36
+ public func encode(to encoder: any Swift.Encoder) throws
37
+ public init(from decoder: any Swift.Decoder) throws
38
+ public var description: Swift.String { get }
39
+ }
40
+ public struct DateInterval : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
41
+ public static func == (a: Foundation.DateInterval, b: Foundation.DateInterval) -> Swift.Bool
42
+ public func hash(into hasher: inout Swift.Hasher)
43
+ public func encode(to encoder: any Swift.Encoder) throws
44
+ public init(from decoder: any Swift.Decoder) throws
45
+ public var description: Swift.String { get }
46
+ }
47
+ public struct URLComponents : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
48
+ public static func == (a: Foundation.URLComponents, b: Foundation.URLComponents) -> Swift.Bool
49
+ public func hash(into hasher: inout Swift.Hasher)
50
+ public func encode(to encoder: any Swift.Encoder) throws
51
+ public init(from decoder: any Swift.Decoder) throws
52
+ public var description: Swift.String { get }
53
+ }
54
+ public struct URLQueryItem : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
55
+ public static func == (a: Foundation.URLQueryItem, b: Foundation.URLQueryItem) -> Swift.Bool
56
+ public func hash(into hasher: inout Swift.Hasher)
57
+ public func encode(to encoder: any Swift.Encoder) throws
58
+ public init(from decoder: any Swift.Decoder) throws
59
+ public var description: Swift.String { get }
60
+ }
61
+ public struct URLRequest : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
62
+ public static func == (a: Foundation.URLRequest, b: Foundation.URLRequest) -> Swift.Bool
63
+ public func hash(into hasher: inout Swift.Hasher)
64
+ public func encode(to encoder: any Swift.Encoder) throws
65
+ public init(from decoder: any Swift.Decoder) throws
66
+ public var description: Swift.String { get }
67
+ }
68
+ public struct UUID : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
69
+ public init()
70
+ public static func == (a: Foundation.UUID, b: Foundation.UUID) -> Swift.Bool
71
+ public func hash(into hasher: inout Swift.Hasher)
72
+ public func encode(to encoder: any Swift.Encoder) throws
73
+ public init(from decoder: any Swift.Decoder) throws
74
+ public var description: Swift.String { get }
75
+ }
76
+ public struct IndexPath : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
77
+ public static func == (a: Foundation.IndexPath, b: Foundation.IndexPath) -> Swift.Bool
78
+ public func hash(into hasher: inout Swift.Hasher)
79
+ public func encode(to encoder: any Swift.Encoder) throws
80
+ public init(from decoder: any Swift.Decoder) throws
81
+ public static func < (a: Foundation.IndexPath, b: Foundation.IndexPath) -> Swift.Bool
82
+ public var description: Swift.String { get }
83
+ }
84
+ public struct IndexSet : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
85
+ public static func == (a: Foundation.IndexSet, b: Foundation.IndexSet) -> Swift.Bool
86
+ public func hash(into hasher: inout Swift.Hasher)
87
+ public func encode(to encoder: any Swift.Encoder) throws
88
+ public init(from decoder: any Swift.Decoder) throws
89
+ public var description: Swift.String { get }
90
+ }
91
+ public struct CharacterSet : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
92
+ public static func == (a: Foundation.CharacterSet, b: Foundation.CharacterSet) -> Swift.Bool
93
+ public func hash(into hasher: inout Swift.Hasher)
94
+ public func encode(to encoder: any Swift.Encoder) throws
95
+ public init(from decoder: any Swift.Decoder) throws
96
+ public var description: Swift.String { get }
97
+ }
98
+ public struct Locale : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
99
+ public static var current: Foundation.Locale { get }
100
+ public static func == (a: Foundation.Locale, b: Foundation.Locale) -> Swift.Bool
101
+ public func hash(into hasher: inout Swift.Hasher)
102
+ public func encode(to encoder: any Swift.Encoder) throws
103
+ public init(from decoder: any Swift.Decoder) throws
104
+ public var description: Swift.String { get }
105
+ }
106
+ public struct TimeZone : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
107
+ public static var current: Foundation.TimeZone { get }
108
+ public static func == (a: Foundation.TimeZone, b: Foundation.TimeZone) -> Swift.Bool
109
+ public func hash(into hasher: inout Swift.Hasher)
110
+ public func encode(to encoder: any Swift.Encoder) throws
111
+ public init(from decoder: any Swift.Decoder) throws
112
+ public var description: Swift.String { get }
113
+ }
114
+ public struct Calendar : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.CustomStringConvertible {
115
+ public static var current: Foundation.Calendar { get }
116
+ public static func == (a: Foundation.Calendar, b: Foundation.Calendar) -> Swift.Bool
117
+ public func hash(into hasher: inout Swift.Hasher)
118
+ public func encode(to encoder: any Swift.Encoder) throws
119
+ public init(from decoder: any Swift.Decoder) throws
120
+ public var description: Swift.String { get }
121
+ }
122
+ public struct Notification {
123
+ public struct Name {}
124
+ }
125
+ public struct Decimal : Swift.Hashable, Swift.Codable, Swift.Sendable, Swift.Comparable, Swift.CustomStringConvertible {
126
+ public static func == (a: Foundation.Decimal, b: Foundation.Decimal) -> Swift.Bool
127
+ public func hash(into hasher: inout Swift.Hasher)
128
+ public func encode(to encoder: any Swift.Encoder) throws
129
+ public init(from decoder: any Swift.Decoder) throws
130
+ public static func < (a: Foundation.Decimal, b: Foundation.Decimal) -> Swift.Bool
131
+ public var description: Swift.String { get }
132
+ }
133
+ open class JSONDecoder {
134
+ public init()
135
+ }
136
+ open class JSONEncoder {
137
+ public init()
13
138
  }
14
- public struct Date {}
15
- public struct DateComponents {}
16
- public struct DateInterval {}
17
- public struct URLComponents {}
18
- public struct URLQueryItem {}
19
- public struct URLRequest {}
20
- public struct UUID {}
21
- public struct IndexPath {}
22
- public struct IndexSet {}
23
- public struct CharacterSet {}
24
- public struct Locale {}
25
- public struct TimeZone {}
26
- public struct Calendar {}
27
- public struct Notification {}
28
- public struct Decimal {}
29
139
  public typealias NSErrorPointer = Swift.AutoreleasingUnsafeMutablePointer<Foundation.NSError?>?
30
140
  public typealias ErrorPointer = Foundation.NSErrorPointer
31
141
  public protocol CustomNSError : Swift.Error {
@@ -33,6 +143,18 @@ public protocol CustomNSError : Swift.Error {
33
143
  var errorCode: Swift.Int { get }
34
144
  var errorUserInfo: [Swift.String : Any] { get }
35
145
  }
146
+ public protocol LocalizedError : Swift.Error {
147
+ var errorDescription: Swift.String? { get }
148
+ var failureReason: Swift.String? { get }
149
+ var recoverySuggestion: Swift.String? { get }
150
+ var helpAnchor: Swift.String? { get }
151
+ }
152
+ extension Foundation.LocalizedError {
153
+ public var errorDescription: Swift.String? { get }
154
+ public var failureReason: Swift.String? { get }
155
+ public var recoverySuggestion: Swift.String? { get }
156
+ public var helpAnchor: Swift.String? { get }
157
+ }
36
158
  public protocol _ObjectiveCBridgeableError : Swift.Error {
37
159
  init?(_bridgedNSError: __shared Foundation.NSError)
38
160
  }
@@ -313,6 +435,15 @@ public func _convertErrorToNSError(_ error: any Swift.Error) -> Foundation.NSErr
313
435
  public protocol ContiguousBytes {
314
436
  func withUnsafeBytes<R>(_ body: (Swift.UnsafeRawBufferPointer) throws -> R) rethrows -> R
315
437
  }
438
+ extension Foundation.Data : Swift.RandomAccessCollection, Swift.MutableCollection, Swift.RangeReplaceableCollection {
439
+ public typealias Element = Swift.UInt8
440
+ public typealias Indices = Swift.Range<Swift.Int>
441
+ public init()
442
+ public var startIndex: Swift.Int { get }
443
+ public var endIndex: Swift.Int { get }
444
+ public subscript(position: Swift.Int) -> Swift.UInt8 { get set }
445
+ public mutating func replaceSubrange<C>(_ subrange: Swift.Range<Swift.Int>, with newElements: C) where C : Swift.Collection, C.Element == Swift.UInt8
446
+ }
316
447
  extension Foundation.Data : Swift.Hashable, Swift.Codable, Foundation.ContiguousBytes, Swift.Sendable {
317
448
  public static func == (lhs: Foundation.Data, rhs: Foundation.Data) -> Swift.Bool
318
449
  public func hash(into hasher: inout Swift.Hasher)
@@ -11,3 +11,8 @@ extension UIKit.UIWindow {
11
11
  extension UIKit.UIDevice {
12
12
  public typealias BatteryState = UIKit.UIDeviceBatteryState
13
13
  }
14
+ extension UIKit.NSLayoutConstraint {
15
+ public typealias Relation = UIKit.NSLayoutRelation
16
+ public typealias Attribute = UIKit.NSLayoutAttribute
17
+ public typealias FormatOptions = UIKit.NSLayoutFormatOptions
18
+ }
@@ -745,7 +745,8 @@ function initializeWorkspaceGit(root: string, work: string) {
745
745
  })
746
746
  const tracked = trackedSourceFiles(root, work)
747
747
  if (tracked.length > 0)
748
- execFileSync('git', ['add', '-f', '--pathspec-from-file=-', '--pathspec-file-nul'], {
748
+ // update-index takes exact paths; add matches every file against every pathspec, which is quadratic here
749
+ execFileSync('git', ['update-index', '--add', '-z', '--stdin'], {
749
750
  cwd: work,
750
751
  env: { ...process.env, ...isolatedGitEnv },
751
752
  input: tracked.join('\0'),
@@ -877,6 +878,7 @@ async function prepareWorkspace(
877
878
  // a pinned bun installs into its own prefix: npm exec keeps one cached copy per spec, so a copy
878
879
  // installed without its postinstall (hosts that set ignore-scripts) would stay broken
879
880
  const bunPrefix = path.join(cacheDir(), 'package-managers', manager)
881
+ const bunExecutable = path.join(bunPrefix, 'node_modules/.bin/bun')
880
882
  const install =
881
883
  manager === 'pnpm' || manager.startsWith('pnpm@')
882
884
  ? [
@@ -893,11 +895,7 @@ async function prepareWorkspace(
893
895
  : manager === 'bun' || manager.startsWith('bun@')
894
896
  ? manager === 'bun'
895
897
  ? ['bun', 'install', '--frozen-lockfile']
896
- : [
897
- path.join(bunPrefix, 'node_modules/.bin/bun'),
898
- 'install',
899
- '--frozen-lockfile',
900
- ]
898
+ : [bunExecutable, 'install', '--frozen-lockfile']
901
899
  : // npm ci would delete the cloned tree before installing it again
902
900
  ['npm', 'install', '--no-audit', '--no-fund']
903
901
  // dependencies such as react-native-skia fetch their native binaries in a lifecycle
@@ -907,22 +905,22 @@ async function prepareWorkspace(
907
905
  const command = [...prefix, ...args]
908
906
  await run(command[0]!, command.slice(1), cwd, env)
909
907
  }
908
+ if (manager.startsWith('bun@') && (!projectReady || !fs.existsSync(bunExecutable)))
909
+ await execute(
910
+ [
911
+ 'npm',
912
+ 'install',
913
+ '--prefix',
914
+ bunPrefix,
915
+ // the bun package ships a placeholder binary its postinstall replaces
916
+ '--ignore-scripts=false',
917
+ '--no-audit',
918
+ '--no-fund',
919
+ manager,
920
+ ],
921
+ work,
922
+ )
910
923
  if (!projectReady) {
911
- if (manager.startsWith('bun@'))
912
- await execute(
913
- [
914
- 'npm',
915
- 'install',
916
- '--prefix',
917
- bunPrefix,
918
- // the bun package ships a placeholder binary its postinstall replaces
919
- '--ignore-scripts=false',
920
- '--no-audit',
921
- '--no-fund',
922
- manager,
923
- ],
924
- work,
925
- )
926
924
  // npm install keeps the cloned tree but can otherwise rewrite a stale lockfile.
927
925
  if (install[0] === 'npm' && fs.existsSync(path.join(work, 'package-lock.json'))) {
928
926
  await execute(
@@ -2,7 +2,10 @@
2
2
  // its immutable native assets beside the javascript bundle.
3
3
  import { compileExpoSwiftModules } from './expo-swift-host'
4
4
  import { swiftIcuBundleAsset } from './swift-icu'
5
- import type { ExpoSwiftCompilationResult } from './expoSwiftContract'
5
+ import type {
6
+ ExpoSwiftCompilationResult,
7
+ ExpoSwiftPreparationOptions,
8
+ } from './expoSwiftContract'
6
9
 
7
10
  export interface ExpoSwiftBundle {
8
11
  metadata: ExpoSwiftCompilationResult
@@ -11,6 +14,7 @@ export interface ExpoSwiftBundle {
11
14
 
12
15
  export async function buildExpoSwiftBundle(
13
16
  appRoot: string,
17
+ oneSDK?: ExpoSwiftPreparationOptions['oneSDK'],
14
18
  ): Promise<ExpoSwiftBundle | null> {
15
19
  const assets: ExpoSwiftBundle['assets'] = []
16
20
  const metadata = await compileExpoSwiftModules(
@@ -25,6 +29,7 @@ export async function buildExpoSwiftBundle(
25
29
  })
26
30
  if ('gzip' in artifact.icu) assets.push(await swiftIcuBundleAsset(artifact.icu))
27
31
  },
32
+ { oneSDK },
28
33
  )
29
34
  if (!metadata) return null
30
35
 
@@ -1999,7 +1999,16 @@ function targetSettings(units: ExpoSwiftSourceUnit[]) {
1999
1999
  return settings
2000
2000
  }
2001
2001
 
2002
- function expoEntry(units: ExpoSwiftSourceUnit[]): string {
2002
+ function oneSDKStamp(oneSDK: ExpoSwiftPreparationOptions['oneSDK']): string {
2003
+ if (!oneSDK) return ''
2004
+ const hash = createHash('sha256')
2005
+ for (const files of [oneSDK.targets, oneSDK.entry])
2006
+ for (const [name, source] of [...files].sort(([a], [b]) => a.localeCompare(b)))
2007
+ hash.update(`${name}\0${source}\0`)
2008
+ return hash.digest('hex')
2009
+ }
2010
+
2011
+ function expoEntry(units: ExpoSwiftSourceUnit[], oneSDK = false): string {
2003
2012
  // an Objective-C bridge module registers with no Swift of its own
2004
2013
  const namespaces = [...new Set(units.map((unit) => unit.namespace))]
2005
2014
  .filter((namespace) => namespace !== 'PeachExpoApp')
@@ -2015,7 +2024,11 @@ function expoEntry(units: ExpoSwiftSourceUnit[]): string {
2015
2024
  subscribers.length + handlers.length > 0
2016
2025
  ? `; PeachExpoRuntime.registerDelegates(subscribers: [${subscribers.join(', ')}], handlers: [${handlers.join(', ')}])`
2017
2026
  : ''
2018
- return `import SwiftUI\ninternal import ExpoModulesCore\n${bridgeModules.length ? 'import React\n' : ''}${namespaces.map((namespace) => `import ${namespace}`).join('\n')}\n\n@main struct PeachExpoApp: PeachPackage {\n init() { MainActor.assumeIsolated { PeachExpoRuntime.register([${units.flatMap((unit) => unit.classes).join(', ')}])${delegates}${bridgeModules.length ? `; RCTModuleHost.register([${bridgeModules.join(', ')}])` : ''} } }\n func view(props: JSON) -> PeachExpoNativeView { PeachExpoNativeView(props: props) }\n}\n\n@_expose(wasm, "peach_expo_call")\n@_cdecl("peach_expo_call")\n@MainActor public func peachExpoCall(_ payload: UnsafePointer<UInt8>?, _ length: Int32) -> UnsafeMutablePointer<UInt8>? {\n PeachExpoRuntime.dispatch(payload, length)\n}\n`
2027
+ // a One SDK host component marks its view; every other view is an Expo view
2028
+ const view = oneSDK
2029
+ ? '@ViewBuilder func view(props: JSON) -> some View {\n if props["oneSDKHost"] != nil { OneSDKUIKitHost(props: props) } else { PeachExpoNativeView(props: props) }\n }'
2030
+ : 'func view(props: JSON) -> PeachExpoNativeView { PeachExpoNativeView(props: props) }'
2031
+ return `import SwiftUI\ninternal import ExpoModulesCore\n${bridgeModules.length ? 'import React\n' : ''}${oneSDK ? 'import One\nimport OneSDKBindings\n' : ''}${namespaces.map((namespace) => `import ${namespace}`).join('\n')}\n\n@main struct PeachExpoApp: PeachPackage {\n init() { MainActor.assumeIsolated { PeachExpoRuntime.register([${units.flatMap((unit) => unit.classes).join(', ')}])${delegates}${bridgeModules.length ? `; RCTModuleHost.register([${bridgeModules.join(', ')}])` : ''} } }\n ${view}\n}\n\n@_expose(wasm, "peach_expo_call")\n@_cdecl("peach_expo_call")\n@MainActor public func peachExpoCall(_ payload: UnsafePointer<UInt8>?, _ length: Int32) -> UnsafeMutablePointer<UInt8>? {\n PeachExpoRuntime.dispatch(payload, length)\n}\n`
2019
2032
  }
2020
2033
 
2021
2034
  // a compile outlives its client: a dropped open leaves the work running so the
@@ -2153,7 +2166,7 @@ export async function compileExpoSwiftModules(
2153
2166
  installSwiftInputTrace()
2154
2167
  let key: string
2155
2168
  try {
2156
- key = `${await discoveryKey(root, options.installedWorkspace, true, options.iosTarget, options.moduleRoot)}\0${options.only?.join(',') ?? ''}`
2169
+ key = `${await discoveryKey(root, options.installedWorkspace, true, options.iosTarget, options.moduleRoot)}\0${options.only?.join(',') ?? ''}\0${oneSDKStamp(options.oneSDK)}`
2157
2170
  } catch {
2158
2171
  return compileExpoSwiftModulesTraced(root, base, publishArtifact, options)
2159
2172
  }
@@ -2406,11 +2419,23 @@ async function compileExpoSwiftModulesTraced(
2406
2419
  throw new Error(`conflicting Expo Swift binary source ${name}`)
2407
2420
  files[name] = source
2408
2421
  }
2409
- files[EXPO_SWIFT_ENTRY] = expoEntry(linked)
2422
+ const settings = targetSettings(linked)
2423
+ if (options.oneSDK) {
2424
+ for (const [name, source] of options.oneSDK.targets) files[name] = source
2425
+ for (const [name, source] of options.oneSDK.entry)
2426
+ files[`Sources/PeachExpoApp/${name}`] = source
2427
+ settings.set('OneSDKBindings', {
2428
+ languageMode: 5,
2429
+ mainActorIsolation: false,
2430
+ swiftFlags: ['-suppress-warnings'],
2431
+ dependencies: [{ kind: 'target', name: 'One' }],
2432
+ })
2433
+ }
2434
+ files[EXPO_SWIFT_ENTRY] = expoEntry(linked, options.oneSDK !== undefined)
2410
2435
  files['Package.swift'] = expoManifest(
2411
2436
  files,
2412
2437
  linked.map((unit) => generations.get(unit) ?? '').join(','),
2413
- targetSettings(linked),
2438
+ settings,
2414
2439
  )
2415
2440
  const provider = linked.some((unit) => unit.reactNativeProvider)
2416
2441
  ? reactProvider
@@ -2648,7 +2673,11 @@ async function compileExpoSwiftModulesTraced(
2648
2673
  stamps.set(unit, stamp)
2649
2674
  candidates.push(unit)
2650
2675
  }
2651
- const preparedKey = expoSwiftPreparedKey(base, units, reactProviderStamp)
2676
+ const preparedKey = expoSwiftPreparedKey(
2677
+ base,
2678
+ units,
2679
+ reactProviderStamp + oneSDKStamp(options.oneSDK),
2680
+ )
2652
2681
  if (!publishArtifact) {
2653
2682
  const prepared = preparedExpoSwift.get(preparedKey)
2654
2683
  if (prepared) {
@@ -5,6 +5,7 @@ import {
5
5
  import { isRecord } from './is-record'
6
6
  import { isNativeAppIdentity, type NativeAppIdentity } from './native-app-identity'
7
7
  import { isSwiftResourcePath } from './swiftContract'
8
+ import type { OneSDKLinkSources } from './one-sdk-bundle'
8
9
  import type {
9
10
  SwiftNativeTarget,
10
11
  SwiftHeaderAliases,
@@ -19,6 +20,8 @@ export interface ExpoSwiftPreparationOptions {
19
20
  moduleRoot?: string
20
21
  // compile only these Swift modules and the modules they import
21
22
  only?: readonly string[]
23
+ // the app's One SDK, linked into the same executable: one process per app
24
+ oneSDK?: Pick<OneSDKLinkSources, 'targets' | 'entry'>
22
25
  }
23
26
 
24
27
  export interface ExpoSwiftSourceOptions {
@@ -47,17 +47,37 @@ export async function buildNativeBundles(
47
47
  configuration: 'Debug' | 'Release',
48
48
  ): Promise<NativeBundles> {
49
49
  return getRuntimePlatformAdapter(platform).select<() => Promise<NativeBundles>>({
50
- ios: async () => ({
51
- oneSDK: await (await import('./one-sdk-bundle')).buildOneSDKBundle(projectRoot),
52
- expoSwift: await (
50
+ ios: async () => {
51
+ const { appOneSDKLinkSources, buildOneSDKBundle } = await import('./one-sdk-bundle')
52
+ // on iOS an app is one process: its One SDK links into the Expo executable
53
+ // when the app has one, and its process serves both
54
+ const oneSDK = await appOneSDKLinkSources(projectRoot)
55
+ const expoSwift = await (
53
56
  await import('./expo-swift-bundle')
54
- ).buildExpoSwiftBundle(projectRoot),
55
- nitro: await (
56
- await import('./nitro-bundle')
57
- ).buildNitroBundle(projectRoot, configuration),
58
- turbo: await (await import('./turbo-bundle')).buildTurboBundle(projectRoot),
59
- expoKotlin: null,
60
- }),
57
+ ).buildExpoSwiftBundle(projectRoot, oneSDK ?? undefined)
58
+ const linked = oneSDK && expoSwift?.metadata.modules[0]
59
+ return {
60
+ oneSDK: linked
61
+ ? {
62
+ metadata: {
63
+ url: linked.url,
64
+ hash: linked.hash,
65
+ icuUrl: linked.icuUrl,
66
+ rootId: `${linked.rootId.split('/')[0]}/OneSDK`,
67
+ bundleFiles: linked.bundleFiles ?? {},
68
+ modules: oneSDK.modules,
69
+ },
70
+ assets: [],
71
+ }
72
+ : await buildOneSDKBundle(projectRoot),
73
+ expoSwift,
74
+ nitro: await (
75
+ await import('./nitro-bundle')
76
+ ).buildNitroBundle(projectRoot, configuration),
77
+ turbo: await (await import('./turbo-bundle')).buildTurboBundle(projectRoot),
78
+ expoKotlin: null,
79
+ }
80
+ },
61
81
  android: async () => ({
62
82
  oneSDK: null,
63
83
  expoSwift: null,
@@ -30,12 +30,13 @@ extension OneNativeComposable {
30
30
  }
31
31
  `
32
32
 
33
- export const oneSDKApp = String.raw`import SwiftUI
33
+ // the view a One SDK host component mounts, in whichever executable links the
34
+ // app's One SDK
35
+ export const oneSDKHost = String.raw`import SwiftUI
34
36
  @_spi(Peach) import UIKit
35
37
  import One
36
- import OneSDKBindings
37
38
 
38
- private struct UIKitHost: UIViewRepresentable {
39
+ struct OneSDKUIKitHost: UIViewRepresentable {
39
40
  let props: JSON
40
41
  func makeUIView(context: Context) -> OneNativeUIKitHostView { OneNativeUIKitHostView() }
41
42
  func updateUIView(_ view: OneNativeUIKitHostView, context: Context) {
@@ -47,10 +48,15 @@ private struct UIKitHost: UIViewRepresentable {
47
48
  }
48
49
  static func dismantleUIView(_ view: OneNativeUIKitHostView, coordinator: Coordinator) { view.reset() }
49
50
  }
51
+ `
52
+
53
+ export const oneSDKApp = String.raw`import SwiftUI
54
+ import One
55
+ import OneSDKBindings
50
56
 
51
57
  @main
52
58
  struct SDKGuest: PeachPackage {
53
- func view(props: JSON) -> some View { UIKitHost(props: props) }
59
+ func view(props: JSON) -> some View { OneSDKUIKitHost(props: props) }
54
60
  }
55
61
  `
56
62
 
@@ -4,7 +4,7 @@ import path from 'node:path'
4
4
  import { prepareExpoNativeProject } from './expo-native-workspace'
5
5
  import { compiledModuleAssets, compiledModuleRequestHandler } from './nitro-bundle'
6
6
  import { selectOneSDK } from './one-sdk-preparation'
7
- import { oneSDKApp, oneSDKModule, oneSDKTransport } from './one-sdk/source'
7
+ import { oneSDKApp, oneSDKHost, oneSDKModule, oneSDKTransport } from './one-sdk/source'
8
8
  import { ONE_SDK_SOURCE_DIRECTORY, readOneSDKSourceManifest } from './oneSdkContract'
9
9
  import { syncSwiftTree } from './swift-compile'
10
10
  import { resolveSwiftModule } from './swift-distribution'
@@ -24,12 +24,19 @@ export async function compileOneSDKApp(
24
24
  return compilePreparedOneSDKApp(appRoot, prepared.app, origin, moduleRootOverride)
25
25
  }
26
26
 
27
- export async function compilePreparedOneSDKApp(
27
+ // the One and OneSDKBindings targets an executable links for the app's One SDK
28
+ // imports, the host view and transport its executable target adds, and the
29
+ // module names the bundle registers
30
+ export interface OneSDKLinkSources {
31
+ targets: Map<string, string>
32
+ entry: Map<string, string>
33
+ modules: string[]
34
+ }
35
+
36
+ export async function oneSDKLinkSources(
28
37
  appRoot: string,
29
38
  preparedRoot: string,
30
- origin: string,
31
- moduleRootOverride?: string,
32
- ) {
39
+ ): Promise<OneSDKLinkSources> {
33
40
  const selected = await selectOneSDK(appRoot)
34
41
  if (!selected) throw new Error('prepared app has no One SDK imports')
35
42
  const { one, frameworks } = selected
@@ -47,6 +54,47 @@ export async function compilePreparedOneSDKApp(
47
54
  throw new Error(
48
55
  'prepared One SDK sources differ from the installed facades or app imports',
49
56
  )
57
+ const targets = new Map<string, string>()
58
+ targets.set('Sources/One/One.swift', oneSDKModule)
59
+ for (const source of [
60
+ 'SDK/OneSDKRuntime.swift',
61
+ 'OneNativeUIKitHostView.swift',
62
+ 'OneNativeContent.swift',
63
+ 'OneNativeAccessibility.swift',
64
+ 'SDKViews/OneNativeViewsTable.swift',
65
+ ])
66
+ targets.set(
67
+ `Sources/One/${path.basename(source)}`,
68
+ fs.readFileSync(path.join(one, 'ios', source), 'utf8'),
69
+ )
70
+ for (const name of generated.files)
71
+ targets.set(
72
+ `Sources/OneSDKBindings/${name}`,
73
+ fs.readFileSync(path.join(sourceRoot, name), 'utf8'),
74
+ )
75
+ return {
76
+ targets,
77
+ entry: new Map([
78
+ ['OneSDKHost.swift', oneSDKHost],
79
+ ['OneSDKTransport.swift', oneSDKTransport],
80
+ ]),
81
+ modules: frameworks.map((name) => `${name}_${generated.generation}`),
82
+ }
83
+ }
84
+
85
+ // the app's One SDK sources, when it imports One's SDK
86
+ export async function appOneSDKLinkSources(appRoot: string) {
87
+ if (!(await selectOneSDK(appRoot))) return null
88
+ return oneSDKLinkSources(appRoot, (await prepareExpoNativeProject(appRoot)).app)
89
+ }
90
+
91
+ export async function compilePreparedOneSDKApp(
92
+ appRoot: string,
93
+ preparedRoot: string,
94
+ origin: string,
95
+ moduleRootOverride?: string,
96
+ ) {
97
+ const sources = await oneSDKLinkSources(appRoot, preparedRoot)
50
98
  const moduleRoot = moduleRootOverride ?? (await resolveSwiftModule()).root
51
99
  const packagePath = path.join(
52
100
  swiftCacheDir(),
@@ -66,25 +114,9 @@ let package = Package(name: "OneSDKGuest", targets: [
66
114
  ])
67
115
  `,
68
116
  )
69
- files.set('Sources/One/One.swift', oneSDKModule)
70
- for (const source of [
71
- 'SDK/OneSDKRuntime.swift',
72
- 'OneNativeUIKitHostView.swift',
73
- 'OneNativeContent.swift',
74
- 'OneNativeAccessibility.swift',
75
- 'SDKViews/OneNativeViewsTable.swift',
76
- ])
77
- files.set(
78
- `Sources/One/${path.basename(source)}`,
79
- fs.readFileSync(path.join(one, 'ios', source), 'utf8'),
80
- )
81
- for (const name of generated.files)
82
- files.set(
83
- `Sources/OneSDKBindings/${name}`,
84
- fs.readFileSync(path.join(sourceRoot, name), 'utf8'),
85
- )
117
+ for (const [name, source] of sources.targets) files.set(name, source)
118
+ for (const [name, source] of sources.entry) files.set(`Sources/App/${name}`, source)
86
119
  files.set('Sources/App/App.swift', oneSDKApp)
87
- files.set('Sources/App/Transport.swift', oneSDKTransport)
88
120
  fs.mkdirSync(packagePath, { recursive: true })
89
121
  syncSwiftTree(
90
122
  packagePath,
@@ -100,7 +132,7 @@ let package = Package(name: "OneSDKGuest", targets: [
100
132
  icuUrl: icuUrl(origin, artifact),
101
133
  rootId: `one-sdk-${artifact.hash.slice(0, 16)}`,
102
134
  bundleFiles: artifact.package.bundleFiles.files,
103
- modules: frameworks.map((name) => `${name}_${generated.generation}`),
135
+ modules: sources.modules,
104
136
  }
105
137
  return { metadata, artifact }
106
138
  }
@@ -6053,7 +6053,7 @@ function readCompiledArtifact(
6053
6053
  if (
6054
6054
  createHash('sha256').update(bytes).digest('hex') !== receipt.wasm ||
6055
6055
  createHash('sha256').update(gzip).digest('hex') !== receipt.icu ||
6056
- bytes.length < 8 ||
6056
+ bytes.length <= 8 ||
6057
6057
  bytes.readUInt32LE(0) !== 0x6d736100 ||
6058
6058
  bytes.readUInt32LE(4) !== 1
6059
6059
  )
@@ -7423,6 +7423,8 @@ function compileSwiftProjectOnce(
7423
7423
  bytes: readFileSync(executable),
7424
7424
  icu: await icu,
7425
7425
  }
7426
+ if (artifact.bytes.length <= 8)
7427
+ throw new Error('swift-compile: deferred linker produced no executable')
7426
7428
  if (!options.project) saveCompiledArtifact(root, artifact)
7427
7429
  saveSharedArtifact(sharedRoot, artifact)
7428
7430
  report('compiled artifact verified')