@nativescript/vite 8.0.0-alpha.0 → 8.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/configuration/angular.d.ts +1 -1
  2. package/configuration/angular.js +286 -119
  3. package/configuration/angular.js.map +1 -1
  4. package/configuration/base.js +40 -35
  5. package/configuration/base.js.map +1 -1
  6. package/configuration/javascript.js +3 -3
  7. package/configuration/javascript.js.map +1 -1
  8. package/configuration/solid.js +7 -0
  9. package/configuration/solid.js.map +1 -1
  10. package/configuration/typescript.js +3 -3
  11. package/configuration/typescript.js.map +1 -1
  12. package/helpers/angular/angular-linker.js +39 -34
  13. package/helpers/angular/angular-linker.js.map +1 -1
  14. package/helpers/angular/inline-decorator-component-templates.d.ts +3 -0
  15. package/helpers/angular/inline-decorator-component-templates.js +400 -0
  16. package/helpers/angular/inline-decorator-component-templates.js.map +1 -0
  17. package/helpers/angular/shared-linker.d.ts +7 -0
  18. package/helpers/angular/shared-linker.js +37 -1
  19. package/helpers/angular/shared-linker.js.map +1 -1
  20. package/helpers/angular/synthesize-decorator-ctor-parameters.d.ts +1 -0
  21. package/helpers/angular/synthesize-decorator-ctor-parameters.js +256 -0
  22. package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +1 -0
  23. package/helpers/angular/synthesize-injectable-factories.d.ts +3 -0
  24. package/helpers/angular/synthesize-injectable-factories.js +414 -0
  25. package/helpers/angular/synthesize-injectable-factories.js.map +1 -0
  26. package/helpers/esbuild-platform-resolver.js +5 -5
  27. package/helpers/esbuild-platform-resolver.js.map +1 -1
  28. package/helpers/external-configs.d.ts +9 -1
  29. package/helpers/external-configs.js +31 -6
  30. package/helpers/external-configs.js.map +1 -1
  31. package/helpers/import-meta-path.d.ts +4 -0
  32. package/helpers/import-meta-path.js +5 -0
  33. package/helpers/import-meta-path.js.map +1 -0
  34. package/helpers/import-specifier.d.ts +1 -0
  35. package/helpers/import-specifier.js +18 -0
  36. package/helpers/import-specifier.js.map +1 -0
  37. package/helpers/main-entry.d.ts +4 -2
  38. package/helpers/main-entry.js +86 -10
  39. package/helpers/main-entry.js.map +1 -1
  40. package/helpers/nativeclass-transform.js +8 -127
  41. package/helpers/nativeclass-transform.js.map +1 -1
  42. package/helpers/nativeclass-transformer-plugin.d.ts +12 -1
  43. package/helpers/nativeclass-transformer-plugin.js +175 -31
  44. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  45. package/helpers/preserve-imports.js +2 -17
  46. package/helpers/preserve-imports.js.map +1 -1
  47. package/hmr/client/css-handler.js +60 -20
  48. package/hmr/client/css-handler.js.map +1 -1
  49. package/hmr/client/index.js +453 -5
  50. package/hmr/client/index.js.map +1 -1
  51. package/hmr/entry-runtime.d.ts +10 -0
  52. package/hmr/entry-runtime.js +263 -21
  53. package/hmr/entry-runtime.js.map +1 -1
  54. package/hmr/frameworks/angular/client/index.js +22 -18
  55. package/hmr/frameworks/angular/client/index.js.map +1 -1
  56. package/hmr/frameworks/angular/server/linker.js +36 -2
  57. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  58. package/hmr/helpers/ast-normalizer.js +22 -10
  59. package/hmr/helpers/ast-normalizer.js.map +1 -1
  60. package/hmr/server/constants.d.ts +1 -0
  61. package/hmr/server/constants.js +2 -0
  62. package/hmr/server/constants.js.map +1 -1
  63. package/hmr/server/core-sanitize.d.ts +42 -0
  64. package/hmr/server/core-sanitize.js +189 -0
  65. package/hmr/server/core-sanitize.js.map +1 -1
  66. package/hmr/server/import-map.d.ts +65 -0
  67. package/hmr/server/import-map.js +213 -0
  68. package/hmr/server/import-map.js.map +1 -0
  69. package/hmr/server/websocket.d.ts +79 -3
  70. package/hmr/server/websocket.js +1888 -233
  71. package/hmr/server/websocket.js.map +1 -1
  72. package/hmr/shared/runtime/dev-overlay.d.ts +38 -0
  73. package/hmr/shared/runtime/dev-overlay.js +664 -0
  74. package/hmr/shared/runtime/dev-overlay.js.map +1 -0
  75. package/hmr/shared/runtime/http-only-boot.d.ts +1 -0
  76. package/hmr/shared/runtime/http-only-boot.js +53 -6
  77. package/hmr/shared/runtime/http-only-boot.js.map +1 -1
  78. package/hmr/shared/runtime/module-provenance.d.ts +1 -0
  79. package/hmr/shared/runtime/module-provenance.js +66 -0
  80. package/hmr/shared/runtime/module-provenance.js.map +1 -0
  81. package/hmr/shared/runtime/platform-polyfills.d.ts +26 -0
  82. package/hmr/shared/runtime/platform-polyfills.js +122 -0
  83. package/hmr/shared/runtime/platform-polyfills.js.map +1 -0
  84. package/hmr/shared/runtime/root-placeholder.js +175 -53
  85. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  86. package/hmr/shared/runtime/vendor-bootstrap.js +51 -6
  87. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  88. package/hmr/shared/vendor/manifest.d.ts +5 -0
  89. package/hmr/shared/vendor/manifest.js +339 -13
  90. package/hmr/shared/vendor/manifest.js.map +1 -1
  91. package/hmr/shared/vendor/registry.js +104 -7
  92. package/hmr/shared/vendor/registry.js.map +1 -1
  93. package/package.json +6 -2
  94. package/shims/solid-jsx-runtime.d.ts +7 -0
  95. package/shims/solid-jsx-runtime.js +17 -0
  96. package/shims/solid-jsx-runtime.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"css-handler.js","sourceRoot":"","sources":["../../../../../packages/vite/hmr/client/css-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"css-handler.js","sourceRoot":"","sources":["../../../../../packages/vite/hmr/client/css-handler.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,CAAC,CAAE,UAAkB,CAAC,kBAAkB,CAAC;AAEzD,SAAS,sBAAsB;IAC9B,IAAI,CAAC;QACJ,MAAM,OAAO,GAAI,UAAkB,CAAC,oBAAoB,CAAC;QACzD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC5B,IAAI,CAAC;QACJ,MAAM,CAAC,GAAG,UAAiB,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,kBAAkB,CAAC;QACjC,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC1C,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACzC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC;QAC9D,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACrC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAQ,UAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,OAAe;IAC3C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO;IAE3D,IAAI,CAAC;QACJ,MAAM,oBAAoB,GAAG,sBAAsB,EAAE,CAAC;QACtD,IAAI,oBAAoB,EAAE,CAAC;YAC1B,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACpC,IAAI,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAC1E,OAAO;QACR,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3C,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACvD,CAAC;QACD,yDAAyD;QACzD,oEAAoE;QACpE,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,WAAW,EAAE,WAAW,EAAE,EAAE,CAAC;YAC9C,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;gBAClE,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YAC9B,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACrB,2DAA2D;gBAC3D,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;gBACrC,QAAQ,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC;gBAC/B,QAAQ,CAAC,SAAS,GAAG,GAAG,CAAC;YAC1B,CAAC;QACF,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACX,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;AACF,CAAC;AAED,eAAe;AACf,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IAC1C,IAAI,CAAC;QACJ,MAAM,CAAC,GAAG,UAAiB,CAAC;QAC5B,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACpB,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5B,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAChE,OAAO,EAAE,CAAC;IACX,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAiB,EAAE,UAAkB;IAC3E,IAAI,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACnH,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;YACzD,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU;gBAAE,SAAS;YAEtC,qDAAqD;YACrD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,UAAU,GAAG,OAAO,GAAG,GAAG,cAAc,SAAS,EAAE,CAAC;YAEnE,IAAI,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YACzD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,OAAO,EAAE,CAAC;gBACb,YAAY,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC;IACF,CAAC;AACF,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,eAAe,CAAC,OAAe;IAC9C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnD,YAAY,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACF,CAAC"}
@@ -43,10 +43,76 @@ function ensureCoreAliasesOnGlobalThis() {
43
43
  }
44
44
  // Apply once on module evaluation
45
45
  ensureCoreAliasesOnGlobalThis();
46
+ function getHmrOverlayApi() {
47
+ try {
48
+ return globalThis.__NS_HMR_DEV_OVERLAY__ || null;
49
+ }
50
+ catch { }
51
+ return null;
52
+ }
53
+ function setConnectionOverlayStage(stage, detail) {
54
+ try {
55
+ const api = getHmrOverlayApi();
56
+ if (api && typeof api.setConnectionStage === 'function') {
57
+ api.setConnectionStage(stage, { detail });
58
+ }
59
+ }
60
+ catch { }
61
+ }
62
+ function hideConnectionOverlay() {
63
+ try {
64
+ const api = getHmrOverlayApi();
65
+ if (api && typeof api.hide === 'function') {
66
+ api.hide('healthy');
67
+ }
68
+ }
69
+ catch { }
70
+ }
71
+ let connectionOverlayTimer = null;
72
+ let connectionOverlayVisible = false;
73
+ let hasOpenedHmrSocket = false;
74
+ let awaitingHealthyHmrMessage = false;
75
+ let pendingConnectionOverlayStage = 'connecting';
76
+ let pendingConnectionOverlayDetail = '';
77
+ function clearConnectionOverlayTimer() {
78
+ if (connectionOverlayTimer) {
79
+ clearTimeout(connectionOverlayTimer);
80
+ connectionOverlayTimer = null;
81
+ }
82
+ }
83
+ function showConnectionOverlayNow(stage, detail) {
84
+ pendingConnectionOverlayStage = stage;
85
+ pendingConnectionOverlayDetail = detail || '';
86
+ connectionOverlayVisible = true;
87
+ setConnectionOverlayStage(stage, detail);
88
+ }
89
+ function scheduleConnectionOverlay(stage, detail, delayMs = 1200) {
90
+ pendingConnectionOverlayStage = stage;
91
+ pendingConnectionOverlayDetail = detail || '';
92
+ clearConnectionOverlayTimer();
93
+ connectionOverlayTimer = setTimeout(() => {
94
+ showConnectionOverlayNow(pendingConnectionOverlayStage, pendingConnectionOverlayDetail);
95
+ }, delayMs);
96
+ }
97
+ function updateConnectionOverlay(stage, detail) {
98
+ pendingConnectionOverlayStage = stage;
99
+ pendingConnectionOverlayDetail = detail || '';
100
+ if (connectionOverlayVisible) {
101
+ showConnectionOverlayNow(stage, detail);
102
+ }
103
+ }
104
+ function markHmrConnectionHealthy() {
105
+ awaitingHealthyHmrMessage = false;
106
+ clearConnectionOverlayTimer();
107
+ if (connectionOverlayVisible) {
108
+ connectionOverlayVisible = false;
109
+ hideConnectionOverlay();
110
+ }
111
+ }
46
112
  /**
47
113
  * Flavor hooks
48
114
  */
49
- import { installNsVueDevShims, ensureBackWrapperInstalled, getRootForVue, loadSfcComponent, ensureVueGlobals, ensurePiniaOnApp, addSfcMapping, recordVuePayloadChanges, handleVueSfcRegistry, handleVueSfcRegistryUpdate } from '../frameworks/vue/client/index.js';
115
+ import { installNsVueDevShims, ensureBackWrapperInstalled, getRootForVue, loadSfcComponent, ensureVueGlobals, ensurePiniaOnApp, addSfcMapping, recordVuePayloadChanges, handleVueSfcRegistry, handleVueSfcRegistryUpdate, sfcArtifactMap } from '../frameworks/vue/client/index.js';
50
116
  import { handleAngularHotUpdateMessage, installAngularHmrClientHooks } from '../frameworks/angular/client/index.js';
51
117
  switch (__NS_TARGET_FLAVOR__) {
52
118
  case 'vue':
@@ -60,6 +126,10 @@ switch (__NS_TARGET_FLAVOR__) {
60
126
  let initialMounted = !!globalThis.__NS_HMR_BOOT_COMPLETE__;
61
127
  // Prevent duplicate initial-mount scheduling across rapid full-graph broadcasts and re-evaluations
62
128
  let initialMounting = !!globalThis.__NS_HMR_INITIAL_MOUNT_IN_PROGRESS__;
129
+ // Track whether the first full-graph has been received. Before the full-graph,
130
+ // delta messages are just the server discovering modules during initial boot —
131
+ // NOT actual code changes. Re-imports must be gated behind this flag.
132
+ let hasReceivedFullGraph = false;
63
133
  // TypeScript flavor: track registry modules and inferred main id
64
134
  let tsModuleSet = null;
65
135
  let tsMainId = null;
@@ -94,10 +164,14 @@ function applyFullGraph(payload) {
94
164
  console.log('[hmr][graph] full graph applied version', getGraphVersion(), 'modules=', graph.size);
95
165
  // Guarded initial mount rescue: if app hasn't replaced the placeholder shortly after graph arrives,
96
166
  // perform a one-time mount. This waits briefly to let the app's main entry start() run first to avoid double mounts.
167
+ // TypeScript flavor: skip the rescue entirely. The HTTP boot will load main.ts which
168
+ // calls Application.run() (patched to resetRootView) — the rescue is redundant and
169
+ // causes a double-mount race (rescue fires at 450ms, then main.ts fires ~1s later,
170
+ // causing a visual flash and leaving the app in an inconsistent state).
97
171
  try {
98
172
  const g = globalThis;
99
173
  const bootDone = !!g.__NS_HMR_BOOT_COMPLETE__;
100
- if (!bootDone && !initialMounted && !initialMounting && !g.__NS_HMR_RESCUE_SCHEDULED__) {
174
+ if (!bootDone && !initialMounted && !initialMounting && !g.__NS_HMR_RESCUE_SCHEDULED__ && __NS_TARGET_FLAVOR__ !== 'typescript') {
101
175
  // simple snapshot helpers
102
176
  const getTopmost = () => {
103
177
  try {
@@ -227,6 +301,19 @@ function applyFullGraph(payload) {
227
301
  }
228
302
  }
229
303
  }
304
+ // Fallback: when the module graph is empty (Vite 7+ may not populate it
305
+ // before the first full-graph broadcast), check the SFC artifact registry
306
+ // which is populated from the ns:vue-sfc-registry message.
307
+ if (!candidate && sfcArtifactMap.size > 0) {
308
+ for (const id of sfcArtifactMap.keys()) {
309
+ if (/\.vue$/i.test(id)) {
310
+ candidate = id;
311
+ if (VERBOSE)
312
+ console.log('[hmr][init] rescue candidate from SFC registry:', id);
313
+ break;
314
+ }
315
+ }
316
+ }
230
317
  break;
231
318
  }
232
319
  }
@@ -301,6 +388,17 @@ function applyFullGraph(payload) {
301
388
  }
302
389
  }
303
390
  }
391
+ // Fallback: SFC registry (same as rescue mount above)
392
+ if (!candidate && sfcArtifactMap.size > 0) {
393
+ for (const id of sfcArtifactMap.keys()) {
394
+ if (/\.vue$/i.test(id)) {
395
+ candidate = id;
396
+ if (VERBOSE)
397
+ console.log('[hmr][init] initial mount candidate from SFC registry:', id);
398
+ break;
399
+ }
400
+ }
401
+ }
304
402
  break;
305
403
  }
306
404
  case 'typescript': {
@@ -445,6 +543,16 @@ function applyDelta(payload) {
445
543
  console.log('[hmr][graph] delta applied newVersion', getGraphVersion(), 'changed=', (payload.changed || []).length, 'removed=', (payload.removed || []).length, 'baseVersion=', payload.baseVersion);
446
544
  // Queue evaluation of changed modules (placeholder pipeline)
447
545
  if (payload.changed?.length) {
546
+ // Gate: Before the first full-graph is received, delta messages are the server
547
+ // discovering modules during initial boot — NOT actual code changes. The entry-runtime
548
+ // already loaded all modules; re-importing them would cause duplicate Application.run(),
549
+ // router initialization, and modal conflicts. Only queue re-imports after the first
550
+ // full-graph confirms the graph is synced and subsequent deltas are real changes.
551
+ if (!hasReceivedFullGraph) {
552
+ if (VERBOSE)
553
+ console.log('[hmr][delta] skipping re-import queue (initial graph build, no full-graph yet)');
554
+ return;
555
+ }
448
556
  // HARD SUPPRESS: the very first delta (baseVersion 0) commonly includes the app main entry which is already evaluated during bootstrap.
449
557
  // Importing it again with a cache-bust often produces a spurious module-not-found (timestamp param treated as distinct file).
450
558
  const isInitial = payload.baseVersion === 0;
@@ -690,6 +798,163 @@ async function processQueue() {
690
798
  case 'vue':
691
799
  // Vue SFCs are handled via the registry update path; nothing to do here.
692
800
  break;
801
+ case 'solid': {
802
+ // Solid .tsx components are self-accepting via solid-refresh's inline
803
+ // patchRegistry — re-importing them is sufficient. For non-component
804
+ // .ts utility modules, we must propagate up the import graph to find
805
+ // the .tsx/.jsx component boundaries and re-import those so their
806
+ // solid-refresh proxies pick up the new dependency values.
807
+ try {
808
+ // Build reverse index: dep id → list of importer ids
809
+ const reverseIndex = new Map();
810
+ for (const [id, mod] of graph) {
811
+ for (const dep of mod.deps) {
812
+ let arr = reverseIndex.get(dep);
813
+ if (!arr) {
814
+ arr = [];
815
+ reverseIndex.set(dep, arr);
816
+ }
817
+ arr.push(id);
818
+ }
819
+ }
820
+ // BFS from each non-tsx changed module up to tsx/jsx boundaries
821
+ const boundaries = new Set();
822
+ for (const id of drained) {
823
+ if (/\.(tsx|jsx)$/i.test(id))
824
+ continue; // already self-accepting
825
+ const visited = new Set();
826
+ const queue = [id];
827
+ while (queue.length) {
828
+ const cur = queue.shift();
829
+ if (visited.has(cur))
830
+ continue;
831
+ visited.add(cur);
832
+ const importers = reverseIndex.get(cur);
833
+ if (!importers)
834
+ continue;
835
+ for (const imp of importers) {
836
+ if (/\.(tsx|jsx)$/i.test(imp)) {
837
+ boundaries.add(imp);
838
+ }
839
+ else {
840
+ queue.push(imp);
841
+ }
842
+ }
843
+ }
844
+ }
845
+ // Re-import each boundary so solid-refresh patchRegistry fires.
846
+ // For route files (TanStack Router), capture the new Route export
847
+ // and patch the router's existing route with the fresh loader.
848
+ let routesPatchCount = 0;
849
+ let discoveredRouter = null;
850
+ // Discover router: try __ns_router global (set by createNativeScriptRouter),
851
+ // then scan globalThis for any router-shaped object with routesById.
852
+ const findRouter = () => {
853
+ if (discoveredRouter)
854
+ return discoveredRouter;
855
+ const g = globalThis;
856
+ if (g.__ns_router?.routesById)
857
+ return (discoveredRouter = g.__ns_router);
858
+ // Fallback: scan common global keys for router
859
+ for (const key of ['__ns_router', 'router', '__router']) {
860
+ if (g[key]?.routesById && g[key]?.invalidate)
861
+ return (discoveredRouter = g[key]);
862
+ }
863
+ return null;
864
+ };
865
+ // Convert boundary file path to TanStack Router fullPath.
866
+ // e.g. /src/routes/posts.$postId.tsx → /posts/$postId
867
+ const boundaryToFullPath = (bid) => {
868
+ const m = bid.match(/\/src\/routes\/(.+)\.(tsx|jsx|ts|js)$/i);
869
+ if (!m)
870
+ return null;
871
+ let p = m[1];
872
+ // Replace dots between segments with slashes (posts.$postId → posts/$postId)
873
+ p = p.replace(/\./g, '/');
874
+ // Handle index files
875
+ if (p === 'index')
876
+ return '/';
877
+ if (p.endsWith('/index'))
878
+ p = p.slice(0, -6);
879
+ // Strip leading - (TanStack pathless layout convention)
880
+ p = p.replace(/(^|\/)-([\w])/g, '$1$2');
881
+ return '/' + p;
882
+ };
883
+ // Find existing route by fullPath (since new Route has no id yet)
884
+ const findRouteByFullPath = (router, fp) => {
885
+ if (!router?.routesById)
886
+ return null;
887
+ for (const rid of Object.keys(router.routesById)) {
888
+ const r = router.routesById[rid];
889
+ if (r?.fullPath === fp)
890
+ return r;
891
+ }
892
+ return null;
893
+ };
894
+ for (const id of boundaries) {
895
+ if (seen.has(id))
896
+ continue;
897
+ try {
898
+ const spec = normalizeSpec(id);
899
+ const url = await requestModuleFromServer(spec);
900
+ if (!url)
901
+ continue;
902
+ if (VERBOSE)
903
+ console.log('[hmr][solid] propagated to boundary', { id, url });
904
+ const mod = await import(/* @vite-ignore */ url);
905
+ // Patch TanStack Router route loaders
906
+ try {
907
+ const newRoute = mod?.Route;
908
+ if (newRoute?.options?.loader) {
909
+ const router = findRouter();
910
+ const fullPath = boundaryToFullPath(id);
911
+ if (VERBOSE)
912
+ console.log('[hmr][solid][diag] route patch attempt', { id, fullPath, hasRouter: !!router, routesByIdKeys: router?.routesById ? Object.keys(router.routesById) : 'none' });
913
+ const existingRoute = fullPath && router ? findRouteByFullPath(router, fullPath) : null;
914
+ if (existingRoute?.options) {
915
+ existingRoute.options.loader = newRoute.options.loader;
916
+ if (newRoute.options.component)
917
+ existingRoute.options.component = newRoute.options.component;
918
+ routesPatchCount++;
919
+ if (VERBOSE)
920
+ console.log('[hmr][solid] patched route loader', existingRoute.id, 'fullPath=', fullPath);
921
+ }
922
+ else if (VERBOSE) {
923
+ console.log('[hmr][solid] no matching route for fullPath', fullPath);
924
+ }
925
+ }
926
+ }
927
+ catch (e) {
928
+ if (VERBOSE)
929
+ console.warn('[hmr][solid] route patch error', id, e);
930
+ }
931
+ }
932
+ catch (e) {
933
+ if (VERBOSE)
934
+ console.warn('[hmr][solid] boundary re-import failed', id, e);
935
+ }
936
+ }
937
+ // Route loaders were patched with fresh closures. The data is
938
+ // correct in router.state.matches[].loaderData (confirmed via
939
+ // diagnostics), but the currently visible page doesn't re-render
940
+ // because the NativeScriptRouterProvider's Solid store flush only
941
+ // fires through history.subscribe. TODO: find the right mechanism
942
+ // to trigger a Solid reactive update for the active match stores.
943
+ if (routesPatchCount > 0 && VERBOSE) {
944
+ console.log('[hmr][solid] patched', routesPatchCount, 'route loaders (data correct in match state, pending UI refresh mechanism)');
945
+ }
946
+ if (VERBOSE) {
947
+ if (boundaries.size)
948
+ console.log('[hmr][solid] propagated non-component change to', boundaries.size, 'boundaries', Array.from(boundaries));
949
+ console.log('[hmr][queue] Solid: modules re-imported, solid-refresh handles reactive update', drained);
950
+ }
951
+ }
952
+ catch (e) {
953
+ if (VERBOSE)
954
+ console.warn('[hmr][solid] propagation failed', e);
955
+ }
956
+ break;
957
+ }
693
958
  case 'typescript': {
694
959
  // For TS apps, always reset back to the conventional app root.
695
960
  // This preserves the shell (Frame, ActionBar, etc.) that the app's
@@ -702,9 +967,124 @@ async function processQueue() {
702
967
  console.warn('[hmr][queue] TS flavor: Application.resetRootView unavailable; skipping UI refresh');
703
968
  break;
704
969
  }
970
+ // Re-fetch changed XML/CSS files and update the bundled module registry
971
+ // so Builder.createViewFromEntry picks up fresh content.
972
+ const rawAssetIds = drained.filter((id) => /\.(xml|css|scss|sass|less)$/i.test(id));
973
+ if (rawAssetIds.length && typeof g.registerModule === 'function') {
974
+ const origin = getHttpOriginForVite() || deriveHttpOrigin(getHMRWsUrl());
975
+ if (origin) {
976
+ for (const id of rawAssetIds) {
977
+ try {
978
+ const spec = normalizeSpec(id);
979
+ // Fetch the raw file content directly from Vite's dev server.
980
+ // Use the project-relative path which Vite serves as static files.
981
+ const fetchUrl = origin + (spec.startsWith('/') ? spec : '/' + spec);
982
+ if (VERBOSE)
983
+ console.log('[hmr][queue] fetching raw asset', { id, fetchUrl });
984
+ const resp = await fetch(fetchUrl);
985
+ if (resp.ok) {
986
+ const rawContent = await resp.text();
987
+ // Register under all nickname variants the module registry uses.
988
+ // The bundler context registers XML as e.g., './main-page.xml' and 'main-page.xml'
989
+ const appVirtual = APP_VIRTUAL_WITH_SLASH.replace(/^\//, '');
990
+ let relPath = spec.startsWith('/') ? spec.slice(1) : spec;
991
+ if (relPath.startsWith(appVirtual))
992
+ relPath = relPath.slice(appVirtual.length);
993
+ const nicknames = ['./' + relPath, relPath];
994
+ // Also add without extension for CSS
995
+ const extIdx = relPath.lastIndexOf('.');
996
+ if (extIdx > 0) {
997
+ const baseName = relPath.slice(0, extIdx);
998
+ if (!relPath.endsWith('.xml'))
999
+ nicknames.push(baseName, './' + baseName);
1000
+ }
1001
+ for (const name of nicknames) {
1002
+ if (VERBOSE)
1003
+ console.log('[hmr][queue] re-registering module', name);
1004
+ g.registerModule(name, () => rawContent);
1005
+ }
1006
+ }
1007
+ else if (VERBOSE) {
1008
+ console.warn('[hmr][queue] raw asset fetch failed', id, resp.status);
1009
+ }
1010
+ }
1011
+ catch (e) {
1012
+ if (VERBOSE)
1013
+ console.warn('[hmr][queue] raw asset refresh failed for', id, e);
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1018
+ // Determine if we can navigate in-place to a changed page
1019
+ // instead of resetting all the way back to app-root.
1020
+ // This keeps the user on the page they're editing for faster iteration.
1021
+ const changedXmlPages = drained
1022
+ .filter((id) => /\.xml$/i.test(id))
1023
+ .map((id) => {
1024
+ const spec = normalizeSpec(id);
1025
+ const appVirtual = APP_VIRTUAL_WITH_SLASH.replace(/^\//, '');
1026
+ let relPath = spec.startsWith('/') ? spec.slice(1) : spec;
1027
+ if (relPath.startsWith(appVirtual))
1028
+ relPath = relPath.slice(appVirtual.length);
1029
+ // Strip .xml extension to get the moduleName (e.g., 'pages/status-bar')
1030
+ return relPath.replace(/\.xml$/i, '');
1031
+ })
1032
+ .filter((m) => m && m !== 'app-root');
1033
+ // Resolve the topmost Frame from the bundled realm.
1034
+ // Frame.topmost() relies on an internal frameStack array, so we must
1035
+ // call it on the bundled-realm class. Multiple strategies to find it:
1036
+ const FrameClass = getCore('Frame') || g.Frame;
1037
+ let topFrame = null;
1038
+ // 1) Try the vendor-realm static topmost()
1039
+ try {
1040
+ topFrame = FrameClass?.topmost?.();
1041
+ }
1042
+ catch { }
1043
+ // 2) Try getting the root view from Application — if it's a Frame, use it
1044
+ if (!topFrame) {
1045
+ try {
1046
+ const rootView = App.getRootView?.() || App._rootView;
1047
+ if (rootView) {
1048
+ // rootView could be a Frame itself, or contain a Frame
1049
+ const isFrame = rootView.constructor?.name === 'Frame' || rootView.navigate;
1050
+ if (isFrame) {
1051
+ topFrame = rootView;
1052
+ }
1053
+ else if (rootView.getChildAt) {
1054
+ // Walk direct children looking for a Frame
1055
+ for (let i = 0; i < (rootView.getChildrenCount?.() || 0); i++) {
1056
+ const child = rootView.getChildAt(i);
1057
+ if (child?.constructor?.name === 'Frame' || child?.navigate) {
1058
+ topFrame = child;
1059
+ break;
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+ }
1065
+ catch { }
1066
+ }
705
1067
  if (VERBOSE)
706
- console.log('[hmr][queue] TS flavor: resetRootView(app-root) after changes');
707
- App.resetRootView({ moduleName: 'app-root' });
1068
+ console.log('[hmr][queue] TS: changedXmlPages=', changedXmlPages, 'topFrame=', !!topFrame);
1069
+ if (changedXmlPages.length > 0 && topFrame) {
1070
+ // Navigate the current frame to the changed page directly.
1071
+ // Use the last changed XML page (most specific).
1072
+ const moduleName = changedXmlPages[changedXmlPages.length - 1];
1073
+ if (VERBOSE)
1074
+ console.log('[hmr][queue] TS: navigating in-place to', moduleName);
1075
+ try {
1076
+ topFrame.navigate({ moduleName, clearHistory: false, animated: false });
1077
+ }
1078
+ catch (navErr) {
1079
+ console.warn('[hmr][queue] TS flavor: in-place navigate failed, falling back to resetRootView', navErr);
1080
+ App.resetRootView({ moduleName: 'app-root' });
1081
+ }
1082
+ }
1083
+ else {
1084
+ if (VERBOSE)
1085
+ console.log('[hmr][queue] TS flavor: resetRootView(app-root) after changes');
1086
+ App.resetRootView({ moduleName: 'app-root' });
1087
+ }
708
1088
  }
709
1089
  catch (e) {
710
1090
  console.warn('[hmr][queue] TS flavor: resetRootView(app-root) failed', e);
@@ -752,6 +1132,7 @@ function connectHmr() {
752
1132
  console.log('[hmr-client] Already connecting to HMR WebSocket, skipping');
753
1133
  return;
754
1134
  }
1135
+ const overlayStage = hasOpenedHmrSocket ? 'reconnecting' : 'connecting';
755
1136
  const baseUrl = getHMRWsUrl() || 'ws://localhost:5173/ns-hmr';
756
1137
  const buildCandidates = (url) => {
757
1138
  let candidates = [];
@@ -811,10 +1192,19 @@ function connectHmr() {
811
1192
  let idx = 0;
812
1193
  const tryNext = () => {
813
1194
  if (idx >= candidates.length) {
1195
+ showConnectionOverlayNow('offline', 'Waiting for the Vite websocket to come back.');
814
1196
  console.warn('[hmr-client] All WS candidates failed:', candidates.join(', '));
1197
+ setTimeout(connectHmr, 1500);
815
1198
  return;
816
1199
  }
817
1200
  const url = candidates[idx++];
1201
+ const connectionDetail = `${overlayStage === 'reconnecting' ? 'Retrying' : 'Opening'} ${url}`;
1202
+ if (connectionOverlayVisible) {
1203
+ updateConnectionOverlay(overlayStage, connectionDetail);
1204
+ }
1205
+ else {
1206
+ scheduleConnectionOverlay(overlayStage, connectionDetail);
1207
+ }
818
1208
  try {
819
1209
  if (__NS_ENV_VERBOSE__)
820
1210
  console.log('[hmr-client] Connecting to HMR WebSocket:', url);
@@ -836,6 +1226,12 @@ function connectHmr() {
836
1226
  sock.onopen = () => {
837
1227
  opened = true;
838
1228
  clearTimeout(timeout);
1229
+ clearConnectionOverlayTimer();
1230
+ hasOpenedHmrSocket = true;
1231
+ awaitingHealthyHmrMessage = true;
1232
+ if (connectionOverlayVisible) {
1233
+ showConnectionOverlayNow('synchronizing', 'Connected. Synchronizing the HMR graph.');
1234
+ }
839
1235
  VERBOSE && console.log('[hmr-client] Connected to HMR WebSocket');
840
1236
  };
841
1237
  sock.onmessage = handleHmrMessage;
@@ -854,6 +1250,7 @@ function connectHmr() {
854
1250
  else {
855
1251
  if (VERBOSE)
856
1252
  console.log('[hmr-client] WebSocket closed (code', ev?.code, '), will reconnect…');
1253
+ scheduleConnectionOverlay('reconnecting', 'The websocket closed. Waiting to reconnect.', 700);
857
1254
  // try to reconnect with full candidate list again
858
1255
  setTimeout(connectHmr, 1000);
859
1256
  }
@@ -874,6 +1271,9 @@ async function handleHmrMessage(ev) {
874
1271
  catch {
875
1272
  return;
876
1273
  }
1274
+ if (awaitingHealthyHmrMessage && msg) {
1275
+ markHmrConnectionHealthy();
1276
+ }
877
1277
  // Notify optional app-level hook after an HMR batch is applied.
878
1278
  function notifyAppHmrUpdate(kind, changedIds) {
879
1279
  try {
@@ -896,6 +1296,34 @@ async function handleHmrMessage(ev) {
896
1296
  const prevGraph = new Map(graph);
897
1297
  setGraphVersion(Number(msg.version || getGraphVersion() || 0));
898
1298
  applyFullGraph(msg);
1299
+ hasReceivedFullGraph = true;
1300
+ // Gate: On first boot, the entry-runtime handles all initial module loading
1301
+ // (with the import map already configured). Don't re-import here — the graph
1302
+ // is stored above for future HMR delta comparisons, but modules are already
1303
+ // loaded correctly via the entry-runtime boot sequence.
1304
+ //
1305
+ // Two cases to catch:
1306
+ // 1. Boot still in progress (__NS_HMR_BOOT_COMPLETE__ is false)
1307
+ // 2. Boot already finished but this is the FIRST full-graph (prevGraph was
1308
+ // empty). The WebSocket often connects after entry-runtime finishes, so
1309
+ // boot is "complete" but we still shouldn't re-import — all modules were
1310
+ // just loaded fresh. Only re-import on subsequent full-graphs (reconnect
1311
+ // scenarios) where prevGraph already has entries.
1312
+ if (!globalThis.__NS_HMR_BOOT_COMPLETE__) {
1313
+ if (VERBOSE)
1314
+ console.info('[hmr][full-graph] skipping initial re-import (boot in progress)');
1315
+ const fullIds = Array.isArray(msg.modules) ? msg.modules.map((m) => m?.id).filter(Boolean) : [];
1316
+ notifyAppHmrUpdate('full-graph', fullIds);
1317
+ return;
1318
+ }
1319
+ if (prevGraph.size === 0) {
1320
+ if (VERBOSE)
1321
+ console.info('[hmr][full-graph] skipping re-import on first graph after boot (modules already fresh)');
1322
+ const fullIds = Array.isArray(msg.modules) ? msg.modules.map((m) => m?.id).filter(Boolean) : [];
1323
+ notifyAppHmrUpdate('full-graph', fullIds);
1324
+ return;
1325
+ }
1326
+ // Reconnect / resync case — re-import changed modules as normal.
899
1327
  // In some cases (e.g. server chooses full-graph resync / page reload), we won't
900
1328
  // receive a delta queue to re-import changed TS modules. Without re-import,
901
1329
  // HTTP ESM caching means module bodies (and side effects) won't re-run.
@@ -1455,7 +1883,27 @@ export function initHmrClient(opts) {
1455
1883
  }
1456
1884
  g.__NS_HMR_CLIENT_ACTIVE__ = true;
1457
1885
  ensureCoreAliasesOnGlobalThis();
1458
- connectHmr();
1886
+ // Defer WebSocket connection until boot completes to avoid native V8 crashes
1887
+ // caused by concurrent WebSocket message handling + HTTP fetch during early startup.
1888
+ // The WebSocket is only needed for HMR updates, not the initial boot sequence.
1889
+ if (g.__NS_HMR_BOOT_COMPLETE__) {
1890
+ connectHmr();
1891
+ }
1892
+ else {
1893
+ const waitForBoot = () => {
1894
+ if (globalThis.__NS_HMR_BOOT_COMPLETE__) {
1895
+ if (VERBOSE)
1896
+ console.log('[hmr-client] boot complete, connecting HMR WebSocket');
1897
+ connectHmr();
1898
+ }
1899
+ else {
1900
+ setTimeout(waitForBoot, 100);
1901
+ }
1902
+ };
1903
+ if (VERBOSE)
1904
+ console.log('[hmr-client] deferring WebSocket connection until boot completes');
1905
+ setTimeout(waitForBoot, 100);
1906
+ }
1459
1907
  // Best-effort: install back wrapper even before first remount; original root may be captured later
1460
1908
  switch (__NS_TARGET_FLAVOR__) {
1461
1909
  case 'vue':