@nativescript/vite 8.0.0-alpha.5 → 8.0.0-alpha.51

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 (424) hide show
  1. package/README.md +51 -11
  2. package/bin/cli.cjs +8 -14
  3. package/configuration/angular.d.ts +34 -1
  4. package/configuration/angular.js +376 -165
  5. package/configuration/angular.js.map +1 -1
  6. package/configuration/base.js +241 -51
  7. package/configuration/base.js.map +1 -1
  8. package/configuration/javascript.js +14 -93
  9. package/configuration/javascript.js.map +1 -1
  10. package/configuration/react.js +41 -73
  11. package/configuration/react.js.map +1 -1
  12. package/configuration/solid.js +51 -6
  13. package/configuration/solid.js.map +1 -1
  14. package/configuration/typescript.js +12 -93
  15. package/configuration/typescript.js.map +1 -1
  16. package/helpers/app-components.d.ts +2 -1
  17. package/helpers/app-components.js.map +1 -1
  18. package/helpers/app-css-state.d.ts +8 -0
  19. package/helpers/app-css-state.js +8 -0
  20. package/helpers/app-css-state.js.map +1 -0
  21. package/helpers/bundler-context.d.ts +11 -0
  22. package/helpers/bundler-context.js +71 -0
  23. package/helpers/bundler-context.js.map +1 -0
  24. package/helpers/cli-flags.d.ts +12 -0
  25. package/helpers/cli-flags.js +34 -0
  26. package/helpers/cli-flags.js.map +1 -1
  27. package/helpers/css-platform-plugin.d.ts +14 -0
  28. package/helpers/css-platform-plugin.js +43 -25
  29. package/helpers/css-platform-plugin.js.map +1 -1
  30. package/helpers/dev-host.d.ts +360 -0
  31. package/helpers/dev-host.js +694 -0
  32. package/helpers/dev-host.js.map +1 -0
  33. package/helpers/dynamic-import-plugin.js +1 -1
  34. package/helpers/dynamic-import-plugin.js.map +1 -1
  35. package/helpers/esbuild-platform-resolver.js +4 -1
  36. package/helpers/esbuild-platform-resolver.js.map +1 -1
  37. package/helpers/external-configs.d.ts +10 -12
  38. package/helpers/external-configs.js +58 -35
  39. package/helpers/external-configs.js.map +1 -1
  40. package/helpers/global-defines.d.ts +142 -0
  41. package/helpers/global-defines.js +213 -11
  42. package/helpers/global-defines.js.map +1 -1
  43. package/helpers/hmr-scope.d.ts +26 -0
  44. package/helpers/hmr-scope.js +67 -0
  45. package/helpers/hmr-scope.js.map +1 -0
  46. package/helpers/init.js +0 -18
  47. package/helpers/init.js.map +1 -1
  48. package/helpers/logging.d.ts +1 -0
  49. package/helpers/logging.js +65 -4
  50. package/helpers/logging.js.map +1 -1
  51. package/helpers/main-entry.d.ts +3 -1
  52. package/helpers/main-entry.js +301 -53
  53. package/helpers/main-entry.js.map +1 -1
  54. package/helpers/nativeclass-esbuild-plugin.d.ts +2 -1
  55. package/helpers/nativeclass-esbuild-plugin.js.map +1 -1
  56. package/helpers/nativeclass-transform.js +5 -6
  57. package/helpers/nativeclass-transform.js.map +1 -1
  58. package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
  59. package/helpers/nativeclass-transformer-plugin.js +157 -14
  60. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  61. package/helpers/nativescript-package-resolver.js +10 -62
  62. package/helpers/nativescript-package-resolver.js.map +1 -1
  63. package/helpers/normalize-id.d.ts +42 -0
  64. package/helpers/normalize-id.js +60 -0
  65. package/helpers/normalize-id.js.map +1 -0
  66. package/helpers/ns-core-url.d.ts +29 -7
  67. package/helpers/ns-core-url.js +69 -12
  68. package/helpers/ns-core-url.js.map +1 -1
  69. package/helpers/optimize-deps.d.ts +16 -0
  70. package/helpers/optimize-deps.js +17 -0
  71. package/helpers/optimize-deps.js.map +1 -0
  72. package/helpers/package-platform-aliases.js +34 -49
  73. package/helpers/package-platform-aliases.js.map +1 -1
  74. package/helpers/platform-types.d.ts +2 -0
  75. package/helpers/platform-types.js +2 -0
  76. package/helpers/platform-types.js.map +1 -0
  77. package/helpers/postcss-platform-config.d.ts +17 -1
  78. package/helpers/postcss-platform-config.js +20 -37
  79. package/helpers/postcss-platform-config.js.map +1 -1
  80. package/helpers/project.d.ts +35 -0
  81. package/helpers/project.js +120 -2
  82. package/helpers/project.js.map +1 -1
  83. package/helpers/resolve-main-field-platform.d.ts +20 -0
  84. package/helpers/resolve-main-field-platform.js +49 -0
  85. package/helpers/resolve-main-field-platform.js.map +1 -0
  86. package/helpers/resolver.js +17 -2
  87. package/helpers/resolver.js.map +1 -1
  88. package/helpers/theme-core-plugins.js +1 -1
  89. package/helpers/theme-core-plugins.js.map +1 -1
  90. package/helpers/ts-config-paths.d.ts +14 -0
  91. package/helpers/ts-config-paths.js +90 -9
  92. package/helpers/ts-config-paths.js.map +1 -1
  93. package/helpers/typescript-check.d.ts +2 -1
  94. package/helpers/typescript-check.js +2 -2
  95. package/helpers/typescript-check.js.map +1 -1
  96. package/helpers/ui-registration.d.ts +21 -0
  97. package/helpers/ui-registration.js +156 -0
  98. package/helpers/ui-registration.js.map +1 -0
  99. package/helpers/utils.d.ts +9 -0
  100. package/helpers/utils.js +22 -2
  101. package/helpers/utils.js.map +1 -1
  102. package/helpers/workers.d.ts +20 -19
  103. package/helpers/workers.js +624 -4
  104. package/helpers/workers.js.map +1 -1
  105. package/hmr/client/css-handler.d.ts +2 -1
  106. package/hmr/client/css-handler.js +50 -26
  107. package/hmr/client/css-handler.js.map +1 -1
  108. package/hmr/client/css-update-overlay.d.ts +18 -0
  109. package/hmr/client/css-update-overlay.js +27 -0
  110. package/hmr/client/css-update-overlay.js.map +1 -0
  111. package/hmr/client/framework-client-strategy.d.ts +79 -0
  112. package/hmr/client/framework-client-strategy.js +19 -0
  113. package/hmr/client/framework-client-strategy.js.map +1 -0
  114. package/hmr/client/hmr-pending-overlay.d.ts +13 -0
  115. package/hmr/client/hmr-pending-overlay.js +60 -0
  116. package/hmr/client/hmr-pending-overlay.js.map +1 -0
  117. package/hmr/client/index.js +891 -220
  118. package/hmr/client/index.js.map +1 -1
  119. package/hmr/client/utils.d.ts +7 -1
  120. package/hmr/client/utils.js +207 -29
  121. package/hmr/client/utils.js.map +1 -1
  122. package/hmr/entry-runtime.d.ts +2 -1
  123. package/hmr/entry-runtime.js +256 -69
  124. package/hmr/entry-runtime.js.map +1 -1
  125. package/hmr/frameworks/angular/build/angular-linker.d.ts +12 -0
  126. package/hmr/frameworks/angular/build/angular-linker.js +109 -0
  127. package/hmr/frameworks/angular/build/angular-linker.js.map +1 -0
  128. package/hmr/frameworks/angular/build/inject-component-hmr-registration.d.ts +112 -0
  129. package/hmr/frameworks/angular/build/inject-component-hmr-registration.js +291 -0
  130. package/hmr/frameworks/angular/build/inject-component-hmr-registration.js.map +1 -0
  131. package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.d.ts +75 -0
  132. package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.js +221 -0
  133. package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.js.map +1 -0
  134. package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.js +1 -170
  135. package/hmr/frameworks/angular/build/inline-decorator-component-templates.js.map +1 -0
  136. package/hmr/frameworks/angular/build/js-lexer.d.ts +4 -0
  137. package/{helpers/angular/synthesize-decorator-ctor-parameters.js → hmr/frameworks/angular/build/js-lexer.js} +22 -96
  138. package/hmr/frameworks/angular/build/js-lexer.js.map +1 -0
  139. package/hmr/frameworks/angular/build/shared-linker.d.ts +39 -0
  140. package/hmr/frameworks/angular/build/shared-linker.js +128 -0
  141. package/hmr/frameworks/angular/build/shared-linker.js.map +1 -0
  142. package/hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js +88 -0
  143. package/hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js.map +1 -0
  144. package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.js +1 -174
  145. package/hmr/frameworks/angular/build/synthesize-injectable-factories.js.map +1 -0
  146. package/{helpers/angular → hmr/frameworks/angular/build}/util.d.ts +1 -0
  147. package/hmr/frameworks/angular/build/util.js +155 -0
  148. package/hmr/frameworks/angular/build/util.js.map +1 -0
  149. package/hmr/frameworks/angular/client/index.d.ts +1 -0
  150. package/hmr/frameworks/angular/client/index.js +859 -21
  151. package/hmr/frameworks/angular/client/index.js.map +1 -1
  152. package/hmr/frameworks/angular/client/strategy.d.ts +9 -0
  153. package/hmr/frameworks/angular/client/strategy.js +19 -0
  154. package/hmr/frameworks/angular/client/strategy.js.map +1 -0
  155. package/hmr/frameworks/angular/server/angular-root-component.d.ts +79 -0
  156. package/hmr/frameworks/angular/server/angular-root-component.js +149 -0
  157. package/hmr/frameworks/angular/server/angular-root-component.js.map +1 -0
  158. package/hmr/frameworks/angular/server/linker.js +1 -4
  159. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  160. package/hmr/frameworks/angular/server/strategy.js +460 -12
  161. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  162. package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.js +2 -2
  163. package/hmr/frameworks/angular/server/websocket-angular-entry.js.map +1 -0
  164. package/hmr/{server → frameworks/angular/server}/websocket-angular-hot-update.d.ts +17 -11
  165. package/hmr/frameworks/angular/server/websocket-angular-hot-update.js +336 -0
  166. package/hmr/frameworks/angular/server/websocket-angular-hot-update.js.map +1 -0
  167. package/hmr/frameworks/react/server/strategy.d.ts +2 -0
  168. package/hmr/frameworks/react/server/strategy.js +150 -0
  169. package/hmr/frameworks/react/server/strategy.js.map +1 -0
  170. package/hmr/frameworks/solid/build/solid-jsx-deps.d.ts +15 -0
  171. package/hmr/frameworks/solid/build/solid-jsx-deps.js +178 -0
  172. package/hmr/frameworks/solid/build/solid-jsx-deps.js.map +1 -0
  173. package/hmr/frameworks/solid/client/app-runtime.d.ts +54 -0
  174. package/hmr/frameworks/solid/client/app-runtime.js +184 -0
  175. package/hmr/frameworks/solid/client/app-runtime.js.map +1 -0
  176. package/hmr/frameworks/solid/server/strategy.js +291 -16
  177. package/hmr/frameworks/solid/server/strategy.js.map +1 -1
  178. package/hmr/frameworks/typescript/server/strategy.js +38 -14
  179. package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
  180. package/hmr/frameworks/vue/client/dep-propagation.d.ts +36 -0
  181. package/hmr/frameworks/vue/client/dep-propagation.js +101 -0
  182. package/hmr/frameworks/vue/client/dep-propagation.js.map +1 -0
  183. package/hmr/frameworks/vue/client/index.d.ts +8 -0
  184. package/hmr/frameworks/vue/client/index.js +56 -243
  185. package/hmr/frameworks/vue/client/index.js.map +1 -1
  186. package/hmr/frameworks/vue/client/strategy.d.ts +33 -0
  187. package/hmr/frameworks/vue/client/strategy.js +157 -0
  188. package/hmr/frameworks/vue/client/strategy.js.map +1 -0
  189. package/hmr/frameworks/vue/client/vue-sfc-update-overlay.d.ts +49 -0
  190. package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js +142 -0
  191. package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js.map +1 -0
  192. package/hmr/frameworks/vue/server/sfc-route-assemble.d.ts +7 -0
  193. package/hmr/frameworks/vue/server/sfc-route-assemble.js +747 -0
  194. package/hmr/frameworks/vue/server/sfc-route-assemble.js.map +1 -0
  195. package/hmr/frameworks/vue/server/sfc-route-meta.d.ts +7 -0
  196. package/hmr/frameworks/vue/server/sfc-route-meta.js +80 -0
  197. package/hmr/frameworks/vue/server/sfc-route-meta.js.map +1 -0
  198. package/hmr/frameworks/vue/server/sfc-route-serve.d.ts +8 -0
  199. package/hmr/frameworks/vue/server/sfc-route-serve.js +459 -0
  200. package/hmr/frameworks/vue/server/sfc-route-serve.js.map +1 -0
  201. package/hmr/frameworks/vue/server/sfc-route-shared.d.ts +38 -0
  202. package/hmr/frameworks/vue/server/sfc-route-shared.js +48 -0
  203. package/hmr/frameworks/vue/server/sfc-route-shared.js.map +1 -0
  204. package/hmr/frameworks/vue/server/strategy.d.ts +35 -0
  205. package/hmr/frameworks/vue/server/strategy.js +278 -1
  206. package/hmr/frameworks/vue/server/strategy.js.map +1 -1
  207. package/hmr/frameworks/vue/server/websocket-sfc.d.ts +15 -0
  208. package/hmr/frameworks/vue/server/websocket-sfc.js +20 -0
  209. package/hmr/frameworks/vue/server/websocket-sfc.js.map +1 -0
  210. package/hmr/helpers/ast-normalizer.d.ts +3 -1
  211. package/hmr/helpers/ast-normalizer.js +77 -10
  212. package/hmr/helpers/ast-normalizer.js.map +1 -1
  213. package/hmr/helpers/cjs-named-exports.d.ts +23 -0
  214. package/hmr/helpers/cjs-named-exports.js +152 -0
  215. package/hmr/helpers/cjs-named-exports.js.map +1 -0
  216. package/hmr/helpers/package-exports.d.ts +16 -0
  217. package/hmr/helpers/package-exports.js +396 -0
  218. package/hmr/helpers/package-exports.js.map +1 -0
  219. package/hmr/server/constants.js +20 -5
  220. package/hmr/server/constants.js.map +1 -1
  221. package/hmr/server/core-sanitize.d.ts +86 -7
  222. package/hmr/server/core-sanitize.js +170 -45
  223. package/hmr/server/core-sanitize.js.map +1 -1
  224. package/hmr/server/device-transform-helpers.d.ts +24 -0
  225. package/hmr/server/device-transform-helpers.js +408 -0
  226. package/hmr/server/device-transform-helpers.js.map +1 -0
  227. package/hmr/server/framework-strategy.d.ts +108 -11
  228. package/hmr/server/hmr-module-graph.d.ts +37 -0
  229. package/hmr/server/hmr-module-graph.js +214 -0
  230. package/hmr/server/hmr-module-graph.js.map +1 -0
  231. package/hmr/server/import-map.d.ts +11 -2
  232. package/hmr/server/import-map.js +92 -45
  233. package/hmr/server/import-map.js.map +1 -1
  234. package/hmr/server/index.js +7 -16
  235. package/hmr/server/index.js.map +1 -1
  236. package/hmr/server/ns-core-cjs-shape.d.ts +2 -4
  237. package/hmr/server/ns-core-cjs-shape.js +4 -6
  238. package/hmr/server/ns-core-cjs-shape.js.map +1 -1
  239. package/hmr/server/ns-rt-bridge.d.ts +51 -0
  240. package/hmr/server/ns-rt-bridge.js +131 -0
  241. package/hmr/server/ns-rt-bridge.js.map +1 -0
  242. package/hmr/server/ns-rt-route.d.ts +5 -0
  243. package/hmr/server/ns-rt-route.js +38 -0
  244. package/hmr/server/ns-rt-route.js.map +1 -0
  245. package/hmr/server/perf-instrumentation.d.ts +114 -0
  246. package/hmr/server/perf-instrumentation.js +197 -0
  247. package/hmr/server/perf-instrumentation.js.map +1 -0
  248. package/hmr/server/process-code-for-device.d.ts +14 -0
  249. package/hmr/server/process-code-for-device.js +699 -0
  250. package/hmr/server/process-code-for-device.js.map +1 -0
  251. package/hmr/server/require-guard.d.ts +1 -0
  252. package/hmr/server/require-guard.js +12 -0
  253. package/hmr/server/require-guard.js.map +1 -0
  254. package/hmr/server/rewrite-imports.d.ts +2 -0
  255. package/hmr/server/rewrite-imports.js +630 -0
  256. package/hmr/server/rewrite-imports.js.map +1 -0
  257. package/hmr/server/route-helpers.d.ts +7 -0
  258. package/hmr/server/route-helpers.js +13 -0
  259. package/hmr/server/route-helpers.js.map +1 -0
  260. package/hmr/server/server-origin.d.ts +2 -0
  261. package/hmr/server/server-origin.js +83 -0
  262. package/hmr/server/server-origin.js.map +1 -0
  263. package/hmr/server/shared-transform-request.js +13 -7
  264. package/hmr/server/shared-transform-request.js.map +1 -1
  265. package/hmr/server/transform-cache-invalidation.d.ts +37 -0
  266. package/hmr/server/transform-cache-invalidation.js +156 -0
  267. package/hmr/server/transform-cache-invalidation.js.map +1 -0
  268. package/hmr/server/vendor-bare-module-shims.d.ts +4 -0
  269. package/hmr/server/vendor-bare-module-shims.js +80 -0
  270. package/hmr/server/vendor-bare-module-shims.js.map +1 -0
  271. package/hmr/server/vite-plugin.js +78 -42
  272. package/hmr/server/vite-plugin.js.map +1 -1
  273. package/hmr/server/websocket-core-bridge.d.ts +45 -4
  274. package/hmr/server/websocket-core-bridge.js +50 -48
  275. package/hmr/server/websocket-core-bridge.js.map +1 -1
  276. package/hmr/server/websocket-css-hot-update.d.ts +33 -0
  277. package/hmr/server/websocket-css-hot-update.js +65 -0
  278. package/hmr/server/websocket-css-hot-update.js.map +1 -0
  279. package/hmr/server/websocket-device-transform.d.ts +3 -0
  280. package/hmr/server/websocket-device-transform.js +7 -0
  281. package/hmr/server/websocket-device-transform.js.map +1 -0
  282. package/hmr/server/websocket-graph-upsert.d.ts +15 -0
  283. package/hmr/server/websocket-graph-upsert.js +20 -0
  284. package/hmr/server/websocket-graph-upsert.js.map +1 -1
  285. package/hmr/server/websocket-hmr-pending.d.ts +37 -0
  286. package/hmr/server/websocket-hmr-pending.js +55 -0
  287. package/hmr/server/websocket-hmr-pending.js.map +1 -0
  288. package/hmr/server/websocket-hot-update.d.ts +77 -0
  289. package/hmr/server/websocket-hot-update.js +360 -0
  290. package/hmr/server/websocket-hot-update.js.map +1 -0
  291. package/hmr/server/websocket-import-map-route.d.ts +15 -0
  292. package/hmr/server/websocket-import-map-route.js +50 -0
  293. package/hmr/server/websocket-import-map-route.js.map +1 -0
  294. package/hmr/server/websocket-module-bindings.js +3 -3
  295. package/hmr/server/websocket-module-bindings.js.map +1 -1
  296. package/hmr/server/websocket-module-specifiers.d.ts +66 -2
  297. package/hmr/server/websocket-module-specifiers.js +191 -20
  298. package/hmr/server/websocket-module-specifiers.js.map +1 -1
  299. package/hmr/server/websocket-ns-core.d.ts +21 -0
  300. package/hmr/server/websocket-ns-core.js +311 -0
  301. package/hmr/server/websocket-ns-core.js.map +1 -0
  302. package/hmr/server/websocket-ns-entry.d.ts +21 -0
  303. package/hmr/server/websocket-ns-entry.js +164 -0
  304. package/hmr/server/websocket-ns-entry.js.map +1 -0
  305. package/hmr/server/websocket-ns-m-paths.d.ts +1 -1
  306. package/hmr/server/websocket-ns-m-paths.js +58 -13
  307. package/hmr/server/websocket-ns-m-paths.js.map +1 -1
  308. package/hmr/server/websocket-ns-m-request.d.ts +11 -1
  309. package/hmr/server/websocket-ns-m-request.js +18 -25
  310. package/hmr/server/websocket-ns-m-request.js.map +1 -1
  311. package/hmr/server/websocket-ns-m.d.ts +33 -0
  312. package/hmr/server/websocket-ns-m.js +752 -0
  313. package/hmr/server/websocket-ns-m.js.map +1 -0
  314. package/hmr/server/websocket-served-module-helpers.d.ts +49 -3
  315. package/hmr/server/websocket-served-module-helpers.js +403 -87
  316. package/hmr/server/websocket-served-module-helpers.js.map +1 -1
  317. package/hmr/server/websocket-txn.js +2 -8
  318. package/hmr/server/websocket-txn.js.map +1 -1
  319. package/hmr/server/websocket-vendor-unifier.d.ts +0 -1
  320. package/hmr/server/websocket-vendor-unifier.js +4 -9
  321. package/hmr/server/websocket-vendor-unifier.js.map +1 -1
  322. package/hmr/server/websocket.d.ts +8 -39
  323. package/hmr/server/websocket.js +608 -6300
  324. package/hmr/server/websocket.js.map +1 -1
  325. package/hmr/shared/ns-globals.d.ts +118 -0
  326. package/hmr/shared/ns-globals.js +29 -0
  327. package/hmr/shared/ns-globals.js.map +1 -0
  328. package/hmr/shared/protocol.d.ts +145 -0
  329. package/hmr/shared/protocol.js +28 -0
  330. package/hmr/shared/protocol.js.map +1 -0
  331. package/hmr/shared/runtime/boot-placeholder-ui.d.ts +69 -0
  332. package/hmr/shared/runtime/boot-placeholder-ui.js +101 -0
  333. package/hmr/shared/runtime/boot-placeholder-ui.js.map +1 -0
  334. package/hmr/shared/runtime/boot-progress.d.ts +44 -0
  335. package/hmr/shared/runtime/boot-progress.js +133 -0
  336. package/hmr/shared/runtime/boot-progress.js.map +1 -0
  337. package/hmr/shared/runtime/boot-timeline.d.ts +18 -0
  338. package/hmr/shared/runtime/boot-timeline.js +42 -0
  339. package/hmr/shared/runtime/boot-timeline.js.map +1 -0
  340. package/hmr/shared/runtime/browser-runtime-contract.js.map +1 -1
  341. package/hmr/shared/runtime/dev-overlay-snapshots.d.ts +31 -0
  342. package/hmr/shared/runtime/dev-overlay-snapshots.js +324 -0
  343. package/hmr/shared/runtime/dev-overlay-snapshots.js.map +1 -0
  344. package/hmr/shared/runtime/dev-overlay.d.ts +119 -26
  345. package/hmr/shared/runtime/dev-overlay.js +1196 -262
  346. package/hmr/shared/runtime/dev-overlay.js.map +1 -1
  347. package/hmr/shared/runtime/global-scope.d.ts +18 -0
  348. package/hmr/shared/runtime/global-scope.js +21 -0
  349. package/hmr/shared/runtime/global-scope.js.map +1 -0
  350. package/hmr/shared/runtime/hooks.js +2 -1
  351. package/hmr/shared/runtime/hooks.js.map +1 -1
  352. package/hmr/shared/runtime/http-only-boot.js +7 -6
  353. package/hmr/shared/runtime/http-only-boot.js.map +1 -1
  354. package/hmr/shared/runtime/module-provenance.js +4 -6
  355. package/hmr/shared/runtime/module-provenance.js.map +1 -1
  356. package/hmr/shared/runtime/root-placeholder-view.d.ts +19 -0
  357. package/hmr/shared/runtime/root-placeholder-view.js +311 -0
  358. package/hmr/shared/runtime/root-placeholder-view.js.map +1 -0
  359. package/hmr/shared/runtime/root-placeholder.js +393 -200
  360. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  361. package/hmr/shared/runtime/session-bootstrap.js +168 -4
  362. package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
  363. package/hmr/shared/runtime/vendor-bootstrap.js +3 -10
  364. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  365. package/hmr/shared/vendor/manifest-collect.d.ts +4 -0
  366. package/hmr/shared/vendor/manifest-collect.js +549 -0
  367. package/hmr/shared/vendor/manifest-collect.js.map +1 -0
  368. package/hmr/shared/vendor/manifest-loader.d.ts +2 -1
  369. package/hmr/shared/vendor/manifest-loader.js +5 -3
  370. package/hmr/shared/vendor/manifest-loader.js.map +1 -1
  371. package/hmr/shared/vendor/manifest.d.ts +1 -7
  372. package/hmr/shared/vendor/manifest.js +84 -819
  373. package/hmr/shared/vendor/manifest.js.map +1 -1
  374. package/hmr/shared/vendor/vendor-device-shim.d.ts +1 -0
  375. package/hmr/shared/vendor/vendor-device-shim.js +208 -0
  376. package/hmr/shared/vendor/vendor-device-shim.js.map +1 -0
  377. package/hmr/shared/vendor/vendor-esbuild-plugins.d.ts +38 -0
  378. package/hmr/shared/vendor/vendor-esbuild-plugins.js +296 -0
  379. package/hmr/shared/vendor/vendor-esbuild-plugins.js.map +1 -0
  380. package/hmr/vendor-bootstrap.d.ts +1 -3
  381. package/hmr/vendor-bootstrap.js +4 -6
  382. package/hmr/vendor-bootstrap.js.map +1 -1
  383. package/index.d.ts +1 -0
  384. package/index.js +5 -0
  385. package/index.js.map +1 -1
  386. package/package.json +61 -11
  387. package/runtime/core-aliases-early.js +25 -55
  388. package/runtime/core-aliases-early.js.map +1 -1
  389. package/shims/react-jsx-runtime.d.ts +4 -0
  390. package/shims/react-jsx-runtime.js +61 -0
  391. package/shims/react-jsx-runtime.js.map +1 -0
  392. package/helpers/angular/angular-linker.d.ts +0 -13
  393. package/helpers/angular/angular-linker.js +0 -194
  394. package/helpers/angular/angular-linker.js.map +0 -1
  395. package/helpers/angular/inline-decorator-component-templates.js.map +0 -1
  396. package/helpers/angular/shared-linker.d.ts +0 -11
  397. package/helpers/angular/shared-linker.js +0 -75
  398. package/helpers/angular/shared-linker.js.map +0 -1
  399. package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +0 -1
  400. package/helpers/angular/synthesize-injectable-factories.js.map +0 -1
  401. package/helpers/angular/util.js +0 -67
  402. package/helpers/angular/util.js.map +0 -1
  403. package/helpers/prelink-angular.d.ts +0 -2
  404. package/helpers/prelink-angular.js +0 -117
  405. package/helpers/prelink-angular.js.map +0 -1
  406. package/hmr/server/websocket-angular-entry.js.map +0 -1
  407. package/hmr/server/websocket-angular-hot-update.js +0 -239
  408. package/hmr/server/websocket-angular-hot-update.js.map +0 -1
  409. package/hmr/server/websocket-ns-m-finalize.d.ts +0 -22
  410. package/hmr/server/websocket-ns-m-finalize.js +0 -88
  411. package/hmr/server/websocket-ns-m-finalize.js.map +0 -1
  412. package/hmr/server/websocket-runtime-compat.d.ts +0 -19
  413. package/hmr/server/websocket-runtime-compat.js +0 -286
  414. package/hmr/server/websocket-runtime-compat.js.map +0 -1
  415. package/hmr/server/websocket-vue-sfc.d.ts +0 -27
  416. package/hmr/server/websocket-vue-sfc.js +0 -1117
  417. package/hmr/server/websocket-vue-sfc.js.map +0 -1
  418. package/transformers/NativeClass/index.d.ts +0 -2
  419. package/transformers/NativeClass/index.js +0 -222
  420. package/transformers/NativeClass/index.js.map +0 -1
  421. /package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.d.ts +0 -0
  422. /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-decorator-ctor-parameters.d.ts +0 -0
  423. /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.d.ts +0 -0
  424. /package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.d.ts +0 -0
