@nativescript/vite 8.0.0-alpha.7 → 8.0.0-alpha.9

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 (97) hide show
  1. package/configuration/angular.js +168 -26
  2. package/configuration/angular.js.map +1 -1
  3. package/configuration/base.js +37 -9
  4. package/configuration/base.js.map +1 -1
  5. package/configuration/typescript.js +1 -1
  6. package/configuration/typescript.js.map +1 -1
  7. package/helpers/angular/angular-linker.js +3 -12
  8. package/helpers/angular/angular-linker.js.map +1 -1
  9. package/helpers/angular/inject-component-hmr-registration.d.ts +112 -0
  10. package/helpers/angular/inject-component-hmr-registration.js +359 -0
  11. package/helpers/angular/inject-component-hmr-registration.js.map +1 -0
  12. package/helpers/angular/util.d.ts +1 -0
  13. package/helpers/angular/util.js +88 -0
  14. package/helpers/angular/util.js.map +1 -1
  15. package/helpers/global-defines.d.ts +2 -0
  16. package/helpers/global-defines.js +2 -0
  17. package/helpers/global-defines.js.map +1 -1
  18. package/helpers/main-entry.js +109 -30
  19. package/helpers/main-entry.js.map +1 -1
  20. package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
  21. package/helpers/nativeclass-transformer-plugin.js +157 -14
  22. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  23. package/helpers/prelink-angular.js +1 -4
  24. package/helpers/prelink-angular.js.map +1 -1
  25. package/helpers/project.d.ts +35 -0
  26. package/helpers/project.js +120 -2
  27. package/helpers/project.js.map +1 -1
  28. package/helpers/ts-config-paths.js +50 -2
  29. package/helpers/ts-config-paths.js.map +1 -1
  30. package/helpers/workers.d.ts +7 -19
  31. package/helpers/workers.js +75 -3
  32. package/helpers/workers.js.map +1 -1
  33. package/hmr/entry-runtime.js +11 -29
  34. package/hmr/entry-runtime.js.map +1 -1
  35. package/hmr/frameworks/angular/client/index.js +40 -50
  36. package/hmr/frameworks/angular/client/index.js.map +1 -1
  37. package/hmr/frameworks/angular/server/linker.js +1 -4
  38. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  39. package/hmr/frameworks/angular/server/strategy.js +10 -1
  40. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  41. package/hmr/frameworks/vue/client/index.js +18 -42
  42. package/hmr/frameworks/vue/client/index.js.map +1 -1
  43. package/hmr/helpers/cjs-named-exports.d.ts +23 -0
  44. package/hmr/helpers/cjs-named-exports.js +152 -0
  45. package/hmr/helpers/cjs-named-exports.js.map +1 -0
  46. package/hmr/server/constants.js +13 -4
  47. package/hmr/server/constants.js.map +1 -1
  48. package/hmr/server/core-sanitize.js +10 -3
  49. package/hmr/server/core-sanitize.js.map +1 -1
  50. package/hmr/server/ns-core-cjs-shape.js +1 -1
  51. package/hmr/server/ns-core-cjs-shape.js.map +1 -1
  52. package/hmr/server/vite-plugin.js +16 -0
  53. package/hmr/server/vite-plugin.js.map +1 -1
  54. package/hmr/server/websocket-angular-hot-update.d.ts +1 -0
  55. package/hmr/server/websocket-angular-hot-update.js +15 -1
  56. package/hmr/server/websocket-angular-hot-update.js.map +1 -1
  57. package/hmr/server/websocket-core-bridge.js +1 -1
  58. package/hmr/server/websocket-core-bridge.js.map +1 -1
  59. package/hmr/server/websocket-module-bindings.js +2 -2
  60. package/hmr/server/websocket-module-bindings.js.map +1 -1
  61. package/hmr/server/websocket-module-specifiers.d.ts +66 -2
  62. package/hmr/server/websocket-module-specifiers.js +190 -19
  63. package/hmr/server/websocket-module-specifiers.js.map +1 -1
  64. package/hmr/server/websocket-ns-m-finalize.js +1 -1
  65. package/hmr/server/websocket-ns-m-finalize.js.map +1 -1
  66. package/hmr/server/websocket-ns-m-request.d.ts +11 -1
  67. package/hmr/server/websocket-ns-m-request.js +17 -9
  68. package/hmr/server/websocket-ns-m-request.js.map +1 -1
  69. package/hmr/server/websocket-runtime-compat.js +1 -1
  70. package/hmr/server/websocket-runtime-compat.js.map +1 -1
  71. package/hmr/server/websocket-served-module-helpers.d.ts +1 -1
  72. package/hmr/server/websocket-served-module-helpers.js +18 -1
  73. package/hmr/server/websocket-served-module-helpers.js.map +1 -1
  74. package/hmr/server/websocket-vue-sfc.js +15 -60
  75. package/hmr/server/websocket-vue-sfc.js.map +1 -1
  76. package/hmr/server/websocket.d.ts +1 -1
  77. package/hmr/server/websocket.js +176 -167
  78. package/hmr/server/websocket.js.map +1 -1
  79. package/hmr/shared/runtime/dev-overlay.js +5 -17
  80. package/hmr/shared/runtime/dev-overlay.js.map +1 -1
  81. package/hmr/shared/runtime/module-provenance.js +1 -4
  82. package/hmr/shared/runtime/module-provenance.js.map +1 -1
  83. package/hmr/shared/runtime/root-placeholder.js +38 -68
  84. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  85. package/hmr/shared/runtime/session-bootstrap.js +1 -4
  86. package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
  87. package/hmr/shared/runtime/vendor-bootstrap.js +1 -9
  88. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  89. package/hmr/shared/vendor/manifest.d.ts +30 -0
  90. package/hmr/shared/vendor/manifest.js +200 -22
  91. package/hmr/shared/vendor/manifest.js.map +1 -1
  92. package/index.d.ts +1 -0
  93. package/index.js +5 -0
  94. package/index.js.map +1 -1
  95. package/package.json +3 -1
  96. package/runtime/core-aliases-early.js +17 -41
  97. package/runtime/core-aliases-early.js.map +1 -1
@@ -11,13 +11,14 @@ const babelTraverse = traverse?.default || traverse;
11
11
  import * as t from '@babel/types';
12
12
  import { existsSync, readFileSync, statSync } from 'fs';
13
13
  import { astNormalizeModuleImportsAndHelpers, astVerifyAndAnnotateDuplicates } from '../helpers/ast-normalizer.js';
14
+ import { getCjsNamedExports } from '../helpers/cjs-named-exports.js';
14
15
  import { stripRtCoreSentinel, stripDanglingViteCjsImports } from '../helpers/sanitize.js';
15
16
  import { WebSocketServer } from 'ws';
16
17
  import * as path from 'path';
17
18
  import { createHash } from 'crypto';
18
19
  import * as PAT from './constants.js';
19
20
  import { getVendorManifest, resolveVendorSpecifier } from '../shared/vendor/registry.js';
20
- import { getPackageJson, getProjectFilePath, getProjectRootPath } from '../../helpers/project.js';
21
+ import { getMonorepoWorkspaceRoot, getPackageJson, getProjectFilePath, getProjectRootPath } from '../../helpers/project.js';
21
22
  import { loadPrebuiltVendorManifest } from '../shared/vendor/manifest-loader.js';
22
23
  import '../vendor-bootstrap.js';
23
24
  import { NS_NATIVE_TAGS } from './compiler.js';
