@thelacanians/vue-native-cli 0.4.15 → 0.6.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 (116) hide show
  1. package/dist/cli.js +329 -15
  2. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +118 -0
  3. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +178 -1
  4. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeneratedModuleRegistry.kt +28 -0
  5. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +3 -0
  6. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/ComponentFactoryTest.kt +674 -0
  7. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/ErrorOverlayViewTest.kt +183 -0
  8. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/EventThrottleTest.kt +203 -0
  9. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/HotReloadManagerTest.kt +162 -0
  10. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/JSPolyfillsTest.kt +153 -0
  11. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/NativeBridgeTest.kt +6 -3
  12. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/NativeModuleTest.kt +475 -0
  13. package/native/android/gradle.properties +1 -0
  14. package/native/android/gradlew +1 -1
  15. package/native/ios/VueNativeCore/Package.swift +1 -1
  16. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/EventThrottle.swift +1 -0
  17. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +143 -5
  18. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +43 -0
  19. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +116 -4
  20. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +100 -0
  21. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeneratedModuleRegistry.swift +28 -0
  22. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +3 -0
  23. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/CertificatePinningTests.swift +190 -0
  24. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/ComponentFactoryTests.swift +585 -0
  25. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/EventThrottleTests.swift +161 -0
  26. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/HotReloadManagerTests.swift +88 -0
  27. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSPolyfillsTests.swift +319 -0
  28. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/NativeModuleTests.swift +400 -0
  29. package/native/macos/VueNativeMacOS/Package.swift +34 -0
  30. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/ErrorOverlayView.swift +112 -0
  31. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/EventThrottle.swift +58 -0
  32. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/HotReloadManager.swift +153 -0
  33. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/JSPolyfills.swift +696 -0
  34. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/JSRuntime.swift +347 -0
  35. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/NativeBridge.swift +877 -0
  36. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/VueNativeWindowController.swift +125 -0
  37. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/ComponentRegistry.swift +209 -0
  38. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VActionSheetFactory.swift +155 -0
  39. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VActivityIndicatorFactory.swift +85 -0
  40. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VAlertDialogFactory.swift +132 -0
  41. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VButtonFactory.swift +83 -0
  42. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VCheckboxFactory.swift +108 -0
  43. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VDropdownFactory.swift +155 -0
  44. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VImageFactory.swift +270 -0
  45. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VInputFactory.swift +257 -0
  46. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VKeyboardAvoidingFactory.swift +22 -0
  47. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VListFactory.swift +324 -0
  48. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VModalFactory.swift +231 -0
  49. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VOutlineViewFactory.swift +276 -0
  50. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VPickerFactory.swift +134 -0
  51. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VPressableFactory.swift +120 -0
  52. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VProgressBarFactory.swift +71 -0
  53. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VRadioFactory.swift +193 -0
  54. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VRefreshControlFactory.swift +25 -0
  55. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSafeAreaFactory.swift +46 -0
  56. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VScrollViewFactory.swift +190 -0
  57. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSectionListFactory.swift +374 -0
  58. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSegmentedControlFactory.swift +125 -0
  59. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSliderFactory.swift +131 -0
  60. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSplitViewFactory.swift +215 -0
  61. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VStatusBarFactory.swift +25 -0
  62. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSwitchFactory.swift +92 -0
  63. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VTextFactory.swift +336 -0
  64. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VToolbarFactory.swift +212 -0
  65. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VVideoFactory.swift +245 -0
  66. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VViewFactory.swift +314 -0
  67. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VWebViewFactory.swift +162 -0
  68. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/NativeComponentFactory.swift +54 -0
  69. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/ClickableView.swift +100 -0
  70. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/Extensions.swift +23 -0
  71. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/GestureWrapper.swift +183 -0
  72. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/NSColor+Hex.swift +78 -0
  73. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Layout/FlippedView.swift +19 -0
  74. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Layout/LayoutNode.swift +493 -0
  75. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/AnimationModule.swift +354 -0
  76. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/AppStateModule.swift +62 -0
  77. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/BiometryModule.swift +60 -0
  78. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/CameraModule.swift +167 -0
  79. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/ClipboardModule.swift +34 -0
  80. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/DeviceInfoModule.swift +49 -0
  81. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/DragDropModule.swift +50 -0
  82. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/FileDialogModule.swift +86 -0
  83. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/HapticsModule.swift +42 -0
  84. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/KeyboardModule.swift +28 -0
  85. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/LinkingModule.swift +49 -0
  86. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/MenuModule.swift +95 -0
  87. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/NativeModuleRegistry.swift +63 -0
  88. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/NotificationsModule.swift +112 -0
  89. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/PermissionsModule.swift +149 -0
  90. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/ShareModule.swift +37 -0
  91. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/WindowModule.swift +71 -0
  92. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Resources/vue-native-placeholder.js +2 -0
  93. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Styling/StyleEngine.swift +885 -0
  94. package/native/macos/VueNativeMacOS/Tests/VueNativeMacOSTests/ComponentFactoryTests.swift +80 -0
  95. package/native/macos/VueNativeMacOS/Tests/VueNativeMacOSTests/VueNativeMacOSTests.swift +149 -0
  96. package/native/shared/VueNativeShared/AGENTS.md +129 -0
  97. package/native/shared/VueNativeShared/Package.swift +14 -0
  98. package/native/shared/VueNativeShared/Sources/VueNativeShared/CertificatePinning.swift +134 -0
  99. package/native/shared/VueNativeShared/Sources/VueNativeShared/EventThrottle.swift +78 -0
  100. package/native/shared/VueNativeShared/Sources/VueNativeShared/HotReloadManager.swift +162 -0
  101. package/native/shared/VueNativeShared/Sources/VueNativeShared/JSRuntime.swift +412 -0
  102. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/AsyncStorageModule.swift +68 -0
  103. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/AudioModule.swift +359 -0
  104. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/DatabaseModule.swift +259 -0
  105. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/FileSystemModule.swift +233 -0
  106. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/GeolocationModule.swift +156 -0
  107. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/NetworkModule.swift +59 -0
  108. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/PerformanceModule.swift +113 -0
  109. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/SecureStorageModule.swift +119 -0
  110. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/WebSocketModule.swift +212 -0
  111. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeEventDispatcher.swift +6 -0
  112. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeModule.swift +26 -0
  113. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeModuleRegistry.swift +37 -0
  114. package/native/shared/VueNativeShared/Sources/VueNativeShared/SharedJSPolyfills.swift +673 -0
  115. package/native/shared/VueNativeShared/Tests/VueNativeSharedTests/VueNativeSharedTests.swift +44 -0
  116. package/package.json +8 -2
