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.
- package/.ai/symbols.json +36135 -0
- package/LICENSE +544 -0
- package/README.md +316 -694
- package/bin/nodefony +2183 -85
- package/dist/client/Container.js +367 -0
- package/dist/client/Event.js +198 -0
- package/dist/client/Service.js +344 -0
- package/dist/client/Tools.js +162 -0
- package/dist/client/client/ClientKernel.js +276 -0
- package/dist/client/client/angular/index.js +352 -0
- package/dist/client/client/announce.js +212 -0
- package/dist/client/client/debugbar/DebugBar.js +1624 -0
- package/dist/client/client/debugbar/format.js +103 -0
- package/dist/client/client/debugbar/hmr.js +37 -0
- package/dist/client/client/debugbar/index.js +29 -0
- package/dist/client/client/debugbar/model.js +133 -0
- package/dist/client/client/debugbar/network.js +173 -0
- package/dist/client/client/debugbar/profile.js +114 -0
- package/dist/client/client/index.js +34 -0
- package/dist/client/client/react/index.js +268 -0
- package/dist/client/client/realtime/AdaptiveRate.js +240 -0
- package/dist/client/client/realtime/BrowserWsTransport.js +57 -0
- package/dist/client/client/realtime/RealtimeClient.js +898 -0
- package/dist/client/client/realtime/localEvents.js +56 -0
- package/dist/client/client/realtime/notice.js +125 -0
- package/dist/client/client/realtime/observe.js +280 -0
- package/dist/client/client/roles/index.js +3 -0
- package/dist/client/client/roles/registry.js +97 -0
- package/dist/client/client/roles/roles.js +91 -0
- package/dist/client/client/shim/events.js +88 -0
- package/dist/client/client/shim/util.js +20 -0
- package/dist/client/client/svelte/index.js +319 -0
- package/dist/client/client/syslog/context.js +122 -0
- package/dist/client/client/syslog/errors.js +49 -0
- package/dist/client/client/syslog/uplink.js +106 -0
- package/dist/client/client/vue/index.js +321 -0
- package/dist/client/colors.js +63 -0
- package/dist/client/debugbar.standalone.js +4274 -0
- package/dist/client/realtime/IRealtimeTransport.js +32 -0
- package/dist/client/realtime/JsonRpcPeer.js +251 -0
- package/dist/client/realtime/channelRate.js +39 -0
- package/dist/client/realtime/platformChannels.js +155 -0
- package/dist/client/syslog/Pdu.js +224 -0
- package/dist/client/syslog/Syslog.js +1159 -0
- package/dist/client/syslog/drivers/pduFlow.js +106 -0
- package/dist/client/syslog/drivers/pduProtocol.js +28 -0
- package/dist/client/syslog/logColor.js +80 -0
- package/dist/client/types/src/Container.d.ts +221 -0
- package/dist/client/types/src/Event.d.ts +171 -0
- package/dist/client/types/src/FileClass.d.ts +184 -0
- package/dist/client/types/src/Service.d.ts +165 -0
- package/dist/client/types/src/Tools.d.ts +116 -0
- package/dist/client/types/src/client/ClientKernel.d.ts +90 -0
- package/dist/client/types/src/client/IClientKernel.d.ts +195 -0
- package/dist/client/types/src/client/angular/index.d.ts +273 -0
- package/dist/client/types/src/client/announce.d.ts +74 -0
- package/dist/client/types/src/client/debugbar/DebugBar.d.ts +279 -0
- package/dist/client/types/src/client/debugbar/format.d.ts +48 -0
- package/dist/client/types/src/client/debugbar/hmr.d.ts +16 -0
- package/dist/client/types/src/client/debugbar/index.d.ts +30 -0
- package/dist/client/types/src/client/debugbar/model.d.ts +158 -0
- package/dist/client/types/src/client/debugbar/network.d.ts +55 -0
- package/dist/client/types/src/client/debugbar/profile.d.ts +99 -0
- package/dist/client/types/src/client/index.d.ts +47 -0
- package/dist/client/types/src/client/react/index.d.ts +207 -0
- package/dist/client/types/src/client/realtime/AdaptiveRate.d.ts +138 -0
- package/dist/client/types/src/client/realtime/BrowserWsTransport.d.ts +27 -0
- package/dist/client/types/src/client/realtime/RealtimeClient.d.ts +573 -0
- package/dist/client/types/src/client/realtime/localEvents.d.ts +53 -0
- package/dist/client/types/src/client/realtime/notice.d.ts +70 -0
- package/dist/client/types/src/client/realtime/observe.d.ts +284 -0
- package/dist/client/types/src/client/roles/index.d.ts +15 -0
- package/dist/client/types/src/client/roles/registry.d.ts +72 -0
- package/dist/client/types/src/client/roles/roles.d.ts +68 -0
- package/dist/client/types/src/client/shim/cli-color.d.ts +2 -0
- package/dist/client/types/src/client/shim/events.d.ts +39 -0
- package/dist/client/types/src/client/shim/util.d.ts +14 -0
- package/dist/client/types/src/client/svelte/index.d.ts +216 -0
- package/dist/client/types/src/client/syslog/context.d.ts +76 -0
- package/dist/client/types/src/client/syslog/errors.d.ts +46 -0
- package/dist/client/types/src/client/syslog/uplink.d.ts +89 -0
- package/dist/client/types/src/client/transport/websocket.d.ts +5 -0
- package/dist/client/types/src/client/vue/index.d.ts +234 -0
- package/dist/client/types/src/colors.d.ts +32 -0
- package/dist/client/types/src/config/infra.d.ts +171 -0
- package/dist/client/types/src/kernel/bootReport.d.ts +112 -0
- package/dist/client/types/src/kernel/readinessRegistry.d.ts +104 -0
- package/dist/client/types/src/realtime/IRealtimeSocket.d.ts +142 -0
- package/dist/client/types/src/realtime/IRealtimeTransport.d.ts +50 -0
- package/dist/client/types/src/realtime/JsonRpcPeer.d.ts +251 -0
- package/dist/client/types/src/realtime/RealtimeEventMap.d.ts +269 -0
- package/dist/client/types/src/realtime/channelRate.d.ts +55 -0
- package/dist/client/types/src/realtime/platformChannels.d.ts +147 -0
- package/dist/client/types/src/syslog/Pdu.d.ts +134 -0
- package/dist/client/types/src/syslog/Syslog.d.ts +482 -0
- package/dist/client/types/src/syslog/drivers/ILogDriver.d.ts +177 -0
- package/dist/client/types/src/syslog/drivers/pduFlow.d.ts +53 -0
- package/dist/client/types/src/syslog/drivers/pduProtocol.d.ts +20 -0
- package/dist/client/types/src/syslog/logColor.d.ts +59 -0
- package/dist/client/types/src/types/ICliKernel.d.ts +28 -0
- package/dist/client/types/src/types/ICommand.d.ts +14 -0
- package/dist/client/types/src/types/IContainer.d.ts +35 -0
- package/dist/client/types/src/types/IKernel.d.ts +138 -0
- package/dist/client/types/src/types/IMcpTool.d.ts +157 -0
- package/dist/client/types/src/types/IModule.d.ts +73 -0
- package/dist/client/types/src/types/IPage.d.ts +119 -0
- package/dist/client/types/src/types/IService.d.ts +62 -0
- package/dist/client/types/src/types/ISyslog.d.ts +58 -0
- package/dist/client/types/src/types/ITransport.d.ts +5 -0
- package/dist/client/types/src/types/globals.d.ts +47 -0
- package/dist/node/Cli.js +750 -0
- package/dist/node/Container.js +367 -0
- package/dist/node/Error.js +309 -0
- package/dist/node/Event.js +198 -0
- package/dist/node/FileClass.js +308 -0
- package/dist/node/Nodefony.js +78 -0
- package/dist/node/Service.js +344 -0
- package/dist/node/Tools.js +205 -0
- package/dist/node/bin/resolveLocalCli.js +10 -0
- package/dist/node/bundler/index.js +103 -0
- package/dist/node/cli/agentTargets.js +461 -0
- package/dist/node/cli/aiMcp.js +553 -0
- package/dist/node/cli/aiMcpReport.js +129 -0
- package/dist/node/cli/aiSync.js +323 -0
- package/dist/node/cli/aiSyncReport.js +142 -0
- package/dist/node/cli/card.js +186 -0
- package/dist/node/cli/cardReport.js +110 -0
- package/dist/node/cli/completion.js +415 -0
- package/dist/node/cli/create.js +805 -0
- package/dist/node/cli/env.js +332 -0
- package/dist/node/cli/envReport.js +159 -0
- package/dist/node/cli/execPortable.js +60 -0
- package/dist/node/cli/gitHooks.js +191 -0
- package/dist/node/cli/gitHooksReport.js +119 -0
- package/dist/node/cli/globalFlags.js +67 -0
- package/dist/node/cli/helpReport.js +288 -0
- package/dist/node/cli/manPage.js +165 -0
- package/dist/node/cli/nodefonyBin.js +61 -0
- package/dist/node/cli/outdated.js +144 -0
- package/dist/node/cli/progress.js +555 -0
- package/dist/node/cli/projectRoot.js +32 -0
- package/dist/node/cli/promptPassword.js +44 -0
- package/dist/node/cli/prompts.js +86 -0
- package/dist/node/cli/scaffold/destination.js +92 -0
- package/dist/node/cli/scaffold/engine.js +2156 -0
- package/dist/node/cli/scaffold/entityFields.js +589 -0
- package/dist/node/cli/scaffold/format.js +243 -0
- package/dist/node/cli/scaffold/interactive.js +124 -0
- package/dist/node/cli/scaffold/moduleLayout.js +38 -0
- package/dist/node/cli/scaffold/reservedEntities.js +74 -0
- package/dist/node/cli/scaffold/spec.js +704 -0
- package/dist/node/cli/scaffold/steps.js +40 -0
- package/dist/node/cli/scaffold/userContractSource.js +133 -0
- package/dist/node/cli/scaffold/versions.js +57 -0
- package/dist/node/cli/scaffold/writer.js +172 -0
- package/dist/node/cli/startMenu.js +496 -0
- package/dist/node/cli/symbols.js +205 -0
- package/dist/node/cli/sysexits.js +34 -0
- package/dist/node/cli/tableReport.js +184 -0
- package/dist/node/cli/usageReport.js +144 -0
- package/dist/node/colors.js +63 -0
- package/dist/node/command/Builder.js +153 -0
- package/dist/node/command/Command.js +348 -0
- package/dist/node/config/configProvenance.js +101 -0
- package/dist/node/config/defaults.js +39 -0
- package/dist/node/config/defineConfig.js +129 -0
- package/dist/node/config/defineEnv.js +264 -0
- package/dist/node/config/envExample.js +41 -0
- package/dist/node/config/envOverride.js +423 -0
- package/dist/node/config/infra.js +163 -0
- package/dist/node/config/reactivity.js +23 -0
- package/dist/node/config/reservedEnv.js +118 -0
- package/dist/node/config/schema.js +134 -0
- package/dist/node/config/use.js +24 -0
- package/dist/node/finder/File.js +49 -0
- package/dist/node/finder/FileResult.js +86 -0
- package/dist/node/finder/Finder.js +201 -0
- package/dist/node/finder/Result.js +45 -0
- package/dist/node/index.js +121 -0
- package/dist/node/kernel/BootConfigurationError.js +54 -0
- package/dist/node/kernel/CliKernel.js +630 -0
- package/dist/node/kernel/Kernel.js +2198 -0
- package/dist/node/kernel/Module.js +453 -0
- package/dist/node/kernel/adminPlane/adminCaller.js +98 -0
- package/dist/node/kernel/adminPlane/adminRbac.js +51 -0
- package/dist/node/kernel/adminPlane/catalog.js +158 -0
- package/dist/node/kernel/adminPlane/executeAdmin.js +78 -0
- package/dist/node/kernel/checks/deep.js +335 -0
- package/dist/node/kernel/checks/freshness.js +139 -0
- package/dist/node/kernel/checks/gating.js +231 -0
- package/dist/node/kernel/checks/guards.js +232 -0
- package/dist/node/kernel/checks/lastBoot.js +136 -0
- package/dist/node/kernel/checks/live.js +330 -0
- package/dist/node/kernel/checks/packageDeps.js +292 -0
- package/dist/node/kernel/checks/readiness.js +153 -0
- package/dist/node/kernel/checks/renderReport.js +780 -0
- package/dist/node/kernel/checks/report.js +421 -0
- package/dist/node/kernel/checks/runDoctor.js +731 -0
- package/dist/node/kernel/checks/surface.js +364 -0
- package/dist/node/kernel/checks/walk.js +100 -0
- package/dist/node/kernel/checks/wiring.js +450 -0
- package/dist/node/kernel/commands/AiMcpCommand.js +65 -0
- package/dist/node/kernel/commands/AiSyncCommand.js +48 -0
- package/dist/node/kernel/commands/BuildCommand.js +49 -0
- package/dist/node/kernel/commands/CardCommand.js +50 -0
- package/dist/node/kernel/commands/ClusterCommand.js +58 -0
- package/dist/node/kernel/commands/CompletionCommand.js +31 -0
- package/dist/node/kernel/commands/CreateCommand.js +45 -0
- package/dist/node/kernel/commands/DevCommand.js +99 -0
- package/dist/node/kernel/commands/DoctorCommand.js +115 -0
- package/dist/node/kernel/commands/EnvCommand.js +52 -0
- package/dist/node/kernel/commands/GitHooksCommand.js +47 -0
- package/dist/node/kernel/commands/InspectCommand.js +153 -0
- package/dist/node/kernel/commands/InstallCommand.js +20 -0
- package/dist/node/kernel/commands/MenuCommand.js +261 -0
- package/dist/node/kernel/commands/OutdatedCommand.js +164 -0
- package/dist/node/kernel/commands/ProdCommand.js +60 -0
- package/dist/node/kernel/commands/StatusCommand.js +30 -0
- package/dist/node/kernel/commands/StopCommand.js +35 -0
- package/dist/node/kernel/commands/SymbolsCommand.js +45 -0
- package/dist/node/kernel/commands/runtimeLauncher.js +95 -0
- package/dist/node/kernel/decorators/kernelDecorator.js +110 -0
- package/dist/node/kernel/injector/injector.js +137 -0
- package/dist/node/kernel/injector/serviceOrder.js +106 -0
- package/dist/node/kernel/inspect/adminSubjects.js +194 -0
- package/dist/node/kernel/inspect/docOutline.js +86 -0
- package/dist/node/kernel/lifecycleTags.js +76 -0
- package/dist/node/kernel/moduleConfig.js +75 -0
- package/dist/node/kernel/moduleGating.js +68 -0
- package/dist/node/kernel/readinessRegistry.js +98 -0
- package/dist/node/kernel/resolveModuleEntry.js +61 -0
- package/dist/node/mcp/caller.js +40 -0
- package/dist/node/mcp/guard.js +51 -0
- package/dist/node/mcp/protocol.js +157 -0
- package/dist/node/mcp/server.js +216 -0
- package/dist/node/mcp/tools.js +861 -0
- package/dist/node/oauth/authorizationServer.js +221 -0
- package/dist/node/oauth/protectedResource.js +293 -0
- package/dist/node/package.js +4 -0
- package/dist/node/realtime/IRealtimeTransport.js +32 -0
- package/dist/node/realtime/JsonRpcPeer.js +251 -0
- package/dist/node/realtime/RealtimeEventMap.js +15 -0
- package/dist/node/realtime/channelRate.js +39 -0
- package/dist/node/realtime/platformChannels.js +155 -0
- package/dist/node/runtime/GcScheduler.js +92 -0
- package/dist/node/runtime/RequestContext.js +76 -0
- package/dist/node/runtime/bearer.js +84 -0
- package/dist/node/runtime/engineEnvironment.js +79 -0
- package/dist/node/runtime/loadEnv.js +105 -0
- package/dist/node/runtime/pageFacets.js +85 -0
- package/dist/node/runtime/pageFilters.js +103 -0
- package/dist/node/runtime/pageGuard.js +84 -0
- package/dist/node/runtime/pageQuery.js +160 -0
- package/dist/node/runtime/pageSort.js +114 -0
- package/dist/node/runtime/redact.js +43 -0
- package/dist/node/runtime/withTimeout.js +71 -0
- package/dist/node/service/cluster/ClusterManager.js +202 -0
- package/dist/node/service/cluster/ClusterProbeAggregator.js +120 -0
- package/dist/node/service/cluster/ClusterRelay.js +74 -0
- package/dist/node/service/cluster/clusterMaster.js +65 -0
- package/dist/node/service/cluster/clusterMessage.js +70 -0
- package/dist/node/service/cluster/cpuQuota.js +59 -0
- package/dist/node/service/cluster/instanceProbe.js +52 -0
- package/dist/node/service/cluster/podEnvironment.js +48 -0
- package/dist/node/service/cluster/processProbe.js +70 -0
- package/dist/node/service/cluster/richProcessProbe.js +115 -0
- package/dist/node/service/cluster/topology.js +71 -0
- package/dist/node/service/dev/BootReporter.js +490 -0
- package/dist/node/service/dev/DevSupervisor.js +1004 -0
- package/dist/node/service/dev/bootVerdict.js +158 -0
- package/dist/node/service/dev/detachedStart.js +372 -0
- package/dist/node/service/dev/devProcess.js +1137 -0
- package/dist/node/service/dev/devProjects.js +138 -0
- package/dist/node/service/dev/devStatusReport.js +395 -0
- package/dist/node/service/dev/devStop.js +263 -0
- package/dist/node/service/fetchService.js +35 -0
- package/dist/node/service/gitService.js +62 -0
- package/dist/node/syslog/Pdu.js +224 -0
- package/dist/node/syslog/Syslog.js +1159 -0
- package/dist/node/syslog/drivers/ClusterFileLogDriver.js +114 -0
- package/dist/node/syslog/drivers/FileLogDriver.js +127 -0
- package/dist/node/syslog/drivers/ILogDriver.js +26 -0
- package/dist/node/syslog/drivers/LokiLogDriver.js +144 -0
- package/dist/node/syslog/drivers/MemoryLogDriver.js +33 -0
- package/dist/node/syslog/drivers/OpenSearchLogDriver.js +159 -0
- package/dist/node/syslog/drivers/builtinLogDrivers.js +114 -0
- package/dist/node/syslog/drivers/filterPdus.js +71 -0
- package/dist/node/syslog/drivers/logDriverRegistry.js +83 -0
- package/dist/node/syslog/drivers/opensearchShared.js +17 -0
- package/dist/node/syslog/drivers/pduFlow.js +106 -0
- package/dist/node/syslog/drivers/pduProtocol.js +28 -0
- package/dist/node/syslog/httpFetch.js +43 -0
- package/dist/node/syslog/logColor.js +80 -0
- package/dist/node/syslog/sinks/FileSink.js +142 -0
- package/dist/node/syslog/transports/BatchingHttpTransport.js +98 -0
- package/dist/node/syslog/transports/ConsoleTransport.js +14 -0
- package/dist/node/syslog/transports/FileTransport.js +17 -0
- package/dist/node/syslog/transports/HttpTransport.js +44 -0
- package/dist/node/syslog/transports/LokiTransport.js +80 -0
- package/dist/node/syslog/transports/OpenSearchTransport.js +53 -0
- package/dist/node/syslog/transports/SyslogTransport.js +13 -0
- package/dist/node/syslog/transports/index.js +8 -0
- package/dist/node/testing/index.js +190 -0
- package/dist/types/Cli.d.ts +177 -0
- package/dist/types/Container.d.ts +221 -0
- package/dist/types/Error.d.ts +162 -0
- package/dist/types/Event.d.ts +171 -0
- package/dist/types/FileClass.d.ts +184 -0
- package/dist/types/Nodefony.d.ts +66 -0
- package/dist/types/Service.d.ts +165 -0
- package/dist/types/Tools.d.ts +116 -0
- package/dist/types/bin/resolveLocalCli.d.ts +49 -0
- package/dist/types/bundler/index.d.ts +66 -0
- package/dist/types/cli/agentTargets.d.ts +378 -0
- package/dist/types/cli/aiMcp.d.ts +239 -0
- package/dist/types/cli/aiMcpReport.d.ts +113 -0
- package/dist/types/cli/aiSync.d.ts +68 -0
- package/dist/types/cli/aiSyncReport.d.ts +149 -0
- package/dist/types/cli/card.d.ts +49 -0
- package/dist/types/cli/cardReport.d.ts +127 -0
- package/dist/types/cli/completion.d.ts +154 -0
- package/dist/types/cli/create.d.ts +177 -0
- package/dist/types/cli/env.d.ts +103 -0
- package/dist/types/cli/envReport.d.ts +153 -0
- package/dist/types/cli/execPortable.d.ts +54 -0
- package/dist/types/cli/gitHooks.d.ts +48 -0
- package/dist/types/cli/gitHooksReport.d.ts +101 -0
- package/dist/types/cli/globalFlags.d.ts +48 -0
- package/dist/types/cli/helpReport.d.ts +110 -0
- package/dist/types/cli/manPage.d.ts +21 -0
- package/dist/types/cli/nodefonyBin.d.ts +45 -0
- package/dist/types/cli/outdated.d.ts +119 -0
- package/dist/types/cli/progress.d.ts +349 -0
- package/dist/types/cli/projectRoot.d.ts +19 -0
- package/dist/types/cli/promptPassword.d.ts +22 -0
- package/dist/types/cli/prompts.d.ts +102 -0
- package/dist/types/cli/scaffold/destination.d.ts +70 -0
- package/dist/types/cli/scaffold/engine.d.ts +545 -0
- package/dist/types/cli/scaffold/entityFields.d.ts +238 -0
- package/dist/types/cli/scaffold/format.d.ts +78 -0
- package/dist/types/cli/scaffold/interactive.d.ts +11 -0
- package/dist/types/cli/scaffold/moduleLayout.d.ts +69 -0
- package/dist/types/cli/scaffold/reservedEntities.d.ts +49 -0
- package/dist/types/cli/scaffold/spec.d.ts +159 -0
- package/dist/types/cli/scaffold/steps.d.ts +24 -0
- package/dist/types/cli/scaffold/userContractSource.d.ts +86 -0
- package/dist/types/cli/scaffold/versions.d.ts +14 -0
- package/dist/types/cli/scaffold/writer.d.ts +100 -0
- package/dist/types/cli/startMenu.d.ts +195 -0
- package/dist/types/cli/symbols.d.ts +84 -0
- package/dist/types/cli/sysexits.d.ts +31 -0
- package/dist/types/cli/tableReport.d.ts +44 -0
- package/dist/types/cli/usageReport.d.ts +108 -0
- package/dist/types/client/ClientKernel.d.ts +90 -0
- package/dist/types/client/IClientKernel.d.ts +195 -0
- package/dist/types/client/angular/index.d.ts +273 -0
- package/dist/types/client/announce.d.ts +74 -0
- package/dist/types/client/debugbar/DebugBar.d.ts +279 -0
- package/dist/types/client/debugbar/format.d.ts +48 -0
- package/dist/types/client/debugbar/hmr.d.ts +16 -0
- package/dist/types/client/debugbar/index.d.ts +30 -0
- package/dist/types/client/debugbar/model.d.ts +158 -0
- package/dist/types/client/debugbar/network.d.ts +55 -0
- package/dist/types/client/debugbar/profile.d.ts +99 -0
- package/dist/types/client/index.d.ts +47 -0
- package/dist/types/client/react/index.d.ts +207 -0
- package/dist/types/client/realtime/AdaptiveRate.d.ts +138 -0
- package/dist/types/client/realtime/BrowserWsTransport.d.ts +27 -0
- package/dist/types/client/realtime/RealtimeClient.d.ts +573 -0
- package/dist/types/client/realtime/localEvents.d.ts +53 -0
- package/dist/types/client/realtime/notice.d.ts +70 -0
- package/dist/types/client/realtime/observe.d.ts +284 -0
- package/dist/types/client/roles/index.d.ts +15 -0
- package/dist/types/client/roles/registry.d.ts +72 -0
- package/dist/types/client/roles/roles.d.ts +68 -0
- package/dist/types/client/shim/cli-color.d.ts +2 -0
- package/dist/types/client/shim/events.d.ts +39 -0
- package/dist/types/client/shim/util.d.ts +14 -0
- package/dist/types/client/svelte/index.d.ts +216 -0
- package/dist/types/client/syslog/context.d.ts +76 -0
- package/dist/types/client/syslog/errors.d.ts +46 -0
- package/dist/types/client/syslog/uplink.d.ts +89 -0
- package/dist/types/client/transport/websocket.d.ts +5 -0
- package/dist/types/client/vue/index.d.ts +234 -0
- package/dist/types/colors.d.ts +32 -0
- package/dist/types/command/Builder.d.ts +47 -0
- package/dist/types/command/Command.d.ts +268 -0
- package/dist/types/config/configMeta.d.ts +53 -0
- package/dist/types/config/configProvenance.d.ts +58 -0
- package/dist/types/config/defaults.d.ts +33 -0
- package/dist/types/config/defineConfig.d.ts +70 -0
- package/dist/types/config/defineEnv.d.ts +170 -0
- package/dist/types/config/envExample.d.ts +23 -0
- package/dist/types/config/envOverride.d.ts +236 -0
- package/dist/types/config/index.d.ts +23 -0
- package/dist/types/config/infra.d.ts +171 -0
- package/dist/types/config/reactivity.d.ts +36 -0
- package/dist/types/config/reservedEnv.d.ts +145 -0
- package/dist/types/config/schema.d.ts +113 -0
- package/dist/types/config/types.d.ts +374 -0
- package/dist/types/config/use.d.ts +80 -0
- package/dist/types/finder/File.d.ts +26 -0
- package/dist/types/finder/FileResult.d.ts +14 -0
- package/dist/types/finder/Finder.d.ts +51 -0
- package/dist/types/finder/Result.d.ts +10 -0
- package/dist/types/index.d.ts +205 -0
- package/dist/types/kernel/BootConfigurationError.d.ts +50 -0
- package/dist/types/kernel/CliKernel.d.ts +289 -0
- package/dist/types/kernel/Kernel.d.ts +1255 -0
- package/dist/types/kernel/Module.d.ts +326 -0
- package/dist/types/kernel/adminPlane/adminCaller.d.ts +105 -0
- package/dist/types/kernel/adminPlane/adminRbac.d.ts +44 -0
- package/dist/types/kernel/adminPlane/catalog.d.ts +122 -0
- package/dist/types/kernel/adminPlane/executeAdmin.d.ts +99 -0
- package/dist/types/kernel/bootReport.d.ts +112 -0
- package/dist/types/kernel/checks/deep.d.ts +122 -0
- package/dist/types/kernel/checks/freshness.d.ts +49 -0
- package/dist/types/kernel/checks/gating.d.ts +134 -0
- package/dist/types/kernel/checks/guards.d.ts +57 -0
- package/dist/types/kernel/checks/lastBoot.d.ts +189 -0
- package/dist/types/kernel/checks/live.d.ts +110 -0
- package/dist/types/kernel/checks/packageDeps.d.ts +44 -0
- package/dist/types/kernel/checks/readiness.d.ts +97 -0
- package/dist/types/kernel/checks/renderReport.d.ts +107 -0
- package/dist/types/kernel/checks/report.d.ts +414 -0
- package/dist/types/kernel/checks/runDoctor.d.ts +361 -0
- package/dist/types/kernel/checks/surface.d.ts +148 -0
- package/dist/types/kernel/checks/walk.d.ts +45 -0
- package/dist/types/kernel/checks/wiring.d.ts +54 -0
- package/dist/types/kernel/commands/AiMcpCommand.d.ts +39 -0
- package/dist/types/kernel/commands/AiSyncCommand.d.ts +28 -0
- package/dist/types/kernel/commands/BuildCommand.d.ts +13 -0
- package/dist/types/kernel/commands/CardCommand.d.ts +34 -0
- package/dist/types/kernel/commands/ClusterCommand.d.ts +29 -0
- package/dist/types/kernel/commands/CompletionCommand.d.ts +17 -0
- package/dist/types/kernel/commands/CreateCommand.d.ts +16 -0
- package/dist/types/kernel/commands/DevCommand.d.ts +40 -0
- package/dist/types/kernel/commands/DoctorCommand.d.ts +55 -0
- package/dist/types/kernel/commands/EnvCommand.d.ts +35 -0
- package/dist/types/kernel/commands/GitHooksCommand.d.ts +27 -0
- package/dist/types/kernel/commands/InspectCommand.d.ts +59 -0
- package/dist/types/kernel/commands/InstallCommand.d.ts +7 -0
- package/dist/types/kernel/commands/MenuCommand.d.ts +58 -0
- package/dist/types/kernel/commands/OutdatedCommand.d.ts +47 -0
- package/dist/types/kernel/commands/ProdCommand.d.ts +29 -0
- package/dist/types/kernel/commands/StatusCommand.d.ts +17 -0
- package/dist/types/kernel/commands/StopCommand.d.ts +17 -0
- package/dist/types/kernel/commands/SymbolsCommand.d.ts +29 -0
- package/dist/types/kernel/commands/runtimeLauncher.d.ts +76 -0
- package/dist/types/kernel/decorators/kernelDecorator.d.ts +76 -0
- package/dist/types/kernel/injector/injector.d.ts +47 -0
- package/dist/types/kernel/injector/serviceOrder.d.ts +29 -0
- package/dist/types/kernel/inspect/adminSubjects.d.ts +169 -0
- package/dist/types/kernel/inspect/docOutline.d.ts +53 -0
- package/dist/types/kernel/lifecycleTags.d.ts +79 -0
- package/dist/types/kernel/moduleConfig.d.ts +35 -0
- package/dist/types/kernel/moduleGating.d.ts +78 -0
- package/dist/types/kernel/readinessRegistry.d.ts +104 -0
- package/dist/types/kernel/resolveModuleEntry.d.ts +46 -0
- package/dist/types/mcp/caller.d.ts +55 -0
- package/dist/types/mcp/guard.d.ts +66 -0
- package/dist/types/mcp/protocol.d.ts +163 -0
- package/dist/types/mcp/server.d.ts +70 -0
- package/dist/types/mcp/tools.d.ts +209 -0
- package/dist/types/oauth/authorizationServer.d.ts +204 -0
- package/dist/types/oauth/protectedResource.d.ts +339 -0
- package/dist/types/realtime/IRealtimeSocket.d.ts +142 -0
- package/dist/types/realtime/IRealtimeTransport.d.ts +50 -0
- package/dist/types/realtime/JsonRpcPeer.d.ts +251 -0
- package/dist/types/realtime/RealtimeEventMap.d.ts +269 -0
- package/dist/types/realtime/channelRate.d.ts +55 -0
- package/dist/types/realtime/platformChannels.d.ts +147 -0
- package/dist/types/runtime/GcScheduler.d.ts +96 -0
- package/dist/types/runtime/RequestContext.d.ts +152 -0
- package/dist/types/runtime/bearer.d.ts +88 -0
- package/dist/types/runtime/engineEnvironment.d.ts +115 -0
- package/dist/types/runtime/loadEnv.d.ts +86 -0
- package/dist/types/runtime/pageFacets.d.ts +104 -0
- package/dist/types/runtime/pageFilters.d.ts +139 -0
- package/dist/types/runtime/pageGuard.d.ts +78 -0
- package/dist/types/runtime/pageQuery.d.ts +138 -0
- package/dist/types/runtime/pageSort.d.ts +86 -0
- package/dist/types/runtime/redact.d.ts +27 -0
- package/dist/types/runtime/withTimeout.d.ts +51 -0
- package/dist/types/service/cluster/ClusterManager.d.ts +112 -0
- package/dist/types/service/cluster/ClusterProbeAggregator.d.ts +68 -0
- package/dist/types/service/cluster/ClusterRelay.d.ts +57 -0
- package/dist/types/service/cluster/clusterMaster.d.ts +40 -0
- package/dist/types/service/cluster/clusterMessage.d.ts +94 -0
- package/dist/types/service/cluster/cpuQuota.d.ts +37 -0
- package/dist/types/service/cluster/instanceProbe.d.ts +82 -0
- package/dist/types/service/cluster/podEnvironment.d.ts +35 -0
- package/dist/types/service/cluster/processProbe.d.ts +53 -0
- package/dist/types/service/cluster/richProcessProbe.d.ts +77 -0
- package/dist/types/service/cluster/topology.d.ts +64 -0
- package/dist/types/service/dev/BootReporter.d.ts +67 -0
- package/dist/types/service/dev/DevSupervisor.d.ts +117 -0
- package/dist/types/service/dev/bootVerdict.d.ts +99 -0
- package/dist/types/service/dev/detachedStart.d.ts +164 -0
- package/dist/types/service/dev/devProcess.d.ts +638 -0
- package/dist/types/service/dev/devProjects.d.ts +121 -0
- package/dist/types/service/dev/devStatusReport.d.ts +141 -0
- package/dist/types/service/dev/devStop.d.ts +57 -0
- package/dist/types/service/fetchService.d.ts +29 -0
- package/dist/types/service/gitService.d.ts +24 -0
- package/dist/types/syslog/Pdu.d.ts +134 -0
- package/dist/types/syslog/Syslog.d.ts +482 -0
- package/dist/types/syslog/drivers/ClusterFileLogDriver.d.ts +40 -0
- package/dist/types/syslog/drivers/FileLogDriver.d.ts +55 -0
- package/dist/types/syslog/drivers/ILogDriver.d.ts +177 -0
- package/dist/types/syslog/drivers/LokiLogDriver.d.ts +44 -0
- package/dist/types/syslog/drivers/MemoryLogDriver.d.ts +20 -0
- package/dist/types/syslog/drivers/OpenSearchLogDriver.d.ts +40 -0
- package/dist/types/syslog/drivers/builtinLogDrivers.d.ts +43 -0
- package/dist/types/syslog/drivers/filterPdus.d.ts +21 -0
- package/dist/types/syslog/drivers/logDriverRegistry.d.ts +100 -0
- package/dist/types/syslog/drivers/opensearchShared.d.ts +11 -0
- package/dist/types/syslog/drivers/pduFlow.d.ts +53 -0
- package/dist/types/syslog/drivers/pduProtocol.d.ts +20 -0
- package/dist/types/syslog/httpFetch.d.ts +48 -0
- package/dist/types/syslog/logColor.d.ts +59 -0
- package/dist/types/syslog/sinks/FileSink.d.ts +78 -0
- package/dist/types/syslog/transports/BatchingHttpTransport.d.ts +59 -0
- package/dist/types/syslog/transports/ConsoleTransport.d.ts +8 -0
- package/dist/types/syslog/transports/FileTransport.d.ts +13 -0
- package/dist/types/syslog/transports/HttpTransport.d.ts +15 -0
- package/dist/types/syslog/transports/LokiTransport.d.ts +45 -0
- package/dist/types/syslog/transports/OpenSearchTransport.d.ts +40 -0
- package/dist/types/syslog/transports/SyslogTransport.d.ts +9 -0
- package/dist/types/syslog/transports/index.d.ts +12 -0
- package/dist/types/testing/index.d.ts +197 -0
- package/dist/types/types/IAdminApi.d.ts +246 -0
- package/dist/types/types/ICliKernel.d.ts +28 -0
- package/dist/types/types/ICommand.d.ts +14 -0
- package/dist/types/types/IContainer.d.ts +35 -0
- package/dist/types/types/IIdempotencyStore.d.ts +159 -0
- package/dist/types/types/IKernel.d.ts +138 -0
- package/dist/types/types/IMcpTool.d.ts +157 -0
- package/dist/types/types/IModule.d.ts +73 -0
- package/dist/types/types/IModuleManifest.d.ts +49 -0
- package/dist/types/types/IPage.d.ts +119 -0
- package/dist/types/types/IService.d.ts +62 -0
- package/dist/types/types/ISyslog.d.ts +58 -0
- package/dist/types/types/ITransport.d.ts +5 -0
- package/dist/types/types/globals.d.ts +47 -0
- package/docs/angular-services.md +318 -0
- package/docs/catalogue.md +184 -0
- package/docs/cli.md +369 -0
- package/docs/client.md +616 -0
- package/docs/debugbar.md +218 -0
- package/docs/environnement.md +308 -0
- package/docs/index.md +388 -0
- package/docs/kernel.md +670 -0
- package/docs/progression.md +228 -0
- package/docs/react-hooks.md +686 -0
- package/docs/request-context.md +507 -0
- package/docs/service.md +590 -0
- package/docs/svelte-reactivite.md +293 -0
- package/docs/syslog.md +848 -0
- package/docs/testing.md +203 -0
- package/docs/vue-composables.md +255 -0
- package/man/nodefony.1 +152 -0
- package/package.json +163 -83
- package/templates/app/agents/AGENTS.md.tpl +967 -0
- package/templates/app/agents/POINTEUR.md.tpl +12 -0
- package/templates/app/base/Dockerfile.tpl +104 -0
- package/templates/app/base/README.md.tpl +314 -0
- package/templates/app/base/dockerignore.tpl +28 -0
- package/templates/app/base/env.ts.tpl +130 -0
- package/templates/app/base/gitattributes.tpl +28 -0
- package/templates/app/base/github/workflows/ci.yml.tpl +91 -0
- package/templates/app/base/gitignore.tpl +46 -0
- package/templates/app/base/gitlab-ci.yml.tpl +42 -0
- package/templates/app/base/index.ts.tpl +69 -0
- package/templates/app/base/nodefony.config.ts.tpl +342 -0
- package/templates/app/base/oxlintrc.json.tpl +127 -0
- package/templates/app/base/package.json.tpl +75 -0
- package/templates/app/base/prettierignore.tpl +24 -0
- package/templates/app/base/prettierrc.json.tpl +12 -0
- package/templates/app/base/rolldown.config.ts.tpl +8 -0
- package/templates/app/base/tests/config.test.ts.tpl +29 -0
- package/templates/app/base/tests/e2e.setup.ts.tpl +181 -0
- package/templates/app/base/tests/e2e.test.ts.tpl +105 -0
- package/templates/app/base/tests/migrations.e2e.test.ts.tpl +579 -0
- package/templates/app/base/tsconfig.json.tpl +47 -0
- package/templates/app/base/vitest.config.ts.tpl +88 -0
- package/templates/app/base/vitest.e2e.config.ts.tpl +39 -0
- package/templates/app/complete/compose.yaml.tpl +328 -0
- package/templates/app/complete/deploy/migrate-job.yaml.tpl +100 -0
- package/templates/app/complete/docker/db/init-nodefony-e2e.sql.tpl +30 -0
- package/templates/app/complete/docker/grafana/provisioning/datasources/loki.yaml.tpl +15 -0
- package/templates/app/complete/env.local.tpl +11 -0
- package/templates/app/complete/env.tpl +53 -0
- package/templates/app/complete/nodefony/entity/User.ts.tpl +69 -0
- package/templates/app/complete/nodefony/security/provisionUsers.ts.tpl +124 -0
- package/templates/app/complete/nodefony/service/AppBannerService.ts.tpl +98 -0
- package/templates/app/complete/nodefony/service/AppInfoService.ts.tpl +85 -0
- package/templates/app/frontend/angular/frontend/src/accent.css.tpl +34 -0
- package/templates/app/frontend/angular/frontend/src/app/app.component.ts.tpl +400 -0
- package/templates/app/frontend/react/frontend/src/App.tsx.tpl +421 -0
- package/templates/app/frontend/react/frontend/src/accent.css.tpl +30 -0
- package/templates/app/frontend/shared/frontend/src/brand.ts.tpl +3 -0
- package/templates/app/frontend/shared/frontend/src/showcase.css.tpl +224 -0
- package/templates/app/frontend/shared/nodefony/controllers/AppController.ts.tpl +45 -0
- package/templates/app/frontend/svelte/frontend/src/App.svelte.tpl +371 -0
- package/templates/app/frontend/svelte/frontend/src/accent.css.tpl +34 -0
- package/templates/app/frontend/vue/frontend/src/App.vue.tpl +367 -0
- package/templates/app/frontend/vue/frontend/src/accent.css.tpl +34 -0
- package/templates/app/home/nodefony/controllers/HomeController.ts.tpl +38 -0
- package/templates/command/nodefony/command/__NAME__.ts.tpl +132 -0
- package/templates/controller/duplex/nodefony/controllers/__NAME__.ts.tpl +188 -0
- package/templates/controller/example/nodefony/controllers/__NAME__.ts.tpl +348 -0
- package/templates/controller/hello/nodefony/controllers/__NAME__.ts.tpl +143 -0
- package/templates/controller/realtime/nodefony/controllers/__NAME__.ts.tpl +153 -0
- package/templates/controller/realtime/tests/__KEBAB__-realtime.test.ts.tpl +79 -0
- package/templates/controller/rest/nodefony/controllers/__NAME__.ts.tpl +159 -0
- package/templates/entity/base/nodefony/entity/__PASCAL__.schema.ts.tpl +31 -0
- package/templates/entity/base/nodefony/entity/__PASCAL__.ts.tpl +68 -0
- package/templates/entity/controller/nodefony/controllers/__PASCAL__Controller.ts.tpl +335 -0
- package/templates/entity/service/nodefony/service/__PASCAL__Service.ts.tpl +126 -0
- package/templates/entity/tests/tests/__KEBAB__.e2e.test.ts.tpl +358 -0
- package/templates/entity/tests/tests/__KEBAB__.test.ts.tpl +87 -0
- package/templates/front/angular/frontend/src/app/app.component.ts.tpl +30 -0
- package/templates/front/base/nodefony/controllers/__NAME__.ts.tpl +60 -0
- package/templates/front/react/frontend/src/App.tsx.tpl +26 -0
- package/templates/front/svelte/frontend/src/App.svelte.tpl +19 -0
- package/templates/front/vue/frontend/src/App.vue.tpl +23 -0
- package/templates/module/ai/AGENTS.md.tpl +71 -0
- package/templates/module/base/README.md.tpl +62 -0
- package/templates/module/base/docs/index.md.tpl +55 -0
- package/templates/module/base/index.ts.tpl +50 -0
- package/templates/module/base/nodefony/config/config.ts.tpl +60 -0
- package/templates/module/base/nodefony/config/defineModuleConfig.ts.tpl +55 -0
- package/templates/module/base/nodefony/src/errors/__PASCAL__Error.ts.tpl +20 -0
- package/templates/module/base/package.json.tpl +53 -0
- package/templates/module/base/rolldown.config.ts.tpl +14 -0
- package/templates/module/base/tests/__KEBAB__.test.ts.tpl +39 -0
- package/templates/module/base/tsconfig.json.tpl +42 -0
- package/templates/module/base/vitest.config.ts.tpl +27 -0
- package/templates/module/packages/CLAUDE.md.tpl +51 -0
- package/templates/module/packages/MEMORY.md.tpl +39 -0
- package/templates/module/packages/tsconfig.declarations.json.tpl +19 -0
- package/templates/module/packages/tsconfig.tests.json.tpl +11 -0
- package/templates/module/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +14 -0
- package/templates/module/service/nodefony/interfaces/index.ts.tpl +1 -0
- package/templates/module/service/nodefony/service/__PASCAL__Service.ts.tpl +116 -0
- package/templates/service/nodefony/interfaces/I__PASCAL__Service.ts.tpl +19 -0
- package/templates/service/nodefony/service/__PASCAL__Service.ts.tpl +136 -0
- package/templates/service/tests/__PASCAL__Service.test.ts.tpl +53 -0
- package/templates/shared/front-entry/angular/frontend/src/main.ts.tpl +17 -0
- package/templates/shared/front-entry/react/frontend/src/main.tsx.tpl +11 -0
- package/templates/shared/front-entry/svelte/frontend/src/main.ts.tpl +13 -0
- package/templates/shared/front-entry/vue/frontend/src/main.ts.tpl +12 -0
- package/templates/shared/front-registrar/nodefony/frontend/register__PASCAL__Entry.ts.tpl +40 -0
- package/templates/shared/front-shell/frontend/index.html.tpl +39 -0
- package/templates/shared/ng-app-tsconfig/frontend/tsconfig.app.json.tpl +18 -0
- package/templates/shared/svelte-shim/frontend/src/env.d.ts.tpl +12 -0
- package/templates/shared/vue-shim/frontend/src/env.d.ts.tpl +15 -0
- package/.yarnclean +0 -45
- package/CHANGELOG.md +0 -406
- package/autoloader.es6 +0 -253
- package/builder.es6 +0 -366
- package/cli/builder/bundles/bundle.js +0 -328
- package/cli/builder/bundles/controller.js +0 -73
- package/cli/builder/bundles/users-bundle/.yarnclean +0 -45
- package/cli/builder/bundles/users-bundle/Command/fixtureTask.js +0 -47
- package/cli/builder/bundles/users-bundle/Command/usersCommand.js +0 -105
- package/cli/builder/bundles/users-bundle/Entity/mongoose/userEntity.js +0 -168
- package/cli/builder/bundles/users-bundle/Entity/sequelize/userEntity.js +0 -231
- package/cli/builder/bundles/users-bundle/Fixtures/users.js +0 -117
- package/cli/builder/bundles/users-bundle/Fixtures/usersFixtures.js +0 -114
- package/cli/builder/bundles/users-bundle/Resources/config/config.js +0 -90
- package/cli/builder/bundles/users-bundle/Resources/config/routing.js +0 -17
- package/cli/builder/bundles/users-bundle/Resources/config/security.js +0 -96
- package/cli/builder/bundles/users-bundle/Resources/config/services.js +0 -7
- package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.dev.config.js +0 -13
- package/cli/builder/bundles/users-bundle/Resources/config/webpack/webpack.prod.config.js +0 -31
- package/cli/builder/bundles/users-bundle/Resources/config/webpack.config.js +0 -146
- package/cli/builder/bundles/users-bundle/Resources/js/users.js +0 -153
- package/cli/builder/bundles/users-bundle/Resources/public/favicon.ico +0 -0
- package/cli/builder/bundles/users-bundle/Resources/public/images/users-logo.png +0 -0
- package/cli/builder/bundles/users-bundle/Resources/scss/awesome/font-awesome.config.js +0 -11
- package/cli/builder/bundles/users-bundle/Resources/scss/custom.scss +0 -23
- package/cli/builder/bundles/users-bundle/Resources/scss/users.scss +0 -59
- package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/login.js +0 -235
- package/cli/builder/bundles/users-bundle/Resources/swagger/openapi/users.js +0 -232
- package/cli/builder/bundles/users-bundle/Resources/translations/login.en_en.yml +0 -14
- package/cli/builder/bundles/users-bundle/Resources/translations/login.fr_fr.yml +0 -14
- package/cli/builder/bundles/users-bundle/Resources/translations/users.en_en.yml +0 -35
- package/cli/builder/bundles/users-bundle/Resources/translations/users.fr_fr.yml +0 -36
- package/cli/builder/bundles/users-bundle/Resources/views/base.html.twig +0 -32
- package/cli/builder/bundles/users-bundle/Resources/views/footer.html.twig +0 -7
- package/cli/builder/bundles/users-bundle/Resources/views/header.html.twig +0 -90
- package/cli/builder/bundles/users-bundle/Resources/views/login/login.html.twig +0 -43
- package/cli/builder/bundles/users-bundle/Resources/views/users/createUser.html.twig +0 -296
- package/cli/builder/bundles/users-bundle/Resources/views/users/readUsers.html.twig +0 -94
- package/cli/builder/bundles/users-bundle/controller/api/graphql/graphqlController.js +0 -56
- package/cli/builder/bundles/users-bundle/controller/api/graphql/userResolver.js +0 -121
- package/cli/builder/bundles/users-bundle/controller/api/graphql/usertype.js +0 -58
- package/cli/builder/bundles/users-bundle/controller/api/openapi/loginApiController.js +0 -210
- package/cli/builder/bundles/users-bundle/controller/api/openapi/restUserController.js +0 -244
- package/cli/builder/bundles/users-bundle/controller/loginController.js +0 -91
- package/cli/builder/bundles/users-bundle/controller/usersController.js +0 -332
- package/cli/builder/bundles/users-bundle/package.json +0 -58
- package/cli/builder/bundles/users-bundle/readme.md +0 -360
- package/cli/builder/bundles/users-bundle/services/usersService.js +0 -411
- package/cli/builder/bundles/users-bundle/src/providers/mongoose/userProvider.js +0 -47
- package/cli/builder/bundles/users-bundle/src/providers/sequelize/userProvider.js +0 -48
- package/cli/builder/bundles/users-bundle/tests/loginTest.js +0 -182
- package/cli/builder/bundles/users-bundle/usersBundle.js +0 -26
- package/cli/builder/microService/microService.js +0 -261
- package/cli/builder/microService/skeletons/.editorconfig +0 -18
- package/cli/builder/microService/skeletons/.env-cmdrc.js +0 -32
- package/cli/builder/microService/skeletons/.jshintrc +0 -37
- package/cli/builder/microService/skeletons/README.md +0 -117
- package/cli/builder/microService/skeletons/bin/bash/hello.sh +0 -5
- package/cli/builder/microService/skeletons/bin/cli +0 -13
- package/cli/builder/microService/skeletons/bin/python/hello.py +0 -20
- package/cli/builder/microService/skeletons/config/config.js +0 -29
- package/cli/builder/microService/skeletons/config/pm2.config.js +0 -72
- package/cli/builder/microService/skeletons/config/webpack/webpack.config.dev.js +0 -8
- package/cli/builder/microService/skeletons/config/webpack/webpack.config.prod.js +0 -25
- package/cli/builder/microService/skeletons/config/webpack.config.js +0 -114
- package/cli/builder/microService/skeletons/package.json +0 -76
- package/cli/builder/microService/skeletons/src/browser/index.css +0 -3
- package/cli/builder/microService/skeletons/src/browser/index.js +0 -16
- package/cli/builder/microService/skeletons/src/browser/socketio.js +0 -46
- package/cli/builder/microService/skeletons/src/cli/cli.js +0 -224
- package/cli/builder/microService/skeletons/src/cli/menu.js +0 -28
- package/cli/builder/microService/skeletons/src/n-api/README.md +0 -1
- package/cli/builder/microService/skeletons/src/n-api/binding.gyp +0 -14
- package/cli/builder/microService/skeletons/src/n-api/hello.cc +0 -14
- package/cli/builder/microService/skeletons/src/n-api/hello.js +0 -23
- package/cli/builder/microService/skeletons/src/n-api/package.json +0 -15
- package/cli/builder/microService/skeletons/src/node/examples/index.js +0 -120
- package/cli/builder/microService/skeletons/src/node/index.js +0 -102
- package/cli/builder/microService/skeletons/src/node/services/markdown/markdown.js +0 -27
- package/cli/builder/microService/skeletons/src/node/services/servers/http.js +0 -45
- package/cli/builder/microService/skeletons/src/node/services/servers/https.js +0 -44
- package/cli/builder/microService/skeletons/src/node/services/socketio/socketio.js +0 -46
- package/cli/builder/microService/skeletons/src/node/services/syscall/syscall.js +0 -111
- package/cli/builder/microService/skeletons/src/node/services/worker/thread.js +0 -59
- package/cli/builder/microService/skeletons/src/node/services/worker/worker.js +0 -60
- package/cli/builder/microService/skeletons/src/templates/base.html +0 -12
- package/cli/builder/microService/skeletons/src/templates/socket.html +0 -23
- package/cli/builder/microService/skeletons/tests/unit/serviceTest.js +0 -30
- package/cli/builder/project/project.js +0 -474
- package/cli/builder/project/skeletons/README.md +0 -778
- package/cli/builder/project/skeletons/bin/dev-deploy.sh +0 -5
- package/cli/builder/project/skeletons/bin/generateCertificates.sh.skeleton +0 -180
- package/cli/builder/project/skeletons/bin/prod-deploy.sh +0 -3
- package/cli/builder/project/skeletons/config/config.js.skeleton +0 -178
- package/cli/builder/project/skeletons/config/openssl/ca/openssl.cnf.skeleton +0 -150
- package/cli/builder/project/skeletons/config/openssl/ca_intermediate/openssl.cnf.skeleton +0 -152
- package/cli/builder/project/skeletons/config/pm2.config.js.skeleton +0 -62
- package/cli/builder/project/skeletons/documentation.html.twig +0 -24
- package/cli/builder/project/skeletons/editorconfig.skeleton +0 -18
- package/cli/builder/project/skeletons/eslintignore.skeleton +0 -15
- package/cli/builder/project/skeletons/eslintrc.js.skeleton +0 -97
- package/cli/builder/project/skeletons/gitignore.skeleton +0 -32
- package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.37.entity-user.js +0 -137
- package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.38.entity-session.js +0 -97
- package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.39.entity-requests.js +0 -115
- package/cli/builder/project/skeletons/migrations/2022.12.25T17.37.40.entity-jwts.js +0 -97
- package/cli/builder/project/skeletons/migrations/migrations.skeleton.js +0 -101
- package/cli/builder/project/skeletons/package.json.twig +0 -71
- package/cli/builder/react/reactBuilder.js +0 -224
- package/cli/builder/react/skeletons/app/Resources/databases/nodefony.db +0 -0
- package/cli/builder/react/skeletons/app/Resources/translations/messages.en_en.yml +0 -5
- package/cli/builder/react/skeletons/app/Resources/translations/messages.fr_fr.yml +0 -5
- package/cli/builder/react/skeletons/app/Resources/views/base.html.twig +0 -33
- package/cli/builder/react/skeletons/app/config/config.js +0 -392
- package/cli/builder/react/skeletons/app/config/routing.js +0 -10
- package/cli/builder/react/skeletons/app/config/security.js +0 -74
- package/cli/builder/react/skeletons/app/controller/appController.js +0 -22
- package/cli/builder/sandbox/sandBoxBuilder.js +0 -610
- package/cli/builder/sandbox/skeletons/Resources/css/entry.css +0 -48
- package/cli/builder/sandbox/skeletons/Resources/js/entry.js +0 -60
- package/cli/builder/sandbox/skeletons/Resources/public/manifest.json +0 -32
- package/cli/builder/sandbox/skeletons/Resources/translations/messages.en_en.yml +0 -5
- package/cli/builder/sandbox/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
- package/cli/builder/sandbox/skeletons/Resources/views/base.html.twig +0 -46
- package/cli/builder/sandbox/skeletons/Resources/views/index.html.twig +0 -34
- package/cli/builder/sandbox/skeletons/bootstrap/custom.scss +0 -27
- package/cli/builder/sandbox/skeletons/bootstrap/entry.scss +0 -60
- package/cli/builder/sandbox/skeletons/workbox/templates/index.html.twig +0 -32
- package/cli/builder/sandbox/skeletons/workbox/workers/service-worker.js +0 -196
- package/cli/builder/skeletons/Resources/public/favicon.ico +0 -0
- package/cli/builder/skeletons/Resources/public/images/app-logo.png +0 -0
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/401.json.twig +0 -24
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/403.json.twig +0 -20
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/404.json.twig +0 -20
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/500.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/base.html.twig +0 -30
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/exception.json.twig +0 -24
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/footer.html.twig +0 -33
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/header.html.twig +0 -6
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.html.twig +0 -6
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/index.json.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.html.twig +0 -125
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/layout.json.twig +0 -5
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.html.twig +0 -1
- package/cli/builder/skeletons/Resources/views/framework-bundle/views/timeout.json.twig +0 -24
- package/cli/builder/skeletons/app/appKernel.js +0 -133
- package/cli/builder/skeletons/binding/binding.cc +0 -26
- package/cli/builder/skeletons/binding/binding.skeleton +0 -8
- package/cli/builder/skeletons/bundle/bundleClass.js +0 -37
- package/cli/builder/skeletons/command/commandClass.js +0 -11
- package/cli/builder/skeletons/command/taskClass.js +0 -20
- package/cli/builder/skeletons/config/config.js +0 -138
- package/cli/builder/skeletons/config/nodefony/elastic-bundle.js +0 -37
- package/cli/builder/skeletons/config/nodefony/framework-bundle.js +0 -22
- package/cli/builder/skeletons/config/nodefony/http-bundle.js +0 -104
- package/cli/builder/skeletons/config/nodefony/mail-bundle.js +0 -44
- package/cli/builder/skeletons/config/nodefony/mongoose-bundle.js +0 -51
- package/cli/builder/skeletons/config/nodefony/monitoring-bundle.js +0 -34
- package/cli/builder/skeletons/config/nodefony/realtime-bundle.js +0 -15
- package/cli/builder/skeletons/config/nodefony/redis-bundle.js +0 -44
- package/cli/builder/skeletons/config/nodefony/security-bundle.js +0 -25
- package/cli/builder/skeletons/config/nodefony/sequelize-bundle.js +0 -156
- package/cli/builder/skeletons/config/routing.js +0 -55
- package/cli/builder/skeletons/config/security.js +0 -102
- package/cli/builder/skeletons/config/services.js +0 -1
- package/cli/builder/skeletons/config/webpack/webpack.dev.config.js +0 -13
- package/cli/builder/skeletons/config/webpack/webpack.prod.config.js +0 -20
- package/cli/builder/skeletons/config/webpack.config.js +0 -148
- package/cli/builder/skeletons/controller/controllerClass.js +0 -75
- package/cli/builder/skeletons/package.json.twig +0 -57
- package/cli/builder/skeletons/unittest/testFile.js +0 -46
- package/cli/builder/vue/skeletons/Resources/public/images/app-logo.png +0 -0
- package/cli/builder/vue/skeletons/Resources/translations/messages.en_en.yml +0 -5
- package/cli/builder/vue/skeletons/Resources/translations/messages.fr_fr.yml +0 -5
- package/cli/builder/vue/skeletons/vue.config.js +0 -129
- package/cli/builder/vue/vueBuilder.js +0 -410
- package/cli/generate/generate.es6 +0 -103
- package/cli/install/install.js +0 -190
- package/cli/sequelize/sequelize.js +0 -94
- package/cli/start.js +0 -702
- package/cli/tools/pm2.es6 +0 -112
- package/cli/tools/tools.es6 +0 -97
- package/cli.es6 +0 -925
- package/container.es6 +0 -272
- package/error.es6 +0 -293
- package/fileClass.es6 +0 -242
- package/finder/file.es6 +0 -33
- package/finder/fileResult.es6 +0 -138
- package/finder/finder2.es6 +0 -275
- package/finder.es6 +0 -427
- package/kernel/annotations/annotations.es6 +0 -286
- package/kernel/api/api.es6 +0 -61
- package/kernel/api/graphqlApi.es6 +0 -107
- package/kernel/api/jsonApi.es6 +0 -177
- package/kernel/api/openApi.es6 +0 -139
- package/kernel/api/schemas/openApiSchema.js +0 -394
- package/kernel/babylon.es6 +0 -162
- package/kernel/bundle.es6 +0 -1200
- package/kernel/cliKernel.es6 +0 -869
- package/kernel/command.es6 +0 -78
- package/kernel/commands/nodefonyCommand.es6 +0 -247
- package/kernel/commands/tasks/bundlesTask.es6 +0 -59
- package/kernel/controllers/controller.es6 +0 -791
- package/kernel/fixture.es6 +0 -19
- package/kernel/injections/injections.es6 +0 -424
- package/kernel/kernel.es6 +0 -1960
- package/kernel/kernelWatcher.es6 +0 -387
- package/kernel/orm/entity.es6 +0 -59
- package/kernel/orm/orm.es6 +0 -139
- package/kernel/reader.es6 +0 -290
- package/kernel/security/encoder.es6 +0 -17
- package/kernel/security/factories/factory.es6 +0 -111
- package/kernel/security/factories/passeportFactory.es6 +0 -61
- package/kernel/security/provider.es6 +0 -58
- package/kernel/security/providers/chainProvider.es6 +0 -99
- package/kernel/security/providers/memoryProvider.es6 +0 -55
- package/kernel/security/providers/providerManager.es6 +0 -67
- package/kernel/security/providers/userEntityProvider.es6 +0 -50
- package/kernel/security/role.es6 +0 -12
- package/kernel/security/secureArea.es6 +0 -431
- package/kernel/security/tokens/token.es6 +0 -171
- package/kernel/security/user.es6 +0 -106
- package/kernel/serviceRealTime.es6 +0 -21
- package/kernel/services/connectionsService.es6 +0 -93
- package/kernel/services/cron/cronService.es6 +0 -123
- package/kernel/task.es6 +0 -80
- package/kernel/templates.es6 +0 -22
- package/kernel/templating/twig.es6 +0 -218
- package/kernel/tests/cliTest.js +0 -59
- package/kernel/tests/containerTest.js +0 -232
- package/kernel/tests/kernelTest.js +0 -39
- package/nodefony.es6 +0 -1084
- package/notificationsCenter.es6 +0 -118
- package/protocol.es6 +0 -86
- package/protocols/bayeux.es6 +0 -174
- package/protocols/jsonRpc/jsonrpc.es6 +0 -56
- package/result.es6 +0 -99
- package/service.es6 +0 -288
- package/syslog/pdu.es6 +0 -141
- package/syslog/syslog.es6 +0 -754
- package/watcher.es6 +0 -113
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Hooks React — nodefony/react"
|
|
3
|
+
lang: fr
|
|
4
|
+
module: "@nodefony/core"
|
|
5
|
+
topic: react-hooks
|
|
6
|
+
coverageModule: nodefony-core
|
|
7
|
+
coveragePackage: "nodefony (cœur)"
|
|
8
|
+
coverageFiles: "client/react/index.ts,client/realtime/RealtimeClient.ts"
|
|
9
|
+
section: "Cœur runtime"
|
|
10
|
+
audience: [developer]
|
|
11
|
+
tags:
|
|
12
|
+
[
|
|
13
|
+
react,
|
|
14
|
+
hooks,
|
|
15
|
+
temps-reel,
|
|
16
|
+
websocket,
|
|
17
|
+
abonnement,
|
|
18
|
+
cadence,
|
|
19
|
+
notices,
|
|
20
|
+
identite,
|
|
21
|
+
isomorphe,
|
|
22
|
+
]
|
|
23
|
+
version: "doc"
|
|
24
|
+
status: stable
|
|
25
|
+
updated: 2026-07-19
|
|
26
|
+
source: "src/nodefony/docs/react-hooks.md"
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
# Hooks React — `nodefony/react`
|
|
30
|
+
|
|
31
|
+
> Le subpath `nodefony/react` branche un composant React sur la socket Nodefony **sans une ligne de
|
|
32
|
+
> glue** : un fournisseur au-dessus de l'arbre, puis des hooks ciblés qui s'abonnent au montage et se
|
|
33
|
+
> débranchent au démontage. Ils ne gèrent **que** l'abonnement — ouvrir et maintenir la connexion
|
|
34
|
+
> reste le travail du client, décrit dans [Client isomorphe](client.md). Ancré sur
|
|
35
|
+
> `src/nodefony/src/client/react/index.ts`.
|
|
36
|
+
|
|
37
|
+
📍 [Documentation](../../../docs/index.md) › [Cœur — @nodefony/core](index.md) › **Hooks React**
|
|
38
|
+
|
|
39
|
+
## 🧠 Le modèle mental — une prise, N composants branchés dessus
|
|
40
|
+
|
|
41
|
+
Un composant React vit et meurt au gré de la navigation. Une socket, elle, doit rester ouverte. Le
|
|
42
|
+
binding tient les deux bouts : **le fil est unique et long**, **les branchements sont nombreux et
|
|
43
|
+
courts**.
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
flowchart LR
|
|
47
|
+
APP["ton app<br/>socket.connect() — UNE fois"] --> CL
|
|
48
|
+
subgraph CL["RealtimeClient (hors React)"]
|
|
49
|
+
direction TB
|
|
50
|
+
S["état · identité · notices"]
|
|
51
|
+
R["abonnements ref-comptés<br/>canal → nb de consommateurs"]
|
|
52
|
+
end
|
|
53
|
+
CL --> P["NodefonyProvider<br/>contexte React"]
|
|
54
|
+
P --> H1["useNodefonyState()<br/>re-rend au changement d'état"]
|
|
55
|
+
P --> H2["useNodefonyChannelData()<br/>re-rend à chaque message"]
|
|
56
|
+
P --> H3["useNodefonyChannel()<br/>ne re-rend jamais seul"]
|
|
57
|
+
H1 -. "démontage" .-> R
|
|
58
|
+
H2 -. "démontage" .-> R
|
|
59
|
+
H3 -. "démontage" .-> R
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Trois idées portent toute la page :
|
|
63
|
+
|
|
64
|
+
1. **Les hooks s'abonnent, ils ne connectent pas.** `socket.connect()` est appelé une fois par l'app ;
|
|
65
|
+
monter ou démonter un écran ne ferme jamais la socket.
|
|
66
|
+
2. **Le comptage de références vit dans le client, pas dans React.** Dix composants sur le même canal
|
|
67
|
+
= **un** `subscribe` sur le fil ; le `unsubscribe` part au dernier qui se démonte.
|
|
68
|
+
3. **Un hook = une responsabilité.** Il n'y a pas de god-hook qui re-rend tout l'écran à chaque
|
|
69
|
+
message : on compose exactement ce que la vue affiche.
|
|
70
|
+
|
|
71
|
+
## 📖 Lexique
|
|
72
|
+
|
|
73
|
+
| Terme | Sens |
|
|
74
|
+
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
75
|
+
| **Binding** | La fine couche qui adapte une brique agnostique (ici la socket) à un framework d'interface (ici React). |
|
|
76
|
+
| **Fournisseur** (provider) | Composant qui met une valeur à disposition de tout son sous-arbre via le contexte React. |
|
|
77
|
+
| **Canal** (channel) | Sous-flux nommé de la socket (`"chat:general"`). Voir [vocabulaire realtime](../../packages/@nodefony/realtime/docs/vocabulaire.md). |
|
|
78
|
+
| **Abonnement ref-compté** | Un compteur par canal : le message réseau ne part qu'aux transitions 0↔1. |
|
|
79
|
+
| **Snapshot** | Valeur lue à un instant donné par `useSyncExternalStore` pour décider s'il faut re-rendre. |
|
|
80
|
+
| **Tearing** | Deux parties d'un même rendu affichant deux versions d'une donnée qui a changé en cours de route. |
|
|
81
|
+
| **StrictMode** | Mode de développement de React qui monte, démonte, puis remonte chaque composant pour révéler les fuites. |
|
|
82
|
+
| **Mémoïsation** | Garder la même référence entre deux rendus (`useMemo`, `useCallback`) pour éviter un travail répété. |
|
|
83
|
+
| **Cadence** | Fréquence d'un canal d'état, portée par son **nom** (`nodefony:orm:health:2000` = toutes les 2 s). |
|
|
84
|
+
| **AIMD** | _Additive Increase, Multiplicative Decrease_ — on ralentit vite sous pression, on réaccélère lentement. |
|
|
85
|
+
| **Latest-wins** | Canal où seule la dernière valeur compte : en décimer est sans perte (supervision, stats). |
|
|
86
|
+
| **Coalescence** | Regrouper N événements en une seule trame — le journal arrive par lots, pas ligne à ligne. |
|
|
87
|
+
| **Notice** | Événement normalisé destiné à l'utilisateur (perte de connexion, refus, rétablissement). |
|
|
88
|
+
| **Welcome** | Première trame poussée par le serveur après la poignée de main ; elle annonce l'identité de la connexion. |
|
|
89
|
+
| **Identité** | Ce que le serveur dit de cette connexion : authentifiée ou non, rôles, scopes. |
|
|
90
|
+
| **Subpath** | Point d'entrée secondaire d'un paquet npm (`nodefony/react`), déclaré dans le champ `exports`. |
|
|
91
|
+
| **Condition d'export** | Variante d'un subpath choisie selon l'environnement (`browser`, `import`) — décide quels types sont lus. |
|
|
92
|
+
|
|
93
|
+
## Qu'est-ce qu'un binding React — et pourquoi pas un simple `useEffect`
|
|
94
|
+
|
|
95
|
+
Brancher une socket sur React « à la main » tient en dix lignes… qu'on réécrit dans chaque composant,
|
|
96
|
+
et qui contiennent toutes le même bug. Trois pièges reviennent systématiquement.
|
|
97
|
+
|
|
98
|
+
- **Le désabonnement qui coupe le voisin.** Deux composants écoutent `"metrics"` ; le premier se
|
|
99
|
+
démonte, envoie `unsubscribe`, et le second cesse silencieusement de recevoir.
|
|
100
|
+
- **Le ré-abonnement en boucle.** Le handler est recréé à chaque rendu, il entre dans les dépendances
|
|
101
|
+
de l'effet, l'effet se rejoue, l'abonnement se refait — à chaque frappe au clavier.
|
|
102
|
+
- **La fuite au démontage.** L'écouteur reste attaché à un composant mort, qui continue d'appeler
|
|
103
|
+
`setState` et de retenir tout son arbre en mémoire.
|
|
104
|
+
|
|
105
|
+
Le binding existe pour que ces trois cas soient traités **une fois**, au bon endroit, et prouvés.
|
|
106
|
+
|
|
107
|
+
## La vision Nodefony
|
|
108
|
+
|
|
109
|
+
Le parti pris est de mettre l'intelligence **sous** React, pas dedans. Le comptage de références et
|
|
110
|
+
le ré-abonnement après coupure vivent dans `RealtimeClient.subscribe()`
|
|
111
|
+
(`client/realtime/RealtimeClient.ts:530`) et `RealtimeClient.unsubscribe()`
|
|
112
|
+
(`client/realtime/RealtimeClient.ts:543`), au-dessus d'une carte `_subscriptions`
|
|
113
|
+
(`client/realtime/RealtimeClient.ts:229`).
|
|
114
|
+
|
|
115
|
+
Conséquence directe : cette autorité est **partagée**. Les hooks et un store applicatif (MobX, Zustand,
|
|
116
|
+
Redux) peuvent tenir le même canal sans se marcher dessus — chacun compte pour un.
|
|
117
|
+
|
|
118
|
+
Le binding lui-même reste volontairement pauvre. Il ne fait que trois choses :
|
|
119
|
+
|
|
120
|
+
1. **Publier le client** dans le contexte React — `NodefonyProvider` (`client/react/index.ts:116`)
|
|
121
|
+
au-dessus d'un `NodefonyContext` (`client/react/index.ts:77`).
|
|
122
|
+
2. **Capturer les handlers par référence** — `handlerRef` (`client/react/index.ts:126`) : un handler
|
|
123
|
+
redéfini à chaque rendu ne re-déclenche jamais l'abonnement, donc **aucun `useCallback` requis**.
|
|
124
|
+
3. **Lire l'état sans tearing** — `useNodefonyState()` (`client/react/index.ts:149`) passe par
|
|
125
|
+
`useSyncExternalStore`, qui garantit une valeur cohérente en rendu concurrent.
|
|
126
|
+
|
|
127
|
+
Le fichier n'écrit **aucun JSX** : le fournisseur est construit par `createElement`. C'est ce qui
|
|
128
|
+
permet au cœur `nodefony` d'être bâti sans transformation JSX, tout en livrant des hooks React.
|
|
129
|
+
|
|
130
|
+
Le compromis assumé : **les hooks ne pilotent pas la connexion**. Ils n'appellent ni `connect()` ni
|
|
131
|
+
`disconnect()`. Un écran ne peut donc pas couper le temps réel du reste de l'application. C'est le
|
|
132
|
+
**fournisseur** qui ouvre la connexion, une fois, quand tu lui donnes une adresse.
|
|
133
|
+
|
|
134
|
+
## 🚀 Démarrage rapide
|
|
135
|
+
|
|
136
|
+
### 1. Le fournisseur, au-dessus de l'arbre
|
|
137
|
+
|
|
138
|
+
Donne-lui l'adresse du serveur temps réel : il fabrique la socket et la connecte.
|
|
139
|
+
|
|
140
|
+
```tsx ignore
|
|
141
|
+
// frontend/src/main.tsx
|
|
142
|
+
import { createRoot } from "react-dom/client";
|
|
143
|
+
import { NodefonyProvider } from "nodefony/react";
|
|
144
|
+
import { Shell } from "./Shell";
|
|
145
|
+
|
|
146
|
+
createRoot(document.getElementById("root")!).render(
|
|
147
|
+
<NodefonyProvider url="/api/live/realtime">
|
|
148
|
+
<Shell />
|
|
149
|
+
</NodefonyProvider>,
|
|
150
|
+
);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
C'est tout le câblage : **deux concepts**, ce fournisseur et un hook. L'URL est relative, donc
|
|
154
|
+
résolue contre la page — `ws://` en http, `wss://` en https. Une application générée par
|
|
155
|
+
`nodefony create app` monte `/api/live/realtime` ; la console d'administration,
|
|
156
|
+
`/nodefony/studio/api/realtime`.
|
|
157
|
+
|
|
158
|
+
> [!IMPORTANT]
|
|
159
|
+
> **Il n'y a pas d'adresse par défaut.** Sans `url` ni `client`, le client refuse de démarrer avec
|
|
160
|
+
> un message qui nomme la route attendue. C'est délibéré : la route dépend de ton application, pas
|
|
161
|
+
> du framework, et une adresse devinée donnait une socket qui ne se connecte jamais et se contente
|
|
162
|
+
> de retenter — sans un mot.
|
|
163
|
+
|
|
164
|
+
Deux fournisseurs qui reçoivent la **même URL** partagent la **même socket** : une seule connexion
|
|
165
|
+
WebSocket pour toute la page, quel que soit le nombre d'écrans montés.
|
|
166
|
+
|
|
167
|
+
### 2. Quand l'application possède son cycle de connexion
|
|
168
|
+
|
|
169
|
+
Passe `client` au lieu de `url`. Le fournisseur ne touche alors ni à `connect()` ni à
|
|
170
|
+
`disconnect()` : c'est toi qui décides. C'est le cas de la console d'administration, qui
|
|
171
|
+
re-négocie sa socket à chaque changement d'identité (anti-élévation de privilège).
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
// frontend/src/realtime.ts — LA socket de l'application.
|
|
175
|
+
import { RealtimeClient } from "nodefony/client";
|
|
176
|
+
|
|
177
|
+
// `shared` réutilise l'instance existante pour une même URL : le shell, un widget
|
|
178
|
+
// et la barre de debug ouvrent UNE socket, pas trois.
|
|
179
|
+
export const socket = RealtimeClient.shared({
|
|
180
|
+
url: "/api/live/realtime", // relative → ws:// ou wss:// selon la page
|
|
181
|
+
autoReconnect: true,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
/** À appeler une seule fois, au démarrage de l'app. */
|
|
185
|
+
export async function startRealtime(): Promise<void> {
|
|
186
|
+
await socket.connect();
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
```tsx ignore
|
|
191
|
+
// frontend/src/main.tsx
|
|
192
|
+
import { NodefonyProvider } from "nodefony/react";
|
|
193
|
+
import { socket, startRealtime } from "./realtime";
|
|
194
|
+
|
|
195
|
+
void startRealtime(); // la connexion s'ouvre ici, et nulle part ailleurs
|
|
196
|
+
|
|
197
|
+
createRoot(document.getElementById("root")!).render(
|
|
198
|
+
<NodefonyProvider client={socket}>
|
|
199
|
+
<Shell />
|
|
200
|
+
</NodefonyProvider>,
|
|
201
|
+
);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
> [!IMPORTANT]
|
|
205
|
+
> Importe `RealtimeClient` depuis **`nodefony/client`**, pas depuis `"nodefony"`. Le point d'entrée
|
|
206
|
+
> racine n'expose le client qu'à travers la condition d'export `browser` : sans
|
|
207
|
+
> `customConditions: ["browser"]` dans le `tsconfig.json`, TypeScript lit les types serveur et
|
|
208
|
+
> répond `has no exported member 'RealtimeClient'`. Le subpath `nodefony/client`, lui, résout
|
|
209
|
+
> partout.
|
|
210
|
+
|
|
211
|
+
### 3. Un hook métier, bâti sur les hooks Nodefony
|
|
212
|
+
|
|
213
|
+
C'est la forme recommandée : les hooks Nodefony restent bas niveau, ton hook porte le vocabulaire de
|
|
214
|
+
ton domaine.
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
// frontend/src/useRoomPresence.ts
|
|
218
|
+
import { useNodefonyChannelData, useNodefonyState } from "nodefony/react";
|
|
219
|
+
|
|
220
|
+
export interface Presence {
|
|
221
|
+
online: number;
|
|
222
|
+
typing: string[];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Présence d'un salon : `null` tant qu'aucune trame n'est arrivée. */
|
|
226
|
+
export function useRoomPresence(room: string): {
|
|
227
|
+
presence: Presence | null;
|
|
228
|
+
live: boolean;
|
|
229
|
+
} {
|
|
230
|
+
const live = useNodefonyState() === "connected";
|
|
231
|
+
// Le nom du canal dépend de `room` → l'abonnement suit le changement de salon.
|
|
232
|
+
const presence = useNodefonyChannelData<Presence>(`chat:${room}:presence`);
|
|
233
|
+
return { presence, live };
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 4. L'écran qui consomme
|
|
238
|
+
|
|
239
|
+
```tsx ignore
|
|
240
|
+
// frontend/src/RoomHeader.tsx
|
|
241
|
+
import { useRoomPresence } from "./useRoomPresence";
|
|
242
|
+
|
|
243
|
+
export function RoomHeader({ room }: { room: string }) {
|
|
244
|
+
const { presence, live } = useRoomPresence(room);
|
|
245
|
+
|
|
246
|
+
if (!live) return <p>Temps réel indisponible…</p>;
|
|
247
|
+
if (!presence) return <p>Connexion au salon…</p>;
|
|
248
|
+
return <p>{presence.online} personnes en ligne</p>;
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Ce qu'on observe
|
|
253
|
+
|
|
254
|
+
Sur le fil, un montage produit exactement deux échanges — l'accueil, puis la demande d'abonnement :
|
|
255
|
+
|
|
256
|
+
```text
|
|
257
|
+
← {"jsonrpc":"2.0","method":"realtime:welcome","params":{"identity":{"authenticated":false,…}}}
|
|
258
|
+
→ {"jsonrpc":"2.0","method":"subscribe","params":{"channel":"chat:general:presence"}}
|
|
259
|
+
← {"jsonrpc":"2.0","method":"chat:general:presence","params":{"online":3,"typing":[]}}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Au démontage du **dernier** consommateur du canal, et seulement à ce moment :
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
→ {"jsonrpc":"2.0","method":"unsubscribe","params":{"channel":"chat:general:presence"}}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Ces trames se lisent en direct dans la console temps réel de Studio (`/nodefony/hub`).
|
|
269
|
+
|
|
270
|
+
## 🧰 Les hooks
|
|
271
|
+
|
|
272
|
+
Onze hooks et un fournisseur. La colonne **re-rend quand** est celle qui compte : c'est elle qui
|
|
273
|
+
décide du coût de ton écran.
|
|
274
|
+
|
|
275
|
+
| Hook | Rend | Re-rend quand | Ancre |
|
|
276
|
+
| ------------------------------------- | -------------------------- | --------------------------------------------- | --------------------------- |
|
|
277
|
+
| `NodefonyProvider` | le sous-arbre | quand `client` change | `client/react/index.ts:50` |
|
|
278
|
+
| `useNodefony()` | le client | **jamais** (référence stable) | `client/react/index.ts:67` |
|
|
279
|
+
| `useNodefonyState()` | l'état de connexion | à chaque changement d'état | `client/react/index.ts:149` |
|
|
280
|
+
| `useNodefonyIdentity()` | l'identité, ou `null` | à l'accueil et au logout | `client/react/index.ts:166` |
|
|
281
|
+
| `useNodefonyChannel()` | rien | **jamais** — ton handler décide | `client/react/index.ts:182` |
|
|
282
|
+
| `useNodefonyChannelData<T>()` | la dernière valeur | à chaque message du canal | `client/react/index.ts:210` |
|
|
283
|
+
| `useNodefonyAdaptiveChannel()` | la cadence effective (ms) | à chaque changement de cadence | `client/react/index.ts:244` |
|
|
284
|
+
| `useNodefonyAdaptiveChannelData<T>()` | `{ data, intervalMs }` | à chaque message **ou** changement de cadence | `client/react/index.ts:221` |
|
|
285
|
+
| `useNodefonyChannelStats()` | débit, série, total | ⚠️ une seule fois — voir Pièges | `client/react/index.ts:315` |
|
|
286
|
+
| `useNodefonySyslog()` | un tampon de lignes de log | à chaque lot retenu par le filtre | `client/react/index.ts:373` |
|
|
287
|
+
| `useNodefonyNotifications()` | rien | **jamais** — ton handler décide | `client/react/index.ts:382` |
|
|
288
|
+
| `useNodefonyNoticeLog()` | un tampon de notices | à chaque notice retenue | `client/react/index.ts:407` |
|
|
289
|
+
|
|
290
|
+
### `NodefonyProvider` — publier le client dans l'arbre
|
|
291
|
+
|
|
292
|
+
Le seul composant du subpath. Il prend l'instance créée par ton app et la met à disposition de tout
|
|
293
|
+
son sous-arbre. Tous les hooks ci-dessous **lèvent** s'ils sont montés en dehors
|
|
294
|
+
(`client/react/index.ts:69`) — un oubli se voit immédiatement, il ne se traduit pas par un écran vide.
|
|
295
|
+
|
|
296
|
+
À monter une seule fois, aussi haut que possible. Un second fournisseur imbriqué avec un autre client
|
|
297
|
+
est possible (deux endpoints distincts), mais chaque sous-arbre ne voit alors que le sien.
|
|
298
|
+
|
|
299
|
+
### `useNodefony()` — l'échappatoire
|
|
300
|
+
|
|
301
|
+
Rend le client brut, pour tout ce que les hooks ne couvrent pas : un appel aller-retour
|
|
302
|
+
(`socket.request(…)`), une publication, un flux de réponse. La référence est **stable** — l'utiliser
|
|
303
|
+
n'ajoute aucun rendu.
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
const socket = useNodefony();
|
|
307
|
+
const ask = () => void socket.request("chat:ask", { prompt });
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### `useNodefonyState()` — l'état de la connexion
|
|
311
|
+
|
|
312
|
+
Rend `"disconnected" | "connecting" | "connected" | "reconnecting" | "error"`. Lu via
|
|
313
|
+
`useSyncExternalStore`, donc **sans tearing** en rendu concurrent : le snapshot est une chaîne, la
|
|
314
|
+
comparaison est exacte.
|
|
315
|
+
|
|
316
|
+
Le re-rendu suit `RealtimeClient.setState()` (`client/realtime/RealtimeClient.ts:1400`), qui
|
|
317
|
+
court-circuite si l'état est inchangé — un état stable ne coûte rien, même sous un flux dense.
|
|
318
|
+
|
|
319
|
+
C'est le hook des badges de connexion et des écrans dégradés (« temps réel indisponible »).
|
|
320
|
+
|
|
321
|
+
### `useNodefonyIdentity()` — qui est cette connexion
|
|
322
|
+
|
|
323
|
+
Rend l'identité **annoncée par le serveur** dans la trame d'accueil : `authenticated`,
|
|
324
|
+
`userIdentifier`, `roles`, `scopes` (`RealtimeEventMap.ts:185`). `null` tant qu'aucun accueil n'a été
|
|
325
|
+
reçu ; une fois reçu, un visiteur anonyme vaut `authenticated: false` — jamais `null`.
|
|
326
|
+
|
|
327
|
+
Elle est rafraîchie à chaque (re)connexion par `ingestWelcome()`
|
|
328
|
+
(`client/realtime/RealtimeClient.ts:1022`) et remise à `null` au `disconnect()` volontaire.
|
|
329
|
+
|
|
330
|
+
L'intérêt pratique : basculer anonyme ↔ authentifié **sans appeler la moindre route** `/auth/me`. La
|
|
331
|
+
socket porte déjà l'information.
|
|
332
|
+
|
|
333
|
+
> [!WARNING]
|
|
334
|
+
> Une perte réseau **conserve** la dernière identité jusqu'au prochain accueil. C'est délibéré : sans
|
|
335
|
+
> ça, chaque micro-reconnexion ferait clignoter un écran de connexion. Ne déduis donc pas « déconnecté
|
|
336
|
+
> de la session » d'une identité présente — croise avec `useNodefonyState()`.
|
|
337
|
+
|
|
338
|
+
### `useNodefonyChannel()` — écouter un canal
|
|
339
|
+
|
|
340
|
+
Le primitif : il s'abonne, appelle ton `onMessage` à chaque trame, se désabonne au démontage. Il ne
|
|
341
|
+
rend **rien** et ne provoque **aucun** rendu par lui-même.
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
useNodefonyChannel("orders:new", (payload) => {
|
|
345
|
+
playSound();
|
|
346
|
+
queue.push(payload);
|
|
347
|
+
});
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Deux propriétés à connaître :
|
|
351
|
+
|
|
352
|
+
- **Le handler n'a pas besoin d'être mémoïsé** : il est capturé par référence à chaque rendu
|
|
353
|
+
(`client/react/index.ts:126`). Le passer en fonction fléchée inline est le bon usage.
|
|
354
|
+
- **`deps` est réservé au nom du canal.** Le troisième argument est concaténé aux dépendances de
|
|
355
|
+
l'effet (`client/react/index.ts:185`) : n'y mets que ce qui doit provoquer un **ré-abonnement**.
|
|
356
|
+
|
|
357
|
+
### `useNodefonyChannelData<T>()` — la dernière valeur
|
|
358
|
+
|
|
359
|
+
Le cas le plus courant, et la surcouche la plus mince : garder la dernière valeur reçue dans un état
|
|
360
|
+
local. `null` tant que rien n'est arrivé, sauf si tu fournis une valeur initiale (utilisée au premier
|
|
361
|
+
rendu seulement).
|
|
362
|
+
|
|
363
|
+
```tsx
|
|
364
|
+
const stats = useNodefonyChannelData<Stats>("nodefony:dashboard");
|
|
365
|
+
if (!stats) return <p>en attente…</p>;
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Le composant se re-rend à **chaque** trame. Sur un canal rapide, préfère la variante adaptative
|
|
369
|
+
ci-dessous, ou remonte le hook dans un composant parent minuscule.
|
|
370
|
+
|
|
371
|
+
### `useNodefonyAdaptiveChannel()` — la cadence qui s'ajuste toute seule
|
|
372
|
+
|
|
373
|
+
Même contrat que `useNodefonyChannel()`, mais la cadence du canal est pilotée par un régulateur
|
|
374
|
+
**client** (`bindAdaptiveChannel()`, `client/realtime/AdaptiveRate.ts:239`). Si les trames arrivent
|
|
375
|
+
plus lentement que demandé, la lib se ré-abonne à une cadence plus grossière ; quand le flux
|
|
376
|
+
redevient sain, elle réaccélère par paliers.
|
|
377
|
+
|
|
378
|
+
Le hook **rend la cadence effective en millisecondes** — exactement ce qu'il faut pour l'afficher en
|
|
379
|
+
badge (« mise à jour toutes les 2 s »).
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
const intervalMs = useNodefonyAdaptiveChannel(
|
|
383
|
+
"nodefony:orm:health",
|
|
384
|
+
(payload) => setHealth(payload as Health),
|
|
385
|
+
1000, // cadence désirée, la plus fine
|
|
386
|
+
);
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Réglages disponibles (quatrième argument, dérivés de `AdaptiveRateOptions`,
|
|
390
|
+
`client/realtime/AdaptiveRate.ts:49`) :
|
|
391
|
+
|
|
392
|
+
| Réglage | Défaut | Effet |
|
|
393
|
+
| ------------------ | ------- | ---------------------------------------------------------------------- |
|
|
394
|
+
| `enabled` | `true` | `false` = cadence fixe, aucun régulateur, aucun ré-abonnement |
|
|
395
|
+
| `ladder` | ×2 | Échelle de cadences ; dérivée en doublant jusqu'à `maxMs` |
|
|
396
|
+
| `maxMs` | `60000` | Plafond de l'échelle dérivée |
|
|
397
|
+
| `starvationFactor` | `1.8` | Au-delà de ce multiple de la cadence, on considère qu'on est en famine |
|
|
398
|
+
| `healthyFactor` | `1.25` | En deçà, l'échantillon compte comme sain |
|
|
399
|
+
| `recoveryWindow` | `4` | Nombre d'échantillons sains consécutifs avant de réaccélérer |
|
|
400
|
+
|
|
401
|
+
> [!CAUTION]
|
|
402
|
+
> Réservé aux canaux d'**état** (latest-wins : supervision, métriques). Sur un canal d'**événements**
|
|
403
|
+
> — journal, messages de chat, trames de protocole — ralentir la cadence **perd** des éléments. Ces
|
|
404
|
+
> canaux se regroupent côté serveur, ils ne se décimen't pas.
|
|
405
|
+
|
|
406
|
+
### `useNodefonyAdaptiveChannelData<T>()` — dernière valeur **et** cadence
|
|
407
|
+
|
|
408
|
+
La composition des deux précédents : `{ data, intervalMs }`. C'est le primitif des tuiles de
|
|
409
|
+
supervision — une valeur à afficher, une cadence à annoncer.
|
|
410
|
+
|
|
411
|
+
```tsx
|
|
412
|
+
const { data, intervalMs } = useNodefonyAdaptiveChannelData<Health>(
|
|
413
|
+
"nodefony:orm:health",
|
|
414
|
+
2000,
|
|
415
|
+
);
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### `useNodefonyChannelStats()` — débit et série d'un canal
|
|
419
|
+
|
|
420
|
+
Rend `{ msgCount, lastMessage, rate, series }` pour un canal, calculé par le client à partir des
|
|
421
|
+
trames reçues (`getChannelStats()`, `client/realtime/RealtimeClient.ts:975`). La série glisse sur 32
|
|
422
|
+
points — `STATS_SERIES_POINTS` (`client/realtime/RealtimeClient.ts:131`) —, échantillonnés une fois par seconde par
|
|
423
|
+
`startStatsSampler()` (`client/realtime/RealtimeClient.ts:1139`).
|
|
424
|
+
|
|
425
|
+
> [!WARNING]
|
|
426
|
+
> Ce hook ne se rafraîchit **pas** tout seul après sa première valeur. Le client réutilise le même
|
|
427
|
+
> objet de statistiques et le mute en place (`trackFrame()`, `client/realtime/RealtimeClient.ts:982`) :
|
|
428
|
+
> l'état React reçoit une référence identique, et React court-circuite le rendu. La valeur affichée
|
|
429
|
+
> n'est correcte que si le composant se re-rend pour une autre raison. Pour un VU-mètre fiable,
|
|
430
|
+
> compte toi-même sur `useNodefonyChannel()`.
|
|
431
|
+
|
|
432
|
+
### `useNodefonySyslog()` — le flux de journal
|
|
433
|
+
|
|
434
|
+
Un tampon borné des lignes de journal poussées par le serveur. Il comprend les deux formes du canal :
|
|
435
|
+
le lot groupé `{ logs, dropped }` — c'est la forme normale, produite par `createSyslogBridge()`
|
|
436
|
+
(`realtime/providers.ts:145`) — et l'entrée isolée.
|
|
437
|
+
|
|
438
|
+
| Option | Défaut | Effet |
|
|
439
|
+
| ------------ | ------------------- | ------------------------------------------------------------- |
|
|
440
|
+
| `max` | `500` | Taille du tampon ; au-delà, les plus anciennes lignes sortent |
|
|
441
|
+
| `severities` | toutes | Ne conserver que ces sévérités |
|
|
442
|
+
| `channel` | `"nodefony:syslog"` | Canal source |
|
|
443
|
+
|
|
444
|
+
Le tableau `severities` n'a pas besoin d'être mémoïsé : la dépendance de l'effet est la **chaîne**
|
|
445
|
+
jointe (`sevKey`, `client/react/index.ts:376`), pas le tableau.
|
|
446
|
+
|
|
447
|
+
> [!CAUTION]
|
|
448
|
+
> Le filtre — porté par le socle, pas par le hook — compare la valeur du champ `severity` de chaque entrée aux chaînes fournies
|
|
449
|
+
> (`client/realtime/observe.ts:422`). Or une entrée de journal Nodefony porte sa sévérité **numérique**
|
|
450
|
+
> dans `severity` et son nom dans `severityName` (`Pdu.ts:180`) : filtrer sur `["ERROR"]` ne retient
|
|
451
|
+
> donc rien du flux standard. Filtre côté rendu tant que ce n'est pas aligné, ou lis
|
|
452
|
+
> [Journalisation](syslog.md) pour la forme exacte d'une entrée.
|
|
453
|
+
|
|
454
|
+
### `useNodefonyNotifications()` — les notices, une seule fois
|
|
455
|
+
|
|
456
|
+
S'abonne aux **notices normalisées** du client : fermeture anormale de la socket (code RFC 6455
|
|
457
|
+
interprété par `closeCodeToNotice()`, `client/realtime/notice.ts:67`), erreur serveur poussée,
|
|
458
|
+
rétablissement de la connexion, refus de canal. Chaque notice porte `level`, `message`, `source` et
|
|
459
|
+
un horodatage (`NodefonyNotice`, `client/realtime/notice.ts:20`).
|
|
460
|
+
|
|
461
|
+
```tsx
|
|
462
|
+
// Dans le shell de l'app, UNE fois — sinon chaque incident lève N toasts.
|
|
463
|
+
useNodefonyNotifications((notice) =>
|
|
464
|
+
toast({ type: notice.level, message: notice.message }),
|
|
465
|
+
);
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Le handler est capturé par référence, comme partout : pas de `useCallback`.
|
|
469
|
+
|
|
470
|
+
### `useNodefonyNoticeLog()` — l'historique des incidents
|
|
471
|
+
|
|
472
|
+
Le pendant persistant du précédent : un tampon borné (50 par défaut) des dernières notices,
|
|
473
|
+
filtrable par source (`"realtime" | "api" | "server"`). Utile pour un panneau « incidents » à côté
|
|
474
|
+
des toasts, qui eux disparaissent.
|
|
475
|
+
|
|
476
|
+
Comme pour le journal, la liste `sources` n'a pas besoin d'être mémoïsée (`srcKey`,
|
|
477
|
+
`client/react/index.ts:399`).
|
|
478
|
+
|
|
479
|
+
### Fabriquer un nom de canal cadencé
|
|
480
|
+
|
|
481
|
+
Le subpath réexporte la convention de nommage partagée avec le serveur
|
|
482
|
+
(`client/react/index.ts:31`) — pas un hook, mais utile au même endroit :
|
|
483
|
+
|
|
484
|
+
| Fonction | Ancre | Rôle |
|
|
485
|
+
| ---------------------------------- | ---------------------------- | ---------------------------------------------------------------- |
|
|
486
|
+
| `rateChannel(base, ms?)` | `realtime/channelRate.ts:44` | Construit `base:<ms>`, ou `base` nu si la cadence vaut le défaut |
|
|
487
|
+
| `parseRate(channel, base, bounds)` | `realtime/channelRate.ts:63` | Extrait et **borne** la cadence — usage serveur |
|
|
488
|
+
| `isRateChannel(channel, base)` | `realtime/channelRate.ts:75` | Teste si un canal est une variante cadencée d'une base |
|
|
489
|
+
|
|
490
|
+
Le point important : **un canal = une cadence = un compteur de références**. `nodefony:orm:health:2000` et
|
|
491
|
+
`nodefony:orm:health:5000` sont deux flux distincts, jamais réconciliés.
|
|
492
|
+
|
|
493
|
+
## 🏗️ Cycle de vie d'un abonnement
|
|
494
|
+
|
|
495
|
+
### Le trajet complet, du montage au démontage
|
|
496
|
+
|
|
497
|
+
```mermaid
|
|
498
|
+
sequenceDiagram
|
|
499
|
+
participant C as Composant
|
|
500
|
+
participant H as useNodefonyChannel
|
|
501
|
+
participant R as RealtimeClient
|
|
502
|
+
participant S as Serveur
|
|
503
|
+
C->>H: montage (effet)
|
|
504
|
+
H->>R: on(canal, handler)
|
|
505
|
+
H->>R: subscribe(canal)
|
|
506
|
+
R->>S: 0 → 1 : notification « subscribe »
|
|
507
|
+
Note over R,S: un 2ᵉ composant ⇒ 1 → 2, rien sur le fil
|
|
508
|
+
S-->>R: trames du canal
|
|
509
|
+
R-->>C: handler(payload)
|
|
510
|
+
C->>H: démontage (nettoyage)
|
|
511
|
+
H->>R: dispose() puis unsubscribe(canal)
|
|
512
|
+
R->>S: 1 → 0 : notification « unsubscribe »
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Le nettoyage retire **d'abord** le handler, **puis** décrémente le compteur
|
|
516
|
+
(`client/react/index.ts:134`). L'ordre importe : un message en vol ne peut plus atteindre un composant
|
|
517
|
+
démonté.
|
|
518
|
+
|
|
519
|
+
### Ce qui survit à une coupure
|
|
520
|
+
|
|
521
|
+
Après une perte de connexion, le client se reconnecte avec un délai croissant et **rejoue tous les
|
|
522
|
+
abonnements encore comptés** (`client/realtime/RealtimeClient.ts:1007`). Un composant monté avant la
|
|
523
|
+
coupure retrouve son flux sans une ligne de code — et sans même savoir qu'il y a eu coupure.
|
|
524
|
+
|
|
525
|
+
Corollaire utile : s'abonner **avant** que la socket ne soit ouverte est sûr. Le compteur est posé,
|
|
526
|
+
la notification partira à l'ouverture.
|
|
527
|
+
|
|
528
|
+
Le détail de la boucle de reconnexion, des codes de fermeture définitifs et du battement de cœur vit
|
|
529
|
+
dans [Client isomorphe](client.md) — pas ici.
|
|
530
|
+
|
|
531
|
+
### Le double montage de StrictMode
|
|
532
|
+
|
|
533
|
+
En développement, React monte, démonte, puis remonte chaque composant. Le binding **n'a aucun
|
|
534
|
+
traitement particulier** pour ce cas : il est simplement symétrique.
|
|
535
|
+
|
|
536
|
+
| Étape | Compteur | Sur le fil |
|
|
537
|
+
| -------------------- | -------- | ------------- |
|
|
538
|
+
| 1ᵉʳ montage | 0 → 1 | `subscribe` |
|
|
539
|
+
| Démontage StrictMode | 1 → 0 | `unsubscribe` |
|
|
540
|
+
| Remontage | 0 → 1 | `subscribe` |
|
|
541
|
+
|
|
542
|
+
À retenir :
|
|
543
|
+
|
|
544
|
+
- **Aucune fuite** — le compteur revient exactement à sa valeur, l'écouteur est retiré.
|
|
545
|
+
- **Un aller-retour visible** sur le fil, uniquement en développement. Il disparaît en production, où
|
|
546
|
+
React ne double pas le montage.
|
|
547
|
+
- **Si un autre consommateur tient déjà le canal** (un store, un autre écran), le compteur ne
|
|
548
|
+
redescend jamais à zéro : rien du tout ne passe sur le fil.
|
|
549
|
+
- **L'état local repart de zéro** : un `useNodefonyChannelData` réaffiche `null` jusqu'à la trame
|
|
550
|
+
suivante. Sur un canal lent, l'écran semble « vide » plus longtemps en développement qu'en
|
|
551
|
+
production.
|
|
552
|
+
|
|
553
|
+
## ⚡ Temps réel « calme » — ne pas faire clignoter l'écran
|
|
554
|
+
|
|
555
|
+
Un flux temps réel naïf produit un écran qui tremble : chiffres qui sautent, listes qui se
|
|
556
|
+
réordonnent, texte illisible. La responsabilité est **partagée** entre la lib et ton composant.
|
|
557
|
+
|
|
558
|
+
### Ce que les hooks font pour toi
|
|
559
|
+
|
|
560
|
+
- **La cadence s'adapte à la charge.** Le régulateur AIMD ralentit le canal sous pression et
|
|
561
|
+
réaccélère par paliers, avec une bande morte qui empêche l'oscillation
|
|
562
|
+
(`client/realtime/AdaptiveRate.ts:239`).
|
|
563
|
+
- **Le journal arrive par lots, pas ligne à ligne.** Le pont serveur regroupe les entrées d'une
|
|
564
|
+
fenêtre en une seule trame et compte les omissions — `createSyslogBridge()`
|
|
565
|
+
(`realtime/providers.ts:145`). `useNodefonySyslog()` consomme ce format nativement.
|
|
566
|
+
- **L'état ne re-rend qu'aux transitions.** `useNodefonyState()` compare un snapshot primitif ; un
|
|
567
|
+
flux dense sur une connexion stable ne provoque **aucun** rendu supplémentaire.
|
|
568
|
+
- **Les tampons sont bornés.** 500 lignes de journal, 50 notices, 32 points de série : la mémoire
|
|
569
|
+
d'un écran laissé ouvert une nuit reste plate.
|
|
570
|
+
- **Le ré-abonnement n'est pas déclenché par un changement de handler**, donc le simple fait de
|
|
571
|
+
re-rendre ne rejoue jamais l'effet.
|
|
572
|
+
|
|
573
|
+
### Ce qui reste à ta charge
|
|
574
|
+
|
|
575
|
+
- **Descendre le hook au plus près de ce qui change.** Un `useNodefonyChannelData` dans une page
|
|
576
|
+
entière re-rend la page entière ; dans un composant de trois lignes, il ne re-rend que ces trois
|
|
577
|
+
lignes.
|
|
578
|
+
- **Mémoïser le calcul dérivé**, jamais le handler :
|
|
579
|
+
|
|
580
|
+
```tsx
|
|
581
|
+
const series = useNodefonyChannelData<Point[]>("metrics:cpu");
|
|
582
|
+
const path = React.useMemo(() => toSvgPath(series ?? []), [series]);
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
- **Donner une clé stable aux listes.** Un index de tableau sur un flux qui s'évince par le haut
|
|
586
|
+
remonte l'arbre entier à chaque lot — utilise l'identifiant de la ligne.
|
|
587
|
+
- **Choisir la bonne cadence.** Un affichage humain n'a pas besoin de plus de 1 à 2 mises à jour par
|
|
588
|
+
seconde ; demander 100 ms coûte cher des deux côtés du fil pour un résultat illisible.
|
|
589
|
+
- **Amortir l'affichage, pas le flux.** Pour un compteur nerveux, arrondis ou lisse la valeur au
|
|
590
|
+
rendu plutôt que de jeter des trames.
|
|
591
|
+
|
|
592
|
+
## 🔐 Rôles et identité côté client — ergonomie, jamais garantie
|
|
593
|
+
|
|
594
|
+
`useNodefonyIdentity()` rend des rôles et des scopes, et le subpath `nodefony/roles` fournit de quoi
|
|
595
|
+
les tester : `hasRole()` (`client/roles/roles.ts:19`), `hasAnyRole()`, `hasAllRoles()`, et `RoleSet`
|
|
596
|
+
(`client/roles/roles.ts:69`) pour des contrôles répétés en temps constant.
|
|
597
|
+
|
|
598
|
+
Leur seul usage légitime est **l'ergonomie** :
|
|
599
|
+
|
|
600
|
+
- masquer une entrée de menu qui mènerait à un écran refusé ;
|
|
601
|
+
- griser un bouton dont l'action serait rejetée ;
|
|
602
|
+
- afficher un écran de connexion au lieu d'un tableau vide.
|
|
603
|
+
|
|
604
|
+
> [!CAUTION]
|
|
605
|
+
> Un contrôle de rôle côté navigateur n'est **pas** une mesure de sécurité. Les rôles arrivent dans
|
|
606
|
+
> une trame, et une trame se falsifie. L'autorité est **entièrement** serveur : le pare-feu décide,
|
|
607
|
+
> et un refus revient explicitement en `realtime:denied`, qu'on capte via `onDenied()`
|
|
608
|
+
> (`client/realtime/RealtimeClient.ts:386`) pour réagir canal par canal. Ne protège jamais une donnée
|
|
609
|
+
> en te contentant de ne pas afficher le composant qui l'affiche.
|
|
610
|
+
|
|
611
|
+
La règle pratique : **cache pour le confort, refuse au serveur**. Voir la
|
|
612
|
+
[sécurité du temps réel](../../packages/@nodefony/realtime/docs/securite.md) pour la moitié qui fait
|
|
613
|
+
autorité.
|
|
614
|
+
|
|
615
|
+
## 📡 Observabilité — Studio
|
|
616
|
+
|
|
617
|
+
Studio est le consommateur de référence de ces hooks, et sert de banc d'essai visuel :
|
|
618
|
+
|
|
619
|
+
- **Console temps réel** (`/nodefony/hub`) — les trames dans les deux sens, abonnements compris. La
|
|
620
|
+
page la plus utile pour vérifier qu'un hook s'abonne à ce qu'on croit, et une seule fois.
|
|
621
|
+
- **Jumeau vivant** (`/nodefony/twin`) — la topologie animée par les mêmes canaux.
|
|
622
|
+
- **Journal** (`/nodefony/logs`) — le flux `nodefony:syslog` en direct.
|
|
623
|
+
|
|
624
|
+
Ce que ces écrans montrent, une app tierce l'obtient avec les mêmes hooks : rien n'est réservé à
|
|
625
|
+
Studio.
|
|
626
|
+
|
|
627
|
+
## ⚠️ Pièges (symptôme → cause → correction)
|
|
628
|
+
|
|
629
|
+
| Symptôme | Cause | Correction |
|
|
630
|
+
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
631
|
+
| `useNodefony() doit être utilisé dans un <NodefonyProvider>` | Hook monté hors du sous-arbre du fournisseur (`client/react/index.ts:69`) | Remonter `NodefonyProvider` au shell, au-dessus du routeur |
|
|
632
|
+
| `Module 'nodefony' has no exported member 'RealtimeClient'` | Condition d'export `browser` inactive dans le `tsconfig.json` de l'app | Importer depuis `nodefony/client`, ou ajouter `customConditions: ["browser"]` |
|
|
633
|
+
| Rien n'arrive et l'état reste `disconnected` | Les hooks s'abonnent mais ne connectent pas | Appeler `socket.connect()` une fois (`client/realtime/RealtimeClient.ts:311`) |
|
|
634
|
+
| Un `subscribe`/`unsubscribe`/`subscribe` par montage | StrictMode double le montage ; le comptage est symétrique | Comportement attendu en développement ; absent en production |
|
|
635
|
+
| Le débit de `useNodefonyChannelStats()` reste figé | `trackFrame()` mute le même objet de stats (`client/realtime/RealtimeClient.ts:982`) → React court-circuite | Compter soi-même via `useNodefonyChannel()` |
|
|
636
|
+
| `useNodefonySyslog({ severities })` ne rend rien | Le filtre compare un champ numérique à des noms (`client/react/index.ts:346`) | Filtrer au rendu sur `severityName` (`Pdu.ts:180`) |
|
|
637
|
+
| L'abonnement se refait à chaque frappe | Le nom du canal est recalculé et passé dans `deps` | Ne mettre dans `deps` que ce qui doit vraiment ré-abonner |
|
|
638
|
+
| Changer un réglage AIMD ne change rien | Les options sont capturées par référence (`client/react/index.ts:192`) | Passer par `desiredMs`/`enabled`, ou ajouter la valeur aux `deps` |
|
|
639
|
+
| Toasts en double, voire en triple | `useNodefonyNotifications` monté dans plusieurs composants | Un seul montage, au shell (`client/react/index.ts:382`) |
|
|
640
|
+
| Une exception dans un handler disparaît sans trace | Le dispatch avale les erreurs de handler (`client/realtime/RealtimeClient.ts:1101`) | Envelopper le corps du handler dans son propre `try`/`catch` |
|
|
641
|
+
| Un écran perd son flux quand un autre se démonte | N'arrive plus : le compteur vit dans le client (`client/realtime/RealtimeClient.ts:543`) | Rien à faire — vérifier qu'on n'appelle pas `unsubscribe` à la main |
|
|
642
|
+
| Un canal cadencé ne renvoie jamais rien | Le serveur n'a pas déclaré de bornes pour ce canal | Vérifier la résolution serveur (`realtime/channelRate.ts:63`) |
|
|
643
|
+
| L'écran de connexion clignote à chaque micro-coupure | L'identité est conservée pendant une perte réseau, pas pendant un logout | Croiser `useNodefonyIdentity()` avec `useNodefonyState()` |
|
|
644
|
+
|
|
645
|
+
## 🧪 Tests & couverture
|
|
646
|
+
|
|
647
|
+
Il faut être précis sur ce qui est prouvé, parce que le partage n'est pas intuitif : **la logique
|
|
648
|
+
testée est celle du client, pas celle des hooks**.
|
|
649
|
+
|
|
650
|
+
Ce qui **est** couvert — les invariants dont les hooks dépendent entièrement :
|
|
651
|
+
|
|
652
|
+
- **Le comptage de références** : un seul `subscribe` pour N consommateurs, `unsubscribe` au dernier
|
|
653
|
+
seulement, et le rejeu complet des abonnements après reconnexion.
|
|
654
|
+
- **Le dispatch** : ordre d'ingestion de l'accueil puis des handlers, isolation des exceptions de
|
|
655
|
+
handler, canal générique.
|
|
656
|
+
- **L'identité** : présence après accueil, anonyme jamais `null`, remise à zéro au `disconnect()`.
|
|
657
|
+
- **Les notices** : interprétation des codes de fermeture, distinction transitoire/définitif, refus de
|
|
658
|
+
canal.
|
|
659
|
+
- **Le transport et le ping** : ouverture, fermeture, mesure d'aller-retour.
|
|
660
|
+
- **Les rôles** : `hasRole`, `hasAnyRole`, `hasAllRoles`, `RoleSet`.
|
|
661
|
+
|
|
662
|
+
Ce qui **manque**, et qu'il faut savoir avant de s'appuyer sur cette page :
|
|
663
|
+
|
|
664
|
+
- **Aucun test de rendu React.** Il n'existe pas de suite montant un composant sous
|
|
665
|
+
`NodefonyProvider` — ni bibliothèque de test de rendu dans le dépôt. Le cycle montage/démontage, le
|
|
666
|
+
comportement en StrictMode et l'absence de re-rendu superflu sont raisonnés sur le code, pas
|
|
667
|
+
exercés.
|
|
668
|
+
- **Cinq hooks n'ont aucun consommateur** dans le dépôt : `useNodefonyIdentity`,
|
|
669
|
+
`useNodefonyChannelStats`, `useNodefonySyslog`, `useNodefonyNotifications` et
|
|
670
|
+
`useNodefonyNoticeLog`. C'est précisément là que se logent les deux défauts signalés plus haut — un
|
|
671
|
+
code que personne n'exécute n'est pas un code prouvé.
|
|
672
|
+
- **Aucun banc de charge côté interface** : le coût d'un flux dense sur un arbre React n'est pas mesuré.
|
|
673
|
+
|
|
674
|
+
Couverture : `npm run coverage` dans `src/nodefony`.
|
|
675
|
+
|
|
676
|
+
## 🔗 Pour aller plus loin
|
|
677
|
+
|
|
678
|
+
- ⬆️ **Retour au hub** : [@nodefony/core — vue d'ensemble](index.md) · [Toute la documentation](../../../docs/index.md)
|
|
679
|
+
- 🧭 **Pages sœurs** : [Client isomorphe](client.md) — la socket, le transport, la reconnexion, les
|
|
680
|
+
rôles · [Journalisation](syslog.md) — la forme d'une entrée de journal · [Service](service.md) ·
|
|
681
|
+
[Contexte de requête](request-context.md) · [Kernel](kernel.md)
|
|
682
|
+
- Le vocabulaire commun aux deux bords du fil → [Vocabulaire de la socket](../../packages/@nodefony/realtime/docs/vocabulaire.md)
|
|
683
|
+
- Le module serveur qui pousse les canaux → [@nodefony/realtime](../../packages/@nodefony/realtime/docs/index.md)
|
|
684
|
+
- Un chat complet, du contrôleur à l'écran React → [Cookbook chat](../../packages/@nodefony/realtime/docs/cookbook-chat.md)
|
|
685
|
+
- Qui sert et reconstruit ton interface → [@nodefony/frontend](../../packages/@nodefony/frontend/docs/index.md)
|
|
686
|
+
- Qui décide vraiment des droits → [Sécurité du temps réel](../../packages/@nodefony/realtime/docs/securite.md)
|