@nativescript/vite 0.0.2 → 1.0.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 (71) hide show
  1. package/README.md +37 -0
  2. package/bin/cli.cjs +32 -0
  3. package/configuration/angular.js +66 -175
  4. package/configuration/angular.js.map +1 -1
  5. package/configuration/base.js +18 -21
  6. package/configuration/base.js.map +1 -1
  7. package/configuration/javascript.js +6 -5
  8. package/configuration/javascript.js.map +1 -1
  9. package/configuration/typescript.js +6 -5
  10. package/configuration/typescript.js.map +1 -1
  11. package/helpers/{angular-linker.js → angular/angular-linker.js} +27 -19
  12. package/helpers/angular/angular-linker.js.map +1 -0
  13. package/helpers/angular/shared-linker.d.ts +4 -0
  14. package/helpers/angular/shared-linker.js +39 -0
  15. package/helpers/angular/shared-linker.js.map +1 -0
  16. package/helpers/angular/util.d.ts +1 -0
  17. package/helpers/angular/util.js +67 -0
  18. package/helpers/angular/util.js.map +1 -0
  19. package/helpers/global-defines.d.ts +2 -0
  20. package/helpers/global-defines.js +5 -0
  21. package/helpers/global-defines.js.map +1 -1
  22. package/helpers/init.d.ts +1 -0
  23. package/helpers/init.js +119 -0
  24. package/helpers/init.js.map +1 -0
  25. package/helpers/logging.js +4 -0
  26. package/helpers/logging.js.map +1 -1
  27. package/helpers/main-entry.js +12 -4
  28. package/helpers/main-entry.js.map +1 -1
  29. package/helpers/nativeclass-transform.js +1 -1
  30. package/helpers/nativeclass-transform.js.map +1 -1
  31. package/helpers/utils.d.ts +4 -0
  32. package/helpers/utils.js +55 -0
  33. package/helpers/utils.js.map +1 -1
  34. package/hmr/client/index.js +257 -84
  35. package/hmr/client/index.js.map +1 -1
  36. package/hmr/entry-runtime.js +1 -1
  37. package/hmr/entry-runtime.js.map +1 -1
  38. package/hmr/frameworks/angular/client/index.d.ts +8 -0
  39. package/hmr/frameworks/angular/client/index.js +59 -0
  40. package/hmr/frameworks/angular/client/index.js.map +1 -0
  41. package/hmr/frameworks/angular/server/linker.d.ts +1 -0
  42. package/hmr/frameworks/angular/server/linker.js +101 -0
  43. package/hmr/frameworks/angular/server/linker.js.map +1 -0
  44. package/hmr/frameworks/angular/server/strategy.js +106 -20
  45. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  46. package/hmr/frameworks/solid/server/strategy.d.ts +2 -0
  47. package/hmr/frameworks/solid/server/strategy.js +56 -0
  48. package/hmr/frameworks/solid/server/strategy.js.map +1 -0
  49. package/hmr/frameworks/typescript/server/strategy.d.ts +2 -0
  50. package/hmr/frameworks/typescript/server/strategy.js +125 -0
  51. package/hmr/frameworks/typescript/server/strategy.js.map +1 -0
  52. package/hmr/frameworks/vue/client/index.js +7 -3
  53. package/hmr/frameworks/vue/client/index.js.map +1 -1
  54. package/hmr/frameworks/vue/server/strategy.js +3 -4
  55. package/hmr/frameworks/vue/server/strategy.js.map +1 -1
  56. package/hmr/server/index.js +5 -1
  57. package/hmr/server/index.js.map +1 -1
  58. package/hmr/server/websocket.d.ts +6 -0
  59. package/hmr/server/websocket.js +117 -26
  60. package/hmr/server/websocket.js.map +1 -1
  61. package/hmr/shared/vendor/manifest.d.ts +1 -0
  62. package/hmr/shared/vendor/manifest.js +38 -14
  63. package/hmr/shared/vendor/manifest.js.map +1 -1
  64. package/index.js +11 -0
  65. package/index.js.map +1 -1
  66. package/package.json +12 -9
  67. package/shims/angular-animations-stub.d.ts +62 -2
  68. package/shims/angular-animations-stub.js +132 -6
  69. package/shims/angular-animations-stub.js.map +1 -1
  70. package/helpers/angular-linker.js.map +0 -1
  71. /package/helpers/{angular-linker.d.ts → angular/angular-linker.d.ts} +0 -0
