nativescript 9.1.0-alpha.1 → 9.1.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 (246) hide show
  1. package/lib/commands/prepare.js +5 -0
  2. package/lib/common/definitions/mobile.d.ts +15 -10
  3. package/lib/common/mobile/android/android-emulator-services.js +11 -3
  4. package/lib/common/mobile/emulator-helper.js +1 -0
  5. package/lib/common/mobile/ios/device/ios-device-file-system.js +29 -1
  6. package/lib/controllers/prepare-controller.js +53 -11
  7. package/lib/controllers/run-controller.js +200 -13
  8. package/lib/data/prepare-data.js +4 -0
  9. package/lib/declarations.d.ts +38 -42
  10. package/lib/definitions/ios.d.ts +29 -14
  11. package/lib/definitions/project.d.ts +16 -0
  12. package/lib/options.js +1 -0
  13. package/lib/services/android-plugin-build-service.js +20 -12
  14. package/lib/services/bundler/bundler-compiler-service.js +160 -2
  15. package/lib/services/ios/spm-service.js +170 -10
  16. package/lib/services/ios/xcodebuild-args-service.js +26 -0
  17. package/lib/services/ios/xcodebuild-command-service.js +19 -3
  18. package/lib/services/ios-project-service.js +79 -14
  19. package/lib/services/livesync/ios-livesync-service.js +113 -2
  20. package/lib/services/plugins-service.js +12 -4
  21. package/lib/services/project-data-service.js +14 -11
  22. package/node_modules/debug/LICENSE +20 -0
  23. package/node_modules/debug/README.md +481 -0
  24. package/node_modules/debug/package.json +64 -0
  25. package/node_modules/debug/src/browser.js +272 -0
  26. package/node_modules/debug/src/common.js +292 -0
  27. package/node_modules/debug/src/index.js +10 -0
  28. package/node_modules/debug/src/node.js +263 -0
  29. package/node_modules/ms/index.js +162 -0
  30. package/node_modules/ms/license.md +21 -0
  31. package/node_modules/ms/package.json +38 -0
  32. package/node_modules/ms/readme.md +59 -0
  33. package/node_modules/universal-analytics/.travis.yml +11 -0
  34. package/node_modules/universal-analytics/AcceptableParams.md +757 -0
  35. package/node_modules/universal-analytics/HISTORY.md +170 -0
  36. package/node_modules/universal-analytics/Makefile +5 -0
  37. package/node_modules/universal-analytics/README.md +651 -0
  38. package/node_modules/universal-analytics/index.js +2 -0
  39. package/node_modules/universal-analytics/lib/config.js +171 -0
  40. package/node_modules/universal-analytics/lib/index.js +563 -0
  41. package/node_modules/universal-analytics/lib/request.js +73 -0
  42. package/node_modules/universal-analytics/lib/utils.js +29 -0
  43. package/node_modules/universal-analytics/package.json +33 -0
  44. package/node_modules/universal-analytics/test/_enqueue.js +144 -0
  45. package/node_modules/universal-analytics/test/event.js +346 -0
  46. package/node_modules/universal-analytics/test/exception.js +233 -0
  47. package/node_modules/universal-analytics/test/index.js +141 -0
  48. package/node_modules/universal-analytics/test/item.js +550 -0
  49. package/node_modules/universal-analytics/test/middleware.js +119 -0
  50. package/node_modules/universal-analytics/test/mocha.opts +3 -0
  51. package/node_modules/universal-analytics/test/pageview.js +286 -0
  52. package/node_modules/universal-analytics/test/send.js +232 -0
  53. package/node_modules/universal-analytics/test/set.js +68 -0
  54. package/node_modules/universal-analytics/test/timing.js +363 -0
  55. package/node_modules/universal-analytics/test/transaction.js +371 -0
  56. package/node_modules/uuid/LICENSE.md +9 -0
  57. package/node_modules/uuid/README.md +510 -0
  58. package/node_modules/uuid/dist/cjs/index.d.ts +15 -0
  59. package/node_modules/uuid/dist/cjs/index.js +31 -0
  60. package/node_modules/uuid/dist/cjs/max.d.ts +2 -0
  61. package/node_modules/uuid/dist/cjs/max.js +3 -0
  62. package/node_modules/uuid/dist/cjs/md5.d.ts +4 -0
  63. package/node_modules/uuid/dist/cjs/md5.js +13 -0
  64. package/node_modules/uuid/dist/cjs/native.d.ts +6 -0
  65. package/node_modules/uuid/dist/cjs/native.js +4 -0
  66. package/node_modules/uuid/dist/cjs/nil.d.ts +2 -0
  67. package/node_modules/uuid/dist/cjs/nil.js +3 -0
  68. package/node_modules/uuid/dist/cjs/package.json +1 -0
  69. package/node_modules/uuid/dist/cjs/parse.d.ts +2 -0
  70. package/node_modules/uuid/dist/cjs/parse.js +11 -0
  71. package/node_modules/uuid/dist/cjs/regex.d.ts +2 -0
  72. package/node_modules/uuid/dist/cjs/regex.js +3 -0
  73. package/node_modules/uuid/dist/cjs/rng.d.ts +1 -0
  74. package/node_modules/uuid/dist/cjs/rng.js +13 -0
  75. package/node_modules/uuid/dist/cjs/sha1.d.ts +4 -0
  76. package/node_modules/uuid/dist/cjs/sha1.js +13 -0
  77. package/node_modules/uuid/dist/cjs/stringify.d.ts +3 -0
  78. package/node_modules/uuid/dist/cjs/stringify.js +39 -0
  79. package/node_modules/uuid/dist/cjs/types.d.ts +21 -0
  80. package/node_modules/uuid/dist/cjs/types.js +2 -0
  81. package/node_modules/uuid/dist/cjs/uuid-bin.d.ts +1 -0
  82. package/node_modules/uuid/dist/cjs/uuid-bin.js +72 -0
  83. package/node_modules/uuid/dist/cjs/v1.d.ts +11 -0
  84. package/node_modules/uuid/dist/cjs/v1.js +87 -0
  85. package/node_modules/uuid/dist/cjs/v1ToV6.d.ts +2 -0
  86. package/node_modules/uuid/dist/cjs/v1ToV6.js +13 -0
  87. package/node_modules/uuid/dist/cjs/v3.d.ts +9 -0
  88. package/node_modules/uuid/dist/cjs/v3.js +14 -0
  89. package/node_modules/uuid/dist/cjs/v35.d.ts +7 -0
  90. package/node_modules/uuid/dist/cjs/v35.js +41 -0
  91. package/node_modules/uuid/dist/cjs/v4.d.ts +4 -0
  92. package/node_modules/uuid/dist/cjs/v4.js +29 -0
  93. package/node_modules/uuid/dist/cjs/v5.d.ts +9 -0
  94. package/node_modules/uuid/dist/cjs/v5.js +14 -0
  95. package/node_modules/uuid/dist/cjs/v6.d.ts +4 -0
  96. package/node_modules/uuid/dist/cjs/v6.js +19 -0
  97. package/node_modules/uuid/dist/cjs/v6ToV1.d.ts +2 -0
  98. package/node_modules/uuid/dist/cjs/v6ToV1.js +13 -0
  99. package/node_modules/uuid/dist/cjs/v7.d.ts +9 -0
  100. package/node_modules/uuid/dist/cjs/v7.js +69 -0
  101. package/node_modules/uuid/dist/cjs/validate.d.ts +2 -0
  102. package/node_modules/uuid/dist/cjs/validate.js +7 -0
  103. package/node_modules/uuid/dist/cjs/version.d.ts +2 -0
  104. package/node_modules/uuid/dist/cjs/version.js +10 -0
  105. package/node_modules/uuid/dist/cjs-browser/index.d.ts +15 -0
  106. package/node_modules/uuid/dist/cjs-browser/index.js +31 -0
  107. package/node_modules/uuid/dist/cjs-browser/max.d.ts +2 -0
  108. package/node_modules/uuid/dist/cjs-browser/max.js +3 -0
  109. package/node_modules/uuid/dist/cjs-browser/md5.d.ts +2 -0
  110. package/node_modules/uuid/dist/cjs-browser/md5.js +137 -0
  111. package/node_modules/uuid/dist/cjs-browser/native.d.ts +4 -0
  112. package/node_modules/uuid/dist/cjs-browser/native.js +4 -0
  113. package/node_modules/uuid/dist/cjs-browser/nil.d.ts +2 -0
  114. package/node_modules/uuid/dist/cjs-browser/nil.js +3 -0
  115. package/node_modules/uuid/dist/cjs-browser/package.json +1 -0
  116. package/node_modules/uuid/dist/cjs-browser/parse.d.ts +2 -0
  117. package/node_modules/uuid/dist/cjs-browser/parse.js +11 -0
  118. package/node_modules/uuid/dist/cjs-browser/regex.d.ts +2 -0
  119. package/node_modules/uuid/dist/cjs-browser/regex.js +3 -0
  120. package/node_modules/uuid/dist/cjs-browser/rng.d.ts +1 -0
  121. package/node_modules/uuid/dist/cjs-browser/rng.js +14 -0
  122. package/node_modules/uuid/dist/cjs-browser/sha1.d.ts +2 -0
  123. package/node_modules/uuid/dist/cjs-browser/sha1.js +72 -0
  124. package/node_modules/uuid/dist/cjs-browser/stringify.d.ts +3 -0
  125. package/node_modules/uuid/dist/cjs-browser/stringify.js +39 -0
  126. package/node_modules/uuid/dist/cjs-browser/types.d.ts +21 -0
  127. package/node_modules/uuid/dist/cjs-browser/types.js +2 -0
  128. package/node_modules/uuid/dist/cjs-browser/uuid-bin.d.ts +1 -0
  129. package/node_modules/uuid/dist/cjs-browser/uuid-bin.js +72 -0
  130. package/node_modules/uuid/dist/cjs-browser/v1.d.ts +11 -0
  131. package/node_modules/uuid/dist/cjs-browser/v1.js +87 -0
  132. package/node_modules/uuid/dist/cjs-browser/v1ToV6.d.ts +2 -0
  133. package/node_modules/uuid/dist/cjs-browser/v1ToV6.js +13 -0
  134. package/node_modules/uuid/dist/cjs-browser/v3.d.ts +9 -0
  135. package/node_modules/uuid/dist/cjs-browser/v3.js +14 -0
  136. package/node_modules/uuid/dist/cjs-browser/v35.d.ts +7 -0
  137. package/node_modules/uuid/dist/cjs-browser/v35.js +41 -0
  138. package/node_modules/uuid/dist/cjs-browser/v4.d.ts +4 -0
  139. package/node_modules/uuid/dist/cjs-browser/v4.js +29 -0
  140. package/node_modules/uuid/dist/cjs-browser/v5.d.ts +9 -0
  141. package/node_modules/uuid/dist/cjs-browser/v5.js +14 -0
  142. package/node_modules/uuid/dist/cjs-browser/v6.d.ts +4 -0
  143. package/node_modules/uuid/dist/cjs-browser/v6.js +19 -0
  144. package/node_modules/uuid/dist/cjs-browser/v6ToV1.d.ts +2 -0
  145. package/node_modules/uuid/dist/cjs-browser/v6ToV1.js +13 -0
  146. package/node_modules/uuid/dist/cjs-browser/v7.d.ts +9 -0
  147. package/node_modules/uuid/dist/cjs-browser/v7.js +69 -0
  148. package/node_modules/uuid/dist/cjs-browser/validate.d.ts +2 -0
  149. package/node_modules/uuid/dist/cjs-browser/validate.js +7 -0
  150. package/node_modules/uuid/dist/cjs-browser/version.d.ts +2 -0
  151. package/node_modules/uuid/dist/cjs-browser/version.js +10 -0
  152. package/node_modules/uuid/dist/esm/bin/uuid +2 -0
  153. package/node_modules/uuid/dist/esm/index.d.ts +15 -0
  154. package/node_modules/uuid/dist/esm/index.js +14 -0
  155. package/node_modules/uuid/dist/esm/max.d.ts +2 -0
  156. package/node_modules/uuid/dist/esm/max.js +1 -0
  157. package/node_modules/uuid/dist/esm/md5.d.ts +4 -0
  158. package/node_modules/uuid/dist/esm/md5.js +11 -0
  159. package/node_modules/uuid/dist/esm/native.d.ts +6 -0
  160. package/node_modules/uuid/dist/esm/native.js +2 -0
  161. package/node_modules/uuid/dist/esm/nil.d.ts +2 -0
  162. package/node_modules/uuid/dist/esm/nil.js +1 -0
  163. package/node_modules/uuid/dist/esm/parse.d.ts +2 -0
  164. package/node_modules/uuid/dist/esm/parse.js +9 -0
  165. package/node_modules/uuid/dist/esm/regex.d.ts +2 -0
  166. package/node_modules/uuid/dist/esm/regex.js +1 -0
  167. package/node_modules/uuid/dist/esm/rng.d.ts +1 -0
  168. package/node_modules/uuid/dist/esm/rng.js +10 -0
  169. package/node_modules/uuid/dist/esm/sha1.d.ts +4 -0
  170. package/node_modules/uuid/dist/esm/sha1.js +11 -0
  171. package/node_modules/uuid/dist/esm/stringify.d.ts +3 -0
  172. package/node_modules/uuid/dist/esm/stringify.js +35 -0
  173. package/node_modules/uuid/dist/esm/types.d.ts +21 -0
  174. package/node_modules/uuid/dist/esm/types.js +1 -0
  175. package/node_modules/uuid/dist/esm/uuid-bin.d.ts +1 -0
  176. package/node_modules/uuid/dist/esm/uuid-bin.js +70 -0
  177. package/node_modules/uuid/dist/esm/v1.d.ts +11 -0
  178. package/node_modules/uuid/dist/esm/v1.js +83 -0
  179. package/node_modules/uuid/dist/esm/v1ToV6.d.ts +2 -0
  180. package/node_modules/uuid/dist/esm/v1ToV6.js +10 -0
  181. package/node_modules/uuid/dist/esm/v3.d.ts +9 -0
  182. package/node_modules/uuid/dist/esm/v3.js +9 -0
  183. package/node_modules/uuid/dist/esm/v35.d.ts +7 -0
  184. package/node_modules/uuid/dist/esm/v35.js +36 -0
  185. package/node_modules/uuid/dist/esm/v4.d.ts +4 -0
  186. package/node_modules/uuid/dist/esm/v4.js +27 -0
  187. package/node_modules/uuid/dist/esm/v5.d.ts +9 -0
  188. package/node_modules/uuid/dist/esm/v5.js +9 -0
  189. package/node_modules/uuid/dist/esm/v6.d.ts +4 -0
  190. package/node_modules/uuid/dist/esm/v6.js +17 -0
  191. package/node_modules/uuid/dist/esm/v6ToV1.d.ts +2 -0
  192. package/node_modules/uuid/dist/esm/v6ToV1.js +10 -0
  193. package/node_modules/uuid/dist/esm/v7.d.ts +9 -0
  194. package/node_modules/uuid/dist/esm/v7.js +65 -0
  195. package/node_modules/uuid/dist/esm/validate.d.ts +2 -0
  196. package/node_modules/uuid/dist/esm/validate.js +5 -0
  197. package/node_modules/uuid/dist/esm/version.d.ts +2 -0
  198. package/node_modules/uuid/dist/esm/version.js +8 -0
  199. package/node_modules/uuid/dist/esm-browser/index.d.ts +15 -0
  200. package/node_modules/uuid/dist/esm-browser/index.js +14 -0
  201. package/node_modules/uuid/dist/esm-browser/max.d.ts +2 -0
  202. package/node_modules/uuid/dist/esm-browser/max.js +1 -0
  203. package/node_modules/uuid/dist/esm-browser/md5.d.ts +2 -0
  204. package/node_modules/uuid/dist/esm-browser/md5.js +135 -0
  205. package/node_modules/uuid/dist/esm-browser/native.d.ts +4 -0
  206. package/node_modules/uuid/dist/esm-browser/native.js +2 -0
  207. package/node_modules/uuid/dist/esm-browser/nil.d.ts +2 -0
  208. package/node_modules/uuid/dist/esm-browser/nil.js +1 -0
  209. package/node_modules/uuid/dist/esm-browser/parse.d.ts +2 -0
  210. package/node_modules/uuid/dist/esm-browser/parse.js +9 -0
  211. package/node_modules/uuid/dist/esm-browser/regex.d.ts +2 -0
  212. package/node_modules/uuid/dist/esm-browser/regex.js +1 -0
  213. package/node_modules/uuid/dist/esm-browser/rng.d.ts +1 -0
  214. package/node_modules/uuid/dist/esm-browser/rng.js +11 -0
  215. package/node_modules/uuid/dist/esm-browser/sha1.d.ts +2 -0
  216. package/node_modules/uuid/dist/esm-browser/sha1.js +70 -0
  217. package/node_modules/uuid/dist/esm-browser/stringify.d.ts +3 -0
  218. package/node_modules/uuid/dist/esm-browser/stringify.js +35 -0
  219. package/node_modules/uuid/dist/esm-browser/types.d.ts +21 -0
  220. package/node_modules/uuid/dist/esm-browser/types.js +1 -0
  221. package/node_modules/uuid/dist/esm-browser/uuid-bin.d.ts +1 -0
  222. package/node_modules/uuid/dist/esm-browser/uuid-bin.js +70 -0
  223. package/node_modules/uuid/dist/esm-browser/v1.d.ts +11 -0
  224. package/node_modules/uuid/dist/esm-browser/v1.js +83 -0
  225. package/node_modules/uuid/dist/esm-browser/v1ToV6.d.ts +2 -0
  226. package/node_modules/uuid/dist/esm-browser/v1ToV6.js +10 -0
  227. package/node_modules/uuid/dist/esm-browser/v3.d.ts +9 -0
  228. package/node_modules/uuid/dist/esm-browser/v3.js +9 -0
  229. package/node_modules/uuid/dist/esm-browser/v35.d.ts +7 -0
  230. package/node_modules/uuid/dist/esm-browser/v35.js +36 -0
  231. package/node_modules/uuid/dist/esm-browser/v4.d.ts +4 -0
  232. package/node_modules/uuid/dist/esm-browser/v4.js +27 -0
  233. package/node_modules/uuid/dist/esm-browser/v5.d.ts +9 -0
  234. package/node_modules/uuid/dist/esm-browser/v5.js +9 -0
  235. package/node_modules/uuid/dist/esm-browser/v6.d.ts +4 -0
  236. package/node_modules/uuid/dist/esm-browser/v6.js +17 -0
  237. package/node_modules/uuid/dist/esm-browser/v6ToV1.d.ts +2 -0
  238. package/node_modules/uuid/dist/esm-browser/v6ToV1.js +10 -0
  239. package/node_modules/uuid/dist/esm-browser/v7.d.ts +9 -0
  240. package/node_modules/uuid/dist/esm-browser/v7.js +65 -0
  241. package/node_modules/uuid/dist/esm-browser/validate.d.ts +2 -0
  242. package/node_modules/uuid/dist/esm-browser/validate.js +5 -0
  243. package/node_modules/uuid/dist/esm-browser/version.d.ts +2 -0
  244. package/node_modules/uuid/dist/esm-browser/version.js +8 -0
  245. package/node_modules/uuid/package.json +132 -0
  246. package/package.json +8 -4
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.BundlerCompilerService = void 0;
10
10
  const path = require("path");
