semantic-typescript 0.0.8 → 0.1.4

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,529 +1,426 @@
1
- # Semantic-TypeScript Stream Processing Framework
1
+ # Semantic-TypeScript Stream Processing Library
2
2
 
3
3
  ## Introduction
4
4
 
5
- Semantic-TypeScript is a modern stream processing library inspired by JavaScript GeneratorFunction, Java Stream, and MySQL Index. The core design philosophy is based on constructing efficient data processing pipelines through data indexing, providing a type-safe, functional-style streaming operation experience for frontend development.
5
+ Semantic-TypeScript is a modern stream processing library inspired by JavaScript GeneratorFunction, Java Stream, and MySQL Index. Its core design philosophy is based on building efficient data processing pipelines using data indexing, providing a type-safe, functional-style streaming operation experience for front-end development.
6
6
 
7
- Unlike traditional synchronous processing, Semantic employs an asynchronous processing model. When creating data streams, the timing of terminal data reception depends entirely on when upstream calls the `accept` and `interrupt` callback functions. This design enables the library to elegantly handle real-time data streams, large datasets, and asynchronous data sources.
7
+ Unlike traditional synchronous processing, Semantic employs an asynchronous processing model. When creating a data stream, the time when the terminal receives data entirely depends on when the upstream calls the `accept` and `interrupt` callback functions. This design allows the library to elegantly handle real-time data streams, large datasets, and asynchronous data sources.
8
8
 
9
- ## Core Features
9
+ ## Installation
10
10
 
11
- | Feature | Description | Advantage |
12
- |------|------|------|
13
- | **Type-Safe Generics** | Complete TypeScript type support | Compile-time error detection, better development experience |
14
- | **Functional Programming** | Immutable data structures and pure functions | More predictable code, easier testing and maintenance |
15
- | **Lazy Evaluation** | On-demand computation, performance optimisation | High memory efficiency when processing large datasets |
16
- | **Asynchronous Stream Processing** | Generator-based asynchronous data streams | Suitable for real-time data and event-driven scenarios |
17
- | **Multi-Paradigm Collectors** | Ordered, unordered, statistical collection strategies | Optimal strategy selection based on different scenarios |
18
- | **Statistical Analysis** | Built-in complete statistical calculation functions | Integrated data analysis and reporting generation |
19
-
20
- ## Performance Considerations
21
-
22
- **Important Note**: The following methods sacrifice performance to collect and sort data, resulting in ordered data collections:
23
- - `toOrdered()`
24
- - `toWindow()`
25
- - `toNumericStatistics()`
26
- - `toBigIntStatistics()`
27
- - `sorted()`
28
- - `sorted(comparator)`
29
-
30
- Particularly important to note: `sorted()` and `sorted(comparator)` will override the results of the following methods:
31
- - `redirect(redirector)`
32
- - `translate(translator)`
33
- - `shuffle(mapper)`
34
-
35
- ## Factory Methods
36
-
37
- ### Stream Creation Factories
11
+ ```bash
12
+ npm install semantic-typescript
13
+ ```
38
14
 
39
- | Method | Signature | Description | Example |
40
- |------|------|------|------|
41
- | `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | Convert Blob to byte stream | `blob(fileBlob, 1024n)` |
42
- | `empty` | `<E>() => Semantic<E>` | Create empty stream | `empty<number>()` |
43
- | `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | Fill with specified number of elements | `fill("hello", 5n)` |
44
- | `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | Create stream from iterable object | `from([1, 2, 3])` |
45
- | `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | Create numerical range stream | `range(1, 10, 2)` |
46
- | `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | Create stream from generator function | `iterate(myGenerator)` |
47
- | `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | Create event stream from WebSocket | `websocket(socket)` |
15
+ ## Basic Types
16
+
17
+ | Type | Description |
18
+ |------|------|
19
+ | `Invalid<T>` | Type extending null or undefined |
20
+ | `Valid<T>` | Type excluding null and undefined |
21
+ | `MaybeInvalid<T>` | Type that may be null or undefined |
22
+ | `Primitive` | Collection of primitive types |
23
+ | `MaybePrimitive<T>` | Type that may be a primitive type |
24
+ | `OptionalSymbol` | Symbol identifier for the Optional class |
25
+ | `SemanticSymbol` | Symbol identifier for the Semantic class |
26
+ | `CollectorsSymbol` | Symbol identifier for the Collector class |
27
+ | `CollectableSymbol` | Symbol identifier for the Collectable class |
28
+ | `OrderedCollectableSymbol` | Symbol identifier for the OrderedCollectable class |
29
+ | `WindowCollectableSymbol` | Symbol identifier for the WindowCollectable class |
30
+ | `StatisticsSymbol` | Symbol identifier for the Statistics class |
31
+ | `NumericStatisticsSymbol` | Symbol identifier for the NumericStatistics class |
32
+ | `BigIntStatisticsSymbol` | Symbol identifier for the BigIntStatistics class |
33
+ | `UnorderedCollectableSymbol` | Symbol identifier for the UnorderedCollectable class |
34
+ | `Runnable` | Function with no parameters and no return value |
35
+ | `Supplier<R>` | Function with no parameters returning R |
36
+ | `Functional<T, R>` | Single-parameter transformation function |
37
+ | `Predicate<T>` | Single-parameter predicate function |
38
+ | `BiFunctional<T, U, R>` | Two-parameter transformation function |
39
+ | `BiPredicate<T, U>` | Two-parameter predicate function |
40
+ | `Comparator<T>` | Comparison function |
41
+ | `TriFunctional<T, U, V, R>` | Three-parameter transformation function |
42
+ | `Consumer<T>` | Single-parameter consumer function |
43
+ | `BiConsumer<T, U>` | Two-parameter consumer function |
44
+ | `TriConsumer<T, U, V>` | Three-parameter consumer function |
45
+ | `Generator<T>` | Generator function |
48
46
 
