@nativescript/vite 8.0.0-alpha.1 → 8.0.0-alpha.11

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 (220) hide show
  1. package/configuration/angular.d.ts +1 -1
  2. package/configuration/angular.js +486 -140
  3. package/configuration/angular.js.map +1 -1
  4. package/configuration/base.js +159 -29
  5. package/configuration/base.js.map +1 -1
  6. package/configuration/javascript.js +3 -3
  7. package/configuration/javascript.js.map +1 -1
  8. package/configuration/solid.js +27 -0
  9. package/configuration/solid.js.map +1 -1
  10. package/configuration/typescript.js +4 -4
  11. package/configuration/typescript.js.map +1 -1
  12. package/helpers/angular/angular-linker.js +38 -42
  13. package/helpers/angular/angular-linker.js.map +1 -1
  14. package/helpers/angular/inject-component-hmr-registration.d.ts +112 -0
  15. package/helpers/angular/inject-component-hmr-registration.js +359 -0
  16. package/helpers/angular/inject-component-hmr-registration.js.map +1 -0
  17. package/helpers/angular/inline-decorator-component-templates.d.ts +3 -0
  18. package/helpers/angular/inline-decorator-component-templates.js +400 -0
  19. package/helpers/angular/inline-decorator-component-templates.js.map +1 -0
  20. package/helpers/angular/shared-linker.d.ts +7 -0
  21. package/helpers/angular/shared-linker.js +37 -1
  22. package/helpers/angular/shared-linker.js.map +1 -1
  23. package/helpers/angular/synthesize-decorator-ctor-parameters.d.ts +1 -0
  24. package/helpers/angular/synthesize-decorator-ctor-parameters.js +256 -0
  25. package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +1 -0
  26. package/helpers/angular/synthesize-injectable-factories.d.ts +3 -0
  27. package/helpers/angular/synthesize-injectable-factories.js +414 -0
  28. package/helpers/angular/synthesize-injectable-factories.js.map +1 -0
  29. package/helpers/angular/util.d.ts +1 -0
  30. package/helpers/angular/util.js +88 -0
  31. package/helpers/angular/util.js.map +1 -1
  32. package/helpers/commonjs-plugins.d.ts +5 -2
  33. package/helpers/commonjs-plugins.js +126 -0
  34. package/helpers/commonjs-plugins.js.map +1 -1
  35. package/helpers/config-as-json.js +10 -0
  36. package/helpers/config-as-json.js.map +1 -1
  37. package/helpers/esbuild-platform-resolver.js +5 -5
  38. package/helpers/esbuild-platform-resolver.js.map +1 -1
  39. package/helpers/external-configs.d.ts +9 -1
  40. package/helpers/external-configs.js +31 -6
  41. package/helpers/external-configs.js.map +1 -1
  42. package/helpers/global-defines.d.ts +51 -0
  43. package/helpers/global-defines.js +77 -0
  44. package/helpers/global-defines.js.map +1 -1
  45. package/helpers/import-meta-path.d.ts +4 -0
  46. package/helpers/import-meta-path.js +5 -0
  47. package/helpers/import-meta-path.js.map +1 -0
  48. package/helpers/import-specifier.d.ts +1 -0
  49. package/helpers/import-specifier.js +18 -0
  50. package/helpers/import-specifier.js.map +1 -0
  51. package/helpers/logging.d.ts +1 -0
  52. package/helpers/logging.js +63 -3
  53. package/helpers/logging.js.map +1 -1
  54. package/helpers/main-entry.d.ts +5 -2
  55. package/helpers/main-entry.js +375 -116
  56. package/helpers/main-entry.js.map +1 -1
  57. package/helpers/nativeclass-transform.js +8 -127
  58. package/helpers/nativeclass-transform.js.map +1 -1
  59. package/helpers/nativeclass-transformer-plugin.d.ts +19 -1
  60. package/helpers/nativeclass-transformer-plugin.js +318 -36
  61. package/helpers/nativeclass-transformer-plugin.js.map +1 -1
  62. package/helpers/ns-core-url.d.ts +83 -0
  63. package/helpers/ns-core-url.js +167 -0
  64. package/helpers/ns-core-url.js.map +1 -0
  65. package/helpers/prelink-angular.js +1 -4
  66. package/helpers/prelink-angular.js.map +1 -1
  67. package/helpers/project.d.ts +35 -0
  68. package/helpers/project.js +120 -2
  69. package/helpers/project.js.map +1 -1
  70. package/helpers/ts-config-paths.js +50 -2
  71. package/helpers/ts-config-paths.js.map +1 -1
  72. package/helpers/workers.d.ts +20 -19
  73. package/helpers/workers.js +620 -3
  74. package/helpers/workers.js.map +1 -1
  75. package/hmr/client/css-handler.js +60 -19
  76. package/hmr/client/css-handler.js.map +1 -1
  77. package/hmr/client/hmr-pending-overlay.d.ts +27 -0
  78. package/hmr/client/hmr-pending-overlay.js +50 -0
  79. package/hmr/client/hmr-pending-overlay.js.map +1 -0
  80. package/hmr/client/index.js +767 -24
  81. package/hmr/client/index.js.map +1 -1
  82. package/hmr/client/utils.d.ts +5 -0
  83. package/hmr/client/utils.js +283 -12
  84. package/hmr/client/utils.js.map +1 -1
  85. package/hmr/entry-runtime.d.ts +10 -0
  86. package/hmr/entry-runtime.js +330 -42
  87. package/hmr/entry-runtime.js.map +1 -1
  88. package/hmr/frameworks/angular/client/index.d.ts +3 -1
  89. package/hmr/frameworks/angular/client/index.js +821 -25
  90. package/hmr/frameworks/angular/client/index.js.map +1 -1
  91. package/hmr/frameworks/angular/server/linker.js +37 -6
  92. package/hmr/frameworks/angular/server/linker.js.map +1 -1
  93. package/hmr/frameworks/angular/server/strategy.js +30 -6
  94. package/hmr/frameworks/angular/server/strategy.js.map +1 -1
  95. package/hmr/frameworks/typescript/server/strategy.js +8 -2
  96. package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
  97. package/hmr/frameworks/vue/client/index.js +18 -42
  98. package/hmr/frameworks/vue/client/index.js.map +1 -1
  99. package/hmr/helpers/ast-normalizer.js +22 -10
  100. package/hmr/helpers/ast-normalizer.js.map +1 -1
  101. package/hmr/helpers/cjs-named-exports.d.ts +23 -0
  102. package/hmr/helpers/cjs-named-exports.js +152 -0
  103. package/hmr/helpers/cjs-named-exports.js.map +1 -0
  104. package/hmr/server/constants.d.ts +1 -0
  105. package/hmr/server/constants.js +14 -3
  106. package/hmr/server/constants.js.map +1 -1
  107. package/hmr/server/core-sanitize.d.ts +49 -2
  108. package/hmr/server/core-sanitize.js +267 -24
  109. package/hmr/server/core-sanitize.js.map +1 -1
  110. package/hmr/server/import-map.d.ts +65 -0
  111. package/hmr/server/import-map.js +222 -0
  112. package/hmr/server/import-map.js.map +1 -0
  113. package/hmr/server/index.d.ts +2 -1
  114. package/hmr/server/index.js.map +1 -1
  115. package/hmr/server/ns-core-cjs-shape.d.ts +204 -0
  116. package/hmr/server/ns-core-cjs-shape.js +271 -0
  117. package/hmr/server/ns-core-cjs-shape.js.map +1 -0
  118. package/hmr/server/perf-instrumentation.d.ts +114 -0
  119. package/hmr/server/perf-instrumentation.js +195 -0
  120. package/hmr/server/perf-instrumentation.js.map +1 -0
  121. package/hmr/server/runtime-graph-filter.d.ts +5 -0
  122. package/hmr/server/runtime-graph-filter.js +21 -0
  123. package/hmr/server/runtime-graph-filter.js.map +1 -0
  124. package/hmr/server/shared-transform-request.d.ts +12 -0
  125. package/hmr/server/shared-transform-request.js +144 -0
  126. package/hmr/server/shared-transform-request.js.map +1 -0
  127. package/hmr/server/vite-plugin.d.ts +21 -1
  128. package/hmr/server/vite-plugin.js +461 -22
  129. package/hmr/server/vite-plugin.js.map +1 -1
  130. package/hmr/server/websocket-angular-entry.d.ts +2 -0
  131. package/hmr/server/websocket-angular-entry.js +68 -0
  132. package/hmr/server/websocket-angular-entry.js.map +1 -0
  133. package/hmr/server/websocket-angular-hot-update.d.ts +78 -0
  134. package/hmr/server/websocket-angular-hot-update.js +413 -0
  135. package/hmr/server/websocket-angular-hot-update.js.map +1 -0
  136. package/hmr/server/websocket-core-bridge.d.ts +21 -0
  137. package/hmr/server/websocket-core-bridge.js +357 -0
  138. package/hmr/server/websocket-core-bridge.js.map +1 -0
  139. package/hmr/server/websocket-graph-upsert.d.ts +21 -0
  140. package/hmr/server/websocket-graph-upsert.js +33 -0
  141. package/hmr/server/websocket-graph-upsert.js.map +1 -0
  142. package/hmr/server/websocket-hmr-pending.d.ts +43 -0
  143. package/hmr/server/websocket-hmr-pending.js +55 -0
  144. package/hmr/server/websocket-hmr-pending.js.map +1 -0
  145. package/hmr/server/websocket-module-bindings.d.ts +6 -0
  146. package/hmr/server/websocket-module-bindings.js +471 -0
  147. package/hmr/server/websocket-module-bindings.js.map +1 -0
  148. package/hmr/server/websocket-module-specifiers.d.ts +101 -0
  149. package/hmr/server/websocket-module-specifiers.js +820 -0
  150. package/hmr/server/websocket-module-specifiers.js.map +1 -0
  151. package/hmr/server/websocket-ns-m-finalize.d.ts +22 -0
  152. package/hmr/server/websocket-ns-m-finalize.js +88 -0
  153. package/hmr/server/websocket-ns-m-finalize.js.map +1 -0
  154. package/hmr/server/websocket-ns-m-paths.d.ts +3 -0
  155. package/hmr/server/websocket-ns-m-paths.js +92 -0
  156. package/hmr/server/websocket-ns-m-paths.js.map +1 -0
  157. package/hmr/server/websocket-ns-m-request.d.ts +45 -0
  158. package/hmr/server/websocket-ns-m-request.js +196 -0
  159. package/hmr/server/websocket-ns-m-request.js.map +1 -0
  160. package/hmr/server/websocket-runtime-compat.d.ts +19 -0
  161. package/hmr/server/websocket-runtime-compat.js +287 -0
  162. package/hmr/server/websocket-runtime-compat.js.map +1 -0
  163. package/hmr/server/websocket-served-module-helpers.d.ts +36 -0
  164. package/hmr/server/websocket-served-module-helpers.js +631 -0
  165. package/hmr/server/websocket-served-module-helpers.js.map +1 -0
  166. package/hmr/server/websocket-txn.d.ts +6 -0
  167. package/hmr/server/websocket-txn.js +45 -0
  168. package/hmr/server/websocket-txn.js.map +1 -0
  169. package/hmr/server/websocket-vendor-unifier.d.ts +10 -0
  170. package/hmr/server/websocket-vendor-unifier.js +51 -0
  171. package/hmr/server/websocket-vendor-unifier.js.map +1 -0
  172. package/hmr/server/websocket-vue-sfc.d.ts +27 -0
  173. package/hmr/server/websocket-vue-sfc.js +1069 -0
  174. package/hmr/server/websocket-vue-sfc.js.map +1 -0
  175. package/hmr/server/websocket.d.ts +26 -3
  176. package/hmr/server/websocket.js +2492 -798
  177. package/hmr/server/websocket.js.map +1 -1
  178. package/hmr/shared/package-classifier.d.ts +9 -0
  179. package/hmr/shared/package-classifier.js +58 -0
  180. package/hmr/shared/package-classifier.js.map +1 -0
  181. package/hmr/shared/runtime/boot-timeline.d.ts +17 -0
  182. package/hmr/shared/runtime/boot-timeline.js +51 -0
  183. package/hmr/shared/runtime/boot-timeline.js.map +1 -0
  184. package/hmr/shared/runtime/browser-runtime-contract.d.ts +64 -0
  185. package/hmr/shared/runtime/browser-runtime-contract.js +54 -0
  186. package/hmr/shared/runtime/browser-runtime-contract.js.map +1 -0
  187. package/hmr/shared/runtime/dev-overlay.d.ts +85 -0
  188. package/hmr/shared/runtime/dev-overlay.js +1236 -0
  189. package/hmr/shared/runtime/dev-overlay.js.map +1 -0
  190. package/hmr/shared/runtime/http-only-boot.d.ts +1 -0
  191. package/hmr/shared/runtime/http-only-boot.js +53 -6
  192. package/hmr/shared/runtime/http-only-boot.js.map +1 -1
  193. package/hmr/shared/runtime/module-provenance.d.ts +1 -0
  194. package/hmr/shared/runtime/module-provenance.js +63 -0
  195. package/hmr/shared/runtime/module-provenance.js.map +1 -0
  196. package/hmr/shared/runtime/platform-polyfills.d.ts +26 -0
  197. package/hmr/shared/runtime/platform-polyfills.js +122 -0
  198. package/hmr/shared/runtime/platform-polyfills.js.map +1 -0
  199. package/hmr/shared/runtime/root-placeholder.d.ts +1 -0
  200. package/hmr/shared/runtime/root-placeholder.js +552 -82
  201. package/hmr/shared/runtime/root-placeholder.js.map +1 -1
  202. package/hmr/shared/runtime/session-bootstrap.d.ts +1 -0
  203. package/hmr/shared/runtime/session-bootstrap.js +195 -0
  204. package/hmr/shared/runtime/session-bootstrap.js.map +1 -0
  205. package/hmr/shared/runtime/vendor-bootstrap.js +52 -15
  206. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
  207. package/hmr/shared/vendor/manifest.d.ts +37 -0
  208. package/hmr/shared/vendor/manifest.js +677 -57
  209. package/hmr/shared/vendor/manifest.js.map +1 -1
  210. package/hmr/shared/vendor/registry.js +104 -7
  211. package/hmr/shared/vendor/registry.js.map +1 -1
  212. package/index.d.ts +1 -0
  213. package/index.js +5 -0
  214. package/index.js.map +1 -1
  215. package/package.json +14 -2
  216. package/runtime/core-aliases-early.js +94 -67
  217. package/runtime/core-aliases-early.js.map +1 -1
  218. package/shims/solid-jsx-runtime.d.ts +7 -0
  219. package/shims/solid-jsx-runtime.js +17 -0
  220. package/shims/solid-jsx-runtime.js.map +1 -0