@@ -22,14 +22,25 @@ import { loadPrebuiltVendorManifest } from '../shared/vendor/manifest-loader.js'
22
22
  import '../vendor-bootstrap.js';
23
23
  import { NS_NATIVE_TAGS } from './compiler.js';
24
24
  import { vueSfcCompiler } from '../frameworks/vue/server/compiler.js';
25
+ import { linkAngularPartialsIfNeeded } from '../frameworks/angular/server/linker.js';
25
26
  import { vueServerStrategy } from '../frameworks/vue/server/strategy.js';
26
27
  import { angularServerStrategy } from '../frameworks/angular/server/strategy.js';
28
+ import { solidServerStrategy } from '../frameworks/solid/server/strategy.js';
29
+ import { typescriptServerStrategy } from '../frameworks/typescript/server/strategy.js';
27
30
  import { buildInlineTemplateBlock, createProcessSfcCode, extractTemplateRender, processTemplateVariantMinimal } from '../frameworks/vue/server/sfc-transforms.js';
28
31
  import { astExtractImportsAndStripTypes } from '../helpers/ast-extract.js';
32
+ import { getProjectAppPath, getProjectAppRelativePath, getProjectAppVirtualPath } from '../../helpers/utils.js';
29
33
  const { parse, compileTemplate, compileScript } = vueSfcCompiler;
34
+ const APP_ROOT_DIR = getProjectAppPath();
35
+ const APP_VIRTUAL_PREFIX = getProjectAppVirtualPath();
36
+ const APP_VIRTUAL_WITH_SLASH = `${APP_VIRTUAL_PREFIX}/`;
37
+ const DEFAULT_MAIN_ENTRY = getProjectAppRelativePath('app.ts');
38
+ const DEFAULT_MAIN_ENTRY_VIRTUAL = getProjectAppVirtualPath('app.ts');
30
39
  const STRATEGY_REGISTRY = new Map([
31
40
  ['vue', vueServerStrategy],
32
41
  ['angular', angularServerStrategy],
42
+ ['solid', solidServerStrategy],
43
+ ['typescript', typescriptServerStrategy],
33
44
  ]);