@@ -1,143 +1,68 @@
1
1
  import { mergeConfig } from 'vite';
2
2
  import path from 'path';
3
3
  import fs from 'node:fs';
4
- import { createRequire } from 'node:module';
5
4
  import angular from '@analogjs/vite-plugin-angular';
6
- import { angularLinkerVitePlugin, angularLinkerVitePluginPost } from '../helpers/angular/angular-linker.js';
7
- import { synthesizeMissingInjectableFactories } from '../helpers/angular/synthesize-injectable-factories.js';
8
- import { ensureSharedAngularLinker, resolveAngularFileSystem } from '../helpers/angular/shared-linker.js';
9
- import { inlineDecoratorComponentTemplates } from '../helpers/angular/inline-decorator-component-templates.js';
10
- import { synthesizeDecoratorCtorParameters } from '../helpers/angular/synthesize-decorator-ctor-parameters.js';
11
- import { containsRealNgDeclare } from '../helpers/angular/util.js';
5
+ import { angularLinkerVitePlugin, angularLinkerVitePluginPost } from '../hmr/frameworks/angular/build/angular-linker.js';
6
+ import { synthesizeMissingInjectableFactories } from '../hmr/frameworks/angular/build/synthesize-injectable-factories.js';
7
+ import { getAngularLinkerFactory, runAngularLinker } from '../hmr/frameworks/angular/build/shared-linker.js';
8
+ import { inlineDecoratorComponentTemplates } from '../hmr/frameworks/angular/build/inline-decorator-component-templates.js';
9
+ import { appendComponentHmrRegistration, findComponentClassNames, INJECTION_MARKER as HMR_REGISTER_MARKER } from '../hmr/frameworks/angular/build/inject-component-hmr-registration.js';
10
+ import { injectAngularHmrViteIgnore } from '../hmr/frameworks/angular/build/inject-hmr-vite-ignore.js';
11
+ import { synthesizeDecoratorCtorParameters } from '../hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js';
12
+ import { containsRealNgDeclare, stripJsComments } from '../hmr/frameworks/angular/build/util.js';
12
13
  import { baseConfig } from './base.js';
