@nativescript/vite 1.0.5 → 1.0.6-next.1

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 (38) hide show
  1. package/bin/cli.cjs +0 -0
  2. package/configuration/angular.js +1 -1
  3. package/configuration/angular.js.map +1 -1
  4. package/configuration/base.js +2 -2
  5. package/configuration/base.js.map +1 -1
  6. package/configuration/react.js +1 -1
  7. package/configuration/react.js.map +1 -1
  8. package/configuration/solid.js +1 -1
  9. package/configuration/solid.js.map +1 -1
  10. package/configuration/typescript.js +1 -1
  11. package/configuration/typescript.js.map +1 -1
  12. package/configuration/vue.js +1 -1
  13. package/configuration/vue.js.map +1 -1
  14. package/helpers/css-tree.js +1 -0
  15. package/helpers/css-tree.js.map +1 -1
  16. package/helpers/main-entry.js +5 -50
  17. package/helpers/main-entry.js.map +1 -1
  18. package/hmr/client/index.js +398 -146
  19. package/hmr/client/index.js.map +1 -1
  20. package/hmr/client/utils.d.ts +2 -0
  21. package/hmr/client/utils.js +179 -25
  22. package/hmr/client/utils.js.map +1 -1
  23. package/hmr/entry-runtime.js +1 -18
  24. package/hmr/entry-runtime.js.map +1 -1
  25. package/hmr/frameworks/vue/client/index.js +5 -1
  26. package/hmr/frameworks/vue/client/index.js.map +1 -1
  27. package/hmr/server/vite-plugin.js +6 -66
  28. package/hmr/server/vite-plugin.js.map +1 -1
  29. package/hmr/server/websocket.js +173 -52
  30. package/hmr/server/websocket.js.map +1 -1
  31. package/hmr/shared/runtime/http-only-boot.js +3 -20
  32. package/hmr/shared/runtime/http-only-boot.js.map +1 -1
  33. package/hmr/shared/vendor/manifest.js +5 -8
  34. package/hmr/shared/vendor/manifest.js.map +1 -1
  35. package/package.json +10 -1
  36. package/hmr/shared/runtime/hooks.d.ts +0 -17
  37. package/hmr/shared/runtime/hooks.js +0 -68
  38. package/hmr/shared/runtime/hooks.js.map +0 -1
