semantic-typescript 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/asynchronous/collector.d.ts +231 -0
  2. package/dist/asynchronous/collector.js +800 -0
  3. package/dist/asynchronous/semantic.d.ts +257 -0
  4. package/dist/asynchronous/semantic.js +1853 -0
  5. package/dist/factory.d.ts +110 -32
  6. package/dist/factory.js +582 -189
  7. package/dist/guard.d.ts +24 -27
  8. package/dist/guard.js +37 -43
  9. package/dist/hook.d.ts +11 -7
  10. package/dist/hook.js +74 -21
  11. package/dist/index.d.ts +2 -3
  12. package/dist/index.js +2 -3
  13. package/dist/optional.d.ts +5 -5
  14. package/dist/optional.js +14 -10
  15. package/dist/symbol.d.ts +19 -23
  16. package/dist/symbol.js +19 -23
  17. package/dist/synchronous/collector.d.ts +232 -0
  18. package/dist/{collector.js → synchronous/collector.js} +160 -170
  19. package/dist/{collectable.d.ts → synchronous/semantic.d.ts} +114 -71
  20. package/dist/{collectable.js → synchronous/semantic.js} +761 -294
  21. package/dist/utility.d.ts +8 -2
  22. package/dist/utility.js +1 -0
  23. package/package.json +1 -1
  24. package/readme.cn.md +158 -697
  25. package/readme.de.md +163 -432
  26. package/readme.es.md +163 -433
  27. package/readme.fr.md +162 -444
  28. package/readme.jp.md +162 -442
  29. package/readme.kr.md +161 -430
  30. package/readme.md +157 -799
  31. package/readme.ru.md +161 -426
  32. package/readme.tw.md +161 -436
  33. package/dist/collector.d.ts +0 -245
  34. package/dist/map.d.ts +0 -76
  35. package/dist/map.js +0 -253
  36. package/dist/node.d.ts +0 -182
  37. package/dist/node.js +0 -918
  38. package/dist/semantic.d.ts +0 -52
  39. package/dist/semantic.js +0 -504
  40. package/dist/set.d.ts +0 -19
  41. package/dist/set.js +0 -65
  42. package/dist/statistics.d.ts +0 -97
  43. package/dist/statistics.js +0 -483
  44. package/dist/tree.d.ts +0 -82
  45. package/dist/tree.js +0 -257
  46. package/dist/window.d.ts +0 -12
  47. package/dist/window.js +0 -72
package/readme.fr.md CHANGED
@@ -1,486 +1,204 @@
1
- # Bibliothèque de traitement de flux Semantic-TypeScript
1
+ # Semantic-TypeScript : Une bibliothèque de traitement de flux qui change de paradigme
2
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
- Semantic-TypeScript est une bibliothèque moderne de traitement de flux inspirée par les fonctions génératrices de JavaScript, les flux Java et l'index de MySQL. Sa philosophie de conception centrale repose sur la construction de pipelines efficaces de traitement de données en utilisant l'indexation des données, offrant une expérience d'opération de flux fonctionnelle avec sécurité de types pour le développement front-end.
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
10
 
7
- Contrairement au traitement synchrone traditionnel, Semantic utilise un modèle de traitement asynchrone. Lors de la création d'un flux de données, le moment où le terminal reçoit les données dépend entièrement de quand l'amont appelle les fonctions de rappel `accept` et `interrupt`. Ce design permet à la bibliothèque de gérer élégamment les flux de données en temps réel, les grands ensembles de données et les sources de données asynchrones.
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
12
 
9
- ## Installation
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
17
 
11
- ```bash
12
- npm install semantic-typescript
13
- ```
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.
14
19
 
