semantic-typescript 0.6.0 → 0.7.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.
package/readme.fr.md CHANGED
@@ -1,204 +1,267 @@
1
- # Semantic-TypeScript : Une bibliothèque de traitement de flux qui change de paradigme
1
+ # **SemanticTypeScript**
2
+ **Flux, indexés.** Vos données, sous contrôle précis.
2
3
 
3
- ## Introduction
4
- Semantic-TypeScript représente une avancée significative dans la technologie de traitement de flux, synthétisant les concepts les plus efficaces des JavaScript GeneratorFunctions, des Java Streams et des paradigmes d'indexation de bases de données. Son principe de conception fondamental est centré sur la construction de pipelines de traitement de données exceptionnellement efficaces grâce à une évaluation paresseuse sophistiquée et une indexation intelligente. La bibliothèque offre une expérience d'opération de streaming rigoureusement type-safe et fonctionnellement pure, spécialement conçue pour le développement TypeScript et JavaScript contemporain.
4
+ ---
5
5
 
6
- Contrairement aux architectures de traitement synchrone conventionnelles, Semantic-TypeScript implémente un modèle unifié qui gère avec grâce à la fois les sources de données synchrones (Iterable) et asynchrones (AsyncIterable). Pendant la génération du flux, le flux et la terminaison des données sont précisément contrôlés par des mécanismes de rappel (callback), permettant à la bibliothèque de gérer avec une grâce exceptionnelle :
7
- - Les flux de données en temps réel (événements DOM, WebSockets, intervalles) avec un contrôle déterministe
8
- - Les jeux de données à grande échelle grâce à des pipelines paresseux et économes en mémoire
9
- - Les transformations de données complexes avec une API fluide et déclarative
6
+ ### Vue d'ensemble
10
7
 
11
- L'approche innovante de la bibliothèque réinvente fondamentalement la façon dont les développeurs interagissent avec les séquences de données, offrant à la fois des caractéristiques de performance sans précédent et une ergonomie pour le développeur dans un ensemble unique et cohérent.
8
+ Semantic‑TypeScript représente une avancée significative dans le traitement des flux, **synthétisant** avec élégance les paradigmes les plus efficaces des générateurs JavaScript, des Streams Java et de l'indexation de style MySQL. Son postulat fondamental est à la fois puissant et délibéré : construire des pipelines de traitement de données exceptionnellement efficaces grâce à une indexation intelligente, plutôt que par une itération conventionnelle en force brute.
12
9
 
13
- ## Philosophie de base : Séparation de la Définition et de l'Exécution
14
- Une idée architecturale clé de Semantic-TypeScript est la séparation claire entre la définition d'un flux et son exécution :
15
- - **`Semantic<E>`** : Un modèle immuable et paresseux d'un pipeline de transformation de données. Il définit quelles opérations (filter, map, etc.) seront effectuées.
16
- - **`Collectable<E>`** : Une vue exécutable et matérialisée du flux. Elle est obtenue à partir d'un Semantic et fournit toutes les opérations terminales (collect, forEach, etc.) pour exécuter le pipeline et produire un résultat.
10
+ les bibliothèques typiques imposent des boucles synchrones ou des chaînes de promesses (*Promises*) maladroites, Semantic‑TypeScript fournit une expérience **entièrement asynchrone**, fonctionnellement pure et rigoureusement sûre au niveau des types, conçue expressément pour les exigences du développement d'applications modernes.
17
11
 
18
- Cette séparation impose un modèle mental clair et débloque des optimisations puissantes, comme le choix d'un `UnorderedCollectable` pour ignorer les tris inutiles et obtenir une vitesse maximale.
12
+ Ce modèle incarne une forme raffinée de flux de contrôle : les données ne sont transmises au consommateur en aval que lorsque le pipeline en amont invoque explicitement le rappel (*callback*) `accept`. Vous conservez un contrôle complet et granulaire sur le moment du traitement – celui‑ci se produit précisément quand, et seulement quand, c'est nécessaire.
19
13
 
20
- ## Pourquoi choisir Semantic-TypeScript ?
21
- Choisir la bonne bibliothèque pour le traitement de flux de données implique d'équilibrer performance, sûreté des types (type safety) et expressivité. Semantic-TypeScript est conçu pour exceller dans toutes ces dimensions.
14
+ ---
22
15
 
