@swiftbrowser/swift 0.1.0 → 0.2.0

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 (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +105 -7
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +93 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +3 -2
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +67 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +80 -10
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +11 -2
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +164 -37
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +10 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +39 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -0,0 +1,606 @@
1
+ // `import CoreTransferable` for the browser: `Transferable`, the protocol a
2
+ // type adopts to say how it turns into bytes or a file of some content type
3
+ // and back, and the representations it says it with (`DataRepresentation`,
4
+ // `FileRepresentation`, `ProxyRepresentation`, `CodableRepresentation`).
5
+ // On iOS SwiftUI re-exports this module, and so does the shim's SwiftUI
6
+ // (this module sits under it), so `struct Photo: Transferable` compiles with
7
+ // `import SwiftUI` alone.
8
+ //
9
+ // The representations are real: they run. A value exports through the first
10
+ // representation that can (`ShareLink` sends the bytes or the file to the
11
+ // page, which shares them with the Web Share API or downloads them), and a
12
+ // type imports through the first one that accepts the content type offered
13
+ // (`PhotosPickerItem.loadTransferable`, `NSItemProvider.loadTransferable`).
14
+ // A received file is a copy in the temporary directory that is removed once
15
+ // the importing closure returns, as on iOS. What the browser has no use for
16
+ // is kept and ignored: visibility (there is no other app or process to hide
17
+ // from) and `shouldAttemptToOpenInPlace` beyond reporting `isOriginalFile`.
18
+ // docs/ops-protocol.md, "Sharing and media".
19
+
20
+ @_exported import UniformTypeIdentifiers
21
+ import Foundation
22
+
23
+ // MARK: - Transferable
24
+
25
+ /// A type that can be shared, dragged, pasted or picked: it lists the
26
+ /// representations it exports and imports, in order of preference.
27
+ public protocol Transferable {
28
+ associatedtype Representation: TransferRepresentation
29
+ @TransferRepresentationBuilder<Self> static var transferRepresentation: Representation { get }
30
+ }
31
+
32
+ /// One way of turning an `Item` into content of some type, or back.
33
+ /// Compose them with the builder; your own representation is a `body` of others.
34
+ public protocol TransferRepresentation<Item> {
35
+ associatedtype Item: Transferable
36
+ associatedtype Body: TransferRepresentation
37
+ @TransferRepresentationBuilder<Item> var body: Body { get }
38
+ }
39
+
40
+ extension Never: Transferable {
41
+ public static var transferRepresentation: Never { return fatalError("Never has no representation") }
42
+ }
43
+
44
+ extension Never: TransferRepresentation {
45
+ public typealias Item = Never
46
+ public var body: Never { return fatalError("Never has no representation") }
47
+ }
48
+
49
+ /// Who may see a representation. Kept: in the browser the app is alone, so
50
+ /// every representation is visible to it.
51
+ public struct TransferRepresentationVisibility: Hashable, Sendable {
52
+ let name: String
53
+ public static let all = TransferRepresentationVisibility(name: "all")
54
+ public static let team = TransferRepresentationVisibility(name: "team")
55
+ public static let group = TransferRepresentationVisibility(name: "group")
56
+ public static let ownProcess = TransferRepresentationVisibility(name: "ownProcess")
57
+ }
58
+
59
+ // MARK: - Files
60
+
61
+ /// A file a value exports (`FileRepresentation`'s exporting closure returns one).
62
+ public struct SentTransferredFile: Sendable {
63
+ public let file: URL
64
+ public let allowAccessingOriginalFile: Bool
65
+
66
+ public init(_ file: URL, allowAccessingOriginalFile: Bool = false) {
67
+ self.file = file
68
+ self.allowAccessingOriginalFile = allowAccessingOriginalFile
69
+ }
70
+ }
71
+
72
+ /// A file handed to `FileRepresentation`'s importing closure: a copy in the
73
+ /// temporary directory (removed once the closure returns; copy it to keep
74
+ /// it), or the original when the representation asked to open in place and
75
+ /// the content was a file.
76
+ public struct ReceivedTransferredFile: Sendable {
77
+ public let file: URL
78
+ public let isOriginalFile: Bool
79
+
80
+ public init(_file file: URL, isOriginalFile: Bool) {
81
+ self.file = file
82
+ self.isOriginalFile = isOriginalFile
83
+ }
84
+ }
85
+
86
+ // MARK: - The representations
87
+
88
+ /// The value as bytes of one content type.
89
+ public struct DataRepresentation<Item: Transferable>: TransferRepresentation, _TransferPrimitive {
90
+ public typealias Body = Never
91
+ public var body: Never { return fatalError("a primitive representation has no body") }
92
+ let node: _TransferNode
93
+
94
+ public init(contentType: UTType,
95
+ exporting: @escaping (Item) async throws -> Data,
96
+ importing: @escaping (Data) async throws -> Item) {
97
+ node = _TransferNode(exportType: contentType, importType: contentType,
98
+ exporter: Self.exporter(contentType, exporting), importer: Self.importer(importing))
99
+ }
100
+
101
+ public init(exportedContentType: UTType, exporting: @escaping (Item) async throws -> Data) {
102
+ node = _TransferNode(exportType: exportedContentType, importType: nil,
103
+ exporter: Self.exporter(exportedContentType, exporting), importer: nil)
104
+ }
105
+
106
+ public init(importedContentType: UTType, importing: @escaping (Data) async throws -> Item) {
107
+ node = _TransferNode(exportType: nil, importType: importedContentType, exporter: nil, importer: Self.importer(importing))
108
+ }
109
+
110
+ private static func exporter(_ type: UTType, _ exporting: @escaping (Item) async throws -> Data) -> _TransferNode.Exporter {
111
+ { item, _ in
112
+ nonisolated(unsafe) let value = item as! Item
113
+ return _TransferContent(contentType: type, data: try await exporting(value))
114
+ }
115
+ }
116
+
117
+ private static func importer(_ importing: @escaping (Data) async throws -> Item) -> _TransferNode.Importer {
118
+ { content in try await importing(try content.loadData()) }
119
+ }
120
+
121
+ public var _transferNodes: [_TransferNode] { [node] }
122
+ }
123
+
124
+ /// The value as a file of one content type.
125
+ public struct FileRepresentation<Item: Transferable>: TransferRepresentation, _TransferPrimitive {
126
+ public typealias Body = Never
127
+ public var body: Never { return fatalError("a primitive representation has no body") }
128
+ let node: _TransferNode
129
+
130
+ public init(contentType: UTType, shouldAttemptToOpenInPlace: Bool = false,
131
+ exporting: @escaping (Item) async throws -> SentTransferredFile,
132
+ importing: @escaping (ReceivedTransferredFile) async throws -> Item) {
133
+ node = _TransferNode(exportType: contentType, importType: contentType,
134
+ exporter: Self.exporter(contentType, exporting),
135
+ importer: Self.importer(inPlace: shouldAttemptToOpenInPlace, importing))
136
+ }
137
+
138
+ public init(exportedContentType: UTType, shouldAllowToOpenInPlace: Bool = false,
139
+ exporting: @escaping (Item) async throws -> SentTransferredFile) {
140
+ node = _TransferNode(exportType: exportedContentType, importType: nil,
141
+ exporter: Self.exporter(exportedContentType, exporting), importer: nil)
142
+ }
143
+
144
+ public init(importedContentType: UTType, shouldAttemptToOpenInPlace: Bool = false,
145
+ importing: @escaping (ReceivedTransferredFile) async throws -> Item) {
146
+ node = _TransferNode(exportType: nil, importType: importedContentType, exporter: nil,
147
+ importer: Self.importer(inPlace: shouldAttemptToOpenInPlace, importing))
148
+ }
149
+
150
+ private static func exporter(_ type: UTType, _ exporting: @escaping (Item) async throws -> SentTransferredFile) -> _TransferNode.Exporter {
151
+ { item, _ in
152
+ nonisolated(unsafe) let value = item as! Item
153
+ let sent = try await exporting(value)
154
+ return _TransferContent(contentType: type, file: sent.file, isOriginalFile: sent.allowAccessingOriginalFile,
155
+ suggestedName: sent.file.deletingPathExtension().lastPathComponent)
156
+ }
157
+ }
158
+
159
+ private static func importer(inPlace: Bool, _ importing: @escaping (ReceivedTransferredFile) async throws -> Item) -> _TransferNode.Importer {
160
+ { content in
161
+ let received = try content.receivedFile(inPlace: inPlace)
162
+ defer { if !received.isOriginalFile { try? FileManager.default.removeItem(at: received.file) } }
163
+ return try await importing(received)
164
+ }
165
+ }
166
+
167
+ public var _transferNodes: [_TransferNode] { [node] }
168
+ }
169
+
170
+ /// The value as another `Transferable` value (a `URL`, a `String`…), which
171
+ /// carries the content types.
172
+ public struct ProxyRepresentation<Item: Transferable, ProxyRepresentation: Transferable>: TransferRepresentation, _TransferPrimitive {
173
+ public typealias Body = Never
174
+ public var body: Never { return fatalError("a primitive representation has no body") }
175
+ let node: _TransferNode
176
+
177
+ public init(exporting: @escaping (Item) async throws -> ProxyRepresentation,
178
+ importing: @escaping (ProxyRepresentation) async throws -> Item) {
179
+ node = Self.node(exporting: exporting, importing: importing)
180
+ }
181
+
182
+ public init(exporting: @escaping (Item) async throws -> ProxyRepresentation) {
183
+ node = Self.node(exporting: exporting, importing: nil)
184
+ }
185
+
186
+ public init(importing: @escaping (ProxyRepresentation) async throws -> Item) {
187
+ node = Self.node(exporting: nil, importing: importing)
188
+ }
189
+
190
+ private static func node(exporting: ((Item) async throws -> ProxyRepresentation)?,
191
+ importing: ((ProxyRepresentation) async throws -> Item)?) -> _TransferNode {
192
+ var exporter: _TransferNode.Exporter?
193
+ if let exporting {
194
+ exporter = { item, wanted in
195
+ nonisolated(unsafe) let value = item as! Item
196
+ return try await _Transfer.export(try await exporting(value), as: wanted)
197
+ }
198
+ }
199
+ var importer: _TransferNode.Importer?
200
+ if let importing {
201
+ importer = { content in
202
+ guard let proxy = try await _Transfer.import(ProxyRepresentation.self, from: content) else { return nil }
203
+ nonisolated(unsafe) let value = proxy
204
+ return try await importing(value)
205
+ }
206
+ }
207
+ var node = _TransferNode(exportType: nil, importType: nil, exporter: exporter, importer: importer)
208
+ node.proxyExportTypes = exporting == nil ? nil : { _Transfer.exportedContentTypes(ProxyRepresentation.self) }
209
+ node.proxyImportTypes = importing == nil ? nil : { _Transfer.importedContentTypes(ProxyRepresentation.self) }
210
+ return node
211
+ }
212
+
213
+ public var _transferNodes: [_TransferNode] { [node] }
214
+ }
215
+
216
+ /// What `CodableRepresentation` encodes with: `JSONEncoder` and
217
+ /// `PropertyListEncoder` (Combine's `TopLevelEncoder`, which the browser's
218
+ /// Foundation does not have, for this purpose).
219
+ public protocol _TransferTopLevelEncoder {
220
+ func encode<T: Encodable>(_ value: T) throws -> Data
221
+ }
222
+
223
+ /// What `CodableRepresentation` decodes with.
224
+ public protocol _TransferTopLevelDecoder {
225
+ func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T
226
+ }
227
+
228
+ extension JSONEncoder: _TransferTopLevelEncoder {}
229
+ extension JSONDecoder: _TransferTopLevelDecoder {}
230
+ extension PropertyListEncoder: _TransferTopLevelEncoder {}
231
+ extension PropertyListDecoder: _TransferTopLevelDecoder {}
232
+
233
+ /// The value encoded with `Codable`, as JSON unless you pass a coder.
234
+ public struct CodableRepresentation<Item: Transferable & Codable, Encoder: _TransferTopLevelEncoder, Decoder: _TransferTopLevelDecoder>:
235
+ TransferRepresentation, _TransferPrimitive {
236
+ public typealias Body = Never
237
+ public var body: Never { return fatalError("a primitive representation has no body") }
238
+ let node: _TransferNode
239
+
240
+ public init(for itemType: Item.Type = Item.self, contentType: UTType, encoder: Encoder, decoder: Decoder) {
241
+ let encode = Self.encoding(encoder)
242
+ let decode = Self.decoding(decoder)
243
+ node = _TransferNode(
244
+ exportType: contentType, importType: contentType,
245
+ exporter: { item, _ in _TransferContent(contentType: contentType, data: try encode(item as! Item)) },
246
+ importer: { content in try decode(try content.loadData()) })
247
+ }
248
+
249
+ private static func encoding(_ encoder: Encoder) -> (Item) throws -> Data {
250
+ let box = _UncheckedBox(encoder)
251
+ return { item in try box.value.encode(item) }
252
+ }
253
+
254
+ private static func decoding(_ decoder: Decoder) -> (Data) throws -> Item {
255
+ let box = _UncheckedBox(decoder)
256
+ return { data in try box.value.decode(Item.self, from: data) }
257
+ }
258
+
259
+ public var _transferNodes: [_TransferNode] { [node] }
260
+ }
261
+
262
+ extension CodableRepresentation where Encoder == JSONEncoder, Decoder == JSONDecoder {
263
+ public init(for itemType: Item.Type = Item.self, contentType: UTType) {
264
+ self.init(for: itemType, contentType: contentType, encoder: JSONEncoder(), decoder: JSONDecoder())
265
+ }
266
+ }
267
+
268
+ // MARK: - Modifiers
269
+
270
+ extension TransferRepresentation {
271
+ /// The file name the exported content is offered under (the page uses
272
+ /// it for the shared or downloaded file).
273
+ public func suggestedFileName(_ fileName: String) -> _TransferRepresentationList<Item> {
274
+ modified { $0.suggestedFileName = { _ in fileName } }
275
+ }
276
+
277
+ public func suggestedFileName(_ fileName: @escaping (Item) -> String?) -> _TransferRepresentationList<Item> {
278
+ modified { $0.suggestedFileName = { fileName($0 as! Item) } }
279
+ }
280
+
281
+ /// Exports only the values for which `condition` holds.
282
+ public func exportingCondition(_ condition: @escaping (Item) -> Bool) -> _TransferRepresentationList<Item> {
283
+ modified { $0.exportingCondition = { condition($0 as! Item) } }
284
+ }
285
+
286
+ /// Kept, with nothing to apply it to: the app is alone in the browser.
287
+ public func visibility(_ visibility: TransferRepresentationVisibility) -> _TransferRepresentationList<Item> {
288
+ modified { $0.visibility = visibility }
289
+ }
290
+
291
+ private func modified(_ change: (inout _TransferNode) -> Void) -> _TransferRepresentationList<Item> {
292
+ var nodes = _Transfer.nodes(of: self)
293
+ for index in nodes.indices { change(&nodes[index]) }
294
+ return _TransferRepresentationList(nodes: nodes)
295
+ }
296
+ }
297
+
298
+ // MARK: - Builder
299
+
300
+ /// Several representations, in order of preference: what the builder makes.
301
+ public struct _TransferRepresentationList<Item: Transferable>: TransferRepresentation, _TransferPrimitive {
302
+ public typealias Body = Never
303
+ public var body: Never { return fatalError("a primitive representation has no body") }
304
+ public let _transferNodes: [_TransferNode]
305
+
306
+ public init(nodes: [_TransferNode]) { _transferNodes = nodes }
307
+ }
308
+
309
+ @resultBuilder
310
+ public enum TransferRepresentationBuilder<Item: Transferable> {
311
+ public static func buildExpression<R: TransferRepresentation>(_ representation: R) -> _TransferRepresentationList<Item> where R.Item == Item {
312
+ _TransferRepresentationList(nodes: _Transfer.nodes(of: representation))
313
+ }
314
+
315
+ public static func buildBlock() -> _TransferRepresentationList<Item> {
316
+ _TransferRepresentationList(nodes: [])
317
+ }
318
+
319
+ public static func buildBlock(_ components: _TransferRepresentationList<Item>...) -> _TransferRepresentationList<Item> {
320
+ _TransferRepresentationList(nodes: components.flatMap(\._transferNodes))
321
+ }
322
+
323
+ public static func buildOptional(_ component: _TransferRepresentationList<Item>?) -> _TransferRepresentationList<Item> {
324
+ component ?? _TransferRepresentationList(nodes: [])
325
+ }
326
+
327
+ public static func buildEither(first component: _TransferRepresentationList<Item>) -> _TransferRepresentationList<Item> { component }
328
+ public static func buildEither(second component: _TransferRepresentationList<Item>) -> _TransferRepresentationList<Item> { component }
329
+ public static func buildLimitedAvailability(_ component: _TransferRepresentationList<Item>) -> _TransferRepresentationList<Item> { component }
330
+ public static func buildArray(_ components: [_TransferRepresentationList<Item>]) -> _TransferRepresentationList<Item> {
331
+ _TransferRepresentationList(nodes: components.flatMap(\._transferNodes))
332
+ }
333
+ }
334
+
335
+ // MARK: - Exporting and importing
336
+
337
+ extension Transferable {
338
+ /// The content types the type exports, in order of preference.
339
+ public static func exportedContentTypes(_ visibility: TransferRepresentationVisibility = .all) -> [UTType] {
340
+ _Transfer.exportedContentTypes(Self.self)
341
+ }
342
+
343
+ /// The content types the type imports, in order of preference.
344
+ public static func importedContentTypes(_ visibility: TransferRepresentationVisibility = .all) -> [UTType] {
345
+ _Transfer.importedContentTypes(Self.self)
346
+ }
347
+
348
+ /// The value's bytes as `contentType` (or a type conforming to it), from
349
+ /// the first representation that exports it.
350
+ nonisolated(nonsending) public func exported(as contentType: UTType) async throws -> Data {
351
+ guard let content = try await _Transfer.export(self, as: contentType) else {
352
+ throw _TransferError.noRepresentation(contentType)
353
+ }
354
+ return try content.loadData()
355
+ }
356
+
357
+ /// A value made from `data` by the first representation that imports
358
+ /// `contentType` (with no type: the first that imports anything).
359
+ nonisolated(nonsending) public init(importing data: Data, contentType: UTType?) async throws {
360
+ let types = contentType.map { [$0] } ?? Self.importedContentTypes()
361
+ for type in types {
362
+ if let value = try await _Transfer.import(Self.self, from: _TransferContent(contentType: type, data: data)) {
363
+ self = value
364
+ return
365
+ }
366
+ }
367
+ throw _TransferError.noRepresentation(contentType ?? .data)
368
+ }
369
+ }
370
+
371
+ /// Why a transfer failed.
372
+ public enum _TransferError: Error, CustomStringConvertible {
373
+ case noRepresentation(UTType)
374
+ case noContent
375
+
376
+ public var description: String {
377
+ switch self {
378
+ case .noRepresentation(let type): "no representation for \(type.identifier)"
379
+ case .noContent: "the content has no data"
380
+ }
381
+ }
382
+ }
383
+
384
+ /// Content on its way out of a value or into one: bytes or a file, of a type.
385
+ public struct _TransferContent: @unchecked Sendable {
386
+ public var contentType: UTType
387
+ public var data: Data?
388
+ public var file: URL?
389
+ /// Whether `file` is the exporter's own (not a copy made for the transfer).
390
+ public var isOriginalFile: Bool
391
+ /// The file name (without extension) to offer the content under.
392
+ public var suggestedName: String?
393
+ /// A `Transferable` value exported through a `ProxyRepresentation` to a
394
+ /// `String` or `URL` (the page shares those as text and links).
395
+ public var value: Any?
396
+
397
+ public init(contentType: UTType, data: Data? = nil, file: URL? = nil, isOriginalFile: Bool = false,
398
+ suggestedName: String? = nil, value: Any? = nil) {
399
+ self.contentType = contentType
400
+ self.data = data
401
+ self.file = file
402
+ self.isOriginalFile = isOriginalFile
403
+ self.suggestedName = suggestedName
404
+ self.value = value
405
+ }
406
+
407
+ /// The bytes: `data`, or the file's contents.
408
+ public func loadData() throws -> Data {
409
+ if let data { return data }
410
+ if let file { return try Data(contentsOf: file) }
411
+ throw _TransferError.noContent
412
+ }
413
+
414
+ /// A file name with the content type's extension.
415
+ public var fileName: String {
416
+ let base = suggestedName.flatMap { $0.isEmpty ? nil : $0 } ?? file?.deletingPathExtension().lastPathComponent ?? "Shared"
417
+ if let file, !file.pathExtension.isEmpty { return "\(base).\(file.pathExtension)" }
418
+ guard let ext = contentType.preferredFilenameExtension else { return base }
419
+ return "\(base).\(ext)"
420
+ }
421
+
422
+ /// The file an importing `FileRepresentation` receives: the original in
423
+ /// place when asked for and there is one, else a copy (or the bytes
424
+ /// written) in the temporary directory.
425
+ func receivedFile(inPlace: Bool) throws -> ReceivedTransferredFile {
426
+ if let file, inPlace { return ReceivedTransferredFile(_file: file, isOriginalFile: true) }
427
+ let folder = FileManager.default.temporaryDirectory.appendingPathComponent("Transfers-\(UUID().uuidString)", isDirectory: true)
428
+ try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
429
+ let copy = folder.appendingPathComponent(fileName)
430
+ if let file { try FileManager.default.copyItem(at: file, to: copy) } else { try loadData().write(to: copy) }
431
+ return ReceivedTransferredFile(_file: copy, isOriginalFile: false)
432
+ }
433
+ }
434
+
435
+ /// One representation, with the item type erased: what the shim's
436
+ /// `ShareLink`, `NSItemProvider` and `PhotosPickerItem` walk.
437
+ public struct _TransferNode: @unchecked Sendable {
438
+ // Not `@Sendable`: the browser runs one thread, and the nodes are
439
+ // `@unchecked Sendable`. The app's closures are not `@Sendable` either,
440
+ // so a closure written in a main-actor type (a package with main-actor
441
+ // default isolation, as Ice Cubes' are) stays on the main actor and may
442
+ // call that type's initializers; being async, it hops there when called.
443
+ public typealias Exporter = nonisolated(nonsending) (Any, UTType?) async throws -> _TransferContent?
444
+ public typealias Importer = nonisolated(nonsending) (_TransferContent) async throws -> Any?
445
+
446
+ let exportType: UTType?
447
+ let importType: UTType?
448
+ let exporter: Exporter?
449
+ let importer: Importer?
450
+ var proxyExportTypes: (() -> [UTType])?
451
+ var proxyImportTypes: (() -> [UTType])?
452
+ var suggestedFileName: ((Any) -> String?)?
453
+ var exportingCondition: ((Any) -> Bool)?
454
+ var visibility = TransferRepresentationVisibility.all
455
+
456
+ /// A representation of the shim's own (SwiftUI's `Image`, whose bytes
457
+ /// know their type): `exporter` returns nil when it has nothing to give.
458
+ public init(exportType: UTType?, importType: UTType?, exporter: Exporter?, importer: Importer?) {
459
+ self.exportType = exportType
460
+ self.importType = importType
461
+ self.exporter = exporter
462
+ self.importer = importer
463
+ }
464
+
465
+ var exportedContentTypes: [UTType] {
466
+ guard exporter != nil else { return [] }
467
+ return proxyExportTypes?() ?? exportType.map { [$0] } ?? []
468
+ }
469
+
470
+ var importedContentTypes: [UTType] {
471
+ guard importer != nil else { return [] }
472
+ return proxyImportTypes?() ?? importType.map { [$0] } ?? []
473
+ }
474
+
475
+ /// Whether this representation exports something `wanted` takes (anything, for nil).
476
+ func exports(_ wanted: UTType?) -> Bool {
477
+ guard exporter != nil else { return false }
478
+ guard let wanted else { return true }
479
+ return exportedContentTypes.contains { $0.conforms(to: wanted) }
480
+ }
481
+
482
+ /// Whether this representation imports content of `type`.
483
+ func imports(_ type: UTType) -> Bool {
484
+ importedContentTypes.contains { type.conforms(to: $0) }
485
+ }
486
+ }
487
+
488
+ /// A representation the shim builds from nodes directly.
489
+ public protocol _TransferPrimitive {
490
+ var _transferNodes: [_TransferNode] { get }
491
+ }
492
+
493
+ struct _UncheckedBox<Value>: @unchecked Sendable {
494
+ let value: Value
495
+ init(_ value: Value) { self.value = value }
496
+ }
497
+
498
+ /// Walks representations: what sharing, item providers and pickers use.
499
+ public enum _Transfer {
500
+ /// A representation's nodes: its own, or its body's.
501
+ public static func nodes<R: TransferRepresentation>(of representation: R) -> [_TransferNode] {
502
+ if let primitive = representation as? any _TransferPrimitive { return primitive._transferNodes }
503
+ return nodes(of: representation.body)
504
+ }
505
+
506
+ public static func nodes<T: Transferable>(_ type: T.Type) -> [_TransferNode] {
507
+ nodes(of: T.transferRepresentation)
508
+ }
509
+
510
+ public static func exportedContentTypes<T: Transferable>(_ type: T.Type) -> [UTType] {
511
+ unique(nodes(type).flatMap(\.exportedContentTypes))
512
+ }
513
+
514
+ public static func importedContentTypes<T: Transferable>(_ type: T.Type) -> [UTType] {
515
+ unique(nodes(type).flatMap(\.importedContentTypes))
516
+ }
517
+
518
+ /// Whether `type` imports content of `contentType`.
519
+ public static func canImport<T: Transferable>(_ type: T.Type, contentType: UTType) -> Bool {
520
+ nodes(type).contains { $0.imports(contentType) }
521
+ }
522
+
523
+ /// The item's content from the first representation that exports
524
+ /// `wanted` (anything, for nil) and whose condition holds; nil if none does.
525
+ nonisolated(nonsending) public static func export<T: Transferable>(_ item: T, as wanted: UTType? = nil) async throws -> _TransferContent? {
526
+ // `String` and `URL` are leaves the page shares as text and links.
527
+ for node in nodes(T.self) where node.exports(wanted) {
528
+ if let condition = node.exportingCondition, !condition(item) { continue }
529
+ guard var content = try await node.exporter?(item, wanted) else { continue }
530
+ if let name = node.suggestedFileName?(item) {
531
+ content.suggestedName = (name as NSString).deletingPathExtension
532
+ }
533
+ if content.value == nil, wanted == nil, T.self == String.self || T.self == URL.self { content.value = item }
534
+ return content
535
+ }
536
+ return nil
537
+ }
538
+
539
+ /// A value of `type` from `content`, through the first representation
540
+ /// that imports its content type; nil if none does.
541
+ nonisolated(nonsending) public static func `import`<T: Transferable>(_ type: T.Type, from content: _TransferContent) async throws -> T? {
542
+ for node in nodes(type) where node.imports(content.contentType) {
543
+ if let value = try await node.importer?(content) as? T { return value }
544
+ }
545
+ return nil
546
+ }
547
+
548
+ private static func unique(_ types: [UTType]) -> [UTType] {
549
+ var seen = Set<UTType>()
550
+ return types.filter { seen.insert($0).inserted }
551
+ }
552
+ }
553
+
554
+ // MARK: - Foundation's types
555
+
556
+ extension String: Transferable {
557
+ public static var transferRepresentation: _TransferRepresentationList<String> {
558
+ return _TransferRepresentationList(nodes: [
559
+ _TransferNode(exportType: .utf8PlainText, importType: .text,
560
+ exporter: { item, _ in _TransferContent(contentType: .utf8PlainText, data: Data((item as! String).utf8)) },
561
+ importer: { content in String(decoding: try content.loadData(), as: UTF8.self) }),
562
+ ])
563
+ }
564
+ }
565
+
566
+ extension Data: Transferable {
567
+ public static var transferRepresentation: _TransferRepresentationList<Data> {
568
+ return _TransferRepresentationList(nodes: [
569
+ _TransferNode(exportType: .data, importType: .data,
570
+ exporter: { item, _ in _TransferContent(contentType: .data, data: item as? Data) },
571
+ importer: { content in try content.loadData() }),
572
+ ])
573
+ }
574
+ }
575
+
576
+ extension URL: Transferable {
577
+ /// A link as `public.url` (its string), or a file as `public.file-url`.
578
+ public static var transferRepresentation: _TransferRepresentationList<URL> {
579
+ return _TransferRepresentationList(nodes: [
580
+ _TransferNode(exportType: .url, importType: .url,
581
+ exporter: { item, _ in
582
+ let url = item as! URL
583
+ return _TransferContent(contentType: url.isFileURL ? .fileURL : .url, data: Data(url.absoluteString.utf8))
584
+ },
585
+ importer: { content in
586
+ if content.contentType.conforms(to: .url), let data = content.data {
587
+ return URL(string: String(decoding: data, as: UTF8.self).trimmingCharacters(in: .whitespacesAndNewlines))
588
+ }
589
+ return content.file
590
+ }),
591
+ ])
592
+ }
593
+ }
594
+
595
+ extension AttributedString: Transferable {
596
+ /// As its plain text: the browser's share sheet and clipboard take text.
597
+ public static var transferRepresentation: _TransferRepresentationList<AttributedString> {
598
+ return _TransferRepresentationList(nodes: [
599
+ _TransferNode(exportType: .utf8PlainText, importType: .text,
600
+ exporter: { item, _ in
601
+ _TransferContent(contentType: .utf8PlainText, data: Data(String((item as! AttributedString).characters).utf8))
602
+ },
603
+ importer: { content in AttributedString(String(decoding: try content.loadData(), as: UTF8.self)) }),
604
+ ])
605
+ }
606
+ }