@swiftbrowser/native 0.19.0 → 0.21.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 (64) hide show
  1. package/README.md +34 -11
  2. package/dist/blob.d.ts +85 -11
  3. package/dist/blob.d.ts.map +1 -1
  4. package/dist/blob.js +184 -34
  5. package/dist/blob.js.map +1 -1
  6. package/dist/bridge.d.ts +33 -2
  7. package/dist/bridge.d.ts.map +1 -1
  8. package/dist/bridge.js.map +1 -1
  9. package/dist/fetch.d.ts +19 -11
  10. package/dist/fetch.d.ts.map +1 -1
  11. package/dist/fetch.js +105 -41
  12. package/dist/fetch.js.map +1 -1
  13. package/dist/hostRequests.d.ts +3 -1
  14. package/dist/hostRequests.d.ts.map +1 -1
  15. package/dist/hostRequests.js +47 -6
  16. package/dist/hostRequests.js.map +1 -1
  17. package/dist/index.d.ts +1 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/runtime.js +1 -1
  22. package/dist/runtime.js.map +1 -1
  23. package/dist/webSocket.d.ts.map +1 -1
  24. package/dist/webSocket.js +13 -1
  25. package/dist/webSocket.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/blob.ts +215 -34
  28. package/src/bridge.ts +27 -2
  29. package/src/fetch.ts +99 -41
  30. package/src/hostRequests.ts +62 -8
  31. package/src/index.ts +1 -2
  32. package/src/runtime.ts +1 -1
  33. package/src/webSocket.ts +10 -1
  34. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSP/ProgramNode.swift +122 -19
  35. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSP/ScopeView.swift +79 -0
  36. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSPCore/Machine.swift +1247 -209
  37. package/swift/Packages/SwiftBrowserDSP/Sources/SwiftBrowserDSPCore/Program.swift +314 -19
  38. package/swift/Packages/SwiftBrowserShader/Package.swift +31 -0
  39. package/swift/Packages/SwiftBrowserShader/README.md +45 -0
  40. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShader/ShaderRenderer.swift +103 -0
  41. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShader/ShaderView.swift +168 -0
  42. package/swift/Packages/SwiftBrowserShader/Sources/SwiftBrowserShaderCore/ShaderProps.swift +120 -0
  43. package/swift/Sources/SwiftBrowserNative/Host/BodyStream.swift +166 -0
  44. package/swift/Sources/SwiftBrowserNative/Host/FilesBridge.swift +141 -7
  45. package/swift/Sources/SwiftBrowserNative/Host/HostBridge.swift +47 -1
  46. package/swift/Sources/SwiftBrowserNative/Host/HostRequestBridge.swift +98 -29
  47. package/swift/Sources/SwiftBrowserNative/Runtime/NativeFunctions.swift +1 -1
  48. package/swift/Sources/SwiftBrowserNative/Runtime/ViewRegistry.swift +57 -0
  49. package/swift/Sources/SwiftBrowserNative/Views/ElementView.swift +11 -7
  50. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Drawing.swift +378 -0
  51. package/swift/Sources/SwiftBrowserNative/Views/Kinds/Navigation.swift +15 -10
  52. package/swift/Sources/SwiftBrowserNative/Views/Kinds/PopTap.swift +31 -28
  53. package/swift/Sources/SwiftBrowserNative/Views/StyleModifier.swift +142 -0
  54. package/swift/Sources/SwiftBrowserProtocol/Drawing.swift +306 -0
  55. package/swift/Sources/SwiftBrowserProtocol/Props.swift +5 -2
  56. package/swift/Sources/SwiftBrowserProtocol/RendererEvent.swift +24 -3
  57. package/swift/Sources/SwiftBrowserProtocol/Style.swift +87 -0
  58. package/wasm/SwiftBrowserNative.wasm +2 -2
  59. package/dist/native.d.ts +0 -19
  60. package/dist/native.d.ts.map +0 -1
  61. package/dist/native.js +0 -17
  62. package/dist/native.js.map +0 -1
  63. package/src/native.ts +0 -35
  64. package/swift/Sources/SwiftBrowserNative/Runtime/NativeRegistry.swift +0 -53
