@nodefony/realtime 10.0.0-alpha.8 → 10.0.0-beta.1

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.
@@ -127,7 +127,7 @@ vers un autre service — et le consommateur ne voit jamais la différence
127
127
  **`contrôleur` est le même mot qu'en HTTP.** Un endpoint temps réel est un contrôleur qui étend
128
128
  `RealtimeController` (`RealtimeController.ts:144`) et porte une route WebSocket : HTTP et WebSocket
129
129
  vivent dans le **même contexte de contrôleur**. C'est ce qui permet au pont `api.request`
130
- (`RealtimeController.realtimeApiRequest()`, `RealtimeController.ts:219`) de rejouer sur la socket
130
+ (`RealtimeController.realtimeApiRequest()`, `RealtimeController.ts:276`) de rejouer sur la socket
131
131
  **la même action** que celle servie en REST.
132
132
 
133
133
  ## 🚀 Démarrage rapide — les mots en situation
@@ -229,7 +229,7 @@ Un **tuyau bidirectionnel nommé**, multiplexé sur la connexion : `"chat:room-4
229
229
  `"nodefony:orm:health"`, `"nodefony:socket"`. Convention de nommage par `:` (espace de noms, puis
230
230
  précision). Ce n'est pas une classe — c'est une **chaîne de caractères indexée par le hub**.
231
231
 
232
- `RealtimeHub.subscribe()` (`RealtimeHub.ts:388`) l'indexe ; `IRealtimeSocket.subscribe()`
232
+ `RealtimeHub.subscribe()` (`RealtimeHub.ts:462`) l'indexe ; `IRealtimeSocket.subscribe()`
233
233
  (`IRealtimeSocket.ts:132`) le demande. Plusieurs canaux cohabitent sur **une** connexion : c'est le
234
234
  multiplexage.
235
235
 
@@ -269,8 +269,8 @@ Un handler qui lève une erreur rend un `-32603` **générique** ; seule une `Rp
269
269
  ### `canal entrant` (inbound) — le client pousse
270
270
 
271
271
  Un canal où le **client a le droit d'émettre** vers le serveur. Défaut sûr : **aucun**. Un canal
272
- n'accepte d'entrée que déclaré explicitement, par `@RealtimeInbound` (`realtimeDecorators.ts:30`) ou
273
- par l'override `realtimeInbound()` (`RealtimeController.ts:205`).
272
+ n'accepte d'entrée que déclaré explicitement, par `@RealtimeInbound` (`realtimeDecorators.ts:231`) ou
273
+ par l'override `realtimeInbound()` (`RealtimeController.ts:262`).
274
274
 
275
275
  Le handler reçoit `(params, reply)` — `params` vient du réseau, donc **jamais fiable** :
276
276
  `RealtimeInboundHandler` (`IRealtimeController.ts:16`).
@@ -297,7 +297,7 @@ importable **sans** aucune dépendance serveur, ce qui est la condition de l'iso
297
297
  (`ServerRealtimeSocket.ts:223`) : un service métier tient un handle et publie **comme une page
298
298
  front**. Une différence assumée : `request()` n'y est pas supporté — au-dessus du hub il n'y a pas
299
299
  **un** pair mais N clients. Pour un appel serveur → un client précis, c'est `requestClient()`
300
- (`RealtimeController.ts:279`).
300
+ (`RealtimeController.ts:329`).
301
301
 
302
302
  ### `accueil` (welcome) — la première frame
303
303
 
@@ -335,7 +335,7 @@ handshake, jamais renégociée par frame.
335
335
  ### `hub` — le broker du process
336
336
 
337
337
  Le **standard téléphonique** du pod : il tient la table « canal → abonnés locaux » et diffuse. Un
338
- process = un hub, obtenu par `getRealtimeHub()` (`RealtimeHub.ts:1435`). Il ne connaît **ni** les
338
+ process = un hub, obtenu par `getRealtimeHub()` (`RealtimeHub.ts:1451`). Il ne connaît **ni** les
339
339
  contrôleurs, **ni** le métier : ce sont les providers qui portent les dépendances.
340
340
 
341
341
  `RealtimeHub` (`RealtimeHub.ts:213`). ⚠️ « hub » désigne **toujours** le serveur ; ce que tient le
