semantic-typescript 0.5.3 → 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 (42) 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 +71 -37
  6. package/dist/factory.js +443 -262
  7. package/dist/guard.d.ts +24 -14
  8. package/dist/guard.js +73 -19
  9. package/dist/hook.d.ts +6 -6
  10. package/dist/hook.js +2 -2
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +2 -2
  13. package/dist/optional.d.ts +2 -2
  14. package/dist/symbol.d.ts +19 -10
  15. package/dist/symbol.js +19 -10
  16. package/dist/synchronous/collector.d.ts +232 -0
  17. package/dist/{collector.js → synchronous/collector.js} +160 -151
  18. package/dist/{semantic.d.ts → synchronous/semantic.d.ts} +111 -120
  19. package/dist/{semantic.js → synchronous/semantic.js} +299 -337
  20. package/dist/utility.d.ts +7 -1
  21. package/dist/utility.js +1 -0
  22. package/package.json +1 -1
  23. package/readme.cn.md +158 -697
  24. package/readme.de.md +163 -432
  25. package/readme.es.md +163 -433
  26. package/readme.fr.md +162 -444
  27. package/readme.jp.md +162 -442
  28. package/readme.kr.md +161 -430
  29. package/readme.md +157 -1009
  30. package/readme.ru.md +161 -426
  31. package/readme.tw.md +161 -436
  32. package/dist/collector.d.ts +0 -236
  33. package/dist/main.d.ts +0 -1
  34. package/dist/main.js +0 -4
  35. package/dist/map.d.ts +0 -76
  36. package/dist/map.js +0 -245
  37. package/dist/node.d.ts +0 -182
  38. package/dist/node.js +0 -918
  39. package/dist/set.d.ts +0 -19
  40. package/dist/set.js +0 -65
  41. package/dist/tree.d.ts +0 -82
  42. package/dist/tree.js +0 -257
package/readme.de.md CHANGED
@@ -1,483 +1,214 @@
1
- # Semantic-TypeScript Stream Processing Library
1
+ # Semantic-TypeScript: Eine bahnbrechende Stream-Processing-Bibliothek
2
2
 
3
- ## Einleitung
3
+ ## Einführung
4
+ Semantic-TypeScript stellt einen bedeutenden Fortschritt in der Stream-Processing-Technologie dar und vereint die effektivsten Konzepte aus JavaScript GeneratorFunctions, Java Streams und Datenbank-Indizierungs-Paradigmen. Ihr grundlegendes Designprinzip zielt darauf ab, durch ausgeklügelte verzögerte Auswertung (Lazy Evaluation) und intelligente Indizierung äußerst effiziente Datenverarbeitungspipelines zu konstruieren. Die Bibliothek bietet eine streng typensichere, funktional reine Streaming-Operation-Erfahrung, die speziell für die moderne TypeScript- und JavaScript-Entwicklung entwickelt wurde.
4
5
 
5
- Semantic-TypeScript ist eine moderne Stream-Verarbeitungsbibliothek, inspiriert von JavaScript GeneratorFunction, Java Stream und MySQL Index. Seine Kernphilosophie basiert auf dem Aufbau effizienter Datenverarbeitungspipelines mit Hilfe von Datenindizierung und bietet eine typsichere, funktionsbasierte Streaming-Benutzererfahrung für Frontend-Entwicklung.
6
+ Im Gegensatz zu herkömmlichen synchronen Verarbeitungsarchitekturen implementiert Semantic-TypeScript ein einheitliches Modell, das sowohl synchrone (Iterable) als auch asynchrone (AsyncIterable) Datenquellen elegant behandelt. Während der Stream-Erzeugung werden der Fluss und die Beendigung von Daten präzise durch Callback-Mechanismen gesteuert, was es der Bibliothek ermöglicht, mit außergewöhnlicher Anmut zu arbeiten:
6
7
 
7
- Im Gegensatz zur traditionellen synchronen Verarbeitung verwendet Semantic ein asynchrones Verarbeitungsmodell. Beim Erstellen eines Datenstroms hängt die Zeit, zu der das Terminal Daten empfängt, vollständig davon ab, wann der Upstream die `accept`- und `interrupt`-Callback-Funktionen aufruft. Dieses Design ermöglicht es der Bibliothek, Echtzeitdatenströme, große Datensätze und asynchrone Datenquellen elegant zu verarbeiten.
8
+ - Echtzeit-Datenströme (DOM-Events, WebSockets, Intervalle) mit deterministischer Kontrolle
9
+ - Große Datensätze über speichereffiziente, verzögerte Pipelines
10
+ - Komplexe Datentransformationen mit einer fließenden, deklarativen API
8
11
 
9
- ## Installation
12
+ Der innovative Ansatz der Bibliothek überdenkt grundlegend, wie Entwickler mit Datenfolgen interagieren, und bietet beispiellose Leistungsmerkmale und Entwicklerfreundlichkeit in einem einzigen, kohärenten Paket.
10
13
 
11
- ```bash
12
- npm install semantic-typescript
13
- ```
14
+ ## Kernphilosophie: Trennung von Definition und Ausführung
15
+ Eine zentrale architektonische Erkenntnis von Semantic-TypeScript ist die klare Trennung zwischen der Definition eines Streams und seiner Ausführung:
14
16
 