23
- ### 1. Un paradigme unifié et type-safe pour toutes les séquences de données
24
- Il fournit une API déclarative cohérente pour traiter n'importe quelle séquence de données – qu'il s'agisse de tableaux statiques, d'événements en temps réel ou de morceaux de données asynchrones – tout en exploitant toute la puissance de TypeScript pour garantir une sûreté des types de bout en bout. Cela élimine toute une classe d'erreurs d'exécution et transforme la manipulation de flux en une activité prévisible et vérifiée par le compilateur.
16
+ ### Pourquoi les développeurs choisissent Semantic‑TypeScript
25
17
 
26
- ### 2. Performance sans compromis avec une "paresse" intelligente
27
- À sa base, la bibliothèque est construite sur l'évaluation paresseuse (lazy evaluation). Des opérations comme `filter`, `map`, et `flatMap` se contentent de composer un pipeline de traitement ; aucun travail n'est effectué tant qu'une opération terminale n'est invoquée. Ceci est couplé à des capacités de court-circuit (via `limit`, `anyMatch` ou des rappels `interrupt` personnalisés), ce qui permet d'arrêter le traitement prématurément, améliorant considérablement l'efficacité pour les flux grands ou infinis.
18
+ - **Indexation sans répétition** Chaque élément possède intrinsèquement son index naturel ou sur mesure, éliminant le suivi manuel.
19
+ - **Purement fonctionnel et sûr pour les types** Bénéficiez d'une inférence de types TypeScript complète et idiomatique avec des opérations immuables.
20
+ - **Flux d'événements étanches aux fuites** – Le modèle `useSubscription` est conçu avec la sécurité des ressources comme premier principe. Vous définissez la limite logique – en utilisant `limit(n)`, `sub(start, end)` ou `takeWhile(predicate)` – et la bibliothèque gère entièrement le cycle de vie de l'abonnement. Cela garantit l'absence d'écouteurs (*listeners*) résiduels et de fuites de mémoire.
21
+ - **Suite statistique intégrée** – Accédez à des analyses exhaustives pour les flux de type `number` et `bigint`, incluant moyennes, médianes, modes, variance, asymétrie (*skewness*) et aplatissement (*kurtosis*), sans dépendances externes.
22
+ - **Performances prévisibles et ajustables** – Choisissez entre des collecteurs ordonnés ou non ordonnés pour correspondre exactement à vos besoins en matière de performances et d'ordre.
23
+ - **Inhéremment économe en mémoire** – Les flux sont évalués de manière paresseuse (*lazy*), traitant les éléments à la demande pour soulager la pression sur la mémoire.
24
+ - **Aucun comportement indéfini** – TypeScript garantit une sécurité des types et une nullabilité complètes. Vos données sources restent immuables, sauf si elles sont modifiées explicitement dans vos fonctions de rappel.
28
25
 
29
- ### 3. La puissance du motif `Collector<E, A, R>`
30
- Inspiré de Java, le motif Collector est le moteur de la flexibilité. Il découple la spécification de la manière d'accumuler les éléments du flux de l'exécution du flux lui-même. La bibliothèque fournit un riche ensemble de collecteurs intégrés (`toArray`, `groupBy`, `summate`, etc.) pour les tâches courantes, tout en facilitant l'implémentation de votre propre logique de réduction complexe et réutilisable. C'est bien plus puissant et composable qu'un ensemble fixe de méthodes terminales.
26
+ ---
31
27
 
32
- ### 4. Support de première classe pour les données Web modernes et asynchrones
33
- Semantic-TypeScript est conçu pour le développement contemporain. Il offre des méthodes d'usine natives pour les sources web modernes :
34
- - `useFrom(iterable)`, `useRange()` pour les données statiques
35
- - `useInterval()`, `useAnimationFrame()` pour les flux basés sur le temps
36
- - `useBlob()` pour le traitement de données binaires par morceaux (chunked)
37
- - `useWebSocket()`, `useDocument()`, `useWindow()` pour les flux d'événements en temps réel
28
+ ### Installation
38
29
 
39
- ### 5. Au-delà de l'agrégation basique : Analyse statistique intégrée
40
- Allez au-delà des simples sommes et moyennes. La bibliothèque fournit les interfaces dédiées `NumericStatistics` et `BigIntStatistics`, offrant un accès immédiat à des mesures statistiques avancées directement depuis vos flux – variance, écart-type, médiane, asymétrie (skewness) et aplatissement (kurtosis). Cela transforme l'analyse de données complexes en une simple ligne de code.
30
+ Intégrez Semantic‑TypeScript à votre projet en utilisant votre gestionnaire de paquets préféré :
41
31
 