34
45
  function resolveFrameworkStrategy(flavor) {
35
46
  return STRATEGY_REGISTRY.get(flavor);
@@ -1019,6 +1030,8 @@ function normalizeAbsoluteFilesystemImport(spec, importerPath, projectRoot) {
1019
1030
  */
1020
1031
  function processCodeForDevice(code, isVitePreBundled) {
1021
1032
  let result = code;
1033
+ // Ensure Angular partial declarations are linked before any sanitizers run so runtime never hits the JIT path.
1034
+ result = linkAngularPartialsIfNeeded(result);
1022
1035
  // First: aggressively strip any lingering virtual dynamic-import-helper before anything else.
1023
1036
  // Doing this up-front prevents downstream dependency collection from seeing the virtual id.
1024
1037
  result = stripViteDynamicImportVirtual(result);
@@ -1873,7 +1886,7 @@ function rewriteImports(code, importerPath, sfcFileMap, depFileMap, projectRoot,
1873
1886
  else {
1874
1887
  const vueFile = sfcFileMap.get(vueKey);
1875
1888
  if (vueFile) {
1876
- const target = `_ns_hmr/src/sfc/${vueFile}`;
1889
+ const target = `_ns_hmr/${APP_ROOT_DIR}/sfc/${vueFile}`;
1877
1890
  const relPath = importerOutDir ? ensureRel(path.posix.relative(importerOutDir, target)) : ensureRel(target);
1878
1891
  if (verbose) {
1879
1892
  console.log(`[rewrite] .vue rewrite: ${spec} → ${relPath}`);
@@ -2000,7 +2013,7 @@ function rewriteImports(code, importerPath, sfcFileMap, depFileMap, projectRoot,
2000
2013
  if (vueKey) {
2001
2014
  const vueFile = sfcFileMap.get(vueKey);
2002
2015
  if (vueFile) {
2003
- const target = `_ns_hmr/src/sfc/${vueFile}`;
2016
+ const target = `_ns_hmr/${APP_ROOT_DIR}/sfc/${vueFile}`;
2004
2017
  const relPath = importerOutDir ? ensureRel(path.posix.relative(importerOutDir, target)) : ensureRel(target);
2005
2018
  if (verbose) {
2006
2019
  console.log(`[rewrite] .vue rewrite (VUE_FILE_IMPORT): ${spec} → ${relPath}`);
@@ -2059,7 +2072,7 @@ function createHmrWebSocketPlugin(opts) {
2059
2072
  // Only include application modules we can serve (e.g., under /src and known .vue/.ts/.js entries in the graph).
2060
2073
  function computeTxnOrderForChanged(changedIds) {
2061
2074
  const includeExt = (id) => ACTIVE_STRATEGY.matchesFile(id) || /\.(ts|js|mjs|tsx|jsx)$/i.test(id);
2062
- const isApp = (id) => id.startsWith('/src/');
2075
+ const isApp = (id) => id.startsWith(APP_VIRTUAL_WITH_SLASH);
2063
2076
  const roots = changedIds.map(normalizeGraphId).filter((id) => graph.has(id) && (isApp(id) || ACTIVE_STRATEGY.matchesFile(id)) && includeExt(id));
2064
2077
  const toVisit = new Set();
2065
2078
  // Collect dependency closure (downstream deps from roots)
@@ -2122,8 +2135,8 @@ function createHmrWebSocketPlugin(opts) {
2122
2135
  }
2123
2136
  if (!id.startsWith('/'))
2124
2137
  id = '/' + id;
2125
- // Collapse ./src/ or /src/ when nested (defensive)
2126
- const idx = id.indexOf('/src/');
2138
+ // Collapse nested app root indicators when present (defensive)
2139
+ const idx = id.indexOf(APP_VIRTUAL_WITH_SLASH);
2127
2140
  if (idx !== -1)
2128
2141
  id = id.slice(idx);
2129
2142
  return id;
@@ -2148,6 +2161,16 @@ function createHmrWebSocketPlugin(opts) {
2148
2161
  }
2149
2162
  function emitFullGraph(ws) {
2150
2163
  try {
2164
+ if (verbose) {
2165
+ try {
2166
+ const payload = fullGraphPayload();
2167
+ console.log('[hmr-ws][graph] emitFullGraph version', payload.version, 'modules=', payload.modules.length);
2168
+ if (payload.modules.length) {
2169
+ console.log('[hmr-ws][graph] sample module ids', payload.modules.slice(0, 5).map((m) => m.id));
2170
+ }
2171
+ }
2172
+ catch { }
2173
+ }
2151
2174
  ws.send(JSON.stringify(fullGraphPayload()));
2152
2175
  }
2153
2176
  catch { }
@@ -2201,8 +2224,23 @@ function createHmrWebSocketPlugin(opts) {
2201
2224
  graphVersion++;
2202
2225
  const gm = { id, deps: normDeps, hash };
2203
2226
  graph.set(id, gm);
2227
+ if (verbose) {
2228
+ try {
2229
+ console.log('[hmr-ws][graph] upsert', { id, deps: normDeps, hash, graphVersion });
2230
+ console.log('[hmr-ws][graph] size', graph.size);
2231
+ }
2232
+ catch { }
2233
+ }
2204
2234
  emitDelta([gm], []);
2205
2235
  }
2236
+ function isTypescriptFlavor() {
2237
+ try {
2238
+ return ACTIVE_STRATEGY?.flavor === 'typescript';
2239
+ }
2240
+ catch {
2241
+ return false;
2242
+ }
2243
+ }
2206
2244
  function removeGraphModule(id) {
2207
2245
  if (!graph.has(id))
2208
2246
  return;
@@ -2358,7 +2396,7 @@ function createHmrWebSocketPlugin(opts) {
2358
2396
  // Mirror normalization from ws handler
2359
2397
  spec = spec.replace(/[?#].*$/, '');
2360
2398
  if (spec.startsWith('@/'))
2361
- spec = '/src/' + spec.slice(2);
2399
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
2362
2400
  spec = spec.replace(/\/(index)(?:\/(?:index))+$/i, '/$1');
2363
2401
  if (spec.startsWith('./'))
2364
2402
  spec = spec.slice(1);
@@ -2558,7 +2596,7 @@ function createHmrWebSocketPlugin(opts) {
2558
2596
  }
2559
2597
  catch { }
2560
2598
  if (spec.startsWith('@/'))
2561
- spec = '/src/' + spec.slice(2);
2599
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
2562
2600
  if (spec.startsWith('./'))
2563
2601
  spec = spec.slice(1);
2564
2602
  if (!spec.startsWith('/'))
@@ -2655,6 +2693,27 @@ function createHmrWebSocketPlugin(opts) {
2655
2693
  // 5) __ns_import(new URL('/ns/m/...', import.meta.url).href)
2656
2694
  code = code.replace(/(new\s+URL\(\s*["'])(\/ns\/m\/[^"'?]+)(["']\s*,\s*import\.meta\.url\s*\)\.href)/g, `$1$2?v=${ver}$3`);
2657
2695
  transformed.code = code;
2696
+ // TypeScript-specific graph population: when TS flavor is active
2697
+ // and this is an application module under the virtual app root,
2698
+ // upsert it into the HMR graph so ns:hmr-full-graph is non-empty.
2699
+ try {
2700
+ if (isTypescriptFlavor()) {
2701
+ const id = (resolvedCandidate || spec).replace(/[?#].*$/, '');
2702
+ // Only track app modules (under APP_VIRTUAL_WITH_SLASH) and ts/js/tsx/jsx/mjs.
2703
+ const isApp = id.startsWith(APP_VIRTUAL_WITH_SLASH) || id.startsWith('/app/');
2704
+ if (isApp && /\.(ts|tsx|js|jsx|mjs|mts|cts)$/i.test(id)) {
2705
+ const deps = Array.from(collectImportDependencies(code, id));
2706
+ if (verbose) {
2707
+ try {
2708
+ console.log('[hmr-ws][ts-graph] candidate', { id, depsCount: deps.length });
2709
+ }
2710
+ catch { }
2711
+ }
2712
+ upsertGraphModule(id, code, deps);
2713
+ }
2714
+ }
2715
+ }
2716
+ catch { }
2658
2717
  }
2659
2718
  }
2660
2719
  catch { }
@@ -2914,7 +2973,7 @@ export const piniaSymbol = p.piniaSymbol;
2914
2973
  try {
2915
2974
  // Normalize project-relative path
2916
2975
  if (local.startsWith('@/'))
2917
- local = '/src/' + local.slice(2);
2976
+ local = APP_VIRTUAL_WITH_SLASH + local.slice(2);
2918
2977
  if (local.startsWith('./'))
2919
2978
  local = local.slice(1);
2920
2979
  if (!local.startsWith('/'))
@@ -3283,11 +3342,12 @@ export const piniaSymbol = p.piniaSymbol;
3283
3342
  let mainEntry = '/';
3284
3343
  try {
3285
3344
  const pkg = getPackageJson();
3286
- const main = pkg?.main || 'src/app.ts';
3287
- const abs = getProjectFilePath(main).replace(/\\\\/g, '/');
3288
- // Normalize to '/src/...' if within project root
3289
- const idx = abs.indexOf('/src/');
3290
- mainEntry = idx >= 0 ? abs.substring(idx) : '/src/app.ts';
3345
+ const main = pkg?.main || DEFAULT_MAIN_ENTRY;
3346
+ const abs = getProjectFilePath(main).replace(/\\/g, '/');
3347
+ // Normalize to '/app/...'
3348
+ const marker = `/${APP_ROOT_DIR}/`;
3349
+ const idx = abs.indexOf(marker);
3350
+ mainEntry = idx >= 0 ? abs.substring(idx) : DEFAULT_MAIN_ENTRY_VIRTUAL;
3291
3351
  }
3292
3352
  catch { }
3293
3353
  // Build a tiny wrapper that imports the compiled entry runtime from the dev server
@@ -3440,7 +3500,7 @@ export const piniaSymbol = p.piniaSymbol;
3440
3500
  return;
3441
3501
  }
3442
3502
  if (fullSpec.startsWith('@/'))
3443
- fullSpec = '/src/' + fullSpec.slice(2);
3503
+ fullSpec = APP_VIRTUAL_WITH_SLASH + fullSpec.slice(2);
3444
3504
  if (!fullSpec.startsWith('/'))
3445
3505
  fullSpec = '/' + fullSpec;
3446
3506
  const isVariant = /[?&]vue&type=/.test(fullSpec);
@@ -3761,7 +3821,7 @@ export const piniaSymbol = p.piniaSymbol;
3761
3821
  if (spec.startsWith('@@/'))
3762
3822
  spec = '/' + spec.slice(2);
3763
3823
  if (spec.startsWith('@/'))
3764
- spec = '/src/' + spec.slice(2);
3824
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
3765
3825
  }
3766
3826
  // Strip query for plain .vue (keep variant imports intact)
3767
3827
  if (!/\bvue&type=/.test(src)) {
@@ -3937,7 +3997,7 @@ export const piniaSymbol = p.piniaSymbol;
3937
3997
  return;
3938
3998
  }
3939
3999
  if (spec.startsWith('@/'))
3940
- spec = '/src/' + spec.slice(2);
4000
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
3941
4001
  if (!spec.startsWith('/'))
3942
4002
  spec = '/' + spec;
3943
4003
  const base = spec.replace(/[?#].*$/, '');
@@ -4015,7 +4075,7 @@ export const piniaSymbol = p.piniaSymbol;
4015
4075
  return;
4016
4076
  }
4017
4077
  if (spec.startsWith('@/'))
4018
- spec = '/src/' + spec.slice(2);
4078
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
4019
4079
  if (!spec.startsWith('/'))
4020
4080
  spec = '/' + spec;
4021
4081
  const base = spec.replace(/[?#].*$/, '');
@@ -4265,7 +4325,7 @@ export const piniaSymbol = p.piniaSymbol;
4265
4325
  }
4266
4326
  else if (!spec.startsWith('/')) {
4267
4327
  if (absImp.startsWith('@/'))
4268
- absImp = '/src/' + absImp.slice(2);
4328
+ absImp = APP_VIRTUAL_WITH_SLASH + absImp.slice(2);
4269
4329
  }
4270
4330
  const asmUrl = `/ns/asm/${ver}?path=${encodeURIComponent(absImp)}&mode=inline`;
4271
4331
  return `${pfx}import ${clause} from ${JSON.stringify(asmUrl)};`;
@@ -4818,7 +4878,7 @@ export const piniaSymbol = p.piniaSymbol;
4818
4878
  if (typeof spec === 'string') {
4819
4879
  spec = spec.replace(/[?#].*$/, '');
4820
4880
  if (spec.startsWith('@/'))
4821
- spec = '/src/' + spec.slice(2);
4881
+ spec = APP_VIRTUAL_WITH_SLASH + spec.slice(2);
4822
4882
  // Collapse accidental repeated index segments: /foo/index/index -> /foo/index
4823
4883
  spec = spec.replace(/\/(index)(?:\/(?:index))+$/i, '/$1');
4824
4884
  if (spec === '@') {
@@ -5118,8 +5178,11 @@ export const piniaSymbol = p.piniaSymbol;
5118
5178
  const root = server.config.root || process.cwd();
5119
5179
  const srcDir = `${root}/src`;
5120
5180
  const coreDir = `${root}/core`;
5181
+ const appDir = `${root}/${APP_ROOT_DIR}`;
5121
5182
  const normalizedFile = file.split(path.sep).join('/');
5122
- const shouldIgnore = !(normalizedFile.includes(srcDir) || normalizedFile.includes(coreDir));
5183
+ const inSrcOrCore = normalizedFile.includes(srcDir) || normalizedFile.includes(coreDir);
5184
+ const inApp = normalizedFile.includes(appDir);
5185
+ const shouldIgnore = !(inSrcOrCore || inApp);
5123
5186
  if (shouldIgnore)
5124
5187
  return;
5125
5188
  if (verbose)
@@ -5180,6 +5243,26 @@ export const piniaSymbol = p.piniaSymbol;
5180
5243
  }
5181
5244
  return;
5182
5245
  }
5246
+ // TypeScript flavor: emit generic graph delta for app XML/TS/style changes
5247
+ if (ACTIVE_STRATEGY.flavor === 'typescript') {
5248
+ try {
5249
+ const rel = '/' + path.posix.normalize(path.relative(root, file)).split(path.sep).join('/');
5250
+ if (verbose)
5251
+ console.log('[hmr-ws][ts] app file hot update', { file, rel });
5252
+ // Treat the changed file itself as a graph module with no deps. We only
5253
+ // care that its hash/identity changes so the client sees a delta and can
5254
+ // perform a TS root reset. Code is not used for execution here.
5255
+ upsertGraphModule(rel, '', []);
5256
+ const gm = graph.get(normalizeGraphId(rel));
5257
+ if (gm)
5258
+ emitDelta([gm], []);
5259
+ }
5260
+ catch (e) {
5261
+ if (verbose)
5262
+ console.warn('[hmr-ws][ts] failed to emit delta for', file, e);
5263
+ }
5264
+ return;
5265
+ }
5183
5266
  // Handle .vue file updates
5184
5267
  if (!file.endsWith('.vue')) {
5185
5268
  if (verbose)
@@ -5440,12 +5523,12 @@ if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
5440
5523
  }
5441
5524
  }
5442
5525
  // Heuristic for barrel index modules that might not have explicit .mjs import strings
5443
- // If an import referencing '/src/utils' (without explicit 'index') was collapsed by rewriting,
5444
- // ensure '/src/utils/index.mjs' is included when we see either '/src/utils' base or a usage pattern.
5445
- if (!Array.from(filtered).some((p) => /\/src\/utils\/index\.mjs$/i.test(p))) {
5446
- // Simple pattern: presence of 'src/utils/' substring in code implies possible barrel usage.
5447
- if (/src\/utils\//.test(code)) {
5448
- addCandidate('/src/utils/index.mjs');
5526
+ const utilsIndexCandidate = `${APP_VIRTUAL_WITH_SLASH}utils/index.mjs`;
5527
+ const hasUtilsIndex = Array.from(filtered).some((p) => p.toLowerCase() === utilsIndexCandidate.toLowerCase());
5528
+ if (!hasUtilsIndex) {
5529
+ const utilsMarker = `${APP_VIRTUAL_WITH_SLASH}utils/`;
5530
+ if (code.includes(utilsMarker)) {
5531
+ addCandidate(utilsIndexCandidate);
5449
5532
  }
5450
5533
  }
5451
5534
  if (filtered.size) {
@@ -5478,6 +5561,14 @@ export function hmrWebSocketAngular(opts) {
5478
5561
  ACTIVE_STRATEGY = resolveFrameworkStrategy('angular');
5479
5562
  return createHmrWebSocketPlugin(opts);
5480
5563
  }
5564
+ export function hmrWebSocketSolid(opts) {
5565
+ ACTIVE_STRATEGY = resolveFrameworkStrategy('solid');
5566
+ return createHmrWebSocketPlugin(opts);
5567
+ }
5568
+ export function hmrWebSocketTypescript(opts) {
5569
+ ACTIVE_STRATEGY = resolveFrameworkStrategy('typescript');
5570
+ return createHmrWebSocketPlugin(opts);
5571
+ }
5481
5572
  /**
5482
5573
  * Get server origin for URLs
5483
5574
  */