15
- ## Grundlegende Typen
16
-
17
- | Typ | Beschreibung |
18
- |------|-------------|
19
- | `Invalid<T>` | Typ, der sich von `null` oder `undefined` ableitet |
20
- | `Valid<T>` | Typ, der `null` und `undefined` ausschließt |
21
- | `MaybeInvalid<T>` | Typ, der `null` oder `undefined` sein kann |
22
- | `Primitive` | Sammlung primitiver Typen |
23
- | `MaybePrimitive<T>` | Typ, der ein primitiver Typ sein kann |
24
- | `OptionalSymbol` | Symbolbezeichner der `Optional`-Klasse |
25
- | `SemanticSymbol` | Symbolbezeichner der `Semantic`-Klasse |
26
- | `CollectorsSymbol` | Symbolbezeichner der `Collector`-Klasse |
27
- | `CollectableSymbol` | Symbolbezeichner der `Collectable`-Klasse |
28
- | `OrderedCollectableSymbol` | Symbolbezeichner der `OrderedCollectable`-Klasse |
29
- | `WindowCollectableSymbol` | Symbolbezeichner der `WindowCollectable`-Klasse |
30
- | `StatisticsSymbol` | Symbolbezeichner der `Statistics`-Klasse |
31
- | `NumericStatisticsSymbol` | Symbolbezeichner der `NumericStatistics`-Klasse |
32
- | `BigIntStatisticsSymbol` | Symbolbezeichner der `BigIntStatistics`-Klasse |
33
- | `UnorderedCollectableSymbol` | Symbolbezeichner der `UnorderedCollectable`-Klasse |
34
-
35
- ## Funktionsorientierte Schnittstellen
36
-
37
- | Schnittstelle | Beschreibung |
38
- |-----------|-------------|
39
- | `Runnable` | Funktion ohne Parameter und ohne Rückgabewert |
40
- | `Supplier<R>` | Funktion ohne Parameter, die `R` zurückgibt |
41
- | `Functional<T, R>` | Einzelparameter-Transformationsfunktion |
42
- | `BiFunctional<T, U, R>` | Zweiparameter-Transformationsfunktion |
43
- | `TriFunctional<T, U, V, R>` | Dreiparameter-Transformationsfunktion |
44
- | `Predicate<T>` | Einzelparameter-Prädikatfunktion |
45
- | `BiPredicate<T, U>` | Zweiparameter-Prädikatfunktion |
46
- | `TriPredicate<T, U, V>` | Dreiparameter-Prädikatfunktion |
47
- | `Consumer<T>` | Einzelparameter-Consumerfunktion |
48
- | `BiConsumer<T, U>` | Zweiparameter-Consumerfunktion |
49
- | `TriConsumer<T, U, V>` | Dreiparameter-Consumerfunktion |
50
- | `Comparator<T>` | Zweiparameter-Vergleichsfunktion |
51
- | `Generator<T>` | Generatorfunktion (Kern und Basis) |
17
+ - **Semantic<E>**: Eine unveränderliche, verzögerte Blaupause einer Datentransformationspipeline. Sie definiert, welche Operationen (Filter, Map usw.) ausgeführt werden.
18
+ - **Collectable<E>**: Eine materialisierte, ausführbare Ansicht des Streams. Sie wird von einem Semantic erhalten und stellt alle Terminaloperationen (collect, forEach usw.) zur Ausführung der Pipeline und Erzeugung eines Ergebnisses bereit.
52
19
 
53
- ```typescript
54
- // Beispiel für die Verwendung von Typen
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
- ```
20
+ Diese Trennung erzwingt ein klares mentales Modell und ermöglicht leistungsstarke Optimierungen, wie z. B. die Auswahl eines UnorderedCollectable, um unnötige Sortiervorgänge für maximale Geschwindigkeit zu überspringen.
59
21
 
60
- ## Typguards
61
-
62
- | Funktion | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
63
- |------|------|------------|------------|
64
- | `validate<T>(t: MaybeInvalid<T>): t is T` | Überprüft, ob der Wert nicht null oder undefined ist | O(1) | O(1) |
65
- | `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | Überprüft, ob der Wert null oder undefined ist | O(1) | O(1) |
66
- | `isBoolean(t: unknown): t is boolean` | Überprüft, ob es sich um einen booleschen Wert handelt | O(1) | O(1) |
67
- | `isString(t: unknown): t is string` | Überprüft, ob es sich um einen String handelt | O(1) | O(1) |
68
- | `isNumber(t: unknown): t is number` | Überprüft, ob es sich um eine Zahl handelt | O(1) | O(1) |
69
- | `isFunction(t: unknown): t is Function` | Überprüft, ob es sich um eine Funktion handelt | O(1) | O(1) |
70
- | `isObject(t: unknown): t is object` | Überprüft, ob es sich um ein Objekt handelt | O(1) | O(1) |
71
- | `isSymbol(t: unknown): t is symbol` | Überprüft, ob es sich um ein Symbol handelt | O(1) | O(1) |
72
- | `isBigint(t: unknown): t is bigint` | Überprüft, ob es sich um ein BigInt handelt | O(1) | O(1) |
73
- | `isPrimitive(t: unknown): t is Primitive` | Überprüft, ob es sich um einen primitiven Typ handelt | O(1) | O(1) |
74
- | `isIterable(t: unknown): t is Iterable<unknown>` | Überprüft, ob es sich um ein iterierbares Objekt handelt | O(1) | O(1) |
75
- | `isOptional(t: unknown): t is Optional<unknown>` | Überprüft, ob es sich um eine Optional-Instanz handelt | O(1) | O(1) |
76
- | `isSemantic(t: unknown): t is Semantic<unknown>` | Überprüft, ob es sich um eine Semantic-Instanz handelt | O(1) | O(1) |
77
- | `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Überprüft, ob es sich um eine Collector-Instanz handelt | O(1) | O(1) |
78
- | `isCollectable(t: unknown): t is Collectable<unknown>` | Überprüft, ob es sich um eine Collectable-Instanz handelt | O(1) | O(1) |
79
- | `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | Überprüft, ob es sich um eine OrderedCollectable-Instanz handelt | O(1) | O(1) |
80
- | `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | Überprüft, ob es sich um eine WindowCollectable-Instanz handelt | O(1) | O(1) |
81
- | `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | Überprüft, ob es sich um eine UnorderedCollectable-Instanz handelt | O(1) | O(1) |
82
- | `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Überprüft, ob es sich um eine Statistics-Instanz handelt | O(1) | O(1) |
83
- | `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | Überprüft, ob es sich um eine NumericStatistics-Instanz handelt | O(1) | O(1) |
84
- | `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | Überprüft, ob es sich um eine BigIntStatistics-Instanz handelt | O(1) | O(1) |
85
- | `isPromise(t: unknown): t is Promise<unknown>` | Überprüft, ob es sich um ein Promise-Objekt handelt | O(1) | O(1) |
86
- | `isAsync(t: unknown): t is AsyncFunction` | Überprüft, ob es sich um eine AsyncFunction handelt | O(1) | O(1) |
22
+ ## Warum Semantic-TypeScript wählen?
23
+ Die Wahl der richtigen Bibliothek für die Verarbeitung von Datenströmen erfordert eine Abwägung zwischen Leistung, Typsicherheit und Ausdruckskraft. Semantic-TypeScript ist so konzipiert, dass es in all diesen Dimensionen herausragt.
87
24
 