15
- ## Types de base
16
-
17
- | Type | Description |
18
- |------|-------------|
19
- | `Invalid<T>` | Type qui étend `null` ou `undefined` |
20
- | `Valid<T>` | Type qui exclut `null` et `undefined` |
21
- | `MaybeInvalid<T>` | Type qui peut être `null` ou `undefined` |
22
- | `Primitive` | Collection de types primitifs |
23
- | `MaybePrimitive<T>` | Type qui peut être un type primitif |
24
- | `OptionalSymbol` | Identificateur de symbole de la classe `Optional` |
25
- | `SemanticSymbol` | Identificateur de symbole de la classe `Semantic` |
26
- | `CollectorsSymbol` | Identificateur de symbole de la classe `Collector` |
27
- | `CollectableSymbol` | Identificateur de symbole de la classe `Collectable` |
28
- | `OrderedCollectableSymbol` | Identificateur de symbole de la classe `OrderedCollectable` |
29
- | `WindowCollectableSymbol` | Identificateur de symbole de la classe `WindowCollectable` |
30
- | `StatisticsSymbol` | Identificateur de symbole de la classe `Statistics` |
31
- | `NumericStatisticsSymbol` | Identificateur de symbole de la classe `NumericStatistics` |
32
- | `BigIntStatisticsSymbol` | Identificateur de symbole de la classe `BigIntStatistics` |
33
- | `UnorderedCollectableSymbol` | Identificateur de symbole de la classe `UnorderedCollectable` |
34
-
35
- ## Interfaces fonctionnelles
36
-
37
- | Interface | Description |
38
- |-----------|-------------|
39
- | `Runnable` | Fonction sans paramètres et sans valeur de retour |
40
- | `Supplier<R>` | Fonction sans paramètres retournant `R` |
41
- | `Functional<T, R>` | Fonction de transformation à un seul paramètre |
42
- | `BiFunctional<T, U, R>` | Fonction de transformation à deux paramètres |
43
- | `TriFunctional<T, U, V, R>` | Fonction de transformation à trois paramètres |
44
- | `Predicate<T>` | Fonction de prédicat à un seul paramètre |
45
- | `BiPredicate<T, U>` | Fonction de prédicat à deux paramètres |
46
- | `TriPredicate<T, U, V>` | Fonction de prédicat à trois paramètres |
47
- | `Consumer<T>` | Fonction de consommateur à un seul paramètre |
48
- | `BiConsumer<T, U>` | Fonction de consommateur à deux paramètres |
49
- | `TriConsumer<T, U, V>` | Fonction de consommateur à trois paramètres |
50
- | `Comparator<T>` | Fonction de comparaison à deux paramètres |
51
- | `Generator<T>` | Fonction génératrice (noyau et base) |
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.
52
22
 
53
- ```typescript
54
- // Exemples d'utilisation des types
55
- let predicate: Predicate<number> = (n: number): boolean => n > 0;
56
- let mapper: Functional<string, number> = (text: string): number => text.length;
57
- let comparator: Comparator<number> = (a: number, b: number): number => a - b;
58
- ```
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.
59
25
 
60
- ## Gardiens de type
61
-
62
- | Fonction | Description | Complexité temporelle | Complexité spatiale |
63
- |------|------|------------|------------|
64
- | `validate<T>(t: MaybeInvalid<T>): t is T` | Vérifie que la valeur n'est pas null ou undefined | O(1) | O(1) |
65
- | `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | Vérifie que la valeur est null ou undefined | O(1) | O(1) |
66
- | `isBoolean(t: unknown): t is boolean` | Vérifie si c'est un booléen | O(1) | O(1) |
67
- | `isString(t: unknown): t is string` | Vérifie si c'est une chaîne | O(1) | O(1) |
68
- | `isNumber(t: unknown): t is number` | Vérifie si c'est un nombre | O(1) | O(1) |
69
- | `isFunction(t: unknown): t is Function` | Vérifie si c'est une fonction | O(1) | O(1) |
70
- | `isObject(t: unknown): t is object` | Vérifie si c'est un objet | O(1) | O(1) |
71
- | `isSymbol(t: unknown): t is symbol` | Vérifie si c'est un symbole | O(1) | O(1) |
72
- | `isBigint(t: unknown): t is bigint` | Vérifie si c'est un BigInt | O(1) | O(1) |
73
- | `isPrimitive(t: unknown): t is Primitive` | Vérifie si c'est un type primitif | O(1) | O(1) |
74
- | `isIterable(t: unknown): t is Iterable<unknown>` | Vérifie si c'est un objet itérable | O(1) | O(1) |
75
- | `isOptional(t: unknown): t is Optional<unknown>` | Vérifie si c'est une instance d'Optional | O(1) | O(1) |
76
- | `isSemantic(t: unknown): t is Semantic<unknown>` | Vérifie si c'est une instance de Semantic | O(1) | O(1) |
77
- | `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Vérifie si c'est une instance de Collector | O(1) | O(1) |
78
- | `isCollectable(t: unknown): t is Collectable<unknown>` | Vérifie si c'est une instance de Collectable | O(1) | O(1) |
79
- | `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | Vérifie si c'est une instance de OrderedCollectable | O(1) | O(1) |
80
- | `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | Vérifie si c'est une instance de WindowCollectable | O(1) | O(1) |
81
- | `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | Vérifie si c'est une instance de UnorderedCollectable | O(1) | O(1) |
82
- | `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Vérifie si c'est une instance de Statistics | O(1) | O(1) |
83
- | `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | Vérifie si c'est une instance de NumericStatistics | O(1) | O(1) |
84
- | `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | Vérifie si c'est une instance de BigIntStatistics | O(1) | O(1) |
85
- | `isPromise(t: unknown): t is Promise<unknown>` | Vérifie si c'est un objet Promise | O(1) | O(1) |
86
- | `isAsync(t: unknown): t is AsyncFunction` | Vérifie si c'est une AsyncFunction | O(1) | O(1) |
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.
87
28
 
