semantic-typescript 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/asynchronous/collector.d.ts +231 -0
- package/dist/asynchronous/collector.js +800 -0
- package/dist/asynchronous/semantic.d.ts +257 -0
- package/dist/asynchronous/semantic.js +1853 -0
- package/dist/factory.d.ts +110 -32
- package/dist/factory.js +582 -189
- package/dist/guard.d.ts +24 -27
- package/dist/guard.js +37 -43
- package/dist/hook.d.ts +11 -7
- package/dist/hook.js +74 -21
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/optional.d.ts +5 -5
- package/dist/optional.js +14 -10
- package/dist/symbol.d.ts +19 -23
- package/dist/symbol.js +19 -23
- package/dist/synchronous/collector.d.ts +232 -0
- package/dist/{collector.js → synchronous/collector.js} +160 -170
- package/dist/{collectable.d.ts → synchronous/semantic.d.ts} +114 -71
- package/dist/{collectable.js → synchronous/semantic.js} +761 -294
- package/dist/utility.d.ts +8 -2
- package/dist/utility.js +1 -0
- package/package.json +1 -1
- package/readme.cn.md +158 -697
- package/readme.de.md +163 -432
- package/readme.es.md +163 -433
- package/readme.fr.md +162 -444
- package/readme.jp.md +162 -442
- package/readme.kr.md +161 -430
- package/readme.md +157 -799
- package/readme.ru.md +161 -426
- package/readme.tw.md +161 -436
- package/dist/collector.d.ts +0 -245
- package/dist/map.d.ts +0 -76
- package/dist/map.js +0 -253
- package/dist/node.d.ts +0 -182
- package/dist/node.js +0 -918
- package/dist/semantic.d.ts +0 -52
- package/dist/semantic.js +0 -504
- package/dist/set.d.ts +0 -19
- package/dist/set.js +0 -65
- package/dist/statistics.d.ts +0 -97
- package/dist/statistics.js +0 -483
- package/dist/tree.d.ts +0 -82
- package/dist/tree.js +0 -257
- package/dist/window.d.ts +0 -12
- package/dist/window.js +0 -72
package/readme.es.md
CHANGED
|
@@ -1,478 +1,208 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Semantic-TypeScript: Una biblioteca de procesamiento de flujo que cambia paradigmas
|
|
2
2
|
|
|
3
3
|
## Introducción
|
|
4
|
+
Semantic-TypeScript representa un avance significativo en la tecnología de procesamiento de flujos, sintetizando los conceptos más efectivos de JavaScript GeneratorFunctions, Java Streams y los paradigmas de indexación de bases de datos. Su principio de diseño fundamental se centra en la construcción de pipelines de procesamiento de datos excepcionalmente eficientes mediante evaluación diferida (lazy) sofisticada e indexación inteligente. La biblioteca ofrece una experiencia de operación de flujos rigurosamente segura en tipos y funcionalmente pura, específicamente diseñada para el desarrollo moderno en TypeScript y JavaScript.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
En contraste con las arquitecturas de procesamiento sincrónico convencionales, Semantic-TypeScript implementa un modelo unificado que maneja con gracia tanto fuentes de datos sincrónicas (Iterable) como asincrónicas (AsyncIterable). Durante la generación del flujo, el flujo y la terminación de los datos se controlan con precisión mediante mecanismos de callback, lo que permite a la biblioteca manejar con excepcional gracia:
|
|
7
|
+
- Flujos de datos en tiempo real (eventos DOM, WebSockets, intervalos) con control determinista
|
|
8
|
+
- Conjuntos de datos a gran escala mediante pipelines diferidos y eficientes en memoria
|
|
9
|
+
- Transformaciones de datos complejas con una API fluida y declarativa
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
El enfoque innovador de la biblioteca reinterpreta fundamentalmente cómo los desarrolladores interactúan con secuencias de datos, ofreciendo tanto características de rendimiento sin precedentes como ergonomía para el desarrollador en un paquete único y cohesivo.
|
|
8
12
|
|
|
9
|
-
##
|
|
13
|
+
## Filosofía Central: Separación de Definición y Ejecución
|
|
14
|
+
Una idea arquitectónica clave de Semantic-TypeScript es la clara separación entre la definición de un flujo y su ejecución:
|
|
15
|
+
- **Semantic<E>**: Un plano inmutable y diferido de un pipeline de transformación de datos. Define qué operaciones (filter, map, etc.) se realizarán
|
|
16
|
+
- **Collectable<E>**: Una vista materializada y ejecutable del flujo. Se obtiene a partir de un Semantic y proporciona todas las operaciones terminales (collect, forEach, etc.) para ejecutar el pipeline y producir un resultado
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
npm install semantic-typescript
|
|
13
|
-
```
|
|
18
|
+
Esta separación impone un modelo mental limpio y desbloquea optimizaciones potentes, como elegir un UnorderedCollectable para omitir ordenaciones innecesarias y obtener la máxima velocidad.
|
|
14
19
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
| Tipo | Descripción |
|
|
18
|
-
|------|-------------|
|
|
19
|
-
| `Invalid<T>` | Tipo que extiende `null` o `undefined` |
|
|
20
|
-
| `Valid<T>` | Tipo que excluye `null` y `undefined` |
|
|
21
|
-
| `MaybeInvalid<T>` | Tipo que puede ser `null` o `undefined` |
|
|
22
|
-
| `Primitive` | Colección de tipos primitivos |
|
|
23
|
-
| `MaybePrimitive<T>` | Tipo que puede ser un tipo primitivo |
|
|
24
|
-
| `OptionalSymbol` | Identificador de símbolo de la clase `Optional` |
|
|
25
|
-
| `SemanticSymbol` | Identificador de símbolo de la clase `Semantic` |
|
|
26
|
-
| `CollectorsSymbol` | Identificador de símbolo de la clase `Collector` |
|
|
27
|
-
| `CollectableSymbol` | Identificador de símbolo de la clase `Collectable` |
|
|
28
|
-
| `OrderedCollectableSymbol` | Identificador de símbolo de la clase `OrderedCollectable` |
|
|
29
|
-
| `WindowCollectableSymbol` | Identificador de símbolo de la clase `WindowCollectable` |
|
|
30
|
-
| `StatisticsSymbol` | Identificador de símbolo de la clase `Statistics` |
|
|
31
|
-
| `NumericStatisticsSymbol` | Identificador de símbolo de la clase `NumericStatistics` |
|
|
32
|
-
| `BigIntStatisticsSymbol` | Identificador de símbolo de la clase `BigIntStatistics` |
|
|
33
|
-
| `UnorderedCollectableSymbol` | Identificador de símbolo de la clase `UnorderedCollectable` |
|
|
34
|
-
|
|
35
|
-
## Interfaces Funcionales
|
|
36
|
-
|
|
37
|
-
| Interfaz | Descripción |
|
|
38
|
-
|-----------|-------------|
|
|
39
|
-
| `Runnable` | Función sin parámetros y sin valor de retorno |
|
|
40
|
-
| `Supplier<R>` | Función sin parámetros que devuelve `R` |
|
|
41
|
-
| `Functional<T, R>` | Función de transformación de un solo parámetro |
|
|
42
|
-
| `BiFunctional<T, U, R>` | Función de transformación de dos parámetros |
|
|
43
|
-
| `TriFunctional<T, U, V, R>` | Función de transformación de tres parámetros |
|
|
44
|
-
| `Predicate<T>` | Función de predicado de un solo parámetro |
|
|
45
|
-
| `BiPredicate<T, U>` | Función de predicado de dos parámetros |
|
|
46
|
-
| `TriPredicate<T, U, V>` | Función de predicado de tres parámetros |
|
|
47
|
-
| `Consumer<T>` | Función de consumidor de un solo parámetro |
|
|
48
|
-
| `BiConsumer<T, U>` | Función de consumidor de dos parámetros |
|
|
49
|
-
| `TriConsumer<T, U, V>` | Función de consumidor de tres parámetros |
|
|
50
|
-
| `Comparator<T>` | Función de comparación de dos parámetros |
|
|
51
|
-
| `Generator<T>` | Función generadora (núcleo y base) |
|
|
20
|
+
## ¿Por qué elegir Semantic-TypeScript?
|
|
21
|
+
Seleccionar la biblioteca adecuada para el procesamiento de flujos de datos implica equilibrar rendimiento, seguridad de tipos y expresividad. Semantic-TypeScript está diseñada para sobresalir en todas estas dimensiones.
|
|
52
22
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let predicate: Predicate<number> = (n: number): boolean => n > 0;
|
|
56
|
-
let mapper: Functional<string, number> = (text: string): number => text.length;
|
|
57
|
-
let comparator: Comparator<number> = (a: number, b: number): number => a - b;
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Guardias de Tipo
|
|
61
|
-
|
|
62
|
-
| Función | Descripción | Complejidad Temporal | Complejidad Espacial |
|
|
63
|
-
|------|------|------------|------------|
|
|
64
|
-
| `validate<T>(t: MaybeInvalid<T>): t is T` | Valida que el valor no sea null ni undefined | O(1) | O(1) |
|
|
65
|
-
| `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | Valida que el valor sea null o undefined | O(1) | O(1) |
|
|
66
|
-
| `isBoolean(t: unknown): t is boolean` | Comprueba si es un booleano | O(1) | O(1) |
|
|
67
|
-
| `isString(t: unknown): t is string` | Comprueba si es una cadena | O(1) | O(1) |
|
|
68
|
-
| `isNumber(t: unknown): t is number` | Comprueba si es un número | O(1) | O(1) |
|
|
69
|
-
| `isFunction(t: unknown): t is Function` | Comprueba si es una función | O(1) | O(1) |
|
|
70
|
-
| `isObject(t: unknown): t is object` | Comprueba si es un objeto | O(1) | O(1) |
|
|
71
|
-
| `isSymbol(t: unknown): t is symbol` | Comprueba si es un símbolo | O(1) | O(1) |
|
|
72
|
-
| `isBigint(t: unknown): t is bigint` | Comprueba si es un BigInt | O(1) | O(1) |
|
|
73
|
-
| `isPrimitive(t: unknown): t is Primitive` | Comprueba si es un tipo primitivo | O(1) | O(1) |
|
|
74
|
-
| `isIterable(t: unknown): t is Iterable<unknown>` | Comprueba si es un objeto iterable | O(1) | O(1) |
|
|
75
|
-
| `isOptional(t: unknown): t is Optional<unknown>` | Comprueba si es una instancia de Optional | O(1) | O(1) |
|
|
76
|
-
| `isSemantic(t: unknown): t is Semantic<unknown>` | Comprueba si es una instancia de Semantic | O(1) | O(1) |
|
|
77
|
-
| `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Comprueba si es una instancia de Collector | O(1) | O(1) |
|
|
78
|
-
| `isCollectable(t: unknown): t is Collectable<unknown>` | Comprueba si es una instancia de Collectable | O(1) | O(1) |
|
|
79
|
-
| `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | Comprueba si es una instancia de OrderedCollectable | O(1) | O(1) |
|
|
80
|
-
| `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | Comprueba si es una instancia de WindowCollectable | O(1) | O(1) |
|
|
81
|
-
| `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | Comprueba si es una instancia de UnorderedCollectable | O(1) | O(1) |
|
|
82
|
-
| `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Comprueba si es una instancia de Statistics | O(1) | O(1) |
|
|
83
|
-
| `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | Comprueba si es una instancia de NumericStatistics | O(1) | O(1) |
|
|
84
|
-
| `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | Comprueba si es una instancia de BigIntStatistics | O(1) | O(1) |
|
|
85
|
-
| `isPromise(t: unknown): t is Promise<unknown>` | Comprueba si es un objeto Promise | O(1) | O(1) |
|
|
86
|
-
| `isAsync(t: unknown): t is AsyncFunction` | Comprueba si es una AsyncFunction | O(1) | O(1) |
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// Ejemplos de uso de guardias de tipo
|
|
90
|
-
let value: unknown = "hello";
|
|
91
|
-
|
|
92
|
-
if (isString(value)) {
|
|
93
|
-
console.log(value.length); // Seguro para tipos, value inferido como string
|
|
94
|
-
}
|
|
23
|
+
### 1. Un paradigma unificado y seguro en tipos para todas las secuencias de datos
|
|
24
|
+
Proporciona una API declarativa y consistente para procesar cualquier secuencia de datos, ya sean arreglos estáticos, eventos en tiempo real o fragmentos asincrónicos, al tiempo que aprovecha todo el poder de TypeScript para garantizar seguridad de tipos de extremo a extremo. Esto elimina toda una clase de errores en tiempo de ejecución y transforma la manipulación de flujos en una actividad predecible y verificada por el compilador.
|
|
95
25
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
26
|
+
### 2. Rendimiento sin concesiones con evaluación diferida inteligente
|
|
27
|
+
En su núcleo, la biblioteca está construida sobre evaluación diferida. Operaciones como filter, map y flatMap simplemente componen un pipeline de procesamiento; no se realiza ningún trabajo hasta que se invoca una operación terminal. Esto se combina con capacidades de cortocircuito (a través de limit, anyMatch o callbacks de interrupción personalizados), que permiten detener el procesamiento anticipadamente, mejorando drásticamente la eficiencia para flujos grandes o infinitos.
|
|
99
28
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
for(let item of value){
|
|
103
|
-
console.log(item);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
29
|
+
### 3. El poder del patrón `Collector<E, A, R>`
|
|
30
|
+
Inspirado en Java, el patrón Collector es el motor de la flexibilidad. Desacopla la especificación de cómo acumular elementos del flujo de la ejecución del flujo en sí. La biblioteca proporciona un rico conjunto de coleccionadores integrados (toArray, groupBy, summate, etc.) para tareas cotidianas, al tiempo que hace que sea trivial implementar tu propia lógica de reducción compleja y reutilizable. Esto es mucho más potente y componible que un conjunto fijo de métodos terminales.
|
|
107
31
|
|
|
108
|
-
|
|
32
|
+
### 4. Soporte de primera clase para datos web modernos y asincrónicos
|
|
33
|
+
Semantic-TypeScript está diseñada para el desarrollo contemporáneo. Ofrece métodos de fábrica nativos para fuentes web modernas:
|
|
34
|
+
- `useFrom(iterable)`, `useRange()` para datos estáticos
|
|
35
|
+
- `useInterval()`, `useAnimationFrame()` para flujos basados en tiempo
|
|
36
|
+
- `useBlob()` para procesamiento de datos binarios fragmentados
|
|
37
|
+
- `useWebSocket()`, `useDocument()`, `useWindow()` para flujos de eventos en tiempo real
|
|
109
38
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| `useCompare<T>(t1: T, t2: T): number` | Función de comparación genérica | O(1) | O(1) |
|
|
113
|
-
| `useRandom<T = number \| bigint>(index: T): T` | Generador de números pseudoaleatorios | O(log n) | O(1) |
|
|
39
|
+
### 5. Más allá de la agregación básica: análisis estadístico integrado
|
|
40
|
+
Ve más allá de simples sumas y promedios. La biblioteca proporciona interfaces dedicadas NumericStatistics y BigIntStatistics, ofreciendo acceso inmediato a medidas estadísticas avanzadas directamente desde tus flujos: varianza, desviación estándar, mediana, asimetría y curtosis. Esto convierte el análisis de datos complejos en una sola línea de código.
|
|
114
41
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
42
|
+
### 6. Diseñada para la ergonomía del desarrollador
|
|
43
|
+
- **API fluida y encadenable**: Escribe pipelines de datos complejos como cadenas secuenciales y legibles
|
|
44
|
+
- **Suite integral de utilidades**: Protecciones esenciales (isFunction, isIterable), utilidades (useCompare, useTraverse) e interfaces funcionales incluidas
|
|
45
|
+
- **Integración Optional<T>**: Modela de forma segura la ausencia de un valor, eliminando preocupaciones de punteros nulos
|
|
46
|
+
- **Guía de rendimiento**: Orientación clara sobre cuándo usar recolección no ordenada (unordered) para velocidad versus ordenada (ordered) para secuencia
|
|
119
47
|
|
|
120
|
-
|
|
48
|
+
## Instalación
|
|
49
|
+
```bash
|
|
50
|
+
npm install semantic-typescript
|
|
121
51
|
```
|
|
122
52
|
|
|
123
|
-
##
|
|
124
|
-
|
|
125
|
-
### Métodos de Fábrica de Optional
|
|
126
|
-
|
|
127
|
-
| Método | Descripción | Complejidad Temporal | Complejidad Espacial |
|
|
128
|
-
|------|------|------------|------------|
|
|
129
|
-
| `Optional.empty<T>()` | Crea un Optional vacío | O(1) | O(1) |
|
|
130
|
-
| `Optional.of<T>(value)` | Crea un Optional que contiene un valor | O(1) | O(1) |
|
|
131
|
-
| `Optional.ofNullable<T>(value)` | Crea un Optional que podría estar vacío | O(1) | O(1) |
|
|
132
|
-
| `Optional.ofNonNull<T>(value)` | Crea un Optional que no está vacío | O(1) | O(1) |
|
|
53
|
+
## Conceptos centrales en la práctica
|
|
133
54
|
|
|
55
|
+
### 1. Creación de flujos (Semantic)
|
|
56
|
+
Los flujos se pueden crear desde varias fuentes usando funciones de fábrica.
|
|
134
57
|
```typescript
|
|
135
|
-
|
|
136
|
-
let empty: Optional<number> = Optional.empty();
|
|
137
|
-
let present: Optional<number> = Optional.of(42);
|
|
138
|
-
let nullable: Optional<string> = Optional.ofNullable<string>(null);
|
|
139
|
-
let nonNull: Optional<string> = Optional.ofNonNull("hello");
|
|
140
|
-
|
|
141
|
-
present.ifPresent((val: number): void => console.log(val)); // Salida: 42
|
|
142
|
-
console.log(emptyOpt.get(100)); // Salida: 100
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Métodos de Fábrica de Collector
|
|
58
|
+
import { useFrom, useInterval, useDocument } from 'semantic-typescript';
|
|
146
59
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
| `Collector.full(identity, accumulator, finisher)` | Crea un Collector completo | O(1) | O(1) |
|
|
150
|
-
| `Collector.shortable(identity, interruptor, accumulator, finisher)` | Crea un Collector interrumpible | O(1) | O(1) |
|
|
60
|
+
// Desde un arreglo estático
|
|
61
|
+
const staticStream = useFrom([1, 2, 3, 4, 5]);
|
|
151
62
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let unordered = numbers
|
|
158
|
-
.filter((n: number): boolean => n > 3)
|
|
159
|
-
.toUnordered(); // Mejor rendimiento
|
|
160
|
-
|
|
161
|
-
// Necesita ordenación: usa un Collector ordenado
|
|
162
|
-
let ordered = numbers.sorted();
|
|
163
|
-
|
|
164
|
-
// Operaciones de recuento de elementos
|
|
165
|
-
let count = Collector.full(
|
|
166
|
-
(): number => 0, // Valor inicial
|
|
167
|
-
(accumulator: number, element: number): number => accumulator + element, // Acumular
|
|
168
|
-
(accumulator: number): number => accumulator // Finalizar
|
|
169
|
-
);
|
|
170
|
-
count.collect(from([1, 2, 3, 4, 5])); // Recuento desde un flujo
|
|
171
|
-
count.collect([1, 2, 3, 4, 5]); // Recuento desde un objeto iterable
|
|
172
|
-
|
|
173
|
-
let find = Collector.shortable(
|
|
174
|
-
(): Optional<number> => Optional.empty(), // Valor inicial
|
|
175
|
-
(element: number, index: bigint, accumulator: Optional<number>): Optional<number> => accumulator.isPresent(), // Interrumpir
|
|
176
|
-
(accumulator: Optional<number>, element: number, index: bigint): Optional<number> => Optional.of(element), // Acumular
|
|
177
|
-
(accumulator: Optional<number>): Optional<number> => accumulator // Finalizar
|
|
178
|
-
);
|
|
179
|
-
find.collect(from([1, 2, 3, 4, 5])); // Encuentra el primer elemento
|
|
180
|
-
find.collect([1, 2, 3, 4, 5]); // Encuentra el primer elemento
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Métodos de Fábrica de Semantic
|
|
63
|
+
// Desde un generador asincrónico
|
|
64
|
+
const asyncStream = useFrom(async function*() {
|
|
65
|
+
yield 1;
|
|
66
|
+
yield 2;
|
|
67
|
+
});
|
|
184
68
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
| `animationFrame(period: number, delay: number = 0)` | Crea un flujo de fotogramas de animación basado en tiempo | O(1)* | O(1) |
|
|
188
|
-
| `blob(blob, chunkSize)` | Crea un flujo a partir de un Blob | O(n) | O(chunkSize) |
|
|
189
|
-
| `empty<E>()` | Crea un flujo vacío | O(1) | O(1) |
|
|
190
|
-
| `fill<E>(element, count)` | Crea un flujo lleno | O(n) | O(1) |
|
|
191
|
-
| `from<E>(iterable)` | Crea un flujo a partir de un objeto iterable | O(1) | O(1) |
|
|
192
|
-
| `interval(period, delay?)` | Crea un flujo de intervalo de tiempo | O(1)* | O(1) |
|
|
193
|
-
| `iterate<E>(generator)` | Crea un flujo a partir de un generador | O(1) | O(1) |
|
|
194
|
-
| `range(start, end, step)` | Crea un flujo de rango numérico | O(n) | O(1) |
|
|
195
|
-
| `websocket(websocket)` | Crea un flujo a partir de un WebSocket | O(1) | O(1) |
|
|
69
|
+
// Un flujo basado en tiempo
|
|
70
|
+
const tickStream = useInterval(1000); // emite cada segundo
|
|
196
71
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// Crea un flujo a partir de un Blob (lectura por partes)
|
|
201
|
-
blob(someBlob, 1024n)
|
|
202
|
-
.toUnordered()
|
|
203
|
-
.write(WritableStream)
|
|
204
|
-
.then(callback) // Escritura del flujo exitosa
|
|
205
|
-
.catch(callback); // Escritura del flujo fallida
|
|
206
|
-
|
|
207
|
-
// Crea un flujo vacío, no se ejecutará hasta concatenarse con otros flujos
|
|
208
|
-
empty<string>()
|
|
209
|
-
.toUnordered()
|
|
210
|
-
.join(); // []
|
|
211
|
-
|
|
212
|
-
// Crea un flujo lleno
|
|
213
|
-
const filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
214
|
-
|
|
215
|
-
// Crea un flujo de intervalo con un retraso inicial de 2 segundos y un período de ejecución de 5 segundos, implementado sobre un mecanismo de temporizador; puede experimentar deriva temporal debido a las limitaciones de precisión de la programación del sistema.
|
|
216
|
-
const intervalStream = interval(5000, 2000);
|
|
217
|
-
|
|
218
|
-
// Crea un flujo a partir de un objeto iterable
|
|
219
|
-
const numberStream = from([1, 2, 3, 4, 5]);
|
|
220
|
-
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
221
|
-
|
|
222
|
-
// Crea un flujo de rango
|
|
223
|
-
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
224
|
-
|
|
225
|
-
// Flujo de eventos WebSocket
|
|
226
|
-
const ws = new WebSocket("ws://localhost:8080");
|
|
227
|
-
websocket(ws)
|
|
228
|
-
.filter((event): boolean => event.type === "message") // Solo escucha eventos de mensaje
|
|
229
|
-
.toUnordered() // Los eventos generalmente no están ordenados
|
|
230
|
-
.forEach((event): void => receive(event)); // Recibe mensajes
|
|
72
|
+
// Un flujo de eventos DOM (ver nota crucial a continuación)
|
|
73
|
+
const clickStream = useDocument('click');
|
|
231
74
|
```
|
|
232
75
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
| Método | Descripción | Complejidad Temporal | Complejidad Espacial |
|
|
236
|
-
|------|------|------------|------------|
|
|
237
|
-
| `concat(other)` | Concatena dos flujos | O(n) | O(1) |
|
|
238
|
-
| `distinct()` | Elimina duplicados | O(n) | O(n) |
|
|
239
|
-
| `distinct(comparator)` | Elimina duplicados usando un comparador | O(n²) | O(n) |
|
|
240
|
-
| `dropWhile(predicate)` | Descarta elementos que satisfacen la condición | O(n) | O(1) |
|
|
241
|
-
| `filter(predicate)` | Filtra elementos | O(n) | O(1) |
|
|
242
|
-
| `flat(mapper)` | Aplicación plana de mapa | O(n × m) | O(1) |
|
|
243
|
-
| `flatMap(mapper)` | Aplicación plana de mapa a un nuevo tipo | O(n × m) | O(1) |
|
|
244
|
-
| `limit(n)` | Limita el número de elementos | O(n) | O(1) |
|
|
245
|
-
| `map(mapper)` | Transformación de asignación | O(n) | O(1) |
|
|
246
|
-
| `peek(consumer)` | Mirar elementos | O(n) | O(1) |
|
|
247
|
-
| `redirect(redirector)` | Redirigir índice | O(n) | O(1) |
|
|
248
|
-
| `reverse()` | Invierte el flujo | O(n) | O(1) |
|
|
249
|
-
| `shuffle()` | Mezcla al azar | O(n) | O(1) |
|
|
250
|
-
| `shuffle(mapper)` | Mezcla usando un mapeador | O(n) | O(1) |
|
|
251
|
-
| `skip(n)` | Omite los primeros n elementos | O(n) | O(1) |
|
|
252
|
-
| `sorted()` | Ordena | O(n log n) | O(n) |
|
|
253
|
-
| `sorted(comparator)` | Ordena usando un comparador | O(n log n) | O(n) |
|
|
254
|
-
| `sub(start, end)` | Obtiene un subflujo | O(n) | O(1) |
|
|
255
|
-
| `takeWhile(predicate)` | Obtiene elementos que satisfacen la condición | O(n) | O(1) |
|
|
256
|
-
| `translate(offset)` | Traduce índice | O(n) | O(1) |
|
|
257
|
-
| `translate(translator)` | Traduce índice usando un traductor | O(n) | O(1) |
|
|
258
|
-
|
|
76
|
+
### 2. Transformación de flujos (Operaciones intermedias)
|
|
77
|
+
Las operaciones se encadenan de forma diferida para definir el pipeline.
|
|
259
78
|
```typescript
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
.limit(3) // Limita a 3 elementos
|
|
266
|
-
.toUnordered() // Convierte a un colector no ordenado
|
|
267
|
-
.toArray(); // Convierte a arreglo
|
|
268
|
-
// Resultado: [8, 12, 20]
|
|
269
|
-
|
|
270
|
-
// Ejemplo de operación compleja
|
|
271
|
-
const complexResult = range(1, 100, 1)
|
|
272
|
-
.flatMap((n: number): Semantics<number> => from([n, n * 2])) // Asigna cada elemento a dos
|
|
273
|
-
.distinct() // Elimina duplicados
|
|
274
|
-
.shuffle() // Mezcla el orden
|
|
275
|
-
.takeWhile((n: number): boolean => n < 50) // Toma elementos menores que 50
|
|
276
|
-
.toOrdered() // Convierte a un colector ordenado
|
|
277
|
-
.toArray(); // Convierte a arreglo
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## Métodos de Conversión Semantic
|
|
79
|
+
const processedStream = staticStream
|
|
80
|
+
.filter(x => x % 2 === 0) // Mantener solo números pares
|
|
81
|
+
.map(x => x * 10) // Multiplicar por 10
|
|
82
|
+
.flatMap(x => [x, x + 1]) // Transformar cada elemento en dos
|
|
83
|
+
.distinct(); // Eliminar duplicados
|
|
281
84
|
|
|
282
|
-
|
|
283
|
-
|------------|------------|------------|------------|
|
|
284
|
-
| `sorted()` | Convierte a un colector ordenado | O(n log n) | O(n) |
|
|
285
|
-
| `toUnordered()` | Convierte a un colector no ordenado | O(1) | O(1) |
|
|
286
|
-
| `toOrdered()` | Convierte a un colector ordenado | O(1) | O(1) |
|
|
287
|
-
| `toNumericStatistics()` | Convierte a estadísticas numéricas | O(n) | O(1) |
|
|
288
|
-
| `toBigintStatistics()` | Convierte a estadísticas BigInt | O(n) | O(1) |
|
|
289
|
-
| `toWindow()` | Convierte a un colector de ventana | O(1) | O(1) |
|
|
290
|
-
| `toCollectable()` | Convierte a `UnorderdCollectable` | O(n) | O(1) |
|
|
291
|
-
| `toCollectable(mapper)` | Convierte a un colector personalizado | O(n) | O(1) |
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
// Convierte a un arreglo ordenado ascendente
|
|
295
|
-
from([6, 4, 3, 5, 2]) // Crea un flujo
|
|
296
|
-
.sorted() // Ordena el flujo en orden ascendente
|
|
297
|
-
.toArray(); // [2, 3, 4, 5, 6]
|
|
298
|
-
|
|
299
|
-
// Convierte a un arreglo ordenado descendente
|
|
300
|
-
from([6, 4, 3, 5, 2]) // Crea un flujo
|
|
301
|
-
.soted((a: number, b: number): number => b - a) // Ordena el flujo en orden descendente
|
|
302
|
-
.toArray(); // [6, 5, 4, 3, 2]
|
|
303
|
-
|
|
304
|
-
// Redirige a un arreglo invertido
|
|
305
|
-
from([6, 4, 3, 5, 2])
|
|
306
|
-
.redirect((element, index): bigint => -index) // Redirige a orden inverso
|
|
307
|
-
.toOrderd() // Mantiene el orden redirigido
|
|
308
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
309
|
-
|
|
310
|
-
// Ignora las redirecciones para invertir el arreglo
|
|
311
|
-
from([6, 4, 3, 5, 2])
|
|
312
|
-
.redirect((element, index): bigint => -index) // Redirige a orden inverso
|
|
313
|
-
.toUnorderd() // Descarta el orden redirigido. Esta operación ignorará `redirect`, `reverse`, `shuffle` y `translate`
|
|
314
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
315
|
-
|
|
316
|
-
// Invierte el flujo en un arreglo
|
|
317
|
-
from([6, 4, 3, 5, 2])
|
|
318
|
-
.reverse() // Invierte el flujo
|
|
319
|
-
.toOrdered() // Garantiza el orden invertido
|
|
320
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
321
|
-
|
|
322
|
-
// Sobrescribe el flujo mezclado en un arreglo
|
|
323
|
-
from([6, 4, 3, 5, 2])
|
|
324
|
-
.shuffle() // Mezcla el flujo
|
|
325
|
-
.sorted() // Sobrescribe el orden mezclado. Esta operación sobrescribirá `redirect`, `reverse`, `shuffle` y `translate`
|
|
326
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
327
|
-
|
|
328
|
-
// Convierte a un colector de ventana
|
|
329
|
-
from([6, 4, 3, 5, 2])
|
|
330
|
-
.toWindow(); // Convierte a estadísticas numéricas
|
|
331
|
-
|
|
332
|
-
from([6, 4, 3, 5, 2])
|
|
333
|
-
.toNumericStatistics(); // Convierte a estadísticas BigInt
|
|
334
|
-
|
|
335
|
-
from([6n, 4n, 3n, 5n, 2n])
|
|
336
|
-
.toBigintStatistics(); // Define un colector personalizado para recopilar datos
|
|
337
|
-
|
|
338
|
-
let customizedCollector = from([1, 2, 3, 4, 5])
|
|
339
|
-
.toCollectable((generator: Generator<E>) => new CustomizedCollector(generator));
|
|
85
|
+
// Nada se ha ejecutado todavía
|
|
340
86
|
```
|
|
341
87
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
| Método | Descripción | Complejidad Temporal | Complejidad Espacial |
|
|
345
|
-
|------|------|------------|------------|
|
|
346
|
-
| `anyMatch(predicate)` | Si algún elemento coincide | O(n) | O(1) |
|
|
347
|
-
| `allMatch(predicate)` | Si todos los elementos coinciden | O(n) | O(1) |
|
|
348
|
-
| `count()` | Recuento de elementos | O(n) | O(1) |
|
|
349
|
-
| `isEmpty()` | Si está vacío | O(1) | O(1) |
|
|
350
|
-
| `findAny()` | Encuentra cualquier elemento | O(n) | O(1) |
|
|
351
|
-
| `findFirst()` | Encuentra el primer elemento | O(n) | O(1) |
|
|
352
|
-
| `findLast()` | Encuentra el último elemento | O(n) | O(1) |
|
|
353
|
-
| `forEach(action)` | Itera sobre todos los elementos | O(n) | O(1) |
|
|
354
|
-
| `group(classifier)` | Agrupa por clasificador | O(n) | O(n) |
|
|
355
|
-
| `groupBy(keyExtractor, valueExtractor)` | Agrupa por extracción de clave-valor | O(n) | O(n) |
|
|
356
|
-
| `join()` | Únete como cadena | O(n) | O(n) |
|
|
357
|
-
| `join(delimiter)` | Únete usando un delimitador | O(n) | O(n) |
|
|
358
|
-
| `nonMatch(predicate)` | Si ningún elemento coincide | O(n) | O(1) |
|
|
359
|
-
| `partition(count)` | Particionar por recuento | O(n) | O(n) |
|
|
360
|
-
| `partitionBy(classifier)` | Particionar por clasificador | O(n) | O(n) |
|
|
361
|
-
| `reduce(accumulator)` | Operación de reducción | O(n) | O(1) |
|
|
362
|
-
| `reduce(identity, accumulator)` | Reducción con valor inicial | O(n) | O(1) |
|
|
363
|
-
| `toArray()` | Convierte a arreglo | O(n) | O(n) |
|
|
364
|
-
| `toMap(keyExtractor, valueExtractor)` | Convierte a Map | O(n) | O(n) |
|
|
365
|
-
| `toSet()` | Convierte a Set | O(n) | O(n) |
|
|
366
|
-
| `write(stream)` | Escribe en el flujo | O(n) | O(1) |
|
|
367
|
-
|
|
88
|
+
### 3. Ejecución de flujos (Operaciones terminales)
|
|
89
|
+
Para obtener un resultado, debes obtener un Collectable e invocar una operación terminal.
|
|
368
90
|
```typescript
|
|
369
|
-
//
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
console.log(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const grouped = data.groupBy(
|
|
384
|
-
(n: number): string => (n > 5 ? "grande" : "pequeño"),
|
|
385
|
-
(n: number): number => n * 2
|
|
386
|
-
); // {pequeño: [4, 8], grande: [12, 16, 20]}
|
|
387
|
-
|
|
388
|
-
// Operaciones de reducción
|
|
389
|
-
const sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
390
|
-
|
|
391
|
-
// Operaciones de salida
|
|
392
|
-
data.join(", "); // "[2, 4, 6, 8, 10]"
|
|
91
|
+
// Obtener un collectable no ordenado para rendimiento
|
|
92
|
+
const resultArray = await processedStream.toUnordered().toArray();
|
|
93
|
+
console.log(resultArray); // ej., [20, 21, 40, 41]
|
|
94
|
+
|
|
95
|
+
// Usar un coleccionador incorporado
|
|
96
|
+
const sum = await processedStream.toUnordered().collect(useSummate());
|
|
97
|
+
console.log(sum);
|
|
98
|
+
|
|
99
|
+
// O usar el método collect genérico
|
|
100
|
+
const customResult = await processedStream.toOrdered().collect(
|
|
101
|
+
() => new Map<number, number>(),
|
|
102
|
+
(map, element, index) => map.set(index, element),
|
|
103
|
+
map => map
|
|
104
|
+
);
|
|
393
105
|
```
|
|
394
106
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
### Métodos de NumericStatistics
|
|
398
|
-
|
|
399
|
-
| Método | Descripción | Complejidad Temporal | Complejidad Espacial |
|
|
400
|
-
|------|------|------------|------------|
|
|
401
|
-
| `range()` | Rango | O(n) | O(1) |
|
|
402
|
-
| `variance()` | Varianza | O(n) | O(1) |
|
|
403
|
-
| `standardDeviation()` | Desviación estándar | O(n) | O(1) |
|
|
404
|
-
| `mean()` | Media | O(n) | O(1) |
|
|
405
|
-
| `median()` | Mediana | O(n log n) | O(n) |
|
|
406
|
-
| `mode()` | Moda | O(n) | O(n) |
|
|
407
|
-
| `frequency()` | Distribución de frecuencia | O(n) | O(n) |
|
|
408
|
-
| `summate()` | Suma | O(n) | O(1) |
|
|
409
|
-
| `quantile(quantile)` | Cuantil | O(n log n) | O(n) |
|
|
410
|
-
| `interquartileRange()` | Rango intercuartílico | O(n log n) | O(n) |
|
|
411
|
-
| `skewness()` | Sesgo | O(n) | O(1) |
|
|
412
|
-
| `kurtosis()` | Curtosis | O(n) | O(1) |
|
|
413
|
-
|
|
107
|
+
### 4. Crucial: Trabajar con flujos de eventos
|
|
108
|
+
Los flujos de eventos (useDocument, useWindow, useHTMLElement, useWebSocket) son infinitos por naturaleza. Debes usar operaciones como sub, takeWhile o limit para definir cuándo dejar de recolectar eventos y completar el flujo. De lo contrario, la operación terminal esperará indefinidamente.
|
|
414
109
|
```typescript
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
110
|
+
import { useDocument } from 'semantic-typescript';
|
|
111
|
+
|
|
112
|
+
// Recolectar solo los primeros 5 clics
|
|
113
|
+
const first5Clicks = await useDocument('click')
|
|
114
|
+
.limit(5) // <- Esencial: limita el flujo a 5 eventos
|
|
115
|
+
.toUnordered()
|
|
116
|
+
.toArray();
|
|
117
|
+
|
|
118
|
+
// Recolectar clics durante una ventana de 10 segundos
|
|
119
|
+
const clicksIn10s = await useDocument('click')
|
|
120
|
+
.takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
|
|
121
|
+
.toUnordered()
|
|
122
|
+
.toArray();
|
|
123
|
+
|
|
124
|
+
// Recolectar clics desde el índice 2 al 5 (base 0)
|
|
125
|
+
const specificClicks = await useDocument('click')
|
|
126
|
+
.sub(2n, 6n) // <- Toma elementos con índice 2, 3, 4, 5
|
|
127
|
+
.toUnordered()
|
|
128
|
+
.toArray();
|
|
431
129
|
```
|
|
432
130
|
|
|
433
|
-
|
|
131
|
+
**Perspicacia clave**: El evento (por ejemplo, un MouseEvent) y su índice de disparo secuencial (como un bigint) se pasan juntos a través del pipeline mediante el callback `accept(event, index)`.
|
|
434
132
|
|
|
435
|
-
###
|
|
133
|
+
### 5. Aprovechando las estadísticas
|
|
436
134
|
```typescript
|
|
437
|
-
|
|
438
|
-
let highPerformance = data
|
|
439
|
-
.filter(predicate)
|
|
440
|
-
.map(mapper)
|
|
441
|
-
.toUnordered(); // Mejor rendimiento
|
|
442
|
-
```
|
|
135
|
+
const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
|
|
443
136
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
```
|
|
137
|
+
const average = await numericStream.average();
|
|
138
|
+
const median = await numericStream.median();
|
|
139
|
+
const standardDeviation = await numericStream.standardDeviation();
|
|
140
|
+
const skewness = await numericStream.skewness();
|
|
449
141
|
|
|
450
|
-
|
|
451
|
-
```typescript
|
|
452
|
-
// Cuando se necesitan operaciones de ventana
|
|
453
|
-
let windowed: WindowCollectable<number> = data
|
|
454
|
-
.toWindow()
|
|
455
|
-
.slide(5n, 2n); // Ventana deslizante
|
|
142
|
+
console.log(`Promedio: ${average}, Mediana: ${median}, DesvEst: ${standardDeviation}`);
|
|
456
143
|
```
|
|
457
144
|
|
|
458
|
-
|
|
145
|
+
## Características principales
|
|
146
|
+
- **Tipos de flujo dual**: Soporte completo para ambos SynchronousSemantic (para Iterable) y AsynchronousSemantic (para AsyncIterable y eventos)
|
|
147
|
+
- **Conjunto de operaciones rico**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
|
|
148
|
+
- **Operaciones terminales flexibles**: collect (con coleccionadores personalizados), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
|
|
149
|
+
- **Coleccionadores avanzados**: Coleccionadores integrados para joining, groupingBy, partitioningBy, summing, averaging, maxBy, minBy
|
|
150
|
+
- **Módulo estadístico**: Métodos listos para usar para media, mediana, moda, varianza, desviaciónEstándar, rango, cuantiles, asimetría, curtosis en flujos numéricos/de bigint
|
|
151
|
+
- **Funciones de utilidad**: Protecciones de tipo (isPromise, isAsyncIterable), comparadores (useCompare), recorrido (useTraverse) y ganchos de conversión
|
|
152
|
+
- **Optional<T>**: Un contenedor monádico para valores anulables, integrado con operaciones de búsqueda
|
|
153
|
+
|
|
154
|
+
## Resumen de la API
|
|
155
|
+
|
|
156
|
+
### Clases e interfaces centrales
|
|
157
|
+
- `Semantic<E>` / `AsynchronousSemantic<E>`: La definición abstracta del flujo
|
|
158
|
+
- `Collectable<E>` / `AsynchronousCollectable<E>`: El flujo ejecutable con operaciones terminales
|
|
159
|
+
- `OrderedCollectable<E>` / `UnorderedCollectable<E>`: Versiones materializadas optimizadas para operaciones sensibles o no sensibles al orden
|
|
160
|
+
- `Collector<E, A, R>`: La abstracción para operaciones de reducción mutables
|
|
161
|
+
|
|
162
|
+
### Funciones de fábrica (use*)
|
|
163
|
+
- **Desde fuentes**: useFrom, useRange, useFill, useEmpty
|
|
164
|
+
- **Desde tiempo**: useInterval, useAnimationFrame
|
|
165
|
+
- **Desde APIs web**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
|
|
166
|
+
- **Coleccionadores**: useToArray, useGroupBy, useSummate, useJoin, etc.
|
|
167
|
+
|
|
168
|
+
## Notas de rendimiento
|
|
169
|
+
- **Evaluación diferida**: Los pipelines se componen sin ejecución hasta que se llama a una operación terminal
|
|
170
|
+
- **Cortocircuito**: Operaciones como limit, anyMatch y findFirst detendrán el procesamiento de elementos tan pronto como se determine el resultado
|
|
171
|
+
- **Ordenado vs No ordenado**:
|
|
172
|
+
- Usa `.toUnordered()` para operaciones terminales cuando el orden de los elementos fuente no importa para tu resultado (por ejemplo, para suma, máximo o toSet). Esto puede permitir optimizaciones internas que omiten costosos pasos de ordenación
|
|
173
|
+
- Usa `.toOrdered()` cuando la secuencia es importante (por ejemplo, para toArray donde se debe preservar el orden)
|
|
174
|
+
|
|
175
|
+
## Ejemplo de inicio
|
|
459
176
|
```typescript
|
|
460
|
-
|
|
461
|
-
let statistics: NumericStatistics<number> = data
|
|
462
|
-
.toNumericStatistics(); // Estadísticas numéricas
|
|
463
|
-
|
|
464
|
-
let bigIntStatistics: BigintStatistics<bigint> = data
|
|
465
|
-
.toBigintStatistics(); // Estadísticas de enteros grandes
|
|
466
|
-
```
|
|
177
|
+
import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
|
|
467
178
|
|
|
468
|
-
|
|
469
|
-
|
|
179
|
+
interface Transaction {
|
|
180
|
+
id: number;
|
|
181
|
+
amount: number;
|
|
182
|
+
category: string;
|
|
183
|
+
}
|
|
470
184
|
|
|
471
|
-
|
|
185
|
+
const transactions: Transaction[] = [
|
|
186
|
+
{ id: 1, amount: 100, category: 'Food' },
|
|
187
|
+
{ id: 2, amount: 200, category: 'Electronics' },
|
|
188
|
+
{ id: 3, amount: 50, category: 'Food' },
|
|
189
|
+
{ id: 4, amount: 300, category: 'Electronics' },
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
// Calcular el monto total por categoría
|
|
193
|
+
const totalsByCategory = await useFrom(transactions)
|
|
194
|
+
.toUnordered()
|
|
195
|
+
.collect(
|
|
196
|
+
useGroupBy(
|
|
197
|
+
t => t.category,
|
|
198
|
+
t => t.amount,
|
|
199
|
+
useSummate() // Coleccionador para los valores
|
|
200
|
+
)
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
|
|
204
|
+
```
|
|
472
205
|
|
|
473
|
-
|
|
474
|
-
2. **Consideraciones de Rendimiento**: Si no se necesita garantizar el orden, priorice el uso de `toUnordered()` para un mejor rendimiento.
|
|
475
|
-
3. **Uso de Memoria**: Las operaciones de ordenación requieren espacio adicional de O(n).
|
|
476
|
-
4. **Datos en Tiempo Real**: Los flujos Semantic son adecuados para procesar datos en tiempo real y admiten fuentes de datos asíncronas.
|
|
206
|
+
Semantic-TypeScript está construida para desarrolladores que buscan una biblioteca de procesamiento de flujos rigurosamente diseñada, segura en tipos y de alto rendimiento. Lleva el poder de los patrones de transformación de datos a nivel empresarial al ecosistema TypeScript, perfectamente adecuada para aplicaciones front-end intensivas en datos, procesamiento de datos en Node.js y cualquier escenario donde se requiera un manejo elegante y eficiente de secuencias.
|
|
477
207
|
|
|
478
|
-
|
|
208
|
+
[](https://github.com/eloyhere/semantic-typescript) [](https://www.npmjs.com/package/semantic-typescript)
|