13
14
  import { getCliFlags } from '../helpers/cli-flags.js';
14
15
  import { resolveRelativeToImportMeta } from '../helpers/import-meta-path.js';
15
- // Lazily import the Angular linker factory function. Used by chunk-level linkers
16
- // to create FRESH plugin instances per invocation (avoiding stale state in watch mode).
17
- let _cachedLinkerFactory = null;
18
- async function importLinkerFactory() {
19
- if (_cachedLinkerFactory)
20
- return _cachedLinkerFactory;
21
- const req = createRequire(process.cwd() + '/package.json');
22
- try {
23
- const linkerPath = req.resolve('@angular/compiler-cli/linker/babel');
24
- const linkerMod = await import(linkerPath);
25
- _cachedLinkerFactory = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
26
- }
27
- catch {
28
- try {
29
- const linkerMod = await import('@angular/compiler-cli/linker/babel');
30
- _cachedLinkerFactory = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin || null;
31
- }
32
- catch { }
33
- }
34
- return _cachedLinkerFactory;
16
+ import { resolveVerboseFlag } from '../helpers/logging.js';
17
+ import { NS_OPTIMIZE_DEPS_EXCLUDE } from '../helpers/optimize-deps.js';
18
+ function hasNgDeclarePartial(code) {
19
+ return code.indexOf('\u0275\u0275ngDeclare') !== -1 || code.indexOf('ɵɵngDeclare') !== -1 || code.indexOf('ngDeclare') !== -1;
35
20
  }
36
21
  // Rollup-level linker to guarantee Angular libraries are linked when included in the bundle graph.
37
22
  function angularRollupLinker(projectRoot) {
38
- let babel = null;
39
- let createLinker = null;
40
- let angularFileSystem = null;
41
23
  const FILTER = /node_modules\/(?:@angular|@nativescript\/angular)\/.*\.[mc]?js$/;
42
- async function ensureDeps() {
43
- if (babel && createLinker)
44
- return;
45
- try {
46
- const req = createRequire((projectRoot ? projectRoot + '/package.json' : import.meta.url));
47
- const babelPath = req.resolve('@babel/core');
48
- const linkerPath = req.resolve('@angular/compiler-cli/linker/babel');
49
- babel = await import(babelPath);
50
- const linkerMod = await import(linkerPath);
51
- createLinker = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin;
52
- }
53
- catch {
54
- try {
55
- babel = await import('@babel/core');
56
- }
57
- catch { }
58
- try {
59
- const linkerMod = await import('@angular/compiler-cli/linker/babel');
60
- createLinker = linkerMod.createLinkerPlugin || linkerMod.createEs2015LinkerPlugin;
61
- }
62
- catch { }
63
- }
64
- if (!angularFileSystem) {
65
- angularFileSystem = await resolveAngularFileSystem(projectRoot);
66
- }
67
- }
24
+ const debug = process.env.VITE_DEBUG_LOGS === 'true' || process.env.VITE_DEBUG_LOGS === '1';
68
25
  return {
69
26
  name: 'ns-angular-linker-rollup',
70
27
  enforce: 'pre',
71
28
  apply: 'build',
72
29
  async load(id) {
73
- const debug = process.env.VITE_DEBUG_LOGS === 'true' || process.env.VITE_DEBUG_LOGS === '1';
74
- const cleanId = id.split('?', 1)[0];
30
+ const cleanId = normalizeAngularWatchPath(id);
75
31
  if (!FILTER.test(cleanId))
76
32
  return null;
77
33
  try {
78
- await ensureDeps();
79
- if (!babel || !createLinker)
80
- return null;
81
34
  const fs = await import('node:fs/promises');
82
35
  const code = await fs.readFile(cleanId, 'utf8');
83
36
  const forceLink = cleanId.includes('/node_modules/@nativescript/angular/') && cleanId.includes('polyfills');
84
37
  if (!code)
85
38
  return null;
86
- if (!forceLink && code.indexOf('\u0275\u0275ngDeclare') === -1 && code.indexOf('ɵɵngDeclare') === -1 && code.indexOf('ngDeclare') === -1)
39
+ if (!forceLink && !hasNgDeclarePartial(code))
87
40
  return null;
88
- const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
89
- if (debug) {
90
- try {
91
- console.log('[ns-angular-linker][rollup-load] linking', cleanId);
92
- }
93
- catch { }
94
- }
95
- const result = await babel.transformAsync(code, {
96
- filename: cleanId,
97
- configFile: false,
98
- babelrc: false,
99
- sourceMaps: false,
100
- compact: false,
101
- plugins: [plugin],
102
- });
103
- if (result?.code && result.code !== code) {
104
- return { code: result.code, map: null };
41
+ const linked = await runAngularLinker(code, { filename: cleanId, projectRoot, freshPlugin: true });
42
+ if (linked) {
43
+ if (debug)
44
+ console.log('[ns-angular-linker][rollup-load] linked', cleanId);
45
+ return { code: linked, map: null };
105
46
  }
106
47
  }
107
48
  catch { }
108
49
  return null;
109
50
  },
110
51
  async transform(code, id) {
111
- const debug = process.env.VITE_DEBUG_LOGS === 'true' || process.env.VITE_DEBUG_LOGS === '1';
112
- const cleanId = id.split('?', 1)[0];
52
+ const cleanId = normalizeAngularWatchPath(id);
113
53
  if (!FILTER.test(cleanId))
114
54
  return null;
115
55
  const forceLink = cleanId.includes('/node_modules/@nativescript/angular/') && cleanId.includes('polyfills');
116
56
  if (!code)
117
57
  return null;
118
- if (!forceLink && code.indexOf('\u0275\u0275ngDeclare') === -1 && code.indexOf('ɵɵngDeclare') === -1 && code.indexOf('ngDeclare') === -1)
119
- return null;
120
- await ensureDeps();
121
- if (!babel || !createLinker)
58
+ if (!forceLink && !hasNgDeclarePartial(code))
122
59
  return null;
123
60
  try {
124
- const plugin = createLinker({ sourceMapping: false, fileSystem: angularFileSystem });
125
- if (debug) {
126
- try {
127
- console.log('[ns-angular-linker][rollup] linking', cleanId);
128
- }
129
- catch { }
130
- }
131
- const result = await babel.transformAsync(code, {
132
- filename: cleanId,
133
- configFile: false,
134
- babelrc: false,
135
- sourceMaps: false,
136
- compact: false,
137
- plugins: [plugin],
138
- });
139
- if (result?.code && result.code !== code) {
140
- return { code: result.code, map: null };
61
+ const linked = await runAngularLinker(code, { filename: cleanId, projectRoot, freshPlugin: true });
62
+ if (linked) {
63
+ if (debug)
64
+ console.log('[ns-angular-linker][rollup] linked', cleanId);
65
+ return { code: linked, map: null };
141
66
  }
142
67
  }
143
68
  catch { }
@@ -148,6 +73,37 @@ function angularRollupLinker(projectRoot) {
148
73
  const cliFlags = getCliFlags();
149
74
  const isDevEnv = process.env.NODE_ENV !== 'production';
150
75
  const hmrActive = isDevEnv && !!cliFlags.hmr;
76
+ /**
77
+ * Web-style template HMR opt-out.
78
+ *
79
+ * When `hmrActive` is true we default to the in-place template-replacement
80
+ * pipeline (`liveReload: true` on Analog → `_enableHmr: true` on the Angular
81
+ * TS compiler → `angular:component-update` events served via the
82
+ * `/@ng/component` middleware → `ɵɵreplaceMetadata` on the live class).
83
+ * Setting `_enableHmr: true` also forces Analog to set
84
+ * `externalRuntimeStyles: true`, changing how component styles are emitted
85
+ * (URLs fetched lazily instead of inlined). On the web that's fine; for
86
+ * NativeScript it's a new code path that touches the SCSS / Tailwind
87
+ * pipeline and the iOS runtime's HTTP module loader.
88
+ *
89
+ * If a project hits a regression on day one (broken styling, unresolved
90
+ * `?ngcomp=` imports, etc.) the user can roll back to the legacy reboot
91
+ * pipeline without an upstream patch by setting the env flag. We honour
92
+ * `0`, `false`, `off`, and `no` (case-insensitive) as "off" — anything
93
+ * else (including unset) keeps the new path on.
94
+ *
95
+ * The flag is read once at module load, mirroring how `hmrActive` is
96
+ * computed, so a project can flip it via `cross-env` in their dev script
97
+ * and never look back.
98
+ */
99
+ const angularLiveReloadDisabledByEnv = (() => {
100
+ const raw = process.env.NS_VITE_ANGULAR_LIVE_RELOAD;
101
+ if (typeof raw !== 'string')
102
+ return false;
103
+ const v = raw.trim().toLowerCase();
104
+ return v === '0' || v === 'false' || v === 'off' || v === 'no';
105
+ })();
106
+ const hmrAngularLiveReload = hmrActive && !angularLiveReloadDisabledByEnv;
151
107
  const projectRoot = process.cwd();
152
108
  const tsConfigAppPath = path.resolve(projectRoot, 'tsconfig.app.json');
153
109
  const tsConfigPath = path.resolve(projectRoot, 'tsconfig.json');
@@ -193,15 +149,24 @@ function extractComponentAssetPaths(code, componentId) {
193
149
  const componentPath = normalizeAngularWatchPath(componentId);
194
150
  const assetPaths = new Set();
195
151
  const resolveAssetPath = (assetPath) => normalizeAngularWatchPath(path.resolve(path.dirname(componentPath), assetPath));
196
- const templateUrlMatch = code.match(/templateUrl\s*:\s*['"](.+?\.(?:html|htm))['"]/);
152
+ // Blank out `//` and `/* */` comments before scanning. The regexes below
153
+ // are intentionally simple (no JS parser) so they would otherwise match
154
+ // commented-out `templateUrl` / `styleUrls` declarations and register
155
+ // phantom asset deps via `addWatchFile`. In current Rolldown-Vite that
156
+ // also enrolls them as `_addedImports`, which `vite:import-analysis`
157
+ // then tries to resolve — surfacing as a misleading
158
+ // `Failed to resolve import "<file>" from "<importer>". Does the file
159
+ // exist?` pre-transform error if the file (predictably) doesn't exist.
160
+ const scanCode = stripJsComments(code);
161
+ const templateUrlMatch = scanCode.match(/templateUrl\s*:\s*['"](.+?\.(?:html|htm))['"]/);
197
162
  if (templateUrlMatch) {
198
163
  assetPaths.add(resolveAssetPath(templateUrlMatch[1]));
199
164
  }
200
- const styleUrlMatch = code.match(/styleUrl\s*:\s*['"](.+?\.(?:css|less|sass|scss))['"]/);
165
+ const styleUrlMatch = scanCode.match(/styleUrl\s*:\s*['"](.+?\.(?:css|less|sass|scss))['"]/);
201
166
  if (styleUrlMatch) {
202
167
  assetPaths.add(resolveAssetPath(styleUrlMatch[1]));
203
168
  }
204
- const styleUrlsMatch = code.match(/styleUrls\s*:\s*\[([\s\S]*?)\]/m);
169
+ const styleUrlsMatch = scanCode.match(/styleUrls\s*:\s*\[([\s\S]*?)\]/m);
205
170
  if (styleUrlsMatch) {
206
171
  for (const match of styleUrlsMatch[1].matchAll(/['"](.+?\.(?:css|less|sass|scss))['"]/g)) {
207
172
  assetPaths.add(resolveAssetPath(match[1]));
@@ -210,9 +175,18 @@ function extractComponentAssetPaths(code, componentId) {
210
175
  return Array.from(assetPaths);
211
176
  }
212
177
  function createAngularPlugins(opts) {
178
+ const verbose = resolveVerboseFlag();
213
179
  const assetToComponents = new Map();
214
180
  const componentToAssets = new Map();
215
181
  const pendingComponentInvalidations = new Set();
182
+ // Shared state between the `enforce: 'pre'` discovery plugin and the
183
+ // `enforce: 'post'` injection plugin. Maps a clean (no-querystring)
184
+ // .ts file id to the list of `@Component`-decorated class names found
185
+ // in its RAW TypeScript source. The pre plugin populates this map;
186
+ // the post plugin reads it to know which class names to register
187
+ // against the compiled output. Cleared on each pre-plugin invocation
188
+ // so renames or `@Component` removals don't leave stale entries.
189
+ const componentsByCleanId = new Map();
216
190
  const untrackComponentAssets = (componentPath) => {
217
191
  const previousAssets = componentToAssets.get(componentPath);
218
192
  if (!previousAssets)
@@ -240,7 +214,121 @@ function createAngularPlugins(opts) {
240
214
  assetToComponents.set(assetPath, components);
241
215
  }
242
216
  };
217
+ const isCandidateComponentTs = (cleanId) => {
218
+ if (!cleanId.endsWith('.ts'))
219
+ return false;
220
+ if (cleanId.includes('/node_modules/'))
221
+ return false;
222
+ if (cleanId.endsWith('.d.ts'))
223
+ return false;
224
+ if (cleanId.endsWith('.spec.ts') || cleanId.endsWith('.test.ts'))
225
+ return false;
226
+ return true;
227
+ };
243
228
  return [
229
+ // HMR self-registration runs in two steps:
230
+ //
231
+ // 1. (this plugin, `enforce: 'pre'`) Walk the raw TypeScript
232
+ // source for each user `.ts` file and record the names of
233
+ // any `@Component`-decorated classes into the shared
234
+ // `componentsByCleanId` map. Discovery has to happen on the
235
+ // raw source because the Analog Angular plugin rewrites
236
+ // `@Component(...)` into static metadata calls and removes
237
+ // the textual decorator pattern.
238
+ //
239
+ // 2. (`ns-component-hmr-register-post`, `enforce: 'post'`)
240
+ // After the Analog Angular plugin has compiled the file,
241
+ // append the global `__NS_HMR_REGISTER_COMPONENT__`
242
+ // registration calls keyed by the names recorded in step 1.
243
+ //
244
+ // Why the two-step split: the Analog Angular plugin's `transform`
245
+ // returns its OWN regenerated compiled output (from its internal
246
+ // `outputFiles` cache populated at `buildStart`), discarding any
247
+ // code modifications applied earlier in the pipeline. We
248
+ // previously appended the registration snippet here, in the pre
249
+ // plugin, and the snippet was silently dropped — leaving the
250
+ // HMR class registry empty and `getFreshComponentClass` returning
251
+ // `found=false reason=no-registry` after every reboot.
252
+ //
253
+ // Placement notes that still apply:
254
+ // - `apply: 'serve'`: the registry runtime hook is dev-only;
255
+ // production builds never need self-registration.
256
+ // - Intentionally NOT gated on `hmrActive`. The injected
257
+ // snippet self-guards with
258
+ // `typeof globalThis.__NS_HMR_REGISTER_COMPONENT__ === 'function'`,
259
+ // so it's a no-op when the runtime hook isn't installed
260
+ // (e.g. `--no-hmr` users still serving modules through
261
+ // Vite). Gating the transform itself on `hmrActive` produced
262
+ // a silent failure mode where `--no-hmr` users got HMR
263
+ // machinery up but never got the registration calls
264
+ // injected, leaving the registry empty.
265
+ {
266
+ name: 'ns-component-hmr-register',
267
+ enforce: 'pre',
268
+ apply: 'serve',
269
+ transform(code, id) {
270
+ const cleanId = normalizeAngularWatchPath(id);
271
+ if (!isCandidateComponentTs(cleanId))
272
+ return null;
273
+ const componentNames = findComponentClassNames(code);
274
+ if (componentNames.length === 0) {
275
+ // Drop any stale entry from a previous transform
276
+ // pass; the file may have lost its `@Component`
277
+ // decorator across a rename/refactor.
278
+ componentsByCleanId.delete(cleanId);
279
+ return null;
280
+ }
281
+ componentsByCleanId.set(cleanId, componentNames);
282
+ if (verbose) {
283
+ console.info(`[ns-hmr][ns-component-hmr-register] discovered ${componentNames.length} component(s) in ${cleanId} (${componentNames.join(', ')})`);
284
+ }
285
+ // Discovery only — never modify the raw TS source. Any
286
+ // modification here is discarded by the Analog Angular
287
+ // plugin downstream; the actual snippet append happens
288
+ // in `ns-component-hmr-register-post`.
289
+ return null;
290
+ },
291
+ },
292
+ // Step 2 (post plugin): append the HMR registration snippet to the compiled
293
+ // JS output produced by `@analogjs/vite-plugin-angular`. Runs
294
+ // `enforce: 'post'` so we see the post-Angular code (where the
295
+ // pre plugin's work would otherwise be discarded). Reads the
296
+ // component names recorded by the pre plugin via
297
+ // `componentsByCleanId`.
298
+ {
299
+ name: 'ns-component-hmr-register-post',
300
+ enforce: 'post',
301
+ apply: 'serve',
302
+ transform(code, id) {
303
+ const cleanId = normalizeAngularWatchPath(id);
304
+ if (!isCandidateComponentTs(cleanId))
305
+ return null;
306
+ const componentNames = componentsByCleanId.get(cleanId);
307
+ if (!componentNames || componentNames.length === 0)
308
+ return null;
309
+ // Idempotency: the Vite cache may replay the transform
310
+ // pipeline on cached modules. The marker comment is
311
+ // inserted by `appendComponentHmrRegistration` and
312
+ // guards against double-injection. We also defensively
313
+ // short-circuit here so we don't have to allocate the
314
+ // suffix string on every cached re-run.
315
+ if (code.includes(HMR_REGISTER_MARKER))
316
+ return null;
317
+ const result = appendComponentHmrRegistration(code, componentNames);
318
+ if (!result.code)
319
+ return null;
320
+ if (verbose) {
321
+ console.info(`[ns-hmr][ns-component-hmr-register-post] appended registrations for ${result.componentNames.length} component(s) in ${cleanId} (${result.componentNames.join(', ')})`);
322
+ }
323
+ // Returning `null` for the source map is acceptable for
324
+ // dev: lines 1..N (the original compiled body) keep
325
+ // the upstream Angular source map; the appended snippet
326
+ // is invisible to debuggers but harmless. For
327
+ // production-grade source maps a MagicString-based
328
+ // pass-through could be used; not required for HMR.
329
+ return { code: result.code, map: null };
330
+ },
331
+ },
244
332
  // Allow external html template changes to trigger hot reload: Make .ts files depend on their .html templates
245
333
  {
246
334
  name: 'angular-template-deps',
@@ -255,6 +343,15 @@ function createAngularPlugins(opts) {
255
343
  for (const assetPath of assetPaths) {
256
344
  this.addWatchFile(assetPath);
257
345
  }
346
+ // Diagnostic: surface which .ts files we've registered
347
+ // asset (template/styleUrls) dependencies for. This is
348
+ // the first fence the HTML→TS invalidation pipeline must
349
+ // pass — if we never see a [tracking] log for the
350
+ // component we're editing, the watcher will never fire
351
+ // and `pendingComponentInvalidations` stays empty.
352
+ if (verbose) {
353
+ console.info(`[ns-hmr][angular-template-deps] [tracking] componentKey=${componentKey} assets=${assetPaths.length} (${assetPaths.slice(0, 4).join(', ')})`);
354
+ }
258
355
  return null;
259
356
  },
260
357
  watchChange(id) {
@@ -269,12 +366,27 @@ function createAngularPlugins(opts) {
269
366
  for (const componentPath of components) {
270
367
  pendingComponentInvalidations.add(componentPath);
271
368
  }
369
+ if (verbose) {
370
+ console.info(`[ns-hmr][angular-template-deps] watchChange [via assetToComponents] changed=${changedPath} → invalidating ${components.size} component(s):`, Array.from(components));
371
+ }
272
372
  return;
273
373
  }
274
374
  if (/\.(html|htm)$/i.test(changedPath)) {
275
375
  const componentPath = changedPath.replace(/\.(html|htm)$/i, '.ts');
276
- if (fs.existsSync(resolveAngularWatchFilePath(componentPath))) {
277
- pendingComponentInvalidations.add(normalizeAngularWatchKey(componentPath));
376
+ const exists = fs.existsSync(resolveAngularWatchFilePath(componentPath));
377
+ if (exists) {
378
+ const componentKey = normalizeAngularWatchKey(componentPath);
379
+ pendingComponentInvalidations.add(componentKey);
380
+ if (verbose) {
381
+ console.info(`[ns-hmr][angular-template-deps] watchChange [via fallback .html→.ts] changed=${changedPath} componentKey=${componentKey}`);
382
+ }
383
+ }
384
+ else {
385
+ // Truly anomalous: a watched template/style asset has no companion
386
+ // `.ts` file, so we cannot route the edit through the Angular
387
+ // HMR pipeline. Always-on warning so it surfaces in non-verbose
388
+ // runs — silent fallback would hide a real wiring break.
389
+ console.warn(`[ns-hmr][angular-template-deps] watchChange [no companion .ts found] changed=${changedPath} expectedTs=${componentPath}`);
278
390
  }
279
391
  }
280
392
  },
@@ -283,6 +395,9 @@ function createAngularPlugins(opts) {
283
395
  if (!pendingComponentInvalidations.has(componentPath))
284
396
  return null;
285
397
  pendingComponentInvalidations.delete(componentPath);
398
+ if (verbose) {
399
+ console.info(`[ns-hmr][angular-template-deps] shouldTransformCachedModule → re-transform componentKey=${componentPath}`);
400
+ }
286
401
  return true;
287
402
  },
288
403
  },
@@ -295,11 +410,140 @@ function createAngularPlugins(opts) {
295
410
  experimental: {
296
411
  useAngularCompilationAPI: opts.useAngularCompilationAPI,
297
412
  },
298
- liveReload: false, // Disable live reload in favor of HMR
413
+ // `liveReload` is Analog's flag for Angular's web-style template HMR
414
+ // pipeline. When ON, Analog:
415
+ // 1. Sets `_enableHmr = true` on the TS compiler so each compiled
416
+ // component `.mjs` emits `<ClassName>_HmrLoad` plus an
417
+ // `import.meta.hot.on('angular:component-update', ...)` listener.
418
+ // 2. Registers a `/@ng/component?c=<id>` middleware that serves the
419
+ // recompiled template's `_UpdateMetadata` source on demand.
420
+ // 3. In `handleHotUpdate` for `.html` / `.css` / `.scss` edits, sends
421
+ // `server.ws.send('angular:component-update', { id, timestamp })`
422
+ // so the runtime can call `ɵɵreplaceMetadata` on the live class —
423
+ // swapping the template definition AND walking live LViews to
424
+ // recreate matching views in-place. NO Angular reboot, NO route
425
+ // navigation.
426
+ //
427
+ // Previously this was `false` because the NativeScript HMR pipeline
428
+ // rebuilt every save through `__reboot_ng_modules__`. That works but
429
+ // has two big downsides on mobile: every save triggers a full app
430
+ // reboot AND the captured route-history replay (see
431
+ // `@nativescript/angular`'s `hmr-route-replay.ts`), which produces 2-3
432
+ // re-navigations per save and re-instantiates the page component
433
+ // multiple times. For pure template/style edits — the common case —
434
+ // the web-style component-replacement path keeps the page mounted and
435
+ // only swaps the changed bits.
436
+ //
437
+ // We only enable this when HMR itself is active (`hmrActive` already
438
+ // gates on `--hmr` and `NODE_ENV !== 'production'`). With HMR off the
439
+ // behaviour is unchanged: production builds and `--no-hmr` dev still
440
+ // see `liveReload: false`, the compiler skips the HMR initializers,
441
+ // and the middleware is not registered.
442
+ //
443
+ // Important interactions to be aware of:
444
+ // - When `_enableHmr` is true, Analog also sets
445
+ // `externalRuntimeStyles = true`, changing how component styles
446
+ // are emitted (URLs fetched at runtime instead of inlined). For
447
+ // NativeScript, the existing CSS pipeline expects inlined styles;
448
+ // `ns-component-hmr-style-overrides` (below) restores the
449
+ // pre-HMR style-emission strategy so Tailwind/global SCSS
450
+ // packaging keeps working.
451
+ // - The runtime dynamic-import resolves the metadata URL relative
452
+ // to `import.meta.url`, e.g. `http://host:port/ns/m/<componentDir>/@ng/component?c=...`.
453
+ // Analog's middleware uses `req.url.includes('/@ng/component')`
454
+ // (substring match), so the request still matches even with the
455
+ // `/ns/m/` prefix in the path.
456
+ // - The NS HMR client (`packages/vite/hmr/client/index.ts`)
457
+ // forwards Vite's standard `{ type: 'custom', event, data }`
458
+ // payloads to `import.meta.hot.on` listeners via
459
+ // `__NS_DISPATCH_HOT_EVENT__`, and short-circuits before the
460
+ // reboot path for `angular:component-update`.
461
+ // - The NS server-side hot-update handler in
462
+ // `packages/vite/hmr/server/websocket.ts` skips its own
463
+ // `ns:angular-update` broadcast for `.html` / component-style
464
+ // edits so we don't double-fire (the reboot path stays for `.ts`
465
+ // edits).
466
+ // - To roll back to the legacy reboot-only pipeline (e.g. while
467
+ // debugging an `externalRuntimeStyles` regression), set
468
+ // `NS_VITE_ANGULAR_LIVE_RELOAD=0` in the dev environment.
469
+ // `hmrAngularLiveReload` collapses both gates above.
470
+ liveReload: hmrAngularLiveReload,
471
+ // NativeScript can't consume Angular's `externalRuntimeStyles`
472
+ // mode — that emits component styles as runtime-loaded
473
+ // `<hash>.css` URL references which only a browser CSSOM/`<link>`
474
+ // pipeline can resolve. We tell our patched Analog plugin (see
475
+ // `patches/@analogjs+vite-plugin-angular+2.3.1.patch` in
476
+ // downstream apps; upstream PR pending) to keep the legacy
477
+ // behavior of inlining preprocessed CSS strings into the
478
+ // component metadata's `styles: [...]` array, which the NS
479
+ // renderer's CSS-bundle pipeline already knows how to apply.
480
+ // The option is independent from `liveReload` (`_enableHmr`
481
+ // still wires up `ɵɵreplaceMetadata` for in-place template
482
+ // HMR) — we keep HMR ON, just opt out of the URL-style
483
+ // emission. Note the option lands as a no-op on stock
484
+ // Analog releases that haven't merged the patch; once
485
+ // merged, this will switch the compiler off external styles
486
+ // for NativeScript without affecting web builds.
487
+ //
488
+ // `@ts-expect-error` because the option is not yet in
489
+ // `@analogjs/vite-plugin-angular`'s published `PluginOptions`
490
+ // type. When the upstream PR (https://github.com/analogjs/analog)
491
+ // adds it, this `@ts-expect-error` will itself become an
492
+ // "unused suppression" error — that's the signal to remove
493
+ // this comment AND the surrounding explanation, and bump
494
+ // the Analog peer dep to the version that ships the type.
495
+ // @ts-expect-error -- pending upstream Analog type publish
496
+ externalRuntimeStyles: false,
299
497
  tsconfig: tsConfig,
498
+ // Forward Angular-style file replacements (e.g. `environment.ts`
499
+ // → `environment.stg.ts`) directly into the Analog plugin so the
500
+ // Angular TypeScript host (which reads source files via its own
501
+ // CompilerHost, bypassing Vite's load chain) sees the swap. This
502
+ // is the same hook Angular CLI uses for `fileReplacements` in
503
+ // `angular.json` build configurations.
504
+ fileReplacements: opts.fileReplacements ?? [],
505
+ workspaceRoot: opts.workspaceRoot ?? process.cwd(),
300
506
  }),
301
507
  // Post-phase linker to catch any declarations introduced after other transforms (including project code)
302
508
  angularLinkerVitePluginPost(process.cwd()),
509
+ // Re-inject the `/* @vite-ignore */` annotation onto Angular's HMR
510
+ // initializer dynamic imports.
511
+ //
512
+ // Angular's compiler emits each component's HMR loader as
513
+ // `import(/* @vite-ignore */ i0.ɵɵgetReplaceMetadataURL(...))` so
514
+ // Vite leaves the runtime-computed URL alone. The annotation goes
515
+ // missing somewhere in the post-Angular pipeline (empirically the
516
+ // linker's `compact: false` Babel pass loses it on some files),
517
+ // causing Vite's static analyzer to flag the import and rewrite
518
+ // the call site through its runtime resolver — which then throws
519
+ // `TypeError at ɵɵgetReplaceMetadataURL` on the iOS device because
520
+ // the resolver expects a statically known specifier.
521
+ //
522
+ // Running `enforce: 'post'` and `apply: 'serve'` here ensures we
523
+ // see the file AFTER every other transform has had its chance to
524
+ // strip comments, AND only in dev (the HMR initializer is gated
525
+ // behind `ngDevMode` and never runs in a production build, so the
526
+ // fix would be wasted work outside `serve`). The helper is
527
+ // idempotent: if the annotation is already present, the file is
528
+ // returned unchanged.
529
+ {
530
+ name: 'ns-angular-hmr-vite-ignore',
531
+ enforce: 'post',
532
+ apply: 'serve',
533
+ transform(code, id) {
534
+ if (!hmrAngularLiveReload)
535
+ return null;
536
+ const cleanId = normalizeAngularWatchPath(id);
537
+ if (!cleanId.endsWith('.ts') && !cleanId.endsWith('.mjs') && !cleanId.endsWith('.js'))
538
+ return null;
539
+ if (cleanId.includes('/node_modules/'))
540
+ return null;
541
+ const next = injectAngularHmrViteIgnore(code);
542
+ if (next === code)
543
+ return null;
544
+ return { code: next, map: null };
545
+ },
546
+ },
303
547
  // Enforce: fully disable dependency optimization during serve to avoid rxjs esm5 crawling and OOM
304
548
  {
305
549
  name: 'ns-disable-optimize-deps',
@@ -309,7 +553,7 @@ function createAngularPlugins(opts) {
309
553
  const od = userConfig?.optimizeDeps || {};
310
554
  const prevExclude = Array.isArray(od.exclude) ? od.exclude : [];
311
555
  const exclude = new Set(prevExclude);
312
- ['@nativescript/core', 'rxjs', '@valor/nativescript-websockets', 'set-value', 'react', 'react-reconciler', 'react-nativescript'].forEach((x) => exclude.add(x));
556
+ [...NS_OPTIMIZE_DEPS_EXCLUDE, 'rxjs'].forEach((x) => exclude.add(x));
313
557
  return {
314
558
  optimizeDeps: {
315
559
  noDiscovery: true,
@@ -330,7 +574,7 @@ function createAngularPlugins(opts) {
330
574
  deps.entries = [];
331
575
  deps.include = [];
332
576
  const exclude = new Set(Array.isArray(deps.exclude) ? deps.exclude : []);
333
- ['@nativescript/core', 'rxjs', '@valor/nativescript-websockets', 'set-value', 'react', 'react-reconciler', 'react-nativescript'].forEach((x) => exclude.add(x));
577
+ [...NS_OPTIMIZE_DEPS_EXCLUDE, 'rxjs'].forEach((x) => exclude.add(x));
334
578
  deps.exclude = Array.from(exclude);
335
579
  const rolldownOptions = (deps.rolldownOptions || (deps.rolldownOptions = {}));
336
580
  rolldownOptions.plugins = [];
@@ -338,7 +582,7 @@ function createAngularPlugins(opts) {
338
582
  },
339
583
  ];
340
584
  }
341
- export const angularConfig = ({ mode }) => {
585
+ export const angularConfig = ({ mode, fileReplacements, workspaceRoot, }) => {
342
586
  const useSingleBundleDevOutput = mode === 'development' && !hmrActive;
343
587
  const plugins = createAngularPlugins({
344
588
  // Vite build --watch with the legacy Analog compilation path can regress
@@ -346,6 +590,8 @@ export const angularConfig = ({ mode }) => {
346
590
  // Restrict the newer compilation API to NativeScript's development no-HMR
347
591
  // flow, which is where the unstable rebuilds occur today.
348
592
  useAngularCompilationAPI: useSingleBundleDevOutput,
593
+ fileReplacements,
594
+ workspaceRoot,
349
595
  });
350
596
  const disableAnimations = true;
351
597
  //process.env.NS_DISABLE_NG_ANIMATIONS === "1" ||
@@ -366,17 +612,16 @@ export const angularConfig = ({ mode }) => {
366
612
  apply: 'build',
367
613
  enforce: 'post',
368
614
  async generateBundle(_options, bundle) {
615
+ function isNsAngularPolyfillsModule(id) {
616
+ return normalizeAngularWatchPath(id).includes('node_modules/@nativescript/angular/fesm2022/nativescript-angular-polyfills.mjs');
617
+ }
369
618
  function isNsAngularPolyfillsChunk(chunk) {
370
619
  if (!chunk || !chunk.modules)
371
620
  return false;
372
- return Object.keys(chunk.modules).some((m) => m.includes('node_modules/@nativescript/angular/fesm2022/nativescript-angular-polyfills.mjs'));
621
+ return Object.keys(chunk.modules).some(isNsAngularPolyfillsModule);
373
622
  }
374
- const { babel } = await ensureSharedAngularLinker(process.cwd());
375
- if (!babel)
376
- return;
377
- const fileSystem = await resolveAngularFileSystem(process.cwd());
378
- const linkerFactory = await importLinkerFactory();
379
- if (!linkerFactory)
623
+ const { babel, createLinker } = await getAngularLinkerFactory(process.cwd());
624
+ if (!babel || !createLinker)
380
625
  return;
381
626
  const strict = process.env.NS_STRICT_NG_LINK === '1' || process.env.NS_STRICT_NG_LINK === 'true';
382
627
  const enforceStrict = process.env.NS_STRICT_NG_LINK_ENFORCE === '1' || process.env.NS_STRICT_NG_LINK_ENFORCE === 'true';
@@ -396,26 +641,13 @@ export const angularConfig = ({ mode }) => {
396
641
  continue;
397
642
  const isNsPolyfills = isNsAngularPolyfillsChunk(chunk);
398
643
  try {
399
- // Create a FRESH linker plugin per chunk — the linker may have
400
- // internal state that becomes stale across watch-mode rebuild cycles.
401
- const freshPlugin = linkerFactory({ sourceMapping: false, fileSystem });
402
- const res = await babel.transformAsync(code, {
403
- filename: fileName,
404
- configFile: false,
405
- babelrc: false,
406
- sourceMaps: false,
407
- compact: false,
408
- plugins: [freshPlugin],
409
- });
410
- const linkedCode = res?.code && res.code !== code ? res.code : code;
411
- const finalCode = applyAngularChunkPostProcessing(linkedCode, { vendorInjectExport });
644
+ // Fresh plugin per chunk — avoids stale linker state across watch-mode rebuilds.
645
+ const linked = await runAngularLinker(code, { filename: fileName, projectRoot: process.cwd(), freshPlugin: true });
646
+ const finalCode = applyAngularChunkPostProcessing(linked ?? code, { vendorInjectExport });
412
647
  if (finalCode !== code) {
413
648
  chunk.code = finalCode;
414
649
  if (debug) {
415
- try {
416
- console.log('[ns-angular-linker][post] linked', fileName, isNsPolyfills ? '(polyfills)' : '');
417
- }
418
- catch { }
650
+ console.log('[ns-angular-linker][post] linked', fileName, isNsPolyfills ? '(polyfills)' : '');
419
651
  }
420
652
  }
421
653
  if (strict && !isNsPolyfills && containsRealNgDeclare(finalCode)) {
@@ -435,10 +667,10 @@ export const angularConfig = ({ mode }) => {
435
667
  const chunk = bundle[fname];
436
668
  const modIds = chunk?.modules
437
669
  ? Object.keys(chunk.modules)
438
- .filter((m) => /node_modules\/(?:@angular|@nativescript\/angular)\//.test(m))
670
+ .filter((m) => /node_modules\/(?:@angular|@nativescript\/angular)\//.test(normalizeAngularWatchPath(m)))
439
671
  .slice(0, 8)
440
672
  : [];
441
- const isOnlyPolyfills = modIds.length > 0 && modIds.every((m) => m.includes('node_modules/@nativescript/angular/fesm2022/nativescript-angular-polyfills.mjs'));
673
+ const isOnlyPolyfills = modIds.length > 0 && modIds.every(isNsAngularPolyfillsModule);
442
674
  if (isOnlyPolyfills)
443
675
  continue;
444
676
  let snippet = '';
@@ -461,10 +693,7 @@ export const angularConfig = ({ mode }) => {
461
693
  throw new Error(message);
462
694
  }
463
695
  else {
464
- try {
465
- console.warn(`[ns-angular-linker-post] ${message}`);
466
- }
467
- catch { }
696
+ console.warn(`[ns-angular-linker-post] ${message}`);
468
697
  }
469
698
  }
470
699
  },
@@ -484,37 +713,19 @@ export const angularConfig = ({ mode }) => {
484
713
  try {
485
714
  let transformed = code;
486
715
  if (containsRealNgDeclare(code)) {
487
- const { babel } = await ensureSharedAngularLinker(process.cwd());
488
- if (!babel)
716
+ const { babel, createLinker } = await getAngularLinkerFactory(process.cwd());
717
+ if (!babel || !createLinker)
489
718
  return null;
490
- const fileSystem = await resolveAngularFileSystem(process.cwd());
491
- // Fresh plugin per chunk avoids stale linker state across watch-mode rebuilds
492
- const freshPlugin = (await importLinkerFactory())?.({ sourceMapping: false, fileSystem });
493
- if (!freshPlugin)
494
- return null;
495
- const runLink = async (input) => {
496
- const result = await babel.transformAsync(input, {
497
- filename,
498
- configFile: false,
499
- babelrc: false,
500
- sourceMaps: false,
501
- compact: false,
502
- plugins: [freshPlugin],
503
- });
504
- return result?.code ?? input;
505
- };
506
- transformed = await runLink(code);
719
+ // Fresh plugin per pass — avoids stale linker state across watch-mode rebuilds.
720
+ transformed = (await runAngularLinker(code, { filename, projectRoot: process.cwd(), freshPlugin: true })) ?? code;
507
721
  if (containsRealNgDeclare(transformed)) {
508
- transformed = await runLink(transformed);
722
+ transformed = (await runAngularLinker(transformed, { filename, projectRoot: process.cwd(), freshPlugin: true })) ?? transformed;
509
723
  }
510
724
  }
511
725
  transformed = applyAngularChunkPostProcessing(transformed);
512
726
  if (transformed !== code) {
513
727
  if (debug) {
514
- try {
515
- console.log('[ns-angular-linker][render] linked', filename);
516
- }
517
- catch { }
728
+ console.log('[ns-angular-linker][render] linked', filename);
518
729
  }
519
730
  return { code: transformed, map: null };
520
731
  }