@@ -347,7 +347,7 @@ L'action de diffuser : une charge publiée sur un canal part vers **tous** les s
347
347
  localement. Une connexion fautive ne casse pas la diffusion aux autres — chaque livraison est isolée.
348
348
 
349
349
  `RealtimeHub.publish()` (`RealtimeHub.ts:604`) pour le chemin complet, `publishLocal()`
350
- (`RealtimeHub.ts:549`) pour la diffusion **strictement locale** (voie d'entrée du backplane).
350
+ (`RealtimeHub.ts:623`) pour la diffusion **strictement locale** (voie d'entrée du backplane).
351
351
 
352
352
  ### `sink` — le point de livraison d'une connexion
353
353
 
@@ -371,7 +371,7 @@ Le modèle de coût du module : là où une implémentation naïve crée un tick
371
371
  Nodefony en crée **un par canal et par pod** et se contente d'ajouter un sink par abonné. Mille
372
372
  spectateurs d'un tableau de bord coûtent un timer, pas mille.
373
373
 
374
- `RealtimeHub.subscribe()` (`RealtimeHub.ts:388`).
374
+ `RealtimeHub.subscribe()` (`RealtimeHub.ts:462`).
375
375
 
376
376
  ### `canal passif` — écouter n'est pas posséder
377
377
 
@@ -395,7 +395,7 @@ Un canal dont la fabrique est déclarée par un module bas niveau (le journal d'
395
395
  qui devient servable par **n'importe quel** endpoint, présent ou futur, sans qu'aucun contrôleur ne
396
396
  le connaisse. Consulté seulement quand la fabrique du contrôleur a dit « inconnu ».
397
397
 
398
- `RealtimeHub.registerSystemChannel()` (`RealtimeHub.ts:1281`).
398
+ `RealtimeHub.registerSystemChannel()` (`RealtimeHub.ts:1297`).
399
399
 
400
400
  ### `canal broadcast` — celui qui traverse le backplane
401
401
 
@@ -403,7 +403,7 @@ Un canal **déclaré** comme franchissant la frontière du process : chat, prés
403
403
  déclaration se fait par **préfixe**, ce qui couvre les variantes de cadence (`chat:` couvre
404
404
  `chat:room-42:1000`).
405
405
 
406
- `RealtimeHub.markBroadcastChannel()` (`RealtimeHub.ts:594`), déclaré côté contrôleur par
406
+ `RealtimeHub.markBroadcastChannel()` (`RealtimeHub.ts:668`), déclaré côté contrôleur par
407
407
  `@RealtimeBroadcast` (`realtimeDecorators.ts:342`).
408
408
 
409
409
  ### `canal instance-local` — le défaut
@@ -420,7 +420,7 @@ La classe de base d'un endpoint : elle porte tout le protocole (handshake, accue
420
420
  des frames, cycle de vie des canaux) et ne laisse au métier que ses canaux et ses actions.
421
421
 
422
422
  `RealtimeController` (`RealtimeController.ts:144`), point d'entrée `handleRealtime()`
423
- (`RealtimeController.ts:249`). C'est un **contrôleur** au sens habituel de Nodefony : la même classe
423
+ (`RealtimeController.ts:299`). C'est un **contrôleur** au sens habituel de Nodefony : la même classe
424
424
  peut porter des routes HTTP.
425
425
 
426
426
  ### `service realtime` — la façade d'injection
@@ -437,8 +437,8 @@ L'option qui expose la méthode `api.request { path }` : la connexion rejoue **l
437
437
  contrôleur** que celle servie en REST, avec **la même garde**. Le pont n'atteint que les routes qui
438
438
  déclarent explicitement le transport WebSocket — aucun contournement possible.
439
439
 
440
- `realtimeApiRequest()` (`RealtimeController.ts:219`), mise en œuvre `invokeApiRequest()`
441
- (`RealtimeController.ts:878`). Désactivé par défaut.
440
+ `realtimeApiRequest()` (`RealtimeController.ts:276`), mise en œuvre `invokeApiRequest()`
441
+ (`RealtimeController.ts:949`). Désactivé par défaut.
442
442
 
443
443
  ## 🔌 Le protocole et le transport — ce qui passe sur le fil
444
444
 
@@ -469,14 +469,14 @@ Client et serveur sont des **pairs** : classer une frame, router, corréler les
469
469
  travail des deux côtés. Nodefony l'écrit **une seule fois** ; chaque côté l'entoure de son transport
470
470
  et de ses handlers. Aucune dépendance Node — le même fichier tourne dans le navigateur.
471
471
 
472
- `JsonRpcPeer` (`JsonRpcPeer.ts:271`), contrat `IRealtimePeer` (`JsonRpcPeer.ts:213`).
472
+ `JsonRpcPeer` (`JsonRpcPeer.ts:280`), contrat `IRealtimePeer` (`JsonRpcPeer.ts:213`).
473
473
 
474
474
  ### `dispatch` — classer puis router
475
475
 
476
476
  Le geste du pair sur une frame entrante : décider de sa nature, trouver le handler, l'appeler,
477
477
  renvoyer la réponse s'il en faut une. Ce n'est pas une méthode publique — c'est un **moment**, et
478
478
  c'est précisément là que se greffe le [verrou de frame](#verrou-de-frame--la-décision-par-frame),
479
- par le crochet `beforeDispatch` (`JsonRpcPeer.ts:172`).
479
+ par le crochet `beforeDispatch` (`JsonRpcPeer.ts:192`).
480
480
 
481
481
  ### `transport` — la couche octets
482
482
 
@@ -534,7 +534,7 @@ Le **fond de panier** d'un rack : la carte qui relie toutes les autres. Ici, le
534
534
  publications d'un process aux autres. Un contrat volontairement minuscule — `publish`, `onMessage`,
535
535
  `start`, `stop`, `describe` — parce que tout ce qui est riche appartient au hub.
536
536
 
537
- `IBackplane` (`IBackplane.ts:75`), message `IBackplaneMessage` (`IBackplane.ts:51`), branchement
537
+ `IBackplane` (`IBackplane.ts:107`), message `IBackplaneMessage` (`IBackplane.ts:51`), branchement
538
538
  `RealtimeHub.setBackplane()` (`RealtimeHub.ts:714`).
539
539
 
540
540
  > [!TIP]
@@ -630,7 +630,7 @@ l'authenticator tourne et que l'identité est figée. Tout ce qui coûte cher se
630
630
  frame.
631
631
 
632
632
  DTO neutre `IRealtimeHandshake` (`IRealtimeHandshake.ts:14`) — en-têtes, cookies, URL, origine,
633
- sous-protocoles. Traitement dans `onHandshake()` (`RealtimeController.ts:328`).
633
+ sous-protocoles. Traitement dans `onHandshake()` (`RealtimeController.ts:374`).
634
634
 
635
635
  ### `authenticator` — du handshake à l'identité
636
636
 
@@ -639,7 +639,7 @@ La stratégie qui transforme une poignée de main en identité : `supports` (est
639
639
  HTTP — un seul modèle mental pour les deux transports.
640
640
 
641
641
  `IRealtimeAuthenticator` (`IRealtimeAuthenticator.ts:24`), enregistrement
642
- `RealtimeHub.useAuthenticator()` (`RealtimeHub.ts:927`).
642
+ `RealtimeHub.useAuthenticator()` (`RealtimeHub.ts:943`).
643
643
 
644
644
  ### `matcher` — qui capture quoi
645
645
 
@@ -647,7 +647,7 @@ Le sélecteur (motif d'URL, hôte optionnel) qui décide **quel** authenticator
647
647
  **premier** qui capture gagne : on enregistre donc du plus spécifique au plus général.
648
648
 
649
649
  `IRealtimeAuthenticatorMatcher` (`IRealtimeAuthenticatorMatcher.ts:25`), résolution
650
- `resolveAuthenticator()` (`RealtimeHub.ts:945`).
650
+ `resolveAuthenticator()` (`RealtimeHub.ts:961`).
651
651
 
652
652
  ### `jeton` (token) — l'identité figée
653
653
 
@@ -664,7 +664,7 @@ Les exigences déclarées d'un canal : authentifié, rôles, scopes. Elles s'att
664
664
  canal, pas à la méthode qui l'implémente — parce que c'est le nom que le pare-feu résout.
665
665
 
666
666
  `IChannelPolicy` (`IChannelPolicy.ts:20`), déclaration par `@RealtimeChannel`
667
- (`realtimeDecorators.ts:192`), résolution `resolveChannelPolicy()` (`RealtimeHub.ts:1212`).
667
+ (`realtimeDecorators.ts:192`), résolution `resolveChannelPolicy()` (`RealtimeHub.ts:1228`).
668
668
 
669
669
  ### `verrou de frame` — la décision par frame
670
670
 
@@ -672,8 +672,8 @@ La fonction qui répond « cette frame passe-t-elle ? » à partir du jeton **d
672
672
  **Synchrone par doctrine** : attendre une réponse distante à chaque frame sérialiserait le flux d'une
673
673
  connexion. Un contrôle qui doit interroger le réseau se fait au handshake, pas ici.
674
674
 
675
- `FrameAuthorizer` (`RealtimeHub.ts:39`), pose `setFrameAuthorizer()` (`RealtimeHub.ts:1023`), appel
676
- `runAuthorizer()` (`RealtimeHub.ts:1312`).
675
+ `FrameAuthorizer` (`RealtimeHub.ts:39`), pose `setFrameAuthorizer()` (`RealtimeHub.ts:1039`), appel
676
+ `runAuthorizer()` (`RealtimeHub.ts:1328`).
677
677
 
678
678
  ### `contrôle d'origine` — la défense d'ouverture
679
679
 
@@ -681,7 +681,7 @@ Le contrôle de l'en-tête `Origin` à l'ouverture (RFC 6455 §10.2) : un site t
681
681
  ouvrir une connexion authentifiée dans le dos de l'utilisateur. Correspondance **exacte**, aucun
682
682
  caractère générique.
683
683
 
684
- `OriginGuard` (`RealtimeHub.ts:25`), configuration `csrf.checkOrigin` (`config.ts:181`).
684
+ `OriginGuard` (`RealtimeHub.ts:33`), configuration `csrf.checkOrigin` (`config.ts:255`).
685
685
 
686
686
  ### `révocation` — la connexion qui survit à sa session
687
687
 
@@ -689,7 +689,7 @@ Le problème que ce mot nomme : une connexion ouverte pourrait survivre à la se
689
689
  autorisée, puisque le verrou de frame ne relit rien. Un contrôle périodique referme l'écart en
690
690
  re-validant les identités révocables et en fermant celles qui ne valent plus.
691
691
 
692
- `registerRevocable()` (`RealtimeHub.ts:778`), `revalidateRevocable()` (`RealtimeHub.ts:810`), période
692
+ `registerRevocable()` (`RealtimeHub.ts:794`), `revalidateRevocable()` (`RealtimeHub.ts:826`), période
693
693
  `REVOCATION_REVALIDATE_MS` (`RealtimeHub.ts:111`). Une re-validation en erreur **ferme** — jamais
694
694
  l'inverse.
695
695
 
@@ -708,7 +708,7 @@ Le signal émis sur les événements protocolaires qui méritent une trace : fra
708
708
  refusée, méthode inconnue, erreur interne. Émis sans attente, avec le pair — ce qui permet de
709
709
  retrouver **qui** a été refusé, pas seulement d'où venait le paquet.
710
710
 
711
- `FrameAuditReason` (`JsonRpcPeer.ts:143`), crochet `onFrameAudit` (`JsonRpcPeer.ts:190`).
711
+ `FrameAuditReason` (`JsonRpcPeer.ts:155`), crochet `onFrameAudit` (`JsonRpcPeer.ts:210`).
712
712
 
713
713
  ### `seam` — le point de greffe
714
714
 
@@ -716,8 +716,8 @@ Littéralement une **couture** : un point prévu dans une couche basse pour qu'u
716
716
  greffe du comportement **sans modifier la couche basse**. Le module en expose cinq, et c'est ce qui
717
717
  permet à la couche sécurité de se brancher sans qu'aucune ligne de realtime ne la connaisse.
718
718
 
719
- Les deux du protocole sont `beforeDispatch` (`JsonRpcPeer.ts:172`) et `onFrameAudit`
720
- (`JsonRpcPeer.ts:190`) ; les trois du hub sont l'authenticator, le matcher et le contrôle d'origine.
719
+ Les deux du protocole sont `beforeDispatch` (`JsonRpcPeer.ts:192`) et `onFrameAudit`
720
+ (`JsonRpcPeer.ts:210`) ; les trois du hub sont l'authenticator, le matcher et le contrôle d'origine.
721
721
 
722
722
  → [Sécurité](./securite.md) pour le détail de chacun.
723
723
 
@@ -728,7 +728,7 @@ ressources ; sans borne, une seule connexion peut les épuiser. Au-delà, l'abon
728
728
  client en est informé.
729
729
 
730
730
  `limits.maxChannelsPerConnection` (`config.ts:142`), pose `setMaxChannelsPerConnection()`
731
- (`RealtimeHub.ts:979`).
731
+ (`RealtimeHub.ts:995`).
732
732
 
733
733
  ## 📡 L'observabilité — ce que la socket dit d'elle-même
734
734
 
@@ -747,7 +747,7 @@ L'oscilloscope du module : « voici mon état, maintenant ». Canaux et abonnés
747
747
  livraisons, connexions, octets, back-pressure, carte d'identité du backplane. Lecture **pure**, sans
748
748
  allocation sur le chemin chaud.
749
749
 
750
- `RealtimeHub.probe()` (`RealtimeHub.ts:775`) rend un `IRealtimeProbe` (`IRealtimeProbe.ts:61`).
750
+ `RealtimeHub.probe()` (`RealtimeHub.ts:865`) rend un `IRealtimeProbe` (`IRealtimeProbe.ts:61`).
751
751
 
752
752
  > [!WARNING]
753
753
  > `IRealtimeProbe` est la **forme des données**, pas une interface à implémenter avec une méthode
@@ -769,8 +769,8 @@ décide de rien. Les seuils d'ACTION, eux, sont des réglages : `websocket.maxBa
769
769
  Une connexion dont le back-pressure dépasse le seuil de comptage. C'est une **métrique**, pas une
770
770
  sanction : le seuil de comptage se règle indépendamment des seuils d'action.
771
771
 
772
- `slowConsumer.bytes` (`config.ts:84`), champ `backpressure.slowConsumers`
773
- (`IRealtimeProbe.ts:81`).
772
+ `slowConsumer.bytes` (`config.ts:121`), champ `backpressure.slowConsumers`
773
+ (`IRealtimeProbe.ts:102`).
774
774
 
775
775
  ### `compteurs de canal` — mesurés à l'arrivée
776
776
 
@@ -794,20 +794,20 @@ Le producteur qui expose la sonde sous `/nodefony/realtime/api/health`, selon la
794
794
  routage des administrations de modules. C'est de l'**auto-observabilité** : la socket se regarde
795
795
  elle-même par le même chemin que les autres modules.
796
796
 
797
- `createRealtimeAdminApi()` (`RealtimeAdminApi.ts:91`), construction `buildOwnHealth()`
797
+ `createRealtimeAdminApi()` (`RealtimeAdminApi.ts:98`), construction `buildOwnHealth()`
798
798
  (`RealtimeAdminApi.ts:52`).
799
799
 
800
800
  ## ⚠️ Pièges — les faux-amis du vocabulaire
801
801
 
802
802
  | Symptôme | Cause — le mot pris pour un autre | Correction |
803
803
  | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
804
- | « Je suis abonné mais je ne reçois rien » | `subscribe` confondu avec `on` : le flux est demandé, aucun écouteur ne le lit | Les deux : `subscribe(canal)` **et** `on(canal, handler)` (`IRealtimeSocket.ts:141`) |
804
+ | « Je suis abonné mais je ne reçois rien » | `subscribe` confondu avec `on` : le flux est demandé, aucun écouteur ne le lit | Les deux : `subscribe(canal)` **et** `on(canal, handler)` (`IRealtimeSocket.ts:131`) |
805
805
  | « Ça marche en local, plus rien dès qu'on passe à plusieurs pods » | canal resté **instance-local** — le défaut. Traverser le process est une capacité qu'on **demande** | Déclarer le préfixe dans `@RealtimeBroadcast` (`realtimeDecorators.ts:342`) |
806
- | « Le client publie, le serveur ignore » | canal non déclaré **entrant**. Un client ne peut rien pousser tant qu'aucun handler n'existe | `@RealtimeInbound("mon:canal")` (`realtimeDecorators.ts:182`) |
806
+ | « Le client publie, le serveur ignore » | canal non déclaré **entrant**. Un client ne peut rien pousser tant qu'aucun handler n'existe | `@RealtimeInbound("mon:canal")` (`realtimeDecorators.ts:231`) |
807
807
  | Deux déploiements se mélangent sur un même serveur Redis | pas de **cloison** — le numéro de base ne cloisonne pas le pub/sub | Poser `backplane.namespace` (`config.ts:59`) |
808
808
  | Le fan-out disparaît entre conteneurs identiques | **origine** dérivée du seul identifiant de processus : deux conteneurs sont tous deux le n° 1, l'anti-écho avale tout | `resolveBackplaneOriginId()` (`originId.ts:24`) dérive du pod ou de l'hôte |
809
809
  | Deux tickers pour le même tableau de bord | **cadence** différente = **canal** différent, jamais réconcilié | Fabriquer le nom via `rateChannel()` (`channelRate.ts:44`) des deux côtés |
810
- | Un canal se croit protégé mais laisse tout passer | **politique** déclarée sans **verrou de frame** posé pour la faire respecter | Le hub le détecte et avertit : `hasUnenforcedChannelPolicies()` (`RealtimeHub.ts:1101`) |
810
+ | Un canal se croit protégé mais laisse tout passer | **politique** déclarée sans **verrou de frame** posé pour la faire respecter | Le hub le détecte et avertit : `hasUnenforcedChannelPolicies()` (`RealtimeHub.ts:1117`) |
811
811
  | Une connexion garde ses flux après une déconnexion applicative | le **verrou de frame** ne relit rien : par construction, il ne voit pas la session mourir | Inscrire l'identité au registre de **révocation** (`RealtimeHub.ts:433`) |
812
812
  | « Le provider a planté après la fermeture d'un onglet » | **provider** confondu avec **sink** : le provider est partagé, il survit à la connexion créatrice | N'y capturer que des dépendances à longue vie (`ChannelFactory`, `RealtimeHub.ts:170`) |
813
813
  | « Notre store realtime est indisponible » | **store** employé pour **driver** : le backplane ne conserve rien, il fait passer | Dire « le driver de backplane » — les données ont des stores, les flux ont des drivers |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodefony/realtime",
3
- "version": "10.0.0-alpha.8",
3
+ "version": "10.0.0-beta.1",
4
4
  "description": "Couche temps réel serveur de Nodefony : canaux, appels bidirectionnels JSON-RPC 2.0, contre-pression, et diffusion entre plusieurs instances (boucle locale, IPC de grappe, Redis)",
5
5
  "author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
6
6
  "type": "module",
@@ -20,9 +20,9 @@
20
20
  "./package.json": "./package.json"
21
21
  },
22
22
  "scripts": {
23
- "build": "rimraf dist && rolldown -c rolldown.config.ts && tsgo -p tsconfig.declarations.json",
23
+ "build": "rolldown -c rolldown.config.ts && tsgo -p tsconfig.declarations.json",
24
24
  "dev": "rolldown -c rolldown.config.ts --watch",
25
- "clean": "rimraf dist",
25
+ "clean": "node --eval \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
26
26
  "test": "vitest run",
27
27
  "test:cluster": "vitest run --config vitest.cluster.config.ts",
28
28
  "coverage": "vitest run --coverage",
@@ -41,21 +41,20 @@
41
41
  "esm"
42
42
  ],
43
43
  "peerDependencies": {
44
- "@nodefony/framework": "^10.0.0-alpha.8",
45
- "@nodefony/http": "^10.0.0-alpha.8",
46
- "nodefony": "^10.0.0-alpha.8",
44
+ "@nodefony/framework": "^10.0.0-beta.1",
45
+ "@nodefony/http": "^10.0.0-beta.1",
46
+ "nodefony": "^10.0.0-beta.1",
47
47
  "reflect-metadata": "0.2.2",
48
48
  "zod": "^4.6.5"
49
49
  },
50
50
  "devDependencies": {
51
- "@nodefony/framework": "^10.0.0-alpha.8",
52
- "@nodefony/http": "^10.0.0-alpha.8",
53
- "@types/node": "26.6.2",
54
- "@vitest/coverage-v8": "5.0.1",
55
- "nodefony": "^10.0.0-alpha.8",
51
+ "@nodefony/framework": "^10.0.0-beta.1",
52
+ "@nodefony/http": "^10.0.0-beta.1",
53
+ "@types/node": "26.6.3",
54
+ "@vitest/coverage-v8": "5.0.2",
55
+ "nodefony": "^10.0.0-beta.1",
56
56
  "reflect-metadata": "0.2.2",
57
- "rimraf": "6.1.3",
58
- "vitest": "5.0.1"
57
+ "vitest": "5.0.2"
59
58
  },
60
59
  "private": false,
61
60
  "engines": {