42
- ### 6. Conçu pour l'ergonomie du développeur
43
- - **API fluide et chaînable** : Écrivez des pipelines de données complexes sous forme de chaînes séquentielles lisibles.
44
- - **Suite utilitaire complète** : Gardes essentiels (`isFunction`, `isIterable`), utilitaires (`useCompare`, `useTraverse`) et interfaces fonctionnelles inclus.
45
- - **Intégration `Optional<T>`** : Modélise en toute sécurité l'absence d'une valeur, éliminant les problèmes de pointeur nul.
46
- - **Conseils de performance** : Guide clair sur quand utiliser la collection non ordonnée (`unordered`) pour la vitesse contre la collection ordonnée (`ordered`) pour la séquence.
47
-
48
- ## Installation
49
32
  ```bash
50
33
  npm install semantic-typescript
51
34
  ```
35
+ ou
36
+ ```bash
37
+ yarn add semantic-typescript
38
+ ```
52
39
 
53
- ## Concepts de base en pratique
40
+ ---
41
+
42
+ ### Introduction pratique
43
+
44
+ Les exemples suivants démontrent des concepts clés, des transformations fondamentales à la gestion d'événements réels.
54
45
 
55
- ### 1. Création de flux (Semantic)
56
- Les flux peuvent être créés à partir de diverses sources en utilisant des fonctions d'usine.
57
46
  ```typescript
58
- import { useFrom, useInterval, useDocument } from 'semantic-typescript';
47
+ import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
48
+
49
+ // ====================================================================
50
+ // EXEMPLE 1 : Opérations fondamentales et statistiques numériques
51
+ // ====================================================================
52
+ // Démontre les opérations de mappage (*map*) et les opérations statistiques terminales. Après transformation, le pipeline doit être converti en un collecteur de statistiques avant de pouvoir appeler des méthodes terminales comme `.summate()`.
53
+
54
+ const numericSum: number = useOf(10, 20, 30, 40)
55
+ .map((n: number): number => n * 2) // Double chaque élément : [20, 40, 60, 80]
56
+ .toNumericStatistics() // Convertit en un collecteur de statistiques
57
+ .summate(); // Opération terminale : 200
58
+
59
+ // Autres méthodes statistiques (disponibles après `.toNumericStatistics()`) :
60
+ // .average(), .median(), .mode(), .variance(), .skewness(), .kurtosis()
61
+
62
+ // ====================================================================
63
+ // EXEMPLE 2 : Statistiques BigInt
64
+ // ====================================================================
65
+ // Fonctionne de manière identique aux statistiques numériques mais est optimisé pour les données BigInt.
66
+
67
+ const bigintSum: bigint = useOf(10n, 20n, 30n, 40n)
68
+ .map((n: bigint): bigint => n * 2n) // Arithmétique BigInt
69
+ .toBigIntStatistics() // Convertit en un collecteur de statistiques BigInt
70
+ .summate(); // Opération terminale : 200n
71
+
72
+ // ====================================================================
73
+ // EXEMPLE 3 : Manipulation d'index pour inverser un flux
74
+ // ====================================================================
75
+ // Illustre le réordonnancement des éléments en réattribuant stratégiquement leurs index à l'aide de la méthode `.redirect()`, permettant des modèles personnalisés comme l'inversion.
76
+
77
+ const reversedArray: number[] = useFrom([1, 2, 3, 4, 5])
78
+ .redirect((_element: number, index: bigint): bigint => -index) // Mappe sur des index négatifs
79
+ .toOrdered() // Essentiel : collecte les éléments triés selon leurs nouveaux index
80
+ .toArray(); // Résultat : [5, 4, 3, 2, 1]
81
+
82
+ // Pour une inversion simple, `.reverse()` est également disponible.
83
+
84
+ // ====================================================================
85
+ // EXEMPLE 4 : Mélange (*Shuffle*) d'un flux
86
+ // ====================================================================
87
+ // Permute aléatoirement les index des éléments à l'aide d'un algorithme de mélange sur place (*in‑place*).
88
+
89
+ const shuffledArray: number[] = useFrom([1, 2, 3, 4, 5])
90
+ .shuffle() // Réattribue aléatoirement les index
91
+ .toOrdered() // Trie selon les nouveaux index aléatoires
92
+ .toArray(); // Par exemple : [2, 5, 1, 4, 3] (varie à chaque exécution)
93
+
94
+ // ====================================================================
95
+ // EXEMPLE 5 : Rotation circulaire d'un flux
96
+ // ====================================================================
97
+ // Décale les éléments de manière cyclique. Les valeurs positives tournent vers la droite ; les valeurs négatives vers la gauche.
98
+
99
+ // Rotation à droite de 2 positions
100
+ const rightRotated: number[] = useFrom([1, 2, 3, 4, 5])
101
+ .translate(2) // Décale les index de 2 vers la droite
102
+ .toOrdered()
103
+ .toArray(); // Résultat : [4, 5, 1, 2, 3]
104
+
105
+ // ====================================================================
106
+ // EXEMPLE 6 : Évaluation paresseuse (*Lazy*) avec des plages infinies
107
+ // ====================================================================
108
+ // Traite des flux théoriquement infinis de manière paresseuse, ne calculant les éléments que lorsqu'ils sont nécessaires.
109
+
110
+ const firstTenMultiples: bigint[] = useRange(0n, 1_000_000n)
111
+ .filter(n => n % 17n === 0n) // Conserve les multiples de 17
112
+ .limit(10n) // Critique : s'arrête après le 10e élément correspondant
113
+ .toUnordered() // Aucun tri requis
114
+ .toArray(); // Résultat : [0, 17, 34, 51, 68, 85, 102, 119, 136, 153]
115
+
116
+ // Sans `.limit(10n)`, le pipeline traiterait le million d'éléments.
117
+
118
+ // ====================================================================
119
+ // EXEMPLE 7 : Composition d'un pipeline complexe
120
+ // ====================================================================
121
+ // Démontre la composition séquentielle de plusieurs opérations.
122
+
123
+ const complexResult: number[] = useRange(1n, 100n)
124
+ .map(n => Number(n) * 2)
125
+ .filter(n => n > 50)
126
+ .shuffle()
127
+ .limit(5n)
128
+ .translate(2)
129
+ .toOrdered()
130
+ .toArray();
59
131
 
60
- // Depuis un tableau statique
61
- const staticStream = useFrom([1, 2, 3, 4, 5]);
132
+ // ====================================================================
133
+ // EXEMPLE 8 : Abonnement géré aux événements du DOM
134
+ // ====================================================================
135
+ // Écoute les événements du navigateur avec un nettoyage automatique et étanche aux fuites.
136
+ // L'appel `.limit(n)` définit la limite pour la suppression automatique de l'écouteur.
137
+
138
+ // Définit un abonné pour une cible Window
139
+ const windowSubscriber = {
140
+ mount: (target: Window): void => { /* Logique de configuration */ },
141
+ subscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
142
+ target.addEventListener(event, handler);
143
+ },
144
+ unsubscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
145
+ target.removeEventListener(event, handler);
146
+ },
147
+ unmount: (): void => { /* Logique de nettoyage */ }
148
+ };
149
+
150
+ useSubscription(window, windowSubscriber, "resize")
151
+ .limit(5n) // Se désabonne automatiquement après 5 événements
152
+ .toUnordered()
153
+ .forEach((ev: Event, idx) =>
154
+ console.log(`Redimensionnement #${idx} : ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
155
+ );
62
156
 
