@warlock.js/core 4.8.1 → 4.9.0

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 (854) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/esm/application/app.d.mts +1 -1
  3. package/esm/application/app.d.mts.map +1 -1
  4. package/esm/application/app.mjs +1 -1
  5. package/esm/application/app.mjs.map +1 -1
  6. package/esm/application/application-config-types.d.mts +1 -1
  7. package/esm/application/application-config-types.d.mts.map +1 -1
  8. package/esm/application/application.d.mts +1 -1
  9. package/esm/application/application.d.mts.map +1 -1
  10. package/esm/application/application.mjs +1 -1
  11. package/esm/application/application.mjs.map +1 -1
  12. package/esm/benchmark/benchmark-snapshots.d.mts +1 -1
  13. package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
  14. package/esm/benchmark/benchmark-snapshots.mjs +1 -1
  15. package/esm/benchmark/benchmark-snapshots.mjs.map +1 -1
  16. package/esm/benchmark/benchmark.d.mts +1 -1
  17. package/esm/benchmark/benchmark.d.mts.map +1 -1
  18. package/esm/benchmark/benchmark.mjs +1 -1
  19. package/esm/benchmark/benchmark.mjs.map +1 -1
  20. package/esm/benchmark/channels/console.channel.d.mts +1 -1
  21. package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
  22. package/esm/benchmark/channels/console.channel.mjs +1 -1
  23. package/esm/benchmark/channels/console.channel.mjs.map +1 -1
  24. package/esm/benchmark/channels/noop.channel.d.mts +1 -1
  25. package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
  26. package/esm/benchmark/channels/noop.channel.mjs +1 -1
  27. package/esm/benchmark/channels/noop.channel.mjs.map +1 -1
  28. package/esm/benchmark/profiler.d.mts +1 -1
  29. package/esm/benchmark/profiler.d.mts.map +1 -1
  30. package/esm/benchmark/profiler.mjs +1 -1
  31. package/esm/benchmark/profiler.mjs.map +1 -1
  32. package/esm/benchmark/types.d.mts +1 -1
  33. package/esm/benchmark/types.d.mts.map +1 -1
  34. package/esm/bootstrap/setup.d.mts +1 -1
  35. package/esm/bootstrap/setup.d.mts.map +1 -1
  36. package/esm/bootstrap/setup.mjs +1 -1
  37. package/esm/bootstrap/setup.mjs.map +1 -1
  38. package/esm/bootstrap.d.mts +1 -1
  39. package/esm/bootstrap.d.mts.map +1 -1
  40. package/esm/bootstrap.mjs +1 -1
  41. package/esm/bootstrap.mjs.map +1 -1
  42. package/esm/cache/database-cache-driver.d.mts +1 -1
  43. package/esm/cache/database-cache-driver.d.mts.map +1 -1
  44. package/esm/cache/database-cache-driver.mjs +1 -1
  45. package/esm/cache/database-cache-driver.mjs.map +1 -1
  46. package/esm/cache/index.mjs +1 -1
  47. package/esm/cache/index.mjs.map +1 -1
  48. package/esm/cli/cli-command.d.mts +1 -1
  49. package/esm/cli/cli-command.d.mts.map +1 -1
  50. package/esm/cli/cli-command.mjs +1 -1
  51. package/esm/cli/cli-command.mjs.map +1 -1
  52. package/esm/cli/cli-commands.manager.mjs +1 -1
  53. package/esm/cli/cli-commands.manager.mjs.map +1 -1
  54. package/esm/cli/cli-commands.utils.mjs +1 -1
  55. package/esm/cli/cli-commands.utils.mjs.map +1 -1
  56. package/esm/cli/commands/add.command.mjs +1 -1
  57. package/esm/cli/commands/add.command.mjs.map +1 -1
  58. package/esm/cli/commands/build.command.mjs +1 -1
  59. package/esm/cli/commands/build.command.mjs.map +1 -1
  60. package/esm/cli/commands/create-database.command.mjs +1 -1
  61. package/esm/cli/commands/create-database.command.mjs.map +1 -1
  62. package/esm/cli/commands/dev-server.command.mjs +5 -4
  63. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  64. package/esm/cli/commands/doctor/checks/config.check.mjs +1 -1
  65. package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
  66. package/esm/cli/commands/doctor/checks/connectors.check.mjs +1 -1
  67. package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
  68. package/esm/cli/commands/doctor/checks/health.check.mjs +1 -1
  69. package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
  70. package/esm/cli/commands/doctor/checks/index.mjs +1 -1
  71. package/esm/cli/commands/doctor/checks/index.mjs.map +1 -1
  72. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -1
  73. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
  74. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +1 -1
  75. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
  76. package/esm/cli/commands/doctor/checks/routes.check.mjs +1 -1
  77. package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
  78. package/esm/cli/commands/doctor/doctor-command.action.mjs +1 -1
  79. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  80. package/esm/cli/commands/doctor/format-report.mjs +1 -1
  81. package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
  82. package/esm/cli/commands/doctor/run-checks.mjs +1 -1
  83. package/esm/cli/commands/doctor/run-checks.mjs.map +1 -1
  84. package/esm/cli/commands/doctor.command.mjs +1 -1
  85. package/esm/cli/commands/doctor.command.mjs.map +1 -1
  86. package/esm/cli/commands/drop-tables.command.mjs +1 -1
  87. package/esm/cli/commands/drop-tables.command.mjs.map +1 -1
  88. package/esm/cli/commands/generate/generate.command.mjs +1 -1
  89. package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
  90. package/esm/cli/commands/generate/generators/column-dsl-parser.mjs +1 -1
  91. package/esm/cli/commands/generate/generators/column-dsl-parser.mjs.map +1 -1
  92. package/esm/cli/commands/generate/generators/controller.generator.mjs +1 -1
  93. package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
  94. package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
  95. package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
  96. package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
  97. package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
  98. package/esm/cli/commands/generate/generators/module.generator.mjs +1 -1
  99. package/esm/cli/commands/generate/generators/module.generator.mjs.map +1 -1
  100. package/esm/cli/commands/generate/generators/repository.generator.mjs +1 -1
  101. package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
  102. package/esm/cli/commands/generate/generators/resource.generator.mjs +1 -1
  103. package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
  104. package/esm/cli/commands/generate/generators/service.generator.mjs +1 -1
  105. package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
  106. package/esm/cli/commands/generate/templates/stubs.mjs +1 -1
  107. package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
  108. package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
  109. package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
  110. package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
  111. package/esm/cli/commands/generate/utils/path-resolver.mjs.map +1 -1
  112. package/esm/cli/commands/generate/utils/prompt.mjs +1 -1
  113. package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
  114. package/esm/cli/commands/generate/utils/writer.mjs +1 -1
  115. package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
  116. package/esm/cli/commands/migrate.command.mjs +1 -1
  117. package/esm/cli/commands/migrate.command.mjs.map +1 -1
  118. package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
  119. package/esm/cli/commands/routes/format-routes-table.mjs.map +1 -1
  120. package/esm/cli/commands/routes/route-row.mjs +1 -1
  121. package/esm/cli/commands/routes/route-row.mjs.map +1 -1
  122. package/esm/cli/commands/routes/routes-command.action.mjs +1 -1
  123. package/esm/cli/commands/routes/routes-command.action.mjs.map +1 -1
  124. package/esm/cli/commands/routes.command.mjs +1 -1
  125. package/esm/cli/commands/routes.command.mjs.map +1 -1
  126. package/esm/cli/commands/seed.command.mjs +1 -1
  127. package/esm/cli/commands/seed.command.mjs.map +1 -1
  128. package/esm/cli/commands/start-production.command.mjs +2 -2
  129. package/esm/cli/commands/start-production.command.mjs.map +1 -1
  130. package/esm/cli/commands/storage-put.action.mjs +1 -1
  131. package/esm/cli/commands/storage-put.action.mjs.map +1 -1
  132. package/esm/cli/commands/storage-put.command.mjs +1 -1
  133. package/esm/cli/commands/storage-put.command.mjs.map +1 -1
  134. package/esm/cli/commands/typings-generator.command.mjs +1 -1
  135. package/esm/cli/commands/typings-generator.command.mjs.map +1 -1
  136. package/esm/cli/commands/update.command.mjs +30 -7
  137. package/esm/cli/commands/update.command.mjs.map +1 -1
  138. package/esm/cli/commands-loader.mjs +1 -1
  139. package/esm/cli/commands-loader.mjs.map +1 -1
  140. package/esm/cli/framework-cli-commands.mjs +1 -1
  141. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  142. package/esm/cli/parse-cli-args.mjs +1 -1
  143. package/esm/cli/parse-cli-args.mjs.map +1 -1
  144. package/esm/cli/start.mjs +1 -1
  145. package/esm/cli/start.mjs.map +1 -1
  146. package/esm/cli/string-similarity.mjs +1 -1
  147. package/esm/cli/string-similarity.mjs.map +1 -1
  148. package/esm/cli/types.d.mts +1 -1
  149. package/esm/cli/types.d.mts.map +1 -1
  150. package/esm/config/config-getter.d.mts +1 -1
  151. package/esm/config/config-getter.d.mts.map +1 -1
  152. package/esm/config/config-getter.mjs +1 -1
  153. package/esm/config/config-getter.mjs.map +1 -1
  154. package/esm/config/config-handlers.d.mts +1 -1
  155. package/esm/config/config-handlers.d.mts.map +1 -1
  156. package/esm/config/config-handlers.mjs +1 -1
  157. package/esm/config/config-handlers.mjs.map +1 -1
  158. package/esm/config/config-loader.d.mts +1 -1
  159. package/esm/config/config-loader.d.mts.map +1 -1
  160. package/esm/config/config-loader.mjs +1 -1
  161. package/esm/config/config-loader.mjs.map +1 -1
  162. package/esm/config/config-manager.mjs +1 -1
  163. package/esm/config/config-manager.mjs.map +1 -1
  164. package/esm/config/config-special-handlers.d.mts +1 -1
  165. package/esm/config/config-special-handlers.d.mts.map +1 -1
  166. package/esm/config/config-special-handlers.mjs +1 -1
  167. package/esm/config/config-special-handlers.mjs.map +1 -1
  168. package/esm/config/load-config-files.mjs +1 -1
  169. package/esm/config/load-config-files.mjs.map +1 -1
  170. package/esm/config/types.d.mts +1 -1
  171. package/esm/config/types.d.mts.map +1 -1
  172. package/esm/connectors/access-connector.d.mts +1 -1
  173. package/esm/connectors/access-connector.d.mts.map +1 -1
  174. package/esm/connectors/access-connector.mjs +1 -1
  175. package/esm/connectors/access-connector.mjs.map +1 -1
  176. package/esm/connectors/ai-connector.d.mts +1 -1
  177. package/esm/connectors/ai-connector.d.mts.map +1 -1
  178. package/esm/connectors/ai-connector.mjs +1 -1
  179. package/esm/connectors/ai-connector.mjs.map +1 -1
  180. package/esm/connectors/base-connector.d.mts +1 -1
  181. package/esm/connectors/base-connector.d.mts.map +1 -1
  182. package/esm/connectors/base-connector.mjs +1 -1
  183. package/esm/connectors/base-connector.mjs.map +1 -1
  184. package/esm/connectors/cache-connector.d.mts +1 -1
  185. package/esm/connectors/cache-connector.d.mts.map +1 -1
  186. package/esm/connectors/cache-connector.mjs +1 -1
  187. package/esm/connectors/cache-connector.mjs.map +1 -1
  188. package/esm/connectors/connectors-manager.d.mts +1 -1
  189. package/esm/connectors/connectors-manager.d.mts.map +1 -1
  190. package/esm/connectors/connectors-manager.mjs +1 -1
  191. package/esm/connectors/connectors-manager.mjs.map +1 -1
  192. package/esm/connectors/database-connector.d.mts +1 -1
  193. package/esm/connectors/database-connector.d.mts.map +1 -1
  194. package/esm/connectors/database-connector.mjs +1 -1
  195. package/esm/connectors/database-connector.mjs.map +1 -1
  196. package/esm/connectors/herald-connector.d.mts +1 -1
  197. package/esm/connectors/herald-connector.d.mts.map +1 -1
  198. package/esm/connectors/herald-connector.mjs +1 -1
  199. package/esm/connectors/herald-connector.mjs.map +1 -1
  200. package/esm/connectors/http-connector.d.mts +1 -1
  201. package/esm/connectors/http-connector.d.mts.map +1 -1
  202. package/esm/connectors/http-connector.mjs +1 -1
  203. package/esm/connectors/http-connector.mjs.map +1 -1
  204. package/esm/connectors/logger-connector.d.mts +1 -1
  205. package/esm/connectors/logger-connector.d.mts.map +1 -1
  206. package/esm/connectors/logger-connector.mjs +1 -1
  207. package/esm/connectors/logger-connector.mjs.map +1 -1
  208. package/esm/connectors/mail-connector.d.mts +1 -1
  209. package/esm/connectors/mail-connector.d.mts.map +1 -1
  210. package/esm/connectors/mail-connector.mjs +1 -1
  211. package/esm/connectors/mail-connector.mjs.map +1 -1
  212. package/esm/connectors/notifications-connector.d.mts +1 -1
  213. package/esm/connectors/notifications-connector.d.mts.map +1 -1
  214. package/esm/connectors/notifications-connector.mjs +1 -1
  215. package/esm/connectors/notifications-connector.mjs.map +1 -1
  216. package/esm/connectors/socket-connector.d.mts +1 -1
  217. package/esm/connectors/socket-connector.d.mts.map +1 -1
  218. package/esm/connectors/socket-connector.mjs +1 -1
  219. package/esm/connectors/socket-connector.mjs.map +1 -1
  220. package/esm/connectors/storage.connector.d.mts +1 -1
  221. package/esm/connectors/storage.connector.d.mts.map +1 -1
  222. package/esm/connectors/storage.connector.mjs +1 -1
  223. package/esm/connectors/storage.connector.mjs.map +1 -1
  224. package/esm/connectors/types.d.mts +1 -1
  225. package/esm/connectors/types.d.mts.map +1 -1
  226. package/esm/connectors/types.mjs +1 -1
  227. package/esm/connectors/types.mjs.map +1 -1
  228. package/esm/container/index.d.mts +1 -1
  229. package/esm/container/index.d.mts.map +1 -1
  230. package/esm/container/index.mjs +1 -1
  231. package/esm/container/index.mjs.map +1 -1
  232. package/esm/database/create-database-action.mjs +1 -1
  233. package/esm/database/create-database-action.mjs.map +1 -1
  234. package/esm/database/drop-tables-action.mjs +1 -1
  235. package/esm/database/drop-tables-action.mjs.map +1 -1
  236. package/esm/database/migrate-action.mjs +1 -1
  237. package/esm/database/migrate-action.mjs.map +1 -1
  238. package/esm/database/models/database-log/database-log.d.mts +1 -1
  239. package/esm/database/models/database-log/database-log.d.mts.map +1 -1
  240. package/esm/database/models/database-log/database-log.mjs +1 -1
  241. package/esm/database/models/database-log/database-log.mjs.map +1 -1
  242. package/esm/database/seed-command-action.mjs +1 -1
  243. package/esm/database/seed-command-action.mjs.map +1 -1
  244. package/esm/database/seeds/seed-records-table-migration.mjs +1 -1
  245. package/esm/database/seeds/seed-records-table-migration.mjs.map +1 -1
  246. package/esm/database/seeds/seeder.d.mts +1 -1
  247. package/esm/database/seeds/seeder.d.mts.map +1 -1
  248. package/esm/database/seeds/seeder.errors.d.mts +1 -1
  249. package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
  250. package/esm/database/seeds/seeder.errors.mjs +1 -1
  251. package/esm/database/seeds/seeder.errors.mjs.map +1 -1
  252. package/esm/database/seeds/seeder.mjs +1 -1
  253. package/esm/database/seeds/seeder.mjs.map +1 -1
  254. package/esm/database/seeds/seeders.manager.mjs +1 -1
  255. package/esm/database/seeds/seeders.manager.mjs.map +1 -1
  256. package/esm/database/seeds/seeds-table-migration.mjs +1 -1
  257. package/esm/database/seeds/seeds-table-migration.mjs.map +1 -1
  258. package/esm/database/seeds/types.d.mts +1 -1
  259. package/esm/database/seeds/types.d.mts.map +1 -1
  260. package/esm/database/seeds/utils.mjs +1 -1
  261. package/esm/database/seeds/utils.mjs.map +1 -1
  262. package/esm/database/utils.d.mts +1 -1
  263. package/esm/database/utils.d.mts.map +1 -1
  264. package/esm/database/utils.mjs +1 -1
  265. package/esm/database/utils.mjs.map +1 -1
  266. package/esm/dev-server/check-for-updates.mjs +91 -8
  267. package/esm/dev-server/check-for-updates.mjs.map +1 -1
  268. package/esm/dev-server/create-worker.mjs +1 -1
  269. package/esm/dev-server/create-worker.mjs.map +1 -1
  270. package/esm/dev-server/dependency-graph.d.mts +1 -1
  271. package/esm/dev-server/dependency-graph.d.mts.map +1 -1
  272. package/esm/dev-server/dependency-graph.mjs +1 -1
  273. package/esm/dev-server/dependency-graph.mjs.map +1 -1
  274. package/esm/dev-server/dev-logger.mjs +1 -1
  275. package/esm/dev-server/dev-logger.mjs.map +1 -1
  276. package/esm/dev-server/development-server.mjs +32 -3
  277. package/esm/dev-server/development-server.mjs.map +1 -1
  278. package/esm/dev-server/events.mjs +1 -1
  279. package/esm/dev-server/events.mjs.map +1 -1
  280. package/esm/dev-server/file-event-handler.mjs +1 -1
  281. package/esm/dev-server/file-event-handler.mjs.map +1 -1
  282. package/esm/dev-server/file-manager.d.mts +1 -1
  283. package/esm/dev-server/file-manager.d.mts.map +1 -1
  284. package/esm/dev-server/file-manager.mjs +1 -1
  285. package/esm/dev-server/file-manager.mjs.map +1 -1
  286. package/esm/dev-server/file-operations.d.mts +1 -1
  287. package/esm/dev-server/file-operations.d.mts.map +1 -1
  288. package/esm/dev-server/file-operations.mjs +1 -1
  289. package/esm/dev-server/file-operations.mjs.map +1 -1
  290. package/esm/dev-server/files-orchestrator.d.mts +1 -1
  291. package/esm/dev-server/files-orchestrator.d.mts.map +1 -1
  292. package/esm/dev-server/files-orchestrator.mjs +1 -1
  293. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  294. package/esm/dev-server/files-watcher.d.mts +1 -1
  295. package/esm/dev-server/files-watcher.d.mts.map +1 -1
  296. package/esm/dev-server/files-watcher.mjs +1 -1
  297. package/esm/dev-server/files-watcher.mjs.map +1 -1
  298. package/esm/dev-server/flags.mjs +1 -1
  299. package/esm/dev-server/flags.mjs.map +1 -1
  300. package/esm/dev-server/health-checker/checkers/base-health-checker.d.mts +1 -1
  301. package/esm/dev-server/health-checker/checkers/base-health-checker.d.mts.map +1 -1
  302. package/esm/dev-server/health-checker/checkers/base-health-checker.mjs +1 -1
  303. package/esm/dev-server/health-checker/checkers/base-health-checker.mjs.map +1 -1
  304. package/esm/dev-server/health-checker/checkers/eslint-health-checker.d.mts +1 -1
  305. package/esm/dev-server/health-checker/checkers/eslint-health-checker.d.mts.map +1 -1
  306. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +1 -1
  307. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
  308. package/esm/dev-server/health-checker/checkers/typescript-health-checker.d.mts +1 -1
  309. package/esm/dev-server/health-checker/checkers/typescript-health-checker.d.mts.map +1 -1
  310. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +1 -1
  311. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs.map +1 -1
  312. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +1 -1
  313. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  314. package/esm/dev-server/health-checker/file-health-result.d.mts +1 -1
  315. package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
  316. package/esm/dev-server/health-checker/file-health-result.mjs +1 -1
  317. package/esm/dev-server/health-checker/file-health-result.mjs.map +1 -1
  318. package/esm/dev-server/health-checker/files-healthcare.manager.d.mts +1 -1
  319. package/esm/dev-server/health-checker/files-healthcare.manager.d.mts.map +1 -1
  320. package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -1
  321. package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
  322. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +1 -1
  323. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +1 -1
  324. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +1 -1
  325. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
  326. package/esm/dev-server/layer-executor.mjs +1 -1
  327. package/esm/dev-server/layer-executor.mjs.map +1 -1
  328. package/esm/dev-server/loader/build-transpile-init.mjs +1 -1
  329. package/esm/dev-server/loader/build-transpile-init.mjs.map +1 -1
  330. package/esm/dev-server/loader/hook-thread.d.mts +1 -1
  331. package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
  332. package/esm/dev-server/loader/hook-thread.mjs +1 -1
  333. package/esm/dev-server/loader/hook-thread.mjs.map +1 -1
  334. package/esm/dev-server/loader/load-hook.d.mts +1 -1
  335. package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
  336. package/esm/dev-server/loader/load-hook.mjs +1 -1
  337. package/esm/dev-server/loader/load-hook.mjs.map +1 -1
  338. package/esm/dev-server/loader/own-resolver.mjs +1 -1
  339. package/esm/dev-server/loader/own-resolver.mjs.map +1 -1
  340. package/esm/dev-server/loader/register-loader.mjs +1 -1
  341. package/esm/dev-server/loader/register-loader.mjs.map +1 -1
  342. package/esm/dev-server/loader/resolve-capture.mjs +1 -1
  343. package/esm/dev-server/loader/resolve-capture.mjs.map +1 -1
  344. package/esm/dev-server/loader/resolve-hook.d.mts +1 -1
  345. package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
  346. package/esm/dev-server/loader/resolve-hook.mjs +1 -1
  347. package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
  348. package/esm/dev-server/loader/source-slug.mjs +1 -1
  349. package/esm/dev-server/loader/source-slug.mjs.map +1 -1
  350. package/esm/dev-server/loader/transpile-cache.mjs +1 -1
  351. package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
  352. package/esm/dev-server/loader/version-registry.mjs +1 -1
  353. package/esm/dev-server/loader/version-registry.mjs.map +1 -1
  354. package/esm/dev-server/manifest-manager.d.mts +1 -1
  355. package/esm/dev-server/manifest-manager.d.mts.map +1 -1
  356. package/esm/dev-server/manifest-manager.mjs +1 -1
  357. package/esm/dev-server/manifest-manager.mjs.map +1 -1
  358. package/esm/dev-server/module-loader.d.mts +1 -1
  359. package/esm/dev-server/module-loader.d.mts.map +1 -1
  360. package/esm/dev-server/module-loader.mjs +1 -1
  361. package/esm/dev-server/module-loader.mjs.map +1 -1
  362. package/esm/dev-server/package-json-manager.mjs +1 -1
  363. package/esm/dev-server/package-json-manager.mjs.map +1 -1
  364. package/esm/dev-server/parse-imports.mjs +1 -1
  365. package/esm/dev-server/parse-imports.mjs.map +1 -1
  366. package/esm/dev-server/path.mjs +1 -1
  367. package/esm/dev-server/path.mjs.map +1 -1
  368. package/esm/dev-server/register-dev-shortcuts.mjs +70 -0
  369. package/esm/dev-server/register-dev-shortcuts.mjs.map +1 -0
  370. package/esm/dev-server/restart-dev-server.mjs +36 -0
  371. package/esm/dev-server/restart-dev-server.mjs.map +1 -0
  372. package/esm/dev-server/shortcuts.mjs +121 -0
  373. package/esm/dev-server/shortcuts.mjs.map +1 -0
  374. package/esm/dev-server/special-files-collector.d.mts +1 -1
  375. package/esm/dev-server/special-files-collector.d.mts.map +1 -1
  376. package/esm/dev-server/special-files-collector.mjs +1 -1
  377. package/esm/dev-server/special-files-collector.mjs.map +1 -1
  378. package/esm/dev-server/start-development-server.mjs +3 -1
  379. package/esm/dev-server/start-development-server.mjs.map +1 -1
  380. package/esm/dev-server/supervisor.mjs +141 -0
  381. package/esm/dev-server/supervisor.mjs.map +1 -0
  382. package/esm/dev-server/tsconfig-manager.mjs +1 -1
  383. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  384. package/esm/dev-server/type-generator.mjs +1 -1
  385. package/esm/dev-server/type-generator.mjs.map +1 -1
  386. package/esm/dev-server/types.d.mts +1 -1
  387. package/esm/dev-server/types.d.mts.map +1 -1
  388. package/esm/dev-server/update-check-cache.mjs +53 -0
  389. package/esm/dev-server/update-check-cache.mjs.map +1 -0
  390. package/esm/dev-server/utils.mjs +1 -1
  391. package/esm/dev-server/utils.mjs.map +1 -1
  392. package/esm/encryption/encrypt.d.mts +1 -1
  393. package/esm/encryption/encrypt.d.mts.map +1 -1
  394. package/esm/encryption/encrypt.mjs +1 -1
  395. package/esm/encryption/encrypt.mjs.map +1 -1
  396. package/esm/encryption/hash.d.mts +1 -1
  397. package/esm/encryption/hash.d.mts.map +1 -1
  398. package/esm/encryption/hash.mjs +1 -1
  399. package/esm/encryption/hash.mjs.map +1 -1
  400. package/esm/encryption/password.d.mts +1 -1
  401. package/esm/encryption/password.d.mts.map +1 -1
  402. package/esm/encryption/password.mjs +1 -1
  403. package/esm/encryption/password.mjs.map +1 -1
  404. package/esm/encryption/types.d.mts +1 -1
  405. package/esm/encryption/types.d.mts.map +1 -1
  406. package/esm/generations/add-command.action.mjs +3 -13
  407. package/esm/generations/add-command.action.mjs.map +1 -1
  408. package/esm/generations/stubs.mjs +1 -1
  409. package/esm/generations/stubs.mjs.map +1 -1
  410. package/esm/http/config.d.mts +1 -1
  411. package/esm/http/config.d.mts.map +1 -1
  412. package/esm/http/config.mjs +1 -1
  413. package/esm/http/config.mjs.map +1 -1
  414. package/esm/http/context/request-context.d.mts +1 -1
  415. package/esm/http/context/request-context.d.mts.map +1 -1
  416. package/esm/http/context/request-context.mjs +1 -1
  417. package/esm/http/context/request-context.mjs.map +1 -1
  418. package/esm/http/createHttpApplication.d.mts +1 -1
  419. package/esm/http/createHttpApplication.d.mts.map +1 -1
  420. package/esm/http/createHttpApplication.mjs +1 -1
  421. package/esm/http/createHttpApplication.mjs.map +1 -1
  422. package/esm/http/database/RequestLog.d.mts +1 -1
  423. package/esm/http/database/RequestLog.d.mts.map +1 -1
  424. package/esm/http/database/RequestLog.mjs +1 -1
  425. package/esm/http/database/RequestLog.mjs.map +1 -1
  426. package/esm/http/error-codes.d.mts +1 -1
  427. package/esm/http/error-codes.d.mts.map +1 -1
  428. package/esm/http/error-codes.mjs +1 -1
  429. package/esm/http/error-codes.mjs.map +1 -1
  430. package/esm/http/errors/errors.d.mts +1 -1
  431. package/esm/http/errors/errors.d.mts.map +1 -1
  432. package/esm/http/errors/errors.mjs +1 -1
  433. package/esm/http/errors/errors.mjs.map +1 -1
  434. package/esm/http/events.d.mts +1 -1
  435. package/esm/http/events.d.mts.map +1 -1
  436. package/esm/http/events.mjs +1 -1
  437. package/esm/http/events.mjs.map +1 -1
  438. package/esm/http/health.d.mts +1 -1
  439. package/esm/http/health.d.mts.map +1 -1
  440. package/esm/http/health.mjs +1 -1
  441. package/esm/http/health.mjs.map +1 -1
  442. package/esm/http/middleware/cache-response-middleware.d.mts +1 -1
  443. package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
  444. package/esm/http/middleware/cache-response-middleware.mjs +1 -1
  445. package/esm/http/middleware/cache-response-middleware.mjs.map +1 -1
  446. package/esm/http/middleware/concurrency-limit.middleware.d.mts +1 -1
  447. package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
  448. package/esm/http/middleware/concurrency-limit.middleware.mjs +1 -1
  449. package/esm/http/middleware/concurrency-limit.middleware.mjs.map +1 -1
  450. package/esm/http/middleware/idempotency.middleware.d.mts +1 -1
  451. package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
  452. package/esm/http/middleware/idempotency.middleware.mjs +1 -1
  453. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  454. package/esm/http/middleware/inject-request-context.d.mts +1 -1
  455. package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
  456. package/esm/http/middleware/inject-request-context.mjs +1 -1
  457. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  458. package/esm/http/middleware/ip-filter.middleware.d.mts +1 -1
  459. package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
  460. package/esm/http/middleware/ip-filter.middleware.mjs +1 -1
  461. package/esm/http/middleware/ip-filter.middleware.mjs.map +1 -1
  462. package/esm/http/middleware/maintenance.middleware.d.mts +1 -1
  463. package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
  464. package/esm/http/middleware/maintenance.middleware.mjs +1 -1
  465. package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
  466. package/esm/http/middleware/max-body-size.middleware.d.mts +1 -1
  467. package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
  468. package/esm/http/middleware/max-body-size.middleware.mjs +1 -1
  469. package/esm/http/middleware/max-body-size.middleware.mjs.map +1 -1
  470. package/esm/http/middleware/middleware-list.d.mts +1 -1
  471. package/esm/http/middleware/middleware-list.d.mts.map +1 -1
  472. package/esm/http/middleware/middleware-list.mjs +1 -1
  473. package/esm/http/middleware/middleware-list.mjs.map +1 -1
  474. package/esm/http/middleware/rate-limit.middleware.d.mts +1 -1
  475. package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
  476. package/esm/http/middleware/rate-limit.middleware.mjs +1 -1
  477. package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
  478. package/esm/http/middleware/utils/cidr-match.d.mts +1 -1
  479. package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
  480. package/esm/http/middleware/utils/cidr-match.mjs +1 -1
  481. package/esm/http/middleware/utils/cidr-match.mjs.map +1 -1
  482. package/esm/http/middleware/utils/idempotency-key.d.mts +1 -1
  483. package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
  484. package/esm/http/middleware/utils/idempotency-key.mjs +1 -1
  485. package/esm/http/middleware/utils/idempotency-key.mjs.map +1 -1
  486. package/esm/http/middleware/utils/parse-size.d.mts +1 -1
  487. package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
  488. package/esm/http/middleware/utils/parse-size.mjs +1 -1
  489. package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
  490. package/esm/http/plugins.d.mts +1 -1
  491. package/esm/http/plugins.d.mts.map +1 -1
  492. package/esm/http/plugins.mjs +1 -1
  493. package/esm/http/plugins.mjs.map +1 -1
  494. package/esm/http/request-controller.d.mts +1 -1
  495. package/esm/http/request-controller.d.mts.map +1 -1
  496. package/esm/http/request-controller.mjs +1 -1
  497. package/esm/http/request-controller.mjs.map +1 -1
  498. package/esm/http/request.d.mts +1 -1
  499. package/esm/http/request.d.mts.map +1 -1
  500. package/esm/http/request.mjs +1 -1
  501. package/esm/http/request.mjs.map +1 -1
  502. package/esm/http/response.d.mts +1 -1
  503. package/esm/http/response.d.mts.map +1 -1
  504. package/esm/http/response.mjs +1 -1
  505. package/esm/http/response.mjs.map +1 -1
  506. package/esm/http/server.d.mts +1 -1
  507. package/esm/http/server.d.mts.map +1 -1
  508. package/esm/http/server.mjs +1 -1
  509. package/esm/http/server.mjs.map +1 -1
  510. package/esm/http/types.d.mts +1 -1
  511. package/esm/http/types.d.mts.map +1 -1
  512. package/esm/http/uploaded-file.d.mts +1 -1
  513. package/esm/http/uploaded-file.d.mts.map +1 -1
  514. package/esm/http/uploaded-file.mjs +1 -1
  515. package/esm/http/uploaded-file.mjs.map +1 -1
  516. package/esm/http/uploads-config.d.mts +1 -1
  517. package/esm/http/uploads-config.d.mts.map +1 -1
  518. package/esm/http/uploads-config.mjs +1 -1
  519. package/esm/http/uploads-config.mjs.map +1 -1
  520. package/esm/http/uploads-types.d.mts +1 -1
  521. package/esm/http/uploads-types.d.mts.map +1 -1
  522. package/esm/image/image.d.mts +1 -1
  523. package/esm/image/image.d.mts.map +1 -1
  524. package/esm/image/image.mjs +1 -1
  525. package/esm/image/image.mjs.map +1 -1
  526. package/esm/logger/logger.d.mts +1 -1
  527. package/esm/logger/logger.d.mts.map +1 -1
  528. package/esm/logger/logger.mjs +1 -1
  529. package/esm/logger/logger.mjs.map +1 -1
  530. package/esm/logger/types.d.mts +1 -1
  531. package/esm/logger/types.d.mts.map +1 -1
  532. package/esm/mail/config.d.mts +1 -1
  533. package/esm/mail/config.d.mts.map +1 -1
  534. package/esm/mail/config.mjs +1 -1
  535. package/esm/mail/config.mjs.map +1 -1
  536. package/esm/mail/events.d.mts +1 -1
  537. package/esm/mail/events.d.mts.map +1 -1
  538. package/esm/mail/events.mjs +1 -1
  539. package/esm/mail/events.mjs.map +1 -1
  540. package/esm/mail/mail.d.mts +1 -1
  541. package/esm/mail/mail.d.mts.map +1 -1
  542. package/esm/mail/mail.mjs +1 -1
  543. package/esm/mail/mail.mjs.map +1 -1
  544. package/esm/mail/mailer-pool.d.mts +1 -1
  545. package/esm/mail/mailer-pool.d.mts.map +1 -1
  546. package/esm/mail/mailer-pool.mjs +1 -1
  547. package/esm/mail/mailer-pool.mjs.map +1 -1
  548. package/esm/mail/react-mail.d.mts +1 -1
  549. package/esm/mail/react-mail.d.mts.map +1 -1
  550. package/esm/mail/react-mail.mjs +1 -1
  551. package/esm/mail/react-mail.mjs.map +1 -1
  552. package/esm/mail/send-mail.d.mts +1 -1
  553. package/esm/mail/send-mail.d.mts.map +1 -1
  554. package/esm/mail/send-mail.mjs +1 -1
  555. package/esm/mail/send-mail.mjs.map +1 -1
  556. package/esm/mail/test-mailbox.d.mts +1 -1
  557. package/esm/mail/test-mailbox.d.mts.map +1 -1
  558. package/esm/mail/test-mailbox.mjs +1 -1
  559. package/esm/mail/test-mailbox.mjs.map +1 -1
  560. package/esm/mail/types.d.mts +1 -1
  561. package/esm/mail/types.d.mts.map +1 -1
  562. package/esm/mail/types.mjs +1 -1
  563. package/esm/mail/types.mjs.map +1 -1
  564. package/esm/manifest/manifest-manager.mjs +1 -1
  565. package/esm/manifest/manifest-manager.mjs.map +1 -1
  566. package/esm/production/build-app-production.mjs +1 -1
  567. package/esm/production/build-app-production.mjs.map +1 -1
  568. package/esm/production/esbuild-plugins.mjs +1 -1
  569. package/esm/production/esbuild-plugins.mjs.map +1 -1
  570. package/esm/production/production-builder.mjs +1 -1
  571. package/esm/production/production-builder.mjs.map +1 -1
  572. package/esm/production/resolve-build-config.mjs +3 -2
  573. package/esm/production/resolve-build-config.mjs.map +1 -1
  574. package/esm/react/index.d.mts +1 -1
  575. package/esm/react/index.d.mts.map +1 -1
  576. package/esm/react/index.mjs +1 -1
  577. package/esm/react/index.mjs.map +1 -1
  578. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +1 -1
  579. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
  580. package/esm/repositories/adapters/cascade/cascade-adapter.mjs +1 -1
  581. package/esm/repositories/adapters/cascade/cascade-adapter.mjs.map +1 -1
  582. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +1 -1
  583. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
  584. package/esm/repositories/adapters/cascade/cascade-query-builder.mjs +1 -1
  585. package/esm/repositories/adapters/cascade/cascade-query-builder.mjs.map +1 -1
  586. package/esm/repositories/adapters/cascade/filter-applicator.mjs +1 -1
  587. package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
  588. package/esm/repositories/contracts/query-builder.contract.d.mts +1 -1
  589. package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
  590. package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -1
  591. package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
  592. package/esm/repositories/contracts/types.d.mts +1 -1
  593. package/esm/repositories/contracts/types.d.mts.map +1 -1
  594. package/esm/repositories/repository.manager.d.mts +1 -1
  595. package/esm/repositories/repository.manager.d.mts.map +1 -1
  596. package/esm/repositories/repository.manager.mjs +1 -1
  597. package/esm/repositories/repository.manager.mjs.map +1 -1
  598. package/esm/resource/define-resource.d.mts +1 -1
  599. package/esm/resource/define-resource.d.mts.map +1 -1
  600. package/esm/resource/define-resource.mjs +1 -1
  601. package/esm/resource/define-resource.mjs.map +1 -1
  602. package/esm/resource/register-resource.d.mts +1 -1
  603. package/esm/resource/register-resource.d.mts.map +1 -1
  604. package/esm/resource/register-resource.mjs +1 -1
  605. package/esm/resource/register-resource.mjs.map +1 -1
  606. package/esm/resource/resource-field-builder.d.mts +1 -1
  607. package/esm/resource/resource-field-builder.d.mts.map +1 -1
  608. package/esm/resource/resource-field-builder.mjs +1 -1
  609. package/esm/resource/resource-field-builder.mjs.map +1 -1
  610. package/esm/resource/resource.d.mts +1 -1
  611. package/esm/resource/resource.d.mts.map +1 -1
  612. package/esm/resource/resource.mjs +1 -1
  613. package/esm/resource/resource.mjs.map +1 -1
  614. package/esm/resource/types.d.mts +1 -1
  615. package/esm/resource/types.d.mts.map +1 -1
  616. package/esm/restful/restful.d.mts +1 -1
  617. package/esm/restful/restful.d.mts.map +1 -1
  618. package/esm/restful/restful.mjs +1 -1
  619. package/esm/restful/restful.mjs.map +1 -1
  620. package/esm/router/route-builder.d.mts +1 -1
  621. package/esm/router/route-builder.d.mts.map +1 -1
  622. package/esm/router/route-builder.mjs +1 -1
  623. package/esm/router/route-builder.mjs.map +1 -1
  624. package/esm/router/route-registry.mjs +1 -1
  625. package/esm/router/route-registry.mjs.map +1 -1
  626. package/esm/router/router.d.mts +1 -1
  627. package/esm/router/router.d.mts.map +1 -1
  628. package/esm/router/router.mjs +1 -1
  629. package/esm/router/router.mjs.map +1 -1
  630. package/esm/router/types.d.mts +1 -1
  631. package/esm/router/types.d.mts.map +1 -1
  632. package/esm/socket/types.d.mts +1 -1
  633. package/esm/socket/types.d.mts.map +1 -1
  634. package/esm/socket/utils.d.mts +1 -1
  635. package/esm/socket/utils.d.mts.map +1 -1
  636. package/esm/socket/utils.mjs +1 -1
  637. package/esm/socket/utils.mjs.map +1 -1
  638. package/esm/storage/config.d.mts +1 -1
  639. package/esm/storage/config.d.mts.map +1 -1
  640. package/esm/storage/config.mjs +1 -1
  641. package/esm/storage/config.mjs.map +1 -1
  642. package/esm/storage/context/storage-driver-context.d.mts +1 -1
  643. package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
  644. package/esm/storage/context/storage-driver-context.mjs +1 -1
  645. package/esm/storage/context/storage-driver-context.mjs.map +1 -1
  646. package/esm/storage/drivers/cloud-driver.d.mts +1 -1
  647. package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
  648. package/esm/storage/drivers/cloud-driver.mjs +1 -1
  649. package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
  650. package/esm/storage/drivers/do-spaces-driver.d.mts +1 -1
  651. package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
  652. package/esm/storage/drivers/do-spaces-driver.mjs +1 -1
  653. package/esm/storage/drivers/do-spaces-driver.mjs.map +1 -1
  654. package/esm/storage/drivers/local-driver.d.mts +1 -1
  655. package/esm/storage/drivers/local-driver.d.mts.map +1 -1
  656. package/esm/storage/drivers/local-driver.mjs +1 -1
  657. package/esm/storage/drivers/local-driver.mjs.map +1 -1
  658. package/esm/storage/drivers/r2-driver.d.mts +1 -1
  659. package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
  660. package/esm/storage/drivers/r2-driver.mjs +1 -1
  661. package/esm/storage/drivers/r2-driver.mjs.map +1 -1
  662. package/esm/storage/drivers/s3-driver.d.mts +1 -1
  663. package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
  664. package/esm/storage/drivers/s3-driver.mjs +1 -1
  665. package/esm/storage/drivers/s3-driver.mjs.map +1 -1
  666. package/esm/storage/scoped-storage.d.mts +1 -1
  667. package/esm/storage/scoped-storage.d.mts.map +1 -1
  668. package/esm/storage/scoped-storage.mjs +1 -1
  669. package/esm/storage/scoped-storage.mjs.map +1 -1
  670. package/esm/storage/storage-file.d.mts +1 -1
  671. package/esm/storage/storage-file.d.mts.map +1 -1
  672. package/esm/storage/storage-file.mjs +1 -1
  673. package/esm/storage/storage-file.mjs.map +1 -1
  674. package/esm/storage/storage.d.mts +1 -1
  675. package/esm/storage/storage.d.mts.map +1 -1
  676. package/esm/storage/storage.mjs +1 -1
  677. package/esm/storage/storage.mjs.map +1 -1
  678. package/esm/storage/types.d.mts +1 -1
  679. package/esm/storage/types.d.mts.map +1 -1
  680. package/esm/storage/utils/contain-path.d.mts +1 -1
  681. package/esm/storage/utils/contain-path.d.mts.map +1 -1
  682. package/esm/storage/utils/contain-path.mjs +1 -1
  683. package/esm/storage/utils/contain-path.mjs.map +1 -1
  684. package/esm/storage/utils/mime.d.mts +1 -1
  685. package/esm/storage/utils/mime.d.mts.map +1 -1
  686. package/esm/storage/utils/mime.mjs +1 -1
  687. package/esm/storage/utils/mime.mjs.map +1 -1
  688. package/esm/storage/utils/safe-fetch.d.mts +1 -1
  689. package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
  690. package/esm/storage/utils/safe-fetch.mjs +1 -1
  691. package/esm/storage/utils/safe-fetch.mjs.map +1 -1
  692. package/esm/storage/utils/storage-error.d.mts +1 -1
  693. package/esm/storage/utils/storage-error.d.mts.map +1 -1
  694. package/esm/storage/utils/storage-error.mjs +1 -1
  695. package/esm/storage/utils/storage-error.mjs.map +1 -1
  696. package/esm/tests/start-http-development-server.d.mts +1 -1
  697. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  698. package/esm/tests/start-http-development-server.mjs +1 -1
  699. package/esm/tests/start-http-development-server.mjs.map +1 -1
  700. package/esm/tests/test-helpers.d.mts +1 -1
  701. package/esm/tests/test-helpers.d.mts.map +1 -1
  702. package/esm/tests/test-helpers.mjs +1 -1
  703. package/esm/tests/test-helpers.mjs.map +1 -1
  704. package/esm/tests/vitest-setup.d.mts +1 -1
  705. package/esm/tests/vitest-setup.d.mts.map +1 -1
  706. package/esm/tests/vitest-setup.mjs +1 -1
  707. package/esm/tests/vitest-setup.mjs.map +1 -1
  708. package/esm/updater/package-manager.mjs +47 -7
  709. package/esm/updater/package-manager.mjs.map +1 -1
  710. package/esm/updater/update-warlock-packages.mjs +63 -10
  711. package/esm/updater/update-warlock-packages.mjs.map +1 -1
  712. package/esm/use-cases/types.d.mts +1 -1
  713. package/esm/use-cases/types.d.mts.map +1 -1
  714. package/esm/use-cases/use-case-broadcast.d.mts +1 -1
  715. package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
  716. package/esm/use-cases/use-case-broadcast.mjs +1 -1
  717. package/esm/use-cases/use-case-broadcast.mjs.map +1 -1
  718. package/esm/use-cases/use-case-events.d.mts +1 -1
  719. package/esm/use-cases/use-case-events.d.mts.map +1 -1
  720. package/esm/use-cases/use-case-events.mjs +1 -1
  721. package/esm/use-cases/use-case-events.mjs.map +1 -1
  722. package/esm/use-cases/use-case-pipeline.d.mts +1 -1
  723. package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
  724. package/esm/use-cases/use-case-pipeline.mjs +1 -1
  725. package/esm/use-cases/use-case-pipeline.mjs.map +1 -1
  726. package/esm/use-cases/use-case.d.mts +1 -1
  727. package/esm/use-cases/use-case.d.mts.map +1 -1
  728. package/esm/use-cases/use-case.errors.d.mts +1 -1
  729. package/esm/use-cases/use-case.errors.d.mts.map +1 -1
  730. package/esm/use-cases/use-case.errors.mjs +1 -1
  731. package/esm/use-cases/use-case.errors.mjs.map +1 -1
  732. package/esm/use-cases/use-case.mjs +1 -1
  733. package/esm/use-cases/use-case.mjs.map +1 -1
  734. package/esm/use-cases/use-cases-registry.d.mts +1 -1
  735. package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
  736. package/esm/use-cases/use-cases-registry.mjs +1 -1
  737. package/esm/use-cases/use-cases-registry.mjs.map +1 -1
  738. package/esm/utils/app-log.d.mts +1 -1
  739. package/esm/utils/app-log.d.mts.map +1 -1
  740. package/esm/utils/app-log.mjs +1 -1
  741. package/esm/utils/app-log.mjs.map +1 -1
  742. package/esm/utils/database-log.d.mts +1 -1
  743. package/esm/utils/database-log.d.mts.map +1 -1
  744. package/esm/utils/database-log.mjs +1 -1
  745. package/esm/utils/database-log.mjs.map +1 -1
  746. package/esm/utils/environment.d.mts +1 -1
  747. package/esm/utils/environment.d.mts.map +1 -1
  748. package/esm/utils/environment.mjs +1 -1
  749. package/esm/utils/environment.mjs.map +1 -1
  750. package/esm/utils/framework-vesion.mjs +1 -1
  751. package/esm/utils/framework-vesion.mjs.map +1 -1
  752. package/esm/utils/get-localized.d.mts +1 -1
  753. package/esm/utils/get-localized.d.mts.map +1 -1
  754. package/esm/utils/get-localized.mjs +1 -1
  755. package/esm/utils/get-localized.mjs.map +1 -1
  756. package/esm/utils/npm-registry.d.mts +1 -1
  757. package/esm/utils/npm-registry.d.mts.map +1 -1
  758. package/esm/utils/npm-registry.mjs +1 -1
  759. package/esm/utils/npm-registry.mjs.map +1 -1
  760. package/esm/utils/paths.d.mts +1 -1
  761. package/esm/utils/paths.d.mts.map +1 -1
  762. package/esm/utils/paths.mjs +1 -1
  763. package/esm/utils/paths.mjs.map +1 -1
  764. package/esm/utils/promise-all-object.d.mts +1 -1
  765. package/esm/utils/promise-all-object.d.mts.map +1 -1
  766. package/esm/utils/promise-all-object.mjs +1 -1
  767. package/esm/utils/promise-all-object.mjs.map +1 -1
  768. package/esm/utils/queue.d.mts +1 -1
  769. package/esm/utils/queue.d.mts.map +1 -1
  770. package/esm/utils/queue.mjs +1 -1
  771. package/esm/utils/queue.mjs.map +1 -1
  772. package/esm/utils/sleep.d.mts +1 -1
  773. package/esm/utils/sleep.d.mts.map +1 -1
  774. package/esm/utils/sleep.mjs +1 -1
  775. package/esm/utils/sleep.mjs.map +1 -1
  776. package/esm/utils/sluggable.d.mts +1 -1
  777. package/esm/utils/sluggable.d.mts.map +1 -1
  778. package/esm/utils/sluggable.mjs +1 -1
  779. package/esm/utils/sluggable.mjs.map +1 -1
  780. package/esm/utils/to-json.d.mts +1 -1
  781. package/esm/utils/to-json.d.mts.map +1 -1
  782. package/esm/utils/to-json.mjs +1 -1
  783. package/esm/utils/to-json.mjs.map +1 -1
  784. package/esm/utils/types.d.mts +1 -1
  785. package/esm/utils/types.d.mts.map +1 -1
  786. package/esm/utils/urls.d.mts +1 -1
  787. package/esm/utils/urls.d.mts.map +1 -1
  788. package/esm/utils/urls.mjs +1 -1
  789. package/esm/utils/urls.mjs.map +1 -1
  790. package/esm/utils/version-compare.d.mts +1 -1
  791. package/esm/utils/version-compare.d.mts.map +1 -1
  792. package/esm/utils/version-compare.mjs +1 -1
  793. package/esm/utils/version-compare.mjs.map +1 -1
  794. package/esm/validation/database/exists-except-current-id.d.mts +1 -1
  795. package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
  796. package/esm/validation/database/exists-except-current-id.mjs +1 -1
  797. package/esm/validation/database/exists-except-current-id.mjs.map +1 -1
  798. package/esm/validation/database/exists-except-current-user.d.mts +1 -1
  799. package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
  800. package/esm/validation/database/exists-except-current-user.mjs +1 -1
  801. package/esm/validation/database/exists-except-current-user.mjs.map +1 -1
  802. package/esm/validation/database/types.d.mts +1 -1
  803. package/esm/validation/database/types.d.mts.map +1 -1
  804. package/esm/validation/database/unique-except-current-id.d.mts +1 -1
  805. package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
  806. package/esm/validation/database/unique-except-current-id.mjs +1 -1
  807. package/esm/validation/database/unique-except-current-id.mjs.map +1 -1
  808. package/esm/validation/database/unique-except-current-user.d.mts +1 -1
  809. package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
  810. package/esm/validation/database/unique-except-current-user.mjs +1 -1
  811. package/esm/validation/database/unique-except-current-user.mjs.map +1 -1
  812. package/esm/validation/file/file.d.mts +1 -1
  813. package/esm/validation/file/file.d.mts.map +1 -1
  814. package/esm/validation/file/file.mjs +1 -1
  815. package/esm/validation/file/file.mjs.map +1 -1
  816. package/esm/validation/init.mjs +1 -1
  817. package/esm/validation/init.mjs.map +1 -1
  818. package/esm/validation/plugins/database-plugin.mjs +1 -1
  819. package/esm/validation/plugins/database-plugin.mjs.map +1 -1
  820. package/esm/validation/plugins/file-plugin.mjs +1 -1
  821. package/esm/validation/plugins/file-plugin.mjs.map +1 -1
  822. package/esm/validation/plugins/localized-plugin.mjs +1 -1
  823. package/esm/validation/plugins/localized-plugin.mjs.map +1 -1
  824. package/esm/validation/types.d.mts +1 -1
  825. package/esm/validation/types.d.mts.map +1 -1
  826. package/esm/validation/validateAll.mjs +1 -1
  827. package/esm/validation/validateAll.mjs.map +1 -1
  828. package/esm/validation/validators/file-validator.d.mts +1 -1
  829. package/esm/validation/validators/file-validator.d.mts.map +1 -1
  830. package/esm/validation/validators/file-validator.mjs +1 -1
  831. package/esm/validation/validators/file-validator.mjs.map +1 -1
  832. package/esm/vite/lower-stage3-decorators.d.mts +1 -1
  833. package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
  834. package/esm/vite/lower-stage3-decorators.mjs +1 -1
  835. package/esm/vite/lower-stage3-decorators.mjs.map +1 -1
  836. package/esm/warlock-config/default-configurations.mjs +1 -1
  837. package/esm/warlock-config/default-configurations.mjs.map +1 -1
  838. package/esm/warlock-config/define-config.d.mts +1 -1
  839. package/esm/warlock-config/define-config.d.mts.map +1 -1
  840. package/esm/warlock-config/define-config.mjs +6 -2
  841. package/esm/warlock-config/define-config.mjs.map +1 -1
  842. package/esm/warlock-config/normalize-build-config.mjs +24 -0
  843. package/esm/warlock-config/normalize-build-config.mjs.map +1 -0
  844. package/esm/warlock-config/types.d.mts +21 -1
  845. package/esm/warlock-config/types.d.mts.map +1 -1
  846. package/esm/warlock-config/warlock-config.manager.d.mts +1 -1
  847. package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
  848. package/esm/warlock-config/warlock-config.manager.mjs +1 -1
  849. package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
  850. package/llms-full.txt +131 -13
  851. package/llms.txt +2 -2
  852. package/package.json +12 -12
  853. package/skills/run-app/SKILL.md +70 -7
  854. package/skills/update-packages/SKILL.md +61 -6