49
- **Code Example Supplement:**
50
47
  ```typescript
51
- import { from, range, fill, empty } from 'semantic-typescript';
52
-
53
- // Create stream from array
54
- const numberStream = from([1, 2, 3, 4, 5]);
55
-
56
- // Create numerical range stream
57
- const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
58
-
59
- // Fill with repeated elements
60
- const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
61
-
62
- // Create empty stream
63
- const emptyStream = empty<number>();
48
+ // Type usage examples
49
+ const predicate: Predicate<number> = (n) => n > 0;
50
+ const mapper: Functional<string, number> = (str) => str.length;
51
+ const comparator: Comparator<number> = (a, b) => a - b;
64
52
  ```
65
53
 
66
- ### Utility Function Factories
67
-
68
- | Method | Signature | Description | Example |
69
- |------|------|------|------|
70
- | `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | Validate if value is valid | `validate(null)` `false` |
71
- | `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | Validate if value is invalid | `invalidate(0)` `false` |
72
- | `useCompare` | `<T>(t1: T, t2: T) => number` | Generic comparison function | `useCompare("a", "b")` `-1` |
73
- | `useRandom` | `<T = number\|bigint>(index: T) => T` | Pseudorandom number generator | `useRandom(5)` random number |
54
+ ## Type Guards
55
+
56
+ | Function | Description | Time Complexity | Space Complexity |
57
+ |------|------|------------|------------|
58
+ | `validate<T>(t: MaybeInvalid<T>): t is T` | Validate value is not null or undefined | O(1) | O(1) |
59
+ | `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | Validate value is null or undefined | O(1) | O(1) |
60
+ | `isBoolean(t: unknown): t is boolean` | Check if it is a boolean | O(1) | O(1) |
61
+ | `isString(t: unknown): t is string` | Check if it is a string | O(1) | O(1) |
62
+ | `isNumber(t: unknown): t is number` | Check if it is a number | O(1) | O(1) |
63
+ | `isFunction(t: unknown): t is Function` | Check if it is a function | O(1) | O(1) |
64
+ | `isObject(t: unknown): t is object` | Check if it is an object | O(1) | O(1) |
65
+ | `isSymbol(t: unknown): t is symbol` | Check if it is a Symbol | O(1) | O(1) |
66
+ | `isBigint(t: unknown): t is bigint` | Check if it is a BigInt | O(1) | O(1) |
67
+ | `isPrimitive(t: unknown): t is Primitive` | Check if it is a primitive type | O(1) | O(1) |
68
+ | `isIterable(t: unknown): t is Iterable<unknown>` | Check if it is an iterable object | O(1) | O(1) |
69
+ | `isOptional(t: unknown): t is Optional<unknown>` | Check if it is an Optional instance | O(1) | O(1) |
70
+ | `isSemantic(t: unknown): t is Semantic<unknown>` | Check if it is a Semantic instance | O(1) | O(1) |
71
+ | `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Check if it is a Collector instance | O(1) | O(1) |
72
+ | `isCollectable(t: unknown): t is Collectable<unknown>` | Check if it is a Collectable instance | O(1) | O(1) |
73
+ | `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | Check if it is an OrderedCollectable instance | O(1) | O(1) |
74
+ | `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | Check if it is a WindowCollectable instance | O(1) | O(1) |
75
+ | `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | Check if it is an UnorderedCollectable instance | O(1) | O(1) |
76
+ | `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Check if it is a Statistics instance | O(1) | O(1) |
77
+ | `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | Check if it is a NumericStatistics instance | O(1) | O(1) |
78
+ | `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | Check if it is a BigIntStatistics instance | O(1) | O(1) |
74
79
 
75
- **Code Example Supplement:**
76
80
  ```typescript
77
- import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
81
+ // Type guard usage examples
82
+ const value: unknown = "hello";
78
83
 
79
- // Validate data validity
80
- const data: string | null = "hello";
81
- if (validate(data)) {
82
- console.log(data.toUpperCase()); // Safe call because validate ensures data is not null
84
+ if (isString(value)) {
85
+ console.log(value.length); // Type-safe, value inferred as string
83
86
  }
84
87
 
85
- const nullData: string | null = null;
86
- if (invalidate(nullData)) {
87
- console.log("Data invalid"); // Will execute because invalidate detected null
88
+ if (isOptional(someValue)) {
89
+ someValue.ifPresent(val => console.log(val));
88
90
  }
89
-
90
- // Compare values
91
- const comparison = useCompare("apple", "banana"); // -1
92
-
93
- // Generate random number
94
- const randomNum = useRandom(42); // Random number based on seed 42
95
91
  ```
96
92
 
97
- ## Core Class Details
98
-
99
- ### Optional<T> - Safe Null Value Handling
100
-
101
- The Optional class provides a functional approach to safely handle values that may be null or undefined.
93
+ ## Utility Functions
102
94
 
103
- | Method | Return Type | Description | Time Complexity |
104
- |------|----------|------|------------|
105
- | `filter(predicate: Predicate<T>)` | `Optional<T>` | Filter values satisfying condition | O(1) |
106
- | `get()` | `T` | Get value, throw error if empty | O(1) |
107
- | `getOrDefault(defaultValue: T)` | `T` | Get value or default value | O(1) |
108
- | `ifPresent(action: Consumer<T>)` | `void` | Execute action if value exists | O(1) |
109
- | `isEmpty()` | `boolean` | Check if empty | O(1) |
110
- | `isPresent()` | `boolean` | Check if value exists | O(1) |
111
- | `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | Map and transform value | O(1) |
112
- | `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | Create Optional instance | O(1) |
113
- | `static ofNullable<T>(value?)` | `Optional<T>` | Create nullable Optional | O(1) |
114
- | `static ofNonNull<T>(value: T)` | `Optional<T>` | Create non-null Optional | O(1) |
95
+ | Function | Description | Time Complexity | Space Complexity |
96
+ |------|------|------------|------------|
97
+ | `useCompare<T>(t1: T, t2: T): number` | Generic comparison function | O(1) | O(1) |
98
+ | `useRandom<T = number \| bigint>(index: T): T` | Pseudo-random number generator | O(log n) | O(1) |
115
99
 