88
- ```typescript
89
- // Beispiel für die Verwendung von Typguards
90
- let value: unknown = "hello";
25
+ ### 1. Ein einheitliches, typsicheres Paradigma für alle Datenfolgen
26
+ Es bietet eine konsistente, deklarative API zur Verarbeitung jeder Datenfolge – sei es statische Arrays, Echtzeit-Ereignisse oder asynchrone Datenblöcke – und nutzt gleichzeitig die volle Leistungsfähigkeit von TypeScript, um eine Ende-zu-Ende-Typsicherheit zu gewährleisten. Dadurch wird eine ganze Klasse von Laufzeitfehlern eliminiert und die Stream-Manipulation in eine vorhersehbare, vom Compiler überprüfte Aktivität verwandelt.
91
27
 
92
- if (isString(value)) {
93
- console.log(value.length); // Typsicher, value wird als string abgeleitet
94
- }
28
+ ### 2. Kompromisslose Leistung durch intelligente Verzögerung (Lazy Evaluation)
29
+ Im Kern basiert die Bibliothek auf Lazy Evaluation. Operationen wie Filter, Map und FlatMap komponieren lediglich eine Verarbeitungspipeline; es wird keine Arbeit ausgeführt, bis eine Terminaloperation aufgerufen wird. Dies wird mit Short-Circuiting-Fähigkeiten (über limit, anyMatch oder benutzerdefinierte Unterbrechungs-Callbacks) kombiniert, wodurch die Verarbeitung vorzeitig gestoppt werden kann, was die Effizienz für große oder unendliche Ströme erheblich verbessert.
95
30
 
96
- if (isOptional(someValue)) {
97
- someValue.ifPresent((value): void => console.log(val));
98
- }
31
+ ### 3. Die Leistungsfähigkeit des `Collector<E, A, R>`-Musters
32
+ Inspiriert von Java ist das Collector-Muster der Motor der Flexibilität. Es entkoppelt die Spezifikation, wie Stream-Elemente akkumuliert werden sollen, von der Ausführung des Streams selbst. Die Bibliothek bietet eine reichhaltige Auswahl an integrierten Collectors (toArray, groupBy, summate usw.) für alltägliche Aufgaben und macht es gleichzeitig einfach, eigene komplexe, wiederverwendbare Reduktionslogiken zu implementieren. Dies ist weitaus leistungsfähiger und komponierbarer als ein fester Satz von Terminalmethoden.
99
33
 
100
- if(isIterable(value)){
101
- // Typsicher, jetzt ist es ein iterierbares Objekt.
102
- for(let item of value){
103
- console.log(item);
104
- }
105
- }
106
- ```
34
+ ### 4. Erstklassige Unterstützung für moderne Web- und asynchrone Daten
35
+ Semantic-TypeScript ist für die moderne Entwicklung konzipiert. Es bietet native Factory-Methoden für moderne Web-Quellen:
107
36
 
108
- ## Hilfsfunktionen
37
+ - `useFrom(iterable)`, `useRange()` für statische Daten
38
+ - `useInterval()`, `useAnimationFrame()` für zeitbasierte Ströme
39
+ - `useBlob()` für die blockweise Verarbeitung von Binärdaten
40
+ - `useWebSocket()`, `useDocument()`, `useWindow()` für Echtzeit-Ereignisströme
109
41
 
110
- | Funktion | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
111
- |------|------|------------|------------|
112
- | `useCompare<T>(t1: T, t2: T): number` | Allgemeine Vergleichsfunktion | O(1) | O(1) |
113
- | `useRandom<T = number \| bigint>(index: T): T` | Pseudozufallszahlengenerator | O(log n) | O(1) |
42
+ ### 5. Jenseits der grundlegenden Aggregation: Integrierte statistische Analyse
43
+ Gehen Sie über einfache Summen und Durchschnitte hinaus. Die Bibliothek bietet dedizierte NumericStatistics- und BigIntStatistics-Schnittstellen, die sofortigen Zugang zu fortschrittlichen statistischen Kennzahlen direkt aus Ihren Strömen ermöglichen – Varianz, Standardabweichung, Median, Schiefe und Kurtosis. Dies verwandelt komplexe Datenanalysen in eine einzelne Codezeile.
114
44
 
115
- ```typescript
116
- // Beispiel für die Verwendung von Hilfsfunktionen
117
- let numbers: Array<number> = [3, 1, 4, 1, 5];
118
- numbers.sort(useCompare); // [1, 1, 3, 4, 5]
45
+ ### 6. Für eine hervorragende Entwickler-Ergonomie gestaltet
46
+ - **Fließende, verkettbare API**: Schreiben Sie komplexe Datenpipelines als lesbare, sequentielle Ketten.
47
+ - **Umfassendes Utility-Set**: Wesentliche Guards (isFunction, isIterable), Utilities (useCompare, useTraverse) und funktionale Schnittstellen sind enthalten.
48
+ - **Optional<T>-Integration**: Modelliert sicher das Fehlen eines Werts und eliminiert Nullzeiger-Probleme.
49
+ - **Leistungsanleitung**: Klare Hinweise, wann ungeordnete Sammlungen für Geschwindigkeit gegenüber geordneten für die Reihenfolge zu verwenden sind.
119
50
 
120
- let randomNum = useRandom(42); // Saat-basierter Zufallszahl
51
+ ## Installation
52
+ ```bash
53
+ npm install semantic-typescript
121
54
  ```
122
55
 
123
- ## Fabrikmethoden
56
+ ## Kernkonzepte in der Praxis
124
57
 
125
- ### Optionale Fabrikmethoden
126
-
127
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
128
- |------|------|------------|------------|
129
- | `Optional.empty<T>()` | Erstellt eine leere Optional | O(1) | O(1) |
130
- | `Optional.of<T>(value)` | Erstellt eine Optional, die einen Wert enthält | O(1) | O(1) |
131
- | `Optional.ofNullable<T>(value)` | Erstellt eine potenziell leere Optional | O(1) | O(1) |
132
- | `Optional.ofNonNull<T>(value)` | Erstellt eine nicht-null Optional | O(1) | O(1) |
58
+ ### 1. Streams erstellen (Semantic)
59
+ Streams können aus verschiedenen Quellen mithilfe von Factory-Funktionen erstellt werden.
133
60
 
134
61
  ```typescript