88
- ```typescript
89
- // Exemples d'utilisation des gardiens de type
90
- let value: unknown = "hello";
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.
91
31
 
92
- if (isString(value)) {
93
- console.log(value.length); // Sécurité de type, value est inféré comme une chaîne
94
- }
95
-
96
- if (isOptional(someValue)) {
97
- someValue.ifPresent((value): void => console.log(val));
98
- }
99
-
100
- if(isIterable(value)){
101
- // Sécurité de type, maintenant c'est un objet itérable.
102
- for(let item of value){
103
- console.log(item);
104
- }
105
- }
106
- ```
107
-
108
- ## Fonctions utilitaires
109
-
110
- | Fonction | Description | Complexité temporelle | Complexité spatiale |
111
- |------|------|------------|------------|
112
- | `useCompare<T>(t1: T, t2: T): number` | Fonction de comparaison générique | O(1) | O(1) |
113
- | `useRandom<T = number \| bigint>(index: T): T` | Générateur de nombres pseudo-aléatoires | O(log n) | O(1) |
114
-
115
- ```typescript
116
- // Exemples d'utilisation des fonctions utilitaires
117
- let numbers: Array<number> = [3, 1, 4, 1, 5];
118
- numbers.sort(useCompare); // [1, 1, 3, 4, 5]
119
-
120
- let randomNum = useRandom(42); // Nombre aléatoire basé sur une graine
121
- ```
122
-
123
- ## Méthodes de fabrique
124
-
125
- ### Méthodes de fabrique d'Optional
126
-
127
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
128
- |------|------|------------|------------|
129
- | `Optional.empty<T>()` | Crée un Optional vide | O(1) | O(1) |
130
- | `Optional.of<T>(value)` | Crée un Optional contenant une valeur | O(1) | O(1) |
131
- | `Optional.ofNullable<T>(value)` | Crée un Optional potentiellement vide | O(1) | O(1) |
132
- | `Optional.ofNonNull<T>(value)` | Crée un Optional non vide | O(1) | O(1) |
133
-
134
- ```typescript
135
- // Exemples d'utilisation d'Optional
136
- let emptyOpt: Optional<number> = Optional.empty();
137
- let presentOpt: Optional<number> = Optional.of(42);
138
- let nullableOpt: Optional<string> = Optional.ofNullable<string>(null);
139
- let nonNullOpt: Optional<string> = Optional.ofNonNull("hello");
140
-
141
- presentOpt.ifPresent((value: number): void => console.log(value)); // Affiche 42
142
- console.log(emptyOpt.get(100)); // Affiche 100
143
- ```
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
144
38
 
145
- ### Méthodes de fabrique de Collector
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.
146
41
 