116
- **Code Example Supplement:**
117
100
  ```typescript
118
- import { Optional } from 'semantic-typescript';
101
+ // Utility function usage examples
102
+ const numbers = [3, 1, 4, 1, 5];
103
+ numbers.sort(useCompare); // [1, 1, 3, 4, 5]
119
104
 
120
- // Create Optional instance
121
- const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
105
+ const randomNum = useRandom(42); // Seed-based random number
106
+ const randomBigInt = useRandom(1000n); // BigInt random number
107
+ ```
122
108
 
123
- // Chain operations
124
- const result = optionalValue
125
- .filter(val => val.length > 3) // Filter values longer than 3
126
- .map(val => val.toUpperCase()) // Convert to uppercase
127
- .getOrDefault("default"); // Get value or default
109
+ ## Factory Methods
128
110
 
129
- console.log(result); // "HELLO" or "default"
111
+ ### Optional Factory Methods
130
112
 
131
- // Safe operations
132
- optionalValue.ifPresent(val => {
133
- console.log(`Value exists: ${val}`);
134
- });
113
+ | Method | Description | Time Complexity | Space Complexity |
114
+ |------|------|------------|------------|
115
+ | `Optional.empty<T>()` | Create an empty Optional | O(1) | O(1) |
116
+ | `Optional.of<T>(value)` | Create an Optional containing a value | O(1) | O(1) |
117
+ | `Optional.ofNullable<T>(value)` | Create a potentially empty Optional | O(1) | O(1) |
118
+ | `Optional.ofNonNull<T>(value)` | Create a non-null Optional | O(1) | O(1) |
135
119
 
136
- // Check status
137
- if (optionalValue.isPresent()) {
138
- console.log("Has value");
139
- } else if (optionalValue.isEmpty()) {
140
- console.log("Is empty");
141
- }
120
+ ```typescript
121
+ // Optional usage examples
122
+ const emptyOpt = Optional.empty<number>();
123
+ const presentOpt = Optional.of(42);
124
+ const nullableOpt = Optional.ofNullable<string>(null);
125
+ const nonNullOpt = Optional.ofNonNull("hello");
126
+
127
+ presentOpt.ifPresent(val => console.log(val)); // Outputs 42
128
+ console.log(emptyOpt.orElse(100)); // Outputs 100
142
129
  ```
143
130
 
144
- ### Semantic<E> - Lazy Data Stream
145
-
146
- Semantic is the core stream processing class, providing rich stream operators.
147
-
148
- #### Stream Transformation Operations
149
-
150
- | Method | Return Type | Description | Performance Impact |
151
- |------|----------|------|----------|
152
- | `concat(other: Semantic<E>)` | `Semantic<E>` | Concatenate two streams | O(n+m) |
153
- | `distinct()` | `Semantic<E>` | Remove duplicates (using Set) | O(n) |
154
- | `distinct(comparator)` | `Semantic<E>` | Custom comparator deduplication | O(n²) |
155
- | `dropWhile(predicate)` | `Semantic<E>` | Discard starting elements satisfying condition | O(n) |
156
- | `filter(predicate)` | `Semantic<E>` | Filter elements | O(n) |
157
- | `flat(mapper)` | `Semantic<E>` | Flatten nested streams | O(n×m) |
158
- | `flatMap(mapper)` | `Semantic<R>` | Map and flatten | O(n×m) |
159
- | `limit(n)` | `Semantic<E>` | Limit number of elements | O(n) |
160
- | `map(mapper)` | `Semantic<R>` | Map and transform elements | O(n) |
161
- | `peek(consumer)` | `Semantic<E>` | View elements without modification | O(n) |
162
- | `redirect(redirector)` | `Semantic<E>` | Redirect indices | O(n) |
163
- | `reverse()` | `Semantic<E>` | Reverse stream order | O(n) |
164
- | `shuffle()` | `Semantic<E>` | Randomly shuffle order | O(n) |
165
- | `shuffle(mapper)` | `Semantic<E>` | Custom shuffle logic | O(n) |
166
- | `skip(n)` | `Semantic<E>` | Skip first n elements | O(n) |
167
- | `sub(start, end)` | `Semantic<E>` | Get substream | O(n) |
168
- | `takeWhile(predicate)` | `Semantic<E>` | Get starting elements satisfying condition | O(n) |
169
- | `translate(offset)` | `Semantic<E>` | Translate indices | O(n) |
170
- | `translate(translator)` | `Semantic<E>` | Custom index transformation | O(n) |
171
-
172
- **Code Example Supplement:**
173
- ```typescript
174
- import { from } from 'semantic-typescript';
131
+ ### Collector Factory Methods
175
132
 
176
- const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
133
+ | Method | Description | Time Complexity | Space Complexity |
134
+ |------|------|------------|------------|
135
+ | `Collector.full(identity, accumulator, finisher)` | Create a full collector | O(1) | O(1) |
136
+ | `Collector.shortable(identity, interruptor, accumulator, finisher)` | Create an interruptible collector | O(1) | O(1) |
177
137
 
178
- // Stream transformation operation examples
179
- const processedStream = stream
180
- .filter(x => x % 2 === 0) // Filter even numbers
181
- .map(x => x * 2) // Multiply each element by 2
182
- .distinct() // Remove duplicates
183
- .limit(3) // Limit to first 3 elements
184
- .peek((val, index) => console.log(`Element ${val} at index ${index}`)); // View elements
138
+ ```typescript
139
+ // Collector usage examples
140
+ const sumCollector = Collector.full(
141
+ () => 0,
142
+ (sum, num) => sum + num,
143
+ result => result
144
+ );
185
145
 
