@swiftbrowser/swift 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. package/Package.swift +200 -9
  2. package/README.md +7 -9
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +0 -4
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/{_FoundationCommon → FoundationBridge}/Bundle.swift +41 -4
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +24 -72
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Localization.swift +149 -0
  170. package/Sources/FoundationBridge/Locks.swift +50 -0
  171. package/Sources/FoundationBridge/Markdown.swift +527 -0
  172. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  173. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  174. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  175. package/Sources/FoundationBridge/Operation.swift +195 -0
  176. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  177. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  178. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  179. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  180. package/Sources/FoundationBridge/Selector.swift +226 -0
  181. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  182. package/Sources/FoundationBridge/Table.swift +211 -0
  183. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  184. package/Sources/FoundationBridge/Timer.swift +6 -1
  185. package/Sources/FoundationBridge/URLSession.swift +718 -0
  186. package/Sources/{_FoundationCommon → FoundationBridge}/UserDefaults.swift +17 -4
  187. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  188. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  189. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  190. package/Sources/ImageIO/GIF.swift +72 -0
  191. package/Sources/ImageIO/ImageIO.swift +248 -0
  192. package/Sources/ImageIO/ImageTypes.swift +28 -0
  193. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  194. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  195. package/Sources/MapKit/Geometry.swift +223 -0
  196. package/Sources/MapKit/Map.swift +638 -0
  197. package/Sources/MapKit/MapView.swift +229 -0
  198. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  199. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  200. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  201. package/Sources/OSLog/OSLog.swift +6 -0
  202. package/Sources/Photos/Photos.swift +572 -0
  203. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  204. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  205. package/Sources/QuickLook/QuickLook.swift +168 -0
  206. package/Sources/SafariServices/SafariServices.swift +106 -0
  207. package/Sources/Security/Security.swift +332 -0
  208. package/Sources/StoreKit/AppStore.swift +207 -0
  209. package/Sources/StoreKit/Products.swift +280 -0
  210. package/Sources/StoreKit/RequestReview.swift +28 -0
  211. package/Sources/StoreKit/StoreKit1.swift +486 -0
  212. package/Sources/StoreKit/StoreViews.swift +428 -0
  213. package/Sources/StoreKit/Transactions.swift +197 -0
  214. package/Sources/SwiftData/Macros.swift +58 -0
  215. package/Sources/SwiftData/ModelActor.swift +38 -0
  216. package/Sources/SwiftData/ModelContainer.swift +129 -0
  217. package/Sources/SwiftData/ModelContext.swift +451 -0
  218. package/Sources/SwiftData/PersistentModel.swift +238 -0
  219. package/Sources/SwiftData/Properties.swift +261 -0
  220. package/Sources/SwiftData/Query.swift +256 -0
  221. package/Sources/SwiftData/Schema.swift +192 -0
  222. package/Sources/SwiftData/Store.swift +146 -0
  223. package/Sources/SwiftData/StringPredicates.swift +125 -0
  224. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  225. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  226. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  227. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  228. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  229. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  230. package/Sources/SwiftUI/API/Accessibility.swift +55 -6
  231. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  232. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  233. package/Sources/SwiftUI/API/Alert.swift +1 -1
  234. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  235. package/Sources/SwiftUI/API/Animation.swift +37 -5
  236. package/Sources/SwiftUI/API/App.swift +31 -1
  237. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  238. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  239. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  240. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  241. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  242. package/Sources/SwiftUI/API/Color.swift +104 -28
  243. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  244. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  245. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  246. package/Sources/SwiftUI/API/Commands.swift +106 -0
  247. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  248. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  249. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  250. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  251. package/Sources/SwiftUI/API/Controls.swift +59 -27
  252. package/Sources/SwiftUI/API/CustomLayout.swift +49 -10
  253. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  254. package/Sources/SwiftUI/API/Decorations.swift +1 -1
  255. package/Sources/SwiftUI/API/EditMode.swift +25 -82
  256. package/Sources/SwiftUI/API/Effects.swift +105 -7
  257. package/Sources/SwiftUI/API/Entry.swift +8 -0
  258. package/Sources/SwiftUI/API/Environment.swift +93 -9
  259. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  260. package/Sources/SwiftUI/API/Focus.swift +11 -3
  261. package/Sources/SwiftUI/API/Gauge.swift +3 -2
  262. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  263. package/Sources/SwiftUI/API/GeometryReader.swift +13 -2
  264. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  265. package/Sources/SwiftUI/API/Gestures.swift +1 -1
  266. package/Sources/SwiftUI/API/Glass.swift +127 -0
  267. package/Sources/SwiftUI/API/Grid.swift +1 -1
  268. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  269. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  270. package/Sources/SwiftUI/API/LabelStyle.swift +13 -6
  271. package/Sources/SwiftUI/API/Layout.swift +67 -12
  272. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  273. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  274. package/Sources/SwiftUI/API/Lists.swift +61 -6
  275. package/Sources/SwiftUI/API/Menu.swift +8 -1
  276. package/Sources/SwiftUI/API/Modifiers.swift +80 -10
  277. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  278. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  279. package/Sources/SwiftUI/API/Navigation.swift +24 -9
  280. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  281. package/Sources/SwiftUI/API/ObservableObject.swift +16 -2
  282. package/Sources/SwiftUI/API/Path.swift +543 -0
  283. package/Sources/SwiftUI/API/Phase8Controls.swift +48 -31
  284. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  285. package/Sources/SwiftUI/API/Picker.swift +11 -2
  286. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  287. package/Sources/SwiftUI/API/Popover.swift +41 -0
  288. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  289. package/Sources/SwiftUI/API/Presentation.swift +17 -4
  290. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  291. package/Sources/SwiftUI/API/Primitives.swift +164 -37
  292. package/Sources/SwiftUI/API/Publishers.swift +4 -4
  293. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  294. package/Sources/SwiftUI/API/RowActions.swift +3 -2
  295. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  296. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  297. package/Sources/SwiftUI/API/ScrollTargets.swift +3 -3
  298. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  299. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  300. package/Sources/SwiftUI/API/Shape.swift +214 -0
  301. package/Sources/SwiftUI/API/ShapeStyle.swift +105 -7
  302. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  303. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  304. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  305. package/Sources/SwiftUI/API/State.swift +18 -1
  306. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  307. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  308. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  309. package/Sources/SwiftUI/API/Table.swift +382 -0
  310. package/Sources/SwiftUI/API/Tabs.swift +148 -4
  311. package/Sources/SwiftUI/API/Tasks.swift +2 -2
  312. package/Sources/SwiftUI/API/Text.swift +386 -0
  313. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  314. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  315. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  316. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  317. package/Sources/SwiftUI/API/Toolbar.swift +52 -16
  318. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  319. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  320. package/Sources/SwiftUI/API/Video.swift +64 -0
  321. package/Sources/SwiftUI/API/View.swift +10 -2
  322. package/Sources/SwiftUI/API/ViewModifier.swift +4 -1
  323. package/Sources/SwiftUI/API/VisualEffect.swift +74 -1
  324. package/Sources/SwiftUI/API/Windows.swift +25 -0
  325. package/Sources/SwiftUI/Charts/Axis.swift +7 -1
  326. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  327. package/Sources/SwiftUI/Charts/Chart.swift +17 -3
  328. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  329. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  330. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  331. package/Sources/SwiftUI/Runtime/Executor.swift +2 -0
  332. package/Sources/SwiftUI/Runtime/Exports.swift +37 -1
  333. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  334. package/Sources/SwiftUI/Runtime/JSON.swift +76 -4
  335. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  336. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  337. package/Sources/SwiftUI/Runtime/Ops.swift +58 -12
  338. package/Sources/SwiftUI/Runtime/Reconciler.swift +10 -1
  339. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  340. package/Sources/SwiftUI/Runtime/Runtime.swift +977 -198
  341. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  342. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  343. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  344. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  345. package/Sources/Symbols/Symbols.swift +25 -0
  346. package/Sources/Translation/Translation.swift +423 -0
  347. package/Sources/UIKit/Activity.swift +213 -0
  348. package/Sources/UIKit/Alerts.swift +69 -0
  349. package/Sources/UIKit/AppDelegate.swift +222 -0
  350. package/Sources/UIKit/Appearance.swift +84 -0
  351. package/Sources/UIKit/ColorConversions.swift +70 -0
  352. package/Sources/UIKit/Controls.swift +225 -0
  353. package/Sources/UIKit/Device.swift +200 -0
  354. package/Sources/UIKit/Feedback.swift +65 -0
  355. package/Sources/UIKit/Font.swift +307 -0
  356. package/Sources/UIKit/Graphics.swift +204 -0
  357. package/Sources/UIKit/HostingController.swift +185 -0
  358. package/Sources/UIKit/Identity.swift +24 -0
  359. package/Sources/UIKit/Introspectable.swift +510 -0
  360. package/Sources/UIKit/Pasteboard.swift +363 -0
  361. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  362. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  363. package/Sources/UIKit/Representable.swift +288 -0
  364. package/Sources/UIKit/SafeArea.swift +12 -0
  365. package/Sources/UIKit/SceneDelegates.swift +132 -0
  366. package/Sources/UIKit/Scenes.swift +40 -0
  367. package/Sources/UIKit/ScrollView.swift +157 -0
  368. package/Sources/UIKit/ShortcutItems.swift +67 -0
  369. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  370. package/Sources/UIKit/TargetAction.swift +123 -0
  371. package/Sources/UIKit/TextPaste.swift +161 -0
  372. package/Sources/UIKit/TextView.swift +538 -0
  373. package/Sources/UIKit/UIKit.swift +292 -0
  374. package/Sources/UIKit/UIView.swift +855 -0
  375. package/Sources/UIKit/ViewTranslation.swift +311 -0
  376. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  377. package/Sources/UserNotifications/Content.swift +370 -0
  378. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  379. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  380. package/Sources/WebKit/WebKit.swift +245 -0
  381. package/Sources/os/os.swift +376 -0
  382. package/Sources/zlib/zlib.swift +6 -0
  383. package/index.d.ts +1 -1
  384. package/index.mjs +2 -2
  385. package/manifest.d.mts +2 -0
  386. package/manifest.mjs +39 -0
  387. package/package.json +5 -3
  388. package/sync-sources.mjs +21 -7
  389. package/Sources/FoundationLite/Common.swift +0 -3
  390. package/Sources/FoundationLite/FoundationLite.swift +0 -171
  391. package/Sources/FoundationLite/Interaction.swift +0 -146
  392. package/Sources/FoundationLite/Timer.swift +0 -48
  393. package/Sources/_FoundationCommon/_FoundationCommon.swift +0 -10
