@thelacanians/vue-native-cli 0.4.15 → 0.6.2

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,347 @@
1
+ import JavaScriptCore
2
+ import Foundation
3
+
4
+ // MARK: - Bundle Source
5
+
6
+ /// Describes where to load the JS application bundle from.
7
+ public enum BundleSource {
8
+ /// Load from an embedded resource in the app bundle.
9
+ case embedded(name: String)
10
+ /// Load from a development server URL (for live reload).
11
+ case devServer(url: URL)
12
+ }
13
+
14
+ // MARK: - JSRuntime
15
+
16
+ /// Core JavaScript runtime manager for macOS. Wraps JSContext on a dedicated serial DispatchQueue.
17
+ /// All JS operations are guaranteed to execute on the JS queue. AppKit operations
18
+ /// are never performed on this queue.
19
+ ///
20
+ /// Thread safety contract:
21
+ /// - All JSContext access happens exclusively on `jsQueue`
22
+ /// - Never pass JSValue across threads -- extract primitives first
23
+ /// - All closures registered with JSContext use [weak self]
24
+ public final class JSRuntime: @unchecked Sendable {
25
+
26
+ // MARK: - Singleton
27
+
28
+ public static let shared = JSRuntime()
29
+
30
+ // MARK: - Properties
31
+
32
+ /// Dedicated serial queue for all JavaScript execution.
33
+ /// QoS is userInteractive because JS drives the UI pipeline.
34
+ public let jsQueue = DispatchQueue(label: "com.vuenative.macos.js", qos: .userInteractive)
35
+
36
+ /// The underlying JavaScriptCore context. Only access on jsQueue.
37
+ public private(set) var context: JSContext!
38
+
39
+ /// Whether the runtime has been initialized.
40
+ public private(set) var isInitialized = false
41
+
42
+ /// Startup time reference for performance.now()
43
+ public let startTime: CFAbsoluteTime = CFAbsoluteTimeGetCurrent()
44
+
45
+ // MARK: - Initialization
46
+
47
+ private init() {}
48
+
49
+ /// Initialize the JS runtime. Creates the JSContext on the JS queue,
50
+ /// configures exception handling, and registers polyfills.
51
+ /// Must be called before any other method.
52
+ public func initialize(completion: (() -> Void)? = nil) {
53
+ jsQueue.async { [weak self] in
54
+ guard let self = self else { return }
55
+ guard !self.isInitialized else {
56
+ completion?()
57
+ return
58
+ }
59
+
60
+ self.context = JSContext()
61
+
62
+ self.context.exceptionHandler = { [weak self] context, exception in
63
+ guard let exception = exception else { return }
64
+ let message = exception.toString() ?? "Unknown JS error"
65
+ let line = exception.objectForKeyedSubscript("line")?.toInt32() ?? 0
66
+ let column = exception.objectForKeyedSubscript("column")?.toInt32() ?? 0
67
+ let stack = exception.objectForKeyedSubscript("stack")?.toString() ?? ""
68
+ NSLog("[VueNative macOS JS Error] \(message) at line \(line):\(column)")
69
+ if !stack.isEmpty {
70
+ NSLog("[VueNative macOS JS Stack] \(stack)")
71
+ }
72
+ #if DEBUG
73
+ let fullMessage = stack.isEmpty ? message : "\(message)\n\n\(stack)"
74
+ ErrorOverlayView.show(error: fullMessage)
75
+ #endif
76
+ _ = self
77
+ }
78
+
79
+ self.context.evaluateScript("var globalThis = this;")
80
+
81
+ // Register polyfills
82
+ JSPolyfills.register(in: self)
83
+
84
+ self.isInitialized = true
85
+ completion?()
86
+ }
87
+ }
88
+
89
+ // MARK: - Script Evaluation
90
+
91
+ /// Evaluate a JavaScript string on the JS queue.
92
+ public func evaluateScript(_ script: String, sourceURL: String? = nil, completion: ((JSValue?) -> Void)? = nil) {
93
+ jsQueue.async { [weak self] in
94
+ guard let self = self, let context = self.context else {
95
+ completion?(nil)
96
+ return
97
+ }
98
+
99
+ let result: JSValue?
100
+ if let sourceURL = sourceURL, let url = URL(string: sourceURL) {
101
+ result = context.evaluateScript(script, withSourceURL: url)
102
+ } else {
103
+ result = context.evaluateScript(script)
104
+ }
105
+
106
+ // Force microtask drain after evaluation.
107
+ context.evaluateScript("void 0;")
108
+
109
+ completion?(result)
110
+ }
111
+ }
112
+
113
+ /// Evaluate a script synchronously. MUST only be called from the JS queue.
114
+ @discardableResult
115
+ public func evaluateScriptSync(_ script: String, sourceURL: String? = nil) -> JSValue? {
116
+ dispatchPrecondition(condition: .onQueue(jsQueue))
117
+ guard let context = context else { return nil }
118
+
119
+ let result: JSValue?
120
+ if let sourceURL = sourceURL, let url = URL(string: sourceURL) {
121
+ result = context.evaluateScript(script, withSourceURL: url)
122
+ } else {
123
+ result = context.evaluateScript(script)
124
+ }
125
+
126
+ context.evaluateScript("void 0;")
127
+ return result
128
+ }
129
+
130
+ // MARK: - Function Calls
131
+
132
+ /// Call a global JS function by name with arguments. Runs on the JS queue.
133
+ public func callFunction(_ name: String, withArguments args: [Any], completion: ((JSValue?) -> Void)? = nil) {
134
+ jsQueue.async { [weak self] in
135
+ guard let self = self, let context = self.context else {
136
+ completion?(nil)
137
+ return
138
+ }
139
+
140
+ let function = context.objectForKeyedSubscript(name)
141
+ guard let fn = function, !fn.isUndefined else {
142
+ NSLog("[VueNative macOS] Warning: JS function '\(name)' not found")
143
+ completion?(nil)
144
+ return
145
+ }
146
+
147
+ let result = fn.call(withArguments: args)
148
+ context.evaluateScript("void 0;")
149
+
150
+ completion?(result)
151
+ }
152
+ }
153
+
154
+ /// Call a global JS function synchronously. MUST only be called from the JS queue.
155
+ @discardableResult
156
+ public func callFunctionSync(_ name: String, withArguments args: [Any]) -> JSValue? {
157
+ dispatchPrecondition(condition: .onQueue(jsQueue))
158
+ guard let context = context else { return nil }
159
+
160
+ let function = context.objectForKeyedSubscript(name)
161
+ guard let fn = function, !fn.isUndefined else {
162
+ NSLog("[VueNative macOS] Warning: JS function '\(name)' not found")
163
+ return nil
164
+ }
165
+
166
+ let result = fn.call(withArguments: args)
167
+ context.evaluateScript("void 0;")
168
+ return result
169
+ }
170
+
171
+ // MARK: - Function Registration
172
+
173
+ /// Register a Swift function as a global JS function.
174
+ public func registerFunction(_ name: String, block: @escaping @convention(block) (JSValue) -> Void) {
175
+ jsQueue.async { [weak self] in
176
+ guard let self = self, let context = self.context else { return }
177
+ let wrappedBlock: @convention(block) (JSValue) -> Void = { [weak self] value in
178
+ _ = self
179
+ block(value)
180
+ }
181
+ context.setObject(wrappedBlock, forKeyedSubscript: name as NSString)
182
+ }
183
+ }
184
+
185
+ // MARK: - Bundle Loading
186
+
187
+ /// Load a JS application bundle from the given source.
188
+ public func loadBundle(source: BundleSource, completion: ((Bool) -> Void)? = nil) {
189
+ jsQueue.async { [weak self] in
190
+ guard let self = self, self.context != nil else {
191
+ completion?(false)
192
+ return
193
+ }
194
+
195
+ switch source {
196
+ case .embedded(let name):
197
+ self.loadEmbeddedBundle(name: name, completion: completion)
198
+ case .devServer(let url):
199
+ self.loadDevServerBundle(url: url, completion: completion)
200
+ }
201
+ }
202
+ }
203
+
204
+ // MARK: - Private: Bundle Loading
205
+
206
+ private func loadEmbeddedBundle(name: String, completion: ((Bool) -> Void)?) {
207
+ let bundleName: String
208
+ let bundleExtension: String
209
+
210
+ if name.contains(".") {
211
+ let parts = name.split(separator: ".", maxSplits: 1)
212
+ bundleName = String(parts[0])
213
+ bundleExtension = String(parts[1])
214
+ } else {
215
+ bundleName = name
216
+ bundleExtension = "js"
217
+ }
218
+
219
+ var scriptURL: URL?
220
+
221
+ if let url = Bundle.main.url(forResource: bundleName, withExtension: bundleExtension) {
222
+ scriptURL = url
223
+ } else {
224
+ #if SWIFT_PACKAGE
225
+ if let url = Bundle.module.url(forResource: bundleName, withExtension: bundleExtension) {
226
+ scriptURL = url
227
+ }
228
+ #endif
229
+ }
230
+
231
+ guard let url = scriptURL else {
232
+ NSLog("[VueNative macOS] Error: Bundle '\(name)' not found in app resources")
233
+ completion?(false)
234
+ return
235
+ }
236
+
237
+ do {
238
+ let script = try String(contentsOf: url, encoding: .utf8)
239
+ NSLog("[VueNative macOS] Loading bundle: \(name) (\(script.count) bytes)")
240
+ self.context.evaluateScript(script, withSourceURL: url)
241
+ self.context.evaluateScript("void 0;")
242
+ NSLog("[VueNative macOS] Bundle loaded successfully")
243
+ completion?(true)
244
+ } catch {
245
+ NSLog("[VueNative macOS] Error loading bundle '\(name)': \(error.localizedDescription)")
246
+ completion?(false)
247
+ }
248
+ }
249
+
250
+ private func loadDevServerBundle(url: URL, completion: ((Bool) -> Void)?) {
251
+ let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
252
+ guard let self = self else {
253
+ completion?(false)
254
+ return
255
+ }
256
+
257
+ self.jsQueue.async { [weak self] in
258
+ guard let self = self, self.context != nil else {
259
+ completion?(false)
260
+ return
261
+ }
262
+
263
+ if let error = error {
264
+ NSLog("[VueNative macOS] Dev server error: \(error.localizedDescription)")
265
+ completion?(false)
266
+ return
267
+ }
268
+
269
+ guard let data = data, let script = String(data: data, encoding: .utf8) else {
270
+ NSLog("[VueNative macOS] Dev server returned invalid data")
271
+ completion?(false)
272
+ return
273
+ }
274
+
275
+ NSLog("[VueNative macOS] Loading dev bundle from \(url) (\(script.count) bytes)")
276
+ self.context.evaluateScript(script, withSourceURL: url)
277
+ self.context.evaluateScript("void 0;")
278
+ NSLog("[VueNative macOS] Dev bundle loaded successfully")
279
+ completion?(true)
280
+ }
281
+ }
282
+ task.resume()
283
+ }
284
+
285
+ // MARK: - Hot Reload
286
+
287
+ /// Reload the runtime with a new JavaScript bundle string.
288
+ public func reload(bundle: String, completion: ((Bool) -> Void)? = nil) {
289
+ jsQueue.async { [weak self] in
290
+ guard let self = self else {
291
+ completion?(false)
292
+ return
293
+ }
294
+
295
+ NSLog("[VueNative macOS] Hot reload: tearing down old context...")
296
+
297
+ if let teardown = self.context?.objectForKeyedSubscript("__VN_teardown"),
298
+ !teardown.isUndefined {
299
+ teardown.call(withArguments: [])
300
+ self.context?.evaluateScript("void 0;")
301
+ }
302
+
303
+ JSPolyfills.reset()
304
+
305
+ self.context = JSContext()
306
+ self.context.exceptionHandler = { [weak self] _, exception in
307
+ guard let exception = exception else { return }
308
+ let message = exception.toString() ?? "Unknown JS error"
309
+ let line = exception.objectForKeyedSubscript("line")?.toInt32() ?? 0
310
+ let stack = exception.objectForKeyedSubscript("stack")?.toString() ?? ""
311
+ NSLog("[VueNative macOS JS Error] \(message) at line \(line)")
312
+ #if DEBUG
313
+ let fullMessage = stack.isEmpty ? message : "\(message)\n\n\(stack)"
314
+ ErrorOverlayView.show(error: fullMessage)
315
+ #endif
316
+ _ = self
317
+ }
318
+
319
+ self.context.evaluateScript("var globalThis = this;")
320
+ JSPolyfills.register(in: self)
321
+
322
+ NSLog("[VueNative macOS] Hot reload: evaluating new bundle (\(bundle.count) bytes)...")
323
+ self.context.evaluateScript(bundle)
324
+ if let exception = self.context.exception {
325
+ NSLog("[VueNative macOS] Hot reload bundle error: %@", exception.toString() ?? "unknown")
326
+ self.context.exception = nil
327
+ completion?(false)
328
+ return
329
+ }
330
+ self.context.evaluateScript("void 0;")
331
+ NSLog("[VueNative macOS] Hot reload: complete")
332
+
333
+ completion?(true)
334
+ }
335
+ }
336
+
337
+ // MARK: - Teardown
338
+
339
+ public func invalidate() {
340
+ jsQueue.async { [weak self] in
341
+ guard let self = self else { return }
342
+ self.context = nil
343
+ self.isInitialized = false
344
+ NSLog("[VueNative macOS] JS runtime invalidated")
345
+ }
346
+ }
347
+ }