186
- // Note: The stream hasn't executed yet, needs conversion to Collectable for terminal operations
146
+ const numbers = from([1, 2, 3, 4, 5]);
147
+ const total = numbers.toUnoredered().collect(sumCollector); // 15
187
148
  ```
188
149
 
189
- #### Stream Terminal Operations
150
+ ### Semantic Factory Methods
190
151
 
191
- | Method | Return Type | Description | Performance Characteristics |
192
- |------|----------|------|----------|
193
- | `toOrdered()` | `OrderedCollectable<E>` | Convert to ordered collection | Sorting operation, lower performance |
194
- | `toUnordered()` | `UnorderedCollectable<E>` | Convert to unordered collection | Fastest, no sorting |
195
- | `toWindow()` | `WindowCollectable<E>` | Convert to window collection | Sorting operation, lower performance |
196
- | `toNumericStatistics()` | `Statistics<E, number>` | Numerical statistical analysis | Sorting operation, lower performance |
197
- | `toBigintStatistics()` | `Statistics<E, bigint>` | Big integer statistical analysis | Sorting operation, lower performance |
198
- | `sorted()` | `OrderedCollectable<E>` | Natural sorting | Overrides redirection results |
199
- | `sorted(comparator)` | `OrderedCollectable<E>` | Custom sorting | Overrides redirection results |
152
+ | Method | Description | Time Complexity | Space Complexity |
153
+ |------|------|------------|------------|
154
+ | `blob(blob, chunkSize)` | Create a stream from a Blob | O(n) | O(chunkSize) |
155
+ | `empty<E>()` | Create an empty stream | O(1) | O(1) |
156
+ | `fill<E>(element, count)` | Create a filled stream | O(n) | O(1) |
157
+ | `from<E>(iterable)` | Create a stream from an iterable object | O(1) | O(1) |
158
+ | `interval(period, delay?)` | Create a timed interval stream | O(1)* | O(1) |
159
+ | `iterate<E>(generator)` | Create a stream from a generator | O(1) | O(1) |
160
+ | `range(start, end, step)` | Create a numerical range stream | O(n) | O(1) |
161
+ | `websocket(websocket)` | Create a stream from a WebSocket | O(1) | O(1) |
200
162
 
201
- **Code Example Supplement:**
202
163
  ```typescript
203
- import { from } from 'semantic-typescript';
164
+ // Semantic factory method usage examples
204
165
 
205
- const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
166
+ // Create a stream from a Blob (chunked reading)
167
+ blob(someBlob, 1024n)
168
+ .toUnordered()
169
+ .write(WritableStream)
170
+ .then(callback) // Write stream successful
171
+ .catch(writeFi); // Write stream failed
206
172
 
207
- // Convert to ordered collection (lower performance)
208
- const ordered = semanticStream.toOrdered();
173
+ // Create an empty stream, won't execute until concatenated with other streams
174
+ empty<string>()
175
+ .toUnordered()
176
+ .join(); //[]
209
177
 
210
- // Convert to unordered collection (fastest)
211
- const unordered = semanticStream.toUnordered();
178
+ // Create a filled stream
179
+ const filledStream = fill("hello", 3); // "hello", "hello", "hello"
212
180
 
213
- // Natural sorting
214
- const sortedNatural = semanticStream.sorted();
181
+ // Create a timed stream with initial 2-second delay and 5-second execution period, implemented based on timer mechanism; may experience time drift due to system scheduling precision limitations.
182
+ const intervalStream = interval(5000, 2000);
215
183
 
216
- // Custom sorting
217
- const sortedCustom = semanticStream.sorted((a, b) => b - a); // Descending sort
184
+ // Create a stream from an iterable object
185
+ const numberStream = from([1, 2, 3, 4, 5]);
186
+ const stringStream = from(new Set(["Alex", "Bob"]));
218
187
 
219
- // Convert to statistical object
220
- const stats = semanticStream.toNumericStatistics();
188
+ // Create a range stream
189
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
221
190
 
222
- // Note: Must call above methods through Semantic instance to get Collectable before using terminal methods
191
+ // WebSocket event stream
192
+ const ws = new WebSocket("ws://localhost:8080");
193
+ websocket(ws)
194
+ .filter((event)=> event.type === "message"); // Only listen to message events
195
+ .toUnordered() // Generally not ordered for events
196
+ .forEach((event)=> receive(event)); // Receive messages
223
197
  ```
224
198
 
225
- ### Collector<E, A, R> - Data Collector
226
-
227
- Collectors are used to aggregate stream data into specific structures.
199
+ ## Semantic Class Methods
200
+
201
+ | Method | Description | Time Complexity | Space Complexity |
202
+ |------|------|------------|------------|
203
+ | `concat(other)` | Concatenate two streams | O(n) | O(1) |
204
+ | `distinct()` | Remove duplicates | O(n) | O(n) |
205
+ | `distinct(comparator)` | Remove duplicates using a comparator | O(n²) | O(n) |
206
+ | `dropWhile(predicate)` | Discard elements satisfying condition | O(n) | O(1) |
207
+ | `filter(predicate)` | Filter elements | O(n) | O(1) |
208
+ | `flat(mapper)` | Flattening map | O(n × m) | O(1) |
209
+ | `flatMap(mapper)` | Flattening map to new type | O(n × m) | O(1) |
210
+ | `limit(n)` | Limit number of elements | O(n) | O(1) |
211
+ | `map(mapper)` | Map transformation | O(n) | O(1) |
212
+ | `peek(consumer)` | Peek at elements | O(n) | O(1) |
213
+ | `redirect(redirector)` | Redirect index | O(n) | O(1) |
214
+ | `reverse()` | Reverse stream | O(n) | O(1) |
215
+ | `shuffle()` | Randomly shuffle | O(n) | O(1) |
216
+ | `shuffle(mapper)` | Shuffle using a mapper | O(n) | O(1) |
217
+ | `skip(n)` | Skip first n elements | O(n) | O(1) |
218
+ | `sorted()` | Sort | O(n log n) | O(n) |
219
+ | `sorted(comparator)` | Sort using a comparator | O(n log n) | O(n) |
220
+ | `sub(start, end)` | Get substream | O(n) | O(1) |
221
+ | `takeWhile(predicate)` | Get elements satisfying condition | O(n) | O(1) |
222
+ | `translate(offset)` | Translate index | O(n) | O(1) |
223
+ | `translate(translator)` | Translate index using a translator | O(n) | O(1) |
228
224
 
229
- | Method | Description | Usage Scenario |
230
- |------|------|----------|
231
- | `collect(generator)` | Execute data collection | Stream terminal operation |
232
- | `static full(identity, accumulator, finisher)` | Create complete collector | Requires complete processing |
233
- | `static shortable(identity, interruptor, accumulator, finisher)` | Create interruptible collector | May terminate early |
234
-
235
- **Code Example Supplement:**
236
225
  ```typescript