135
- // Beispiele für die Verwendung von Optional
136
- let empty: Optional<number> = Optional.empty();
137
- let present: Optional<number> = Optional.of(42);
138
- let nullable: Optional<string> = Optional.ofNullable<string>(null);
139
- let nonNull: Optional<string> = Optional.ofNonNull("hello");
140
-
141
- present.ifPresent((value: number): void => console.log(value)); // Gibt 42 aus
142
- console.log(empty.get(100)); // Gibt 100 aus
143
- ```
62
+ import { useFrom, useInterval, useDocument } from 'semantic-typescript';
144
63
 
145
- ### Collector Fabrikmethoden
64
+ // Aus einem statischen Array
65
+ const staticStream = useFrom([1, 2, 3, 4, 5]);
146
66
 
147
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
148
- |------|------|------------|------------|
149
- | `Collector.full(identity, accumulator, finisher)` | Erstellt einen vollständigen Collector | O(1) | O(1) |
150
- | `Collector.shortable(identity, interruptor, accumulator, finisher)` | Erstellt einen unterbrechbaren Collector | O(1) | O(1) |
67
+ // Aus einem asynchronen Generator
68
+ const asyncStream = useFrom(async function*() {
69
+ yield 1;
70
+ yield 2;
71
+ });
151
72
 
152
- ```typescript
153
- // Beispiele für die Konvertierung von Collectors
154
- let numbers: Semantic<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
155
-
156
- // Leistung zuerst: verwenden Sie den ungeordneten Collector
157
- let unordered: UnorderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
158
- .filter((n: number): boolean => n > 3)
159
- .toUnordered();
160
-
161
- // Sortierung erforderlich: verwenden Sie den geordneten Collector
162
- let ordered: OrderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
163
- .sorted();
164
-
165
- // Zählt die Anzahl der Elemente
166
- let count: Collector<number, number, number> = Collector.full(
167
- (): number => 0, // Anfangswert
168
- (accumulator: number, element: number): number => accumulator + element, // Akkumulieren
169
- (accumulator: number): number => accumulator // Fertigstellen
170
- );
171
- count.collect(from([1,2,3,4,5])); // Zählt aus einem Stream
172
- count.collect([1,2,3,4,5]); // Zählt aus einem iterierbaren Objekt
173
-
174
- let find: Optional<number> = Collector.shortable(
175
- (): Optional<number> => Optional.empty(), // Anfangswert
176
- (element: number, index: bigint, accumulator: Optional<number>): Optional<number> => accumulator.isPresent(), // Unterbrechen
177
- (accumulator: Optional<number>, element: number, index: bigint): Optional<number> => Optional.of(element), // Akkumulieren
178
- (accumulator: Optional<number>): Optional<number> => accumulator // Fertigstellen
179
- );
180
- find.collect(from([1,2,3,4,5])); // Findet das erste Element
181
- find.collect([1,2,3,4,5]); // Findet das erste Element
182
- ```
183
-
184
- ### Semantic Fabrikmethoden
73
+ // Ein zeitbasierter Stream
74
+ const tickStream = useInterval(1000); // emittiert jede Sekunde
185
75
 
186
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
187
- |------|------|------------|------------|
188
- | `animationFrame(period: number, delay: number = 0)` | Erstellt einen zeitgesteuerten Animationsframe-Stream | O(1)* | O(1) |
189
- | `blob(blob, chunkSize)` | Erstellt einen Stream aus einem Blob | O(n) | O(chunkSize) |
190
- | `empty<E>()` | Erstellt einen leeren Stream | O(1) | O(1) |
191
- | `fill<E>(element, count)` | Erstellt einen gefüllten Stream | O(n) | O(1) |
192
- | `from<E>(iterable)` | Erstellt einen Stream aus einem iterierbaren Objekt | O(1) | O(1) |
193
- | `interval(period, delay?)` | Erstellt einen zeitgesteuerten Intervall-Stream | O(1)* | O(1) |
194
- | `iterate<E>(generator)` | Erstellt einen Stream aus einem Generator | O(1) | O(1) |
195
- | `range(start, end, step)` | Erstellt einen numerischen Bereichs-Stream | O(n) | O(1) |
196
- | `websocket(websocket)` | Erstellt einen Stream aus einem WebSocket | O(1) | O(1) |
197
-
198
- ```typescript
199
- // Beispiele für die Verwendung von Semantic Fabrikmethoden
200
-
201
- // Erstellt einen Stream aus einem zeitgesteuerten Animationsframe
202
- animationFrame(1000)
203
- .toUnordered()
204
- .forEach(frame => console.log(frame));
205
-
206
- // Erstellt einen Stream aus einem Blob (chunked reading)
207
- blob(someBlob, 1024n)
208
- .toUnordered()
209
- .write(WritableStream)
210
- .then(callback) // Schreiben des Streams erfolgreich
211
- .catch(callback); // Schreiben des Streams fehlgeschlagen
212
-
213
- // Erstellt einen leeren Stream, der erst ausgeführt wird, wenn er mit anderen Streams verkettet wird
214
- empty<string>()
215
- .toUnordered()
216
- .join(); //[]
217
-
218
- // Erstellt einen gefüllten Stream
219
- let filledStream = fill("hello", 3); // "hello", "hello", "hello"
220
-
221
- // Erstellt einen zeitgesteuerten Stream mit einer anfänglichen Verzögerung von 2 Sekunden und einer Ausführungsperiode von 5 Sekunden, implementiert auf der Grundlage eines Timer-Mechanismus; kann aufgrund von Systemplanungsgenauigkeitsbeschränkungen zu Zeitdrift führen.
222
- let intervalStream = interval(5000, 2000);
223
-
224
- // Erstellt einen Stream aus einem iterierbaren Objekt
225
- let numberStream = from([1, 2, 3, 4, 5]);
226
- let stringStream = from(new Set(["Alex", "Bob"]));
227
-
228
- // Erstellt einen Bereichs-Stream
229
- let rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
230
-
231
- // WebSocket-Ereignis-Stream
232
- let ws = new WebSocket("ws://localhost:8080");
233
- websocket(ws)
234
- .filter((event): boolean => event.type === "message"); // Nur Nachrichtenereignisse abhören
235
- .toUnordered() // Ereignisse sind in der Regel nicht geordnet
236
- .forEach((event): void => receive(event)); // Nachrichten empfangen
76
+ // Ein DOM-Ereignisstream (siehe wichtigen Hinweis unten)
77
+ const clickStream = useDocument('click');
237
78
  ```
238
79
 
239
- ## Semantic Klassenmethoden
240
-
241
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
242
- |------|------|------------|------------|
243
- | `concat(other)` | Verbindet zwei Streams | O(n) | O(1) |
244
- | `distinct()` | Entfernt Duplikate | O(n) | O(n) |
245
- | `distinct(comparator)` | Entfernt Duplikate mit einem Vergleichsoperator | O(n²) | O(n) |
246
- | `dropWhile(predicate)` | Verwirft Elemente, die die Bedingung erfüllen | O(n) | O(1) |
247
- | `filter(predicate)` | Filtert Elemente | O(n) | O(1) |
248
- | `flat(mapper)` | Flachemapping | O(n × m) | O(1) |
249
- | `flatMap(mapper)` | Flachemapping in einen neuen Typ | O(n × m) | O(1) |
250
- | `limit(n)` | Begrenzt die Anzahl der Elemente | O(n) | O(1) |
251
- | `map(mapper)` | Zuordnungstransformation | O(n) | O(1) |
252
- | `peek(consumer)` | Blickt auf Elemente | O(n) | O(1) |
253
- | `redirect(redirector)` | Leitet den Index um | O(n) | O(1) |
254
- | `reverse()` | Umkehrt den Stream | O(n) | O(1) |
255
- | `shuffle()` | Mischt zufällig | O(n) | O(1) |
256
- | `shuffle(mapper)` | Mischt mit einem Mapper | O(n) | O(1) |
257
- | `skip(n)` | Überspringt die ersten n Elemente | O(n) | O(1) |
258
- | `sorted()` | Sortiert | O(n log n) | O(n) |
259
- | `sorted(comparator)` | Sortiert mit einem Vergleichsoperator | O(n log n) | O(n) |
260
- | `sub(start, end)` | Holt einen Substream | O(n) | O(1) |
261
- | `takeWhile(predicate)` | Holt Elemente, die die Bedingung erfüllen | O(n) | O(1) |
262
- | `translate(offset)` | Übersetzt den Index | O(n) | O(1) |
263
- | `translate(translator)` | Übersetzt den Index mit einem Translator | O(n) | O(1) |
80
+ ### 2. Streams transformieren (Zwischenoperationen)
81
+ Operationen werden träge verkettet, um die Pipeline zu definieren.
264
82
 
265
83
  ```typescript
