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/dist/asynchronous/collector.d.ts +62 -58
- package/dist/asynchronous/collector.js +16 -5
- package/dist/asynchronous/semantic.d.ts +6 -2
- package/dist/asynchronous/semantic.js +19 -6
- package/dist/factory.d.ts +32 -71
- package/dist/factory.js +192 -603
- package/dist/guard.d.ts +0 -3
- package/dist/guard.js +0 -19
- package/dist/hash.js +3 -0
- package/dist/hook.d.ts +6 -1
- package/dist/hook.js +20 -3
- package/dist/synchronous/collector.d.ts +8 -4
- package/dist/synchronous/collector.js +74 -59
- package/dist/synchronous/semantic.d.ts +31 -23
- package/dist/synchronous/semantic.js +218 -286
- package/package.json +3 -2
- package/readme.cn.md +267 -214
- package/readme.de.md +225 -172
- package/readme.es.md +229 -170
- package/readme.fr.md +233 -170
- package/readme.jp.md +232 -169
- package/readme.kr.md +227 -169
- package/readme.md +270 -214
- package/readme.ru.md +231 -169
- package/readme.tw.md +225 -172
package/readme.de.md
CHANGED
|
@@ -1,214 +1,267 @@
|
|
|
1
|
-
# Semantic
|
|
1
|
+
# **Semantic‑TypeScript**
|
|
2
|
+
**Ströme, indiziert.** Ihre Daten unter präziser Kontrolle.
|
|
2
3
|
|
|
3
|
-
|
|
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
|
|
|
6
|
-
|
|
6
|
+
### Überblick
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
- Große Datensätze über speichereffiziente, verzögerte Pipelines
|
|
10
|
-
- Komplexe Datentransformationen mit einer fließenden, deklarativen API
|
|
8
|
+
Semantic‑TypeScript stellt eine bedeutende Weiterentwicklung in der Stream‑Verarbeitung dar und vereint elegant die effektivsten Paradigmen aus JavaScript‑Generatoren, Java‑Streams und MySQL‑artiger Indizierung. Die Grundidee ist sowohl leistungsfähig als auch bewusst gewählt: Ausnahmslos effiziente Datenverarbeitungspipelines durch intelligente Indizierung zu konstruieren, anstatt durch konventionelle Brute‑Force‑Iteration.
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
Wo typische Bibliotheken synchrone Schleifen oder umständliche Promise‑Ketten erzwingen, bietet Semantic‑TypeScript eine **vollständig asynchrone**, funktional reine und rigoros typsichere Erfahrung, die ausdrücklich für die Anforderungen moderner Anwendungsentwicklung konzipiert ist.
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
Eine zentrale architektonische Erkenntnis von Semantic-TypeScript ist die klare Trennung zwischen der Definition eines Streams und seiner Ausführung:
|
|
12
|
+
Dieses Modell verkörpert eine raffinierte Form des Kontrollflusses: Daten werden nur dann an den nachgelagerten Verbraucher weitergegeben, wenn die vorgelagerte Pipeline explizit den `accept`‑Callback aufruft. Sie behalten die vollständige, granulare Kontrolle über den Zeitpunkt – die Verarbeitung erfolgt genau dann und nur dann, wenn es erforderlich ist.
|
|
16
13
|
|
|
17
|
-
|
|
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.
|
|
14
|
+
---
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
### Warum Entwickler Semantic‑TypeScript wählen
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
- **Zero‑Boilerplate‑Indizierung** – Jedes Element besitzt inhärent seinen natürlichen oder maßgeschneiderten Index, wodurch manuelle Nachverfolgung entfällt.
|
|
19
|
+
- **Rein funktional & typsicher** – Genießen Sie vollständige, idiomatische TypeScript‑Inferenz zusammen mit unveränderlichen Operationen.
|
|
20
|
+
- **Leck‑sichere Ereignisströme** – Das `useSubscription`‑Muster wurde mit Ressourcensicherheit als erstem Prinzip entworfen. Sie definieren die logische Grenze – mittels `limit(n)`, `sub(start, end)` oder `takeWhile(predicate)` – und die Bibliothek verwaltet den vollständigen Abonnement‑Lebenszyklus. Dies stellt sicher, dass keine verbleibenden Listener und keine Speicherlecks entstehen.
|
|
21
|
+
- **Integrierte Statistik‑Suite** – Greifen Sie ohne externe Abhängigkeiten auf umfassende Analysen für sowohl `number`‑ als auch `bigint`‑Ströme zu, einschließlich Mittelwert, Median, Modus, Varianz, Schiefe und Kurtosis.
|
|
22
|
+
- **Vorhersehbare, fein abstimmbare Leistung** – Wählen Sie zwischen geordneten oder ungeordneten Sammlern, um Ihren genauen Leistungs‑ und Reihenfolgeanforderungen gerecht zu werden.
|
|
23
|
+
- **Inherent speichereffizient** – Ströme werden lazy evaluiert, verarbeiten Elemente bei Bedarf und entlasten so den Speicher.
|
|
24
|
+
- **Kein undefiniertes Verhalten** – TypeScript garantiert vollständige Typsicherheit und Nullsicherheit. Ihre Quelldaten bleiben unveränderlich, es sei denn, sie werden explizit in Ihren Callback‑Funktionen geändert.
|
|
24
25
|
|
|
25
|
-
|
|
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.
|
|
26
|
+
---
|
|
27
27
|
|
|
28
|
-
###
|
|
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.
|
|
28
|
+
### Installation
|
|
30
29
|
|
|
31
|
-
|
|
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.
|
|
30
|
+
Integrieren Sie Semantic‑TypeScript mit Ihrem bevorzugten Paketmanager in Ihr Projekt:
|
|
33
31
|
|
|
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:
|
|
36
|
-
|
|
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
|
|
41
|
-
|
|
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.
|
|
44
|
-
|
|
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.
|
|
50
|
-
|
|
51
|
-
## Installation
|
|
52
32
|
```bash
|
|
53
33
|
npm install semantic-typescript
|
|
54
34
|
```
|
|
35
|
+
oder
|
|
36
|
+
```bash
|
|
37
|
+
yarn add semantic-typescript
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
55
41
|
|
|
56
|
-
|
|
42
|
+
### Praktische Einführung
|
|
57
43
|
|
|
58
|
-
|
|
59
|
-
Streams können aus verschiedenen Quellen mithilfe von Factory-Funktionen erstellt werden.
|
|
44
|
+
Die folgenden Beispiele demonstrieren Kernkonzepte, von grundlegenden Transformationen bis zur praktischen Ereignisbehandlung.
|
|
60
45
|
|
|
61
46
|
```typescript
|
|
62
|
-
import { useFrom,
|
|
47
|
+
import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
|
|
48
|
+
|
|
49
|
+
// ====================================================================
|
|
50
|
+
// BEISPIEL 1: Grundlegende Operationen & numerische Statistik
|
|
51
|
+
// ====================================================================
|
|
52
|
+
// Demonstriert Mapping und terminale Statistikoperationen. Nach der Transformation muss die Pipeline in einen Statistik‑Collector umgewandelt werden, bevor terminale Methoden wie `.summate()` aufgerufen werden können.
|
|
53
|
+
|
|
54
|
+
const numericSum: number = useOf(10, 20, 30, 40)
|
|
55
|
+
.map((n: number): number => n * 2) // Verdoppelt jedes Element: [20, 40, 60, 80]
|
|
56
|
+
.toNumericStatistics() // In einen Statistik‑Collector umwandeln
|
|
57
|
+
.summate(); // Terminale Operation: 200
|
|
58
|
+
|
|
59
|
+
// Weitere statistische Methoden (verfügbar nach .toNumericStatistics()):
|
|
60
|
+
// .average(), .median(), .mode(), .variance(), .skewness(), .kurtosis()
|
|
61
|
+
|
|
62
|
+
// ====================================================================
|
|
63
|
+
// BEISPIEL 2: BigInt‑Statistik
|
|
64
|
+
// ====================================================================
|
|
65
|
+
// Funktioniert identisch zur numerischen Statistik, ist jedoch für BigInt‑Daten optimiert.
|
|
66
|
+
|
|
67
|
+
const bigintSum: bigint = useOf(10n, 20n, 30n, 40n)
|
|
68
|
+
.map((n: bigint): bigint => n * 2n) // BigInt‑Arithmetik
|
|
69
|
+
.toBigIntStatistics() // In BigInt‑Statistik‑Collector umwandeln
|
|
70
|
+
.summate(); // Terminale Operation: 200n
|
|
71
|
+
|
|
72
|
+
// ====================================================================
|
|
73
|
+
// BEISPIEL 3: Indexmanipulation zur Stromumkehrung
|
|
74
|
+
// ====================================================================
|
|
75
|
+
// Veranschaulicht die Neuanordnung von Elementen durch strategische Neuzuweisung ihrer Indizes mithilfe der `.redirect()`‑Methode, was benutzerdefinierte Muster wie Umkehrung ermöglicht.
|
|
76
|
+
|
|
77
|
+
const reversedArray: number[] = useFrom([1, 2, 3, 4, 5])
|
|
78
|
+
.redirect((_element: number, index: bigint): bigint => -index) // Auf negative Indizes abbilden
|
|
79
|
+
.toOrdered() // Essentiell: Sammelt Elemente sortiert nach ihren neuen Indizes
|
|
80
|
+
.toArray(); // Ergebnis: [5, 4, 3, 2, 1]
|
|
81
|
+
|
|
82
|
+
// Für einfache Umkehrung ist auch `.reverse()` verfügbar.
|
|
83
|
+
|
|
84
|
+
// ====================================================================
|
|
85
|
+
// BEISPIEL 4: Strom‑Mischen (Shuffle)
|
|
86
|
+
// ====================================================================
|
|
87
|
+
// Permutiert Elementindizes zufällig mit einem In‑Place‑Shuffle‑Algorithmus.
|
|
88
|
+
|
|
89
|
+
const shuffledArray: number[] = useFrom([1, 2, 3, 4, 5])
|
|
90
|
+
.shuffle() // Weist Indizes zufällig neu zu
|
|
91
|
+
.toOrdered() // Sortiert nach den neuen zufälligen Indizes
|
|
92
|
+
.toArray(); // Z.B.: [2, 5, 1, 4, 3] (variiert bei jeder Ausführung)
|
|
93
|
+
|
|
94
|
+
// ====================================================================
|
|
95
|
+
// BEISPIEL 5: Zirkuläre Strom‑Rotation
|
|
96
|
+
// ====================================================================
|
|
97
|
+
// Verschiebt Elemente zyklisch. Positive Werte rotieren nach rechts; negative Werte nach links.
|
|
98
|
+
|
|
99
|
+
// Rechts‑Rotation um 2 Positionen
|
|
100
|
+
const rightRotated: number[] = useFrom([1, 2, 3, 4, 5])
|
|
101
|
+
.translate(2) // Verschiebt Indizes um 2 nach rechts
|
|
102
|
+
.toOrdered()
|
|
103
|
+
.toArray(); // Ergebnis: [4, 5, 1, 2, 3]
|
|
104
|
+
|
|
105
|
+
// ====================================================================
|
|
106
|
+
// BEISPIEL 6: Lazy Evaluation mit unendlichen Bereichen
|
|
107
|
+
// ====================================================================
|
|
108
|
+
// Verarbeitet theoretisch unendliche Ströme lazy, berechnet Elemente nur bei Bedarf.
|
|
109
|
+
|
|
110
|
+
const firstTenMultiples: bigint[] = useRange(0n, 1_000_000n)
|
|
111
|
+
.filter(n => n % 17n === 0n) // Behält Vielfache von 17
|
|
112
|
+
.limit(10n) // Kritisch: Stoppt nach dem 10. Treffer
|
|
113
|
+
.toUnordered() // Keine Sortierung erforderlich
|
|
114
|
+
.toArray(); // Ergebnis: [0, 17, 34, 51, 68, 85, 102, 119, 136, 153]
|
|
115
|
+
|
|
116
|
+
// Ohne `.limit(10n)` würde die Pipeline alle eine Million Elemente verarbeiten.
|
|
117
|
+
|
|
118
|
+
// ====================================================================
|
|
119
|
+
// BEISPIEL 7: Zusammensetzung einer komplexen Pipeline
|
|
120
|
+
// ====================================================================
|
|
121
|
+
// Demonstriert die sequentielle Komposition mehrerer Operationen.
|
|
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();
|
|
131
|
+
|
|
132
|
+
// ====================================================================
|
|
133
|
+
// BEISPIEL 8: Verwaltete DOM‑Ereignis‑Abonnements
|
|
134
|
+
// ====================================================================
|
|
135
|
+
// Hört auf Browser‑Ereignisse mit automatischer, lecksicherer Bereinigung.
|
|
136
|
+
// Der `.limit(n)`‑Aufruf definiert die Grenze für die automatische Listener‑Entfernung.
|
|
137
|
+
|
|
138
|
+
// Definiere einen Abonnenten für ein Window‑Ziel
|
|
139
|
+
const windowSubscriber = {
|
|
140
|
+
mount: (target: Window): void => { /* Setup‑Logik */ },
|
|
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 => { /* Cleanup‑Logik */ }
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
useSubscription(window, windowSubscriber, "resize")
|
|
151
|
+
.limit(5n) // Automatische Abmeldung nach 5 Ereignissen
|
|
152
|
+
.toUnordered()
|
|
153
|
+
.forEach((ev: Event, idx) =>
|
|
154
|
+
console.log(`Größenänderung #${idx}: ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// ====================================================================
|
|
158
|
+
// BEISPIEL 9: String‑Verarbeitung nach Unicode‑Codepunkten
|
|
159
|
+
// ====================================================================
|
|
160
|
+
// Iteriert korrekt über einen String, behandelt Multi‑Byte‑Unicode‑Zeichen.
|
|
63
161
|
|
|
64
|
-
|
|
65
|
-
|
|
162
|
+
useText("My emotion now is: 😊, and semantic is 👍")
|
|
163
|
+
.toUnordered()
|
|
164
|
+
.log(); // Gibt jedes Zeichen (inkl. Emoji) in einer neuen Zeile aus.
|
|
66
165
|
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
166
|
+
// ====================================================================
|
|
167
|
+
// BEISPIEL 10: Sichere Stringifizierung zirkulärer Referenzen
|
|
168
|
+
// ====================================================================
|
|
169
|
+
// Serialisiert sicher Objekte, die zirkuläre Referenzen enthalten.
|
|
72
170
|
|
|
73
|
-
|
|
74
|
-
|
|
171
|
+
const obj = {
|
|
172
|
+
a: 1,
|
|
173
|
+
b: "text"
|
|
174
|
+
};
|
|
175
|
+
(obj as any).c = [obj.a, obj.b, (obj as any).c]; // Führt zirkuläre Referenz ein
|
|
75
176
|
|
|
76
|
-
//
|
|
77
|
-
const
|
|
177
|
+
// const text: string = JSON.stringify(obj); // Wirft einen Fehler
|
|
178
|
+
const text: string = useStringify(obj); // Ergibt sicher `{a: 1, b: "text", c: []}`
|
|
78
179
|
```
|
|
79
180
|
|
|
80
|
-
|
|
81
|
-
Operationen werden träge verkettet, um die Pipeline zu definieren.
|
|
181
|
+
---
|
|
82
182
|
|
|
83
|
-
|
|
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
|
|
183
|
+
### Kernkonzepte
|
|
89
184
|
|
|
90
|
-
|
|
91
|
-
|
|
185
|
+
| Konzept | Zweck | Hauptanwendungsfall |
|
|
186
|
+
| :--- | :--- | :--- |
|
|
187
|
+
| `AsynchronousSemantic` | Der Kern‑Builder für asynchrone Ströme, Ereignisse und push‑basierte lazy Pipelines. | Echtzeit‑Ereignisse, WebSockets, DOM‑Listener oder jeder langlebige/unendliche Strom. |
|
|
188
|
+
| `SynchronousSemantic` | Der Builder für synchrone, speicherinterne oder pull‑basierte eager Ströme. | Statische Daten, endliche Bereiche oder sofortige Iterationsaufgaben. |
|
|
189
|
+
| `toUnordered()` | Der schnellste terminale Collector, verwendet eine Map zur Indexspeicherung. | Leistungskritische Pfade, bei denen stabile Reihenfolge nicht erforderlich ist (O(n) Zeit & Speicher). |
|
|
190
|
+
| `toOrdered()` | Ein sortierter, indexstabiler terminaler Collector. | Wenn die Elementreihenfolge erhalten bleiben muss oder Indexzugriff benötigt wird. |
|
|
191
|
+
| `toNumericStatistics()` | Ein Collector, der umfangreiche statistische Analysen auf `number`‑Strömen ermöglicht. | Datenanalyse, Metriken und statistische Berechnungen. |
|
|
192
|
+
| `toBigIntStatistics()` | Ein Collector, der umfangreiche statistische Analysen auf `bigint`‑Strömen ermöglicht. | Analyse und Statistik für große Integer‑Datensätze. |
|
|
193
|
+
| `toWindow()` | Bietet Sliding‑ und Tumbling‑Window‑Operationen über einen Strom. | Zeitreihenanalyse, Batch‑Verarbeitung und Fenster‑Aggregationen. |
|
|
92
194
|
|
|
93
|
-
|
|
94
|
-
Um ein Ergebnis zu erhalten, müssen Sie ein Collectable erhalten und eine Terminaloperation aufrufen.
|
|
195
|
+
---
|
|
95
196
|
|
|
96
|
-
|
|
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
|
-
);
|
|
111
|
-
```
|
|
197
|
+
**Wesentliche Nutzungsregeln**
|
|
112
198
|
|
|
113
|
-
|
|
114
|
-
|
|
199
|
+
1. **Ereignisströme** (erstellt über Fabriken wie `useSubscription`) geben ein `AsynchronousSemantic` zurück.
|
|
200
|
+
→ Sie **müssen** eine grenzendefinierende Methode wie `.limit(n)`, `.sub(start, end)` oder `.takeWhile(predicate)` aufrufen, um den Listener zu beenden. Andernfalls bleibt das Abonnement aktiv.
|
|
115
201
|
|
|
116
|
-
|
|
117
|
-
|
|
202
|
+
2. **Terminale Operationen** (`.toArray()`, `.count()`, `.forEach()`, `.findFirst()`, etc.) sind **erst nach** der Umwandlung der Pipeline in einen Collector **verfügbar**:
|
|
203
|
+
```typescript
|
|
204
|
+
.toUnordered() // Für maximale Geschwindigkeit, Reihenfolge nicht garantiert.
|
|
205
|
+
// oder
|
|
206
|
+
.toOrdered() // Für stabile, sortierte Ausgabe.
|
|
207
|
+
// oder
|
|
208
|
+
.toNumericStatistics() // Für statistische Methoden.
|
|
209
|
+
```
|
|
118
210
|
|
|
119
|
-
|
|
120
|
-
const first5Clicks = await useDocument('click')
|
|
121
|
-
.limit(5) // <- Essentiell: Begrenzt den Stream auf 5 Ereignisse
|
|
122
|
-
.toUnordered()
|
|
123
|
-
.toArray();
|
|
211
|
+
---
|
|
124
212
|
|
|
125
|
-
|
|
126
|
-
const clicksIn10s = await useDocument('click')
|
|
127
|
-
.takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
|
|
128
|
-
.toUnordered()
|
|
129
|
-
.toArray();
|
|
213
|
+
### Leistungsmerkmale
|
|
130
214
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
215
|
+
| Collector | Zeitkomplexität | Speicherkomplexität | Reihenfolge garantiert? | Ideales Szenario |
|
|
216
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
217
|
+
| `toUnordered()` | O(n) | O(n) | Nein | Rohdurchsatz ist entscheidend; Endreihenfolge irrelevant. |
|
|
218
|
+
| `toOrdered()` | O(n log n) | O(n) | Ja (sortiert) | Stabile Reihenfolge, Indexzugriff oder Vorsortierung für Statistiken. |
|
|
219
|
+
| `toNumericStatistics()` | O(n log n) | O(n) | Ja (interne Sortierung) | Durchführung statistischer Operationen, die sortierte Daten erfordern. |
|
|
220
|
+
| `toBigIntStatistics()` | O(n log n) | O(n) | Ja (interne Sortierung) | Statistische Operationen auf BigInt‑Daten. |
|
|
221
|
+
| `toWindow()` | O(n log n) | O(n) | Ja (interne Sortierung) | Fensteroperationen, die von sortierten Indizes profitieren. |
|
|
137
222
|
|
|
138
|
-
|
|
223
|
+
Wählen Sie `toUnordered()`, wenn absolute Geschwindigkeit entscheidend ist. Entscheiden Sie sich nur dann für `toOrdered()` oder einen Statistik‑Collector, wenn Ihre Logik von der Elementreihenfolge abhängt.
|
|
139
224
|
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
|
|
225
|
+
---
|
|
143
226
|
|
|
144
|
-
|
|
145
|
-
const median = await numericStream.median();
|
|
146
|
-
const standardDeviation = await numericStream.standardDeviation();
|
|
147
|
-
const skewness = await numericStream.skewness();
|
|
227
|
+
**Vergleichende Analyse mit modernen Stream‑Bibliotheken**
|
|
148
228
|
|
|
149
|
-
|
|
150
|
-
|
|
229
|
+
| Merkmal | Semantic‑TypeScript | RxJS | Native Async Iterators / Generators | Most.js |
|
|
230
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
231
|
+
| **TypeScript‑Integration** | Erstklassig, tief typisiert mit inhärenter Index‑Wahrnehmung. | Hervorragend, beinhaltet jedoch oft komplexe Generika‑Ketten. | Gut, erfordert jedoch manuelle Typannotationen. | Stark, mit funktional‑first‑Typisierungsstil. |
|
|
232
|
+
| **Integrierte Statistik‑Analyse** | Umfassende native Unterstützung für `number` und `bigint`. | Nicht nativ verfügbar (erfordert benutzerdefinierte Operatoren oder andere Bibliotheken). | Keine. | Keine. |
|
|
233
|
+
| **Indizierung & Positionsbewusstsein** | Native, leistungsstarke BigInt‑Indizierung für jedes Element. | Erfordert benutzerdefinierte Operatoren (z.B. `scan`, `withLatestFrom`). | Manuelle Zählerverwaltung notwendig. | Basis, keine integrierte Index‑Eigenschaft. |
|
|
234
|
+
| **Ereignisstrom‑Management** | Dedizierte, typsichere Fabriken mit expliziter, deklarativer Lebenszyklus‑Steuerung. | Leistungsstark, erfordert jedoch sorgfältige manuelle Abonnementverwaltung, um Lecks zu verhindern. | Manuelles Anhängen von Event‑Listenern und Verwaltung von Abbruchtokens. | Gutes `fromEvent`, generell leichtgewichtig. |
|
|
235
|
+
| **Leistung & Speicher** | Herausragend – bietet optimierte `toUnordered()` und `toOrdered()` Collector. | Sehr gut, tiefe Operator‑Ketten können jedoch Overhead einführen. | Hervorragend (minimaler nativer Overhead). | Hervorragend. |
|
|
236
|
+
| **Bundle‑Größe** | Sehr leichtgewichtig. | Substantiell (selbst mit Tree‑Shaking). | Null (natives Sprachfeature). | Klein. |
|
|
237
|
+
| **API‑Design‑Philosophie** | Funktionales Collector‑Muster mit expliziter Index‑Semantik. | Reaktives Observable‑Muster. | Imperatives Iterator / deklaratives Generator‑Muster. | Funktional, point‑free Komposition. |
|
|
238
|
+
| **Flusskontrolle** | Explizit (`interrupt`, `.limit()`, `.takeWhile()`, `.sub()`). | Gut (`take`, `takeUntil`, `first`). | Manuell (`break` in Schleifen). | Gut (`take`, `until`). |
|
|
239
|
+
| **Sync & Async Support** | Vereinheitlichte API – Erstklassiger Support für beide Paradigmen. | Hauptsächlich asynchron. | Beide unterstützt, aber mit manueller Brücke. | Hauptsächlich asynchron. |
|
|
240
|
+
| **Lernkurve** | Flach für Entwickler, die mit funktionalen und indizierten Collection‑Pipelines vertraut sind. | Steiler (umfangreicher Operator‑Wortschatz, Hot/Cold‑Observable‑Konzepte). | Niedrig bis mittel. | Mittel. |
|
|
151
241
|
|
|
152
|
-
|
|
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
|
|
182
|
-
```typescript
|
|
183
|
-
import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
|
|
184
|
-
|
|
185
|
-
interface Transaction {
|
|
186
|
-
id: number;
|
|
187
|
-
amount: number;
|
|
188
|
-
category: string;
|
|
189
|
-
}
|
|
190
|
-
|
|
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
|
-
);
|
|
242
|
+
**Der Semantic‑TypeScript‑Vorteil**
|
|
208
243
|
|
|
209
|
-
|
|
210
|
-
|
|
244
|
+
* **Einzigartige Fähigkeiten:** Integrierte Statistik‑ und Index‑Funktionen eliminieren die Notwendigkeit manueller `reduce`‑Operationen oder ergänzender Datenanalyse‑Bibliotheken.
|
|
245
|
+
* **Vorhersehbare Ressourcenverwaltung:** Explizite Kontrolle über Ereignisströme verhindert die speicherlecks, die in RxJS‑Anwendungen subtil auftreten können.
|
|
246
|
+
* **Vereinheitlichtes Design:** Eine konsistente API für sowohl synchrone als auch asynchrone Workflows reduziert kognitive Belastung und Code‑Duplizierung.
|
|
247
|
+
|
|
248
|
+
Dieser Vergleich unterstreicht, warum Semantic‑TypeScript besonders gut für moderne TypeScript‑Anwendungen geeignet ist, die hohe Leistung, robuste Typsicherheit und umfangreiche Datenverarbeitungsfunktionen ohne die Komplexität traditioneller reaktiver Frameworks erfordern.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### Beginnen Sie Ihre Erkundung
|
|
253
|
+
|
|
254
|
+
Semantic‑TypeScript verwandelt komplexe Datenflüsse in lesbare, komponierbare und hochleistungsfähige Pipelines. Egal, ob Sie Echtzeit‑UI‑Ereignisse verarbeiten, umfangreiche Datensätze bearbeiten oder Analyse‑Dashboards erstellen – es bietet die Leistung von Datenbank‑Level‑Indizierung mit der Eleganz der funktionalen Programmierung.
|
|
255
|
+
|
|
256
|
+
**Ihre nächsten Schritte:**
|
|
257
|
+
|
|
258
|
+
* Erkunden Sie die vollständig typisierte API direkt in Ihrer IDE (alle Exporte sind über den Hauptpaket‑Einstiegspunkt verfügbar).
|
|
259
|
+
* Werden Sie Teil der wachsenden Community von Entwicklern, die komplexe asynchrone Iteratoren und reaktive Ketten durch klare, intentionale Semantic‑Pipelines ersetzt haben.
|
|
260
|
+
|
|
261
|
+
**Semantic‑TypeScript** – wo Ströme auf Struktur treffen.
|
|
262
|
+
|
|
263
|
+
Beginnen Sie noch heute mit dem Bauen und erleben Sie den spürbaren Unterschied, den durchdachte Indizierung bringt.
|
|
211
264
|
|
|
212
|
-
|
|
265
|
+
**Bauen Sie mit Klarheit, handeln Sie mit Vertrauen und transformieren Sie Daten mit Absicht.**
|
|
213
266
|
|
|
214
|
-
|
|
267
|
+
MIT © Eloy Kim
|