147
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
148
- |------|------|------------|------------|
149
- | `Collector.full(identity, accumulator, finisher)` | Crée un Collector complet | O(1) | O(1) |
150
- | `Collector.shortable(identity, interruptor, accumulator, finisher)` | Crée un Collector interruptible | O(1) | O(1) |
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.
151
47
 
152
- ```typescript
153
- // Exemples de conversion de Collector
154
- let numbers: Semantic<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
155
-
156
- // Priorité de performance : utilisez un Collector non ordonné pour obtenir la meilleure performance
157
- let unordered: UnorderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
158
- .filter((n: number): boolean => n > 3)
159
- .toUnordered(); // Meilleure performance
160
-
161
- // Tri nécessaire : utilisez un Collector ordonné
162
- let ordered: OrderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
163
- .sorted();
164
-
165
- // Compte le nombre d'éléments
166
- let count: Collector<number, number, number> = Collector.full(
167
- (): number => 0, // Valeur initiale
168
- (accumulator: number, element: number): number => accumulator + element, // Accumuler
169
- (accumulator: number): number => accumulator // Terminer
170
- );
171
- count.collect(from([1,2,3,4,5])); // Compte depuis un flux
172
- count.collect([1,2,3,4,5]); // Compte depuis un objet itérable
173
-
174
- let find: Optional<number> = Collector.shortable(
175
- (): Optional<number> => Optional.empty(), // Valeur initiale
176
- (element: number, index: bigint, accumulator: Optional<number>): Optional<number> => accumulator.isPresent(), // Interruption
177
- (accumulator: Optional<number>, element: number, index: bigint): Optional<number> => Optional.of(element), // Accumuler
178
- (accumulator: Optional<number>): Optional<number> => accumulator // Terminer
179
- );
180
- find.collect(from([1,2,3,4,5])); // Trouve le premier élément
181
- find.collect([1,2,3,4,5]); // Trouve le premier élément
48
+ ## Installation
49
+ ```bash
50
+ npm install semantic-typescript
182
51
  ```
183
52
 
184
- ### Méthodes de fabrique de Semantic
185
-
186
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
187
- |------|------|------------|------------|
188
- | `animationFrame(period: number, delay: number = 0)` | Crée un flux de trames d'animation basé sur le temps | O(1)* | O(1) |
189
- | `blob(blob, chunkSize)` | Crée un flux à partir d'un Blob | O(n) | O(chunkSize) |
190
- | `empty<E>()` | Crée un flux vide | O(1) | O(1) |
191
- | `fill<E>(element, count)` | Crée un flux rempli | O(n) | O(1) |
192
- | `from<E>(iterable)` | Crée un flux à partir d'un objet itérable | O(1) | O(1) |
193
- | `interval(period, delay?)` | Crée un flux d'intervalle de temps | O(1)* | O(1) |
194
- | `iterate<E>(generator)` | Crée un flux à partir d'un générateur | O(1) | O(1) |
195
- | `range(start, end, step)` | Crée un flux de plage numérique | O(n) | O(1) |
196
- | `websocket(websocket)` | Crée un flux à partir d'un WebSocket | O(1) | O(1) |
53
+ ## Concepts de base en pratique
197
54
 
55
+ ### 1. Création de flux (Semantic)
56
+ Les flux peuvent être créés à partir de diverses sources en utilisant des fonctions d'usine.
198
57
  ```typescript
