@swiftbrowser/swift 0.1.0 → 0.3.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 +68 -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 +125 -10
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +100 -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 +26 -10
  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 +71 -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 +88 -12
  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 +14 -4
  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 +168 -39
  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 +86 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +187 -8
  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 +46 -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 +524 -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 +41 -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,458 @@
1
+ // `DispatchQueue` for the browser. The WASI SDK ships no Dispatch, yet
2
+ // `DispatchQueue.main.async { … }` and `asyncAfter(deadline: .now() + 0.5)`
3
+ // are how much SwiftUI code (and many packages) defer work to the next turn
4
+ // or a moment later. The page has one thread, so every queue is the main
5
+ // queue: work runs on the main actor, in order, from the runtime's executor,
6
+ // and a deadline is a `Task.sleep` (so headless runs stay deterministic, like
7
+ // `Timer` in Timer.swift).
8
+ //
9
+ // The CLI's staging gives the app (and each package built against the shim)
10
+ // typealiases for these names, so a host `check`, where Foundation re-exports
11
+ // Dispatch, type-checks against the same API the browser build has. Work
12
+ // items and groups are here (a group's `notify` runs once everything that
13
+ // entered has left), and memory-pressure sources, which never fire;
14
+ // semaphores and other sources are not (waiting would block the only
15
+ // thread): code that needs them is a compile error in the browser build.
16
+
17
+ import Foundation
18
+
19
+ /// A point in time for `asyncAfter`, on the clock `Task.sleep` uses.
20
+ public struct DispatchTime: Comparable, Hashable, Sendable {
21
+ /// Nanoseconds since the first `now()` of the process.
22
+ public let uptimeNanoseconds: UInt64
23
+
24
+ public init(uptimeNanoseconds: UInt64) {
25
+ self.uptimeNanoseconds = uptimeNanoseconds
26
+ }
27
+
28
+ nonisolated(unsafe) private static let origin = ContinuousClock.now
29
+
30
+ public static func now() -> DispatchTime {
31
+ let elapsed = ContinuousClock.now - origin
32
+ let (seconds, attoseconds) = elapsed.components
33
+ return DispatchTime(uptimeNanoseconds: UInt64(max(0, seconds)) * 1_000_000_000 + UInt64(max(0, attoseconds) / 1_000_000_000))
34
+ }
35
+
36
+ public static let distantFuture = DispatchTime(uptimeNanoseconds: .max)
37
+
38
+ public static func < (lhs: DispatchTime, rhs: DispatchTime) -> Bool {
39
+ lhs.uptimeNanoseconds < rhs.uptimeNanoseconds
40
+ }
41
+
42
+ /// The time from this one to `other` (negative when `other` is earlier).
43
+ public func distance(to other: DispatchTime) -> DispatchTimeInterval {
44
+ .nanoseconds(Int(truncatingIfNeeded: Int64(bitPattern: other.uptimeNanoseconds &- uptimeNanoseconds)))
45
+ }
46
+
47
+ /// The time `nanoseconds` later (or earlier), clamped. Public for the CLI's generated operators.
48
+ public func _adding(nanoseconds: Double) -> DispatchTime {
49
+ let sum = Double(uptimeNanoseconds) + nanoseconds
50
+ if sum <= 0 { return DispatchTime(uptimeNanoseconds: 0) }
51
+ if sum >= Double(UInt64.max) { return .distantFuture }
52
+ return DispatchTime(uptimeNanoseconds: UInt64(sum))
53
+ }
54
+ }
55
+
56
+ // Global, as Dispatch declares them, so that `.now() + 0.5` finds them: the
57
+ // left operand's type comes from the context, too late for a static operator.
58
+
59
+ public func + (time: DispatchTime, seconds: Double) -> DispatchTime {
60
+ time._adding(nanoseconds: seconds * 1_000_000_000)
61
+ }
62
+
63
+ public func - (time: DispatchTime, seconds: Double) -> DispatchTime {
64
+ time._adding(nanoseconds: -seconds * 1_000_000_000)
65
+ }
66
+
67
+ public func + (time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime { DispatchTime._plus(time, interval) }
68
+ public func - (time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime { DispatchTime._minus(time, interval) }
69
+
70
+ extension DispatchTime {
71
+ public static func _plus(_ time: DispatchTime, _ interval: DispatchTimeInterval) -> DispatchTime {
72
+ guard let nanoseconds = interval.nanoseconds else { return .distantFuture }
73
+ return time._adding(nanoseconds: nanoseconds)
74
+ }
75
+
76
+ public static func _minus(_ time: DispatchTime, _ interval: DispatchTimeInterval) -> DispatchTime {
77
+ guard let nanoseconds = interval.nanoseconds else { return DispatchTime(uptimeNanoseconds: 0) }
78
+ return time._adding(nanoseconds: -nanoseconds)
79
+ }
80
+ }
81
+
82
+ /// A duration for `DispatchTime` arithmetic.
83
+ public enum DispatchTimeInterval: Equatable, Sendable {
84
+ case seconds(Int)
85
+ case milliseconds(Int)
86
+ case microseconds(Int)
87
+ case nanoseconds(Int)
88
+ case never
89
+
90
+ var nanoseconds: Double? {
91
+ switch self {
92
+ case .seconds(let n): Double(n) * 1_000_000_000
93
+ case .milliseconds(let n): Double(n) * 1_000_000
94
+ case .microseconds(let n): Double(n) * 1_000
95
+ case .nanoseconds(let n): Double(n)
96
+ case .never: nil
97
+ }
98
+ }
99
+ }
100
+
101
+ /// A quality of service, accepted and ignored: the page runs everything on one thread.
102
+ public struct DispatchQoS: Equatable, Sendable {
103
+ public enum QoSClass: Equatable, Sendable {
104
+ case background, utility, `default`, userInitiated, userInteractive, unspecified
105
+ }
106
+
107
+ public let qosClass: QoSClass
108
+
109
+ public init(qosClass: QoSClass, relativePriority: Int) {
110
+ self.qosClass = qosClass
111
+ }
112
+
113
+ public static let background = DispatchQoS(qosClass: .background, relativePriority: 0)
114
+ public static let utility = DispatchQoS(qosClass: .utility, relativePriority: 0)
115
+ public static let `default` = DispatchQoS(qosClass: .default, relativePriority: 0)
116
+ public static let userInitiated = DispatchQoS(qosClass: .userInitiated, relativePriority: 0)
117
+ public static let userInteractive = DispatchQoS(qosClass: .userInteractive, relativePriority: 0)
118
+ public static let unspecified = DispatchQoS(qosClass: .unspecified, relativePriority: 0)
119
+ }
120
+
121
+ /// A queue of work. Every queue runs its work on the main actor, in order.
122
+ public final class DispatchQueue: Sendable {
123
+ public struct Attributes: OptionSet, Sendable {
124
+ public let rawValue: UInt64
125
+ public init(rawValue: UInt64) { self.rawValue = rawValue }
126
+ public static let concurrent = Attributes(rawValue: 1 << 1)
127
+ public static let initiallyInactive = Attributes(rawValue: 1 << 2)
128
+ }
129
+
130
+ public let label: String
131
+ /// `setSpecific` values, by key.
132
+ private let specifics = _QueueSpecifics()
133
+
134
+ public init(label: String, qos: DispatchQoS = .unspecified, attributes: Attributes = []) {
135
+ self.label = label
136
+ }
137
+
138
+ /// The queues whose work is running, innermost last: what
139
+ /// `DispatchQueue.getSpecific(key:)` reads. Code outside any queue's work
140
+ /// runs on the main queue.
141
+ nonisolated(unsafe) private static var running: [DispatchQueue] = []
142
+
143
+ /// Runs `work` as this queue's: `getSpecific(key:)` reads this queue's values meanwhile.
144
+ private func running<T>(_ work: () throws -> T) rethrows -> T {
145
+ Self.running.append(self)
146
+ defer { Self.running.removeLast() }
147
+ return try work()
148
+ }
149
+
150
+ /// Stores `value` under `key` on this queue (nil removes it).
151
+ public func setSpecific<T>(key: DispatchSpecificKey<T>, value: T?) {
152
+ specifics.values[ObjectIdentifier(key)] = value.map { $0 as Any }
153
+ }
154
+
155
+ /// The value stored under `key` on this queue.
156
+ public func getSpecific<T>(key: DispatchSpecificKey<T>) -> T? {
157
+ specifics.values[ObjectIdentifier(key)] as? T
158
+ }
159
+
160
+ /// The value stored under `key` on the queue whose work is running (the
161
+ /// main queue's outside any): how code tells it is already on a queue
162
+ /// (SQLite.swift's connections do before `sync`).
163
+ public static func getSpecific<T>(key: DispatchSpecificKey<T>) -> T? {
164
+ (running.last ?? main).getSpecific(key: key)
165
+ }
166
+
167
+ public static let main = DispatchQueue(label: "com.apple.main-thread")
168
+
169
+ public static func global(qos: DispatchQoS.QoSClass = .default) -> DispatchQueue {
170
+ main
171
+ }
172
+
173
+ /// Runs `work` on the next turn of the main actor.
174
+ public func async(execute work: @escaping () -> Void) {
175
+ nonisolated(unsafe) let work = work
176
+ Task { @MainActor in self.running(work) }
177
+ }
178
+
179
+ /// `async(group:qos:flags:execute:)`: the group, QoS and flags are accepted.
180
+ public func async(group: DispatchGroup? = nil, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping () -> Void) {
181
+ group?.enter()
182
+ nonisolated(unsafe) let work = work
183
+ Task { @MainActor in
184
+ self.running(work)
185
+ group?.leave()
186
+ }
187
+ }
188
+
189
+ public func async(execute item: DispatchWorkItem) {
190
+ Task { @MainActor in self.running { item.perform() } }
191
+ }
192
+
193
+ /// Runs `work` once `deadline` has passed.
194
+ public func asyncAfter(deadline: DispatchTime, execute work: @escaping () -> Void) {
195
+ nonisolated(unsafe) let work = work
196
+ asyncAfter(deadline: deadline, qos: .unspecified, flags: [], execute: { work() })
197
+ }
198
+
199
+ public func asyncAfter(deadline: DispatchTime, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping () -> Void) {
200
+ nonisolated(unsafe) let work = work
201
+ let delay = Self.delay(until: deadline)
202
+ Task { @MainActor in
203
+ if delay > 0 { try? await Task.sleep(for: .seconds(delay)) }
204
+ self.running(work)
205
+ }
206
+ }
207
+
208
+ public func asyncAfter(deadline: DispatchTime, execute item: DispatchWorkItem) {
209
+ let delay = Self.delay(until: deadline)
210
+ Task { @MainActor in
211
+ if delay > 0 { try? await Task.sleep(for: .seconds(delay)) }
212
+ self.running { item.perform() }
213
+ }
214
+ }
215
+
216
+ static func delay(until deadline: DispatchTime) -> Double {
217
+ let now = DispatchTime.now()
218
+ return deadline > now ? Double(deadline.uptimeNanoseconds - now.uptimeNanoseconds) / 1_000_000_000 : 0
219
+ }
220
+
221
+ public func sync(execute item: DispatchWorkItem) { running { item.perform() } }
222
+
223
+ public func sync<T>(flags: DispatchWorkItemFlags, execute work: () throws -> T) rethrows -> T {
224
+ try running(work)
225
+ }
226
+
227
+ /// Runs `work` now and returns its result: with one thread, nothing else can be running.
228
+ public func sync<T>(execute work: () throws -> T) rethrows -> T {
229
+ try running(work)
230
+ }
231
+ }
232
+
233
+ /// A key for `DispatchQueue.setSpecific(key:value:)`; keys compare by identity.
234
+ public final class DispatchSpecificKey<T>: @unchecked Sendable {
235
+ public init() {}
236
+ }
237
+
238
+ final class _QueueSpecifics: @unchecked Sendable {
239
+ var values: [ObjectIdentifier: Any] = [:]
240
+ }
241
+
242
+ // MARK: - Sources
243
+
244
+ /// A dispatch source. The browser raises no events for the kinds here: a
245
+ /// memory-pressure source never fires (the page cannot tell), and handlers
246
+ /// are kept until the source is cancelled.
247
+ public protocol DispatchSourceProtocol: AnyObject, Sendable {
248
+ func setEventHandler(handler: (@Sendable () -> Void)?)
249
+ func setCancelHandler(handler: (@Sendable () -> Void)?)
250
+ func setRegistrationHandler(handler: (@Sendable () -> Void)?)
251
+ func activate()
252
+ func resume()
253
+ func suspend()
254
+ func cancel()
255
+ var isCancelled: Bool { get }
256
+ }
257
+
258
+ public protocol DispatchSourceMemoryPressure: DispatchSourceProtocol {
259
+ var data: DispatchSource.MemoryPressureEvent { get }
260
+ var mask: DispatchSource.MemoryPressureEvent { get }
261
+ }
262
+
263
+ public enum DispatchSource {
264
+ public struct MemoryPressureEvent: OptionSet, Sendable {
265
+ public let rawValue: UInt
266
+ public init(rawValue: UInt) { self.rawValue = rawValue }
267
+ public static let normal = MemoryPressureEvent(rawValue: 1 << 0)
268
+ public static let warning = MemoryPressureEvent(rawValue: 1 << 1)
269
+ public static let critical = MemoryPressureEvent(rawValue: 1 << 2)
270
+ public static let all: MemoryPressureEvent = [.normal, .warning, .critical]
271
+ }
272
+
273
+ public static func makeMemoryPressureSource(eventMask: MemoryPressureEvent, queue: DispatchQueue? = nil) -> any DispatchSourceMemoryPressure {
274
+ _MemoryPressureSource(mask: eventMask)
275
+ }
276
+ }
277
+
278
+ /// A timer source: once scheduled and resumed, it calls its handler at the
279
+ /// deadline, and every `repeating` interval after that, on the main actor's
280
+ /// clock, the executor's (asyncAfter's).
281
+ public protocol DispatchSourceTimer: DispatchSourceProtocol {
282
+ /// Fires at `deadline`, then every `nanoseconds` (nil: once).
283
+ func _schedule(deadline: DispatchTime, repeatingNanoseconds nanoseconds: Double?)
284
+ }
285
+
286
+ extension DispatchSourceTimer {
287
+ public func schedule(deadline: DispatchTime, repeating interval: DispatchTimeInterval = .never, leeway: DispatchTimeInterval = .nanoseconds(0)) {
288
+ _schedule(deadline: deadline, repeatingNanoseconds: interval.nanoseconds.flatMap { $0 > 0 ? $0 : nil })
289
+ }
290
+ public func schedule(deadline: DispatchTime, repeating interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) {
291
+ _schedule(deadline: deadline, repeatingNanoseconds: interval > 0 && interval.isFinite ? interval * 1_000_000_000 : nil)
292
+ }
293
+ }
294
+
295
+ extension DispatchSource {
296
+ public struct TimerFlags: OptionSet, Sendable {
297
+ public let rawValue: UInt
298
+ public init(rawValue: UInt) { self.rawValue = rawValue }
299
+ public static let strict = TimerFlags(rawValue: 1)
300
+ }
301
+
302
+ public static func makeTimerSource(flags: TimerFlags = [], queue: DispatchQueue? = nil) -> any DispatchSourceTimer {
303
+ _TimerSource()
304
+ }
305
+ }
306
+
307
+ final class _TimerSource: DispatchSourceTimer, @unchecked Sendable {
308
+ private var handler: (@Sendable () -> Void)?
309
+ private var cancelHandler: (@Sendable () -> Void)?
310
+ private var deadline: DispatchTime?
311
+ /// Nanoseconds between firings; nil for once.
312
+ private var interval: Double?
313
+ private var task: Task<Void, Never>?
314
+ private var running = false
315
+ private(set) var isCancelled = false
316
+
317
+ func setEventHandler(handler: (@Sendable () -> Void)?) { self.handler = handler }
318
+ func setCancelHandler(handler: (@Sendable () -> Void)?) { cancelHandler = handler }
319
+ func setRegistrationHandler(handler: (@Sendable () -> Void)?) { handler?() }
320
+
321
+ func _schedule(deadline: DispatchTime, repeatingNanoseconds nanoseconds: Double?) {
322
+ self.deadline = deadline
323
+ interval = nanoseconds
324
+ if running { start() }
325
+ }
326
+
327
+ func activate() { resume() }
328
+
329
+ func resume() {
330
+ guard !running, !isCancelled else { return }
331
+ running = true
332
+ start()
333
+ }
334
+
335
+ func suspend() {
336
+ running = false
337
+ task?.cancel()
338
+ task = nil
339
+ }
340
+
341
+ func cancel() {
342
+ guard !isCancelled else { return }
343
+ isCancelled = true
344
+ suspend()
345
+ handler = nil
346
+ let cancelHandler = self.cancelHandler
347
+ self.cancelHandler = nil
348
+ if let cancelHandler { DispatchQueue.main.async { cancelHandler() } }
349
+ }
350
+
351
+ private func start() {
352
+ task?.cancel()
353
+ guard let deadline, deadline != .distantFuture else { return }
354
+ nonisolated(unsafe) let source = self
355
+ task = Task { @MainActor in
356
+ let wait = Double(deadline.uptimeNanoseconds) - Double(DispatchTime.now().uptimeNanoseconds)
357
+ if wait > 0 { try? await Task.sleep(nanoseconds: UInt64(wait)) }
358
+ while !Task.isCancelled {
359
+ source.handler?()
360
+ guard let interval = source.interval else { break }
361
+ try? await Task.sleep(nanoseconds: UInt64(interval))
362
+ }
363
+ }
364
+ }
365
+ }
366
+
367
+ final class _MemoryPressureSource: DispatchSourceMemoryPressure, @unchecked Sendable {
368
+ let mask: DispatchSource.MemoryPressureEvent
369
+ private var handlers: [@Sendable () -> Void] = []
370
+ private(set) var isCancelled = false
371
+
372
+ init(mask: DispatchSource.MemoryPressureEvent) { self.mask = mask }
373
+
374
+ var data: DispatchSource.MemoryPressureEvent { [] }
375
+ func setEventHandler(handler: (@Sendable () -> Void)?) { handlers = handler.map { [$0] } ?? [] }
376
+ func setCancelHandler(handler: (@Sendable () -> Void)?) {}
377
+ func setRegistrationHandler(handler: (@Sendable () -> Void)?) {}
378
+ func activate() {}
379
+ func resume() {}
380
+ func suspend() {}
381
+ func cancel() {
382
+ isCancelled = true
383
+ handlers = []
384
+ }
385
+ }
386
+
387
+ // MARK: - Work items and groups
388
+
389
+ public struct DispatchWorkItemFlags: OptionSet, Sendable {
390
+ public let rawValue: UInt
391
+ public init(rawValue: UInt) { self.rawValue = rawValue }
392
+ public static let barrier = DispatchWorkItemFlags(rawValue: 1 << 0)
393
+ public static let detached = DispatchWorkItemFlags(rawValue: 1 << 1)
394
+ public static let assignCurrentContext = DispatchWorkItemFlags(rawValue: 1 << 2)
395
+ public static let noQoS = DispatchWorkItemFlags(rawValue: 1 << 3)
396
+ public static let inheritQoS = DispatchWorkItemFlags(rawValue: 1 << 4)
397
+ public static let enforceQoS = DispatchWorkItemFlags(rawValue: 1 << 5)
398
+ }
399
+
400
+ /// Work that can be cancelled before it runs.
401
+ public final class DispatchWorkItem: @unchecked Sendable {
402
+ private var block: (() -> Void)?
403
+ public private(set) var isCancelled = false
404
+
405
+ public init(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], block: @escaping @convention(block) () -> Void) {
406
+ self.block = block
407
+ }
408
+
409
+ public func perform() {
410
+ guard !isCancelled else { return }
411
+ block?()
412
+ }
413
+
414
+ public func cancel() {
415
+ isCancelled = true
416
+ block = nil
417
+ }
418
+
419
+ /// Returns at once: with one thread, the work ran already or cannot run while this waits.
420
+ public func wait() {}
421
+ }
422
+
423
+ /// A group of work. `notify` runs once everything entered has left.
424
+ public final class DispatchGroup: @unchecked Sendable {
425
+ private var count = 0
426
+ private var waiting: [() -> Void] = []
427
+
428
+ public init() {}
429
+
430
+ public func enter() { count += 1 }
431
+
432
+ public func leave() {
433
+ count = max(0, count - 1)
434
+ guard count == 0 else { return }
435
+ let ready = waiting
436
+ waiting = []
437
+ for work in ready { work() }
438
+ }
439
+
440
+ public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @escaping () -> Void) {
441
+ nonisolated(unsafe) let work = work
442
+ if count == 0 {
443
+ queue.async(execute: { work() })
444
+ } else {
445
+ waiting.append { queue.async(execute: { work() }) }
446
+ }
447
+ }
448
+ }
449
+
450
+ // MARK: - Time constants
451
+
452
+ // Dispatch's (C) time constants, which code multiplies `Task.sleep`
453
+ // durations with (`Task.sleep(nanoseconds: NSEC_PER_SEC / 2)`).
454
+ public let NSEC_PER_SEC: UInt64 = 1_000_000_000
455
+ public let NSEC_PER_MSEC: UInt64 = 1_000_000
456
+ public let NSEC_PER_USEC: UInt64 = 1_000
457
+ public let USEC_PER_SEC: UInt64 = 1_000_000
458
+ public let MSEC_PER_SEC: UInt64 = 1_000
@@ -0,0 +1,41 @@
1
+ // SwiftUI's environment values of Foundation types: `locale`, `calendar` and
2
+ // `timeZone`. The SwiftUI shim does not import Foundation, so they are
3
+ // declared here. Each defaults to the current one (the viewer's locale,
4
+ // FoundationBridge/Locale.swift); a view may set them for the views it
5
+ // contains, which read them back. The shim's own texts and formatters do
6
+ // not consult them.
7
+
8
+ import Foundation
9
+ import SwiftUI
10
+
11
+ private struct LocaleKey: EnvironmentKey {
12
+ static var defaultValue: Locale? { nil }
13
+ }
14
+
15
+ private struct CalendarKey: EnvironmentKey {
16
+ static var defaultValue: Calendar? { nil }
17
+ }
18
+
19
+ private struct TimeZoneKey: EnvironmentKey {
20
+ static var defaultValue: TimeZone? { nil }
21
+ }
22
+
23
+ extension EnvironmentValues {
24
+ /// The locale views format for: the viewer's unless a view sets one.
25
+ public var locale: Locale {
26
+ get { self[LocaleKey.self] ?? .current }
27
+ set { self[LocaleKey.self] = newValue }
28
+ }
29
+
30
+ /// The calendar views use: the current one unless a view sets one.
31
+ public var calendar: Calendar {
32
+ get { self[CalendarKey.self] ?? .current }
33
+ set { self[CalendarKey.self] = newValue }
34
+ }
35
+
36
+ /// The time zone views use: the current one unless a view sets one.
37
+ public var timeZone: TimeZone {
38
+ get { self[TimeZoneKey.self] ?? .current }
39
+ set { self[TimeZoneKey.self] = newValue }
40
+ }
41
+ }
@@ -0,0 +1,128 @@
1
+ // `.fileImporter`: the page's file chooser in place of the Files app. It is
2
+ // the photo picker's `pickFiles` host request (docs/ops-protocol.md, "Photos
3
+ // picker"), with an `accept` made from the allowed content types. The
4
+ // chosen files are written to a folder of their own in the app's temporary
5
+ // directory, and `onCompletion` gets their file URLs, which the app reads
6
+ // like any file (no security scope to start: `startAccessingSecurityScopedResource`
7
+ // answers true). A dismissed chooser calls `onCancellation`, if given, and
8
+ // not `onCompletion`, as on iOS. Opening a chooser needs a tap, so set
9
+ // `isPresented` from a button's action.
10
+
11
+ import Foundation
12
+ import SwiftUI
13
+ import UniformTypeIdentifiers
14
+
15
+ /// One file import: what to offer and what to do with the files.
16
+ struct _FileImport {
17
+ let types: [UTType]
18
+ let multiple: Bool
19
+ let completion: @MainActor (Result<[URL], any Error>) -> Void
20
+ let cancellation: (@MainActor () -> Void)?
21
+
22
+ /// The chooser's `accept`: a MIME pattern or an extension per type;
23
+ /// empty (any file) when a type covers all data.
24
+ var accept: String {
25
+ var parts: [String] = []
26
+ for type in types {
27
+ if [UTType.item, .data, .content].contains(type) { return "" }
28
+ if type == .image { parts.append("image/*") }
29
+ else if type == .movie || type == .video || type == .audiovisualContent { parts.append("video/*") }
30
+ else if type == .audio { parts.append("audio/*") }
31
+ else if type == .text || type == .plainText { parts.append("text/*") }
32
+ else if let mime = type.preferredMIMEType { parts.append(mime) }
33
+ else if let ext = type.preferredFilenameExtension { parts.append(".\(ext)") }
34
+ }
35
+ return parts.joined(separator: ",")
36
+ }
37
+
38
+ @MainActor func run() async {
39
+ let params: _JSON = .object(["accept": .string(accept), "multiple": .bool(multiple)])
40
+ let value: _JSON
41
+ do {
42
+ value = try await _Runtime.shared._hostRequest(kind: "pickFiles", params: params)
43
+ } catch {
44
+ completion(.failure(error))
45
+ return
46
+ }
47
+ guard case .object(let fields) = value, case .array(let entries)? = fields["items"], !entries.isEmpty else {
48
+ cancellation?()
49
+ return
50
+ }
51
+ do {
52
+ completion(.success(try entries.map(Self.write)))
53
+ } catch {
54
+ completion(.failure(error))
55
+ }
56
+ }
57
+
58
+ /// Writes one chosen file (`{name, data}`) to a new folder in the temporary directory.
59
+ static func write(_ entry: _JSON) throws -> URL {
60
+ guard case .object(let fields) = entry, case .string(let base64)? = fields["data"],
61
+ let data = Data(base64Encoded: base64) else {
62
+ throw CocoaError(.fileReadCorruptFile)
63
+ }
64
+ var name = "file"
65
+ if case .string(let given)? = fields["name"], !given.isEmpty, !given.contains("/") { name = given }
66
+ let folder = FileManager.default.temporaryDirectory.appendingPathComponent("Imports/\(UUID().uuidString)", isDirectory: true)
67
+ try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
68
+ let url = folder.appendingPathComponent(name)
69
+ try data.write(to: url)
70
+ return url
71
+ }
72
+ }
73
+
74
+ /// Opens the chooser when `isPresented` becomes true and sets it back to false once the viewer is done.
75
+ struct _FileImporterPresenter<Content: View>: View {
76
+ let content: Content
77
+ let isPresented: Binding<Bool>
78
+ let fileImport: _FileImport
79
+
80
+ var body: some View {
81
+ let isPresented = isPresented
82
+ nonisolated(unsafe) let fileImport = fileImport
83
+ return content.onChange(of: isPresented.wrappedValue, initial: true) { _, presented in
84
+ guard presented else { return }
85
+ MainActor.assumeIsolated {
86
+ Task { @MainActor in
87
+ await fileImport.run()
88
+ isPresented.wrappedValue = false
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ extension View {
96
+ /// Lets the viewer pick one file of `allowedContentTypes`.
97
+ public func fileImporter(isPresented: Binding<Bool>, allowedContentTypes: [UTType],
98
+ onCompletion: @escaping (Result<URL, any Error>) -> Void) -> some View {
99
+ _FileImporterPresenter(content: self, isPresented: isPresented,
100
+ fileImport: _FileImport(types: allowedContentTypes, multiple: false,
101
+ completion: { onCompletion($0.flatMap { urls in .success(urls[0]) }) },
102
+ cancellation: nil))
103
+ }
104
+
105
+ /// Lets the viewer pick files of `allowedContentTypes`, several when `allowsMultipleSelection`.
106
+ public func fileImporter(isPresented: Binding<Bool>, allowedContentTypes: [UTType], allowsMultipleSelection: Bool,
107
+ onCompletion: @escaping (Result<[URL], any Error>) -> Void) -> some View {
108
+ _FileImporterPresenter(content: self, isPresented: isPresented,
109
+ fileImport: _FileImport(types: allowedContentTypes, multiple: allowsMultipleSelection,
110
+ completion: { onCompletion($0) }, cancellation: nil))
111
+ }
112
+
113
+ /// As above, with `onCancellation` called when the viewer dismisses the chooser.
114
+ public func fileImporter(isPresented: Binding<Bool>, allowedContentTypes: [UTType], allowsMultipleSelection: Bool,
115
+ onCompletion: @escaping (Result<[URL], any Error>) -> Void,
116
+ onCancellation: @escaping () -> Void) -> some View {
117
+ _FileImporterPresenter(content: self, isPresented: isPresented,
118
+ fileImport: _FileImport(types: allowedContentTypes, multiple: allowsMultipleSelection,
119
+ completion: { onCompletion($0) }, cancellation: { onCancellation() }))
120
+ }
121
+ }
122
+
123
+ extension URL {
124
+ /// True: picked files are plain files of the app's.
125
+ public func startAccessingSecurityScopedResource() -> Bool { true }
126
+ /// Nothing to stop.
127
+ public func stopAccessingSecurityScopedResource() {}
128
+ }