@@ -39,7 +40,7 @@ import { angularSourceHasSemanticDecorator, canonicalizeTransformRequestCacheKey
39
40
  import { classifyGraphUpsert, shouldBroadcastGraphUpsertDelta, shouldBumpGraphVersion } from './websocket-graph-upsert.js';
40
41
  import { classifyBootRoute, classifyHmrUpdateKind, createColdBootRequestCounter, formatHmrUpdateSummary, formatPopulateInitialGraphSummary, formatServerStartupBanner } from './perf-instrumentation.js';
41
42
  import { createHmrPendingMessage } from './websocket-hmr-pending.js';
42
- import { extractVitePrebundleId, filterExistingNodeModulesTransformCandidates, getBlockedDeviceNodeModulesReason, getFlattenedManifestMap, isCoreGlobalsReference, isEsmFrameworkPackageSpecifier, isLikelyNativeScriptPluginSpecifier, isLikelyNativeScriptRuntimePluginSpecifier, isNativeScriptCoreModule, isNativeScriptPluginModule, normalizeNativeScriptCoreSpecifier, normalizeNodeModulesSpecifier, resolveCandidateFilePath, resolveInternalRuntimePluginBareSpecifier, resolveNodeModulesPackageBoundary, resolveVendorFromCandidate, resolveVendorRouting, shouldPreserveBareRuntimePluginSubpathImport, stripDecoratedServePrefixes, tryReadRawExplicitJavaScriptModule, viteDepsPathToBareSpecifier, } from './websocket-module-specifiers.js';
43
+ import { extractVitePrebundleId, filterExistingNodeModulesTransformCandidates, getBlockedDeviceNodeModulesReason, getFlattenedManifestMap, isCoreGlobalsReference, isEsmFrameworkPackageSpecifier, isLikelyNativeScriptPluginSpecifier, isLikelyNativeScriptRuntimePluginSpecifier, isNativeScriptCoreModule, isNativeScriptPluginModule, normalizeNativeScriptCoreSpecifier, normalizeNodeModulesSpecifier, resolveCandidateFilePath, resolveInternalRuntimePluginBareSpecifier, resolveNodeModulesPackageBoundary, resolveVendorFromCandidate, resolveVendorRouting, rewriteFsAbsoluteToNsM, shouldPreserveBareRuntimePluginSubpathImport, stripDecoratedServePrefixes, tryReadRawExplicitJavaScriptModule, viteDepsPathToBareSpecifier, } from './websocket-module-specifiers.js';
43
44
  import { ensureNativeScriptModuleBindings, getProcessCodeResolvedSpecifierOverrides } from './websocket-module-bindings.js';
44
45
  import { collectStaticExportNamesFromFile, collectStaticExportOriginsFromFile, ensureVersionedCoreImports, extractDirectExportedNames, normalizeCoreExportOriginsForRuntime, parseCoreBridgeRequest, resolveRuntimeCoreModulePath } from './websocket-core-bridge.js';
45
46
  import { createSharedTransformRequestRunner } from './shared-transform-request.js';
@@ -387,10 +388,7 @@ async function expandStarExports(code, server, projectRoot, verbose, sharedTrans
387
388
  if (!names.length)
388
389
  return null;
389
390
  if (verbose) {
390
- try {
391
- console.log(`[ns/m] expanded export* -> ${names.length} names from ${vitePath}`);
392
- }
393
- catch { }
391
+ console.log(`[ns/m] expanded export* -> ${names.length} names from ${vitePath}`);
394
392
  }
395
393
  return { rep, names };
396
394
  }
@@ -453,7 +451,7 @@ function stripViteDynamicImportVirtual(code) {
453
451
  }
454
452
  return code;
455
453
  }
456
- const REQUIRE_GUARD_SNIPPET = `// [guard] install require('http(s)://') detector\n(()=>{try{var g=globalThis;if(g.__NS_REQUIRE_GUARD_INSTALLED__){}else{var mk=function(o,l){return function(){try{var s=arguments[0];if(typeof s==='string'&&/^(?:https?:)\\/\\//.test(s)){var e=new Error('[ns-hmr][require-guard] require of URL: '+s+' via '+l);try{console.error(e.message+'\\n'+(e.stack||''));}catch(e2){}try{g.__NS_REQUIRE_GUARD_LAST__={spec:s,stack:e.stack,label:l,ts:Date.now()};}catch(e3){}}}catch(e1){}return o.apply(this, arguments);};};if(typeof g.require==='function'&&!g.require.__NS_REQ_GUARDED__){var o1=g.require;g.require=mk(o1,'require');g.require.__NS_REQ_GUARDED__=true;}if(typeof g.__nsRequire==='function'&&!g.__nsRequire.__NS_REQ_GUARDED__){var o2=g.__nsRequire;g.__nsRequire=mk(o2,'__nsRequire');g.__nsRequire.__NS_REQ_GUARDED__=true;}g.__NS_REQUIRE_GUARD_INSTALLED__=true;}}catch(e){}})();\n`;
454
+ const REQUIRE_GUARD_SNIPPET = `// [guard] install require('http(s)://') detector\n(()=>{try{var g=globalThis;if(g.__NS_REQUIRE_GUARD_INSTALLED__){}else{var mk=function(o,l){return function(){try{var s=arguments[0];if(typeof s==='string'&&/^(?:https?:)\\/\\//.test(s)){var e=new Error('[ns-hmr][require-guard] require of URL: '+s+' via '+l);console.error(e.message+'\\n'+(e.stack||''));try{g.__NS_REQUIRE_GUARD_LAST__={spec:s,stack:e.stack,label:l,ts:Date.now()};}catch(e3){}}}catch(e1){}return o.apply(this, arguments);};};if(typeof g.require==='function'&&!g.require.__NS_REQ_GUARDED__){var o1=g.require;g.require=mk(o1,'require');g.require.__NS_REQ_GUARDED__=true;}if(typeof g.__nsRequire==='function'&&!g.__nsRequire.__NS_REQ_GUARDED__){var o2=g.__nsRequire;g.__nsRequire=mk(o2,'__nsRequire');g.__nsRequire.__NS_REQ_GUARDED__=true;}g.__NS_REQUIRE_GUARD_INSTALLED__=true;}}catch(e){}})();\n`;
457
455
  function shouldRemapImport(spec) {
458
456
  if (!spec || typeof spec !== 'string')
459
457
  return false;
@@ -1039,7 +1037,7 @@ function deduplicateLinkerImports(code) {
1039
1037
  return code;
1040
1038
  }
1041
1039
  }