@@ -1045,7 +1045,7 @@ function processCodeForDevice(code, isVitePreBundled) {
1045
1045
  'const __ANDROID__ = globalThis.__ANDROID__ !== undefined ? globalThis.__ANDROID__ : false;',
1046
1046
  'const __IOS__ = globalThis.__IOS__ !== undefined ? globalThis.__IOS__ : false;',
1047
1047
  'const __VISIONOS__ = globalThis.__VISIONOS__ !== undefined ? globalThis.__VISIONOS__ : false;',
1048
- 'const __APPLE__ = globalThis.__APPLE__ !== undefined ? globalThis.__APPLE__ : (__IOS__ || __VISIONOS__);',
1048
+ 'const __APPLE__ = globalThis.__APPLE__ !== undefined ? globalThis.__APPLE__ : false;',
1049
1049
  'const __DEV__ = globalThis.__DEV__ !== undefined ? globalThis.__DEV__ : false;',
1050
1050
  'const __COMMONJS__ = globalThis.__COMMONJS__ !== undefined ? globalThis.__COMMONJS__ : false;',
1051
1051
  'const __NS_WEBPACK__ = globalThis.__NS_WEBPACK__ !== undefined ? globalThis.__NS_WEBPACK__ : true;',
@@ -1139,16 +1139,6 @@ function processCodeForDevice(code, isVitePreBundled) {
1139
1139
  // This allows the rewriter to see and canonicalize '/node_modules/.vite/deps/*' specifiers back
1140
1140
  // to their package ids (e.g., '@nativescript/firebase-core') and generate require-based bindings
1141
1141
  // so named imports like `{ firebase }` are preserved as const bindings.
1142
- //
1143
- // Some upstream transforms can emit a multiline form:
1144
- // import { x } from
1145
- // "/node_modules/.vite/deps/...";
1146
- // If we don't normalize it, later stripping of naked string-only lines can leave
1147
- // an invalid `import ... from` statement.
1148
- try {
1149
- result = result.replace(/(^|\n)([\t ]*import\s+[^;]*?\s+from)\s*\n\s*("\/?node_modules\/\.vite\/deps\/[^"\n]+"\s*;?\s*)/gm, (_m, p1, p2, p3) => `${p1}${p2} ${p3}`);
1150
- }
1151
- catch { }
1152
1142
  result = ensureNativeScriptModuleBindings(result);
1153
1143
  // Repair any accidental "import ... = expr" assignments that may have slipped in.
1154
1144
  try {
@@ -2586,16 +2576,6 @@ function createHmrWebSocketPlugin(opts) {
2586
2576
  return;
2587
2577
  }
2588
2578
  spec = spec.replace(/[?#].*$/, '');
2589
- // Accept path-based HMR cache-busting: /ns/m/__ns_hmr__/<tag>/<real-spec>
2590
- // The iOS HTTP ESM loader canonicalizes cache keys by stripping query params,
2591
- // so we must carry the cache-buster in the path.
2592
- try {
2593
- const m = spec.match(/^\/?__ns_hmr__\/[^\/]+(\/.*)?$/);
2594
- if (m) {
2595
- spec = m[1] || '/';
2596
- }
2597
- }
2598
- catch { }
2599
2579
  // Normalize absolute filesystem paths back to project-relative ids (e.g. /src/app.ts)
2600
2580
  try {
2601
2581
  const projectRoot = (server.config?.root || process.cwd());
@@ -2682,38 +2662,36 @@ function createHmrWebSocketPlugin(opts) {
2682
2662
  catch { }
2683
2663
  }
2684
2664
  }
2685
- // Post-transform: inject cache-busting version for all internal /ns/m/* imports to avoid stale module reuse on device.
2686
- // IMPORTANT: use PATH-based busting (not query) because the iOS HTTP ESM loader strips query params
2687
- // when computing module cache keys.
2665
+ // RAW BYPASS: allow fetching original Vite transform before sanitation for diffing/debugging
2666
+ if (urlObj.searchParams.get('raw') === '1') {
2667
+ const raw = transformed?.code || 'export {}\n';
2668
+ try {
2669
+ const h = createHash('sha1').update(raw).digest('hex');
2670
+ res.setHeader('X-NS-Source-Hash', h);
2671
+ res.statusCode = 200;
2672
+ res.end(`// [hash:${h}] bytes=${raw.length} raw=1 m path=${spec}\n` + raw);
2673
+ }
2674
+ catch {
2675
+ res.statusCode = 200;
2676
+ res.end(`// [raw=1] m path=${spec}\n` + raw);
2677
+ }
2678
+ return;
2679
+ }
2680
+ // Post-transform: inject cache-busting version for all internal /ns/m/* imports to avoid stale module reuse on device
2688
2681
  try {
2689
2682
  if (transformed?.code) {
2690
2683
  const ver = Number(global.graphVersion || graphVersion || 0);
2691
2684
  let code = transformed.code;
2692
- const prefix = `/ns/m/__ns_hmr__/v${ver}`;
2693
- const rewrite = (p) => {
2694
- try {
2695
- if (!p || typeof p !== 'string')
2696
- return p;
2697
- if (!p.startsWith('/ns/m/'))
2698
- return p;
2699
- if (p.startsWith('/ns/m/__ns_hmr__/'))
2700
- return p;
2701
- return prefix + p.slice('/ns/m'.length);
2702
- }
2703
- catch {
2704
- return p;
2705
- }
2706
- };
2707
2685
  // 1) Static imports: import ... from "/ns/m/..."
2708
- code = code.replace(/(from\s*["'])(\/ns\/m\/[^"'?]+)(["'])/g, (_m, a, p, b) => `${a}${rewrite(p)}${b}`);
2686
+ code = code.replace(/(from\s*["'])(\/ns\/m\/[^"'?]+)(["'])/g, `$1$2?v=${ver}$3`);
2709
2687
  // 2) Side-effect imports: import "/ns/m/..."
2710
- code = code.replace(/(import\s*(?!\()\s*["'])(\/ns\/m\/[^"'?]+)(["'])/g, (_m, a, p, b) => `${a}${rewrite(p)}${b}`);
2688
+ code = code.replace(/(import\s*(?!\()\s*["'])(\/ns\/m\/[^"'?]+)(["'])/g, `$1$2?v=${ver}$3`);
2711
2689
  // 3) Dynamic imports: import("/ns/m/...")
2712
- code = code.replace(/(import\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*\))/g, (_m, a, p, b) => `${a}${rewrite(p)}${b}`);
2690
+ code = code.replace(/(import\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*\))/g, `$1$2?v=${ver}$3`);
2713
2691
  // 4) new URL("/ns/m/...", import.meta.url)
2714
- code = code.replace(/(new\s+URL\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*,\s*import\.meta\.url\s*\))/g, (_m, a, p, b) => `${a}${rewrite(p)}${b}`);
2692
+ code = code.replace(/(new\s+URL\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*,\s*import\.meta\.url\s*\))/g, `$1$2?v=${ver}$3`);
2715
2693
  // 5) __ns_import(new URL('/ns/m/...', import.meta.url).href)
2716
- code = code.replace(/(new\s+URL\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*,\s*import\.meta\.url\s*\)\.href)/g, (_m, a, p, b) => `${a}${rewrite(p)}${b}`);
2694
+ code = code.replace(/(new\s+URL\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*,\s*import\.meta\.url\s*\)\.href)/g, `$1$2?v=${ver}$3`);
2717
2695
  transformed.code = code;
2718
2696
  // TypeScript-specific graph population: when TS flavor is active
2719
2697
  // and this is an application module under the virtual app root,
@@ -2841,10 +2819,16 @@ export const piniaSymbol = p.piniaSymbol;
2841
2819
  catch { }
2842
2820
  }
2843
2821
  if (!transformed?.code) {
2844
- // Emit a module that throws with context for easier on-device debugging
2822
+ // Enhanced diagnostics: emit a module that throws with context for easier on-device debugging
2845
2823
  try {
2846
2824
  const tried = Array.from(new Set(candidates)).slice(0, 12);
2847
- const out = `// [ns:m] transform miss path=${spec} tried=${tried.length}\n` + `throw new Error(${JSON.stringify(`[ns/m] transform failed for ${spec} (tried ${tried.length} candidates).`)});\nexport {};\n`;
2825
+ let out = `// [ns:m] transform miss path=${spec} tried=${tried.length}\n` + `throw new Error(${JSON.stringify(`[ns/m] transform failed for ${spec} (tried ${tried.length} candidates). Use ?raw=1 to inspect Vite output.`)});\nexport {};\n`;
2826
+ try {
2827
+ const h = createHash('sha1').update(out).digest('hex');
2828
+ res.setHeader('X-NS-Source-Hash', h);
2829
+ out = `// [hash:${h}] bytes=${out.length}\n` + out;
2830
+ }
2831
+ catch { }
2848
2832
  res.statusCode = 404;
2849
2833
  res.end(out);
2850
2834
  return;
@@ -3052,6 +3036,11 @@ export const piniaSymbol = p.piniaSymbol;
3052
3036
  }
3053
3037
  catch { }
3054
3038
  }
3039
+ try {
3040
+ const h = createHash('sha1').update(code).digest('hex');
3041
+ res.setHeader('X-NS-Source-Hash', h);
3042
+ }
3043
+ catch { }
3055
3044
  res.statusCode = 200;
3056
3045
  res.end(code);
3057
3046
  }
@@ -3185,9 +3174,9 @@ export const piniaSymbol = p.piniaSymbol;
3185
3174
  `export const vShow = (__ensure().vShow);\n` +
3186
3175
  `export const createApp = (...a) => (__ensure().createApp)(...a);\n` +
3187
3176
  `export const registerElement = (...a) => (__ensure().registerElement)(...a);\n` +
3188
- `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` +
3189
- `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` +
3190
- `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` +
3177
+ `export const $navigateTo = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); if (g.__NS_VERBOSE_RT_NAV__ || g.__NS_DEV_LOGS__) console.log('[ns-rt] $navigateTo invoked'); 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; if (g.__NS_VERBOSE_RT_NAV__ || g.__NS_DEV_LOGS__) { console.log('[ns-rt] $navigateTo(single-path)', { via: 'app', rtRealm: __RT_REALM_TAG, hmrRealm, hasTop, topCtor: ctor }); } } 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` +
3178
+ `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'); if (globalThis && (globalThis.__NS_VERBOSE_RT_NAV__ || globalThis.__NS_DEV_LOGS__)) { console.log('[ns-rt] $navigateBack', { via }); } } 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` +
3179
+ `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) { try { if (g && (g.__NS_VERBOSE_RT_NAV__ || g.__NS_DEV_LOGS__)) { console.error('[ns-rt] $showModal error', e); } } catch {} } return undefined; }\n` +
3191
3180
  `export default {\n` +
3192
3181
  ` defineComponent, resolveComponent, createVNode, createTextVNode, createCommentVNode,\n` +
3193
3182
  ` Fragment, Teleport, Transition, TransitionGroup, KeepAlive, Suspense, withCtx, openBlock,\n` +
@@ -3272,6 +3261,12 @@ export const piniaSymbol = p.piniaSymbol;
3272
3261
  `const __core = new Proxy({}, { get(_t, p){ if (p === 'default') return __core; if (p === Symbol.toStringTag) return 'Module'; try { const v = g[p]; if (v !== undefined) return v; } catch {} try { const vc = __getVendorCore(); return vc ? vc[p] : undefined; } catch {} return undefined; } });\n` +
3273
3262
  `// Default export: namespace-like proxy\n` +
3274
3263
  `export default __core;\n`;
3264
+ try {
3265
+ const h = createHash('sha1').update(code).digest('hex');
3266
+ res.setHeader('X-NS-Source-Hash', h);
3267
+ code = `// [hash:${h}] bytes=${code.length} core\n` + code;
3268
+ }
3269
+ catch { }
3275
3270
  res.statusCode = 200;
3276
3271
  res.end(code);
3277
3272
  }
@@ -3308,6 +3303,12 @@ export const piniaSymbol = p.piniaSymbol;
3308
3303
  catch (e) {
3309
3304
  content = 'export default async function start(){ console.error("[/ns/entry-rt] not found"); }\n';
3310
3305
  }
3306
+ try {
3307
+ const h = createHash('sha1').update(content).digest('hex');
3308
+ res.setHeader('X-NS-Source-Hash', h);
3309
+ content = `// [hash:${h}] bytes=${content.length} entry-rt\n` + content;
3310
+ }
3311
+ catch { }
3311
3312
  res.statusCode = 200;
3312
3313
  res.end(content);
3313
3314
  }
