semantic-typescript 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.md CHANGED
@@ -1,214 +1,270 @@
1
- # Semantic-TypeScript: A Paradigm-Shifting Stream Processing Library
2
-
3
- ## Introduction
4
- Semantic-TypeScript represents a significant advancement in stream processing technology, synthesising the most effective concepts from JavaScript GeneratorFunctions, Java Streams, and database indexing paradigms. Its foundational design principle is centred on constructing exceptionally efficient data processing pipelines through sophisticated, lazy evaluation and intelligent indexing. The library delivers a rigorously type-safe, functionally pure streaming operation experience specifically engineered for contemporary TypeScript and JavaScript development.
5
-
6
- In contrast to conventional synchronous processing architectures, Semantic-TypeScript implements a unified model that gracefully handles both synchronous (Iterable) and asynchronous (AsyncIterable) data sources. During stream generation, the flow and termination of data are precisely controlled by callback mechanisms, enabling the library to handle with exceptional grace:
7
-
8
- - Real-time data streams (DOM events, WebSockets, intervals) with deterministic control
9
- - Large-scale datasets through memory-efficient, lazy pipelines
10
- - Complex data transformations with a fluent, declarative API
11
-
12
- The library's innovative approach fundamentally reimagines how developers interact with sequences of data, providing both unprecedented performance characteristics and developer ergonomics in a single, cohesive package.
13
-
14
- ## Core Philosophy: Separation of Definition and Execution
15
- A key architectural insight of Semantic-TypeScript is the clear separation between a stream's definition and its execution:
16
-
17
- - **Semantic<E>**: An immutable, lazy blueprint of a data transformation pipeline. It defines what operations (filter, map, etc.) will be performed
18
- - **Collectable<E>**: A materialised, executable view of the stream. It is obtained from a Semantic and provides all terminal operations (collect, forEach, etc.) to execute the pipeline and produce a result
19
-
20
- This separation enforces a clean mental model and unlocks powerful optimisations, such as choosing an UnorderedCollectable to skip unnecessary sorting for maximum speed.
21
-
22
- ## Why Choose Semantic-TypeScript?
23
- Selecting the right library for data stream processing involves balancing performance, type safety, and expressiveness. Semantic-TypeScript is engineered to excel across all these dimensions.
24
-
25
- ### 1. A Unified, Type-Safe Paradigm for All Data Sequences
26
- It provides a consistent, declarative API for processing any data sequence—be it static arrays, real-time events, or asynchronous chunks—while leveraging TypeScript's full power to ensure end-to-end type safety. This eliminates a whole class of runtime errors and transforms stream manipulation into a predictable, compiler-verified activity.
27
-
28
- ### 2. Uncompromising Performance with Intelligent Laziness
29
- At its core, the library is built on lazy evaluation. Operations like filter, map, and flatMap merely compose a processing pipeline; no work is done until a terminal operation is invoked. This is coupled with short-circuiting capabilities (via limit, anyMatch, or custom interrupt callbacks), which allows processing to stop early, dramatically improving efficiency for large or infinite streams.
30
-
31
- ### 3. The Power of the `Collector<E, A, R>` Pattern
32
- Inspired by Java, the Collector pattern is the engine of flexibility. It decouples the specification of how to accumulate stream elements from the execution of the stream itself. The library provides a rich set of built-in collectors (toArray, groupBy, summate, etc.) for everyday tasks, while making it trivial to implement your own complex, reusable reduction logic. This is far more powerful and composable than a fixed set of terminal methods.
33
-
34
- ### 4. First-Class Support for Modern Web & Async Data
35
- Semantic-TypeScript is designed for contemporary development. It offers native factory methods for modern web sources:
36
-
37
- - `useFrom(iterable)`, `useRange()` for static data
38
- - `useInterval()`, `useAnimationFrame()` for time-based streams
39
- - `useBlob()` for chunked binary data processing
40
- - `useWebSocket()`, `useDocument()`, `useWindow()` for real-time event streams
41
-
42
- ### 5. Beyond Basic Aggregation: Built-in Statistical Analysis
43
- Move beyond simple sums and averages. The library provides dedicated NumericStatistics and BigIntStatistics interfaces, offering immediate access to advanced statistical measures directly from your streams—variance, standard deviation, median, skewness, and kurtosis. This turns complex data analysis into a one-liner.
44
-
45
- ### 6. Designed for Developer Ergonomics
46
- - **Fluent, Chainable API**: Write complex data pipelines as readable, sequential chains
47
- - **Comprehensive Utility Suite**: Essential guards (isFunction, isIterable), utilities (useCompare, useTraverse), and functional interfaces included
48
- - **Optional<T> Integration**: Safely models the absence of a value, eliminating null-pointer concerns
49
- - **Performance Guidance**: Clear guidance on when to use unordered collection for speed versus ordered for sequence
50
-
51
- ## Installation
52
- ```bash
53
- npm install semantic-typescript
54
- ```
55
-
56
- ## Core Concepts in Practice
57
-
58
- ### 1. Creating Streams (Semantic)
59
- Streams can be created from various sources using factory functions.
60
-
61
- ```typescript
62
- import { useFrom, useInterval, useDocument } from 'semantic-typescript';
63
-
64
- // From a static array
65
- const staticStream = useFrom([1, 2, 3, 4, 5]);
66
-
67
- // From an asynchronous generator
68
- const asyncStream = useFrom(async function*() {
69
- yield 1;
70
- yield 2;
71
- });
72
-
73
- // A time-based stream
74
- const tickStream = useInterval(1000); // emits every second
75
-
76
- // A DOM event stream (see crucial note below)
77
- const clickStream = useDocument('click');
78
- ```
79
-
80
- ### 2. Transforming Streams (Intermediate Operations)
81
- Operations are lazily chained to define the pipeline.
82
-
83
- ```typescript
84
- const processedStream = staticStream
85
- .filter(x => x % 2 === 0) // Keep only even numbers
86
- .map(x => x * 10) // Multiply by 10
87
- .flatMap(x => [x, x + 1]) // Transform each element into two
88
- .distinct(); // Remove duplicates
89
-
90
- // Nothing has been executed yet
91
- ```
92
-
93
- ### 3. Executing Streams (Terminal Operations)
94
- To get a result, you must obtain a Collectable and invoke a terminal operation.
95
-
96
- ```typescript
97
- // Get an unordered collectable for performance
98
- const resultArray = await processedStream.toUnordered().toArray();
99
- console.log(resultArray); // e.g., [20, 21, 40, 41]
100
-
101
- // Use a built-in collector
102
- const sum = await processedStream.toUnordered().collect(useSummate());
103
- console.log(sum);
104
-
105
- // Or use the generic collect method
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
- ```
112
-
113
- ### 4. Crucial: Working with Event Streams
114
- Event streams (useDocument, useWindow, useHTMLElement, useWebSocket) are infinite by nature. You must use operations like sub, takeWhile, or limit to define when to stop collecting events and complete the stream. Otherwise, the terminal operation will wait indefinitely.
115
-
116
- ```typescript
117
- import { useDocument } from 'semantic-typescript';
118
-
119
- // Collect only the first 5 clicks
120
- const first5Clicks = await useDocument('click')
121
- .limit(5) // <- Essential: limits the stream to 5 events
122
- .toUnordered()
123
- .toArray();
124
-
125
- // Collect clicks for a 10-second window
126
- const clicksIn10s = await useDocument('click')
127
- .takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
128
- .toUnordered()
129
- .toArray();
130
-
131
- // Collect clicks from index 2 to 5 (0-based)
132
- const specificClicks = await useDocument('click')
133
- .sub(2n, 6n) // <- Takes elements with index 2, 3, 4, 5
134
- .toUnordered()
135
- .toArray();
136
- ```
137
-
138
- **Key Insight**: The event (e.g., a MouseEvent) and its sequential firing index (as a bigint) are passed together through the pipeline via the `accept(event, index)` callback.
139
-
140
- ### 5. Leveraging Statistics
141
- ```typescript
142
- const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
143
-
144
- const average = await numericStream.average();
145
- const median = await numericStream.median();
146
- const standardDeviation = await numericStream.standardDeviation();
147
- const skewness = await numericStream.skewness();
148
-
149
- console.log(`Average: ${average}, Median: ${median}, StdDev: ${standardDeviation}`);
150
- ```
151
-
152
- ## Main Features
153
- - **Dual Stream Types**: Full support for both SynchronousSemantic (for Iterable) and AsynchronousSemantic (for AsyncIterable and events)
154
- - **Rich Operation Set**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
155
- - **Flexible Terminal Operations**: collect (with custom collectors), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
156
- - **Advanced Collectors**: Built-in collectors for joining, groupingBy, partitioningBy, summing, averaging, maxBy, minBy
157
- - **Statistical Module**: Ready-to-use methods for mean, median, mode, variance, standardDeviation, range, quantiles, skewness, kurtosis on numeric/bigint streams
158
- - **Utility Functions**: Type guards (isPromise, isAsyncIterable), comparators (useCompare), traversal (useTraverse), and conversion hooks
159
- - **Optional<T>**: A monadic container for nullable values, integrated with find operations
160
-
161
- ## API Overview
162
- ### Core Classes & Interfaces
163
- - `Semantic<E>` / `AsynchronousSemantic<E>`: The abstract stream definition
164
- - `Collectable<E>` / `AsynchronousCollectable<E>`: The executable stream with terminal operations
165
- - `OrderedCollectable<E>` / `UnorderedCollectable<E>`: Materialised versions optimised for order-sensitive or order-insensitive operations
166
- - `Collector<E, A, R>`: The abstraction for mutable reduction operations
167
-
168
- ### Factory Functions (use*)
169
- - **From Sources**: useFrom, useRange, useFill, useEmpty
170
- - **From Time**: useInterval, useAnimationFrame
171
- - **From Web APIs**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
172
- - **Collectors**: useToArray, useGroupBy, useSummate, useJoin, etc.
173
-
174
- ## Performance Notes
175
- - **Lazy Evaluation**: Pipelines are composed without execution until a terminal operation is called
176
- - **Short-Circuiting**: Operations like limit, anyMatch, and findFirst will stop processing elements as soon as the result is determined
177
- - **Ordered vs Unordered**:
178
- - Use `.toUnordered()` for terminal operations when the order of the source elements does not matter to your result (e.g., for sum, max, or toSet). This can allow internal optimisations that skip costly sorting steps
179
- - Use `.toOrdered()` when sequence is important (e.g., for toArray where order must be preserved)
180
-
181
- ## Getting Started Example
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
- // Calculate total amount per category
199
- const totalsByCategory = await useFrom(transactions)
200
- .toUnordered()
201
- .collect(
202
- useGroupBy(
203
- t => t.category,
204
- t => t.amount,
205
- useSummate() // Collector for the values
206
- )
207
- );
208
-
209
- console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
210
- ```
211
-
212
- Semantic-TypeScript is built for developers who seek a rigorously designed, type-safe, and high-performance stream processing library. It brings the power of enterprise-level data transformation patterns to the TypeScript ecosystem, perfectly suited for data-intensive front-end applications, Node.js data processing, and any scenario where elegant, efficient handling of sequences is required.
213
-
214
- [![GitHub](./GitHub.png)](https://github.com/eloyhere/semantic-typescript) [![NPM](./NPM.png)](https://www.npmjs.com/package/semantic-typescript)
1
+ # **SemanticTypeScript**
2
+ **Flow, Indexed.** Your data, under precise control.
3
+
4
+ ---
5
+
6
+ ### Overview
7
+
8
+ Semantic‑TypeScript represents a significant evolution in stream processing, elegantly **synthesising** the most effective paradigms from JavaScript generators, Java Streams, and MySQL-style indexing. Its foundational premise is both powerful and deliberate: to construct exceptionally efficient data‑processing pipelines through intelligent indexing, rather than through conventional brute‑force iteration.
9
+
10
+ Where typical libraries enforce synchronous loops or unwieldy promise chains, Semantic‑TypeScript provides a **fully asynchronous**, functionally pure, and rigorously type‑safe experience, designed expressly for the demands of modern application development.
11
+
12
+ This model embodies a refined form of control flow: data only proceeds to the consumer when the upstream pipeline explicitly invokes the `accept` callback. You retain complete, granular command over timing—processing occurs precisely when, and only when, it is required.
13
+
14
+ ---
15
+
16
+ ### Why Developers Choose Semantic‑TypeScript
17
+
18
+ - **Zero‑Boilerplate Indexing** Every element inherently possesses its natural or bespoke index, eliminating manual tracking.
19
+ - **Purely Functional & Type‑Safe** – Enjoy full, idiomatic TypeScript inference alongside immutable operations.
20
+ - **Leak‑Proof Event Streams** – The `useSubscription` pattern is designed with resource safety as a first principle. You define the logical boundary—using `limit(n)`, `sub(start, end)`, or `takeWhile(predicate)`—and the library manages the complete subscription lifecycle. This ensures no lingering listeners and no memory leaks.
21
+ - **Built‑in Statistical Suite** – Access comprehensive analytics for both `number` and `bigint` streams, including averages, medians, modes, variance, skewness, and kurtosis without external dependencies.
22
+ - **Predictable, Tunable Performance** – Select between ordered or unordered collectors to match your exact performance and ordering requirements.
23
+ - **Inherently Memory‑Efficient** Streams are evaluated lazily, processing elements on‑demand to alleviate memory pressure.
24
+ - **No Undefined Behaviour** – TypeScript guarantees complete type safety and nullability. Your source data remains immutable unless explicitly altered within your callback functions.
25
+
26
+ ---
27
+
28
+ ### Installation
29
+
30
+ Integrate Semantic‑TypeScript into your project using your preferred package manager:
31
+
32
+ ```bash
33
+ npm install semantic-typescript
34
+ ```
35
+ or
36
+ ```bash
37
+ yarn add semantic-typescript
38
+ ```
39
+
40
+ ---
41
+
42
+ ### A Practical Introduction
43
+
44
+ The following examples demonstrate core concepts, from foundational transformations to real‑world event handling.
45
+
46
+ ```typescript
47
+ import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
48
+
49
+ // ====================================================================
50
+ // EXAMPLE 1: Foundational Operations & Numeric Statistics
51
+ // ====================================================================
52
+ // Demonstrates mapping and terminal statistical operations. After transformation,
53
+ // the pipeline must be converted to a statistics collector before calling
54
+ // terminal methods like `.summate()`.
55
+
56
+ const numericSum: number = useOf(10, 20, 30, 40)
57
+ .map((n: number): number => n * 2) // Double each element: [20, 40, 60, 80]
58
+ .toNumericStatistics() // Convert to a statistics collector
59
+ .summate(); // Terminal operation: 200
60
+
61
+ // Additional statistical methods (available after .toNumericStatistics()):
62
+ // .average(), .median(), .mode(), .variance(), .skewness(), .kurtosis()
63
+
64
+ // ====================================================================
65
+ // EXAMPLE 2: BigInt Statistics
66
+ // ====================================================================
67
+ // Operates identically to numeric statistics but is optimised for BigInt data.
68
+
69
+ const bigintSum: bigint = useOf(10n, 20n, 30n, 40n)
70
+ .map((n: bigint): bigint => n * 2n) // BigInt arithmetic
71
+ .toBigIntStatistics() // Convert to BigInt statistics collector
72
+ .summate(); // Terminal operation: 200n
73
+
74
+ // ====================================================================
75
+ // EXAMPLE 3: Index Manipulation for Stream Reversal
76
+ // ====================================================================
77
+ // Illustrates reordering elements by strategically reassigning their indices
78
+ // using the `.redirect()` method, enabling custom patterns like reversal.
79
+
80
+ const reversedArray: number[] = useFrom([1, 2, 3, 4, 5])
81
+ .redirect((_element: number, index: bigint): bigint => -index) // Map to negative indices
82
+ .toOrdered() // Essential: collects elements sorted by their new indices
83
+ .toArray(); // Result: [5, 4, 3, 2, 1]
84
+
85
+ // For simple reversal, `.reverse()` is also available.
86
+
87
+ // ====================================================================
88
+ // EXAMPLE 4: Stream Shuffling
89
+ // ====================================================================
90
+ // Randomly permutes element indices using an in-place shuffle algorithm.
91
+
92
+ const shuffledArray: number[] = useFrom([1, 2, 3, 4, 5])
93
+ .shuffle() // Randomly reassigns indices
94
+ .toOrdered() // Orders by the new random indices
95
+ .toArray(); // e.g., [2, 5, 1, 4, 3] (varies per execution)
96
+
97
+ // ====================================================================
98
+ // EXAMPLE 5: Circular Stream Rotation
99
+ // ====================================================================
100
+ // Shifts elements cyclically. Positive values rotate right; negative values rotate left.
101
+
102
+ // Right rotation by 2 positions
103
+ const rightRotated: number[] = useFrom([1, 2, 3, 4, 5])
104
+ .translate(2) // Shift indices right by 2
105
+ .toOrdered()
106
+ .toArray(); // Result: [4, 5, 1, 2, 3]
107
+
108
+ // ====================================================================
109
+ // EXAMPLE 6: Lazy Evaluation with Infinite Ranges
110
+ // ====================================================================
111
+ // Processes theoretically infinite streams lazily, computing elements only as needed.
112
+
113
+ const firstTenMultiples: bigint[] = useRange(0n, 1_000_000n)
114
+ .filter(n => n % 17n === 0n) // Keep multiples of 17
115
+ .limit(10n) // Critical: stops after the 10th match
116
+ .toUnordered() // No sorting required
117
+ .toArray(); // Result: [0, 17, 34, 51, 68, 85, 102, 119, 136, 153]
118
+
119
+ // Without `.limit(10n)`, the pipeline would process all one million elements.
120
+
121
+ // ====================================================================
122
+ // EXAMPLE 7: Composing a Complex Pipeline
123
+ // ====================================================================
124
+ // Demonstrates sequential composition of multiple operations.
125
+
126
+ const complexResult: number[] = useRange(1n, 100n)
127
+ .map(n => Number(n) * 2)
128
+ .filter(n => n > 50)
129
+ .shuffle()
130
+ .limit(5n)
131
+ .translate(2)
132
+ .toOrdered()
133
+ .toArray();
134
+
135
+ // ====================================================================
136
+ // EXAMPLE 8: Managed DOM Event Subscription
137
+ // ====================================================================
138
+ // Listens to browser events with automatic, leak-proof cleanup.
139
+ // The `.limit(n)` call defines the boundary for automatic listener removal.
140
+
141
+ // Define a subscriber for a Window target
142
+ const windowSubscriber = {
143
+ mount: (target: Window): void => { /* Setup logic */ },
144
+ subscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
145
+ target.addEventListener(event, handler);
146
+ },
147
+ unsubscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
148
+ target.removeEventListener(event, handler);
149
+ },
150
+ unmount: (): void => { /* Cleanup logic */ }
151
+ };
152
+
153
+ useSubscription(window, windowSubscriber, "resize")
154
+ .limit(5n) // Automatically unsubscribes after 5 events
155
+ .toUnordered()
156
+ .forEach((ev: Event, idx) =>
157
+ console.log(`Resize #${idx}: ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
158
+ );
159
+
160
+ // ====================================================================
161
+ // EXAMPLE 9: String Processing by Unicode Code Points
162
+ // ====================================================================
163
+ // Iterates over a string correctly, handling multi-byte Unicode characters.
164
+
165
+ useText("My emotion now is: 😊, and semantic is 👍")
166
+ .toUnordered()
167
+ .log(); // Logs each character, including emoji, on a new line.
168
+
169
+ // ====================================================================
170
+ // EXAMPLE 10: Safe Circular Reference Stringification
171
+ // ====================================================================
172
+ // Safely serialises objects containing circular references.
173
+
174
+ const obj = {
175
+ a: 1,
176
+ b: "text"
177
+ };
178
+ (obj as any).c = [obj.a, obj.b, (obj as any).c]; // Introduce circularity
179
+
180
+ // const text: string = JSON.stringify(obj); // Throws an error
181
+ const text: string = useStringify(obj); // Safely yields `{a: 1, b: "text", c: []}`
182
+ ```
183
+
184
+ ---
185
+
186
+ ### Core Concepts
187
+
188
+ | Concept | Purpose | Primary Use Case |
189
+ | :--- | :--- | :--- |
190
+ | `AsynchronousSemantic` | The core builder for asynchronous streams, events, and lazy, push‑based pipelines. | Real‑time events, WebSockets, DOM listeners, or any long‑running/infinite stream. |
191
+ | `SynchronousSemantic` | The builder for synchronous, in‑memory, or eager, pull‑based streams. | Static data, finite ranges, or immediate iteration tasks. |
192
+ | `toUnordered()` | The fastest terminal collector, using a Map for index storage. | Performance‑critical paths where stable order is not required (O(n) time & space). |
193
+ | `toOrdered()` | A sorted, index‑stable terminal collector. | When element order must be preserved or indexed access is needed. |
194
+ | `toNumericStatistics()` | A collector enabling rich statistical analysis on `number` streams. | Data analytics, metrics, and statistical computations. |
195
+ | `toBigIntStatistics()` | A collector enabling rich statistical analysis on `bigint` streams. | Analytics and statistics for large integer datasets. |
196
+ | `toWindow()` | Provides sliding and tumbling window operations over a stream. | Time‑series analysis, batch processing, and windowed aggregations. |
197
+
198
+ ---
199
+
200
+ **Essential Usage Rules**
201
+
202
+ 1. **Event streams** (created via factories like `useSubscription`) return an `AsynchronousSemantic`.
203
+ You **must** call a boundary‑defining method like `.limit(n)`, `.sub(start, end)`, or `.takeWhile(predicate)` to terminate the listener. Failure to do so will leave the subscription active.
204
+
205
+ 2. **Terminal operations** (`.toArray()`, `.count()`, `.forEach()`, `.findFirst()`, etc.) are **only available after** converting the pipeline to a collector:
206
+ ```typescript
207
+ .toUnordered() // For maximum speed, order not guaranteed.
208
+ // or
209
+ .toOrdered() // For stable, sorted output.
210
+ // or
211
+ .toNumericStatistics() // For statistical methods.
212
+ ```
213
+
214
+ ---
215
+
216
+ ### Performance Characteristics
217
+
218
+ | Collector | Time Complexity | Space Complexity | Order Guarantee? | Ideal Scenario |
219
+ | :--- | :--- | :--- | :--- | :--- |
220
+ | `toUnordered()` | O(n) | O(n) | No | Raw throughput is key; final order is irrelevant. |
221
+ | `toOrdered()` | O(n log n) | O(n) | Yes (sorted) | Stable ordering, indexed access, or pre‑sorting for statistics. |
222
+ | `toNumericStatistics()` | O(n log n) | O(n) | Yes (internal sort) | Performing statistical operations which require sorted data. |
223
+ | `toBigIntStatistics()` | O(n log n) | O(n) | Yes (internal sort) | Statistical operations on BigInt data. |
224
+ | `toWindow()` | O(n log n) | O(n) | Yes (internal sort) | Windowing operations which benefit from sorted indices. |
225
+
226
+ Select `toUnordered()` when absolute speed is paramount. Opt for `toOrdered()` or a statistics collector only when your logic depends on element order.
227
+
228
+ ---
229
+
230
+ **Comparative Analysis with Contemporary Stream Libraries**
231
+
232
+ | Feature | Semantic‑TypeScript | RxJS | Native Async Iterators / Generators | Most.js |
233
+ | :--- | :--- | :--- | :--- | :--- |
234
+ | **TypeScript Integration** | First‑class, deeply typed with inherent index awareness. | Excellent, though often involving complex generic chains. | Good, but requires manual type annotations. | Strong, with a functional‑first typing style. |
235
+ | **Built‑in Statistical Analysis** | Comprehensive native support for `number` and `bigint`. | Not available natively (requires custom operators or other libraries). | None. | None. |
236
+ | **Indexing & Position Awareness** | Native, powerful BigInt indexing on every element. | Requires custom operators (e.g., `scan`, `withLatestFrom`). | Manual counter management is necessary. | Basic, no built‑in index property. |
237
+ | **Event Stream Management** | Dedicated, type‑safe factories with explicit, declarative lifecycle control. | Powerful but requires careful manual subscription management to prevent leaks. | Manual event listener attachment and cancellation token management. | Good `fromEvent`, generally lightweight. |
238
+ | **Performance & Memory** | Exceptional – offers optimised `toUnordered()` and `toOrdered()` collectors. | Very good, though deep operator chains can introduce overhead. | Excellent (minimal native overhead). | Excellent. |
239
+ | **Bundle Size** | Very lightweight. | Substantial (even with tree‑shaking). | Zero (native language feature). | Small. |
240
+ | **API Design Philosophy** | Functional collector pattern with explicit indexing semantics. | Reactive Observable pattern. | Imperative Iterator / declarative Generator pattern. | Functional, point‑free composition. |
241
+ | **Flow Control** | Explicit (`interrupt`, `.limit()`, `.takeWhile()`, `.sub()`). | Good (`take`, `takeUntil`, `first`). | Manual (`break` in loops). | Good (`take`, `until`). |
242
+ | **Sync & Async Support** | Unified API – first‑class support for both paradigms. | Primarily asynchronous. | Both supported, but with manual bridging. | Primarily asynchronous. |
243
+ | **Learning Curve** | Gentle for developers familiar with functional and indexed collection pipelines. | Steeper (extensive operator lexicon, hot/cold observable concepts). | Low to moderate. | Moderate. |
244
+
245
+ **The Semantic‑TypeScript Advantage**
246
+
247
+ * **Unique Capabilities:** Integrated statistical and indexing features eliminate the need for manual `reduce` operations or supplementary data‑analysis libraries.
248
+ * **Predictable Resource Management:** Explicit control over event streams prevents the memory leaks that can be subtle in RxJS applications.
249
+ * **Unified Design:** A consistent API for both synchronous and asynchronous workflows reduces cognitive load and code duplication.
250
+
251
+ This comparison highlights why Semantic‑TypeScript is particularly well‑suited for modern TypeScript applications that demand high performance, robust type safety, and rich data‑processing features without the complexity of traditional reactive frameworks.
252
+
253
+ ---
254
+
255
+ ### Begin Your Exploration
256
+
257
+ Semantic‑TypeScript transforms intricate data flows into readable, composable, and high‑performance pipelines. Whether you are handling real‑time UI events, processing substantial datasets, or constructing analytical dashboards, it delivers the power of database‑grade indexing with the elegance of functional programming.
258
+
259
+ **Your Next Steps:**
260
+
261
+ * Explore the fully typed API directly within your IDE (all exports are available from the main package entry point).
262
+ * Join the growing community of developers who have replaced convoluted async iterators and complex reactive chains with clear, intentional Semantic pipelines.
263
+
264
+ **Semantic‑TypeScript** — where streams meet structure.
265
+
266
+ Begin building today and experience the tangible difference that thoughtful indexing delivers.
267
+
268
+ **Build with clarity, proceed with confidence, and transform data with intent.**
269
+
270
+ MIT © Eloy Kim