@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.
- package/Package.swift +200 -9
- package/README.md +7 -9
- package/Sources/AVFoundation/AVFoundation.swift +131 -0
- package/Sources/AVFoundation/Asset.swift +487 -0
- package/Sources/AVFoundation/AudioSession.swift +144 -0
- package/Sources/AVFoundation/CMTime.swift +303 -0
- package/Sources/AVFoundation/Capture.swift +688 -0
- package/Sources/AVFoundation/Player.swift +749 -0
- package/Sources/AVFoundation/PlayerView.swift +117 -0
- package/Sources/AVKit/AVKit.swift +132 -0
- package/Sources/Accelerate/Accelerate.swift +122 -0
- package/Sources/AppIntents/AppIntents.swift +144 -0
- package/Sources/AppIntents/Parameters.swift +220 -0
- package/Sources/AppIntents/Shortcuts.swift +159 -0
- package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
- package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
- package/Sources/AuthenticationServices/Authorization.swift +251 -0
- package/Sources/Charts/Charts.swift +0 -4
- package/Sources/Combine/AnyCancellable.swift +65 -0
- package/Sources/Combine/AnyPublisher.swift +148 -0
- package/Sources/Combine/AnySubscriber.swift +230 -0
- package/Sources/Combine/Cancellable.swift +35 -0
- package/Sources/Combine/Codable.swift +29 -0
- package/Sources/Combine/CombineIdentifier.swift +45 -0
- package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
- package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
- package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
- package/Sources/Combine/CurrentValueSubject.swift +252 -0
- package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
- package/Sources/Combine/Future.swift +228 -0
- package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
- package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
- package/Sources/Combine/Helpers/ConduitList.swift +59 -0
- package/Sources/Combine/Helpers/DebugHook.swift +177 -0
- package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
- package/Sources/Combine/Helpers/Locking.swift +30 -0
- package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
- package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
- package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
- package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
- package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
- package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
- package/Sources/Combine/Helpers/Utils.swift +30 -0
- package/Sources/Combine/Helpers/Violations.swift +33 -0
- package/Sources/Combine/ImmediateScheduler.swift +178 -0
- package/Sources/Combine/LICENSE +21 -0
- package/Sources/Combine/NotificationPublisher.swift +48 -0
- package/Sources/Combine/ObjectWillChange.swift +46 -0
- package/Sources/Combine/PassthroughSubject.swift +222 -0
- package/Sources/Combine/Publisher+Subscribe.swift +53 -0
- package/Sources/Combine/Publishers/Deferred.swift +48 -0
- package/Sources/Combine/Publishers/Empty.swift +54 -0
- package/Sources/Combine/Publishers/Fail.swift +42 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
- package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
- package/Sources/Combine/Publishers/Just.swift +313 -0
- package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
- package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
- package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
- package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
- package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
- package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
- package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
- package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
- package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
- package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
- package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
- package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
- package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
- package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
- package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
- package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
- package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
- package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
- package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
- package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
- package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
- package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
- package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
- package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
- package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
- package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
- package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
- package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
- package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
- package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
- package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
- package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
- package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
- package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
- package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
- package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
- package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
- package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
- package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
- package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
- package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
- package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
- package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
- package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
- package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
- package/Sources/Combine/Publishers/Publishers.swift +13 -0
- package/Sources/Combine/Publishers/Record.swift +237 -0
- package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
- package/Sources/Combine/Result.swift +46 -0
- package/Sources/Combine/Scheduler.swift +89 -0
- package/Sources/Combine/Schedulers.swift +211 -0
- package/Sources/Combine/Subject+Void.swift +17 -0
- package/Sources/Combine/Subscriber+Void.swift +20 -0
- package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
- package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
- package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
- package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
- package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
- package/Sources/Combine/Subscription.swift +22 -0
- package/Sources/Combine/Subscriptions.swift +42 -0
- package/Sources/Combine/SwiftUIObservation.swift +10 -0
- package/Sources/Combine/_Introspection.swift +107 -0
- package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
- package/Sources/Compression/Compression.swift +365 -0
- package/Sources/Compression/Deflate.swift +407 -0
- package/Sources/Compression/Zlib.swift +179 -0
- package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
- package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
- package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
- package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
- package/Sources/CoreImage/CIColor.swift +41 -0
- package/Sources/CoreImage/CIContext.swift +31 -0
- package/Sources/CoreImage/CIDetector.swift +57 -0
- package/Sources/CoreImage/CIFilter.swift +243 -0
- package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
- package/Sources/CoreImage/CIImage.swift +162 -0
- package/Sources/CoreImage/QRCode.swift +393 -0
- package/Sources/CoreLocation/Coordinate.swift +30 -0
- package/Sources/CoreLocation/Location.swift +65 -0
- package/Sources/CoreML/Evaluation.swift +414 -0
- package/Sources/CoreML/FeatureValue.swift +266 -0
- package/Sources/CoreML/Model.swift +269 -0
- package/Sources/CoreML/MultiArray.swift +92 -0
- package/Sources/CoreML/Specification.swift +233 -0
- package/Sources/CoreText/CoreText.swift +64 -0
- package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
- package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
- package/Sources/CryptoKit/CryptoKit.swift +375 -0
- package/Sources/CryptoKit/Curve25519.swift +317 -0
- package/Sources/CryptoKit/P256.swift +321 -0
- package/Sources/FoundationBridge/AppStorage.swift +165 -0
- package/Sources/FoundationBridge/AssetResources.swift +90 -0
- package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
- package/Sources/FoundationBridge/AsyncImage.swift +116 -0
- package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
- package/Sources/FoundationBridge/CombineExports.swift +8 -0
- package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
- package/Sources/FoundationBridge/Dispatch.swift +458 -0
- package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
- package/Sources/FoundationBridge/FileImporter.swift +128 -0
- package/Sources/FoundationBridge/FileSystem.swift +68 -0
- package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
- package/Sources/FoundationBridge/HostResolution.swift +31 -0
- package/Sources/FoundationBridge/ItemProvider.swift +655 -0
- package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
- package/Sources/FoundationBridge/Links.swift +127 -0
- package/Sources/FoundationBridge/ListFormatter.swift +32 -0
- package/Sources/FoundationBridge/Localization.swift +149 -0
- package/Sources/FoundationBridge/Locks.swift +50 -0
- package/Sources/FoundationBridge/Markdown.swift +527 -0
- package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
- package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
- package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
- package/Sources/FoundationBridge/Operation.swift +195 -0
- package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
- package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
- package/Sources/FoundationBridge/SceneStorage.swift +78 -0
- package/Sources/FoundationBridge/SecurityExports.swift +8 -0
- package/Sources/FoundationBridge/Selector.swift +226 -0
- package/Sources/FoundationBridge/StringComparators.swift +17 -0
- package/Sources/FoundationBridge/Table.swift +211 -0
- package/Sources/FoundationBridge/TextAttributes.swift +42 -0
- package/Sources/FoundationBridge/Timer.swift +6 -1
- package/Sources/FoundationBridge/URLSession.swift +718 -0
- package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
- package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
- package/Sources/FoundationBridge/WebSocket.swift +187 -0
- package/Sources/FoundationModels/FoundationModels.swift +1098 -0
- package/Sources/ImageIO/GIF.swift +72 -0
- package/Sources/ImageIO/ImageIO.swift +248 -0
- package/Sources/ImageIO/ImageTypes.swift +28 -0
- package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
- package/Sources/LocalAuthentication/LAContext.swift +86 -0
- package/Sources/MapKit/Geometry.swift +223 -0
- package/Sources/MapKit/Map.swift +638 -0
- package/Sources/MapKit/MapView.swift +229 -0
- package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
- package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
- package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
- package/Sources/OSLog/OSLog.swift +6 -0
- package/Sources/Photos/Photos.swift +572 -0
- package/Sources/PhotosUI/PhotosPicker.swift +248 -0
- package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
- package/Sources/QuickLook/QuickLook.swift +168 -0
- package/Sources/SafariServices/SafariServices.swift +106 -0
- package/Sources/Security/Security.swift +332 -0
- package/Sources/StoreKit/AppStore.swift +207 -0
- package/Sources/StoreKit/Products.swift +280 -0
- package/Sources/StoreKit/RequestReview.swift +28 -0
- package/Sources/StoreKit/StoreKit1.swift +486 -0
- package/Sources/StoreKit/StoreViews.swift +428 -0
- package/Sources/StoreKit/Transactions.swift +197 -0
- package/Sources/SwiftData/Macros.swift +58 -0
- package/Sources/SwiftData/ModelActor.swift +38 -0
- package/Sources/SwiftData/ModelContainer.swift +129 -0
- package/Sources/SwiftData/ModelContext.swift +451 -0
- package/Sources/SwiftData/PersistentModel.swift +238 -0
- package/Sources/SwiftData/Properties.swift +261 -0
- package/Sources/SwiftData/Query.swift +256 -0
- package/Sources/SwiftData/Schema.swift +192 -0
- package/Sources/SwiftData/Store.swift +146 -0
- package/Sources/SwiftData/StringPredicates.swift +125 -0
- package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
- package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
- package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
- package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
- package/Sources/SwiftDataMacros/Plugin.swift +18 -0
- package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
- package/Sources/SwiftUI/API/Accessibility.swift +55 -6
- package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
- package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
- package/Sources/SwiftUI/API/Alert.swift +1 -1
- package/Sources/SwiftUI/API/AlignmentGuides.swift +68 -0
- package/Sources/SwiftUI/API/Animation.swift +37 -5
- package/Sources/SwiftUI/API/App.swift +31 -1
- package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
- package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
- package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
- package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
- package/Sources/SwiftUI/API/Canvas.swift +337 -0
- package/Sources/SwiftUI/API/Color.swift +104 -28
- package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
- package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
- package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
- package/Sources/SwiftUI/API/Commands.swift +106 -0
- package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
- package/Sources/SwiftUI/API/ContentShape.swift +33 -0
- package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
- package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
- package/Sources/SwiftUI/API/Controls.swift +59 -27
- package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
- package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
- package/Sources/SwiftUI/API/Decorations.swift +1 -1
- package/Sources/SwiftUI/API/EditMode.swift +25 -82
- package/Sources/SwiftUI/API/Effects.swift +125 -10
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +100 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +26 -10
- package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
- package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
- package/Sources/SwiftUI/API/GestureState.swift +65 -0
- package/Sources/SwiftUI/API/Gestures.swift +1 -1
- package/Sources/SwiftUI/API/Glass.swift +127 -0
- package/Sources/SwiftUI/API/Grid.swift +1 -1
- package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
- package/Sources/SwiftUI/API/KeyPress.swift +54 -0
- package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
- package/Sources/SwiftUI/API/Layout.swift +71 -12
- package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
- package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
- package/Sources/SwiftUI/API/Lists.swift +61 -6
- package/Sources/SwiftUI/API/Menu.swift +8 -1
- package/Sources/SwiftUI/API/Modifiers.swift +88 -12
- package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
- package/Sources/SwiftUI/API/Namespace.swift +44 -0
- package/Sources/SwiftUI/API/Navigation.swift +24 -9
- package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
- package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
- package/Sources/SwiftUI/API/Path.swift +543 -0
- package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
- package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
- package/Sources/SwiftUI/API/Picker.swift +14 -4
- package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
- package/Sources/SwiftUI/API/Popover.swift +41 -0
- package/Sources/SwiftUI/API/Preferences.swift +262 -0
- package/Sources/SwiftUI/API/Presentation.swift +17 -4
- package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
- package/Sources/SwiftUI/API/Primitives.swift +168 -39
- package/Sources/SwiftUI/API/Publishers.swift +4 -4
- package/Sources/SwiftUI/API/Redaction.swift +75 -0
- package/Sources/SwiftUI/API/RowActions.swift +3 -2
- package/Sources/SwiftUI/API/Scenes.swift +131 -0
- package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
- package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
- package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
- package/Sources/SwiftUI/API/SectionSupplements.swift +86 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +187 -8
- package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
- package/Sources/SwiftUI/API/Sharing.swift +193 -0
- package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
- package/Sources/SwiftUI/API/State.swift +18 -1
- package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
- package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
- package/Sources/SwiftUI/API/TabContent.swift +841 -0
- package/Sources/SwiftUI/API/Table.swift +382 -0
- package/Sources/SwiftUI/API/Tabs.swift +148 -4
- package/Sources/SwiftUI/API/Tasks.swift +2 -2
- package/Sources/SwiftUI/API/Text.swift +386 -0
- package/Sources/SwiftUI/API/TextDates.swift +61 -0
- package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
- package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
- package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
- package/Sources/SwiftUI/API/Toolbar.swift +52 -16
- package/Sources/SwiftUI/API/Transfer.swift +145 -0
- package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
- package/Sources/SwiftUI/API/Video.swift +64 -0
- package/Sources/SwiftUI/API/View.swift +46 -2
- package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
- package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
- package/Sources/SwiftUI/API/Windows.swift +25 -0
- package/Sources/SwiftUI/Charts/Axis.swift +7 -1
- package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
- package/Sources/SwiftUI/Charts/Chart.swift +17 -3
- package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
- package/Sources/SwiftUI/Localization/Localization.swift +524 -0
- package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
- package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
- package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
- package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
- package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
- package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
- package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
- package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
- package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
- package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
- package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
- package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
- package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
- package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
- package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
- package/Sources/Symbols/Symbols.swift +25 -0
- package/Sources/Translation/Translation.swift +423 -0
- package/Sources/UIKit/Activity.swift +213 -0
- package/Sources/UIKit/Alerts.swift +69 -0
- package/Sources/UIKit/AppDelegate.swift +222 -0
- package/Sources/UIKit/Appearance.swift +84 -0
- package/Sources/UIKit/ColorConversions.swift +70 -0
- package/Sources/UIKit/Controls.swift +225 -0
- package/Sources/UIKit/Device.swift +200 -0
- package/Sources/UIKit/Feedback.swift +65 -0
- package/Sources/UIKit/Font.swift +307 -0
- package/Sources/UIKit/Graphics.swift +204 -0
- package/Sources/UIKit/HostingController.swift +185 -0
- package/Sources/UIKit/Identity.swift +24 -0
- package/Sources/UIKit/Introspectable.swift +510 -0
- package/Sources/UIKit/Pasteboard.swift +363 -0
- package/Sources/UIKit/PhotoAlbum.swift +81 -0
- package/Sources/UIKit/RemoteNotifications.swift +15 -0
- package/Sources/UIKit/Representable.swift +288 -0
- package/Sources/UIKit/SafeArea.swift +12 -0
- package/Sources/UIKit/SceneDelegates.swift +132 -0
- package/Sources/UIKit/Scenes.swift +40 -0
- package/Sources/UIKit/ScrollView.swift +157 -0
- package/Sources/UIKit/ShortcutItems.swift +67 -0
- package/Sources/UIKit/SymbolConfiguration.swift +124 -0
- package/Sources/UIKit/TargetAction.swift +123 -0
- package/Sources/UIKit/TextPaste.swift +161 -0
- package/Sources/UIKit/TextView.swift +538 -0
- package/Sources/UIKit/UIKit.swift +292 -0
- package/Sources/UIKit/UIView.swift +855 -0
- package/Sources/UIKit/ViewTranslation.swift +311 -0
- package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
- package/Sources/UserNotifications/Content.swift +370 -0
- package/Sources/UserNotifications/NotificationCenter.swift +309 -0
- package/Sources/WeatherKit/WeatherKit.swift +228 -0
- package/Sources/WebKit/WebKit.swift +245 -0
- package/Sources/os/os.swift +376 -0
- package/Sources/zlib/zlib.swift +6 -0
- package/index.d.ts +1 -1
- package/index.mjs +2 -2
- package/manifest.d.mts +2 -0
- package/manifest.mjs +41 -0
- package/package.json +5 -3
- package/sync-sources.mjs +21 -7
- package/Sources/FoundationLite/Common.swift +0 -3
- package/Sources/FoundationLite/FoundationLite.swift +0 -171
- package/Sources/FoundationLite/Interaction.swift +0 -146
- package/Sources/FoundationLite/Timer.swift +0 -48
- package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// `NotificationCenter` with the API apps and packages use. On WASI, Swift
|
|
2
|
+
// 6.4's Foundation keeps only the new message-based center: no
|
|
3
|
+
// `addObserver(forName:object:queue:using:)`, no `post(name:object:)`, and no
|
|
4
|
+
// selectors. So code that observes notifications type-checks on the host and
|
|
5
|
+
// fails to build for the browser. This class is the classic center, and the
|
|
6
|
+
// CLI's staging aliases it into every module (like `Timer`), so the host
|
|
7
|
+
// check and the browser build use the same one.
|
|
8
|
+
//
|
|
9
|
+
// The page has one thread: observers run synchronously when a notification
|
|
10
|
+
// is posted, whatever queue they were added with. (Foundation runs a queue's
|
|
11
|
+
// observer on that queue and waits for it, which has the same effect here.)
|
|
12
|
+
|
|
13
|
+
import Foundation
|
|
14
|
+
import SwiftUI
|
|
15
|
+
|
|
16
|
+
open class NotificationCenter: @unchecked Sendable {
|
|
17
|
+
public static let `default` = NotificationCenter()
|
|
18
|
+
|
|
19
|
+
public init() {}
|
|
20
|
+
|
|
21
|
+
/// What `addObserver(forName:object:queue:using:)` returns; pass it to `removeObserver`.
|
|
22
|
+
final class Observation: NSObject, @unchecked Sendable {
|
|
23
|
+
let name: Notification.Name?
|
|
24
|
+
weak var object: AnyObject?
|
|
25
|
+
let hasObject: Bool
|
|
26
|
+
let block: (Notification) -> Void
|
|
27
|
+
/// For a selector observer: the observer, held weakly.
|
|
28
|
+
weak var observer: AnyObject?
|
|
29
|
+
let observes: Bool
|
|
30
|
+
|
|
31
|
+
init(name: Notification.Name?, object: Any?, observer: AnyObject?, block: @escaping (Notification) -> Void) {
|
|
32
|
+
self.name = name
|
|
33
|
+
self.object = object.map { $0 as AnyObject }
|
|
34
|
+
hasObject = object != nil
|
|
35
|
+
self.observer = observer
|
|
36
|
+
observes = observer != nil
|
|
37
|
+
self.block = block
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func matches(_ notification: Notification) -> Bool {
|
|
41
|
+
if let name, name != notification.name { return false }
|
|
42
|
+
if hasObject {
|
|
43
|
+
guard let object, let sender = notification.object.map({ $0 as AnyObject }), sender === object else { return false }
|
|
44
|
+
}
|
|
45
|
+
return true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private var observations: [Observation] = []
|
|
50
|
+
|
|
51
|
+
// MARK: Observing
|
|
52
|
+
|
|
53
|
+
@discardableResult
|
|
54
|
+
open func addObserver(forName name: Notification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping @Sendable (Notification) -> Void) -> any NSObjectProtocol {
|
|
55
|
+
let observation = Observation(name: name, object: obj, observer: nil, block: block)
|
|
56
|
+
observations.append(observation)
|
|
57
|
+
return observation
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// Calls `selector` on `observer` for each matching notification. The
|
|
61
|
+
/// observer is held weakly, as on iOS 9 and later: once it is gone, the
|
|
62
|
+
/// observation ends.
|
|
63
|
+
open func addObserver(_ observer: Any, selector aSelector: Selector, name aName: Notification.Name?, object anObject: Any?) {
|
|
64
|
+
let target = observer as AnyObject
|
|
65
|
+
let observation = Observation(name: aName, object: anObject, observer: target) { [weak target] note in
|
|
66
|
+
if let target { aSelector._perform(on: target, with: note) }
|
|
67
|
+
}
|
|
68
|
+
observations.append(observation)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// The matching notifications, as they are posted.
|
|
72
|
+
public func notifications(named name: Notification.Name, object: AnyObject? = nil) -> Notifications {
|
|
73
|
+
Notifications(center: self, name: name, object: object)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// For `onReceive(NotificationCenter.default.publisher(for: …))`.
|
|
77
|
+
public func publisher(for name: Notification.Name, object: AnyObject? = nil) -> Publisher {
|
|
78
|
+
Publisher(center: self, name: name, object: object)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// MARK: Removing
|
|
82
|
+
|
|
83
|
+
/// Removes an observation token, or every selector observation of an observer.
|
|
84
|
+
open func removeObserver(_ observer: Any) {
|
|
85
|
+
let target = observer as AnyObject
|
|
86
|
+
observations.removeAll { $0 === target || ($0.observes && $0.observer === target) }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
open func removeObserver(_ observer: Any, name aName: Notification.Name?, object anObject: Any?) {
|
|
90
|
+
let target = observer as AnyObject
|
|
91
|
+
let sender = anObject.map { $0 as AnyObject }
|
|
92
|
+
observations.removeAll { observation in
|
|
93
|
+
guard observation === target || (observation.observes && observation.observer === target) else { return false }
|
|
94
|
+
if let aName, observation.name != aName { return false }
|
|
95
|
+
if let sender, observation.object !== sender { return false }
|
|
96
|
+
return true
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// MARK: Posting
|
|
101
|
+
|
|
102
|
+
open func post(_ notification: Notification) {
|
|
103
|
+
// Observers that are gone end their observations.
|
|
104
|
+
observations.removeAll { $0.observes && $0.observer == nil }
|
|
105
|
+
for observation in observations where observation.matches(notification) {
|
|
106
|
+
observation.block(notification)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
open func post(name aName: Notification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable: Any]? = nil) {
|
|
111
|
+
post(Notification(name: aName, object: anObject, userInfo: aUserInfo))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// MARK: Sequences and publishers
|
|
115
|
+
|
|
116
|
+
public struct Notifications: AsyncSequence, @unchecked Sendable {
|
|
117
|
+
public typealias Element = Notification
|
|
118
|
+
let center: NotificationCenter
|
|
119
|
+
let name: Notification.Name
|
|
120
|
+
let object: AnyObject?
|
|
121
|
+
|
|
122
|
+
public func makeAsyncIterator() -> AsyncStream<Notification>.Iterator {
|
|
123
|
+
let (stream, continuation) = AsyncStream<Notification>.makeStream()
|
|
124
|
+
nonisolated(unsafe) let token = center.addObserver(forName: name, object: object, queue: nil) { note in
|
|
125
|
+
nonisolated(unsafe) let note = note
|
|
126
|
+
continuation.yield(note)
|
|
127
|
+
}
|
|
128
|
+
let center = self.center
|
|
129
|
+
continuation.onTermination = { _ in center.removeObserver(token) }
|
|
130
|
+
return stream.makeAsyncIterator()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public struct Publisher: _Publisher, @unchecked Sendable {
|
|
135
|
+
public typealias Output = Notification
|
|
136
|
+
public let center: NotificationCenter
|
|
137
|
+
public let name: Notification.Name
|
|
138
|
+
public let object: AnyObject?
|
|
139
|
+
|
|
140
|
+
@MainActor public func _subscribe(_ receive: @escaping @MainActor (Notification) -> Void) -> any _Cancellable {
|
|
141
|
+
let token = center.addObserver(forName: name, object: object, queue: nil) { note in
|
|
142
|
+
nonisolated(unsafe) let note = note
|
|
143
|
+
MainActor.assumeIsolated { receive(note) }
|
|
144
|
+
}
|
|
145
|
+
return _NotificationCancellable(center: center, token: token)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
struct _NotificationCancellable: _Cancellable, @unchecked Sendable {
|
|
151
|
+
let center: NotificationCenter
|
|
152
|
+
let token: any NSObjectProtocol
|
|
153
|
+
func cancel() { center.removeObserver(token) }
|
|
154
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// `onOpenURL`: the app's own URL schemes, opened from inside the app. On iOS
|
|
2
|
+
// a URL in a scheme the app declares (CFBundleURLTypes) launches the app and
|
|
3
|
+
// reaches its `onOpenURL` handlers. In the browser nothing outside the page
|
|
4
|
+
// can open such a URL, but the app itself can: a link or `openURL` call (and
|
|
5
|
+
// `UIApplication.open`) with `myapp://…` goes to the handlers of the views on
|
|
6
|
+
// screen instead of the page, which could not open it. The schemes are the
|
|
7
|
+
// ones signing in uses (`SB_URL_SCHEMES`; WebAuthRedirects.swift). Universal
|
|
8
|
+
// links and `NSUserActivity` continuation are not delivered.
|
|
9
|
+
|
|
10
|
+
import Foundation
|
|
11
|
+
import SwiftUI
|
|
12
|
+
|
|
13
|
+
/// The `onOpenURL` actions of the views on screen, in the order they appeared.
|
|
14
|
+
@MainActor
|
|
15
|
+
public enum _OpenURLHandlers {
|
|
16
|
+
final class Token {}
|
|
17
|
+
|
|
18
|
+
static var handlers: [(token: ObjectIdentifier, action: (URL) -> Void)] = []
|
|
19
|
+
|
|
20
|
+
static func set(_ token: Token, _ action: @escaping (URL) -> Void) {
|
|
21
|
+
let id = ObjectIdentifier(token)
|
|
22
|
+
if let index = handlers.firstIndex(where: { $0.token == id }) {
|
|
23
|
+
handlers[index].action = action
|
|
24
|
+
} else {
|
|
25
|
+
handlers.append((id, action))
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static func remove(_ token: Token) {
|
|
30
|
+
handlers.removeAll { $0.token == ObjectIdentifier(token) }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// Hands `url` to every handler when it is in one of the app's schemes and
|
|
34
|
+
/// some view handles URLs; false otherwise (the caller opens it as usual).
|
|
35
|
+
public static func deliver(_ url: URL) -> Bool {
|
|
36
|
+
guard !handlers.isEmpty, _WebAuthRedirects.isAppRedirect(url.absoluteString) else { return false }
|
|
37
|
+
for handler in handlers { handler.action(url) }
|
|
38
|
+
return true
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private struct _OpenURLModifier: ViewModifier {
|
|
43
|
+
let action: (URL) -> Void
|
|
44
|
+
@State private var token = _OpenURLHandlers.Token()
|
|
45
|
+
|
|
46
|
+
func body(content: Content) -> some View {
|
|
47
|
+
let token = token, action = action
|
|
48
|
+
return content
|
|
49
|
+
.onAppear { _OpenURLHandlers.set(token, action) }
|
|
50
|
+
.onDisappear { _OpenURLHandlers.remove(token) }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
extension View {
|
|
55
|
+
/// Calls `action` with each URL in one of the app's own schemes that the
|
|
56
|
+
/// app opens while this view is on screen (see the top of this file).
|
|
57
|
+
public func onOpenURL(perform action: @escaping (URL) -> Void) -> some View {
|
|
58
|
+
modifier(_OpenURLModifier(action: action))
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// `Operation` and `OperationQueue` for the browser. The WASI SDK's
|
|
2
|
+
// Foundation has neither (they need Dispatch). The page has one thread, so a
|
|
3
|
+
// queue runs its operations on the main actor, one at a time, in the order
|
|
4
|
+
// they were added, each on a later turn than the one that added it; that is
|
|
5
|
+
// what a serial queue (`maxConcurrentOperationCount = 1`, or the main queue)
|
|
6
|
+
// promises, and a concurrent queue's work cannot overlap anyway. An
|
|
7
|
+
// asynchronous operation (one that overrides `start()`, `isExecuting` and
|
|
8
|
+
// `isFinished`) finishes later: it says so with
|
|
9
|
+
// `didChangeValue(forKey: "isFinished")`, as it does for key-value observing
|
|
10
|
+
// on Apple platforms, and that runs its completion block and lets a serial
|
|
11
|
+
// queue go on to the next operation. The CLI's
|
|
12
|
+
// staging aliases the names to these (the host's Foundation has its own), so
|
|
13
|
+
// `check` type-checks what the browser runs.
|
|
14
|
+
|
|
15
|
+
import Foundation
|
|
16
|
+
|
|
17
|
+
/// A unit of work.
|
|
18
|
+
open class Operation: @unchecked Sendable {
|
|
19
|
+
public enum QueuePriority: Int, Sendable {
|
|
20
|
+
case veryLow = -8, low = -4, normal = 0, high = 4, veryHigh = 8
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private var _isCancelled = false
|
|
24
|
+
private var _isExecuting = false
|
|
25
|
+
private var _isFinished = false
|
|
26
|
+
|
|
27
|
+
// Open, as in Foundation: an asynchronous operation overrides them with
|
|
28
|
+
// its own state (and calls `willChangeValue`/`didChangeValue` around it).
|
|
29
|
+
open var isCancelled: Bool { _isCancelled }
|
|
30
|
+
open var isExecuting: Bool { _isExecuting }
|
|
31
|
+
open var isFinished: Bool { _isFinished }
|
|
32
|
+
open var isAsynchronous: Bool { false }
|
|
33
|
+
open var isReady: Bool { dependencies.allSatisfy(\.isFinished) }
|
|
34
|
+
public var queuePriority: QueuePriority = .normal
|
|
35
|
+
public var name: String?
|
|
36
|
+
public var completionBlock: (@Sendable () -> Void)?
|
|
37
|
+
/// Accepted and ignored: everything runs on the main actor.
|
|
38
|
+
public var qualityOfService: QualityOfService = .default
|
|
39
|
+
public private(set) var dependencies: [Operation] = []
|
|
40
|
+
|
|
41
|
+
/// The queue running it, told when it finishes.
|
|
42
|
+
fileprivate weak var queue: OperationQueue?
|
|
43
|
+
private var completed = false
|
|
44
|
+
|
|
45
|
+
public init() {}
|
|
46
|
+
|
|
47
|
+
/// The work. Subclasses override it.
|
|
48
|
+
open func main() {}
|
|
49
|
+
|
|
50
|
+
/// Runs `main()` unless cancelled, then the completion block. An
|
|
51
|
+
/// operation that keeps its own `isFinished` (an asynchronous one whose
|
|
52
|
+
/// `main()` starts work that ends later) is finished when that says so:
|
|
53
|
+
/// at its `didChangeValue(forKey: "isFinished")`, as a queue on Apple
|
|
54
|
+
/// platforms waits for that key-value notification.
|
|
55
|
+
open func start() {
|
|
56
|
+
guard !isFinished else { return }
|
|
57
|
+
if !isCancelled {
|
|
58
|
+
_isExecuting = true
|
|
59
|
+
main()
|
|
60
|
+
_isExecuting = false
|
|
61
|
+
}
|
|
62
|
+
_isFinished = true
|
|
63
|
+
if isFinished { finished() }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// Runs the completion block and tells the queue, once.
|
|
67
|
+
private func finished() {
|
|
68
|
+
guard !completed else { return }
|
|
69
|
+
completed = true
|
|
70
|
+
completionBlock?()
|
|
71
|
+
queue?.operationFinished(self)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
open func cancel() { _isCancelled = true }
|
|
75
|
+
|
|
76
|
+
/// Key-value observing's change notifications, which an asynchronous
|
|
77
|
+
/// operation sends around its changes to `isExecuting` and `isFinished`.
|
|
78
|
+
/// The change to `isFinished` finishes it (completion block, queue); the
|
|
79
|
+
/// others have nothing observing them.
|
|
80
|
+
public func willChangeValue(forKey key: String) {}
|
|
81
|
+
public func didChangeValue(forKey key: String) {
|
|
82
|
+
if key == "isFinished", isFinished { finished() }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public func addDependency(_ operation: Operation) { dependencies.append(operation) }
|
|
86
|
+
public func removeDependency(_ operation: Operation) { dependencies.removeAll { $0 === operation } }
|
|
87
|
+
|
|
88
|
+
/// Returns at once: with one thread, the operation either ran already or cannot run while this waits.
|
|
89
|
+
public func waitUntilFinished() {}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/// Runs closures.
|
|
93
|
+
open class BlockOperation: Operation, @unchecked Sendable {
|
|
94
|
+
public private(set) var executionBlocks: [@Sendable () -> Void] = []
|
|
95
|
+
|
|
96
|
+
public override init() {}
|
|
97
|
+
|
|
98
|
+
public convenience init(block: @escaping @Sendable () -> Void) {
|
|
99
|
+
self.init()
|
|
100
|
+
executionBlocks = [block]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public func addExecutionBlock(_ block: @escaping @Sendable () -> Void) { executionBlocks.append(block) }
|
|
104
|
+
|
|
105
|
+
open override func main() {
|
|
106
|
+
for block in executionBlocks { block() }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/// Runs operations on the main actor, in order.
|
|
111
|
+
open class OperationQueue: @unchecked Sendable {
|
|
112
|
+
public static let defaultMaxConcurrentOperationCount = -1
|
|
113
|
+
|
|
114
|
+
nonisolated(unsafe) public static let main: OperationQueue = {
|
|
115
|
+
let queue = OperationQueue()
|
|
116
|
+
queue.name = "NSOperationQueue Main Queue"
|
|
117
|
+
queue.maxConcurrentOperationCount = 1
|
|
118
|
+
return queue
|
|
119
|
+
}()
|
|
120
|
+
|
|
121
|
+
/// The queue running the current operation: the main queue (everything runs there).
|
|
122
|
+
public static var current: OperationQueue? { main }
|
|
123
|
+
|
|
124
|
+
public var name: String?
|
|
125
|
+
/// Accepted and ignored: everything runs on the main actor.
|
|
126
|
+
public var qualityOfService: QualityOfService = .default
|
|
127
|
+
public var maxConcurrentOperationCount = OperationQueue.defaultMaxConcurrentOperationCount
|
|
128
|
+
public var underlyingQueue: DispatchQueue?
|
|
129
|
+
public var isSuspended = false {
|
|
130
|
+
didSet { if !isSuspended { drain() } }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private var pending: [Operation] = []
|
|
134
|
+
/// Asynchronous operations started and not yet finished.
|
|
135
|
+
private var running: [Operation] = []
|
|
136
|
+
private var scheduled = false
|
|
137
|
+
|
|
138
|
+
public init() {}
|
|
139
|
+
|
|
140
|
+
public var operations: [Operation] { running + pending }
|
|
141
|
+
public var operationCount: Int { running.count + pending.count }
|
|
142
|
+
|
|
143
|
+
public func addOperation(_ operation: Operation) {
|
|
144
|
+
pending.append(operation)
|
|
145
|
+
schedule()
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public func addOperation(_ block: @escaping @Sendable () -> Void) {
|
|
149
|
+
addOperation(BlockOperation(block: block))
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public func addOperations(_ operations: [Operation], waitUntilFinished wait: Bool) {
|
|
153
|
+
pending += operations
|
|
154
|
+
schedule()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/// Runs `block` after every operation added before it.
|
|
158
|
+
public func addBarrierBlock(_ block: @escaping @Sendable () -> Void) {
|
|
159
|
+
addOperation(block)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public func cancelAllOperations() {
|
|
163
|
+
for operation in running + pending { operation.cancel() }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/// Returns at once: the operations run on later turns of the main actor.
|
|
167
|
+
public func waitUntilAllOperationsAreFinished() {}
|
|
168
|
+
|
|
169
|
+
private func schedule() {
|
|
170
|
+
guard !scheduled, !isSuspended else { return }
|
|
171
|
+
scheduled = true
|
|
172
|
+
nonisolated(unsafe) let queue = self
|
|
173
|
+
Task { @MainActor in
|
|
174
|
+
queue.scheduled = false
|
|
175
|
+
queue.drain()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private func drain() {
|
|
180
|
+
// A serial queue waits for an asynchronous operation to finish.
|
|
181
|
+
while !isSuspended, maxConcurrentOperationCount != 1 || running.isEmpty,
|
|
182
|
+
let index = pending.firstIndex(where: \.isReady) {
|
|
183
|
+
let operation = pending.remove(at: index)
|
|
184
|
+
operation.queue = self
|
|
185
|
+
operation.start()
|
|
186
|
+
if !operation.isFinished { running.append(operation) }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
fileprivate func operationFinished(_ operation: Operation) {
|
|
191
|
+
guard let index = running.firstIndex(where: { $0 === operation }) else { return }
|
|
192
|
+
running.remove(at: index)
|
|
193
|
+
schedule()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// `ProcessInfo.processInfo.physicalMemory` for the browser. swift-foundation
|
|
2
|
+
// answers 0 on WASI, and libraries size their limits from it (Nuke refuses
|
|
3
|
+
// any download larger than a tenth of it, so every image would fail). The
|
|
4
|
+
// getter is reached through the class's vtable, out of a linker's reach, so
|
|
5
|
+
// the CLI's staging rewrites the expression to `_physicalMemory`: 4 GiB in the
|
|
6
|
+
// browser, the most a wasm32 module can address (Nuke's own cap, 200 MB, then
|
|
7
|
+
// applies as on a phone), and Foundation's answer elsewhere.
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
public var _physicalMemory: UInt64 {
|
|
12
|
+
#if os(WASI)
|
|
13
|
+
4 * 1024 * 1024 * 1024
|
|
14
|
+
#else
|
|
15
|
+
ProcessInfo.processInfo.physicalMemory
|
|
16
|
+
#endif
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extension ProcessInfo {
|
|
20
|
+
/// The browser is no Mac: an iOS app here runs as on an iPhone.
|
|
21
|
+
public var isiOSAppOnMac: Bool { false }
|
|
22
|
+
public var isMacCatalystApp: Bool { false }
|
|
23
|
+
/// The page cannot read the battery's saver: never on, so animations run.
|
|
24
|
+
public var isLowPowerModeEnabled: Bool { false }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Darwin's `sysctlbyname`, which apps call for the hardware model. The browser
|
|
28
|
+
/// has no kernel to ask: every name is unknown (-1, nothing written).
|
|
29
|
+
public func sysctlbyname(_ name: UnsafePointer<CChar>?, _ oldp: UnsafeMutableRawPointer?, _ oldlenp: UnsafeMutablePointer<Int>?, _ newp: UnsafeMutableRawPointer?, _ newlen: Int) -> Int32 {
|
|
30
|
+
oldlenp?.pointee = 0
|
|
31
|
+
return -1
|
|
32
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// `RelativeDateTimeFormatter` ("2 hr. ago", "in 3 days"), which corelibs
|
|
2
|
+
// Foundation does not have. English only, like the rest of the bridge's
|
|
3
|
+
// formatting: the largest unit with a nonzero amount, counted as Apple's
|
|
4
|
+
// does (weeks of 7 days, months of 30 and years of 365, rounded toward zero).
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
|
|
8
|
+
open class RelativeDateTimeFormatter: @unchecked Sendable {
|
|
9
|
+
public enum DateTimeStyle: Int, Sendable {
|
|
10
|
+
case numeric = 0
|
|
11
|
+
case named = 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public enum UnitsStyle: Int, Sendable {
|
|
15
|
+
case full = 0
|
|
16
|
+
case spellOut = 1
|
|
17
|
+
case short = 2
|
|
18
|
+
case abbreviated = 3
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// How the string will be used; the bridge's English has no capitalization rules to apply.
|
|
22
|
+
public enum Context: Int, Sendable {
|
|
23
|
+
case unknown = 0
|
|
24
|
+
case dynamic = 1
|
|
25
|
+
case standalone = 2
|
|
26
|
+
case listItem = 3
|
|
27
|
+
case beginningOfSentence = 4
|
|
28
|
+
case middleOfSentence = 5
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
open var dateTimeStyle: DateTimeStyle = .numeric
|
|
32
|
+
open var unitsStyle: UnitsStyle = .full
|
|
33
|
+
open var formattingContext: Context = .unknown
|
|
34
|
+
open var calendar: Calendar! = .current
|
|
35
|
+
open var locale: Locale! = .current
|
|
36
|
+
|
|
37
|
+
public init() {}
|
|
38
|
+
|
|
39
|
+
open func localizedString(for date: Date, relativeTo referenceDate: Date) -> String {
|
|
40
|
+
localizedString(fromTimeInterval: date.timeIntervalSince(referenceDate))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
open func localizedString(fromTimeInterval timeInterval: TimeInterval) -> String {
|
|
44
|
+
let seconds = Int(timeInterval.rounded(.towardZero))
|
|
45
|
+
let magnitude = abs(seconds)
|
|
46
|
+
let (amount, unit): (Int, _Unit) = switch magnitude {
|
|
47
|
+
case ..<60: (magnitude, .second)
|
|
48
|
+
case ..<3_600: (magnitude / 60, .minute)
|
|
49
|
+
case ..<86_400: (magnitude / 3_600, .hour)
|
|
50
|
+
case ..<604_800: (magnitude / 86_400, .day)
|
|
51
|
+
case ..<2_592_000: (magnitude / 604_800, .week)
|
|
52
|
+
case ..<31_536_000: (magnitude / 2_592_000, .month)
|
|
53
|
+
default: (magnitude / 31_536_000, .year)
|
|
54
|
+
}
|
|
55
|
+
return phrase(amount, unit, future: seconds >= 0)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
open func localizedString(from dateComponents: DateComponents) -> String {
|
|
59
|
+
let parts: [(Int?, _Unit)] = [
|
|
60
|
+
(dateComponents.year, .year), (dateComponents.month, .month), (dateComponents.weekOfMonth, .week),
|
|
61
|
+
(dateComponents.day, .day), (dateComponents.hour, .hour), (dateComponents.minute, .minute),
|
|
62
|
+
(dateComponents.second, .second),
|
|
63
|
+
]
|
|
64
|
+
let (value, unit) = parts.first { ($0.0 ?? 0) != 0 }.map { ($0.0!, $0.1) } ?? (0, .second)
|
|
65
|
+
return phrase(abs(value), unit, future: value >= 0)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
open func string(for obj: Any?) -> String? {
|
|
69
|
+
guard let date = obj as? Date else { return nil }
|
|
70
|
+
return localizedString(for: date, relativeTo: Date())
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
enum _Unit { case second, minute, hour, day, week, month, year }
|
|
74
|
+
|
|
75
|
+
func phrase(_ amount: Int, _ unit: _Unit, future: Bool) -> String {
|
|
76
|
+
if dateTimeStyle == .named, let named = named(amount, unit, future: future) { return named }
|
|
77
|
+
let count = unitsStyle == .spellOut ? Self.spelled(amount) : String(amount)
|
|
78
|
+
let quantity: String
|
|
79
|
+
switch unitsStyle {
|
|
80
|
+
case .abbreviated:
|
|
81
|
+
let suffix = switch unit {
|
|
82
|
+
case .second: "s"
|
|
83
|
+
case .minute: "m"
|
|
84
|
+
case .hour: "h"
|
|
85
|
+
case .day: "d"
|
|
86
|
+
case .week: "w"
|
|
87
|
+
case .month: "mo"
|
|
88
|
+
case .year: "y"
|
|
89
|
+
}
|
|
90
|
+
quantity = count + suffix
|
|
91
|
+
case .short:
|
|
92
|
+
let word = switch unit {
|
|
93
|
+
case .second: "sec."
|
|
94
|
+
case .minute: "min."
|
|
95
|
+
case .hour: "hr."
|
|
96
|
+
case .day: amount == 1 ? "day" : "days"
|
|
97
|
+
case .week: "wk."
|
|
98
|
+
case .month: "mo."
|
|
99
|
+
case .year: "yr."
|
|
100
|
+
}
|
|
101
|
+
quantity = "\(count) \(word)"
|
|
102
|
+
case .full, .spellOut:
|
|
103
|
+
let word = switch unit {
|
|
104
|
+
case .second: "second"
|
|
105
|
+
case .minute: "minute"
|
|
106
|
+
case .hour: "hour"
|
|
107
|
+
case .day: "day"
|
|
108
|
+
case .week: "week"
|
|
109
|
+
case .month: "month"
|
|
110
|
+
case .year: "year"
|
|
111
|
+
}
|
|
112
|
+
quantity = "\(count) \(word)\(amount == 1 ? "" : "s")"
|
|
113
|
+
}
|
|
114
|
+
return future ? "in \(quantity)" : "\(quantity) ago"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// "now", "yesterday", "next week" and the like, for the named style.
|
|
118
|
+
func named(_ amount: Int, _ unit: _Unit, future: Bool) -> String? {
|
|
119
|
+
if amount == 0 { return unit == .second ? "now" : "this \(unit)" }
|
|
120
|
+
guard amount == 1 else { return nil }
|
|
121
|
+
switch unit {
|
|
122
|
+
case .second, .minute, .hour: return nil
|
|
123
|
+
case .day: return future ? "tomorrow" : "yesterday"
|
|
124
|
+
default: return "\(future ? "next" : "last") \(unit)"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static func spelled(_ n: Int) -> String {
|
|
129
|
+
let ones = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven",
|
|
130
|
+
"twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
|
|
131
|
+
let tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
|
|
132
|
+
if n < 20 { return ones[n] }
|
|
133
|
+
if n < 100 { return tens[n / 10] + (n % 10 == 0 ? "" : "-" + ones[n % 10]) }
|
|
134
|
+
return String(n)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// `@SceneStorage`: a view property the scene restores. The page is one
|
|
2
|
+
// scene, restored when it reloads, so a scene-stored value is an
|
|
3
|
+
// `@AppStorage` value under a key of its own (`SceneStorage.<key>`): it
|
|
4
|
+
// survives reloads and re-renders the views that read it when it changes.
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
import SwiftUI
|
|
8
|
+
|
|
9
|
+
@propertyWrapper
|
|
10
|
+
public struct SceneStorage<Value>: DynamicProperty {
|
|
11
|
+
let storage: AppStorage<Value>
|
|
12
|
+
|
|
13
|
+
init(_ storage: AppStorage<Value>) { self.storage = storage }
|
|
14
|
+
|
|
15
|
+
public var wrappedValue: Value {
|
|
16
|
+
get { storage.wrappedValue }
|
|
17
|
+
nonmutating set { storage.wrappedValue = newValue }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public var projectedValue: Binding<Value> { storage.projectedValue }
|
|
21
|
+
|
|
22
|
+
static func key(_ key: String) -> String { "SceneStorage." + key }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
extension SceneStorage {
|
|
26
|
+
public init(wrappedValue: Value, _ key: String) where Value == Bool {
|
|
27
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
28
|
+
}
|
|
29
|
+
public init(wrappedValue: Value, _ key: String) where Value == Int {
|
|
30
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
31
|
+
}
|
|
32
|
+
public init(wrappedValue: Value, _ key: String) where Value == Double {
|
|
33
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
34
|
+
}
|
|
35
|
+
public init(wrappedValue: Value, _ key: String) where Value == String {
|
|
36
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
37
|
+
}
|
|
38
|
+
public init(wrappedValue: Value, _ key: String) where Value == URL {
|
|
39
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
40
|
+
}
|
|
41
|
+
public init(wrappedValue: Value, _ key: String) where Value == Data {
|
|
42
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
43
|
+
}
|
|
44
|
+
public init(wrappedValue: Value, _ key: String) where Value == Date {
|
|
45
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
46
|
+
}
|
|
47
|
+
public init(wrappedValue: Value, _ key: String) where Value: RawRepresentable, Value.RawValue == Int {
|
|
48
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
49
|
+
}
|
|
50
|
+
public init(wrappedValue: Value, _ key: String) where Value: RawRepresentable, Value.RawValue == String {
|
|
51
|
+
self.init(AppStorage(wrappedValue: wrappedValue, Self.key(key)))
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// The optional forms: nil when nothing is stored.
|
|
56
|
+
extension SceneStorage where Value: ExpressibleByNilLiteral {
|
|
57
|
+
public init(_ key: String) where Value == Bool? {
|
|
58
|
+
self.init(AppStorage(Self.key(key)))
|
|
59
|
+
}
|
|
60
|
+
public init(_ key: String) where Value == Int? {
|
|
61
|
+
self.init(AppStorage(Self.key(key)))
|
|
62
|
+
}
|
|
63
|
+
public init(_ key: String) where Value == Double? {
|
|
64
|
+
self.init(AppStorage(Self.key(key)))
|
|
65
|
+
}
|
|
66
|
+
public init(_ key: String) where Value == String? {
|
|
67
|
+
self.init(AppStorage(Self.key(key)))
|
|
68
|
+
}
|
|
69
|
+
public init(_ key: String) where Value == URL? {
|
|
70
|
+
self.init(AppStorage(Self.key(key)))
|
|
71
|
+
}
|
|
72
|
+
public init(_ key: String) where Value == Data? {
|
|
73
|
+
self.init(AppStorage(Self.key(key)))
|
|
74
|
+
}
|
|
75
|
+
public init(_ key: String) where Value == Date? {
|
|
76
|
+
self.init(AppStorage(Self.key(key)))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// On Apple platforms Foundation brings parts of Security along (its headers
|
|
2
|
+
// import it), so code that imports only Foundation calls
|
|
3
|
+
// `SecRandomCopyBytes` (Ice Cubes makes its push-notification auth key that
|
|
4
|
+
// way). These come from the shim's Security module.
|
|
5
|
+
|
|
6
|
+
@_exported import func Security.SecRandomCopyBytes
|
|
7
|
+
@_exported import var Security.kSecRandomDefault
|
|
8
|
+
@_exported import typealias Security.SecRandomRef
|