@swiftbrowser/swift 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +65 -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 +105 -7
- package/Sources/SwiftUI/API/Entry.swift +8 -0
- package/Sources/SwiftUI/API/Environment.swift +93 -9
- package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
- package/Sources/SwiftUI/API/Focus.swift +11 -3
- package/Sources/SwiftUI/API/Gauge.swift +3 -2
- 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 +67 -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 +80 -10
- 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 +11 -2
- 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 +164 -37
- 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 +96 -0
- package/Sources/SwiftUI/API/Shape.swift +214 -0
- package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
- 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 +10 -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 +498 -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 +39 -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,238 @@
|
|
|
1
|
+
// A persistent model and the data behind it. `@Model` turns each persisted
|
|
2
|
+
// property into accessors over the model's `_ModelBacking`, which holds the
|
|
3
|
+
// property values: live Swift values once set or read, or the JSON a record
|
|
4
|
+
// was stored with until a property is first read (decoding is lazy, so a
|
|
5
|
+
// fetch does not decode what a screen never shows, and a related model is
|
|
6
|
+
// looked up only when the relationship is followed).
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import Observation
|
|
10
|
+
import SwiftUI
|
|
11
|
+
|
|
12
|
+
public protocol PersistentModel: AnyObject, Observable, Hashable, Identifiable, _RelationshipValue {
|
|
13
|
+
/// The values behind the model's persisted properties.
|
|
14
|
+
var persistentBackingData: _ModelBacking { get set }
|
|
15
|
+
/// The persisted properties, as `@Model` describes them.
|
|
16
|
+
static var schemaMetadata: [Schema.PropertyMetadata] { get }
|
|
17
|
+
/// Creates a model over existing data; a context does this to
|
|
18
|
+
/// materialize a stored record.
|
|
19
|
+
init(backingData: _ModelBacking)
|
|
20
|
+
var _$observationRegistrar: ObservationRegistrar { get }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// The type of the placeholder peers `@Model` adds next to each persisted
|
|
24
|
+
/// property, so that definite initialization still requires the class's
|
|
25
|
+
/// initializers to give every persisted property a value.
|
|
26
|
+
public struct _SwiftDataNoType {
|
|
27
|
+
public init() {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// The identity of a model: its entity and its record in a store.
|
|
31
|
+
public struct PersistentIdentifier: Hashable, Comparable, Codable, Sendable, CustomStringConvertible {
|
|
32
|
+
public let entityName: String
|
|
33
|
+
/// The store the model was saved to; nil until it is inserted.
|
|
34
|
+
public let storeIdentifier: String?
|
|
35
|
+
let primaryKey: Int64
|
|
36
|
+
|
|
37
|
+
init(entityName: String, storeIdentifier: String?, primaryKey: Int64) {
|
|
38
|
+
self.entityName = entityName
|
|
39
|
+
self.storeIdentifier = storeIdentifier
|
|
40
|
+
self.primaryKey = primaryKey
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static func == (lhs: PersistentIdentifier, rhs: PersistentIdentifier) -> Bool {
|
|
44
|
+
lhs.primaryKey == rhs.primaryKey && lhs.entityName == rhs.entityName
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public func hash(into hasher: inout Hasher) {
|
|
48
|
+
hasher.combine(entityName)
|
|
49
|
+
hasher.combine(primaryKey)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public static func < (lhs: PersistentIdentifier, rhs: PersistentIdentifier) -> Bool {
|
|
53
|
+
(lhs.primaryKey, lhs.entityName) < (rhs.primaryKey, rhs.entityName)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public var description: String { "\(entityName)/\(primaryKey)" }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// One property's value in a model's backing data.
|
|
60
|
+
enum _Slot {
|
|
61
|
+
/// A Swift value of the property's type.
|
|
62
|
+
case live(Any)
|
|
63
|
+
/// The JSON of a stored record, decoded at first read.
|
|
64
|
+
case stored(_JSON)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/// The data behind a model: its property values, identity and context.
|
|
68
|
+
public final class _ModelBacking {
|
|
69
|
+
let modelType: any PersistentModel.Type
|
|
70
|
+
var slots: [String: _Slot] = [:]
|
|
71
|
+
/// Assigned when the model is first identified (hashed, inserted).
|
|
72
|
+
var primaryKey: Int64?
|
|
73
|
+
var storeIdentifier: String?
|
|
74
|
+
weak var context: ModelContext?
|
|
75
|
+
var isDeleted = false
|
|
76
|
+
|
|
77
|
+
public init<Model: PersistentModel>(for type: Model.Type) {
|
|
78
|
+
modelType = type
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
init(type: any PersistentModel.Type, primaryKey: Int64, storeIdentifier: String, stored values: [String: _JSON]) {
|
|
82
|
+
modelType = type
|
|
83
|
+
self.primaryKey = primaryKey
|
|
84
|
+
self.storeIdentifier = storeIdentifier
|
|
85
|
+
for (key, value) in values { slots[key] = .stored(value) }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// Resolved on first use: a model's initial values may themselves create
|
|
89
|
+
/// models, so the entity is not looked up while the model initializes.
|
|
90
|
+
lazy var entity: _Entity = _Entity.of(modelType)
|
|
91
|
+
|
|
92
|
+
var identifier: PersistentIdentifier {
|
|
93
|
+
if primaryKey == nil { primaryKey = _Store.allocatePrimaryKey() }
|
|
94
|
+
return PersistentIdentifier(entityName: entity.name, storeIdentifier: storeIdentifier, primaryKey: primaryKey!)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// Called by a persisted property's `init` accessor.
|
|
98
|
+
public func _setInitialValue<Value>(_ value: Value, forKey key: String) {
|
|
99
|
+
slots[key] = .live(value)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// The property's value as a Swift value, decoding a stored one.
|
|
103
|
+
func value(of property: _Property) -> Any {
|
|
104
|
+
switch slots[property.name] {
|
|
105
|
+
case .live(let value)?:
|
|
106
|
+
return value
|
|
107
|
+
case .stored(let json)?:
|
|
108
|
+
let value = decode(json, for: property)
|
|
109
|
+
slots[property.name] = .live(value)
|
|
110
|
+
return value
|
|
111
|
+
case nil:
|
|
112
|
+
if let initial = property.defaultValue { return initial }
|
|
113
|
+
if property.isRelationship { return property.make([]) }
|
|
114
|
+
if property.isOptional, let none = try? property.decode(.null) { return none }
|
|
115
|
+
fatalError("SwiftData: this \(entity.name) has no value for \(property.name), a property added without an initial value. Give it one, or clear the app's data.")
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private func decode(_ json: _JSON, for property: _Property) -> Any {
|
|
120
|
+
switch property.kind {
|
|
121
|
+
case .attribute:
|
|
122
|
+
do {
|
|
123
|
+
return try property.decode(json)
|
|
124
|
+
} catch {
|
|
125
|
+
if let initial = property.defaultValue { return initial }
|
|
126
|
+
fatalError("SwiftData: cannot read \(entity.name).\(property.name) from \(json.serialized): \(error)")
|
|
127
|
+
}
|
|
128
|
+
case .toOne, .toMany:
|
|
129
|
+
let keys: [Int64] = switch json {
|
|
130
|
+
case .number(let n): [Int64(n)]
|
|
131
|
+
case .array(let items): items.compactMap { if case .number(let n) = $0 { Int64(n) } else { nil } }
|
|
132
|
+
default: []
|
|
133
|
+
}
|
|
134
|
+
let models = keys.compactMap { context?._model(primaryKey: $0, type: property.relatedType!) }
|
|
135
|
+
return property.make(models)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// The JSON of a property's current value, for a record.
|
|
140
|
+
func json(of property: _Property) -> _JSON {
|
|
141
|
+
switch slots[property.name] {
|
|
142
|
+
case .stored(let json)?:
|
|
143
|
+
return json
|
|
144
|
+
case .live(let value)?:
|
|
145
|
+
switch property.kind {
|
|
146
|
+
case .attribute:
|
|
147
|
+
return property.encode(value)
|
|
148
|
+
case .toOne:
|
|
149
|
+
let keys = property.models(value).compactMap { $0.persistentBackingData.savedKey }
|
|
150
|
+
return keys.first.map { .number(Double($0)) } ?? .null
|
|
151
|
+
case .toMany:
|
|
152
|
+
return .array(property.models(value).compactMap { $0.persistentBackingData.savedKey.map { .number(Double($0)) } })
|
|
153
|
+
}
|
|
154
|
+
case nil:
|
|
155
|
+
if let initial = property.defaultValue, property.kind == .attribute { return property.encode(initial) }
|
|
156
|
+
return property.kind == .toMany ? .array([]) : .null
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/// The key a relationship stores for this model: none once it is deleted
|
|
161
|
+
/// or when it belongs to no context.
|
|
162
|
+
private var savedKey: Int64? {
|
|
163
|
+
guard !isDeleted, context != nil else { return nil }
|
|
164
|
+
return primaryKey
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/// The models a relationship currently holds.
|
|
168
|
+
func relatedModels(_ property: _Property) -> [any PersistentModel] {
|
|
169
|
+
property.models(value(of: property))
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
extension PersistentModel {
|
|
174
|
+
public var persistentModelID: PersistentIdentifier { persistentBackingData.identifier }
|
|
175
|
+
|
|
176
|
+
public var id: PersistentIdentifier { persistentModelID }
|
|
177
|
+
|
|
178
|
+
/// The context the model was inserted into or fetched from.
|
|
179
|
+
public var modelContext: ModelContext? { persistentBackingData.context }
|
|
180
|
+
|
|
181
|
+
/// Whether the model was deleted from its context.
|
|
182
|
+
public var isDeleted: Bool { persistentBackingData.isDeleted }
|
|
183
|
+
|
|
184
|
+
/// Whether the model has changes its context has not saved.
|
|
185
|
+
public var hasChanges: Bool {
|
|
186
|
+
guard let context = persistentBackingData.context else { return false }
|
|
187
|
+
return context._hasChanges(persistentModelID)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public static func == (lhs: Self, rhs: Self) -> Bool {
|
|
191
|
+
lhs === rhs || lhs.persistentModelID == rhs.persistentModelID
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public func hash(into hasher: inout Hasher) {
|
|
195
|
+
hasher.combine(persistentModelID)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// MARK: Accessors
|
|
199
|
+
|
|
200
|
+
/// A persisted property's value (called by the property's getter).
|
|
201
|
+
public func _$getValue<Value>(forKey key: String) -> Value {
|
|
202
|
+
let backing = persistentBackingData
|
|
203
|
+
guard let property = backing.entity.property(key) else {
|
|
204
|
+
if case .live(let value)? = backing.slots[key] { return value as! Value }
|
|
205
|
+
fatalError("SwiftData: \(Self.self) has no persisted property \(key)")
|
|
206
|
+
}
|
|
207
|
+
return backing.value(of: property) as! Value
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/// Sets a persisted property (called by the property's setter). A
|
|
211
|
+
/// relationship keeps its inverse in step and brings the models it now
|
|
212
|
+
/// holds into the model's context.
|
|
213
|
+
public func _$setValue<Value>(_ value: Value, forKey key: String) {
|
|
214
|
+
let backing = persistentBackingData
|
|
215
|
+
guard let context = backing.context, !backing.isDeleted, let property = backing.entity.property(key) else {
|
|
216
|
+
backing.slots[key] = .live(value)
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
if property.isRelationship {
|
|
220
|
+
let old = backing.relatedModels(property)
|
|
221
|
+
backing.slots[key] = .live(value)
|
|
222
|
+
context._relationship(property, of: self, changedFrom: old, to: property.models(value))
|
|
223
|
+
} else {
|
|
224
|
+
backing.slots[key] = .live(value)
|
|
225
|
+
}
|
|
226
|
+
context._modelDidChange(self)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/// A persisted property's value, by key path.
|
|
230
|
+
public func getValue<Value>(forKey keyPath: KeyPath<Self, Value>) -> Value {
|
|
231
|
+
self[keyPath: keyPath]
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/// Sets a persisted property, by key path.
|
|
235
|
+
public func setValue<Value>(forKey keyPath: ReferenceWritableKeyPath<Self, Value>, to value: Value) {
|
|
236
|
+
self[keyPath: keyPath] = value
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// What the store knows about each persisted property, worked out once per
|
|
2
|
+
// model type from `@Model`'s generated `schemaMetadata`, where each
|
|
3
|
+
// property's static type is still known: how to encode and decode its value,
|
|
4
|
+
// whether it relates to other models, and how to notify its observers.
|
|
5
|
+
|
|
6
|
+
import Foundation
|
|
7
|
+
import Observation
|
|
8
|
+
import SwiftUI
|
|
9
|
+
|
|
10
|
+
/// A value of a relationship property: a model, an optional model, or an
|
|
11
|
+
/// array (optional or not) or set of models.
|
|
12
|
+
public protocol _RelationshipValue {
|
|
13
|
+
static var _relatedType: any PersistentModel.Type { get }
|
|
14
|
+
static var _isToMany: Bool { get }
|
|
15
|
+
var _relatedModels: [any PersistentModel] { get }
|
|
16
|
+
static func _make(_ models: [any PersistentModel]) -> Self
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
extension PersistentModel {
|
|
20
|
+
public static var _relatedType: any PersistentModel.Type { Self.self }
|
|
21
|
+
public static var _isToMany: Bool { false }
|
|
22
|
+
public var _relatedModels: [any PersistentModel] { [self] }
|
|
23
|
+
public static func _make(_ models: [any PersistentModel]) -> Self {
|
|
24
|
+
guard let model = models.first else {
|
|
25
|
+
fatalError("SwiftData: the non-optional relationship to \(Self.self) has no model")
|
|
26
|
+
}
|
|
27
|
+
return model as! Self
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
extension Optional: _RelationshipValue where Wrapped: _RelationshipValue {
|
|
32
|
+
public static var _relatedType: any PersistentModel.Type { Wrapped._relatedType }
|
|
33
|
+
public static var _isToMany: Bool { Wrapped._isToMany }
|
|
34
|
+
public var _relatedModels: [any PersistentModel] { self?._relatedModels ?? [] }
|
|
35
|
+
public static func _make(_ models: [any PersistentModel]) -> Self {
|
|
36
|
+
if !Wrapped._isToMany, models.isEmpty { return nil }
|
|
37
|
+
return Wrapped._make(models)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
extension Array: _RelationshipValue where Element: PersistentModel {
|
|
42
|
+
public static var _relatedType: any PersistentModel.Type { Element.self }
|
|
43
|
+
public static var _isToMany: Bool { true }
|
|
44
|
+
public var _relatedModels: [any PersistentModel] { map { $0 } }
|
|
45
|
+
public static func _make(_ models: [any PersistentModel]) -> Self { models.map { $0 as! Element } }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
extension Set: _RelationshipValue where Element: PersistentModel {
|
|
49
|
+
public static var _relatedType: any PersistentModel.Type { Element.self }
|
|
50
|
+
public static var _isToMany: Bool { true }
|
|
51
|
+
public var _relatedModels: [any PersistentModel] { map { $0 } }
|
|
52
|
+
public static func _make(_ models: [any PersistentModel]) -> Self { Set(models.map { $0 as! Element }) }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Optionals of attribute values: nil travels as JSON `null`.
|
|
56
|
+
protocol _AnyOptional {
|
|
57
|
+
static var _none: Any { get }
|
|
58
|
+
static func _unwrap(_ value: Any) -> Any?
|
|
59
|
+
static func _decodeWrapped(_ json: _JSON) throws -> Any
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
extension Optional: _AnyOptional {
|
|
63
|
+
static var _none: Any { Optional<Wrapped>.none as Any }
|
|
64
|
+
static func _unwrap(_ value: Any) -> Any? { (value as! Wrapped?).map { $0 as Any } }
|
|
65
|
+
static func _decodeWrapped(_ json: _JSON) throws -> Any {
|
|
66
|
+
let wrapped: Wrapped = try _decodeAttribute(json)
|
|
67
|
+
return Optional(wrapped) as Any
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
final class _Property {
|
|
72
|
+
enum Kind { case attribute, toOne, toMany }
|
|
73
|
+
|
|
74
|
+
let name: String
|
|
75
|
+
let keyPath: AnyKeyPath
|
|
76
|
+
let kind: Kind
|
|
77
|
+
/// The model type a relationship points at.
|
|
78
|
+
let relatedType: (any PersistentModel.Type)?
|
|
79
|
+
let attribute: Schema.Attribute?
|
|
80
|
+
let relationship: Schema.Relationship?
|
|
81
|
+
let isOptional: Bool
|
|
82
|
+
let hasDefault: Bool
|
|
83
|
+
|
|
84
|
+
/// The initial value (`= …` in the class), typed as the property.
|
|
85
|
+
let defaultValue: Any?
|
|
86
|
+
/// Encodes a value of the property (an attribute; relationships store ids).
|
|
87
|
+
let encode: (Any) -> _JSON
|
|
88
|
+
/// Decodes a stored attribute value.
|
|
89
|
+
let decode: (_JSON) throws -> Any
|
|
90
|
+
/// A relationship value from its models.
|
|
91
|
+
let make: ([any PersistentModel]) -> Any
|
|
92
|
+
/// The models a relationship value holds.
|
|
93
|
+
let models: (Any) -> [any PersistentModel]
|
|
94
|
+
/// Tells the property's observers on `model` that it changed.
|
|
95
|
+
let notify: (AnyObject) -> Void
|
|
96
|
+
|
|
97
|
+
init<Model: PersistentModel, Value>(name: String, keyPath: KeyPath<Model, Value>, defaultValue: Value?, metadata: Any?) {
|
|
98
|
+
self.name = name
|
|
99
|
+
self.keyPath = keyPath
|
|
100
|
+
attribute = metadata as? Schema.Attribute
|
|
101
|
+
relationship = metadata as? Schema.Relationship
|
|
102
|
+
isOptional = Value.self is any _AnyOptional.Type
|
|
103
|
+
hasDefault = defaultValue != nil
|
|
104
|
+
self.defaultValue = defaultValue.map { $0 as Any }
|
|
105
|
+
if let relation = Value.self as? any _RelationshipValue.Type {
|
|
106
|
+
kind = relation._isToMany ? .toMany : .toOne
|
|
107
|
+
relatedType = relation._relatedType
|
|
108
|
+
make = { models in relation._make(models) }
|
|
109
|
+
models = { value in (value as! any _RelationshipValue)._relatedModels }
|
|
110
|
+
} else {
|
|
111
|
+
kind = .attribute
|
|
112
|
+
relatedType = nil
|
|
113
|
+
make = { _ in fatalError("SwiftData: \(name) is not a relationship") }
|
|
114
|
+
models = { _ in [] }
|
|
115
|
+
}
|
|
116
|
+
encode = { value in _encodeAttribute(value as! Value) }
|
|
117
|
+
decode = { json in try _decodeAttribute(json) as Value }
|
|
118
|
+
notify = { object in
|
|
119
|
+
let model = object as! Model
|
|
120
|
+
model._$observationRegistrar.withMutation(of: model, keyPath: keyPath) {}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
var isRelationship: Bool { kind != .attribute }
|
|
125
|
+
var deleteRule: Schema.Relationship.DeleteRule { relationship?.deleteRule ?? .nullify }
|
|
126
|
+
var isUnique: Bool { attribute?.isUnique ?? false }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// MARK: - Attribute values
|
|
130
|
+
|
|
131
|
+
/// The JSON an attribute value is stored as: strings, numbers and booleans as
|
|
132
|
+
/// themselves, `Date` as seconds since 1970, nil as `null`, anything else
|
|
133
|
+
/// `Codable` as `JSONEncoder` writes it (dates inside it as seconds since 1970).
|
|
134
|
+
func _encodeAttribute<Value>(_ value: Value) -> _JSON {
|
|
135
|
+
if let optional = Value.self as? any _AnyOptional.Type {
|
|
136
|
+
guard let wrapped = optional._unwrap(value) else { return .null }
|
|
137
|
+
return _encodeAny(wrapped)
|
|
138
|
+
}
|
|
139
|
+
return _encodeAny(value)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func _encodeAny(_ value: Any) -> _JSON {
|
|
143
|
+
switch value {
|
|
144
|
+
case let v as String: return .string(v)
|
|
145
|
+
case let v as Bool: return .bool(v)
|
|
146
|
+
case let v as Int: return .number(Double(v))
|
|
147
|
+
case let v as Double: return .number(v)
|
|
148
|
+
case let v as Date: return .number(v.timeIntervalSince1970)
|
|
149
|
+
default: break
|
|
150
|
+
}
|
|
151
|
+
guard let encodable = value as? any Encodable else {
|
|
152
|
+
print("[SwiftData] cannot save a value of type \(type(of: value)); make it Codable")
|
|
153
|
+
return .null
|
|
154
|
+
}
|
|
155
|
+
do {
|
|
156
|
+
let data = try _jsonEncoder.encode(encodable)
|
|
157
|
+
return try _JSON.parse(String(decoding: data, as: UTF8.self))
|
|
158
|
+
} catch {
|
|
159
|
+
print("[SwiftData] cannot encode \(type(of: value)): \(error)")
|
|
160
|
+
return .null
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
func _decodeAttribute<Value>(_ json: _JSON) throws -> Value {
|
|
165
|
+
if let optional = Value.self as? any _AnyOptional.Type {
|
|
166
|
+
if json == .null { return optional._none as! Value }
|
|
167
|
+
return try optional._decodeWrapped(json) as! Value
|
|
168
|
+
}
|
|
169
|
+
switch json {
|
|
170
|
+
case .string(let s) where Value.self == String.self: return s as! Value
|
|
171
|
+
case .bool(let b) where Value.self == Bool.self: return b as! Value
|
|
172
|
+
case .number(let n) where Value.self == Int.self && n == n.rounded(): return Int(n) as! Value
|
|
173
|
+
case .number(let n) where Value.self == Double.self: return n as! Value
|
|
174
|
+
case .number(let n) where Value.self == Date.self: return Date(timeIntervalSince1970: n) as! Value
|
|
175
|
+
default: break
|
|
176
|
+
}
|
|
177
|
+
guard let decodable = Value.self as? any Decodable.Type else {
|
|
178
|
+
throw SwiftDataError(._decodeFailed, "\(Value.self) is not Decodable")
|
|
179
|
+
}
|
|
180
|
+
let decoded = try _jsonDecoder.decode(decodable, from: Data(json.serialized.utf8))
|
|
181
|
+
return decoded as! Value
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
nonisolated(unsafe) private let _jsonEncoder: JSONEncoder = {
|
|
185
|
+
let encoder = JSONEncoder()
|
|
186
|
+
encoder.dateEncodingStrategy = .secondsSince1970
|
|
187
|
+
encoder.outputFormatting = [.sortedKeys]
|
|
188
|
+
return encoder
|
|
189
|
+
}()
|
|
190
|
+
|
|
191
|
+
nonisolated(unsafe) private let _jsonDecoder: JSONDecoder = {
|
|
192
|
+
let decoder = JSONDecoder()
|
|
193
|
+
decoder.dateDecodingStrategy = .secondsSince1970
|
|
194
|
+
return decoder
|
|
195
|
+
}()
|
|
196
|
+
|
|
197
|
+
// MARK: - Entities
|
|
198
|
+
|
|
199
|
+
/// A model type's persisted properties, in declaration order.
|
|
200
|
+
final class _Entity {
|
|
201
|
+
let name: String
|
|
202
|
+
let type: any PersistentModel.Type
|
|
203
|
+
let properties: [Schema.PropertyMetadata]
|
|
204
|
+
private let byName: [String: _Property]
|
|
205
|
+
private let byKeyPath: [AnyKeyPath: _Property]
|
|
206
|
+
let relationships: [_Property]
|
|
207
|
+
let uniqueAttributes: [_Property]
|
|
208
|
+
private var inverses: [String: _Property?] = [:]
|
|
209
|
+
|
|
210
|
+
private init(type: any PersistentModel.Type) {
|
|
211
|
+
self.type = type
|
|
212
|
+
name = String(describing: type)
|
|
213
|
+
properties = type.schemaMetadata
|
|
214
|
+
byName = Dictionary(properties.map { ($0.name, $0.property) }, uniquingKeysWith: { first, _ in first })
|
|
215
|
+
byKeyPath = Dictionary(properties.map { ($0.keypath, $0.property) }, uniquingKeysWith: { first, _ in first })
|
|
216
|
+
relationships = properties.map(\.property).filter(\.isRelationship)
|
|
217
|
+
uniqueAttributes = properties.map(\.property).filter(\.isUnique)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
nonisolated(unsafe) private static var byType: [ObjectIdentifier: _Entity] = [:]
|
|
221
|
+
nonisolated(unsafe) private(set) static var byEntityName: [String: _Entity] = [:]
|
|
222
|
+
|
|
223
|
+
static func of(_ type: any PersistentModel.Type) -> _Entity {
|
|
224
|
+
let key = ObjectIdentifier(type)
|
|
225
|
+
if let known = byType[key] { return known }
|
|
226
|
+
let entity = _Entity(type: type)
|
|
227
|
+
byType[key] = entity
|
|
228
|
+
if byEntityName[entity.name] == nil { byEntityName[entity.name] = entity }
|
|
229
|
+
return entity
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
func property(_ name: String) -> _Property? { byName[name] }
|
|
233
|
+
func property(_ keyPath: AnyKeyPath) -> _Property? { byKeyPath[keyPath] }
|
|
234
|
+
|
|
235
|
+
/// The property on the related type that mirrors `property`: the one
|
|
236
|
+
/// `@Relationship(inverse:)` names (on either side), else the only
|
|
237
|
+
/// relationship of the related type that points back at this type.
|
|
238
|
+
func inverse(of property: _Property) -> _Property? {
|
|
239
|
+
if let known = inverses[property.name] { return known }
|
|
240
|
+
let found = findInverse(of: property)
|
|
241
|
+
inverses[property.name] = .some(found)
|
|
242
|
+
return found
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private func findInverse(of property: _Property) -> _Property? {
|
|
246
|
+
guard let relatedType = property.relatedType else { return nil }
|
|
247
|
+
let target = _Entity.of(relatedType)
|
|
248
|
+
if let keyPath = property.relationship?.inverseKeyPath {
|
|
249
|
+
return target.property(keyPath)
|
|
250
|
+
}
|
|
251
|
+
if let declared = target.relationships.first(where: { $0.relationship?.inverseKeyPath == property.keyPath }) {
|
|
252
|
+
return declared
|
|
253
|
+
}
|
|
254
|
+
let candidates = target.relationships.filter { candidate in
|
|
255
|
+
candidate !== property
|
|
256
|
+
&& candidate.relatedType.map { ObjectIdentifier($0) == ObjectIdentifier(type) } == true
|
|
257
|
+
&& candidate.relationship?.inverseKeyPath == nil
|
|
258
|
+
}
|
|
259
|
+
return candidates.count == 1 ? candidates[0] : nil
|
|
260
|
+
}
|
|
261
|
+
}
|