@nativescript/vite 0.0.1-alpha.7 → 0.0.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 (265) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +44 -0
  3. package/{dist/configuration → configuration}/angular.d.ts +1 -1
  4. package/configuration/angular.js +480 -0
  5. package/configuration/angular.js.map +1 -0
  6. package/configuration/base.d.ts +5 -0
  7. package/configuration/base.js +494 -0
  8. package/configuration/base.js.map +1 -0
  9. package/configuration/javascript.d.ts +4 -0
  10. package/configuration/javascript.js +151 -0
  11. package/configuration/javascript.js.map +1 -0
  12. package/{dist/configuration → configuration}/react.d.ts +1 -1
  13. package/{dist/configuration → configuration}/react.js +18 -17
  14. package/configuration/react.js.map +1 -0
  15. package/{dist/configuration → configuration}/solid.d.ts +1 -1
  16. package/{dist/configuration → configuration}/solid.js +17 -16
  17. package/configuration/solid.js.map +1 -0
  18. package/configuration/typescript.d.ts +4 -0
  19. package/configuration/typescript.js +175 -0
  20. package/configuration/typescript.js.map +1 -0
  21. package/{dist/configuration → configuration}/vue.d.ts +1 -1
  22. package/configuration/vue.js +163 -0
  23. package/configuration/vue.js.map +1 -0
  24. package/helpers/angular-linker.d.ts +13 -0
  25. package/helpers/angular-linker.js +181 -0
  26. package/helpers/angular-linker.js.map +1 -0
  27. package/helpers/cli-flags.d.ts +1 -0
  28. package/helpers/cli-flags.js +15 -0
  29. package/helpers/cli-flags.js.map +1 -0
  30. package/{dist/helpers → helpers}/commonjs-plugins.js +14 -13
  31. package/helpers/commonjs-plugins.js.map +1 -0
  32. package/{dist/helpers → helpers}/config-as-json.d.ts +1 -1
  33. package/{dist/helpers → helpers}/config-as-json.js +7 -6
  34. package/helpers/config-as-json.js.map +1 -0
  35. package/helpers/css-platform-plugin.d.ts +10 -0
  36. package/helpers/css-platform-plugin.js +76 -0
  37. package/helpers/css-platform-plugin.js.map +1 -0
  38. package/helpers/css-tree.js +22 -0
  39. package/helpers/css-tree.js.map +1 -0
  40. package/{dist/helpers → helpers}/dynamic-import-plugin.js +8 -7
  41. package/helpers/dynamic-import-plugin.js.map +1 -0
  42. package/helpers/esbuild-platform-resolver.d.ts +14 -0
  43. package/helpers/esbuild-platform-resolver.js +93 -0
  44. package/helpers/esbuild-platform-resolver.js.map +1 -0
  45. package/{dist/helpers → helpers}/external-configs.js +2 -1
  46. package/helpers/external-configs.js.map +1 -0
  47. package/{dist/helpers → helpers}/flavor.d.ts +1 -0
  48. package/helpers/flavor.js +51 -0
  49. package/helpers/flavor.js.map +1 -0
  50. package/{dist/helpers → helpers}/global-defines.d.ts +11 -3
  51. package/helpers/global-defines.js +24 -0
  52. package/helpers/global-defines.js.map +1 -0
  53. package/helpers/logging.d.ts +13 -0
  54. package/helpers/logging.js +111 -0
  55. package/helpers/logging.js.map +1 -0
  56. package/helpers/main-entry.d.ts +10 -0
  57. package/helpers/main-entry.js +215 -0
  58. package/helpers/main-entry.js.map +1 -0
  59. package/{dist/helpers → helpers}/module-resolution.js +4 -3
  60. package/helpers/module-resolution.js.map +1 -0
  61. package/{dist/helpers → helpers}/module-runner-patch.d.ts +1 -1
  62. package/{dist/helpers → helpers}/module-runner-patch.js +10 -12
  63. package/helpers/module-runner-patch.js.map +1 -0
  64. package/helpers/nativeclass-transform.d.ts +7 -0
  65. package/helpers/nativeclass-transform.js +158 -0
  66. package/helpers/nativeclass-transform.js.map +1 -0
  67. package/helpers/nativeclass-transformer-plugin.d.ts +5 -0
  68. package/helpers/nativeclass-transformer-plugin.js +23 -0
  69. package/helpers/nativeclass-transformer-plugin.js.map +1 -0
  70. package/{dist/helpers → helpers}/nativescript-package-resolver.js +18 -17
  71. package/helpers/nativescript-package-resolver.js.map +1 -0
  72. package/{dist/helpers → helpers}/ns-cli-plugins.d.ts +6 -1
  73. package/{dist/helpers → helpers}/ns-cli-plugins.js +31 -51
  74. package/helpers/ns-cli-plugins.js.map +1 -0
  75. package/helpers/package-platform-aliases.d.ts +10 -0
  76. package/{dist/helpers → helpers}/package-platform-aliases.js +18 -22
  77. package/helpers/package-platform-aliases.js.map +1 -0
  78. package/helpers/postcss-platform-config.d.ts +13 -0
  79. package/helpers/postcss-platform-config.js +97 -0
  80. package/helpers/postcss-platform-config.js.map +1 -0
  81. package/helpers/prelink-angular.d.ts +2 -0
  82. package/helpers/prelink-angular.js +117 -0
  83. package/helpers/prelink-angular.js.map +1 -0
  84. package/helpers/preserve-imports.js +38 -0
  85. package/helpers/preserve-imports.js.map +1 -0
  86. package/{dist/helpers → helpers}/project.js +2 -4
  87. package/helpers/project.js.map +1 -0
  88. package/helpers/resolver.d.ts +4 -0
  89. package/{dist/helpers → helpers}/resolver.js +7 -6
  90. package/helpers/resolver.js.map +1 -0
  91. package/helpers/theme-core-plugins.d.ts +14 -0
  92. package/helpers/theme-core-plugins.js +121 -0
  93. package/helpers/theme-core-plugins.js.map +1 -0
  94. package/helpers/ts-config-paths.d.ts +10 -0
  95. package/{dist/helpers → helpers}/ts-config-paths.js +70 -71
  96. package/helpers/ts-config-paths.js.map +1 -0
  97. package/{dist/helpers → helpers}/utils.js +14 -27
  98. package/helpers/utils.js.map +1 -0
  99. package/{dist/helpers → helpers}/workers.js +15 -16
  100. package/helpers/workers.js.map +1 -0
  101. package/{dist/hmr → hmr/client}/css-handler.js +18 -17
  102. package/hmr/client/css-handler.js.map +1 -0
  103. package/hmr/client/index.d.ts +13 -0
  104. package/hmr/client/index.js +1550 -0
  105. package/hmr/client/index.js.map +1 -0
  106. package/hmr/client/utils.d.ts +38 -0
  107. package/hmr/client/utils.js +426 -0
  108. package/hmr/client/utils.js.map +1 -0
  109. package/hmr/entry-runtime.d.ts +8 -0
  110. package/hmr/entry-runtime.js +135 -0
  111. package/hmr/entry-runtime.js.map +1 -0
  112. package/hmr/frameworks/angular/server/strategy.d.ts +2 -0
  113. package/hmr/frameworks/angular/server/strategy.js +101 -0
  114. package/hmr/frameworks/angular/server/strategy.js.map +1 -0
  115. package/hmr/frameworks/vue/client/index.d.ts +22 -0
  116. package/hmr/frameworks/vue/client/index.js +1537 -0
  117. package/hmr/frameworks/vue/client/index.js.map +1 -0
  118. package/hmr/frameworks/vue/server/compiler.d.ts +11 -0
  119. package/hmr/frameworks/vue/server/compiler.js +26 -0
  120. package/hmr/frameworks/vue/server/compiler.js.map +1 -0
  121. package/hmr/frameworks/vue/server/sfc-transforms.d.ts +14 -0
  122. package/hmr/frameworks/vue/server/sfc-transforms.js +282 -0
  123. package/hmr/frameworks/vue/server/sfc-transforms.js.map +1 -0
  124. package/hmr/frameworks/vue/server/strategy.d.ts +2 -0
  125. package/hmr/frameworks/vue/server/strategy.js +273 -0
  126. package/hmr/frameworks/vue/server/strategy.js.map +1 -0
  127. package/hmr/helpers/ast-extract.d.ts +6 -0
  128. package/hmr/helpers/ast-extract.js +72 -0
  129. package/hmr/helpers/ast-extract.js.map +1 -0
  130. package/hmr/helpers/ast-normalizer.d.ts +7 -0
  131. package/hmr/helpers/ast-normalizer.js +772 -0
  132. package/hmr/helpers/ast-normalizer.js.map +1 -0
  133. package/hmr/helpers/babel.d.ts +3 -0
  134. package/hmr/helpers/babel.js +17 -0
  135. package/hmr/helpers/babel.js.map +1 -0
  136. package/hmr/helpers/sanitize.d.ts +6 -0
  137. package/hmr/helpers/sanitize.js +55 -0
  138. package/hmr/helpers/sanitize.js.map +1 -0
  139. package/hmr/helpers/vendor-rewrite.d.ts +1 -0
  140. package/hmr/helpers/vendor-rewrite.js +35 -0
  141. package/hmr/helpers/vendor-rewrite.js.map +1 -0
  142. package/hmr/server/compiler.d.ts +2 -0
  143. package/hmr/server/compiler.js +75 -0
  144. package/hmr/server/compiler.js.map +1 -0
  145. package/hmr/server/constants.d.ts +14 -0
  146. package/hmr/server/constants.js +23 -0
  147. package/hmr/server/constants.js.map +1 -0
  148. package/hmr/server/core-sanitize.d.ts +32 -0
  149. package/hmr/server/core-sanitize.js +134 -0
  150. package/hmr/server/core-sanitize.js.map +1 -0
  151. package/hmr/server/framework-strategy.d.ts +68 -0
  152. package/hmr/server/framework-strategy.js +2 -0
  153. package/hmr/server/framework-strategy.js.map +1 -0
  154. package/hmr/server/index.d.ts +5 -0
  155. package/hmr/server/index.js +19 -0
  156. package/hmr/server/index.js.map +1 -0
  157. package/hmr/server/vite-plugin.d.ts +5 -0
  158. package/{dist/hmr/plugins/plugin-vue.js → hmr/server/vite-plugin.js} +13 -15
  159. package/hmr/server/vite-plugin.js.map +1 -0
  160. package/hmr/server/websocket.d.ts +15 -0
  161. package/hmr/server/websocket.js +5528 -0
  162. package/hmr/server/websocket.js.map +1 -0
  163. package/hmr/shared/runtime/http-only-boot.d.ts +1 -0
  164. package/hmr/shared/runtime/http-only-boot.js +107 -0
  165. package/hmr/shared/runtime/http-only-boot.js.map +1 -0
  166. package/hmr/shared/runtime/root-placeholder.d.ts +1 -0
  167. package/hmr/shared/runtime/root-placeholder.js +142 -0
  168. package/hmr/shared/runtime/root-placeholder.js.map +1 -0
  169. package/hmr/shared/runtime/vendor-bootstrap.d.ts +1 -0
  170. package/hmr/shared/runtime/vendor-bootstrap.js +134 -0
  171. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -0
  172. package/hmr/shared/vendor/manifest-loader.d.ts +9 -0
  173. package/hmr/shared/vendor/manifest-loader.js +38 -0
  174. package/hmr/shared/vendor/manifest-loader.js.map +1 -0
  175. package/hmr/shared/vendor/manifest.d.ts +34 -0
  176. package/hmr/shared/vendor/manifest.js +787 -0
  177. package/hmr/shared/vendor/manifest.js.map +1 -0
  178. package/hmr/shared/vendor/registry.d.ts +9 -0
  179. package/hmr/shared/vendor/registry.js +62 -0
  180. package/hmr/shared/vendor/registry.js.map +1 -0
  181. package/hmr/vendor-bootstrap.d.ts +3 -0
  182. package/hmr/vendor-bootstrap.js +32 -0
  183. package/hmr/vendor-bootstrap.js.map +1 -0
  184. package/{dist/index.d.ts → index.d.ts} +2 -0
  185. package/{dist/index.js → index.js} +3 -0
  186. package/index.js.map +1 -0
  187. package/package.json +39 -31
  188. package/{dist/polyfills → polyfills}/mdn-data-at-rules.js +1 -0
  189. package/polyfills/mdn-data-at-rules.js.map +1 -0
  190. package/{dist/polyfills → polyfills}/mdn-data-properties.js +1 -0
  191. package/polyfills/mdn-data-properties.js.map +1 -0
  192. package/{dist/polyfills → polyfills}/mdn-data-syntaxes.js +1 -0
  193. package/polyfills/mdn-data-syntaxes.js.map +1 -0
  194. package/{dist/polyfills → polyfills}/module.js +1 -0
  195. package/polyfills/module.js.map +1 -0
  196. package/runtime/core-aliases-early.d.ts +1 -0
  197. package/runtime/core-aliases-early.js +334 -0
  198. package/runtime/core-aliases-early.js.map +1 -0
  199. package/shims/angular-animations-stub.d.ts +8 -0
  200. package/shims/angular-animations-stub.js +14 -0
  201. package/shims/angular-animations-stub.js.map +1 -0
  202. package/{dist/shims → shims}/node-module.js +3 -2
  203. package/shims/node-module.js.map +1 -0
  204. package/{dist/shims → shims}/react-reconciler-constants.js +2 -1
  205. package/shims/react-reconciler-constants.js.map +1 -0
  206. package/{dist/shims → shims}/react-reconciler.js +1 -0
  207. package/shims/react-reconciler.js.map +1 -0
  208. package/{dist/shims → shims}/set-value.js +5 -1
  209. package/shims/set-value.js.map +1 -0
  210. package/transformers/NativeClass/index.d.ts +2 -0
  211. package/transformers/NativeClass/index.js +222 -0
  212. package/transformers/NativeClass/index.js.map +1 -0
  213. package/dist/configuration/angular.js +0 -30
  214. package/dist/configuration/base.d.ts +0 -4
  215. package/dist/configuration/base.js +0 -386
  216. package/dist/configuration/vue.js +0 -45
  217. package/dist/helpers/css-tree.js +0 -21
  218. package/dist/helpers/flavor.js +0 -40
  219. package/dist/helpers/global-defines.js +0 -20
  220. package/dist/helpers/main-entry-hmr-includes.d.ts +0 -1
  221. package/dist/helpers/main-entry-hmr-includes.js +0 -18
  222. package/dist/helpers/main-entry.d.ts +0 -5
  223. package/dist/helpers/main-entry.js +0 -82
  224. package/dist/helpers/package-platform-aliases.d.ts +0 -4
  225. package/dist/helpers/preserve-imports.js +0 -19
  226. package/dist/helpers/resolver.d.ts +0 -4
  227. package/dist/helpers/ts-config-paths.d.ts +0 -4
  228. package/dist/hmr/client-vue.d.ts +0 -6
  229. package/dist/hmr/client-vue.js +0 -585
  230. package/dist/hmr/component-tracker.d.ts +0 -23
  231. package/dist/hmr/component-tracker.js +0 -193
  232. package/dist/hmr/message-handler.d.ts +0 -1
  233. package/dist/hmr/message-handler.js +0 -590
  234. package/dist/hmr/nsv-hooks.d.ts +0 -2
  235. package/dist/hmr/nsv-hooks.js +0 -481
  236. package/dist/hmr/plugins/index.d.ts +0 -1
  237. package/dist/hmr/plugins/index.js +0 -16
  238. package/dist/hmr/plugins/plugin-vue.d.ts +0 -2
  239. package/dist/hmr/plugins/websocket-vue.d.ts +0 -2
  240. package/dist/hmr/plugins/websocket-vue.js +0 -911
  241. package/dist/hmr/runtime-vue.d.ts +0 -13
  242. package/dist/hmr/runtime-vue.js +0 -2306
  243. package/dist/hmr/types.d.ts +0 -24
  244. package/dist/hmr/types.js +0 -2
  245. package/dist/transformers/NativeClass/index.d.ts +0 -5
  246. package/dist/transformers/NativeClass/index.js +0 -46
  247. /package/{dist/helpers → helpers}/commonjs-plugins.d.ts +0 -0
  248. /package/{dist/helpers → helpers}/css-tree.d.ts +0 -0
  249. /package/{dist/helpers → helpers}/dynamic-import-plugin.d.ts +0 -0
  250. /package/{dist/helpers → helpers}/external-configs.d.ts +0 -0
  251. /package/{dist/helpers → helpers}/module-resolution.d.ts +0 -0
  252. /package/{dist/helpers → helpers}/nativescript-package-resolver.d.ts +0 -0
  253. /package/{dist/helpers → helpers}/preserve-imports.d.ts +0 -0
  254. /package/{dist/helpers → helpers}/project.d.ts +0 -0
  255. /package/{dist/helpers → helpers}/utils.d.ts +0 -0
  256. /package/{dist/helpers → helpers}/workers.d.ts +0 -0
  257. /package/{dist/hmr → hmr/client}/css-handler.d.ts +0 -0
  258. /package/{dist/polyfills → polyfills}/mdn-data-at-rules.d.ts +0 -0
  259. /package/{dist/polyfills → polyfills}/mdn-data-properties.d.ts +0 -0
  260. /package/{dist/polyfills → polyfills}/mdn-data-syntaxes.d.ts +0 -0
  261. /package/{dist/polyfills → polyfills}/module.d.ts +0 -0
  262. /package/{dist/shims → shims}/node-module.d.ts +0 -0
  263. /package/{dist/shims → shims}/react-reconciler-constants.d.ts +0 -0
  264. /package/{dist/shims → shims}/react-reconciler.d.ts +0 -0
  265. /package/{dist/shims → shims}/set-value.d.ts +0 -0
