@thelacanians/vue-native-cli 0.4.2 → 0.4.4

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 (172) hide show
  1. package/dist/cli.js +43 -23
  2. package/native/android/README.md +205 -0
  3. package/native/android/VueNativeCore/build.gradle.kts +100 -0
  4. package/native/android/VueNativeCore/consumer-rules.pro +12 -0
  5. package/native/android/VueNativeCore/proguard-rules.pro +33 -0
  6. package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
  7. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
  8. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
  9. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
  10. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
  11. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
  12. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
  13. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
  14. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
  15. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
  16. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
  17. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
  18. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
  19. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
  20. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
  21. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
  22. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
  23. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
  24. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
  25. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
  26. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
  27. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
  28. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
  29. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
  30. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
  31. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
  32. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
  33. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
  34. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
  35. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
  36. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
  37. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
  38. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
  39. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
  40. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
  41. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
  42. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
  43. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
  44. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
  45. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
  46. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
  47. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
  48. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
  49. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
  50. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
  51. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
  52. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
  53. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
  54. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
  55. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
  56. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
  57. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
  58. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
  59. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
  60. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
  61. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
  62. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
  63. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
  64. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
  65. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
  66. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
  67. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
  68. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
  69. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
  70. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
  71. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
  72. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
  73. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
  74. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
  75. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +160 -0
  76. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
  77. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
  78. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
  79. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
  80. package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
  81. package/native/android/app/build.gradle.kts +45 -0
  82. package/native/android/app/proguard-rules.pro +5 -0
  83. package/native/android/app/src/main/AndroidManifest.xml +25 -0
  84. package/native/android/app/src/main/assets/.gitkeep +0 -0
  85. package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
  86. package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
  87. package/native/android/app/src/main/res/values/strings.xml +3 -0
  88. package/native/android/app/src/main/res/values/themes.xml +9 -0
  89. package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
  90. package/native/android/build.gradle.kts +6 -0
  91. package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  92. package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  93. package/native/android/gradle.properties +4 -0
  94. package/native/android/gradlew +87 -0
  95. package/native/android/gradlew.bat +48 -0
  96. package/native/android/settings.gradle.kts +20 -0
  97. package/native/ios/VueNativeCore/Package.resolved +23 -0
  98. package/native/ios/VueNativeCore/Package.swift +32 -0
  99. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +132 -0
  100. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +92 -0
  101. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
  102. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
  103. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
  104. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +891 -0
  105. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
  106. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
  107. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +91 -0
  108. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
  109. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +150 -0
  110. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
  111. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
  112. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
  113. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
  114. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
  115. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
  116. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
  117. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +112 -0
  118. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
  119. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
  120. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
  121. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
  122. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
  123. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
  124. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
  125. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
  126. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
  127. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
  128. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
  129. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
  130. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
  131. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +246 -0
  132. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
  133. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +172 -0
  134. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
  135. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
  136. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
  137. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
  138. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +291 -0
  139. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +65 -0
  140. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
  141. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +366 -0
  142. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
  143. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
  144. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +387 -0
  145. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +161 -0
  146. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +318 -0
  147. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
  148. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
  149. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
  150. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
  151. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
  152. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
  153. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
  154. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
  155. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
  156. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
  157. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
  158. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
  159. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
  160. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
  161. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
  162. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +138 -0
  163. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
  164. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
  165. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
  166. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +49 -0
  167. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +240 -0
  168. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
  169. package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
  170. package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
  171. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
  172. package/package.json +3 -2