237
- import { Collector } from 'semantic-typescript';
238
-
239
- // Create custom collector
240
- const sumCollector = Collector.full(
241
- () => 0, // Initial value
242
- (acc, value) => acc + value, // Accumulator
243
- result => result // Finisher function
244
- );
245
-
246
- // Use collector (requires conversion from Semantic to Collectable first)
247
- const numbers = from([1, 2, 3, 4, 5]);
248
- const sum = numbers.toUnordered().collect(sumCollector); // 15
226
+ // Semantic operation examples
227
+ const result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
228
+ .filter(n => n % 2 === 0) // Filter even numbers
229
+ .map(n => n * 2) // Multiply by 2
230
+ .skip(1) // Skip the first
231
+ .limit(3) // Limit to 3 elements
232
+ .toArray(); // Convert to array
233
+ // Result: [8, 12, 20]
234
+
235
+ // Complex operation example
236
+ const complexResult = range(1, 100, 1)
237
+ .flatMap(n => from([n, n * 2])) // Map each element to two
238
+ .distinct() // Remove duplicates
239
+ .shuffle() // Shuffle order
240
+ .takeWhile(n => n < 50) // Take elements less than 50
241
+ .toOrdered() // Convert to ordered collector
242
+ .toArray(); // Convert to array
249
243
  ```
250
244
 
251
- ### Collectable<E> - Collectable Data Abstract Class
252
-
253
- Provides rich data aggregation and transformation methods. **Note: Must first obtain Collectable instance by calling sorted(), toOrdered() etc. through Semantic instance before using the following methods.**
245
+ ## Collector Conversion Methods
254
246
 
255
- #### Data Query Operations
247
+ | Method | Description | Time Complexity | Space Complexity |
248
+ |------|------|------------|------------|
249
+ | `toUnoredered()` | Convert to unordered collector (performance first) | O(1) | O(1) |
250
+ | `toOrdered()` | Convert to ordered collector | O(1) | O(1) |
251
+ | `sorted()` | Sort and convert to ordered collector | O(n log n) | O(n) |
252
+ | `toWindow()` | Convert to window collector | O(1) | O(1) |
253
+ | `toNumericStatistics()` | Convert to numerical statistics | O(1) | O(1) |
254
+ | `toBigintStatistics()` | Convert to big integer statistics | O(1) | O(1) |
256
255
 
257
- | Method | Return Type | Description | Example |
258
- |------|----------|------|------|
259
- | `anyMatch(predicate)` | `boolean` | Whether any element matches | `anyMatch(x => x > 0)` |
260
- | `allMatch(predicate)` | `boolean` | Whether all elements match | `allMatch(x => x > 0)` |
261
- | `count()` | `bigint` | Element count statistics | `count()` → `5n` |
262
- | `isEmpty()` | `boolean` | Whether stream is empty | `isEmpty()` |
263
- | `findAny()` | `Optional<E>` | Find any element | `findAny()` |
264
- | `findFirst()` | `Optional<E>` | Find first element | `findFirst()` |
265
- | `findLast()` | `Optional<E>` | Find last element | `findLast()` |
266
-
267
- **Code Example Supplement:**
268
256
  ```typescript