266
- // Beispiele für Semantic-Operationen
267
- let result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
268
- .filter((n: number): boolean => n % 2 === 0) // Filtert gerade Zahlen
269
- .map((n: number): number => n * 2) // Multipliziert mit 2
270
- .skip(1) // Überspringt das erste
271
- .limit(3) // Begrenzt auf 3 Elemente
272
- .toUnordered() // Konvertiert in einen ungeordneten Collector
273
- .toArray(); // Konvertiert in ein Array
274
- // Ergebnis: [8, 12, 20]
275
-
276
- // Komplexes Operationsexample
277
- let complexResult = range(1, 100, 1)
278
- .flatMap((n: number): Semantics<number> => from([n, n * 2])) // Mappt jedes Element auf zwei
279
- .distinct() // Entfernt Duplikate
280
- .shuffle() // Mischt die Reihenfolge
281
- .takeWhile((n: number): boolean => n < 50) // Nimmt Elemente kleiner als 50
282
- .toOrdered() // Konvertiert in einen geordneten Collector
283
- .toArray(); // Konvertiert in ein Array
284
- ```
285
-
286
- ## Semantic Konvertierungsmethoden
84
+ const processedStream = staticStream
85
+ .filter(x => x % 2 === 0) // Nur gerade Zahlen behalten
86
+ .map(x => x * 10) // Mit 10 multiplizieren
87
+ .flatMap(x => [x, x + 1]) // Jedes Element in zwei umwandeln
88
+ .distinct(); // Duplikate entfernen
287
89
 
288
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
289
- |------------|------------|------------|------------|
290
- | `sorted()` | Konvertiert in einen geordneten Collector | O(n log n) | O(n) |
291
- | `toUnordered()` | Konvertiert in einen ungeordneten Collector | O(1) | O(1) |
292
- | `toOrdered()` | Konvertiert in einen geordneten Collector | O(1) | O(1) |
293
- | `toNumericStatistics()` | Konvertiert in numerische Statistiken | O(n) | O(1) |
294
- | `toBigintStatistics()` | Konvertiert in BigInt-Statistiken | O(n) | O(1) |
295
- | `toWindow()` | Konvertiert in einen Fenstercollector | O(1) | O(1) |
296
- | `toCollectable()` | Konvertiert in `UnorderdCollectable` | O(n) | O(1) |
297
- | `toCollectable(mapper)` | Konvertiert in einen benutzerdefinierten Collectable | O(n) | O(1) |
298
-
299
- ```typescript
300
- // Konvertiert in ein aufsteigend sortiertes Array
301
- from([6,4,3,5,2]) // Erstellt einen Stream
302
- .sorted() // Sortiert den Stream in aufsteigender Reihenfolge
303
- .toArray(); // [2, 3, 4, 5, 6]
304
-
305
- // Konvertiert in ein absteigend sortiertes Array
306
- from([6,4,3,5,2]) // Erstellt einen Stream
307
- .soted((a: number, b: number): number => b - a) // Sortiert den Stream in absteigender Reihenfolge
308
- .toArray(); // [6, 5, 4, 3, 2]
309
-
310
- // Leitet um in ein umgekehrtes Array
311
- from([6,4,3,5,2])
312
- .redirect((element, index): bigint => -index) // Leitet um in umgekehrter Reihenfolge
313
- .toOrderd() // Behält die umgeleitete Reihenfolge bei
314
- .toArray(); // [2, 5, 3, 4, 6]
315
-
316
- // Ignoriert Umleitungen, um ein umgekehrtes Array zu erhalten
317
- from([6,4,3,5,2])
318
- .redirect((element: number, index: bigint) => -index) // Leitet um in umgekehrter Reihenfolge
319
- .toUnorderd() // Ignoriert die umgeleitete Reihenfolge. Diese Operation ignoriert `redirect`, `reverse`, `shuffle` und `translate` Operationen
320
- .toArray(); // [2, 5, 3, 4, 6]
321
-
322
- // Kehrt den Stream in ein Array um
323
- from([6, 4, 3, 5, 2])
324
- .reverse() // Kehrt den Stream um
325
- .toOrdered() // Garantiert die umgekehrte Reihenfolge
326
- .toArray(); // [2, 5, 3, 4, 6]
327
-
328
- // Überschreibt den gemischten Stream in ein Array
329
- from([6, 4, 3, 5, 2])
330
- .shuffle() // Mischt den Stream
331
- .sorted() // Überschreibt die gemischte Reihenfolge. Diese Operation überschreibt `redirect`, `reverse`, `shuffle` und `translate` Operationen
332
- .toArray(); // [2, 5, 3, 4, 6]
333
-
334
- // Konvertiert in einen Fenstercollector
335
- from([6, 4, 3, 5, 2]).toWindow();
336
-
337
- // Konvertiert in numerische Statistiken
338
- from([6, 4, 3, 5, 2]).toNumericStatistics();
339
-
340
- // Konvertiert in BigInt-Statistiken
341
- from([6n, 4n, 3n, 5n, 2n]).toBigintStatistics();
342
-
343
- // Definiert einen benutzerdefinierten Collector zum Sammeln von Daten
344
- let customizedCollector = from([1, 2, 3, 4, 5]).toCollectable((generator: Generator<E>) => new CustomizedCollector(generator));
90
+ // Bisher wurde noch nichts ausgeführt
345
91
  ```
346
92
 
347
- ## Collectable Auflistungsmethoden
348
-
349
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
350
- |------|------|------------|------------|
351
- | `anyMatch(predicate)` | Ob irgendein Element übereinstimmt | O(n) | O(1) |
352
- | `allMatch(predicate)` | Ob alle Elemente übereinstimmen | O(n) | O(1) |
353
- | `count()` | Elementanzahl | O(n) | O(1) |
354
- | `isEmpty()` | Ob es leer ist | O(1) | O(1) |
355
- | `findAny()` | Finde ein beliebiges Element | O(n) | O(1) |
356
- | `findFirst()` | Finde das erste Element | O(n) | O(1) |
357
- | `findLast()` | Finde das letzte Element | O(n) | O(1) |
358
- | `forEach(action)` | Durchlaufe alle Elemente | O(n) | O(1) |
359
- | `group(classifier)` | Gruppiere nach Klassifizierer | O(n) | O(n) |
360
- | `groupBy(keyExtractor, valueExtractor)` | Gruppiere nach Schlüssel-Wert-Extraktor | O(n) | O(n) |
361
- | `join()` | Verbinde als Zeichenkette | O(n) | O(n) |
362
- | `join(delimiter)` | Verbinde mit einem Trennzeichen | O(n) | O(n) |
363
- | `nonMatch(predicate)` | Ob kein Element übereinstimmt | O(n) | O(1) |
364
- | `partition(count)` | Partitioniere nach Anzahl | O(n) | O(n) |
365
- | `partitionBy(classifier)` | Partitioniere nach Klassifizierer | O(n) | O(n) |
366
- | `reduce(accumulator)` | Reduktionsoperation | O(n) | O(1) |
367
- | `reduce(identity, accumulator)` | Reduzierung mit Anfangswert | O(n) | O(1) |
368
- | `toArray()` | Konvertiere in ein Array | O(n) | O(n) |
369
- | `toMap(keyExtractor, valueExtractor)` | Konvertiere in eine Map | O(n) | O(n) |
370
- | `toSet()` | Konvertiere in eine Menge | O(n) | O(n) |
371
- | `write(stream)` | Schreibe in einen Stream | O(n) | O(1) |
93
+ ### 3. Streams ausführen (Terminaloperationen)
94
+ Um ein Ergebnis zu erhalten, müssen Sie ein Collectable erhalten und eine Terminaloperation aufrufen.
372
95
 
373
96
  ```typescript