@@ -1,2306 +0,0 @@
1
- // Vue HMR Runtime Integration for NativeScript
2
- // Clean implementation replacing corrupted content
3
- import componentTracker from './component-tracker';
4
- const VERBOSE = true;
5
- // Track deferred update attempts per instance to avoid infinite loops
6
- const __pendingUpdateAttempts = new WeakMap();
7
- const MAX_DEFER_ATTEMPTS = 8;
8
- const BASE_DEFER_MS = 16; // ~1 frame
9
- // Microtask and frame schedulers for consistent timing across runtimes
10
- function scheduleMicrotask(fn) {
11
- try {
12
- if (typeof globalThis.queueMicrotask === 'function')
13
- return void globalThis.queueMicrotask(fn);
14
- }
15
- catch { }
16
- try {
17
- Promise.resolve().then(fn);
18
- }
19
- catch {
20
- setTimeout(fn, 0);
21
- }
22
- }
23
- function scheduleNextFrame(fn) {
24
- try {
25
- const raf = globalThis.requestAnimationFrame;
26
- if (typeof raf === 'function')
27
- return void raf(() => fn());
28
- }
29
- catch { }
30
- setTimeout(fn, 16);
31
- }
32
- function resolveNSView(el) {
33
- let view = null;
34
- let nativeView = null;
35
- try {
36
- if (el && typeof el === 'object') {
37
- // Method 1: Direct NativeScript view
38
- if (el.nativeViewProtected) {
39
- view = el;
40
- nativeView = el.nativeViewProtected;
41
- }
42
- else if (el.nativeView) {
43
- nativeView = el.nativeView;
44
- view = el.view || el; // Use el as view if no separate view property
45
- }
46
- // Method 2: NSVElement wrapper
47
- else if (el.view && el.view.nativeViewProtected) {
48
- view = el.view;
49
- nativeView = el.view.nativeViewProtected;
50
- }
51
- else if (el.view) {
52
- view = el.view;
53
- nativeView = view.nativeViewProtected || view.nativeView || null;
54
- }
55
- // Method 3: Check if el itself is a native view that we need to wrap
56
- else if (el._nativeView || el.__native) {
57
- nativeView = el._nativeView || el.__native;
58
- view = el; // el is the wrapper
59
- }
60
- // Method 4: Check parent node navigation
61
- else if (el.parentNode) {
62
- try {
63
- const p = el.parentNode;
64
- if (p) {
65
- if (p.nativeViewProtected) {
66
- view = p;
67
- nativeView = p.nativeViewProtected;
68
- }
69
- else if (p.view && p.view.nativeViewProtected) {
70
- view = p.view;
71
- nativeView = p.view.nativeViewProtected;
72
- }
73
- else if (p.nativeView) {
74
- nativeView = p.nativeView;
75
- view = p.view || p;
76
- }
77
- }
78
- }
79
- catch { }
80
- }
81
- // Method 5: Try to find NativeScript view from iOS/Android native objects
82
- else if (typeof el.ios !== 'undefined' || typeof el.android !== 'undefined') {
83
- // el might be a native view directly, try to find the wrapper
84
- nativeView = el;
85
- // Look for ViewBase wrapper in parent hierarchy or references
86
- try {
87
- if (el._owner) {
88
- view = el._owner;
89
- }
90
- else if (el.__owner) {
91
- view = el.__owner;
92
- }
93
- }
94
- catch { }
95
- }
96
- }
97
- }
98
- catch { }
99
- const hasNativeView = !!nativeView;
100
- let suspendCount;
101
- let isLoaded;
102
- try {
103
- const v = view || el;
104
- if (v && typeof v === 'object') {
105
- suspendCount = v._suspendNativeUpdatesCount;
106
- const field = v._isLoaded;
107
- const getter = v.isLoaded;
108
- isLoaded = typeof field === 'boolean' ? field : (typeof getter === 'boolean' ? getter : undefined);
109
- }
110
- }
111
- catch { }
112
- const isRootView = !!(view && view.mIsRootView);
113
- return { el, view, nativeView, hasNativeView, isRootView, suspendCount, isLoaded };
114
- }
115
- // Probe multiple likely locations on a component instance to find an NS view quickly after updates
116
- function findNSViewFromInternal(internal) {
117
- const candidates = [];
118
- try {
119
- const ins = internal || {};
120
- const vnode = ins.vnode;
121
- const proxy = ins.proxy;
122
- const subTree = ins.subTree;
123
- // Add candidates in order of preference - prioritize NativeScript elements
124
- if (proxy && proxy.$el) {
125
- const el = proxy.$el;
126
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
127
- candidates.unshift(el); // Prioritize NSVElement
128
- }
129
- else {
130
- candidates.push(el);
131
- }
132
- }
133
- if (vnode && vnode.el) {
134
- const el = vnode.el;
135
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
136
- candidates.unshift(el); // Prioritize NSVElement
137
- }
138
- else {
139
- candidates.push(el);
140
- }
141
- }
142
- if (subTree && subTree.el) {
143
- const el = subTree.el;
144
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
145
- candidates.unshift(el); // Prioritize NSVElement
146
- }
147
- else {
148
- candidates.push(el);
149
- }
150
- }
151
- // Check subTree component hierarchy
152
- if (subTree && subTree.component && subTree.component.vnode) {
153
- const c = subTree.component;
154
- if (c.vnode && c.vnode.el) {
155
- const el = c.vnode.el;
156
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
157
- candidates.unshift(el); // Prioritize NSVElement
158
- }
159
- else {
160
- candidates.push(el);
161
- }
162
- }
163
- if (c.subTree && c.subTree.el) {
164
- const el = c.subTree.el;
165
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
166
- candidates.unshift(el); // Prioritize NSVElement
167
- }
168
- else {
169
- candidates.push(el);
170
- }
171
- }
172
- }
173
- // Also peek one level deeper through children arrays if present
174
- try {
175
- const st = subTree;
176
- const ch = st && (st.children || st.child);
177
- if (Array.isArray(ch)) {
178
- for (const it of ch) {
179
- if (!it || typeof it !== 'object')
180
- continue;
181
- try {
182
- if (it.el) {
183
- const el = it.el;
184
- if (el && el.constructor && el.constructor.name === 'NSVElement') {
185
- candidates.unshift(el); // Prioritize NSVElement
186
- }
187
- else {
188
- candidates.push(el);
189
- }
190
- }
191
- }
192
- catch { }
193
- try {
194
- if (it.component && it.component.vnode && it.component.vnode.el)
195
- candidates.push(it.component.vnode.el);
196
- }
197
- catch { }
198
- try {
199
- if (it.component && it.component.subTree && it.component.subTree.el)
200
- candidates.push(it.component.subTree.el);
201
- }
202
- catch { }
203
- }
204
- }
205
- }
206
- catch { }
207
- // Add the internal instance itself as a candidate only if it might be useful
208
- if (ins && typeof ins === 'object' && !candidates.length) {
209
- candidates.push(ins);
210
- }
211
- }
212
- catch { }
213
- if (VERBOSE && candidates.length > 0) {
214
- console.info('[ns-hmr][vue-runtime] findNSViewFromInternal candidates:', {
215
- count: candidates.length,
216
- types: candidates.map(c => c?.constructor?.name || typeof c).slice(0, 5)
217
- });
218
- }
219
- // Evaluate in order; return first with a nativeView
220
- for (const el of candidates) {
221
- try {
222
- const info = resolveNSView(el);
223
- if (VERBOSE) {
224
- console.info('[ns-hmr][vue-runtime] candidate evaluation:', {
225
- elType: el?.constructor?.name || typeof el,
226
- hasNativeView: info.hasNativeView,
227
- hasView: !!info.view,
228
- viewType: info.view?.constructor?.name
229
- });
230
- }
231
- if (info && info.hasNativeView) {
232
- if (VERBOSE)
233
- console.info('[ns-hmr][vue-runtime] Found valid candidate with native view');
234
- return { el, info };
235
- }
236
- }
237
- catch { }
238
- }
239
- // Fallback to first candidate if any
240
- const first = candidates.length ? candidates[0] : null;
241
- const info = resolveNSView(first);
242
- if (VERBOSE) {
243
- console.info('[ns-hmr][vue-runtime] Using fallback candidate:', {
244
- hasFirst: !!first,
245
- firstType: first?.constructor?.name || typeof first,
246
- hasNativeView: info.hasNativeView,
247
- hasView: !!info.view
248
- });
249
- }
250
- return { el: first, info };
251
- }
252
- function registerExistingComponents(runtime) {
253
- try {
254
- if (VERBOSE)
255
- console.info('[ns-hmr][vue-runtime] Registering existing components with HMR runtime');
256
- let registeredCount = 0;
257
- // Method 1: Use component tracker
258
- const allInstances = componentTracker.getAllInstances();
259
- for (const [id, instances] of allInstances) {
260
- try {
261
- // Create record for this component type if not already recorded
262
- if (typeof runtime.createRecord === 'function' && typeof runtime.isRecorded === 'function') {
263
- if (!runtime.isRecorded(id)) {
264
- // Get component definition from first instance
265
- const firstInstance = Array.from(instances)[0];
266
- const componentDef = firstInstance?.$?.type || firstInstance?.type || {};
267
- runtime.createRecord(id, componentDef);
268
- if (VERBOSE)
269
- console.info('[ns-hmr][vue-runtime] Created record for component:', id);
270
- }
271
- }
272
- // Register all instances of this component
273
- if (typeof runtime.registerInstance === 'function') {
274
- for (const instance of instances) {
275
- runtime.registerInstance(id, instance);
276
- registeredCount++;
277
- }
278
- }
279
- }
280
- catch (e) {
281
- if (VERBOSE)
282
- console.warn('[ns-hmr][vue-runtime] Failed to register component:', id, e?.message);
283
- }
284
- }
285
- // Method 2: Bridge with fallback runtime records (handle the disconnect)
286
- try {
287
- const fallbackRuntime = runtime;
288
- if (fallbackRuntime && fallbackRuntime.map) {
289
- let fallbackCount = 0;
290
- const records = fallbackRuntime.map;
291
- if (records && typeof records.forEach === 'function') {
292
- // Map object with forEach
293
- records.forEach((instances, id) => {
294
- fallbackCount++;
295
- if (VERBOSE)
296
- console.info('[ns-hmr][vue-runtime] Found fallback record:', id, 'instances:', instances ? instances.length : 0);
297
- });
298
- }
299
- else if (records && typeof records === 'object') {
300
- // Plain object
301
- for (const [id, instances] of Object.entries(records)) {
302
- fallbackCount++;
303
- if (VERBOSE)
304
- console.info('[ns-hmr][vue-runtime] Found fallback record:', id, 'instances:', instances?.length || 0);
305
- }
306
- }
307
- if (VERBOSE)
308
- console.info('[ns-hmr][vue-runtime] Fallback runtime has', fallbackCount, 'records');
309
- }
310
- }
311
- catch (e) {
312
- if (VERBOSE)
313
- console.warn('[ns-hmr][vue-runtime] Failed to analyze fallback runtime records:', e?.message);
314
- }
315
- if (VERBOSE)
316
- console.info('[ns-hmr][vue-runtime] Registered existing components:', {
317
- componentTypes: allInstances.size,
318
- instanceCount: registeredCount
319
- });
320
- }
321
- catch (e) {
322
- if (VERBOSE)
323
- console.warn('[ns-hmr][vue-runtime] Failed to register existing components:', e?.message);
324
- }
325
- }
326
- function getComponentIdFromInternal(internal) {
327
- try {
328
- // Try to get component ID from various locations
329
- const type = internal?.type || internal?.vnode?.type;
330
- if (type) {
331
- // Check for __hmrId (Vue 3 HMR component ID)
332
- if (type.__hmrId)
333
- return type.__hmrId;
334
- // Check for __file (component file path)
335
- if (type.__file)
336
- return type.__file;
337
- // Check for name
338
- if (type.name)
339
- return type.name;
340
- // Check for _name (internal Vue name)
341
- if (type._name)
342
- return type._name;
343
- }
344
- // Check component instance for name
345
- if (internal?.proxy?.$options?.name)
346
- return internal.proxy.$options.name;
347
- if (internal?.proxy?.$options?.__file)
348
- return internal.proxy.$options.__file;
349
- // Fallback to component constructor name
350
- if (internal?.constructor?.name && internal.constructor.name !== 'Object') {
351
- return internal.constructor.name;
352
- }
353
- return null;
354
- }
355
- catch {
356
- return null;
357
- }
358
- }
359
- function instanceHasFrameOrPage(internal) {
360
- try {
361
- const q = [];
362
- const push = (n) => { if (n && typeof n === 'object')
363
- q.push(n); };
364
- push(internal?.subTree || internal?.vnode);
365
- let seen = 0;
366
- while (q.length && seen < 50) {
367
- const n = q.shift();
368
- seen++;
369
- try {
370
- const t = (n && (n.type || n.component?.type)) || null;
371
- const name = t && ((t.__name || t.name || '').toString().toLowerCase());
372
- if (name === 'frame' || name === 'page')
373
- return true;
374
- }
375
- catch { }
376
- try {
377
- if (n.component)
378
- push(n.component.subTree);
379
- }
380
- catch { }
381
- try {
382
- const ch = (n.children || n.child);
383
- if (Array.isArray(ch))
384
- for (const c of ch)
385
- push(c);
386
- else
387
- push(ch);
388
- }
389
- catch { }
390
- }
391
- }
392
- catch { }
393
- return false;
394
- }
395
- // Cache resolved views per instance to avoid inconsistent lookups
396
- const instanceViewCache = new WeakMap();
397
- // Cache the working instance per component ID to ensure consistency
398
- const workingInstanceCache = new Map();
399
- // Global registry to track the current working instance being processed
400
- let currentWorkingInstance = null;
401
- let currentComponentId = null;
402
- function setCurrentWorkingInstance(instance, componentId) {
403
- currentWorkingInstance = instance;
404
- currentComponentId = componentId || null;
405
- if (VERBOSE && componentId) {
406
- console.info('[ns-hmr][vue-runtime] Set current working instance for:', componentId);
407
- }
408
- }
409
- function getCurrentWorkingInstance() {
410
- return currentWorkingInstance;
411
- }
412
- function isNSViewReady(instance, componentId) {
413
- try {
414
- if (VERBOSE) {
415
- console.info('[ns-hmr][vue-runtime] isNSViewReady called with:', {
416
- hasInstance: !!instance,
417
- instanceType: instance?.constructor?.name,
418
- componentId: componentId || 'none',
419
- hasCachedWorking: componentId ? workingInstanceCache.has(componentId) : false,
420
- hasCurrentWorking: !!currentWorkingInstance
421
- });
422
- }
423
- // Priority 1: If we have a cached working instance for this component, use it
424
- if (componentId && workingInstanceCache.has(componentId)) {
425
- const workingInstance = workingInstanceCache.get(componentId);
426
- if (workingInstance && workingInstance !== instance) {
427
- if (VERBOSE) {
428
- console.info('[ns-hmr][vue-runtime] Using cached working instance for component:', componentId);
429
- }
430
- instance = workingInstance;
431
- }
432
- }
433
- // Priority 2: If no cached instance but we have a current working instance, try it
434
- else if (currentWorkingInstance && currentWorkingInstance !== instance) {
435
- if (VERBOSE) {
436
- console.info('[ns-hmr][vue-runtime] Trying current working instance as fallback');
437
- }
438
- // Test the current working instance first
439
- const testFound = findNSViewFromInternal(currentWorkingInstance);
440
- if (testFound.info?.hasNativeView) {
441
- if (VERBOSE) {
442
- console.info('[ns-hmr][vue-runtime] Current working instance is valid, using it');
443
- }
444
- instance = currentWorkingInstance;
445
- // Cache it for this component if we have a component ID
446
- if (componentId) {
447
- workingInstanceCache.set(componentId, currentWorkingInstance);
448
- }
449
- }
450
- }
451
- let cached = instanceViewCache.get(instance);
452
- if (!cached) {
453
- const found = findNSViewFromInternal(instance);
454
- if (found.info?.hasNativeView) {
455
- instanceViewCache.set(instance, found);
456
- cached = found;
457
- // Cache this as the working instance for this component
458
- if (componentId && !workingInstanceCache.has(componentId)) {
459
- workingInstanceCache.set(componentId, instance);
460
- if (VERBOSE) {
461
- console.info('[ns-hmr][vue-runtime] Cached working instance for component:', componentId);
462
- }
463
- }
464
- }
465
- }
466
- const hasNativeView = cached?.info?.hasNativeView || false;
467
- const view = cached?.info?.view;
468
- if (VERBOSE) {
469
- console.info('[ns-hmr][vue-runtime] isNSViewReady check:', {
470
- hasEl: !!cached?.el,
471
- elType: cached?.el?.constructor?.name,
472
- hasNativeView,
473
- suspendCount: cached?.info?.suspendCount,
474
- isLoaded: cached?.info?.isLoaded,
475
- view: !!view,
476
- viewType: view?.constructor?.name,
477
- fromCache: instanceViewCache.has(instance),
478
- usingWorkingInstance: componentId && workingInstanceCache.has(componentId),
479
- componentId: componentId || 'none'
480
- });
481
- }
482
- if (!hasNativeView) {
483
- if (VERBOSE)
484
- console.info('[ns-hmr][vue-runtime] Not ready: no native view');
485
- return false;
486
- }
487
- if (typeof cached?.info?.suspendCount === 'number' && cached.info.suspendCount !== 0) {
488
- if (VERBOSE)
489
- console.info('[ns-hmr][vue-runtime] Not ready: suspended', { suspendCount: cached.info.suspendCount });
490
- return false;
491
- }
492
- if (typeof cached?.info?.isLoaded === 'boolean' && cached.info.isLoaded === false) {
493
- if (VERBOSE)
494
- console.info('[ns-hmr][vue-runtime] Not ready: not loaded');
495
- return false;
496
- }
497
- if (VERBOSE)
498
- console.info('[ns-hmr][vue-runtime] View is ready for update');
499
- }
500
- catch (e) {
501
- if (VERBOSE)
502
- console.warn('[ns-hmr][vue-runtime] isNSViewReady failed:', e?.message);
503
- return false;
504
- }
505
- return true;
506
- }
507
- const __postUpdateStabilized = new WeakSet();
508
- const __postUpdateFollowed = new WeakSet();
509
- // Cache the last resolved element for an internal instance to help stabilization find it later
510
- const __lastResolvedEl = new WeakMap();
511
- // Guard to avoid blasting global layout more than once per instance
512
- const __globalLayoutRequested = new WeakSet();
513
- function stabilizeNativeLayout(internal, attempt = 1) {
514
- try {
515
- if (!internal || __postUpdateStabilized.has(internal))
516
- return;
517
- // Prefer the last-resolved element if we have one; otherwise probe fresh
518
- let cached = __lastResolvedEl.get(internal) || null;
519
- let probe = cached || findNSViewFromInternal(internal);
520
- let el = probe.el;
521
- let info = probe.info;
522
- // If still no native view, attempt to walk up a couple of parent components to find a parent view
523
- let parentInfo = null;
524
- if (!info?.hasNativeView) {
525
- try {
526
- let p = internal.parent;
527
- let hops = 0;
528
- while (p && hops < 3 && !(parentInfo && parentInfo.hasNativeView)) {
529
- try {
530
- const pp = findNSViewFromInternal(p);
531
- if (pp && pp.info && pp.info.hasNativeView) {
532
- parentInfo = pp.info;
533
- break;
534
- }
535
- }
536
- catch { }
537
- p = p.parent;
538
- hops++;
539
- }
540
- }
541
- catch { }
542
- }
543
- const v = info.view;
544
- const nv = info.nativeView;
545
- // If this instance has a working native view, set it as current working instance
546
- if (info?.hasNativeView && probe.el) {
547
- setCurrentWorkingInstance(internal);
548
- if (VERBOSE) {
549
- console.info('[ns-hmr][vue-runtime] stabilizeNativeLayout found working instance');
550
- }
551
- }
552
- if (VERBOSE) {
553
- try {
554
- const name = v && v.constructor ? v.constructor.name : undefined;
555
- const snap = {
556
- attempt,
557
- hasView: !!v,
558
- hasNativeView: !!nv,
559
- viewType: name,
560
- hasVNode: !!(internal && internal.vnode),
561
- hasSubTree: !!(internal && internal.subTree),
562
- parentHasNativeView: !!(parentInfo && parentInfo.hasNativeView),
563
- };
564
- console.info('[ns-hmr][vue-runtime] stabilizeNativeLayout', snap);
565
- }
566
- catch { }
567
- }
568
- // If not yet attached or wrapper view not yet resolved, retry shortly (up to 5 attempts)
569
- if ((!nv || !v) && attempt < 5) {
570
- // On the third attempt, try a remedial internal.update once to nudge vnode attachment
571
- if (attempt === 3) {
572
- try {
573
- typeof internal?.update === 'function' && internal.update();
574
- }
575
- catch { }
576
- }
577
- // First a microtask, then a frame on subsequent attempts
578
- if (attempt === 1) {
579
- return void scheduleMicrotask(() => stabilizeNativeLayout(internal, attempt + 1));
580
- }
581
- return void scheduleNextFrame(() => stabilizeNativeLayout(internal, attempt + 1));
582
- }
583
- // Light-touch layout refresh
584
- let did = false;
585
- try {
586
- if (v && typeof v.requestLayout === 'function') {
587
- v.requestLayout();
588
- did = true;
589
- }
590
- }
591
- catch { }
592
- if (!did && nv) {
593
- // Try common NativeScript native view layout methods
594
- try {
595
- if (typeof nv.setNeedsLayout === 'function') {
596
- nv.setNeedsLayout();
597
- did = true;
598
- }
599
- }
600
- catch { }
601
- try {
602
- if (!did && typeof nv.setNeedsDisplay === 'function') {
603
- nv.setNeedsDisplay();
604
- did = true;
605
- }
606
- }
607
- catch { }
608
- try {
609
- if (!did && typeof nv.requestLayout === 'function') {
610
- nv.requestLayout();
611
- did = true;
612
- }
613
- }
614
- catch { }
615
- try {
616
- if (!did && typeof nv.invalidate === 'function') {
617
- nv.invalidate();
618
- did = true;
619
- }
620
- }
621
- catch { }
622
- // For iOS views
623
- try {
624
- if (!did && typeof nv.setNeedsLayout === 'function') {
625
- nv.setNeedsLayout();
626
- did = true;
627
- }
628
- }
629
- catch { }
630
- try {
631
- if (!did && typeof nv.layoutIfNeeded === 'function') {
632
- nv.layoutIfNeeded();
633
- did = true;
634
- }
635
- }
636
- catch { }
637
- }
638
- // Page-level fallback: request layout on the nearest Page to flush subtree
639
- if (!did) {
640
- try {
641
- const candidateView = v || (parentInfo && parentInfo.view) || null;
642
- const page = candidateView && (candidateView.page || candidateView._page);
643
- if (page && typeof page.requestLayout === 'function') {
644
- page.requestLayout();
645
- did = true;
646
- }
647
- }
648
- catch { }
649
- }
650
- // If we didn't find a child view but a parent has a native view, request layout there
651
- if (!did && parentInfo && parentInfo.nativeView) {
652
- try {
653
- const pnv = parentInfo.nativeView;
654
- if (typeof pnv.setNeedsLayout === 'function') {
655
- pnv.setNeedsLayout();
656
- did = true;
657
- }
658
- else if (typeof pnv.requestLayout === 'function') {
659
- pnv.requestLayout();
660
- did = true;
661
- }
662
- }
663
- catch { }
664
- }
665
- // Minor CSS state poke if layout wasn’t available
666
- if (!did) {
667
- try {
668
- if (v && typeof v._onCssStateChange === 'function') {
669
- v._onCssStateChange();
670
- did = true;
671
- }
672
- }
673
- catch { }
674
- }
675
- // As a final fallback before giving up: request layout on topmost Frame or root view once
676
- if (!did && attempt >= 4 && !__globalLayoutRequested.has(internal)) {
677
- try {
678
- const req = globalThis.require;
679
- const core = req && (() => { try {
680
- return req('@nativescript/core');
681
- }
682
- catch {
683
- return null;
684
- } })();
685
- if (core) {
686
- let flushed = false;
687
- try {
688
- const Frame = core.Frame;
689
- const top = Frame && (typeof Frame.topmost === 'function' ? Frame.topmost() : null);
690
- if (top) {
691
- if (typeof top.requestLayout === 'function') {
692
- top.requestLayout();
693
- flushed = true;
694
- }
695
- else if (top.nativeViewProtected && typeof top.nativeViewProtected.setNeedsLayout === 'function') {
696
- top.nativeViewProtected.setNeedsLayout();
697
- flushed = true;
698
- }
699
- else if (top.nativeView && typeof top.nativeView.requestLayout === 'function') {
700
- top.nativeView.requestLayout();
701
- flushed = true;
702
- }
703
- }
704
- }
705
- catch { }
706
- if (!flushed) {
707
- try {
708
- const App = core.Application || core.app || core.application;
709
- const root = App && (typeof App.getRootView === 'function' ? App.getRootView() : null);
710
- if (root) {
711
- if (typeof root.requestLayout === 'function') {
712
- root.requestLayout();
713
- flushed = true;
714
- }
715
- else if (root.nativeViewProtected && typeof root.nativeViewProtected.setNeedsLayout === 'function') {
716
- root.nativeViewProtected.setNeedsLayout();
717
- flushed = true;
718
- }
719
- else if (root.nativeView && typeof root.nativeView.requestLayout === 'function') {
720
- root.nativeView.requestLayout();
721
- flushed = true;
722
- }
723
- }
724
- }
725
- catch { }
726
- }
727
- if (VERBOSE)
728
- console.info('[ns-hmr][vue-runtime] global layout fallback', { flushed });
729
- if (flushed)
730
- did = true;
731
- }
732
- }
733
- catch { }
734
- try {
735
- __globalLayoutRequested.add(internal);
736
- }
737
- catch { }
738
- }
739
- // Only mark stabilized when wrapper view is present or we exhausted retries
740
- if (did || attempt >= 5) {
741
- if (v || attempt >= 5) {
742
- try {
743
- __postUpdateStabilized.add(internal);
744
- }
745
- catch { }
746
- }
747
- else {
748
- // Schedule one final microtask check before giving up
749
- scheduleMicrotask(() => stabilizeNativeLayout(internal, Math.min(attempt + 1, 5)));
750
- }
751
- }
752
- }
753
- catch { }
754
- }
755
- function scheduleDeferredUpdate(internal, reason) {
756
- try {
757
- const prev = __pendingUpdateAttempts.get(internal) || 0;
758
- const attempt = prev + 1;
759
- if (VERBOSE)
760
- console.info('[ns-hmr][vue-runtime] deferring update', { attempt, reason });
761
- if (attempt > MAX_DEFER_ATTEMPTS) {
762
- if (VERBOSE)
763
- console.warn('[ns-hmr][vue-runtime] max deferral attempts reached; giving up for this instance');
764
- return;
765
- }
766
- __pendingUpdateAttempts.set(internal, attempt);
767
- const delay = Math.min(BASE_DEFER_MS * attempt, 80);
768
- // Prefer nextTick when available, then timeout
769
- try {
770
- const req = globalThis.require;
771
- const vueMod = req && (() => { try {
772
- return req('vue');
773
- }
774
- catch {
775
- return null;
776
- } })();
777
- const nsv = req && (() => { try {
778
- return req('nativescript-vue');
779
- }
780
- catch {
781
- return null;
782
- } })();
783
- const nextTick = (vueMod && vueMod.nextTick) || (nsv && nsv.nextTick);
784
- if (VERBOSE)
785
- console.info('[ns-hmr][vue-runtime] scheduleDeferredUpdate nextTick found:', typeof nextTick === 'function');
786
- if (typeof nextTick === 'function') {
787
- return void nextTick(() => {
788
- try {
789
- setTimeout(() => { try {
790
- internal?.update && internal.update();
791
- }
792
- catch { } }, delay);
793
- }
794
- catch { }
795
- });
796
- }
797
- }
798
- catch { }
799
- setTimeout(() => { try {
800
- internal?.update && internal.update();
801
- }
802
- catch { } }, delay);
803
- }
804
- catch { }
805
- }
806
- function dumpRuntime(label, rt) {
807
- try {
808
- const g = globalThis;
809
- const hasRt = !!rt;
810
- const keys = rt && typeof rt === 'object' ? Object.keys(rt) : [];
811
- const map = rt && (rt.map || rt.records);
812
- const recordKeys = map && typeof map.keys === 'function' ? Array.from(map.keys()) : (map && typeof map === 'object' ? Object.keys(map) : []);
813
- const flags = {
814
- hasRuntime: hasRt,
815
- hasRerender: !!(rt && rt.rerender),
816
- hasReload: !!(rt && rt.reload),
817
- keys,
818
- recordCount: recordKeys ? recordKeys.length : 0,
819
- hooksApplied: !!g.__NS_VUE_HOOKS_APPLIED__,
820
- hasNSVue: !!(g.require && (() => { try {
821
- g.require('nativescript-vue');
822
- return true;
823
- }
824
- catch {
825
- return false;
826
- } })()),
827
- hasVue: !!(g.require && (() => { try {
828
- g.require('vue');
829
- return true;
830
- }
831
- catch {
832
- return false;
833
- } })()),
834
- };
835
- console.info(`[ns-hmr][vue-runtime] ${label}`, flags);
836
- }
837
- catch { }
838
- }
839
- export function initializeVueHMRRuntime() {
840
- return ensureVueHMRRuntimeEnhanced();
841
- }
842
- export function ensureVueHMRRuntimeEnhanced() {
843
- try {
844
- const g = global;
845
- let rt = g.__VUE_HMR_RUNTIME__;
846
- if (!rt) {
847
- if (VERBOSE)
848
- console.info('[ns-hmr][vue-runtime] Vue HMR runtime not present yet; attempting lazy init');
849
- // In ES modules mode, skip require() and use direct global access
850
- let Vue = null;
851
- // Try to get Vue from global namespace or require (NativeScript ES modules)
852
- try {
853
- Vue = g.Vue || g.__VUE__;
854
- if (Vue) {
855
- if (VERBOSE)
856
- console.info('[ns-hmr][vue-runtime] Vue module loaded via globals:', { hasVue: !!Vue, keys: Vue ? Object.keys(Vue).slice(0, 10) : [] });
857
- }
858
- else {
859
- if (VERBOSE)
860
- console.info('[ns-hmr][vue-runtime] Vue not found in global namespace, checking require fallback');
861
- // Only try require() if globals failed and we're sure it's available
862
- const req = globalThis.require;
863
- if (req && typeof req === 'function') {
864
- try {
865
- Vue = req('vue');
866
- if (VERBOSE)
867
- console.info('[ns-hmr][vue-runtime] Vue module loaded via require:', { hasVue: !!Vue, keys: Vue ? Object.keys(Vue).slice(0, 10) : [] });
868
- }
869
- catch (e) {
870
- if (VERBOSE)
871
- console.warn('[ns-hmr][vue-runtime] Vue require failed:', e.message);
872
- }
873
- }
874
- }
875
- // Force Vue HMR runtime initialization if not already done
876
- if (Vue && !g.__VUE_HMR_RUNTIME__) {
877
- // Check if Vue has HMR functionality
878
- if (Vue.createApp && !g.__VUE_HMR_RUNTIME__) {
879
- if (VERBOSE)
880
- console.info('[ns-hmr][vue-runtime] Manually initializing Vue HMR runtime');
881
- // Create a minimal HMR runtime that Vue can recognize
882
- g.__VUE_HMR_RUNTIME__ = {
883
- createRecord: () => true,
884
- reload: () => { },
885
- rerender: () => { },
886
- updateStyle: () => { },
887
- isRecorded: () => false,
888
- map: new Map()
889
- };
890
- if (VERBOSE)
891
- console.info('[ns-hmr][vue-runtime] Created minimal Vue HMR runtime');
892
- }
893
- }
894
- }
895
- catch (e) {
896
- if (VERBOSE)
897
- console.warn('[ns-hmr][vue-runtime] Vue module loading failed:', e.message || String(e));
898
- }
899
- // Also try to require nativescript-vue if available
900
- try {
901
- const req = globalThis.require;
902
- if (req && typeof req === 'function') {
903
- try {
904
- req('nativescript-vue');
905
- }
906
- catch { }
907
- }
908
- }
909
- catch { }
910
- rt = g.__VUE_HMR_RUNTIME__;
911
- if (!rt) {
912
- if (VERBOSE) {
913
- console.info('[ns-hmr][vue-runtime] Vue HMR runtime still unavailable after lazy init');
914
- dumpRuntime('after-lazy-init', rt);
915
- console.info('[ns-hmr][vue-runtime] Using minimal fallback Vue HMR runtime (local only)');
916
- }
917
- try {
918
- rt = installFallbackHMRRuntime();
919
- // In ES modules mode, enhance the fallback with ES modules detection
920
- if (rt && !g.__VUE_HMR_RUNTIME__) {
921
- // Set global reference for ES modules compatibility
922
- g.__VUE_HMR_RUNTIME__ = rt;
923
- if (VERBOSE)
924
- console.info('[ns-hmr][vue-runtime] Set global Vue HMR runtime for ES modules compatibility');
925
- // Try to detect Vue through NativeScript ES modules
926
- try {
927
- const detectVueInESModules = () => {
928
- // In NativeScript ES modules environment, look for Vue in globals
929
- const possibleVue = g.Vue || g.__VUE__ || g.vue;
930
- if (possibleVue && possibleVue.createApp) {
931
- if (VERBOSE)
932
- console.info('[ns-hmr][vue-runtime] Found Vue in ES modules global space');
933
- return possibleVue;
934
- }
935
- return null;
936
- };
937
- const esVue = detectVueInESModules();
938
- if (esVue) {
939
- // Enhance runtime with ES modules Vue reference
940
- rt.__esModulesVue = esVue;
941
- if (VERBOSE)
942
- console.info('[ns-hmr][vue-runtime] Enhanced runtime with ES modules Vue reference');
943
- }
944
- }
945
- catch (esErr) {
946
- if (VERBOSE)
947
- console.warn('[ns-hmr][vue-runtime] ES modules Vue detection failed:', esErr);
948
- }
949
- }
950
- /* IMPORTANT: do NOT assign to global to avoid blocking real runtime later */
951
- }
952
- catch (e) {
953
- console.warn('[ns-hmr][vue-runtime] Failed to create fallback runtime:', e?.message || String(e));
954
- return null;
955
- }
956
- }
957
- }
958
- if (VERBOSE)
959
- dumpRuntime('before-enhance', rt);
960
- if (rt.__nsEnhanced)
961
- return rt;
962
- const enhanced = enhanceVueHMRRuntime(rt);
963
- enhanced.__nsEnhanced = true;
964
- if (VERBOSE)
965
- dumpRuntime('after-enhance', enhanced);
966
- // Trigger hook setup now that Vue is available
967
- try {
968
- const g = globalThis;
969
- if (g.__ns_attemptHookSetup) {
970
- g.__ns_attemptHookSetup();
971
- }
972
- }
973
- catch { }
974
- // Register any existing components that were tracked before HMR runtime was available
975
- try {
976
- registerExistingComponents(enhanced);
977
- }
978
- catch (e) {
979
- if (VERBOSE)
980
- console.warn('[ns-hmr][vue-runtime] Failed to register existing components:', e?.message);
981
- }
982
- return enhanced;
983
- }
984
- catch (error) {
985
- console.warn('[ns-hmr][vue-runtime] Error ensuring Vue HMR runtime:', error?.message);
986
- return null;
987
- }
988
- }
989
- function enhanceVueHMRRuntime(existingRuntime) {
990
- const enhanced = { ...existingRuntime };
991
- const originalReload = enhanced.reload;
992
- const originalRerender = enhanced.rerender;
993
- enhanced.reload = function (id, newDef) {
994
- if (VERBOSE)
995
- console.info('[ns-hmr][vue-runtime] Enhanced reload for:', id);
996
- try {
997
- if (originalReload)
998
- originalReload.call(this, id, newDef);
999
- handleNativeScriptComponentReload(id, newDef);
1000
- }
1001
- catch (error) {
1002
- console.warn('[ns-hmr][vue-runtime] Enhanced reload failed:', error?.message);
1003
- if (originalReload)
1004
- originalReload.call(this, id, newDef);
1005
- }
1006
- };
1007
- enhanced.rerender = function (id, newRender) {
1008
- if (VERBOSE)
1009
- console.info('[ns-hmr][vue-runtime] Enhanced rerender for:', id);
1010
- try {
1011
- try {
1012
- globalThis.__NS_LAST_RERENDER_ID__ = id;
1013
- }
1014
- catch { }
1015
- // Set current component ID for working instance tracking
1016
- currentComponentId = id;
1017
- if (originalRerender)
1018
- originalRerender.call(this, id, newRender);
1019
- try {
1020
- handleNativeScriptComponentRerender(id, newRender, enhanced);
1021
- }
1022
- catch { }
1023
- }
1024
- catch (error) {
1025
- console.warn('[ns-hmr][vue-runtime] Enhanced rerender failed:', error?.message);
1026
- if (originalRerender)
1027
- originalRerender.call(this, id, newRender);
1028
- }
1029
- finally {
1030
- // Clear the current component ID after processing
1031
- currentComponentId = null;
1032
- }
1033
- };
1034
- return enhanced;
1035
- }
1036
- function normalizeIdToFile(id) {
1037
- try {
1038
- let s = String(id || '');
1039
- s = s.split('?')[0];
1040
- s = s.replace(/\\/g, '/');
1041
- return s;
1042
- }
1043
- catch {
1044
- return id;
1045
- }
1046
- }
1047
- function installFallbackHMRRuntime() {
1048
- const records = new Map();
1049
- const api = {
1050
- __nsFallback: true,
1051
- map: records,
1052
- createRecord(id, initialDef) { const key = String(id); if (records.has(key))
1053
- return true; records.set(key, { def: initialDef || {}, instances: new Set() }); if (VERBOSE)
1054
- console.info('[ns-hmr][vue-runtime:fallback] createRecord', key); return true; },
1055
- isRecorded(id) { return records.has(String(id)); },
1056
- registerInstance(id, instance) { const key = String(id); if (!records.has(key))
1057
- this.createRecord(key, (instance && (instance.$?.type || instance.type)) || {}); const rec = records.get(key); rec.instances.add(instance); if (VERBOSE)
1058
- console.info('[ns-hmr][vue-runtime:fallback] registerInstance', key); },
1059
- rerender(id, newRender) {
1060
- const key = String(id);
1061
- const rec = records.get(key);
1062
- if (rec && rec.def) {
1063
- try {
1064
- rec.def.render = newRender;
1065
- }
1066
- catch { }
1067
- }
1068
- const targets = [];
1069
- if (rec)
1070
- targets.push(...Array.from(rec.instances));
1071
- try {
1072
- const file = normalizeIdToFile(key);
1073
- const more = componentTracker.findInstancesByFile(file);
1074
- for (const ins of more)
1075
- targets.push(ins);
1076
- }
1077
- catch { }
1078
- let applied = 0;
1079
- for (const ins of targets) {
1080
- try {
1081
- applyRenderAndTriggerWithId(ins, newRender, key);
1082
- applied++;
1083
- }
1084
- catch { }
1085
- }
1086
- if (applied === 0) {
1087
- try {
1088
- applied += tryPatchInstancesFromRootByFileSuffix(key, newRender);
1089
- }
1090
- catch { }
1091
- try {
1092
- applied += tryPatchInstancesFromRootByName(key, newRender, api);
1093
- }
1094
- catch { }
1095
- }
1096
- if (VERBOSE)
1097
- console.info('[ns-hmr][vue-runtime:fallback] rerender applied for', key, 'instances:', applied);
1098
- },
1099
- reload(id, newDef) { const key = String(id); const rec = records.get(key); if (rec) {
1100
- try {
1101
- Object.assign(rec.def || (rec.def = {}), newDef);
1102
- }
1103
- catch { }
1104
- } this.rerender(key, (newDef && newDef.render) ? newDef.render : (() => { })); if (VERBOSE)
1105
- console.info('[ns-hmr][vue-runtime:fallback] reload applied for', key); },
1106
- updateStyle() { },
1107
- };
1108
- return api;
1109
- }
1110
- function handleNativeScriptComponentReload(id, newDef) {
1111
- try {
1112
- if (VERBOSE)
1113
- console.info('[ns-hmr][vue-runtime] NativeScript component reload for:', id);
1114
- }
1115
- catch (error) {
1116
- if (VERBOSE)
1117
- console.warn('[ns-hmr][vue-runtime] NativeScript component reload failed:', error?.message);
1118
- }
1119
- }
1120
- function handleNativeScriptComponentRerender(id, newRender, runtime) {
1121
- try {
1122
- if (VERBOSE)
1123
- console.info('[ns-hmr][vue-runtime] NativeScript component rerender for:', id);
1124
- const map = runtime.map || runtime.records;
1125
- let record = null;
1126
- if (map) {
1127
- if (typeof map.get === 'function')
1128
- record = map.get(id) || null;
1129
- else if (map[id])
1130
- record = map[id];
1131
- }
1132
- // Let Vue runtime update instances; we just stabilize the root and any known instances after a tick
1133
- try {
1134
- scheduleMicrotask(() => { try {
1135
- const g = globalThis;
1136
- const root = g.__NS_VUE_ROOT_INSTANCE__;
1137
- if (root)
1138
- stabilizeNativeLayout(root.$ || root, 1);
1139
- }
1140
- catch { } });
1141
- }
1142
- catch { }
1143
- }
1144
- catch (error) {
1145
- if (VERBOSE)
1146
- console.warn('[ns-hmr][vue-runtime] NativeScript component rerender failed:', error?.message);
1147
- }
1148
- }
1149
- function baseFileSuffixesFromId(id) {
1150
- try {
1151
- const noQuery = String(id || '').split('?')[0].replace(/\\/g, '/');
1152
- const base = noQuery.split('/').pop() || '';
1153
- const relFromSrc = noQuery.replace(/^.*?\/src\//, '/src/');
1154
- const relNoLead = relFromSrc.replace(/^\//, '');
1155
- const suffixes = new Set();
1156
- if (base)
1157
- suffixes.add('/' + base);
1158
- if (relFromSrc)
1159
- suffixes.add(relFromSrc);
1160
- if (relNoLead)
1161
- suffixes.add('/' + relNoLead);
1162
- if (VERBOSE)
1163
- console.info('[ns-hmr][vue-runtime] baseFileSuffixesFromId', { id, suffixes: Array.from(suffixes) });
1164
- return Array.from(suffixes);
1165
- }
1166
- catch {
1167
- return [];
1168
- }
1169
- }
1170
- function getComponentType(obj) { try {
1171
- return (obj && (obj.$?.type || obj.type)) || null;
1172
- }
1173
- catch {
1174
- return null;
1175
- } }
1176
- function getComponentName(obj) { try {
1177
- const t = getComponentType(obj);
1178
- const n = (t && (t.__name || t.name)) || '';
1179
- return String(n || '').trim();
1180
- }
1181
- catch {
1182
- return '';
1183
- } }
1184
- function forceUpdateInstance(ins, componentId) {
1185
- try {
1186
- const internal = ins.$ || ins;
1187
- // If the underlying NativeScript view isn't ready (loading/suspended), defer the update
1188
- try {
1189
- const probe = findNSViewFromInternal(internal);
1190
- const el = probe.el;
1191
- const resolved = probe.info;
1192
- // If this instance has a working native view, set it as current working instance
1193
- if (resolved?.hasNativeView && el) {
1194
- setCurrentWorkingInstance(internal, componentId);
1195
- if (VERBOSE) {
1196
- console.info('[ns-hmr][vue-runtime] forceUpdateInstance found working instance');
1197
- }
1198
- }
1199
- // Cache last resolved element right away for stabilization to use soon after
1200
- try {
1201
- __lastResolvedEl.set(internal, { el, info: resolved });
1202
- }
1203
- catch { }
1204
- const suspendCount = resolved.suspendCount;
1205
- const isLoaded = resolved.isLoaded;
1206
- const isMounted = typeof internal?.isMounted === 'boolean' ? internal.isMounted : undefined;
1207
- const isSuspended = typeof suspendCount === 'number' && suspendCount !== 0;
1208
- // Require loaded when available to avoid re-entrant creation on Frame/Page
1209
- const elReady = isNSViewReady(el) && (typeof isLoaded === 'boolean' ? isLoaded === true : true);
1210
- // Decode NativeScript suspend flags for richer logs
1211
- let flagsInfo = undefined;
1212
- try {
1213
- if (typeof suspendCount === 'number') {
1214
- const LOADED = 1 << 20;
1215
- const NATIVEVIEW = 1 << 21;
1216
- const UISETUP = 1 << 22;
1217
- const FLAGS_MASK = LOADED | NATIVEVIEW | UISETUP;
1218
- const inc = suspendCount & ~FLAGS_MASK;
1219
- flagsInfo = {
1220
- suspendCount,
1221
- inc,
1222
- LOADED: (suspendCount & LOADED) !== 0,
1223
- NATIVEVIEW: (suspendCount & NATIVEVIEW) !== 0,
1224
- UISETUP: (suspendCount & UISETUP) !== 0,
1225
- };
1226
- }
1227
- }
1228
- catch { }
1229
- const notReady = (isMounted === false) || !elReady || isSuspended;
1230
- if (VERBOSE) {
1231
- try {
1232
- const elType = el && el.constructor ? el.constructor.name : (el ? typeof el : 'null');
1233
- console.info('[ns-hmr][vue-runtime] update-check', { isMounted, isLoaded, elReady, isSuspended, elType, hasNativeView: resolved.hasNativeView, isRootView: resolved.isRootView, flags: flagsInfo });
1234
- }
1235
- catch { }
1236
- }
1237
- if (notReady) {
1238
- if (VERBOSE)
1239
- console.info('[ns-hmr][vue-runtime] deferring update: NS view not ready', { isMounted, isLoaded, suspendCount, elReady, hasNativeView: resolved.hasNativeView });
1240
- scheduleDeferredUpdate(internal, 'not-ready');
1241
- return;
1242
- }
1243
- // Clear any previous deferral attempts now that we're ready
1244
- try {
1245
- __pendingUpdateAttempts.delete(internal);
1246
- }
1247
- catch { }
1248
- }
1249
- catch { }
1250
- // If the component tree includes Frame/Page, avoid immediate updates: schedule on next frame(s)
1251
- if (instanceHasFrameOrPage(internal)) {
1252
- if (VERBOSE)
1253
- console.info('[ns-hmr][vue-runtime] frame/page detected; scheduling via scheduler and next frames');
1254
- try {
1255
- const eff = internal.effect;
1256
- if (eff && typeof eff.scheduler === 'function') {
1257
- scheduleNextFrame(() => { try {
1258
- eff.scheduler();
1259
- }
1260
- catch { } scheduleNextFrame(() => stabilizeNativeLayout(internal)); });
1261
- return;
1262
- }
1263
- }
1264
- catch { }
1265
- scheduleNextFrame(() => { try {
1266
- internal?.update && internal.update();
1267
- }
1268
- catch { } scheduleNextFrame(() => stabilizeNativeLayout(internal)); });
1269
- return;
1270
- }
1271
- // Prefer scheduler then nextTick before attempting direct update
1272
- try {
1273
- const eff = internal.effect;
1274
- if (eff && typeof eff.scheduler === 'function') {
1275
- if (VERBOSE) {
1276
- console.info('[ns-hmr][vue-runtime] About to call effect.scheduler()', {
1277
- hasEffect: !!eff,
1278
- effectKeys: eff ? Object.keys(eff).slice(0, 10) : [],
1279
- schedulerType: typeof eff.scheduler
1280
- });
1281
- }
1282
- try {
1283
- eff.scheduler();
1284
- if (VERBOSE)
1285
- console.info('[ns-hmr][vue-runtime] effect.scheduler() executed successfully');
1286
- // Also try to force a re-render by marking the effect as dirty
1287
- if (typeof eff.trigger === 'function') {
1288
- eff.trigger();
1289
- if (VERBOSE)
1290
- console.info('[ns-hmr][vue-runtime] effect.trigger() called');
1291
- }
1292
- // Force update the instance as well
1293
- if (typeof internal.update === 'function') {
1294
- scheduleMicrotask(() => {
1295
- try {
1296
- internal.update();
1297
- if (VERBOSE)
1298
- console.info('[ns-hmr][vue-runtime] internal.update() called after scheduler');
1299
- }
1300
- catch (e) {
1301
- if (VERBOSE)
1302
- console.warn('[ns-hmr][vue-runtime] internal.update() failed:', e?.message);
1303
- }
1304
- });
1305
- }
1306
- // Force a complete re-render cycle - try internal render method
1307
- if (typeof internal.render === 'function') {
1308
- scheduleMicrotask(() => {
1309
- try {
1310
- if (VERBOSE)
1311
- console.info('[ns-hmr][vue-runtime] Triggering internal.render() for complete re-render');
1312
- // Validate render context before calling render
1313
- const hasValidContext = internal.ctx || internal.setupState || internal.data;
1314
- if (!hasValidContext) {
1315
- if (VERBOSE)
1316
- console.warn('[ns-hmr][vue-runtime] No valid render context found, skipping internal.render()');
1317
- return;
1318
- }
1319
- // Set up proper render context
1320
- const originalCtx = internal.ctx;
1321
- const originalScope = internal.scope;
1322
- try {
1323
- const newVNode = internal.render.call(internal, internal.ctx || internal.setupState || internal.data, internal.renderCache || {}, internal.props || {}, internal.setupState || {}, internal.data || {}, internal.$options || {});
1324
- if (VERBOSE)
1325
- console.info('[ns-hmr][vue-runtime] internal.render() result:', {
1326
- hasVNode: !!newVNode,
1327
- vNodeType: newVNode?.type?.name || newVNode?.type || 'unknown'
1328
- });
1329
- // Apply new VNode by replacing subTree and scheduling an update
1330
- if (newVNode) {
1331
- if (VERBOSE)
1332
- console.info('[ns-hmr][vue-runtime] New vNode created, applying via subTree replacement');
1333
- try {
1334
- internal.subTree = newVNode;
1335
- }
1336
- catch { }
1337
- if (internal.update && typeof internal.update === 'function') {
1338
- scheduleMicrotask(() => {
1339
- try {
1340
- internal.update();
1341
- if (VERBOSE)
1342
- console.info('[ns-hmr][vue-runtime] Triggered component update after subTree replacement');
1343
- }
1344
- catch (e) {
1345
- if (VERBOSE)
1346
- console.warn('[ns-hmr][vue-runtime] Component update after subTree replacement failed:', e?.message);
1347
- }
1348
- });
1349
- }
1350
- }
1351
- }
1352
- finally {
1353
- // Restore original context
1354
- if (originalCtx)
1355
- internal.ctx = originalCtx;
1356
- if (originalScope)
1357
- internal.scope = originalScope;
1358
- }
1359
- }
1360
- catch (e) {
1361
- if (VERBOSE)
1362
- console.warn('[ns-hmr][vue-runtime] internal.render() failed:', e?.message, e?.stack);
1363
- }
1364
- });
1365
- }
1366
- // Enhanced NativeScript-specific component update approach
1367
- scheduleMicrotask(() => {
1368
- try {
1369
- if (VERBOSE)
1370
- console.info('[ns-hmr][vue-runtime] Starting NativeScript-specific component update');
1371
- const nsEl = findNSViewFromInternal(internal);
1372
- if (nsEl && nsEl.info && nsEl.info.view) {
1373
- const view = nsEl.info.view;
1374
- const nativeView = nsEl.info.nativeView;
1375
- if (VERBOSE)
1376
- console.info('[ns-hmr][vue-runtime] Found NativeScript view for update:', {
1377
- hasView: !!view,
1378
- hasNativeView: !!nativeView,
1379
- viewType: view?.constructor?.name || typeof view
1380
- });
1381
- // Step 1: Force Vue component to re-evaluate its render function using Vue 3 compatible methods
1382
- if (internal.effect) {
1383
- try {
1384
- // Use Vue 3's proper effect triggering methods instead of setting readonly 'dirty' property
1385
- if (typeof internal.effect.trigger === 'function') {
1386
- internal.effect.trigger();
1387
- if (VERBOSE)
1388
- console.info('[ns-hmr][vue-runtime] Triggered Vue effect via trigger()');
1389
- }
1390
- else if (typeof internal.effect.run === 'function') {
1391
- // Force effect to run again
1392
- internal.effect.run();
1393
- if (VERBOSE)
1394
- console.info('[ns-hmr][vue-runtime] Triggered Vue effect via run()');
1395
- }
1396
- else {
1397
- // Fallback: try to schedule the effect
1398
- if (typeof internal.effect.scheduler === 'function') {
1399
- internal.effect.scheduler();
1400
- if (VERBOSE)
1401
- console.info('[ns-hmr][vue-runtime] Triggered Vue effect via scheduler()');
1402
- }
1403
- else {
1404
- if (VERBOSE)
1405
- console.warn('[ns-hmr][vue-runtime] No compatible Vue effect trigger method found');
1406
- }
1407
- }
1408
- }
1409
- catch (e) {
1410
- if (VERBOSE)
1411
- console.warn('[ns-hmr][vue-runtime] Vue effect triggering failed:', e?.message);
1412
- }
1413
- }
1414
- // Step 2: Clear any cached render results
1415
- if (internal.renderCache) {
1416
- const cacheKeys = Object.keys(internal.renderCache);
1417
- internal.renderCache = {};
1418
- if (VERBOSE)
1419
- console.info('[ns-hmr][vue-runtime] Cleared render cache:', cacheKeys.length, 'entries');
1420
- }
1421
- // Step 3: Force NativeScript view updates
1422
- if (nativeView) {
1423
- // Platform-specific layout forcing
1424
- const isIOS = globalThis.__ios || (nativeView.setNeedsLayout && !nativeView.requestLayout);
1425
- const isAndroid = globalThis.__android || (nativeView.requestLayout && !nativeView.setNeedsLayout);
1426
- if (isIOS) {
1427
- // iOS-specific layout forcing
1428
- if (nativeView.setNeedsLayout) {
1429
- nativeView.setNeedsLayout();
1430
- if (VERBOSE)
1431
- console.info('[ns-hmr][vue-runtime] Called iOS setNeedsLayout()');
1432
- }
1433
- if (nativeView.layoutIfNeeded) {
1434
- nativeView.layoutIfNeeded();
1435
- if (VERBOSE)
1436
- console.info('[ns-hmr][vue-runtime] Called iOS layoutIfNeeded()');
1437
- }
1438
- }
1439
- else if (isAndroid) {
1440
- // Android-specific layout forcing
1441
- if (nativeView.requestLayout) {
1442
- nativeView.requestLayout();
1443
- if (VERBOSE)
1444
- console.info('[ns-hmr][vue-runtime] Called Android requestLayout()');
1445
- }
1446
- if (nativeView.invalidate) {
1447
- nativeView.invalidate();
1448
- if (VERBOSE)
1449
- console.info('[ns-hmr][vue-runtime] Called Android invalidate()');
1450
- }
1451
- }
1452
- else {
1453
- // Fallback: try both but log appropriately
1454
- if (nativeView.setNeedsLayout) {
1455
- nativeView.setNeedsLayout();
1456
- if (VERBOSE)
1457
- console.info('[ns-hmr][vue-runtime] Called iOS setNeedsLayout() (fallback)');
1458
- }
1459
- if (nativeView.requestLayout) {
1460
- nativeView.requestLayout();
1461
- if (VERBOSE)
1462
- console.info('[ns-hmr][vue-runtime] Called Android requestLayout() (fallback)');
1463
- }
1464
- }
1465
- }
1466
- // Step 4: Force NativeScript view hierarchy update
1467
- if (view) {
1468
- // Try NativeScript's own update mechanisms
1469
- if (view.requestLayout && typeof view.requestLayout === 'function') {
1470
- view.requestLayout();
1471
- if (VERBOSE)
1472
- console.info('[ns-hmr][vue-runtime] Called NativeScript view requestLayout()');
1473
- }
1474
- if (view._onCssStateChange && typeof view._onCssStateChange === 'function') {
1475
- view._onCssStateChange();
1476
- if (VERBOSE)
1477
- console.info('[ns-hmr][vue-runtime] Called view CSS state change');
1478
- }
1479
- if (view._redrawNativeBackground && typeof view._redrawNativeBackground === 'function') {
1480
- view._redrawNativeBackground();
1481
- if (VERBOSE)
1482
- console.info('[ns-hmr][vue-runtime] Called view background redraw');
1483
- }
1484
- }
1485
- // Step 5: Trigger Vue's update cycle in NativeScript-safe way
1486
- if (internal.update && typeof internal.update === 'function') {
1487
- // Use setTimeout to break out of current execution context
1488
- setTimeout(() => {
1489
- try {
1490
- internal.update();
1491
- if (VERBOSE)
1492
- console.info('[ns-hmr][vue-runtime] Called Vue internal.update() via setTimeout');
1493
- }
1494
- catch (e) {
1495
- if (VERBOSE)
1496
- console.warn('[ns-hmr][vue-runtime] Vue internal.update() failed:', e?.message);
1497
- }
1498
- }, 0);
1499
- }
1500
- }
1501
- else {
1502
- if (VERBOSE)
1503
- console.warn('[ns-hmr][vue-runtime] No NativeScript view found for update');
1504
- }
1505
- }
1506
- catch (e) {
1507
- if (VERBOSE)
1508
- console.warn('[ns-hmr][vue-runtime] NativeScript component update failed:', e?.message);
1509
- }
1510
- });
1511
- // Experimental: Try to force a complete component rebuild
1512
- scheduleMicrotask(() => {
1513
- try {
1514
- if (VERBOSE)
1515
- console.info('[ns-hmr][vue-runtime] Attempting experimental complete component refresh');
1516
- // Clear more Vue caches that might be blocking updates
1517
- if (internal.renderCache) {
1518
- const oldLen = Object.keys(internal.renderCache).length;
1519
- internal.renderCache = {};
1520
- if (VERBOSE)
1521
- console.info('[ns-hmr][vue-runtime] Cleared renderCache entries:', oldLen);
1522
- }
1523
- // Try to force Vue to think the component has changed
1524
- if (internal.dirtyLevel !== undefined) {
1525
- internal.dirtyLevel = 3; // Force dirty
1526
- if (VERBOSE)
1527
- console.info('[ns-hmr][vue-runtime] Set dirtyLevel to 3');
1528
- }
1529
- // Try to force the component's patch
1530
- if (internal.parent && internal.parent.update) {
1531
- internal.parent.update();
1532
- if (VERBOSE)
1533
- console.info('[ns-hmr][vue-runtime] Called parent.update()');
1534
- }
1535
- // Try to force app-level update
1536
- const app = internal.appContext?.app;
1537
- if (app && app._instance && app._instance.update) {
1538
- app._instance.update();
1539
- if (VERBOSE)
1540
- console.info('[ns-hmr][vue-runtime] Called app._instance.update()');
1541
- }
1542
- // Force re-evaluation of computed properties
1543
- if (internal.scope && internal.scope.effects) {
1544
- for (const effect of internal.scope.effects) {
1545
- if (effect && effect.scheduler) {
1546
- effect.scheduler();
1547
- if (VERBOSE)
1548
- console.info('[ns-hmr][vue-runtime] Triggered scope effect scheduler');
1549
- }
1550
- }
1551
- }
1552
- }
1553
- catch (e) {
1554
- if (VERBOSE)
1555
- console.warn('[ns-hmr][vue-runtime] Experimental refresh failed:', e?.message);
1556
- }
1557
- });
1558
- }
1559
- catch (e) {
1560
- if (VERBOSE)
1561
- console.warn('[ns-hmr][vue-runtime] effect.scheduler() failed:', e?.message);
1562
- }
1563
- scheduleMicrotask(() => stabilizeNativeLayout(internal));
1564
- return;
1565
- }
1566
- else {
1567
- if (VERBOSE) {
1568
- console.info('[ns-hmr][vue-runtime] No effect.scheduler available', {
1569
- hasEffect: !!eff,
1570
- hasScheduler: eff && typeof eff.scheduler === 'function',
1571
- effectType: eff?.constructor?.name,
1572
- effectKeys: eff ? Object.keys(eff).slice(0, 10) : []
1573
- });
1574
- }
1575
- }
1576
- }
1577
- catch (e) {
1578
- if (VERBOSE)
1579
- console.warn('[ns-hmr][vue-runtime] Effect scheduler attempt failed:', e?.message);
1580
- }
1581
- // Prefer scheduling on nextTick before attempting immediate update to avoid NS creation timing
1582
- try {
1583
- const req = globalThis.require;
1584
- const vueMod = req && (() => { try {
1585
- return req('vue');
1586
- }
1587
- catch {
1588
- return null;
1589
- } })();
1590
- const nsv = req && (() => { try {
1591
- return req('nativescript-vue');
1592
- }
1593
- catch {
1594
- return null;
1595
- } })();
1596
- const nextTick = (vueMod && vueMod.nextTick) || (nsv && nsv.nextTick);
1597
- if (VERBOSE)
1598
- console.info('[ns-hmr][vue-runtime] forceUpdate nextTick found:', typeof nextTick === 'function');
1599
- if (typeof nextTick === 'function') {
1600
- if (VERBOSE)
1601
- console.info('[ns-hmr][vue-runtime] scheduling nextTick update (preferred path)');
1602
- nextTick(() => {
1603
- try {
1604
- internal?.update && internal.update();
1605
- if (VERBOSE)
1606
- console.info('[ns-hmr][vue-runtime] nextTick(preferred) internal.update');
1607
- // After update, schedule stabilization on the next microtask to allow vnode.el to attach
1608
- try {
1609
- scheduleMicrotask(() => stabilizeNativeLayout(internal));
1610
- // And one-time next-frame follow-up update to flush any late vnode attachments
1611
- if (!__postUpdateFollowed.has(internal)) {
1612
- __postUpdateFollowed.add(internal);
1613
- scheduleNextFrame(() => {
1614
- try {
1615
- typeof internal?.update === 'function' && internal.update();
1616
- }
1617
- catch { }
1618
- scheduleMicrotask(() => stabilizeNativeLayout(internal));
1619
- });
1620
- }
1621
- }
1622
- catch { }
1623
- }
1624
- catch (e) {
1625
- if (VERBOSE)
1626
- console.warn('[ns-hmr][vue-runtime] nextTick(preferred) update failed:', e?.message);
1627
- if (e && String(e.message || e).includes('entry.create')) {
1628
- scheduleDeferredUpdate(internal, 'entry.create');
1629
- }
1630
- else {
1631
- // For non-entry.create errors, try gentle approach
1632
- scheduleGentleRerender(internal);
1633
- }
1634
- }
1635
- });
1636
- return;
1637
- }
1638
- }
1639
- catch { }
1640
- if (typeof internal?.update === 'function') {
1641
- try {
1642
- internal.update();
1643
- try {
1644
- __pendingUpdateAttempts.delete(internal);
1645
- }
1646
- catch { }
1647
- if (VERBOSE)
1648
- console.info('[ns-hmr][vue-runtime] internal.update');
1649
- try {
1650
- scheduleMicrotask(() => stabilizeNativeLayout(internal));
1651
- // And one-time next-frame follow-up update to flush any late vnode attachments
1652
- if (!__postUpdateFollowed.has(internal)) {
1653
- __postUpdateFollowed.add(internal);
1654
- scheduleNextFrame(() => {
1655
- try {
1656
- typeof internal?.update === 'function' && internal.update();
1657
- }
1658
- catch { }
1659
- scheduleMicrotask(() => stabilizeNativeLayout(internal));
1660
- });
1661
- }
1662
- }
1663
- catch { }
1664
- return;
1665
- }
1666
- catch (e) {
1667
- if (VERBOSE)
1668
- console.warn('[ns-hmr][vue-runtime] internal.update failed:', e?.message);
1669
- // If NativeScript is still creating views, defer and retry
1670
- if (e && String(e.message || e).includes('entry.create')) {
1671
- scheduleDeferredUpdate(internal, 'entry.create');
1672
- return;
1673
- }
1674
- else {
1675
- // For other errors, try gentle approach
1676
- scheduleGentleRerender(internal);
1677
- return;
1678
- }
1679
- }
1680
- }
1681
- try {
1682
- const eff = internal.effect;
1683
- if (eff && typeof eff.run === 'function') {
1684
- eff.run();
1685
- if (VERBOSE)
1686
- console.info('[ns-hmr][vue-runtime] effect.run()');
1687
- return;
1688
- }
1689
- if (eff && typeof eff.scheduler === 'function') {
1690
- eff.scheduler();
1691
- if (VERBOSE)
1692
- console.info('[ns-hmr][vue-runtime] effect.scheduler()');
1693
- return;
1694
- }
1695
- }
1696
- catch { }
1697
- try {
1698
- const vue = globalThis.require && globalThis.require('nativescript-vue');
1699
- const nextTick = (vue && vue.nextTick) || (globalThis.require && globalThis.require('vue')?.nextTick);
1700
- if (typeof nextTick === 'function') {
1701
- nextTick(() => { try {
1702
- internal?.update && internal.update();
1703
- if (VERBOSE)
1704
- console.info('[ns-hmr][vue-runtime] nextTick internal.update');
1705
- }
1706
- catch (e) {
1707
- if (VERBOSE)
1708
- console.warn('[ns-hmr][vue-runtime] nextTick update failed:', e?.message);
1709
- } });
1710
- return;
1711
- }
1712
- }
1713
- catch { }
1714
- function attemptReloadForInstance(internal) {
1715
- try {
1716
- const g = globalThis;
1717
- const rt = g.__VUE_HMR_RUNTIME__;
1718
- if (!rt || typeof rt.reload !== 'function')
1719
- return;
1720
- const type = internal?.type || internal?.proxy?.type || internal?.vnode?.type;
1721
- const file = (type && (type.__file || type.file)) ? String(type.__file || type.file).replace(/\\/g, '/') : '';
1722
- const recentId = g.__NS_LAST_RERENDER_ID__ ? String(g.__NS_LAST_RERENDER_ID__) : '';
1723
- const candidates = new Set();
1724
- if (recentId)
1725
- candidates.add(recentId);
1726
- if (file) {
1727
- const suffixes = baseFileSuffixesFromId(file);
1728
- // Scan runtime records and match by suffix
1729
- const map = rt.map || rt.records || {};
1730
- const keys = map && typeof map.keys === 'function'
1731
- ? Array.from(map.keys())
1732
- : (map && typeof map === 'object' ? Object.keys(map) : []);
1733
- for (const k of keys) {
1734
- for (const s of suffixes) {
1735
- if (String(k).endsWith(s))
1736
- candidates.add(String(k));
1737
- }
1738
- }
1739
- }
1740
- const ids = Array.from(candidates);
1741
- if (VERBOSE)
1742
- console.info('[ns-hmr][vue-runtime] Attempting component-local reload', { file, ids });
1743
- for (const id of ids) {
1744
- try {
1745
- rt.reload(id, { /* best-effort */});
1746
- if (VERBOSE)
1747
- console.info('[ns-hmr][vue-runtime] Reload triggered for', id);
1748
- break;
1749
- }
1750
- catch (e) {
1751
- if (VERBOSE)
1752
- console.warn('[ns-hmr][vue-runtime] Reload failed for', id, e?.message);
1753
- }
1754
- }
1755
- }
1756
- catch { }
1757
- }
1758
- if (VERBOSE) {
1759
- try {
1760
- const keys = internal ? Object.keys(internal).slice(0, 30) : [];
1761
- console.warn('[ns-hmr][vue-runtime] No safe update path found for instance', { hasInternal: !!internal, internalKeys: keys });
1762
- }
1763
- catch { }
1764
- }
1765
- }
1766
- catch { }
1767
- }
1768
- export function applyRenderAndTrigger(ins, newRender) {
1769
- return applyRenderAndTriggerWithId(ins, newRender);
1770
- }
1771
- export function applyRenderAndTriggerWithId(ins, newRender, componentId) {
1772
- try {
1773
- const internal = ins.$ || ins;
1774
- const type = internal?.type || (ins && ins.type) || null;
1775
- if (VERBOSE) {
1776
- try {
1777
- const prevTypeRender = type && type.render;
1778
- const prevVNodeTypeRender = internal?.vnode?.type && internal.vnode.type.render;
1779
- // Also surface some readiness info for the target instance
1780
- const vnode = internal?.vnode;
1781
- const el = vnode && vnode.el;
1782
- const resolved = resolveNSView(el);
1783
- const suspendCount = resolved.suspendCount;
1784
- const hasNativeView = resolved.hasNativeView;
1785
- const flags = (() => {
1786
- try {
1787
- if (typeof suspendCount !== 'number')
1788
- return undefined;
1789
- const LOADED = 1 << 20;
1790
- const NATIVEVIEW = 1 << 21;
1791
- const UISETUP = 1 << 22;
1792
- const FLAGS_MASK = LOADED | NATIVEVIEW | UISETUP;
1793
- const inc = suspendCount & ~FLAGS_MASK;
1794
- return {
1795
- suspendCount,
1796
- inc,
1797
- LOADED: (suspendCount & LOADED) !== 0,
1798
- NATIVEVIEW: (suspendCount & NATIVEVIEW) !== 0,
1799
- UISETUP: (suspendCount & UISETUP) !== 0,
1800
- };
1801
- }
1802
- catch {
1803
- return undefined;
1804
- }
1805
- })();
1806
- console.info('[ns-hmr][vue-runtime] patching renders (minimal)', {
1807
- name: (type && (type.__name || type.name)) || undefined,
1808
- hadTypeRender: typeof prevTypeRender === 'function',
1809
- hadVNodeTypeRender: typeof prevVNodeTypeRender === 'function',
1810
- hasNativeView,
1811
- flags
1812
- });
1813
- }
1814
- catch { }
1815
- }
1816
- // IMPORTANT: patch the component type.render, vnode.type.render, and internal.render so next updates use new render
1817
- try {
1818
- if (type)
1819
- type.render = newRender;
1820
- }
1821
- catch { }
1822
- try {
1823
- if (internal?.vnode?.type)
1824
- internal.vnode.type.render = newRender;
1825
- }
1826
- catch { }
1827
- try {
1828
- if (internal)
1829
- internal.render = newRender;
1830
- }
1831
- catch { }
1832
- // Clear render cache so compiled template changes take effect immediately
1833
- try {
1834
- if (internal && Array.isArray(internal.renderCache)) {
1835
- const len = internal.renderCache.length;
1836
- internal.renderCache.length = 0;
1837
- if (VERBOSE)
1838
- console.info('[ns-hmr][vue-runtime] cleared instance.renderCache', { prevLen: len });
1839
- }
1840
- else if (internal && internal.renderCache) {
1841
- internal.renderCache = [];
1842
- if (VERBOSE)
1843
- console.info('[ns-hmr][vue-runtime] reset instance.renderCache to empty array');
1844
- }
1845
- }
1846
- catch { }
1847
- if (VERBOSE) {
1848
- try {
1849
- const file = (type && type.__file) ? String(type.__file) : undefined;
1850
- const name = (type && (type.__name || type.name)) ? String(type.__name || type.name) : undefined;
1851
- console.info('[ns-hmr][vue-runtime] applyRenderAndTrigger', { file, name, hasType: !!type, hasVNodeType: !!(internal?.vnode?.type) });
1852
- }
1853
- catch { }
1854
- }
1855
- }
1856
- catch { }
1857
- // Check if the instance is ready for update before forcing
1858
- try {
1859
- const ready = isNSViewReady(ins, componentId);
1860
- if (VERBOSE)
1861
- console.info('[ns-hmr][vue-runtime] applyRenderAndTrigger readiness:', { ready });
1862
- if (!ready) {
1863
- if (VERBOSE)
1864
- console.info('[ns-hmr][vue-runtime] Instance not ready for update, trying progressive approach');
1865
- // Instead of giving up, try a more progressive approach
1866
- // First try the gentle approach, but with a fallback to direct update
1867
- try {
1868
- scheduleGentleRerender(ins, componentId);
1869
- // Also schedule a backup direct update after a delay in case gentle approach fails
1870
- setTimeout(() => {
1871
- try {
1872
- if (VERBOSE)
1873
- console.info('[ns-hmr][vue-runtime] Backup direct update attempt');
1874
- forceUpdateInstance(ins, componentId);
1875
- }
1876
- catch (e) {
1877
- if (VERBOSE)
1878
- console.warn('[ns-hmr][vue-runtime] Backup update failed:', e?.message);
1879
- }
1880
- }, 100);
1881
- }
1882
- catch (e) {
1883
- if (VERBOSE)
1884
- console.warn('[ns-hmr][vue-runtime] Progressive approach failed, falling back to direct update:', e?.message);
1885
- forceUpdateInstance(ins, componentId);
1886
- }
1887
- return;
1888
- }
1889
- }
1890
- catch (e) {
1891
- if (VERBOSE)
1892
- console.warn('[ns-hmr][vue-runtime] Readiness check failed, proceeding with direct update:', e?.message);
1893
- }
1894
- forceUpdateInstance(ins);
1895
- }
1896
- function tryPatchInstancesFromRootByFileSuffix(id, newRender) {
1897
- const g = globalThis;
1898
- const root = g.__NS_VUE_ROOT_INSTANCE__;
1899
- if (!root)
1900
- return 0;
1901
- const suffixes = baseFileSuffixesFromId(id);
1902
- let patched = 0;
1903
- const maybePatch = (ins) => {
1904
- try {
1905
- const type = getComponentType(ins);
1906
- const file = type && type.__file ? String(type.__file).replace(/\\/g, '/') : '';
1907
- if (file) {
1908
- for (const suf of suffixes) {
1909
- if (file.endsWith(suf)) {
1910
- applyRenderAndTrigger(ins, newRender);
1911
- patched++;
1912
- if (VERBOSE)
1913
- console.info('[ns-hmr][vue-runtime] patched instance via file suffix match', { file, suf, setType: !!type, setVNode: !!(ins?.vnode?.type), setInternal: true });
1914
- break;
1915
- }
1916
- }
1917
- }
1918
- }
1919
- catch { }
1920
- };
1921
- const enqueueChildren = (node, q) => {
1922
- try {
1923
- if (!node)
1924
- return;
1925
- const internal = (node.$ ? node.$ : node);
1926
- if (internal?.subTree)
1927
- q.push(internal.subTree);
1928
- if (node && typeof node === 'object') {
1929
- try {
1930
- const comp = node.component;
1931
- if (comp)
1932
- q.push(comp);
1933
- }
1934
- catch { }
1935
- const ch = node.children || node.child || null;
1936
- if (Array.isArray(ch)) {
1937
- for (const c of ch) {
1938
- if (c && typeof c === 'object')
1939
- q.push(c);
1940
- }
1941
- }
1942
- else if (ch && typeof ch === 'object') {
1943
- q.push(ch);
1944
- }
1945
- }
1946
- }
1947
- catch { }
1948
- };
1949
- const queue = [root];
1950
- while (queue.length) {
1951
- const cur = queue.shift();
1952
- try {
1953
- maybePatch(cur);
1954
- }
1955
- catch { }
1956
- try {
1957
- enqueueChildren(cur, queue);
1958
- }
1959
- catch { }
1960
- }
1961
- return patched;
1962
- }
1963
- function baseNameFromId(id) { try {
1964
- const noQ = String(id || '').split('?')[0].replace(/\\/g, '/');
1965
- const base = (noQ.split('/').pop() || '').replace(/\.vue$/i, '');
1966
- return base;
1967
- }
1968
- catch {
1969
- return '';
1970
- } }
1971
- function tryPatchInstancesFromRootByName(id, newRender, runtime) {
1972
- const g = globalThis;
1973
- const root = g.__NS_VUE_ROOT_INSTANCE__;
1974
- if (!root)
1975
- return 0;
1976
- const target = baseNameFromId(id);
1977
- if (!target)
1978
- return 0;
1979
- const targetLower = target.toLowerCase();
1980
- let patched = 0;
1981
- const maybePatch = (ins) => {
1982
- try {
1983
- const type = getComponentType(ins);
1984
- const name = (type && (type.__name || type.name)) ? String(type.__name || type.name) : '';
1985
- if (name && name.toLowerCase() === targetLower) {
1986
- applyRenderAndTrigger(ins, newRender);
1987
- patched++;
1988
- if (VERBOSE) {
1989
- try {
1990
- const vnode = (ins && ins.vnode) || ((ins && ins.$) ? ins.$.vnode : undefined);
1991
- const el = vnode && vnode.el;
1992
- const suspendCount = el && typeof el === 'object' ? el._suspendNativeUpdatesCount : undefined;
1993
- const isLoaded = el && typeof el === 'object' ? el._isLoaded : undefined;
1994
- const isMounted = typeof ins?.isMounted === 'boolean' ? ins.isMounted : undefined;
1995
- console.info('[ns-hmr][vue-runtime] patched instance via name match', { name, target: targetLower, setType: !!type, setVNode: !!(ins?.vnode?.type), setInternal: true, isMounted, isLoaded, suspendCount });
1996
- }
1997
- catch { }
1998
- }
1999
- try {
2000
- if (runtime && typeof runtime.registerInstance === 'function')
2001
- runtime.registerInstance(id, ins);
2002
- }
2003
- catch { }
2004
- }
2005
- }
2006
- catch { }
2007
- };
2008
- const enqueueChildren = (node, q) => {
2009
- try {
2010
- if (!node)
2011
- return;
2012
- const internal = (node.$ ? node.$ : node);
2013
- if (internal && internal.subTree)
2014
- q.push(internal.subTree);
2015
- if (node && typeof node === 'object') {
2016
- try {
2017
- const comp = node.component;
2018
- if (comp)
2019
- q.push(comp);
2020
- }
2021
- catch { }
2022
- const ch = node.children || node.child || null;
2023
- if (Array.isArray(ch)) {
2024
- for (const c of ch) {
2025
- if (c && typeof c === 'object')
2026
- q.push(c);
2027
- }
2028
- }
2029
- else if (ch && typeof ch === 'object') {
2030
- q.push(ch);
2031
- }
2032
- }
2033
- }
2034
- catch { }
2035
- };
2036
- const queue = [root];
2037
- while (queue.length) {
2038
- const cur = queue.shift();
2039
- try {
2040
- maybePatch(cur);
2041
- }
2042
- catch { }
2043
- try {
2044
- enqueueChildren(cur, queue);
2045
- }
2046
- catch { }
2047
- }
2048
- return patched;
2049
- }
2050
- // New function to handle gentle re-rendering without forcing component recreation
2051
- function scheduleGentleRerender(internal, componentId) {
2052
- try {
2053
- if (VERBOSE)
2054
- console.info('[ns-hmr][vue-runtime] scheduleGentleRerender');
2055
- // First approach: invalidate the render effect using Vue 3 compatible methods
2056
- try {
2057
- const renderEffect = internal.renderEffect || internal.effect;
2058
- if (renderEffect) {
2059
- // Use Vue 3's proper effect triggering instead of setting readonly 'dirty' property
2060
- if (typeof renderEffect.trigger === 'function') {
2061
- renderEffect.trigger();
2062
- if (VERBOSE)
2063
- console.info('[ns-hmr][vue-runtime] gentle update: triggered render effect via trigger()');
2064
- }
2065
- else if (typeof renderEffect.run === 'function') {
2066
- renderEffect.run();
2067
- if (VERBOSE)
2068
- console.info('[ns-hmr][vue-runtime] gentle update: triggered render effect via run()');
2069
- }
2070
- else if (typeof renderEffect.scheduler === 'function') {
2071
- renderEffect.scheduler();
2072
- if (VERBOSE)
2073
- console.info('[ns-hmr][vue-runtime] gentle update: triggered render effect via scheduler()');
2074
- }
2075
- else {
2076
- if (VERBOSE)
2077
- console.warn('[ns-hmr][vue-runtime] gentle update: no compatible render effect trigger method found');
2078
- }
2079
- // Trigger scheduler if available for gentle scheduling
2080
- if (typeof renderEffect.scheduler === 'function') {
2081
- const req = globalThis.require;
2082
- const vueMod = req && (() => { try {
2083
- return req('vue');
2084
- }
2085
- catch {
2086
- return null;
2087
- } })();
2088
- const nextTick = vueMod && vueMod.nextTick;
2089
- if (typeof nextTick === 'function') {
2090
- nextTick(() => {
2091
- try {
2092
- renderEffect.scheduler();
2093
- if (VERBOSE)
2094
- console.info('[ns-hmr][vue-runtime] gentle rerender via scheduler');
2095
- // Also request layout to ensure visual update
2096
- try {
2097
- const { el, info } = findNSViewFromInternal(internal);
2098
- if (info.view && typeof info.view.requestLayout === 'function') {
2099
- info.view.requestLayout();
2100
- }
2101
- else if (info.nativeView && typeof info.nativeView.setNeedsLayout === 'function') {
2102
- info.nativeView.setNeedsLayout();
2103
- }
2104
- }
2105
- catch { }
2106
- }
2107
- catch (e) {
2108
- if (VERBOSE)
2109
- console.warn('[ns-hmr][vue-runtime] gentle scheduler failed:', e?.message);
2110
- }
2111
- });
2112
- }
2113
- else {
2114
- renderEffect.scheduler();
2115
- // Request layout after scheduler
2116
- setTimeout(() => {
2117
- try {
2118
- const { el, info } = findNSViewFromInternal(internal);
2119
- if (info.view && typeof info.view.requestLayout === 'function') {
2120
- info.view.requestLayout();
2121
- }
2122
- else if (info.nativeView && typeof info.nativeView.setNeedsLayout === 'function') {
2123
- info.nativeView.setNeedsLayout();
2124
- }
2125
- }
2126
- catch { }
2127
- }, 0);
2128
- }
2129
- return;
2130
- }
2131
- }
2132
- }
2133
- catch (e) {
2134
- if (VERBOSE)
2135
- console.warn('[ns-hmr][vue-runtime] gentle effect invalidation failed:', e?.message);
2136
- }
2137
- // Fallback: schedule a deferred update with longer delay to give view time to stabilize
2138
- const attempt = (__pendingUpdateAttempts.get(internal) || 0) + 1;
2139
- __pendingUpdateAttempts.set(internal, attempt);
2140
- const delay = Math.min(BASE_DEFER_MS * attempt * 2, 200); // Longer delays for gentle approach
2141
- setTimeout(() => {
2142
- try {
2143
- const { el } = findNSViewFromInternal(internal);
2144
- if (isNSViewReady(internal)) {
2145
- if (VERBOSE)
2146
- console.info('[ns-hmr][vue-runtime] gentle deferred update - view ready, applying');
2147
- try {
2148
- // Try multiple update approaches for better coverage
2149
- let updateApplied = false;
2150
- // Method 1: Use effect scheduler if available
2151
- const eff = internal.effect;
2152
- if (eff && typeof eff.scheduler === 'function') {
2153
- eff.scheduler();
2154
- updateApplied = true;
2155
- if (VERBOSE)
2156
- console.info('[ns-hmr][vue-runtime] gentle update: effect.scheduler() called');
2157
- }
2158
- // Method 2: Direct internal update
2159
- if (internal?.update && typeof internal.update === 'function') {
2160
- internal.update();
2161
- updateApplied = true;
2162
- if (VERBOSE)
2163
- console.info('[ns-hmr][vue-runtime] gentle update: internal.update() called');
2164
- }
2165
- // Method 3: Force component re-render
2166
- const vnode = internal?.vnode;
2167
- if (vnode && !updateApplied) {
2168
- // Try to trigger Vue's re-render mechanisms
2169
- if (typeof internal.renderCache?.clear === 'function') {
2170
- internal.renderCache.clear();
2171
- }
2172
- if (Array.isArray(internal.renderCache)) {
2173
- internal.renderCache.length = 0;
2174
- }
2175
- if (VERBOSE)
2176
- console.info('[ns-hmr][vue-runtime] gentle update: cleared render cache');
2177
- }
2178
- if (VERBOSE)
2179
- console.info('[ns-hmr][vue-runtime] gentle update completed, applied:', updateApplied);
2180
- // If gentle update failed, try proper Vue component lifecycle approach
2181
- if (!updateApplied) {
2182
- try {
2183
- if (VERBOSE)
2184
- console.info('[ns-hmr][vue-runtime] Gentle update failed, attempting Vue component lifecycle approach');
2185
- // Get the Vue HMR runtime for proper component updates
2186
- const vueRuntime = ensureVueHMRRuntimeEnhanced();
2187
- const componentId = getComponentIdFromInternal(internal);
2188
- if (vueRuntime && componentId) {
2189
- // Use Vue's official HMR rerender instead of manual effect manipulation
2190
- if (typeof vueRuntime.rerender === 'function') {
2191
- if (VERBOSE)
2192
- console.info('[ns-hmr][vue-runtime] Using Vue HMR runtime rerender for component:', componentId);
2193
- // Get the new render function from the component type
2194
- const componentType = internal.type || internal.vnode?.type;
2195
- if (componentType && componentType.render) {
2196
- vueRuntime.rerender(componentId, componentType.render);
2197
- if (VERBOSE)
2198
- console.info('[ns-hmr][vue-runtime] Vue HMR rerender called successfully');
2199
- }
2200
- else {
2201
- if (VERBOSE)
2202
- console.warn('[ns-hmr][vue-runtime] No render function found for Vue HMR rerender');
2203
- }
2204
- }
2205
- // Also try Vue's reload as backup
2206
- if (typeof vueRuntime.reload === 'function') {
2207
- const componentDef = internal.type || internal.vnode?.type;
2208
- if (componentDef) {
2209
- vueRuntime.reload(componentId, componentDef);
2210
- if (VERBOSE)
2211
- console.info('[ns-hmr][vue-runtime] Vue HMR reload called as backup');
2212
- }
2213
- }
2214
- }
2215
- else {
2216
- if (VERBOSE)
2217
- console.warn('[ns-hmr][vue-runtime] No Vue HMR runtime or component ID available for lifecycle approach');
2218
- }
2219
- // Force component instance update through proper Vue channels
2220
- if (internal.parent && internal.parent.update) {
2221
- internal.parent.update();
2222
- if (VERBOSE)
2223
- console.info('[ns-hmr][vue-runtime] Triggered parent component update');
2224
- }
2225
- // Force root app update if available
2226
- const g = globalThis;
2227
- const root = g.__NS_VUE_ROOT_INSTANCE__;
2228
- if (root && root.$ && typeof root.$.update === 'function') {
2229
- root.$.update();
2230
- if (VERBOSE)
2231
- console.info('[ns-hmr][vue-runtime] Triggered root instance update');
2232
- }
2233
- }
2234
- catch (e) {
2235
- if (VERBOSE)
2236
- console.warn('[ns-hmr][vue-runtime] Vue component lifecycle approach failed:', e?.message);
2237
- }
2238
- }
2239
- // Force native layout updates to ensure visual changes appear
2240
- try {
2241
- const probe = findNSViewFromInternal(internal);
2242
- if (probe.info?.view) {
2243
- const view = probe.info.view;
2244
- if (typeof view.requestLayout === 'function') {
2245
- view.requestLayout();
2246
- if (VERBOSE)
2247
- console.info('[ns-hmr][vue-runtime] gentle update: requested layout');
2248
- }
2249
- if (probe.info.nativeView && typeof probe.info.nativeView.setNeedsLayout === 'function') {
2250
- probe.info.nativeView.setNeedsLayout();
2251
- if (VERBOSE)
2252
- console.info('[ns-hmr][vue-runtime] gentle update: set needs layout');
2253
- }
2254
- }
2255
- }
2256
- catch (e) {
2257
- if (VERBOSE)
2258
- console.warn('[ns-hmr][vue-runtime] Layout update failed:', e?.message);
2259
- }
2260
- }
2261
- catch (e) {
2262
- if (VERBOSE)
2263
- console.warn('[ns-hmr][vue-runtime] gentle update failed:', e?.message);
2264
- }
2265
- __pendingUpdateAttempts.delete(internal);
2266
- }
2267
- else {
2268
- if (attempt < MAX_DEFER_ATTEMPTS) {
2269
- if (VERBOSE)
2270
- console.info('[ns-hmr][vue-runtime] gentle deferred update - view not ready, retrying');
2271
- scheduleGentleRerender(internal, componentId);
2272
- }
2273
- else {
2274
- if (VERBOSE)
2275
- console.warn('[ns-hmr][vue-runtime] giving up on gentle rerender after max attempts');
2276
- // Last resort: force update anyway
2277
- try {
2278
- if (VERBOSE)
2279
- console.info('[ns-hmr][vue-runtime] last resort: forcing update despite view state');
2280
- internal?.update && internal.update();
2281
- __pendingUpdateAttempts.delete(internal);
2282
- }
2283
- catch (e) {
2284
- if (VERBOSE)
2285
- console.warn('[ns-hmr][vue-runtime] last resort update failed:', e?.message);
2286
- }
2287
- }
2288
- }
2289
- }
2290
- catch (e) {
2291
- if (VERBOSE)
2292
- console.warn('[ns-hmr][vue-runtime] gentle deferred update failed:', e?.message);
2293
- if (attempt < MAX_DEFER_ATTEMPTS) {
2294
- scheduleGentleRerender(internal, componentId);
2295
- }
2296
- }
2297
- }, delay);
2298
- }
2299
- catch (e) {
2300
- if (VERBOSE)
2301
- console.warn('[ns-hmr][vue-runtime] scheduleGentleRerender failed:', e?.message);
2302
- }
2303
- }
2304
- // Note: Avoid auto-initializing Vue HMR runtime here to prevent fallback
2305
- // runtime creation and noisy logs at app boot. The webpack5-style handler
2306
- // manages HMR runtime setup explicitly.