199
- // Exemples de méthodes de fabrique de Semantic
200
-
201
- // Crée un flux à partir d'un Blob (lecture par morceaux)
202
- blob(someBlob, 1024n)
203
- .toUnordered()
204
- .write(WritableStream)
205
- .then(callback) // Écriture du flux réussie
206
- .catch(callback); // Échec de l'écriture du flux
207
-
208
- // Crée un flux vide, ne sera exécuté qu'une fois concaténé avec d'autres flux
209
- empty<string>()
210
- .toUnordered()
211
- .join(); // []
212
-
213
- // Crée un flux rempli
214
- let filledStream = fill("hello", 3); // "hello", "hello", "hello"
215
-
216
- // Crée un flux d'intervalle avec un délai initial de 2 secondes et une période d'exécution de 5 secondes, implémenté sur un mécanisme de minuterie ; peut subir un décalage temporel en raison des limites de précision de la planification système.
217
- let intervalStream = interval(5000, 2000);
218
-
219
- // Crée un flux à partir d'un objet itérable
220
- let numberStream = from([1, 2, 3, 4, 5]);
221
- let stringStream = from(new Set(["Alex", "Bob"]));
222
-
223
- // Crée un flux de plage
224
- let rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
225
-
226
- // Flux d'événements WebSocket
227
- let ws = new WebSocket("ws://localhost:8080");
228
- websocket(ws)
229
- .filter((event): boolean => event.type === "message") // Écoute uniquement les événements de message
230
- .toUnordered() // Les événements sont généralement non ordonnés
231
- .forEach((event): void => receive(event)); // Réception des messages
232
- ```
233
-
234
- ## Méthodes de classe Semantic
235
-
236
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
237
- |------|------|------------|------------|
238
- | `concat(other)` | Concatène deux flux | O(n) | O(1) |
239
- | `distinct()` | Supprime les doublons | O(n) | O(n) |
240
- | `distinct(comparator)` | Supprime les doublons en utilisant un comparateur | O(n²) | O(n) |
241
- | `dropWhile(predicate)` | Abandonne les éléments satisfaisant la condition | O(n) | O(1) |
242
- | `filter(predicate)` | Filtre les éléments | O(n) | O(1) |
243
- | `flat(mapper)` | Aplatissement de la carte | O(n × m) | O(1) |
244
- | `flatMap(mapper)` | Aplatissement de la carte vers un nouveau type | O(n × m) | O(1) |
245
- | `limit(n)` | Limite le nombre d'éléments | O(n) | O(1) |
246
- | `map(mapper)` | Transformation de la carte | O(n) | O(1) |
247
- | `peek(consumer)` | Jeter un œil aux éléments | O(n) | O(1) |
248
- | `redirect(redirector)` | Rediriger l'index | O(n) | O(1) |
249
- | `reverse()` | Inverse le flux | O(n) | O(1) |
250
- | `shuffle()` | Mélange aléatoirement | O(n) | O(1) |
251
- | `shuffle(mapper)` | Mélange en utilisant un mappeur | O(n) | O(1) |
252
- | `skip(n)` | Ignore les n premiers éléments | O(n) | O(1) |
253
- | `sorted()` | Trie | O(n log n) | O(n) |
254
- | `sorted(comparator)` | Trie en utilisant un comparateur | O(n log n) | O(n) |
255
- | `sub(start, end)` | Obtient un sous-flux | O(n) | O(1) |
256
- | `takeWhile(predicate)` | Prend les éléments satisfaisant la condition | O(n) | O(1) |
257
- | `translate(offset)` | Traduire l'index | O(n) | O(1) |
258
- | `translate(translator)` | Traduire l'index à l'aide d'un traducteur | O(n) | O(1) |
58
+ import { useFrom, useInterval, useDocument } from 'semantic-typescript';
259
59
 
260
- ```typescript
261
- // Exemples d'opérations Semantic
262
- let result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
263
- .filter((n: number): boolean => n % 2 === 0) // Filtre les nombres pairs
264
- .map((n: number): number => n * 2) // Multiplie par 2
265
- .skip(1) // Ignore le premier
266
- .limit(3) // Limite à 3 éléments
267
- .toUnordered() // Convertit en collecteur non ordonné
268
- .toArray(); // Convertit en tableau
269
- // Résultat: [8, 12, 20]
270
-
271
- // Exemple d'opération complexe
272
- let complexResult = range(1, 100, 1)
273
- .flatMap((n: number): Semantics<number> => from([n, n * 2])) // Mappe chaque élément à deux
274
- .distinct() // Supprime les doublons
275
- .shuffle() // Mélange l'ordre
276
- .takeWhile((n: number): boolean => n < 50) // Prend les éléments inférieurs à 50
277
- .toOrdered() // Convertit en collecteur ordonné
278
- .toArray(); // Convertit en tableau
279
- ```
60
+ // Depuis un tableau statique
61
+ const staticStream = useFrom([1, 2, 3, 4, 5]);
280
62
 
281
- ## Méthodes de conversion Semantic
63
+ // Depuis un générateur asynchrone
64
+ const asyncStream = useFrom(async function*() {
65
+ yield 1;
66
+ yield 2;
67
+ });
282
68
 
283
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
284
- |------------|------------|------------|------------|
285
- | `sorted()` | Convertit en collecteur ordonné | O(n log n) | O(n) |
286
- | `toUnordered()` | Convertit en collecteur non ordonné | O(1) | O(1) |
287
- | `toOrdered()` | Convertit en collecteur ordonné | O(1) | O(1) |
288
- | `toNumericStatistics()` | Convertit en statistiques numériques | O(n) | O(1) |
289
- | `toBigintStatistics()` | Convertit en statistiques BigInt | O(n) | O(1) |
290
- | `toWindow()` | Convertit en collecteur de fenêtre | O(1) | O(1) |
291
- | `toCollectable()` | Convertit en `UnorderdCollectable` | O(n) | O(1) |
292
- | `toCollectable(mapper)` | Convertit en collecteur personnalisé | O(n) | O(1) |
69
+ // Un flux basé sur le temps
70
+ const tickStream = useInterval(1000); // émet toutes les secondes
293
71
 
294
- ```typescript
295
- // Convertit en un tableau trié ascendant
296
- from([6, 4, 3, 5, 2]) // Crée un flux
297
- .sorted() // Trie le flux dans l'ordre croissant
298
- .toArray(); // [2, 3, 4, 5, 6]
299
-
300
- // Convertit en un tableau trié décroissant
301
- from([6, 4, 3, 5, 2]) // Crée un flux
302
- .soted((a: number, b: number): number => b - a) // Trie le flux dans l'ordre décroissant
303
- .toArray(); // [6, 5, 4, 3, 2]
304
-
305
- // Redirige vers un tableau inversé
306
- from([6, 4, 3, 5, 2])
307
- .redirect((element, index): bigint => -index) // Redirige vers l'ordre inverse
308
- .toOrderd() // Garde l'ordre redirigé
309
- .toArray(); // [2, 5, 3, 4, 6]
310
-
311
- // Ignore les redirections pour inverser le tableau
312
- from([6, 4, 3, 5, 2])
313
- .redirect((element, index): bigint => -index) // Redirige vers l'ordre inverse
314
- .toUnorderd() // Ignore l'ordre redirigé. Cette opération ignorera `redirect`, `reverse`, `shuffle` et `translate`
315
- .toArray(); // [2, 5, 3, 4, 6]
316
-
317
- // Inverse le flux dans un tableau
318
- from([6, 4, 3, 5, 2])
319
- .reverse() // Inverse le flux
320
- .toOrdered() // Garantit l'ordre inversé
321
- .toArray(); // [2, 5, 3, 4, 6]
322
-
323
- // Remplace le flux mélangé dans un tableau
324
- from([6, 4, 3, 5, 2])
325
- .shuffle() // Mélange le flux
326
- .sorted() // Remplace l'ordre mélangé. Cette opération écrasera `redirect`, `reverse`, `shuffle` et `translate`
327
- .toArray(); // [2, 5, 3, 4, 6]
328
-
329
- // Convertit en collecteur de fenêtre
330
- from([6, 4, 3, 5, 2])
331
- .toWindow();
332
-
333
- // Convertit en statistiques numériques
334
- from([6, 4, 3, 5, 2])
335
- .toNumericStatistics();
336
-
337
- // Convertit en statistiques BigInt
338
- from([6n, 4n, 3n, 5n, 2n])
339
- .toBigintStatistics();
340
-
341
- // Définit un collecteur personnalisé pour collecter des données
342
- let customizedCollector = from([1, 2, 3, 4, 5])
343
- .toCollectable((generator: Generator<E>) => new CustomizedCollector(generator));
72
+ // Un flux d'événements DOM (voir note cruciale ci-dessous)
73
+ const clickStream = useDocument('click');
344
74
  ```
345
75
 
346
- ## Méthodes de collection Collectable
347
-
348
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
349
- |------|------|------------|------------|
350
- | `anyMatch(predicate)` | Si un élément quelconque correspond | O(n) | O(1) |
351
- | `allMatch(predicate)` | Si tous les éléments correspondent | O(n) | O(1) |
352
- | `count()` | Comptage des éléments | O(n) | O(1) |
353
- | `isEmpty()` | Si c'est vide | O(1) | O(1) |
354
- | `findAny()` | Trouve n'importe quel élément | O(n) | O(1) |
355
- | `findFirst()` | Trouve le premier élément | O(n) | O(1) |
356
- | `findLast()` | Trouve le dernier élément | O(n) | O(1) |
357
- | `forEach(action)` | Itère sur tous les éléments | O(n) | O(1) |
358
- | `group(classifier)` | Regroupe par classifieur | O(n) | O(n) |
359
- | `groupBy(keyExtractor, valueExtractor)` | Regroupe par extracteurs de clé-valeur | O(n) | O(n) |
360
- | `join()` | Jointure en tant que chaîne | O(n) | O(n) |
361
- | `join(delimiter)` | Jointure en utilisant un délimiteur | O(n) | O(n) |
362
- | `nonMatch(predicate)` | Si aucun élément ne correspond | O(n) | O(1) |
363
- | `partition(count)` | Partitionne par nombre | O(n) | O(n) |
364
- | `partitionBy(classifier)` | Partitionne par classifieur | O(n) | O(n) |
365
- | `reduce(accumulator)` | Opération de réduction | O(n) | O(1) |
366
- | `reduce(identity, accumulator)` | Réduction avec valeur initiale | O(n) | O(1) |
367
- | `toArray()` | Convertit en tableau | O(n) | O(n) |
368
- | `toMap(keyExtractor, valueExtractor)` | Convertit en Map | O(n) | O(n) |
369
- | `toSet()` | Convertit en Set | O(n) | O(n) |
370
- | `write(stream)` | Écrit dans le flux | O(n) | O(1) |
371
-
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.
372
78
  ```typescript