374
- // Collectable Operationsexamples
375
- let data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
376
- .filter((n: number): boolean => n % 2 === 0)
377
- .toOrdered();
378
-
379
- // Übereinstimmungsüberprüfungen
380
- console.log(data.anyMatch((n: number): boolean => n > 5)); // true
381
- console.log(data.allMatch((n: number): boolean => n < 20)); // true
382
-
383
- // Suchvorgänge
384
- data.findFirst().ifPresent((n: number): void => console.log(n)); // 2
385
- data.findAny().ifPresent((n: number): void => console.log(n)); // Ein beliebiges Element
386
-
387
- // Gruppierungsvorgänge
388
- let grouped = data.groupBy(
389
- (n: number): string => (n > 5 ? "groß" : "klein"),
390
- (n: number): number => n * 2
391
- ); // {klein: [4, 8], groß: [12, 16, 20]}
392
-
393
- // Reduktionsvorgänge
394
- let sum = data.reduce(0, (acc, n) => acc + n); // 30
395
-
396
- // Ausgabeoperationen
397
- data.join(", "); // "[2, 4, 6, 8, 10]"
97
+ // Ein ungeordnetes Collectable für Leistung erhalten
98
+ const resultArray = await processedStream.toUnordered().toArray();
99
+ console.log(resultArray); // z.B. [20, 21, 40, 41]
100
+
101
+ // Einen eingebauten Collector verwenden
102
+ const sum = await processedStream.toUnordered().collect(useSummate());
103
+ console.log(sum);
104
+
105
+ // Oder die generische collect-Methode verwenden
106
+ const customResult = await processedStream.toOrdered().collect(
107
+ () => new Map<number, number>(),
108
+ (map, element, index) => map.set(index, element),
109
+ map => map
110
+ );
398
111
  ```
399
112
 
400
- ## Statistische Analysemethode
401
-
402
- ### NumericStatistics Methoden
403
-
404
- | Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
405
- |------|------|------------|------------|
406
- | `range()` | Bereich | O(n) | O(1) |
407
- | `variance()` | Varianz | O(n) | O(1) |
408
- | `standardDeviation()` | Standardabweichung | O(n) | O(1) |
409
- | `mean()` | Mittelwert | O(n) | O(1) |
410
- | `median()` | Median | O(n log n) | O(n) |
411
- | `mode()` | Modus | O(n) | O(n) |
412
- | `frequency()` | Häufigkeitsverteilung | O(n) | O(n) |
413
- | `summate()` | Summation | O(n) | O(1) |
414
- | `quantile(quantile)` | Quantil | O(n log n) | O(n) |
415
- | `interquartileRange()` | Interquartilsabstand | O(n log n) | O(n) |
416
- | `skewness()` | Schiefe | O(n) | O(1) |
417
- | `kurtosis()` | Wölbung | O(n) | O(1) |
113
+ ### 4. Wichtig: Umgang mit Ereignisströmen
114
+ Ereignisströme (useDocument, useWindow, useHTMLElement, useWebSocket) sind von Natur aus unendlich. Sie müssen Operationen wie sub, takeWhile oder limit verwenden, um zu definieren, wann das Sammeln von Ereignissen beendet und der Stream abgeschlossen werden soll. Andernfalls wartet die Terminaloperation unendlich lange.
418
115
 
419
116
  ```typescript