@@ -3375,7 +3376,19 @@ export const piniaSymbol = p.piniaSymbol;
3375
3376
  ` const startEntry = (__mod && (__mod.default || __mod));\n` +
3376
3377
  ` try { await startEntry({ origin, main, ver: __ns_graph_ver, verbose: !!__VERBOSE__ }); if (__VERBOSE__) console.info('[ns-entry][wrapper] startEntry() resolved'); } catch (e) { console.error('[ns-entry][wrapper] startEntry() failed', e && (e.message||e)); throw e; }\n` +
3377
3378
  `})();\n`;
3378
- code = code + `\n//# sourceURL=${origin}/ns/entry`;
3379
+ try {
3380
+ const h = createHash('sha1').update(code).digest('hex');
3381
+ res.setHeader('X-NS-Source-Hash', h);
3382
+ const banner = `// [hash:${h}] bytes=${code.length} entry\n`;
3383
+ if (verbose) {
3384
+ try {
3385
+ console.log('[hmr-http] reply /ns/entry hash', h, 'bytes', code.length);
3386
+ }
3387
+ catch { }
3388
+ }
3389
+ code = banner + code + `\n//# sourceURL=${origin}/ns/entry`;
3390
+ }
3391
+ catch { }
3379
3392
  res.statusCode = 200;