63
- // Depuis un générateur asynchrone
64
- const asyncStream = useFrom(async function*() {
65
- yield 1;
66
- yield 2;
67
- });
157
+ // ====================================================================
158
+ // EXEMPLE 9 : Traitement de chaînes par points de code Unicode
159
+ // ====================================================================
160
+ // Parcourt correctement une chaîne, gérant les caractères Unicode multi‑octets.
68
161
 
69
- // Un flux basé sur le temps
70
- const tickStream = useInterval(1000); // émet toutes les secondes
162
+ useText("My emotion now is: 😊, and semantic is 👍")
163
+ .toUnordered()
164
+ .log(); // Affiche chaque caractère (y compris les émojis) sur une nouvelle ligne.
71
165
 
72
- // Un flux d'événements DOM (voir note cruciale ci-dessous)
73
- const clickStream = useDocument('click');
74
- ```
166
+ // ====================================================================
167
+ // EXEMPLE 10 : Transformation sécurisée en chaîne pour références circulaires
168
+ // ====================================================================
169
+ // Sérialise de manière sûre des objets contenant des références circulaires.
75
170
 
76
- ### 2. Transformation de flux (Opérations intermédiaires)
77
- Les opérations sont enchaînées de manière paresseuse pour définir le pipeline.
78
- ```typescript
79
- const processedStream = staticStream
80
- .filter(x => x % 2 === 0) // Ne garde que les nombres pairs
81
- .map(x => x * 10) // Multiplie par 10
82
- .flatMap(x => [x, x + 1]) // Transforme chaque élément en deux
83
- .distinct(); // Supprime les doublons
84
- // Rien n'a été exécuté pour l'instant
85
- ```
171
+ const obj = {
172
+ a: 1,
173
+ b: "texte"
174
+ };
175
+ (obj as any).c = [obj.a, obj.b, (obj as any).c]; // Introduit une référence circulaire
86
176
 
87
- ### 3. Exécution de flux (Opérations terminales)
88
- Pour obtenir un résultat, vous devez obtenir un `Collectable` et invoquer une opération terminale.
89
- ```typescript
90
- // Obtenir un collectable non ordonné pour la performance
91
- const resultArray = await processedStream.toUnordered().toArray();
92
- console.log(resultArray); // ex: [20, 21, 40, 41]
93
-
94
- // Utiliser un collecteur intégré
95
- const sum = await processedStream.toUnordered().collect(useSummate());
96
- console.log(sum);
97
-
98
- // Ou utiliser la méthode générique collect
99
- const customResult = await processedStream.toOrdered().collect(
100
- () => new Map<number, number>(),
101
- (map, element, index) => map.set(index, element),
102
- map => map
103
- );
177
+ // const text: string = JSON.stringify(obj); // Lance une erreur
178
+ const text: string = useStringify(obj); // Produit de manière sûre `{a: 1, b: "texte", c: []}`
104
179
  ```
105
180
 
106
- ### 4. Crucial : Travailler avec les flux d'événements
107
- Les flux d'événements (`useDocument`, `useWindow`, `useHTMLElement`, `useWebSocket`) sont par nature infinis. Vous devez utiliser des opérations comme `sub`, `takeWhile`, ou `limit` pour définir quand arrêter de collecter les événements et terminer le flux. Sinon, l'opération terminale attendra indéfiniment.
108
- ```typescript
109
- import { useDocument } from 'semantic-typescript';
181
+ ---
110
182
 