420
- // Statistische Analysebeispiele
421
- let numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
422
- .toNumericStatistics();
423
-
424
- console.log("Mittelwert:", numbers.mean()); // 5.5
425
- console.log("Median:", numbers.median()); // 5.5
426
- console.log("Standardabweichung:", numbers.standardDeviation()); // ~2.87
427
- console.log("Summe:", numbers.summate()); // 55
428
-
429
- // Mit Mappern statistische Analyse durchführen
430
- let objects = from([
431
- { value: 10 },
432
- { value: 20 },
433
- { value: 30 }
434
- ]).toNumericStatistics();
435
- console.log("Gemappter Mittelwert:", objects.mean(obj => obj.value)); // 20
117
+ import { useDocument } from 'semantic-typescript';
118
+
119
+ // Nur die ersten 5 Klicks sammeln
120
+ const first5Clicks = await useDocument('click')
121
+ .limit(5) // <- Essentiell: Begrenzt den Stream auf 5 Ereignisse
122
+ .toUnordered()
123
+ .toArray();
124
+
125
+ // Klicks in einem 10-Sekunden-Fenster sammeln
126
+ const clicksIn10s = await useDocument('click')
127
+ .takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
128
+ .toUnordered()
129
+ .toArray();
130
+
131
+ // Klicks von Index 2 bis 5 sammeln (0-basiert)
132
+ const specificClicks = await useDocument('click')
133
+ .sub(2n, 6n) // <- Nimmt Elemente mit Index 2, 3, 4, 5
134
+ .toUnordered()
135
+ .toArray();
436
136
  ```
437
137
 
438
- ## Leistungsauswahlhandbuch
138
+ **Wichtige Erkenntnis**: Das Ereignis (z. B. ein MouseEvent) und sein sequenzieller Auslöseindex (als BigInt) werden über den Callback `accept(event, index)` gemeinsam durch die Pipeline geleitet.
439
139
 
440
- ### Wählen Sie einen ungeordneten Collector (Leistung zuerst)
140
+ ### 5. Statistikfunktionen nutzen
441
141
  ```typescript