1042
- export function wrapCommonJsModuleForDevice(code) {
1040
+ export function wrapCommonJsModuleForDevice(code, absolutePath) {
1043
1041
  if (!code)
1044
1042
  return code;
1045
1043
  try {
@@ -1065,6 +1063,22 @@ export function wrapCommonJsModuleForDevice(code) {
1065
1063
  namedExports.add(name);
1066
1064
  }
1067
1065
  }
1066
+ // Static enumeration only sees `exports.foo = ...` and `Object.defineProperty(exports, 'foo', ...)`.
1067
+ // Real-world packages like lodash attach their entire surface to a function inside an IIFE and
1068
+ // then `module.exports = thatFunction`. Static analysis returns zero in that case. To handle
1069
+ // these modules we ALSO load the package in the dev-server's Node context (only when we have a
1070
+ // node_modules path) and merge the runtime keys. See `helpers/cjs-named-exports.ts` for the
1071
+ // reasoning and safety boundaries.
1072
+ if (absolutePath) {
1073
+ try {
1074
+ for (const n of getCjsNamedExports(absolutePath)) {
1075
+ namedExports.add(n);
1076
+ }
1077
+ }
1078
+ catch {
1079
+ /* fall through to whatever we caught statically */
1080
+ }
1081
+ }
1068
1082
  let suffix = `\nvar __cjs_mod = module.exports;\nexport default __cjs_mod;\n`;
1069
1083
  if (namedExports.size) {
1070
1084
  const entries = Array.from(namedExports);
@@ -1457,10 +1471,18 @@ function processCodeForDevice(code, isVitePreBundled, preserveVendorImports = fa
1457
1471
  result = result.replace(/;\s*import\s+/g, ';\nimport ');
1458
1472
  result = result.replace(/}\s*import\s+/g, '}\nimport ');
1459
1473
  // Fallback: ensure any static import that isn't at start of line gets a newline before it.
1460
- // Only match after statement-ending characters (;, }, ), ], quotes) — NOT after `*` or
1461
- // spaces inside JSDoc comment blocks, which would accidentally extract example imports
1462
- // from documentation comments and hoist them as real code.
1463
- result = result.replace(/([;}\)\]'"`])\s*(import\s+[^;\n]*\s+from\s*["'][^"']+["'])/g, '$1\n$2');
1474
+ //
1475
+ // Only match after **structural** statement-ending characters: `;`, `}`, `)`, `]`. We
1476
+ // deliberately do NOT include `'`, `"`, or `` ` `` here — those are string-literal
1477
+ // terminators (and openers!), and including them caused the regex to fire inside
1478
+ // example code embedded in error strings. Concrete failure observed:
1479
+ // `@supabase/realtime-js` throws an Error whose message contains the literal
1480
+ // `' import ws from "ws"\n' +`. With `'` in the delimiter class, the engine matched
1481
+ // the opening `'` of that string literal as a "statement terminator" and rewrote the
1482
+ // example to `'\nimport ws from "..."` — splitting the string across two lines and
1483
+ // producing a SyntaxError on device. The structural delimiters below do not appear
1484
+ // inside string-literal openers, so the rewrite is safe.
1485
+ result = result.replace(/([;}\)\]])\s*(import\s+[^;\n]*\s+from\s*["'][^"']+["'])/g, '$1\n$2');
1464
1486
  }
1465
1487
  catch { }
1466
1488
  // Collapse duplicate destructuring from the same temp namespace var (e.g., multiple const { x } = __ns_rt_ns1)
@@ -1823,6 +1845,10 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
1823
1845
  const mixedRuntimePluginHttpRootPackages = collectMixedRuntimePluginHttpRootPackages(result, projectRoot);
