@nativescript/vite 0.0.1-alpha.7 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +44 -0
  3. package/{dist/configuration → configuration}/angular.d.ts +1 -1
  4. package/configuration/angular.js +480 -0
  5. package/configuration/angular.js.map +1 -0
  6. package/configuration/base.d.ts +5 -0
  7. package/configuration/base.js +494 -0
  8. package/configuration/base.js.map +1 -0
  9. package/configuration/javascript.d.ts +4 -0
  10. package/configuration/javascript.js +151 -0
  11. package/configuration/javascript.js.map +1 -0
  12. package/{dist/configuration → configuration}/react.d.ts +1 -1
  13. package/{dist/configuration → configuration}/react.js +18 -17
  14. package/configuration/react.js.map +1 -0
  15. package/{dist/configuration → configuration}/solid.d.ts +1 -1
  16. package/{dist/configuration → configuration}/solid.js +17 -16
  17. package/configuration/solid.js.map +1 -0
  18. package/configuration/typescript.d.ts +4 -0
  19. package/configuration/typescript.js +175 -0
  20. package/configuration/typescript.js.map +1 -0
  21. package/{dist/configuration → configuration}/vue.d.ts +1 -1
  22. package/configuration/vue.js +163 -0
  23. package/configuration/vue.js.map +1 -0
  24. package/helpers/angular-linker.d.ts +13 -0
  25. package/helpers/angular-linker.js +181 -0
  26. package/helpers/angular-linker.js.map +1 -0
  27. package/helpers/cli-flags.d.ts +1 -0
  28. package/helpers/cli-flags.js +15 -0
  29. package/helpers/cli-flags.js.map +1 -0
  30. package/{dist/helpers → helpers}/commonjs-plugins.js +14 -13
  31. package/helpers/commonjs-plugins.js.map +1 -0
  32. package/{dist/helpers → helpers}/config-as-json.d.ts +1 -1
  33. package/{dist/helpers → helpers}/config-as-json.js +7 -6
  34. package/helpers/config-as-json.js.map +1 -0
  35. package/helpers/css-platform-plugin.d.ts +10 -0
  36. package/helpers/css-platform-plugin.js +76 -0
  37. package/helpers/css-platform-plugin.js.map +1 -0
  38. package/helpers/css-tree.js +22 -0
  39. package/helpers/css-tree.js.map +1 -0
  40. package/{dist/helpers → helpers}/dynamic-import-plugin.js +8 -7
  41. package/helpers/dynamic-import-plugin.js.map +1 -0
  42. package/helpers/esbuild-platform-resolver.d.ts +14 -0
  43. package/helpers/esbuild-platform-resolver.js +93 -0
  44. package/helpers/esbuild-platform-resolver.js.map +1 -0
  45. package/{dist/helpers → helpers}/external-configs.js +2 -1
  46. package/helpers/external-configs.js.map +1 -0
  47. package/{dist/helpers → helpers}/flavor.d.ts +1 -0
  48. package/helpers/flavor.js +51 -0
  49. package/helpers/flavor.js.map +1 -0
  50. package/{dist/helpers → helpers}/global-defines.d.ts +11 -3
  51. package/helpers/global-defines.js +24 -0
  52. package/helpers/global-defines.js.map +1 -0
  53. package/helpers/logging.d.ts +13 -0
  54. package/helpers/logging.js +111 -0
  55. package/helpers/logging.js.map +1 -0
  56. package/helpers/main-entry.d.ts +10 -0
  57. package/helpers/main-entry.js +215 -0
  58. package/helpers/main-entry.js.map +1 -0
  59. package/{dist/helpers → helpers}/module-resolution.js +4 -3
  60. package/helpers/module-resolution.js.map +1 -0
  61. package/{dist/helpers → helpers}/module-runner-patch.d.ts +1 -1
  62. package/{dist/helpers → helpers}/module-runner-patch.js +10 -12
  63. package/helpers/module-runner-patch.js.map +1 -0
  64. package/helpers/nativeclass-transform.d.ts +7 -0
  65. package/helpers/nativeclass-transform.js +158 -0
  66. package/helpers/nativeclass-transform.js.map +1 -0
  67. package/helpers/nativeclass-transformer-plugin.d.ts +5 -0
  68. package/helpers/nativeclass-transformer-plugin.js +23 -0
  69. package/helpers/nativeclass-transformer-plugin.js.map +1 -0
  70. package/{dist/helpers → helpers}/nativescript-package-resolver.js +18 -17
  71. package/helpers/nativescript-package-resolver.js.map +1 -0
  72. package/{dist/helpers → helpers}/ns-cli-plugins.d.ts +6 -1
  73. package/{dist/helpers → helpers}/ns-cli-plugins.js +31 -51
  74. package/helpers/ns-cli-plugins.js.map +1 -0
  75. package/helpers/package-platform-aliases.d.ts +10 -0
  76. package/{dist/helpers → helpers}/package-platform-aliases.js +18 -22
  77. package/helpers/package-platform-aliases.js.map +1 -0
  78. package/helpers/postcss-platform-config.d.ts +13 -0
  79. package/helpers/postcss-platform-config.js +97 -0
  80. package/helpers/postcss-platform-config.js.map +1 -0
  81. package/helpers/prelink-angular.d.ts +2 -0
  82. package/helpers/prelink-angular.js +117 -0
  83. package/helpers/prelink-angular.js.map +1 -0
  84. package/helpers/preserve-imports.js +38 -0
  85. package/helpers/preserve-imports.js.map +1 -0
  86. package/{dist/helpers → helpers}/project.js +2 -4
  87. package/helpers/project.js.map +1 -0
  88. package/helpers/resolver.d.ts +4 -0
  89. package/{dist/helpers → helpers}/resolver.js +7 -6
  90. package/helpers/resolver.js.map +1 -0
  91. package/helpers/theme-core-plugins.d.ts +14 -0
  92. package/helpers/theme-core-plugins.js +121 -0
  93. package/helpers/theme-core-plugins.js.map +1 -0
  94. package/helpers/ts-config-paths.d.ts +10 -0
  95. package/{dist/helpers → helpers}/ts-config-paths.js +70 -71
  96. package/helpers/ts-config-paths.js.map +1 -0
  97. package/{dist/helpers → helpers}/utils.js +14 -27
  98. package/helpers/utils.js.map +1 -0
  99. package/{dist/helpers → helpers}/workers.js +15 -16
  100. package/helpers/workers.js.map +1 -0
  101. package/{dist/hmr → hmr/client}/css-handler.js +18 -17
  102. package/hmr/client/css-handler.js.map +1 -0
  103. package/hmr/client/index.d.ts +13 -0
  104. package/hmr/client/index.js +1550 -0
  105. package/hmr/client/index.js.map +1 -0
  106. package/hmr/client/utils.d.ts +38 -0
  107. package/hmr/client/utils.js +426 -0
  108. package/hmr/client/utils.js.map +1 -0
  109. package/hmr/entry-runtime.d.ts +8 -0
  110. package/hmr/entry-runtime.js +135 -0
  111. package/hmr/entry-runtime.js.map +1 -0
  112. package/hmr/frameworks/angular/server/strategy.d.ts +2 -0
  113. package/hmr/frameworks/angular/server/strategy.js +101 -0
  114. package/hmr/frameworks/angular/server/strategy.js.map +1 -0
  115. package/hmr/frameworks/vue/client/index.d.ts +22 -0
  116. package/hmr/frameworks/vue/client/index.js +1537 -0
  117. package/hmr/frameworks/vue/client/index.js.map +1 -0
  118. package/hmr/frameworks/vue/server/compiler.d.ts +11 -0
  119. package/hmr/frameworks/vue/server/compiler.js +26 -0
  120. package/hmr/frameworks/vue/server/compiler.js.map +1 -0
  121. package/hmr/frameworks/vue/server/sfc-transforms.d.ts +14 -0
  122. package/hmr/frameworks/vue/server/sfc-transforms.js +282 -0
  123. package/hmr/frameworks/vue/server/sfc-transforms.js.map +1 -0
  124. package/hmr/frameworks/vue/server/strategy.d.ts +2 -0
  125. package/hmr/frameworks/vue/server/strategy.js +273 -0
  126. package/hmr/frameworks/vue/server/strategy.js.map +1 -0
  127. package/hmr/helpers/ast-extract.d.ts +6 -0
  128. package/hmr/helpers/ast-extract.js +72 -0
  129. package/hmr/helpers/ast-extract.js.map +1 -0
  130. package/hmr/helpers/ast-normalizer.d.ts +7 -0
  131. package/hmr/helpers/ast-normalizer.js +772 -0
  132. package/hmr/helpers/ast-normalizer.js.map +1 -0
  133. package/hmr/helpers/babel.d.ts +3 -0
  134. package/hmr/helpers/babel.js +17 -0
  135. package/hmr/helpers/babel.js.map +1 -0
  136. package/hmr/helpers/sanitize.d.ts +6 -0
  137. package/hmr/helpers/sanitize.js +55 -0
  138. package/hmr/helpers/sanitize.js.map +1 -0
  139. package/hmr/helpers/vendor-rewrite.d.ts +1 -0
  140. package/hmr/helpers/vendor-rewrite.js +35 -0
  141. package/hmr/helpers/vendor-rewrite.js.map +1 -0
  142. package/hmr/server/compiler.d.ts +2 -0
  143. package/hmr/server/compiler.js +75 -0
  144. package/hmr/server/compiler.js.map +1 -0
  145. package/hmr/server/constants.d.ts +14 -0
  146. package/hmr/server/constants.js +23 -0
  147. package/hmr/server/constants.js.map +1 -0
  148. package/hmr/server/core-sanitize.d.ts +32 -0
  149. package/hmr/server/core-sanitize.js +134 -0
  150. package/hmr/server/core-sanitize.js.map +1 -0
  151. package/hmr/server/framework-strategy.d.ts +68 -0
  152. package/hmr/server/framework-strategy.js +2 -0
  153. package/hmr/server/framework-strategy.js.map +1 -0
  154. package/hmr/server/index.d.ts +5 -0
  155. package/hmr/server/index.js +19 -0
  156. package/hmr/server/index.js.map +1 -0
  157. package/hmr/server/vite-plugin.d.ts +5 -0
  158. package/{dist/hmr/plugins/plugin-vue.js → hmr/server/vite-plugin.js} +13 -15
  159. package/hmr/server/vite-plugin.js.map +1 -0
  160. package/hmr/server/websocket.d.ts +15 -0
  161. package/hmr/server/websocket.js +5528 -0
  162. package/hmr/server/websocket.js.map +1 -0
  163. package/hmr/shared/runtime/http-only-boot.d.ts +1 -0
  164. package/hmr/shared/runtime/http-only-boot.js +107 -0
  165. package/hmr/shared/runtime/http-only-boot.js.map +1 -0
  166. package/hmr/shared/runtime/root-placeholder.d.ts +1 -0
  167. package/hmr/shared/runtime/root-placeholder.js +142 -0
  168. package/hmr/shared/runtime/root-placeholder.js.map +1 -0
  169. package/hmr/shared/runtime/vendor-bootstrap.d.ts +1 -0
  170. package/hmr/shared/runtime/vendor-bootstrap.js +134 -0
  171. package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -0
  172. package/hmr/shared/vendor/manifest-loader.d.ts +9 -0
  173. package/hmr/shared/vendor/manifest-loader.js +38 -0
  174. package/hmr/shared/vendor/manifest-loader.js.map +1 -0
  175. package/hmr/shared/vendor/manifest.d.ts +34 -0
  176. package/hmr/shared/vendor/manifest.js +787 -0
  177. package/hmr/shared/vendor/manifest.js.map +1 -0
  178. package/hmr/shared/vendor/registry.d.ts +9 -0
  179. package/hmr/shared/vendor/registry.js +62 -0
  180. package/hmr/shared/vendor/registry.js.map +1 -0
  181. package/hmr/vendor-bootstrap.d.ts +3 -0
  182. package/hmr/vendor-bootstrap.js +32 -0
  183. package/hmr/vendor-bootstrap.js.map +1 -0
  184. package/{dist/index.d.ts → index.d.ts} +2 -0
  185. package/{dist/index.js → index.js} +3 -0
  186. package/index.js.map +1 -0
  187. package/package.json +39 -31
  188. package/{dist/polyfills → polyfills}/mdn-data-at-rules.js +1 -0
  189. package/polyfills/mdn-data-at-rules.js.map +1 -0
  190. package/{dist/polyfills → polyfills}/mdn-data-properties.js +1 -0
  191. package/polyfills/mdn-data-properties.js.map +1 -0
  192. package/{dist/polyfills → polyfills}/mdn-data-syntaxes.js +1 -0
  193. package/polyfills/mdn-data-syntaxes.js.map +1 -0
  194. package/{dist/polyfills → polyfills}/module.js +1 -0
  195. package/polyfills/module.js.map +1 -0
  196. package/runtime/core-aliases-early.d.ts +1 -0
  197. package/runtime/core-aliases-early.js +334 -0
  198. package/runtime/core-aliases-early.js.map +1 -0
  199. package/shims/angular-animations-stub.d.ts +8 -0
  200. package/shims/angular-animations-stub.js +14 -0
  201. package/shims/angular-animations-stub.js.map +1 -0
  202. package/{dist/shims → shims}/node-module.js +3 -2
  203. package/shims/node-module.js.map +1 -0
  204. package/{dist/shims → shims}/react-reconciler-constants.js +2 -1
  205. package/shims/react-reconciler-constants.js.map +1 -0
  206. package/{dist/shims → shims}/react-reconciler.js +1 -0
  207. package/shims/react-reconciler.js.map +1 -0
  208. package/{dist/shims → shims}/set-value.js +5 -1
  209. package/shims/set-value.js.map +1 -0
  210. package/transformers/NativeClass/index.d.ts +2 -0
  211. package/transformers/NativeClass/index.js +222 -0
  212. package/transformers/NativeClass/index.js.map +1 -0
  213. package/dist/configuration/angular.js +0 -30
  214. package/dist/configuration/base.d.ts +0 -4
  215. package/dist/configuration/base.js +0 -386
  216. package/dist/configuration/vue.js +0 -45
  217. package/dist/helpers/css-tree.js +0 -21
  218. package/dist/helpers/flavor.js +0 -40
  219. package/dist/helpers/global-defines.js +0 -20
  220. package/dist/helpers/main-entry-hmr-includes.d.ts +0 -1
  221. package/dist/helpers/main-entry-hmr-includes.js +0 -18
  222. package/dist/helpers/main-entry.d.ts +0 -5
  223. package/dist/helpers/main-entry.js +0 -82
  224. package/dist/helpers/package-platform-aliases.d.ts +0 -4
  225. package/dist/helpers/preserve-imports.js +0 -19
  226. package/dist/helpers/resolver.d.ts +0 -4
  227. package/dist/helpers/ts-config-paths.d.ts +0 -4
  228. package/dist/hmr/client-vue.d.ts +0 -6
  229. package/dist/hmr/client-vue.js +0 -585
  230. package/dist/hmr/component-tracker.d.ts +0 -23
  231. package/dist/hmr/component-tracker.js +0 -193
  232. package/dist/hmr/message-handler.d.ts +0 -1
  233. package/dist/hmr/message-handler.js +0 -590
  234. package/dist/hmr/nsv-hooks.d.ts +0 -2
  235. package/dist/hmr/nsv-hooks.js +0 -481
  236. package/dist/hmr/plugins/index.d.ts +0 -1
  237. package/dist/hmr/plugins/index.js +0 -16
  238. package/dist/hmr/plugins/plugin-vue.d.ts +0 -2
  239. package/dist/hmr/plugins/websocket-vue.d.ts +0 -2
  240. package/dist/hmr/plugins/websocket-vue.js +0 -911
  241. package/dist/hmr/runtime-vue.d.ts +0 -13
  242. package/dist/hmr/runtime-vue.js +0 -2306
  243. package/dist/hmr/types.d.ts +0 -24
  244. package/dist/hmr/types.js +0 -2
  245. package/dist/transformers/NativeClass/index.d.ts +0 -5
  246. package/dist/transformers/NativeClass/index.js +0 -46
  247. /package/{dist/helpers → helpers}/commonjs-plugins.d.ts +0 -0
  248. /package/{dist/helpers → helpers}/css-tree.d.ts +0 -0
  249. /package/{dist/helpers → helpers}/dynamic-import-plugin.d.ts +0 -0
  250. /package/{dist/helpers → helpers}/external-configs.d.ts +0 -0
  251. /package/{dist/helpers → helpers}/module-resolution.d.ts +0 -0
  252. /package/{dist/helpers → helpers}/nativescript-package-resolver.d.ts +0 -0
  253. /package/{dist/helpers → helpers}/preserve-imports.d.ts +0 -0
  254. /package/{dist/helpers → helpers}/project.d.ts +0 -0
  255. /package/{dist/helpers → helpers}/utils.d.ts +0 -0
  256. /package/{dist/helpers → helpers}/workers.d.ts +0 -0
  257. /package/{dist/hmr → hmr/client}/css-handler.d.ts +0 -0
  258. /package/{dist/polyfills → polyfills}/mdn-data-at-rules.d.ts +0 -0
  259. /package/{dist/polyfills → polyfills}/mdn-data-properties.d.ts +0 -0
  260. /package/{dist/polyfills → polyfills}/mdn-data-syntaxes.d.ts +0 -0
  261. /package/{dist/polyfills → polyfills}/module.d.ts +0 -0
  262. /package/{dist/shims → shims}/node-module.d.ts +0 -0
  263. /package/{dist/shims → shims}/react-reconciler-constants.d.ts +0 -0
  264. /package/{dist/shims → shims}/react-reconciler.d.ts +0 -0
  265. /package/{dist/shims → shims}/set-value.d.ts +0 -0