@@ -0,0 +1,212 @@
1
+ import Foundation
2
+
3
+ /// Native module for WebSocket connections.
4
+ /// Uses URLSession which is available on both iOS and macOS.
5
+ ///
6
+ /// Supports multiple simultaneous connections keyed by connection ID.
7
+ ///
8
+ /// Methods:
9
+ /// - connect(url: String, connectionId: String)
10
+ /// - send(connectionId: String, data: String)
11
+ /// - close(connectionId: String, code: Int?, reason: String?)
12
+ ///
13
+ /// Global events dispatched via NativeEventDispatcher:
14
+ /// "websocket:open" { connectionId }
15
+ /// "websocket:message" { connectionId, data }
16
+ /// "websocket:close" { connectionId, code, reason }
17
+ /// "websocket:error" { connectionId, message }
18
+ public final class WebSocketModule: NativeModule {
19
+ public var moduleName: String { "WebSocket" }
20
+ private weak var eventDispatcher: NativeEventDispatcher?
21
+
22
+ /// Active WebSocket tasks keyed by connectionId
23
+ private var connections: [String: URLSessionWebSocketTask] = [:]
24
+ private var sessions: [String: URLSession] = [:]
25
+
26
+ public init(eventDispatcher: NativeEventDispatcher) {
27
+ self.eventDispatcher = eventDispatcher
28
+ }
29
+
30
+ public func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
31
+ switch method {
32
+ case "connect":
33
+ guard let url = args.first as? String,
34
+ let connectionId = args.count > 1 ? args[1] as? String : nil else {
35
+ callback(nil, "WebSocketModule: expected (url, connectionId)")
36
+ return
37
+ }
38
+ connect(url: url, connectionId: connectionId, callback: callback)
39
+
40
+ case "send":
41
+ guard let connectionId = args.first as? String,
42
+ let data = args.count > 1 ? args[1] as? String : nil else {
43
+ callback(nil, "WebSocketModule: expected (connectionId, data)")
44
+ return
45
+ }
46
+ send(connectionId: connectionId, data: data, callback: callback)
47
+
48
+ case "close":
49
+ guard let connectionId = args.first as? String else {
50
+ callback(nil, "WebSocketModule: expected (connectionId)")
51
+ return
52
+ }
53
+ let code = args.count > 1 ? args[1] as? Int : nil
54
+ let reason = args.count > 2 ? args[2] as? String : nil
55
+ close(connectionId: connectionId, code: code, reason: reason, callback: callback)
56
+
57
+ default:
58
+ callback(nil, "WebSocketModule: Unknown method '\(method)'")
59
+ }
60
+ }
61
+
62
+ // MARK: - Connect
63
+
64
+ private func connect(url: String, connectionId: String, callback: @escaping (Any?, String?) -> Void) {
65
+ guard let wsURL = URL(string: url) else {
66
+ callback(nil, "WebSocketModule: invalid URL '\(url)'")
67
+ return
68
+ }
69
+
70
+ // Clean up existing connection with same ID if any
71
+ closeConnection(connectionId)
72
+
73
+ let session = URLSession(configuration: .default)
74
+ let task = session.webSocketTask(with: wsURL)
75
+ connections[connectionId] = task
76
+ sessions[connectionId] = session
77
+
78
+ task.resume()
79
+
80
+ // Dispatch open event once resumed
81
+ let weakDispatcher = eventDispatcher
82
+ DispatchQueue.main.async {
83
+ weakDispatcher?.dispatchGlobalEvent("websocket:open", payload: [
84
+ "connectionId": connectionId
85
+ ])
86
+ }
87
+
88
+ // Start receive loop
89
+ receiveLoop(connectionId: connectionId, task: task)
90
+
91
+ callback(true, nil)
92
+ }
93
+
94
+ // MARK: - Receive loop
95
+
96
+ private func receiveLoop(connectionId: String, task: URLSessionWebSocketTask) {
97
+ task.receive { [weak self] result in
98
+ guard let self = self else { return }
99
+ // Check if connection still exists (may have been closed)
100
+ guard self.connections[connectionId] != nil else { return }
101
+
102
+ switch result {
103
+ case .success(let message):
104
+ let data: String
105
+ switch message {
106
+ case .string(let text):
107
+ data = text
108
+ case .data(let bytes):
109
+ data = String(data: bytes, encoding: .utf8) ?? ""
110
+ @unknown default:
111
+ data = ""
112
+ }
113
+
114
+ let weakDispatcher = self.eventDispatcher
115
+ DispatchQueue.main.async {
116
+ weakDispatcher?.dispatchGlobalEvent("websocket:message", payload: [
117
+ "connectionId": connectionId,
118
+ "data": data
119
+ ])
120
+ }
121
+
122
+ // Continue receiving
123
+ self.receiveLoop(connectionId: connectionId, task: task)
124
+
125
+ case .failure(let error):
126
+ let weakDispatcher = self.eventDispatcher
127
+ let errorMessage = error.localizedDescription
128
+ DispatchQueue.main.async {
129
+ // Check if this is a normal close or an actual error
130
+ let nsError = error as NSError
131
+ if nsError.domain == NSPOSIXErrorDomain && nsError.code == 57 {
132
+ // Socket not connected — normal close, dispatch close event
133
+ weakDispatcher?.dispatchGlobalEvent("websocket:close", payload: [
134
+ "connectionId": connectionId,
135
+ "code": 1000,
136
+ "reason": ""
137
+ ])
138
+ } else {
139
+ weakDispatcher?.dispatchGlobalEvent("websocket:error", payload: [
140
+ "connectionId": connectionId,
141
+ "message": errorMessage
142
+ ])
143
+ weakDispatcher?.dispatchGlobalEvent("websocket:close", payload: [
144
+ "connectionId": connectionId,
145
+ "code": 1006,
146
+ "reason": errorMessage
147
+ ])
148
+ }
149
+ }
150
+ self.connections.removeValue(forKey: connectionId)
151
+ self.sessions[connectionId]?.invalidateAndCancel()
152
+ self.sessions.removeValue(forKey: connectionId)
153
+ }
154
+ }
155
+ }
156
+
157
+ // MARK: - Send
158
+
159
+ private func send(connectionId: String, data: String, callback: @escaping (Any?, String?) -> Void) {
160
+ guard let task = connections[connectionId] else {
161
+ callback(nil, "WebSocketModule: no connection '\(connectionId)'")
162
+ return
163
+ }
164
+ task.send(.string(data)) { error in
165
+ if let error = error {
166
+ callback(nil, error.localizedDescription)
167
+ } else {
168
+ callback(true, nil)
169
+ }
170
+ }
171
+ }
172
+
173
+ // MARK: - Close
174
+
175
+ private func close(connectionId: String, code: Int?, reason: String?, callback: @escaping (Any?, String?) -> Void) {
176
+ guard let task = connections[connectionId] else {
177
+ callback(nil, nil) // Already closed, not an error
178
+ return
179
+ }
180
+
181
+ let closeCode = URLSessionWebSocketTask.CloseCode(rawValue: code ?? 1000) ?? .normalClosure
182
+ let reasonData = reason?.data(using: .utf8)
183
+ task.cancel(with: closeCode, reason: reasonData)
184
+
185
+ let weakDispatcher = eventDispatcher
186
+ DispatchQueue.main.async {
187
+ weakDispatcher?.dispatchGlobalEvent("websocket:close", payload: [
188
+ "connectionId": connectionId,
189
+ "code": code ?? 1000,
190
+ "reason": reason ?? ""
191
+ ])
192
+ }
193
+
194
+ connections.removeValue(forKey: connectionId)
195
+ sessions[connectionId]?.invalidateAndCancel()
196
+ sessions.removeValue(forKey: connectionId)
197
+
198
+ callback(true, nil)
199
+ }
200
+
201
+ // MARK: - Helpers
202
+
203
+ private func closeConnection(_ connectionId: String) {
204
+ guard let task = connections[connectionId] else { return }
205
+ task.cancel(with: .normalClosure, reason: nil)
206
+ connections.removeValue(forKey: connectionId)
207
+ sessions[connectionId]?.invalidateAndCancel()
208
+ sessions.removeValue(forKey: connectionId)
209
+ }
210
+
211
+ public func invokeSync(method: String, args: [Any]) -> Any? { nil }
212
+ }
@@ -0,0 +1,6 @@
1
+ import Foundation
2
+
3
+ /// Protocol for dispatching events back to JS. Platform-specific bridges conform to this.
4
+ public protocol NativeEventDispatcher: AnyObject {
5
+ func dispatchGlobalEvent(_ eventName: String, payload: [String: Any])
6
+ }
@@ -0,0 +1,26 @@
1
+ import Foundation
2
+
3
+ /// Protocol that all native modules must conform to.
4
+ /// Modules are registered with NativeModuleRegistry and invoked from JS
5
+ /// via the platform-specific bridge's invokeNativeModule / invokeNativeModuleSync operations.
6
+ public protocol NativeModule: AnyObject {
7
+ /// The name used to identify this module from JS (e.g. "Haptics", "AsyncStorage").
8
+ var moduleName: String { get }
9
+
10
+ /// Invoke a method asynchronously.
11
+ /// - Parameters:
12
+ /// - method: The method name to invoke.
13
+ /// - args: Arguments passed from JS.
14
+ /// - callback: Called when the method completes. Pass (result, nil) on success,
15
+ /// (nil, errorMessage) on failure.
16
+ func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void)
17
+
18
+ /// Invoke a method synchronously and return the result.
19
+ /// Use sparingly — prefer the async variant.
20
+ func invokeSync(method: String, args: [Any]) -> Any?
21
+ }
22
+
23
+ public extension NativeModule {
24
+ /// Default sync implementation: just returns nil.
25
+ func invokeSync(method: String, args: [Any]) -> Any? { return nil }
26
+ }
@@ -0,0 +1,37 @@
1
+ import Foundation
2
+
3
+ /// Registry for all native modules.
4
+ /// Modules are registered by name and looked up when JS invokes them.
5
+ /// Each platform registers its own set of modules — there is no `registerDefaults()` here.
6
+ public final class NativeModuleRegistry {
7
+
8
+ public static let shared = NativeModuleRegistry()
9
+
10
+ private var modules: [String: NativeModule] = [:]
11
+
12
+ private init() {}
13
+
14
+ // MARK: - Registration
15
+
16
+ public func register(_ module: NativeModule) {
17
+ modules[module.moduleName] = module
18
+ }
19
+
20
+ // MARK: - Invocation
21
+
22
+ public func invoke(module moduleName: String, method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
23
+ guard let module = modules[moduleName] else {
24
+ callback(nil, "Module '\(moduleName)' not found")
25
+ return
26
+ }
27
+ module.invoke(method: method, args: args, callback: callback)
28
+ }
29
+
30
+ public func invokeSync(module moduleName: String, method: String, args: [Any]) -> Any? {
31
+ guard let module = modules[moduleName] else {
32
+ NSLog("[VueNative] NativeModuleRegistry: Module '\(moduleName)' not found")
33
+ return nil
34
+ }
35
+ return module.invokeSync(method: method, args: args)
36
+ }
37
+ }