111
- // Collecter uniquement les 5 premiers clics
112
- const first5Clicks = await useDocument('click')
113
- .limit(5) // <- Essentiel : limite le flux à 5 événements
114
- .toUnordered()
115
- .toArray();
183
+ ### Concepts principaux
116
184
 
117
- // Collecter les clics pendant une fenêtre de 10 secondes
118
- const clicksIn10s = await useDocument('click')
119
- .takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
120
- .toUnordered()
121
- .toArray();
185
+ | Concept | Objectif | Cas d'utilisation principal |
186
+ | :--- | :--- | :--- |
187
+ | `AsynchronousSemantic` | Le constructeur principal pour les flux asynchrones, les événements et les pipelines paresseux basés sur une poussée (*push*). | Événements en temps réel, WebSockets, écouteurs DOM ou tout flux de longue durée/infini. |
188
+ | `SynchronousSemantic` | Le constructeur pour les flux synchrones, en mémoire ou basés sur une traction (*pull*) immédiate (*eager*). | Données statiques, plages finies ou tâches d'itération immédiate. |
189
+ | `toUnordered()` | Le collecteur terminal le plus rapide, utilise une Map pour stocker les index. | Chemins critiques pour les performances où l'ordre stable n'est pas requis (temps et espace O(n)). |
190
+ | `toOrdered()` | Un collecteur terminal trié, stable en termes d'index. | Lorsque l'ordre des éléments doit être préservé ou qu'un accès indexé est nécessaire. |
191
+ | `toNumericStatistics()` | Un collecteur permettant des analyses statistiques riches sur les flux de type `number`. | Analyse de données, métriques et calculs statistiques. |
192
+ | `toBigIntStatistics()` | Un collecteur permettant des analyses statistiques riches sur les flux de type `bigint`. | Analyse et statistiques pour des jeux de données d'entiers de grande taille. |
193
+ | `toWindow()` | Fournit des opérations de fenêtre glissante (*sliding*) et fixe (*tumbling*) sur un flux. | Analyse de séries temporelles, traitement par lots et agrégations par fenêtres. |
122
194
 
