@swiftbrowser/native 0.17.8 → 0.18.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 (60) hide show
  1. package/README.md +20 -9
  2. package/dist/bridge.d.ts +27 -1
  3. package/dist/bridge.d.ts.map +1 -1
  4. package/dist/bridge.js.map +1 -1
  5. package/dist/hostRequests.d.ts +10 -4
  6. package/dist/hostRequests.d.ts.map +1 -1
  7. package/dist/hostRequests.js +65 -3
  8. package/dist/hostRequests.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/run.d.ts.map +1 -1
  14. package/dist/run.js +14 -1
  15. package/dist/run.js.map +1 -1
  16. package/dist/runtime.d.ts +1 -0
  17. package/dist/runtime.d.ts.map +1 -1
  18. package/dist/runtime.js +12 -1
  19. package/dist/runtime.js.map +1 -1
  20. package/dist/site.d.ts +3 -3
  21. package/dist/site.d.ts.map +1 -1
  22. package/dist/site.js +1 -1
  23. package/dist/site.js.map +1 -1
  24. package/dist/undo.d.ts +23 -0
  25. package/dist/undo.d.ts.map +1 -0
  26. package/dist/undo.js +44 -0
  27. package/dist/undo.js.map +1 -0
  28. package/package.json +3 -3
  29. package/src/bridge.ts +26 -1
  30. package/src/hostRequests.ts +72 -4
  31. package/src/index.ts +1 -0
  32. package/src/run.ts +11 -1
  33. package/src/runtime.ts +12 -1
  34. package/src/site.ts +3 -3
  35. package/src/undo.ts +47 -0
  36. package/swift/Sources/SwiftBrowserNative/Host/AudioRecorderBridge.swift +199 -0
  37. package/swift/Sources/SwiftBrowserNative/Host/FilesBridge.swift +154 -0
  38. package/swift/Sources/SwiftBrowserNative/Host/HostBridge.swift +45 -0
  39. package/swift/Sources/SwiftBrowserNative/Host/HostRequestBridge.swift +16 -2
  40. package/swift/Sources/SwiftBrowserNative/Host/TextMeasureBridge.swift +139 -0
  41. package/swift/Sources/SwiftBrowserNative/Host/UndoBridge.swift +170 -0
  42. package/swift/Sources/SwiftBrowserNative/Runtime/NativeApp.swift +30 -0
  43. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Controls.swift +347 -12
  44. package/swift/Sources/SwiftBrowserNative/Views/Kinds/DeleteBackward.swift +147 -0
  45. package/swift/Sources/SwiftBrowserNative/Views/Kinds/KeyboardBar.swift +84 -0
  46. package/swift/Sources/SwiftBrowserNative/Views/Kinds/More.swift +116 -11
  47. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Navigation.swift +12 -1
  48. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Shapes.swift +30 -9
  49. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Stacks.swift +163 -10
  50. package/swift/Sources/SwiftBrowserNative/Views/Kinds/TextAndImages.swift +17 -4
  51. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Video.swift +8 -3
  52. package/swift/Sources/SwiftBrowserNative/Views/NativeRootView.swift +8 -0
  53. package/swift/Sources/SwiftBrowserNative/Views/StyleModifier.swift +41 -0
  54. package/swift/Sources/SwiftBrowserProtocol/Op.swift +27 -4
  55. package/swift/Sources/SwiftBrowserProtocol/Props.swift +110 -3
  56. package/swift/Sources/SwiftBrowserProtocol/RendererEvent.swift +47 -0
  57. package/swift/Sources/SwiftBrowserProtocol/SVGPath.swift +260 -0
  58. package/swift/Sources/SwiftBrowserProtocol/Style.swift +58 -0
  59. package/swift/Sources/SwiftBrowserTree/OpTree.swift +22 -2
  60. package/wasm/SwiftBrowserNative.wasm +2 -2