@@ -0,0 +1,144 @@
1
+ export function createSharedTransformRequestRunner(transformRequest, onTimeout, options = {}) {
2
+ const inFlight = new Map();
3
+ const recentResults = new Map();
4
+ const cacheGenerations = new Map();
5
+ const queue = [];
6
+ const maxConcurrent = Math.max(1, Math.floor(options.maxConcurrent ?? 1));
7
+ const resultCacheTtlMs = Math.max(0, Math.floor(options.resultCacheTtlMs ?? 0));
8
+ const getResultCacheKey = options.getResultCacheKey ?? ((url) => url);
9
+ let activeCount = 0;
10
+ const getCacheGeneration = (cacheKey) => cacheGenerations.get(cacheKey) ?? 0;
11
+ const invalidateCacheKey = (cacheKey) => {
12
+ cacheGenerations.set(cacheKey, getCacheGeneration(cacheKey) + 1);
13
+ recentResults.delete(cacheKey);
14
+ };
15
+ const pruneRecentResults = () => {
16
+ if (!recentResults.size) {
17
+ return;
18
+ }
19
+ const now = Date.now();
20
+ for (const [key, entry] of recentResults) {
21
+ if (entry.expiresAt <= now) {
22
+ recentResults.delete(key);
23
+ }
24
+ }
25
+ };
26
+ const rememberRecentResult = (url, result, generation) => {
27
+ if (!result || resultCacheTtlMs <= 0) {
28
+ return;
29
+ }
30
+ const cacheKey = getResultCacheKey(url);
31
+ if (getCacheGeneration(cacheKey) !== generation) {
32
+ return;
33
+ }
34
+ recentResults.delete(cacheKey);
35
+ recentResults.set(cacheKey, {
36
+ expiresAt: Date.now() + resultCacheTtlMs,
37
+ result,
38
+ });
39
+ if (recentResults.size > 512) {
40
+ const oldestKey = recentResults.keys().next().value;
41
+ if (oldestKey) {
42
+ recentResults.delete(oldestKey);
43
+ }
44
+ }
45
+ };
46
+ const runNext = () => {
47
+ while (activeCount < maxConcurrent) {
48
+ const next = queue.shift();
49
+ if (!next) {
50
+ return;
51
+ }
52
+ activeCount += 1;
53
+ next();
54
+ }
55
+ };
56
+ const schedule = (task) => {
57
+ let resolveStarted = null;
58
+ const started = new Promise((resolve) => {
59
+ resolveStarted = resolve;
60
+ });
61
+ const execution = new Promise((resolve, reject) => {
62
+ queue.push(() => {
63
+ let started;
64
+ resolveStarted?.();
65
+ try {
66
+ started = Promise.resolve(task());
67
+ }
68
+ catch (error) {
69
+ started = Promise.reject(error);
70
+ }
71
+ started.then(resolve, reject).finally(() => {
72
+ activeCount = Math.max(0, activeCount - 1);
73
+ runNext();
74
+ });
75
+ });
76
+ runNext();
77
+ });
78
+ return { execution, started };
79
+ };
80
+ const withTimeout = (entry, url, timeoutMs) => {
81
+ if (!(timeoutMs > 0)) {
82
+ return entry.execution;
83
+ }
84
+ return entry.started.then(() => new Promise((resolve, reject) => {
85
+ const timer = setTimeout(() => {
86
+ try {
87
+ onTimeout?.(url, timeoutMs);
88
+ }
89
+ catch { }
90
+ }, timeoutMs);
91
+ entry.execution.then(resolve, reject).finally(() => {
92
+ clearTimeout(timer);
93
+ });
94
+ }));
95
+ };
96
+ const runner = ((url, timeoutMs = 120000) => {
97
+ pruneRecentResults();
98
+ const cacheKey = getResultCacheKey(url);
99
+ const generation = getCacheGeneration(cacheKey);
100
+ const recent = recentResults.get(cacheKey);
101
+ if (recent && recent.expiresAt > Date.now()) {
102
+ return Promise.resolve(recent.result);
103
+ }
104
+ // Key the in-flight map on the canonical `cacheKey`, not the raw URL,
105
+ // so two concurrent calls for `/foo.ts?t=1` and `/foo.ts?t=2` share a
106
+ // single transform rather than doing the same work twice. The cache
107
+ // key already strips `?t=` and `?v=` cache-busters and sorts the
108
+ // remaining query — see `canonicalizeTransformRequestCacheKey`. This
109
+ // pairs with `rememberRecentResult`, which was always keyed by
110
+ // cacheKey.
111
+ const existingExecution = inFlight.get(cacheKey);
112
+ if (existingExecution && existingExecution.generation === generation) {
113
+ return withTimeout(existingExecution, url, timeoutMs);
114
+ }
115
+ const scheduled = schedule(async () => {
116
+ const result = await Promise.resolve(transformRequest(url));
117
+ rememberRecentResult(url, result, generation);
118
+ return result;
119
+ });
120
+ let execution;
121
+ execution = scheduled.execution.finally(() => {
122
+ if (inFlight.get(cacheKey)?.execution === execution) {
123
+ inFlight.delete(cacheKey);
124
+ }
125
+ });
126
+ const entry = { execution, started: scheduled.started, cacheKey, generation };
127
+ inFlight.set(cacheKey, entry);
128
+ return withTimeout(entry, url, timeoutMs);
129
+ });
130
+ runner.invalidate = (url) => {
131
+ invalidateCacheKey(getResultCacheKey(url));
132
+ };
133
+ runner.invalidateMany = (urls) => {
134
+ for (const url of urls || []) {
135
+ runner.invalidate(url);
136
+ }
137
+ };
138
+ runner.clear = () => {
139
+ recentResults.clear();
140
+ cacheGenerations.clear();
141
+ };
142
+ return runner;
143
+ }
144
+ //# sourceMappingURL=shared-transform-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-transform-request.js","sourceRoot":"","sources":["../../../../../packages/vite/hmr/server/shared-transform-request.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,25 @@
1
1
  import type { Plugin } from 'vite';