123
- // Collecter les clics de l'index 2 à 5 (base 0)
124
- const specificClicks = await useDocument('click')
125
- .sub(2n, 6n) // <- Prend les éléments avec les index 2, 3, 4, 5
126
- .toUnordered()
127
- .toArray();
128
- ```
129
- **Idée clé** : L'événement (par exemple, un `MouseEvent`) et son index d'émission séquentiel (sous forme de `bigint`) sont passés ensemble à travers le pipeline via le rappel `accept(event, index)`.
195
+ ---
130
196
 
131
- ### 5. Tirer parti des statistiques
132
- ```typescript
133
- const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
134
- const average = await numericStream.average();
135
- const median = await numericStream.median();
136
- const standardDeviation = await numericStream.standardDeviation();
137
- const skewness = await numericStream.skewness();
138
- console.log(`Moyenne: ${average}, Médiane: ${median}, Écart-type: ${standardDeviation}`);
139
- ```
197
+ **Règles d'utilisation essentielles**
140
198
 
141
- ## Fonctionnalités principales
142
- - **Deux types de flux** : Support complet à la fois de `SynchronousSemantic` (pour `Iterable`) et d'`AsynchronousSemantic` (pour `AsyncIterable` et les événements)
143
- - **Ensemble d'opérations riche** : `filter`, `map`, `flatMap`, `concat`, `distinct`, `sorted`, `limit`, `skip`, `peek`, `reverse`, `shuffle`
144
- - **Opérations terminales flexibles** : `collect` (avec collecteurs personnalisés), `toArray`, `toSet`, `toMap`, `forEach`, `reduce`, `findFirst`, `anyMatch`, `allMatch`, `count`
145
- - **Collecteurs avancés** : Collecteurs intégrés pour `joining`, `groupingBy`, `partitioningBy`, `summing`, `averaging`, `maxBy`, `minBy`
146
- - **Module statistique** : Méthodes prêtes à l'emploi pour `mean`, `median`, `mode`, `variance`, `standardDeviation`, `range`, `quantiles`, `skewness`, `kurtosis` sur les flux numériques/bigint
147
- - **Fonctions utilitaires** : Gardes de type (`isPromise`, `isAsyncIterable`), comparateurs (`useCompare`), traversée (`useTraverse`) et crochets de conversion
148
- - **`Optional<T>`** : Un conteneur monadique pour les valeurs nullables, intégré aux opérations de recherche
149
-
150
- ## Aperçu de l'API
151
-
152
- ### Classes et Interfaces de base
153
- - `Semantic<E>` / `AsynchronousSemantic<E>` : La définition abstraite du flux
154
- - `Collectable<E>` / `AsynchronousCollectable<E>` : Le flux exécutable avec les opérations terminales
155
- - `OrderedCollectable<E>` / `UnorderedCollectable<E>` : Versions matérialisées optimisées pour les opérations respectant l'ordre (`order-sensitive`) ou non (`order-insensitive`)
156
- - `Collector<E, A, R>` : L'abstraction pour les opérations de réduction mutables
157
-
158
- ### Fonctions d'usine (`use*`)
159
- - **Depuis des sources** : `useFrom`, `useRange`, `useFill`, `useEmpty`
160
- - **Depuis le temps** : `useInterval`, `useAnimationFrame`
161
- - **Depuis les APIs Web** : `useBlob`, `useDocument`, `useWindow`, `useHTMLElement`, `useWebSocket`
162
- - **Collecteurs** : `useToArray`, `useGroupBy`, `useSummate`, `useJoin`, etc.
163
-
164
- ## Notes sur la performance
165
- - **Évaluation paresseuse (Lazy Evaluation)** : Les pipelines sont composés sans exécution jusqu'à ce qu'une opération terminale soit appelée.
166
- - **Court-circuit (Short-Circuiting)** : Des opérations comme `limit`, `anyMatch` et `findFirst` arrêteront de traiter les éléments dès que le résultat est déterminé.
167
- - **Ordonné vs Non ordonné** :
168
- - Utilisez `.toUnordered()` pour les opérations terminales lorsque l'ordre des éléments source n'a pas d'importance pour votre résultat (ex: pour `sum`, `max`, ou `toSet`). Cela peut permettre des optimisations internes qui sautent des étapes de tri coûteuses.
169
- - Utilisez `.toOrdered()` lorsque la séquence est importante (ex: pour `toArray` où l'ordre doit être préservé).
170
-
171
- ## Exemple pour commencer
172
- ```typescript
173
- import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
174
-
175
- interface Transaction {
176
- id: number;
177
- amount: number;
178
- category: string;
179
- }
180
-
181
- const transactions: Transaction[] = [
182
- { id: 1, amount: 100, category: 'Food' },
183
- { id: 2, amount: 200, category: 'Electronics' },
184
- { id: 3, amount: 50, category: 'Food' },
185
- { id: 4, amount: 300, category: 'Electronics' },
186
- ];
187
-
188
- // Calculer le montant total par catégorie
189
- const totalsByCategory = await useFrom(transactions)
190
- .toUnordered()
191
- .collect(
192
- useGroupBy(
193
- t => t.category,
194
- t => t.amount,
195
- useSummate() // Collecteur pour les valeurs
196
- )
197
- );
199
+ 1. **Les flux d'événements** (créés via des fabriques comme `useSubscription`) retournent un `AsynchronousSemantic`.
200
+ Vous **devez** appeler une méthode définissant une limite, comme `.limit(n)`, `.sub(start, end)` ou `.takeWhile(predicate)` pour mettre fin à l'écoute. Sinon, l'abonnement restera actif.
198
201
 
