@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,165 @@
|
|
|
1
|
+
// `@AppStorage`: a view property kept in `UserDefaults` (UserDefaults.swift),
|
|
2
|
+
// so it survives reloads like the rest of the app's defaults. It lives here
|
|
3
|
+
// rather than in the SwiftUI shim because the shim's `UserDefaults` does.
|
|
4
|
+
//
|
|
5
|
+
// A read registers with the observation tracking the runtime runs each body
|
|
6
|
+
// under, and every write to the key (through any `@AppStorage`, or
|
|
7
|
+
// `UserDefaults.set` itself) is a mutation of it: the views that read the key
|
|
8
|
+
// re-render, and nothing else does.
|
|
9
|
+
|
|
10
|
+
import Foundation
|
|
11
|
+
import Observation
|
|
12
|
+
import SwiftUI
|
|
13
|
+
|
|
14
|
+
/// A property that reads and writes a `UserDefaults` value and re-renders the
|
|
15
|
+
/// view when it changes, as SwiftUI's does.
|
|
16
|
+
@propertyWrapper
|
|
17
|
+
public struct AppStorage<Value>: DynamicProperty {
|
|
18
|
+
let key: String
|
|
19
|
+
let defaultValue: Value
|
|
20
|
+
let store: UserDefaults
|
|
21
|
+
let read: (UserDefaults, String) -> Value?
|
|
22
|
+
let write: (UserDefaults, String, Value) -> Void
|
|
23
|
+
|
|
24
|
+
init(key: String, defaultValue: Value, store: UserDefaults?,
|
|
25
|
+
read: @escaping (UserDefaults, String) -> Value?,
|
|
26
|
+
write: @escaping (UserDefaults, String, Value) -> Void) {
|
|
27
|
+
self.key = key
|
|
28
|
+
self.defaultValue = defaultValue
|
|
29
|
+
self.store = store ?? .standard
|
|
30
|
+
self.read = read
|
|
31
|
+
self.write = write
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public var wrappedValue: Value {
|
|
35
|
+
get {
|
|
36
|
+
_DefaultsKey.named(key).access()
|
|
37
|
+
guard store.object(forKey: key) != nil else { return defaultValue }
|
|
38
|
+
return read(store, key) ?? defaultValue
|
|
39
|
+
}
|
|
40
|
+
nonmutating set { write(store, key, newValue) }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public var projectedValue: Binding<Value> {
|
|
44
|
+
let storage = self
|
|
45
|
+
return Binding(get: { storage.wrappedValue }, set: { storage.wrappedValue = $0 })
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Reads a stored value as `T`: the property-list types as `UserDefaults`
|
|
50
|
+
/// keeps them, accepting what a reload hands back (JSON numbers come back as
|
|
51
|
+
/// `Int` when whole).
|
|
52
|
+
private func _stored<T>(_ type: T.Type, _ store: UserDefaults, _ key: String) -> T? {
|
|
53
|
+
switch type {
|
|
54
|
+
case is Bool.Type: return store.bool(forKey: key) as? T
|
|
55
|
+
case is Int.Type: return store.integer(forKey: key) as? T
|
|
56
|
+
case is Double.Type: return store.double(forKey: key) as? T
|
|
57
|
+
case is String.Type: return store.string(forKey: key) as? T
|
|
58
|
+
case is URL.Type: return store.url(forKey: key) as? T
|
|
59
|
+
default: return store.object(forKey: key) as? T
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private func _plain<T>(_: T.Type) -> (UserDefaults, String) -> T? {
|
|
64
|
+
{ store, key in _stored(T.self, store, key) }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private func _plainWrite<T>(_: T.Type) -> (UserDefaults, String, T) -> Void {
|
|
68
|
+
{ store, key, value in store.set(value as Any, forKey: key) }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private func _optional<T>(_: T.Type) -> (UserDefaults, String) -> T?? {
|
|
72
|
+
{ store, key in _stored(T.self, store, key).map { .some($0) } }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private func _optionalWrite<T>(_: T.Type) -> (UserDefaults, String, T?) -> Void {
|
|
76
|
+
{ store, key, value in
|
|
77
|
+
if let value { store.set(value as Any, forKey: key) } else { store.removeObject(forKey: key) }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
extension AppStorage {
|
|
82
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == Bool {
|
|
83
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(Bool.self), write: _plainWrite(Bool.self))
|
|
84
|
+
}
|
|
85
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == Int {
|
|
86
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(Int.self), write: _plainWrite(Int.self))
|
|
87
|
+
}
|
|
88
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == Double {
|
|
89
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(Double.self), write: _plainWrite(Double.self))
|
|
90
|
+
}
|
|
91
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == String {
|
|
92
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(String.self), write: _plainWrite(String.self))
|
|
93
|
+
}
|
|
94
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == URL {
|
|
95
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(URL.self), write: _plainWrite(URL.self))
|
|
96
|
+
}
|
|
97
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == Data {
|
|
98
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(Data.self), write: _plainWrite(Data.self))
|
|
99
|
+
}
|
|
100
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil) where Value == Date {
|
|
101
|
+
self.init(key: key, defaultValue: wrappedValue, store: store, read: _plain(Date.self), write: _plainWrite(Date.self))
|
|
102
|
+
}
|
|
103
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil)
|
|
104
|
+
where Value: RawRepresentable, Value.RawValue == Int {
|
|
105
|
+
self.init(key: key, defaultValue: wrappedValue, store: store,
|
|
106
|
+
read: { store, key in Value(rawValue: store.integer(forKey: key)) },
|
|
107
|
+
write: { store, key, value in store.set(value.rawValue, forKey: key) })
|
|
108
|
+
}
|
|
109
|
+
public init(wrappedValue: Value, _ key: String, store: UserDefaults? = nil)
|
|
110
|
+
where Value: RawRepresentable, Value.RawValue == String {
|
|
111
|
+
self.init(key: key, defaultValue: wrappedValue, store: store,
|
|
112
|
+
read: { store, key in store.string(forKey: key).flatMap(Value.init(rawValue:)) },
|
|
113
|
+
write: { store, key, value in store.set(value.rawValue, forKey: key) })
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// The optional forms: nil when nothing is stored, and assigning nil removes
|
|
118
|
+
/// the key.
|
|
119
|
+
extension AppStorage where Value: ExpressibleByNilLiteral {
|
|
120
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == Bool? {
|
|
121
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(Bool.self), write: _optionalWrite(Bool.self))
|
|
122
|
+
}
|
|
123
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == Int? {
|
|
124
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(Int.self), write: _optionalWrite(Int.self))
|
|
125
|
+
}
|
|
126
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == Double? {
|
|
127
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(Double.self), write: _optionalWrite(Double.self))
|
|
128
|
+
}
|
|
129
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == String? {
|
|
130
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(String.self), write: _optionalWrite(String.self))
|
|
131
|
+
}
|
|
132
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == URL? {
|
|
133
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(URL.self), write: _optionalWrite(URL.self))
|
|
134
|
+
}
|
|
135
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == Data? {
|
|
136
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(Data.self), write: _optionalWrite(Data.self))
|
|
137
|
+
}
|
|
138
|
+
public init(_ key: String, store: UserDefaults? = nil) where Value == Date? {
|
|
139
|
+
self.init(key: key, defaultValue: nil, store: store, read: _optional(Date.self), write: _optionalWrite(Date.self))
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/// One defaults key as something observation tracking can watch.
|
|
144
|
+
final class _DefaultsKey: Observable, @unchecked Sendable {
|
|
145
|
+
nonisolated(unsafe) private static var keys: [String: _DefaultsKey] = [:]
|
|
146
|
+
|
|
147
|
+
static func named(_ key: String) -> _DefaultsKey {
|
|
148
|
+
if let known = keys[key] { return known }
|
|
149
|
+
let made = _DefaultsKey()
|
|
150
|
+
keys[key] = made
|
|
151
|
+
return made
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/// Every key some view has read, for a change that touches them all.
|
|
155
|
+
static var all: [_DefaultsKey] { Array(keys.values) }
|
|
156
|
+
|
|
157
|
+
private let registrar = ObservationRegistrar()
|
|
158
|
+
private var version = 0
|
|
159
|
+
|
|
160
|
+
func access() { registrar.access(self, keyPath: \.version) }
|
|
161
|
+
|
|
162
|
+
func changed() {
|
|
163
|
+
registrar.withMutation(of: self, keyPath: \.version) { version &+= 1 }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Asset catalog resources (iOS 17): `ImageResource` and `ColorResource`,
|
|
2
|
+
// which Xcode generates a static member of for each image and color set
|
|
3
|
+
// (`Image(.avatar)`, `Color(.accent)`), and which packages take as
|
|
4
|
+
// parameters. They name a catalog entry and the bundle it is in. The page's
|
|
5
|
+
// asset catalog is the whole app's (docs/ops-protocol.md, "Phase 5"), so a
|
|
6
|
+
// resource draws as the catalog image or color of its name, whichever
|
|
7
|
+
// bundle it names.
|
|
8
|
+
|
|
9
|
+
import SwiftUI
|
|
10
|
+
|
|
11
|
+
/// An image set of an asset catalog.
|
|
12
|
+
public struct ImageResource: Hashable, Sendable {
|
|
13
|
+
public let name: String
|
|
14
|
+
let bundlePath: String
|
|
15
|
+
|
|
16
|
+
public init(name: String, bundle: Bundle) {
|
|
17
|
+
self.name = name
|
|
18
|
+
bundlePath = bundle.bundlePath
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// A color set of an asset catalog.
|
|
23
|
+
public struct ColorResource: Hashable, Sendable {
|
|
24
|
+
public let name: String
|
|
25
|
+
let bundlePath: String
|
|
26
|
+
|
|
27
|
+
public init(name: String, bundle: Bundle) {
|
|
28
|
+
self.name = name
|
|
29
|
+
bundlePath = bundle.bundlePath
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
extension Image {
|
|
34
|
+
/// The catalog image `resource` names.
|
|
35
|
+
public init(_ resource: ImageResource) {
|
|
36
|
+
self.init(resource.name)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// The catalog image `resource` names, hidden from assistive technology.
|
|
40
|
+
public init(decorative resource: ImageResource) {
|
|
41
|
+
self.init(decorative: resource.name)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// The catalog image `name`, from any bundle (a package's `.module`):
|
|
45
|
+
/// the page's catalog is the whole app's.
|
|
46
|
+
public init(_ name: String, bundle: Bundle?) {
|
|
47
|
+
self.init(name)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public init(decorative name: String, bundle: Bundle?) {
|
|
51
|
+
self.init(decorative: name)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
extension Color {
|
|
56
|
+
/// The catalog color `resource` names (light and dark resolved by the page).
|
|
57
|
+
///
|
|
58
|
+
/// Disfavored: a color set named like a UIKit color (Ice Cubes'
|
|
59
|
+
/// `label`, a reference to the system label color) makes `.label` a
|
|
60
|
+
/// member of both `ColorResource` and `UIColor`, and `Color(.label)`
|
|
61
|
+
/// means the system color, which such a set refers to anyway.
|
|
62
|
+
@_disfavoredOverload
|
|
63
|
+
public init(_ resource: ColorResource) {
|
|
64
|
+
self.init(resource.name)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/// The catalog color `name`, from any bundle (as `Image(_:bundle:)`).
|
|
68
|
+
public init(_ name: String, bundle: Bundle?) {
|
|
69
|
+
self.init(name)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
extension Label where Title == Text, Icon == Image {
|
|
74
|
+
/// A label whose icon is the catalog image `resource` names.
|
|
75
|
+
public init(_ titleKey: LocalizedStringKey, image resource: ImageResource) {
|
|
76
|
+
self.init(titleKey, image: resource.name)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@_disfavoredOverload
|
|
80
|
+
public init<S: StringProtocol>(_ title: S, image resource: ImageResource) {
|
|
81
|
+
self.init(title, image: resource.name)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
extension UIImage {
|
|
86
|
+
/// The catalog image `resource` names (its size is the page's to know, as for `UIImage(named:)`).
|
|
87
|
+
public convenience init(resource: ImageResource) {
|
|
88
|
+
self.init(named: resource.name)!
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Bytes and lines as async sequences, which Foundation has on Apple platforms
|
|
2
|
+
// and corelibs Foundation does not: `FileHandle.bytes`, `URLSession`'s
|
|
3
|
+
// `bytes(for:)` and `bytes(from:)`, and `.lines` on any sequence of bytes.
|
|
4
|
+
// A file's bytes are read in chunks as the sequence is iterated; a response's
|
|
5
|
+
// arrive whole (the page's `fetch` answers with the body), then are handed out
|
|
6
|
+
// one by one.
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
/// The lines of a sequence of UTF-8 bytes: split at `\n`, `\r\n` and `\r`,
|
|
11
|
+
/// without the separators. A last line without a separator is a line; an
|
|
12
|
+
/// empty one after the last separator is not.
|
|
13
|
+
public struct AsyncLineSequence<Base: AsyncSequence>: AsyncSequence where Base.Element == UInt8 {
|
|
14
|
+
public typealias Element = String
|
|
15
|
+
|
|
16
|
+
let base: Base
|
|
17
|
+
|
|
18
|
+
public struct AsyncIterator: AsyncIteratorProtocol {
|
|
19
|
+
var base: Base.AsyncIterator
|
|
20
|
+
var line: [UInt8] = []
|
|
21
|
+
/// The byte read past a `\r`, to see whether it was `\r\n`.
|
|
22
|
+
var lookahead: UInt8?
|
|
23
|
+
var finished = false
|
|
24
|
+
|
|
25
|
+
public mutating func next() async throws -> String? {
|
|
26
|
+
guard !finished else { return nil }
|
|
27
|
+
while true {
|
|
28
|
+
let byte: UInt8?
|
|
29
|
+
if let pending = lookahead {
|
|
30
|
+
byte = pending
|
|
31
|
+
lookahead = nil
|
|
32
|
+
} else {
|
|
33
|
+
byte = try await base.next()
|
|
34
|
+
}
|
|
35
|
+
guard let byte else {
|
|
36
|
+
finished = true
|
|
37
|
+
if line.isEmpty { return nil }
|
|
38
|
+
defer { line = [] }
|
|
39
|
+
return String(decoding: line, as: UTF8.self)
|
|
40
|
+
}
|
|
41
|
+
switch byte {
|
|
42
|
+
case UInt8(ascii: "\n"):
|
|
43
|
+
defer { line = [] }
|
|
44
|
+
return String(decoding: line, as: UTF8.self)
|
|
45
|
+
case UInt8(ascii: "\r"):
|
|
46
|
+
if let following = try await base.next(), following != UInt8(ascii: "\n") {
|
|
47
|
+
lookahead = following
|
|
48
|
+
}
|
|
49
|
+
defer { line = [] }
|
|
50
|
+
return String(decoding: line, as: UTF8.self)
|
|
51
|
+
default:
|
|
52
|
+
line.append(byte)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public func makeAsyncIterator() -> AsyncIterator {
|
|
59
|
+
AsyncIterator(base: base.makeAsyncIterator())
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
extension AsyncSequence where Element == UInt8 {
|
|
64
|
+
/// The bytes' lines (UTF-8).
|
|
65
|
+
public var lines: AsyncLineSequence<Self> { AsyncLineSequence(base: self) }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
extension FileHandle {
|
|
69
|
+
/// The file's bytes from the current offset on, read in chunks.
|
|
70
|
+
public struct AsyncBytes: AsyncSequence, @unchecked Sendable {
|
|
71
|
+
public typealias Element = UInt8
|
|
72
|
+
|
|
73
|
+
let handle: FileHandle
|
|
74
|
+
|
|
75
|
+
public struct AsyncIterator: AsyncIteratorProtocol {
|
|
76
|
+
let handle: FileHandle
|
|
77
|
+
var chunk: [UInt8] = []
|
|
78
|
+
var index = 0
|
|
79
|
+
var finished = false
|
|
80
|
+
|
|
81
|
+
public mutating func next() async throws -> UInt8? {
|
|
82
|
+
if index == chunk.count {
|
|
83
|
+
guard !finished else { return nil }
|
|
84
|
+
chunk = Array(try handle.read(upToCount: 64 * 1024) ?? Data())
|
|
85
|
+
index = 0
|
|
86
|
+
if chunk.isEmpty {
|
|
87
|
+
finished = true
|
|
88
|
+
return nil
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
defer { index += 1 }
|
|
92
|
+
return chunk[index]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public func makeAsyncIterator() -> AsyncIterator { AsyncIterator(handle: handle) }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// The file's bytes, as an async sequence.
|
|
100
|
+
public var bytes: AsyncBytes { AsyncBytes(handle: self) }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
extension URLSession {
|
|
104
|
+
/// A response body's bytes. The body arrives whole; its bytes are then
|
|
105
|
+
/// handed out in order.
|
|
106
|
+
public struct AsyncBytes: AsyncSequence, Sendable {
|
|
107
|
+
public typealias Element = UInt8
|
|
108
|
+
|
|
109
|
+
let data: Data
|
|
110
|
+
|
|
111
|
+
public struct AsyncIterator: AsyncIteratorProtocol {
|
|
112
|
+
var bytes: Data.Iterator
|
|
113
|
+
|
|
114
|
+
public mutating func next() async throws -> UInt8? { bytes.next() }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public func makeAsyncIterator() -> AsyncIterator { AsyncIterator(bytes: data.makeIterator()) }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public func bytes(for request: URLRequest, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (AsyncBytes, URLResponse) {
|
|
121
|
+
let (data, response) = try await data(for: request, delegate: delegate)
|
|
122
|
+
return (AsyncBytes(data: data), response)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public func bytes(from url: URL, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (AsyncBytes, URLResponse) {
|
|
126
|
+
try await bytes(for: URLRequest(url: url), delegate: delegate)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// `AsyncImage` for the browser. The page loads the picture itself: the view
|
|
2
|
+
// sends an `image` request op with the URL, the host decodes the image (an
|
|
3
|
+
// `<img>` off screen) and answers with its pixel size, and the phase becomes
|
|
4
|
+
// `.success` with an `Image` that renders as an `<img src=url>` the browser
|
|
5
|
+
// already has cached. Nothing of the bitmap crosses into Wasm. Lives here
|
|
6
|
+
// next to `URLSession`, whose errors it reports; `import SwiftUI` brings this
|
|
7
|
+
// module along (the CLI's staging), so it is in scope like Apple's.
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
/// The current state of an `AsyncImage` load.
|
|
13
|
+
public enum AsyncImagePhase: Sendable {
|
|
14
|
+
/// No image yet (loading, or the URL was nil).
|
|
15
|
+
case empty
|
|
16
|
+
case success(Image)
|
|
17
|
+
case failure(any Error)
|
|
18
|
+
|
|
19
|
+
public var image: Image? {
|
|
20
|
+
if case .success(let image) = self { return image }
|
|
21
|
+
return nil
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public var error: (any Error)? {
|
|
25
|
+
if case .failure(let error) = self { return error }
|
|
26
|
+
return nil
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public struct AsyncImage<Content: View>: View {
|
|
31
|
+
private let url: URL?
|
|
32
|
+
private let scale: SwiftUI.CGFloat
|
|
33
|
+
private let content: (AsyncImagePhase) -> Content
|
|
34
|
+
/// `AsyncImage(url:)`: SwiftUI draws a neutral placeholder until the
|
|
35
|
+
/// image arrives, and nothing when it fails.
|
|
36
|
+
private let defaultPlaceholder: Bool
|
|
37
|
+
@State private var phase: AsyncImagePhase = .empty
|
|
38
|
+
|
|
39
|
+
/// Shows the image once loaded, a gray placeholder before.
|
|
40
|
+
public init(url: URL?, scale: SwiftUI.CGFloat = 1) where Content == Image {
|
|
41
|
+
self.url = url
|
|
42
|
+
self.scale = scale
|
|
43
|
+
self.defaultPlaceholder = true
|
|
44
|
+
// Never shown for `.empty` (the placeholder takes over) or `.failure` (nothing).
|
|
45
|
+
self.content = { $0.image ?? Image(_url: "", pixelWidth: 0, pixelHeight: 0, scale: 1) }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// `content` receives the loaded image; `placeholder` shows until then
|
|
49
|
+
/// (and if the load fails, as in SwiftUI).
|
|
50
|
+
public init<I: View, P: View>(url: URL?, scale: SwiftUI.CGFloat = 1,
|
|
51
|
+
@ViewBuilder content: @escaping (Image) -> I,
|
|
52
|
+
@ViewBuilder placeholder: @escaping () -> P) where Content == _AsyncImageContent<I, P> {
|
|
53
|
+
self.url = url
|
|
54
|
+
self.scale = scale
|
|
55
|
+
self.defaultPlaceholder = false
|
|
56
|
+
self.content = { phase in
|
|
57
|
+
if let image = phase.image { _AsyncImageContent(image: content(image), placeholder: nil) }
|
|
58
|
+
else { _AsyncImageContent(image: nil, placeholder: placeholder()) }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// `content` receives every phase.
|
|
63
|
+
public init(url: URL?, scale: SwiftUI.CGFloat = 1, transaction: Transaction = Transaction(),
|
|
64
|
+
@ViewBuilder content: @escaping (AsyncImagePhase) -> Content) {
|
|
65
|
+
self.url = url
|
|
66
|
+
self.scale = scale
|
|
67
|
+
self.defaultPlaceholder = false
|
|
68
|
+
self.content = content
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public var body: some View {
|
|
72
|
+
Group {
|
|
73
|
+
if defaultPlaceholder {
|
|
74
|
+
switch phase {
|
|
75
|
+
case .success(let image): image
|
|
76
|
+
case .empty: Color(red: 0.82, green: 0.82, blue: 0.84)
|
|
77
|
+
case .failure: EmptyView()
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
content(phase)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
.task(id: url?.absoluteString ?? "") { await load() }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@MainActor
|
|
87
|
+
private func load() async {
|
|
88
|
+
guard let url else {
|
|
89
|
+
phase = .empty
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
if case .success = phase { phase = .empty }
|
|
93
|
+
do {
|
|
94
|
+
let value = try await _Runtime.shared._hostRequest(kind: "image", params: .object(["url": .string(url.absoluteString)]))
|
|
95
|
+
guard case .object(let fields) = value, case .number(let width)? = fields["width"], case .number(let height)? = fields["height"] else {
|
|
96
|
+
phase = .failure(URLError(.cannotDecodeContentData, userInfo: ["NSErrorFailingURLKey": url]))
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
phase = .success(Image(_url: url.absoluteString, pixelWidth: width, pixelHeight: height, scale: Double(scale)))
|
|
100
|
+
} catch let failure as _HostRequestError {
|
|
101
|
+
phase = .failure(URLSession.urlError(from: failure.message, url: url))
|
|
102
|
+
} catch {
|
|
103
|
+
phase = .failure(error)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/// What `AsyncImage(url:content:placeholder:)` shows: one of the two.
|
|
109
|
+
public struct _AsyncImageContent<I: View, P: View>: View {
|
|
110
|
+
let image: I?
|
|
111
|
+
let placeholder: P?
|
|
112
|
+
|
|
113
|
+
public var body: some View {
|
|
114
|
+
if let image { image } else if let placeholder { placeholder }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// `NSAttributedString()` and `NSMutableAttributedString()` for the browser.
|
|
2
|
+
// On Apple platforms they inherit NSObject's `init()`, so an empty string is
|
|
3
|
+
// `.init()` (Ice Cubes' composer starts from one); corelibs Foundation's
|
|
4
|
+
// classes only have the `string:` initializers, and an extension cannot
|
|
5
|
+
// declare `init()` (it would override NSObject's). This takes one defaulted
|
|
6
|
+
// parameter instead, which `.init()` and `NSAttributedString()` call alike.
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
extension NSAttributedString {
|
|
11
|
+
/// An empty attributed string (`NSAttributedString()`; inherited, so
|
|
12
|
+
/// `NSMutableAttributedString()` too).
|
|
13
|
+
public convenience init(_empty: Void = ()) {
|
|
14
|
+
self.init(string: "")
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// answers the resource lookups apps make. Headless runs mount a directory
|
|
7
7
|
// through `SB_BUNDLE_DIR` (scripts/run-wasi.mjs).
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import Foundation
|
|
10
10
|
import SwiftUI
|
|
11
11
|
|
|
12
12
|
public final class Bundle: @unchecked Sendable {
|
|
@@ -28,6 +28,8 @@ public final class Bundle: @unchecked Sendable {
|
|
|
28
28
|
public var resourceURL: URL? { bundleURL }
|
|
29
29
|
public var executablePath: String? { nil }
|
|
30
30
|
public var bundleIdentifier: String? { _environment("SB_BUNDLE_ID") }
|
|
31
|
+
/// None: a web app has no App Store receipt.
|
|
32
|
+
public var appStoreReceiptURL: URL? { nil }
|
|
31
33
|
public var infoDictionary: [String: Any]? {
|
|
32
34
|
var info: [String: Any] = [:]
|
|
33
35
|
if let id = bundleIdentifier { info["CFBundleIdentifier"] = id }
|
|
@@ -74,9 +76,44 @@ public final class Bundle: @unchecked Sendable {
|
|
|
74
76
|
urls(forResourcesWithExtension: ext, subdirectory: subpath)?.map(\.path) ?? []
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
///
|
|
79
|
+
/// The key's format string in the running language's table
|
|
80
|
+
/// (`<language>.lproj/<table>.strings` or `.stringsdict`; `Localizable` by
|
|
81
|
+
/// default), then the development language's; else `value` when not
|
|
82
|
+
/// empty, else the key (SwiftUI's Localization/Localization.swift).
|
|
78
83
|
public func localizedString(forKey key: String, value: String?, table: String?) -> String {
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
_Localization.localizedString(forKey: key, value: value, table: table, bundlePath: bundlePath)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// MARK: Localizations
|
|
88
|
+
|
|
89
|
+
/// The language the app was developed in; the CLI stages no other default.
|
|
90
|
+
public var developmentLocalization: String? { "en" }
|
|
91
|
+
|
|
92
|
+
/// The `<name>.lproj` folders among the resources (without `Base`), sorted;
|
|
93
|
+
/// the development localization alone when the app ships none.
|
|
94
|
+
public var localizations: [String] {
|
|
95
|
+
let found = _Localization.localizations(bundlePath: bundlePath)
|
|
96
|
+
return found.isEmpty ? [developmentLocalization ?? "en"] : found
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// The localization the app runs in: the viewer's language as the host
|
|
100
|
+
/// chose it (`SB_LOCALE`, see docs/ops-protocol.md "Phase 11") matched
|
|
101
|
+
/// against `localizations`, else the development localization.
|
|
102
|
+
public var preferredLocalizations: [String] {
|
|
103
|
+
let preferences = _environment("SB_LOCALE").map { [$0] } ?? []
|
|
104
|
+
return Bundle.preferredLocalizations(from: localizations, forPreferences: preferences)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/// The first of `localizationsArray` that matches the viewer's language.
|
|
108
|
+
public static func preferredLocalizations(from localizationsArray: [String]) -> [String] {
|
|
109
|
+
preferredLocalizations(from: localizationsArray, forPreferences: _environment("SB_LOCALE").map { [$0] })
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// The first of `localizationsArray` that matches a preference, by whole
|
|
113
|
+
/// tag (`pt-BR`, case and `_` / `-` aside), Chinese script, then language
|
|
114
|
+
/// (`pt`); without a match, the development localization when listed, else the first.
|
|
115
|
+
public static func preferredLocalizations(from localizationsArray: [String],
|
|
116
|
+
forPreferences preferencesArray: [String]?) -> [String] {
|
|
117
|
+
_Localization.preferredLocalizations(from: localizationsArray, forPreferences: preferencesArray)
|
|
81
118
|
}
|
|
82
119
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// On Apple platforms Foundation brings Combine's observable-object types
|
|
2
|
+
// along, so a view model that imports only Foundation declares
|
|
3
|
+
// `ObservableObject` and `@Published` (WishKit's `ChatViewModel` does).
|
|
4
|
+
// They are the SwiftUI shim's, which the Combine module shares.
|
|
5
|
+
|
|
6
|
+
@_exported import protocol SwiftUI.ObservableObject
|
|
7
|
+
@_exported import struct SwiftUI.Published
|
|
8
|
+
@_exported import class SwiftUI.ObservableObjectPublisher
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// The Core Foundation clock, which Darwin's Foundation brings along and the
|
|
2
|
+
// WASI SDK's does not (nor does Linux's, publicly). The CLI's staging aliases
|
|
3
|
+
// the names, so code that imports only Foundation finds them.
|
|
4
|
+
|
|
5
|
+
import Foundation
|
|
6
|
+
// `CFString`, `CFURL`, `CFURLCreateWithString`…: Darwin's Foundation brings
|
|
7
|
+
// CoreFoundation along, so code that imports only Foundation uses them
|
|
8
|
+
// (SwiftSoup parses URLs with CFURL).
|
|
9
|
+
@_exported import CoreFoundationTypes
|
|
10
|
+
|
|
11
|
+
/// Seconds since 1 January 2001 (GMT), as `Date.timeIntervalSinceReferenceDate`.
|
|
12
|
+
public typealias CFAbsoluteTime = Double
|
|
13
|
+
public typealias CFTimeInterval = Double
|
|
14
|
+
|
|
15
|
+
public func CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime {
|
|
16
|
+
Date().timeIntervalSinceReferenceDate
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extension NSError {
|
|
20
|
+
/// The type of `userInfo` keys (`NSErrorUserInfoKey`), which corelibs
|
|
21
|
+
/// Foundation leaves out. On Apple platforms it is a struct wrapping the
|
|
22
|
+
/// string; here it is the string, so `[NSError.UserInfoKey: Any]` is
|
|
23
|
+
/// `[String: Any]` and `key as String` holds.
|
|
24
|
+
public typealias UserInfoKey = String
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Runs `body`: there is no Objective-C runtime, so nothing to release early.
|
|
28
|
+
public func autoreleasepool<Result>(invoking body: () throws -> Result) rethrows -> Result {
|
|
29
|
+
try body()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// MARK: - Associated objects
|
|
33
|
+
|
|
34
|
+
/// How an associated value is held. Recorded; values are always retained.
|
|
35
|
+
public enum objc_AssociationPolicy: UInt, Sendable {
|
|
36
|
+
case OBJC_ASSOCIATION_ASSIGN = 0
|
|
37
|
+
case OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1
|
|
38
|
+
case OBJC_ASSOCIATION_COPY_NONATOMIC = 3
|
|
39
|
+
case OBJC_ASSOCIATION_RETAIN = 769
|
|
40
|
+
case OBJC_ASSOCIATION_COPY = 771
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// The values attached to objects with `objc_setAssociatedObject`. There is
|
|
44
|
+
/// no Objective-C runtime, so the table is kept here: each object is held
|
|
45
|
+
/// weakly, and the entries of objects that are gone are dropped as the table
|
|
46
|
+
/// changes.
|
|
47
|
+
nonisolated(unsafe) private var _associations: [ObjectIdentifier: (object: _WeakObject, values: [UnsafeRawPointer: Any])] = [:]
|
|
48
|
+
|
|
49
|
+
private struct _WeakObject {
|
|
50
|
+
weak var object: AnyObject?
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public func objc_setAssociatedObject(_ object: Any, _ key: UnsafeRawPointer, _ value: Any?, _ policy: objc_AssociationPolicy) {
|
|
54
|
+
let target = object as AnyObject
|
|
55
|
+
let id = ObjectIdentifier(target)
|
|
56
|
+
_associations = _associations.filter { $0.value.object.object != nil }
|
|
57
|
+
var entry = _associations[id] ?? (_WeakObject(object: target), [:])
|
|
58
|
+
entry.values[key] = value
|
|
59
|
+
_associations[id] = entry.values.isEmpty ? nil : entry
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public func objc_getAssociatedObject(_ object: Any, _ key: UnsafeRawPointer) -> Any? {
|
|
63
|
+
let target = object as AnyObject
|
|
64
|
+
guard let entry = _associations[ObjectIdentifier(target)], entry.object.object === target else { return nil }
|
|
65
|
+
return entry.values[key]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public func objc_removeAssociatedObjects(_ object: Any) {
|
|
69
|
+
_associations[ObjectIdentifier(object as AnyObject)] = nil
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// An estimate: without the Objective-C runtime there is no instance size to
|
|
73
|
+
/// read, and callers use it to weigh cache costs. Two words of header and six
|
|
74
|
+
/// of storage.
|
|
75
|
+
public func class_getInstanceSize(_ cls: AnyClass?) -> Int {
|
|
76
|
+
cls == nil ? 0 : 8 * MemoryLayout<Int>.size
|
|
77
|
+
}
|