@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,363 @@
1
+ // `UIPasteboard` in the browser. A page cannot read the system clipboard
2
+ // without asking the viewer each time (and never synchronously), so the
3
+ // pasteboard keeps its items in memory, as an app-private pasteboard would:
4
+ // what the app put there, it reads back. Writing also copies to the system
5
+ // clipboard through the page (a `clipboard` host request: the Async
6
+ // Clipboard API's `writeText`, or an `image/png` item for an image), so the
7
+ // viewer can paste a copied link or picture in another app. Text the viewer
8
+ // pastes into a text field or editor is the browser's own paste, which needs
9
+ // none of this (docs/ops-protocol.md, "Sharing and media").
10
+
11
+ // On iOS, UIKit brings UniformTypeIdentifiers along (`UTType.jpeg` with
12
+ // only `import UIKit`).
13
+ @_exported import UniformTypeIdentifiers
14
+ import Foundation
15
+ import FoundationBridge
16
+ import SwiftUI
17
+
18
+ /// The system clipboard, through the page.
19
+ @MainActor
20
+ public enum _PageClipboard {
21
+ /// Copies `fields` (`text`, or a picture's `files` / `bitmaps` / `images`)
22
+ /// to the system clipboard. The answer is not awaited by the app: the
23
+ /// browser may refuse (no focus, no permission), and the in-memory
24
+ /// pasteboard has the items either way.
25
+ public static func write(_ fields: [String: _JSON]) {
26
+ guard !fields.isEmpty else { return }
27
+ var params = fields
28
+ params["action"] = .string("write")
29
+ Task { @MainActor in
30
+ _ = try? await _PageFiles.hostRequest("clipboard", .object(params), .object([:]))
31
+ }
32
+ }
33
+
34
+ /// Reads the system clipboard's text (the browser may ask the viewer
35
+ /// first, or refuse); nil when there is none or the page could not read it.
36
+ public static func readText() async -> String? {
37
+ guard let answer = try? await _PageFiles.hostRequest("clipboard", .object(["action": .string("readText")]), .object([:])),
38
+ case .object(let fields) = answer, case .string(let text)? = fields["text"] else { return nil }
39
+ return text
40
+ }
41
+ }
42
+
43
+ /// A pasteboard: the general one (also copied to the system clipboard) or a
44
+ /// named one, private to the app. Items are dictionaries from type
45
+ /// identifiers to values (strings, URLs, images, data), as on iOS.
46
+ open class UIPasteboard: @unchecked Sendable {
47
+ public struct Name: RawRepresentable, Hashable, Sendable {
48
+ public let rawValue: String
49
+ public init(rawValue: String) { self.rawValue = rawValue }
50
+ public init(_ rawValue: String) { self.rawValue = rawValue }
51
+ public static let general = Name("com.apple.UIKit.pboard.general")
52
+ @available(*, deprecated)
53
+ public static let find = Name("com.apple.UIKit.pboard.find")
54
+ }
55
+
56
+ public struct OptionsKey: RawRepresentable, Hashable, Sendable {
57
+ public let rawValue: String
58
+ public init(rawValue: String) { self.rawValue = rawValue }
59
+ public static let localOnly = OptionsKey(rawValue: "com.apple.UIKit.pboard.localOnly")
60
+ public static let expirationDate = OptionsKey(rawValue: "com.apple.UIKit.pboard.expirationDate")
61
+ }
62
+
63
+ public static let changedNotification = Notification.Name("UIPasteboardChangedNotification")
64
+ public static let removedNotification = Notification.Name("UIPasteboardRemovedNotification")
65
+ public static let changedTypesAddedUserInfoKey = "UIPasteboardChangedTypesAddedKey"
66
+ public static let changedTypesRemovedUserInfoKey = "UIPasteboardChangedTypesRemovedKey"
67
+
68
+ public static let typeListString: [String] = [UTType.utf8PlainText.identifier, UTType.plainText.identifier, UTType.text.identifier]
69
+ public static let typeListURL: [String] = [UTType.url.identifier]
70
+ public static let typeListImage: [String] = [UTType.png.identifier, UTType.jpeg.identifier, UTType.gif.identifier, UTType.image.identifier]
71
+ public static let typeListColor: [String] = ["com.apple.uikit.color"]
72
+ public static let typeAutomatic = "com.apple.uikit.pasteboard.automatic"
73
+
74
+ nonisolated(unsafe) private static var named: [Name: UIPasteboard] = [:]
75
+
76
+ /// The general pasteboard: what the app copies also goes to the system clipboard.
77
+ public static var general: UIPasteboard { pasteboard(.general) }
78
+
79
+ public let name: Name
80
+ open var isPersistent = false
81
+ public private(set) var changeCount = 0
82
+ private var storage: [[String: Any]] = []
83
+
84
+ init(name: Name) { self.name = name }
85
+
86
+ private static func pasteboard(_ name: Name) -> UIPasteboard {
87
+ if let existing = named[name] { return existing }
88
+ let pasteboard = UIPasteboard(name: name)
89
+ named[name] = pasteboard
90
+ return pasteboard
91
+ }
92
+
93
+ /// A named pasteboard, private to the app; nil when it does not exist and `create` is false.
94
+ public convenience init?(name pasteboardName: Name, create: Bool) {
95
+ guard create || Self.named[pasteboardName] != nil else { return nil }
96
+ self.init(name: pasteboardName)
97
+ }
98
+
99
+ public static func withUniqueName() -> UIPasteboard { pasteboard(Name(UUID().uuidString)) }
100
+
101
+ public static func remove(withName pasteboardName: Name) { named[pasteboardName] = nil }
102
+
103
+ // MARK: Items
104
+
105
+ /// The items, each a dictionary from type identifiers to values.
106
+ open var items: [[String: Any]] {
107
+ get { storage }
108
+ set { setItems(newValue) }
109
+ }
110
+
111
+ open func setItems(_ items: [[String: Any]], options: [OptionsKey: Any] = [:]) {
112
+ storage = items
113
+ changed()
114
+ }
115
+
116
+ open func addItems(_ items: [[String: Any]]) {
117
+ storage += items
118
+ changed()
119
+ }
120
+
121
+ open var numberOfItems: Int { storage.count }
122
+
123
+ /// The types of the first item.
124
+ open var types: [String] { storage.first.map { Array($0.keys) } ?? [] }
125
+
126
+ open func types(forItemSet itemSet: IndexSet?) -> [[String]]? {
127
+ indices(itemSet).map { Array(storage[$0].keys) }
128
+ }
129
+
130
+ open func contains(pasteboardTypes: [String]) -> Bool {
131
+ storage.contains { item in item.keys.contains { key in pasteboardTypes.contains { Self.conforms(key, to: $0) } } }
132
+ }
133
+
134
+ open func contains(pasteboardTypes: [String], inItemSet itemSet: IndexSet?) -> Bool {
135
+ indices(itemSet).contains { index in storage[index].keys.contains { key in pasteboardTypes.contains { Self.conforms(key, to: $0) } } }
136
+ }
137
+
138
+ open func data(forPasteboardType pasteboardType: String) -> Data? {
139
+ guard let value = value(forPasteboardType: pasteboardType) else { return nil }
140
+ switch value {
141
+ case let data as Data: return data
142
+ case let string as String: return Data(string.utf8)
143
+ case let url as URL: return Data(url.absoluteString.utf8)
144
+ case let image as UIImage: return image._encodedFile?.data
145
+ default: return nil
146
+ }
147
+ }
148
+
149
+ open func setData(_ data: Data, forPasteboardType pasteboardType: String) {
150
+ storage = [[pasteboardType: data]]
151
+ changed()
152
+ if UTType(pasteboardType)?.conforms(to: .text) == true {
153
+ copyValueToSystem(String(decoding: data, as: UTF8.self))
154
+ } else if let image = UIImage(data: data) {
155
+ copyValueToSystem(image)
156
+ }
157
+ }
158
+
159
+ /// The first item's value for a type (or a type conforming to it).
160
+ open func value(forPasteboardType pasteboardType: String) -> Any? {
161
+ guard let first = storage.first else { return nil }
162
+ if let value = first[pasteboardType] { return value }
163
+ return first.first { Self.conforms($0.key, to: pasteboardType) }?.value
164
+ }
165
+
166
+ open func setValue(_ value: Any, forPasteboardType pasteboardType: String) {
167
+ storage = [[pasteboardType: value]]
168
+ changed()
169
+ copyValueToSystem(value)
170
+ }
171
+
172
+ open func data(forPasteboardType pasteboardType: String, inItemSet itemSet: IndexSet?) -> [Data]? {
173
+ let found = indices(itemSet).compactMap { storage[$0][pasteboardType] as? Data }
174
+ return found.isEmpty ? nil : found
175
+ }
176
+
177
+ open func values(forPasteboardType pasteboardType: String, inItemSet itemSet: IndexSet?) -> [Any]? {
178
+ let found = indices(itemSet).compactMap { storage[$0][pasteboardType] }
179
+ return found.isEmpty ? nil : found
180
+ }
181
+
182
+ // MARK: Item providers
183
+
184
+ /// An item provider per item, offering its values.
185
+ open var itemProviders: [NSItemProvider] {
186
+ get {
187
+ storage.map { item in
188
+ let provider = NSItemProvider()
189
+ for (key, value) in item {
190
+ if let object = value as? any NSItemProviderWriting {
191
+ provider.registerObject(object, visibility: .all)
192
+ } else {
193
+ let box = _PasteboardValue(value)
194
+ provider.registerDataRepresentation(forTypeIdentifier: key, visibility: .all) { completion in
195
+ completion(box.data, nil)
196
+ return nil
197
+ }
198
+ }
199
+ }
200
+ return provider
201
+ }
202
+ }
203
+ set { setItemProviders(newValue, localOnly: false, expirationDate: nil) }
204
+ }
205
+
206
+ /// Takes the providers' objects: what each offers as text, a URL or an
207
+ /// image is loaded and becomes an item, in order, when loaded.
208
+ open func setItemProviders(_ itemProviders: [NSItemProvider], localOnly: Bool, expirationDate: Date?) {
209
+ storage = []
210
+ changed()
211
+ for provider in itemProviders {
212
+ if provider.canLoadObject(ofClass: UIImage.self) {
213
+ provider.loadObject(ofClass: UIImage.self) { [weak self] image, _ in
214
+ guard let image else { return }
215
+ Task { @MainActor in self?.image = image }
216
+ }
217
+ } else if provider.canLoadObject(ofClass: URL.self) {
218
+ provider.loadObject(ofClass: URL.self) { [weak self] url, _ in
219
+ guard let url else { return }
220
+ Task { @MainActor in self?.url = url }
221
+ }
222
+ } else if provider.canLoadObject(ofClass: String.self) {
223
+ provider.loadObject(ofClass: String.self) { [weak self] string, _ in
224
+ guard let string else { return }
225
+ Task { @MainActor in self?.string = string }
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ open func setObjects<T: NSItemProviderWriting>(_ objects: [T]) {
232
+ setObjects(objects, localOnly: false, expirationDate: nil)
233
+ }
234
+
235
+ open func setObjects<T: NSItemProviderWriting>(_ objects: [T], localOnly: Bool, expirationDate: Date?) {
236
+ storage = objects.map { object in
237
+ Dictionary(object.writableTypeIdentifiersForItemProvider.map { ($0, object as Any) }, uniquingKeysWith: { first, _ in first })
238
+ }
239
+ changed()
240
+ if let first = objects.first { copyValueToSystem(first) }
241
+ }
242
+
243
+ // MARK: Strings, URLs, images, colors
244
+
245
+ /// The first text item, or the first URL as text (as iOS coerces it).
246
+ open var string: String? {
247
+ get { strings?.first }
248
+ set { set(newValue.map { [$0] } ?? [], type: UTType.utf8PlainText.identifier) }
249
+ }
250
+
251
+ open var strings: [String]? {
252
+ get {
253
+ let found = storage.compactMap { item -> String? in
254
+ if let text = Self.typeListString.lazy.compactMap({ item[$0] as? String }).first { return text }
255
+ return (item[UTType.url.identifier] as? URL)?.absoluteString
256
+ }
257
+ return found.isEmpty ? nil : found
258
+ }
259
+ set { set(newValue ?? [], type: UTType.utf8PlainText.identifier) }
260
+ }
261
+
262
+ open var url: URL? {
263
+ get { urls?.first }
264
+ set { set(newValue.map { [$0] } ?? [], type: UTType.url.identifier) }
265
+ }
266
+
267
+ open var urls: [URL]? {
268
+ get {
269
+ let found = storage.compactMap { item -> URL? in
270
+ if let url = item[UTType.url.identifier] as? URL { return url }
271
+ return Self.typeListString.lazy.compactMap { item[$0] as? String }.first.flatMap { URL(string: $0) }.flatMap { $0.scheme == nil ? nil : $0 }
272
+ }
273
+ return found.isEmpty ? nil : found
274
+ }
275
+ set { set(newValue ?? [], type: UTType.url.identifier) }
276
+ }
277
+
278
+ open var image: UIImage? {
279
+ get { images?.first }
280
+ set { set(newValue.map { [$0] } ?? [], type: UTType.png.identifier) }
281
+ }
282
+
283
+ open var images: [UIImage]? {
284
+ get {
285
+ let found = storage.compactMap { item in item.values.lazy.compactMap { $0 as? UIImage }.first }
286
+ return found.isEmpty ? nil : found
287
+ }
288
+ set { set(newValue ?? [], type: UTType.png.identifier) }
289
+ }
290
+
291
+ open var color: UIColor? {
292
+ get { colors?.first }
293
+ set { set(newValue.map { [$0] } ?? [], type: Self.typeListColor[0]) }
294
+ }
295
+
296
+ open var colors: [UIColor]? {
297
+ get {
298
+ let found = storage.compactMap { item in item.values.lazy.compactMap { $0 as? UIColor }.first }
299
+ return found.isEmpty ? nil : found
300
+ }
301
+ set { set(newValue ?? [], type: Self.typeListColor[0]) }
302
+ }
303
+
304
+ open var hasStrings: Bool { strings != nil }
305
+ open var hasURLs: Bool { urls != nil }
306
+ open var hasImages: Bool { images != nil }
307
+ open var hasColors: Bool { colors != nil }
308
+
309
+ // MARK: Helpers
310
+
311
+ private func set(_ values: [Any], type: String) {
312
+ storage = values.map { [type: $0] }
313
+ changed()
314
+ if let first = values.first { copyValueToSystem(first) }
315
+ }
316
+
317
+ private func changed() {
318
+ changeCount += 1
319
+ FoundationBridge.NotificationCenter.default.post(name: Self.changedNotification, object: self)
320
+ }
321
+
322
+ /// Copies a string, URL or image to the system clipboard: only the
323
+ /// general pasteboard's, from a task on the main actor (which the
324
+ /// browser runs right after the tap that copied, so the page still has
325
+ /// the viewer's activation).
326
+ private func copyValueToSystem(_ value: Any) {
327
+ guard name == .general else { return }
328
+ let box = _PasteboardValue(value)
329
+ Task { @MainActor in
330
+ switch box.value {
331
+ case let string as String: _PageClipboard.write(["text": .string(string)])
332
+ case let url as URL: _PageClipboard.write(["text": .string(url.absoluteString)])
333
+ case let image as UIImage: _PageClipboard.write(_PageFiles.fields(for: image, name: "Image"))
334
+ default: break
335
+ }
336
+ }
337
+ }
338
+
339
+ private func indices(_ itemSet: IndexSet?) -> [Int] {
340
+ guard let itemSet else { return Array(storage.indices) }
341
+ return itemSet.filter { storage.indices.contains($0) }
342
+ }
343
+
344
+ private static func conforms(_ identifier: String, to other: String) -> Bool {
345
+ if identifier == other { return true }
346
+ guard let type = UTType(identifier), let otherType = UTType(other) else { return false }
347
+ return type.conforms(to: otherType)
348
+ }
349
+ }
350
+
351
+ private struct _PasteboardValue: @unchecked Sendable {
352
+ let value: Any
353
+ init(_ value: Any) { self.value = value }
354
+ var data: Data? {
355
+ switch value {
356
+ case let data as Data: data
357
+ case let string as String: Data(string.utf8)
358
+ case let url as URL: Data(url.absoluteString.utf8)
359
+ case let image as UIImage: image._encodedFile?.data
360
+ default: nil
361
+ }
362
+ }
363
+ }
@@ -0,0 +1,81 @@
1
+ // Saving to the photo album, in the browser: the page has no photo library,
2
+ // so a saved image or video becomes a download (a `download` host request;
3
+ // docs/ops-protocol.md, "Sharing and media"). The browser puts it in the
4
+ // viewer's downloads folder, or asks where to, as it does for any download.
5
+ // Photos' `PHAssetChangeRequest` saves the same way (Sources/Photos).
6
+
7
+ import Foundation
8
+ import FoundationBridge
9
+ import SwiftUI
10
+
11
+ /// Files the app hands to the page: to download (`download`), share
12
+ /// (`share`) or copy (`clipboard`). Used by UIKit, Photos and LinkPresentation.
13
+ @MainActor
14
+ public enum _PageFiles {
15
+ /// The request fields that carry `image`: `files` for an image made from
16
+ /// a file (its own bytes), `bitmaps` for one the page draws from a recipe
17
+ /// (Core Image, a drawing; the page encodes it as PNG), `images` for an
18
+ /// asset-catalog image. Empty for a symbol or an empty image.
19
+ public static func fields(for image: UIImage, name: String) -> [String: _JSON] {
20
+ if let file = image._encodedFile {
21
+ let ext = UTType(mimeType: file.mime)?.preferredFilenameExtension ?? "png"
22
+ return ["files": .array([entry(name: "\(name).\(ext)", type: file.mime, data: file.data)])]
23
+ }
24
+ if let recipe = image._recipe, let source = recipe.source {
25
+ _Runtime.shared._sendImageSource(source)
26
+ return ["bitmaps": .array([recipe._json])]
27
+ }
28
+ if let catalogName = image._catalogName { return ["images": .array([.string(catalogName)])] }
29
+ return [:]
30
+ }
31
+
32
+ /// The `files` entry for a file's bytes.
33
+ public static func entry(name: String, type: String, data: Data) -> _JSON {
34
+ .object(["name": .string(name), "type": .string(type), "data": .string(_base64([UInt8](data)))])
35
+ }
36
+
37
+ /// The `files` entry for the file at `url`, typed by its extension.
38
+ public static func entry(fileURL url: URL) throws -> _JSON {
39
+ let type = UTType(filenameExtension: url.pathExtension)?.preferredMIMEType ?? "application/octet-stream"
40
+ return entry(name: url.lastPathComponent, type: type, data: try Data(contentsOf: url))
41
+ }
42
+
43
+ /// Asks the page to download what `fields` carry (`title` names bitmap
44
+ /// files). Headless runs answer at once; the op in the log is the record.
45
+ public static func download(_ fields: [String: _JSON], title: String) async throws {
46
+ guard !fields.isEmpty else { throw CocoaError(.fileWriteUnknown) }
47
+ var params = fields
48
+ params["title"] = .string(title)
49
+ _ = try await hostRequest("download", .object(params), .object(["outcome": .string("headless")]))
50
+ }
51
+
52
+ /// Sends a host request (kind, params, headless answer); tests replace it.
53
+ public static var hostRequest: @MainActor (String, _JSON, _JSON) async throws -> _JSON = { kind, params, headless in
54
+ try await _Runtime.shared._hostRequest(kind: kind, params: params, headless: headless)
55
+ }
56
+ }
57
+
58
+ /// Saves `image` to the photo album: in the browser, downloads it (its own
59
+ /// file for an image made from data, else a PNG the page draws). The
60
+ /// completion selector is not called (the browser's Swift cannot call a
61
+ /// three-argument selector); the download happens or fails on its own.
62
+ public func UIImageWriteToSavedPhotosAlbum(_ image: UIImage, _ completionTarget: Any?, _ completionSelector: Selector?,
63
+ _ contextInfo: UnsafeMutableRawPointer?) {
64
+ Task { @MainActor in
65
+ try? await _PageFiles.download(_PageFiles.fields(for: image, name: "Photo"), title: "Photo")
66
+ }
67
+ }
68
+
69
+ /// Whether the video at `videoPath` can be saved: any file that exists.
70
+ public func UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(_ videoPath: String) -> Bool {
71
+ FileManager.default.fileExists(atPath: videoPath)
72
+ }
73
+
74
+ /// Saves the video at `videoPath` to the photo album: in the browser, downloads the file.
75
+ public func UISaveVideoAtPathToSavedPhotosAlbum(_ videoPath: String, _ completionTarget: Any?, _ completionSelector: Selector?,
76
+ _ contextInfo: UnsafeMutableRawPointer?) {
77
+ Task { @MainActor in
78
+ guard let entry = try? _PageFiles.entry(fileURL: URL(fileURLWithPath: videoPath)) else { return }
79
+ try? await _PageFiles.download(["files": .array([entry])], title: "Video")
80
+ }
81
+ }
@@ -0,0 +1,15 @@
1
+ // Remote (APNs) notification registration. The browser has no APNs: Apple
2
+ // never hands the page a device token, so registering does nothing and the
3
+ // app delegate's `didRegisterForRemoteNotificationsWithDeviceToken` is never
4
+ // called, which apps already handle (a simulator behaves the same). Local
5
+ // notifications are UserNotifications' (docs/ops-protocol.md, "Notifications").
6
+
7
+ import Foundation
8
+
9
+ extension UIApplication {
10
+ /// Does nothing: no device token ever arrives.
11
+ public func registerForRemoteNotifications() {}
12
+ public func unregisterForRemoteNotifications() {}
13
+ /// False: the page never gets a device token.
14
+ public var isRegisteredForRemoteNotifications: Bool { false }
15
+ }