3380
3393
  res.end(code);
3381
3394
  }
@@ -3522,7 +3535,13 @@ export const piniaSymbol = p.piniaSymbol;
3522
3535
  // Emit an erroring module to surface the failure at import site with helpful hints
3523
3536
  try {
3524
3537
  const tried = candidates.slice(0, 8);
3525
- const out = `// [sfc] transform miss kind=full path=${fullSpec.replace(/\n/g, '')} tried=${tried.length}\n` + `throw new Error(${JSON.stringify('[ns/sfc] transform failed for full SFC: ' + fullSpec + ' (tried ' + tried.length + ')')});\nexport {}\n`;
3538
+ let out = `// [sfc] transform miss kind=full path=${fullSpec.replace(/\n/g, '')} tried=${tried.length}\n` + `throw new Error(${JSON.stringify('[ns/sfc] transform failed for full SFC: ' + fullSpec + ' (tried ' + tried.length + ')')});\nexport {}\n`;
3539
+ try {
3540
+ const h = createHash('sha1').update(out).digest('hex');
3541
+ res.setHeader('X-NS-Source-Hash', h);
3542
+ out = `// [hash:${h}] bytes=${out.length}\n` + out;
3543
+ }
3544
+ catch { }
3526
3545
  res.statusCode = 404;
3527
3546
  res.end(out);
3528
3547
  return;
@@ -3541,7 +3560,13 @@ export const piniaSymbol = p.piniaSymbol;
3541
3560
  catch { }
3542
3561
  if (!transformed?.code) {
3543
3562
  try {
3544
- const out = `// [sfc] transform miss kind=variant path=${fullSpec.replace(/\n/g, '')}\n` + `throw new Error(${JSON.stringify('[ns/sfc] transform failed for variant: ' + fullSpec)});\nexport {}\n`;
3563
+ let out = `// [sfc] transform miss kind=variant path=${fullSpec.replace(/\n/g, '')}\n` + `throw new Error(${JSON.stringify('[ns/sfc] transform failed for variant: ' + fullSpec)});\nexport {}\n`;
3564
+ try {
3565
+ const h = createHash('sha1').update(out).digest('hex');
3566
+ res.setHeader('X-NS-Source-Hash', h);
3567
+ out = `// [hash:${h}] bytes=${out.length}\n` + out;
3568
+ }
3569
+ catch { }
3545
3570
  res.statusCode = 404;
3546
3571
  res.end(out);
3547
3572
  return;
@@ -3560,6 +3585,31 @@ export const piniaSymbol = p.piniaSymbol;
3560
3585
  res.end(`${sig}export {}\n`);
3561
3586
  return;
3562
3587
  }
3588
+ // RAW BYPASS: serve unsanitized transform output (or direct transform of candidate) when ?raw=1
3589
+ const rawBypass = urlObj.searchParams.get('raw') === '1';
3590
+ if (rawBypass) {
3591
+ try {
3592
+ let rawOut = transformed.code || 'export {}\n';
3593
+ try {
3594
+ const h = createHash('sha1').update(rawOut).digest('hex');
3595
+ res.setHeader('X-NS-Source-Hash', h);
3596
+ rawOut = `// [hash:${h}] bytes=${rawOut.length} raw=1 sfc kind=${isVariant ? 'variant' : 'full'}\n` + rawOut;
3597
+ }
3598
+ catch { }
3599
+ res.statusCode = 200;
3600
+ res.end(`// [sfc] raw bypass path=${fullSpec.replace(/\n/g, '')}\n` + rawOut);
3601
+ return;
3602
+ }
3603
+ catch (eRaw) {
3604
+ try {
3605
+ console.warn('[sfc][raw] failed', fullSpec, eRaw?.message);
3606
+ }
3607
+ catch { }
3608
+ res.statusCode = 200;
3609
+ res.end('// [sfc] raw bypass error\nexport {}\n');
3610
+ return;
3611
+ }
3612
+ }
3563
3613
  let code = transformed.code;
3564
3614
  // Prepend guard to capture any URL-based require attempts
3565
3615
  code = REQUIRE_GUARD_SNIPPET + code;
@@ -3887,6 +3937,29 @@ export const piniaSymbol = p.piniaSymbol;
3887
3937
  code += `\nexport default (typeof __ns_sfc__ !== "undefined" ? __ns_sfc__ : (typeof _sfc_main !== "undefined" ? _sfc_main : undefined));`;
3888
3938
  }
3889
3939
  }