269
- import { from } from 'semantic-typescript';
270
-
271
- const numbers = from([1, 2, 3, 4, 5]);
272
-
273
- // Must convert to Collectable before using terminal methods
274
- const collectable = numbers.toUnordered();
275
-
276
- // Data query operations
277
- const hasEven = collectable.anyMatch(x => x % 2 === 0); // true
278
- const allPositive = collectable.allMatch(x => x > 0); // true
279
- const count = collectable.count(); // 5n
280
- const isEmpty = collectable.isEmpty(); // false
281
- const firstElement = collectable.findFirst(); // Optional.of(1)
282
- const anyElement = collectable.findAny(); // Any element
257
+ // Collector conversion examples
258
+ const numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
259
+
260
+ // Performance first: use unordered collector
261
+ const unordered = numbers
262
+ .filter(n => n > 3)
263
+ .toUnoredered();
264
+
265
+ // Need sorting: use ordered collector
266
+ const ordered = numbers
267
+ .sorted()
268
+ .toOrdered();
269
+
270
+ // Statistical analysis: use statistical collector
271
+ const stats = numbers
272
+ .toNumericStatistics();
273
+
274
+ console.log(stats.mean()); // Average value
275
+ console.log(stats.median()); // Median value
276
+ console.log(stats.standardDeviation()); // Standard deviation
277
+
278
+ // Window operations
279
+ const windowed = numbers
280
+ .toWindow()
281
+ .tumble(3n); // Every 3 elements form a window
282
+
283
+ windowed.forEach(window => {
284
+ console.log(window.toArray()); // Contents of each window
285
+ });
283
286
  ```
284
287
 
285
- #### Data Aggregation Operations
286
-
287
- | Method | Return Type | Description | Complexity |
288
- |------|----------|------|--------|
289
- | `group(classifier)` | `Map<K, E[]>` | Group by classifier | O(n) |
290
- | `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | Group by key-value extractors | O(n) |
291
- | `join()` | `string` | Join as string | O(n) |
292
- | `join(delimiter)` | `string` | Join with delimiter | O(n) |
293
- | `partition(count)` | `E[][]` | Partition by count | O(n) |
294
- | `partitionBy(classifier)` | `E[][]` | Partition by classifier | O(n) |
295
- | `reduce(accumulator)` | `Optional<E>` | Reduction operation | O(n) |
296
- | `reduce(identity, accumulator)` | `E` | Reduction with identity | O(n) |
297
- | `toArray()` | `E[]` | Convert to array | O(n) |
298
- | `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Convert to Map | O(n) |
299
- | `toSet()` | `Set<E>` | Convert to Set | O(n) |
300
-
301
- **Code Example Supplement:**
288
+ ## Collectable Collection Methods
289
+
290
+ | Method | Description | Time Complexity | Space Complexity |
291
+ |------|------|------------|------------|
292
+ | `anyMatch(predicate)` | Whether any element matches | O(n) | O(1) |
293
+ | `allMatch(predicate)` | Whether all elements match | O(n) | O(1) |
294
+ | `count()` | Element count | O(n) | O(1) |
295
+ | `isEmpty()` | Whether it is empty | O(1) | O(1) |
296
+ | `findAny()` | Find any element | O(n) | O(1) |
297
+ | `findFirst()` | Find the first element | O(n) | O(1) |
298
+ | `findLast()` | Find the last element | O(n) | O(1) |
299
+ | `forEach(action)` | Iterate over all elements | O(n) | O(1) |
300
+ | `group(classifier)` | Group by classifier | O(n) | O(n) |
301
+ | `groupBy(keyExtractor, valueExtractor)` | Group by key-value extractor | O(n) | O(n) |
302
+ | `join()` | Join as string | O(n) | O(n) |
303
+ | `join(delimiter)` | Join using a delimiter | O(n) | O(n) |
304
+ | `nonMatch(predicate)` | Whether no elements match | O(n) | O(1) |
305
+ | `partition(count)` | Partition by count | O(n) | O(n) |
306
+ | `partitionBy(classifier)` | Partition by classifier | O(n) | O(n) |
307
+ | `reduce(accumulator)` | Reduction operation | O(n) | O(1) |
308
+ | `reduce(identity, accumulator)` | Reduction with initial value | O(n) | O(1) |
309
+ | `toArray()` | Convert to array | O(n) | O(n) |
310
+ | `toMap(keyExtractor, valueExtractor)` | Convert to Map | O(n) | O(n) |
311
+ | `toSet()` | Convert to Set | O(n) | O(n) |
312
+ | `write(stream)` | Write to stream | O(n) | O(1) |
313
+
302
314
  ```typescript
303
- import { from } from 'semantic-typescript';
315
+ // Collectable operation examples
316
+ const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
317
+ .filter(n => n % 2 === 0)
318
+ .toOrdered();
304
319
 
305
- const people = from([
306
- { name: "Alice", age: 25, city: "New York" },
307
- { name: "Bob", age: 30, city: "London" },
308
- { name: "Charlie", age: 25, city: "New York" }
309
- ]);
320
+ // Match checks
321
+ console.log(data.anyMatch(n => n > 5)); // true
322
+ console.log(data.allMatch(n => n < 20)); // true
310
323
 
311
- // Must convert to Collectable before using aggregation operations
312
- const collectable = people.toUnordered();
324
+ // Find operations
325
+ data.findFirst().ifPresent(n => console.log(n)); // 2
326
+ data.findAny().ifPresent(n => console.log(n)); // Any element
313
327
 
314
328
  // Grouping operations
