nodefony 7.0.2 → 10.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (903) hide show
  1. package/.ai/symbols.json +36135 -0
  2. package/LICENSE +544 -0
  3. package/README.md +316 -694
  4. package/bin/nodefony +2183 -85
  5. package/dist/client/Container.js +367 -0
  6. package/dist/client/Event.js +198 -0
  7. package/dist/client/Service.js +344 -0
  8. package/dist/client/Tools.js +162 -0
  9. package/dist/client/client/ClientKernel.js +276 -0
  10. package/dist/client/client/angular/index.js +352 -0
  11. package/dist/client/client/announce.js +212 -0
  12. package/dist/client/client/debugbar/DebugBar.js +1624 -0
  13. package/dist/client/client/debugbar/format.js +103 -0
  14. package/dist/client/client/debugbar/hmr.js +37 -0
  15. package/dist/client/client/debugbar/index.js +29 -0
  16. package/dist/client/client/debugbar/model.js +133 -0
  17. package/dist/client/client/debugbar/network.js +173 -0
  18. package/dist/client/client/debugbar/profile.js +114 -0
  19. package/dist/client/client/index.js +34 -0
  20. package/dist/client/client/react/index.js +268 -0
  21. package/dist/client/client/realtime/AdaptiveRate.js +240 -0
  22. package/dist/client/client/realtime/BrowserWsTransport.js +57 -0
  23. package/dist/client/client/realtime/RealtimeClient.js +898 -0
  24. package/dist/client/client/realtime/localEvents.js +56 -0
  25. package/dist/client/client/realtime/notice.js +125 -0
  26. package/dist/client/client/realtime/observe.js +280 -0
  27. package/dist/client/client/roles/index.js +3 -0
  28. package/dist/client/client/roles/registry.js +97 -0
  29. package/dist/client/client/roles/roles.js +91 -0
  30. package/dist/client/client/shim/events.js +88 -0
  31. package/dist/client/client/shim/util.js +20 -0
  32. package/dist/client/client/svelte/index.js +319 -0
  33. package/dist/client/client/syslog/context.js +122 -0
  34. package/dist/client/client/syslog/errors.js +49 -0
  35. package/dist/client/client/syslog/uplink.js +106 -0
  36. package/dist/client/client/vue/index.js +321 -0
  37. package/dist/client/colors.js +63 -0
  38. package/dist/client/debugbar.standalone.js +4274 -0
  39. package/dist/client/realtime/IRealtimeTransport.js +32 -0
  40. package/dist/client/realtime/JsonRpcPeer.js +251 -0
  41. package/dist/client/realtime/channelRate.js +39 -0
  42. package/dist/client/realtime/platformChannels.js +155 -0
  43. package/dist/client/syslog/Pdu.js +224 -0
  44. package/dist/client/syslog/Syslog.js +1159 -0
  45. package/dist/client/syslog/drivers/pduFlow.js +106 -0
  46. package/dist/client/syslog/drivers/pduProtocol.js +28 -0
  47. package/dist/client/syslog/logColor.js +80 -0
  48. package/dist/client/types/src/Container.d.ts +221 -0
  49. package/dist/client/types/src/Event.d.ts +171 -0
  50. package/dist/client/types/src/FileClass.d.ts +184 -0
  51. package/dist/client/types/src/Service.d.ts +165 -0
  52. package/dist/client/types/src/Tools.d.ts +116 -0
  53. package/dist/client/types/src/client/ClientKernel.d.ts +90 -0
  54. package/dist/client/types/src/client/IClientKernel.d.ts +195 -0
  55. package/dist/client/types/src/client/angular/index.d.ts +273 -0
  56. package/dist/client/types/src/client/announce.d.ts +74 -0
  57. package/dist/client/types/src/client/debugbar/DebugBar.d.ts +279 -0
  58. package/dist/client/types/src/client/debugbar/format.d.ts +48 -0
  59. package/dist/client/types/src/client/debugbar/hmr.d.ts +16 -0
  60. package/dist/client/types/src/client/debugbar/index.d.ts +30 -0
  61. package/dist/client/types/src/client/debugbar/model.d.ts +158 -0
  62. package/dist/client/types/src/client/debugbar/network.d.ts +55 -0
  63. package/dist/client/types/src/client/debugbar/profile.d.ts +99 -0
  64. package/dist/client/types/src/client/index.d.ts +47 -0
  65. package/dist/client/types/src/client/react/index.d.ts +207 -0
  66. package/dist/client/types/src/client/realtime/AdaptiveRate.d.ts +138 -0
  67. package/dist/client/types/src/client/realtime/BrowserWsTransport.d.ts +27 -0
  68. package/dist/client/types/src/client/realtime/RealtimeClient.d.ts +573 -0
  69. package/dist/client/types/src/client/realtime/localEvents.d.ts +53 -0
  70. package/dist/client/types/src/client/realtime/notice.d.ts +70 -0
  71. package/dist/client/types/src/client/realtime/observe.d.ts +284 -0
  72. package/dist/client/types/src/client/roles/index.d.ts +15 -0
  73. package/dist/client/types/src/client/roles/registry.d.ts +72 -0
  74. package/dist/client/types/src/client/roles/roles.d.ts +68 -0
  75. package/dist/client/types/src/client/shim/cli-color.d.ts +2 -0
  76. package/dist/client/types/src/client/shim/events.d.ts +39 -0
  77. package/dist/client/types/src/client/shim/util.d.ts +14 -0
  78. package/dist/client/types/src/client/svelte/index.d.ts +216 -0
  79. package/dist/client/types/src/client/syslog/context.d.ts +76 -0
  80. package/dist/client/types/src/client/syslog/errors.d.ts +46 -0
  81. package/dist/client/types/src/client/syslog/uplink.d.ts +89 -0
  82. package/dist/client/types/src/client/transport/websocket.d.ts +5 -0
  83. package/dist/client/types/src/client/vue/index.d.ts +234 -0
  84. package/dist/client/types/src/colors.d.ts +32 -0
  85. package/dist/client/types/src/config/infra.d.ts +171 -0
  86. package/dist/client/types/src/kernel/bootReport.d.ts +112 -0
  87. package/dist/client/types/src/kernel/readinessRegistry.d.ts +104 -0
  88. package/dist/client/types/src/realtime/IRealtimeSocket.d.ts +142 -0
  89. package/dist/client/types/src/realtime/IRealtimeTransport.d.ts +50 -0
  90. package/dist/client/types/src/realtime/JsonRpcPeer.d.ts +251 -0
  91. package/dist/client/types/src/realtime/RealtimeEventMap.d.ts +269 -0
  92. package/dist/client/types/src/realtime/channelRate.d.ts +55 -0
  93. package/dist/client/types/src/realtime/platformChannels.d.ts +147 -0
  94. package/dist/client/types/src/syslog/Pdu.d.ts +134 -0
  95. package/dist/client/types/src/syslog/Syslog.d.ts +482 -0
  96. package/dist/client/types/src/syslog/drivers/ILogDriver.d.ts +177 -0
  97. package/dist/client/types/src/syslog/drivers/pduFlow.d.ts +53 -0
  98. package/dist/client/types/src/syslog/drivers/pduProtocol.d.ts +20 -0
  99. package/dist/client/types/src/syslog/logColor.d.ts +59 -0
  100. package/dist/client/types/src/types/ICliKernel.d.ts +28 -0
  101. package/dist/client/types/src/types/ICommand.d.ts +14 -0
  102. package/dist/client/types/src/types/IContainer.d.ts +35 -0
  103. package/dist/client/types/src/types/IKernel.d.ts +138 -0
  104. package/dist/client/types/src/types/IMcpTool.d.ts +157 -0
  105. package/dist/client/types/src/types/IModule.d.ts +73 -0
  106. package/dist/client/types/src/types/IPage.d.ts +119 -0
  107. package/dist/client/types/src/types/IService.d.ts +62 -0
  108. package/dist/client/types/src/types/ISyslog.d.ts +58 -0
  109. package/dist/client/types/src/types/ITransport.d.ts +5 -0
  110. package/dist/client/types/src/types/globals.d.ts +47 -0
  111. package/dist/node/Cli.js +750 -0
  112. package/dist/node/Container.js +367 -0
  113. package/dist/node/Error.js +309 -0
  114. package/dist/node/Event.js +198 -0
  115. package/dist/node/FileClass.js +308 -0
  116. package/dist/node/Nodefony.js +78 -0
  117. package/dist/node/Service.js +344 -0
  118. package/dist/node/Tools.js +205 -0
  119. package/dist/node/bin/resolveLocalCli.js +10 -0
  120. package/dist/node/bundler/index.js +103 -0
  121. package/dist/node/cli/agentTargets.js +461 -0
  122. package/dist/node/cli/aiMcp.js +553 -0
  123. package/dist/node/cli/aiMcpReport.js +129 -0
  124. package/dist/node/cli/aiSync.js +323 -0
  125. package/dist/node/cli/aiSyncReport.js +142 -0
  126. package/dist/node/cli/card.js +186 -0
  127. package/dist/node/cli/cardReport.js +110 -0
  128. package/dist/node/cli/completion.js +415 -0
  129. package/dist/node/cli/create.js +805 -0
  130. package/dist/node/cli/env.js +332 -0
  131. package/dist/node/cli/envReport.js +159 -0
  132. package/dist/node/cli/execPortable.js +60 -0
  133. package/dist/node/cli/gitHooks.js +191 -0
  134. package/dist/node/cli/gitHooksReport.js +119 -0
  135. package/dist/node/cli/globalFlags.js +67 -0
  136. package/dist/node/cli/helpReport.js +288 -0
  137. package/dist/node/cli/manPage.js +165 -0
  138. package/dist/node/cli/nodefonyBin.js +61 -0
  139. package/dist/node/cli/outdated.js +144 -0
  140. package/dist/node/cli/progress.js +555 -0
  141. package/dist/node/cli/projectRoot.js +32 -0
  142. package/dist/node/cli/promptPassword.js +44 -0
  143. package/dist/node/cli/prompts.js +86 -0
  144. package/dist/node/cli/scaffold/destination.js +92 -0
  145. package/dist/node/cli/scaffold/engine.js +2156 -0
  146. package/dist/node/cli/scaffold/entityFields.js +589 -0
  147. package/dist/node/cli/scaffold/format.js +243 -0
  148. package/dist/node/cli/scaffold/interactive.js +124 -0
  149. package/dist/node/cli/scaffold/moduleLayout.js +38 -0
  150. package/dist/node/cli/scaffold/reservedEntities.js +74 -0
  151. package/dist/node/cli/scaffold/spec.js +704 -0
  152. package/dist/node/cli/scaffold/steps.js +40 -0
  153. package/dist/node/cli/scaffold/userContractSource.js +133 -0
  154. package/dist/node/cli/scaffold/versions.js +57 -0
  155. package/dist/node/cli/scaffold/writer.js +172 -0
  156. package/dist/node/cli/startMenu.js +496 -0
  157. package/dist/node/cli/symbols.js +205 -0
  158. package/dist/node/cli/sysexits.js +34 -0
  159. package/dist/node/cli/tableReport.js +184 -0
  160. package/dist/node/cli/usageReport.js +144 -0
  161. package/dist/node/colors.js +63 -0
  162. package/dist/node/command/Builder.js +153 -0
  163. package/dist/node/command/Command.js +348 -0
  164. package/dist/node/config/configProvenance.js +101 -0
  165. package/dist/node/config/defaults.js +39 -0
  166. package/dist/node/config/defineConfig.js +129 -0
  167. package/dist/node/config/defineEnv.js +264 -0
  168. package/dist/node/config/envExample.js +41 -0
  169. package/dist/node/config/envOverride.js +423 -0
  170. package/dist/node/config/infra.js +163 -0
  171. package/dist/node/config/reactivity.js +23 -0
  172. package/dist/node/config/reservedEnv.js +118 -0
  173. package/dist/node/config/schema.js +134 -0
  174. package/dist/node/config/use.js +24 -0
  175. package/dist/node/finder/File.js +49 -0
  176. package/dist/node/finder/FileResult.js +86 -0
  177. package/dist/node/finder/Finder.js +201 -0
  178. package/dist/node/finder/Result.js +45 -0
  179. package/dist/node/index.js +121 -0
  180. package/dist/node/kernel/BootConfigurationError.js +54 -0
  181. package/dist/node/kernel/CliKernel.js +630 -0
  182. package/dist/node/kernel/Kernel.js +2198 -0
  183. package/dist/node/kernel/Module.js +453 -0
  184. package/dist/node/kernel/adminPlane/adminCaller.js +98 -0
  185. package/dist/node/kernel/adminPlane/adminRbac.js +51 -0
  186. package/dist/node/kernel/adminPlane/catalog.js +158 -0
  187. package/dist/node/kernel/adminPlane/executeAdmin.js +78 -0
  188. package/dist/node/kernel/checks/deep.js +335 -0
  189. package/dist/node/kernel/checks/freshness.js +139 -0
  190. package/dist/node/kernel/checks/gating.js +231 -0
  191. package/dist/node/kernel/checks/guards.js +232 -0
  192. package/dist/node/kernel/checks/lastBoot.js +136 -0
  193. package/dist/node/kernel/checks/live.js +330 -0
  194. package/dist/node/kernel/checks/packageDeps.js +292 -0
  195. package/dist/node/kernel/checks/readiness.js +153 -0
  196. package/dist/node/kernel/checks/renderReport.js +780 -0
  197. package/dist/node/kernel/checks/report.js +421 -0
  198. package/dist/node/kernel/checks/runDoctor.js +731 -0
  199. package/dist/node/kernel/checks/surface.js +364 -0
  200. package/dist/node/kernel/checks/walk.js +100 -0
  201. package/dist/node/kernel/checks/wiring.js +450 -0
  202. package/dist/node/kernel/commands/AiMcpCommand.js +65 -0
  203. package/dist/node/kernel/commands/AiSyncCommand.js +48 -0
  204. package/dist/node/kernel/commands/BuildCommand.js +49 -0
  205. package/dist/node/kernel/commands/CardCommand.js +50 -0
  206. package/dist/node/kernel/commands/ClusterCommand.js +58 -0
  207. package/dist/node/kernel/commands/CompletionCommand.js +31 -0
  208. package/dist/node/kernel/commands/CreateCommand.js +45 -0
  209. package/dist/node/kernel/commands/DevCommand.js +99 -0
  210. package/dist/node/kernel/commands/DoctorCommand.js +115 -0
  211. package/dist/node/kernel/commands/EnvCommand.js +52 -0
  212. package/dist/node/kernel/commands/GitHooksCommand.js +47 -0
  213. package/dist/node/kernel/commands/InspectCommand.js +153 -0
  214. package/dist/node/kernel/commands/InstallCommand.js +20 -0
  215. package/dist/node/kernel/commands/MenuCommand.js +261 -0
  216. package/dist/node/kernel/commands/OutdatedCommand.js +164 -0
  217. package/dist/node/kernel/commands/ProdCommand.js +60 -0
  218. package/dist/node/kernel/commands/StatusCommand.js +30 -0
  219. package/dist/node/kernel/commands/StopCommand.js +35 -0
  220. package/dist/node/kernel/commands/SymbolsCommand.js +45 -0
  221. package/dist/node/kernel/commands/runtimeLauncher.js +95 -0
  222. package/dist/node/kernel/decorators/kernelDecorator.js +110 -0
  223. package/dist/node/kernel/injector/injector.js +137 -0
  224. package/dist/node/kernel/injector/serviceOrder.js +106 -0
  225. package/dist/node/kernel/inspect/adminSubjects.js +194 -0
  226. package/dist/node/kernel/inspect/docOutline.js +86 -0
  227. package/dist/node/kernel/lifecycleTags.js +76 -0
  228. package/dist/node/kernel/moduleConfig.js +75 -0
  229. package/dist/node/kernel/moduleGating.js +68 -0
  230. package/dist/node/kernel/readinessRegistry.js +98 -0
  231. package/dist/node/kernel/resolveModuleEntry.js +61 -0
  232. package/dist/node/mcp/caller.js +40 -0
  233. package/dist/node/mcp/guard.js +51 -0
  234. package/dist/node/mcp/protocol.js +157 -0
  235. package/dist/node/mcp/server.js +216 -0
  236. package/dist/node/mcp/tools.js +861 -0
  237. package/dist/node/oauth/authorizationServer.js +221 -0
  238. package/dist/node/oauth/protectedResource.js +293 -0
  239. package/dist/node/package.js +4 -0
  240. package/dist/node/realtime/IRealtimeTransport.js +32 -0
  241. package/dist/node/realtime/JsonRpcPeer.js +251 -0
  242. package/dist/node/realtime/RealtimeEventMap.js +15 -0
  243. package/dist/node/realtime/channelRate.js +39 -0
  244. package/dist/node/realtime/platformChannels.js +155 -0
  245. package/dist/node/runtime/GcScheduler.js +92 -0
  246. package/dist/node/runtime/RequestContext.js +76 -0
  247. package/dist/node/runtime/bearer.js +84 -0
  248. package/dist/node/runtime/engineEnvironment.js +79 -0
  249. package/dist/node/runtime/loadEnv.js +105 -0
  250. package/dist/node/runtime/pageFacets.js +85 -0
  251. package/dist/node/runtime/pageFilters.js +103 -0
  252. package/dist/node/runtime/pageGuard.js +84 -0
  253. package/dist/node/runtime/pageQuery.js +160 -0
  254. package/dist/node/runtime/pageSort.js +114 -0
  255. package/dist/node/runtime/redact.js +43 -0
  256. package/dist/node/runtime/withTimeout.js +71 -0
  257. package/dist/node/service/cluster/ClusterManager.js +202 -0
  258. package/dist/node/service/cluster/ClusterProbeAggregator.js +120 -0
  259. package/dist/node/service/cluster/ClusterRelay.js +74 -0
  260. package/dist/node/service/cluster/clusterMaster.js +65 -0
  261. package/dist/node/service/cluster/clusterMessage.js +70 -0
  262. package/dist/node/service/cluster/cpuQuota.js +59 -0
  263. package/dist/node/service/cluster/instanceProbe.js +52 -0
  264. package/dist/node/service/cluster/podEnvironment.js +48 -0
  265. package/dist/node/service/cluster/processProbe.js +70 -0
  266. package/dist/node/service/cluster/richProcessProbe.js +115 -0
  267. package/dist/node/service/cluster/topology.js +71 -0
  268. package/dist/node/service/dev/BootReporter.js +490 -0
  269. package/dist/node/service/dev/DevSupervisor.js +1004 -0
  270. package/dist/node/service/dev/bootVerdict.js +158 -0
  271. package/dist/node/service/dev/detachedStart.js +372 -0
  272. package/dist/node/service/dev/devProcess.js +1137 -0
  273. package/dist/node/service/dev/devProjects.js +138 -0
  274. package/dist/node/service/dev/devStatusReport.js +395 -0
  275. package/dist/node/service/dev/devStop.js +263 -0
  276. package/dist/node/service/fetchService.js +35 -0
  277. package/dist/node/service/gitService.js +62 -0
  278. package/dist/node/syslog/Pdu.js +224 -0
  279. package/dist/node/syslog/Syslog.js +1159 -0
  280. package/dist/node/syslog/drivers/ClusterFileLogDriver.js +114 -0
  281. package/dist/node/syslog/drivers/FileLogDriver.js +127 -0
  282. package/dist/node/syslog/drivers/ILogDriver.js +26 -0
  283. package/dist/node/syslog/drivers/LokiLogDriver.js +144 -0
  284. package/dist/node/syslog/drivers/MemoryLogDriver.js +33 -0
  285. package/dist/node/syslog/drivers/OpenSearchLogDriver.js +159 -0
  286. package/dist/node/syslog/drivers/builtinLogDrivers.js +114 -0
  287. package/dist/node/syslog/drivers/filterPdus.js +71 -0
  288. package/dist/node/syslog/drivers/logDriverRegistry.js +83 -0
  289. package/dist/node/syslog/drivers/opensearchShared.js +17 -0
  290. package/dist/node/syslog/drivers/pduFlow.js +106 -0
  291. package/dist/node/syslog/drivers/pduProtocol.js +28 -0
  292. package/dist/node/syslog/httpFetch.js +43 -0
  293. package/dist/node/syslog/logColor.js +80 -0
  294. package/dist/node/syslog/sinks/FileSink.js +142 -0
  295. package/dist/node/syslog/transports/BatchingHttpTransport.js +98 -0
  296. package/dist/node/syslog/transports/ConsoleTransport.js +14 -0
  297. package/dist/node/syslog/transports/FileTransport.js +17 -0
  298. package/dist/node/syslog/transports/HttpTransport.js +44 -0
  299. package/dist/node/syslog/transports/LokiTransport.js +80 -0
  300. package/dist/node/syslog/transports/OpenSearchTransport.js +53 -0
  301. package/dist/node/syslog/transports/SyslogTransport.js +13 -0
  302. package/dist/node/syslog/transports/index.js +8 -0
  303. package/dist/node/testing/index.js +190 -0
  304. package/dist/types/Cli.d.ts +177 -0
  305. package/dist/types/Container.d.ts +221 -0
  306. package/dist/types/Error.d.ts +162 -0
  307. package/dist/types/Event.d.ts +171 -0
  308. package/dist/types/FileClass.d.ts +184 -0
  309. package/dist/types/Nodefony.d.ts +66 -0
  310. package/dist/types/Service.d.ts +165 -0
  311. package/dist/types/Tools.d.ts +116 -0
  312. package/dist/types/bin/resolveLocalCli.d.ts +49 -0
  313. package/dist/types/bundler/index.d.ts +66 -0
  314. package/dist/types/cli/agentTargets.d.ts +378 -0
  315. package/dist/types/cli/aiMcp.d.ts +239 -0
  316. package/dist/types/cli/aiMcpReport.d.ts +113 -0
  317. package/dist/types/cli/aiSync.d.ts +68 -0
  318. package/dist/types/cli/aiSyncReport.d.ts +149 -0
  319. package/dist/types/cli/card.d.ts +49 -0
  320. package/dist/types/cli/cardReport.d.ts +127 -0
  321. package/dist/types/cli/completion.d.ts +154 -0
  322. package/dist/types/cli/create.d.ts +177 -0
  323. package/dist/types/cli/env.d.ts +103 -0
  324. package/dist/types/cli/envReport.d.ts +153 -0
  325. package/dist/types/cli/execPortable.d.ts +54 -0
  326. package/dist/types/cli/gitHooks.d.ts +48 -0
  327. package/dist/types/cli/gitHooksReport.d.ts +101 -0
  328. package/dist/types/cli/globalFlags.d.ts +48 -0
  329. package/dist/types/cli/helpReport.d.ts +110 -0
  330. package/dist/types/cli/manPage.d.ts +21 -0
  331. package/dist/types/cli/nodefonyBin.d.ts +45 -0
  332. package/dist/types/cli/outdated.d.ts +119 -0
  333. package/dist/types/cli/progress.d.ts +349 -0
  334. package/dist/types/cli/projectRoot.d.ts +19 -0
  335. package/dist/types/cli/promptPassword.d.ts +22 -0
  336. package/dist/types/cli/prompts.d.ts +102 -0
  337. package/dist/types/cli/scaffold/destination.d.ts +70 -0
  338. package/dist/types/cli/scaffold/engine.d.ts +545 -0
  339. package/dist/types/cli/scaffold/entityFields.d.ts +238 -0
  340. package/dist/types/cli/scaffold/format.d.ts +78 -0
  341. package/dist/types/cli/scaffold/interactive.d.ts +11 -0
  342. package/dist/types/cli/scaffold/moduleLayout.d.ts +69 -0
  343. package/dist/types/cli/scaffold/reservedEntities.d.ts +49 -0
  344. package/dist/types/cli/scaffold/spec.d.ts +159 -0
  345. package/dist/types/cli/scaffold/steps.d.ts +24 -0
  346. package/dist/types/cli/scaffold/userContractSource.d.ts +86 -0
  347. package/dist/types/cli/scaffold/versions.d.ts +14 -0
  348. package/dist/types/cli/scaffold/writer.d.ts +100 -0
  349. package/dist/types/cli/startMenu.d.ts +195 -0
  350. package/dist/types/cli/symbols.d.ts +84 -0
  351. package/dist/types/cli/sysexits.d.ts +31 -0
  352. package/dist/types/cli/tableReport.d.ts +44 -0
  353. package/dist/types/cli/usageReport.d.ts +108 -0
  354. package/dist/types/client/ClientKernel.d.ts +90 -0
  355. package/dist/types/client/IClientKernel.d.ts +195 -0
  356. package/dist/types/client/angular/index.d.ts +273 -0
  357. package/dist/types/client/announce.d.ts +74 -0
  358. package/dist/types/client/debugbar/DebugBar.d.ts +279 -0
  359. package/dist/types/client/debugbar/format.d.ts +48 -0
  360. package/dist/types/client/debugbar/hmr.d.ts +16 -0
  361. package/dist/types/client/debugbar/index.d.ts +30 -0
  362. package/dist/types/client/debugbar/model.d.ts +158 -0
  363. package/dist/types/client/debugbar/network.d.ts +55 -0
  364. package/dist/types/client/debugbar/profile.d.ts +99 -0
  365. package/dist/types/client/index.d.ts +47 -0
  366. package/dist/types/client/react/index.d.ts +207 -0
  367. package/dist/types/client/realtime/AdaptiveRate.d.ts +138 -0
  368. package/dist/types/client/realtime/BrowserWsTransport.d.ts +27 -0
  369. package/dist/types/client/realtime/RealtimeClient.d.ts +573 -0
  370. package/dist/types/client/realtime/localEvents.d.ts +53 -0
  371. package/dist/types/client/realtime/notice.d.ts +70 -0
  372. package/dist/types/client/realtime/observe.d.ts +284 -0
  373. package/dist/types/client/roles/index.d.ts +15 -0
  374. package/dist/types/client/roles/registry.d.ts +72 -0
  375. package/dist/types/client/roles/roles.d.ts +68 -0
  376. package/dist/types/client/shim/cli-color.d.ts +2 -0
  377. package/dist/types/client/shim/events.d.ts +39 -0
  378. package/dist/types/client/shim/util.d.ts +14 -0
  379. package/dist/types/client/svelte/index.d.ts +216 -0
  380. package/dist/types/client/syslog/context.d.ts +76 -0
  381. package/dist/types/client/syslog/errors.d.ts +46 -0
  382. package/dist/types/client/syslog/uplink.d.ts +89 -0
  383. package/dist/types/client/transport/websocket.d.ts +5 -0
  384. package/dist/types/client/vue/index.d.ts +234 -0
  385. package/dist/types/colors.d.ts +32 -0
  386. package/dist/types/command/Builder.d.ts +47 -0
  387. package/dist/types/command/Command.d.ts +268 -0
  388. package/dist/types/config/configMeta.d.ts +53 -0
  389. package/dist/types/config/configProvenance.d.ts +58 -0
  390. package/dist/types/config/defaults.d.ts +33 -0
  391. package/dist/types/config/defineConfig.d.ts +70 -0
  392. package/dist/types/config/defineEnv.d.ts +170 -0
  393. package/dist/types/config/envExample.d.ts +23 -0
  394. package/dist/types/config/envOverride.d.ts +236 -0
  395. package/dist/types/config/index.d.ts +23 -0
  396. package/dist/types/config/infra.d.ts +171 -0
  397. package/dist/types/config/reactivity.d.ts +36 -0
  398. package/dist/types/config/reservedEnv.d.ts +145 -0
  399. package/dist/types/config/schema.d.ts +113 -0
  400. package/dist/types/config/types.d.ts +374 -0
  401. package/dist/types/config/use.d.ts +80 -0
  402. package/dist/types/finder/File.d.ts +26 -0
  403. package/dist/types/finder/FileResult.d.ts +14 -0
  404. package/dist/types/finder/Finder.d.ts +51 -0
  405. package/dist/types/finder/Result.d.ts +10 -0
  406. package/dist/types/index.d.ts +205 -0
  407. package/dist/types/kernel/BootConfigurationError.d.ts +50 -0
  408. package/dist/types/kernel/CliKernel.d.ts +289 -0
  409. package/dist/types/kernel/Kernel.d.ts +1255 -0
  410. package/dist/types/kernel/Module.d.ts +326 -0
  411. package/dist/types/kernel/adminPlane/adminCaller.d.ts +105 -0
  412. package/dist/types/kernel/adminPlane/adminRbac.d.ts +44 -0
  413. package/dist/types/kernel/adminPlane/catalog.d.ts +122 -0
  414. package/dist/types/kernel/adminPlane/executeAdmin.d.ts +99 -0
  415. package/dist/types/kernel/bootReport.d.ts +112 -0
  416. package/dist/types/kernel/checks/deep.d.ts +122 -0
  417. package/dist/types/kernel/checks/freshness.d.ts +49 -0
  418. package/dist/types/kernel/checks/gating.d.ts +134 -0
  419. package/dist/types/kernel/checks/guards.d.ts +57 -0
  420. package/dist/types/kernel/checks/lastBoot.d.ts +189 -0
  421. package/dist/types/kernel/checks/live.d.ts +110 -0
  422. package/dist/types/kernel/checks/packageDeps.d.ts +44 -0
  423. package/dist/types/kernel/checks/readiness.d.ts +97 -0
  424. package/dist/types/kernel/checks/renderReport.d.ts +107 -0
  425. package/dist/types/kernel/checks/report.d.ts +414 -0
  426. package/dist/types/kernel/checks/runDoctor.d.ts +361 -0
  427. package/dist/types/kernel/checks/surface.d.ts +148 -0
  428. package/dist/types/kernel/checks/walk.d.ts +45 -0
  429. package/dist/types/kernel/checks/wiring.d.ts +54 -0
  430. package/dist/types/kernel/commands/AiMcpCommand.d.ts +39 -0
  431. package/dist/types/kernel/commands/AiSyncCommand.d.ts +28 -0
  432. package/dist/types/kernel/commands/BuildCommand.d.ts +13 -0
  433. package/dist/types/kernel/commands/CardCommand.d.ts +34 -0
  434. package/dist/types/kernel/commands/ClusterCommand.d.ts +29 -0
  435. package/dist/types/kernel/commands/CompletionCommand.d.ts +17 -0
  436. package/dist/types/kernel/commands/CreateCommand.d.ts +16 -0
  437. package/dist/types/kernel/commands/DevCommand.d.ts +40 -0
  438. package/dist/types/kernel/commands/DoctorCommand.d.ts +55 -0
  439. package/dist/types/kernel/commands/EnvCommand.d.ts +35 -0
  440. package/dist/types/kernel/commands/GitHooksCommand.d.ts +27 -0
  441. package/dist/types/kernel/commands/InspectCommand.d.ts +59 -0
  442. package/dist/types/kernel/commands/InstallCommand.d.ts +7 -0
  443. package/dist/types/kernel/commands/MenuCommand.d.ts +58 -0
  444. package/dist/types/kernel/commands/OutdatedCommand.d.ts +47 -0
  445. package/dist/types/kernel/commands/ProdCommand.d.ts +29 -0
  446. package/dist/types/kernel/commands/StatusCommand.d.ts +17 -0
  447. package/dist/types/kernel/commands/StopCommand.d.ts +17 -0
  448. package/dist/types/kernel/commands/SymbolsCommand.d.ts +29 -0
  449. package/dist/types/kernel/commands/runtimeLauncher.d.ts +76 -0
  450. package/dist/types/kernel/decorators/kernelDecorator.d.ts +76 -0
  451. package/dist/types/kernel/injector/injector.d.ts +47 -0
  452. package/dist/types/kernel/injector/serviceOrder.d.ts +29 -0
  453. package/dist/types/kernel/inspect/adminSubjects.d.ts +169 -0
  454. package/dist/types/kernel/inspect/docOutline.d.ts +53 -0
  455. package/dist/types/kernel/lifecycleTags.d.ts +79 -0
  456. package/dist/types/kernel/moduleConfig.d.ts +35 -0
  457. package/dist/types/kernel/moduleGating.d.ts +78 -0
  458. package/dist/types/kernel/readinessRegistry.d.ts +104 -0
  459. package/dist/types/kernel/resolveModuleEntry.d.ts +46 -0
  460. package/dist/types/mcp/caller.d.ts +55 -0
  461. package/dist/types/mcp/guard.d.ts +66 -0
  462. package/dist/types/mcp/protocol.d.ts +163 -0
  463. package/dist/types/mcp/server.d.ts +70 -0
  464. package/dist/types/mcp/tools.d.ts +209 -0
  465. package/dist/types/oauth/authorizationServer.d.ts +204 -0
  466. package/dist/types/oauth/protectedResource.d.ts +339 -0
  467. package/dist/types/realtime/IRealtimeSocket.d.ts +142 -0
  468. package/dist/types/realtime/IRealtimeTransport.d.ts +50 -0
  469. package/dist/types/realtime/JsonRpcPeer.d.ts +251 -0
  470. package/dist/types/realtime/RealtimeEventMap.d.ts +269 -0
  471. package/dist/types/realtime/channelRate.d.ts +55 -0
  472. package/dist/types/realtime/platformChannels.d.ts +147 -0
  473. package/dist/types/runtime/GcScheduler.d.ts +96 -0
  474. package/dist/types/runtime/RequestContext.d.ts +152 -0
  475. package/dist/types/runtime/bearer.d.ts +88 -0
  476. package/dist/types/runtime/engineEnvironment.d.ts +115 -0
  477. package/dist/types/runtime/loadEnv.d.ts +86 -0
  478. package/dist/types/runtime/pageFacets.d.ts +104 -0
  479. package/dist/types/runtime/pageFilters.d.ts +139 -0
  480. package/dist/types/runtime/pageGuard.d.ts +78 -0
  481. package/dist/types/runtime/pageQuery.d.ts +138 -0
  482. package/dist/types/runtime/pageSort.d.ts +86 -0
  483. package/dist/types/runtime/redact.d.ts +27 -0
  484. package/dist/types/runtime/withTimeout.d.ts +51 -0
  485. package/dist/types/service/cluster/ClusterManager.d.ts +112 -0
  486. package/dist/types/service/cluster/ClusterProbeAggregator.d.ts +68 -0
  487. package/dist/types/service/cluster/ClusterRelay.d.ts +57 -0
  488. package/dist/types/service/cluster/clusterMaster.d.ts +40 -0
  489. package/dist/types/service/cluster/clusterMessage.d.ts +94 -0
  490. package/dist/types/service/cluster/cpuQuota.d.ts +37 -0
  491. package/dist/types/service/cluster/instanceProbe.d.ts +82 -0
  492. package/dist/types/service/cluster/podEnvironment.d.ts +35 -0
  493. package/dist/types/service/cluster/processProbe.d.ts +53 -0
  494. package/dist/types/service/cluster/richProcessProbe.d.ts +77 -0
  495. package/dist/types/service/cluster/topology.d.ts +64 -0
  496. package/dist/types/service/dev/BootReporter.d.ts +67 -0
  497. package/dist/types/service/dev/DevSupervisor.d.ts +117 -0
  498. package/dist/types/service/dev/bootVerdict.d.ts +99 -0
  499. package/dist/types/service/dev/detachedStart.d.ts +164 -0
  500. package/dist/types/service/dev/devProcess.d.ts +638 -0
  501. package/dist/types/service/dev/devProjects.d.ts +121 -0
  502. package/dist/types/service/dev/devStatusReport.d.ts +141 -0
  503. package/dist/types/service/dev/devStop.d.ts +57 -0
  504. package/dist/types/service/fetchService.d.ts +29 -0
  505. package/dist/types/service/gitService.d.ts +24 -0
  506. package/dist/types/syslog/Pdu.d.ts +134 -0
  507. package/dist/types/syslog/Syslog.d.ts +482 -0
  508. package/dist/types/syslog/drivers/ClusterFileLogDriver.d.ts +40 -0
  509. package/dist/types/syslog/drivers/FileLogDriver.d.ts +55 -0
  510. package/dist/types/syslog/drivers/ILogDriver.d.ts +177 -0
  511. package/dist/types/syslog/drivers/LokiLogDriver.d.ts +44 -0
  512. package/dist/types/syslog/drivers/MemoryLogDriver.d.ts +20 -0
  513. package/dist/types/syslog/drivers/OpenSearchLogDriver.d.ts +40 -0
  514. package/dist/types/syslog/drivers/builtinLogDrivers.d.ts +43 -0
  515. package/dist/types/syslog/drivers/filterPdus.d.ts +21 -0
  516. package/dist/types/syslog/drivers/logDriverRegistry.d.ts +100 -0
  517. package/dist/types/syslog/drivers/opensearchShared.d.ts +11 -0
  518. package/dist/types/syslog/drivers/pduFlow.d.ts +53 -0
  519. package/dist/types/syslog/drivers/pduProtocol.d.ts +20 -0
  520. package/dist/types/syslog/httpFetch.d.ts +48 -0
  521. package/dist/types/syslog/logColor.d.ts +59 -0
  522. package/dist/types/syslog/sinks/FileSink.d.ts +78 -0
  523. package/dist/types/syslog/transports/BatchingHttpTransport.d.ts +59 -0
  524. package/dist/types/syslog/transports/ConsoleTransport.d.ts +8 -0
  525. package/dist/types/syslog/transports/FileTransport.d.ts +13 -0
  526. package/dist/types/syslog/transports/HttpTransport.d.ts +15 -0
  527. package/dist/types/syslog/transports/LokiTransport.d.ts +45 -0
  528. package/dist/types/syslog/transports/OpenSearchTransport.d.ts +40 -0
  529. package/dist/types/syslog/transports/SyslogTransport.d.ts +9 -0
  530. package/dist/types/syslog/transports/index.d.ts +12 -0
  531. package/dist/types/testing/index.d.ts +197 -0
  532. package/dist/types/types/IAdminApi.d.ts +246 -0
  533. package/dist/types/types/ICliKernel.d.ts +28 -0
  534. package/dist/types/types/ICommand.d.ts +14 -0
  535. package/dist/types/types/IContainer.d.ts +35 -0
  536. package/dist/types/types/IIdempotencyStore.d.ts +159 -0
  537. package/dist/types/types/IKernel.d.ts +138 -0
  538. package/dist/types/types/IMcpTool.d.ts +157 -0
  539. package/dist/types/types/IModule.d.ts +73 -0
  540. package/dist/types/types/IModuleManifest.d.ts +49 -0
  541. package/dist/types/types/IPage.d.ts +119 -0
  542. package/dist/types/types/IService.d.ts +62 -0
  543. package/dist/types/types/ISyslog.d.ts +58 -0
  544. package/dist/types/types/ITransport.d.ts +5 -0
  545. package/dist/types/types/globals.d.ts +47 -0
  546. package/docs/angular-services.md +318 -0
  547. package/docs/catalogue.md +184 -0
  548. package/docs/cli.md +369 -0
  549. package/docs/client.md +616 -0
  550. package/docs/debugbar.md +218 -0
  551. package/docs/environnement.md +308 -0
  552. package/docs/index.md +388 -0
  553. package/docs/kernel.md +670 -0
  554. package/docs/progression.md +228 -0
  555. package/docs/react-hooks.md +686 -0
  556. package/docs/request-context.md +507 -0
  557. package/docs/service.md +590 -0
  558. package/docs/svelte-reactivite.md +293 -0
  559. package/docs/syslog.md +848 -0
  560. package/docs/testing.md +203 -0
  561. package/docs/vue-composables.md +255 -0
  562. package/man/nodefony.1 +152 -0
  563. package/package.json +163 -83
  564. package/templates/app/agents/AGENTS.md.tpl +967 -0
  565. package/templates/app/agents/POINTEUR.md.tpl +12 -0
  566. package/templates/app/base/Dockerfile.tpl +104 -0
  567. package/templates/app/base/README.md.tpl +314 -0
  568. package/templates/app/base/dockerignore.tpl +28 -0
  569. package/templates/app/base/env.ts.tpl +130 -0
  570. package/templates/app/base/gitattributes.tpl +28 -0
  571. package/templates/app/base/github/workflows/ci.yml.tpl +91 -0
  572. package/templates/app/base/gitignore.tpl +46 -0
  573. package/templates/app/base/gitlab-ci.yml.tpl +42 -0
  574. package/templates/app/base/index.ts.tpl +69 -0
  575. package/templates/app/base/nodefony.config.ts.tpl +342 -0
  576. package/templates/app/base/oxlintrc.json.tpl +127 -0
  577. package/templates/app/base/package.json.tpl +75 -0
  578. package/templates/app/base/prettierignore.tpl +24 -0
  579. package/templates/app/base/prettierrc.json.tpl +12 -0
  580. package/templates/app/base/rolldown.config.ts.tpl +8 -0
  581. package/templates/app/base/tests/config.test.ts.tpl +29 -0
  582. package/templates/app/base/tests/e2e.setup.ts.tpl +181 -0
  583. package/templates/app/base/tests/e2e.test.ts.tpl +105 -0
  584. package/templates/app/base/tests/migrations.e2e.test.ts.tpl +579 -0
  585. package/templates/app/base/tsconfig.json.tpl +47 -0
  586. package/templates/app/base/vitest.config.ts.tpl +88 -0
  587. package/templates/app/base/vitest.e2e.config.ts.tpl +39 -0
  588. package/templates/app/complete/compose.yaml.tpl +328 -0
  589. package/templates/app/complete/deploy/migrate-job.yaml.tpl +100 -0
  590. package/templates/app/complete/docker/db/init-nodefony-e2e.sql.tpl +30 -0
  591. package/templates/app/complete/docker/grafana/provisioning/datasources/loki.yaml.tpl +15 -0
  592. package/templates/app/complete/env.local.tpl +11 -0
  593. package/templates/app/complete/env.tpl +53 -0
  594. package/templates/app/complete/nodefony/entity/User.ts.tpl +69 -0
  595. package/templates/app/complete/nodefony/security/provisionUsers.ts.tpl +124 -0
  596. package/templates/app/complete/nodefony/service/AppBannerService.ts.tpl +98 -0
  597. package/templates/app/complete/nodefony/service/AppInfoService.ts.tpl +85 -0
  598. package/templates/app/frontend/angular/frontend/src/accent.css.tpl +34 -0
  599. package/templates/app/frontend/angular/frontend/src/app/app.component.ts.tpl +400 -0
  600. package/templates/app/frontend/react/frontend/src/App.tsx.tpl +421 -0
  601. package/templates/app/frontend/react/frontend/src/accent.css.tpl +30 -0
  602. package/templates/app/frontend/shared/frontend/src/brand.ts.tpl +3 -0
  603. package/templates/app/frontend/shared/frontend/src/showcase.css.tpl +224 -0
  604. package/templates/app/frontend/shared/nodefony/controllers/AppController.ts.tpl +45 -0
  605. package/templates/app/frontend/svelte/frontend/src/App.svelte.tpl +371 -0
  606. package/templates/app/frontend/svelte/frontend/src/accent.css.tpl +34 -0
  607. package/templates/app/frontend/vue/frontend/src/App.vue.tpl +367 -0
  608. package/templates/app/frontend/vue/frontend/src/accent.css.tpl +34 -0
  609. package/templates/app/home/nodefony/controllers/HomeController.ts.tpl +38 -0
  610. package/templates/command/nodefony/command/__NAME__.ts.tpl +132 -0
  611. package/templates/controller/duplex/nodefony/controllers/__NAME__.ts.tpl +188 -0
  612. package/templates/controller/example/nodefony/controllers/__NAME__.ts.tpl +348 -0
  613. package/templates/controller/hello/nodefony/controllers/__NAME__.ts.tpl +143 -0
  614. package/templates/controller/realtime/nodefony/controllers/__NAME__.ts.tpl +153 -0
  615. package/templates/controller/realtime/tests/__KEBAB__-realtime.test.ts.tpl +79 -0
  616. package/templates/controller/rest/nodefony/controllers/__NAME__.ts.tpl +159 -0
  617. package/templates/entity/base/nodefony/entity/__PASCAL__.schema.ts.tpl +31 -0
  618. package/templates/entity/base/nodefony/entity/__PASCAL__.ts.tpl +68 -0
  619. package/templates/entity/controller/nodefony/controllers/__PASCAL__Controller.ts.tpl +335 -0
  620. package/templates/entity/service/nodefony/service/__PASCAL__Service.ts.tpl +126 -0
  621. package/templates/entity/tests/tests/__KEBAB__.e2e.test.ts.tpl +358 -0
  622. package/templates/entity/tests/tests/__KEBAB__.test.ts.tpl +87 -0
  623. package/templates/front/angular/frontend/src/app/app.component.ts.tpl +30 -0
  624. package/templates/front/base/nodefony/controllers/__NAME__.ts.tpl +60 -0
  625. package/templates/front/react/frontend/src/App.tsx.tpl +26 -0
  626. package/templates/front/svelte/frontend/src/App.svelte.tpl +19 -0
  627. package/templates/front/vue/frontend/src/App.vue.tpl +23 -0
  628. package/templates/module/ai/AGENTS.md.tpl +71 -0
  629. package/templates/module/base/README.md.tpl +62 -0
  630. package/templates/module/base/docs/index.md.tpl +55 -0
  631. package/templates/module/base/index.ts.tpl +50 -0
  632. package/templates/module/base/nodefony/config/config.ts.tpl +60 -0
  633. package/templates/module/base/nodefony/config/defineModuleConfig.ts.tpl +55 -0
  634. package/templates/module/base/nodefony/src/errors/__PASCAL__Error.ts.tpl +20 -0
  635. package/templates/module/base/package.json.tpl +53 -0
  636. package/templates/module/base/rolldown.config.ts.tpl +14 -0
  637. package/templates/module/base/tests/__KEBAB__.test.ts.tpl +39 -0
  638. package/templates/module/base/tsconfig.json.tpl +42 -0
  639. package/templates/module/base/vitest.config.ts.tpl +27 -0
  640. package/templates/module/packages/CLAUDE.md.tpl +51 -0
  641. package/templates/module/packages/MEMORY.md.tpl +39 -0
  642. package/templates/module/packages/tsconfig.declarations.json.tpl +19 -0
  643. package/templates/module/packages/tsconfig.tests.json.tpl +11 -0
  644. package/templates/module/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +14 -0
  645. package/templates/module/service/nodefony/interfaces/index.ts.tpl +1 -0
  646. package/templates/module/service/nodefony/service/__PASCAL__Service.ts.tpl +116 -0
  647. package/templates/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +19 -0
  648. package/templates/service/nodefony/service/__PASCAL__Service.ts.tpl +136 -0
  649. package/templates/service/tests/__PASCAL__Service.test.ts.tpl +53 -0
  650. package/templates/shared/front-entry/angular/frontend/src/main.ts.tpl +17 -0
  651. package/templates/shared/front-entry/react/frontend/src/main.tsx.tpl +11 -0
  652. package/templates/shared/front-entry/svelte/frontend/src/main.ts.tpl +13 -0
  653. package/templates/shared/front-entry/vue/frontend/src/main.ts.tpl +12 -0
  654. package/templates/shared/front-registrar/nodefony/frontend/register__PASCAL__Entry.ts.tpl +40 -0
  655. package/templates/shared/front-shell/frontend/index.html.tpl +39 -0
  656. package/templates/shared/ng-app-tsconfig/frontend/tsconfig.app.json.tpl +18 -0
  657. package/templates/shared/svelte-shim/frontend/src/env.d.ts.tpl +12 -0
  658. package/templates/shared/vue-shim/frontend/src/env.d.ts.tpl +15 -0
  659. package/.yarnclean +0 -45
  660. package/CHANGELOG.md +0 -406
  661. package/autoloader.es6 +0 -253
  662. package/builder.es6 +0 -366
  663. package/cli/builder/bundles/bundle.js +0 -328
  664. package/cli/builder/bundles/controller.js +0 -73
  665. package/cli/builder/bundles/users-bundle/.yarnclean +0 -45
  666. package/cli/builder/bundles/users-bundle/Command/fixtureTask.js +0 -47
  667. package/cli/builder/bundles/users-bundle/Command/usersCommand.js +0 -105
  668. package/cli/builder/bundles/users-bundle/Entity/mongoose/userEntity.js +0 -168
  669. package/cli/builder/bundles/users-bundle/Entity/sequelize/userEntity.js +0 -231
  670. package/cli/builder/bundles/users-bundle/Fixtures/users.js +0 -117
  671. package/cli/builder/bundles/users-bundle/Fixtures/usersFixtures.js +0 -114
  672. package/cli/builder/bundles/users-bundle/Resources/config/config.js +0 -90
  673. package/cli/builder/bundles/users-bundle/Resources/config/routing.js +0 -17
  674. package/cli/builder/bundles/users-bundle/Resources/config/security.js +0 -96
  675. package/cli/builder/bundles/users-bundle/Resources/config/services.js +0 -7
  676. package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js +0 -13
  677. package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js +0 -31
  678. package/cli/builder/bundles/users-bundle/Resources/config/webpack.config.js +0 -146
  679. package/cli/builder/bundles/users-bundle/Resources/js/users.js +0 -153
  680. package/cli/builder/bundles/users-bundle/Resources/public/favicon.ico +0 -0
  681. package/cli/builder/bundles/users-bundle/Resources/public/images/users-logo.png +0 -0
  682. package/cli/builder/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js +0 -11
  683. package/cli/builder/bundles/users-bundle/Resources/scss/custom.scss +0 -23
  684. package/cli/builder/bundles/users-bundle/Resources/scss/users.scss +0 -59
  685. package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/login.js +0 -235
  686. package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/users.js +0 -232
  687. package/cli/builder/bundles/users-bundle/Resources/translations/login.en_en.yml +0 -14
  688. package/cli/builder/bundles/users-bundle/Resources/translations/login.fr_fr.yml +0 -14
  689. package/cli/builder/bundles/users-bundle/Resources/translations/users.en_en.yml +0 -35
  690. package/cli/builder/bundles/users-bundle/Resources/translations/users.fr_fr.yml +0 -36
  691. package/cli/builder/bundles/users-bundle/Resources/views/base.html.twig +0 -32
  692. package/cli/builder/bundles/users-bundle/Resources/views/footer.html.twig +0 -7
  693. package/cli/builder/bundles/users-bundle/Resources/views/header.html.twig +0 -90
  694. package/cli/builder/bundles/users-bundle/Resources/views/login/login.html.twig +0 -43
  695. package/cli/builder/bundles/users-bundle/Resources/views/users/createUser.html.twig +0 -296
  696. package/cli/builder/bundles/users-bundle/Resources/views/users/readUsers.html.twig +0 -94
  697. package/cli/builder/bundles/users-bundle/controller/api/graphql/graphqlController.js +0 -56
  698. package/cli/builder/bundles/users-bundle/controller/api/graphql/userResolver.js +0 -121
  699. package/cli/builder/bundles/users-bundle/controller/api/graphql/usertype.js +0 -58
  700. package/cli/builder/bundles/users-bundle/controller/api/openapi/loginApiController.js +0 -210
  701. package/cli/builder/bundles/users-bundle/controller/api/openapi/restUserController.js +0 -244
  702. package/cli/builder/bundles/users-bundle/controller/loginController.js +0 -91
  703. package/cli/builder/bundles/users-bundle/controller/usersController.js +0 -332
  704. package/cli/builder/bundles/users-bundle/package.json +0 -58
  705. package/cli/builder/bundles/users-bundle/readme.md +0 -360
  706. package/cli/builder/bundles/users-bundle/services/usersService.js +0 -411
  707. package/cli/builder/bundles/users-bundle/src/providers/mongoose/userProvider.js +0 -47
  708. package/cli/builder/bundles/users-bundle/src/providers/sequelize/userProvider.js +0 -48
  709. package/cli/builder/bundles/users-bundle/tests/loginTest.js +0 -182
  710. package/cli/builder/bundles/users-bundle/usersBundle.js +0 -26
  711. package/cli/builder/microService/microService.js +0 -261
  712. package/cli/builder/microService/skeletons/.editorconfig +0 -18
  713. package/cli/builder/microService/skeletons/.env-cmdrc.js +0 -32
  714. package/cli/builder/microService/skeletons/.jshintrc +0 -37
  715. package/cli/builder/microService/skeletons/README.md +0 -117
  716. package/cli/builder/microService/skeletons/bin/bash/hello.sh +0 -5
  717. package/cli/builder/microService/skeletons/bin/cli +0 -13
  718. package/cli/builder/microService/skeletons/bin/python/hello.py +0 -20
  719. package/cli/builder/microService/skeletons/config/config.js +0 -29
  720. package/cli/builder/microService/skeletons/config/pm2.config.js +0 -72
  721. package/cli/builder/microService/skeletons/config/webpack/webpack.config.dev.js +0 -8
  722. package/cli/builder/microService/skeletons/config/webpack/webpack.config.prod.js +0 -25
  723. package/cli/builder/microService/skeletons/config/webpack.config.js +0 -114
  724. package/cli/builder/microService/skeletons/package.json +0 -76
  725. package/cli/builder/microService/skeletons/src/browser/index.css +0 -3
  726. package/cli/builder/microService/skeletons/src/browser/index.js +0 -16
  727. package/cli/builder/microService/skeletons/src/browser/socketio.js +0 -46
  728. package/cli/builder/microService/skeletons/src/cli/cli.js +0 -224
  729. package/cli/builder/microService/skeletons/src/cli/menu.js +0 -28
  730. package/cli/builder/microService/skeletons/src/n-api/README.md +0 -1
  731. package/cli/builder/microService/skeletons/src/n-api/binding.gyp +0 -14
  732. package/cli/builder/microService/skeletons/src/n-api/hello.cc +0 -14
  733. package/cli/builder/microService/skeletons/src/n-api/hello.js +0 -23
  734. package/cli/builder/microService/skeletons/src/n-api/package.json +0 -15
  735. package/cli/builder/microService/skeletons/src/node/examples/index.js +0 -120
  736. package/cli/builder/microService/skeletons/src/node/index.js +0 -102
  737. package/cli/builder/microService/skeletons/src/node/services/markdown/markdown.js +0 -27
  738. package/cli/builder/microService/skeletons/src/node/services/servers/http.js +0 -45
  739. package/cli/builder/microService/skeletons/src/node/services/servers/https.js +0 -44
  740. package/cli/builder/microService/skeletons/src/node/services/socketio/socketio.js +0 -46
  741. package/cli/builder/microService/skeletons/src/node/services/syscall/syscall.js +0 -111
  742. package/cli/builder/microService/skeletons/src/node/services/worker/thread.js +0 -59
  743. package/cli/builder/microService/skeletons/src/node/services/worker/worker.js +0 -60
  744. package/cli/builder/microService/skeletons/src/templates/base.html +0 -12
  745. package/cli/builder/microService/skeletons/src/templates/socket.html +0 -23
  746. package/cli/builder/microService/skeletons/tests/unit/serviceTest.js +0 -30
  747. package/cli/builder/project/project.js +0 -474
  748. package/cli/builder/project/skeletons/README.md +0 -778
  749. package/cli/builder/project/skeletons/bin/dev-deploy.sh +0 -5
  750. package/cli/builder/project/skeletons/bin/generateCertificates.sh.skeleton +0 -180
  751. package/cli/builder/project/skeletons/bin/prod-deploy.sh +0 -3
  752. package/cli/builder/project/skeletons/config/config.js.skeleton +0 -178
  753. package/cli/builder/project/skeletons/config/openssl/ca/openssl.cnf.skeleton +0 -150
  754. package/cli/builder/project/skeletons/config/openssl/ca_intermediate/openssl.cnf.skeleton +0 -152
  755. package/cli/builder/project/skeletons/config/pm2.config.js.skeleton +0 -62
  756. package/cli/builder/project/skeletons/documentation.html.twig +0 -24
  757. package/cli/builder/project/skeletons/editorconfig.skeleton +0 -18
  758. package/cli/builder/project/skeletons/eslintignore.skeleton +0 -15
  759. package/cli/builder/project/skeletons/eslintrc.js.skeleton +0 -97
  760. package/cli/builder/project/skeletons/gitignore.skeleton +0 -32
  761. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.37.entity-user.js +0 -137
  762. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.38.entity-session.js +0 -97
  763. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.39.entity-requests.js +0 -115
  764. package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.40.entity-jwts.js +0 -97
  765. package/cli/builder/project/skeletons/migrations/migrations.skeleton.js +0 -101
  766. package/cli/builder/project/skeletons/package.json.twig +0 -71
  767. package/cli/builder/react/reactBuilder.js +0 -224
  768. package/cli/builder/react/skeletons/app/Resources/databases/nodefony.db +0 -0
  769. package/cli/builder/react/skeletons/app/Resources/translations/messages.en_en.yml +0 -5
  770. package/cli/builder/react/skeletons/app/Resources/translations/messages.fr_fr.yml +0 -5
  771. package/cli/builder/react/skeletons/app/Resources/views/base.html.twig +0 -33
  772. package/cli/builder/react/skeletons/app/config/config.js +0 -392
  773. package/cli/builder/react/skeletons/app/config/routing.js +0 -10
  774. package/cli/builder/react/skeletons/app/config/security.js +0 -74
  775. package/cli/builder/react/skeletons/app/controller/appController.js +0 -22
  776. package/cli/builder/sandbox/sandBoxBuilder.js +0 -610
  777. package/cli/builder/sandbox/skeletons/Resources/css/entry.css +0 -48
  778. package/cli/builder/sandbox/skeletons/Resources/js/entry.js +0 -60
  779. package/cli/builder/sandbox/skeletons/Resources/public/manifest.json +0 -32
  780. package/cli/builder/sandbox/skeletons/Resources/translations/messages.en_en.yml +0 -5
  781. package/cli/builder/sandbox/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
  782. package/cli/builder/sandbox/skeletons/Resources/views/base.html.twig +0 -46
  783. package/cli/builder/sandbox/skeletons/Resources/views/index.html.twig +0 -34
  784. package/cli/builder/sandbox/skeletons/bootstrap/custom.scss +0 -27
  785. package/cli/builder/sandbox/skeletons/bootstrap/entry.scss +0 -60
  786. package/cli/builder/sandbox/skeletons/workbox/templates/index.html.twig +0 -32
  787. package/cli/builder/sandbox/skeletons/workbox/workers/service-worker.js +0 -196
  788. package/cli/builder/skeletons/Resources/public/favicon.ico +0 -0
  789. package/cli/builder/skeletons/Resources/public/images/app-logo.png +0 -0
  790. package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.html.twig +0 -1
  791. package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.json.twig +0 -24
  792. package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.html.twig +0 -1
  793. package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.json.twig +0 -20
  794. package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.html.twig +0 -1
  795. package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.json.twig +0 -20
  796. package/cli/builder/skeletons/Resources/views/framework-bundle/views/500.html.twig +0 -1
  797. package/cli/builder/skeletons/Resources/views/framework-bundle/views/base.html.twig +0 -30
  798. package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.html.twig +0 -1
  799. package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.json.twig +0 -24
  800. package/cli/builder/skeletons/Resources/views/framework-bundle/views/footer.html.twig +0 -33
  801. package/cli/builder/skeletons/Resources/views/framework-bundle/views/header.html.twig +0 -6
  802. package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.html.twig +0 -6
  803. package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.json.twig +0 -1
  804. package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.html.twig +0 -125
  805. package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.json.twig +0 -5
  806. package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.html.twig +0 -1
  807. package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.json.twig +0 -24
  808. package/cli/builder/skeletons/app/appKernel.js +0 -133
  809. package/cli/builder/skeletons/binding/binding.cc +0 -26
  810. package/cli/builder/skeletons/binding/binding.skeleton +0 -8
  811. package/cli/builder/skeletons/bundle/bundleClass.js +0 -37
  812. package/cli/builder/skeletons/command/commandClass.js +0 -11
  813. package/cli/builder/skeletons/command/taskClass.js +0 -20
  814. package/cli/builder/skeletons/config/config.js +0 -138
  815. package/cli/builder/skeletons/config/nodefony/elastic-bundle.js +0 -37
  816. package/cli/builder/skeletons/config/nodefony/framework-bundle.js +0 -22
  817. package/cli/builder/skeletons/config/nodefony/http-bundle.js +0 -104
  818. package/cli/builder/skeletons/config/nodefony/mail-bundle.js +0 -44
  819. package/cli/builder/skeletons/config/nodefony/mongoose-bundle.js +0 -51
  820. package/cli/builder/skeletons/config/nodefony/monitoring-bundle.js +0 -34
  821. package/cli/builder/skeletons/config/nodefony/realtime-bundle.js +0 -15
  822. package/cli/builder/skeletons/config/nodefony/redis-bundle.js +0 -44
  823. package/cli/builder/skeletons/config/nodefony/security-bundle.js +0 -25
  824. package/cli/builder/skeletons/config/nodefony/sequelize-bundle.js +0 -156
  825. package/cli/builder/skeletons/config/routing.js +0 -55
  826. package/cli/builder/skeletons/config/security.js +0 -102
  827. package/cli/builder/skeletons/config/services.js +0 -1
  828. package/cli/builder/skeletons/config/webpack/webpack.dev.config.js +0 -13
  829. package/cli/builder/skeletons/config/webpack/webpack.prod.config.js +0 -20
  830. package/cli/builder/skeletons/config/webpack.config.js +0 -148
  831. package/cli/builder/skeletons/controller/controllerClass.js +0 -75
  832. package/cli/builder/skeletons/package.json.twig +0 -57
  833. package/cli/builder/skeletons/unittest/testFile.js +0 -46
  834. package/cli/builder/vue/skeletons/Resources/public/images/app-logo.png +0 -0
  835. package/cli/builder/vue/skeletons/Resources/translations/messages.en_en.yml +0 -5
  836. package/cli/builder/vue/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
  837. package/cli/builder/vue/skeletons/vue.config.js +0 -129
  838. package/cli/builder/vue/vueBuilder.js +0 -410
  839. package/cli/generate/generate.es6 +0 -103
  840. package/cli/install/install.js +0 -190
  841. package/cli/sequelize/sequelize.js +0 -94
  842. package/cli/start.js +0 -702
  843. package/cli/tools/pm2.es6 +0 -112
  844. package/cli/tools/tools.es6 +0 -97
  845. package/cli.es6 +0 -925
  846. package/container.es6 +0 -272
  847. package/error.es6 +0 -293
  848. package/fileClass.es6 +0 -242
  849. package/finder/file.es6 +0 -33
  850. package/finder/fileResult.es6 +0 -138
  851. package/finder/finder2.es6 +0 -275
  852. package/finder.es6 +0 -427
  853. package/kernel/annotations/annotations.es6 +0 -286
  854. package/kernel/api/api.es6 +0 -61
  855. package/kernel/api/graphqlApi.es6 +0 -107
  856. package/kernel/api/jsonApi.es6 +0 -177
  857. package/kernel/api/openApi.es6 +0 -139
  858. package/kernel/api/schemas/openApiSchema.js +0 -394
  859. package/kernel/babylon.es6 +0 -162
  860. package/kernel/bundle.es6 +0 -1200
  861. package/kernel/cliKernel.es6 +0 -869
  862. package/kernel/command.es6 +0 -78
  863. package/kernel/commands/nodefonyCommand.es6 +0 -247
  864. package/kernel/commands/tasks/bundlesTask.es6 +0 -59
  865. package/kernel/controllers/controller.es6 +0 -791
  866. package/kernel/fixture.es6 +0 -19
  867. package/kernel/injections/injections.es6 +0 -424
  868. package/kernel/kernel.es6 +0 -1960
  869. package/kernel/kernelWatcher.es6 +0 -387
  870. package/kernel/orm/entity.es6 +0 -59
  871. package/kernel/orm/orm.es6 +0 -139
  872. package/kernel/reader.es6 +0 -290
  873. package/kernel/security/encoder.es6 +0 -17
  874. package/kernel/security/factories/factory.es6 +0 -111
  875. package/kernel/security/factories/passeportFactory.es6 +0 -61
  876. package/kernel/security/provider.es6 +0 -58
  877. package/kernel/security/providers/chainProvider.es6 +0 -99
  878. package/kernel/security/providers/memoryProvider.es6 +0 -55
  879. package/kernel/security/providers/providerManager.es6 +0 -67
  880. package/kernel/security/providers/userEntityProvider.es6 +0 -50
  881. package/kernel/security/role.es6 +0 -12
  882. package/kernel/security/secureArea.es6 +0 -431
  883. package/kernel/security/tokens/token.es6 +0 -171
  884. package/kernel/security/user.es6 +0 -106
  885. package/kernel/serviceRealTime.es6 +0 -21
  886. package/kernel/services/connectionsService.es6 +0 -93
  887. package/kernel/services/cron/cronService.es6 +0 -123
  888. package/kernel/task.es6 +0 -80
  889. package/kernel/templates.es6 +0 -22
  890. package/kernel/templating/twig.es6 +0 -218
  891. package/kernel/tests/cliTest.js +0 -59
  892. package/kernel/tests/containerTest.js +0 -232
  893. package/kernel/tests/kernelTest.js +0 -39
  894. package/nodefony.es6 +0 -1084
  895. package/notificationsCenter.es6 +0 -118
  896. package/protocol.es6 +0 -86
  897. package/protocols/bayeux.es6 +0 -174
  898. package/protocols/jsonRpc/jsonrpc.es6 +0 -56
  899. package/result.es6 +0 -99
  900. package/service.es6 +0 -288
  901. package/syslog/pdu.es6 +0 -141
  902. package/syslog/syslog.es6 +0 -754
  903. package/watcher.es6 +0 -113