373
- // Exemples d'opérations Collectable
374
- const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
375
- .filter((n: number): boolean => n % 2 === 0)
376
- .toOrdered();
377
-
378
- // Vérifications de correspondance
379
- console.log(data.anyMatch((n: number): boolean => n > 5)); // true
380
- console.log(data.allMatch((n: number): boolean => n < 20)); // true
381
-
382
- // Opérations de recherche
383
- data.findFirst().ifPresent((n: number): void => console.log(n)); // 2
384
- data.findAny().ifPresent((n: number): void => console.log(n)); // N'importe quel élément
385
-
386
- // Opérations de regroupement
387
- const grouped = data.groupBy(
388
- (n: number): string => (n > 5 ? "grand" : "petit"),
389
- (n: number): number => n * 2
390
- ); // {petit: [4, 8], grand: [12, 16, 20]}
391
-
392
- // Opérations de réduction
393
- const sum = data.reduce(0, (acc, n) => acc + n); // 30
394
-
395
- // Opérations de sortie
396
- data.join(", "); // "[2, 4, 6, 8, 10]"
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
397
85
  ```
398
86
 
399
- ## Méthodes d'analyse statistique
400
-
401
- ### Méthodes de NumericStatistics
402
-
403
- | Méthode | Description | Complexité temporelle | Complexité spatiale |
404
- |------|------|------------|------------|
405
- | `range()` | Plage | O(n) | O(1) |
406
- | `variance()` | Variance | O(n) | O(1) |
407
- | `standardDeviation()` | Écart-type | O(n) | O(1) |
408
- | `mean()` | Moyenne | O(n) | O(1) |
409
- | `median()` | Médiane | O(n log n) | O(n) |
410
- | `mode()` | Mode | O(n) | O(n) |
411
- | `frequency()` | Distribution de fréquence | O(n) | O(n) |
412
- | `summate()` | Somme | O(n) | O(1) |
413
- | `quantile(quantile)` | Quantile | O(n log n) | O(n) |
414
- | `interquartileRange()` | Intervalle interquartile | O(n log n) | O(n) |
415
- | `skewness()` | Asymétrie | O(n) | O(1) |
416
- | `kurtosis()` | Curtosis | O(n) | O(1) |
417
-
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.
418
89
  ```typescript