2
+ import { type NsDevPlatform, type NsDevSessionDescriptor } from '../shared/runtime/browser-runtime-contract.js';
3
+ export declare function computeClientImportSpecifier(options: {
4
+ projectRoot: string;
5
+ clientFsPath: string;
6
+ }): string;
7
+ export declare function resolveProjectMainEntryPath(projectRoot: string): string;
8
+ export declare function createNsDevSessionDescriptor(options: {
9
+ projectRoot: string;
10
+ requestHost: string;
11
+ platform: NsDevPlatform;
12
+ sessionId: string;
13
+ secure?: boolean;
14
+ mainEntryPathname?: string;
15
+ }): NsDevSessionDescriptor;
16
+ export declare function createNsDevClientBootstrapCode(options: {
17
+ wsUrl: string;
18
+ origin: string;
19
+ clientImport: string;
20
+ verbose?: boolean;
21
+ }): string;
2
22
  export declare function nsHmrClientVitePlugin(opts: {
3
- platform: string;
23
+ platform: NsDevPlatform;
4
24
  verbose?: boolean;
5
25
  }): Plugin;
@@ -1,12 +1,417 @@
1
1
  import { createRequire } from 'node:module';
2
+ import fs from 'node:fs';
2
3
  import path from 'path';
3
4
  import os from 'os';