199
- console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
200
- ```
202
+ 2. **Les opérations terminales** (`.toArray()`, `.count()`, `.forEach()`, `.findFirst()`, etc.) ne sont **disponibles qu'après** avoir converti le pipeline en un collecteur :
203
+ ```typescript
204
+ .toUnordered() // Pour une vitesse maximale, sans garantie d'ordre.
205
+ // ou
206
+ .toOrdered() // Pour une sortie stable et triée.
207
+ // ou
208
+ .toNumericStatistics() // Pour les méthodes statistiques.
209
+ ```
210
+
211
+ ---
212
+
213
+ ### Caractéristiques de performance
214
+
215
+ | Collecteur | Complexité temporelle | Complexité spatiale | Ordre garanti ? | Scénario idéal |
216
+ | :--- | :--- | :--- | :--- | :--- |
217
+ | `toUnordered()` | O(n) | O(n) | Non | Le débit brut est primordial ; l'ordre final est sans importance. |
218
+ | `toOrdered()` | O(n log n) | O(n) | Oui (trié) | Ordre stable, accès indexé ou pré‑tri pour les statistiques. |
219
+ | `toNumericStatistics()` | O(n log n) | O(n) | Oui (tri interne) | Exécution d'opérations statistiques nécessitant des données triées. |
220
+ | `toBigIntStatistics()` | O(n log n) | O(n) | Oui (tri interne) | Opérations statistiques sur des données BigInt. |
221
+ | `toWindow()` | O(n log n) | O(n) | Oui (tri interne) | Opérations de fenêtre bénéficiant d'index triés. |
222
+
223
+ Choisissez `toUnordered()` lorsque la vitesse absolue est primordiale. Optez pour `toOrdered()` ou un collecteur de statistiques uniquement lorsque votre logique dépend de l'ordre des éléments.
224
+
225
+ ---
226
+
227
+ **Analyse comparative avec les bibliothèques de flux modernes**
228
+
229
+ | Caractéristique | Semantic‑TypeScript | RxJS | Async Iterators / Generators natifs | Most.js |
230
+ | :--- | :--- | :--- | :--- | :--- |
231
+ | **Intégration TypeScript** | De première classe, fortement typée avec une conscience d'index inhérente. | Excellente, mais implique souvent des chaînes génériques complexes. | Bonne, mais nécessite des annotations de type manuelles. | Solide, avec un style de typage fonctionnel‑*first*. |
232
+ | **Analyse statistique intégrée** | Prise en charge native complète pour `number` et `bigint`. | Non disponible nativement (nécessite des opérateurs personnalisés ou d'autres bibliothèques). | Aucune. | Aucune. |
233
+ | **Indexation et conscience de position** | Indexation BigInt native et puissante sur chaque élément. | Nécessite des opérateurs personnalisés (ex. `scan`, `withLatestFrom`). | Gestion manuelle de compteur nécessaire. | Basique, aucune propriété d'index intégrée. |
234
+ | **Gestion des flux d'événements** | Fabriques dédiées, sûres pour les types, avec contrôle de cycle de vie explicite et déclaratif. | Puissante mais nécessite une gestion manuelle minutieuse des abonnements pour éviter les fuites. | Attachement manuel des écouteurs d'événements et gestion de jetons d'annulation. | Bon `fromEvent`, généralement léger. |
235
+ | **Performances et mémoire** | Exceptionnel – offre des collecteurs optimisés `toUnordered()` et `toOrdered()`. | Très bonne, bien que les chaînes profondes d'opérateurs puissent introduire une surcharge. | Excellente (surcharge native minimale). | Excellente. |
236
+ | **Taille du bundle** | Très léger. | Substantielle (même avec l'élagage d'arbre – *tree‑shaking*). | Zéro (fonctionnalité native du langage). | Petit. |
237
+ | **Philosophie de conception d'API** | Modèle de collecteur fonctionnel avec sémantique d'index explicite. | Modèle Observable réactif. | Modèle Iterator impératif / Generator déclaratif. | Fonctionnel, composition *point‑free*. |
238
+ | **Contrôle de flux** | Explicite (`interrupt`, `.limit()`, `.takeWhile()`, `.sub()`). | Bon (`take`, `takeUntil`, `first`). | Manuel (`break` dans les boucles). | Bon (`take`, `until`). |
239
+ | **Support synchrone et asynchrone** | API unifiée – support de première classe pour les deux paradigmes. | Principalement asynchrone. | Les deux pris en charge, mais avec un pont manuel. | Principalement asynchrone. |
240
+ | **Courbe d'apprentissage** | Douce pour les développeurs familiers avec les pipelines de collections fonctionnelles et indexées. | Plus raide (lexique étendu d'opérateurs, concepts Observable chaud/froid – *hot/cold*). | Faible à moyenne. | Moyenne. |
241
+
242
+ **L'avantage de Semantic‑TypeScript**
243
+
244
+ * **Capacités uniques :** Les fonctionnalités de statistique et d'indexation intégrées éliminent le besoin d'opérations manuelles de `reduce` ou de bibliothèques d'analyse de données supplémentaires.
245
+ * **Gestion prévisible des ressources :** Le contrôle explicite des flux d'événements prévient les fuites de mémoire qui peuvent être subtiles dans les applications RxJS.
246
+ * **Conception unifiée :** Une API cohérente pour les flux de travail synchrones et asynchrones réduit la charge cognitive et la duplication de code.
247
+
248
+ Cette comparaison met en lumière pourquoi Semantic‑TypeScript est particulièrement adapté aux applications TypeScript modernes qui exigent des performances élevées, une robustesse en matière de sécurité des types et des fonctionnalités de traitement de données riches sans la complexité des frameworks réactifs traditionnels.
249
+
250
+ ---
251
+
252
+ ### Commencez votre exploration
253
+
254
+ Semantic‑TypeScript transforme des flux de données complexes en pipelines lisibles, composables et performants. Que vous manipuliez des événements d'interface utilisateur en temps réel, traitiez de grands ensembles de données ou construisiez des tableaux de bord analytiques, il offre la puissance de l'indexation au niveau base de données avec l'élégance de la programmation fonctionnelle.
255
+
256
+ **Vos prochaines étapes :**
257
+
258
+ * Explorez l'API entièrement typée directement dans votre IDE (toutes les exportations sont disponibles depuis le point d'entrée principal du paquet).
259
+ * Rejoignez la communauté grandissante de développeurs qui ont remplacé des itérateurs asynchrones complexes et des chaînes réactives par des pipelines Semantic clairs et intentionnels.
260
+
261
+ **Semantic‑TypeScript** – où les flux rencontrent la structure.
262
+
263
+ Commencez à construire dès aujourd'hui et expérimentez la différence tangible qu'apporte une conception d'indexation réfléchie.
201
264
 
202
- Semantic-TypeScript est conçue pour les développeurs qui recherchent une bibliothèque de traitement de flux rigoureusement conçue, type-safe et haute performance. Elle apporte la puissance des modèles de transformation de données de niveau entreprise à l'écosystème TypeScript, parfaitement adaptée aux applications front-end gourmandes en données, au traitement de données Node.js, et à tout scénario où une manipulation élégante et efficace des séquences est requise.
265
+ **Construisez avec clarté, avancez avec confiance et transformez les données avec intention.**
203
266
 
204
- [![GitHub](./GitHub.png)](https://github.com/eloyhere/semantic-typescript) [![NPM](./NPM.png)](https://www.npmjs.com/package/semantic-typescript)
267
+ MIT © Eloy Kim