1824
1846
  const isDynamicImportPrefix = (prefix) => /import\(\s*["']?$/.test(prefix.trimStart());
1825
1847
  const importerDir = path.posix.dirname(importerPath);
1848
+ // Resolved once per `rewriteImports` call so the per-import `/@fs/` rewriter
1849
+ // can convert workspace-lib paths back into our `/ns/m/` pipeline. Memoized
1850
+ // upstream — calling here is cheap and we reuse the value below.
1851
+ const monorepoWorkspaceRootForRewrite = getMonorepoWorkspaceRoot(projectRoot);
1826
1852
  // Determine importer output relative path (project-relative .mjs) to compute relative imports consistently
1827
1853
  const importerOutRel = outputDirOverrideRel || getProjectRelativeImportPath(importerPath, projectRoot) || stripToProjectRelative(importerPath, projectRoot).replace(/\.(ts|js|tsx|jsx|mjs|mts|cts)$/i, '.mjs');
1828
1854
  const importerOutDir = importerOutRel ? path.posix.dirname(importerOutRel) : '';
@@ -1889,7 +1915,23 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
1889
1915
  const cleanPath = jsonPath.split('?')[0];
1890
1916
  // Resolve the JSON file path relative to the importer
1891
1917
  let fullPath;
1892
- if (cleanPath.startsWith('/')) {
1918
+ if (cleanPath.startsWith('/@fs/')) {
1919
+ // Vite filesystem URL: `/@fs/<abs-path>`. Strip the `/@fs` prefix
1920
+ // (4 chars, leaving the leading `/`) to recover the absolute
1921
+ // path. This matches `rewriteFsAbsoluteToNsM`'s convention and
1922
+ // covers both bare specifiers Vite pre-resolved out of the
1923
+ // project root (e.g. `emojibase-data/en/compact.json` →
1924
+ // `/@fs/.../node_modules/.../compact.json`) and tsconfig
1925
+ // path-alias targets that resolve outside the project root
1926
+ // (e.g. `~shared/...metadata.json` → `/@fs/.../tools/...json`).
1927
+ // Without this branch the next `else if` would `path.join` the
1928
+ // `/@fs/...` URL onto `projectRoot`, collapsing the leading `/`
1929
+ // and producing a malformed nested path that always misses on
1930
+ // `existsSync` and triggers a `ReferenceError` at runtime when
1931
+ // the JSON-import-failed comment leaves the binding undefined.
1932
+ fullPath = cleanPath.slice('/@fs'.length);
1933
+ }
1934
+ else if (cleanPath.startsWith('/')) {
1893
1935
  // Absolute from project root
1894
1936
  fullPath = path.join(projectRoot, cleanPath);
1895
1937
  }
@@ -1911,7 +1953,7 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
1911
1953
  return `const ${varName} = ${jsonContent};`;
1912
1954
  }
1913
1955
  else {
1914
- console.warn(`[rewrite] JSON file not found: ${fullPath}`);
1956
+ console.warn(`[rewrite] JSON file not found: ${fullPath} (specifier=${jsonPath})`);
1915
1957
  }
1916
1958
  }
1917
1959
  catch (error) {
@@ -1962,17 +2004,41 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
1962
2004
  if (spec === '@') {
1963
2005
  const stub = `/ns/m/__invalid_at__.mjs`;
1964
2006
  if (verbose) {
1965
- try {
1966
- console.warn(`[rewrite] mapped bare '@' spec to stub: ${stub}`);
1967
- }
1968
- catch { }
2007
+ console.warn(`[rewrite] mapped bare '@' spec to stub: ${stub}`);
1969
2008
  }
1970
2009
  return `${prefix}${stub}${suffix}`;
1971
2010
  }
1972
2011
  spec = normalizeNativeScriptCoreSpecifier(spec);
2012
+ // Pull `/@fs/<abs-path>` URLs back into the `/ns/m/` pipeline so they
2013
+ // hit our CJS/UMD-wrapping handler. Vite emits `/@fs/...` for any
2014
+ // resolved id outside the configured `root` — including hoisted
2015
+ // `node_modules/<pkg>` entries and workspace libs in monorepos. Left
2016
+ // untouched, the device fetches them through Vite's standard
2017
+ // middleware which never invokes `wrapCommonJsModuleForDevice`, so a
2018
+ // UMD module like papaparse crashes on `(this).Papa = factory()`
2019
+ // because top-level `this` is `undefined` in ESM context.
2020
+ if (spec.startsWith('/@fs/')) {
2021
+ const rewritten = rewriteFsAbsoluteToNsM(spec, projectRoot, monorepoWorkspaceRootForRewrite);
2022
+ if (rewritten) {
2023
+ if (httpOriginSafe) {
2024
+ return `${prefix}${httpOriginSafe}${rewritten}${suffix}`;
2025
+ }
2026
+ return `${prefix}${rewritten}${suffix}`;
2027
+ }
2028
+ // Path resolves outside both roots — leave Vite's URL alone as a
2029
+ // last resort. The original behaviour was to fall through here
2030
+ // and let downstream branches (e.g. `normalizeNodeModulesSpecifier`)
2031
+ // handle paths whose abs form happens to contain `/node_modules/`,
2032
+ // so preserve that for the unrewritable case below.
2033
+ }
1973
2034
  // Route Vite virtual modules (/@solid-refresh, etc.) through /ns/m/ so their
1974
2035
  // internal imports (e.g. solid-js) get vendor-rewritten by our pipeline.
1975
- // Skip known Vite internals (/@vite/, /@id/, /@fs/) which are handled elsewhere.
2036
+ // Skip known Vite internals (/@vite/, /@id/) which are handled elsewhere.
2037
+ // `/@fs/` is intentionally excluded above; if we ever reach here with a
2038
+ // `/@fs/` spec it means the rewrite-to-`/ns/m/` pass couldn't anchor it
2039
+ // under projectRoot or workspaceRoot, so we fall through and rely on the
2040
+ // `normalizeNodeModulesSpecifier` branch below for paths that still
2041
+ // contain a `/node_modules/<pkg>/` segment.
1976
2042
  if (spec.startsWith('/@') && !/^\/@(?:vite|id|fs)\//.test(spec)) {
1977
2043
  const out = `/ns/m${spec}`;
1978
2044
  if (httpOriginSafe) {
@@ -2186,10 +2252,7 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
2186
2252
  result = result.replace(/(import\(\s*['"])@(['"]\s*\))/g, (_m) => {
2187
2253
  const stubExpr = `import(new URL('/ns/m/__invalid_at__.mjs', import.meta.url).href)`;
2188
2254
  if (verbose) {
2189
- try {
2190
- console.warn(`[rewrite] mapped dynamic import('@') to /ns/m/__invalid_at__.mjs via import.meta.url`);
2191
- }
2192
- catch { }
2255
+ console.warn(`[rewrite] mapped dynamic import('@') to /ns/m/__invalid_at__.mjs via import.meta.url`);
2193
2256
  }
2194
2257
  return stubExpr;
2195
2258
  });
@@ -2198,10 +2261,7 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
2198
2261
  result = result.replace(/(from\s*['"])@(['"])/g, (_m, p1, p2) => {
2199
2262
  const stub = `/ns/m/__invalid_at__.mjs`;
2200
2263
  if (verbose) {
2201
- try {
2202
- console.warn(`[rewrite] mapped static from '@' to ${stub}`);
2203
- }
2204
- catch { }
2264
+ console.warn(`[rewrite] mapped static from '@' to ${stub}`);
2205
2265
  }
2206
2266
  return `${p1}${stub}${p2}`;
2207
2267
  });
@@ -2209,10 +2269,7 @@ export function rewriteImports(code, importerPath, sfcFileMap, depFileMap, proje
2209
2269
  result = result.replace(/(import\s*(?!\()\s*['"])@(['"])/g, (_m, p1, p2) => {
2210
2270
  const stub = `/ns/m/__invalid_at__.mjs`;
2211
2271
  if (verbose) {
2212
- try {
2213
- console.warn(`[rewrite] mapped side-effect import '@' to ${stub}`);
2214
- }
2215
- catch { }
2272
+ console.warn(`[rewrite] mapped side-effect import '@' to ${stub}`);
2216
2273
  }
2217
2274
  return `${p1}${stub}${p2}`;
2218
2275
  });
@@ -2504,11 +2561,8 @@ function createHmrWebSocketPlugin(opts) {
2504
2561
  const gm = { id, deps: normDeps, hash };
2505
2562
  graph.set(id, gm);
2506
2563
  if (verbose) {
2507
- try {
2508
- console.log('[hmr-ws][graph] upsert', { id, deps: normDeps, hash, graphVersion, classification, bumpVersion });
2509
- console.log('[hmr-ws][graph] size', graph.size);
2510
- }
2511
- catch { }
2564
+ console.log('[hmr-ws][graph] upsert', { id, deps: normDeps, hash, graphVersion, classification, bumpVersion });
2565
+ console.log('[hmr-ws][graph] size', graph.size);
2512
2566
  }
2513
2567
  if (shouldBroadcastGraphUpsertDelta(classification, options?.emitDeltaOnInsert === true, options?.broadcastDelta !== false)) {
2514
2568
  emitDelta([gm], []);
@@ -2609,15 +2663,12 @@ function createHmrWebSocketPlugin(opts) {
2609
2663
  // `bumpedVersion=no` result is the happy path, `yes`
2610
2664
  // indicates a regression.
2611
2665
  if (verbose) {
2612
- try {
2613
- console.info(formatPopulateInitialGraphSummary({
2614
- moduleCount: graph.size,
2615
- durationMs: Date.now() - tStart,
2616
- graphVersion,
2617
- bumpedVersion: graphVersion !== versionAtStart,
2618
- }));
2619
- }
2620
- catch { }
2666
+ console.info(formatPopulateInitialGraphSummary({
2667
+ moduleCount: graph.size,
2668
+ durationMs: Date.now() - tStart,
2669
+ graphVersion,
2670
+ bumpedVersion: graphVersion !== versionAtStart,
2671
+ }));
2621
2672
  }
2622
2673
  }
2623
2674
  // Kick off `populateInitialGraph` in the background (non-awaited) so /ns/m
@@ -2682,10 +2733,7 @@ function createHmrWebSocketPlugin(opts) {
2682
2733
  const configuredTransformCacheMs = Number.parseInt(process.env.NS_VITE_HMR_TRANSFORM_CACHE_MS || '', 10);
2683
2734
  const transformCacheMs = Number.isFinite(configuredTransformCacheMs) && configuredTransformCacheMs >= 0 ? configuredTransformCacheMs : 60000;
2684
2735
  sharedTransformRequest = createSharedTransformRequestRunner((url) => server.transformRequest(url), (url, timeoutMs) => {
2685
- try {
2686
- console.warn('[ns:m] slow transformRequest for', url, '(>' + timeoutMs + 'ms)');
2687
- }
2688
- catch { }
2736
+ console.warn('[ns:m] slow transformRequest for', url, '(>' + timeoutMs + 'ms)');
2689
2737
  }, {
2690
2738
  maxConcurrent: transformConcurrency,
2691
2739
  resultCacheTtlMs: transformCacheMs,
@@ -2752,10 +2800,7 @@ function createHmrWebSocketPlugin(opts) {
2752
2800
  log: (line) => {
2753
2801
  if (!verbose)
2754
2802
  return;
2755
- try {
2756
- console.info(line);
2757
- }
2758
- catch { }
2803
+ console.info(line);
2759
2804
  },
2760
2805
  });
2761
2806
  }
@@ -2874,10 +2919,7 @@ function createHmrWebSocketPlugin(opts) {
2874
2919
  });
2875
2920
  });
2876
2921
  wss.on('error', (err) => {
2877
- try {
2878
- console.warn('[hmr-ws] server error:', err?.message || String(err));
2879
- }
2880
- catch { }
2922
+ console.warn('[hmr-ws] server error:', err?.message || String(err));
2881
2923
  });
2882
2924
  // Import map endpoint: GET /ns/import-map.json
2883
2925
  // Returns the import map + runtime config for __nsConfigureRuntime()
@@ -2948,11 +2990,12 @@ function createHmrWebSocketPlugin(opts) {
2948
2990
  const hasExt = /\.(ts|tsx|js|jsx|mjs|mts|cts|vue)$/i.test(spec);
2949
2991
  const baseNoExt = hasExt ? spec.replace(/\.(ts|tsx|js|jsx|mjs|mts|cts)$/i, '') : spec;
2950
2992
  const transformRoot = server.config?.root || process.cwd();
2993
+ const transformWorkspaceRoot = getMonorepoWorkspaceRoot(transformRoot);
2951
2994
  const candidates = [];
2952
2995
  if (hasExt)
2953
2996
  candidates.push(spec);
2954
2997
  candidates.push(baseNoExt + '.ts', baseNoExt + '.js', baseNoExt + '.tsx', baseNoExt + '.jsx', baseNoExt + '.mjs', baseNoExt + '.mts', baseNoExt + '.cts', baseNoExt + '.vue', baseNoExt + '/index.ts', baseNoExt + '/index.js', baseNoExt + '/index.tsx', baseNoExt + '/index.jsx', baseNoExt + '/index.mjs');
2955
- const transformCandidates = filterExistingNodeModulesTransformCandidates(spec, candidates, transformRoot);
2998
+ const transformCandidates = filterExistingNodeModulesTransformCandidates(spec, candidates, transformRoot, transformWorkspaceRoot);
2956
2999
  let transformed = null;
2957
3000
  let resolvedCandidate = null;
2958
3001
  for (const cand of transformCandidates) {
@@ -3024,7 +3067,7 @@ function createHmrWebSocketPlugin(opts) {
3024
3067
  if (seen.has(depBase))
3025
3068
  continue;
3026
3069
  seen.add(depBase);
3027
- const depCandidates = filterExistingNodeModulesTransformCandidates(depBase, [depBase + '.ts', depBase + '.js', depBase + '.tsx', depBase + '.jsx', depBase + '.mjs', depBase + '.mts', depBase + '.cts', depBase + '.vue', depBase + '/index.ts', depBase + '/index.js', depBase + '/index.tsx', depBase + '/index.jsx', depBase + '/index.mjs'], transformRoot);
3070
+ const depCandidates = filterExistingNodeModulesTransformCandidates(depBase, [depBase + '.ts', depBase + '.js', depBase + '.tsx', depBase + '.jsx', depBase + '.mjs', depBase + '.mts', depBase + '.cts', depBase + '.vue', depBase + '/index.ts', depBase + '/index.js', depBase + '/index.tsx', depBase + '/index.jsx', depBase + '/index.mjs'], transformRoot, transformWorkspaceRoot);
3028
3071
  let depTrans = null;
3029
3072
  let depResolved = null;
3030
3073
  for (const c of depCandidates) {
@@ -3129,6 +3172,7 @@ function createHmrWebSocketPlugin(opts) {
3129
3172
  return;
3130
3173
  }
3131
3174
  const serverRoot = (server.config?.root || process.cwd());
3175
+ const monorepoWorkspaceRoot = getMonorepoWorkspaceRoot(serverRoot);
3132
3176
  spec = spec.replace(/[?#].*$/, '');
3133
3177
  // Accept path-based boot/HMR prefixes:
3134
3178
  // /ns/m/__ns_boot__/b1/<real-spec>
@@ -3206,7 +3250,7 @@ function createHmrWebSocketPlugin(opts) {
3206
3250
  const hasExt = /\.(ts|tsx|js|jsx|mjs|mts|cts|vue)$/i.test(spec);
3207
3251
  const baseNoExt = hasExt ? spec.replace(/\.(ts|tsx|js|jsx|mjs|mts|cts)$/i, '') : spec;
3208
3252
  const candidates = [...(hasExt ? [spec] : []), baseNoExt + '.ts', baseNoExt + '.js', baseNoExt + '.tsx', baseNoExt + '.jsx', baseNoExt + '.mjs', baseNoExt + '.mts', baseNoExt + '.cts', baseNoExt + '.vue', baseNoExt + '/index.ts', baseNoExt + '/index.js', baseNoExt + '/index.tsx', baseNoExt + '/index.jsx', baseNoExt + '/index.mjs'];
3209
- const transformCandidates = filterExistingNodeModulesTransformCandidates(spec, candidates, serverRoot);
3253
+ const transformCandidates = filterExistingNodeModulesTransformCandidates(spec, candidates, serverRoot, monorepoWorkspaceRoot);
3210
3254
  let transformed = null;
3211
3255
  let resolvedCandidate = null;
3212
3256
  const rawExplicitModule = tryReadRawExplicitJavaScriptModule(spec, serverRoot);
@@ -3270,18 +3314,24 @@ function createHmrWebSocketPlugin(opts) {
3270
3314
  }
3271
3315
  catch { }
3272
3316
  }
3273
- // Fallback 2: try /@fs absolute path under project root (Vite file system alias)
3317
+ // Fallback 2: try /@fs absolute path under project root (Vite file system alias).
3318
+ // In a monorepo with hoisted node_modules the file may live above
3319
+ // `serverRoot`, so try the workspace root next.
3274
3320
  if (!transformed?.code) {
3275
3321
  try {
3276
3322
  const toPosix = (p) => p.replace(/\\/g, '/');
3277
- const rootPosix = toPosix(serverRoot).replace(/\/$/, '');
3278
- const absPosix = `${rootPosix}${spec.startsWith('/') ? '' : '/'}${spec}`;
3279
- const fsId = `/@fs${absPosix}`;
3280
- if (resolveCandidateFilePath(fsId, serverRoot)) {
3281
- const r = await transformWithTimeout(fsId);
3282
- if (r?.code) {
3283
- transformed = r;
3284
- resolvedCandidate = fsId;
3323
+ const rootsToTry = [serverRoot, ...(monorepoWorkspaceRoot && path.resolve(monorepoWorkspaceRoot) !== path.resolve(serverRoot) ? [monorepoWorkspaceRoot] : [])];
3324
+ for (const root of rootsToTry) {
3325
+ const rootPosix = toPosix(root).replace(/\/$/, '');
3326
+ const absPosix = `${rootPosix}${spec.startsWith('/') ? '' : '/'}${spec}`;
3327
+ const fsId = `/@fs${absPosix}`;
3328
+ if (resolveCandidateFilePath(fsId, serverRoot, monorepoWorkspaceRoot)) {
3329
+ const r = await transformWithTimeout(fsId);
3330
+ if (r?.code) {
3331
+ transformed = r;
3332
+ resolvedCandidate = fsId;
3333
+ break;
3334
+ }
3285
3335
  }
3286
3336
  }
3287
3337
  }
@@ -3386,10 +3436,7 @@ function createHmrWebSocketPlugin(opts) {
3386
3436
  if (isApp && /\.(ts|tsx|js|jsx|mjs|mts|cts)$/i.test(id) && !isRuntimeGraphExcludedPath(id)) {
3387
3437
  const deps = Array.from(collectImportDependencies(code, id));
3388
3438
  if (verbose) {
3389
- try {
3390
- console.log('[hmr-ws][ts-graph] candidate', { id, depsCount: deps.length });
3391
- }
3392
- catch { }
3439
+ console.log('[hmr-ws][ts-graph] candidate', { id, depsCount: deps.length });
3393
3440
  }
3394
3441
  // Serve-time warm-up: no live edit happened, so don't bump
3395
3442
  // graphVersion.
@@ -3594,7 +3641,7 @@ export const piniaSymbol = p.piniaSymbol;
3594
3641
  // typically fall back to `self` or `globalThis`.
3595
3642
  // - `module`, `exports` must be shims since they don't exist in ESM.
3596
3643
  try {
3597
- code = wrapCommonJsModuleForDevice(code);
3644
+ code = wrapCommonJsModuleForDevice(code, resolvedCandidate || null);
3598
3645
  }
3599
3646
  catch { }
3600
3647
  try {
@@ -3808,10 +3855,7 @@ export const piniaSymbol = p.piniaSymbol;
3808
3855
  const hasCjsPattern = /\bmodule\s*\.\s*exports\b/.test(targetCode) || /\bexports\s*\.\s*\w/.test(targetCode);
3809
3856
  if (hasCjsPattern) {
3810
3857
  if (verbose) {
3811
- try {
3812
- console.warn(`[ns:m][link-check] CJS module without export default: ${u.pathname} (will be CJS-wrapped at serve time)`);
3813
- }
3814
- catch { }
3858
+ console.warn(`[ns:m][link-check] CJS module without export default: ${u.pathname} (will be CJS-wrapped at serve time)`);
3815
3859
  }
3816
3860
  continue;
3817
3861
  }
@@ -3827,20 +3871,14 @@ export const piniaSymbol = p.piniaSymbol;
3827
3871
  }
3828
3872
  catch (eLC) {
3829
3873
  if (verbose) {
3830
- try {
3831
- console.warn('[ns:m][link-check] failed', eLC?.message || eLC);
3832
- }
3833
- catch { }
3874
+ console.warn('[ns:m][link-check] failed', eLC?.message || eLC);
3834
3875
  }
3835
3876
  }
3836
3877
  res.statusCode = 200;
3837
3878
  res.end(code);
3838
3879
  }
3839
3880
  catch (e) {
3840
- try {
3841
- console.warn('[sfc-asm] error serving', req.url, e && e.message ? e.message : e);
3842
- }
3843
- catch { }
3881
+ console.warn('[sfc-asm] error serving', req.url, e && e.message ? e.message : e);
3844
3882
  res.statusCode = 500;
3845
3883
  res.end('export {}\n');
3846
3884
  }
@@ -3968,7 +4006,7 @@ export const piniaSymbol = p.piniaSymbol;
3968
4006
  `export const vShow = (__ensure().vShow);\n` +
3969
4007
  `export const createApp = (...a) => (__ensure().createApp)(...a);\n` +
3970
4008
  `export const registerElement = (...a) => (__ensure().registerElement)(...a);\n` +
3971
- `export const $navigateTo = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); try { if (!(g && g.Frame)) { const ns = (__ns_core_bridge && (__ns_core_bridge.__esModule && __ns_core_bridge.default ? __ns_core_bridge.default : (__ns_core_bridge.default || __ns_core_bridge))) || __ns_core_bridge || {}; if (ns) { if (!g.Frame && ns.Frame) g.Frame = ns.Frame; if (!g.Page && ns.Page) g.Page = ns.Page; if (!g.Application && (ns.Application||ns.app||ns.application)) g.Application = (ns.Application||ns.app||ns.application); } } } catch {} try { const hmrRealm = (g && g.__NS_HMR_REALM__) || 'unknown'; const hasTop = !!(g && g.Frame && g.Frame.topmost && g.Frame.topmost()); const top = hasTop ? g.Frame.topmost() : null; const ctor = top && top.constructor && top.constructor.name; } catch {} if (g && typeof g.__nsNavigateUsingApp === 'function') { try { return g.__nsNavigateUsingApp(...a); } catch (e) { try { console.error('[ns-rt] $navigateTo app navigator error', e); } catch {} throw e; } } try { console.error('[ns-rt] $navigateTo unavailable: app navigator missing'); } catch {} throw new Error('$navigateTo unavailable: app navigator missing'); } ;\n` +
4009
+ `export const $navigateTo = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); try { if (!(g && g.Frame)) { const ns = (__ns_core_bridge && (__ns_core_bridge.__esModule && __ns_core_bridge.default ? __ns_core_bridge.default : (__ns_core_bridge.default || __ns_core_bridge))) || __ns_core_bridge || {}; if (ns) { if (!g.Frame && ns.Frame) g.Frame = ns.Frame; if (!g.Page && ns.Page) g.Page = ns.Page; if (!g.Application && (ns.Application||ns.app||ns.application)) g.Application = (ns.Application||ns.app||ns.application); } } } catch {} try { const hmrRealm = (g && g.__NS_HMR_REALM__) || 'unknown'; const hasTop = !!(g && g.Frame && g.Frame.topmost && g.Frame.topmost()); const top = hasTop ? g.Frame.topmost() : null; const ctor = top && top.constructor && top.constructor.name; } catch {} if (g && typeof g.__nsNavigateUsingApp === 'function') { try { return g.__nsNavigateUsingApp(...a); } catch (e) { console.error('[ns-rt] $navigateTo app navigator error', e); throw e; } } console.error('[ns-rt] $navigateTo unavailable: app navigator missing'); throw new Error('$navigateTo unavailable: app navigator missing'); } ;\n` +
3972
4010
  `export const $navigateBack = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); const impl = (vm && (vm.$navigateBack || (vm.default && vm.default.$navigateBack))) || (rt && (rt.$navigateBack || (rt.runtimeHelpers && rt.runtimeHelpers.navigateBack))); let res; try { const via = (impl && (impl === (vm && vm.$navigateBack) || impl === (vm && vm.default && vm.default.$navigateBack))) ? 'vm' : (impl ? 'rt' : 'none'); } catch {} try { if (typeof impl === 'function') res = impl(...a); } catch {} try { const top = (g && g.Frame && g.Frame.topmost && g.Frame.topmost()); if (!res && top && top.canGoBack && top.canGoBack()) { res = top.goBack(); } } catch {} try { const hook = g && (g.__NS_HMR_ON_NAVIGATE_BACK || g.__NS_HMR_ON_BACK || g.__nsAttemptBackRemount); if (typeof hook === 'function') hook(); } catch {} return res; }\n` +
3973
4011
  `export const $showModal = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); const impl = (vm && (vm.$showModal || (vm.default && vm.default.$showModal))) || (rt && (rt.$showModal || (rt.runtimeHelpers && rt.runtimeHelpers.showModal))); try { if (typeof impl === 'function') return impl(...a); } catch (e) { } return undefined; }\n` +
3974
4012
  `export default {\n` +
@@ -4212,7 +4250,7 @@ export const piniaSymbol = p.piniaSymbol;
4212
4250
  ` }`,
4213
4251
  ` if (!__nsFirst[__nsKey]) __nsFirst[__nsKey] = __nsUrl;`,
4214
4252
  ` globalThis.__NS_CORE_EVAL_COUNT__ = (globalThis.__NS_CORE_EVAL_COUNT__ || 0) + 1;`,
4215
- `} } catch (e) { try { console.warn('[ns-core] instrumentation failed:', (e && e.message) || e); } catch {} }`,
4253
+ `} } catch (e) { console.warn('[ns-core] instrumentation failed:', (e && e.message) || e); }`,
4216
4254
  ].join('\n');
4217
4255
  // CJS/ESM interop shape — REGISTRATION side.
4218
4256
  //
@@ -4237,7 +4275,7 @@ export const piniaSymbol = p.piniaSymbol;
4237
4275
  ` const __nsSelfRaw = (typeof __ns_core_self_ns__ !== 'undefined') ? __ns_core_self_ns__ : { default: undefined };`,
4238
4276
  ` const __nsSelf = __nsShapeFn(__nsSelfRaw);`,
4239
4277
  ...registrationKeys.map((k) => ` __nsReg[${k}] = __nsSelf;`),
4240
- `} } catch (e) { try { console.warn('[ns-core] self-register failed:', (e && e.message) || e); } catch {} }`,
4278
+ `} } catch (e) { console.warn('[ns-core] self-register failed:', (e && e.message) || e); }`,
4241
4279
  ].join('\n');
4242
4280
  // Bind `import * as __ns_core_self_ns__` to the module's
4243
4281
  // own export namespace so the footer can stash it into
@@ -4285,10 +4323,7 @@ export const piniaSymbol = p.piniaSymbol;
4285
4323
  res.end(moduleCode);
4286
4324
  }
4287
4325
  catch (e) {
4288
- try {
4289
- console.warn('[ns-core-bridge] serve failed:', e?.message);
4290
- }
4291
- catch { }
4326
+ console.warn('[ns-core-bridge] serve failed:', e?.message);
4292
4327
  next();
4293
4328
  }
4294
4329
  });
@@ -4298,14 +4333,11 @@ export const piniaSymbol = p.piniaSymbol;
4298
4333
  const urlObj = new URL(req.url || '', 'http://localhost');
4299
4334
  if (!(urlObj.pathname === '/ns/entry-rt'))
4300
4335
  return next();
4301
- try {
4302
- if (verbose) {
4303
- const ra = req.socket?.remoteAddress;
4304
- const rp = req.socket?.remotePort;
4305
- console.log('[hmr-http] GET /ns/entry-rt from', ra + (rp ? ':' + rp : ''));
4306
- }
4336
+ if (verbose) {
4337
+ const ra = req.socket?.remoteAddress;
4338
+ const rp = req.socket?.remotePort;
4339
+ console.log('[hmr-http] GET /ns/entry-rt from', ra + (rp ? ':' + rp : ''));
4307
4340
  }
4308
- catch { }
4309
4341
  res.setHeader('Access-Control-Allow-Origin', '*');
4310
4342
  res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
4311
4343
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
@@ -4550,10 +4582,7 @@ export const piniaSymbol = p.piniaSymbol;
4550
4582
  }
4551
4583
  if (!transformed?.code) {
4552
4584
  if (verbose) {
4553
- try {
4554
- console.warn(`[sfc][serve] transform miss for`, fullSpec);
4555
- }
4556
- catch { }
4585
+ console.warn(`[sfc][serve] transform miss for`, fullSpec);
4557
4586
  }
4558
4587
  // Emit an erroring module to surface the failure at import site with helpful hints
4559
4588
  try {
@@ -4669,10 +4698,7 @@ export const piniaSymbol = p.piniaSymbol;
4669
4698
  }
4670
4699
  catch (eTplSelf) {
4671
4700
  if (verbose) {
4672
- try {
4673
- console.warn('[sfc][template][self-compile][fail]', fullSpec, eTplSelf?.message);
4674
- }
4675
- catch { }
4701
+ console.warn('[sfc][template][self-compile][fail]', fullSpec, eTplSelf?.message);
4676
4702
  }
4677
4703
  code = transformed.code || 'export {}\n';
4678
4704
  code = processTemplateVariantMinimal(code);
@@ -4839,10 +4865,7 @@ export const piniaSymbol = p.piniaSymbol;
4839
4865
  }
4840
4866
  catch (eTsVar) {
4841
4867
  if (verbose) {
4842
- try {
4843
- console.warn('[sfc][variant:script][babel-ts][fail]', fullSpec, eTsVar?.message);
4844
- }
4845
- catch { }
4868
+ console.warn('[sfc][variant:script][babel-ts][fail]', fullSpec, eTsVar?.message);
4846
4869
  }
4847
4870
  }
4848
4871
  }
@@ -4906,10 +4929,7 @@ export const piniaSymbol = p.piniaSymbol;
4906
4929
  const kind = isVariant ? `variant:${variantType || 'unknown'}` : 'full';
4907
4930
  const sig = `// [sfc] kind=${kind} path=${importerPath} len=${code.length} default=${hasDefault} wrapped=${false}\n`;
4908
4931
  if (verbose) {
4909
- try {
4910
- console.log(`[sfc][serve] ${fullSpec} kind=${kind} default=${hasDefault} bytes=${code.length}`);
4911
- }
4912
- catch { }
4932
+ console.log(`[sfc][serve] ${fullSpec} kind=${kind} default=${hasDefault} bytes=${code.length}`);
4913
4933
  }
4914
4934
  // Ensure script variants always provide a default export if they declare a component
4915
4935
  if (!hasDefault) {
@@ -4978,16 +4998,10 @@ export const piniaSymbol = p.piniaSymbol;
4978
4998
  // 6) Object property forms (rare in template output) render: (...) => {}
4979
4999
  const hasRender = /export\s+function\s+render\s*\(/.test(templateCode) || /(?:^|\n)\s*function\s+render\s*\(/.test(templateCode) || /export\s+(?:const|let|var)\s+render\s*=/.test(templateCode) || /(?:^|\n)\s*(?:const|let|var)\s+render\s*=/.test(templateCode) || /\brender\s*[:=]\s*/.test(templateCode) || /export\s*\{\s*render\s*(?:as\s*render)?\s*\}/.test(templateCode);
4980
5000
  if (hasRender && verbose) {
4981
- try {
4982
- console.log('[sfc-meta] detected render for', base);
4983
- }
4984
- catch { }
5001
+ console.log('[sfc-meta] detected render for', base);
4985
5002
  }
4986
5003
  else if (!hasRender && verbose) {
4987
- try {
4988
- console.warn('[sfc-meta] render NOT detected for', base);
4989
- }
4990
- catch { }
5004
+ console.warn('[sfc-meta] render NOT detected for', base);
4991
5005
  }
4992
5006
  const hash = createHash('md5').update(base).digest('hex').slice(0, 8);
4993
5007
  const payload = {
@@ -5121,10 +5135,7 @@ export const piniaSymbol = p.piniaSymbol;
5121
5135
  }
5122
5136
  catch (eScript) {
5123
5137
  if (verbose) {
5124
- try {
5125
- console.warn('[sfc-asm][compileScript] failed', base, eScript?.message);
5126
- }
5127
- catch { }
5138
+ console.warn('[sfc-asm][compileScript] failed', base, eScript?.message);
5128
5139
  }
5129
5140
  // Retry without inlineTemplate
5130
5141
  try {
@@ -5140,10 +5151,7 @@ export const piniaSymbol = p.piniaSymbol;
5140
5151
  }
5141
5152
  catch (eNoInline) {
5142
5153
  if (verbose) {
5143
- try {
5144
- console.warn('[sfc-asm][compileScript][no-inline-fallback] failed', base, eNoInline?.message);
5145
- }
5146
- catch { }
5154
+ console.warn('[sfc-asm][compileScript][no-inline-fallback] failed', base, eNoInline?.message);
5147
5155
  }
5148
5156
  }
5149
5157
  }
@@ -5174,10 +5182,7 @@ export const piniaSymbol = p.piniaSymbol;
5174
5182
  }
5175
5183
  catch (eNoInline) {
5176
5184
  if (verbose) {
5177
- try {
5178
- console.warn('[sfc-asm][compileScript][no-inline-fallback] failed', base, eNoInline?.message);
5179
- }
5180
- catch { }
5185
+ console.warn('[sfc-asm][compileScript][no-inline-fallback] failed', base, eNoInline?.message);
5181
5186
  }
5182
5187
  }
5183
5188
  }
@@ -5200,20 +5205,14 @@ export const piniaSymbol = p.piniaSymbol;
5200
5205
  });
5201
5206
  compiledTplCode = (ct && (ct.code || '')) || '';
5202
5207
  if (ct?.errors?.length && verbose) {
5203
- try {
5204
- console.warn('[sfc-asm][compileTemplate][errors]', base, ct.errors);
5205
- }
5206
- catch { }
5208
+ console.warn('[sfc-asm][compileTemplate][errors]', base, ct.errors);
5207
5209
  }
5208
5210
  }
5209
5211
  }
5210
5212
  catch (eTpl) {
5211
5213
  templateErr = eTpl;
5212
5214
  if (verbose) {
5213
- try {
5214
- console.warn('[sfc-asm][compileTemplate] failed', base, eTpl?.message);
5215
- }
5216
- catch { }
5215
+ console.warn('[sfc-asm][compileTemplate] failed', base, eTpl?.message);
5217
5216
  }
5218
5217
  // Fallback: use the variant-transformed template code if available
5219
5218
  try {
@@ -5276,10 +5275,7 @@ export const piniaSymbol = p.piniaSymbol;
5276
5275
  }
5277
5276
  catch (eExtract) {
5278
5277
  if (verbose) {
5279
- try {
5280
- console.warn('[sfc-asm][extractTemplateRender] failed', base, eExtract?.message);
5281
- }
5282
- catch { }
5278
+ console.warn('[sfc-asm][extractTemplateRender] failed', base, eExtract?.message);
5283
5279
  }
5284
5280
  }
5285
5281
  }
@@ -5357,10 +5353,7 @@ export const piniaSymbol = p.piniaSymbol;
5357
5353
  }
5358
5354
  catch (eTs) {
5359
5355
  if (verbose) {
5360
- try {
5361
- console.warn('[sfc-asm][babel-ts][fail]', base, eTs?.message);
5362
- }
5363
- catch { }
5356
+ console.warn('[sfc-asm][babel-ts][fail]', base, eTs?.message);
5364
5357
  }
5365
5358
  }
5366
5359
  // Hoist imports + strip residual TS via AST
@@ -5370,18 +5363,12 @@ export const piniaSymbol = p.piniaSymbol;
5370
5363
  importLines = astRes.imports;
5371
5364
  scriptTransformed = astRes.body;
5372
5365
  if (astRes.diagnostics.length && verbose) {
5373
- try {
5374
- console.warn('[sfc-asm][ast]', base, astRes.diagnostics.join('; '));
5375
- }
5376
- catch { }
5366
+ console.warn('[sfc-asm][ast]', base, astRes.diagnostics.join('; '));
5377
5367
  }
5378
5368
  }
5379
5369
  catch (eAst) {
5380
5370
  if (verbose) {
5381
- try {
5382
- console.warn('[sfc-asm][ast][fail]', base, eAst?.message);
5383
- }
5384
- catch { }
5371
+ console.warn('[sfc-asm][ast][fail]', base, eAst?.message);
5385
5372
  }
5386
5373
  }
5387
5374
  // Ensure renderDecl ends with closing brace ONLY for function declaration forms
@@ -6179,6 +6166,7 @@ export const piniaSymbol = p.piniaSymbol;
6179
6166
  flavor: ACTIVE_STRATEGY.flavor,
6180
6167
  modules: ctx.modules,
6181
6168
  getModuleById: (id) => server.moduleGraph.getModuleById(id),
6169
+ verbose,
6182
6170
  });
6183
6171
  for (const mod of graphTargets) {
6184
6172
  if (!mod?.id)
@@ -6259,6 +6247,12 @@ export const piniaSymbol = p.piniaSymbol;
6259
6247
  getModuleById: (id) => server.moduleGraph.getModuleById(id),
6260
6248
  getModulesByFile: (targetFile) => server.moduleGraph.getModulesByFile?.(targetFile),
6261
6249
  });
6250
+ if (verbose) {
6251
+ console.info(`[ns-hmr-diag][server] hot-update file=${file} isHtml=${isHtml} isTs=${isTs} ctxModules=${Array.from(ctx.modules || []).length} hotUpdateRoots=${angularHotUpdateRoots.length} (${angularHotUpdateRoots
6252
+ .map((m) => m?.id ?? '(none)')
6253
+ .slice(0, 8)
6254
+ .join(', ')}${angularHotUpdateRoots.length > 8 ? ', …' : ''})`);
6255
+ }
6262
6256
  if (!(isHtml || isTs))
6263
6257
  return;
6264
6258
  updateMetrics.invalidated += angularHotUpdateRoots.length;
@@ -6343,6 +6337,9 @@ export const piniaSymbol = p.piniaSymbol;
6343
6337
  // narrowing wins (saves re-transform work on the server).
6344
6338
  // The eviction set always includes importers so V8 re-fetches
6345
6339
  // and re-binds them.
6340
+ if (verbose) {
6341
+ console.info(`[ns-hmr-diag][server] angularNeedsTransitive=${angularNeedsTransitive} (file=${path.basename(file)})`);
6342
+ }
6346
6343
  let transitiveImporters = [];
6347
6344
  try {
6348
6345
  transitiveImporters = collectAngularTransitiveImportersForInvalidation({
@@ -6350,6 +6347,9 @@ export const piniaSymbol = p.piniaSymbol;
6350
6347
  isExcluded: (id) => id.includes('/node_modules/'),
6351
6348
  maxDepth: 16,
6352
6349
  });
6350
+ if (verbose) {
6351
+ console.info(`[ns-hmr-diag][server] transitiveImporters count=${transitiveImporters.length} firstN=`, transitiveImporters.slice(0, 16).map((m) => m?.id ?? '(none)'));
6352
+ }
6353
6353
  if (angularNeedsTransitive) {
6354
6354
  updateMetrics.invalidated += transitiveImporters.length;
6355
6355
  for (const mod of transitiveImporters) {
@@ -6463,14 +6463,23 @@ export const piniaSymbol = p.piniaSymbol;
6463
6463
  });
6464
6464
  }
6465
6465
  catch (error) {
6466
- if (verbose)
6467
- console.warn('[hmr-ws][angular] eviction set computation failed', error);
6466
+ if (verbose) {
6467
+ console.warn('[ns-hmr-diag][server] eviction set computation failed', error);
6468
+ }
6468
6469
  }
6469
6470
  if (verbose) {
6470
- console.log('[hmr-ws][angular] eviction set', {
6471
- count: evictPaths.length,
6472
- importerEntry: bootstrapEntryRel,
6473
- });
6471
+ try {
6472
+ const tsRel = rel.replace(/\.(html|htm)$/i, '.ts');
6473
+ const jsRel = rel.replace(/\.(html|htm)$/i, '.js');
6474
+ const containsRelatedTs = evictPaths.some((u) => u.endsWith(tsRel));
6475
+ const containsRelatedJs = evictPaths.some((u) => u.endsWith(jsRel));
6476
+ const sample = evictPaths.slice(0, 32);
6477
+ console.info(`[ns-hmr-diag][server] evict-set count=${evictPaths.length} importerEntry=${bootstrapEntryRel ?? '(none)'} containsRelatedTs=${containsRelatedTs} containsRelatedJs=${containsRelatedJs} firstN=`, sample);
6478
+ if (evictPaths.length > sample.length) {
6479
+ console.info(`[ns-hmr-diag][server] evict-set hidden=${evictPaths.length - sample.length} (showed first ${sample.length})`);
6480
+ }
6481
+ }
6482
+ catch { }
6474
6483
  }
6475
6484
  const msg = {
6476
6485
  type: 'ns:angular-update',
@@ -6713,7 +6722,7 @@ if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
6713
6722
  if (typeof spec === 'string' && /^(?:https?:)\/\//.test(spec)) {
6714
6723
  const err = new Error('[ns-hmr][require-guard] require of URL: ' + spec + ' via ' + label);
6715
6724
  const stack = err.stack || '';
6716
- try { console.error(err.message + '\n' + stack); } catch {}
6725
+ console.error(err.message + '\n' + stack);
6717
6726
  try { g.__NS_REQUIRE_GUARD_LAST__ = { spec, stack, label, ts: Date.now() }; } catch {}
6718
6727
  }
6719
6728
  } catch {}