@nativescript/vite 8.0.0-alpha.3 → 8.0.0-alpha.30

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 (295) hide show
  1. package/README.md +51 -11
  2. package/configuration/angular.d.ts +34 -1
  3. package/configuration/angular.js +369 -159
  4. package/configuration/angular.js.map +1 -1
  5. package/configuration/base.js +184 -14
  6. package/configuration/base.js.map +1 -1
  7. package/configuration/javascript.js +5 -72
  8. package/configuration/javascript.js.map +1 -1
  9. package/configuration/solid.js +27 -1
  10. package/configuration/solid.js.map +1 -1
  11. package/configuration/typescript.js +5 -75
  12. package/configuration/typescript.js.map +1 -1
  13. package/helpers/angular/angular-linker.d.ts +5 -6
  14. package/helpers/angular/angular-linker.js +36 -121
  15. package/helpers/angular/angular-linker.js.map +1 -1
  16. package/helpers/angular/inject-component-hmr-registration.d.ts +112 -0
  17. package/helpers/angular/inject-component-hmr-registration.js +291 -0
  18. package/helpers/angular/inject-component-hmr-registration.js.map +1 -0
  19. package/helpers/angular/inject-hmr-vite-ignore.d.ts +75 -0
  20. package/helpers/angular/inject-hmr-vite-ignore.js +221 -0
  21. package/helpers/angular/inject-hmr-vite-ignore.js.map +1 -0
  22. package/helpers/angular/inline-decorator-component-templates.js +1 -170
  23. package/helpers/angular/inline-decorator-component-templates.js.map +1 -1
  24. package/helpers/angular/js-lexer.d.ts +4 -0
  25. package/helpers/angular/js-lexer.js +182 -0
  26. package/helpers/angular/js-lexer.js.map +1 -0
  27. package/helpers/angular/shared-linker.d.ts +31 -3
  28. package/helpers/angular/shared-linker.js +67 -14
  29. package/helpers/angular/shared-linker.js.map +1 -1
  30. package/helpers/angular/synthesize-decorator-ctor-parameters.js +2 -170
  31. package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +1 -1
  32. package/helpers/angular/synthesize-injectable-factories.js +1 -174
  33. package/helpers/angular/synthesize-injectable-factories.js.map +1 -1
  34. package/helpers/angular/util.d.ts +1 -0
  35. package/helpers/angular/util.js +88 -0
  36. package/helpers/angular/util.js.map +1 -1
  37. package/helpers/app-components.d.ts +2 -1
  38. package/helpers/app-components.js.map +1 -1
  39. package/helpers/app-css-state.d.ts +8 -0
  40. package/helpers/app-css-state.js +8 -0
  41. package/helpers/app-css-state.js.map +1 -0
  42. package/helpers/bundler-context.d.ts +11 -0
  43. package/helpers/bundler-context.js +71 -0
  44. package/helpers/bundler-context.js.map +1 -0
  45. package/helpers/config-as-json.js +10 -0
  46. package/helpers/config-as-json.js.map +1 -1
  47. package/helpers/dev-host.d.ts +341 -0
  48. package/helpers/dev-host.js +617 -0
  49. package/helpers/dev-host.js.map +1 -0
  50. package/helpers/esbuild-platform-resolver.js +4 -1
  51. package/helpers/esbuild-platform-resolver.js.map +1 -1
  52. package/helpers/global-defines.d.ts +51 -0
  53. package/helpers/global-defines.js +77 -0
  54. package/helpers/global-defines.js.map +1 -1
  55. package/helpers/hmr-scope.d.ts +26 -0
  56. package/helpers/hmr-scope.js +67 -0
  57. package/helpers/hmr-scope.js.map +1 -0
  58. package/helpers/init.js +0 -18
  59. package/helpers/init.js.map +1 -1
  60. package/helpers/logging.d.ts +1 -0
  61. package/helpers/logging.js +63 -3
  62. package/helpers/logging.js.map +1 -1
  63. package/helpers/main-entry.d.ts +2 -1
  64. package/helpers/main-entry.js +430 -47
  65. package/helpers/main-entry.js.map +1 -1
  66. package/helpers/nativeclass-esbuild-plugin.d.ts +2 -1
  67. package/helpers/nativeclass-esbuild-plugin.js.map +1 -1
  68. package/helpers/nativeclass-transform.js.map +1 -1
  69. package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
  70. package/helpers/nativeclass-transformer-plugin.js +157 -14
  71. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  72. package/helpers/nativescript-package-resolver.js +8 -3
  73. package/helpers/nativescript-package-resolver.js.map +1 -1
  74. package/helpers/normalize-id.d.ts +42 -0
  75. package/helpers/normalize-id.js +60 -0
  76. package/helpers/normalize-id.js.map +1 -0
  77. package/helpers/ns-core-url.d.ts +88 -0
  78. package/helpers/ns-core-url.js +191 -0
  79. package/helpers/ns-core-url.js.map +1 -0
  80. package/helpers/package-platform-aliases.js +4 -3
  81. package/helpers/package-platform-aliases.js.map +1 -1
  82. package/helpers/platform-types.d.ts +2 -0
  83. package/helpers/platform-types.js +2 -0
  84. package/helpers/platform-types.js.map +1 -0
  85. package/helpers/prelink-angular.js +12 -33
  86. package/helpers/prelink-angular.js.map +1 -1
  87. package/helpers/project.d.ts +35 -0
  88. package/helpers/project.js +120 -2
  89. package/helpers/project.js.map +1 -1
  90. package/helpers/resolver.js +17 -2
  91. package/helpers/resolver.js.map +1 -1
  92. package/helpers/solid-jsx-deps.d.ts +15 -0
  93. package/helpers/solid-jsx-deps.js +178 -0
  94. package/helpers/solid-jsx-deps.js.map +1 -0
  95. package/helpers/ts-config-paths.d.ts +14 -0
  96. package/helpers/ts-config-paths.js +89 -8
  97. package/helpers/ts-config-paths.js.map +1 -1
  98. package/helpers/typescript-check.d.ts +2 -1
  99. package/helpers/typescript-check.js.map +1 -1
  100. package/helpers/workers.d.ts +20 -19
  101. package/helpers/workers.js +624 -4
  102. package/helpers/workers.js.map +1 -1
  103. package/hmr/client/css-handler.d.ts +1 -0
  104. package/hmr/client/css-handler.js +33 -20
  105. package/hmr/client/css-handler.js.map +1 -1
  106. package/hmr/client/css-update-overlay.d.ts +18 -0
  107. package/hmr/client/css-update-overlay.js +27 -0
  108. package/hmr/client/css-update-overlay.js.map +1 -0
  109. package/hmr/client/hmr-pending-overlay.d.ts +27 -0
  110. package/hmr/client/hmr-pending-overlay.js +50 -0
  111. package/hmr/client/hmr-pending-overlay.js.map +1 -0
  112. package/hmr/client/index.js +419 -15
  113. package/hmr/client/index.js.map +1 -1
  114. package/hmr/client/utils.d.ts +6 -1
  115. package/hmr/client/utils.js +184 -8
  116. package/hmr/client/utils.js.map +1 -1
  117. package/hmr/client/vue-sfc-update-overlay.d.ts +82 -0
  118. package/hmr/client/vue-sfc-update-overlay.js +133 -0
  119. package/hmr/client/vue-sfc-update-overlay.js.map +1 -0
  120. package/hmr/entry-runtime.d.ts +2 -1
  121. package/hmr/entry-runtime.js +252 -65
  122. package/hmr/entry-runtime.js.map +1 -1
  123. package/hmr/frameworks/angular/client/index.d.ts +1 -0
  124. package/hmr/frameworks/angular/client/index.js +778 -20
  125. package/hmr/frameworks/angular/client/index.js.map +1 -1
  126. package/hmr/frameworks/angular/server/linker.js +1 -4
  127. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  128. package/hmr/frameworks/angular/server/strategy.js +13 -15
  129. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  130. package/hmr/frameworks/solid/server/strategy.js +3 -18
  131. package/hmr/frameworks/solid/server/strategy.js.map +1 -1
  132. package/hmr/frameworks/typescript/server/strategy.js +2 -15
  133. package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
  134. package/hmr/frameworks/vue/client/index.js +30 -199
  135. package/hmr/frameworks/vue/client/index.js.map +1 -1
  136. package/hmr/helpers/ast-normalizer.js +52 -5
  137. package/hmr/helpers/ast-normalizer.js.map +1 -1
  138. package/hmr/helpers/cjs-named-exports.d.ts +23 -0
  139. package/hmr/helpers/cjs-named-exports.js +152 -0
  140. package/hmr/helpers/cjs-named-exports.js.map +1 -0
  141. package/hmr/helpers/package-exports.d.ts +16 -0
  142. package/hmr/helpers/package-exports.js +396 -0
  143. package/hmr/helpers/package-exports.js.map +1 -0
  144. package/hmr/server/angular-root-component.d.ts +79 -0
  145. package/hmr/server/angular-root-component.js +149 -0
  146. package/hmr/server/angular-root-component.js.map +1 -0
  147. package/hmr/server/constants.js +13 -4
  148. package/hmr/server/constants.js.map +1 -1
  149. package/hmr/server/core-sanitize.d.ts +90 -7
  150. package/hmr/server/core-sanitize.js +211 -56
  151. package/hmr/server/core-sanitize.js.map +1 -1
  152. package/hmr/server/framework-strategy.d.ts +9 -19
  153. package/hmr/server/hmr-module-graph.d.ts +37 -0
  154. package/hmr/server/hmr-module-graph.js +214 -0
  155. package/hmr/server/hmr-module-graph.js.map +1 -0
  156. package/hmr/server/import-map.js +60 -8
  157. package/hmr/server/import-map.js.map +1 -1
  158. package/hmr/server/index.js +1 -0
  159. package/hmr/server/index.js.map +1 -1
  160. package/hmr/server/ns-core-cjs-shape.d.ts +204 -0
  161. package/hmr/server/ns-core-cjs-shape.js +271 -0
  162. package/hmr/server/ns-core-cjs-shape.js.map +1 -0
  163. package/hmr/server/ns-rt-bridge.d.ts +51 -0
  164. package/hmr/server/ns-rt-bridge.js +131 -0
  165. package/hmr/server/ns-rt-bridge.js.map +1 -0
  166. package/hmr/server/ns-rt-route.d.ts +5 -0
  167. package/hmr/server/ns-rt-route.js +35 -0
  168. package/hmr/server/ns-rt-route.js.map +1 -0
  169. package/hmr/server/perf-instrumentation.d.ts +114 -0
  170. package/hmr/server/perf-instrumentation.js +195 -0
  171. package/hmr/server/perf-instrumentation.js.map +1 -0
  172. package/hmr/server/require-guard.d.ts +1 -0
  173. package/hmr/server/require-guard.js +12 -0
  174. package/hmr/server/require-guard.js.map +1 -0
  175. package/hmr/server/route-helpers.d.ts +7 -0
  176. package/hmr/server/route-helpers.js +13 -0
  177. package/hmr/server/route-helpers.js.map +1 -0
  178. package/hmr/server/server-origin.d.ts +12 -0
  179. package/hmr/server/server-origin.js +66 -0
  180. package/hmr/server/server-origin.js.map +1 -0
  181. package/hmr/server/shared-transform-request.js +12 -5
  182. package/hmr/server/shared-transform-request.js.map +1 -1
  183. package/hmr/server/vendor-bare-module-shims.d.ts +4 -0
  184. package/hmr/server/vendor-bare-module-shims.js +80 -0
  185. package/hmr/server/vendor-bare-module-shims.js.map +1 -0
  186. package/hmr/server/vite-plugin.js +60 -42
  187. package/hmr/server/vite-plugin.js.map +1 -1
  188. package/hmr/server/websocket-angular-entry.js +1 -1
  189. package/hmr/server/websocket-angular-entry.js.map +1 -1
  190. package/hmr/server/websocket-angular-hot-update.d.ts +17 -0
  191. package/hmr/server/websocket-angular-hot-update.js +176 -2
  192. package/hmr/server/websocket-angular-hot-update.js.map +1 -1
  193. package/hmr/server/websocket-core-bridge.d.ts +41 -6
  194. package/hmr/server/websocket-core-bridge.js +72 -75
  195. package/hmr/server/websocket-core-bridge.js.map +1 -1
  196. package/hmr/server/websocket-css-hot-update.d.ts +33 -0
  197. package/hmr/server/websocket-css-hot-update.js +65 -0
  198. package/hmr/server/websocket-css-hot-update.js.map +1 -0
  199. package/hmr/server/websocket-device-transform.d.ts +21 -0
  200. package/hmr/server/websocket-device-transform.js +1570 -0
  201. package/hmr/server/websocket-device-transform.js.map +1 -0
  202. package/hmr/server/websocket-graph-upsert.d.ts +15 -0
  203. package/hmr/server/websocket-graph-upsert.js +20 -0
  204. package/hmr/server/websocket-graph-upsert.js.map +1 -1
  205. package/hmr/server/websocket-hmr-pending.d.ts +43 -0
  206. package/hmr/server/websocket-hmr-pending.js +55 -0
  207. package/hmr/server/websocket-hmr-pending.js.map +1 -0
  208. package/hmr/server/websocket-hot-update.d.ts +51 -0
  209. package/hmr/server/websocket-hot-update.js +1160 -0
  210. package/hmr/server/websocket-hot-update.js.map +1 -0
  211. package/hmr/server/websocket-import-map-route.d.ts +15 -0
  212. package/hmr/server/websocket-import-map-route.js +44 -0
  213. package/hmr/server/websocket-import-map-route.js.map +1 -0
  214. package/hmr/server/websocket-module-bindings.js +3 -3
  215. package/hmr/server/websocket-module-bindings.js.map +1 -1
  216. package/hmr/server/websocket-module-specifiers.d.ts +66 -2
  217. package/hmr/server/websocket-module-specifiers.js +202 -19
  218. package/hmr/server/websocket-module-specifiers.js.map +1 -1
  219. package/hmr/server/websocket-ns-core.d.ts +21 -0
  220. package/hmr/server/websocket-ns-core.js +305 -0
  221. package/hmr/server/websocket-ns-core.js.map +1 -0
  222. package/hmr/server/websocket-ns-entry.d.ts +22 -0
  223. package/hmr/server/websocket-ns-entry.js +150 -0
  224. package/hmr/server/websocket-ns-entry.js.map +1 -0
  225. package/hmr/server/websocket-ns-m-paths.d.ts +3 -0
  226. package/hmr/server/websocket-ns-m-paths.js +92 -0
  227. package/hmr/server/websocket-ns-m-paths.js.map +1 -0
  228. package/hmr/server/websocket-ns-m-request.d.ts +45 -0
  229. package/hmr/server/websocket-ns-m-request.js +196 -0
  230. package/hmr/server/websocket-ns-m-request.js.map +1 -0
  231. package/hmr/server/websocket-ns-m.d.ts +34 -0
  232. package/hmr/server/websocket-ns-m.js +853 -0
  233. package/hmr/server/websocket-ns-m.js.map +1 -0
  234. package/hmr/server/websocket-served-module-helpers.d.ts +39 -0
  235. package/hmr/server/websocket-served-module-helpers.js +654 -0
  236. package/hmr/server/websocket-served-module-helpers.js.map +1 -0
  237. package/hmr/server/websocket-sfc.d.ts +24 -0
  238. package/hmr/server/websocket-sfc.js +1223 -0
  239. package/hmr/server/websocket-sfc.js.map +1 -0
  240. package/hmr/server/websocket-txn.d.ts +6 -0
  241. package/hmr/server/websocket-txn.js +39 -0
  242. package/hmr/server/websocket-txn.js.map +1 -0
  243. package/hmr/server/websocket-vendor-unifier.d.ts +10 -0
  244. package/hmr/server/websocket-vendor-unifier.js +45 -0
  245. package/hmr/server/websocket-vendor-unifier.js.map +1 -0
  246. package/hmr/server/websocket.d.ts +0 -30
  247. package/hmr/server/websocket.js +599 -6038
  248. package/hmr/server/websocket.js.map +1 -1
  249. package/hmr/shared/runtime/boot-placeholder-ui.d.ts +69 -0
  250. package/hmr/shared/runtime/boot-placeholder-ui.js +101 -0
  251. package/hmr/shared/runtime/boot-placeholder-ui.js.map +1 -0
  252. package/hmr/shared/runtime/boot-progress.d.ts +40 -0
  253. package/hmr/shared/runtime/boot-progress.js +128 -0
  254. package/hmr/shared/runtime/boot-progress.js.map +1 -0
  255. package/hmr/shared/runtime/boot-timeline.d.ts +18 -0
  256. package/hmr/shared/runtime/boot-timeline.js +52 -0
  257. package/hmr/shared/runtime/boot-timeline.js.map +1 -0
  258. package/hmr/shared/runtime/dev-overlay-snapshots.d.ts +31 -0
  259. package/hmr/shared/runtime/dev-overlay-snapshots.js +324 -0
  260. package/hmr/shared/runtime/dev-overlay-snapshots.js.map +1 -0
  261. package/hmr/shared/runtime/dev-overlay.d.ts +75 -26
  262. package/hmr/shared/runtime/dev-overlay.js +990 -260
  263. package/hmr/shared/runtime/dev-overlay.js.map +1 -1
  264. package/hmr/shared/runtime/module-provenance.js +1 -4
  265. package/hmr/shared/runtime/module-provenance.js.map +1 -1
  266. package/hmr/shared/runtime/root-placeholder-view.d.ts +19 -0
  267. package/hmr/shared/runtime/root-placeholder-view.js +310 -0
  268. package/hmr/shared/runtime/root-placeholder-view.js.map +1 -0
  269. package/hmr/shared/runtime/root-placeholder.js +352 -194
  270. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  271. package/hmr/shared/runtime/session-bootstrap.js +164 -1
  272. package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
  273. package/hmr/shared/runtime/vendor-bootstrap.js +1 -9
  274. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  275. package/hmr/shared/vendor/manifest-collect.d.ts +32 -0
  276. package/hmr/shared/vendor/manifest-collect.js +512 -0
  277. package/hmr/shared/vendor/manifest-collect.js.map +1 -0
  278. package/hmr/shared/vendor/manifest-loader.d.ts +2 -1
  279. package/hmr/shared/vendor/manifest-loader.js +3 -2
  280. package/hmr/shared/vendor/manifest-loader.js.map +1 -1
  281. package/hmr/shared/vendor/manifest.d.ts +1 -5
  282. package/hmr/shared/vendor/manifest.js +102 -739
  283. package/hmr/shared/vendor/manifest.js.map +1 -1
  284. package/hmr/shared/vendor/vendor-device-shim.d.ts +1 -0
  285. package/hmr/shared/vendor/vendor-device-shim.js +208 -0
  286. package/hmr/shared/vendor/vendor-device-shim.js.map +1 -0
  287. package/hmr/shared/vendor/vendor-esbuild-plugins.d.ts +16 -0
  288. package/hmr/shared/vendor/vendor-esbuild-plugins.js +203 -0
  289. package/hmr/shared/vendor/vendor-esbuild-plugins.js.map +1 -0
  290. package/index.d.ts +1 -0
  291. package/index.js +5 -0
  292. package/index.js.map +1 -1
  293. package/package.json +55 -11
  294. package/runtime/core-aliases-early.js +17 -41
  295. package/runtime/core-aliases-early.js.map +1 -1
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Vite-side helper that injects HMR self-registration calls into the
3
+ * compiled output of user `.ts` files that declare `@Component`-
4
+ * decorated classes.
5
+ *
6
+ * After an HMR reboot, the global `__NS_HMR_REGISTER_COMPONENT__` hook
7
+ * (installed by `@nativescript/angular`) records each fresh class
8
+ * keyed by source name. HMR helpers (modal restore, route replay) read
9
+ * the registry to re-attach to the live class. See
10
+ * `hmr-class-registry.ts` for the runtime side of the contract.
11
+ *
12
+ * The helper exposes two phases used by complementary Vite plugins:
13
+ * 1. `findComponentClassNames(rawTs)` — scans the user's raw TS
14
+ * source for `@Component`-decorated classes. Used by an
15
+ * `enforce: 'pre'` plugin to discover names BEFORE the Analog
16
+ * Angular plugin compiles the file. The discovery has to happen
17
+ * on raw TS because the Angular plugin rewrites the `@Component`
18
+ * decorator into static metadata calls (`ɵsetClassMetadata`,
19
+ * `ɵɵdefineComponent`) and removes the textual `@Component(...)`
20
+ * pattern.
21
+ * 2. `appendComponentHmrRegistration(compiledCode, names)` — appends
22
+ * the registration snippet to the END of compiled JS produced by
23
+ * the Analog Angular plugin. Used by an `enforce: 'post'` plugin.
24
+ * Appending here is the only reliable insertion point because:
25
+ * - Class declarations are evaluated and bound by then.
26
+ * - Angular's static metadata (`ɵcmp`/`ɵfac`) has finished
27
+ * attaching, so the registered class identity already
28
+ * carries the up-to-date component definition.
29
+ * - The Analog Angular plugin's `transform` discards anything
30
+ * appended before its compilation step (it returns code
31
+ * regenerated from its own `outputFiles` cache, not the
32
+ * input passed in). Verified directly in the plugin chain.
33
+ * - Source-map line offsets for the original module body are
34
+ * preserved (we only append).
35
+ *
36
+ * The legacy `injectComponentHmrRegistration(rawTs)` helper is kept
37
+ * for backward compatibility — it appends to raw TS in a single call —
38
+ * but is no longer the path used by the live HMR pipeline (its output
39
+ * is silently dropped by the Angular plugin for `@Component` files).
40
+ *
41
+ * The helpers are dev-only: production builds skip the Vite plugins
42
+ * (`apply: 'serve'`), and the runtime hook short-circuits when
43
+ * `isAngularHmrEnabled()` is false.
44
+ */
45
+ import { findMatchingDelimiter } from './js-lexer.js';
46
+ const COMPONENT_DECORATOR_RE = /@Component\s*\(/g;
47
+ /**
48
+ * Marker comment placed immediately before the appended registration
49
+ * block. Plugins can scan for this string to make their work
50
+ * idempotent across re-transforms (the Vite cache may replay the
51
+ * transform pipeline on cached modules).
52
+ */
53
+ export const INJECTION_MARKER = '/* @nativescript/vite ns-hmr-register */';
54
+ /**
55
+ * Build the trailing snippet that registers each component class with
56
+ * the global HMR hook. Pure string construction — exposed so the post-
57
+ * Angular plugin can append it to compiled output without re-scanning
58
+ * for class names (the pre plugin already scanned the raw TS source).
59
+ *
60
+ * Returns an empty string when `componentNames` is empty so callers
61
+ * can concatenate unconditionally.
62
+ */
63
+ export function buildComponentHmrRegistrationSuffix(componentNames, options = {}) {
64
+ if (!componentNames || componentNames.length === 0) {
65
+ return '';
66
+ }
67
+ const hookName = options.hookName ?? '__NS_HMR_REGISTER_COMPONENT__';
68
+ const registrationLines = componentNames.map((name) => buildRegistrationLine(hookName, name));
69
+ // Pad with two newlines so the appended block is visually separated
70
+ // from the original module body in source maps and stack traces.
71
+ return `\n\n${INJECTION_MARKER}\n${registrationLines.join('\n')}\n`;
72
+ }
73
+ /**
74
+ * Append the registration snippet to a piece of code (typically the
75
+ * compiled output from `@analogjs/vite-plugin-angular`) using a list
76
+ * of component names previously discovered in the raw TS source.
77
+ *
78
+ * Returns `{ code: null, componentNames: [] }` if `componentNames`
79
+ * is empty or if the code already contains the injection marker
80
+ * (idempotent re-transform case).
81
+ */
82
+ export function appendComponentHmrRegistration(code, componentNames, options = {}) {
83
+ if (!code) {
84
+ return { code: null, componentNames: [] };
85
+ }
86
+ if (!componentNames || componentNames.length === 0) {
87
+ return { code: null, componentNames: [] };
88
+ }
89
+ if (code.includes(INJECTION_MARKER)) {
90
+ return { code: null, componentNames: [] };
91
+ }
92
+ const suffix = buildComponentHmrRegistrationSuffix(componentNames, options);
93
+ if (!suffix) {
94
+ return { code: null, componentNames: [] };
95
+ }
96
+ return {
97
+ code: code + suffix,
98
+ componentNames: [...componentNames],
99
+ };
100
+ }
101
+ /**
102
+ * Legacy helper: scan raw TypeScript source for `@Component` classes
103
+ * and append registration calls. Retained for tests and for any
104
+ * caller running outside the post-Angular plugin chain.
105
+ *
106
+ * NOTE: For files compiled by `@analogjs/vite-plugin-angular`, this
107
+ * helper's output is discarded — the Angular plugin replaces the
108
+ * input code with the regenerated compiled output from its internal
109
+ * `outputFiles` cache. Use `findComponentClassNames(rawTs)` +
110
+ * `appendComponentHmrRegistration(compiledCode, names)` from a
111
+ * `enforce: 'post'` plugin to survive that compilation step.
112
+ */
113
+ export function injectComponentHmrRegistration(code, options = {}) {
114
+ if (!code) {
115
+ return { code: null, componentNames: [] };
116
+ }
117
+ if (code.includes(INJECTION_MARKER)) {
118
+ // Already injected (re-transform case) — return original to avoid
119
+ // duplicating registration calls.
120
+ return { code: null, componentNames: [] };
121
+ }
122
+ if (!COMPONENT_DECORATOR_RE.test(code)) {
123
+ return { code: null, componentNames: [] };
124
+ }
125
+ // RegExp.prototype.test with `g` flag advances lastIndex; reset for the
126
+ // next walk in `findComponentClassNames`.
127
+ COMPONENT_DECORATOR_RE.lastIndex = 0;
128
+ const componentNames = findComponentClassNames(code);
129
+ if (componentNames.length === 0) {
130
+ return { code: null, componentNames: [] };
131
+ }
132
+ const suffix = buildComponentHmrRegistrationSuffix(componentNames, options);
133
+ return {
134
+ code: code + suffix,
135
+ componentNames,
136
+ };
137
+ }
138
+ function buildRegistrationLine(hookName, className) {
139
+ // Wrap each call in its own try so a failure (e.g. the class binding
140
+ // not in scope at module end because the user re-exported it from
141
+ // somewhere else) doesn't break sibling registrations.
142
+ // The typeof guard prevents a ReferenceError if the global hook isn't
143
+ // installed (production builds, non-Angular contexts, isolated unit
144
+ // tests). The "globalThis" reference is universal across modern JS
145
+ // runtimes including the NativeScript iOS/Android runtimes.
146
+ return `try { if (typeof globalThis !== 'undefined' && typeof globalThis.${hookName} === 'function' && typeof ${className} !== 'undefined') { globalThis.${hookName}(${JSON.stringify(className)}, ${className}, typeof import.meta !== 'undefined' && import.meta && import.meta.url ? import.meta.url : ''); } } catch (e) {}`;
147
+ }
148
+ /**
149
+ * Walk a TS source string and collect class names declared after a
150
+ * `@Component(...)` decorator. Supports:
151
+ * - `export class Foo` and bare `class Foo`
152
+ * - `abstract class Foo` (rare for @Component but allowed)
153
+ * - Any number of additional decorators stacked between `@Component`
154
+ * and the class keyword (e.g. `@Component({}) @SomethingElse() ...`)
155
+ *
156
+ * Skips matches that fall inside string literals or comments. Uses a
157
+ * paren-matching scanner instead of regex `[\s\S]*?` so multi-line
158
+ * decorator arguments (templates, styles arrays) don't trip up the
159
+ * scanner.
160
+ */
161
+ export function findComponentClassNames(code) {
162
+ const names = [];
163
+ const componentRe = /@Component\s*\(/g;
164
+ let match;
165
+ while ((match = componentRe.exec(code)) !== null) {
166
+ const matchStart = match.index;
167
+ if (isInsideStringOrComment(code, matchStart)) {
168
+ continue;
169
+ }
170
+ const openParenIdx = matchStart + match[0].length - 1;
171
+ const closeParenIdx = findMatchingDelimiter(code, openParenIdx, '(', ')');
172
+ if (closeParenIdx === -1) {
173
+ continue;
174
+ }
175
+ const className = findClassNameAfter(code, closeParenIdx + 1);
176
+ if (className && !names.includes(className)) {
177
+ names.push(className);
178
+ }
179
+ }
180
+ return names;
181
+ }
182
+ /**
183
+ * Starting at `position`, skip whitespace and any further decorators
184
+ * (`@Foo(...)`) and return the next class name encountered, or
185
+ * `null` if no class declaration follows.
186
+ */
187
+ function findClassNameAfter(code, position) {
188
+ let i = position;
189
+ while (i < code.length) {
190
+ while (i < code.length && /\s/.test(code[i])) {
191
+ i++;
192
+ }
193
+ if (i >= code.length) {
194
+ return null;
195
+ }
196
+ if (code[i] === '@') {
197
+ // Another decorator stacked between @Component and class.
198
+ i++;
199
+ // Decorator name (identifier).
200
+ while (i < code.length && /[\w$.]/.test(code[i])) {
201
+ i++;
202
+ }
203
+ while (i < code.length && /\s/.test(code[i])) {
204
+ i++;
205
+ }
206
+ if (code[i] === '(') {
207
+ const decoClose = findMatchingDelimiter(code, i, '(', ')');
208
+ if (decoClose === -1) {
209
+ return null;
210
+ }
211
+ i = decoClose + 1;
212
+ }
213
+ continue;
214
+ }
215
+ const remainder = code.slice(i);
216
+ const classMatch = /^(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/.exec(remainder);
217
+ if (classMatch) {
218
+ return classMatch[1];
219
+ }
220
+ return null;
221
+ }
222
+ return null;
223
+ }
224
+ /**
225
+ * True if `index` falls inside a // line comment, /* block comment, or
226
+ * a string/template literal. Used to filter out false positives from
227
+ * `@Component(` matches inside docs or stringified examples.
228
+ */
229
+ function isInsideStringOrComment(code, index) {
230
+ let i = 0;
231
+ let quote = null;
232
+ let escape = false;
233
+ let inLineComment = false;
234
+ let inBlockComment = false;
235
+ while (i < index) {
236
+ const char = code[i];
237
+ const next = code[i + 1];
238
+ if (inLineComment) {
239
+ if (char === '\n') {
240
+ inLineComment = false;
241
+ }
242
+ i++;
243
+ continue;
244
+ }
245
+ if (inBlockComment) {
246
+ if (char === '*' && next === '/') {
247
+ inBlockComment = false;
248
+ i += 2;
249
+ continue;
250
+ }
251
+ i++;
252
+ continue;
253
+ }
254
+ if (quote) {
255
+ if (escape) {
256
+ escape = false;
257
+ i++;
258
+ continue;
259
+ }
260
+ if (char === '\\') {
261
+ escape = true;
262
+ i++;
263
+ continue;
264
+ }
265
+ if (char === quote) {
266
+ quote = null;
267
+ }
268
+ i++;
269
+ continue;
270
+ }
271
+ if (char === '/' && next === '/') {
272
+ inLineComment = true;
273
+ i += 2;
274
+ continue;
275
+ }
276
+ if (char === '/' && next === '*') {
277
+ inBlockComment = true;
278
+ i += 2;
279
+ continue;
280
+ }
281
+ if (char === '"' || char === "'" || char === '`') {
282
+ quote = char;
283
+ i++;
284
+ continue;
285
+ }
286
+ i++;
287
+ }
288
+ return inLineComment || inBlockComment || quote !== null;
289
+ }
290
+ // Comment-aware delimiter matcher lives in ./js-lexer.ts
291
+ //# sourceMappingURL=inject-component-hmr-registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-component-hmr-registration.js","sourceRoot":"","sources":["../../../../../packages/vite/helpers/angular/inject-component-hmr-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;AAkB3E;;;;;;;;GAQG;AACH,MAAM,UAAU,mCAAmC,CAAC,cAAwB,EAAE,UAAiD,EAAE;IAChI,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,+BAA+B,CAAC;IACrE,MAAM,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9F,oEAAoE;IACpE,iEAAiE;IACjE,OAAO,OAAO,gBAAgB,KAAK,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACrE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAAY,EAAE,cAAwB,EAAE,UAAiD,EAAE;IACzI,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,MAAM,MAAM,GAAG,mCAAmC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO;QACN,IAAI,EAAE,IAAI,GAAG,MAAM;QACnB,cAAc,EAAE,CAAC,GAAG,cAAc,CAAC;KACnC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAAY,EAAE,UAAiD,EAAE;IAC/G,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,kEAAkE;QAClE,kCAAkC;QAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,wEAAwE;IACxE,0CAA0C;IAC1C,sBAAsB,CAAC,SAAS,GAAG,CAAC,CAAC;IAErC,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,mCAAmC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC5E,OAAO;QACN,IAAI,EAAE,IAAI,GAAG,MAAM;QACnB,cAAc;KACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAgB,EAAE,SAAiB;IACjE,qEAAqE;IACrE,kEAAkE;IAClE,uDAAuD;IACvD,sEAAsE;IACtE,oEAAoE;IACpE,mEAAmE;IACnE,4DAA4D;IAC5D,OAAO,oEAAoE,QAAQ,6BAA6B,SAAS,kCAAkC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,SAAS,kHAAkH,CAAC;AAClU,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC;IACvC,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;QAC/B,IAAI,uBAAuB,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,SAAS;QACV,CAAC;QAED,MAAM,YAAY,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1E,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,SAAS,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,IAAY,EAAE,QAAgB;IACzD,IAAI,CAAC,GAAG,QAAQ,CAAC;IACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,CAAC,EAAE,CAAC;QACL,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,0DAA0D;YAC1D,CAAC,EAAE,CAAC;YACJ,+BAA+B;YAC/B,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,CAAC,EAAE,CAAC;YACL,CAAC;YACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,CAAC,EAAE,CAAC;YACL,CAAC;YACD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC3D,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC;gBACb,CAAC;gBACD,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;YACnB,CAAC;YACD,SAAS;QACV,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,0EAA0E,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9G,IAAI,UAAU,EAAE,CAAC;YAChB,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB,CAAC,IAAY,EAAE,KAAa;IAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzB,IAAI,aAAa,EAAE,CAAC;YACnB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACnB,aAAa,GAAG,KAAK,CAAC;YACvB,CAAC;YACD,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACpB,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBAClC,cAAc,GAAG,KAAK,CAAC;gBACvB,CAAC,IAAI,CAAC,CAAC;gBACP,SAAS;YACV,CAAC;YACD,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,KAAK,CAAC;gBACf,CAAC,EAAE,CAAC;gBACJ,SAAS;YACV,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,IAAI,CAAC;gBACd,CAAC,EAAE,CAAC;gBACJ,SAAS;YACV,CAAC;YACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACpB,KAAK,GAAG,IAAI,CAAC;YACd,CAAC;YACD,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAClC,aAAa,GAAG,IAAI,CAAC;YACrB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACV,CAAC;QACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAClC,cAAc,GAAG,IAAI,CAAC;YACtB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACV,CAAC;QACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAClD,KAAK,GAAG,IAAI,CAAC;YACb,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,CAAC,EAAE,CAAC;IACL,CAAC;IAED,OAAO,aAAa,IAAI,cAAc,IAAI,KAAK,KAAK,IAAI,CAAC;AAC1D,CAAC;AAED,yDAAyD"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Re-inject `/* @vite-ignore *\/` into Angular's HMR initializer dynamic
3
+ * imports.
4
+ *
5
+ * # Why this exists
6
+ *
7
+ * Angular's compiler (`@angular/compiler`'s `compileHmrInitializer`) emits
8
+ * each `@Component`-decorated class's HMR loader as:
9
+ *
10
+ * ```js
11
+ * function FooComponent_HmrLoad(t) {
12
+ * import(\/* @vite-ignore *\/ i0.ɵɵgetReplaceMetadataURL(id, t, import.meta.url))
13
+ * .then((m) => m.default && i0.ɵɵreplaceMetadata(FooComponent, m.default, ...));
14
+ * }
15
+ * ```
16
+ *
17
+ * The `\/* @vite-ignore *\/` annotation tells Vite "do not try to
18
+ * statically analyze this dynamic import" — the URL is computed at
19
+ * runtime by `ɵɵgetReplaceMetadataURL`, which produces something like
20
+ * `http://host/ns/m/<componentDir>/@ng/component?c=<id>&t=<ts>` to be
21
+ * resolved by Analog's `liveReloadPlugin` middleware on the dev server.
22
+ *
23
+ * Somewhere along the post-Angular transform chain — empirically the
24
+ * `compact: false` Babel pass driven by the Angular linker, but
25
+ * potentially other plugins as well — the leading-argument comment is
26
+ * being dropped. By the time the file lands on the device, the
27
+ * compiled emit reads:
28
+ *
29
+ * ```js
30
+ * import(i0.ɵɵgetReplaceMetadataURL(id, t, import.meta.url))
31
+ * ```
32
+ *
33
+ * Vite's static analyzer logs:
34
+ *
35
+ * > The above dynamic import cannot be analyzed by Vite.
36
+ *
37
+ * and rewrites the call site to route through Vite's runtime resolver,
38
+ * which fails on the iOS runtime because the resolver expects a
39
+ * statically-known module specifier. The HMR loader IIFE runs at every
40
+ * component module evaluation (gated by `ngDevMode`), so the failure
41
+ * fires at boot for the FIRST `@Component` whose module is evaluated —
42
+ * typically a base/utility component like `ConfirmationDialogBaseComponent`
43
+ * — and aborts session startup with:
44
+ *
45
+ * > TypeError at Module.ɵɵgetReplaceMetadataURL
46
+ *
47
+ * Re-inserting the annotation downstream of every other transform makes
48
+ * us tolerant of upstream comment-loss without depending on the linker's
49
+ * comment behaviour. The fix is purely additive: if the comment is still
50
+ * present (Angular versions that emit it differently, or future
51
+ * compilers that wrap the URL in an alternate helper), `appendIfMissing`
52
+ * leaves the import untouched.
53
+ *
54
+ * # Idempotence
55
+ *
56
+ * The helper is safe to call repeatedly on the same source — once the
57
+ * annotation is present, subsequent calls become a no-op match by match.
58
+ * Vite's transform pipeline can replay cached transforms during a
59
+ * single dev session, so idempotence is required, not optional.
60
+ *
61
+ * # Surface area
62
+ *
63
+ * We only touch `import()` calls whose argument expression contains
64
+ * `ɵɵgetReplaceMetadataURL` (matching either the literal Unicode form
65
+ * or the escaped `\u0275\u0275getReplaceMetadataURL`). Every other
66
+ * dynamic import is left alone — an over-broad sweep would suppress
67
+ * Vite warnings on user dynamic imports that genuinely should be
68
+ * statically analyzed.
69
+ */
70
+ /**
71
+ * Inject `/* @vite-ignore *\/` into every `import()` whose argument
72
+ * references Angular's `ɵɵgetReplaceMetadataURL`. Returns the original
73
+ * code unchanged when no qualifying imports are found.
74
+ */
75
+ export declare function injectAngularHmrViteIgnore(code: string): string;
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Re-inject `/* @vite-ignore *\/` into Angular's HMR initializer dynamic
3
+ * imports.
4
+ *
5
+ * # Why this exists
6
+ *
7
+ * Angular's compiler (`@angular/compiler`'s `compileHmrInitializer`) emits
8
+ * each `@Component`-decorated class's HMR loader as:
9
+ *
10
+ * ```js
11
+ * function FooComponent_HmrLoad(t) {
12
+ * import(\/* @vite-ignore *\/ i0.ɵɵgetReplaceMetadataURL(id, t, import.meta.url))
13
+ * .then((m) => m.default && i0.ɵɵreplaceMetadata(FooComponent, m.default, ...));
14
+ * }
15
+ * ```
16
+ *
17
+ * The `\/* @vite-ignore *\/` annotation tells Vite "do not try to
18
+ * statically analyze this dynamic import" — the URL is computed at
19
+ * runtime by `ɵɵgetReplaceMetadataURL`, which produces something like
20
+ * `http://host/ns/m/<componentDir>/@ng/component?c=<id>&t=<ts>` to be
21
+ * resolved by Analog's `liveReloadPlugin` middleware on the dev server.
22
+ *
23
+ * Somewhere along the post-Angular transform chain — empirically the
24
+ * `compact: false` Babel pass driven by the Angular linker, but
25
+ * potentially other plugins as well — the leading-argument comment is
26
+ * being dropped. By the time the file lands on the device, the
27
+ * compiled emit reads:
28
+ *
29
+ * ```js
30
+ * import(i0.ɵɵgetReplaceMetadataURL(id, t, import.meta.url))
31
+ * ```
32
+ *
33
+ * Vite's static analyzer logs:
34
+ *
35
+ * > The above dynamic import cannot be analyzed by Vite.
36
+ *
37
+ * and rewrites the call site to route through Vite's runtime resolver,
38
+ * which fails on the iOS runtime because the resolver expects a
39
+ * statically-known module specifier. The HMR loader IIFE runs at every
40
+ * component module evaluation (gated by `ngDevMode`), so the failure
41
+ * fires at boot for the FIRST `@Component` whose module is evaluated —
42
+ * typically a base/utility component like `ConfirmationDialogBaseComponent`
43
+ * — and aborts session startup with:
44
+ *
45
+ * > TypeError at Module.ɵɵgetReplaceMetadataURL
46
+ *
47
+ * Re-inserting the annotation downstream of every other transform makes
48
+ * us tolerant of upstream comment-loss without depending on the linker's
49
+ * comment behaviour. The fix is purely additive: if the comment is still
50
+ * present (Angular versions that emit it differently, or future
51
+ * compilers that wrap the URL in an alternate helper), `appendIfMissing`
52
+ * leaves the import untouched.
53
+ *
54
+ * # Idempotence
55
+ *
56
+ * The helper is safe to call repeatedly on the same source — once the
57
+ * annotation is present, subsequent calls become a no-op match by match.
58
+ * Vite's transform pipeline can replay cached transforms during a
59
+ * single dev session, so idempotence is required, not optional.
60
+ *
61
+ * # Surface area
62
+ *
63
+ * We only touch `import()` calls whose argument expression contains
64
+ * `ɵɵgetReplaceMetadataURL` (matching either the literal Unicode form
65
+ * or the escaped `\u0275\u0275getReplaceMetadataURL`). Every other
66
+ * dynamic import is left alone — an over-broad sweep would suppress
67
+ * Vite warnings on user dynamic imports that genuinely should be
68
+ * statically analyzed.
69
+ */
70
+ import { findMatchingDelimiter } from './js-lexer.js';
71
+ const ANGULAR_HMR_IDENTIFIER = 'getReplaceMetadataURL';
72
+ const VITE_IGNORE_COMMENT = '/* @vite-ignore */';
73
+ /**
74
+ * Inject `/* @vite-ignore *\/` into every `import()` whose argument
75
+ * references Angular's `ɵɵgetReplaceMetadataURL`. Returns the original
76
+ * code unchanged when no qualifying imports are found.
77
+ */
78
+ export function injectAngularHmrViteIgnore(code) {
79
+ if (!code)
80
+ return code;
81
+ // Cheap pre-check: bail out before walking the source if neither
82
+ // the unicode nor the escape form of the identifier is anywhere in
83
+ // the file. The vast majority of files aren't components, so this
84
+ // short-circuit is the hot path.
85
+ if (!code.includes(ANGULAR_HMR_IDENTIFIER))
86
+ return code;
87
+ let output = '';
88
+ let cursor = 0;
89
+ let changed = false;
90
+ while (cursor < code.length) {
91
+ const importIndex = findNextImportCall(code, cursor);
92
+ if (importIndex === -1) {
93
+ output += code.slice(cursor);
94
+ break;
95
+ }
96
+ const openParenIndex = findOpenParenAfter(code, importIndex + 'import'.length);
97
+ if (openParenIndex === -1) {
98
+ output += code.slice(cursor, importIndex + 'import'.length);
99
+ cursor = importIndex + 'import'.length;
100
+ continue;
101
+ }
102
+ const closeParenIndex = findMatchingDelimiter(code, openParenIndex, '(', ')');
103
+ if (closeParenIndex === -1) {
104
+ output += code.slice(cursor, openParenIndex + 1);
105
+ cursor = openParenIndex + 1;
106
+ continue;
107
+ }
108
+ const argumentBody = code.slice(openParenIndex + 1, closeParenIndex);
109
+ if (!referencesReplaceMetadataUrl(argumentBody)) {
110
+ output += code.slice(cursor, closeParenIndex + 1);
111
+ cursor = closeParenIndex + 1;
112
+ continue;
113
+ }
114
+ if (alreadyAnnotated(argumentBody)) {
115
+ output += code.slice(cursor, closeParenIndex + 1);
116
+ cursor = closeParenIndex + 1;
117
+ continue;
118
+ }
119
+ // Insert the annotation immediately after `import(` so the
120
+ // original argument expression — including any leading
121
+ // whitespace the upstream emitter chose — keeps its byte
122
+ // layout. This preserves source-map line stability for the
123
+ // rest of the file: only column offsets after the injection
124
+ // shift, never line numbers.
125
+ output += code.slice(cursor, openParenIndex + 1);
126
+ output += ` ${VITE_IGNORE_COMMENT} `;
127
+ output += code.slice(openParenIndex + 1, closeParenIndex + 1);
128
+ cursor = closeParenIndex + 1;
129
+ changed = true;
130
+ }
131
+ return changed ? output : code;
132
+ }
133
+ function findNextImportCall(source, startIndex) {
134
+ let i = startIndex;
135
+ while (i < source.length) {
136
+ const next = source.indexOf('import', i);
137
+ if (next === -1)
138
+ return -1;
139
+ // Reject `import.meta` and `import ` keyword forms; only
140
+ // `import(` (with optional whitespace) is a dynamic import.
141
+ const tail = next + 'import'.length;
142
+ const before = source.charCodeAt(next - 1);
143
+ const isWordCharBefore = isIdentifierPart(before);
144
+ if (!isWordCharBefore) {
145
+ let scan = tail;
146
+ while (scan < source.length && isWhitespace(source.charCodeAt(scan)))
147
+ scan++;
148
+ if (source.charCodeAt(scan) === 0x28 /* '(' */) {
149
+ return next;
150
+ }
151
+ }
152
+ i = tail;
153
+ }
154
+ return -1;
155
+ }
156
+ function findOpenParenAfter(source, index) {
157
+ let i = index;
158
+ while (i < source.length && isWhitespace(source.charCodeAt(i)))
159
+ i++;
160
+ if (source.charCodeAt(i) === 0x28 /* '(' */)
161
+ return i;
162
+ return -1;
163
+ }
164
+ function alreadyAnnotated(argumentBody) {
165
+ // Trim only the leading whitespace + comments — body may have many
166
+ // non-`@vite-ignore` block comments later that we don't want to
167
+ // confuse for an already-applied annotation.
168
+ let i = 0;
169
+ while (i < argumentBody.length) {
170
+ const c = argumentBody.charCodeAt(i);
171
+ if (isWhitespace(c)) {
172
+ i++;
173
+ continue;
174
+ }
175
+ if (c === 0x2f /* '/' */ && argumentBody.charCodeAt(i + 1) === 0x2a /* '*' */) {
176
+ const closeIndex = argumentBody.indexOf('*/', i + 2);
177
+ if (closeIndex === -1)
178
+ return false;
179
+ const commentBody = argumentBody.slice(i + 2, closeIndex);
180
+ if (commentBody.includes('@vite-ignore'))
181
+ return true;
182
+ i = closeIndex + 2;
183
+ continue;
184
+ }
185
+ // First non-whitespace, non-block-comment token — there's no
186
+ // annotation in the leading whitespace window.
187
+ return false;
188
+ }
189
+ return false;
190
+ }
191
+ function referencesReplaceMetadataUrl(argumentBody) {
192
+ if (!argumentBody)
193
+ return false;
194
+ if (argumentBody.includes(ANGULAR_HMR_IDENTIFIER))
195
+ return true;
196
+ // `\u0275\u0275getReplaceMetadataURL` — unicode-escaped form some
197
+ // transforms emit. The substring above already covers the suffix
198
+ // regardless of the prefix encoding, so this branch is mostly
199
+ // defensive — keep it explicit so future changes to the identifier
200
+ // (e.g. a `replaceMetadataURL` rename without `ɵɵ`) don't silently
201
+ // stop matching.
202
+ return /\\u0275\\u0275getReplaceMetadataURL/.test(argumentBody);
203
+ }
204
+ function isWhitespace(code) {
205
+ return code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d || code === 0x0b || code === 0x0c;
206
+ }
207
+ function isIdentifierPart(code) {
208
+ if (Number.isNaN(code))
209
+ return false;
210
+ if (code === 0x5f /* '_' */ || code === 0x24 /* '$' */)
211
+ return true;
212
+ if (code >= 0x30 && code <= 0x39)
213
+ return true;
214
+ if (code >= 0x41 && code <= 0x5a)
215
+ return true;
216
+ if (code >= 0x61 && code <= 0x7a)
217
+ return true;
218
+ return false;
219
+ }
220
+ // Comment-aware paren matcher lives in ./js-lexer.ts
221
+ //# sourceMappingURL=inject-hmr-vite-ignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-hmr-vite-ignore.js","sourceRoot":"","sources":["../../../../../packages/vite/helpers/angular/inject-hmr-vite-ignore.ts"],"names":[],"mappings":"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"}