@@ -0,0 +1,79 @@
1
+ #if canImport(AVFoundation) && canImport(SwiftUI)
2
+ import SwiftBrowserProtocol
3
+ import SwiftUI
4
+
5
+ /// `ScopeView` (@swiftbrowser/dsp): a program node's output as a waveform,
6
+ /// drawn every display frame from what the audio thread keeps for it
7
+ /// (`ScopeTap`), its frames never crossing to the app's JavaScript. The
8
+ /// trace starts at a rising zero crossing, so a steady tone stands still;
9
+ /// it is the page's canvas (packages/dsp/src/scope.ts), step for step.
10
+ struct DSPScopeView: View {
11
+ let token: String
12
+ let color: Color
13
+ let gain: Float
14
+ @State private var reader = ScopeReader()
15
+
16
+ init(props: JSONValue) {
17
+ token = props["view"].string ?? ""
18
+ gain = Float(props["gain"].double ?? 1)
19
+ color = props["color"].string.flatMap(Self.color(hex:)) ?? .accentColor
20
+ }
21
+
22
+ var body: some View {
23
+ TimelineView(.animation) { timeline in
24
+ // The tick's date is the trace's own input: SwiftUI draws a view again only when its inputs change, and
25
+ // a canvas that read nothing from the timeline was drawn once and left.
26
+ ScopeTrace(date: timeline.date, token: token, color: color, gain: gain, reader: reader)
27
+ }
28
+ }
29
+
30
+ /// The first rising zero crossing in the first half (scope.ts `traceStart`).
31
+ static func traceStart(_ samples: [Float], _ length: Int) -> Int {
32
+ let last = Swift.max(1, samples.count - length)
33
+ for i in 1..<last where samples[i - 1] < 0 && samples[i] >= 0 { return i }
34
+ return 0
35
+ }
36
+
37
+ /// `#rrggbb`.
38
+ static func color(hex: String) -> Color? {
39
+ let digits = hex.hasPrefix("#") ? String(hex.dropFirst()) : hex
40
+ guard digits.count == 6, let value = UInt32(digits, radix: 16) else { return nil }
41
+ return Color(red: Double((value >> 16) & 0xFF) / 255, green: Double((value >> 8) & 0xFF) / 255, blue: Double(value & 0xFF) / 255)
42
+ }
43
+ }
44
+
45
+ /// One display frame's trace: what the tap holds at `date`.
46
+ private struct ScopeTrace: View {
47
+ let date: Date
48
+ let token: String
49
+ let color: Color
50
+ let gain: Float
51
+ let reader: ScopeReader
52
+
53
+ var body: some View {
54
+ Canvas { context, size in
55
+ let samples = reader.read(ScopeTaps.tap(token))
56
+ let length = samples.count / 2
57
+ let start = DSPScopeView.traceStart(samples, length)
58
+ var path = Path()
59
+ for i in 0..<length {
60
+ let x = CGFloat(i) / CGFloat(length - 1) * size.width
61
+ let value = Swift.max(-1, Swift.min(1, samples[start + i] * gain))
62
+ let y = size.height / 2 - CGFloat(value) * size.height / 2
63
+ if i == 0 { path.move(to: CGPoint(x: x, y: y)) } else { path.addLine(to: CGPoint(x: x, y: y)) }
64
+ }
65
+ context.stroke(path, with: .color(color), style: StrokeStyle(lineWidth: 1.5, lineJoin: .round))
66
+ }
67
+ }
68
+ }
69
+
70
+ /// The view's copy of the newest frames, made again each display frame.
71
+ final class ScopeReader {
72
+ private var samples = [Float](repeating: 0, count: 1024)
73
+
74
+ func read(_ tap: ScopeTap?) -> [Float] {
75
+ tap?.read(into: &samples)
76
+ return samples
77
+ }
78
+ }
79
+ #endif