419
- // Exemples d'analyse statistique
420
- const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
421
- .toNumericStatistics();
422
-
423
- console.log("Moyenne:", numbers.mean()); // 5.5
424
- console.log("Médiane:", numbers.median()); // 5.5
425
- console.log("Écart-type:", numbers.standardDeviation()); // ~2.87
426
- console.log("Somme:", numbers.summate()); // 55
427
-
428
- // Analyse statistique utilisant des mappers
429
- const objects = from([
430
- { value: 10 },
431
- { value: 20 },
432
- { value: 30 }
433
- ]).toNumericStatistics();
434
- console.log("Moyenne mappée:", objects.mean(obj => obj.value)); // 20
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
+ );
435
104
  ```
436
105
 
437
- ## Guide de sélection des performances
438
-
439
- ### Choisissez un collecteur non ordonné (performance prioritaire)
440
-
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.
441
108
  ```typescript
442
- // Lorsque la garantie d'ordre n'est pas nécessaire, utilisez un collecteur non ordonné pour obtenir la meilleure performance
443
- let highPerformance = data
444
- .filter(predicate)
445
- .map(mapper)
446
- .toUnordered(); // Meilleure performance
109
+ import { useDocument } from 'semantic-typescript';
110
+
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();
116
+
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();
122
+
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();
447
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)`.
448
130
 
449
- ### Choisissez un collecteur ordonné (ordre requis)
450
-
131
+ ### 5. Tirer parti des statistiques
451
132
  ```typescript