11
+ const net = require("net");
11
12
  const semver = require("semver");
12
13
  const _ = require("lodash");
13
14
  const events_1 = require("events");
@@ -34,8 +35,15 @@ class BundlerCompilerService extends events_1.EventEmitter {
34
35
  this.$packageInstallationManager = $packageInstallationManager;
35
36
  this.$projectConfigService = $projectConfigService;
36
37
  this.bundlerProcesses = {};
38
+ // Vite-only: the long-lived `vite serve` dev server the device fetches
39
+ // modules and HMR updates from. Keyed by platform, managed by this CLI
40
+ // so users no longer need a separate `concurrently`/`wait-on` process.
41
+ this.viteServeProcesses = {};
37
42
  this.expectedHashes = {};
38
43
  }
44
+ getViteDistOutputPath(projectDir) {
45
+ return path.join(projectDir, process.env.NS_VITE_DIST_DIR || constants_1.VITE_DIST_FOLDER_NAME);
46
+ }
39
47
  async compileWithWatch(platformData, projectData, prepareData) {
40
48
  return new Promise(async (resolve, reject) => {
41
49
  if (this.bundlerProcesses[platformData.platformNameLowerCase]) {
@@ -44,6 +52,14 @@ class BundlerCompilerService extends events_1.EventEmitter {
44
52
  }
45
53
  let isFirstBundlerWatchCompilation = true;
46
54
  prepareData.watch = true;
55
+ // Bring up the Vite HMR dev server the device fetches modules /
56
+ // HMR updates from. No-op unless bundler is vite + hmr + watch.
57
+ // Fired in parallel with the build watcher; both child processes
58
+ // inherit the adb-reverse env the run-controller set before
59
+ // prepare, so neither one spawns adb on its own. Intentionally not
60
+ // awaited — the device only connects to it at app launch, well
61
+ // after the first build.
62
+ this.startViteDevServer(platformData, projectData, prepareData);
47
63
  try {
48
64
  const childProcess = await this.startBundleProcess(platformData, projectData, prepareData);
49
65
  // Handle Vite differently from webpack
@@ -67,7 +83,7 @@ class BundlerCompilerService extends events_1.EventEmitter {
67
83
  console.log("Received Vite IPC message:", message);
68
84
  }
69
85
  // Copy Vite output files directly to platform destination
70
- const distOutput = path.join(projectData.projectDir, constants_1.VITE_DIST_FOLDER_NAME);
86
+ const distOutput = this.getViteDistOutputPath(projectData.projectDir);
71
87
  const destDir = path.join(platformData.appDestinationDirectoryPath, this.$options.hostProjectModuleName);
72
88
  if (debugLog) {
73
89
  console.log(`Copying from ${distOutput} to ${destDir}.`);
@@ -232,7 +248,7 @@ class BundlerCompilerService extends events_1.EventEmitter {
232
248
  // launch with `Check failed: has_pending_exception()`.
233
249
  if (isVite) {
234
250
  try {
235
- const distOutput = path.join(projectData.projectDir, constants_1.VITE_DIST_FOLDER_NAME);
251
+ const distOutput = this.getViteDistOutputPath(projectData.projectDir);
236
252
  const destDir = path.join(platformData.appDestinationDirectoryPath, this.$options.hostProjectModuleName);
237
253
  this.copyViteBundleToNative(distOutput, destDir);
238
254
  }
@@ -343,6 +359,141 @@ class BundlerCompilerService extends events_1.EventEmitter {
343
359
  await this.$cleanupService.addKillProcess(childProcess.pid.toString());
344
360
  return childProcess;
345
361
  }
362
+ getViteHmrPort() {
363
+ const fromEnv = Number(process.env.NS_HMR_PORT);
364
+ return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 5173;
365
+ }
366
+ /**
367
+ * Spawn and manage the Vite dev server (`vite serve`) for HMR.
368
+ *
369
+ * Why the CLI owns this. With Vite, HMR needs a long-lived dev server
370
+ * (HTTP + the `/ns-hmr` websocket on port 5173) that the device fetches
371
+ * modules and hot updates from — it is SEPARATE from the
372
+ * `vite build --watch` process that emits the `bundle.mjs` bootstrap
373
+ * baked into the app. Historically users wired this up themselves with
374
+ * `concurrently`/`wait-on`, which left two uncoordinated processes both
375
+ * touching adb during cold start (the source of the Android
376
+ * "Searching for devices…" freeze). By spawning it here as a child of
377
+ * the CLI, the dev server inherits the CLI's environment — crucially
378
+ * `NS_ADB_REVERSE_READY`/`NS_DEVICE_SERIAL`/`NS_ADB_PATH` set by the
379
+ * run-controller — so the CLI is the single adb owner and the dev
380
+ * server never spawns adb itself.
381
+ *
382
+ * No-op unless bundler is vite, HMR is on, watch mode, and not release.
383
+ * Best-effort: failures are logged, never thrown — a dev-server hiccup
384
+ * must not fail the run.
385
+ */
386
+ async startViteDevServer(platformData, projectData, prepareData) {
387
+ try {
388
+ if (this.getBundler() !== "vite") {
389
+ return;
390
+ }
391
+ if (!prepareData.watch || !prepareData.hmr || prepareData.release) {
392
+ return;
393
+ }
394
+ const key = platformData.platformNameLowerCase;
395
+ if (this.viteServeProcesses[key]) {
396
+ return;
397
+ }
398
+ const port = this.getViteHmrPort();
399
+ // One dev server per port. Simultaneous multi-platform HMR in a
400
+ // single CLI invocation would collide on 5173 — that case still
401
+ // needs a distinct NS_HMR_PORT per platform, so skip + warn rather
402
+ // than fail to bind.
403
+ const collidingPlatform = Object.keys(this.viteServeProcesses)[0];
404
+ if (collidingPlatform) {
405
+ this.$logger.warn(`Vite dev server already running for '${collidingPlatform}' on port ${port}; skipping a second server for '${key}'. For simultaneous multi-platform HMR, set a distinct NS_HMR_PORT per platform.`);
406
+ return;
407
+ }
408
+ const envData = this.buildEnvData(platformData.platformNameLowerCase, projectData, prepareData);
409
+ const cliArgs = await this.buildEnvCommandLineParams(envData, platformData, projectData, prepareData);
410
+ const additionalNodeArgs = semver.major(process.version) <= 8 ? ["--harmony"] : [];
411
+ if (await this.shouldUsePreserveSymlinksOption()) {
412
+ additionalNodeArgs.push("--preserve-symlinks");
413
+ }
414
+ // `vite serve` (not `build`): runs the dev server and watches on
415
+ // its own — no `--watch`. Env flags (`--env.android --env.hmr …`)
416
+ // go after `--` so vite's CLI doesn't choke on unknown options.
417
+ const args = [
418
+ ...additionalNodeArgs,
419
+ this.getBundlerExecutablePath(projectData),
420
+ "serve",
421
+ `--config=${projectData.bundlerConfigPath}`,
422
+ `--mode=development`,
423
+ "--",
424
+ ...cliArgs,
425
+ ].filter(Boolean);
426
+ const options = {
427
+ cwd: projectData.projectDir,
428
+ // Inherit so the dev server's URLs/logs stream to the user as
429
+ // before. No IPC needed here — the build watcher provides the
430
+ // bundle-complete IPC; the dev server is fetched over HTTP/ws.
431
+ stdio: "inherit",
432
+ env: {
433
+ ...process.env,
434
+ NATIVESCRIPT_BUNDLER_ENV: JSON.stringify(envData),
435
+ },
436
+ };
437
+ if (this.$hostInfo.isWindows) {
438
+ Object.assign(options.env, { APPDATA: process.env.appData });
439
+ }
440
+ this.$logger.info(`Starting Vite dev server (HMR) for ${key} on port ${port}…`);
441
+ const childProcess = this.$childProcess.spawn(process.execPath, args, options);
442
+ this.viteServeProcesses[key] = childProcess;
443
+ await this.$cleanupService.addKillProcess(childProcess.pid.toString());
444
+ childProcess.once("exit", (code) => {
445
+ delete this.viteServeProcesses[key];
446
+ if (code) {
447
+ this.$logger.warn(`Vite dev server for ${key} exited with code ${code}.`);
448
+ }
449
+ });
450
+ // Bounded readiness probe so we can surface a clear log once the
451
+ // device can actually reach modules.
452
+ const ready = await this.waitForPort(port, 30000);
453
+ if (ready) {
454
+ this.$logger.info(`Vite dev server ready on port ${port} (HMR for ${key}).`);
455
+ }
456
+ else {
457
+ this.$logger.trace(`Vite dev server port ${port} not observed open within the readiness probe window; continuing (it may bind shortly).`);
458
+ }
459
+ }
460
+ catch (err) {
461
+ this.$logger.warn(`Failed to start the Vite dev server: ${err}. HMR may be unavailable.`);
462
+ }
463
+ }
464
+ /**
465
+ * Resolve true once `127.0.0.1:<port>` accepts a TCP connection, or
466
+ * false after `timeoutMs`. Used to detect the Vite dev server is up.
467
+ */
468
+ waitForPort(port, timeoutMs) {
469
+ const deadline = Date.now() + timeoutMs;
470
+ return new Promise((resolve) => {
471
+ const attempt = () => {
472
+ const socket = net.connect({ port, host: "127.0.0.1" });
473
+ let settled = false;
474
+ const done = (ok) => {
475
+ if (settled) {
476
+ return;
477
+ }
478
+ settled = true;
479
+ socket.destroy();
480
+ if (ok) {
481
+ resolve(true);
482
+ }
483
+ else if (Date.now() >= deadline) {
484
+ resolve(false);
485
+ }
486
+ else {
487
+ setTimeout(attempt, 250);
488
+ }
489
+ };
490
+ socket.once("connect", () => done(true));
491
+ socket.once("error", () => done(false));
492
+ socket.setTimeout(1000, () => done(false));
493
+ };
494
+ attempt();
495
+ });
496
+ }
346
497
  buildEnvData(platform, projectData, prepareData) {
347
498
  var _a, _b, _c;
348
499
  const { env } = prepareData;
@@ -474,6 +625,13 @@ class BundlerCompilerService extends events_1.EventEmitter {
474
625
  bundlerProcess.kill("SIGINT");
475
626
  delete this.bundlerProcesses[platform];
476
627
  }
628
+ // Tear down the Vite dev server we manage alongside the build watcher.
629
+ const viteServeProcess = this.viteServeProcesses[platform];
630
+ if (viteServeProcess) {
631
+ await this.$cleanupService.removeKillProcess(viteServeProcess.pid.toString());
632
+ viteServeProcess.kill("SIGINT");
633
+ delete this.viteServeProcesses[platform];
634
+ }
477
635
  }
478
636
  handleHMRMessage(message, platformData, projectData, prepareData) {
479
637
  // handle new bundler hmr packets
@@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SPMService = void 0;
4
4
  const yok_1 = require("../../common/yok");
5
5
  const trapezedev_project_1 = require("@nstudio/trapezedev-project");
6
+ const color_1 = require("../../color");
6
7
  const path = require("path");
7
8
  class SPMService {
8
- constructor($logger, $projectConfigService, $xcodebuildCommandService, $xcodebuildArgsService) {
9
+ constructor($logger, $fs, $projectConfigService, $terminalSpinnerService, $xcodebuildCommandService, $xcodebuildArgsService) {
9
10
  this.$logger = $logger;
11
+ this.$fs = $fs;
10
12
  this.$projectConfigService = $projectConfigService;
13
+ this.$terminalSpinnerService = $terminalSpinnerService;
11
14
  this.$xcodebuildCommandService = $xcodebuildCommandService;
12
15
  this.$xcodebuildArgsService = $xcodebuildArgsService;
13
16
  }
@@ -24,7 +27,7 @@ class SPMService {
24
27
  mergePluginSPMPackages(appPackages, pluginPackages) {
25
28
  // include swift packages from plugin configs
26
29
  // but allow app packages to override plugin packages with the same name
27
- const appPackageNames = new Set(appPackages.map(pkg => pkg.name));
30
+ const appPackageNames = new Set(appPackages.map((pkg) => pkg.name));
28
31
  for (const pluginPkg of pluginPackages) {
29
32
  if (appPackageNames.has(pluginPkg.name)) {
30
33
  this.$logger.trace(`SPM: app package overrides plugin package: ${pluginPkg.name}`);
@@ -39,7 +42,7 @@ class SPMService {
39
42
  // return this.getSPMPackages(projectData).length > 0;
40
43
  // }
41
44
  async applySPMPackages(platformData, projectData, pluginSpmPackages) {
42
- var _a;
45
+ var _a, _b;
43
46
  try {
44
47
  const spmPackages = this.getSPMPackages(projectData, platformData.platformNameLowerCase);
45
48
  if (pluginSpmPackages === null || pluginSpmPackages === void 0 ? void 0 : pluginSpmPackages.length) {
@@ -79,23 +82,180 @@ class SPMService {
79
82
  }
80
83
  await project.commit();
81
84
  // finally resolve the dependencies
82
- await this.resolveSPMDependencies(platformData, projectData);
85
+ await this.resolveSPMDependencies(platformData, projectData, {
86
+ showProgress: true,
87
+ });
83
88
  }
84
89
  catch (err) {
90
+ // best-effort, but don't bury the failure below trace level — a red
91
+ // resolve spinner with no visible reason is confusing. Warn with the
92
+ // message, keep the full error at trace.
93
+ this.$logger.warn(`Failed to apply Swift Package dependencies: ${(_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err}`);
85
94
  this.$logger.trace("SPM: error applying SPM packages: ", err);
86
95
  }
87
96
  }
88
- async resolveSPMDependencies(platformData, projectData) {
89
- await this.$xcodebuildCommandService.executeCommand(this.$xcodebuildArgsService
97
+ /**
98
+ * Resolves (downloads + pins) the Swift Package dependencies referenced by
99
+ * the Xcode project. On a first build this is where the NativeScript runtime
100
+ * (now distributed as a remote Swift package) and any other SPM packages are
101
+ * actually downloaded — which can take a while. Pass `showProgress` to render
102
+ * a live spinner so the CLI doesn't look stalled while that happens.
103
+ *
104
+ * In verbose mode (`--log trace`) the condensed spinner is bypassed and
105
+ * xcodebuild's raw resolution log is streamed straight through instead.
106
+ */
107
+ async resolveSPMDependencies(platformData, projectData, options) {
108
+ const args = this.$xcodebuildArgsService
90
109
  .getXcodeProjectArgs(platformData, projectData)
91
110
  .concat([
92
111
  "-destination",
93
112
  "generic/platform=iOS",
94
113
  "-resolvePackageDependencies",
95
- ]), {
96
- cwd: projectData.projectDir,
97
- message: "Resolving SPM dependencies...",
98
- });
114
+ ]);
115
+ // Without progress, or when verbose: let xcodebuild's own resolution log
116
+ // stream straight to the terminal (inherited stdio). Verbose users want
117
+ // the raw log, not a condensed spinner that hides it.
118
+ if (!(options === null || options === void 0 ? void 0 : options.showProgress) || this.$logger.isVerbose()) {
119
+ await this.$xcodebuildCommandService.executeCommand(args, {
120
+ cwd: projectData.projectDir,
121
+ message: "Resolving Swift Package dependencies...",
122
+ });
123
+ return;
124
+ }
125
+ const spinner = this.$terminalSpinnerService.createSpinner();
126
+ const startedAt = Date.now();
127
+ let activity = "Resolving Swift Package dependencies";
128
+ let lineBuffer = "";
129
+ const render = () => {
130
+ const elapsed = Math.round((Date.now() - startedAt) / 1000);
131
+ spinner.text = `${activity}… ${color_1.color.dim(`(${elapsed}s)`)}`;
132
+ };
133
+ // keep the elapsed timer ticking even when xcodebuild is silent (e.g.
134
+ // while a binary artifact downloads) so the user can see it's alive.
135
+ const ticker = setInterval(render, 1000);
136
+ const onProgress = (chunk) => {
137
+ lineBuffer += chunk.data;
138
+ const lines = lineBuffer.split("\n");
139
+ // keep the last (possibly partial) line in the buffer
140
+ lineBuffer = lines.pop();
141
+ for (const line of lines) {
142
+ const described = this.describeSPMActivity(line);
143
+ if (described) {
144
+ activity = described;
145
+ render();
146
+ }
147
+ }
148
+ };
149
+ render();
150
+ spinner.start();
151
+ try {
152
+ await this.$xcodebuildCommandService.executeCommand(args, {
153
+ cwd: projectData.projectDir,
154
+ onProgress,
155
+ });
156
+ spinner.succeed(color_1.color.green("Swift Package dependencies resolved"));
157
+ }
158
+ catch (err) {
159
+ spinner.fail(color_1.color.red("Failed to resolve Swift Package dependencies"));
160
+ throw err;
161
+ }
162
+ finally {
163
+ clearInterval(ticker);
164
+ }
165
+ }
166
+ /**
167
+ * Best-effort pre-resolve before a build so the (potentially slow) first-time
168
+ * Swift package download happens under a clear progress indicator instead of
169
+ * silently inside the subsequent "Xcode build..." step. No-op when the
170
+ * project has no SPM references or they're already resolved.
171
+ */
172
+ async ensureSPMDependenciesResolved(platformData, projectData) {
173
+ if (!this.hasSPMReferences(platformData, projectData)) {
174
+ this.$logger.trace("SPM: project has no Swift Package references.");
175
+ return;
176
+ }
177
+ if (this.arePackagesResolved(platformData, projectData)) {
178
+ this.$logger.trace("SPM: Swift Package dependencies already resolved; skipping pre-resolve.");
179
+ return;
180
+ }
181
+ try {
182
+ await this.resolveSPMDependencies(platformData, projectData, {
183
+ showProgress: true,
184
+ });
185
+ }
186
+ catch (err) {
187
+ // non-fatal: the build itself will resolve packages and surface the
188
+ // authoritative error if something is genuinely wrong.
189
+ this.$logger.trace("SPM: pre-resolve failed (continuing): ", err);
190
+ }
191
+ }
192
+ /**
193
+ * Maps a raw xcodebuild/SwiftPM resolution log line to a concise,
194
+ * user-facing activity description (or null for lines we don't surface).
195
+ */
196
+ describeSPMActivity(line) {
197
+ const trimmed = line.trim();
198
+ if (!trimmed) {
199
+ return null;
200
+ }
201
+ // the big, otherwise-silent wait on a first build: a binary artifact
202
+ // (the NativeScript runtime xcframework) downloading.
203
+ if (/Downloading binary artifact/i.test(trimmed)) {
204
+ if (/ios-spm|nativescript/i.test(trimmed)) {
205
+ return "Downloading the NativeScript runtime (first build only)";
206
+ }
207
+ return "Downloading Swift Package binaries (first build only)";
208
+ }
209
+ if (/^Fetching\b/i.test(trimmed)) {
210
+ return `Fetching ${this.shortenPackageRef(trimmed)}`;
211
+ }
212
+ if (/^Cloning\b/i.test(trimmed)) {
213
+ return `Cloning ${this.shortenPackageRef(trimmed)}`;
214
+ }
215
+ if (/Computing version for/i.test(trimmed)) {
216
+ return "Computing package versions";
217
+ }
218
+ if (/Resolve Package Graph/i.test(trimmed)) {
219
+ return "Resolving Swift Package graph";
220
+ }
221
+ if (/Resolved source packages/i.test(trimmed)) {
222
+ return "Finalizing Swift Package dependencies";
223
+ }
224
+ return null;
225
+ }
226
+ /** Extracts a short, readable name from a SwiftPM repo URL/log line. */
227
+ shortenPackageRef(line) {
228
+ const match = line.match(/https?:\/\/\S+/);
229
+ if (!match) {
230
+ return "Swift Packages";
231
+ }
232
+ return path
233
+ .basename(match[0])
234
+ .replace(/\.git$/, "")
235
+ .replace(/[)\s].*$/, "");
236
+ }
237
+ /** True when the Xcode project references any Swift packages. */
238
+ hasSPMReferences(platformData, projectData) {
239
+ const pbxprojPath = path.join(platformData.projectRoot, `${projectData.projectName}.xcodeproj`, "project.pbxproj");
240
+ if (!this.$fs.exists(pbxprojPath)) {
241
+ return false;
242
+ }
243
+ const contents = this.$fs.readText(pbxprojPath);
244
+ return (contents.includes("XCRemoteSwiftPackageReference") ||
245
+ contents.includes("XCLocalSwiftPackageReference") ||
246
+ contents.includes("packageReferences"));
247
+ }
248
+ /**
249
+ * True when a Package.resolved already exists for the project — i.e. packages
250
+ * have been resolved at least once, so the build's own resolve step will be a
251
+ * fast no-op rather than a slow, silent first-time download.
252
+ */
253
+ arePackagesResolved(platformData, projectData) {
254
+ const candidates = [
255
+ path.join(platformData.projectRoot, `${projectData.projectName}.xcworkspace`, "xcshareddata", "swiftpm", "Package.resolved"),
256
+ path.join(platformData.projectRoot, `${projectData.projectName}.xcodeproj`, "project.xcworkspace", "xcshareddata", "swiftpm", "Package.resolved"),
257
+ ];
258
+ return candidates.some((p) => this.$fs.exists(p));
99
259
  }
100
260
  }
101
261
  exports.SPMService = SPMService;
@@ -100,10 +100,17 @@ class XcodebuildArgsService {
100
100
  // Introduced in Xcode 14+
101
101
  // ref: https://forums.swift.org/t/telling-xcode-14-beta-4-to-trust-build-tool-plugins-programatically/59305/5
102
102
  const skipPackageValidation = "-skipPackagePluginValidation";
103
+ // Introduced in Xcode 15+ to trust Swift macros (compiler plugins)
104
+ // non-interactively. Required for SPM packages that ship macros
105
+ // (e.g. apple/RealityKitScripting), otherwise the build fails with:
106
+ // "Macro '...' from package '...' must be enabled before it can be used"
107
+ // ref: https://developer.apple.com/documentation/xcode/writing-swift-macros
108
+ const skipMacroValidation = "-skipMacroValidation";
103
109
  const extraArgs = [
104
110
  "-scheme",
105
111
  projectData.projectName,
106
112
  skipPackageValidation,
113
+ skipMacroValidation,
107
114
  ];
108
115
  const BUILD_SETTINGS_FILE_PATH = path.join(projectData.appResourcesDirectoryPath, platformData.normalizedPlatformName, constants.BUILD_XCCONFIG_FILE_NAME);
109
116
  // Only include explicit properties from build.xcconfig
@@ -112,6 +119,17 @@ class XcodebuildArgsService {
112
119
  // like cocoapods issues related to ASSETCATALOG_COMPILER_APPICON_NAME
113
120
  // references: https://medium.com/@iostechset/why-cocoapods-eats-app-icons-79fe729808d4
114
121
  // https://github.com/CocoaPods/CocoaPods/issues/7003
122
+ // Xcode 26 makes Swift "explicitly built modules" the default. A
123
+ // regression there prevents macro/compiler-plugin SPM targets from
124
+ // resolving their swift-syntax module dependencies, failing with:
125
+ // "Unable to resolve module dependency: 'SwiftSyntax'" (and SwiftParser,
126
+ // SwiftSyntaxMacros, SwiftCompilerPlugin, SwiftDiagnostics).
127
+ // Passed as a command-line build setting so it overrides ALL targets,
128
+ // including the package targets we don't control.
129
+ // ref: https://forums.swift.org/t/xcode-26-unable-to-find-module-dependency/80516
130
+ const explicitModulesProperty = "SWIFT_ENABLE_EXPLICIT_MODULES";
131
+ const explicitModulesValue = this.$xcconfigService.readPropertyValue(BUILD_SETTINGS_FILE_PATH, explicitModulesProperty) || "NO";
132
+ extraArgs.push(`${explicitModulesProperty}=${explicitModulesValue}`);
115
133
  const deployTargetProperty = "IPHONEOS_DEPLOYMENT_TARGET";
116
134
  const deployTargetVersion = this.$xcconfigService.readPropertyValue(BUILD_SETTINGS_FILE_PATH, deployTargetProperty);
117
135
  if (deployTargetVersion) {
@@ -122,6 +140,14 @@ class XcodebuildArgsService {
122
140
  if (swiftUIBootValue) {
123
141
  extraArgs.push(`${swiftUIBootProperty}=${swiftUIBootValue}`);
124
142
  }
143
+ // Swift macro/compiler-plugin SPM targets must be code-signed with a
144
+ // development team when building for a device. Pass DEVELOPMENT_TEAM as a
145
+ // command-line build setting so it applies to SPM package targets too.
146
+ const developmentTeamProperty = "DEVELOPMENT_TEAM";
147
+ const developmentTeamValue = this.$xcconfigService.readPropertyValue(BUILD_SETTINGS_FILE_PATH, developmentTeamProperty);
148
+ if (developmentTeamValue) {
149
+ extraArgs.push(`${developmentTeamProperty}=${developmentTeamValue}`);
150
+ }
125
151
  if (this.$fs.exists(xcworkspacePath)) {
126
152
  return ["-workspace", xcworkspacePath, ...extraArgs];
127
153
  }
@@ -10,9 +10,22 @@ class XcodebuildCommandService {
10
10
  this.$logger = $logger;
11
11
  }
12
12
  async executeCommand(args, options) {
13
- const { message, cwd, stdio, spawnOptions } = options;
14
- this.$logger.info(message || "Xcode build...");
15
- const childProcessOptions = { cwd, stdio: stdio || "inherit" };
13
+ const { message, cwd, stdio, spawnOptions, onProgress } = options;
14
+ // A caller rendering its own progress UI owns stdout, so skip the
15
+ // default "Xcode build..." line that would otherwise clobber it.
16
+ if (!onProgress) {
17
+ this.$logger.info(message || "Xcode build...");
18
+ }
19
+ const childProcessOptions = {
20
+ cwd,
21
+ stdio: onProgress ? "pipe" : stdio || "inherit",
22
+ };
23
+ let detachProgress;
24
+ if (onProgress) {
25
+ const handler = (chunk) => onProgress(chunk);
26
+ this.$childProcess.on(constants.BUILD_OUTPUT_EVENT_NAME, handler);
27
+ detachProgress = () => this.$childProcess.removeListener(constants.BUILD_OUTPUT_EVENT_NAME, handler);
28
+ }
16
29
  try {
17
30
  const commandResult = await this.$childProcess.spawnFromEvent("xcodebuild", args, "exit", childProcessOptions, spawnOptions || {
18
31
  emitOptions: { eventName: constants.BUILD_OUTPUT_EVENT_NAME },
@@ -23,6 +36,9 @@ class XcodebuildCommandService {
23
36
  catch (err) {
24
37
  this.$errors.fail(err.message);
25
38
  }
39
+ finally {
40
+ detachProgress === null || detachProgress === void 0 ? void 0 : detachProgress();
41
+ }
26
42
  }
27
43
  }
28
44
  exports.XcodebuildCommandService = XcodebuildCommandService;