@@ -0,0 +1,652 @@
1
+ package com.vuenative.core
2
+
3
+ import android.os.Handler
4
+ import android.os.Looper
5
+ import android.util.Log
6
+ import com.eclipsesource.v8.JavaCallback
7
+ import com.eclipsesource.v8.JavaVoidCallback
8
+ import com.eclipsesource.v8.V8Array
9
+ import com.eclipsesource.v8.V8Object
10
+ import okhttp3.Call
11
+ import okhttp3.Callback
12
+ import okhttp3.MediaType.Companion.toMediaTypeOrNull
13
+ import okhttp3.OkHttpClient
14
+ import okhttp3.Request
15
+ import okhttp3.RequestBody.Companion.toRequestBody
16
+ import okhttp3.Response
17
+ import org.json.JSONObject
18
+ import java.io.IOException
19
+ import java.security.SecureRandom
20
+
21
+ /**
22
+ * Registers browser-like APIs in the V8 context.
23
+ * Must be called from the JS thread after V8 is initialized.
24
+ */
25
+ object JSPolyfills {
26
+
27
+ private const val TAG = "VueNative-Polyfills"
28
+ private val mainHandler = Handler(Looper.getMainLooper())
29
+ private val httpClient = OkHttpClient()
30
+
31
+ // Timer storage — accessed from JS thread only
32
+ private val timers = mutableMapOf<Int, Runnable>()
33
+ private var nextTimerId = 1
34
+
35
+ // RAF — accessed from JS thread only
36
+ private val rafCallbacks = mutableMapOf<Int, Any>()
37
+ private var nextRafId = 1
38
+ private var rafChoreographerPosted = false
39
+
40
+ fun register(runtime: JSRuntime) {
41
+ runtime.runOnJsThread {
42
+ val v8 = runtime.v8() ?: return@runOnJsThread
43
+ registerConsole(runtime)
44
+ registerTimers(runtime)
45
+ registerMicrotask(runtime)
46
+ registerRAF(runtime)
47
+ registerPerformance(runtime)
48
+ registerGlobalThis(runtime)
49
+ registerFetch(runtime)
50
+ registerBase64(runtime)
51
+ registerTextEncoding(runtime)
52
+ registerURL(runtime)
53
+ registerCrypto(runtime)
54
+ }
55
+ }
56
+
57
+ /** Reset all timers, RAF callbacks, and counters. Call before hot-reloading a new bundle. */
58
+ fun reset() {
59
+ // Cancel all pending timer callbacks
60
+ for ((_, runnable) in timers) {
61
+ mainHandler.removeCallbacks(runnable)
62
+ }
63
+ timers.clear()
64
+
65
+ // Clear RAF state
66
+ rafCallbacks.clear()
67
+ rafChoreographerPosted = false
68
+
69
+ // Reset counters
70
+ nextTimerId = 1
71
+ nextRafId = 1
72
+ }
73
+
74
+ // -- console ------------------------------------------------------------------
75
+
76
+ private fun registerConsole(runtime: JSRuntime) {
77
+ runtime.runOnJsThread {
78
+ val v8 = runtime.v8() ?: return@runOnJsThread
79
+ v8.executeVoidScript("var console = {};")
80
+
81
+ listOf("log", "warn", "error", "debug", "info").forEach { level ->
82
+ v8.registerJavaMethod(JavaVoidCallback { _, params ->
83
+ try {
84
+ val msg = if (params.length() == 0) "undefined"
85
+ else params.get(0)?.toString() ?: "null"
86
+ when (level) {
87
+ "error" -> Log.e("VueNative JS", msg)
88
+ "warn" -> Log.w("VueNative JS", msg)
89
+ else -> Log.d("VueNative JS", msg)
90
+ }
91
+ } finally {
92
+ params.close()
93
+ }
94
+ }, "__console_$level")
95
+ }
96
+
97
+ v8.executeVoidScript("""
98
+ console.log = function() { __console_log(Array.prototype.join.call(arguments,' ')); };
99
+ console.warn = function() { __console_warn(Array.prototype.join.call(arguments,' ')); };
100
+ console.error = function() { __console_error(Array.prototype.join.call(arguments,' ')); };
101
+ console.debug = function() { __console_debug(Array.prototype.join.call(arguments,' ')); };
102
+ console.info = function() { __console_info(Array.prototype.join.call(arguments,' ')); };
103
+ """)
104
+ }
105
+ }
106
+
107
+ // -- setTimeout / clearTimeout / setInterval / clearInterval ------------------
108
+
109
+ private fun registerTimers(runtime: JSRuntime) {
110
+ runtime.runOnJsThread {
111
+ val v8 = runtime.v8() ?: return@runOnJsThread
112
+
113
+ // setTimeout(fn, delay) -> timerId
114
+ v8.registerJavaMethod(JavaCallback { _, params ->
115
+ try {
116
+ val timerId = nextTimerId++
117
+ val delayMs = if (params.length() > 1) params.getDouble(1).toLong() else 0L
118
+
119
+ // Post to main thread which posts back to JS thread after delay
120
+ val runnable = Runnable {
121
+ runtime.runOnJsThread {
122
+ try {
123
+ v8.executeVoidScript(
124
+ "if(typeof __vnTimerCb_$timerId==='function'){" +
125
+ "var f=__vnTimerCb_$timerId;" +
126
+ "delete __vnTimerCb_$timerId;" +
127
+ "f();}"
128
+ )
129
+ } catch (e: Exception) {
130
+ Log.e(TAG, "Timer callback error", e)
131
+ } finally {
132
+ timers.remove(timerId)
133
+ }
134
+ }
135
+ }
136
+ timers[timerId] = runnable
137
+ mainHandler.postDelayed(runnable, delayMs.coerceAtLeast(1L))
138
+
139
+ return@JavaCallback timerId
140
+ } finally {
141
+ params.close()
142
+ }
143
+ }, "__vnSetTimeout")
144
+
145
+ // clearTimeout(timerId)
146
+ v8.registerJavaMethod(JavaVoidCallback { _, params ->
147
+ try {
148
+ val id = params.getInteger(0)
149
+ timers.remove(id)?.let { mainHandler.removeCallbacks(it) }
150
+ v8.executeVoidScript("delete __vnTimerCb_$id")
151
+ } finally {
152
+ params.close()
153
+ }
154
+ }, "__vnClearTimeout")
155
+
156
+ // setInterval(fn, delay) -> timerId
157
+ v8.registerJavaMethod(JavaCallback { _, params ->
158
+ try {
159
+ val timerId = nextTimerId++
160
+ val delayMs = if (params.length() > 1) params.getDouble(1).toLong() else 0L
161
+
162
+ fun scheduleNext() {
163
+ val runnable = Runnable {
164
+ runtime.runOnJsThread {
165
+ try {
166
+ val active = v8.executeBooleanScript(
167
+ "!!__vnIntervalActive_$timerId"
168
+ )
169
+ if (active) {
170
+ v8.executeVoidScript(
171
+ "if(typeof __vnIntervalCb_$timerId==='function')" +
172
+ "__vnIntervalCb_$timerId()"
173
+ )
174
+ scheduleNext()
175
+ } else {
176
+ timers.remove(timerId)
177
+ }
178
+ } catch (e: Exception) {
179
+ Log.e(TAG, "Interval callback error", e)
180
+ }
181
+ }
182
+ }
183
+ timers[timerId] = runnable
184
+ mainHandler.postDelayed(runnable, delayMs.coerceAtLeast(1L))
185
+ }
186
+ scheduleNext()
187
+ return@JavaCallback timerId
188
+ } finally {
189
+ params.close()
190
+ }
191
+ }, "__vnSetInterval")
192
+
193
+ v8.registerJavaMethod(JavaVoidCallback { _, params ->
194
+ try {
195
+ val id = params.getInteger(0)
196
+ timers.remove(id)?.let { mainHandler.removeCallbacks(it) }
197
+ v8.executeVoidScript("__vnIntervalActive_$id = false; delete __vnIntervalCb_$id")
198
+ } finally {
199
+ params.close()
200
+ }
201
+ }, "__vnClearInterval")
202
+
203
+ // Expose standard names via JS wrapper
204
+ v8.executeVoidScript("""
205
+ function setTimeout(fn, delay) {
206
+ var id = __vnSetTimeout(fn, delay || 0);
207
+ this['__vnTimerCb_' + id] = fn;
208
+ return id;
209
+ }
210
+ function clearTimeout(id) { __vnClearTimeout(id); }
211
+ function setInterval(fn, delay) {
212
+ var id = __vnSetInterval(fn, delay || 0);
213
+ this['__vnIntervalCb_' + id] = fn;
214
+ this['__vnIntervalActive_' + id] = true;
215
+ return id;
216
+ }
217
+ function clearInterval(id) { __vnClearInterval(id); }
218
+ """)
219
+ }
220
+ }
221
+
222
+ // -- queueMicrotask -----------------------------------------------------------
223
+
224
+ private fun registerMicrotask(runtime: JSRuntime) {
225
+ runtime.runOnJsThread {
226
+ val v8 = runtime.v8() ?: return@runOnJsThread
227
+ // V8 has native Promise support — use it for microtasks
228
+ v8.executeVoidScript("""
229
+ function queueMicrotask(callback) {
230
+ Promise.resolve().then(callback);
231
+ }
232
+ """)
233
+ }
234
+ }
235
+
236
+ // -- requestAnimationFrame / cancelAnimationFrame -----------------------------
237
+
238
+ private fun registerRAF(runtime: JSRuntime) {
239
+ runtime.runOnJsThread {
240
+ val v8 = runtime.v8() ?: return@runOnJsThread
241
+
242
+ v8.registerJavaMethod(JavaCallback { _, params ->
243
+ try {
244
+ val rafId = nextRafId++
245
+ rafCallbacks[rafId] = true
246
+
247
+ if (!rafChoreographerPosted) {
248
+ rafChoreographerPosted = true
249
+ postRAFChoreographer(runtime)
250
+ }
251
+ return@JavaCallback rafId
252
+ } finally {
253
+ params.close()
254
+ }
255
+ }, "__vnRequestRAF")
256
+
257
+ v8.registerJavaMethod(JavaVoidCallback { _, params ->
258
+ try {
259
+ val id = params.getInteger(0)
260
+ rafCallbacks.remove(id)
261
+ v8.executeVoidScript("delete __vnRafCb_$id")
262
+ } finally {
263
+ params.close()
264
+ }
265
+ }, "__vnCancelRAF")
266
+
267
+ v8.executeVoidScript("""
268
+ function requestAnimationFrame(fn) {
269
+ var id = __vnRequestRAF(fn);
270
+ this['__vnRafCb_' + id] = fn;
271
+ return id;
272
+ }
273
+ function cancelAnimationFrame(id) { __vnCancelRAF(id); }
274
+ """)
275
+ }
276
+ }
277
+
278
+ private fun postRAFChoreographer(runtime: JSRuntime) {
279
+ mainHandler.post {
280
+ val now = System.currentTimeMillis()
281
+ runtime.runOnJsThread {
282
+ val v8 = runtime.v8() ?: return@runOnJsThread
283
+ try {
284
+ // Fire all pending RAF callbacks
285
+ v8.executeVoidScript("""
286
+ (function() {
287
+ var keys = Object.keys(this).filter(function(k){ return k.startsWith('__vnRafCb_'); });
288
+ var cbs = {};
289
+ keys.forEach(function(k){ cbs[k] = this[k]; delete this[k]; }.bind(this));
290
+ keys.forEach(function(k){ if(typeof cbs[k]==='function') cbs[k]($now); });
291
+ }).call(this);
292
+ """)
293
+ // Check if more RAF callbacks were registered
294
+ val hasMore = v8.executeBooleanScript(
295
+ "Object.keys(this).some(function(k){ return k.startsWith('__vnRafCb_'); })"
296
+ )
297
+ if (hasMore) {
298
+ postRAFChoreographer(runtime)
299
+ } else {
300
+ rafChoreographerPosted = false
301
+ }
302
+ } catch (e: Exception) {
303
+ rafChoreographerPosted = false
304
+ Log.e(TAG, "RAF error", e)
305
+ }
306
+ }
307
+ }
308
+ }
309
+
310
+ // -- performance.now() --------------------------------------------------------
311
+
312
+ private fun registerPerformance(runtime: JSRuntime) {
313
+ runtime.runOnJsThread {
314
+ val v8 = runtime.v8() ?: return@runOnJsThread
315
+ v8.executeVoidScript("var performance = {};")
316
+ v8.registerJavaMethod(JavaCallback { _, params ->
317
+ try {
318
+ return@JavaCallback (System.currentTimeMillis() - runtime.startTimeMs).toDouble()
319
+ } finally {
320
+ params.close()
321
+ }
322
+ }, "__vnPerfNow")
323
+ v8.executeVoidScript("performance.now = function(){ return __vnPerfNow(); };")
324
+ }
325
+ }
326
+
327
+ // -- globalThis ---------------------------------------------------------------
328
+
329
+ private fun registerGlobalThis(runtime: JSRuntime) {
330
+ runtime.runOnJsThread {
331
+ val v8 = runtime.v8() ?: return@runOnJsThread
332
+ v8.executeVoidScript("""
333
+ if (typeof globalThis === 'undefined') {
334
+ var globalThis = this;
335
+ }
336
+ """)
337
+ }
338
+ }
339
+
340
+ // -- fetch --------------------------------------------------------------------
341
+ // Uses per-request IDs to support concurrent fetch() calls safely.
342
+
343
+ private fun registerFetch(runtime: JSRuntime) {
344
+ runtime.runOnJsThread {
345
+ val v8 = runtime.v8() ?: return@runOnJsThread
346
+
347
+ // __vnFetch(url, optsJson, requestId) — requestId is echoed back to JS callbacks
348
+ v8.registerJavaMethod(JavaVoidCallback { _, params ->
349
+ val url: String
350
+ val optsJson: String
351
+ val requestId: Int
352
+ try {
353
+ url = params.getString(0)
354
+ optsJson = if (params.length() > 1 && params.getType(1) == 4) params.getString(1) else "{}"
355
+ requestId = if (params.length() > 2) params.getDouble(2).toInt() else 0
356
+ } finally {
357
+ params.close()
358
+ }
359
+ val opts = try { JSONObject(optsJson) } catch (e: Exception) { JSONObject() }
360
+
361
+ val method = opts.optString("method", "GET").uppercase()
362
+ val bodyStr = opts.optString("body", "")
363
+ val headersObj = opts.optJSONObject("headers")
364
+
365
+ val builder = Request.Builder().url(url)
366
+ headersObj?.keys()?.forEach { k -> builder.addHeader(k, headersObj.getString(k)) }
367
+
368
+ val requestBody = if (bodyStr.isNotEmpty()) {
369
+ val ct = headersObj?.optString("Content-Type") ?: "application/json"
370
+ bodyStr.toRequestBody(ct.toMediaTypeOrNull())
371
+ } else if (method != "GET" && method != "HEAD") {
372
+ "".toRequestBody()
373
+ } else null
374
+
375
+ builder.method(method, requestBody)
376
+
377
+ httpClient.newCall(builder.build()).enqueue(object : Callback {
378
+ override fun onFailure(call: Call, e: IOException) {
379
+ val errMsg = e.message ?: "Network error"
380
+ runtime.runOnJsThread {
381
+ v8.executeVoidScript(
382
+ "__vnFetchReject($requestId,${JSONObject.quote(errMsg)})"
383
+ )
384
+ }
385
+ }
386
+ override fun onResponse(call: Call, response: Response) {
387
+ val status = response.code
388
+ val ok = status in 200..299
389
+ val body = response.body?.string() ?: ""
390
+ val hdrs = JSONObject()
391
+ response.headers.forEach { (k, v) -> hdrs.put(k, v) }
392
+ val resp = JSONObject().apply {
393
+ put("status", status)
394
+ put("ok", ok)
395
+ put("_body", body)
396
+ put("headers", hdrs)
397
+ }
398
+ val respJson = JSONObject.quote(resp.toString())
399
+ runtime.runOnJsThread {
400
+ v8.executeVoidScript("__vnFetchResolve($requestId,$respJson)")
401
+ }
402
+ }
403
+ })
404
+ }, "__vnFetch")
405
+
406
+ v8.executeVoidScript("""
407
+ var __vnFetchCallbacks = {};
408
+ var __vnFetchNextId = 1;
409
+
410
+ function fetch(url, options) {
411
+ return new Promise(function(resolve, reject) {
412
+ var id = __vnFetchNextId++;
413
+ __vnFetchCallbacks[id] = { resolve: resolve, reject: reject };
414
+ __vnFetch(url, options ? JSON.stringify(options) : '{}', id);
415
+ });
416
+ }
417
+
418
+ function __vnFetchResolve(id, respJson) {
419
+ var cb = __vnFetchCallbacks[id];
420
+ if (!cb) return;
421
+ delete __vnFetchCallbacks[id];
422
+ var resp = JSON.parse(respJson) || {};
423
+ resp.text = function() { return Promise.resolve(resp._body || ''); };
424
+ resp.json = function() {
425
+ return new Promise(function(res, rej) {
426
+ try { res(JSON.parse(resp._body || '{}')); }
427
+ catch(e) { rej(e); }
428
+ });
429
+ };
430
+ cb.resolve(resp);
431
+ }
432
+
433
+ function __vnFetchReject(id, msg) {
434
+ var cb = __vnFetchCallbacks[id];
435
+ if (!cb) return;
436
+ delete __vnFetchCallbacks[id];
437
+ cb.reject(new Error(msg));
438
+ }
439
+ """)
440
+ }
441
+ }
442
+
443
+ // -- atob / btoa (Base64) -----------------------------------------------------
444
+
445
+ private fun registerBase64(runtime: JSRuntime) {
446
+ runtime.runOnJsThread {
447
+ val v8 = runtime.v8() ?: return@runOnJsThread
448
+
449
+ // atob — decode base64 string to plain text
450
+ v8.registerJavaMethod(JavaCallback { _, params ->
451
+ try {
452
+ val encoded = params.getString(0)
453
+ val decoded = android.util.Base64.decode(encoded, android.util.Base64.DEFAULT)
454
+ return@JavaCallback String(decoded, Charsets.UTF_8)
455
+ } catch (e: Exception) {
456
+ Log.e(TAG, "atob error", e)
457
+ return@JavaCallback ""
458
+ } finally {
459
+ params.close()
460
+ }
461
+ }, "__vnAtob")
462
+
463
+ // btoa — encode plain text to base64 string
464
+ v8.registerJavaMethod(JavaCallback { _, params ->
465
+ try {
466
+ val str = params.getString(0)
467
+ val encoded = android.util.Base64.encodeToString(
468
+ str.toByteArray(Charsets.UTF_8),
469
+ android.util.Base64.NO_WRAP
470
+ )
471
+ return@JavaCallback encoded
472
+ } catch (e: Exception) {
473
+ Log.e(TAG, "btoa error", e)
474
+ return@JavaCallback ""
475
+ } finally {
476
+ params.close()
477
+ }
478
+ }, "__vnBtoa")
479
+
480
+ v8.executeVoidScript("""
481
+ function atob(encoded) { return __vnAtob(encoded); }
482
+ function btoa(str) { return __vnBtoa(str); }
483
+ """)
484
+ }
485
+ }
486
+
487
+ // -- TextEncoder / TextDecoder ------------------------------------------------
488
+
489
+ private fun registerTextEncoding(runtime: JSRuntime) {
490
+ runtime.runOnJsThread {
491
+ val v8 = runtime.v8() ?: return@runOnJsThread
492
+ v8.executeVoidScript("""
493
+ class TextEncoder {
494
+ constructor(encoding) { this.encoding = encoding || 'utf-8'; }
495
+ encode(str) {
496
+ var arr = [];
497
+ for (var i = 0; i < str.length; i++) {
498
+ var c = str.charCodeAt(i);
499
+ if (c < 0x80) { arr.push(c); }
500
+ else if (c < 0x800) { arr.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f)); }
501
+ else if (c < 0xd800 || c >= 0xe000) { arr.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); }
502
+ else { i++; c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff)); arr.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); }
503
+ }
504
+ return new Uint8Array(arr);
505
+ }
506
+ }
507
+ class TextDecoder {
508
+ constructor(encoding) { this.encoding = encoding || 'utf-8'; }
509
+ decode(buffer) {
510
+ var bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
511
+ var result = '';
512
+ for (var i = 0; i < bytes.length;) {
513
+ var c = bytes[i++];
514
+ if (c < 0x80) { result += String.fromCharCode(c); }
515
+ else if (c < 0xe0) { result += String.fromCharCode(((c & 0x1f) << 6) | (bytes[i++] & 0x3f)); }
516
+ else if (c < 0xf0) { result += String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f)); }
517
+ else { var cp = ((c & 0x07) << 18) | ((bytes[i++] & 0x3f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f); result += String.fromCodePoint(cp); }
518
+ }
519
+ return result;
520
+ }
521
+ }
522
+ if (typeof globalThis !== 'undefined') {
523
+ globalThis.TextEncoder = TextEncoder;
524
+ globalThis.TextDecoder = TextDecoder;
525
+ }
526
+ """)
527
+ }
528
+ }
529
+
530
+ // -- URL / URLSearchParams ----------------------------------------------------
531
+
532
+ private fun registerURL(runtime: JSRuntime) {
533
+ runtime.runOnJsThread {
534
+ val v8 = runtime.v8() ?: return@runOnJsThread
535
+ v8.executeVoidScript("""
536
+ if (typeof URL === 'undefined') {
537
+ var URL = (function() {
538
+ function URL(url, base) {
539
+ if (base) {
540
+ if (!url.match(/^[a-zA-Z]+:/)) {
541
+ var b = new URL(base);
542
+ url = b.origin + (url.charAt(0) === '/' ? '' : '/') + url;
543
+ }
544
+ }
545
+ var match = url.match(/^([a-zA-Z]+:)\/\/([^\/:]+)(:\d+)?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/);
546
+ if (!match) { this.href = url; this.protocol = ''; this.host = ''; this.hostname = ''; this.port = ''; this.pathname = '/'; this.search = ''; this.hash = ''; this.origin = ''; this.searchParams = new URLSearchParams(''); return; }
547
+ this.protocol = match[1] || '';
548
+ this.hostname = match[2] || '';
549
+ this.port = (match[3] || '').slice(1);
550
+ this.host = this.hostname + (this.port ? ':' + this.port : '');
551
+ this.pathname = match[4] || '/';
552
+ this.search = match[5] || '';
553
+ this.hash = match[6] || '';
554
+ this.origin = this.protocol + '//' + this.host;
555
+ this.href = url;
556
+ this.searchParams = new URLSearchParams(this.search);
557
+ }
558
+ URL.prototype.toString = function() { return this.href; };
559
+ return URL;
560
+ })();
561
+ if (typeof globalThis !== 'undefined') globalThis.URL = URL;
562
+ }
563
+ if (typeof URLSearchParams === 'undefined') {
564
+ var URLSearchParams = (function() {
565
+ function URLSearchParams(init) {
566
+ this._params = [];
567
+ if (typeof init === 'string') {
568
+ var parts = init.replace(/^\?/, '').split('&');
569
+ for (var i = 0; i < parts.length; i++) {
570
+ if (!parts[i]) continue;
571
+ var eq = parts[i].indexOf('=');
572
+ if (eq === -1) { this._params.push([decodeURIComponent(parts[i]), '']); }
573
+ else { this._params.push([decodeURIComponent(parts[i].slice(0, eq)), decodeURIComponent(parts[i].slice(eq + 1))]); }
574
+ }
575
+ }
576
+ }
577
+ URLSearchParams.prototype.get = function(name) {
578
+ for (var i = 0; i < this._params.length; i++) { if (this._params[i][0] === name) return this._params[i][1]; }
579
+ return null;
580
+ };
581
+ URLSearchParams.prototype.getAll = function(name) {
582
+ var r = [];
583
+ for (var i = 0; i < this._params.length; i++) { if (this._params[i][0] === name) r.push(this._params[i][1]); }
584
+ return r;
585
+ };
586
+ URLSearchParams.prototype.has = function(name) {
587
+ for (var i = 0; i < this._params.length; i++) { if (this._params[i][0] === name) return true; }
588
+ return false;
589
+ };
590
+ URLSearchParams.prototype.set = function(name, value) { this.delete(name); this._params.push([name, String(value)]); };
591
+ URLSearchParams.prototype.append = function(name, value) { this._params.push([name, String(value)]); };
592
+ URLSearchParams.prototype.delete = function(name) {
593
+ this._params = this._params.filter(function(p) { return p[0] !== name; });
594
+ };
595
+ URLSearchParams.prototype.toString = function() {
596
+ return this._params.map(function(p) { return encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1]); }).join('&');
597
+ };
598
+ URLSearchParams.prototype.forEach = function(cb) {
599
+ for (var i = 0; i < this._params.length; i++) { cb(this._params[i][1], this._params[i][0], this); }
600
+ };
601
+ return URLSearchParams;
602
+ })();
603
+ if (typeof globalThis !== 'undefined') globalThis.URLSearchParams = URLSearchParams;
604
+ }
605
+ """)
606
+ }
607
+ }
608
+
609
+ // -- crypto.getRandomValues ---------------------------------------------------
610
+
611
+ private fun registerCrypto(runtime: JSRuntime) {
612
+ runtime.runOnJsThread {
613
+ val v8 = runtime.v8() ?: return@runOnJsThread
614
+
615
+ // Native method: __vnGetRandomValues(length) -> comma-separated byte string
616
+ v8.registerJavaMethod(JavaCallback { _, params ->
617
+ try {
618
+ val length = params.getInteger(0)
619
+ if (length <= 0) return@JavaCallback ""
620
+ val bytes = ByteArray(length)
621
+ SecureRandom().nextBytes(bytes)
622
+ return@JavaCallback bytes.joinToString(",") { (it.toInt() and 0xFF).toString() }
623
+ } catch (e: Exception) {
624
+ Log.e(TAG, "crypto.getRandomValues error", e)
625
+ return@JavaCallback ""
626
+ } finally {
627
+ params.close()
628
+ }
629
+ }, "__vnGetRandomValues")
630
+
631
+ v8.executeVoidScript("""
632
+ if (typeof crypto === 'undefined') {
633
+ var crypto = {};
634
+ if (typeof globalThis !== 'undefined') globalThis.crypto = crypto;
635
+ }
636
+ crypto.getRandomValues = function(typedArray) {
637
+ var len = typedArray.length;
638
+ if (len > 0) {
639
+ var csv = __vnGetRandomValues(len);
640
+ if (csv) {
641
+ var vals = csv.split(',');
642
+ for (var i = 0; i < len; i++) {
643
+ typedArray[i] = parseInt(vals[i], 10);
644
+ }
645
+ }
646
+ }
647
+ return typedArray;
648
+ };
649
+ """)
650
+ }
651
+ }
652
+ }