@@ -0,0 +1,1624 @@
1
+ import { PLATFORM_CHANNELS, PLATFORM_EVENTS } from "../../realtime/platformChannels.js";
2
+ import { RealtimeClient } from "../realtime/RealtimeClient.js";
3
+ import { fmtClock, formatBytes, formatUptime, gauge, sparklinePoints } from "./format.js";
4
+ import { DebugBarModel } from "./model.js";
5
+ import { observeViteHmr } from "./hmr.js";
6
+ import { installNetworkInterceptor } from "./network.js";
7
+ import { NetworkModel, computeWaterfall, isError } from "./profile.js";
8
+ //#region src/client/debugbar/DebugBar.ts
9
+ /**
10
+ * DebugBar — toolbar de debug par-page type Symfony WDT, **dev-only**, pensée
11
+ * comme une **vitrine du realtime Nodefony** (on doit *voir* le framework
12
+ * respirer en direct).
13
+ *
14
+ * 2ᵉ consommateur navigateur du Core isomorphe après Studio : MÊME backbone
15
+ * realtime (WS JSON-RPC 2.0, canaux `nodefony:supervision` / `nodefony:syslog`) via
16
+ * {@link RealtimeClient}. Aucun rendu serveur splicé dans le body : le serveur
17
+ * *collecte*, le client *rend*.
18
+ *
19
+ * UI : **onglets** (Realtime / Network / Perf / Logs / Runtime) — un seul pane
20
+ * rendu/visible à la fois (≠ grid fourre-tout) + **poignée de resize** (hauteur
21
+ * persistée). Vanilla TS + **Shadow DOM** + sparklines **SVG maison** — 0 dep UI.
22
+ *
23
+ * Perf scroll (critique) : fond OPAQUE sur le panneau (le `backdrop-filter:blur`
24
+ * sur le conteneur scrollable recompositait à chaque frame), `contain:content`
25
+ * par pane, et la liste Network en **mise à jour incrémentale** (nœuds stables,
26
+ * jamais de rebuild `innerHTML` global → le clic n'est plus perdu, le scroll ne
27
+ * saute plus).
28
+ *
29
+ * Panneau **Network** (dev-only) : intercepte `fetch`/`XHR` (header-only,
30
+ * défensif, réversible) → liste des appels AJAX ; clic sur un appel → fetch du
31
+ * profil serveur (`/nodefony/profiler/api/{requestId}`, corrélé via le header
32
+ * `X-Request-Id`) → **waterfall des phases** du pipeline. SPA-first : on profile
33
+ * les appels, pas la page. Le `traceparent` W3C (RFC-propre) est aussi remonté.
34
+ */
35
+ /** Canaux realtime consommés (figés, alignés sur les providers Studio). */
36
+ const CHANNELS = {
37
+ stats: PLATFORM_CHANNELS.debugbar,
38
+ syslog: PLATFORM_CHANNELS.syslog
39
+ };
40
+ /** Endpoint WS realtime par défaut (porté par Studio aujourd'hui, RealtimeService demain). */
41
+ const DEFAULT_PATH = "/nodefony/studio/api/realtime";
42
+ /** Base du data-plane profiler (data-plane admin `IAdminApi` namespace `profiler`). */
43
+ const DEFAULT_PROFILER_BASE = "/nodefony/profiler/api";
44
+ const HOST_ID = "nodefony-debugbar";
45
+ /** Dimensions des sparklines (unités viewBox SVG). */
46
+ const MINI_W = 58;
47
+ const MINI_H = 20;
48
+ const CHART_W = 260;
49
+ const CHART_H = 46;
50
+ const RT_POINTS = 60;
51
+ /** Borne basse de hauteur du panneau (px). */
52
+ const PANEL_H_MIN = 140;
53
+ /**
54
+ * Hauteur par défaut = **fraction de l'écran** (≈48 % du viewport) — gros écran
55
+ * → grand panneau, petit écran → panneau modeste. Bornée [300, 640] pour rester
56
+ * raisonnable aux extrêmes.
57
+ */
58
+ function defaultPanelH() {
59
+ const vh = typeof window !== "undefined" ? window.innerHeight : 800;
60
+ return Math.min(640, Math.max(300, Math.round(vh * .48)));
61
+ }
62
+ /** Hauteur mini à l'ouverture d'un profil (waterfall confortable) ≈55 % écran. */
63
+ function detailPanelH() {
64
+ const vh = typeof window !== "undefined" ? window.innerHeight : 800;
65
+ return Math.min(680, Math.max(360, Math.round(vh * .55)));
66
+ }
67
+ /** Métadonnées d'affichage par framework (couleur de marque officielle). */
68
+ const FRAMEWORKS = {
69
+ react19: {
70
+ label: "React 19",
71
+ color: "#61dafb"
72
+ },
73
+ react: {
74
+ label: "React",
75
+ color: "#61dafb"
76
+ },
77
+ vue3: {
78
+ label: "Vue 3",
79
+ color: "#42b883"
80
+ },
81
+ vue: {
82
+ label: "Vue",
83
+ color: "#42b883"
84
+ },
85
+ angular: {
86
+ label: "Angular",
87
+ color: "#dd0031"
88
+ },
89
+ vanilla: {
90
+ label: "Vanilla",
91
+ color: "#f7df1e"
92
+ }
93
+ };
94
+ const STYLES = `
95
+ :host { all: initial; }
96
+ * { box-sizing: border-box; }
97
+ .bar {
98
+ position: fixed; left: 0; right: 0; z-index: 2147483000;
99
+ font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
100
+ color: #e8eaed;
101
+ /* Fond OPAQUE (pas de backdrop-filter sur le conteneur scrollable : il
102
+ recompositait le blur à chaque frame de scroll → lag). Blur seulement sur
103
+ .strip (fin, non scrollé). */
104
+ background: #14161a;
105
+ --blue:#0067ba; --blue2:#3aa0ff; --orange:#ff8a3d; --ok:#36b37e; --warn:#ffab00;
106
+ --crit:#ff5630; --info:#4c9aff; --muted:#8a9099; --line:#2a2e36; --card:#1c1f26;
107
+ box-shadow: 0 -8px 40px rgba(0,0,0,.5);
108
+ }
109
+ .bar.bottom { bottom: 0; }
110
+ .bar.top { top: 0; }
111
+ .bar::before {
112
+ content:""; position:absolute; left:0; right:0; height:2px;
113
+ background: linear-gradient(90deg, var(--blue), var(--blue2), var(--orange));
114
+ background-size: 200% 100%; animation: flow 4s linear infinite; opacity:.9;
115
+ }
116
+ .bar.bottom::before { top:0; } .bar.top::before { bottom:0; }
117
+ @keyframes flow { to { background-position: 200% 0; } }
118
+
119
+ /* Strip responsive : police (et tout le contenu en em) scale avec la largeur
120
+ d'écran, bornée 12→15px. Padding scale aussi. */
121
+ .strip { display: flex; align-items: center; gap: clamp(12px,1.1vw,20px);
122
+ padding: clamp(8px,1vh,13px) clamp(14px,1.4vw,26px); cursor: pointer;
123
+ font-size: clamp(12px, 0.35vw + 8px, 16px); flex-wrap: nowrap; overflow: hidden;
124
+ background: rgba(20,22,26,.6); backdrop-filter: blur(14px) saturate(140%); }
125
+ .strip:hover { background: rgba(255,255,255,.03); }
126
+ .brand { display:flex; align-items:center; gap:8px; font-weight:800; letter-spacing:.2px; flex:none; }
127
+ .brand .logo { color: var(--blue2); font-size:1.05em; filter: drop-shadow(0 0 6px rgba(58,160,255,.6)); }
128
+ .brand .name { background: linear-gradient(90deg,#fff,var(--blue2)); -webkit-background-clip:text;
129
+ background-clip:text; -webkit-text-fill-color:transparent; }
130
+ .rt-pill { display:flex; align-items:center; gap:5px; padding:.2em .7em; border-radius:11px; flex:none;
131
+ font-size:.76em; font-weight:800; letter-spacing:.6px; text-transform:uppercase;
132
+ color:var(--muted); background:#22262e; border:1px solid var(--line); }
133
+ .rt-pill.connected { color:#fff; border-color:rgba(58,160,255,.5);
134
+ background: linear-gradient(90deg, rgba(0,103,186,.35), rgba(255,138,61,.25));
135
+ box-shadow: 0 0 14px rgba(58,160,255,.35); }
136
+ .rt-pill .bolt { animation: bolt 1.6s ease-in-out infinite; }
137
+ .rt-pill.connected .bolt { color: var(--orange); }
138
+ @keyframes bolt { 0%,100%{opacity:.5;transform:scale(.9)} 50%{opacity:1;transform:scale(1.15)} }
139
+
140
+ .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; color: var(--muted); }
141
+ .dot.connected { background: var(--ok); color: var(--ok); animation: pulse 2s infinite; }
142
+ .dot.connecting, .dot.reconnecting { background: var(--warn); color: var(--warn); }
143
+ .dot.error, .dot.disconnected { background: var(--crit); color: var(--crit); }
144
+ @keyframes pulse { 0%{box-shadow:0 0 0 0 currentColor} 70%{box-shadow:0 0 0 5px transparent} 100%{box-shadow:0 0 0 0 transparent} }
145
+
146
+ .metric { display: flex; align-items: center; gap: 6px; white-space: nowrap; flex:none; }
147
+ .metric .k { color: var(--muted); text-transform: uppercase; font-size: .76em; letter-spacing:.5px; }
148
+ .metric .v { font-weight: 700; min-width: 2.6em; font-size: 1em; }
149
+ .mini { width: 3.8em; height: 1.35em; display:block; }
150
+ .mini polyline { fill:none; stroke-width:1.5; vector-effect:non-scaling-stroke; }
151
+ .chip { display:flex; align-items:center; gap:6px; padding:.2em .7em; border-radius:11px; flex:none;
152
+ background:#22262e; font-weight:700; font-size:.92em; white-space:nowrap; }
153
+ .chip .k { color: var(--muted); font-size:.82em; text-transform:uppercase; }
154
+ .spacer { flex: 1 1 auto; min-width: 8px; }
155
+ .toggle { color: var(--muted); font-size: .85em; transition: transform .25s; flex:none; }
156
+ .bar.open .toggle { transform: rotate(180deg); }
157
+ .ok{color:var(--ok)} .warn{color:var(--warn)} .crit{color:var(--crit)} .info{color:var(--info)} .muted{color:var(--muted)} .blue{color:var(--blue2)}
158
+ .spark.ok{stroke:var(--ok)} .spark.warn{stroke:var(--warn)} .spark.crit{stroke:var(--crit)} .spark.rt{stroke:var(--blue2)}
159
+ .area.ok{fill:rgba(54,179,126,.12)} .area.warn{fill:rgba(255,171,0,.14)} .area.crit{fill:rgba(255,86,48,.16)} .area.rt{fill:rgba(58,160,255,.16)}
160
+
161
+ /* ── Panneau : resize + onglets + panes ──────────────────────────────────── */
162
+ .panelwrap { display:none; flex-direction:column; border-top:1px solid var(--line); }
163
+ .bar.open .panelwrap { display:flex; }
164
+ .resize { height:8px; cursor:ns-resize; display:flex; align-items:center; justify-content:center;
165
+ flex:none; background:rgba(255,255,255,.015); }
166
+ .resize::after { content:""; width:42px; height:3px; border-radius:2px; background:var(--line); transition:background .15s; }
167
+ .resize:hover::after { background:var(--blue2); }
168
+ .tabs { display:flex; gap:2px; padding:0 8px; flex:none; border-bottom:1px solid var(--line);
169
+ overflow-x:auto; scrollbar-width:none; }
170
+ .tabs::-webkit-scrollbar { display:none; }
171
+ .tab { padding:7px 12px; font:inherit; font-size:11px; font-weight:700; color:var(--muted);
172
+ cursor:pointer; border:0; background:none; border-bottom:2px solid transparent;
173
+ text-transform:uppercase; letter-spacing:.4px; white-space:nowrap; display:flex; align-items:center; gap:5px; }
174
+ .tab:hover { color:#fff; }
175
+ .tab.active { color:#fff; border-bottom-color:var(--blue2); }
176
+ .tab .tcount { font-size:9px; padding:0 5px; border-radius:8px; background:#22262e; color:var(--muted); }
177
+ .tab.active .tcount { background:rgba(58,160,255,.25); color:#fff; }
178
+ .tab .tcount.crit { background:rgba(255,86,48,.3); color:#fff; }
179
+ .panes { overflow:hidden; }
180
+ .pane { display:none; height:100%; overflow:auto; padding:14px; contain:content; }
181
+ .pane.active { display:block; }
182
+ .cards { display:grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap:14px; align-items:start; }
183
+ .card { background:var(--card); border:1px solid var(--line); border-radius:10px; padding:11px 13px; }
184
+ .card.hero { border-color: rgba(58,160,255,.35);
185
+ background: linear-gradient(160deg, rgba(0,103,186,.16), rgba(28,31,38,.7) 60%); }
186
+ .card > h4 { margin:0 0 9px; font-size:10px; letter-spacing:1px; text-transform:uppercase; color:var(--muted); font-weight:800; display:flex; gap:6px; align-items:center; }
187
+
188
+ .hero .big { font-size:30px; font-weight:800; line-height:1; letter-spacing:-.5px;
189
+ background:linear-gradient(90deg,var(--blue2),var(--orange)); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
190
+ .hero .big small { font-size:12px; -webkit-text-fill-color:var(--muted); color:var(--muted); font-weight:700; margin-left:4px; }
191
+ .hero svg { width:100%; height:38px; display:block; margin:6px 0 8px; }
192
+ .hero polyline { fill:none; stroke-width:1.75; vector-effect:non-scaling-stroke; }
193
+ .tag { margin-top:9px; padding-top:8px; border-top:1px solid var(--line); color:var(--muted);
194
+ font-size:10px; line-height:1.5; }
195
+ .tag b { color:#cfd3d8; }
196
+
197
+ .chart { margin-bottom:10px; } .chart:last-child { margin-bottom:0; }
198
+ .chart .hd { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:2px; }
199
+ .chart .lbl { color:var(--muted); font-size:10px; text-transform:uppercase; letter-spacing:.5px; }
200
+ .chart .val { font-weight:700; font-size:13px; }
201
+ .chart .peak { color:var(--muted); font-size:9px; }
202
+ .chart svg { width:100%; height:${CHART_H}px; display:block; }
203
+ .chart polyline { fill:none; stroke-width:1.5; vector-effect:non-scaling-stroke; }
204
+
205
+ .kv { display:flex; justify-content:space-between; gap:8px; padding:2px 0; }
206
+ .kv .k { color:var(--muted); } .kv .v { font-weight:600; text-align:right; overflow:hidden; text-overflow:ellipsis; }
207
+
208
+ .counts { display:flex; gap:8px; margin-bottom:8px; flex-wrap:wrap; }
209
+ .feed { font-size:11px; }
210
+ /* ── Explorateur de journal ─────────────────────────────────────────────── */
211
+ .counts { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; }
212
+ .counts .spacer { flex:1 1 auto; }
213
+ .counts button { font: inherit; color: inherit; background:none; border:1px solid transparent; cursor:pointer; }
214
+ .chip.sevf { border-color: var(--line); }
215
+ .chip.sevf.on { border-color: var(--ok); color:#fff; }
216
+ .search { font: inherit; font-size:11px; color:inherit; background:rgba(255,255,255,.04);
217
+ border:1px solid var(--line); border-radius:6px; padding:3px 8px; min-width:120px; max-width:220px; }
218
+ .search::placeholder { color: var(--muted); }
219
+ .toolbtn { font: inherit; font-size:12px; line-height:1; color:var(--muted); background:none;
220
+ border:1px solid var(--line); border-radius:6px; padding:3px 7px; cursor:pointer; }
221
+ .toolbtn:hover { color:#fff; }
222
+ .toolbtn.on { color:var(--ok); border-color:var(--ok); }
223
+ .log { display:flex; align-items:baseline; gap:8px; padding:2px 0; cursor:pointer; }
224
+ .log:hover { background:rgba(255,255,255,.04); }
225
+ .log .ts { color:var(--muted); font-variant-numeric: tabular-nums; flex:none; }
226
+ .log .rid { color:var(--muted); font-family:monospace; flex:none; margin-left:auto;
227
+ border:1px solid var(--line); border-radius:4px; padding:0 4px; }
228
+ .logdetail { margin:2px 0 6px 0; padding:6px 8px; border-left:2px solid var(--line);
229
+ background:rgba(255,255,255,.03); border-radius:0 6px 6px 0; }
230
+ .drow { display:flex; gap:8px; padding:1px 0; }
231
+ .drow .dk { color:var(--muted); min-width:92px; flex:none; }
232
+ .drow .dv { word-break:break-word; }
233
+ .feed .empty { color:var(--muted); padding:6px 0; }
234
+ .log { display:flex; gap:7px; padding:2px 0; align-items:baseline; border-bottom:1px solid rgba(255,255,255,.04); }
235
+ .log .sev { flex:none; width:54px; font-size:9px; font-weight:800; text-transform:uppercase; }
236
+ .log .mod { flex:none; color:var(--muted); max-width:90px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
237
+ .log .txt { flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
238
+
239
+ .card.fe { border-color: rgba(255,138,61,.3);
240
+ background: linear-gradient(160deg, rgba(255,138,61,.12), rgba(28,31,38,.7) 60%); }
241
+ .fw { display:flex; align-items:center; gap:9px; margin-bottom:9px; }
242
+ .fw .badge { padding:2px 10px; border-radius:7px; font-weight:800; font-size:11px; color:#0b0d10; }
243
+ .fw .name { color:var(--muted); }
244
+ .fe .hd { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:2px; }
245
+ .fe .lbl { color:var(--muted); font-size:10px; text-transform:uppercase; letter-spacing:.5px; }
246
+ .hmr-big { font-size:26px; font-weight:800; line-height:1; transition: color .2s; }
247
+ .hmr-big.hmr-flash { color: var(--orange); text-shadow: 0 0 14px rgba(255,138,61,.7); }
248
+ .fe svg { width:100%; height:34px; display:block; margin:6px 0 8px; }
249
+ .fe polyline { fill:none; stroke-width:1.75; vector-effect:non-scaling-stroke; }
250
+ .spark.fe { stroke:var(--orange); } .area.fe { fill:rgba(255,138,61,.16); }
251
+
252
+ .env-badge { padding:.2em .7em; border-radius:6px; font-size:.76em; font-weight:800;
253
+ letter-spacing:.6px; text-transform:uppercase; color:#0b0d10; background:var(--muted); flex:none; }
254
+ .env-badge.dev { background: var(--ok); } .env-badge.prod { background: var(--crit); color:#fff; }
255
+ .env-badge.test { background: var(--warn); } .env-badge.staging { background:#a06bff; color:#fff; }
256
+ .branch { display:flex; align-items:center; gap:5px; padding:2px 9px; border-radius:6px; flex:none;
257
+ background:#22262e; font-weight:700; max-width:200px; cursor:help; }
258
+ .branch .git { color:var(--blue2); } .branch span:last-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
259
+ /* Les contrôles et les indicateurs du bandeau sont de VRAIS <button> : ils
260
+ s'atteignent au clavier et s'annoncent. Ce bloc leur retire l'apparence
261
+ native que le navigateur leur donne, sans leur retirer leur nature. */
262
+ .strip button { font: inherit; color: inherit; background: none; border: 0; margin: 0; padding: 0; cursor: pointer; }
263
+ .strip button:focus-visible, .tab:focus-visible, .toolbtn:focus-visible {
264
+ outline: 2px solid var(--ok); outline-offset: 2px; border-radius: 4px; }
265
+ .goto:hover .v, .goto:hover .k { color: #fff; }
266
+
267
+ /* ── Infobulles ────────────────────────────────────────────────────────────
268
+ Maison, et non l'attribut « title » du navigateur : celui-là met environ une
269
+ seconde à venir, ne se style pas, et surtout n'apparaît JAMAIS au focus
270
+ clavier — l'aide restait donc inaccessible à qui n'utilise pas la souris.
271
+ Celle-ci s'ouvre au survol ET au focus, ce qui la rend utilisable par tout le
272
+ monde. En CSS pur : aucun script, aucun écouteur, rien à libérer. */
273
+ [data-tip] { position: relative; }
274
+ [data-tip]::after {
275
+ content: attr(data-tip);
276
+ position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%);
277
+ width: max-content; max-width: 280px; white-space: normal; text-align: left;
278
+ background: #0b0b0d; color: #f2f2f2; border: 1px solid var(--line);
279
+ border-radius: 6px; padding: 6px 9px; font-size: 11px; line-height: 1.45;
280
+ font-weight: 400; text-transform: none; letter-spacing: 0;
281
+ box-shadow: 0 6px 20px rgba(0,0,0,.5);
282
+ opacity: 0; visibility: hidden; transition: opacity .12s ease; pointer-events: none; z-index: 20;
283
+ }
284
+ [data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; visibility: visible; }
285
+ /* Barre ancrée en haut : l'infobulle bascule dessous, sinon elle sort de l'écran. */
286
+ .bar.top [data-tip]::after { bottom: auto; top: calc(100% + 9px); }
287
+ /* Les bords : l'infobulle se recale pour ne pas déborder de la fenêtre. */
288
+ .strip > :first-child[data-tip]::after { left: 0; transform: none; }
289
+ .strip > :last-child[data-tip]::after { left: auto; right: 0; transform: none; }
290
+ @media (prefers-reduced-motion: reduce) { [data-tip]::after { transition: none; } }
291
+
292
+ .ctrl { color:var(--muted); cursor:pointer; padding:0 4px; font-weight:800; font-size:1.05em; line-height:1; flex:none; }
293
+ .ctrl:hover { color:#fff; }
294
+ .ctrl.live { font-size:.78em; font-weight:700; border:1px solid var(--line); border-radius:6px; padding:2px 7px; letter-spacing:.3px; }
295
+ .ctrl.live.on { color:var(--ok); border-color:var(--ok); }
296
+ .ctrl.live:not(.on) { color:var(--muted); }
297
+
298
+ .minbar { position:fixed; z-index:2147483000; display:none; align-items:center; gap:8px;
299
+ padding:6px 13px; border-radius:22px; cursor:pointer;
300
+ font:12px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color:#e8eaed;
301
+ background:rgba(18,20,25,.92); backdrop-filter:blur(12px);
302
+ border:1px solid rgba(58,160,255,.45); box-shadow:0 4px 20px rgba(0,0,0,.5); }
303
+ .minbar:hover { border-color:#3aa0ff; box-shadow:0 4px 26px rgba(58,160,255,.4); }
304
+ .minbar.bottom { bottom:14px; } .minbar.top { top:14px; }
305
+ .minbar.dock-left { left:14px; } .minbar.dock-right { right:14px; }
306
+ .minbar .dot { width:8px; height:8px; border-radius:50%; background:#36b37e; }
307
+ .minbar .dot.connected { background:#36b37e; } .minbar .dot.disconnected,.minbar .dot.error { background:#ff5630; }
308
+ .minbar .dot.connecting,.minbar .dot.reconnecting { background:#ffab00; }
309
+ .minbar .mlogo { color:#ff8a3d; } .minbar .mrate { font-weight:800; }
310
+ .minbar .mbadge { font-size:9px; font-weight:800; text-transform:uppercase; color:#8a9099; }
311
+
312
+ /* ── Network ─────────────────────────────────────────────────────────────── */
313
+ .net-head { display:flex; align-items:center; gap:8px; margin-bottom:8px; flex-wrap:wrap; }
314
+ .net-clear { margin-left:auto; color:var(--muted); cursor:pointer; font-size:10px;
315
+ text-transform:uppercase; letter-spacing:.5px; padding:2px 6px; border-radius:6px; }
316
+ .net-clear:hover { color:#fff; background:rgba(255,255,255,.06); }
317
+ .net-list { border-top:1px solid var(--line); }
318
+ .net-list .empty { color:var(--muted); padding:8px 0; }
319
+ .net-row { display:flex; align-items:center; gap:9px; padding:3px 4px; cursor:pointer;
320
+ border-bottom:1px solid rgba(255,255,255,.04); }
321
+ .net-row:hover { background:rgba(255,255,255,.04); }
322
+ .net-row.sel { background:rgba(58,160,255,.14); }
323
+ .net-row.err .net-path { color:#ffb4a6; }
324
+ .net-method { flex:none; width:46px; text-align:center; font-weight:800; font-size:9px;
325
+ padding:1px 0; border-radius:5px; text-transform:uppercase; color:#0b0d10; background:var(--muted); }
326
+ .net-method.get { background:var(--blue2); } .net-method.post { background:var(--ok); }
327
+ .net-method.put,.net-method.patch { background:var(--orange); }
328
+ .net-method.delete { background:var(--crit); color:#fff; }
329
+ .net-method.ws { background:#a06bff; color:#fff; }
330
+ .net-path { flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
331
+ .net-status { flex:none; width:38px; text-align:center; font-weight:800; font-size:10px; }
332
+ .net-status.s2 { color:var(--ok); } .net-status.s3 { color:var(--info); }
333
+ .net-status.s4 { color:var(--warn); } .net-status.s5 { color:var(--crit); }
334
+ .net-status.sp { color:var(--muted); }
335
+ .net-dur { flex:none; width:58px; text-align:right; color:var(--muted); font-size:10px; }
336
+ .net-rid { flex:none; color:var(--blue2); font-size:9px; opacity:.7; }
337
+
338
+ .net-detail { margin-top:10px; border-top:1px solid var(--line); padding-top:10px; }
339
+ .net-detail .empty { color:var(--muted); }
340
+ .det-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap:2px 14px; margin-bottom:10px; }
341
+ .wf { display:flex; flex-direction:column; gap:3px; }
342
+ .wf-title { color:var(--muted); font-size:10px; text-transform:uppercase; letter-spacing:.5px; margin-bottom:4px; }
343
+ .wf-row { display:flex; align-items:center; gap:8px; }
344
+ .wf-name { flex:none; width:74px; text-align:right; color:#cfd3d8; font-size:10px; }
345
+ .wf-track { flex:1; position:relative; height:14px; background:rgba(255,255,255,.04); border-radius:3px; }
346
+ .wf-bar { position:absolute; top:0; bottom:0; border-radius:3px; min-width:2px;
347
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }
348
+ .wf-ms { flex:none; width:62px; text-align:right; color:var(--muted); font-size:10px; }
349
+ .wf-bar.parse { background:#4c9aff; } .wf-bar.resolve { background:#3aa0ff; }
350
+ .wf-bar.firewall { background:#ff8a3d; } .wf-bar.init { background:#a06bff; }
351
+ .wf-bar.action { background:#36b37e; } .wf-bar.render { background:#ffab00; }
352
+ .wf-bar.send { background:#00b8d9; } .wf-bar.other { background:#8a9099; }
353
+ .wf-bar.identity { background:#ff5c8a; }
354
+ .det-loading,.det-err { color:var(--muted); padding:6px 0; } .det-err { color:var(--crit); }
355
+
356
+ /* Network pane = split DevTools : liste (scroll) + détail (scroll), détail
357
+ TOUJOURS visible (≠ tout dans un seul scroll où le détail finit hors écran). */
358
+ .pane.np.active { display:flex; flex-direction:column; padding:0; }
359
+ .np .net-head { padding:10px 14px 8px; flex:none; margin:0; }
360
+ .np .net-list { flex:1 1 auto; min-height:56px; overflow:auto; padding:0 14px; border-top:1px solid var(--line); }
361
+ /* Détail : placeholder = petit (flex:0). Sélection active (.np.sel) → le détail
362
+ prend une vraie part (60%) avec son propre scroll → le waterfall est visible,
363
+ la liste se réduit. */
364
+ .np .net-detail { flex:0 1 auto; max-height:50%; overflow:auto; padding:8px 14px 12px; margin-top:0; border-top:1px solid var(--line); }
365
+ .np.sel .net-list { flex:1 1 40%; min-height:48px; }
366
+ .np.sel .net-detail { flex:1 1 60%; max-height:none; }
367
+ .det-bar { display:flex; justify-content:flex-end; margin-bottom:2px; }
368
+ .det-close { cursor:pointer; color:var(--muted); font-weight:800; font-size:15px; line-height:1; padding:0 4px; }
369
+ .det-close:hover { color:#fff; }
370
+ `;
371
+ function pushCap(arr, v, cap) {
372
+ arr.push(v);
373
+ if (arr.length > cap) arr.shift();
374
+ }
375
+ function clampH(h) {
376
+ const max = typeof window !== "undefined" ? window.innerHeight * .85 : 700;
377
+ if (h < PANEL_H_MIN) return PANEL_H_MIN;
378
+ if (h > max) return Math.round(max);
379
+ return Math.round(h);
380
+ }
381
+ /**
382
+ * Version du format de l'état persisté.
383
+ *
384
+ * Elle existe pour une raison précise : ces clés survivent aux mises à jour du
385
+ * framework, dans un navigateur que personne ne nettoie. Le jour où l'une change
386
+ * de sens, une valeur écrite par une version d'avant est lue comme si elle
387
+ * disait la même chose — et la barre s'ouvre dans un état incohérent que
388
+ * l'utilisateur ne sait pas défaire. Au changement de version, tout est purgé :
389
+ * on perd une préférence d'affichage, ce qui ne coûte rien, plutôt que de
390
+ * charger un état dont on ne sait rien.
391
+ */
392
+ const LS_VERSION = "1";
393
+ /** Clés de persistance localStorage (état chrome de la barre). */
394
+ const LS = {
395
+ /** Version du format — jamais purgée, c'est elle qui décide de la purge. */
396
+ version: "nf.debugbar.v",
397
+ visible: "nf.debugbar.visible",
398
+ min: "nf.debugbar.min",
399
+ side: "nf.debugbar.side",
400
+ tab: "nf.debugbar.tab",
401
+ h: "nf.debugbar.h",
402
+ live: "nf.debugbar.live"
403
+ };
404
+ /**
405
+ * Toutes les clés que la barre écrit sur CE navigateur.
406
+ *
407
+ * Cette liste n'est pas décorative : elle est ce que la barre AFFICHE dans son
408
+ * onglet Runtime et ce que sa purge efface. Trois choses qui doivent rester
409
+ * d'accord, donc une seule source.
410
+ */
411
+ function lsKeys() {
412
+ return Object.values(LS);
413
+ }
414
+ /** Efface l'état persisté de la barre — et rien d'autre du stockage de l'app. */
415
+ function lsPurge() {
416
+ try {
417
+ for (const k of lsKeys()) localStorage.removeItem(k);
418
+ } catch {}
419
+ }
420
+ /**
421
+ * Purge l'état si le format a changé depuis la dernière visite.
422
+ *
423
+ * Appelée avant toute lecture — sinon on lirait justement les valeurs qu'on
424
+ * s'apprête à jeter.
425
+ */
426
+ function lsMigrate() {
427
+ try {
428
+ if (localStorage.getItem(LS.version) === LS_VERSION) return;
429
+ lsPurge();
430
+ localStorage.setItem(LS.version, LS_VERSION);
431
+ } catch {}
432
+ }
433
+ function lsGet(key, def) {
434
+ try {
435
+ return localStorage.getItem(key) ?? def;
436
+ } catch {
437
+ return def;
438
+ }
439
+ }
440
+ function lsSet(key, val) {
441
+ try {
442
+ localStorage.setItem(key, val);
443
+ } catch {}
444
+ }
445
+ const GLOBAL_KEY = "__NODEFONY_DEBUGBAR__";
446
+ /**
447
+ * Widget DOM. Lazy : ne construit le Shadow DOM qu'au `mount()`. Idempotent
448
+ * (un seul `#nodefony-debugbar` par page).
449
+ */
450
+ var DebugBar = class DebugBar {
451
+ client;
452
+ model = new DebugBarModel();
453
+ url;
454
+ position;
455
+ startOpen;
456
+ ownClient;
457
+ frontend;
458
+ host = null;
459
+ bar = null;
460
+ visible;
461
+ minimized;
462
+ side;
463
+ activeTab;
464
+ panelH;
465
+ live;
466
+ /** dispose des abonnements realtime (null quand OFF). */
467
+ liveOff = null;
468
+ rafPending = false;
469
+ feedLen = -1;
470
+ /** Filtre de sévérité de l'onglet Logs — `all` par défaut. */
471
+ feedSev = "all";
472
+ /** Recherche courante, déjà en minuscules (comparée telle quelle). */
473
+ feedQuery = "";
474
+ /**
475
+ * Affichage suspendu. Les entrées continuent d'arriver dans le modèle : à la
476
+ * reprise, la liste se reconstruit complète — mettre en pause ne fait pas
477
+ * perdre ce qui s'est passé pendant, ce qui serait le pire des deux mondes.
478
+ */
479
+ feedPaused = false;
480
+ /** La liste affichée doit être refaite (changement de filtre ou de recherche). */
481
+ feedDirty = false;
482
+ prevFrames = 0;
483
+ rtRate = 0;
484
+ rtPeak = 0;
485
+ rtSeries = [];
486
+ viteConnected = false;
487
+ hmrCount = 0;
488
+ hmrPrev = 0;
489
+ hmrRate = 0;
490
+ hmrLast = "—";
491
+ hmrSeries = [];
492
+ flashTimer = null;
493
+ disposers = [];
494
+ el = Object.create(null);
495
+ networkEnabled;
496
+ profilerBase;
497
+ net = new NetworkModel();
498
+ /** Observe la barre → publie sa hauteur (var CSS) pour l'app hôte. */
499
+ ro = null;
500
+ netRows = /* @__PURE__ */ new Map();
501
+ selectedRid = null;
502
+ selRowId = null;
503
+ selNoRid = false;
504
+ detailVersion = 0;
505
+ detailRendered = -1;
506
+ constructor(opts = {}) {
507
+ this.url = opts.url ?? DEFAULT_PATH;
508
+ this.position = opts.position ?? "bottom";
509
+ this.startOpen = opts.open ?? false;
510
+ this.ownClient = false;
511
+ this.frontend = opts.frontend ?? null;
512
+ this.networkEnabled = opts.network !== false;
513
+ this.profilerBase = (opts.profilerBase ?? DEFAULT_PROFILER_BASE).replace(/\/$/, "");
514
+ this.client = opts.client ?? RealtimeClient.shared({ url: this.url });
515
+ lsMigrate();
516
+ this.visible = lsGet(LS.visible, "1") !== "0";
517
+ this.minimized = lsGet(LS.min, "0") === "1";
518
+ this.side = lsGet(LS.side, "right") === "left" ? "left" : "right";
519
+ this.activeTab = lsGet(LS.tab, "realtime") || "realtime";
520
+ this.panelH = clampH(parseInt(lsGet(LS.h, String(defaultPanelH())), 10) || defaultPanelH());
521
+ this.live = lsGet(LS.live, "0") === "1";
522
+ }
523
+ /** Construit le DOM, branche le realtime et ouvre la connexion. No-op si déjà monté. */
524
+ mount() {
525
+ if (typeof document === "undefined") return this;
526
+ if (document.getElementById(HOST_ID)) return this;
527
+ this.buildDom();
528
+ this.wireRealtime();
529
+ this.wireHmr();
530
+ this.wireNetwork();
531
+ this.applyChrome();
532
+ this.registerHandle();
533
+ this.client.connect().catch(() => {});
534
+ this.render();
535
+ return this;
536
+ }
537
+ /** Détache listeners, ferme la connexion (si propriétaire) et retire le DOM. */
538
+ unmount() {
539
+ for (const d of this.disposers) d();
540
+ this.disposers.length = 0;
541
+ if (this.flashTimer) clearTimeout(this.flashTimer);
542
+ this.flashTimer = null;
543
+ if (this.ownClient) this.client.disconnect();
544
+ this.unregisterHandle();
545
+ this.ro?.disconnect();
546
+ this.ro = null;
547
+ try {
548
+ document.documentElement.style.removeProperty("--nodefony-debugbar-height");
549
+ } catch {}
550
+ this.host?.remove();
551
+ this.host = null;
552
+ this.bar = null;
553
+ }
554
+ /** Affiche/masque la barre (pilotable depuis une app via le handle global). */
555
+ setVisible(v) {
556
+ this.visible = v;
557
+ lsSet(LS.visible, v ? "1" : "0");
558
+ this.applyChrome();
559
+ }
560
+ setMinimized(v) {
561
+ this.minimized = v;
562
+ lsSet(LS.min, v ? "1" : "0");
563
+ this.applyChrome();
564
+ }
565
+ toggleSide() {
566
+ this.side = this.side === "left" ? "right" : "left";
567
+ lsSet(LS.side, this.side);
568
+ this.applyChrome();
569
+ }
570
+ /**
571
+ * Déplie ou replie le panneau — le SEUL endroit qui bascule cet état.
572
+ *
573
+ * Il porte aussi ce qu'un lecteur d'écran doit entendre : `aria-expanded` sur
574
+ * le bouton qui commande, et un nom qui dit l'action à venir (« Déplier » /
575
+ * « Replier »), pas l'état courant — un nom qui décrit l'état laisse
576
+ * l'utilisateur deviner ce que le bouton va faire.
577
+ */
578
+ setOpen(open) {
579
+ const bar = this.bar;
580
+ if (!bar) return;
581
+ bar.classList.toggle("open", open);
582
+ const btn = this.el.btnToggle;
583
+ if (btn) {
584
+ btn.setAttribute("aria-expanded", open ? "true" : "false");
585
+ const label = open ? "Replier le panneau" : "Déplier le panneau";
586
+ btn.setAttribute("aria-label", label);
587
+ btn.setAttribute("data-tip", label);
588
+ }
589
+ this.render();
590
+ }
591
+ setTab(tab) {
592
+ this.activeTab = tab;
593
+ lsSet(LS.tab, tab);
594
+ this.applyTab();
595
+ this.render();
596
+ }
597
+ setPanelH(h) {
598
+ this.panelH = clampH(h);
599
+ const panes = this.el.panes;
600
+ if (panes) panes.style.height = `${this.panelH}px`;
601
+ }
602
+ /** Reflète l'onglet actif sur les boutons + panes. */
603
+ applyTab() {
604
+ (this.bar?.querySelectorAll(".tab"))?.forEach((t) => t.classList.toggle("active", t.getAttribute("data-tab") === this.activeTab));
605
+ (this.bar?.querySelectorAll(".pane"))?.forEach((p) => p.classList.toggle("active", p.getAttribute("data-pane") === this.activeTab));
606
+ }
607
+ /** Applique l'état chrome au DOM (display + classes de dock + hauteur). */
608
+ applyChrome() {
609
+ if (!this.host || !this.bar) return;
610
+ this.host.style.display = this.visible ? "" : "none";
611
+ this.bar.style.display = this.minimized ? "none" : "";
612
+ const min = this.el.minbar;
613
+ if (min) {
614
+ min.style.display = this.minimized ? "flex" : "none";
615
+ min.setAttribute("class", `minbar ${this.position} dock-${this.side}`);
616
+ }
617
+ this.setPanelH(this.panelH);
618
+ this.applyTab();
619
+ this.publishHeight();
620
+ }
621
+ /**
622
+ * Publie la hauteur occupée par la barre (dock bas, visible, dépliée) en
623
+ * variable CSS `--nodefony-debugbar-height` sur `:root`. L'app hôte (Studio)
624
+ * la réserve en `padding-bottom` → le contenu n'est jamais masqué. `0px` si
625
+ * masquée / réduite (chip flottante) / dockée en haut.
626
+ */
627
+ publishHeight() {
628
+ if (typeof document === "undefined") return;
629
+ const h = this.visible && !this.minimized && this.position === "bottom" && this.bar ? this.bar.offsetHeight : 0;
630
+ document.documentElement.style.setProperty("--nodefony-debugbar-height", `${h}px`);
631
+ }
632
+ registerHandle() {
633
+ globalThis[GLOBAL_KEY] = {
634
+ isVisible: () => this.visible,
635
+ setVisible: (v) => this.setVisible(v),
636
+ toggle: () => this.setVisible(!this.visible),
637
+ minimize: () => this.setMinimized(true),
638
+ restore: () => this.setMinimized(false)
639
+ };
640
+ }
641
+ unregisterHandle() {
642
+ try {
643
+ delete globalThis[GLOBAL_KEY];
644
+ } catch {}
645
+ }
646
+ buildDom() {
647
+ const host = document.createElement("div");
648
+ host.id = HOST_ID;
649
+ host.setAttribute("role", "complementary");
650
+ host.setAttribute("aria-label", "Barre de débogage Nodefony");
651
+ const shadow = host.attachShadow({ mode: "open" });
652
+ const style = document.createElement("style");
653
+ style.textContent = STYLES;
654
+ const bar = document.createElement("div");
655
+ bar.className = `bar ${this.position}${this.startOpen ? " open" : ""}`;
656
+ bar.innerHTML = this.template();
657
+ const minbar = document.createElement("div");
658
+ minbar.className = `minbar ${this.position} dock-${this.side}`;
659
+ minbar.innerHTML = `<span class="dot" data-el="mdot"></span><span class="mlogo">⚡</span><span class="mrate" data-el="mrate">0/s</span><span class="mbadge" data-el="mEnv"></span>`;
660
+ shadow.append(style, bar, minbar);
661
+ document.body.appendChild(host);
662
+ this.host = host;
663
+ this.bar = bar;
664
+ this.el.minbar = minbar;
665
+ if (typeof ResizeObserver !== "undefined") {
666
+ this.ro = new ResizeObserver(() => this.publishHeight());
667
+ this.ro.observe(bar);
668
+ }
669
+ shadow.querySelectorAll("[data-el]").forEach((node) => {
670
+ const key = node.getAttribute("data-el");
671
+ if (key) this.el[key] = node;
672
+ });
673
+ const strip = bar.querySelector(".strip");
674
+ this.wireBtn("btnToggle", () => this.setOpen(!bar.classList.contains("open")));
675
+ const onGoto = (ev) => {
676
+ const id = (ev.target?.closest?.(".goto"))?.getAttribute("data-goto");
677
+ if (!id) return;
678
+ this.setOpen(true);
679
+ this.setTab(id);
680
+ };
681
+ strip.addEventListener("click", onGoto);
682
+ this.disposers.push(() => strip.removeEventListener("click", onGoto));
683
+ this.wireBtn("btnMin", () => this.setMinimized(true));
684
+ this.wireBtn("btnSide", () => this.toggleSide());
685
+ this.wireBtn("btnLive", () => this.setLive(!this.live));
686
+ this.updateLiveBtn();
687
+ const tabsBar = bar.querySelector(".tabs");
688
+ if (tabsBar) {
689
+ const onTab = (ev) => {
690
+ const id = (ev.target?.closest?.(".tab"))?.getAttribute("data-tab");
691
+ if (id) this.setTab(id);
692
+ };
693
+ tabsBar.addEventListener("click", onTab);
694
+ this.disposers.push(() => tabsBar.removeEventListener("click", onTab));
695
+ }
696
+ const resize = this.el.resize;
697
+ if (resize) {
698
+ const onDown = (e) => this.startResize(e);
699
+ resize.addEventListener("pointerdown", onDown);
700
+ this.disposers.push(() => resize.removeEventListener("pointerdown", onDown));
701
+ }
702
+ const counts = bar.querySelector(".counts");
703
+ if (counts) {
704
+ const onSev = (ev) => {
705
+ const sev = (ev.target?.closest?.(".sevf"))?.getAttribute("data-sev");
706
+ if (sev !== "all" && sev !== "err" && sev !== "warn") return;
707
+ this.feedSev = this.feedSev === sev ? "all" : sev;
708
+ counts.querySelectorAll(".sevf").forEach((n) => n.classList.toggle("on", n.getAttribute("data-sev") === this.feedSev && this.feedSev !== "all"));
709
+ this.feedDirty = true;
710
+ this.render();
711
+ };
712
+ counts.addEventListener("click", onSev);
713
+ this.disposers.push(() => counts.removeEventListener("click", onSev));
714
+ }
715
+ const search = this.el.logSearch;
716
+ if (search) {
717
+ const onSearch = () => {
718
+ this.feedQuery = search.value.trim().toLowerCase();
719
+ this.feedDirty = true;
720
+ this.render();
721
+ };
722
+ search.addEventListener("input", onSearch);
723
+ this.disposers.push(() => search.removeEventListener("input", onSearch));
724
+ }
725
+ this.wireBtn("btnPause", () => {
726
+ this.feedPaused = !this.feedPaused;
727
+ const b = this.el.btnPause;
728
+ if (b) {
729
+ b.setAttribute("aria-pressed", this.feedPaused ? "true" : "false");
730
+ b.classList.toggle("on", this.feedPaused);
731
+ b.textContent = this.feedPaused ? "▶" : "⏸";
732
+ const tip = this.feedPaused ? "Reprendre l'affichage — la liste se recompose avec ce qui est arrivé pendant la pause" : "Suspendre l'affichage — les entrées continuent d'arriver et se rattrapent à la reprise";
733
+ b.setAttribute("data-tip", tip);
734
+ }
735
+ if (!this.feedPaused) {
736
+ this.feedDirty = true;
737
+ this.render();
738
+ }
739
+ });
740
+ this.wireBtn("btnCopy", () => {
741
+ const node = this.el.feed;
742
+ const text = node ? node.textContent ?? "" : "";
743
+ navigator.clipboard?.writeText(text).then(() => this.flashBtn("btnCopy", "✓"), () => this.flashBtn("btnCopy", "✗"));
744
+ });
745
+ this.wireBtn("btnClearFeed", () => {
746
+ const node = this.el.feed;
747
+ if (node) node.innerHTML = `<div class="empty">liste vidée — les nouvelles entrées s'afficheront ici.</div>`;
748
+ this.feedLen = this.model.view.feed.length;
749
+ });
750
+ const feed = this.el.feed;
751
+ if (feed) {
752
+ const onFeed = (ev) => {
753
+ const row = ev.target?.closest?.(".log");
754
+ if (!row) return;
755
+ if (row.nextElementSibling?.classList.contains("logdetail")) {
756
+ row.nextElementSibling?.remove();
757
+ row.setAttribute("aria-expanded", "false");
758
+ return;
759
+ }
760
+ const uid = Number(row.getAttribute("data-uid"));
761
+ const entry = this.model.view.feed.find((l) => l.uid === uid);
762
+ if (!entry) return;
763
+ feed.querySelectorAll(".logdetail").forEach((n) => n.remove());
764
+ feed.querySelectorAll(".log[aria-expanded='true']").forEach((n) => n.setAttribute("aria-expanded", "false"));
765
+ row.insertAdjacentHTML("afterend", this.feedDetail(entry));
766
+ row.setAttribute("aria-expanded", "true");
767
+ };
768
+ const onFeedKey = (ev) => {
769
+ const k = ev.key;
770
+ if (k !== "Enter" && k !== " ") return;
771
+ const row = ev.target?.closest?.(".log");
772
+ if (!row) return;
773
+ ev.preventDefault();
774
+ row.click();
775
+ };
776
+ feed.addEventListener("click", onFeed);
777
+ feed.addEventListener("keydown", onFeedKey);
778
+ this.disposers.push(() => {
779
+ feed.removeEventListener("click", onFeed);
780
+ feed.removeEventListener("keydown", onFeedKey);
781
+ });
782
+ }
783
+ this.wireBtn("btnPurge", () => {
784
+ lsPurge();
785
+ this.flashBtn("btnPurge", "état effacé ✓");
786
+ });
787
+ const onMin = () => this.setMinimized(false);
788
+ minbar.addEventListener("click", onMin);
789
+ this.disposers.push(() => minbar.removeEventListener("click", onMin));
790
+ let resizePending = false;
791
+ const onWinResize = () => {
792
+ if (resizePending) return;
793
+ resizePending = true;
794
+ requestAnimationFrame(() => {
795
+ resizePending = false;
796
+ this.setPanelH(this.panelH);
797
+ });
798
+ };
799
+ window.addEventListener("resize", onWinResize);
800
+ this.disposers.push(() => window.removeEventListener("resize", onWinResize));
801
+ }
802
+ startResize(ev) {
803
+ ev.preventDefault();
804
+ const startY = ev.clientY;
805
+ const startH = this.panelH;
806
+ const onMove = (e) => {
807
+ const delta = this.position === "bottom" ? startY - e.clientY : e.clientY - startY;
808
+ this.setPanelH(startH + delta);
809
+ };
810
+ const onUp = () => {
811
+ document.removeEventListener("pointermove", onMove);
812
+ document.removeEventListener("pointerup", onUp);
813
+ lsSet(LS.h, String(this.panelH));
814
+ };
815
+ document.addEventListener("pointermove", onMove);
816
+ document.addEventListener("pointerup", onUp);
817
+ }
818
+ /**
819
+ * Retour visuel bref sur un bouton d'action.
820
+ *
821
+ * Une copie réussie ne change rien à l'écran : sans ce clin d'œil, on ne sait
822
+ * pas si le clic a porté, et on reclique.
823
+ */
824
+ flashBtn(key, glyph) {
825
+ const b = this.el[key];
826
+ if (!b) return;
827
+ const before = b.textContent ?? "";
828
+ b.textContent = glyph;
829
+ const t = setTimeout(() => {
830
+ b.textContent = before;
831
+ }, 900);
832
+ this.disposers.push(() => clearTimeout(t));
833
+ }
834
+ wireBtn(key, handler) {
835
+ const node = this.el[key];
836
+ if (!node) return;
837
+ node.addEventListener("click", handler);
838
+ this.disposers.push(() => node.removeEventListener("click", handler));
839
+ }
840
+ template() {
841
+ return `
842
+ <div class="strip">
843
+ <span class="dot" data-el="dot" data-tip="État de la connexion temps réel"></span>
844
+ <span class="brand" data-tip="Barre de débogage Nodefony — visible en développement uniquement"><span class="logo">◆</span><span class="name">nodefony</span></span>
845
+ <span class="env-badge" data-el="envBadge" data-tip="Environnement dans lequel tourne l'application">env</span>
846
+ <span class="branch" data-el="branch" data-tip="Branche git de la copie de travail"><span class="git">⎇</span><span data-el="branchName">—</span></span>
847
+ <span class="rt-pill" data-el="rtPill" data-tip="Transport temps réel et état de la socket"><span class="bolt">⚡</span> realtime</span>
848
+ ${this.miniMetric("rt", "rt", "rtMini", "0/s", "realtime", "Messages temps réel reçus par seconde — cliquer pour ouvrir l'onglet Realtime")}
849
+ ${this.miniMetric("cpu", "cpu", "cpuMini", "0%", "perf", "Charge processeur du serveur — cliquer pour ouvrir l'onglet Perf")}
850
+ ${this.miniMetric("mem", "mem", "memMini", "0%", "perf", "Mémoire utilisée par le serveur — cliquer pour ouvrir l'onglet Perf")}
851
+ <span class="spacer"></span>
852
+ ${this.networkEnabled ? `<button type="button" class="chip goto" data-goto="network" data-tip="Requêtes réseau observées — cliquer pour ouvrir l'onglet Network"><span class="k">net</span><span class="blue" data-el="netChip">0</span></button>` : ""}
853
+ <button type="button" class="chip goto" data-goto="logs" data-tip="Entrées de journal reçues — cliquer pour ouvrir l'onglet Logs"><span class="k">logs</span><span data-el="logs">0</span></button>
854
+ <button type="button" class="chip goto" data-goto="logs" data-tip="Erreurs et alertes — cliquer pour ouvrir l'onglet Logs"><span class="k">err</span><span class="crit" data-el="err">0</span></button>
855
+ <button type="button" class="ctrl live" data-el="btnLive" aria-pressed="false" data-tip="Recevoir les mesures et les journaux en direct. Coupé par défaut : le flux maintient des compteurs côté serveur.">flux OFF</button>
856
+ <button type="button" class="ctrl" data-el="btnSide" aria-label="Changer la barre de côté" data-tip="Changer la barre de côté">⇄</button>
857
+ <button type="button" class="ctrl" data-el="btnMin" aria-label="Réduire la barre en pastille" data-tip="Réduire en pastille">—</button>
858
+ <button type="button" class="toggle" data-el="btnToggle" aria-expanded="${this.startOpen}" aria-controls="nf-db-panel" aria-label="${this.startOpen ? "Replier" : "Déplier"} le panneau" data-tip="${this.startOpen ? "Replier" : "Déplier"} le panneau">▴</button>
859
+ </div>
860
+ <div class="panelwrap" id="nf-db-panel">
861
+ <div class="resize" data-el="resize" title="Redimensionner"></div>
862
+ <div class="tabs">
863
+ <button class="tab" data-tab="realtime">Realtime</button>
864
+ ${this.networkEnabled ? `<button class="tab" data-tab="network">Network <span class="tcount" data-el="netTab">0</span></button>` : ""}
865
+ <button class="tab" data-tab="perf">Perf</button>
866
+ <button class="tab" data-tab="logs">Logs <span class="tcount" data-el="logsTab">0</span></button>
867
+ <button class="tab" data-tab="runtime">Runtime</button>
868
+ </div>
869
+ <div class="panes" data-el="panes">
870
+ ${this.realtimePane()}
871
+ ${this.networkEnabled ? this.networkPane() : ""}
872
+ ${this.perfPane()}
873
+ ${this.logsPane()}
874
+ ${this.runtimePane()}
875
+ </div>
876
+ </div>`;
877
+ }
878
+ realtimePane() {
879
+ return `<div class="pane" data-pane="realtime"><div class="cards">
880
+ <div class="card hero">
881
+ <h4><span class="blue">⚡</span> Realtime</h4>
882
+ <div class="big"><span data-el="rtBig">0</span><small>msg/s</small></div>
883
+ <svg viewBox="0 0 ${CHART_W} 38" preserveAspectRatio="none">
884
+ <polygon class="area rt" data-el="rtArea" points=""/>
885
+ <polyline class="spark rt" data-el="rtLine" points=""/>
886
+ </svg>
887
+ ${this.kv("transport", "rtTransport")}
888
+ ${this.kv("protocole", "rtProto")}
889
+ ${this.kv("état", "rtState")}
890
+ ${this.kv("frames reçues", "rtFrames")}
891
+ ${this.kv("pic", "rtPeak")}
892
+ <div class="tag"><b>HTTP &amp; WebSocket, même contexte.</b> Push natif, <b>0 polling</b> — chaque chiffre arrive en temps réel par le Core isomorphe.</div>
893
+ </div>
894
+ ${this.frontendCard()}
895
+ </div></div>`;
896
+ }
897
+ networkPane() {
898
+ return `<div class="pane np" data-pane="network">
899
+ <div class="net-head">
900
+ <span class="chip"><span class="k">total</span><span data-el="netTotal">0</span></span>
901
+ <span class="chip"><span class="k">err</span><span class="crit" data-el="netErr">0</span></span>
902
+ <span class="chip"><span class="k">pending</span><span class="muted" data-el="netPend">0</span></span>
903
+ <span class="net-clear" data-el="netClear" title="vider la liste">vider</span>
904
+ </div>
905
+ <div class="net-list" data-el="netList"><div class="empty">en attente d'appels AJAX (fetch / XHR)…</div></div>
906
+ <div class="net-detail" data-el="netDetail"><div class="empty">clique un appel → profil serveur (waterfall des phases, route, user).</div></div>
907
+ </div>`;
908
+ }
909
+ perfPane() {
910
+ return `<div class="pane" data-pane="perf"><div class="cards">
911
+ <div class="card">
912
+ <h4>Performance</h4>
913
+ ${this.chart("CPU", "cpuVal", "cpuPeak", "cpuLine", "cpuArea")}
914
+ ${this.chart("Heap", "heapVal", "heapPeak", "heapLine", "heapArea")}
915
+ ${this.chart("Event loop", "loopVal", "loopPeak", "loopLine", "loopArea")}
916
+ </div>
917
+ </div></div>`;
918
+ }
919
+ /**
920
+ * L'onglet Logs — une petite console de lecture, pas une liste qui défile.
921
+ *
922
+ * Ce qu'elle porte, et pourquoi : un FILTRE par sévérité et une RECHERCHE
923
+ * (sans quoi on lit le bruit au lieu de son incident) ; une PAUSE (sans quoi
924
+ * la ligne qu'on essaie de lire s'en va) ; une COPIE (une trace se colle dans
925
+ * un ticket) ; et le DÉTAIL d'une entrée, où vit le `requestId` — le champ qui
926
+ * relie ce journal à sa requête, et que la barre recevait sans jamais le
927
+ * montrer.
928
+ */
929
+ logsPane() {
930
+ return `<div class="pane" data-pane="logs">
931
+ <div class="counts">
932
+ <button type="button" class="chip sevf" data-sev="all" data-tip="Tout afficher"><span class="k">total</span><span data-el="cTotal">0</span></button>
933
+ <button type="button" class="chip sevf" data-sev="err" data-tip="N'afficher que les erreurs (sévérité 0 à 3)"><span class="k">err</span><span class="crit" data-el="cErr">0</span></button>
934
+ <button type="button" class="chip sevf" data-sev="warn" data-tip="N'afficher que les alertes (sévérité 4)"><span class="k">warn</span><span class="warn" data-el="cWarn">0</span></button>
935
+ <span class="chip" data-tip="Entrées écartées par le serveur faute de place dans le tampon — le flux était plus rapide que l'envoi"><span class="k">dropped</span><span class="muted" data-el="cDrop">0</span></span>
936
+ <span class="spacer"></span>
937
+ <input class="search" data-el="logSearch" type="search" placeholder="rechercher…"
938
+ aria-label="Filtrer les journaux sur leur texte, leur module ou leur requête" />
939
+ <button type="button" class="toolbtn" data-el="btnPause" aria-pressed="false" data-tip="Suspendre l'affichage — les entrées continuent d'arriver et se rattrapent à la reprise">⏸</button>
940
+ <button type="button" class="toolbtn" data-el="btnCopy" data-tip="Copier les entrées affichées dans le presse-papiers">⧉</button>
941
+ <button type="button" class="toolbtn" data-el="btnClearFeed" data-tip="Vider la liste affichée (n'efface rien côté serveur)">⌫</button>
942
+ </div>
943
+ <div class="feed" data-el="feed" role="log" aria-label="Journaux du serveur"><div class="empty">en attente de logs…</div></div>
944
+ </div>`;
945
+ }
946
+ /**
947
+ * Ce que la barre garde sur CE navigateur — écrit noir sur blanc.
948
+ *
949
+ * Une console de développement qui écrit dans le stockage local sans le dire
950
+ * est exactement ce qu'on reproche aux autres. La liste est dérivée des clés
951
+ * réelles, donc elle ne peut pas mentir par oubli, et le bouton efface
952
+ * précisément celles-là — jamais le stockage de l'application hôte.
953
+ */
954
+ storageCard() {
955
+ return `<div class="card">
956
+ <h4>Stockage local</h4>
957
+ <div class="tag">Ces valeurs vivent dans ce navigateur, sur cet appareil. Elles ne quittent jamais la page et ne concernent que l'apparence de la barre.</div>
958
+ ${lsKeys().map((k) => `<div class="drow"><span class="dk">${escapeHtml(k.replace("nf.debugbar.", ""))}</span><span class="dv">${escapeHtml(lsGet(k, "—"))}</span></div>`).join("")}
959
+ <div style="margin-top:8px"><button type="button" class="toolbtn" data-el="btnPurge" data-tip="Effacer les préférences de la barre sur ce navigateur — l'application n'est pas touchée">Purger l'état de la barre</button></div>
960
+ </div>`;
961
+ }
962
+ runtimePane() {
963
+ return `<div class="pane" data-pane="runtime"><div class="cards">
964
+ ${this.storageCard()}
965
+ <div class="card">
966
+ <h4>Runtime</h4>
967
+ ${this.kv("app", "appName")}
968
+ ${this.kv("version", "appVersion")}
969
+ ${this.kv("environnement", "envRow")}
970
+ ${this.kv("branche", "branchRow")}
971
+ ${this.kv("pid", "pid")}
972
+ ${this.kv("uptime", "uptime")}
973
+ ${this.kv("instance", "instance")}
974
+ ${this.kv("cpu cores", "cores")}
975
+ ${this.kv("loadavg", "load")}
976
+ ${this.kv("rss", "rss")}
977
+ ${this.kv("heap used", "heapUsed")}
978
+ ${this.kv("heap total", "heapTotal")}
979
+ ${this.kv("heap limit", "heapLimit")}
980
+ ${this.kv("external", "external")}
981
+ </div>
982
+ </div></div>`;
983
+ }
984
+ /**
985
+ * Un indicateur du bandeau — et un RACCOURCI vers l'onglet qui le détaille.
986
+ *
987
+ * C'est un `<button>` et non un `<span>` : le bandeau ne se replie plus au
988
+ * clic (c'était le défaut principal — lire une valeur refermait le panneau),
989
+ * donc chaque indicateur peut faire quelque chose d'utile de son propre clic.
990
+ * Mener à l'onglet qui explique le chiffre est ce que l'utilisateur attend,
991
+ * et un bouton l'annonce et s'atteint au clavier.
992
+ */
993
+ miniMetric(label, valKey, sparkKey, init, goto, tip) {
994
+ return `<button type="button" class="metric goto" data-goto="${goto}" data-tip="${escapeHtml(tip)}">
995
+ <span class="k">${label}</span>
996
+ <span class="v" data-el="${valKey}">${init}</span>
997
+ <svg class="mini" viewBox="0 0 ${MINI_W} ${MINI_H}" preserveAspectRatio="none">
998
+ <polyline class="spark ok" data-el="${sparkKey}" points=""/>
999
+ </svg>
1000
+ </button>`;
1001
+ }
1002
+ chart(label, valKey, peakKey, lineKey, areaKey) {
1003
+ return `<div class="chart">
1004
+ <div class="hd">
1005
+ <span class="lbl">${label}</span>
1006
+ <span><span class="val" data-el="${valKey}">—</span> <span class="peak" data-el="${peakKey}"></span></span>
1007
+ </div>
1008
+ <svg viewBox="0 0 ${CHART_W} ${CHART_H}" preserveAspectRatio="none">
1009
+ <polygon class="area ok" data-el="${areaKey}" points=""/>
1010
+ <polyline class="spark ok" data-el="${lineKey}" points=""/>
1011
+ </svg>
1012
+ </div>`;
1013
+ }
1014
+ kv(label, key) {
1015
+ return `<div class="kv"><span class="k">${label}</span><span class="v" data-el="${key}">—</span></div>`;
1016
+ }
1017
+ /** Carte Frontend / HMR — affichée seulement si un contexte frontend est fourni. */
1018
+ frontendCard() {
1019
+ if (!this.frontend) return "";
1020
+ const fw = FRAMEWORKS[this.frontend.framework ?? ""] ?? {
1021
+ label: this.frontend.framework ?? "Frontend",
1022
+ color: "#3aa0ff"
1023
+ };
1024
+ return `<div class="card fe">
1025
+ <h4><span style="color:${fw.color}">●</span> Frontend</h4>
1026
+ <div class="fw">
1027
+ <span class="badge" style="background:${fw.color}">${escapeHtml(fw.label)}</span>
1028
+ <span class="name">${escapeHtml(this.frontend.name ?? "")}</span>
1029
+ </div>
1030
+ <div class="hd"><span class="lbl">HMR hot updates</span><span class="hmr-big" data-el="hmrBig">0</span></div>
1031
+ <svg viewBox="0 0 ${CHART_W} 34" preserveAspectRatio="none">
1032
+ <polygon class="area fe" data-el="hmrArea" points=""/>
1033
+ <polyline class="spark fe" data-el="hmrLine" points=""/>
1034
+ </svg>
1035
+ ${this.kv("bundler", "feVite")}
1036
+ ${this.kv("dernier module", "hmrLast")}
1037
+ <div class="tag"><b>Backend &amp; frontend, un seul process.</b> HMR Vite branché au runtime — sauvegarde un composant, la barre pulse.</div>
1038
+ </div>`;
1039
+ }
1040
+ wireRealtime() {
1041
+ const offState = this.client.onState((state) => {
1042
+ this.model.setState(state);
1043
+ this.scheduleRender();
1044
+ });
1045
+ const offTick = this.client.onStats(() => {
1046
+ if (!this.live) return;
1047
+ this.sampleThroughput();
1048
+ this.scheduleRender();
1049
+ });
1050
+ const offStats = this.client.on(CHANNELS.stats, (...a) => {
1051
+ const p = a[0];
1052
+ if (p && typeof p === "object") this.model.ingestStats(p);
1053
+ this.scheduleRender();
1054
+ });
1055
+ const offSyslog = this.client.on(CHANNELS.syslog, (...a) => {
1056
+ const p = a[0];
1057
+ if (p && typeof p === "object") this.model.ingestSyslog(p);
1058
+ this.scheduleRender();
1059
+ });
1060
+ this.model.setState(this.client.state);
1061
+ this.disposers.push(offState, offTick, offStats, offSyslog, () => {
1062
+ this.stopLive();
1063
+ });
1064
+ if (this.live) this.startLive();
1065
+ }
1066
+ /**
1067
+ * Démarre les abonnements realtime (tickers serveur stats+syslog). REF-COMPTÉ
1068
+ * (UNE fois) sur le client PARTAGÉ : un canal reste actif tant qu'un
1069
+ * consommateur le veut ; le client ré-abonne seul au reconnect. Idempotent.
1070
+ */
1071
+ startLive() {
1072
+ if (this.liveOff) return;
1073
+ this.client.subscribe(CHANNELS.stats);
1074
+ this.client.subscribe(CHANNELS.syslog);
1075
+ this.liveOff = () => {
1076
+ this.client.unsubscribe(CHANNELS.stats);
1077
+ this.client.unsubscribe(CHANNELS.syslog);
1078
+ };
1079
+ }
1080
+ /** Arrête les abonnements realtime (relâche la réf de la barre). Idempotent. */
1081
+ stopLive() {
1082
+ if (!this.liveOff) return;
1083
+ this.liveOff();
1084
+ this.liveOff = null;
1085
+ }
1086
+ /** Active/désactive le temps réel (bouton de la barre) + persiste la préférence. */
1087
+ setLive(v) {
1088
+ if (v === this.live && !!this.liveOff === v) return;
1089
+ this.live = v;
1090
+ lsSet(LS.live, v ? "1" : "0");
1091
+ if (v) {
1092
+ this.prevFrames = this.client.framesReceived;
1093
+ this.startLive();
1094
+ } else {
1095
+ this.stopLive();
1096
+ this.rtRate = 0;
1097
+ pushCap(this.rtSeries, 0, RT_POINTS);
1098
+ }
1099
+ this.updateLiveBtn();
1100
+ this.scheduleRender();
1101
+ }
1102
+ /** Met à jour l'aspect du bouton « Temps réel » selon l'état. */
1103
+ updateLiveBtn() {
1104
+ const btn = this.el["btnLive"];
1105
+ if (!btn) return;
1106
+ btn.textContent = this.live ? "flux ON" : "flux OFF";
1107
+ btn.title = this.live ? "Flux push ACTIF (stats + logs) — clic pour couper. ≠ état de la connexion (pastille « realtime »)." : "Flux push coupé (perf) — clic pour activer (stats + logs). ≠ état de la connexion (pastille « realtime »).";
1108
+ btn.setAttribute("aria-pressed", this.live ? "true" : "false");
1109
+ btn.classList.toggle("on", this.live);
1110
+ }
1111
+ sampleThroughput() {
1112
+ const total = this.client.framesReceived;
1113
+ this.rtRate = Math.max(0, total - this.prevFrames);
1114
+ this.prevFrames = total;
1115
+ if (this.rtRate > this.rtPeak) this.rtPeak = this.rtRate;
1116
+ pushCap(this.rtSeries, this.rtRate, RT_POINTS);
1117
+ this.hmrRate = Math.max(0, this.hmrCount - this.hmrPrev);
1118
+ this.hmrPrev = this.hmrCount;
1119
+ pushCap(this.hmrSeries, this.hmrRate, RT_POINTS);
1120
+ }
1121
+ wireHmr() {
1122
+ if (!this.frontend) return;
1123
+ const dispose = observeViteHmr((e) => this.onHmr(e));
1124
+ this.disposers.push(dispose);
1125
+ }
1126
+ onHmr(e) {
1127
+ if (e.kind === "connected") this.viteConnected = true;
1128
+ else if (e.kind === "update") {
1129
+ this.hmrCount++;
1130
+ this.hmrLast = e.path ?? "(module)";
1131
+ this.flashHmr();
1132
+ } else if (e.kind === "full-reload") {
1133
+ this.hmrCount++;
1134
+ this.hmrLast = e.path ?? "full reload";
1135
+ this.flashHmr();
1136
+ }
1137
+ this.scheduleRender();
1138
+ }
1139
+ flashHmr() {
1140
+ const node = this.el.hmrBig;
1141
+ if (!node) return;
1142
+ node.setAttribute("class", "hmr-big hmr-flash");
1143
+ if (this.flashTimer) clearTimeout(this.flashTimer);
1144
+ this.flashTimer = setTimeout(() => {
1145
+ node.setAttribute("class", "hmr-big");
1146
+ }, 600);
1147
+ }
1148
+ wireNetwork() {
1149
+ if (!this.networkEnabled) return;
1150
+ const viteOrigin = this.frontend?.viteOrigin ?? "";
1151
+ const uninstall = installNetworkInterceptor({
1152
+ onChange: (e) => this.onNetEntry(e),
1153
+ ignore: (url) => url.includes(this.profilerBase) || url.includes("/@vite/") || url.includes("/@fs/") || url.includes("/node_modules/.vite/") || viteOrigin !== "" && url.includes(viteOrigin)
1154
+ });
1155
+ this.disposers.push(uninstall);
1156
+ const list = this.el.netList;
1157
+ if (list) {
1158
+ const onClick = (ev) => {
1159
+ const row = ev.target?.closest?.(".net-row");
1160
+ if (!row) return;
1161
+ const rid = row.dataset.rid;
1162
+ this.selectRow(row, rid || null);
1163
+ };
1164
+ list.addEventListener("click", onClick);
1165
+ this.disposers.push(() => list.removeEventListener("click", onClick));
1166
+ }
1167
+ const detail = this.el.netDetail;
1168
+ if (detail) {
1169
+ const onDetail = (ev) => {
1170
+ if (ev.target?.closest?.("[data-act=\"close\"]")) this.deselect();
1171
+ };
1172
+ detail.addEventListener("click", onDetail);
1173
+ this.disposers.push(() => detail.removeEventListener("click", onDetail));
1174
+ }
1175
+ const clear = this.el.netClear;
1176
+ if (clear) {
1177
+ const onClear = (e) => {
1178
+ e.stopPropagation();
1179
+ this.net.clear();
1180
+ this.netRows.clear();
1181
+ this.selectedRid = null;
1182
+ this.selRowId = null;
1183
+ const node = this.el.netList;
1184
+ if (node) node.innerHTML = `<div class="empty">en attente d'appels AJAX (fetch / XHR)…</div>`;
1185
+ this.detailVersion++;
1186
+ this.scheduleRender();
1187
+ };
1188
+ clear.addEventListener("click", onClear);
1189
+ this.disposers.push(() => clear.removeEventListener("click", onClear));
1190
+ }
1191
+ }
1192
+ onNetEntry(e) {
1193
+ this.net.ingest(e);
1194
+ this.upsertNetRow(e);
1195
+ if (e.requestId && e.requestId === this.selectedRid) this.detailVersion++;
1196
+ this.scheduleRender();
1197
+ }
1198
+ /** Crée ou met à jour le nœud de ligne d'un appel (jamais d'innerHTML global). */
1199
+ upsertNetRow(e) {
1200
+ const list = this.el.netList;
1201
+ if (!list) return;
1202
+ let row = this.netRows.get(e.id);
1203
+ if (!row) {
1204
+ if (this.netRows.size === 0) list.textContent = "";
1205
+ row = document.createElement("div");
1206
+ row.className = "net-row";
1207
+ row.innerHTML = "<span class=\"net-method\"></span><span class=\"net-path\"></span><span class=\"net-rid\"></span><span class=\"net-status\"></span><span class=\"net-dur\"></span>";
1208
+ this.netRows.set(e.id, row);
1209
+ list.insertBefore(row, list.firstChild);
1210
+ while (this.netRows.size > 80 && list.lastElementChild) {
1211
+ const last = list.lastElementChild;
1212
+ for (const [id, n] of this.netRows) if (n === last) {
1213
+ this.netRows.delete(id);
1214
+ break;
1215
+ }
1216
+ last.remove();
1217
+ }
1218
+ }
1219
+ this.fillNetRow(row, e);
1220
+ }
1221
+ /** Remplit/actualise les cellules d'une ligne (textContent → 0 échappement). */
1222
+ fillNetRow(row, e) {
1223
+ row.dataset.rid = e.requestId ?? "";
1224
+ row.className = `net-row${e.requestId && e.requestId === this.selectedRid ? " sel" : ""}${isError(e) ? " err" : ""}`;
1225
+ const [m, path, rid, status, dur] = row.children;
1226
+ m.className = `net-method ${methodClass(e.method)}`;
1227
+ m.textContent = e.method;
1228
+ path.textContent = e.path;
1229
+ path.title = e.url;
1230
+ rid.textContent = e.requestId ? shortId(e.requestId) : "";
1231
+ if (e.pending) {
1232
+ status.className = "net-status sp";
1233
+ status.textContent = "···";
1234
+ } else if (e.error) {
1235
+ status.className = "net-status s5";
1236
+ status.textContent = "ERR";
1237
+ } else {
1238
+ status.className = `net-status s${statusFamily(e.status)}`;
1239
+ status.textContent = e.status === null ? "—" : String(e.status);
1240
+ }
1241
+ dur.textContent = e.durationMs === null ? "" : `${e.durationMs}ms`;
1242
+ }
1243
+ /** Sélectionne une ligne (highlight) + déclenche le fetch du profil. */
1244
+ selectRow(row, rid) {
1245
+ if (this.selRowId !== null) this.netRows.get(this.selRowId)?.classList.remove("sel");
1246
+ row.classList.add("sel");
1247
+ const idEntry = [...this.netRows.entries()].find(([, n]) => n === row);
1248
+ this.selRowId = idEntry ? idEntry[0] : null;
1249
+ this.selectedRid = rid;
1250
+ this.selNoRid = !rid;
1251
+ this.detailVersion++;
1252
+ const minDetail = detailPanelH();
1253
+ if (rid && this.panelH < minDetail) this.setPanelH(minDetail);
1254
+ if (rid && !this.net.profileState(rid)) this.fetchProfile(rid);
1255
+ if (rid && typeof window !== "undefined") try {
1256
+ window.dispatchEvent(new CustomEvent(PLATFORM_EVENTS.debugbarSelect, { detail: { requestId: rid } }));
1257
+ } catch {}
1258
+ this.scheduleRender();
1259
+ }
1260
+ /** Fetch `/{profilerBase}/{requestId}` (ignoré par l'intercepteur). */
1261
+ fetchProfile(requestId) {
1262
+ if (typeof fetch === "undefined") return;
1263
+ this.net.setProfileState(requestId, { status: "loading" });
1264
+ fetch(`${this.profilerBase}/${encodeURIComponent(requestId)}`, { headers: { accept: "application/json" } }).then(async (res) => {
1265
+ if (res.status === 404) {
1266
+ this.net.setProfileState(requestId, { status: "missing" });
1267
+ return;
1268
+ }
1269
+ const ct = res.headers.get("content-type") ?? "";
1270
+ if (!res.ok || !ct.includes("application/json")) {
1271
+ this.net.setProfileState(requestId, {
1272
+ status: "error",
1273
+ message: res.ok ? "réponse non-JSON (path profiler non proxifié par Vite ?)" : `HTTP ${res.status}`
1274
+ });
1275
+ return;
1276
+ }
1277
+ const profile = await res.json();
1278
+ this.net.setProfileState(requestId, {
1279
+ status: "ready",
1280
+ profile
1281
+ });
1282
+ }).catch((err) => {
1283
+ this.net.setProfileState(requestId, {
1284
+ status: "error",
1285
+ message: err instanceof Error ? err.message : "fetch failed"
1286
+ });
1287
+ }).finally(() => {
1288
+ if (requestId === this.selectedRid) this.detailVersion++;
1289
+ this.scheduleRender();
1290
+ });
1291
+ }
1292
+ scheduleRender() {
1293
+ if (typeof requestAnimationFrame === "undefined") {
1294
+ this.render();
1295
+ return;
1296
+ }
1297
+ if (this.rafPending) return;
1298
+ this.rafPending = true;
1299
+ requestAnimationFrame(() => {
1300
+ this.rafPending = false;
1301
+ this.render();
1302
+ });
1303
+ }
1304
+ text(key, value) {
1305
+ const node = this.el[key];
1306
+ if (node) node.textContent = value;
1307
+ }
1308
+ /** className safe pour HTML *et* SVG (SVGElement.className n'est pas une string). */
1309
+ cls(key, value) {
1310
+ this.el[key]?.setAttribute("class", value);
1311
+ }
1312
+ setPoints(lineKey, areaKey, series, tier, height, max) {
1313
+ const pts = sparklinePoints(series, CHART_W, height, max);
1314
+ this.el[lineKey]?.setAttribute("points", pts);
1315
+ this.el[lineKey]?.setAttribute("class", `spark ${tier}`);
1316
+ if (areaKey) {
1317
+ const area = this.el[areaKey];
1318
+ if (area) {
1319
+ area.setAttribute("points", pts ? `${pts} ${CHART_W},${height} 0,${height}` : "");
1320
+ area.setAttribute("class", `area ${tier}`);
1321
+ }
1322
+ }
1323
+ }
1324
+ render() {
1325
+ if (!this.bar) return;
1326
+ const v = this.model.view;
1327
+ this.renderStrip(v);
1328
+ if (!this.bar.classList.contains("open")) return;
1329
+ switch (this.activeTab) {
1330
+ case "realtime":
1331
+ this.renderRealtimePane(v);
1332
+ break;
1333
+ case "network":
1334
+ this.renderNetwork();
1335
+ break;
1336
+ case "perf":
1337
+ this.renderPerf(v);
1338
+ break;
1339
+ case "logs":
1340
+ this.renderLogsPane(v);
1341
+ break;
1342
+ case "runtime": this.renderRuntime(v);
1343
+ }
1344
+ }
1345
+ /** Bandeau toujours visible (chips + pouls) — léger. */
1346
+ renderStrip(v) {
1347
+ const connected = v.state === "connected";
1348
+ const cpuT = gauge(v.cpuPercent);
1349
+ const memT = gauge(v.heapPercent);
1350
+ this.text("envBadge", v.env || "env");
1351
+ this.cls("envBadge", `env-badge ${envClass(v.env)}`);
1352
+ this.text("branchName", v.branch || "—");
1353
+ this.el.branch?.setAttribute("title", v.branch ? `branche git : ${v.branch}` : "branche git");
1354
+ this.text("mEnv", v.env);
1355
+ this.cls("dot", `dot ${v.state}`);
1356
+ this.cls("mdot", `dot ${v.state}`);
1357
+ this.text("mrate", `${this.rtRate}/s`);
1358
+ this.cls("rtPill", connected ? "rt-pill connected" : "rt-pill");
1359
+ const connTitle = `Connexion temps réel : ${v.state}`;
1360
+ this.el.rtPill?.setAttribute("title", connTitle);
1361
+ this.el.dot?.setAttribute("title", connTitle);
1362
+ this.text("rt", `${this.rtRate}/s`);
1363
+ this.cls("rt", "v blue");
1364
+ this.el.rtMini?.setAttribute("points", sparklinePoints(this.rtSeries, MINI_W, MINI_H));
1365
+ this.el.rtMini?.setAttribute("class", "spark rt");
1366
+ this.text("cpu", `${v.cpuPercent}%`);
1367
+ this.cls("cpu", `v ${cpuT}`);
1368
+ this.text("mem", `${v.heapPercent}%`);
1369
+ this.cls("mem", `v ${memT}`);
1370
+ this.el.cpuMini?.setAttribute("points", sparklinePoints(v.cpuSeries, MINI_W, MINI_H, 100));
1371
+ this.el.cpuMini?.setAttribute("class", `spark ${cpuT}`);
1372
+ this.el.memMini?.setAttribute("points", sparklinePoints(v.heapSeries, MINI_W, MINI_H, 100));
1373
+ this.el.memMini?.setAttribute("class", `spark ${memT}`);
1374
+ if (this.networkEnabled) {
1375
+ this.text("netChip", String(this.net.total));
1376
+ this.cls("netChip", this.net.errors > 0 ? "crit" : "blue");
1377
+ this.text("netTab", String(this.net.total));
1378
+ this.cls("netTab", this.net.errors > 0 ? "tcount crit" : "tcount");
1379
+ }
1380
+ this.text("logs", String(v.logTotal));
1381
+ this.text("err", String(v.errorCount));
1382
+ this.text("logsTab", String(v.logTotal));
1383
+ this.cls("logsTab", v.errorCount > 0 ? "tcount crit" : "tcount");
1384
+ }
1385
+ renderRealtimePane(v) {
1386
+ const live = v.state === "connected";
1387
+ this.text("rtBig", String(this.rtRate));
1388
+ this.setPoints("rtLine", "rtArea", this.rtSeries, "rt", 38);
1389
+ this.text("rtTransport", "WebSocket");
1390
+ this.text("rtProto", "JSON-RPC 2.0");
1391
+ this.text("rtState", v.state);
1392
+ this.cls("rtState", `v ${live ? "ok" : "warn"}`);
1393
+ this.text("rtFrames", String(this.client.framesReceived));
1394
+ this.text("rtPeak", `${this.rtPeak}/s`);
1395
+ if (this.frontend) {
1396
+ this.text("hmrBig", String(this.hmrCount));
1397
+ this.setPoints("hmrLine", "hmrArea", this.hmrSeries, "fe", 34);
1398
+ this.text("feVite", this.viteConnected ? "Vite · connecté" : "Vite · …");
1399
+ this.cls("feVite", `v ${this.viteConnected ? "ok" : "warn"}`);
1400
+ this.text("hmrLast", this.hmrLast);
1401
+ }
1402
+ }
1403
+ renderPerf(v) {
1404
+ const cpuT = gauge(v.cpuPercent);
1405
+ const memT = gauge(v.heapPercent);
1406
+ const loopT = gauge(v.eventLoopMs, 50, 200);
1407
+ this.text("cpuVal", `${v.cpuPercent}%`);
1408
+ this.text("cpuPeak", v.cpuPeak ? `peak ${v.cpuPeak}%` : "");
1409
+ this.cls("cpuVal", `val ${cpuT}`);
1410
+ this.setPoints("cpuLine", "cpuArea", v.cpuSeries, cpuT, CHART_H, 100);
1411
+ this.text("heapVal", `${v.heapPercent}%`);
1412
+ this.text("heapPeak", v.heapPeak ? `peak ${v.heapPeak}%` : "");
1413
+ this.cls("heapVal", `val ${memT}`);
1414
+ this.setPoints("heapLine", "heapArea", v.heapSeries, memT, CHART_H, 100);
1415
+ this.text("loopVal", `${v.eventLoopMs}ms`);
1416
+ this.text("loopPeak", v.eventLoopPeak ? `peak ${v.eventLoopPeak}ms` : "");
1417
+ this.cls("loopVal", `val ${loopT}`);
1418
+ this.setPoints("loopLine", "loopArea", v.loopSeries, loopT, CHART_H);
1419
+ }
1420
+ renderRuntime(v) {
1421
+ this.text("appName", v.appName || "—");
1422
+ this.text("appVersion", v.appVersion || "—");
1423
+ this.text("envRow", v.debug ? `${v.env} · debug` : v.env || "—");
1424
+ this.text("branchRow", v.branch || "—");
1425
+ this.text("pid", String(v.pid));
1426
+ this.text("uptime", formatUptime(v.uptime));
1427
+ this.text("instance", v.instanceId);
1428
+ this.text("cores", String(v.cpuCount));
1429
+ this.text("load", v.loadavg.map((n) => n.toFixed(2)).join(" ") || "—");
1430
+ this.text("rss", formatBytes(v.rss));
1431
+ this.text("heapUsed", formatBytes(v.heapUsed));
1432
+ this.text("heapTotal", formatBytes(v.heapTotal));
1433
+ this.text("heapLimit", formatBytes(v.heapLimit));
1434
+ this.text("external", formatBytes(v.external));
1435
+ }
1436
+ renderLogsPane(v) {
1437
+ this.text("cTotal", String(v.logTotal));
1438
+ this.text("cErr", String(v.errorCount));
1439
+ this.text("cWarn", String(v.warnCount));
1440
+ this.text("cDrop", String(v.dropped));
1441
+ this.renderFeed(v.feed);
1442
+ }
1443
+ /** Classe de couleur d'une entrée, dérivée de sa sévérité RFC 5424. */
1444
+ static tierOf(severity) {
1445
+ if (severity <= 3) return "crit";
1446
+ if (severity === 4) return "warn";
1447
+ if (severity === 7) return "muted";
1448
+ return "info";
1449
+ }
1450
+ /** L'entrée passe-t-elle le filtre de sévérité et la recherche en cours ? */
1451
+ feedMatch(l) {
1452
+ if (this.feedSev === "err" && l.severity > 3) return false;
1453
+ if (this.feedSev === "warn" && l.severity !== 4) return false;
1454
+ const q = this.feedQuery;
1455
+ if (q === "") return true;
1456
+ return l.text.toLowerCase().includes(q) || l.module.toLowerCase().includes(q) || l.msgid.toLowerCase().includes(q) || (l.requestId ?? "").toLowerCase().includes(q);
1457
+ }
1458
+ /** Une ligne de journal — horodatage, sévérité, module, texte, requête. */
1459
+ feedRow(l) {
1460
+ const tier = DebugBar.tierOf(l.severity);
1461
+ const rid = l.requestId ? `<span class="rid" data-tip="requête ${escapeHtml(l.requestId)} — la même valeur relie ce journal à sa route, à ses requêtes de base et à sa réponse">${escapeHtml(l.requestId.slice(0, 8))}</span>` : "";
1462
+ return `<div class="log" data-uid="${l.uid}" tabindex="0" role="button" aria-expanded="false" aria-label="Entrée ${escapeHtml(l.name)} de ${escapeHtml(l.module)} — ouvrir le détail"><span class="ts">${fmtClock(l.ts)}</span><span class="sev ${tier}">${escapeHtml(l.name)}</span><span class="mod">${escapeHtml(l.module)}</span><span class="txt">${escapeHtml(l.text)}</span>${rid}</div>`;
1463
+ }
1464
+ /** Le détail d'une entrée — ce qu'on colle dans un ticket. */
1465
+ feedDetail(l) {
1466
+ const row = (k, v) => `<div class="drow"><span class="dk">${k}</span><span class="dv">${escapeHtml(v)}</span></div>`;
1467
+ return `<div class="logdetail">
1468
+ ${row("horodatage", new Date(l.ts).toISOString())}
1469
+ ${row("sévérité", `${l.name} (${l.severity})`)}
1470
+ ${row("module", l.module)}
1471
+ ${l.msgid ? row("catégorie", l.msgid) : ""}
1472
+ ${l.pid ? row("worker (pid)", String(l.pid)) : ""}
1473
+ ${row("séquence", String(l.uid))}
1474
+ ${l.requestId ? row("requête", l.requestId) : ""}
1475
+ ${row("message", l.text)}
1476
+ </div>`;
1477
+ }
1478
+ /**
1479
+ * Rendu du journal — **incrémental**, et c'est le point.
1480
+ *
1481
+ * L'ancienne version réassignait `innerHTML` en entier à chaque arrivée. Deux
1482
+ * conséquences qu'on ne voit pas dans le code et qu'on subit à l'écran : la
1483
+ * SÉLECTION de texte s'efface — impossible de copier une ligne pendant que le
1484
+ * flux tourne — et la position de DÉFILEMENT saute. Ici, seules les entrées
1485
+ * nouvelles sont insérées en tête ; ce qui est affiché n'est jamais reconstruit.
1486
+ *
1487
+ * Un changement de filtre ou de recherche, lui, refait bien la liste : le jeu
1488
+ * affiché change entièrement, il n'y a rien à préserver.
1489
+ */
1490
+ renderFeed(feed) {
1491
+ const node = this.el.feed;
1492
+ if (!node) return;
1493
+ if (this.feedPaused) return;
1494
+ const refilter = this.feedDirty;
1495
+ if (!refilter && feed.length === this.feedLen) return;
1496
+ const previous = this.feedLen;
1497
+ this.feedLen = feed.length;
1498
+ this.feedDirty = false;
1499
+ if (refilter) {
1500
+ const rows = [];
1501
+ for (let i = feed.length - 1; i >= 0; i--) {
1502
+ const l = feed[i];
1503
+ if (this.feedMatch(l)) rows.push(this.feedRow(l));
1504
+ }
1505
+ node.innerHTML = rows.length === 0 ? `<div class="empty">${feed.length === 0 ? "en attente de logs…" : "aucune entrée ne correspond au filtre."}</div>` : rows.join("");
1506
+ return;
1507
+ }
1508
+ const added = feed.length - previous;
1509
+ if (previous < 0 || added < 0 || added > feed.length) {
1510
+ this.feedDirty = true;
1511
+ this.renderFeed(feed);
1512
+ return;
1513
+ }
1514
+ if (added === 0) return;
1515
+ let html = "";
1516
+ for (let i = feed.length - 1; i >= feed.length - added; i--) {
1517
+ const l = feed[i];
1518
+ if (this.feedMatch(l)) html += this.feedRow(l);
1519
+ }
1520
+ if (html === "") return;
1521
+ if (node.querySelector(".empty")) node.innerHTML = "";
1522
+ node.insertAdjacentHTML("afterbegin", html);
1523
+ while (node.childElementCount > 40) node.lastElementChild?.remove();
1524
+ }
1525
+ renderNetwork() {
1526
+ this.text("netTotal", String(this.net.total));
1527
+ this.text("netErr", String(this.net.errors));
1528
+ this.text("netPend", String(this.net.pending));
1529
+ if (this.detailVersion !== this.detailRendered) {
1530
+ this.detailRendered = this.detailVersion;
1531
+ this.renderDetail();
1532
+ }
1533
+ }
1534
+ renderDetail() {
1535
+ const node = this.el.netDetail;
1536
+ if (!node) return;
1537
+ const rid = this.selectedRid;
1538
+ const hasSel = !!rid || this.selNoRid;
1539
+ node.parentElement?.classList.toggle("sel", hasSel);
1540
+ if (!hasSel) {
1541
+ node.innerHTML = `<div class="empty">clique un appel → profil serveur (waterfall des phases, route, user).</div>`;
1542
+ return;
1543
+ }
1544
+ const closeBar = `<div class="det-bar"><span class="det-close" data-act="close" title="Fermer le détail">✕</span></div>`;
1545
+ let body;
1546
+ if (!rid) body = `<div class="det-err">cet appel n'a pas de requestId lisible — réponse sans header <b>X-Request-Id</b> (cross-origin sans Access-Control-Expose-Headers, ou appel hors Nodefony).</div>`;
1547
+ else {
1548
+ const st = this.net.profileState(rid);
1549
+ if (!st || st.status === "loading") body = `<div class="det-loading">profil <b>${escapeHtml(shortId(rid))}</b> — chargement…</div>`;
1550
+ else if (st.status === "missing") body = `<div class="det-err">profil introuvable (évincé du ring buffer, ou requête sans timing).</div>`;
1551
+ else if (st.status === "error") body = `<div class="det-err">erreur profiler : ${escapeHtml(st.message)}</div>`;
1552
+ else body = this.profileHtml(st.profile);
1553
+ }
1554
+ node.innerHTML = closeBar + body;
1555
+ }
1556
+ /** Désélectionne la requête → referme le détail (placeholder). */
1557
+ deselect() {
1558
+ if (this.selRowId !== null) this.netRows.get(this.selRowId)?.classList.remove("sel");
1559
+ this.selRowId = null;
1560
+ this.selectedRid = null;
1561
+ this.selNoRid = false;
1562
+ this.detailVersion++;
1563
+ this.scheduleRender();
1564
+ }
1565
+ /** Rend le détail d'un profil serveur (méta + waterfall des phases). */
1566
+ profileHtml(p) {
1567
+ const bars = computeWaterfall(p.phases);
1568
+ const total = p.durationMs === null ? "—" : `${p.durationMs}ms`;
1569
+ const kv = (k, val) => `<div class="kv"><span class="k">${k}</span><span class="v">${val}</span></div>`;
1570
+ const meta = `<div class="det-grid">` + kv("route", escapeHtml(p.route ?? "—")) + kv("controller", escapeHtml(p.controller ? `${p.controller}.${p.action ?? "?"}` : "—")) + kv("status", `${p.status ?? "—"}`) + kv("total serveur", total) + kv("user", escapeHtml(p.user ?? "anonyme")) + kv("kind", p.kind) + kv("requestId", escapeHtml(shortId(p.requestId))) + kv("traceparent", escapeHtml(traceId(p))) + (p.error ? kv("erreur", `<span class="crit">${escapeHtml(p.error)}</span>`) : "") + `</div>`;
1571
+ let wf = "";
1572
+ if (bars.length === 0) wf = `<div class="empty">aucune phase mesurée (timing désactivé ?).</div>`;
1573
+ else {
1574
+ wf = `<div class="wf-title">timeline des phases (serveur)</div><div class="wf">`;
1575
+ for (const b of bars) wf += `<div class="wf-row"><span class="wf-name">${escapeHtml(b.name)}</span><div class="wf-track"><div class="wf-bar ${b.tier}" style="left:${b.leftPct}%;width:${b.widthPct}%"></div></div><span class="wf-ms">${b.durationMs}ms</span></div>`;
1576
+ wf += `</div>`;
1577
+ }
1578
+ return meta + wf + this.queriesHtml(p.queries);
1579
+ }
1580
+ /** Rend les requêtes ORM (SEAM futur) — vide tant qu'aucun adapter ne pushe. */
1581
+ queriesHtml(queries) {
1582
+ if (!queries || queries.length === 0) return "";
1583
+ let out = `<div class="wf-title" style="margin-top:10px">requêtes ORM (${queries.length})</div><div class="net-list" style="border:0">`;
1584
+ for (const q of queries) out += `<div class="net-row" style="cursor:default"><span class="net-path" title="${escapeHtml(q.sql)}">${escapeHtml(q.sql)}</span>` + (q.connector ? `<span class="net-rid">${escapeHtml(q.connector)}</span>` : "") + (typeof q.rows === "number" ? `<span class="net-dur">${q.rows} rows</span>` : "") + `<span class="net-dur">${q.durationMs}ms</span></div>`;
1585
+ out += `</div>`;
1586
+ return out;
1587
+ }
1588
+ };
1589
+ /** Famille de status (2/3/4/5) → classe de couleur. `null` → 5 (inconnu). */
1590
+ function statusFamily(status) {
1591
+ if (status === null) return 5;
1592
+ return Math.floor(status / 100);
1593
+ }
1594
+ /** Méthode HTTP → classe de couleur du chip. */
1595
+ function methodClass(method) {
1596
+ const m = method.toLowerCase();
1597
+ if (m === "get" || m === "post" || m === "put" || m === "patch" || m === "delete") return m;
1598
+ return "ws";
1599
+ }
1600
+ /** Raccourci d'un id (1er bloc UUID, ou 8 chars). */
1601
+ function shortId(id) {
1602
+ return id.length > 8 ? id.slice(0, 8) : id;
1603
+ }
1604
+ /** Extrait le trace-id (2ᵉ segment) d'un `traceparent` W3C, raccourci. */
1605
+ function traceId(p) {
1606
+ if (!p.traceparent) return "—";
1607
+ const seg = p.traceparent.split("-");
1608
+ const tid = seg.length >= 2 ? seg[1] : p.traceparent;
1609
+ return tid && tid.length > 12 ? tid.slice(0, 12) + "…" : tid ?? "—";
1610
+ }
1611
+ /** Mappe un nom d'environnement vers une classe de couleur du badge. */
1612
+ function envClass(env) {
1613
+ const e = env.toLowerCase();
1614
+ if (e.startsWith("prod")) return "prod";
1615
+ if (e.startsWith("dev")) return "dev";
1616
+ if (e.startsWith("test")) return "test";
1617
+ if (e.startsWith("stag")) return "staging";
1618
+ return "";
1619
+ }
1620
+ function escapeHtml(s) {
1621
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1622
+ }
1623
+ //#endregion
1624
+ export { DebugBar, DebugBar as default };