@@ -0,0 +1,256 @@
1
+ // SwiftData in views: `@Query`, the `modelContext` environment value and the
2
+ // `.modelContainer` / `.modelContext` modifiers for views and scenes.
3
+
4
+ import Foundation
5
+ import Observation
6
+ import SwiftUI
7
+
8
+ /// What to fetch: a predicate, a sort order and a window of the results.
9
+ public struct FetchDescriptor<T: PersistentModel> {
10
+ public var predicate: Predicate<T>?
11
+ public var sortBy: [SortDescriptor<T>]
12
+ public var fetchLimit: Int?
13
+ public var fetchOffset: Int?
14
+ public var includePendingChanges = true
15
+ public var propertiesToFetch: [PartialKeyPath<T>] = []
16
+ public var relationshipKeyPathsForPrefetching: [PartialKeyPath<T>] = []
17
+
18
+ public init(predicate: Predicate<T>? = nil, sortBy: [SortDescriptor<T>] = []) {
19
+ self.predicate = predicate
20
+ self.sortBy = sortBy
21
+ }
22
+ }
23
+
24
+ // MARK: - Environment
25
+
26
+ private enum _ModelContextKey: EnvironmentKey {
27
+ static var defaultValue: ModelContext { _ModelContextFallback.context }
28
+ }
29
+
30
+ /// What `modelContext` is outside any `.modelContainer`: an empty in-memory
31
+ /// container's context, as in SwiftUI.
32
+ @MainActor
33
+ enum _ModelContextFallback {
34
+ nonisolated(unsafe) private static var shared: ModelContext?
35
+
36
+ nonisolated static var context: ModelContext {
37
+ if let shared { return shared }
38
+ let container = try! ModelContainer(for: Schema([]), configurations: [ModelConfiguration(isStoredInMemoryOnly: true)])
39
+ let context = ModelContext(container)
40
+ shared = context
41
+ return context
42
+ }
43
+ }
44
+
45
+ extension EnvironmentValues {
46
+ /// The context `@Query` fetches from and views insert into.
47
+ public var modelContext: ModelContext {
48
+ get { self[_ModelContextKey.self] }
49
+ set { self[_ModelContextKey.self] = newValue }
50
+ }
51
+ }
52
+
53
+ // MARK: - @Query
54
+
55
+ /// The models a fetch returns, kept current: the view re-runs when its
56
+ /// context changes (an insert, a delete, a property set, a save).
57
+ ///
58
+ /// `Result` is always `[Element]`; tying the two lets `@Query var books: [Book]`
59
+ /// declare the wrapper with no initial value and assign it in `init`.
60
+ @propertyWrapper
61
+ public struct Query<Element: PersistentModel, Result>: DynamicProperty where Result: Sequence, Result.Element == Element {
62
+ let descriptor: FetchDescriptor<Element>
63
+ let animation: Animation?
64
+ let box = _QueryBox<Element>()
65
+
66
+ init(descriptor: FetchDescriptor<Element>, animation: Animation?) {
67
+ self.descriptor = descriptor
68
+ self.animation = animation
69
+ }
70
+
71
+ /// Every model of the type, unsorted. Declared here, without a
72
+ /// constraint, so that `@Query var items: [Item]` gives a view's
73
+ /// memberwise initializer a default for `items`, as Apple's does.
74
+ public init() {
75
+ self.init(descriptor: FetchDescriptor(), animation: nil)
76
+ }
77
+
78
+ public var wrappedValue: Result { box.results(for: descriptor) as! Result }
79
+
80
+ /// The error of the last fetch, if it failed.
81
+ public var fetchError: (any Error)? { box.error }
82
+
83
+ /// The context the query fetches from.
84
+ public var modelContext: ModelContext { box.context ?? _ModelContextFallback.context }
85
+ }
86
+
87
+ extension Query: _EnvironmentReading {
88
+ public func _resolve(in environment: EnvironmentValues) {
89
+ box.context = environment.modelContext
90
+ }
91
+ }
92
+
93
+ extension Query where Result == [Element] {
94
+
95
+ public init(_ descriptor: FetchDescriptor<Element>, animation: Animation = .default) {
96
+ self.init(descriptor: descriptor, animation: animation)
97
+ }
98
+
99
+ public init(_ descriptor: FetchDescriptor<Element>, transaction: Transaction?) {
100
+ self.init(descriptor: descriptor, animation: nil)
101
+ }
102
+
103
+ public init(filter: Predicate<Element>? = nil, sort: [SortDescriptor<Element>] = [], animation: Animation = .default) {
104
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: sort), animation: animation)
105
+ }
106
+
107
+ public init(filter: Predicate<Element>? = nil, sort: [SortDescriptor<Element>] = [], transaction: Transaction?) {
108
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: sort), animation: nil)
109
+ }
110
+
111
+ public init(filter: Predicate<Element>? = nil, sort: SortDescriptor<Element>, animation: Animation = .default) {
112
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: [sort]), animation: animation)
113
+ }
114
+
115
+ public init<Value: Comparable>(filter: Predicate<Element>? = nil, sort keyPath: any KeyPath<Element, Value> & Sendable, order: SortOrder = .forward, animation: Animation = .default) {
116
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: [SortDescriptor(keyPath, order: order)]), animation: animation)
117
+ }
118
+
119
+ public init<Value: Comparable>(filter: Predicate<Element>? = nil, sort keyPath: any KeyPath<Element, Value?> & Sendable, order: SortOrder = .forward, animation: Animation = .default) {
120
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: [SortDescriptor(keyPath, order: order)]), animation: animation)
121
+ }
122
+
123
+ public init<Value: Comparable>(filter: Predicate<Element>? = nil, sort keyPath: any KeyPath<Element, Value> & Sendable, order: SortOrder = .forward, transaction: Transaction?) {
124
+ self.init(descriptor: FetchDescriptor(predicate: filter, sortBy: [SortDescriptor(keyPath, order: order)]), animation: nil)
125
+ }
126
+ }
127
+
128
+ /// A query's context and its last results, which stay valid until the
129
+ /// context changes.
130
+ public final class _QueryBox<Element: PersistentModel> {
131
+ var context: ModelContext?
132
+ var error: (any Error)?
133
+ private var cached: [Element]?
134
+ private weak var cachedContext: ModelContext?
135
+ private var cachedGeneration = -1
136
+
137
+ func results(for descriptor: FetchDescriptor<Element>) -> [Element] {
138
+ let context = context ?? _ModelContextFallback.context
139
+ // Reading the generation makes the view's body depend on the context.
140
+ let generation = context.signal.generation
141
+ if let cached, cachedContext === context, cachedGeneration == generation { return cached }
142
+ let results: [Element]
143
+ do {
144
+ results = try context.fetch(descriptor)
145
+ error = nil
146
+ } catch {
147
+ self.error = error
148
+ results = []
149
+ }
150
+ cached = results
151
+ cachedContext = context
152
+ cachedGeneration = generation
153
+ return results
154
+ }
155
+ }
156
+
157
+ // MARK: - Modifiers
158
+
159
+ /// Puts a container's main context into the environment.
160
+ struct _ModelContainerModifier: ViewModifier {
161
+ let context: ModelContext
162
+
163
+ func body(content: Content) -> some View {
164
+ content.environment(\.modelContext, context)
165
+ }
166
+ }
167
+
168
+ /// The containers `.modelContainer(for:)` made, so that a body that runs
169
+ /// again gets the same container.
170
+ @MainActor
171
+ enum _ModifierContainers {
172
+ private static var made: [String: ModelContainer] = [:]
173
+
174
+ static func container(for types: [any PersistentModel.Type], inMemory: Bool, autosave: Bool,
175
+ onSetup: (Result<ModelContainer, any Error>) -> Void) -> ModelContainer {
176
+ let key = types.map { String(reflecting: $0) }.sorted().joined(separator: ",") + (inMemory ? "|memory" : "")
177
+ if let container = made[key] { return container }
178
+ let container: ModelContainer
179
+ do {
180
+ container = try ModelContainer(for: Schema(types), configurations: [ModelConfiguration(isStoredInMemoryOnly: inMemory)])
181
+ onSetup(.success(container))
182
+ } catch {
183
+ onSetup(.failure(error))
184
+ container = try! ModelContainer(for: Schema(types), configurations: [ModelConfiguration(isStoredInMemoryOnly: true)])
185
+ }
186
+ container.mainContext.autosaveEnabled = autosave
187
+ made[key] = container
188
+ return container
189
+ }
190
+ }
191
+
192
+ extension View {
193
+ /// Supplies the container's main context to the views below.
194
+ public func modelContainer(_ container: ModelContainer) -> some View {
195
+ modifier(_ModelContainerModifier(context: container.mainContext))
196
+ }
197
+
198
+ /// Supplies a container for these model types (made once) to the views below.
199
+ public func modelContainer(
200
+ for modelType: any PersistentModel.Type,
201
+ inMemory: Bool = false,
202
+ isAutosaveEnabled: Bool = true,
203
+ isUndoEnabled: Bool = false,
204
+ onSetup: @escaping (Result<ModelContainer, any Error>) -> Void = { _ in }
205
+ ) -> some View {
206
+ modelContainer(_ModifierContainers.container(for: [modelType], inMemory: inMemory, autosave: isAutosaveEnabled, onSetup: onSetup))
207
+ }
208
+
209
+ public func modelContainer(
210
+ for modelTypes: [any PersistentModel.Type],
211
+ inMemory: Bool = false,
212
+ isAutosaveEnabled: Bool = true,
213
+ isUndoEnabled: Bool = false,
214
+ onSetup: @escaping (Result<ModelContainer, any Error>) -> Void = { _ in }
215
+ ) -> some View {
216
+ modelContainer(_ModifierContainers.container(for: modelTypes, inMemory: inMemory, autosave: isAutosaveEnabled, onSetup: onSetup))
217
+ }
218
+
219
+ /// Supplies a context to the views below.
220
+ public func modelContext(_ modelContext: ModelContext) -> some View {
221
+ modifier(_ModelContainerModifier(context: modelContext))
222
+ }
223
+ }
224
+
225
+ extension Scene {
226
+ /// Supplies the container's main context to the scene's views.
227
+ public func modelContainer(_ container: ModelContainer) -> some Scene {
228
+ _modifyingRootView(_ModelContainerModifier(context: container.mainContext))
229
+ }
230
+
231
+ /// Supplies a container for these model types to the scene's views.
232
+ public func modelContainer(
233
+ for modelType: any PersistentModel.Type,
234
+ inMemory: Bool = false,
235
+ isAutosaveEnabled: Bool = true,
236
+ isUndoEnabled: Bool = false,
237
+ onSetup: @escaping (Result<ModelContainer, any Error>) -> Void = { _ in }
238
+ ) -> some Scene {
239
+ modelContainer(_ModifierContainers.container(for: [modelType], inMemory: inMemory, autosave: isAutosaveEnabled, onSetup: onSetup))
240
+ }
241
+
242
+ public func modelContainer(
243
+ for modelTypes: [any PersistentModel.Type],
244
+ inMemory: Bool = false,
245
+ isAutosaveEnabled: Bool = true,
246
+ isUndoEnabled: Bool = false,
247
+ onSetup: @escaping (Result<ModelContainer, any Error>) -> Void = { _ in }
248
+ ) -> some Scene {
249
+ modelContainer(_ModifierContainers.container(for: modelTypes, inMemory: inMemory, autosave: isAutosaveEnabled, onSetup: onSetup))
250
+ }
251
+
252
+ /// Supplies a context to the scene's views.
253
+ public func modelContext(_ modelContext: ModelContext) -> some Scene {
254
+ _modifyingRootView(_ModelContainerModifier(context: modelContext))
255
+ }
256
+ }
@@ -0,0 +1,192 @@
1
+ // The schema of a container: the model types, their persisted properties and
2
+ // the options `@Attribute` and `@Relationship` gave them. `@Model` generates
3
+ // each type's `schemaMetadata`; the store reads it to encode, decode and
4
+ // relate records.
5
+
6
+ import Foundation
7
+
8
+ public final class Schema: Hashable, @unchecked Sendable {
9
+ public struct Version: Hashable, Comparable, Codable, Sendable, CustomStringConvertible {
10
+ public let major: Int
11
+ public let minor: Int
12
+ public let patch: Int
13
+
14
+ public init(_ major: Int, _ minor: Int, _ patch: Int) {
15
+ self.major = major
16
+ self.minor = minor
17
+ self.patch = patch
18
+ }
19
+
20
+ public static func < (lhs: Version, rhs: Version) -> Bool {
21
+ (lhs.major, lhs.minor, lhs.patch) < (rhs.major, rhs.minor, rhs.patch)
22
+ }
23
+
24
+ public var description: String { "\(major).\(minor).\(patch)" }
25
+ }
26
+
27
+ /// One model type of the schema.
28
+ public struct Entity: Hashable, @unchecked Sendable {
29
+ public let name: String
30
+ let type: any PersistentModel.Type
31
+
32
+ public var properties: [PropertyMetadata] { _Entity.of(type).properties }
33
+
34
+ public static func == (lhs: Entity, rhs: Entity) -> Bool { lhs.name == rhs.name }
35
+ public func hash(into hasher: inout Hasher) { hasher.combine(name) }
36
+ }
37
+
38
+ /// A persisted property of a model, as `@Model` describes it.
39
+ public struct PropertyMetadata: @unchecked Sendable {
40
+ public let name: String
41
+ public let keypath: AnyKeyPath
42
+ public let defaultValue: Any?
43
+ /// The `Schema.Attribute` or `Schema.Relationship` the property was
44
+ /// declared with, if any.
45
+ public let metadata: Any?
46
+ let property: _Property
47
+
48
+ public init<Model: PersistentModel, Value>(name: String, keyPath: KeyPath<Model, Value>, defaultValue: Value? = nil, metadata: Any? = nil) {
49
+ self.name = name
50
+ keypath = keyPath
51
+ self.defaultValue = defaultValue
52
+ self.metadata = metadata
53
+ property = _Property(name: name, keyPath: keyPath, defaultValue: defaultValue, metadata: metadata)
54
+ }
55
+ }
56
+
57
+ /// Options of a persisted attribute.
58
+ public struct Attribute: @unchecked Sendable {
59
+ public struct Option: Hashable, Sendable {
60
+ let name: String
61
+ /// Records may not share a value: inserting a model whose value
62
+ /// another record has updates that record instead (an upsert).
63
+ public static let unique = Option(name: "unique")
64
+ public static let externalStorage = Option(name: "externalStorage")
65
+ public static let allowsCloudEncryption = Option(name: "allowsCloudEncryption")
66
+ public static let preserveValueOnDeletion = Option(name: "preserveValueOnDeletion")
67
+ public static let ephemeral = Option(name: "ephemeral")
68
+ public static let spotlight = Option(name: "spotlight")
69
+ public static func transformable(by transformerName: String) -> Option { Option(name: "transformable") }
70
+ public static func transformable(by transformerType: Any.Type) -> Option { Option(name: "transformable") }
71
+ }
72
+
73
+ public let options: [Option]
74
+ public let originalName: String?
75
+ public let hashModifier: String?
76
+
77
+ public init(_ options: Option..., originalName: String? = nil, hashModifier: String? = nil) {
78
+ self.options = options
79
+ self.originalName = originalName
80
+ self.hashModifier = hashModifier
81
+ }
82
+
83
+ public var isUnique: Bool { options.contains(.unique) }
84
+ }
85
+
86
+ /// Options of a relationship between models.
87
+ public struct Relationship: @unchecked Sendable {
88
+ public enum DeleteRule: Hashable, Codable, Sendable {
89
+ /// Deleting the model deletes the related models.
90
+ case cascade
91
+ /// A model with related models cannot be deleted (its save fails).
92
+ case deny
93
+ /// Nothing happens to the related models.
94
+ case noAction
95
+ /// The related models stop referring to the deleted one.
96
+ case nullify
97
+ }
98
+
99
+ public struct Option: Hashable, Sendable {
100
+ let name: String
101
+ public static let unique = Option(name: "unique")
102
+ }
103
+
104
+ public let options: [Option]
105
+ public let deleteRule: DeleteRule
106
+ public let minimumModelCount: Int?
107
+ public let maximumModelCount: Int?
108
+ public let originalName: String?
109
+ public let inverseKeyPath: AnyKeyPath?
110
+ public let hashModifier: String?
111
+
112
+ public init(
113
+ _ options: Option...,
114
+ deleteRule: DeleteRule = .nullify,
115
+ minimumModelCount: Int? = 0,
116
+ maximumModelCount: Int? = 0,
117
+ originalName: String? = nil,
118
+ inverse: AnyKeyPath? = nil,
119
+ hashModifier: String? = nil
120
+ ) {
121
+ self.options = options
122
+ self.deleteRule = deleteRule
123
+ self.minimumModelCount = minimumModelCount
124
+ self.maximumModelCount = maximumModelCount
125
+ self.originalName = originalName
126
+ inverseKeyPath = inverse
127
+ self.hashModifier = hashModifier
128
+ }
129
+ }
130
+
131
+ public let entities: [Entity]
132
+ public let version: Version
133
+
134
+ public init(_ types: [any PersistentModel.Type], version: Version = Version(1, 0, 0)) {
135
+ var seen = Set<ObjectIdentifier>()
136
+ var entities: [Entity] = []
137
+ // The listed types and every type they relate to, as SwiftData infers them.
138
+ var queue = types
139
+ while !queue.isEmpty {
140
+ let type = queue.removeFirst()
141
+ guard seen.insert(ObjectIdentifier(type)).inserted else { continue }
142
+ let entity = _Entity.of(type)
143
+ entities.append(Entity(name: entity.name, type: type))
144
+ queue += entity.properties.compactMap { $0.property.relatedType }
145
+ }
146
+ self.entities = entities
147
+ self.version = version
148
+ }
149
+
150
+ public convenience init(_ types: any PersistentModel.Type..., version: Version = Version(1, 0, 0)) {
151
+ self.init(types, version: version)
152
+ }
153
+
154
+ public convenience init(versionedSchema: any VersionedSchema.Type) {
155
+ self.init(versionedSchema.models, version: versionedSchema.versionIdentifier)
156
+ }
157
+
158
+ public static func == (lhs: Schema, rhs: Schema) -> Bool { lhs.entities == rhs.entities && lhs.version == rhs.version }
159
+ public func hash(into hasher: inout Hasher) {
160
+ hasher.combine(entities)
161
+ hasher.combine(version)
162
+ }
163
+
164
+ public var entitiesByName: [String: Entity] {
165
+ Dictionary(entities.map { ($0.name, $0) }, uniquingKeysWith: { first, _ in first })
166
+ }
167
+ }
168
+
169
+ /// A version of an app's schema, for migration plans.
170
+ public protocol VersionedSchema {
171
+ static var versionIdentifier: Schema.Version { get }
172
+ static var models: [any PersistentModel.Type] { get }
173
+ }
174
+
175
+ /// How to migrate between versioned schemas. Records are decoded on demand
176
+ /// (a property missing from a record takes its initial value), which covers
177
+ /// what a lightweight migration does; custom stages' closures run against the
178
+ /// container's main context.
179
+ public protocol SchemaMigrationPlan {
180
+ static var schemas: [any VersionedSchema.Type] { get }
181
+ static var stages: [MigrationStage] { get }
182
+ }
183
+
184
+ public enum MigrationStage: @unchecked Sendable {
185
+ case lightweight(fromVersion: any VersionedSchema.Type, toVersion: any VersionedSchema.Type)
186
+ case custom(
187
+ fromVersion: any VersionedSchema.Type,
188
+ toVersion: any VersionedSchema.Type,
189
+ willMigrate: ((ModelContext) throws -> Void)?,
190
+ didMigrate: ((ModelContext) throws -> Void)?
191
+ )
192
+ }
@@ -0,0 +1,146 @@
1
+ // A store: the saved records of one `ModelConfiguration`, kept in memory for
2
+ // the run. The page reads the app's IndexedDB database before it starts the
3
+ // module and hands every store in through `SB_SWIFTDATA`; each save sends
4
+ // what changed back as a `swiftdata` op, which the page writes to IndexedDB
5
+ // (docs/ops-protocol.md, "Phase 18"). Fetches are evaluated here, against
6
+ // the records and the contexts' unsaved changes, so they stay synchronous as
7
+ // SwiftData's are.
8
+
9
+ import Foundation
10
+ import SwiftUI
11
+
12
+ /// A saved model: its entity name and its properties' JSON.
13
+ struct _Record: Equatable {
14
+ var entity: String
15
+ var values: [String: _JSON]
16
+ }
17
+
18
+ final class _Store {
19
+ /// The store's name: the configuration URL's last path component
20
+ /// (`default.store`).
21
+ let identifier: String
22
+ /// Whether saves reach the host; in-memory stores keep nothing.
23
+ let persistent: Bool
24
+ private(set) var records: [Int64: _Record] = [:]
25
+ /// Record keys per entity, in insertion order.
26
+ private var keysByEntity: [String: [Int64]] = [:]
27
+ private var contexts: [_WeakContext] = []
28
+
29
+ private init(identifier: String, persistent: Bool, records: [Int64: _Record]) {
30
+ self.identifier = identifier
31
+ self.persistent = persistent
32
+ self.records = records
33
+ for key in records.keys.sorted() { keysByEntity[records[key]!.entity, default: []].append(key) }
34
+ }
35
+
36
+ // MARK: Opening
37
+
38
+ nonisolated(unsafe) private static var opened: [String: _Store] = [:]
39
+
40
+ /// The persistent store with this name (shared by every container that
41
+ /// opens it), or a new in-memory store.
42
+ static func open(identifier: String, inMemory: Bool) -> _Store {
43
+ if inMemory { return _Store(identifier: identifier, persistent: false, records: [:]) }
44
+ if let store = opened[identifier] { return store }
45
+ let store = _Store(identifier: identifier, persistent: true, records: launchRecords[identifier] ?? [:])
46
+ opened[identifier] = store
47
+ return store
48
+ }
49
+
50
+ /// The stores the host handed in (`SB_SWIFTDATA`):
51
+ /// `{"<store>": [{"id": 1, "entity": "Book", "values": {…}}, …]}`.
52
+ nonisolated(unsafe) private static var launchRecords: [String: [Int64: _Record]] = {
53
+ guard let text = _environment("SB_SWIFTDATA"), !text.isEmpty else { return [:] }
54
+ guard let json = try? _JSON.parse(text), case .object(let stores) = json else {
55
+ print("[SwiftData] ignoring malformed SB_SWIFTDATA")
56
+ return [:]
57
+ }
58
+ var result: [String: [Int64: _Record]] = [:]
59
+ for (name, items) in stores {
60
+ guard case .array(let items) = items else { continue }
61
+ var records: [Int64: _Record] = [:]
62
+ for item in items {
63
+ guard case .object(let fields) = item, case .number(let id)? = fields["id"],
64
+ case .string(let entity)? = fields["entity"] else { continue }
65
+ var values: [String: _JSON] = [:]
66
+ if case .object(let stored)? = fields["values"] { values = stored }
67
+ records[Int64(id)] = _Record(entity: entity, values: values)
68
+ }
69
+ result[name] = records
70
+ }
71
+ return result
72
+ }()
73
+
74
+ // MARK: Keys
75
+
76
+ /// Model keys are unique across every store of the app, increasing, and
77
+ /// continue after the largest key the host handed in.
78
+ nonisolated(unsafe) private static var nextPrimaryKey: Int64 = {
79
+ let largest = launchRecords.values.flatMap(\.keys).max() ?? 0
80
+ return largest + 1
81
+ }()
82
+
83
+ static func allocatePrimaryKey() -> Int64 {
84
+ defer { nextPrimaryKey += 1 }
85
+ return nextPrimaryKey
86
+ }
87
+
88
+ /// Clears every opened store's in-memory state (tests).
89
+ static func _resetForTesting(launch: [String: [Int64: _Record]] = [:]) {
90
+ opened = [:]
91
+ launchRecords = launch
92
+ nextPrimaryKey = (launch.values.flatMap(\.keys).max() ?? 0) + 1
93
+ }
94
+
95
+ // MARK: Reading
96
+
97
+ func keys(of entity: String) -> [Int64] { keysByEntity[entity] ?? [] }
98
+
99
+ func record(_ key: Int64) -> _Record? { records[key] }
100
+
101
+ // MARK: Contexts
102
+
103
+ func register(_ context: ModelContext) {
104
+ contexts.removeAll { $0.context == nil }
105
+ contexts.append(_WeakContext(context: context))
106
+ }
107
+
108
+ // MARK: Writing
109
+
110
+ /// Applies one save: `put` records (new or changed) and `delete` keys,
111
+ /// tells the host, and lets the store's other contexts catch up.
112
+ func commit(put: [(Int64, _Record)], delete: [Int64], clear: Bool = false, from origin: ModelContext?) {
113
+ if clear {
114
+ records.removeAll()
115
+ keysByEntity.removeAll()
116
+ }
117
+ for key in delete {
118
+ guard let removed = records.removeValue(forKey: key) else { continue }
119
+ keysByEntity[removed.entity]?.removeAll { $0 == key }
120
+ }
121
+ for (key, record) in put {
122
+ if records[key] == nil { keysByEntity[record.entity, default: []].append(key) }
123
+ records[key] = record
124
+ }
125
+ if persistent {
126
+ var change: [String: _JSON] = ["store": .string(identifier)]
127
+ if clear { change["clear"] = .bool(true) }
128
+ change["put"] = .array(put.map { key, record in
129
+ .object(["id": .number(Double(key)), "entity": .string(record.entity), "values": .object(record.values)])
130
+ })
131
+ change["delete"] = .array(delete.map { .number(Double($0)) })
132
+ let json = _JSON.object(change)
133
+ MainActor.assumeIsolated { _Runtime.shared.storeSwiftData(json) }
134
+ }
135
+ let changed = Set(put.map(\.0))
136
+ let deleted = Set(delete)
137
+ for weak in contexts {
138
+ guard let context = weak.context, context !== origin else { continue }
139
+ context._storeDidChange(changed: changed, deleted: deleted, cleared: clear)
140
+ }
141
+ }
142
+ }
143
+
144
+ struct _WeakContext {
145
+ weak var context: ModelContext?
146
+ }