@@ -48,6 +48,8 @@ public struct Style: Equatable, Sendable {
48
48
  public var hidden: Bool
49
49
  public var mask: ShapeStyleSpec?
50
50
  public var hitTesting: Bool?
51
+ /// `.contentShape(Rectangle())`: `rectangle`.
52
+ public var contentShape: String?
51
53
  public var blendMode: String?
52
54
  public var zIndex: Double?
53
55
  public var blur: Double?
@@ -73,6 +75,8 @@ public struct Style: Equatable, Sendable {
73
75
  public var scrollID: Bool
74
76
  /// `proxy.scrollTo(x)`: the request (its serial is new each time) on the element it names.
75
77
  public var scrollTo: ScrollToSpec?
78
+ /// `.scrollTransition`: the effects in its three phases.
79
+ public var scrollTransition: ScrollTransitionSpec?
76
80
 
77
81
  public init(json: JSONValue) {
78
82
  let fields = json.object ?? [:]
@@ -121,6 +125,7 @@ public struct Style: Equatable, Sendable {
121
125
  hidden = fields.bool("hidden") ?? false
122
126
  mask = ShapeStyleSpec(json: fields.value("mask"))
123
127
  hitTesting = fields.bool("hitTesting")
128
+ contentShape = fields.string("contentShape")
124
129
  blendMode = fields.string("blendMode")
125
130
  zIndex = fields.double("zIndex")
126
131
  blur = fields.double("blur")
@@ -146,6 +151,7 @@ public struct Style: Equatable, Sendable {
146
151
  containerRelativeFrame = ContainerRelativeFrameSpec(json: fields.value("containerRelativeFrame"))
147
152
  scrollID = fields.bool("scrollID") ?? false
148
153
  scrollTo = ScrollToSpec(json: fields.value("scrollTo"))
154
+ scrollTransition = ScrollTransitionSpec(json: fields.value("scrollTransition"))
149
155
  }
150
156
 
151
157
  public init() {
@@ -187,3 +193,55 @@ public struct ScrollToSpec: Equatable, Sendable {
187
193
  axes = fields.string("axes") ?? "both"
188
194
  }
189
195
  }
196
+
197
+ /// `.scrollTransition(_:axis:transition:)` as the app sends it: its closure's
198
+ /// effects in each phase, drawn by SwiftUI's own as the view scrolls.
199
+ public struct ScrollTransitionSpec: Equatable, Sendable {
200
+ /// `interactive`, `animated` or `identity`.
201
+ public var configuration: String
202
+ /// `horizontal` or `vertical`; the scroll view's own axis when nil.
203
+ public var axis: String?
204
+ public var identity: EffectSpec
205
+ public var topLeading: EffectSpec
206
+ public var bottomTrailing: EffectSpec
207
+ public init?(json: JSONValue) {
208
+ guard let fields = json.object else { return nil }
209
+ configuration = fields.string("configuration") ?? "interactive"
210
+ axis = fields.string("axis")
211
+ identity = EffectSpec(json: fields.value("identity"))
212
+ topLeading = EffectSpec(json: fields.value("topLeading"))
213
+ bottomTrailing = EffectSpec(json: fields.value("bottomTrailing"))
214
+ }
215
+ }
216
+
217
+ /// The visual effects of one scroll-transition phase (the `Style` fields of
218
+ /// the same names); absent fields are the identity's.
219
+ public struct EffectSpec: Equatable, Sendable {
220
+ public var offset: PointSpec?
221
+ public var scale: PointSpec?
222
+ public var scaleAnchor: UnitPointSpec?
223
+ public var rotation: Double?
224
+ public var rotationAnchor: UnitPointSpec?
225
+ public var opacity: Double?
226
+ public var blur: Double?
227
+ public var brightness: Double?
228
+ public var contrast: Double?
229
+ public var saturation: Double?
230
+ public var grayscale: Double?
231
+ public var hueRotation: Double?
232
+ public init(json: JSONValue) {
233
+ let fields = json.object ?? [:]
234
+ offset = PointSpec(json: fields.value("offset"))
235
+ scale = PointSpec(json: fields.value("scale"))
236
+ scaleAnchor = UnitPointSpec(json: fields.value("scaleAnchor"))
237
+ rotation = fields.double("rotation")
238
+ rotationAnchor = UnitPointSpec(json: fields.value("rotationAnchor"))
239
+ opacity = fields.double("opacity")
240
+ blur = fields.double("blur")
241
+ brightness = fields.double("brightness")
242
+ contrast = fields.double("contrast")
243
+ saturation = fields.double("saturation")
244
+ grayscale = fields.double("grayscale")
245
+ hueRotation = fields.double("hueRotation")
246
+ }
247
+ }
@@ -35,6 +35,13 @@ public final class OpTree {
35
35
 
36
36
  /// Runs the body of a pass, animated as the commit asks (`withAnimation` on a SwiftUI host).
37
37
  public var animate: (AnimationSpec?, () -> Void) -> Void = { _, body in body() }
38
+ /// Runs the body of a pass whose commit wants a completion: the host calls
39
+ /// the last closure once the pass has finished animating (SwiftUI's
40
+ /// `withAnimation(_:completionCriteria:_:completion:)`), from any task;
41
+ /// the tree then sends `animationcomplete` on the main actor, a turn
42
+ /// later. Without a host hook the tree runs `animate` and sends it right
43
+ /// after the pass.
44
+ public var animateWithCompletion: ((AnimationSpec?, CommitCompletionSpec, () -> Void, @escaping @Sendable () -> Void) -> Void)?
38
45
  /// Called after every committed pass.
39
46
  public var onCommit: ((AnimationSpec?) -> Void)?
40
47
  /// Where the renderer's events go (the app's `dispatch`).
@@ -65,17 +72,30 @@ public final class OpTree {
65
72
  /// id, an insert into a missing parent); the ops before it have applied.
66
73
  public func apply(_ ops: [Op]) throws {
67
74
  for op in ops {
68
- if case .commit(let animation) = op {
75
+ if case .commit(let animation, let completion) = op {
69
76
  let pass = pending
70
77
  pending.removeAll()
71
78
  var failure: Error?
72
- animate(animation) {
79
+ let body = {
73
80
  do {
74
81
  for each in pass { try self.applyOne(each) }
75
82
  } catch {
76
83
  failure = error
77
84
  }
78
85
  }
86
+ if let completion {
87
+ if let animateWithCompletion {
88
+ let serial = completion.serial
89
+ animateWithCompletion(animation, completion, body) { [weak self] in
90
+ Task { @MainActor in self?.send(.animationComplete(serial: serial)) }
91
+ }
92
+ } else {
93
+ animate(animation, body)
94
+ send(.animationComplete(serial: completion.serial))
95
+ }
96
+ } else {
97
+ animate(animation, body)
98
+ }
79
99
  if let failure { throw failure }
80
100
  commits += 1
81
101
  onCommit?(animation)
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/wasm/SwiftBrowserNative.wasm
3
- size: 49791914 bytes
4
- sha256: 32b3af1ab0d488c6d0d26f3f6e58f7c8886299aadb7f70dd25d2bf5a7e42c3f9
3
+ size: 49982707 bytes
4
+ sha256: 1f02220b4e3d7e74ce3afb42d5336ba9254bb1cd1cb591409c878548c4a6f6c4