3940
+ try {
3941
+ const h = createHash('sha1').update(code).digest('hex');
3942
+ res.setHeader('X-NS-Source-Hash', h);
3943
+ code = `// [hash:${h}] bytes=${code.length}\n` + code;
3944
+ }
3945
+ catch { }
3946
+ // Diagnostic: when serving full SFCs, emit a short snippet and search for common compiled patterns
3947
+ try {
3948
+ if (!isVariant && verbose) {
3949
+ const snippet = code.slice(0, 1024).replace(/\n/g, '\\n');
3950
+ const hasExportHelper = /_export_sfc\s*\(/.test(code);
3951
+ const hasSfcMain = /_sfc_main\b/.test(code);
3952
+ const hasNsReal = /__ns_real__\b/.test(code);
3953
+ console.log(`[sfc][serve][diag] ${fullSpec} snippet=${snippet}`);
3954
+ console.log(`[sfc][serve][diag] patterns exportHelper=${hasExportHelper} sfcMain=${hasSfcMain} mergedVar=${hasNsReal}`);
3955
+ }
3956
+ }
3957
+ catch (e) {
3958
+ try {
3959
+ console.warn('[sfc][serve][diag] print failed', e);
3960
+ }
3961
+ catch { }
3962
+ }
3890
3963
  res.statusCode = 200;
3891
3964
  res.end(sig + code);
3892
3965
  }