315
- const byCity = collectable.group(person => person.city);
316
- // Map { "New York" => [{name: "Alice", ...}, {name: "Charlie", ...}], "London" => [{name: "Bob", ...}] }
317
-
318
- const byAge = collectable.groupBy(
319
- person => person.age,
320
- person => person.name
329
+ const grouped = data.groupBy(
330
+ n => n > 5 ? "large" : "small",
331
+ n => n * 2
321
332
  );
322
- // Map { 25 => ["Alice", "Charlie"], 30 => ["Bob"] }
323
-
324
- // Convert to collections
325
- const array = collectable.toArray(); // Original array
326
- const set = collectable.toSet(); // Set collection
327
- const map = collectable.toMap(
328
- person => person.name,
329
- person => person.age
330
- ); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
333
+ // {small: [4, 8], large: [12, 16, 20]}
331
334
 
332
335
  // Reduction operations
333
- const totalAge = collectable.reduce(0, (acc, person) => acc + person.age); // 80
334
- const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
335
- ```
336
+ const sum = data.reduce(0, (acc, n) => acc + n); // 30
336
337
 
337
- ### Specific Collector Implementations
338
-
339
- #### UnorderedCollectable<E>
340
- - **Characteristics**: Fastest collector, no sorting
341
- - **Usage Scenarios**: Order unimportant, maximum performance desired
342
- - **Methods**: Inherits all Collectable methods
343
-
344
- #### OrderedCollectable<E>
345
- - **Characteristics**: Guarantees element order, lower performance
346
- - **Usage Scenarios**: Require sorted results
347
- - **Special Methods**: Inherits all methods, maintains internal sort state
338
+ // Output operations
339
+ data.join(", "); // "2, 4, 6, 8, 10"
340
+ ```
348
341
 
349
- #### WindowCollectable<E>
350
- - **Characteristics**: Supports sliding window operations
351
- - **Usage Scenarios**: Time series data analysis
352
- - **Special Methods**:
353
- - `slide(size, step)` - Sliding window
354
- - `tumble(size)` - Tumbling window
342
+ ## Statistical Analysis Methods
343
+
344
+ ### NumericStatistics Methods
345
+
346
+ | Method | Description | Time Complexity | Space Complexity |
347
+ |------|------|------------|------------|
348
+ | `range()` | Range | O(n) | O(1) |
349
+ | `variance()` | Variance | O(n) | O(1) |
350
+ | `standardDeviation()` | Standard deviation | O(n) | O(1) |
351
+ | `mean()` | Mean | O(n) | O(1) |
352
+ | `median()` | Median | O(n log n) | O(n) |
353
+ | `mode()` | Mode | O(n) | O(n) |
354
+ | `frequency()` | Frequency distribution | O(n) | O(n) |
355
+ | `summate()` | Summation | O(n) | O(1) |
356
+ | `quantile(quantile)` | Quantile | O(n log n) | O(n) |
357
+ | `interquartileRange()` | Interquartile range | O(n log n) | O(n) |
358
+ | `skewness()` | Skewness | O(n) | O(1) |
359
+ | `kurtosis()` | Kurtosis | O(n) | O(1) |
355
360
 
356
- **Code Example Supplement:**
357
361
  ```typescript
358
- import { from } from 'semantic-typescript';
359
-
360
- const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
361
-
362
- // Unordered collector (fastest)
363
- const unordered = data.toUnordered();
364
- const unorderedArray = unordered.toArray(); // May maintain original order [1, 2, 3, ...]
365
-
366
- // Ordered collector
367
- const ordered = data.toOrdered();
368
- const orderedArray = ordered.toArray(); // Guaranteed sorted [1, 2, 3, ...]
369
-
370
- // Window collector
371
- const windowed = data.toWindow();
372
- const slidingWindows = windowed.slide(3n, 2n); // Window size 3, step 2
373
- // Window 1: [1, 2, 3], Window 2: [3, 4, 5], Window 3: [5, 6, 7], ...
374
-
375
- const tumblingWindows = windowed.tumble(4n); // Tumbling window size 4
376
- // Window 1: [1, 2, 3, 4], Window 2: [5, 6, 7, 8], ...
362
+ // Statistical analysis examples
363
+ const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
364
+ .toNumericStatistics();
365
+
366
+ console.log("Mean:", numbers.mean()); // 5.5
367
+ console.log("Median:", numbers.median()); // 5.5
368
+ console.log("Standard deviation:", numbers.standardDeviation()); // ~2.87
369
+ console.log("Sum:", numbers.summate()); // 55
370
+
371
+ // Statistical analysis using mappers
372
+ const objects = from([
373
+ { value: 10 },
374
+ { value: 20 },
375
+ { value: 30 }
376
+ ]).toNumericStatistics();
377
+
378
+ console.log("Mapped mean:", objects.mean(obj => obj.value)); // 20
377
379
  ```
378
380
 
379
- ### Statistics<E, D> - Statistical Analysis
380
-
381
- Statistical analysis base class providing rich statistical calculation methods. **Note: Must first obtain Statistics instance by calling toNumericStatistics() or toBigIntStatistics() through Semantic instance before using the following methods.**
382
-
383
- #### Statistical Calculation Operations
384
-
385
- | Method | Return Type | Description | Algorithm Complexity |
386
- |------|----------|------|------------|
387
- | `maximum()` | `Optional<E>` | Maximum value | O(n) |
388
- | `minimum()` | `Optional<E>` | Minimum value | O(n) |
389
- | `range()` | `D` | Range (max-min) | O(n) |
390
- | `variance()` | `D` | Variance | O(n) |
391
- | `standardDeviation()` | `D` | Standard deviation | O(n) |
392
- | `mean()` | `D` | Mean value | O(n) |
393
- | `median()` | `D` | Median value | O(n log n) |
394
- | `mode()` | `D` | Mode value | O(n) |
395
- | `frequency()` | `Map<D, bigint>` | Frequency distribution | O(n) |
396
- | `summate()` | `D` | Summation | O(n) |
397
- | `quantile(quantile)` | `D` | Quantile | O(n log n) |
398
- | `interquartileRange()` | `D` | Interquartile range | O(n log n) |
399
- | `skewness()` | `D` | Skewness | O(n) |
400
- | `kurtosis()` | `D` | Kurtosis | O(n) |
401
-
402
- **Code Example Supplement:**
381
+ ## Performance Selection Guide
382
+
383
+ ### Choose Unordered Collector (Performance First)
403
384
  ```typescript
404
- import { from } from 'semantic-typescript';
405
-
406
- const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
407
-
408
- // Must convert to statistical object before using statistical methods
409
- const stats = numbers.toNumericStatistics();
410
-
411
- // Basic statistics
412
- const count = stats.count(); // 10n
413
- const max = stats.maximum(); // Optional.of(10)
414
- const min = stats.minimum(); // Optional.of(1)
415
- const range = stats.range(); // 9
416
- const mean = stats.mean(); // 5.5
417
- const median = stats.median(); // 5.5
418
- const sum = stats.summate(); // 55
419
-
420
- // Advanced statistics
421
- const variance = stats.variance(); // 8.25
422
- const stdDev = stats.standardDeviation(); // 2.872
423
- const mode = stats.mode(); // Any value (since all appear once)
424
- const q1 = stats.quantile(0.25); // 3.25
425
- const q3 = stats.quantile(0.75); // 7.75
426
- const iqr = stats.interquartileRange(); // 4.5
427
-
428
- // Frequency distribution
429
- const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
385
+ // When order guarantee is not needed, use unordered collector for best performance
386
+ const highPerformance = data
387
+ .filter(predicate)
388
+ .map(mapper)
389
+ .toUnoredered(); // Best performance
430
390
  ```
431
391
 
432
- #### Specific Statistical Implementation Classes
433
-
434
- **NumericStatistics<E>**
435
- - Handles number type statistical analysis
436
- - All statistical calculations return number type
437
-
438
- **BigIntStatistics<E>**
439
- - Handles bigint type statistical analysis
440
- - All statistical calculations return bigint type
441
-
442
- **Code Example Supplement:**
392
+ ### Choose Ordered Collector (Order Required)
443
393
  ```typescript
444
- import { from } from 'semantic-typescript';
445
-
446
- // Numerical statistics
447
- const numberData = from([10, 20, 30, 40, 50]);
448
- const numericStats = numberData.toNumericStatistics();
449
-
450
- console.log(numericStats.mean()); // 30
451
- console.log(numericStats.summate()); // 150
452
-
453
- // Big integer statistics
454
- const bigintData = from([100n, 200n, 300n, 400n, 500n]);
455
- const bigintStats = bigintData.toBigIntStatistics();
394
+ // When element order needs to be maintained, use ordered collector
395
+ const ordered = data.sorted(comparator);
396
+ ```
456
397
 
457
- console.log(bigintStats.mean()); // 300n
458
- console.log(bigintStats.summate()); // 1500n
398
+ ### Choose Window Collector (Window Operations)
399
+ ```typescript
400
+ // When window operations are needed
401
+ const windowed = data
402
+ .toWindow()
403
+ .slide(5n, 2n); // Sliding window
404
+ ```
459
405
 
460
- // Statistics using mapper functions
461
- const objectData = from([
462
- { value: 15 },
463
- { value: 25 },
464
- { value: 35 },
465
- { value: 45 }
466
- ]);
406
+ ### Choose Statistical Analysis (Numerical Calculations)
407
+ ```typescript
408
+ // When statistical analysis is needed
409
+ const stats = data
410
+ .toNumericStatistics(); // Numerical statistics
467
411
 
468
- const objectStats = objectData.toNumericStatistics();
469
- const meanWithMapper = objectStats.mean(obj => obj.value); // 30
470
- const sumWithMapper = objectStats.summate(obj => obj.value); // 120
412
+ const bigIntStats = data
413
+ .toBigintStatistics(); // Big integer statistics
471
414
  ```
472
415
 
473
- ## Complete Usage Example
416
+ [GitHub](https://github.com/eloyhere/semantic-typescript)
417
+ [NPMJS](https://www.npmjs.com/package/semantic-typescript)
474
418
 
475
- ```typescript
476
- import { from, validate, invalidate } from 'semantic-typescript';
477
-
478
- // 1. Create data stream
479
- const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
480
- const semanticStream = from(rawData);
481
-
482
- // 2. Stream processing pipeline
483
- const processedStream = semanticStream
484
- .filter(val => validate(val)) // Filter out null and undefined
485
- .map(val => val! * 2) // Multiply each value by 2 (using ! because validate ensures not empty)
486
- .distinct(); // Remove duplicates
487
-
488
- // 3. Convert to Collectable and use terminal operations
489
- const collectable = processedStream.toUnordered();
490
-
491
- // 4. Data validation and usage
492
- if (!collectable.isEmpty()) {
493
- const results = collectable
494
- .filter(x => x > 5) // Filter again
495
- .toArray(); // Convert to array
496
-
497
- console.log("Processing results:", results); // [16, 18, 14, 8, 12]
498
-
499
- // Statistical information
500
- const stats = processedStream.toNumericStatistics();
501
- console.log("Mean value:", stats.mean()); // 11.2
502
- console.log("Total sum:", stats.summate()); // 56
503
- }
419
+ ## Important Notes
504
420
 
505
- // 5. Handle potentially invalid data
506
- const potentiallyInvalidData: Array<number | null> = [1, null, 3, 4, null];
507
- const validData = potentiallyInvalidData.filter(validate);
508
- const invalidData = potentiallyInvalidData.filter(invalidate);
509
-
510
- console.log("Valid data:", validData); // [1, 3, 4]
511
- console.log("Invalid data:", invalidData); // [null, null]
512
- ```
421
+ 1. **Impact of Sorting Operations**: In ordered collectors, the `sorted()` operation overrides the effects of `redirect`, `translate`, `shuffle`, `reverse`
422
+ 2. **Performance Considerations**: If order guarantee is not needed, prioritise using `toUnoredered()` for better performance
423
+ 3. **Memory Usage**: Sorting operations require O(n) additional space
424
+ 4. **Real-time Data**: Semantic streams are suitable for processing real-time data and support asynchronous data sources
513
425
 
514
- ## Important Usage Rules Summary
515
-
516
- 1. **Create Stream**: Use `from()`, `range()`, `fill()` etc. factory methods to create Semantic instances
517
- 2. **Stream Transformation**: Call `map()`, `filter()`, `distinct()` etc. methods on Semantic instances
518
- 3. **Convert to Collectable**: Must call one of the following methods through Semantic instance:
519
- - `toOrdered()` - Ordered collector
520
- - `toUnordered()` - Unordered collector (fastest)
521
- - `toWindow()` - Window collector
522
- - `toNumericStatistics()` - Numerical statistics
523
- - `toBigIntStatistics()` - Big integer statistics
524
- - `sorted()` - Natural sorting
525
- - `sorted(comparator)` - Custom sorting
526
- 4. **Terminal Operations**: Call `toArray()`, `count()`, `summate()` etc. terminal methods on Collectable instances
527
- 5. **Data Validation**: Use `validate()` to ensure data is not null/undefined, use `invalidate()` to check invalid data
528
-
529
- This design ensures type safety and performance optimisation while providing rich stream processing functionality.
426
+ This library provides TypeScript developers with powerful and flexible streaming capabilities, combining the benefits of functional programming with type safety guarantees.