442
- // Wenn keine Reihenfolgegarantie benötigt wird, verwenden Sie einen ungeordneten Collector für beste Leistung
443
- let highPerformance = data
444
- .filter(predicate)
445
- .map(mapper)
446
- .toUnordered(); // Beste Leistung
447
- ```
142
+ const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
448
143
 
449
- ### Wählen Sie einen geordneten Collector (Reihenfolge erforderlich)
450
- ```typescript
451
- // Wenn die Reihenfolge der Elemente beibehalten werden muss, verwenden Sie einen geordneten Collector
452
- let ordered = data.sorted(comparator);
453
- ```
144
+ const average = await numericStream.average();
145
+ const median = await numericStream.median();
146
+ const standardDeviation = await numericStream.standardDeviation();
147
+ const skewness = await numericStream.skewness();
454
148
 
455
- ### Wählen Sie einen Fenstercollector (Fensteroperationen)
456
- ```typescript
457
- // Wenn Fensteroperationen benötigt werden
458
- let window: WindowCollectable<number> = data
459
- .toWindow()
460
- .slide(5n, 2n); // Gleitender Fenster
149
+ console.log(`Durchschnitt: ${average}, Median: ${median}, Standardabweichung: ${standardDeviation}`);
461
150
  ```
462
151
 
463
- ### Wählen Sie eine statistische Analyse (numerische Berechnungen)
152
+ ## Hauptmerkmale
153
+ - **Duale Stream-Typen**: Volle Unterstützung für sowohl SynchronousSemantic (für Iterable) als auch AsynchronousSemantic (für AsyncIterable und Ereignisse)
154
+ - **Umfangreicher Operationensatz**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
155
+ - **Flexible Terminaloperationen**: collect (mit benutzerdefinierten Collectors), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
156
+ - **Erweiterte Collector**: Eingebaute Collector für joining, groupingBy, partitioningBy, summing, averaging, maxBy, minBy
157
+ - **Statistikmodul**: Gebrauchsfertige Methoden für Mittelwert, Median, Modus, Varianz, Standardabweichung, Bereich, Quantile, Schiefe, Kurtosis für numerische/BigInt-Streams
158
+ - **Hilfsfunktionen**: Typ-Guards (isPromise, isAsyncIterable), Komparatoren (useCompare), Traversal (useTraverse) und Konvertierungs-Hooks
159
+ - **Optional<T>**: Ein monadischer Container für nullable Werte, integriert mit Suchoperationen
160
+
161
+ ## API-Übersicht
162
+ ### Kernklassen und -schnittstellen
163
+ - `Semantic<E>` / `AsynchronousSemantic<E>`: Die abstrakte Stream-Definition
164
+ - `Collectable<E>` / `AsynchronousCollectable<E>`: Der ausführbare Stream mit Terminaloperationen
165
+ - `OrderedCollectable<E>` / `UnorderedCollectable<E>`: Materialisierte Versionen, optimiert für reihenfolgensensitive oder reihenfolgenunempfindliche Operationen
166
+ - `Collector<E, A, R>`: Die Abstraktion für mutable Reduktionsoperationen
167
+
168
+ ### Factory-Funktionen (use*)
169
+ - **Aus Quellen**: useFrom, useRange, useFill, useEmpty
170
+ - **Aus Zeit**: useInterval, useAnimationFrame
171
+ - **Aus Web-APIs**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
172
+ - **Collector**: useToArray, useGroupBy, useSummate, useJoin, usw.
173
+
174
+ ## Leistungshinweise
175
+ - **Lazy Evaluation**: Pipelines werden ohne Ausführung komponiert, bis eine Terminaloperation aufgerufen wird
176
+ - **Short-Circuiting**: Operationen wie limit, anyMatch und findFirst stoppen die Verarbeitung von Elementen, sobald das Ergebnis bestimmt ist
177
+ - **Geordnet vs. Ungeordnet**:
178
+ - Verwenden Sie `.toUnordered()` für Terminaloperationen, wenn die Reihenfolge der Quellelemente für Ihr Ergebnis keine Rolle spielt (z. B. für Summe, Maximum oder toSet). Dies kann interne Optimierungen ermöglichen, die kostspielige Sortierschritte überspringen
179
+ - Verwenden Sie `.toOrdered()`, wenn die Reihenfolge wichtig ist (z. B. für toArray, bei dem die Reihenfolge erhalten bleiben muss)
180
+
181
+ ## Einstiegsbeispiel
464
182
  ```typescript
465
- // Wenn eine statistische Analyse benötigt wird
466
- let statistics: NumericStatistics<number> = data
467
- .toNumericStatistics(); // Numerische Statistiken
183
+ import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
468
184
 
469
- let bigIntStatistics: BigintStatistics<bigint> = data
470
- .toBigintStatistics(); // Große Ganzzahlstatistiken
471
- ```
472
-
473
- [GitHub](https://github.com/eloyhere/semantic-typescript)
474
- [NPMJS](https://www.npmjs.com/package/semantic-typescript)
185
+ interface Transaction {
186
+ id: number;
187
+ amount: number;
188
+ category: string;
189
+ }
475
190
 
476
- ## Wichtige Hinweise
191
+ const transactions: Transaction[] = [
192
+ { id: 1, amount: 100, category: 'Food' },
193
+ { id: 2, amount: 200, category: 'Electronics' },
194
+ { id: 3, amount: 50, category: 'Food' },
195
+ { id: 4, amount: 300, category: 'Electronics' },
196
+ ];
197
+
198
+ // Gesamtbetrag pro Kategorie berechnen
199
+ const totalsByCategory = await useFrom(transactions)
200
+ .toUnordered()
201
+ .collect(
202
+ useGroupBy(
203
+ t => t.category,
204
+ t => t.amount,
205
+ useSummate() // Collector für die Werte
206
+ )
207
+ );
208
+
209
+ console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
210
+ ```
477
211
 
478
- 1. **Auswirkungen von Sortiervorgängen**: In geordneten Collectors überschreibt der `sorted()`-Vorgang die Effekte von `redirect`, `translate`, `shuffle`, `reverse`.
479
- 2. **Leistungserwägungen**: Wenn keine Reihenfolgegarantie benötigt wird, bevorzugen Sie die Verwendung von `toUnordered()` für eine bessere Leistung.
480
- 3. **Speicherverwendung**: Sortiervorgänge erfordern zusätzlichen Speicherplatz von O(n).
481
- 4. **Echtzeitdaten**: Semantic-Streams eignen sich für die Verarbeitung von Echtzeitdaten und unterstützen asynchrone Datenquellen.
212
+ Semantic-TypeScript wurde für Entwickler gebaut, die eine streng entworfene, typsichere und leistungsstarke Stream-Processing-Bibliothek suchen. Es bringt die Leistungsfähigkeit von Unternehmens-Datentransformationsmustern in das TypeScript-Ökosystem und eignet sich perfekt für datenintensive Frontend-Anwendungen, Node.js-Datenverarbeitung und jedes Szenario, in dem elegante, effiziente Handhabung von Sequenzen erforderlich ist.
482
213
 
483
- Diese Bibliothek bietet TypeScript-Entwicklern leistungsstarke und flexible Streaming-Fähigkeiten und kombiniert die Vorteile der funktionalen Programmierung mit Typsicherheitsgarantien.
214
+ [![GitHub](./GitHub.png)](https://github.com/eloyhere/semantic-typescript) [![NPM](./NPM.png)](https://www.npmjs.com/package/semantic-typescript)