4
5
  import { pathToFileURL } from 'url';
6
+ import { NS_DEFAULT_DEV_FEATURE_FLAGS, NS_DEFAULT_HOST_MODULES } from '../shared/runtime/browser-runtime-contract.js';
5
7
  const require = createRequire(import.meta.url);
6
8
  const VIRTUAL_ID = 'virtual:ns-hmr-client';
7
9
  const RESOLVED_ID = '\0' + VIRTUAL_ID;
10
+ export function computeClientImportSpecifier(options) {
11
+ const { projectRoot, clientFsPath } = options;
12
+ let clientImport = clientFsPath;
13
+ try {
14
+ const fsPosix = clientFsPath.replace(/\\/g, '/');
15
+ const rel = path.relative(projectRoot, clientFsPath);
16
+ const relPosix = rel.replace(/\\/g, '/');
17
+ if (path.isAbsolute(rel)) {
18
+ clientImport = pathToFileURL(clientFsPath).toString();
19
+ }
20
+ else {
21
+ // Prefer routing via the absolute fs path's `node_modules/...` tail. This
22
+ // covers monorepo / pnpm setups where node_modules is hoisted ABOVE the
23
+ // project root and `path.relative` would otherwise produce a
24
+ // "../../node_modules/..." specifier. That relative form is sent to the
25
+ // device's bootstrap as `__NS_BROWSER_RUNTIME_CLIENT_IMPORT__`, where the
26
+ // URL constructor resolves it against `${origin}/__ns_dev__/client` and
27
+ // collapses the leading `..` segments back to `${origin}/node_modules/...`.
28
+ // That URL bypasses the `/ns/m/` AST-normalizer pipeline (which strips
29
+ // browser-only `/@vite/client` imports), so the on-device HTTP loader
30
+ // eventually tries to fetch `/@vite/client` and fails with
31
+ // "HTTP import failed (status=0)" / "Instantiation failed (http-loader)".
32
+ const lastNm = fsPosix.lastIndexOf('/node_modules/');
33
+ if (lastNm !== -1) {
34
+ return `/ns/m${fsPosix.slice(lastNm)}`;
35
+ }
36
+ const normalizedRel = (relPosix.startsWith('.') ? relPosix : `/${relPosix}`).replace(/\/+/g, '/');
37
+ clientImport = normalizedRel.startsWith('/node_modules/') ? `/ns/m${normalizedRel}` : normalizedRel;
38
+ }
39
+ }
40
+ catch {
41
+ clientImport = clientFsPath.replace(/\\/g, '/');
42
+ }
43
+ return clientImport;
44
+ }
45
+ export function resolveProjectMainEntryPath(projectRoot) {
46
+ try {
47
+ const packageJsonPath = path.join(projectRoot, 'package.json');
48
+ const raw = fs.readFileSync(packageJsonPath, 'utf-8');
49
+ const parsed = JSON.parse(raw);
50
+ const mainEntry = typeof parsed.main === 'string' && parsed.main ? parsed.main : 'src/app.ts';
51
+ const resolved = path.resolve(projectRoot, mainEntry);
52
+ const relative = path.relative(projectRoot, resolved).replace(/\\/g, '/');
53
+ return `/${relative}`.replace(/\/+/g, '/');
54
+ }
55
+ catch {
56
+ return '/src/app.ts';
57
+ }
58
+ }
59
+ export function createNsDevSessionDescriptor(options) {
60
+ const protocol = options.secure ? 'https' : 'http';
61
+ const wsProtocol = options.secure ? 'wss' : 'ws';
62
+ const origin = `${protocol}://${options.requestHost}`;
63
+ const entryPathname = options.mainEntryPathname || resolveProjectMainEntryPath(options.projectRoot);
64
+ const mirroredEntryPathname = entryPathname.startsWith('/ns/m/') ? entryPathname : `/ns/m${entryPathname.startsWith('/') ? entryPathname : `/${entryPathname}`}`;
65
+ return {
66
+ sessionId: options.sessionId,
67
+ origin,
68
+ entryUrl: `${origin}${mirroredEntryPathname}`,
69
+ clientUrl: `${origin}/__ns_dev__/client`,
70
+ wsUrl: `${wsProtocol}://${options.requestHost}/ns-hmr`,
71
+ platform: options.platform,
72
+ runtimeConfigUrl: `${origin}/ns/import-map.json`,
73
+ hostModules: [...NS_DEFAULT_HOST_MODULES],
74
+ features: { ...NS_DEFAULT_DEV_FEATURE_FLAGS },
75
+ };
76
+ }
77
+ function resolveBootstrapImportUrl(origin, clientImport) {
78
+ const normalizedOrigin = origin.replace(/\/$/, '');
79
+ if (!clientImport) {
80
+ return clientImport;
81
+ }
82
+ if (/^(?:https?|file):\/\//i.test(clientImport)) {
83
+ return clientImport;
84
+ }
85
+ if (clientImport.startsWith('/')) {
86
+ return `${normalizedOrigin}${clientImport}`;
87
+ }
88
+ try {
89
+ return new URL(clientImport, `${normalizedOrigin}/__ns_dev__/client`).toString();
90
+ }
91
+ catch {
92
+ return clientImport;
93
+ }
94
+ }
95
+ export function createNsDevClientBootstrapCode(options) {
96
+ const normalizedOrigin = options.origin.replace(/\/$/, '');
97
+ const resolvedClientImport = resolveBootstrapImportUrl(normalizedOrigin, options.clientImport);
98
+ const vendorBundleUrl = `${normalizedOrigin}/@nativescript/vendor.mjs`;
99
+ const vendorBootstrapUrl = `${normalizedOrigin}/ns/m/node_modules/@nativescript/vite/hmr/shared/runtime/vendor-bootstrap.js`;
100
+ return `
101
+ import { installVendorBootstrap as __nsBrowserRuntimeInstallVendorBootstrap } from ${JSON.stringify(vendorBootstrapUrl)};
102
+ import { vendorManifest as __nsBrowserRuntimeVendorManifest, __nsVendorModuleMap as __nsBrowserRuntimeVendorModuleMap } from ${JSON.stringify(vendorBundleUrl)};
103
+
104
+ const __NS_BROWSER_RUNTIME_WS_URL__ = ${JSON.stringify(options.wsUrl)};
105
+ const __NS_BROWSER_RUNTIME_ORIGIN__ = ${JSON.stringify(options.origin)};
106
+ const __NS_BROWSER_RUNTIME_CLIENT_IMPORT__ = ${JSON.stringify(resolvedClientImport)};
107
+ const __NS_BROWSER_RUNTIME_VERBOSE__ = ${options.verbose ? 'true' : 'false'};
108
+ let __nsBrowserRuntimeHmrClientStartPromise;
109
+ let __nsBrowserRuntimeSocket;
110
+ let __nsBrowserRuntimeSocketReconnectTimer;
111
+ let __nsBrowserRuntimeDelegationTimer;
112
+ let __nsBrowserRuntimeDelegationWarningIssued = false;
113
+ let __nsBrowserRuntimeBootWaitWarningIssued = false;
114
+
115
+ function __nsBrowserRuntimeWithSocketRole(url, role) {
116
+ try {
117
+ const resolved = new URL(url);
118
+ resolved.searchParams.set('ns_hmr_role', role);
119
+ return resolved.toString();
120
+ } catch {
121
+ const sep = url.includes('?') ? '&' : '?';
122
+ return url + sep + 'ns_hmr_role=' + encodeURIComponent(role);
123
+ }
124
+ }
125
+
126
+ const __NS_BROWSER_RUNTIME_FALLBACK_WS_URL__ = __nsBrowserRuntimeWithSocketRole(__NS_BROWSER_RUNTIME_WS_URL__, 'bootstrap');
127
+ const __NS_BROWSER_RUNTIME_FULL_CLIENT_WS_URL__ = __nsBrowserRuntimeWithSocketRole(__NS_BROWSER_RUNTIME_WS_URL__, 'full');
128
+
129
+ function __nsBrowserRuntimeEnsureVendorBootstrap() {
130
+ __nsBrowserRuntimeInstallVendorBootstrap(__nsBrowserRuntimeVendorManifest, __nsBrowserRuntimeVendorModuleMap, __NS_BROWSER_RUNTIME_VERBOSE__);
131
+ const registry = globalThis.__nsVendorRegistry;
132
+ if (!(registry && typeof registry.get === 'function')) {
133
+ throw new Error('NativeScript vendor registry was not initialized');
134
+ }
135
+ }
136
+
137
+ async function __nsBrowserRuntimeReplaySeededCss() {
138
+ const cssText = globalThis.__NS_HMR_APP_CSS__;
139
+ if (typeof cssText !== 'string' || !cssText.length || globalThis.__NS_HMR_HTTP_APP_CSS_APPLIED__) {
140
+ return;
141
+ }
142
+ const apply = globalThis.__nsApplyStyleUpdate;
143
+ if (typeof apply !== 'function') {
144
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
145
+ console.warn('[ns-browser-runtime-client] __nsApplyStyleUpdate is unavailable; skipping seeded app.css replay');
146
+ }
147
+ return;
148
+ }
149
+ const cssUrl = __NS_BROWSER_RUNTIME_ORIGIN__ + '/src/app.css?direct=1&t=' + String(Date.now());
150
+ apply({ url: cssUrl, cssText });
151
+ globalThis.__NS_HMR_HTTP_APP_CSS_APPLIED__ = true;
152
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
153
+ console.info('[ns-entry] app.css applied in HTTP core realm');
154
+ }
155
+ }
156
+
157
+ async function __nsBrowserRuntimeFetchText(url) {
158
+ try {
159
+ if (typeof globalThis.fetch === 'function') {
160
+ const res = await globalThis.fetch(url);
161
+ return await res.text();
162
+ }
163
+ const Http = globalThis.Http;
164
+ if (Http && typeof Http.getString === 'function') {
165
+ return await Http.getString(url);
166
+ }
167
+ } catch (error) {
168
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
169
+ console.warn('[ns-browser-runtime-client] failed to fetch text', url, error);
170
+ }
171
+ }
172
+ return '';
173
+ }
174
+
175
+ async function __nsBrowserRuntimeHandleCssUpdates(msg) {
176
+ const updates = Array.isArray(msg?.updates) ? msg.updates : [];
177
+ const apply = globalThis.__nsApplyStyleUpdate;
178
+ if (!updates.length || typeof apply !== 'function') {
179
+ return;
180
+ }
181
+ for (const update of updates) {
182
+ const cssPath = update?.path || update?.acceptedPath || '';
183
+ if (!cssPath) {
184
+ continue;
185
+ }
186
+ const timestamp = update?.timestamp || Date.now();
187
+ const sep = cssPath.includes('?') ? '&' : '?';
188
+ const url = __NS_BROWSER_RUNTIME_ORIGIN__ + cssPath + sep + 'direct=1&t=' + String(timestamp);
189
+ const cssText = await __nsBrowserRuntimeFetchText(url);
190
+ if (typeof cssText === 'string' && cssText.length) {
191
+ apply({ url, cssText });
192
+ }
193
+ }
194
+ }
195
+
196
+ function __nsBrowserRuntimeHandleAngularUpdate() {
197
+ const reboot = globalThis.__reboot_ng_modules__;
198
+ if (typeof reboot !== 'function') {
199
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
200
+ console.warn('[ns-browser-runtime-client] Angular reboot hook unavailable');
201
+ }
202
+ return;
203
+ }
204
+ try {
205
+ globalThis.__NS_HMR_IMPORT_NONCE__ = (typeof globalThis.__NS_HMR_IMPORT_NONCE__ === 'number' ? globalThis.__NS_HMR_IMPORT_NONCE__ : 0) + 1;
206
+ } catch {}
207
+ try {
208
+ globalThis.__NS_DEV_RESET_IN_PROGRESS__ = true;
209
+ } catch {}
210
+ try {
211
+ reboot(false);
212
+ } finally {
213
+ try {
214
+ globalThis.__NS_DEV_RESET_IN_PROGRESS__ = false;
215
+ } catch {}
216
+ }
217
+ }
218
+
219
+ function __nsBrowserRuntimeHandleSocketMessage(msg) {
220
+ if (!msg || typeof msg.type !== 'string') {
221
+ return;
222
+ }
223
+ if (msg.type === 'ns:hmr-full-graph') {
224
+ globalThis.__NS_HMR_BROWSER_RUNTIME_GRAPH_VERSION__ = typeof msg.version === 'number' ? msg.version : 0;
225
+ return;
226
+ }
227
+ if (globalThis.__NS_HMR_BROWSER_RUNTIME_DELEGATED__) {
228
+ return;
229
+ }
230
+ if (msg.type === 'ns:angular-update') {
231
+ __nsBrowserRuntimeHandleAngularUpdate();
232
+ return;
233
+ }
234
+ if (msg.type === 'ns:css-updates') {
235
+ void __nsBrowserRuntimeHandleCssUpdates(msg);
236
+ }
237
+ }
238
+
239
+ function __nsBrowserRuntimeScheduleReconnect() {
240
+ if (__nsBrowserRuntimeSocketReconnectTimer) {
241
+ return;
242
+ }
243
+ __nsBrowserRuntimeSocketReconnectTimer = setTimeout(() => {
244
+ __nsBrowserRuntimeSocketReconnectTimer = null;
245
+ __nsBrowserRuntimeConnectSocket();
246
+ }, 1000);
247
+ }
248
+
249
+ function __nsBrowserRuntimeClearDelegationTimer() {
250
+ if (__nsBrowserRuntimeDelegationTimer) {
251
+ clearTimeout(__nsBrowserRuntimeDelegationTimer);
252
+ __nsBrowserRuntimeDelegationTimer = null;
253
+ }
254
+ }
255
+
256
+ function __nsBrowserRuntimeCloseFallbackSocket(reason) {
257
+ __nsBrowserRuntimeClearDelegationTimer();
258
+ const ws = __nsBrowserRuntimeSocket;
259
+ if (ws) {
260
+ try {
261
+ ws.onopen = null;
262
+ ws.onmessage = null;
263
+ ws.onerror = null;
264
+ ws.onclose = null;
265
+ } catch {}
266
+ try {
267
+ ws.close();
268
+ } catch {}
269
+ }
270
+ __nsBrowserRuntimeSocket = null;
271
+ globalThis.__NS_HMR_BROWSER_RUNTIME_SOCKET_READY__ = false;
272
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
273
+ console.info('[ns-browser-runtime-client] delegated to full HMR client; closing bootstrap fallback socket', reason || 'delegated');
274
+ }
275
+ }
276
+
277
+ function __nsBrowserRuntimeWaitForDelegation(startedAt) {
278
+ if (globalThis.__NS_HMR_BROWSER_RUNTIME_DELEGATED__) {
279
+ __nsBrowserRuntimeClearDelegationTimer();
280
+ return;
281
+ }
282
+ if (globalThis.__NS_HMR_CLIENT_SOCKET_READY__) {
283
+ globalThis.__NS_HMR_BROWSER_RUNTIME_DELEGATED__ = true;
284
+ __nsBrowserRuntimeCloseFallbackSocket('full-client-ready');
285
+ return;
286
+ }
287
+ if (!__nsBrowserRuntimeDelegationWarningIssued && Date.now() - startedAt >= 10000) {
288
+ __nsBrowserRuntimeDelegationWarningIssued = true;
289
+ console.warn('[ns-browser-runtime-client] full HMR client did not confirm websocket readiness; keeping bootstrap fallback active');
290
+ __nsBrowserRuntimeClearDelegationTimer();
291
+ return;
292
+ }
293
+ __nsBrowserRuntimeDelegationTimer = setTimeout(() => {
294
+ __nsBrowserRuntimeDelegationTimer = null;
295
+ __nsBrowserRuntimeWaitForDelegation(startedAt);
296
+ }, 100);
297
+ }
298
+
299
+ function __nsBrowserRuntimeTrackDelegation() {
300
+ if (globalThis.__NS_HMR_BROWSER_RUNTIME_DELEGATED__) {
301
+ return;
302
+ }
303
+ __nsBrowserRuntimeDelegationWarningIssued = false;
304
+ __nsBrowserRuntimeClearDelegationTimer();
305
+ __nsBrowserRuntimeWaitForDelegation(Date.now());
306
+ }
307
+
308
+ function __nsBrowserRuntimeConnectSocket() {
309
+ const WebSocketCtor = globalThis.WebSocket;
310
+ if (typeof WebSocketCtor !== 'function') {
311
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
312
+ console.warn('[ns-browser-runtime-client] WebSocket API unavailable');
313
+ }
314
+ __nsBrowserRuntimeScheduleReconnect();
315
+ return;
316
+ }
317
+ try {
318
+ if (__nsBrowserRuntimeSocket) {
319
+ const readyState = __nsBrowserRuntimeSocket.readyState;
320
+ const openState = typeof __nsBrowserRuntimeSocket.OPEN === 'number' ? __nsBrowserRuntimeSocket.OPEN : 1;
321
+ const connectingState = typeof WebSocketCtor.CONNECTING === 'number' ? WebSocketCtor.CONNECTING : 0;
322
+ if (readyState === openState || readyState === connectingState) {
323
+ return;
324
+ }
325
+ }
326
+ const ws = new WebSocketCtor(__NS_BROWSER_RUNTIME_FALLBACK_WS_URL__);
327
+ __nsBrowserRuntimeSocket = ws;
328
+ ws.onopen = () => {
329
+ globalThis.__NS_HMR_BROWSER_RUNTIME_SOCKET_READY__ = true;
330
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
331
+ console.info('[ns-browser-runtime-client] connected', __NS_BROWSER_RUNTIME_FALLBACK_WS_URL__);
332
+ }
333
+ };
334
+ ws.onmessage = (event) => {
335
+ try {
336
+ const raw = typeof event?.data === 'string' ? event.data : String(event?.data || '');
337
+ if (!raw) {
338
+ return;
339
+ }
340
+ __nsBrowserRuntimeHandleSocketMessage(JSON.parse(raw));
341
+ } catch (error) {
342
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
343
+ console.warn('[ns-browser-runtime-client] failed to process websocket message', error);
344
+ }
345
+ }
346
+ };
347
+ ws.onerror = (error) => {
348
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
349
+ console.warn('[ns-browser-runtime-client] websocket error', error);
350
+ }
351
+ };
352
+ ws.onclose = () => {
353
+ if (__nsBrowserRuntimeSocket === ws) {
354
+ __nsBrowserRuntimeSocket = null;
355
+ }
356
+ globalThis.__NS_HMR_BROWSER_RUNTIME_SOCKET_READY__ = false;
357
+ __nsBrowserRuntimeScheduleReconnect();
358
+ };
359
+ } catch (error) {
360
+ console.warn('[ns-browser-runtime-client] failed to create websocket', error);
361
+ __nsBrowserRuntimeScheduleReconnect();
362
+ }
363
+ }
364
+
365
+ async function __nsBrowserRuntimeEnsureFullClientStarted() {
366
+ if (!__nsBrowserRuntimeHmrClientStartPromise) {
367
+ __nsBrowserRuntimeHmrClientStartPromise = import(__NS_BROWSER_RUNTIME_CLIENT_IMPORT__)
368
+ .then((mod) => {
369
+ const start = mod?.default;
370
+ if (typeof start !== 'function') {
371
+ throw new Error('NativeScript HMR client bootstrap is missing a default export');
372
+ }
373
+ start({ wsUrl: __NS_BROWSER_RUNTIME_FULL_CLIENT_WS_URL__ });
374
+ __nsBrowserRuntimeTrackDelegation();
375
+ })
376
+ .catch((error) => {
377
+ globalThis.__NS_HMR_BROWSER_RUNTIME_CLIENT_ACTIVE__ = false;
378
+ console.error('[ns-browser-runtime-client] failed to start full NativeScript HMR client', __NS_BROWSER_RUNTIME_CLIENT_IMPORT__, error);
379
+ throw error;
380
+ });
381
+ }
382
+ return __nsBrowserRuntimeHmrClientStartPromise;
383
+ }
384
+
385
+ __nsBrowserRuntimeEnsureVendorBootstrap();
386
+
387
+
388
+ if (!globalThis.__NS_HMR_BROWSER_RUNTIME_CLIENT_ACTIVE__) {
389
+ globalThis.__NS_HMR_BROWSER_RUNTIME_CLIENT_ACTIVE__ = true;
390
+ globalThis.__NS_HTTP_ORIGIN__ = __NS_BROWSER_RUNTIME_ORIGIN__;
391
+ __nsBrowserRuntimeConnectSocket();
392
+ const __nsBrowserRuntimeBootWaitStartedAt = Date.now();
393
+ const __nsBrowserRuntimeWaitForBoot = () => {
394
+ if (globalThis.__NS_HMR_BOOT_COMPLETE__) {
395
+ if (__NS_BROWSER_RUNTIME_VERBOSE__) {
396
+ console.info('[ns-browser-runtime-client] boot complete observed; starting full HMR client');
397
+ }
398
+ void __nsBrowserRuntimeReplaySeededCss();
399
+ void __nsBrowserRuntimeEnsureFullClientStarted();
400
+ } else {
401
+ if (!__nsBrowserRuntimeBootWaitWarningIssued && Date.now() - __nsBrowserRuntimeBootWaitStartedAt >= 10000) {
402
+ __nsBrowserRuntimeBootWaitWarningIssued = true;
403
+ console.warn('[ns-browser-runtime-client] boot completion was not observed; full HMR client start is still pending');
404
+ }
405
+ setTimeout(__nsBrowserRuntimeWaitForBoot, 100);
406
+ }
407
+ };
408
+ __nsBrowserRuntimeWaitForBoot();
409
+ }
410
+ `;
411
+ }
8
412
  export function nsHmrClientVitePlugin(opts) {
9
413
  let config;
414
+ const sessionId = new Date().toISOString();
10
415
  const guessLanHost = () => {
11
416
  try {
12
417
  const nets = os.networkInterfaces();
@@ -41,6 +446,61 @@ export function nsHmrClientVitePlugin(opts) {
41
446
  return RESOLVED_ID;
42
447
  return null;
43
448
  },
449
+ configureServer(server) {
450
+ server.middlewares.use((req, res, next) => {
451
+ try {
452
+ const url = new URL(req.url || '', 'http://localhost');
453
+ if (url.pathname === '/__ns_dev__/client') {
454
+ const requestHost = String(req.headers.host || 'localhost:5173');
455
+ const secure = !!config?.server?.https;
456
+ const origin = `${secure ? 'https' : 'http'}://${requestHost}`;
457
+ const wsUrl = `${secure ? 'wss' : 'ws'}://${requestHost}/ns-hmr`;
458
+ const clientFsPath = require.resolve('@nativescript/vite/hmr/client/index.js');
459
+ const projectRoot = config?.root || process.cwd();
460
+ const clientImport = computeClientImportSpecifier({ projectRoot, clientFsPath });
461
+ const code = createNsDevClientBootstrapCode({
462
+ origin,
463
+ wsUrl,
464
+ clientImport,
465
+ verbose: opts.verbose,
466
+ });
467
+ res.setHeader('Access-Control-Allow-Origin', '*');
468
+ res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
469
+ if (req.method === 'OPTIONS') {
470
+ res.statusCode = 204;
471
+ res.end();
472
+ return;
473
+ }
474
+ res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
475
+ res.end(code);
476
+ return;
477
+ }
478
+ if (url.pathname !== '/__ns_dev__/session')
479
+ return next();
480
+ res.setHeader('Access-Control-Allow-Origin', '*');
481
+ res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
482
+ if (req.method === 'OPTIONS') {
483
+ res.statusCode = 204;
484
+ res.end();
485
+ return;
486
+ }
487
+ const descriptor = createNsDevSessionDescriptor({
488
+ projectRoot: config?.root || process.cwd(),
489
+ requestHost: String(req.headers.host || 'localhost:5173'),
490
+ platform: opts.platform,
491
+ sessionId,
492
+ secure: !!config?.server?.https,
493
+ });
494
+ res.setHeader('Content-Type', 'application/json');
495
+ res.end(JSON.stringify(descriptor, null, 2));
496
+ }
497
+ catch (error) {
498
+ res.statusCode = 500;
499
+ res.setHeader('Content-Type', 'application/json');
500
+ res.end(JSON.stringify({ error: error?.message || 'Failed to build NativeScript dev session descriptor' }));
501
+ }
502
+ });
503
+ },
44
504
  load(id) {
45
505
  if (id !== RESOLVED_ID)
46
506
  return null;
@@ -53,28 +513,7 @@ export function nsHmrClientVitePlugin(opts) {
53
513
  const clientFsPath = require.resolve('@nativescript/vite/hmr/client/index.js');
54
514
  // Prefer project root when available; otherwise fall back to cwd.
55
515
  const projectRoot = config?.root || process.cwd();
56
- let clientImport = clientFsPath;
57
- try {
58
- // Compute a project-relative POSIX path when possible. When `path.relative`
59
- // returns an absolute path (this can occur on Windows if roots differ or
60
- // when path.relative returns a drive-letter-prefixed path), avoid creating
61
- // a specifier like `/D:/...` which later gets resolved to `D:\D:\...`.
62
- const rel = path.relative(projectRoot, clientFsPath);
63
- const relPosix = rel.replace(/\\/g, '/');
64
- // If `rel` is absolute (e.g. starts with a drive letter on Windows),
65
- // use a file:// URL for the import so Vite/Rollup do not prepend the
66
- // project root and cause duplicated drive prefixes.
67
- if (path.isAbsolute(rel)) {
68
- clientImport = pathToFileURL(clientFsPath).toString();
69
- }
70
- else {
71
- clientImport = (relPosix.startsWith('.') ? relPosix : `/${relPosix}`).replace(/\/+/g, '/');
72
- }
73
- }
74
- catch {
75
- // On any failure, keep the original path but normalize to POSIX
76
- clientImport = clientFsPath.replace(/\\/g, '/');
77
- }
516
+ const clientImport = computeClientImportSpecifier({ projectRoot, clientFsPath });
78
517
  // Build ws url from Vite server info
79
518
  let host = process.env.NS_HMR_HOST || config?.server?.host;
80
519
  // If Vite is bound to all interfaces, prefer a LAN IP so physical devices work.