452
- // Lorsque l'ordre des éléments doit être maintenu, utilisez un collecteur ordonné
453
- let ordered = data.sorted(comparator);
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}`);
454
139
  ```
455
140
 
456
- ### Choisissez un collecteur de fenêtre (opérations de fenêtre)
457
-
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
458
172
  ```typescript
459
- // Lorsque des opérations de fenêtre sont nécessaires
460
- let windowed: WindowCollectable<number> = data
461
- .toWindow()
462
- .slide(5n, 2n); // Fenêtre coulissante
463
- ```
464
-
465
- ### Choisissez une analyse statistique (calculs numériques)
173
+ import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
466
174
 
467
- ```typescript
468
- // Lorsqu'une analyse statistique est nécessaire
469
- let statistics: NumericStatistics<number> = data
470
- .toNumericStatistics(); // Statistiques numériques
175
+ interface Transaction {
176
+ id: number;
177
+ amount: number;
178
+ category: string;
179
+ }
471
180
 
472
- let bigIntStatistics: BigintStatistics<bigint> = data
473
- .toBigintStatistics(); // Statistiques BigInt
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
+ );
198
+
199
+ console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
474
200
  ```
475
201
 
476
- [GitHub](https://github.com/eloyhere/semantic-typescript)
477
- [NPMJS](https://www.npmjs.com/package/semantic-typescript)
478
-
479
- ## Notes importantes
480
-
481
- 1. **Impact des opérations de tri**: Dans les collecteurs ordonnés, l'opération `sorted()` remplace les effets de `redirect`, `translate`, `shuffle`, `reverse`.
482
- 2. **Considérations de performance**: Si la garantie d'ordre n'est pas nécessaire, privilégiez l'utilisation de `toUnordered()` pour une meilleure performance.
483
- 3. **Utilisation de la mémoire**: Les opérations de tri nécessitent un espace supplémentaire de O(n).
484
- 4. **Données en temps réel**: Les flux Semantic conviennent pour le traitement de données en temps réel et prennent en charge les sources de données asynchrones.
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.
485
203
 
486
- Cette bibliothèque offre aux développeurs TypeScript des capacités de streaming puissantes et flexibles, combinant les avantages de la programmation fonctionnelle avec des garanties de sécurité de types.
204
+ [![GitHub](./GitHub.png)](https://github.com/eloyhere/semantic-typescript) [![NPM](./NPM.png)](https://www.npmjs.com/package/semantic-typescript)