@@ -1,911 +0,0 @@
1
- import { WebSocketServer } from "ws";
2
- import path from "path";
3
- import { readFileSync, readdirSync, statSync } from "fs";
4
- import { createHash } from "node:crypto";
5
- // Helper: remove balanced `if (import.meta.hot) { ... }` blocks to avoid orphan fragments
6
- function stripImportMetaHotBlocks(input) {
7
- let out = input;
8
- const re = /if\s*\(\s*import\.meta\.hot\s*\)\s*\{/g;
9
- let m;
10
- while ((m = re.exec(out)) !== null) {
11
- let start = m.index;
12
- let i = start + m[0].length;
13
- let depth = 1;
14
- while (i < out.length && depth > 0) {
15
- const ch = out[i++];
16
- if (ch === "{")
17
- depth++;
18
- else if (ch === "}")
19
- depth--;
20
- }
21
- // Replace the whole balanced block with a comment
22
- out =
23
- out.slice(0, start) + "// Removed import.meta.hot block\n" + out.slice(i);
24
- re.lastIndex = start; // reset search after modification
25
- }
26
- return out;
27
- }
28
- // Helper: remove common Vue HMR runtime statements and orphan else blocks
29
- function stripVueHmrRuntimeNoise(input) {
30
- let out = input;
31
- // Remove standalone createRecord/reload/rerender calls
32
- out = out.replace(/__VUE_HMR_RUNTIME__\.(?:createRecord|reload|rerender)\s*\([\s\S]*?\);\s*/g, "");
33
- // Remove patterns like `} else { __VUE_HMR_RUNTIME__.reload(...); }`
34
- out = out.replace(/\}\s*else\s*\{\s*__VUE_HMR_RUNTIME__\.(?:reload|rerender)\s*\([\s\S]*?\);\s*\}\s*/g, "");
35
- // Remove orphan `else { __VUE_HMR_RUNTIME__... }` if the preceding `if (import.meta.hot) {}` was stripped
36
- out = out.replace(/(?:^|\n)\s*else\s*\{\s*__VUE_HMR_RUNTIME__\.(?:reload|rerender)\s*\([\s\S]*?\);\s*\}\s*/g, "\n");
37
- // Collapse any now-empty `else {}` blocks
38
- out = out.replace(/\}\s*else\s*\{\s*\}\s*/g, "}\n");
39
- return out;
40
- }
41
- // Helper: Strip anything between the compiled HMR id assignment and the export default
42
- // This nukes any remaining HMR scaffolding the compiler injects and avoids syntax drift
43
- function stripVueHmrTail(input) {
44
- let out = input;
45
- // Match from a line containing `.__hmrId = "...";` up to but not including the `export default` line
46
- out = out.replace(/\n[^\n]*__hmrId\s*=\s*['\"][^'\"]+['\"];[\s\S]*?(?=\n\s*export\s+default)/g, (match) => {
47
- // Keep just a single newline to preserve spacing before export
48
- return "\n";
49
- });
50
- // Also guard against any stray `typeof __VUE_HMR_RUNTIME__ !== "undefined" && ...` lines left over
51
- out = out.replace(/^[^\n]*typeof\s+__VUE_HMR_RUNTIME__[^\n]*$/gm, "");
52
- return out;
53
- }
54
- // Helper: remove named specifiers from import curly lists; drop import if empty
55
- function removeNamedImports(code, namesToRemove) {
56
- const re = /^(\s*import\s*\{)([^}]*)(\}\s*from\s*['"][^'"]+['"];?)/gm;
57
- return code.replace(re, (_m, p1, specList, p3) => {
58
- const remaining = specList
59
- .split(",")
60
- .map((s) => s.trim())
61
- .filter(Boolean)
62
- .filter((entry) => {
63
- // entry like: name OR name as alias
64
- const base = entry.split(/\s+as\s+/i)[0].trim();
65
- return !namesToRemove.includes(base);
66
- });
67
- if (!remaining.length)
68
- return "";
69
- return `${p1} ${remaining.join(", ")} ${p3}`;
70
- });
71
- }
72
- // Helper: inject const bindings from globals for the given names
73
- function injectGlobalsBindings(code, names) {
74
- if (!names.length)
75
- return code;
76
- const lines = names.map((n) => `const ${n} = globalThis.${n};`);
77
- return lines.join("\n") + "\n" + code;
78
- }
79
- export function hmrWebSocketVue(verboseLogs = false) {
80
- let wss = null;
81
- // Map of project-relative vue path -> device-local hashed filename (e.g., sfc-<hash>.mjs)
82
- const sfcFileMap = new Map();
83
- let registrySent = false;
84
- return {
85
- name: "pure-vue-websocket",
86
- apply: "serve",
87
- configureServer(server) {
88
- const httpServer = server.httpServer;
89
- if (!httpServer)
90
- return;
91
- wss = new WebSocketServer({ noServer: true, path: "/ns-hmr" });
92
- if (verboseLogs)
93
- console.log("[pure-vue-ws] WebSocket server configured on /ns-hmr");
94
- httpServer.on("upgrade", (request, socket, head) => {
95
- const pathname = new URL(request.url || "", "http://localhost")
96
- .pathname;
97
- if (pathname === "/ns-hmr") {
98
- wss?.handleUpgrade(request, socket, head, (ws) => {
99
- wss?.emit("connection", ws, request);
100
- });
101
- }
102
- });
103
- wss.on("connection", async (ws) => {
104
- if (verboseLogs)
105
- console.log("[pure-vue-ws] Client connected to /ns-hmr");
106
- ws.on("close", () => verboseLogs && console.log("[pure-vue-ws] Client disconnected"));
107
- // Send SFC registry once on first client connection
108
- try {
109
- if (!registrySent) {
110
- await buildAndSendSfcRegistry(server, sfcFileMap, wss);
111
- registrySent = true;
112
- }
113
- }
114
- catch (e) {
115
- console.warn("[pure-vue-ws] Failed to send SFC registry:", e?.message || e);
116
- }
117
- });
118
- // console.log("[pure-vue-ws] WebSocket server configured on /ns-hmr");
119
- },
120
- async handleHotUpdate(ctx) {
121
- const { file, server } = ctx;
122
- if (!wss)
123
- return;
124
- // Fast-path: handle plain CSS updates via our single socket with a dedicated message
125
- if (file.endsWith(".css")) {
126
- try {
127
- const root = server.config.root || process.cwd();
128
- let rel = path.posix.join("/", path.posix
129
- .normalize(path.relative(root, file))
130
- .split(path.sep)
131
- .join("/"));
132
- if (!rel.startsWith("/"))
133
- rel = "/" + rel;
134
- const ts = Date.now();
135
- const isHttps = !!server.config.server?.https;
136
- let origin = null;
137
- const urls = server.resolvedUrls;
138
- if (urls?.local?.length) {
139
- origin = String(urls.local[0]).replace(/\/$/, "");
140
- }
141
- else {
142
- const httpServer = server.httpServer;
143
- const addr = httpServer?.address?.();
144
- const port = Number(server.config.server?.port || addr?.port || 5173);
145
- const hostCfg = server.config.server?.host;
146
- const host = typeof hostCfg === "string" && hostCfg !== "0.0.0.0" ? hostCfg : "127.0.0.1";
147
- origin = `${isHttps ? "https" : "http"}://${host}:${port}`;
148
- }
149
- const update = { type: "css-update", path: rel, acceptedPath: rel, timestamp: ts };
150
- const cssMsg = { type: "ns:css-updates", origin: origin || undefined, updates: [update] };
151
- wss.clients.forEach((client) => {
152
- if (client.readyState === client.OPEN)
153
- client.send(JSON.stringify(cssMsg));
154
- });
155
- return;
156
- }
157
- catch (e) {
158
- console.warn("[pure-vue-ws] Failed to process CSS HMR for", file, e?.message || e);
159
- return;
160
- }
161
- }
162
- if (!file.endsWith(".vue"))
163
- return;
164
- try {
165
- // Build a project-root relative path that matches Vite dev served path
166
- const root = server.config.root || process.cwd();
167
- let rel = path.posix.join("/", path.posix
168
- .normalize(path.relative(root, file))
169
- .split(path.sep)
170
- .join("/"));
171
- // Ensure leading slash
172
- if (!rel.startsWith("/"))
173
- rel = "/" + rel;
174
- // Construct template path the client can request from the dev server
175
- const templatePath = `${rel}?vue&type=template`;
176
- const id = path
177
- .basename(file)
178
- .replace(/\.vue$/i, "")
179
- .toLowerCase();
180
- // Compute a stable hashed HMR id similar to webpack/vue plugin behavior
181
- const hmrId = createHash("md5").update(rel).digest("hex").slice(0, 8);
182
- // Get absolute file path for reference (simulator can't access but useful for debugging)
183
- const absolutePath = `file://${path.resolve(file)}`;
184
- const ts = Date.now(); // Compute absolute origin for the dev server
185
- const isHttps = !!server.config.server?.https;
186
- // Prefer resolvedUrls from Vite when available
187
- let origin = null;
188
- const urls = server.resolvedUrls;
189
- if (urls?.local?.length) {
190
- // A local URL is like http://127.0.0.1:5173/
191
- origin = String(urls.local[0]).replace(/\/$/, "");
192
- }
193
- else {
194
- const httpServer = server.httpServer;
195
- const addr = httpServer?.address?.();
196
- const port = Number(server.config.server?.port || addr?.port || 5173);
197
- const hostCfg = server.config.server?.host;
198
- // Default to 127.0.0.1 for iOS simulator reliability
199
- const host = typeof hostCfg === "string" && hostCfg !== "0.0.0.0"
200
- ? hostCfg
201
- : "127.0.0.1";
202
- origin = `${isHttps ? "https" : "http"}://${host}:${port}`;
203
- }
204
- // Try to get transformed code to avoid HTTP fetch when possible
205
- let templateCode;
206
- try {
207
- const transformed = await server.transformRequest(templatePath);
208
- if (transformed?.code)
209
- templateCode = transformed.code;
210
- }
211
- catch (e) {
212
- // non-fatal
213
- }
214
- // Helper to embed minimal HMR runtime polyfills and rewrite imports to on-device vendor.mjs
215
- // Also rewrites any `.vue` sub-imports to local hashed SFC module filenames (./sfc-<hash>.mjs)
216
- function embedHmrRuntimeInModule(code, importerRel) {
217
- const vendorMjs = "~/vendor.mjs"; // NativeScript app-root alias
218
- const hmrPrelude = `
219
- // Embedded HMR Runtime for NativeScript Simulator (minimal)
220
- const createHotContext = (id) => ({
221
- on: (event, handler) => {
222
- if (!globalThis.__NS_HMR_HANDLERS__) globalThis.__NS_HMR_HANDLERS__ = new Map();
223
- if (!globalThis.__NS_HMR_HANDLERS__.has(id)) globalThis.__NS_HMR_HANDLERS__.set(id, []);
224
- globalThis.__NS_HMR_HANDLERS__.get(id).push({ event, handler });
225
- },
226
- accept: (handler) => {
227
- if (!globalThis.__NS_HMR_ACCEPTS__) globalThis.__NS_HMR_ACCEPTS__ = new Map();
228
- globalThis.__NS_HMR_ACCEPTS__.set(id, handler);
229
- }
230
- });
231
-
232
- if (typeof import.meta === 'undefined') {
233
- // Basic meta polyfill; hot is not used directly after rewrite
234
- // @ts-ignore
235
- globalThis.importMeta = { hot: null };
236
- } else if (!import.meta.hot) {
237
- // @ts-ignore
238
- import.meta.hot = null;
239
- }
240
-
241
- // Expose Vite-like hot context factory
242
- // eslint-disable-next-line @typescript-eslint/naming-convention
243
- const __vite__createHotContext = createHotContext;
244
-
245
- // Ensure __VUE_HMR_RUNTIME__ exists (client installs a real one)
246
- if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
247
- // @ts-ignore
248
- globalThis.__VUE_HMR_RUNTIME__ = {
249
- createRecord: () => true,
250
- reload: () => {},
251
- rerender: () => {},
252
- };
253
- }
254
-
255
- // Local copy of _export_sfc helper used by Vue SFCs
256
- function _export_sfc(sfc, props) {
257
- if (props && Array.isArray(props)) {
258
- for (const [key, value] of props) {
259
- if (key === 'render') sfc.render = value;
260
- else sfc[key] = value;
261
- }
262
- }
263
- return sfc;
264
- }
265
-
266
- // Ensure _defineComponent is available by binding from globalThis (set by the HMR client)
267
- // Fallback to identity to keep runtime working even if not provided
268
- const _defineComponent = globalThis._defineComponent || globalThis.defineComponent || ((o) => o);
269
- `;
270
- let enhanced = String(code);
271
- // Remove any @vite/client imports
272
- enhanced = enhanced.replace(/^.*import.*@vite\/client.*$/gm, "// Removed @vite/client import for simulator compatibility");
273
- // Remove import.meta.hot assignments and handlers (we supply our own minimal polyfill)
274
- enhanced = enhanced.replace(/import\.meta\.hot\s*=\s*__vite__createHotContext\([^)]*\);?/g, "// Removed import.meta.hot assignment - using embedded polyfill");
275
- // Remove entire if (import.meta.hot) { ... } blocks to avoid trailing braces (balanced)
276
- enhanced = stripImportMetaHotBlocks(enhanced);
277
- // Remove direct handler registrations like: import.meta.hot.on(..., () => { ... }) and accept((mod) => {...})
278
- // Robustly strip the entire call including nested arrow function bodies until the matching ');'
279
- enhanced = enhanced.replace(/import\.meta\.hot\.(?:on|accept)\s*\([\s\S]*?\);\s*/g, "");
280
- // Remove common Vue HMR runtime statements and orphan else tails
281
- enhanced = stripVueHmrRuntimeNoise(enhanced);
282
- // Aggressively strip compiler HMR tail between __hmrId and export default
283
- enhanced = stripVueHmrTail(enhanced);
284
- // Drop virtual sub-imports (template/style blocks)
285
- enhanced = enhanced.replace(/import\s+[^"']*\s*from\s*["'][^"']*[?&]vue&type=[^"']*["'];?/g, "// Removed virtual vue sub-import for simulator compatibility");
286
- enhanced = enhanced.replace(/import\s*["'][^"']*[?&]vue&type=style[^"']*["'];?/g, "// Removed CSS virtual import");
287
- // Use the already-loaded on-device vendor bundle for framework imports
288
- enhanced = enhanced.replace(/from\s*["']@vue\/runtime-core["']/g, `from "${vendorMjs}"`);
289
- enhanced = enhanced.replace(/from\s*["']vue["']/g, `from "${vendorMjs}"`);
290
- enhanced = enhanced.replace(/from\s*["']nativescript-vue["']/g, `from "${vendorMjs}"`);
291
- // Also handle Vite-deps resolved paths just in case
292
- enhanced = enhanced.replace(/from\s*["']\/node_modules\/\.vite\/deps\/nativescript-vue.*?["']/g, `from "${vendorMjs}"`);
293
- // Remove export helper import (we provide _export_sfc above)
294
- enhanced = enhanced.replace(/^.*import\s+\{\s*?_export_sfc\s*?\}.*$/gm, "// Removed _export_sfc import - using embedded helper");
295
- // Remove remaining virtual id imports
296
- enhanced = enhanced.replace(/^.*import.*\/@id\/__x00__.*$/gm, "// Removed virtual import id");
297
- // Rewrite .vue sub-component imports to device-local hashed SFC files (strip query if present)
298
- enhanced = enhanced.replace(/(import\s+[^;]*?from\s*["'])([^"'?]*\.vue)(?:\?[^"']*)?(["'])/g, (_m, p1, spec, p3) => {
299
- const importerDir = path.posix.dirname(importerRel);
300
- let key = spec;
301
- if (!key.startsWith("/")) {
302
- // Resolve relative spec to project-absolute (leading slash)
303
- key = path.posix.normalize(path.posix.join(importerDir, spec));
304
- if (!key.startsWith("/"))
305
- key = "/" + key;
306
- }
307
- const fileName = sfcFileMap.get(key);
308
- if (!fileName)
309
- return `${p1}${spec}${p3}`;
310
- return `${p1}./${fileName}${p3}`;
311
- });
312
- // Remove imports of core runtime helpers (we'll map to globals) and inject underscore aliases
313
- const coreFns = [
314
- "resolveComponent", "createVNode", "createTextVNode", "withCtx", "openBlock", "createBlock", "createElementVNode", "createElementBlock",
315
- // extended helpers needed by compiled templates
316
- "Fragment", "createCommentVNode", "renderList", "renderSlot", "toDisplayString", "normalizeClass", "normalizeStyle", "unref"
317
- ];
318
- enhanced = removeNamedImports(enhanced, coreFns);
319
- const needsGlobals = /\b_(resolveComponent|createVNode|createTextVNode|withCtx|openBlock|createBlock|createElementVNode|createElementBlock)\b/.test(enhanced) || /\b(Fragment|createCommentVNode|renderList|renderSlot|toDisplayString|normalizeClass|normalizeStyle|unref)\b/.test(enhanced);
320
- if (needsGlobals) {
321
- const globalsPrelude = [
322
- "const _resolveComponent = globalThis._resolveComponent || globalThis.resolveComponent;",
323
- "const _createVNode = globalThis._createVNode || globalThis.createVNode;",
324
- "const _createTextVNode = globalThis._createTextVNode || globalThis.createTextVNode;",
325
- "const _withCtx = globalThis._withCtx || globalThis.withCtx;",
326
- "const _openBlock = globalThis._openBlock || globalThis.openBlock;",
327
- "const _createBlock = globalThis._createBlock || globalThis.createBlock;",
328
- "const _createElementVNode = globalThis._createElementVNode || globalThis.createElementVNode || globalThis.createVNode;",
329
- "const _createElementBlock = globalThis._createElementBlock || globalThis.createElementBlock || globalThis.createBlock;",
330
- "const Fragment = globalThis.Fragment || globalThis._Fragment;",
331
- "const _Fragment = globalThis._Fragment || globalThis.Fragment;",
332
- "const createCommentVNode = globalThis.createCommentVNode || globalThis._createCommentVNode;",
333
- "const _createCommentVNode = globalThis._createCommentVNode || globalThis.createCommentVNode;",
334
- "const renderList = globalThis.renderList;",
335
- "const _renderList = globalThis._renderList || globalThis.renderList;",
336
- "const renderSlot = globalThis.renderSlot;",
337
- "const _renderSlot = globalThis._renderSlot || globalThis.renderSlot;",
338
- "const toDisplayString = globalThis.toDisplayString || globalThis._toDisplayString;",
339
- "const _toDisplayString = globalThis._toDisplayString || globalThis.toDisplayString;",
340
- "const normalizeClass = globalThis.normalizeClass;",
341
- "const normalizeStyle = globalThis.normalizeStyle;",
342
- "const unref = globalThis.unref || globalThis._unref;",
343
- ].join("\n");
344
- enhanced = globalsPrelude + "\n" + enhanced;
345
- }
346
- // Remove lingering imports of reactive helpers and bind from globals if used
347
- const reactiveFns = ["ref", "computed", "onMounted", "onUnmounted"];
348
- enhanced = removeNamedImports(enhanced, reactiveFns);
349
- // Remove any residual import lines for these names
350
- enhanced = enhanced.replace(/^.*import\s*\{[^}]*\b(ref|computed|onMounted|onUnmounted)\b[^}]*\}\s*from\s*["'][^"']+["'];?\s*$/gm, "");
351
- const reactiveToBind = [];
352
- if (/\bref\b/.test(enhanced))
353
- reactiveToBind.push("ref");
354
- if (/\bcomputed\b/.test(enhanced))
355
- reactiveToBind.push("computed");
356
- if (/\bonMounted\b/.test(enhanced))
357
- reactiveToBind.push("onMounted");
358
- if (/\bonUnmounted\b/.test(enhanced))
359
- reactiveToBind.push("onUnmounted");
360
- if (reactiveToBind.length) {
361
- enhanced = injectGlobalsBindings(enhanced, reactiveToBind);
362
- }
363
- // If code uses $navigate helpers, import only missing ones from vendor to avoid duplicates
364
- const usesNavTo = /\$navigateTo\b/.test(enhanced);
365
- const usesNavBack = /\$navigateBack\b/.test(enhanced);
366
- // Remove any named imports of these helpers from any source to avoid missing exports
367
- if (usesNavTo || usesNavBack) {
368
- const names = [];
369
- if (usesNavTo)
370
- names.push("$navigateTo");
371
- if (usesNavBack)
372
- names.push("$navigateBack");
373
- enhanced = removeNamedImports(enhanced, names);
374
- // Inject globals-based bindings
375
- enhanced = injectGlobalsBindings(enhanced, names);
376
- }
377
- // Finally, prepend the minimal HMR prelude
378
- return hmrPrelude + "\n" + enhanced;
379
- }
380
- const msg = {
381
- type: "ns:vue-template-url",
382
- id,
383
- hmrId,
384
- path: rel,
385
- absolutePath,
386
- templatePath,
387
- templateUrl: origin ? `${origin}${templatePath}` : undefined,
388
- origin: origin || undefined,
389
- code: templateCode,
390
- ts,
391
- };
392
- // APPROACH: Generate new .mjs module for dynamic import (preserves context, uses proper module system)
393
- try {
394
- const source = readFileSync(file, "utf8");
395
- // Transform the entire Vue SFC to a module via Vite's pipeline
396
- const transformResult = await server.transformRequest(rel);
397
- if (transformResult?.code) {
398
- // Before sending dynamic module, ensure any newly imported .vue deps are registered
399
- try {
400
- const importerDir = path.posix.dirname(rel);
401
- const depSpecs = [];
402
- const depRe = /(import\s+[^;]*?from\s*["'])([^"'?]*\.vue)(?:\?[^"']*)?["']/g;
403
- let mm;
404
- while ((mm = depRe.exec(transformResult.code)) !== null) {
405
- const spec = mm[2];
406
- let key = spec;
407
- if (!key.startsWith("/")) {
408
- key = path.posix.normalize(path.posix.join(importerDir, spec));
409
- if (!key.startsWith("/"))
410
- key = "/" + key;
411
- }
412
- depSpecs.push(key);
413
- }
414
- for (const depRel of depSpecs) {
415
- if (!sfcFileMap.has(depRel)) {
416
- const depResult = await server.transformRequest(depRel);
417
- if (depResult?.code) {
418
- const sfcHash = createHash("md5").update(depRel).digest("hex").slice(0, 8);
419
- const depFileName = `sfc-${sfcHash}.mjs`;
420
- sfcFileMap.set(depRel, depFileName);
421
- // Clean and rewrite similar to registry path
422
- let depCode = depResult.code
423
- .replace(/^.*import.*@vite\/client.*$/gm, "")
424
- .replace(/import\.meta\.hot\s*=\s*__vite__createHotContext\([^)]*\);?/g, "");
425
- depCode = stripImportMetaHotBlocks(depCode);
426
- depCode = depCode.replace(/import\.meta\.hot\.(?:on|accept)\s*\([\s\S]*?\);\s*/g, "");
427
- depCode = depCode
428
- .replace(/import\s+[^"']*\s*from\s*["'][^"']*[?&]vue&type=[^"']*["'];?/g, "")
429
- .replace(/import\s*["'][^"']*[?&]vue&type=style[^"']*["'];?/g, "")
430
- .replace(/from\s*["']@vue\/runtime-core["']/g, 'from "~/vendor.mjs"')
431
- .replace(/from\s*["']vue["']/g, 'from "~/vendor.mjs"')
432
- .replace(/from\s*["']nativescript-vue["']/g, 'from "~/vendor.mjs"')
433
- .replace(/from\s*["']\/node_modules\/\.vite\/deps\/nativescript-vue.*?["']/g, 'from "~/vendor.mjs"')
434
- .replace(/^.*import\s+\{\s*?_export_sfc\s*?\}.*$/gm, "")
435
- .replace(/^.*import.*\/@id\/__x00__.*$/gm, "");
436
- depCode = stripVueHmrRuntimeNoise(depCode);
437
- depCode = stripVueHmrTail(depCode);
438
- // Export helper and _defineComponent binding
439
- const exportHelperPrelude = `function _export_sfc(sfc, props){if(props&&Array.isArray(props)){for(const [k,v] of props){if(k==='render')sfc.render=v;else sfc[k]=v;}}return sfc;}`;
440
- if (/\b_defineComponent\b/.test(depCode) && !/\bconst\s+_defineComponent\b/.test(depCode)) {
441
- depCode = `const _defineComponent = globalThis._defineComponent || globalThis.defineComponent || ((o) => o);\n` + depCode;
442
- }
443
- // Remove helper imports and inject globals like registry path
444
- const coreFns = [
445
- "resolveComponent", "createVNode", "createTextVNode", "withCtx", "openBlock", "createBlock", "createElementVNode", "createElementBlock",
446
- "Fragment", "createCommentVNode", "renderList", "renderSlot", "toDisplayString", "normalizeClass", "normalizeStyle", "unref"
447
- ];
448
- depCode = removeNamedImports(depCode, coreFns);
449
- if (/\b_(resolveComponent|createVNode|createTextVNode|withCtx|openBlock|createBlock|createElementVNode|createElementBlock)\b/.test(depCode) || /\b(Fragment|createCommentVNode|renderList|renderSlot|toDisplayString|normalizeClass|normalizeStyle|unref)\b/.test(depCode)) {
450
- const globalsPrelude = [
451
- "const _resolveComponent = globalThis._resolveComponent || globalThis.resolveComponent;",
452
- "const _createVNode = globalThis._createVNode || globalThis.createVNode;",
453
- "const _createTextVNode = globalThis._createTextVNode || globalThis.createTextVNode;",
454
- "const _withCtx = globalThis._withCtx || globalThis.withCtx;",
455
- "const _openBlock = globalThis._openBlock || globalThis.openBlock;",
456
- "const _createBlock = globalThis._createBlock || globalThis.createBlock;",
457
- "const _createElementVNode = globalThis._createElementVNode || globalThis.createElementVNode || globalThis.createVNode;",
458
- "const _createElementBlock = globalThis._createElementBlock || globalThis.createElementBlock || globalThis.createBlock;",
459
- "const Fragment = globalThis.Fragment || globalThis._Fragment;",
460
- "const _Fragment = globalThis._Fragment || globalThis.Fragment;",
461
- "const createCommentVNode = globalThis.createCommentVNode || globalThis._createCommentVNode;",
462
- "const _createCommentVNode = globalThis._createCommentVNode || globalThis.createCommentVNode;",
463
- "const renderList = globalThis.renderList;",
464
- "const _renderList = globalThis._renderList || globalThis.renderList;",
465
- "const renderSlot = globalThis.renderSlot;",
466
- "const _renderSlot = globalThis._renderSlot || globalThis.renderSlot;",
467
- "const toDisplayString = globalThis.toDisplayString || globalThis._toDisplayString;",
468
- "const _toDisplayString = globalThis._toDisplayString || globalThis.toDisplayString;",
469
- "const normalizeClass = globalThis.normalizeClass;",
470
- "const normalizeStyle = globalThis.normalizeStyle;",
471
- "const unref = globalThis.unref || globalThis._unref;",
472
- ].join("\n");
473
- depCode = globalsPrelude + "\n" + depCode;
474
- }
475
- const reactiveFns = ["ref", "computed", "onMounted", "onUnmounted"];
476
- depCode = removeNamedImports(depCode, reactiveFns);
477
- depCode = depCode.replace(/^.*import\s*\{[^}]*\b(ref|computed|onMounted|onUnmounted)\b[^}]*\}\s*from\s*["'][^"']+["'];?\s*$/gm, "");
478
- const reactiveToBind = [];
479
- if (/\bref\b/.test(depCode))
480
- reactiveToBind.push("ref");
481
- if (/\bcomputed\b/.test(depCode))
482
- reactiveToBind.push("computed");
483
- if (/\bonMounted\b/.test(depCode))
484
- reactiveToBind.push("onMounted");
485
- if (/\bonUnmounted\b/.test(depCode))
486
- reactiveToBind.push("onUnmounted");
487
- if (reactiveToBind.length)
488
- depCode = injectGlobalsBindings(depCode, reactiveToBind);
489
- // Nav helpers
490
- if (/\$navigate(To|Back)\b/.test(depCode)) {
491
- depCode = removeNamedImports(depCode, ["$navigateTo", "$navigateBack"]);
492
- depCode = injectGlobalsBindings(depCode, ["$navigateTo", "$navigateBack"]);
493
- }
494
- depCode = exportHelperPrelude + "\n" + depCode;
495
- const depUpdateMsg = {
496
- type: "ns:vue-sfc-registry-update",
497
- path: depRel,
498
- fileName: depFileName,
499
- code: depCode,
500
- ts,
501
- };
502
- wss.clients.forEach((client) => {
503
- if (client.readyState === client.OPEN)
504
- client.send(JSON.stringify(depUpdateMsg));
505
- });
506
- console.log(`[pure-vue-websocket] Registered new SFC dep ${depRel} -> ${depFileName}`);
507
- }
508
- }
509
- }
510
- }
511
- catch (e) {
512
- console.warn("[pure-vue-websocket] Failed ensuring SFC deps:", e?.message || e);
513
- }
514
- // Generate unique module name for this HMR update
515
- const moduleId = `hmr-${id}-${ts}`;
516
- const modulePath = `/${rel}?hmr=${ts}`;
517
- // Send dynamic module reload instruction with embedded HMR runtime
518
- const moduleMsg = {
519
- type: "ns:vue-dynamic-module",
520
- id,
521
- hmrId,
522
- path: rel,
523
- absolutePath,
524
- moduleId,
525
- modulePath,
526
- moduleCode: embedHmrRuntimeInModule(transformResult.code, rel), // Apply HMR runtime embedding here!
527
- originalSource: source,
528
- ts,
529
- };
530
- wss.clients.forEach((client) => {
531
- if (client.readyState === client.OPEN)
532
- client.send(JSON.stringify(moduleMsg));
533
- });
534
- console.log(`[pure-vue-websocket] Sent dynamic module for ${rel}: ${modulePath}`);
535
- // Additionally, if app-level CSS exists (e.g., /src/app.css), emit CSS update so Tailwind class changes apply
536
- try {
537
- const appCssFs = path.resolve(root, "src/app.css");
538
- let cssExists = false;
539
- try {
540
- const st = statSync(appCssFs);
541
- cssExists = st?.isFile?.() || false;
542
- }
543
- catch { }
544
- if (cssExists) {
545
- const cssRel = "/src/app.css";
546
- const update = {
547
- type: "css-update",
548
- path: cssRel,
549
- acceptedPath: cssRel,
550
- timestamp: ts,
551
- };
552
- const cssMsg = {
553
- type: "ns:css-updates",
554
- origin: origin || undefined,
555
- updates: [update],
556
- };
557
- wss.clients.forEach((client) => {
558
- if (client.readyState === client.OPEN)
559
- client.send(JSON.stringify(cssMsg));
560
- });
561
- }
562
- }
563
- catch (e) {
564
- console.warn("[pure-vue-websocket] Failed emitting Tailwind CSS update:", e?.message || e);
565
- }
566
- // Also set the transformed code for template URL fallback
567
- templateCode = transformResult.code;
568
- // Additionally, update (or add) the corresponding registry SFC module on device
569
- try {
570
- const sfcHash = createHash("md5")
571
- .update(rel)
572
- .digest("hex")
573
- .slice(0, 8);
574
- const fileName = sfcFileMap.get(rel) || `sfc-${sfcHash}.mjs`;
575
- sfcFileMap.set(rel, fileName);
576
- // Apply similar transforms as in buildAndSendSfcRegistry
577
- let sfcCode = transformResult.code
578
- // Remove @vite/client
579
- .replace(/^.*import.*@vite\/client.*$/gm, "")
580
- // Remove import.meta.hot assignment
581
- .replace(/import\.meta\.hot\s*=\s*__vite__createHotContext\([^)]*\);?/g, "");
582
- sfcCode = stripImportMetaHotBlocks(sfcCode);
583
- sfcCode = sfcCode.replace(/import\.meta\.hot\.(?:on|accept)\s*\([\s\S]*?\);\s*/g, "");
584
- // Remove virtual blocks
585
- sfcCode = sfcCode
586
- .replace(/import\s+[^"']*\s*from\s*["'][^"']*[?&]vue&type=[^"']*["'];?/g, "")
587
- .replace(/import\s*["'][^"']*[?&]vue&type=style[^"']*["'];?/g, "")
588
- // Vendor rewrites
589
- .replace(/from\s*["']@vue\/runtime-core["']/g, 'from "~/vendor.mjs"')
590
- .replace(/from\s*["']vue["']/g, 'from "~/vendor.mjs"')
591
- .replace(/from\s*["']nativescript-vue["']/g, 'from "~/vendor.mjs"')
592
- .replace(/from\s*["']\/node_modules\/\.vite\/deps\/nativescript-vue.*?["']/g, 'from "~/vendor.mjs"')
593
- // Remove export helper import (we inject our own)
594
- .replace(/^.*import\s+\{\s*?_export_sfc\s*?\}.*$/gm, "")
595
- // Remove remaining virtual id imports
596
- .replace(/^.*import.*\/@id\/__x00__.*$/gm, "");
597
- // Remove Vue HMR runtime noise and orphan else
598
- sfcCode = stripVueHmrRuntimeNoise(sfcCode);
599
- sfcCode = stripVueHmrTail(sfcCode);
600
- // Rewrite internal .vue imports to hashed files (strip any query)
601
- const importerDir = path.posix.dirname(rel);
602
- sfcCode = sfcCode.replace(/(import\s+[^;]*?from\s*["'])([^"'?]*\.vue)(?:\?[^"']*)?(["'])/g, (_m, p1, spec, p3) => {
603
- let key = spec;
604
- if (!key.startsWith("/")) {
605
- key = path.posix.normalize(path.posix.join(importerDir, spec));
606
- if (!key.startsWith("/"))
607
- key = "/" + key;
608
- }
609
- const depFile = sfcFileMap.get(key);
610
- if (!depFile)
611
- return `${p1}${spec}${p3}`;
612
- return `${p1}./${depFile}${p3}`;
613
- });
614
- const exportHelperPrelude = `function _export_sfc(sfc, props){if(props&&Array.isArray(props)){for(const [k,v] of props){if(k==='render')sfc.render=v;else sfc[k]=v;}}return sfc;}`;
615
- // Ensure _defineComponent available via globals
616
- if (/\b_defineComponent\b/.test(sfcCode) &&
617
- !/\bconst\s+_defineComponent\b/.test(sfcCode)) {
618
- sfcCode =
619
- `const _defineComponent = globalThis._defineComponent || globalThis.defineComponent || ((o) => o);\n` +
620
- sfcCode;
621
- }
622
- // Remove core runtime helper imports and map to globals
623
- const coreFns = [
624
- "resolveComponent", "createVNode", "createTextVNode", "withCtx", "openBlock", "createBlock", "createElementVNode", "createElementBlock",
625
- "Fragment", "createCommentVNode", "renderList", "renderSlot", "toDisplayString", "normalizeClass", "normalizeStyle", "unref"
626
- ];
627
- sfcCode = removeNamedImports(sfcCode, coreFns);
628
- if (/\b_(resolveComponent|createVNode|createTextVNode|withCtx|openBlock|createBlock|createElementVNode|createElementBlock)\b/.test(sfcCode) || /\b(Fragment|createCommentVNode|renderList|renderSlot|toDisplayString|normalizeClass|normalizeStyle|unref)\b/.test(sfcCode)) {
629
- const globalsPrelude = [
630
- "const _resolveComponent = globalThis._resolveComponent || globalThis.resolveComponent;",
631
- "const _createVNode = globalThis._createVNode || globalThis.createVNode;",
632
- "const _createTextVNode = globalThis._createTextVNode || globalThis.createTextVNode;",
633
- "const _withCtx = globalThis._withCtx || globalThis.withCtx;",
634
- "const _openBlock = globalThis._openBlock || globalThis.openBlock;",
635
- "const _createBlock = globalThis._createBlock || globalThis.createBlock;",
636
- "const _createElementVNode = globalThis._createElementVNode || globalThis.createElementVNode || globalThis.createVNode;",
637
- "const _createElementBlock = globalThis._createElementBlock || globalThis.createElementBlock || globalThis.createBlock;",
638
- "const Fragment = globalThis.Fragment || globalThis._Fragment;",
639
- "const _Fragment = globalThis._Fragment || globalThis.Fragment;",
640
- "const createCommentVNode = globalThis.createCommentVNode || globalThis._createCommentVNode;",
641
- "const _createCommentVNode = globalThis._createCommentVNode || globalThis.createCommentVNode;",
642
- "const renderList = globalThis.renderList;",
643
- "const _renderList = globalThis._renderList || globalThis.renderList;",
644
- "const renderSlot = globalThis.renderSlot;",
645
- "const _renderSlot = globalThis._renderSlot || globalThis.renderSlot;",
646
- "const toDisplayString = globalThis.toDisplayString || globalThis._toDisplayString;",
647
- "const _toDisplayString = globalThis._toDisplayString || globalThis.toDisplayString;",
648
- "const normalizeClass = globalThis.normalizeClass;",
649
- "const normalizeStyle = globalThis.normalizeStyle;",
650
- "const unref = globalThis.unref || globalThis._unref;",
651
- ].join("\n");
652
- sfcCode = globalsPrelude + "\n" + sfcCode;
653
- }
654
- // Remove lingering reactive helper imports and bind from globals if used
655
- const reactiveFns = ["ref", "computed", "onMounted", "onUnmounted"];
656
- sfcCode = removeNamedImports(sfcCode, reactiveFns);
657
- sfcCode = sfcCode.replace(/^.*import\s*\{[^}]*\b(ref|computed|onMounted|onUnmounted)\b[^}]*\}\s*from\s*["'][^"']+["'];?\s*$/gm, "");
658
- const reactiveToBind = [];
659
- if (/\bref\b/.test(sfcCode))
660
- reactiveToBind.push("ref");
661
- if (/\bcomputed\b/.test(sfcCode))
662
- reactiveToBind.push("computed");
663
- if (/\bonMounted\b/.test(sfcCode))
664
- reactiveToBind.push("onMounted");
665
- if (/\bonUnmounted\b/.test(sfcCode))
666
- reactiveToBind.push("onUnmounted");
667
- if (reactiveToBind.length) {
668
- sfcCode = injectGlobalsBindings(sfcCode, reactiveToBind);
669
- }
670
- // Handle navigation helpers via globals
671
- const usesNavTo = /\$navigateTo\b/.test(sfcCode);
672
- const usesNavBack = /\$navigateBack\b/.test(sfcCode);
673
- if (usesNavTo || usesNavBack) {
674
- const names = [];
675
- if (usesNavTo)
676
- names.push("$navigateTo");
677
- if (usesNavBack)
678
- names.push("$navigateBack");
679
- sfcCode = removeNamedImports(sfcCode, names);
680
- sfcCode = injectGlobalsBindings(sfcCode, names);
681
- }
682
- sfcCode = exportHelperPrelude + "\n" + sfcCode;
683
- const updateMsg = {
684
- type: "ns:vue-sfc-registry-update",
685
- path: rel,
686
- fileName,
687
- code: sfcCode,
688
- ts,
689
- };
690
- wss.clients.forEach((client) => {
691
- if (client.readyState === client.OPEN)
692
- client.send(JSON.stringify(updateMsg));
693
- });
694
- }
695
- catch (e) {
696
- console.warn("[pure-vue-websocket] Failed to send SFC registry update for", rel, e);
697
- }
698
- }
699
- // FALLBACK: Send raw SFC source for on-device compilation if needed
700
- const sfcMsg = {
701
- type: "ns:vue-sfc-source",
702
- id,
703
- hmrId,
704
- path: rel,
705
- absolutePath,
706
- source,
707
- ts,
708
- };
709
- wss.clients.forEach((client) => {
710
- if (client.readyState === client.OPEN)
711
- client.send(JSON.stringify(sfcMsg));
712
- });
713
- }
714
- catch (e) {
715
- console.warn("[pure-vue-websocket] Failed to generate dynamic module:", e);
716
- }
717
- // SECOND: Send transformed template as fallback
718
- console.log("[pure-vue-ws] template-url (fallback)", {
719
- path: rel,
720
- hmrId,
721
- templateUrl: msg.templateUrl,
722
- hasCode: !!templateCode,
723
- });
724
- wss.clients.forEach((client) => {
725
- if (client.readyState === client.OPEN)
726
- client.send(JSON.stringify(msg));
727
- });
728
- // Note: keeping template-url as fallback for debugging/alternative paths
729
- }
730
- catch (e) {
731
- console.warn("[pure-vue-ws] Failed to process HMR for", file, e?.message || e);
732
- }
733
- return ctx.modules;
734
- },
735
- };
736
- }
737
- // Recursively walk directories to find .vue files (excluding common large/irrelevant folders)
738
- // TODO: improve this to walk from base src directory (need to think about workspaces)
739
- function walkVueFiles(dir, acc, root) {
740
- for (const name of readdirSync(dir)) {
741
- const full = path.join(dir, name);
742
- const rel = path.relative(root, full);
743
- // skip
744
- if (name === "node_modules" ||
745
- name === ".git" ||
746
- name === "dist" ||
747
- name === '.ns-vite-build' ||
748
- name === "hooks" ||
749
- name === "platform" ||
750
- name === "platforms" ||
751
- name === "App_Resources") {
752
- continue;
753
- }
754
- const st = statSync(full);
755
- if (st.isDirectory()) {
756
- walkVueFiles(full, acc, root);
757
- }
758
- else if (st.isFile() && name.endsWith(".vue")) {
759
- acc.push("/" + rel.split(path.sep).join("/"));
760
- }
761
- }
762
- }
763
- async function buildAndSendSfcRegistry(server, sfcFileMap, wss) {
764
- const root = server.config.root || process.cwd();
765
- const vueFiles = [];
766
- walkVueFiles(root, vueFiles, root);
767
- if (!vueFiles.length)
768
- return;
769
- // Prepare entries
770
- const entries = [];
771
- for (const rel of vueFiles) {
772
- // Generate stable hashed filename for device-local storage
773
- const hash = createHash("md5").update(rel).digest("hex").slice(0, 8);
774
- const fileName = `sfc-${hash}.mjs`;
775
- sfcFileMap.set(rel, fileName);
776
- }
777
- // Transform all and rewrite their own .vue imports to hashed names and vendor path
778
- for (const rel of vueFiles) {
779
- try {
780
- const result = await server.transformRequest(rel);
781
- if (!result?.code)
782
- continue;
783
- let code = result.code;
784
- // Apply same vendor/virtual/remove-hot rewrites as dynamic modules, but no HMR prelude
785
- code = code
786
- // Remove @vite/client
787
- .replace(/^.*import.*@vite\/client.*$/gm, "// Removed @vite/client import")
788
- // Remove import.meta.hot assignment and blocks
789
- .replace(/import\.meta\.hot\s*=\s*__vite__createHotContext\([^)]*\);?/g, "");
790
- code = stripImportMetaHotBlocks(code);
791
- code = code.replace(/import\.meta\.hot\.(?:on|accept)\s*\([\s\S]*?\);\s*/g, "");
792
- code = code
793
- // Remove virtual blocks
794
- .replace(/import\s+[^"']*\s*from\s*["'][^"']*[?&]vue&type=[^"']*["'];?/g, "// Removed virtual vue import")
795
- .replace(/import\s*["'][^"']*[?&]vue&type=style[^"']*["'];?/g, "// Removed CSS virtual import")
796
- // Vendor rewrites
797
- .replace(/from\s*["']@vue\/runtime-core["']/g, 'from "~/vendor.mjs"')
798
- .replace(/from\s*["']vue["']/g, 'from "~/vendor.mjs"')
799
- .replace(/from\s*["']nativescript-vue["']/g, 'from "~/vendor.mjs"')
800
- .replace(/from\s*["']\/node_modules\/\.vite\/deps\/nativescript-vue.*?["']/g, 'from "~/vendor.mjs"')
801
- // Remove export helper import (we provide one in registry output below)
802
- .replace(/^.*import\s+\{\s*?_export_sfc\s*?\}.*$/gm, "")
803
- // Remove remaining virtual id imports
804
- .replace(/^.*import.*\/@id\/__x00__.*$/gm, "");
805
- code = stripVueHmrRuntimeNoise(code);
806
- code = stripVueHmrTail(code);
807
- // Inject a minimal _export_sfc helper at top to satisfy compiled SFC default export pattern
808
- const exportHelperPrelude = `function _export_sfc(sfc, props){if(props&&Array.isArray(props)){for(const [k,v] of props){if(k==='render')sfc.render=v;else sfc[k]=v;}}return sfc;}`;
809
- code = exportHelperPrelude + "\n" + code;
810
- // Rewrite its own .vue imports to hashed SFC local files, resolving relative paths against importer (strip any query)
811
- const importerDir = path.posix.dirname(rel);
812
- code = code.replace(/(import\s+[^;]*?from\s*["'])([^"'?]*\.vue)(?:\?[^"']*)?(["'])/g, (_m, p1, importPath, p3) => {
813
- let key = importPath;
814
- if (!key.startsWith("/")) {
815
- key = path.posix.normalize(path.posix.join(importerDir, importPath));
816
- if (!key.startsWith("/"))
817
- key = "/" + key;
818
- }
819
- const fileName = sfcFileMap.get(key);
820
- if (!fileName)
821
- return `${p1}${importPath}${p3}`;
822
- return `${p1}./${fileName}${p3}`;
823
- });
824
- // Ensure _defineComponent is available via globals if referenced
825
- if (/\b_defineComponent\b/.test(code) &&
826
- !/\bconst\s+_defineComponent\b/.test(code)) {
827
- code =
828
- `const _defineComponent = globalThis._defineComponent || globalThis.defineComponent || ((o) => o);\n` +
829
- code;
830
- }
831
- // Remove imports for core runtime helper functions and map to globals
832
- const coreFns = [
833
- "resolveComponent", "createVNode", "createTextVNode", "withCtx", "openBlock", "createBlock", "createElementVNode", "createElementBlock",
834
- "Fragment", "createCommentVNode", "renderList", "renderSlot", "toDisplayString", "normalizeClass", "normalizeStyle", "unref"
835
- ];
836
- code = removeNamedImports(code, coreFns);
837
- if (/\b_(resolveComponent|createVNode|createTextVNode|withCtx|openBlock|createBlock|createElementVNode|createElementBlock)\b/.test(code) || /\b(Fragment|createCommentVNode|renderList|renderSlot|toDisplayString|normalizeClass|normalizeStyle|unref)\b/.test(code)) {
838
- const globalsPrelude = [
839
- "const _resolveComponent = globalThis._resolveComponent || globalThis.resolveComponent;",
840
- "const _createVNode = globalThis._createVNode || globalThis.createVNode;",
841
- "const _createTextVNode = globalThis._createTextVNode || globalThis.createTextVNode;",
842
- "const _withCtx = globalThis._withCtx || globalThis.withCtx;",
843
- "const _openBlock = globalThis._openBlock || globalThis.openBlock;",
844
- "const _createBlock = globalThis._createBlock || globalThis.createBlock;",
845
- "const _createElementVNode = globalThis._createElementVNode || globalThis.createElementVNode || globalThis.createVNode;",
846
- "const _createElementBlock = globalThis._createElementBlock || globalThis.createElementBlock || globalThis.createBlock;",
847
- "const Fragment = globalThis.Fragment || globalThis._Fragment;",
848
- "const _Fragment = globalThis._Fragment || globalThis.Fragment;",
849
- "const createCommentVNode = globalThis.createCommentVNode || globalThis._createCommentVNode;",
850
- "const _createCommentVNode = globalThis._createCommentVNode || globalThis.createCommentVNode;",
851
- "const renderList = globalThis.renderList;",
852
- "const _renderList = globalThis._renderList || globalThis.renderList;",
853
- "const renderSlot = globalThis.renderSlot;",
854
- "const _renderSlot = globalThis._renderSlot || globalThis.renderSlot;",
855
- "const toDisplayString = globalThis.toDisplayString || globalThis._toDisplayString;",
856
- "const _toDisplayString = globalThis._toDisplayString || globalThis.toDisplayString;",
857
- "const normalizeClass = globalThis.normalizeClass;",
858
- "const normalizeStyle = globalThis.normalizeStyle;",
859
- "const unref = globalThis.unref || globalThis._unref;",
860
- ].join("\n");
861
- code = globalsPrelude + "\n" + code;
862
- }
863
- // Remove lingering imports of reactive helpers and bind from globals if used
864
- const reactiveFns = ["ref", "computed", "onMounted", "onUnmounted"];
865
- code = removeNamedImports(code, reactiveFns);
866
- code = code.replace(/^.*import\s*\{[^}]*\b(ref|computed|onMounted|onUnmounted)\b[^}]*\}\s*from\s*["'][^"']+["'];?\s*$/gm, "");
867
- const reactiveToBind = [];
868
- if (/\bref\b/.test(code))
869
- reactiveToBind.push("ref");
870
- if (/\bcomputed\b/.test(code))
871
- reactiveToBind.push("computed");
872
- if (/\bonMounted\b/.test(code))
873
- reactiveToBind.push("onMounted");
874
- if (/\bonUnmounted\b/.test(code))
875
- reactiveToBind.push("onUnmounted");
876
- if (reactiveToBind.length) {
877
- code = injectGlobalsBindings(code, reactiveToBind);
878
- }
879
- // Handle navigation helpers using globals instead of vendor exports
880
- const usesNavTo = /\$navigateTo\b/.test(code);
881
- const usesNavBack = /\$navigateBack\b/.test(code);
882
- if (usesNavTo || usesNavBack) {
883
- const names = [];
884
- if (usesNavTo)
885
- names.push("$navigateTo");
886
- if (usesNavBack)
887
- names.push("$navigateBack");
888
- code = removeNamedImports(code, names);
889
- code = injectGlobalsBindings(code, names);
890
- }
891
- const hmrId = createHash("md5").update(rel).digest("hex").slice(0, 8);
892
- const fileName = sfcFileMap.get(rel);
893
- entries.push({ path: rel, fileName, hmrId, code });
894
- }
895
- catch (e) {
896
- console.warn("[pure-vue-ws] Failed transforming", rel, e?.message || e);
897
- }
898
- }
899
- if (!entries.length)
900
- return;
901
- const msg = {
902
- type: "ns:vue-sfc-registry",
903
- entries,
904
- ts: Date.now(),
905
- };
906
- wss.clients.forEach((client) => {
907
- if (client.readyState === client.OPEN)
908
- client.send(JSON.stringify(msg));
909
- });
910
- console.log(`[pure-vue-websocket] Sent SFC registry with ${entries.length} entries`);
911
- }