@@ -1 +1 @@
1
- {"version":3,"file":"files-healthcare.manager.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/health-checker/files-healthcare.manager.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { Worker } from \"worker_threads\";\nimport { createWorker } from \"../create-worker\";\nimport { devLogInfo } from \"../dev-logger\";\nimport type { FileManager } from \"../file-manager\";\nimport type {\n FileHealthCheckerContract,\n HealthCheckerFilesStats,\n} from \"./file-health-checker.contract\";\n\n/**\n * Serialized file data to send to workers\n */\ntype SerializedFile = {\n path: string;\n content: string;\n relativePath: string;\n};\n\n/**\n * Diagnostic message from worker\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * File check result from worker\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Worker response type\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig?: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * Files Healthcare Manager\n *\n * Manages health checkers for file validation during development.\n * Supports both main-thread and worker-based checkers.\n *\n * Checkers with `workerPath` run in dedicated worker threads for performance.\n * Checkers without `workerPath` run in the main thread.\n *\n * @example\n * ```typescript\n * const manager = new FilesHealthcareManager(files);\n *\n * manager.setHealthCheckers([\n * new TypescriptHealthChecker(), // Has workerPath → runs in worker\n * new CustomChecker(), // No workerPath → runs in main thread\n * ]);\n *\n * await manager.initialize();\n * await manager.validateAllFiles();\n * ```\n */\nexport class FilesHealthcareManager {\n /**\n * Registered health checkers\n */\n private healthCheckers: FileHealthCheckerContract[] = [];\n\n /**\n * Active worker instances (checkerName → Worker)\n */\n private workers = new Map<string, Worker>();\n\n /**\n * Worker initialization promises (for ensuring workers are ready)\n */\n private workerInitPromises = new Map<string, Promise<boolean>>();\n\n /**\n * Aggregated stats for each checker\n */\n private checkerStats = new Map<\n string,\n {\n totalFiles: number;\n healthyFiles: number;\n defectiveFiles: number;\n totalErrors: number;\n totalWarnings: number;\n filesWithErrors: number;\n filesWithWarnings: number;\n }\n >();\n\n /**\n * Constructor\n * @param files - Map of tracked files\n */\n public constructor(private readonly files: Map<string, FileManager>) {}\n\n /**\n * Add health checkers to the manager\n * @param checkers - Checkers to add\n */\n public addHealthCheckers(...checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers.push(...checkers);\n return this;\n }\n\n /**\n * Set (replace) all health checkers\n * @param checkers - New set of checkers\n */\n public setHealthCheckers(checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers = checkers;\n return this;\n }\n\n /**\n * Initialize all health checkers\n *\n * For checkers with `workerPath`, spawns dedicated worker threads.\n * For other checkers, calls their `initialize()` method directly.\n */\n public async initialize(): Promise<void> {\n const initPromises = this.healthCheckers.map(async (checker) => {\n // Initialize stats for this checker\n this.checkerStats.set(checker.name, {\n totalFiles: 0,\n healthyFiles: 0,\n defectiveFiles: 0,\n totalErrors: 0,\n totalWarnings: 0,\n filesWithErrors: 0,\n filesWithWarnings: 0,\n });\n\n if (checker.workerPath) {\n // Spawn dedicated worker for this checker\n await this.spawnWorker(checker);\n } else {\n // Initialize checker on main thread\n checker.initialize();\n }\n });\n\n await Promise.all(initPromises);\n }\n\n /**\n * Spawn a worker for a checker\n */\n private async spawnWorker(checker: FileHealthCheckerContract): Promise<void> {\n if (!checker.workerPath) return;\n\n const worker = createWorker(checker.workerPath, import.meta.url, {\n workerData: { cwd: process.cwd() },\n });\n\n this.workers.set(checker.name, worker);\n\n // Create init promise\n const initPromise = new Promise<boolean>((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"initialized\") {\n worker.off(\"message\", handler);\n resolve(response.success);\n }\n };\n\n worker.on(\"message\", handler);\n\n // Handle worker errors\n worker.on(\"error\", (error) => {\n console.error(`Health Checker Worker Error (${checker.name}):`, error);\n resolve(false);\n });\n\n // Send init message\n worker.postMessage({ type: \"init\", config: { cwd: process.cwd() } });\n });\n\n this.workerInitPromises.set(checker.name, initPromise);\n\n // Wait for initialization\n await initPromise;\n }\n\n /**\n * Validate all tracked files\n */\n public async validateAllFiles(): Promise<void> {\n const allFiles = Array.from(this.files.values());\n await this.checkFiles(allFiles);\n\n // Display stats\n await this.displayStats();\n }\n\n /**\n * Check the given files with all registered checkers\n *\n * All checkers run in parallel for performance.\n * Worker-based checkers communicate via postMessage.\n * Main-thread checkers are called directly.\n */\n public async checkFiles(files: FileManager[]): Promise<void> {\n const checkPromises = this.healthCheckers.map(async (checker) => {\n if (checker.workerPath) {\n return this.runInWorker(checker.name, files);\n } else {\n return this.runInline(checker, files);\n }\n });\n\n const results = await Promise.all(checkPromises);\n\n // Display any errors/warnings\n for (const checkerResults of results) {\n for (const result of checkerResults) {\n if (!result.healthy) {\n this.displayFileResults(result);\n }\n }\n }\n }\n\n /**\n * Run checker in worker thread\n */\n private async runInWorker(checkerName: string, files: FileManager[]): Promise<FileCheckResult[]> {\n const worker = this.workers.get(checkerName);\n\n if (!worker) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Wait for worker to be initialized\n const initPromise = this.workerInitPromises.get(checkerName);\n if (initPromise) {\n const success = await initPromise;\n if (!success) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n }\n\n // Serialize files for worker\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n return new Promise((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"results\") {\n worker.off(\"message\", handler);\n\n // Update stats\n this.updateStats(checkerName, response.results);\n\n resolve(response.results);\n } else if (response.type === \"error\") {\n worker.off(\"message\", handler);\n resolve(\n files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n })),\n );\n }\n };\n\n worker.on(\"message\", handler);\n worker.postMessage({ type: \"check\", files: serializedFiles });\n });\n }\n\n /**\n * Run checker inline (main thread)\n */\n private async runInline(\n checker: FileHealthCheckerContract,\n files: FileManager[],\n ): Promise<FileCheckResult[]> {\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const healthResult = await checker.check(file);\n const stats = healthResult.getStats();\n\n results.push({\n path: file.absolutePath,\n relativePath: file.relativePath,\n healthy: stats.state === \"healthy\",\n errors: healthResult.messages\n .filter((m) => m.type === \"error\")\n .map((m) => ({\n type: \"error\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n warnings: healthResult.messages\n .filter((m) => m.type === \"warning\")\n .map((m) => ({\n type: \"warning\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n });\n }\n\n // Update stats\n const checkerResults = results;\n this.updateStats(checker.name, checkerResults);\n\n return results;\n }\n\n /**\n * Update aggregated stats for a checker\n */\n private updateStats(checkerName: string, results: FileCheckResult[]): void {\n const stats = this.checkerStats.get(checkerName);\n if (!stats) return;\n\n for (const result of results) {\n stats.totalFiles++;\n if (result.healthy) {\n stats.healthyFiles++;\n } else {\n stats.defectiveFiles++;\n }\n stats.totalErrors += result.errors.length;\n stats.totalWarnings += result.warnings.length;\n if (result.errors.length > 0) stats.filesWithErrors++;\n if (result.warnings.length > 0) stats.filesWithWarnings++;\n }\n }\n\n /**\n * Detect when files are changed\n */\n public async onFileChanges(files: FileManager[]): Promise<void> {\n // Notify workers of file changes\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"fileChanges\", files: serializedFiles });\n }\n\n // Notify inline checkers\n await Promise.all(\n this.healthCheckers.filter((c) => !c.workerPath).map((c) => c.onFileChanges(files)),\n );\n }\n\n /**\n * Remove files from tracking\n * Notifies both inline checkers and worker-based checkers about removed files\n */\n public removeFiles(files: FileManager[]): void {\n // Notify inline checkers\n this.healthCheckers\n .filter((c) => !c.workerPath)\n .forEach((checker) => files.forEach((file) => checker.removeFile(file)));\n\n // Notify workers about deleted files\n if (files.length > 0) {\n const deletedPaths = files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"filesDeleted\", files: deletedPaths });\n }\n }\n }\n\n /**\n * Display file results (errors/warnings)\n */\n private displayFileResults(result: FileCheckResult): void {\n const fileName = result.relativePath.replace(/\\\\/g, \"/\");\n\n // Display errors\n for (const error of result.errors) {\n const icon = colors.redBright(\"✖\");\n const level = colors.redBright(colors.bold(\"ERROR\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\n );\n if (error.ruleId) {\n console.log(\n ` ${colors.magentaBright(error.ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.red(error.message)}`);\n }\n }\n\n // Display warnings\n for (const warning of result.warnings) {\n const icon = colors.yellowBright(\"⚠\");\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\n );\n if (warning.ruleId) {\n console.log(\n ` ${colors.magentaBright(warning.ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`);\n }\n }\n }\n\n /**\n * Display stats for all health checkers\n */\n private async displayStats(): Promise<void> {\n const allStats: HealthCheckerFilesStats[] = [];\n\n for (const checker of this.healthCheckers) {\n const stats = this.checkerStats.get(checker.name);\n if (stats) {\n allStats.push({\n name: checker.name,\n files: {\n healthy: stats.healthyFiles,\n defective: stats.defectiveFiles,\n },\n warnings: {\n total: stats.totalWarnings,\n totalFiles: stats.filesWithWarnings,\n },\n errors: {\n total: stats.totalErrors,\n totalFiles: stats.filesWithErrors,\n },\n });\n }\n }\n\n console.log(\"\\n\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n devLogInfo(colors.bold(\" 📊 Health Checker Statistics\"));\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n\n allStats.forEach((stats: HealthCheckerFilesStats, index: number) => {\n const totalFiles = stats.files.healthy + stats.files.defective;\n const hasIssues = stats.files.defective > 0;\n\n // Checker name with icon\n const statusIcon = hasIssues ? \"⚠️\" : \"✅\";\n console.log(colors.bold(` ${statusIcon} ${stats.name}`));\n console.log(colors.dim(\" \" + \"─\".repeat(76)));\n\n // Files summary\n const filesLine = ` Files: ${colors.white(totalFiles.toString())} total │ ${colors.green(\"✓ \" + stats.files.healthy)} healthy │ ${hasIssues ? colors.red(\"✗ \" + stats.files.defective) : colors.dim(\"✗ 0\")} defective`;\n console.log(filesLine);\n\n // Issues summary\n const warningsText =\n stats.warnings.total > 0\n ? colors.yellow(`⚠ ${stats.warnings.total} warnings`)\n : colors.dim(\"⚠ 0 warnings\");\n\n const errorsText =\n stats.errors.total > 0\n ? colors.red(`✗ ${stats.errors.total} errors`)\n : colors.dim(\"✗ 0 errors\");\n\n console.log(` Issues: ${warningsText} │ ${errorsText}`);\n\n // Add spacing between checkers\n if (index < allStats.length - 1) {\n console.log(\"\");\n }\n });\n\n console.log(\"\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n }\n\n /**\n * Shutdown all workers\n */\n public async shutdown(): Promise<void> {\n for (const [name, worker] of this.workers) {\n try {\n worker.postMessage({ type: \"shutdown\" });\n await worker.terminate();\n } catch {\n // Worker may already be terminated\n }\n }\n\n this.workers.clear();\n this.workerInitPromises.clear();\n this.checkerStats.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"files-healthcare.manager.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/health-checker/files-healthcare.manager.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { Worker } from \"worker_threads\";\nimport { createWorker } from \"../create-worker\";\nimport { devLogInfo } from \"../dev-logger\";\nimport type { FileManager } from \"../file-manager\";\nimport type {\n FileHealthCheckerContract,\n HealthCheckerFilesStats,\n} from \"./file-health-checker.contract\";\n\n/**\n * Serialized file data to send to workers\n */\ntype SerializedFile = {\n path: string;\n content: string;\n relativePath: string;\n};\n\n/**\n * Diagnostic message from worker\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * File check result from worker\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Worker response type\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig?: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * Files Healthcare Manager\n *\n * Manages health checkers for file validation during development.\n * Supports both main-thread and worker-based checkers.\n *\n * Checkers with `workerPath` run in dedicated worker threads for performance.\n * Checkers without `workerPath` run in the main thread.\n *\n * @example\n * ```typescript\n * const manager = new FilesHealthcareManager(files);\n *\n * manager.setHealthCheckers([\n * new TypescriptHealthChecker(), // Has workerPath → runs in worker\n * new CustomChecker(), // No workerPath → runs in main thread\n * ]);\n *\n * await manager.initialize();\n * await manager.validateAllFiles();\n * ```\n */\nexport class FilesHealthcareManager {\n /**\n * Registered health checkers\n */\n private healthCheckers: FileHealthCheckerContract[] = [];\n\n /**\n * Active worker instances (checkerName → Worker)\n */\n private workers = new Map<string, Worker>();\n\n /**\n * Worker initialization promises (for ensuring workers are ready)\n */\n private workerInitPromises = new Map<string, Promise<boolean>>();\n\n /**\n * Aggregated stats for each checker\n */\n private checkerStats = new Map<\n string,\n {\n totalFiles: number;\n healthyFiles: number;\n defectiveFiles: number;\n totalErrors: number;\n totalWarnings: number;\n filesWithErrors: number;\n filesWithWarnings: number;\n }\n >();\n\n /**\n * Constructor\n * @param files - Map of tracked files\n */\n public constructor(private readonly files: Map<string, FileManager>) {}\n\n /**\n * Add health checkers to the manager\n * @param checkers - Checkers to add\n */\n public addHealthCheckers(...checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers.push(...checkers);\n return this;\n }\n\n /**\n * Set (replace) all health checkers\n * @param checkers - New set of checkers\n */\n public setHealthCheckers(checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers = checkers;\n return this;\n }\n\n /**\n * Initialize all health checkers\n *\n * For checkers with `workerPath`, spawns dedicated worker threads.\n * For other checkers, calls their `initialize()` method directly.\n */\n public async initialize(): Promise<void> {\n const initPromises = this.healthCheckers.map(async (checker) => {\n // Initialize stats for this checker\n this.checkerStats.set(checker.name, {\n totalFiles: 0,\n healthyFiles: 0,\n defectiveFiles: 0,\n totalErrors: 0,\n totalWarnings: 0,\n filesWithErrors: 0,\n filesWithWarnings: 0,\n });\n\n if (checker.workerPath) {\n // Spawn dedicated worker for this checker\n await this.spawnWorker(checker);\n } else {\n // Initialize checker on main thread\n checker.initialize();\n }\n });\n\n await Promise.all(initPromises);\n }\n\n /**\n * Spawn a worker for a checker\n */\n private async spawnWorker(checker: FileHealthCheckerContract): Promise<void> {\n if (!checker.workerPath) return;\n\n const worker = createWorker(checker.workerPath, import.meta.url, {\n workerData: { cwd: process.cwd() },\n });\n\n this.workers.set(checker.name, worker);\n\n // Create init promise\n const initPromise = new Promise<boolean>((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"initialized\") {\n worker.off(\"message\", handler);\n resolve(response.success);\n }\n };\n\n worker.on(\"message\", handler);\n\n // Handle worker errors\n worker.on(\"error\", (error) => {\n console.error(`Health Checker Worker Error (${checker.name}):`, error);\n resolve(false);\n });\n\n // Send init message\n worker.postMessage({ type: \"init\", config: { cwd: process.cwd() } });\n });\n\n this.workerInitPromises.set(checker.name, initPromise);\n\n // Wait for initialization\n await initPromise;\n }\n\n /**\n * Validate all tracked files\n */\n public async validateAllFiles(): Promise<void> {\n const allFiles = Array.from(this.files.values());\n await this.checkFiles(allFiles);\n\n // Display stats\n await this.displayStats();\n }\n\n /**\n * Check the given files with all registered checkers\n *\n * All checkers run in parallel for performance.\n * Worker-based checkers communicate via postMessage.\n * Main-thread checkers are called directly.\n */\n public async checkFiles(files: FileManager[]): Promise<void> {\n const checkPromises = this.healthCheckers.map(async (checker) => {\n if (checker.workerPath) {\n return this.runInWorker(checker.name, files);\n } else {\n return this.runInline(checker, files);\n }\n });\n\n const results = await Promise.all(checkPromises);\n\n // Display any errors/warnings\n for (const checkerResults of results) {\n for (const result of checkerResults) {\n if (!result.healthy) {\n this.displayFileResults(result);\n }\n }\n }\n }\n\n /**\n * Run checker in worker thread\n */\n private async runInWorker(checkerName: string, files: FileManager[]): Promise<FileCheckResult[]> {\n const worker = this.workers.get(checkerName);\n\n if (!worker) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Wait for worker to be initialized\n const initPromise = this.workerInitPromises.get(checkerName);\n if (initPromise) {\n const success = await initPromise;\n if (!success) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n }\n\n // Serialize files for worker\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n return new Promise((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"results\") {\n worker.off(\"message\", handler);\n\n // Update stats\n this.updateStats(checkerName, response.results);\n\n resolve(response.results);\n } else if (response.type === \"error\") {\n worker.off(\"message\", handler);\n resolve(\n files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n })),\n );\n }\n };\n\n worker.on(\"message\", handler);\n worker.postMessage({ type: \"check\", files: serializedFiles });\n });\n }\n\n /**\n * Run checker inline (main thread)\n */\n private async runInline(\n checker: FileHealthCheckerContract,\n files: FileManager[],\n ): Promise<FileCheckResult[]> {\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const healthResult = await checker.check(file);\n const stats = healthResult.getStats();\n\n results.push({\n path: file.absolutePath,\n relativePath: file.relativePath,\n healthy: stats.state === \"healthy\",\n errors: healthResult.messages\n .filter((m) => m.type === \"error\")\n .map((m) => ({\n type: \"error\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n warnings: healthResult.messages\n .filter((m) => m.type === \"warning\")\n .map((m) => ({\n type: \"warning\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n });\n }\n\n // Update stats\n const checkerResults = results;\n this.updateStats(checker.name, checkerResults);\n\n return results;\n }\n\n /**\n * Update aggregated stats for a checker\n */\n private updateStats(checkerName: string, results: FileCheckResult[]): void {\n const stats = this.checkerStats.get(checkerName);\n if (!stats) return;\n\n for (const result of results) {\n stats.totalFiles++;\n if (result.healthy) {\n stats.healthyFiles++;\n } else {\n stats.defectiveFiles++;\n }\n stats.totalErrors += result.errors.length;\n stats.totalWarnings += result.warnings.length;\n if (result.errors.length > 0) stats.filesWithErrors++;\n if (result.warnings.length > 0) stats.filesWithWarnings++;\n }\n }\n\n /**\n * Detect when files are changed\n */\n public async onFileChanges(files: FileManager[]): Promise<void> {\n // Notify workers of file changes\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"fileChanges\", files: serializedFiles });\n }\n\n // Notify inline checkers\n await Promise.all(\n this.healthCheckers.filter((c) => !c.workerPath).map((c) => c.onFileChanges(files)),\n );\n }\n\n /**\n * Remove files from tracking\n * Notifies both inline checkers and worker-based checkers about removed files\n */\n public removeFiles(files: FileManager[]): void {\n // Notify inline checkers\n this.healthCheckers\n .filter((c) => !c.workerPath)\n .forEach((checker) => files.forEach((file) => checker.removeFile(file)));\n\n // Notify workers about deleted files\n if (files.length > 0) {\n const deletedPaths = files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"filesDeleted\", files: deletedPaths });\n }\n }\n }\n\n /**\n * Display file results (errors/warnings)\n */\n private displayFileResults(result: FileCheckResult): void {\n const fileName = result.relativePath.replace(/\\\\/g, \"/\");\n\n // Display errors\n for (const error of result.errors) {\n const icon = colors.redBright(\"✖\");\n const level = colors.redBright(colors.bold(\"ERROR\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\n );\n if (error.ruleId) {\n console.log(\n ` ${colors.magentaBright(error.ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.red(error.message)}`);\n }\n }\n\n // Display warnings\n for (const warning of result.warnings) {\n const icon = colors.yellowBright(\"⚠\");\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\n );\n if (warning.ruleId) {\n console.log(\n ` ${colors.magentaBright(warning.ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`);\n }\n }\n }\n\n /**\n * Display stats for all health checkers\n */\n private async displayStats(): Promise<void> {\n const allStats: HealthCheckerFilesStats[] = [];\n\n for (const checker of this.healthCheckers) {\n const stats = this.checkerStats.get(checker.name);\n if (stats) {\n allStats.push({\n name: checker.name,\n files: {\n healthy: stats.healthyFiles,\n defective: stats.defectiveFiles,\n },\n warnings: {\n total: stats.totalWarnings,\n totalFiles: stats.filesWithWarnings,\n },\n errors: {\n total: stats.totalErrors,\n totalFiles: stats.filesWithErrors,\n },\n });\n }\n }\n\n console.log(\"\\n\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n devLogInfo(colors.bold(\" 📊 Health Checker Statistics\"));\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n\n allStats.forEach((stats: HealthCheckerFilesStats, index: number) => {\n const totalFiles = stats.files.healthy + stats.files.defective;\n const hasIssues = stats.files.defective > 0;\n\n // Checker name with icon\n const statusIcon = hasIssues ? \"⚠️\" : \"✅\";\n console.log(colors.bold(` ${statusIcon} ${stats.name}`));\n console.log(colors.dim(\" \" + \"─\".repeat(76)));\n\n // Files summary\n const filesLine = ` Files: ${colors.white(totalFiles.toString())} total │ ${colors.green(\"✓ \" + stats.files.healthy)} healthy │ ${hasIssues ? colors.red(\"✗ \" + stats.files.defective) : colors.dim(\"✗ 0\")} defective`;\n console.log(filesLine);\n\n // Issues summary\n const warningsText =\n stats.warnings.total > 0\n ? colors.yellow(`⚠ ${stats.warnings.total} warnings`)\n : colors.dim(\"⚠ 0 warnings\");\n\n const errorsText =\n stats.errors.total > 0\n ? colors.red(`✗ ${stats.errors.total} errors`)\n : colors.dim(\"✗ 0 errors\");\n\n console.log(` Issues: ${warningsText} │ ${errorsText}`);\n\n // Add spacing between checkers\n if (index < allStats.length - 1) {\n console.log(\"\");\n }\n });\n\n console.log(\"\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n }\n\n /**\n * Shutdown all workers\n */\n public async shutdown(): Promise<void> {\n for (const [name, worker] of this.workers) {\n try {\n worker.postMessage({ type: \"shutdown\" });\n await worker.terminate();\n } catch {\n // Worker may already be terminated\n }\n }\n\n this.workers.clear();\n this.workerInitPromises.clear();\n this.checkerStats.clear();\n }\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import fs from "fs";
3
3
  import { ESLint } from "eslint";
4
4
  import { parentPort, workerData } from "worker_threads";
5
5
 
6
- //#region ../@warlock.js/core/src/dev-server/health-checker/workers/eslint-health.worker.ts
6
+ //#region ../core/src/dev-server/health-checker/workers/eslint-health.worker.ts
7
7
  /**
8
8
  * ESLint Health Check Worker
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-health.worker.mjs","names":[],"sources":["../../../../../../../../../@warlock.js/core/src/dev-server/health-checker/workers/eslint-health.worker.ts"],"sourcesContent":["/**\n * ESLint Health Check Worker\n *\n * This worker runs in a dedicated thread to perform ESLint linting\n * without blocking the main dev server thread. It maintains a persistent\n * ESLint instance for efficient linting.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport { ESLint } from \"eslint\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Lint message sent back to main thread\n */\ntype LintMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: LintMessage[];\n warnings: LintMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * ESLint Health Worker class\n * Maintains persistent ESLint instance for efficient linting\n */\nclass ESLintHealthWorker {\n /**\n * ESLint instance\n */\n private eslint: ESLint | null = null;\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Whether ESLint config was found\n */\n private hasConfig = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with ESLint configuration\n */\n public initialize(config: { cwd: string }): { success: boolean; hasConfig: boolean } {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Check if ESLint flat config exists\n const flatConfigPath = path.join(this.cwd, \"eslint.config.js\");\n const flatConfigMjsPath = path.join(this.cwd, \"eslint.config.mjs\");\n const flatConfigCjsPath = path.join(this.cwd, \"eslint.config.cjs\");\n\n this.hasConfig =\n fs.existsSync(flatConfigPath) ||\n fs.existsSync(flatConfigMjsPath) ||\n fs.existsSync(flatConfigCjsPath);\n\n if (!this.hasConfig) {\n this.initialized = true;\n return { success: true, hasConfig: false };\n }\n\n // Create ESLint instance with flat config\n this.eslint = new ESLint({\n cwd: this.cwd,\n });\n\n this.initialized = true;\n return { success: true, hasConfig: true };\n } catch (error) {\n console.error(\"ESLint Worker: Failed to initialize:\", error);\n this.initialized = true;\n return { success: false, hasConfig: false };\n }\n }\n\n /**\n * Check files for ESLint errors\n */\n public async checkFiles(files: SerializedFile[]): Promise<FileCheckResult[]> {\n if (!this.eslint || !this.hasConfig) {\n // No ESLint config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n // Only lint lintable files\n if (!this.isLintableFile(file.path)) {\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n continue;\n }\n\n try {\n const result = await this.checkSingleFile(file);\n results.push(result);\n } catch (error) {\n // On error, mark as healthy to avoid blocking\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n }\n }\n\n return results;\n }\n\n /**\n * Check a single file for lint issues\n */\n private async checkSingleFile(file: SerializedFile): Promise<FileCheckResult> {\n if (!this.eslint) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n // Use lintText to lint from memory (not disk)\n const lintResults = await this.eslint.lintText(file.content, {\n filePath: file.path,\n });\n\n if (lintResults.length === 0) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const lintResult = lintResults[0];\n const errors: LintMessage[] = [];\n const warnings: LintMessage[] = [];\n\n for (const message of lintResult.messages) {\n const lintMessage: LintMessage = {\n type: message.severity === 2 ? \"error\" : \"warning\",\n message: message.message,\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n filePath: file.path,\n relativePath: file.relativePath,\n ruleId: message.ruleId || undefined,\n };\n\n if (message.severity === 2) {\n errors.push(lintMessage);\n } else if (message.severity === 1) {\n warnings.push(lintMessage);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Check if file is a lintable file\n */\n private isLintableFile(filePath: string): boolean {\n const ext = filePath.toLowerCase();\n return (\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\n );\n }\n}\n\n// Create worker instance\nconst worker = new ESLintHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", async (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const initResult = worker.initialize(message.config);\n const response: WorkerResponse = {\n type: \"initialized\",\n success: initResult.success,\n hasConfig: initResult.hasConfig,\n };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = await worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"filesDeleted\": {\n // ESLint doesn't maintain internal file cache (lints from memory)\n // No cleanup needed, just acknowledge\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"eslint-health.worker.mjs","names":[],"sources":["../../../../../../../../../core/src/dev-server/health-checker/workers/eslint-health.worker.ts"],"sourcesContent":["/**\n * ESLint Health Check Worker\n *\n * This worker runs in a dedicated thread to perform ESLint linting\n * without blocking the main dev server thread. It maintains a persistent\n * ESLint instance for efficient linting.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport { ESLint } from \"eslint\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Lint message sent back to main thread\n */\ntype LintMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: LintMessage[];\n warnings: LintMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * ESLint Health Worker class\n * Maintains persistent ESLint instance for efficient linting\n */\nclass ESLintHealthWorker {\n /**\n * ESLint instance\n */\n private eslint: ESLint | null = null;\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Whether ESLint config was found\n */\n private hasConfig = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with ESLint configuration\n */\n public initialize(config: { cwd: string }): { success: boolean; hasConfig: boolean } {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Check if ESLint flat config exists\n const flatConfigPath = path.join(this.cwd, \"eslint.config.js\");\n const flatConfigMjsPath = path.join(this.cwd, \"eslint.config.mjs\");\n const flatConfigCjsPath = path.join(this.cwd, \"eslint.config.cjs\");\n\n this.hasConfig =\n fs.existsSync(flatConfigPath) ||\n fs.existsSync(flatConfigMjsPath) ||\n fs.existsSync(flatConfigCjsPath);\n\n if (!this.hasConfig) {\n this.initialized = true;\n return { success: true, hasConfig: false };\n }\n\n // Create ESLint instance with flat config\n this.eslint = new ESLint({\n cwd: this.cwd,\n });\n\n this.initialized = true;\n return { success: true, hasConfig: true };\n } catch (error) {\n console.error(\"ESLint Worker: Failed to initialize:\", error);\n this.initialized = true;\n return { success: false, hasConfig: false };\n }\n }\n\n /**\n * Check files for ESLint errors\n */\n public async checkFiles(files: SerializedFile[]): Promise<FileCheckResult[]> {\n if (!this.eslint || !this.hasConfig) {\n // No ESLint config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n // Only lint lintable files\n if (!this.isLintableFile(file.path)) {\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n continue;\n }\n\n try {\n const result = await this.checkSingleFile(file);\n results.push(result);\n } catch (error) {\n // On error, mark as healthy to avoid blocking\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n }\n }\n\n return results;\n }\n\n /**\n * Check a single file for lint issues\n */\n private async checkSingleFile(file: SerializedFile): Promise<FileCheckResult> {\n if (!this.eslint) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n // Use lintText to lint from memory (not disk)\n const lintResults = await this.eslint.lintText(file.content, {\n filePath: file.path,\n });\n\n if (lintResults.length === 0) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const lintResult = lintResults[0];\n const errors: LintMessage[] = [];\n const warnings: LintMessage[] = [];\n\n for (const message of lintResult.messages) {\n const lintMessage: LintMessage = {\n type: message.severity === 2 ? \"error\" : \"warning\",\n message: message.message,\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n filePath: file.path,\n relativePath: file.relativePath,\n ruleId: message.ruleId || undefined,\n };\n\n if (message.severity === 2) {\n errors.push(lintMessage);\n } else if (message.severity === 1) {\n warnings.push(lintMessage);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Check if file is a lintable file\n */\n private isLintableFile(filePath: string): boolean {\n const ext = filePath.toLowerCase();\n return (\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\n );\n }\n}\n\n// Create worker instance\nconst worker = new ESLintHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", async (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const initResult = worker.initialize(message.config);\n const response: WorkerResponse = {\n type: \"initialized\",\n success: initResult.success,\n hasConfig: initResult.hasConfig,\n };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = await worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"filesDeleted\": {\n // ESLint doesn't maintain internal file cache (lints from memory)\n // No cleanup needed, just acknowledge\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqFA,IAAM,qBAAN,MAAyB;;gBAIS;qBAKV;mBAKF;aAKE,QAAQ,IAAI;;;;;CAKlC,AAAO,WAAW,QAAmE;EACnF,IAAI;GACF,KAAK,MAAM,OAAO,OAAO,QAAQ,IAAI;GAGrC,MAAM,iBAAiB,KAAK,KAAK,KAAK,KAAK,kBAAkB;GAC7D,MAAM,oBAAoB,KAAK,KAAK,KAAK,KAAK,mBAAmB;GACjE,MAAM,oBAAoB,KAAK,KAAK,KAAK,KAAK,mBAAmB;GAEjE,KAAK,YACH,GAAG,WAAW,cAAc,KAC5B,GAAG,WAAW,iBAAiB,KAC/B,GAAG,WAAW,iBAAiB;GAEjC,IAAI,CAAC,KAAK,WAAW;IACnB,KAAK,cAAc;IACnB,OAAO;KAAE,SAAS;KAAM,WAAW;IAAM;GAC3C;GAGA,KAAK,SAAS,IAAI,OAAO,EACvB,KAAK,KAAK,IACZ,CAAC;GAED,KAAK,cAAc;GACnB,OAAO;IAAE,SAAS;IAAM,WAAW;GAAK;EAC1C,SAAS,OAAO;GACd,QAAQ,MAAM,wCAAwC,KAAK;GAC3D,KAAK,cAAc;GACnB,OAAO;IAAE,SAAS;IAAO,WAAW;GAAM;EAC5C;CACF;;;;CAKA,MAAa,WAAW,OAAqD;EAC3E,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,WAExB,OAAO,MAAM,KAAK,UAAU;GAC1B,MAAM,KAAK;GACX,cAAc,KAAK;GACnB,SAAS;GACT,QAAQ,CAAC;GACT,UAAU,CAAC;EACb,EAAE;EAGJ,MAAM,UAA6B,CAAC;EAEpC,KAAK,MAAM,QAAQ,OAAO;GAExB,IAAI,CAAC,KAAK,eAAe,KAAK,IAAI,GAAG;IACnC,QAAQ,KAAK;KACX,MAAM,KAAK;KACX,cAAc,KAAK;KACnB,SAAS;KACT,QAAQ,CAAC;KACT,UAAU,CAAC;IACb,CAAC;IACD;GACF;GAEA,IAAI;IACF,MAAM,SAAS,MAAM,KAAK,gBAAgB,IAAI;IAC9C,QAAQ,KAAK,MAAM;GACrB,SAAS,OAAO;IAEd,QAAQ,KAAK;KACX,MAAM,KAAK;KACX,cAAc,KAAK;KACnB,SAAS;KACT,QAAQ,CAAC;KACT,UAAU,CAAC;IACb,CAAC;GACH;EACF;EAEA,OAAO;CACT;;;;CAKA,MAAc,gBAAgB,MAAgD;EAC5E,IAAI,CAAC,KAAK,QACR,OAAO;GACL,MAAM,KAAK;GACX,cAAc,KAAK;GACnB,SAAS;GACT,QAAQ,CAAC;GACT,UAAU,CAAC;EACb;EAIF,MAAM,cAAc,MAAM,KAAK,OAAO,SAAS,KAAK,SAAS,EAC3D,UAAU,KAAK,KACjB,CAAC;EAED,IAAI,YAAY,WAAW,GACzB,OAAO;GACL,MAAM,KAAK;GACX,cAAc,KAAK;GACnB,SAAS;GACT,QAAQ,CAAC;GACT,UAAU,CAAC;EACb;EAGF,MAAM,aAAa,YAAY;EAC/B,MAAM,SAAwB,CAAC;EAC/B,MAAM,WAA0B,CAAC;EAEjC,KAAK,MAAM,WAAW,WAAW,UAAU;GACzC,MAAM,cAA2B;IAC/B,MAAM,QAAQ,aAAa,IAAI,UAAU;IACzC,SAAS,QAAQ;IACjB,YAAY,QAAQ,QAAQ;IAC5B,cAAc,QAAQ,UAAU;IAChC,QAAQ,QAAQ,aAAa,QAAQ,SAAS,QAAQ,YAAY,QAAQ,SAAS;IACnF,UAAU,KAAK;IACf,cAAc,KAAK;IACnB,QAAQ,QAAQ,UAAU;GAC5B;GAEA,IAAI,QAAQ,aAAa,GACvB,OAAO,KAAK,WAAW;QAClB,IAAI,QAAQ,aAAa,GAC9B,SAAS,KAAK,WAAW;EAE7B;EAEA,OAAO;GACL,MAAM,KAAK;GACX,cAAc,KAAK;GACnB,SAAS,OAAO,WAAW,KAAK,SAAS,WAAW;GACpD;GACA;EACF;CACF;;;;CAKA,AAAQ,eAAe,UAA2B;EAChD,MAAM,MAAM,SAAS,YAAY;EACjC,OACE,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,MAAM,KAAK,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,MAAM;CAE7F;AACF;AAGA,MAAM,SAAS,IAAI,mBAAmB;AAGtC,YAAY,GAAG,WAAW,OAAO,YAA2B;CAC1D,IAAI;EACF,QAAQ,QAAQ,MAAhB;GACE,KAAK,QAAQ;IACX,MAAM,aAAa,OAAO,WAAW,QAAQ,MAAM;IACnD,MAAM,WAA2B;KAC/B,MAAM;KACN,SAAS,WAAW;KACpB,WAAW,WAAW;IACxB;IACA,YAAY,YAAY,QAAQ;IAChC;GACF;GAEA,KAAK,SAAS;IAEZ,MAAM,WAA2B;KAAE,MAAM;KAAW,eAD9B,OAAO,WAAW,QAAQ,KAAK;IACO;IAC5D,YAAY,YAAY,QAAQ;IAChC;GACF;GAEA,KAAK,gBAGH;GAGF,KAAK,YACH,QAAQ,KAAK,CAAC;EAElB;CACF,SAAS,OAAO;EACd,MAAM,WAA2B;GAC/B,MAAM;GACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAChE;EACA,YAAY,YAAY,QAAQ;CAClC;AACF,CAAC;AAGD,IAAI,YAAY,UACd,OAAO,WAAW,EAAE,KAAK,WAAW,OAAO,QAAQ,IAAI,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import ts from "typescript";
2
2
  import { parentPort, workerData } from "worker_threads";
3
3
 
4
- //#region ../@warlock.js/core/src/dev-server/health-checker/workers/ts-health.worker.ts
4
+ //#region ../core/src/dev-server/health-checker/workers/ts-health.worker.ts
5
5
  /**
6
6
  * TypeScript Health Check Worker
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ts-health.worker.mjs","names":[],"sources":["../../../../../../../../../@warlock.js/core/src/dev-server/health-checker/workers/ts-health.worker.ts"],"sourcesContent":["/**\n * TypeScript Health Check Worker\n *\n * This worker runs in a dedicated thread to perform TypeScript type checking\n * without blocking the main dev server thread. It maintains a persistent\n * ts.Program instance for fast incremental type checking.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'fileChanges' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport ts from \"typescript\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Diagnostic message sent back to main thread\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string; tsconfigPath?: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"fileChanges\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * TypeScript Health Worker class\n * Maintains persistent ts.Program for incremental type checking\n */\nclass TypeScriptHealthWorker {\n /**\n * Cached TypeScript program instance\n */\n private program: ts.Program | null = null;\n\n /**\n * Parsed TypeScript configuration\n */\n private parsedConfig: ts.ParsedCommandLine | null = null;\n\n /**\n * In-memory file contents cache\n */\n private fileContents = new Map<string, string>();\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with TypeScript configuration\n */\n public initialize(config: { cwd: string; tsconfigPath?: string }): boolean {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Try to load tsconfig.json\n const tsconfigPath = config.tsconfigPath || ts.findConfigFile(this.cwd, ts.sys.fileExists);\n\n if (!tsconfigPath) {\n this.initialized = true;\n return true; // No tsconfig, will skip type checking\n }\n\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.warn(\"TypeScript Worker: Error reading tsconfig:\", configFile.error);\n this.initialized = true;\n return true;\n }\n\n this.parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, this.cwd);\n\n if (this.parsedConfig.errors.length > 0) {\n console.warn(\"TypeScript Worker: tsconfig has errors:\", this.parsedConfig.errors);\n }\n\n this.initialized = true;\n return true;\n } catch (error) {\n console.error(\"TypeScript Worker: Failed to initialize:\", error);\n this.initialized = true;\n return false;\n }\n }\n\n /**\n * Check files for TypeScript errors\n */\n public checkFiles(files: SerializedFile[]): FileCheckResult[] {\n if (!this.parsedConfig) {\n // No config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Update in-memory file cache\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Create or update the program (incremental)\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined, // Pass old program for incremental compilation\n );\n\n // Check each file\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const result = this.checkSingleFile(file);\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Handle file changes (update program incrementally)\n */\n public handleFileChanges(files: SerializedFile[]): void {\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Recreate program with new file contents\n if (this.parsedConfig && this.program) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Handle deleted files (remove from cache)\n */\n public handleFilesDeleted(files: DeletedFile[]): void {\n let hasChanges = false;\n\n for (const file of files) {\n if (this.fileContents.has(file.path)) {\n this.fileContents.delete(file.path);\n hasChanges = true;\n }\n }\n\n // Recreate program without deleted files\n if (hasChanges && this.parsedConfig) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Check a single file for diagnostics\n */\n private checkSingleFile(file: SerializedFile): FileCheckResult {\n if (!this.program) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const sourceFile = this.program.getSourceFile(file.path);\n\n if (!sourceFile) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const syntacticDiagnostics = this.program.getSyntacticDiagnostics(sourceFile);\n const semanticDiagnostics = this.program.getSemanticDiagnostics(sourceFile);\n const allDiagnostics = [...syntacticDiagnostics, ...semanticDiagnostics];\n\n const errors: DiagnosticMessage[] = [];\n const warnings: DiagnosticMessage[] = [];\n\n for (const diagnostic of allDiagnostics) {\n const message = this.formatDiagnostic(diagnostic, file);\n\n if (diagnostic.category === ts.DiagnosticCategory.Error) {\n errors.push(message);\n } else if (diagnostic.category === ts.DiagnosticCategory.Warning) {\n warnings.push(message);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Format a TypeScript diagnostic into our message format\n */\n private formatDiagnostic(diagnostic: ts.Diagnostic, file: SerializedFile): DiagnosticMessage {\n let lineNumber = 1;\n let columnNumber = 1;\n let length = 1;\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n lineNumber = pos.line + 1;\n columnNumber = pos.character + 1;\n length = diagnostic.length || 1;\n }\n\n const messageText =\n typeof diagnostic.messageText === \"string\"\n ? diagnostic.messageText\n : diagnostic.messageText.messageText;\n\n return {\n type: diagnostic.category === ts.DiagnosticCategory.Error ? \"error\" : \"warning\",\n message: messageText,\n lineNumber,\n columnNumber,\n length,\n filePath: file.path,\n relativePath: file.relativePath,\n };\n }\n\n /**\n * Create a custom compiler host that reads from in-memory cache\n */\n private createCompilerHost(): ts.CompilerHost {\n const defaultHost = ts.createCompilerHost(this.parsedConfig?.options || {});\n\n return {\n ...defaultHost,\n readFile: (fileName: string) => {\n // Check in-memory cache first\n if (this.fileContents.has(fileName)) {\n return this.fileContents.get(fileName);\n }\n // Fall back to disk\n return defaultHost.readFile(fileName);\n },\n fileExists: (fileName: string) => {\n if (this.fileContents.has(fileName)) {\n return true;\n }\n return defaultHost.fileExists(fileName);\n },\n };\n }\n}\n\n// Create worker instance\nconst worker = new TypeScriptHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const success = worker.initialize(message.config);\n const response: WorkerResponse = { type: \"initialized\", success };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"fileChanges\": {\n worker.handleFileChanges(message.files);\n break;\n }\n\n case \"filesDeleted\": {\n worker.handleFilesDeleted(message.files);\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ts-health.worker.mjs","names":[],"sources":["../../../../../../../../../core/src/dev-server/health-checker/workers/ts-health.worker.ts"],"sourcesContent":["/**\n * TypeScript Health Check Worker\n *\n * This worker runs in a dedicated thread to perform TypeScript type checking\n * without blocking the main dev server thread. It maintains a persistent\n * ts.Program instance for fast incremental type checking.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'fileChanges' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport ts from \"typescript\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Diagnostic message sent back to main thread\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string; tsconfigPath?: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"fileChanges\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * TypeScript Health Worker class\n * Maintains persistent ts.Program for incremental type checking\n */\nclass TypeScriptHealthWorker {\n /**\n * Cached TypeScript program instance\n */\n private program: ts.Program | null = null;\n\n /**\n * Parsed TypeScript configuration\n */\n private parsedConfig: ts.ParsedCommandLine | null = null;\n\n /**\n * In-memory file contents cache\n */\n private fileContents = new Map<string, string>();\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with TypeScript configuration\n */\n public initialize(config: { cwd: string; tsconfigPath?: string }): boolean {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Try to load tsconfig.json\n const tsconfigPath = config.tsconfigPath || ts.findConfigFile(this.cwd, ts.sys.fileExists);\n\n if (!tsconfigPath) {\n this.initialized = true;\n return true; // No tsconfig, will skip type checking\n }\n\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.warn(\"TypeScript Worker: Error reading tsconfig:\", configFile.error);\n this.initialized = true;\n return true;\n }\n\n this.parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, this.cwd);\n\n if (this.parsedConfig.errors.length > 0) {\n console.warn(\"TypeScript Worker: tsconfig has errors:\", this.parsedConfig.errors);\n }\n\n this.initialized = true;\n return true;\n } catch (error) {\n console.error(\"TypeScript Worker: Failed to initialize:\", error);\n this.initialized = true;\n return false;\n }\n }\n\n /**\n * Check files for TypeScript errors\n */\n public checkFiles(files: SerializedFile[]): FileCheckResult[] {\n if (!this.parsedConfig) {\n // No config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Update in-memory file cache\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Create or update the program (incremental)\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined, // Pass old program for incremental compilation\n );\n\n // Check each file\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const result = this.checkSingleFile(file);\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Handle file changes (update program incrementally)\n */\n public handleFileChanges(files: SerializedFile[]): void {\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Recreate program with new file contents\n if (this.parsedConfig && this.program) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Handle deleted files (remove from cache)\n */\n public handleFilesDeleted(files: DeletedFile[]): void {\n let hasChanges = false;\n\n for (const file of files) {\n if (this.fileContents.has(file.path)) {\n this.fileContents.delete(file.path);\n hasChanges = true;\n }\n }\n\n // Recreate program without deleted files\n if (hasChanges && this.parsedConfig) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Check a single file for diagnostics\n */\n private checkSingleFile(file: SerializedFile): FileCheckResult {\n if (!this.program) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const sourceFile = this.program.getSourceFile(file.path);\n\n if (!sourceFile) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const syntacticDiagnostics = this.program.getSyntacticDiagnostics(sourceFile);\n const semanticDiagnostics = this.program.getSemanticDiagnostics(sourceFile);\n const allDiagnostics = [...syntacticDiagnostics, ...semanticDiagnostics];\n\n const errors: DiagnosticMessage[] = [];\n const warnings: DiagnosticMessage[] = [];\n\n for (const diagnostic of allDiagnostics) {\n const message = this.formatDiagnostic(diagnostic, file);\n\n if (diagnostic.category === ts.DiagnosticCategory.Error) {\n errors.push(message);\n } else if (diagnostic.category === ts.DiagnosticCategory.Warning) {\n warnings.push(message);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Format a TypeScript diagnostic into our message format\n */\n private formatDiagnostic(diagnostic: ts.Diagnostic, file: SerializedFile): DiagnosticMessage {\n let lineNumber = 1;\n let columnNumber = 1;\n let length = 1;\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n lineNumber = pos.line + 1;\n columnNumber = pos.character + 1;\n length = diagnostic.length || 1;\n }\n\n const messageText =\n typeof diagnostic.messageText === \"string\"\n ? diagnostic.messageText\n : diagnostic.messageText.messageText;\n\n return {\n type: diagnostic.category === ts.DiagnosticCategory.Error ? \"error\" : \"warning\",\n message: messageText,\n lineNumber,\n columnNumber,\n length,\n filePath: file.path,\n relativePath: file.relativePath,\n };\n }\n\n /**\n * Create a custom compiler host that reads from in-memory cache\n */\n private createCompilerHost(): ts.CompilerHost {\n const defaultHost = ts.createCompilerHost(this.parsedConfig?.options || {});\n\n return {\n ...defaultHost,\n readFile: (fileName: string) => {\n // Check in-memory cache first\n if (this.fileContents.has(fileName)) {\n return this.fileContents.get(fileName);\n }\n // Fall back to disk\n return defaultHost.readFile(fileName);\n },\n fileExists: (fileName: string) => {\n if (this.fileContents.has(fileName)) {\n return true;\n }\n return defaultHost.fileExists(fileName);\n },\n };\n }\n}\n\n// Create worker instance\nconst worker = new TypeScriptHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const success = worker.initialize(message.config);\n const response: WorkerResponse = { type: \"initialized\", success };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"fileChanges\": {\n worker.handleFileChanges(message.files);\n break;\n }\n\n case \"filesDeleted\": {\n worker.handleFilesDeleted(message.files);\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { connectorsManager } from "../connectors/connectors-manager.mjs";
3
3
  import { configManager } from "../config/config-manager.mjs";
4
4
  import { loadEnv } from "@mongez/dotenv";
5
5
 
6
- //#region ../@warlock.js/core/src/dev-server/layer-executor.ts
6
+ //#region ../core/src/dev-server/layer-executor.ts
7
7
  /**
8
8
  * Decides what to reload when a batch of files changes.
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"layer-executor.mjs","names":[],"sources":["../../../../../../../@warlock.js/core/src/dev-server/layer-executor.ts"],"sourcesContent":["import { loadEnv } from \"@mongez/dotenv\";\r\nimport { configManager } from \"../config/config-manager\";\r\nimport { connectorsManager } from \"../connectors/connectors-manager\";\r\nimport type { DependencyGraph } from \"./dependency-graph\";\r\nimport { devLogHMR } from \"./dev-logger\";\r\nimport { FileManager } from \"./file-manager\";\r\nimport type { ModuleLoader } from \"./module-loader\";\r\nimport type { SpecialFilesCollector } from \"./special-files-collector\";\r\n\r\n/**\r\n * Decides what to reload when a batch of files changes.\r\n *\r\n * Strategy: bump the hook's version counter for every file in the\r\n * invalidation chain, wait for the hook worker to flush, then re-import\r\n * any special files (config / main / routes / events / locales) the chain\r\n * touched and restart any connector whose watched-files overlap the change.\r\n */\r\nexport class LayerExecutor {\r\n public constructor(\r\n private readonly dependencyGraph: DependencyGraph,\r\n private readonly specialFilesCollector: SpecialFilesCollector,\r\n private readonly moduleLoader: ModuleLoader,\r\n private readonly bumpVersion: (absolutePath: string) => void,\r\n private readonly flushVersionBumps: () => Promise<void>,\r\n ) {}\r\n\r\n /**\r\n * Entry point for the file watcher batch.\r\n *\r\n * @param changedPaths - code files added or changed in this batch\r\n * @param filesMap - all tracked files (relativePath → FileManager)\r\n * @param deletedFiles - paths that were removed from disk\r\n * @param allChangedPaths - includes .env so we can detect config reloads\r\n */\r\n public async executeBatchReload(\r\n changedPaths: string[],\r\n filesMap: Map<string, FileManager>,\r\n deletedFiles: string[],\r\n allChangedPaths?: string[],\r\n ): Promise<void> {\r\n const envFilesChanged = (allChangedPaths ?? []).some(isEnvPath);\r\n\r\n if (changedPaths.length === 0 && deletedFiles.length === 0 && !envFilesChanged) {\r\n return;\r\n }\r\n\r\n // Deletes: clean up routes/cleanup hooks for files that no longer exist.\r\n for (const path of deletedFiles) {\r\n const file = filesMap.get(path);\r\n if (file) this.moduleLoader.cleanupDeletedModule(file);\r\n }\r\n\r\n // Env-only change: reload all configs, restart connectors that watch them.\r\n if (changedPaths.length === 0 && envFilesChanged) {\r\n const configPaths = await this.reloadAffectedModules([\".env\"], filesMap);\r\n await this.restartAffectedConnectors(configPaths);\r\n return;\r\n }\r\n\r\n if (changedPaths.length === 0) return;\r\n\r\n const invalidationChain = new Set<string>();\r\n for (const path of changedPaths) {\r\n for (const file of this.dependencyGraph.getInvalidationChain(path)) {\r\n invalidationChain.add(file);\r\n }\r\n devLogHMR(path, invalidationChain.size - 1);\r\n }\r\n\r\n const chain = Array.from(invalidationChain);\r\n\r\n // Step 1: bump version counters so the next import() is fresh.\r\n for (const relativePath of chain) {\r\n const file = filesMap.get(relativePath);\r\n if (!file) continue;\r\n this.moduleLoader.runCleanup(file);\r\n this.bumpVersion(file.absolutePath);\r\n await file.process({ force: true });\r\n }\r\n\r\n // Step 2: wait for the hook worker to ack every bump.\r\n // Without this, resolve() may still return the old ?v=N URL.\r\n await this.flushVersionBumps();\r\n\r\n // Step 3: re-import affected special files.\r\n const affectedConfigPaths = await this.reloadAffectedModules(chain, filesMap);\r\n\r\n // Step 4: restart any connector whose watched-files overlap the chain.\r\n await this.restartAffectedConnectors([...changedPaths, ...affectedConfigPaths]);\r\n }\r\n\r\n private async restartAffectedConnectors(affectedFiles: string[]): Promise<void> {\r\n const toRestart = connectorsManager\r\n .list()\r\n .filter(connector => connector.shouldRestart(affectedFiles));\r\n\r\n for (const connector of toRestart) {\r\n await connector.restart();\r\n }\r\n }\r\n\r\n /**\r\n * Re-import every special file whose path or dependency-set intersects the\r\n * invalidation chain. Returns the relative paths of any config files that\r\n * reloaded so the caller can pass them to the connector-restart pass.\r\n */\r\n private async reloadAffectedModules(\r\n chain: string[],\r\n filesMap: Map<string, FileManager>,\r\n ): Promise<string[]> {\r\n const isEnvAffected = chain.some(isEnvPath);\r\n if (isEnvAffected) await loadEnv();\r\n\r\n const isAffected = (file: FileManager) => isFileAffected(file, chain);\r\n\r\n // Models self-register via the @RegisterModel decorator and rely on the\r\n // module-loader's registerCleanup() to attach Model.$cleanup (which\r\n // unregisters them on the next reload). That only happens inside\r\n // loadModule(), which models hit exactly once — at boot, via\r\n // autoDiscoverFiles. During HMR they're otherwise re-imported\r\n // *transitively* through routes, which never re-runs registerCleanup, so\r\n // after the first reload the cleanup list is empty and the registration\r\n // leaks (\"Model X is already registered\" on every subsequent edit).\r\n //\r\n // Re-importing changed model files through loadModule here re-attaches\r\n // $cleanup every cycle. It runs before the route pass so the decorator\r\n // registers once; the transitive route import then hits the cached ?v=N\r\n // and does not double-register.\r\n const affectedModels = chain\r\n .map(path => filesMap.get(path))\r\n .filter((file): file is FileManager => !!file && file.type === \"model\");\r\n\r\n for (const file of affectedModels) {\r\n await this.moduleLoader.loadModule(file, \"model\");\r\n }\r\n\r\n const collector = this.specialFilesCollector;\r\n const affectedConfigs = collector\r\n .getFilesByType(\"config\")\r\n .filter(file => (isEnvAffected ? true : isAffected(file)));\r\n const affectedMains = collector.getFilesByType(\"main\").filter(isAffected);\r\n const affectedRoutes = collector.getFilesByType(\"route\").filter(isAffected);\r\n const affectedEvents = collector.getFilesByType(\"event\").filter(isAffected);\r\n const affectedLocales = collector.getFilesByType(\"locale\").filter(isAffected);\r\n\r\n const hasSpecialFiles =\r\n affectedConfigs.length > 0 ||\r\n affectedMains.length > 0 ||\r\n affectedRoutes.length > 0 ||\r\n affectedEvents.length > 0 ||\r\n affectedLocales.length > 0;\r\n\r\n // No entry points touched: reloading internal files alone is wasted work\r\n // because the hook will re-import them on next access anyway. But the\r\n // dep chain's last hop is usually the user-facing edge — give it a kick.\r\n if (!hasSpecialFiles) {\r\n const tail = filesMap.get(chain[chain.length - 1]);\r\n if (tail) await this.moduleLoader.reloadModule(tail);\r\n return [];\r\n }\r\n\r\n const configPaths: string[] = [];\r\n for (const file of affectedConfigs) {\r\n await configManager.reload(file);\r\n configPaths.push(file.relativePath);\r\n }\r\n\r\n // Order matters: locales first (translations used by main), main before\r\n // routes (registers state routes consume), events between (listeners).\r\n for (const file of affectedLocales) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedMains) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedEvents) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedRoutes) await this.moduleLoader.reloadModule(file);\r\n\r\n return configPaths;\r\n }\r\n}\r\n\r\nfunction isEnvPath(path: string): boolean {\r\n const basename = path.split(\"/\").pop() ?? path;\r\n return basename === \".env\" || basename.startsWith(\".env.\");\r\n}\r\n\r\n/**\r\n * A file is \"affected\" if it itself is in the chain or imports something in it.\r\n */\r\nfunction isFileAffected(file: FileManager, chain: string[]): boolean {\r\n if (chain.includes(file.relativePath)) return true;\r\n for (const dep of file.dependencies) {\r\n if (chain.includes(dep)) return true;\r\n }\r\n return false;\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"layer-executor.mjs","names":[],"sources":["../../../../../../../core/src/dev-server/layer-executor.ts"],"sourcesContent":["import { loadEnv } from \"@mongez/dotenv\";\r\nimport { configManager } from \"../config/config-manager\";\r\nimport { connectorsManager } from \"../connectors/connectors-manager\";\r\nimport type { DependencyGraph } from \"./dependency-graph\";\r\nimport { devLogHMR } from \"./dev-logger\";\r\nimport { FileManager } from \"./file-manager\";\r\nimport type { ModuleLoader } from \"./module-loader\";\r\nimport type { SpecialFilesCollector } from \"./special-files-collector\";\r\n\r\n/**\r\n * Decides what to reload when a batch of files changes.\r\n *\r\n * Strategy: bump the hook's version counter for every file in the\r\n * invalidation chain, wait for the hook worker to flush, then re-import\r\n * any special files (config / main / routes / events / locales) the chain\r\n * touched and restart any connector whose watched-files overlap the change.\r\n */\r\nexport class LayerExecutor {\r\n public constructor(\r\n private readonly dependencyGraph: DependencyGraph,\r\n private readonly specialFilesCollector: SpecialFilesCollector,\r\n private readonly moduleLoader: ModuleLoader,\r\n private readonly bumpVersion: (absolutePath: string) => void,\r\n private readonly flushVersionBumps: () => Promise<void>,\r\n ) {}\r\n\r\n /**\r\n * Entry point for the file watcher batch.\r\n *\r\n * @param changedPaths - code files added or changed in this batch\r\n * @param filesMap - all tracked files (relativePath → FileManager)\r\n * @param deletedFiles - paths that were removed from disk\r\n * @param allChangedPaths - includes .env so we can detect config reloads\r\n */\r\n public async executeBatchReload(\r\n changedPaths: string[],\r\n filesMap: Map<string, FileManager>,\r\n deletedFiles: string[],\r\n allChangedPaths?: string[],\r\n ): Promise<void> {\r\n const envFilesChanged = (allChangedPaths ?? []).some(isEnvPath);\r\n\r\n if (changedPaths.length === 0 && deletedFiles.length === 0 && !envFilesChanged) {\r\n return;\r\n }\r\n\r\n // Deletes: clean up routes/cleanup hooks for files that no longer exist.\r\n for (const path of deletedFiles) {\r\n const file = filesMap.get(path);\r\n if (file) this.moduleLoader.cleanupDeletedModule(file);\r\n }\r\n\r\n // Env-only change: reload all configs, restart connectors that watch them.\r\n if (changedPaths.length === 0 && envFilesChanged) {\r\n const configPaths = await this.reloadAffectedModules([\".env\"], filesMap);\r\n await this.restartAffectedConnectors(configPaths);\r\n return;\r\n }\r\n\r\n if (changedPaths.length === 0) return;\r\n\r\n const invalidationChain = new Set<string>();\r\n for (const path of changedPaths) {\r\n for (const file of this.dependencyGraph.getInvalidationChain(path)) {\r\n invalidationChain.add(file);\r\n }\r\n devLogHMR(path, invalidationChain.size - 1);\r\n }\r\n\r\n const chain = Array.from(invalidationChain);\r\n\r\n // Step 1: bump version counters so the next import() is fresh.\r\n for (const relativePath of chain) {\r\n const file = filesMap.get(relativePath);\r\n if (!file) continue;\r\n this.moduleLoader.runCleanup(file);\r\n this.bumpVersion(file.absolutePath);\r\n await file.process({ force: true });\r\n }\r\n\r\n // Step 2: wait for the hook worker to ack every bump.\r\n // Without this, resolve() may still return the old ?v=N URL.\r\n await this.flushVersionBumps();\r\n\r\n // Step 3: re-import affected special files.\r\n const affectedConfigPaths = await this.reloadAffectedModules(chain, filesMap);\r\n\r\n // Step 4: restart any connector whose watched-files overlap the chain.\r\n await this.restartAffectedConnectors([...changedPaths, ...affectedConfigPaths]);\r\n }\r\n\r\n private async restartAffectedConnectors(affectedFiles: string[]): Promise<void> {\r\n const toRestart = connectorsManager\r\n .list()\r\n .filter(connector => connector.shouldRestart(affectedFiles));\r\n\r\n for (const connector of toRestart) {\r\n await connector.restart();\r\n }\r\n }\r\n\r\n /**\r\n * Re-import every special file whose path or dependency-set intersects the\r\n * invalidation chain. Returns the relative paths of any config files that\r\n * reloaded so the caller can pass them to the connector-restart pass.\r\n */\r\n private async reloadAffectedModules(\r\n chain: string[],\r\n filesMap: Map<string, FileManager>,\r\n ): Promise<string[]> {\r\n const isEnvAffected = chain.some(isEnvPath);\r\n if (isEnvAffected) await loadEnv();\r\n\r\n const isAffected = (file: FileManager) => isFileAffected(file, chain);\r\n\r\n // Models self-register via the @RegisterModel decorator and rely on the\r\n // module-loader's registerCleanup() to attach Model.$cleanup (which\r\n // unregisters them on the next reload). That only happens inside\r\n // loadModule(), which models hit exactly once — at boot, via\r\n // autoDiscoverFiles. During HMR they're otherwise re-imported\r\n // *transitively* through routes, which never re-runs registerCleanup, so\r\n // after the first reload the cleanup list is empty and the registration\r\n // leaks (\"Model X is already registered\" on every subsequent edit).\r\n //\r\n // Re-importing changed model files through loadModule here re-attaches\r\n // $cleanup every cycle. It runs before the route pass so the decorator\r\n // registers once; the transitive route import then hits the cached ?v=N\r\n // and does not double-register.\r\n const affectedModels = chain\r\n .map(path => filesMap.get(path))\r\n .filter((file): file is FileManager => !!file && file.type === \"model\");\r\n\r\n for (const file of affectedModels) {\r\n await this.moduleLoader.loadModule(file, \"model\");\r\n }\r\n\r\n const collector = this.specialFilesCollector;\r\n const affectedConfigs = collector\r\n .getFilesByType(\"config\")\r\n .filter(file => (isEnvAffected ? true : isAffected(file)));\r\n const affectedMains = collector.getFilesByType(\"main\").filter(isAffected);\r\n const affectedRoutes = collector.getFilesByType(\"route\").filter(isAffected);\r\n const affectedEvents = collector.getFilesByType(\"event\").filter(isAffected);\r\n const affectedLocales = collector.getFilesByType(\"locale\").filter(isAffected);\r\n\r\n const hasSpecialFiles =\r\n affectedConfigs.length > 0 ||\r\n affectedMains.length > 0 ||\r\n affectedRoutes.length > 0 ||\r\n affectedEvents.length > 0 ||\r\n affectedLocales.length > 0;\r\n\r\n // No entry points touched: reloading internal files alone is wasted work\r\n // because the hook will re-import them on next access anyway. But the\r\n // dep chain's last hop is usually the user-facing edge — give it a kick.\r\n if (!hasSpecialFiles) {\r\n const tail = filesMap.get(chain[chain.length - 1]);\r\n if (tail) await this.moduleLoader.reloadModule(tail);\r\n return [];\r\n }\r\n\r\n const configPaths: string[] = [];\r\n for (const file of affectedConfigs) {\r\n await configManager.reload(file);\r\n configPaths.push(file.relativePath);\r\n }\r\n\r\n // Order matters: locales first (translations used by main), main before\r\n // routes (registers state routes consume), events between (listeners).\r\n for (const file of affectedLocales) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedMains) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedEvents) await this.moduleLoader.reloadModule(file);\r\n for (const file of affectedRoutes) await this.moduleLoader.reloadModule(file);\r\n\r\n return configPaths;\r\n }\r\n}\r\n\r\nfunction isEnvPath(path: string): boolean {\r\n const basename = path.split(\"/\").pop() ?? path;\r\n return basename === \".env\" || basename.startsWith(\".env.\");\r\n}\r\n\r\n/**\r\n * A file is \"affected\" if it itself is in the chain or imports something in it.\r\n */\r\nfunction isFileAffected(file: FileManager, chain: string[]): boolean {\r\n if (chain.includes(file.relativePath)) return true;\r\n for (const dep of file.dependencies) {\r\n if (chain.includes(dep)) return true;\r\n }\r\n return false;\r\n}\r\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import "../../utils/index.mjs";
3
3
  import { computeFingerprint } from "./transpile-cache.mjs";
4
4
  import { version } from "esbuild";
5
5
 
6
- //#region ../@warlock.js/core/src/dev-server/loader/build-transpile-init.ts
6
+ //#region ../core/src/dev-server/loader/build-transpile-init.ts
7
7
  /**
8
8
  * esbuild `target` for the dev transform. Pinned to the same value the
9
9
  * production builder uses so dev and prod lower TC39 decorators (Cascade
@@ -1 +1 @@
1
- {"version":3,"file":"build-transpile-init.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/build-transpile-init.ts"],"sourcesContent":["import { version as esbuildVersion } from \"esbuild\";\nimport { warlockPath } from \"../../utils\";\nimport type { TranspileInit } from \"./load-hook.js\";\nimport { CACHE_EPOCH, computeFingerprint } from \"./transpile-cache.js\";\n\n/**\n * esbuild `target` for the dev transform. Pinned to the same value the\n * production builder uses so dev and prod lower TC39 decorators (Cascade\n * leans on them) to identical helper output — a file transpiled in dev and\n * the same file built for prod must behave the same.\n */\nconst TRANSPILE_TARGET = \"node22\";\n\n/**\n * Build the transpile payload shipped into the hook worker. Always\n * returned — esbuild transpile is unconditional (tsx is no longer in the\n * TypeScript path); persistence to `.warlock/transpile` is intrinsic.\n *\n * The fingerprint folds esbuild's version, the cache-format epoch and the\n * whole tsconfig `compilerOptions` blob (plus the target) so any change to\n * the transform contract invalidates every entry structurally — no sweep,\n * no stale output.\n *\n * @param compilerOptions - Raw tsconfig `compilerOptions` (handed to esbuild\n * as `tsconfigRaw` and hashed wholesale into the fingerprint).\n * @param debugNames - `devServer.transpileCacheDebug` — cosmetic readable\n * cache filenames. Default off.\n */\nexport function buildTranspileInit(\n compilerOptions: unknown,\n debugNames: boolean,\n): TranspileInit {\n const fingerprint = computeFingerprint({\n esbuildVersion,\n cacheEpoch: CACHE_EPOCH,\n compilerOptions: { compilerOptions, target: TRANSPILE_TARGET },\n });\n\n return {\n cacheDir: warlockPath(\"transpile\"),\n fingerprint,\n target: TRANSPILE_TARGET,\n tsconfigRaw: JSON.stringify({ compilerOptions: compilerOptions ?? {} }),\n debugNames,\n };\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,mBAAmB;;;;;;;;;;;;;;;;AAiBzB,SAAgB,mBACd,iBACA,YACe;CACf,MAAM,cAAc,mBAAmB;EACrC;EACA;EACA,iBAAiB;GAAE;GAAiB,QAAQ;EAAiB;CAC/D,CAAC;CAED,OAAO;EACL,UAAU,YAAY,WAAW;EACjC;EACA,QAAQ;EACR,aAAa,KAAK,UAAU,EAAE,iBAAiB,mBAAmB,CAAC,EAAE,CAAC;EACtE;CACF;AACF"}
1
+ {"version":3,"file":"build-transpile-init.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/build-transpile-init.ts"],"sourcesContent":["import { version as esbuildVersion } from \"esbuild\";\nimport { warlockPath } from \"../../utils\";\nimport type { TranspileInit } from \"./load-hook.js\";\nimport { CACHE_EPOCH, computeFingerprint } from \"./transpile-cache.js\";\n\n/**\n * esbuild `target` for the dev transform. Pinned to the same value the\n * production builder uses so dev and prod lower TC39 decorators (Cascade\n * leans on them) to identical helper output — a file transpiled in dev and\n * the same file built for prod must behave the same.\n */\nconst TRANSPILE_TARGET = \"node22\";\n\n/**\n * Build the transpile payload shipped into the hook worker. Always\n * returned — esbuild transpile is unconditional (tsx is no longer in the\n * TypeScript path); persistence to `.warlock/transpile` is intrinsic.\n *\n * The fingerprint folds esbuild's version, the cache-format epoch and the\n * whole tsconfig `compilerOptions` blob (plus the target) so any change to\n * the transform contract invalidates every entry structurally — no sweep,\n * no stale output.\n *\n * @param compilerOptions - Raw tsconfig `compilerOptions` (handed to esbuild\n * as `tsconfigRaw` and hashed wholesale into the fingerprint).\n * @param debugNames - `devServer.transpileCacheDebug` — cosmetic readable\n * cache filenames. Default off.\n */\nexport function buildTranspileInit(\n compilerOptions: unknown,\n debugNames: boolean,\n): TranspileInit {\n const fingerprint = computeFingerprint({\n esbuildVersion,\n cacheEpoch: CACHE_EPOCH,\n compilerOptions: { compilerOptions, target: TRANSPILE_TARGET },\n });\n\n return {\n cacheDir: warlockPath(\"transpile\"),\n fingerprint,\n target: TRANSPILE_TARGET,\n tsconfigRaw: JSON.stringify({ compilerOptions: compilerOptions ?? {} }),\n debugNames,\n };\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,mBAAmB;;;;;;;;;;;;;;;;AAiBzB,SAAgB,mBACd,iBACA,YACe;CACf,MAAM,cAAc,mBAAmB;EACrC;EACA;EACA,iBAAiB;GAAE;GAAiB,QAAQ;EAAiB;CAC/D,CAAC;CAED,OAAO;EACL,UAAU,YAAY,WAAW;EACjC;EACA,QAAQ;EACR,aAAa,KAAK,UAAU,EAAE,iBAAiB,mBAAmB,CAAC,EAAE,CAAC;EACtE;CACF;AACF"}
@@ -2,7 +2,7 @@ import { TranspileInit, load } from "./load-hook.mjs";
2
2
  import { resolve } from "./resolve-hook.mjs";
3
3
  import { MessagePort } from "node:worker_threads";
4
4
 
5
- //#region ../@warlock.js/core/src/dev-server/loader/hook-thread.d.ts
5
+ //#region ../core/src/dev-server/loader/hook-thread.d.ts
6
6
  type InitializeData = {
7
7
  port: MessagePort;
8
8
  srcRoot: string; /** Transpile config (always present — esbuild transpile is unconditional). */
@@ -1 +1 @@
1
- {"version":3,"file":"hook-thread.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/hook-thread.ts"],"mappings":";;;;;KAKK,cAAA;EACH,IAAA,EAAM,WAAA;EACN,OAAA,UAFiB;EAIjB,SAAA,EAAW,aAAa;AAAA;;;;;;;AAAA;AAiC1B;;;;;;;;;;;;;;;;;AAAuE;;;;;;iBAAvD,UAAA;EAAa,IAAA;EAAM,OAAA;EAAS;AAAA,GAAa,cAAA"}
1
+ {"version":3,"file":"hook-thread.d.mts","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/hook-thread.ts"],"mappings":";;;;;KAKK,cAAA;EACH,IAAA,EAAM,WAAA;EACN,OAAA,UAFiB;EAIjB,SAAA,EAAW,aAAa;AAAA;;;;;;;AAAA;AAiC1B;;;;;;;;;;;;;;;;;AAAuE;;;;;;iBAAvD,UAAA;EAAa,IAAA;EAAM,OAAA;EAAS;AAAA,GAAa,cAAA"}
@@ -2,7 +2,7 @@ import { configureTranspile, load } from "./load-hook.mjs";
2
2
  import { bumpVersion } from "./version-registry.mjs";
3
3
  import { resolve, setSrcRoot } from "./resolve-hook.mjs";
4
4
 
5
- //#region ../@warlock.js/core/src/dev-server/loader/hook-thread.ts
5
+ //#region ../core/src/dev-server/loader/hook-thread.ts
6
6
  /**
7
7
  * ESM loader hook entry-point.
8
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"hook-thread.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/hook-thread.ts"],"sourcesContent":["import type { MessagePort } from \"node:worker_threads\";\nimport { configureTranspile, load, type TranspileInit } from \"./load-hook.js\";\nimport { resolve, setSrcRoot } from \"./resolve-hook.js\";\nimport { bumpVersion } from \"./version-registry.js\";\n\ntype InitializeData = {\n port: MessagePort;\n srcRoot: string;\n /** Transpile config (always present — esbuild transpile is unconditional). */\n transpile: TranspileInit;\n};\n\n/**\n * ESM loader hook entry-point.\n *\n * Node's `module.register()` runs this file in a dedicated worker thread.\n * The three exported functions (`initialize`, `resolve`, `load`) are the\n * official hook lifecycle callbacks:\n *\n * - `initialize` — runs once when the hook worker starts; receives the data\n * passed as `{ data }` to `module.register()`. We use it to configure the\n * source-root filter and to wire the `MessageChannel` port that the main\n * thread uses to push version-bump notifications.\n *\n * - `resolve` — intercepts every `import` specifier resolution. The\n * framework's own resolver handles tsconfig `paths` + TS extension/index\n * probing; npm/`node:` fall through to Node default. Stamps a `?v=<N>`\n * version token onto tracked `src/` source-file URLs.\n *\n * - `load` — transpiles every `.ts`/`.tsx` with esbuild (content-hash\n * cached); non-TypeScript falls through to the Node default loader.\n *\n * @example\n * // Main thread (register-loader.ts):\n * const { port1, port2 } = new MessageChannel();\n * module.register(hookBundleUrl, import.meta.url, {\n * data: { port: port2, srcRoot: \"/abs/path/to/src\" },\n * transferList: [port2],\n * });\n * // File watcher later:\n * port1.postMessage({ type: \"bump\", absolutePath: \"/abs/path/to/user.model.ts\" });\n */\nexport function initialize({ port, srcRoot, transpile }: InitializeData): void {\n setSrcRoot(srcRoot);\n configureTranspile(transpile);\n\n port.on(\"message\", ({ type, absolutePath }: { type: string; absolutePath: string }) => {\n if (type === \"bump\") {\n bumpVersion(absolutePath);\n } else if (type === \"sync\") {\n port.postMessage({ type: \"sync-ack\" });\n }\n });\n}\n\nexport { load, resolve };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,WAAW,EAAE,MAAM,SAAS,aAAmC;CAC7E,WAAW,OAAO;CAClB,mBAAmB,SAAS;CAE5B,KAAK,GAAG,YAAY,EAAE,MAAM,mBAA2D;EACrF,IAAI,SAAS,QACX,YAAY,YAAY;OACnB,IAAI,SAAS,QAClB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;CAEzC,CAAC;AACH"}
1
+ {"version":3,"file":"hook-thread.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/hook-thread.ts"],"sourcesContent":["import type { MessagePort } from \"node:worker_threads\";\nimport { configureTranspile, load, type TranspileInit } from \"./load-hook.js\";\nimport { resolve, setSrcRoot } from \"./resolve-hook.js\";\nimport { bumpVersion } from \"./version-registry.js\";\n\ntype InitializeData = {\n port: MessagePort;\n srcRoot: string;\n /** Transpile config (always present — esbuild transpile is unconditional). */\n transpile: TranspileInit;\n};\n\n/**\n * ESM loader hook entry-point.\n *\n * Node's `module.register()` runs this file in a dedicated worker thread.\n * The three exported functions (`initialize`, `resolve`, `load`) are the\n * official hook lifecycle callbacks:\n *\n * - `initialize` — runs once when the hook worker starts; receives the data\n * passed as `{ data }` to `module.register()`. We use it to configure the\n * source-root filter and to wire the `MessageChannel` port that the main\n * thread uses to push version-bump notifications.\n *\n * - `resolve` — intercepts every `import` specifier resolution. The\n * framework's own resolver handles tsconfig `paths` + TS extension/index\n * probing; npm/`node:` fall through to Node default. Stamps a `?v=<N>`\n * version token onto tracked `src/` source-file URLs.\n *\n * - `load` — transpiles every `.ts`/`.tsx` with esbuild (content-hash\n * cached); non-TypeScript falls through to the Node default loader.\n *\n * @example\n * // Main thread (register-loader.ts):\n * const { port1, port2 } = new MessageChannel();\n * module.register(hookBundleUrl, import.meta.url, {\n * data: { port: port2, srcRoot: \"/abs/path/to/src\" },\n * transferList: [port2],\n * });\n * // File watcher later:\n * port1.postMessage({ type: \"bump\", absolutePath: \"/abs/path/to/user.model.ts\" });\n */\nexport function initialize({ port, srcRoot, transpile }: InitializeData): void {\n setSrcRoot(srcRoot);\n configureTranspile(transpile);\n\n port.on(\"message\", ({ type, absolutePath }: { type: string; absolutePath: string }) => {\n if (type === \"bump\") {\n bumpVersion(absolutePath);\n } else if (type === \"sync\") {\n port.postMessage({ type: \"sync-ack\" });\n }\n });\n}\n\nexport { load, resolve };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,WAAW,EAAE,MAAM,SAAS,aAAmC;CAC7E,WAAW,OAAO;CAClB,mBAAmB,SAAS;CAE5B,KAAK,GAAG,YAAY,EAAE,MAAM,mBAA2D;EACrF,IAAI,SAAS,QACX,YAAY,YAAY;OACnB,IAAI,SAAS,QAClB,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;CAEzC,CAAC;AACH"}
@@ -1,4 +1,4 @@
1
- //#region ../@warlock.js/core/src/dev-server/loader/load-hook.d.ts
1
+ //#region ../core/src/dev-server/loader/load-hook.d.ts
2
2
  type LoadContext = {
3
3
  format?: string;
4
4
  importAttributes?: Record<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"load-hook.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/load-hook.ts"],"mappings":";KAMK,WAAA;EACH,MAAA;EACA,gBAAA,GAAmB,MAAM;AAAA;AAAA,KAGtB,UAAA;EACH,MAAA;EACA,MAAA,WAAiB,MAAM;EACvB,YAAA;AAAA;AAAA,KAGG,QAAA,IAAY,GAAA,UAAa,OAAA,GAAU,WAAA,KAAgB,OAAA,CAAQ,UAAA;AATrC;;;;;AAAA,KAgBf,aAAA;EAXO,+CAajB,QAAA,UAZY;EAcZ,WAAA,UAXG;EAaH,MAAA;EAEA,WAAA;EAf8D;;;;;EAqB9D,UAAA;AAAA;;;;;;;;;AAAU;AAqDZ;;;;;;;;;;;;;;;;;iBAAsB,IAAA,CACpB,GAAA,UACA,OAAA,EAAS,WAAA,EACT,QAAA,EAAU,QAAA,GACT,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"load-hook.d.mts","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/load-hook.ts"],"mappings":";KAMK,WAAA;EACH,MAAA;EACA,gBAAA,GAAmB,MAAM;AAAA;AAAA,KAGtB,UAAA;EACH,MAAA;EACA,MAAA,WAAiB,MAAM;EACvB,YAAA;AAAA;AAAA,KAGG,QAAA,IAAY,GAAA,UAAa,OAAA,GAAU,WAAA,KAAgB,OAAA,CAAQ,UAAA;AATrC;;;;;AAAA,KAgBf,aAAA;EAXO,+CAajB,QAAA,UAZY;EAcZ,WAAA,UAXG;EAaH,MAAA;EAEA,WAAA;EAf8D;;;;;EAqB9D,UAAA;AAAA;;;;;;;;;AAAU;AAqDZ;;;;;;;;;;;;;;;;;iBAAsB,IAAA,CACpB,GAAA,UACA,OAAA,EAAS,WAAA,EACT,QAAA,EAAU,QAAA,GACT,OAAA,CAAQ,UAAA"}
@@ -4,7 +4,7 @@ import { transformSync } from "esbuild";
4
4
  import { readFileSync } from "node:fs";
5
5
  import { fileURLToPath } from "node:url";
6
6
 
7
- //#region ../@warlock.js/core/src/dev-server/loader/load-hook.ts
7
+ //#region ../core/src/dev-server/loader/load-hook.ts
8
8
  const VERSION_QUERY = /\?v=\d+$/;
9
9
  const TS_FILE = /\.(ts|tsx|mts|cts)$/;
10
10
  let transpile;
@@ -1 +1 @@
1
- {"version":3,"file":"load-hook.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/load-hook.ts"],"sourcesContent":["import { transformSync } from \"esbuild\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { sourceSlug } from \"./source-slug.js\";\nimport { cacheKey, TranspileCache } from \"./transpile-cache.js\";\n\ntype LoadContext = {\n format?: string;\n importAttributes?: Record<string, string>;\n};\n\ntype LoadResult = {\n format: string;\n source: string | Buffer;\n shortCircuit?: boolean;\n};\n\ntype NextLoad = (url: string, context?: LoadContext) => Promise<LoadResult>;\n\n/**\n * Everything the transpile path needs, computed once on the main thread and\n * shipped into the hook worker via `initialize()`. Always present — esbuild\n * transpile is unconditional now (tsx is no longer in the TS path).\n */\nexport type TranspileInit = {\n /** Absolute `.warlock/transpile` directory. */\n cacheDir: string;\n /** Source-content key salt: esbuild version + epoch + tsconfig blob. */\n fingerprint: string;\n /** esbuild `target` (e.g. `\"node22\"` — must match the prod builder). */\n target: string;\n /** JSON string of `{ compilerOptions }` handed to esbuild as tsconfigRaw. */\n tsconfigRaw: string;\n /**\n * Debug-only: name cache files `<slug>.<hash>.js` and append a trailing\n * `// @source <path>` marker so entries are eyeball-identifiable. Off by\n * default (opaque `<hash>.js`). Cosmetic — never affects keys or lookup.\n */\n debugNames: boolean;\n};\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\nconst TS_FILE = /\\.(ts|tsx|mts|cts)$/;\n\nlet transpile: TranspileInit;\nlet cache: TranspileCache;\n\n/**\n * Called once from the hook worker's `initialize()`. Wires the persisted\n * transpile cache and runs one opportunistic GC pass at boot — cheap, off\n * the hot path, single directory scan.\n */\nexport function configureTranspile(init: TranspileInit): void {\n transpile = init;\n cache = new TranspileCache(init.cacheDir);\n\n // Boot-time eviction so the cache can't grow unbounded across weeks of\n // dev. Bounds are generous; correctness never depends on GC (content\n // hashing already guarantees that) — this is purely disk hygiene.\n cache.gc({\n maxBytes: 256 * 1024 * 1024,\n maxAgeMs: 14 * 24 * 60 * 60 * 1000,\n });\n}\n\n/**\n * ESM loader `load()` hook.\n *\n * Owns the transpile for **every** TypeScript file — project `src/`,\n * `@warlock.js/*` framework source, and `warlock.config.ts` alike. There\n * is no tsx in the TypeScript path any more: we read the source, key it by\n * a content hash + options fingerprint, serve the cached JS on a hit, and\n * otherwise transform it with esbuild directly and persist. Non-TypeScript\n * URLs (npm `.js`/`.cjs`/`.mjs`, `node:` builtins, JSON) are not ours —\n * they fall through to the next loader (Node's default).\n *\n * The `?v=<N>` query drives Node's module identity (HMR) for `src/` files\n * and is **never** part of the cache key — the cache is keyed purely by\n * source content, so the two mechanisms are fully orthogonal. Framework\n * and config `.ts` carry no `?v` (no HMR) but are transpiled and cached\n * exactly the same way.\n *\n * The source map esbuild emits is inline base64 with `sourcefile` set to\n * the clean absolute `.ts` path, so V8 (run with source maps enabled)\n * reports stack frames at the original TypeScript location.\n *\n * @example\n * // load(\"file:///src/user.model.ts?v=3\") → esbuild transpile + cache\n * // load(\"file:///@warlock.js/core/src/x.ts\") → esbuild transpile + cache\n * // load(\"file:///node_modules/ms/index.js\") → nextLoad (Node default)\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n const cleanUrl = url.replace(VERSION_QUERY, \"\");\n\n // Not TypeScript → not ours. npm packages, node: builtins, JSON, etc.\n if (!TS_FILE.test(cleanUrl)) {\n return nextLoad(url, context);\n }\n\n const absolutePath = fileURLToPath(cleanUrl);\n const source = readFileSync(absolutePath, \"utf8\");\n const key = cacheKey(source, transpile.fingerprint);\n\n // Cosmetic filename label; undefined keeps opaque <hash>.js names.\n const label = transpile.debugNames ? sourceSlug(absolutePath) : undefined;\n\n const hit = cache.get(key, label);\n if (hit) {\n return { format: \"module\", source: hit.code, shortCircuit: true };\n }\n\n const loader = absolutePath.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n\n const result = transformSync(source, {\n loader,\n format: \"esm\",\n target: transpile.target,\n sourcefile: absolutePath,\n // Inline base64 map, self-contained (sourcesContent on by default), so\n // it survives the ?v=N URL with no extra resolution step.\n sourcemap: \"inline\",\n tsconfigRaw: transpile.tsconfigRaw,\n });\n\n // result.code already carries the inline //# sourceMappingURL. The\n // marker goes AFTER that line: a trailing comment can't shift earlier\n // generated lines, so the inline map (and therefore stack-frame line\n // numbers) stays exact. A leading marker would desync it by one line.\n const code = label\n ? `${result.code}\\n// @source ${absolutePath}\\n`\n : result.code;\n\n cache.put(key, { code, map: \"\" }, label);\n\n return { format: \"module\", source: code, shortCircuit: true };\n}\n"],"mappings":";;;;;;;AAyCA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAEhB,IAAI;AACJ,IAAI;;;;;;AAOJ,SAAgB,mBAAmB,MAA2B;CAC5D,YAAY;CACZ,QAAQ,IAAI,eAAe,KAAK,QAAQ;CAKxC,MAAM,GAAG;EACP,UAAU,MAAM,OAAO;EACvB,UAAU,MAAU,KAAK,KAAK;CAChC,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,KACpB,KACA,SACA,UACqB;CACrB,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE;CAG9C,IAAI,CAAC,QAAQ,KAAK,QAAQ,GACxB,OAAO,SAAS,KAAK,OAAO;CAG9B,MAAM,eAAe,cAAc,QAAQ;CAC3C,MAAM,SAAS,aAAa,cAAc,MAAM;CAChD,MAAM,MAAM,SAAS,QAAQ,UAAU,WAAW;CAGlD,MAAM,QAAQ,UAAU,aAAa,WAAW,YAAY,IAAI;CAEhE,MAAM,MAAM,MAAM,IAAI,KAAK,KAAK;CAChC,IAAI,KACF,OAAO;EAAE,QAAQ;EAAU,QAAQ,IAAI;EAAM,cAAc;CAAK;CAKlE,MAAM,SAAS,cAAc,QAAQ;EACnC,QAHa,aAAa,SAAS,MAAM,IAAI,QAAQ;EAIrD,QAAQ;EACR,QAAQ,UAAU;EAClB,YAAY;EAGZ,WAAW;EACX,aAAa,UAAU;CACzB,CAAC;CAMD,MAAM,OAAO,QACT,GAAG,OAAO,KAAK,eAAe,aAAa,MAC3C,OAAO;CAEX,MAAM,IAAI,KAAK;EAAE;EAAM,KAAK;CAAG,GAAG,KAAK;CAEvC,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAM,cAAc;CAAK;AAC9D"}
1
+ {"version":3,"file":"load-hook.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/load-hook.ts"],"sourcesContent":["import { transformSync } from \"esbuild\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { sourceSlug } from \"./source-slug.js\";\nimport { cacheKey, TranspileCache } from \"./transpile-cache.js\";\n\ntype LoadContext = {\n format?: string;\n importAttributes?: Record<string, string>;\n};\n\ntype LoadResult = {\n format: string;\n source: string | Buffer;\n shortCircuit?: boolean;\n};\n\ntype NextLoad = (url: string, context?: LoadContext) => Promise<LoadResult>;\n\n/**\n * Everything the transpile path needs, computed once on the main thread and\n * shipped into the hook worker via `initialize()`. Always present — esbuild\n * transpile is unconditional now (tsx is no longer in the TS path).\n */\nexport type TranspileInit = {\n /** Absolute `.warlock/transpile` directory. */\n cacheDir: string;\n /** Source-content key salt: esbuild version + epoch + tsconfig blob. */\n fingerprint: string;\n /** esbuild `target` (e.g. `\"node22\"` — must match the prod builder). */\n target: string;\n /** JSON string of `{ compilerOptions }` handed to esbuild as tsconfigRaw. */\n tsconfigRaw: string;\n /**\n * Debug-only: name cache files `<slug>.<hash>.js` and append a trailing\n * `// @source <path>` marker so entries are eyeball-identifiable. Off by\n * default (opaque `<hash>.js`). Cosmetic — never affects keys or lookup.\n */\n debugNames: boolean;\n};\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\nconst TS_FILE = /\\.(ts|tsx|mts|cts)$/;\n\nlet transpile: TranspileInit;\nlet cache: TranspileCache;\n\n/**\n * Called once from the hook worker's `initialize()`. Wires the persisted\n * transpile cache and runs one opportunistic GC pass at boot — cheap, off\n * the hot path, single directory scan.\n */\nexport function configureTranspile(init: TranspileInit): void {\n transpile = init;\n cache = new TranspileCache(init.cacheDir);\n\n // Boot-time eviction so the cache can't grow unbounded across weeks of\n // dev. Bounds are generous; correctness never depends on GC (content\n // hashing already guarantees that) — this is purely disk hygiene.\n cache.gc({\n maxBytes: 256 * 1024 * 1024,\n maxAgeMs: 14 * 24 * 60 * 60 * 1000,\n });\n}\n\n/**\n * ESM loader `load()` hook.\n *\n * Owns the transpile for **every** TypeScript file — project `src/`,\n * `@warlock.js/*` framework source, and `warlock.config.ts` alike. There\n * is no tsx in the TypeScript path any more: we read the source, key it by\n * a content hash + options fingerprint, serve the cached JS on a hit, and\n * otherwise transform it with esbuild directly and persist. Non-TypeScript\n * URLs (npm `.js`/`.cjs`/`.mjs`, `node:` builtins, JSON) are not ours —\n * they fall through to the next loader (Node's default).\n *\n * The `?v=<N>` query drives Node's module identity (HMR) for `src/` files\n * and is **never** part of the cache key — the cache is keyed purely by\n * source content, so the two mechanisms are fully orthogonal. Framework\n * and config `.ts` carry no `?v` (no HMR) but are transpiled and cached\n * exactly the same way.\n *\n * The source map esbuild emits is inline base64 with `sourcefile` set to\n * the clean absolute `.ts` path, so V8 (run with source maps enabled)\n * reports stack frames at the original TypeScript location.\n *\n * @example\n * // load(\"file:///src/user.model.ts?v=3\") → esbuild transpile + cache\n * // load(\"file:///@warlock.js/core/src/x.ts\") → esbuild transpile + cache\n * // load(\"file:///node_modules/ms/index.js\") → nextLoad (Node default)\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n const cleanUrl = url.replace(VERSION_QUERY, \"\");\n\n // Not TypeScript → not ours. npm packages, node: builtins, JSON, etc.\n if (!TS_FILE.test(cleanUrl)) {\n return nextLoad(url, context);\n }\n\n const absolutePath = fileURLToPath(cleanUrl);\n const source = readFileSync(absolutePath, \"utf8\");\n const key = cacheKey(source, transpile.fingerprint);\n\n // Cosmetic filename label; undefined keeps opaque <hash>.js names.\n const label = transpile.debugNames ? sourceSlug(absolutePath) : undefined;\n\n const hit = cache.get(key, label);\n if (hit) {\n return { format: \"module\", source: hit.code, shortCircuit: true };\n }\n\n const loader = absolutePath.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n\n const result = transformSync(source, {\n loader,\n format: \"esm\",\n target: transpile.target,\n sourcefile: absolutePath,\n // Inline base64 map, self-contained (sourcesContent on by default), so\n // it survives the ?v=N URL with no extra resolution step.\n sourcemap: \"inline\",\n tsconfigRaw: transpile.tsconfigRaw,\n });\n\n // result.code already carries the inline //# sourceMappingURL. The\n // marker goes AFTER that line: a trailing comment can't shift earlier\n // generated lines, so the inline map (and therefore stack-frame line\n // numbers) stays exact. A leading marker would desync it by one line.\n const code = label\n ? `${result.code}\\n// @source ${absolutePath}\\n`\n : result.code;\n\n cache.put(key, { code, map: \"\" }, label);\n\n return { format: \"module\", source: code, shortCircuit: true };\n}\n"],"mappings":";;;;;;;AAyCA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAEhB,IAAI;AACJ,IAAI;;;;;;AAOJ,SAAgB,mBAAmB,MAA2B;CAC5D,YAAY;CACZ,QAAQ,IAAI,eAAe,KAAK,QAAQ;CAKxC,MAAM,GAAG;EACP,UAAU,MAAM,OAAO;EACvB,UAAU,MAAU,KAAK,KAAK;CAChC,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,KACpB,KACA,SACA,UACqB;CACrB,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE;CAG9C,IAAI,CAAC,QAAQ,KAAK,QAAQ,GACxB,OAAO,SAAS,KAAK,OAAO;CAG9B,MAAM,eAAe,cAAc,QAAQ;CAC3C,MAAM,SAAS,aAAa,cAAc,MAAM;CAChD,MAAM,MAAM,SAAS,QAAQ,UAAU,WAAW;CAGlD,MAAM,QAAQ,UAAU,aAAa,WAAW,YAAY,IAAI;CAEhE,MAAM,MAAM,MAAM,IAAI,KAAK,KAAK;CAChC,IAAI,KACF,OAAO;EAAE,QAAQ;EAAU,QAAQ,IAAI;EAAM,cAAc;CAAK;CAKlE,MAAM,SAAS,cAAc,QAAQ;EACnC,QAHa,aAAa,SAAS,MAAM,IAAI,QAAQ;EAIrD,QAAQ;EACR,QAAQ,UAAU;EAClB,YAAY;EAGZ,WAAW;EACX,aAAa,UAAU;CACzB,CAAC;CAMD,MAAM,OAAO,QACT,GAAG,OAAO,KAAK,eAAe,aAAa,MAC3C,OAAO;CAEX,MAAM,IAAI,KAAK;EAAE;EAAM,KAAK;CAAG,GAAG,KAAK;CAEvC,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAM,cAAc;CAAK;AAC9D"}
@@ -1,6 +1,6 @@
1
1
  import { URL, fileURLToPath, pathToFileURL } from "node:url";
2
2
 
3
- //#region ../@warlock.js/core/src/dev-server/loader/own-resolver.ts
3
+ //#region ../core/src/dev-server/loader/own-resolver.ts
4
4
  /**
5
5
  * Extension/`index` probing for one candidate base path, mirroring tsx's
6
6
  * TypeScript-aware order:
@@ -1 +1 @@
1
- {"version":3,"file":"own-resolver.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/own-resolver.ts"],"sourcesContent":["import { fileURLToPath, pathToFileURL, URL } from \"node:url\";\n\n/**\n * The framework's own ESM `resolve()` core — the Phase B replacement for\n * delegating resolution to tsx.\n *\n * Scope by design: it owns exactly what Node's default resolver cannot do\n * (TypeScript extension/`index` probing and tsconfig `paths` aliases). For\n * anything else — bare npm packages, `node:` builtins, `file:`/`data:`\n * specifiers — it returns `null`, meaning \"not mine, fall through to the\n * next resolver\" (Node default, which already honours `node_modules` and\n * package `exports`). That keeps the risky surface minimal: we only have\n * to reproduce tsx's TS-path behaviour, not re-implement npm resolution.\n *\n * Pure and dependency-injected (`pathsMatcher`, `fileExists`) so the whole\n * thing is unit-testable and verifiable against the captured tsx-4.21\n * golden fixture without booting.\n */\n\nexport type PathsMatcher = (specifier: string) => string[];\nexport type FileExists = (absolutePath: string) => boolean;\n\n/**\n * Extension/`index` probing for one candidate base path, mirroring tsx's\n * TypeScript-aware order:\n *\n * 1. exact (if it already has a real extension that exists)\n * 2. `.js`/`.jsx`/`.mjs`/`.cjs` specifier → the TS source it compiles from\n * (`.ts`/`.tsx`) — the standard \"import the .js, ship the .ts\" ESM style\n * 3. append `.ts`, `.tsx`, `.js`, `.jsx`, `.json`\n * 4. directory index: `<dir>/index.{ts,tsx,js,jsx}`\n *\n * Returns the resolved absolute path, or `null` if nothing exists.\n */\nexport function probeFile(basePath: string, fileExists: FileExists): string | null {\n // 2. `.js` → `.ts`/`.tsx` rewrite (checked before the literal .js so a\n // co-located source wins, matching tsx).\n const jsRewrite = basePath.match(/\\.(js|jsx|mjs|cjs)$/);\n if (jsRewrite) {\n const stem = basePath.slice(0, -jsRewrite[0].length);\n for (const ext of [\".ts\", \".tsx\"]) {\n if (fileExists(stem + ext)) return stem + ext;\n }\n }\n\n // 1. exact (real extension already present and on disk)\n if (/\\.[a-z]+$/i.test(basePath) && fileExists(basePath)) {\n return basePath;\n }\n\n // 3. append source/asset extensions\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\", \".json\"]) {\n if (fileExists(basePath + ext)) return basePath + ext;\n }\n\n // 4. directory index\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\"]) {\n const candidate = `${basePath}/index${ext}`;\n if (fileExists(candidate)) return candidate;\n }\n\n return null;\n}\n\nfunction isRelative(specifier: string): boolean {\n return specifier.startsWith(\"./\") || specifier.startsWith(\"../\");\n}\n\n/**\n * Resolve `specifier` to a `file://` URL we own, or `null` to fall through\n * to the next resolver.\n *\n * @param specifier - The import specifier.\n * @param parentURL - Importing module's URL (already `?v=N`-stripped).\n * @param pathsMatcher - `get-tsconfig` paths matcher (alias → candidates).\n * @param fileExists - Existence probe (injected for testing).\n */\nexport function ownResolve(\n specifier: string,\n parentURL: string | undefined,\n pathsMatcher: PathsMatcher | null,\n fileExists: FileExists,\n): string | null {\n // Not ours: builtins and already-formed URLs (config-loader imports by\n // file: URL). Node default handles these.\n if (\n specifier.startsWith(\"node:\") ||\n specifier.startsWith(\"file:\") ||\n specifier.startsWith(\"data:\")\n ) {\n return null;\n }\n\n // Relative / absolute path imports → probe against the parent's dir.\n if (isRelative(specifier) || specifier.startsWith(\"/\") || /^[a-zA-Z]:[\\\\/]/.test(specifier)) {\n if (!parentURL) return null;\n const base = fileURLToPath(new URL(specifier, parentURL));\n const hit = probeFile(base.replace(/\\\\/g, \"/\"), fileExists);\n return hit ? pathToFileURL(hit).href : null;\n }\n\n // Bare / aliased: try tsconfig `paths`. Each candidate is probed; the\n // first that exists on disk wins. If none do (e.g. a real npm package\n // whose name happened to match a baseUrl guess), return null so Node\n // default resolves it from node_modules with full `exports` support.\n if (pathsMatcher) {\n for (const candidate of pathsMatcher(specifier)) {\n const hit = probeFile(candidate.replace(/\\\\/g, \"/\"), fileExists);\n if (hit) return pathToFileURL(hit).href;\n }\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,UAAkB,YAAuC;CAGjF,MAAM,YAAY,SAAS,MAAM,qBAAqB;CACtD,IAAI,WAAW;EACb,MAAM,OAAO,SAAS,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,MAAM;EACnD,KAAK,MAAM,OAAO,CAAC,OAAO,MAAM,GAC9B,IAAI,WAAW,OAAO,GAAG,GAAG,OAAO,OAAO;CAE9C;CAGA,IAAI,aAAa,KAAK,QAAQ,KAAK,WAAW,QAAQ,GACpD,OAAO;CAIT,KAAK,MAAM,OAAO;EAAC;EAAO;EAAQ;EAAO;EAAQ;CAAO,GACtD,IAAI,WAAW,WAAW,GAAG,GAAG,OAAO,WAAW;CAIpD,KAAK,MAAM,OAAO;EAAC;EAAO;EAAQ;EAAO;CAAM,GAAG;EAChD,MAAM,YAAY,GAAG,SAAS,QAAQ;EACtC,IAAI,WAAW,SAAS,GAAG,OAAO;CACpC;CAEA,OAAO;AACT;AAEA,SAAS,WAAW,WAA4B;CAC9C,OAAO,UAAU,WAAW,IAAI,KAAK,UAAU,WAAW,KAAK;AACjE;;;;;;;;;;AAWA,SAAgB,WACd,WACA,WACA,cACA,YACe;CAGf,IACE,UAAU,WAAW,OAAO,KAC5B,UAAU,WAAW,OAAO,KAC5B,UAAU,WAAW,OAAO,GAE5B,OAAO;CAIT,IAAI,WAAW,SAAS,KAAK,UAAU,WAAW,GAAG,KAAK,kBAAkB,KAAK,SAAS,GAAG;EAC3F,IAAI,CAAC,WAAW,OAAO;EAEvB,MAAM,MAAM,UADC,cAAc,IAAI,IAAI,WAAW,SAAS,CAC9B,CAAC,CAAC,QAAQ,OAAO,GAAG,GAAG,UAAU;EAC1D,OAAO,MAAM,cAAc,GAAG,CAAC,CAAC,OAAO;CACzC;CAMA,IAAI,cACF,KAAK,MAAM,aAAa,aAAa,SAAS,GAAG;EAC/C,MAAM,MAAM,UAAU,UAAU,QAAQ,OAAO,GAAG,GAAG,UAAU;EAC/D,IAAI,KAAK,OAAO,cAAc,GAAG,CAAC,CAAC;CACrC;CAGF,OAAO;AACT"}
1
+ {"version":3,"file":"own-resolver.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/own-resolver.ts"],"sourcesContent":["import { fileURLToPath, pathToFileURL, URL } from \"node:url\";\n\n/**\n * The framework's own ESM `resolve()` core — the Phase B replacement for\n * delegating resolution to tsx.\n *\n * Scope by design: it owns exactly what Node's default resolver cannot do\n * (TypeScript extension/`index` probing and tsconfig `paths` aliases). For\n * anything else — bare npm packages, `node:` builtins, `file:`/`data:`\n * specifiers — it returns `null`, meaning \"not mine, fall through to the\n * next resolver\" (Node default, which already honours `node_modules` and\n * package `exports`). That keeps the risky surface minimal: we only have\n * to reproduce tsx's TS-path behaviour, not re-implement npm resolution.\n *\n * Pure and dependency-injected (`pathsMatcher`, `fileExists`) so the whole\n * thing is unit-testable and verifiable against the captured tsx-4.21\n * golden fixture without booting.\n */\n\nexport type PathsMatcher = (specifier: string) => string[];\nexport type FileExists = (absolutePath: string) => boolean;\n\n/**\n * Extension/`index` probing for one candidate base path, mirroring tsx's\n * TypeScript-aware order:\n *\n * 1. exact (if it already has a real extension that exists)\n * 2. `.js`/`.jsx`/`.mjs`/`.cjs` specifier → the TS source it compiles from\n * (`.ts`/`.tsx`) — the standard \"import the .js, ship the .ts\" ESM style\n * 3. append `.ts`, `.tsx`, `.js`, `.jsx`, `.json`\n * 4. directory index: `<dir>/index.{ts,tsx,js,jsx}`\n *\n * Returns the resolved absolute path, or `null` if nothing exists.\n */\nexport function probeFile(basePath: string, fileExists: FileExists): string | null {\n // 2. `.js` → `.ts`/`.tsx` rewrite (checked before the literal .js so a\n // co-located source wins, matching tsx).\n const jsRewrite = basePath.match(/\\.(js|jsx|mjs|cjs)$/);\n if (jsRewrite) {\n const stem = basePath.slice(0, -jsRewrite[0].length);\n for (const ext of [\".ts\", \".tsx\"]) {\n if (fileExists(stem + ext)) return stem + ext;\n }\n }\n\n // 1. exact (real extension already present and on disk)\n if (/\\.[a-z]+$/i.test(basePath) && fileExists(basePath)) {\n return basePath;\n }\n\n // 3. append source/asset extensions\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\", \".json\"]) {\n if (fileExists(basePath + ext)) return basePath + ext;\n }\n\n // 4. directory index\n for (const ext of [\".ts\", \".tsx\", \".js\", \".jsx\"]) {\n const candidate = `${basePath}/index${ext}`;\n if (fileExists(candidate)) return candidate;\n }\n\n return null;\n}\n\nfunction isRelative(specifier: string): boolean {\n return specifier.startsWith(\"./\") || specifier.startsWith(\"../\");\n}\n\n/**\n * Resolve `specifier` to a `file://` URL we own, or `null` to fall through\n * to the next resolver.\n *\n * @param specifier - The import specifier.\n * @param parentURL - Importing module's URL (already `?v=N`-stripped).\n * @param pathsMatcher - `get-tsconfig` paths matcher (alias → candidates).\n * @param fileExists - Existence probe (injected for testing).\n */\nexport function ownResolve(\n specifier: string,\n parentURL: string | undefined,\n pathsMatcher: PathsMatcher | null,\n fileExists: FileExists,\n): string | null {\n // Not ours: builtins and already-formed URLs (config-loader imports by\n // file: URL). Node default handles these.\n if (\n specifier.startsWith(\"node:\") ||\n specifier.startsWith(\"file:\") ||\n specifier.startsWith(\"data:\")\n ) {\n return null;\n }\n\n // Relative / absolute path imports → probe against the parent's dir.\n if (isRelative(specifier) || specifier.startsWith(\"/\") || /^[a-zA-Z]:[\\\\/]/.test(specifier)) {\n if (!parentURL) return null;\n const base = fileURLToPath(new URL(specifier, parentURL));\n const hit = probeFile(base.replace(/\\\\/g, \"/\"), fileExists);\n return hit ? pathToFileURL(hit).href : null;\n }\n\n // Bare / aliased: try tsconfig `paths`. Each candidate is probed; the\n // first that exists on disk wins. If none do (e.g. a real npm package\n // whose name happened to match a baseUrl guess), return null so Node\n // default resolves it from node_modules with full `exports` support.\n if (pathsMatcher) {\n for (const candidate of pathsMatcher(specifier)) {\n const hit = probeFile(candidate.replace(/\\\\/g, \"/\"), fileExists);\n if (hit) return pathToFileURL(hit).href;\n }\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,UAAkB,YAAuC;CAGjF,MAAM,YAAY,SAAS,MAAM,qBAAqB;CACtD,IAAI,WAAW;EACb,MAAM,OAAO,SAAS,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,MAAM;EACnD,KAAK,MAAM,OAAO,CAAC,OAAO,MAAM,GAC9B,IAAI,WAAW,OAAO,GAAG,GAAG,OAAO,OAAO;CAE9C;CAGA,IAAI,aAAa,KAAK,QAAQ,KAAK,WAAW,QAAQ,GACpD,OAAO;CAIT,KAAK,MAAM,OAAO;EAAC;EAAO;EAAQ;EAAO;EAAQ;CAAO,GACtD,IAAI,WAAW,WAAW,GAAG,GAAG,OAAO,WAAW;CAIpD,KAAK,MAAM,OAAO;EAAC;EAAO;EAAQ;EAAO;CAAM,GAAG;EAChD,MAAM,YAAY,GAAG,SAAS,QAAQ;EACtC,IAAI,WAAW,SAAS,GAAG,OAAO;CACpC;CAEA,OAAO;AACT;AAEA,SAAS,WAAW,WAA4B;CAC9C,OAAO,UAAU,WAAW,IAAI,KAAK,UAAU,WAAW,KAAK;AACjE;;;;;;;;;;AAWA,SAAgB,WACd,WACA,WACA,cACA,YACe;CAGf,IACE,UAAU,WAAW,OAAO,KAC5B,UAAU,WAAW,OAAO,KAC5B,UAAU,WAAW,OAAO,GAE5B,OAAO;CAIT,IAAI,WAAW,SAAS,KAAK,UAAU,WAAW,GAAG,KAAK,kBAAkB,KAAK,SAAS,GAAG;EAC3F,IAAI,CAAC,WAAW,OAAO;EAEvB,MAAM,MAAM,UADC,cAAc,IAAI,IAAI,WAAW,SAAS,CAC9B,CAAC,CAAC,QAAQ,OAAO,GAAG,GAAG,UAAU;EAC1D,OAAO,MAAM,cAAc,GAAG,CAAC,CAAC,OAAO;CACzC;CAMA,IAAI,cACF,KAAK,MAAM,aAAa,aAAa,SAAS,GAAG;EAC/C,MAAM,MAAM,UAAU,UAAU,QAAQ,OAAO,GAAG,GAAG,UAAU;EAC/D,IAAI,KAAK,OAAO,cAAc,GAAG,CAAC,CAAC;CACrC;CAGF,OAAO;AACT"}
@@ -5,7 +5,7 @@ import { build } from "esbuild";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { MessageChannel } from "node:worker_threads";
7
7
 
8
- //#region ../@warlock.js/core/src/dev-server/loader/register-loader.ts
8
+ //#region ../core/src/dev-server/loader/register-loader.ts
9
9
  /**
10
10
  * Bundle, write, and register the ESM loader hook.
11
11
  *
@@ -1 +1 @@
1
- {"version":3,"file":"register-loader.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/register-loader.ts"],"sourcesContent":["import { putFileAsync } from \"@warlock.js/fs\";\nimport { build } from \"esbuild\";\nimport { register } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { type MessagePort, MessageChannel } from \"node:worker_threads\";\nimport type { TranspileInit } from \"./load-hook.js\";\n\n/**\n * Bundle, write, and register the ESM loader hook.\n *\n * **Why bundle?**\n * `module.register()` runs the hook file in a fresh Node.js worker thread that\n * has no tsx hook of its own. The hook source is TypeScript, so we must produce\n * a plain ESM bundle before registering. esbuild inline-bundles all three hook\n * modules (`hook-thread`, `resolve-hook`, `load-hook`, `version-registry`)\n * into a single `.mjs` file written to `.warlock/`. External npm packages\n * (`esbuild`, `node:*`) are kept external — the hook thread can resolve those\n * from `node_modules` normally.\n *\n * **Why a file and not a `data:` URL?**\n * Some Node versions have issues resolving `import.meta.url` inside `data:`\n * modules. A real file under `.warlock/` is simpler and debuggable.\n *\n * **Timing**\n * Called from `FilesOrchestrator.init()` before any user `src/` module is\n * dynamically imported. `module.register()` takes effect for all subsequent\n * `import()` calls, which is exactly the window we need.\n *\n * @param transpile - Transpile-cache config to ship into the hook worker,\n * or `null` to keep the hook in tsx-passthrough mode.\n *\n * @returns The main-thread side of the MessageChannel. Callers post\n * `{ type: \"bump\", absolutePath }` messages on it to invalidate modules.\n *\n * @example\n * const port = await registerLoader(transpileInit);\n * // Later, when a file changes:\n * port.postMessage({ type: \"bump\", absolutePath: \"/abs/path/to/user.model.ts\" });\n */\nexport async function registerLoader(\n transpile: TranspileInit,\n): Promise<MessagePort> {\n const { port1, port2 } = new MessageChannel();\n\n // hook-thread is a sibling module, so it shares THIS file's extension:\n // `.ts` when core runs from source (tsx), `.mjs` when published.\n const selfPath = fileURLToPath(import.meta.url);\n const hookThreadPath = path.join(\n path.dirname(selfPath),\n `hook-thread${path.extname(selfPath)}`,\n );\n\n const bundleResult = await build({\n entryPoints: [hookThreadPath],\n bundle: true,\n format: \"esm\",\n write: false,\n platform: \"node\",\n target: \"node20\",\n // Keep npm packages and Node built-ins external — the hook thread resolves\n // them normally from node_modules at runtime.\n packages: \"external\",\n });\n\n const bundledCode = bundleResult.outputFiles[0].text;\n // Caller (filesOrchestrator.init) guarantees .warlock/ exists before this runs.\n const hookBundlePath = path.join(process.cwd(), \".warlock\", \"loader-hook.mjs\");\n await putFileAsync(hookBundlePath, bundledCode);\n\n const srcRoot = path.join(process.cwd(), \"src\");\n\n // No tsx registration: our hook owns resolution (own-resolver) and the\n // transpile of every `.ts`/`.tsx` (esbuild, in the load hook). The chain\n // is simply [our hook] → [Node default] for non-TS (npm/.js, node:).\n // In this monorepo tsx is still the *launcher* (`tsx start.ts`) so its\n // loader is present anyway, but it is never consulted for TypeScript —\n // our hook short-circuits first. A released `node bin/warlock.js` has no\n // tsx at all and relies entirely on this hook.\n\n register(pathToFileURL(hookBundlePath).href, import.meta.url, {\n data: { port: port2, srcRoot, transpile },\n transferList: [port2],\n });\n\n return port1;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,eAAsB,eACpB,WACsB;CACtB,MAAM,EAAE,OAAO,UAAU,IAAI,eAAe;CAI5C,MAAM,WAAW,cAAc,OAAO,KAAK,GAAG;CAkB9C,MAAM,eAAc,MAZO,MAAM;EAC/B,aAAa,CANQ,KAAK,KAC1B,KAAK,QAAQ,QAAQ,GACrB,cAAc,KAAK,QAAQ,QAAQ,GAIR,CAAC;EAC5B,QAAQ;EACR,QAAQ;EACR,OAAO;EACP,UAAU;EACV,QAAQ;EAGR,UAAU;CACZ,CAAC,EAE+B,CAAC,YAAY,EAAE,CAAC;CAEhD,MAAM,iBAAiB,KAAK,KAAK,QAAQ,IAAI,GAAG,YAAY,iBAAiB;CAC7E,MAAM,aAAa,gBAAgB,WAAW;CAE9C,MAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,KAAK;CAU9C,SAAS,cAAc,cAAc,CAAC,CAAC,MAAM,OAAO,KAAK,KAAK;EAC5D,MAAM;GAAE,MAAM;GAAO;GAAS;EAAU;EACxC,cAAc,CAAC,KAAK;CACtB,CAAC;CAED,OAAO;AACT"}
1
+ {"version":3,"file":"register-loader.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/register-loader.ts"],"sourcesContent":["import { putFileAsync } from \"@warlock.js/fs\";\nimport { build } from \"esbuild\";\nimport { register } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { type MessagePort, MessageChannel } from \"node:worker_threads\";\nimport type { TranspileInit } from \"./load-hook.js\";\n\n/**\n * Bundle, write, and register the ESM loader hook.\n *\n * **Why bundle?**\n * `module.register()` runs the hook file in a fresh Node.js worker thread that\n * has no tsx hook of its own. The hook source is TypeScript, so we must produce\n * a plain ESM bundle before registering. esbuild inline-bundles all three hook\n * modules (`hook-thread`, `resolve-hook`, `load-hook`, `version-registry`)\n * into a single `.mjs` file written to `.warlock/`. External npm packages\n * (`esbuild`, `node:*`) are kept external — the hook thread can resolve those\n * from `node_modules` normally.\n *\n * **Why a file and not a `data:` URL?**\n * Some Node versions have issues resolving `import.meta.url` inside `data:`\n * modules. A real file under `.warlock/` is simpler and debuggable.\n *\n * **Timing**\n * Called from `FilesOrchestrator.init()` before any user `src/` module is\n * dynamically imported. `module.register()` takes effect for all subsequent\n * `import()` calls, which is exactly the window we need.\n *\n * @param transpile - Transpile-cache config to ship into the hook worker,\n * or `null` to keep the hook in tsx-passthrough mode.\n *\n * @returns The main-thread side of the MessageChannel. Callers post\n * `{ type: \"bump\", absolutePath }` messages on it to invalidate modules.\n *\n * @example\n * const port = await registerLoader(transpileInit);\n * // Later, when a file changes:\n * port.postMessage({ type: \"bump\", absolutePath: \"/abs/path/to/user.model.ts\" });\n */\nexport async function registerLoader(\n transpile: TranspileInit,\n): Promise<MessagePort> {\n const { port1, port2 } = new MessageChannel();\n\n // hook-thread is a sibling module, so it shares THIS file's extension:\n // `.ts` when core runs from source (tsx), `.mjs` when published.\n const selfPath = fileURLToPath(import.meta.url);\n const hookThreadPath = path.join(\n path.dirname(selfPath),\n `hook-thread${path.extname(selfPath)}`,\n );\n\n const bundleResult = await build({\n entryPoints: [hookThreadPath],\n bundle: true,\n format: \"esm\",\n write: false,\n platform: \"node\",\n target: \"node20\",\n // Keep npm packages and Node built-ins external — the hook thread resolves\n // them normally from node_modules at runtime.\n packages: \"external\",\n });\n\n const bundledCode = bundleResult.outputFiles[0].text;\n // Caller (filesOrchestrator.init) guarantees .warlock/ exists before this runs.\n const hookBundlePath = path.join(process.cwd(), \".warlock\", \"loader-hook.mjs\");\n await putFileAsync(hookBundlePath, bundledCode);\n\n const srcRoot = path.join(process.cwd(), \"src\");\n\n // No tsx registration: our hook owns resolution (own-resolver) and the\n // transpile of every `.ts`/`.tsx` (esbuild, in the load hook). The chain\n // is simply [our hook] → [Node default] for non-TS (npm/.js, node:).\n // In this monorepo tsx is still the *launcher* (`tsx start.ts`) so its\n // loader is present anyway, but it is never consulted for TypeScript —\n // our hook short-circuits first. A released `node bin/warlock.js` has no\n // tsx at all and relies entirely on this hook.\n\n register(pathToFileURL(hookBundlePath).href, import.meta.url, {\n data: { port: port2, srcRoot, transpile },\n transferList: [port2],\n });\n\n return port1;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,eAAsB,eACpB,WACsB;CACtB,MAAM,EAAE,OAAO,UAAU,IAAI,eAAe;CAI5C,MAAM,WAAW,cAAc,OAAO,KAAK,GAAG;CAkB9C,MAAM,eAAc,MAZO,MAAM;EAC/B,aAAa,CANQ,KAAK,KAC1B,KAAK,QAAQ,QAAQ,GACrB,cAAc,KAAK,QAAQ,QAAQ,GAIR,CAAC;EAC5B,QAAQ;EACR,QAAQ;EACR,OAAO;EACP,UAAU;EACV,QAAQ;EAGR,UAAU;CACZ,CAAC,EAE+B,CAAC,YAAY,EAAE,CAAC;CAEhD,MAAM,iBAAiB,KAAK,KAAK,QAAQ,IAAI,GAAG,YAAY,iBAAiB;CAC7E,MAAM,aAAa,gBAAgB,WAAW;CAE9C,MAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,KAAK;CAU9C,SAAS,cAAc,cAAc,CAAC,CAAC,MAAM,OAAO,KAAK,KAAK;EAC5D,MAAM;GAAE,MAAM;GAAO;GAAS;EAAU;EACxC,cAAc,CAAC,KAAK;CACtB,CAAC;CAED,OAAO;AACT"}
@@ -1,6 +1,6 @@
1
1
  import { appendFileSync } from "node:fs";
2
2
 
3
- //#region ../@warlock.js/core/src/dev-server/loader/resolve-capture.ts
3
+ //#region ../core/src/dev-server/loader/resolve-capture.ts
4
4
  /**
5
5
  * Golden-fixture recorder for the Phase B resolver work.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-capture.mjs","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/resolve-capture.ts"],"sourcesContent":["import { appendFileSync } from \"node:fs\";\n\n/**\n * Golden-fixture recorder for the Phase B resolver work.\n *\n * When `WARLOCK_RESOLVE_CAPTURE` points at a file path, every resolution\n * the *current* (tsx-backed) hook performs is appended there as one JSON\n * object per line: `{ specifier, parentURL, url, format }`, all with the\n * `?v=N` HMR token stripped so the record is stable across runs.\n *\n * A full `yarn start` boot then yields the real import graph's resolutions\n * — tsconfig paths, workspace `@warlock.js/*`, relative/extensionless,\n * package `exports`, bare npm, `node:` builtins — as the ground truth the\n * replacement resolver must reproduce exactly.\n *\n * Disabled (the default) it is a single env-var read and an immediate\n * return: no measurable cost on the resolve hot path.\n */\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\n\nlet resolvedPath: string | null | undefined;\n\nfunction targetFile(): string | null {\n if (resolvedPath !== undefined) return resolvedPath;\n resolvedPath = process.env.WARLOCK_RESOLVE_CAPTURE || null;\n return resolvedPath;\n}\n\nexport type ResolutionRecord = {\n specifier: string;\n parentURL: string | undefined;\n url: string;\n format: string | undefined;\n};\n\nexport function captureResolution(record: ResolutionRecord): void {\n const file = targetFile();\n if (!file) return;\n\n const line =\n JSON.stringify({\n specifier: record.specifier,\n parentURL: record.parentURL?.replace(VERSION_QUERY, \"\"),\n url: record.url.replace(VERSION_QUERY, \"\"),\n format: record.format,\n }) + \"\\n\";\n\n try {\n appendFileSync(file, line);\n } catch {\n // Capture is a diagnostic aid — never let it break resolution.\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAM,gBAAgB;AAEtB,IAAI;AAEJ,SAAS,aAA4B;CACnC,IAAI,iBAAiB,QAAW,OAAO;CACvC,eAAe,QAAQ,IAAI,2BAA2B;CACtD,OAAO;AACT;AASA,SAAgB,kBAAkB,QAAgC;CAChE,MAAM,OAAO,WAAW;CACxB,IAAI,CAAC,MAAM;CAEX,MAAM,OACJ,KAAK,UAAU;EACb,WAAW,OAAO;EAClB,WAAW,OAAO,WAAW,QAAQ,eAAe,EAAE;EACtD,KAAK,OAAO,IAAI,QAAQ,eAAe,EAAE;EACzC,QAAQ,OAAO;CACjB,CAAC,IAAI;CAEP,IAAI;EACF,eAAe,MAAM,IAAI;CAC3B,QAAQ,CAER;AACF"}
1
+ {"version":3,"file":"resolve-capture.mjs","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/resolve-capture.ts"],"sourcesContent":["import { appendFileSync } from \"node:fs\";\n\n/**\n * Golden-fixture recorder for the Phase B resolver work.\n *\n * When `WARLOCK_RESOLVE_CAPTURE` points at a file path, every resolution\n * the *current* (tsx-backed) hook performs is appended there as one JSON\n * object per line: `{ specifier, parentURL, url, format }`, all with the\n * `?v=N` HMR token stripped so the record is stable across runs.\n *\n * A full `yarn start` boot then yields the real import graph's resolutions\n * — tsconfig paths, workspace `@warlock.js/*`, relative/extensionless,\n * package `exports`, bare npm, `node:` builtins — as the ground truth the\n * replacement resolver must reproduce exactly.\n *\n * Disabled (the default) it is a single env-var read and an immediate\n * return: no measurable cost on the resolve hot path.\n */\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\n\nlet resolvedPath: string | null | undefined;\n\nfunction targetFile(): string | null {\n if (resolvedPath !== undefined) return resolvedPath;\n resolvedPath = process.env.WARLOCK_RESOLVE_CAPTURE || null;\n return resolvedPath;\n}\n\nexport type ResolutionRecord = {\n specifier: string;\n parentURL: string | undefined;\n url: string;\n format: string | undefined;\n};\n\nexport function captureResolution(record: ResolutionRecord): void {\n const file = targetFile();\n if (!file) return;\n\n const line =\n JSON.stringify({\n specifier: record.specifier,\n parentURL: record.parentURL?.replace(VERSION_QUERY, \"\"),\n url: record.url.replace(VERSION_QUERY, \"\"),\n format: record.format,\n }) + \"\\n\";\n\n try {\n appendFileSync(file, line);\n } catch {\n // Capture is a diagnostic aid — never let it break resolution.\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAM,gBAAgB;AAEtB,IAAI;AAEJ,SAAS,aAA4B;CACnC,IAAI,iBAAiB,QAAW,OAAO;CACvC,eAAe,QAAQ,IAAI,2BAA2B;CACtD,OAAO;AACT;AASA,SAAgB,kBAAkB,QAAgC;CAChE,MAAM,OAAO,WAAW;CACxB,IAAI,CAAC,MAAM;CAEX,MAAM,OACJ,KAAK,UAAU;EACb,WAAW,OAAO;EAClB,WAAW,OAAO,WAAW,QAAQ,eAAe,EAAE;EACtD,KAAK,OAAO,IAAI,QAAQ,eAAe,EAAE;EACzC,QAAQ,OAAO;CACjB,CAAC,IAAI;CAEP,IAAI;EACF,eAAe,MAAM,IAAI;CAC3B,QAAQ,CAER;AACF"}
@@ -1,4 +1,4 @@
1
- //#region ../@warlock.js/core/src/dev-server/loader/resolve-hook.d.ts
1
+ //#region ../core/src/dev-server/loader/resolve-hook.d.ts
2
2
  type ResolveContext = {
3
3
  parentURL?: string;
4
4
  conditions?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-hook.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/core/src/dev-server/loader/resolve-hook.ts"],"mappings":";KAqCK,cAAA;EACH,SAAA;EACA,UAAA;EACA,gBAAA,GAAmB,MAAM;AAAA;AAAA,KAGtB,aAAA;EACH,GAAA;EACA,MAAA;EACA,YAAA;AAAA;AAAA,KAGG,WAAA,IAAe,SAAA,UAAmB,OAAA,GAAU,cAAA,KAAmB,OAAA,CAAQ,aAAA;;AAH9D;AAAA;;;;;;;;;;;;;;AAG2E;AA2BzF;;;;;;;;iBAAsB,OAAA,CACpB,SAAA,UACA,OAAA,EAAS,cAAA,EACT,WAAA,EAAa,WAAA,GACZ,OAAA,CAAQ,aAAA"}
1
+ {"version":3,"file":"resolve-hook.d.mts","names":[],"sources":["../../../../../../../../core/src/dev-server/loader/resolve-hook.ts"],"mappings":";KAqCK,cAAA;EACH,SAAA;EACA,UAAA;EACA,gBAAA,GAAmB,MAAM;AAAA;AAAA,KAGtB,aAAA;EACH,GAAA;EACA,MAAA;EACA,YAAA;AAAA;AAAA,KAGG,WAAA,IAAe,SAAA,UAAmB,OAAA,GAAU,cAAA,KAAmB,OAAA,CAAQ,aAAA;;AAH9D;AAAA;;;;;;;;;;;;;;AAG2E;AA2BzF;;;;;;;;iBAAsB,OAAA,CACpB,SAAA,UACA,OAAA,EAAS,cAAA,EACT,WAAA,EAAa,WAAA,GACZ,OAAA,CAAQ,aAAA"}