@@ -4031,6 +4104,48 @@ export const piniaSymbol = p.piniaSymbol;
4031
4104
  const ver = String(verFromPath || graphVersion || Date.now());
4032
4105
  const scriptUrl = `${origin}/ns/sfc/${ver}${base}?vue&type=script`;
4033
4106
  const templateCode = templateR?.code || '';
4107
+ // RAW BYPASS: return unsanitized compiled SFC or script/template when ?raw=1 for differential debugging
4108
+ const rawBypass = urlObj.searchParams.get('raw') === '1';
4109
+ if (rawBypass) {
4110
+ try {
4111
+ let rawOut = '';
4112
+ if (fullR?.code) {
4113
+ rawOut = fullR.code;
4114
+ }
4115
+ else if (scriptR?.code || templateR?.code) {
4116
+ // Reconstruct minimal module if only variants available
4117
+ const parts = [];
4118
+ if (scriptR?.code)
4119
+ parts.push('// [raw][script]\n' + scriptR.code);
4120
+ if (templateR?.code)
4121
+ parts.push('// [raw][template]\n' + templateR.code);
4122
+ rawOut = parts.join('\n');
4123
+ }
4124
+ if (!rawOut) {
4125
+ rawOut = 'export {}\n';
4126
+ }
4127
+ try {
4128
+ const h = createHash('sha1').update(rawOut).digest('hex');
4129
+ res.setHeader('X-NS-Source-Hash', h);
4130
+ rawOut =
4131
+ `// [hash:${h}] bytes=${rawOut.length} raw=1 asm
4132
+ ` + rawOut;
4133
+ }
4134
+ catch { }
4135
+ res.statusCode = 200;
4136
+ res.end(`// [sfc-asm] ${base} (raw bypass)\n` + rawOut);
4137
+ return;
4138
+ }
4139
+ catch (eRaw) {
4140
+ try {
4141
+ console.warn('[sfc-asm][raw] failed', base, eRaw?.message);
4142
+ }
4143
+ catch { }
4144
+ res.statusCode = 200;
4145
+ res.end('// [sfc-asm] raw bypass error\nexport {}\n');
4146
+ return;
4147
+ }
4148
+ }
4034
4149
  // INLINE-FIRST assembler: compile SFC source into a self-contained ESM module (enhanced diagnostics)
4035
4150
  try {
4036
4151
  const root = server.config?.root || process.cwd();
@@ -4608,6 +4723,12 @@ export const piniaSymbol = p.piniaSymbol;
4608
4723
  catch { }
4609
4724
  if (!/export\s+default\s+__ns_sfc__/.test(inlineCode2) && /__ns_sfc__/.test(inlineCode2))
4610
4725
  inlineCode2 += '\nexport default __ns_sfc__';
4726
+ try {
4727
+ const h = createHash('sha1').update(inlineCode2).digest('hex');
4728
+ res.setHeader('X-NS-Source-Hash', h);
4729
+ inlineCode2 = `// [hash:${h}] bytes=${inlineCode2.length}\n` + inlineCode2;
4730
+ }
4731
+ catch { }
4611
4732
  res.statusCode = 200;
4612
4733
  res.end(inlineCode2);
4613
4734
  return;