@nodefony/realtime 10.0.0-alpha.1 → 10.0.0-alpha.3

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.
@@ -56,6 +56,25 @@ const isReservedSystemChannel = isPlatformChannel;
56
56
  */
57
57
  const REVOCATION_REVALIDATE_MS = 3e4;
58
58
  /**
59
+ * Le MOTIF de famille d'un canal — son dernier segment remplacé par `*`.
60
+ *
61
+ * `"studio:metrics:1s"` → `"studio:metrics:*"`, `"alerts"` → `"*"`. Sert à
62
+ * SUGGÉRER une politique qui garde toute une famille, quand un canal dérivé
63
+ * n'est couvert par aucune.
64
+ *
65
+ * Sans expression régulière, et c'est délibéré : `/[^:]*$/` sur un nom de canal
66
+ * venu de l'extérieur se replie à chaque position d'échec, coût quadratique sur
67
+ * une entrée que le module ne choisit pas. Chercher le dernier séparateur est
68
+ * linéaire, et dit plus clairement ce qu'on fait.
69
+ *
70
+ * @param channel - le nom complet du canal
71
+ * @returns le motif couvrant sa famille
72
+ */
73
+ function channelFamily(channel) {
74
+ const i = channel.lastIndexOf(":");
75
+ return i === -1 ? "*" : `${channel.slice(0, i + 1)}*`;
76
+ }
77
+ /**
59
78
  * RealtimeHub — broker temps réel **PAR INSTANCE** (1 pod = 1 process = 1 hub local).
60
79
  *
61
80
  * Élève le realtime serveur du modèle **per-connexion** (chaque connexion son propre
@@ -792,7 +811,7 @@ var RealtimeHub = class RealtimeHub {
792
811
  noticeUnguardedDynamicChannel(channel) {
793
812
  if (!this.hasChannelPolicies()) return;
794
813
  if (this.resolveChannelPolicy(channel) !== null) return;
795
- this.#notifyOnce("unguarded-dynamic-channel", `le canal "${channel}" est servi par une fabrique DYNAMIQUE et n'est couvert par AUCUNE politique déclarée, alors que ce module en déclare pour d'autres canaux. Un canal dérivé (suffixe de cadence, forage, identifiant) n'hérite pas de la politique de son parent : un nom exact ne garde que lui-même. Déclarer un MOTIF pour garder la famille — @RealtimeChannel("${channel.replace(/[^:]*$/u, "*")}", { … }) — ou porter la vérification dans la fabrique elle-même.`);
814
+ this.#notifyOnce("unguarded-dynamic-channel", `le canal "${channel}" est servi par une fabrique DYNAMIQUE et n'est couvert par AUCUNE politique déclarée, alors que ce module en déclare pour d'autres canaux. Un canal dérivé (suffixe de cadence, forage, identifiant) n'hérite pas de la politique de son parent : un nom exact ne garde que lui-même. Déclarer un MOTIF pour garder la famille — @RealtimeChannel("${channelFamily(channel)}", { … }) — ou porter la vérification dans la fabrique elle-même.`);
796
815
  }
797
816
  /**
798
817
  * Enregistre la **factory d'un canal système** (plateforme) — un module bas
@@ -923,4 +942,4 @@ function getRealtimeHub() {
923
942
  return _hub ??= new RealtimeHub();
924
943
  }
925
944
  //#endregion
926
- export { RESERVED_SYSTEM_PREFIXES, REVOCATION_REVALIDATE_MS, RealtimeHub, RealtimeHub as default, SLOW_CONSUMER_BYTES, getRealtimeHub, isReservedSystemChannel };
945
+ export { RESERVED_SYSTEM_PREFIXES, REVOCATION_REVALIDATE_MS, RealtimeHub, RealtimeHub as default, SLOW_CONSUMER_BYTES, channelFamily, getRealtimeHub, isReservedSystemChannel };
@@ -81,6 +81,22 @@ export declare const isReservedSystemChannel: typeof isPlatformChannel;
81
81
  * délai). Ordre de grandeur aligné sur le heartbeat WS (`keepaliveInterval` 20 s).
82
82
  */
83
83
  export declare const REVOCATION_REVALIDATE_MS = 30000;
84
+ /**
85
+ * Le MOTIF de famille d'un canal — son dernier segment remplacé par `*`.
86
+ *
87
+ * `"studio:metrics:1s"` → `"studio:metrics:*"`, `"alerts"` → `"*"`. Sert à
88
+ * SUGGÉRER une politique qui garde toute une famille, quand un canal dérivé
89
+ * n'est couvert par aucune.
90
+ *
91
+ * Sans expression régulière, et c'est délibéré : `/[^:]*$/` sur un nom de canal
92
+ * venu de l'extérieur se replie à chaque position d'échec, coût quadratique sur
93
+ * une entrée que le module ne choisit pas. Chercher le dernier séparateur est
94
+ * linéaire, et dit plus clairement ce qu'on fait.
95
+ *
96
+ * @param channel - le nom complet du canal
97
+ * @returns le motif couvrant sa famille
98
+ */
99
+ export declare function channelFamily(channel: string): string;
84
100
  /**
85
101
  * Connexion à identité RÉVOCABLE inscrite au registre de re-validation (F4). Ne
86
102
  * porte QUE ce qu'il faut pour re-valider puis fermer : le token (avec `isValid`) et
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodefony/realtime",
3
- "version": "10.0.0-alpha.1",
3
+ "version": "10.0.0-alpha.3",
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",
@@ -40,18 +40,18 @@
40
40
  "esm"
41
41
  ],
42
42
  "peerDependencies": {
43
- "@nodefony/framework": "*",
44
- "@nodefony/http": "*",
45
- "nodefony": "*",
43
+ "@nodefony/framework": "^10.0.0-alpha.3",
44
+ "@nodefony/http": "^10.0.0-alpha.3",
45
+ "nodefony": "^10.0.0-alpha.3",
46
46
  "reflect-metadata": "0.2.2",
47
47
  "zod": "^4.4.3"
48
48
  },
49
49
  "devDependencies": {
50
- "@nodefony/framework": "*",
51
- "@nodefony/http": "*",
50
+ "@nodefony/framework": "^10.0.0-alpha.3",
51
+ "@nodefony/http": "^10.0.0-alpha.3",
52
52
  "@types/node": "26.4.1",
53
53
  "@vitest/coverage-v8": "5.0.0",
54
- "nodefony": "*",
54
+ "nodefony": "^10.0.0-alpha.3",
55
55
  "reflect-metadata": "0.2.2",
56
56
  "rimraf": "6.1.3",
57
57
  "vitest": "5.0.0"