@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,655 @@
1
+ // `NSItemProvider`, Foundation's carrier for content offered in several
2
+ // types (a drag, a paste, a share extension's input, a link preview's
3
+ // image), which corelibs Foundation does not have. In the browser a provider
4
+ // is a list of registrations kept in memory: data, a file, an object or a
5
+ // `Transferable` value, each under a content type. Loads run as tasks on the
6
+ // browser's one thread and call their completion handlers when done; a
7
+ // file representation is a copy in the temporary directory, removed once the
8
+ // handler returns, as on iOS.
9
+ //
10
+ // SwiftUI's drag-and-drop API takes providers, so it lives here (the SwiftUI
11
+ // shim cannot see this module): `onDrop`, `onDrag`, `DropInfo`,
12
+ // `DropDelegate`. The page has no drag and drop between views or apps yet,
13
+ // so the views are left as they are and nothing is ever dropped
14
+ // (docs/ops-protocol.md, "Sharing and media").
15
+
16
+ import Foundation
17
+ import SwiftUI
18
+
19
+ #if os(WASI)
20
+ /// Foundation's `Progress`, which corelibs Foundation leaves out on WASI: a
21
+ /// count of units done, children that count for part of their parent, and
22
+ /// cancelling, pausing and resuming (which run the handlers; the work itself
23
+ /// decides what they mean). It is an `NSObject`, so `observe(\.fractionCompleted)`
24
+ /// works (KeyValueObserving.swift), as ButtonKit follows one.
25
+ open class Progress: NSObject, @unchecked Sendable {
26
+ /// The units this progress itself has done; finished children add their pending units.
27
+ private var ownCompleted: Int64 = 0
28
+ private var children: [(progress: Progress, pending: Int64)] = []
29
+
30
+ open var totalUnitCount: Int64
31
+
32
+ /// Units done: this progress's own, plus each finished child's pending units.
33
+ open var completedUnitCount: Int64 {
34
+ get { ownCompleted + finishedChildUnits }
35
+ set { ownCompleted = newValue - finishedChildUnits }
36
+ }
37
+
38
+ open var localizedDescription: String!
39
+ open var localizedAdditionalDescription: String!
40
+ open private(set) var isCancelled = false
41
+ open var isCancellable = true
42
+ open var isPausable = false
43
+ open private(set) var isPaused = false
44
+ open var cancellationHandler: (@Sendable () -> Void)?
45
+ open var pausingHandler: (@Sendable () -> Void)?
46
+ open var resumingHandler: (@Sendable () -> Void)?
47
+
48
+ public init(totalUnitCount: Int64) {
49
+ self.totalUnitCount = totalUnitCount
50
+ super.init()
51
+ }
52
+
53
+ public convenience override init() {
54
+ self.init(totalUnitCount: -1)
55
+ }
56
+
57
+ /// A progress that becomes `parent`'s child (for `pendingUnitCount` of its units, once it has a total).
58
+ public convenience init(totalUnitCount: Int64, parent: Progress, pendingUnitCount: Int64) {
59
+ self.init(totalUnitCount: totalUnitCount)
60
+ parent.addChild(self, withPendingUnitCount: pendingUnitCount)
61
+ }
62
+
63
+ open class func discreteProgress(totalUnitCount: Int64) -> Progress {
64
+ Progress(totalUnitCount: totalUnitCount)
65
+ }
66
+
67
+ /// The progress current on this thread: none, the browser build has no implicit tree.
68
+ open class func current() -> Progress? { nil }
69
+
70
+ open func addChild(_ child: Progress, withPendingUnitCount inUnitCount: Int64) {
71
+ children.append((child, inUnitCount))
72
+ if isCancelled { child.cancel() }
73
+ }
74
+
75
+ private var finishedChildUnits: Int64 {
76
+ children.reduce(0) { $0 + ($1.progress.isFinished ? $1.pending : 0) }
77
+ }
78
+
79
+ /// Done units over the total, counting the unfinished children's fractions; 0 while indeterminate.
80
+ open var fractionCompleted: Double {
81
+ guard totalUnitCount > 0 else { return 0 }
82
+ let running = children.reduce(0.0) { $0 + ($1.progress.isFinished ? 0 : $1.progress.fractionCompleted * Double($1.pending)) }
83
+ return min(1, max(0, (Double(completedUnitCount) + running) / Double(totalUnitCount)))
84
+ }
85
+
86
+ /// As on Apple platforms: a negative count, or both counts zero.
87
+ open var isIndeterminate: Bool {
88
+ totalUnitCount < 0 || completedUnitCount < 0 || (totalUnitCount == 0 && completedUnitCount == 0)
89
+ }
90
+
91
+ open var isFinished: Bool { totalUnitCount > 0 && completedUnitCount >= totalUnitCount }
92
+
93
+ open func cancel() {
94
+ guard !isCancelled else { return }
95
+ isCancelled = true
96
+ cancellationHandler?()
97
+ for child in children { child.progress.cancel() }
98
+ }
99
+
100
+ open func pause() {
101
+ guard !isPaused else { return }
102
+ isPaused = true
103
+ pausingHandler?()
104
+ for child in children { child.progress.pause() }
105
+ }
106
+
107
+ open func resume() {
108
+ guard isPaused else { return }
109
+ isPaused = false
110
+ resumingHandler?()
111
+ for child in children { child.progress.resume() }
112
+ }
113
+ }
114
+ #endif
115
+
116
+ // MARK: - Reading and writing objects
117
+
118
+ /// A type an item provider can hand out as an object (`loadObject(ofClass:)`).
119
+ /// `String`, `URL` and `UIImage` are; on iOS the Objective-C classes behind
120
+ /// them are.
121
+ public protocol NSItemProviderReading {
122
+ static var readableTypeIdentifiersForItemProvider: [String] { get }
123
+ static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self
124
+ }
125
+
126
+ /// A type an item provider can be made from (`NSItemProvider(object:)`).
127
+ public protocol NSItemProviderWriting {
128
+ static var writableTypeIdentifiersForItemProvider: [String] { get }
129
+ var writableTypeIdentifiersForItemProvider: [String] { get }
130
+ func loadData(withTypeIdentifier typeIdentifier: String,
131
+ forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress?
132
+ }
133
+
134
+ extension NSItemProviderWriting {
135
+ public var writableTypeIdentifiersForItemProvider: [String] { Self.writableTypeIdentifiersForItemProvider }
136
+ }
137
+
138
+ extension String: NSItemProviderReading, NSItemProviderWriting {
139
+ public static var readableTypeIdentifiersForItemProvider: [String] { [UTType.utf8PlainText.identifier, UTType.plainText.identifier, UTType.text.identifier] }
140
+ public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> String {
141
+ String(decoding: data, as: UTF8.self)
142
+ }
143
+ public static var writableTypeIdentifiersForItemProvider: [String] { [UTType.utf8PlainText.identifier] }
144
+ public func loadData(withTypeIdentifier typeIdentifier: String,
145
+ forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress? {
146
+ completionHandler(Data(utf8), nil)
147
+ return nil
148
+ }
149
+ }
150
+
151
+ extension URL: NSItemProviderReading, NSItemProviderWriting {
152
+ public static var readableTypeIdentifiersForItemProvider: [String] { [UTType.url.identifier, UTType.fileURL.identifier, UTType.plainText.identifier] }
153
+ public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> URL {
154
+ let text = String(decoding: data, as: UTF8.self).trimmingCharacters(in: .whitespacesAndNewlines)
155
+ guard let url = URL(string: text) else { throw CocoaError(.fileReadCorruptFile) }
156
+ return url
157
+ }
158
+ public static var writableTypeIdentifiersForItemProvider: [String] { [UTType.url.identifier] }
159
+ public var writableTypeIdentifiersForItemProvider: [String] { [(isFileURL ? UTType.fileURL : UTType.url).identifier] }
160
+ public func loadData(withTypeIdentifier typeIdentifier: String,
161
+ forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress? {
162
+ completionHandler(Data(absoluteString.utf8), nil)
163
+ return nil
164
+ }
165
+ }
166
+
167
+ /// UIKit's image (the SwiftUI shim's `UIImage`, which this module sees):
168
+ /// read from any image file the page can draw; written as the file it was
169
+ /// made from, unchanged. An image with no file (a drawing, a Core Image
170
+ /// result, a symbol) offers no data, as it has no bytes in Swift.
171
+ extension UIImage: NSItemProviderReading, NSItemProviderWriting {
172
+ public static var readableTypeIdentifiersForItemProvider: [String] {
173
+ [UTType.png, .jpeg, .gif, .heic, .webP, .tiff, .bmp, .image].map(\.identifier)
174
+ }
175
+
176
+ public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self {
177
+ guard let image = UIImage(data: data) as? Self else { throw CocoaError(.fileReadCorruptFile) }
178
+ return image
179
+ }
180
+
181
+ public static var writableTypeIdentifiersForItemProvider: [String] { [UTType.png.identifier] }
182
+
183
+ public var writableTypeIdentifiersForItemProvider: [String] {
184
+ guard let file = _encodedFile, let type = UTType(mimeType: file.mime) else { return [UTType.png.identifier] }
185
+ return [type.identifier]
186
+ }
187
+
188
+ public func loadData(withTypeIdentifier typeIdentifier: String,
189
+ forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress? {
190
+ if let file = _encodedFile { completionHandler(file.data, nil) } else { completionHandler(nil, CocoaError(.fileReadNoPermission)) }
191
+ return nil
192
+ }
193
+ }
194
+
195
+ // MARK: - NSItemProvider
196
+
197
+ /// Content offered in one or more types, loaded on request.
198
+ open class NSItemProvider: NSObject, @unchecked Sendable {
199
+ public enum FileOptions: Int, Sendable { case openInPlace = 1 }
200
+ public struct _FileOptions: OptionSet, Sendable {
201
+ public let rawValue: Int
202
+ public init(rawValue: Int) { self.rawValue = rawValue }
203
+ public static let openInPlace = _FileOptions(rawValue: 1)
204
+ }
205
+
206
+ /// Who may see a registration. Kept: the app is alone in the browser.
207
+ public enum RepresentationVisibility: Int, Sendable { case all = 0, team = 1, group = 2, ownProcess = 3 }
208
+
209
+ public typealias CompletionHandler = @Sendable (Any?, (any Error)?) -> Void
210
+ public typealias LoadHandler = @Sendable (CompletionHandler?, AnyClass?, [AnyHashable: Any]?) -> Void
211
+
212
+ public static let errorDomain = "NSItemProviderErrorDomain"
213
+ public enum ErrorCode: Int, Sendable {
214
+ case unknownError = -1, itemUnavailableError = -1000, unexpectedValueClassError = -1100, unavailableCoercionError = -1200
215
+ }
216
+
217
+ struct Registration {
218
+ let type: UTType
219
+ /// The content, when asked for; nil when it has none in this type.
220
+ let load: () async throws -> _TransferContent
221
+ /// The object it was registered from (`loadObject` and `loadItem` hand it back).
222
+ let object: Any?
223
+ }
224
+
225
+ private var registrations: [Registration] = []
226
+
227
+ /// The name a receiver gives the content (a file's name, without its extension).
228
+ open var suggestedName: String?
229
+
230
+ public override init() { super.init() }
231
+
232
+ /// A provider of `object` in each type it writes.
233
+ public convenience init(object: any NSItemProviderWriting) {
234
+ self.init()
235
+ registerObject(object, visibility: .all)
236
+ }
237
+
238
+ /// A provider of the file at `fileURL`, typed by its extension; nil for a
239
+ /// URL that is not a file's.
240
+ public convenience init?(contentsOf fileURL: URL?) {
241
+ guard let fileURL, fileURL.isFileURL else { return nil }
242
+ self.init()
243
+ let type = UTType(filenameExtension: fileURL.pathExtension) ?? .data
244
+ suggestedName = fileURL.deletingPathExtension().lastPathComponent
245
+ registrations.append(Registration(type: type, load: {
246
+ _TransferContent(contentType: type, file: fileURL, isOriginalFile: true, suggestedName: fileURL.deletingPathExtension().lastPathComponent)
247
+ }, object: fileURL))
248
+ }
249
+
250
+ /// A provider of `item` (a string, URL, data or other value) as `typeIdentifier`.
251
+ public convenience init(item: Any?, typeIdentifier: String?) {
252
+ self.init()
253
+ guard let item, let typeIdentifier else { return }
254
+ let type = Self.type(typeIdentifier)
255
+ registrations.append(Registration(type: type, load: {
256
+ guard let data = Self.data(of: item) else { throw Self.error(.unavailableCoercionError) }
257
+ return _TransferContent(contentType: type, data: data)
258
+ }, object: item))
259
+ }
260
+
261
+ // MARK: Registering
262
+
263
+ open func registerObject(_ object: any NSItemProviderWriting, visibility: RepresentationVisibility) {
264
+ let box = _UnsafeBox(object)
265
+ for identifier in object.writableTypeIdentifiersForItemProvider {
266
+ let type = Self.type(identifier)
267
+ registrations.append(Registration(type: type, load: {
268
+ let data = try await Self.loadData { box.value.loadData(withTypeIdentifier: identifier, forItemProviderCompletionHandler: $0) }
269
+ return _TransferContent(contentType: type, data: data)
270
+ }, object: object))
271
+ }
272
+ }
273
+
274
+ open func registerDataRepresentation(forTypeIdentifier typeIdentifier: String, visibility: RepresentationVisibility,
275
+ loadHandler: @escaping @Sendable (@escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress?) {
276
+ registerDataRepresentation(for: Self.type(typeIdentifier), visibility: visibility, loadHandler: loadHandler)
277
+ }
278
+
279
+ open func registerDataRepresentation(for contentType: UTType, visibility: RepresentationVisibility = .all,
280
+ loadHandler: @escaping @Sendable (@escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress?) {
281
+ registrations.append(Registration(type: contentType, load: {
282
+ _TransferContent(contentType: contentType, data: try await Self.loadData(loadHandler))
283
+ }, object: nil))
284
+ }
285
+
286
+ open func registerFileRepresentation(forTypeIdentifier typeIdentifier: String, fileOptions: _FileOptions = [],
287
+ visibility: RepresentationVisibility,
288
+ loadHandler: @escaping @Sendable (@escaping @Sendable (URL?, Bool, (any Error)?) -> Void) -> Progress?) {
289
+ registerFileRepresentation(for: Self.type(typeIdentifier), visibility: visibility,
290
+ openInPlace: fileOptions.contains(.openInPlace), loadHandler: loadHandler)
291
+ }
292
+
293
+ open func registerFileRepresentation(for contentType: UTType, visibility: RepresentationVisibility = .all, openInPlace: Bool = false,
294
+ loadHandler: @escaping @Sendable (@escaping @Sendable (URL?, Bool, (any Error)?) -> Void) -> Progress?) {
295
+ registrations.append(Registration(type: contentType, load: {
296
+ let (url, original) = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<(URL, Bool), any Error>) in
297
+ _ = loadHandler { url, original, error in
298
+ if let url { continuation.resume(returning: (url, original)) }
299
+ else { continuation.resume(throwing: error ?? Self.error(.itemUnavailableError)) }
300
+ }
301
+ }
302
+ return _TransferContent(contentType: contentType, file: url, isOriginalFile: original)
303
+ }, object: nil))
304
+ }
305
+
306
+ /// The old, item-based registration: `loadHandler` is asked for the item
307
+ /// and hands it to the completion handler it is given.
308
+ open func registerItem(forTypeIdentifier typeIdentifier: String, loadHandler: @escaping LoadHandler) {
309
+ let type = Self.type(typeIdentifier)
310
+ registrations.append(Registration(type: type, load: {
311
+ let item: Any? = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<_UnsafeBox<Any?>, any Error>) in
312
+ loadHandler({ item, error in
313
+ if let error { continuation.resume(throwing: error) } else { continuation.resume(returning: _UnsafeBox(item)) }
314
+ }, nil, nil)
315
+ }.value
316
+ if let url = item as? URL, url.isFileURL { return _TransferContent(contentType: type, file: url, isOriginalFile: true) }
317
+ guard let item, let data = Self.data(of: item) else { throw Self.error(.unavailableCoercionError) }
318
+ return _TransferContent(contentType: type, data: data)
319
+ }, object: nil))
320
+ }
321
+
322
+ /// A `Transferable` value, in every type it exports.
323
+ public func register<T: Transferable>(_ transferable: @autoclosure @escaping @Sendable () -> T) {
324
+ for type in T.exportedContentTypes() {
325
+ registrations.append(Registration(type: type, load: {
326
+ guard let content = try await _Transfer.export(transferable(), as: type) else { throw Self.error(.unavailableCoercionError) }
327
+ return content
328
+ }, object: nil))
329
+ }
330
+ }
331
+
332
+ // MARK: What it offers
333
+
334
+ open var registeredTypeIdentifiers: [String] { registeredContentTypes.map(\.identifier) }
335
+
336
+ open var registeredContentTypes: [UTType] {
337
+ var seen = Set<UTType>()
338
+ return registrations.map(\.type).filter { seen.insert($0).inserted }
339
+ }
340
+
341
+ open func registeredTypeIdentifiers(fileOptions: _FileOptions) -> [String] { registeredTypeIdentifiers }
342
+
343
+ open func registeredContentTypes(conformingTo contentType: UTType) -> [UTType] {
344
+ registeredContentTypes.filter { $0.conforms(to: contentType) }
345
+ }
346
+
347
+ open var registeredContentTypesForOpenInPlace: [UTType] { [] }
348
+
349
+ open func hasItemConformingToTypeIdentifier(_ typeIdentifier: String) -> Bool {
350
+ let wanted = Self.type(typeIdentifier)
351
+ return registrations.contains { $0.type.conforms(to: wanted) }
352
+ }
353
+
354
+ open func hasRepresentationConforming(toTypeIdentifier typeIdentifier: String, fileOptions: _FileOptions = []) -> Bool {
355
+ hasItemConformingToTypeIdentifier(typeIdentifier)
356
+ }
357
+
358
+ open func canLoadObject(ofClass aClass: any NSItemProviderReading.Type) -> Bool {
359
+ registrations.contains { registration in
360
+ registration.object.map { Swift.type(of: $0) == aClass } ?? false
361
+ || aClass.readableTypeIdentifiersForItemProvider.contains { registration.type.conforms(to: Self.type($0)) }
362
+ }
363
+ }
364
+
365
+ // MARK: Loading
366
+
367
+ /// The content of the first registration conforming to `contentType`.
368
+ func content(conformingTo contentType: UTType) async throws -> _TransferContent {
369
+ guard let registration = registrations.first(where: { $0.type.conforms(to: contentType) }) else {
370
+ throw Self.error(.itemUnavailableError)
371
+ }
372
+ var content = try await registration.load()
373
+ if content.suggestedName == nil { content.suggestedName = suggestedName }
374
+ return content
375
+ }
376
+
377
+ @discardableResult
378
+ open func loadDataRepresentation(forTypeIdentifier typeIdentifier: String,
379
+ completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress {
380
+ loadDataRepresentation(for: Self.type(typeIdentifier), completionHandler: completionHandler)
381
+ }
382
+
383
+ @discardableResult
384
+ open func loadDataRepresentation(for contentType: UTType,
385
+ completionHandler: @escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress {
386
+ run { () async throws -> Data in try await self.content(conformingTo: contentType).loadData() } done: { result in
387
+ switch result {
388
+ case .success(let data): completionHandler(data, nil)
389
+ case .failure(let error): completionHandler(nil, error)
390
+ }
391
+ }
392
+ }
393
+
394
+ /// The content as a file: a copy in the temporary directory, removed once
395
+ /// `completionHandler` returns.
396
+ @discardableResult
397
+ open func loadFileRepresentation(forTypeIdentifier typeIdentifier: String,
398
+ completionHandler: @escaping @Sendable (URL?, (any Error)?) -> Void) -> Progress {
399
+ loadFileRepresentation(for: Self.type(typeIdentifier), openInPlace: false) { url, _, error in completionHandler(url, error) }
400
+ }
401
+
402
+ @discardableResult
403
+ open func loadFileRepresentation(for contentType: UTType, openInPlace: Bool = false,
404
+ completionHandler: @escaping @Sendable (URL?, Bool, (any Error)?) -> Void) -> Progress {
405
+ run { () async throws -> ReceivedTransferredFile in
406
+ try Self.receivedFile(try await self.content(conformingTo: contentType), inPlace: openInPlace)
407
+ } done: { result in
408
+ switch result {
409
+ case .success(let file):
410
+ completionHandler(file.file, file.isOriginalFile, nil)
411
+ if !file.isOriginalFile { try? FileManager.default.removeItem(at: file.file) }
412
+ case .failure(let error):
413
+ completionHandler(nil, false, error)
414
+ }
415
+ }
416
+ }
417
+
418
+ @discardableResult
419
+ open func loadInPlaceFileRepresentation(forTypeIdentifier typeIdentifier: String,
420
+ completionHandler: @escaping @Sendable (URL?, Bool, (any Error)?) -> Void) -> Progress {
421
+ loadFileRepresentation(for: Self.type(typeIdentifier), openInPlace: true, completionHandler: completionHandler)
422
+ }
423
+
424
+ /// The registered object itself when it is of `aClass`, else one made
425
+ /// from the first readable type's data.
426
+ @discardableResult
427
+ open func loadObject<T: NSItemProviderReading>(ofClass aClass: T.Type,
428
+ completionHandler: @escaping @Sendable (T?, (any Error)?) -> Void) -> Progress {
429
+ run { () async throws -> _UnsafeBox<T> in
430
+ if let object = self.registrations.lazy.compactMap({ $0.object as? T }).first { return _UnsafeBox(object) }
431
+ for identifier in T.readableTypeIdentifiersForItemProvider {
432
+ let type = Self.type(identifier)
433
+ guard self.registrations.contains(where: { $0.type.conforms(to: type) }) else { continue }
434
+ let data = try await self.content(conformingTo: type).loadData()
435
+ return _UnsafeBox(try T.object(withItemProviderData: data, typeIdentifier: identifier))
436
+ }
437
+ throw Self.error(.unavailableCoercionError)
438
+ } done: { result in
439
+ switch result {
440
+ case .success(let box): completionHandler(box.value, nil)
441
+ case .failure(let error): completionHandler(nil, error)
442
+ }
443
+ }
444
+ }
445
+
446
+ /// The old, item-based load: the registered object, a file's URL, a
447
+ /// string for text, a URL for a link, a `UIImage` for image data, else the data.
448
+ open func loadItem(forTypeIdentifier typeIdentifier: String, options: [AnyHashable: Any]? = nil,
449
+ completionHandler: CompletionHandler? = nil) {
450
+ let wanted = Self.type(typeIdentifier)
451
+ _ = run { () async throws -> _UnsafeBox<Any?> in
452
+ guard let registration = self.registrations.first(where: { $0.type.conforms(to: wanted) }) else {
453
+ throw Self.error(.itemUnavailableError)
454
+ }
455
+ if let object = registration.object { return _UnsafeBox(object) }
456
+ let content = try await registration.load()
457
+ if let file = content.file { return _UnsafeBox(file) }
458
+ let data = try content.loadData()
459
+ if content.contentType.conforms(to: .url) { return _UnsafeBox(try URL.object(withItemProviderData: data, typeIdentifier: typeIdentifier)) }
460
+ if content.contentType.conforms(to: .text) { return _UnsafeBox(String(decoding: data, as: UTF8.self)) }
461
+ if content.contentType.conforms(to: .image), let image = UIImage(data: data) { return _UnsafeBox(image) }
462
+ return _UnsafeBox(data)
463
+ } done: { result in
464
+ switch result {
465
+ case .success(let box): completionHandler?(box.value, nil)
466
+ case .failure(let error): completionHandler?(nil, error)
467
+ }
468
+ }
469
+ }
470
+
471
+ /// The content as `type`, through its first importing representation
472
+ /// that takes a registered type.
473
+ @discardableResult
474
+ public func loadTransferable<T: Transferable>(type: T.Type,
475
+ completionHandler: @escaping @Sendable (Result<T, any Error>) -> Void) -> Progress {
476
+ run { () async throws -> _UnsafeBox<T> in _UnsafeBox(try await self.loadTransferableNow(type)) } done: { result in
477
+ completionHandler(result.map(\.value))
478
+ }
479
+ }
480
+
481
+ /// `loadTransferable(type:completionHandler:)`, awaited.
482
+ nonisolated(nonsending) public func loadTransferable<T: Transferable>(type: T.Type) async throws -> T {
483
+ try await loadTransferableNow(type)
484
+ }
485
+
486
+ nonisolated(nonsending) private func loadTransferableNow<T: Transferable>(_ type: T.Type) async throws -> T {
487
+ for registration in registrations where _Transfer.canImport(T.self, contentType: registration.type) {
488
+ var content = try await registration.load()
489
+ if content.suggestedName == nil { content.suggestedName = suggestedName }
490
+ if let value = try await _Transfer.import(T.self, from: content) { return value }
491
+ }
492
+ throw Self.error(.unavailableCoercionError)
493
+ }
494
+
495
+ // MARK: Helpers
496
+
497
+ /// Runs `work` as a task and reports its result to `done`; the progress
498
+ /// completes with it.
499
+ private func run<Value>(_ work: @escaping () async throws -> Value, done: @escaping (Result<Value, any Error>) -> Void) -> Progress {
500
+ let job = _ItemProviderJob(work: work, done: done)
501
+ Task { await job.perform() }
502
+ return job.progress
503
+ }
504
+
505
+ private static func loadData(_ handler: @escaping @Sendable (@escaping @Sendable (Data?, (any Error)?) -> Void) -> Progress?) async throws -> Data {
506
+ try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Data, any Error>) in
507
+ _ = handler { data, error in
508
+ if let data { continuation.resume(returning: data) }
509
+ else { continuation.resume(throwing: error ?? Self.error(.itemUnavailableError)) }
510
+ }
511
+ }
512
+ }
513
+
514
+ static func type(_ identifier: String) -> UTType {
515
+ UTType(identifier) ?? UTType(exportedAs: identifier)
516
+ }
517
+
518
+ static func data(of item: Any) -> Data? {
519
+ switch item {
520
+ case let data as Data: data
521
+ case let string as String: Data(string.utf8)
522
+ case let url as URL: Data(url.absoluteString.utf8)
523
+ case let attributed as NSAttributedString: Data(attributed.string.utf8)
524
+ default: nil
525
+ }
526
+ }
527
+
528
+ static func error(_ code: ErrorCode) -> NSError {
529
+ NSError(domain: errorDomain, code: code.rawValue)
530
+ }
531
+
532
+ static func receivedFile(_ content: _TransferContent, inPlace: Bool) throws -> ReceivedTransferredFile {
533
+ if let file = content.file, inPlace { return ReceivedTransferredFile(_file: file, isOriginalFile: true) }
534
+ let folder = FileManager.default.temporaryDirectory.appendingPathComponent("ItemProvider-\(UUID().uuidString)", isDirectory: true)
535
+ try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
536
+ let copy = folder.appendingPathComponent(content.fileName)
537
+ if let file = content.file { try FileManager.default.copyItem(at: file, to: copy) } else { try content.loadData().write(to: copy) }
538
+ return ReceivedTransferredFile(_file: copy, isOriginalFile: false)
539
+ }
540
+ }
541
+
542
+ /// One load: its work, its completion and its progress.
543
+ final class _ItemProviderJob<Value>: @unchecked Sendable {
544
+ let work: () async throws -> Value
545
+ let done: (Result<Value, any Error>) -> Void
546
+ let progress = Progress(totalUnitCount: 1)
547
+
548
+ init(work: @escaping () async throws -> Value, done: @escaping (Result<Value, any Error>) -> Void) {
549
+ self.work = work
550
+ self.done = done
551
+ }
552
+
553
+ func perform() async {
554
+ var result: Result<Value, any Error>
555
+ do {
556
+ let value = try await work()
557
+ result = .success(value)
558
+ } catch {
559
+ result = .failure(error)
560
+ }
561
+ progress.completedUnitCount = 1
562
+ done(result)
563
+ }
564
+ }
565
+
566
+ /// A value carried across a task boundary on the browser's one thread.
567
+ struct _UnsafeBox<Value>: @unchecked Sendable {
568
+ let value: Value
569
+ init(_ value: Value) { self.value = value }
570
+ }
571
+
572
+ // MARK: - SwiftUI: drag and drop
573
+
574
+ /// What a drop offers: where it is and the providers of what was dropped.
575
+ /// The page has no drag and drop yet, so no drop is ever delivered.
576
+ public struct DropInfo {
577
+ public let location: SwiftUI.CGPoint
578
+ let providers: [NSItemProvider]
579
+
580
+ public init(_location location: SwiftUI.CGPoint, providers: [NSItemProvider]) {
581
+ self.location = location
582
+ self.providers = providers
583
+ }
584
+
585
+ public func hasItemsConforming(to contentTypes: [UTType]) -> Bool {
586
+ providers.contains { provider in contentTypes.contains { !provider.registeredContentTypes(conformingTo: $0).isEmpty } }
587
+ }
588
+
589
+ public func hasItemsConforming(to typeIdentifiers: [String]) -> Bool {
590
+ hasItemsConforming(to: typeIdentifiers.map(NSItemProvider.type))
591
+ }
592
+
593
+ public func itemProviders(for contentTypes: [UTType]) -> [NSItemProvider] {
594
+ providers.filter { provider in contentTypes.contains { !provider.registeredContentTypes(conformingTo: $0).isEmpty } }
595
+ }
596
+
597
+ public func itemProviders(for typeIdentifiers: [String]) -> [NSItemProvider] {
598
+ itemProviders(for: typeIdentifiers.map(NSItemProvider.type))
599
+ }
600
+ }
601
+
602
+ /// How a drop would act on what it carries.
603
+ public enum DropOperation: Sendable {
604
+ case cancel, forbidden, copy, move
605
+ }
606
+
607
+ public struct DropProposal: Sendable {
608
+ public let operation: DropOperation
609
+ public init(operation: DropOperation) { self.operation = operation }
610
+ }
611
+
612
+ /// What a drop target is told as a drag moves over it and drops. Every
613
+ /// method has a default, as on iOS. Never called in the browser yet.
614
+ @MainActor
615
+ public protocol DropDelegate {
616
+ func validateDrop(info: DropInfo) -> Bool
617
+ func performDrop(info: DropInfo) -> Bool
618
+ func dropEntered(info: DropInfo)
619
+ func dropUpdated(info: DropInfo) -> DropProposal?
620
+ func dropExited(info: DropInfo)
621
+ }
622
+
623
+ extension DropDelegate {
624
+ public func validateDrop(info: DropInfo) -> Bool { true }
625
+ public func dropEntered(info: DropInfo) {}
626
+ public func dropUpdated(info: DropInfo) -> DropProposal? { nil }
627
+ public func dropExited(info: DropInfo) {}
628
+ }
629
+
630
+ extension View {
631
+ /// Accepted; nothing is dropped in the browser, so `action` is never called.
632
+ public func onDrop(of supportedContentTypes: [UTType], isTargeted: Binding<Bool>?,
633
+ perform action: @escaping ([NSItemProvider]) -> Bool) -> some View { self }
634
+
635
+ /// Accepted; nothing is dropped in the browser, so `action` is never called.
636
+ public func onDrop(of supportedContentTypes: [UTType], isTargeted: Binding<Bool>?,
637
+ perform action: @escaping ([NSItemProvider], SwiftUI.CGPoint) -> Bool) -> some View { self }
638
+
639
+ /// Accepted; nothing is dropped in the browser, so the delegate hears nothing.
640
+ public func onDrop(of supportedContentTypes: [UTType], delegate: any DropDelegate) -> some View { self }
641
+
642
+ public func onDrop(of supportedTypes: [String], isTargeted: Binding<Bool>?,
643
+ perform action: @escaping ([NSItemProvider]) -> Bool) -> some View { self }
644
+
645
+ public func onDrop(of supportedTypes: [String], delegate: any DropDelegate) -> some View { self }
646
+
647
+ /// Accepted; the view cannot be dragged in the browser.
648
+ public func onDrag(_ data: @escaping () -> NSItemProvider) -> some View { self }
649
+
650
+ /// Accepted; the view cannot be dragged in the browser.
651
+ public func onDrag<Preview: View>(_ data: @escaping () -> NSItemProvider, @ViewBuilder preview: () -> Preview) -> some View { self }
652
+
653
+ /// Accepted (macOS's services and iOS's drag source): nothing asks for the provider.
654
+ public func itemProvider(_ action: (() -> NSItemProvider?)?) -> some View { self }
655
+ }