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.es.md CHANGED
@@ -1,208 +1,267 @@
1
- # Semantic-TypeScript: Una biblioteca de procesamiento de flujo que cambia paradigmas
1
+ # **SemanticTypeScript**
2
+ **Flujos, indexados.** Tus datos, bajo control preciso.
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
+ ### Descripción general
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
+ Semantic‑TypeScript representa un avance significativo en el procesamiento de flujos, **fusionando** elegantemente los paradigmas más efectivos de los generadores de JavaScript, los Streams de Java y la indexación al estilo MySQL. Su premisa fundamental es poderosa y deliberada: construir canalizaciones de procesamiento de datos excepcionalmente eficientes mediante indexación inteligente, en lugar de mediante iteración por fuerza bruta convencional.
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
+ Donde las bibliotecas típicas imponen bucles sincrónicos o cadenas de promesas engorrosas, Semantic‑TypeScript proporciona una experiencia **completamente asíncrona**, funcionalmente pura y rigurosamente segura en cuanto a tipos, diseñada expresamente para las exigencias del desarrollo moderno de aplicaciones.
17
11
 
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.
12
+ Este modelo encarna una forma refinada de flujo de control: los datos solo avanzan hacia el consumidor aguas abajo cuando la canalización aguas arriba invoca explícitamente la función de retorno `accept`. Conservas un control completo y granular sobre el momento del procesamiento: este ocurre precisamente cuando, y solo cuando, es necesario.
19
13
 
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.
14
+ ---
22
15
 
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.
16
+ ### ¿Por qué los desarrolladores eligen Semantic‑TypeScript?
25
17
 
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.
18
+ - **Indexación sin código repetitivo** Cada elemento posee inherentemente su índice natural o personalizado, eliminando el seguimiento manual.
19
+ - **Puramente funcional y seguro en tipos** Disfruta de inferencia de tipos TypeScript completa e idiomática junto con operaciones inmutables.
20
+ - **Flujos de eventos a prueba de fugas** – El patrón `useSubscription` se diseña teniendo la seguridad de recursos como primer principio. Defines el límite lógico (usando `limit(n)`, `sub(start, end)` o `takeWhile(predicate)`) y la biblioteca gestiona completamente el ciclo de vida de la suscripción. Esto garantiza que no haya oyentes residuales ni fugas de memoria.
21
+ - **Suite estadística integrada** – Accede a análisis exhaustivos para flujos tanto de `number` como de `bigint`, incluyendo promedios, medianas, modas, varianza, asimetría y curtosis, sin dependencias externas.
22
+ - **Rendimiento predecible y ajustable** – Elige entre colectores ordenados o desordenados para adaptarte exactamente a tus requisitos de rendimiento y orden.
23
+ - **Inherentemente eficiente en memoria** – Los flujos se evalúan de forma diferida, procesando elementos bajo demanda para aliviar la presión sobre la memoria.
24
+ - **Sin comportamiento indefinido** – TypeScript garantiza seguridad de tipos completa y nulabilidad. Tus datos de origen permanecen inmutables a menos que se modifiquen explícitamente dentro de tus funciones de retorno.
28
25
 
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.
26
+ ---
31
27
 
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
28
+ ### Instalación
38
29
 
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.
30
+ Integra Semantic‑TypeScript en tu proyecto usando tu gestor de paquetes preferido:
41
31
 
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
47
-
48
- ## Instalación
49
32
  ```bash
50
33
  npm install semantic-typescript
51
34
  ```
35
+ o
36
+ ```bash
37
+ yarn add semantic-typescript
38
+ ```
39
+
40
+ ---
41
+
42
+ ### Introducción práctica
52
43
 
53
- ## Conceptos centrales en la práctica
44
+ Los siguientes ejemplos demuestran conceptos clave, desde transformaciones básicas hasta manejo de eventos del mundo real.
54
45
 
55
- ### 1. Creación de flujos (Semantic)
56
- Los flujos se pueden crear desde varias fuentes usando funciones de fábrica.
57
46
  ```typescript
58
- import { useFrom, useInterval, useDocument } from 'semantic-typescript';
47
+ import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
48
+
49
+ // ====================================================================
50
+ // EJEMPLO 1: Operaciones básicas y estadísticas numéricas
51
+ // ====================================================================
52
+ // Demuestra operaciones de mapeo y estadísticas terminales. Después de la transformación, la canalización debe convertirse en un colector de estadísticas antes de poder llamar a métodos terminales como `.summate()`.
53
+
54
+ const numericSum: number = useOf(10, 20, 30, 40)
55
+ .map((n: number): number => n * 2) // Duplica cada elemento: [20, 40, 60, 80]
56
+ .toNumericStatistics() // Convierte a un colector de estadísticas
57
+ .summate(); // Operación terminal: 200
58
+
59
+ // Otros métodos estadísticos (disponibles después de `.toNumericStatistics()`):
60
+ // .average(), .median(), .mode(), .variance(), .skewness(), .kurtosis()
61
+
62
+ // ====================================================================
63
+ // EJEMPLO 2: Estadísticas de BigInt
64
+ // ====================================================================
65
+ // Funciona de manera idéntica a las estadísticas numéricas pero está optimizado para datos BigInt.
66
+
67
+ const bigintSum: bigint = useOf(10n, 20n, 30n, 40n)
68
+ .map((n: bigint): bigint => n * 2n) // Aritmética BigInt
69
+ .toBigIntStatistics() // Convierte a un colector de estadísticas BigInt
70
+ .summate(); // Operación terminal: 200n
71
+
72
+ // ====================================================================
73
+ // EJEMPLO 3: Manipulación de índices para invertir un flujo
74
+ // ====================================================================
75
+ // Ilustra cómo reordenar elementos reasignando estratégicamente sus índices utilizando el método `.redirect()`, permitiendo patrones personalizados como la inversión.
76
+
77
+ const reversedArray: number[] = useFrom([1, 2, 3, 4, 5])
78
+ .redirect((_element: number, index: bigint): bigint => -index) // Mapea a índices negativos
79
+ .toOrdered() // Esencial: recoge elementos ordenados por sus nuevos índices
80
+ .toArray(); // Resultado: [5, 4, 3, 2, 1]
81
+
82
+ // Para una inversión simple, también está disponible `.reverse()`.
83
+
84
+ // ====================================================================
85
+ // EJEMPLO 4: Mezcla (Shuffle) de un flujo
86
+ // ====================================================================
87
+ // Permuta aleatoriamente los índices de los elementos usando un algoritmo de mezcla in situ.
88
+
89
+ const shuffledArray: number[] = useFrom([1, 2, 3, 4, 5])
90
+ .shuffle() // Reasigna índices aleatoriamente
91
+ .toOrdered() // Ordena según los nuevos índices aleatorios
92
+ .toArray(); // Ejemplo: [2, 5, 1, 4, 3] (varía en cada ejecución)
93
+
94
+ // ====================================================================
95
+ // EJEMPLO 5: Rotación circular de un flujo
96
+ // ====================================================================
97
+ // Desplaza elementos cíclicamente. Los valores positivos rotan a la derecha; los negativos a la izquierda.
98
+
99
+ // Rotación a la derecha 2 posiciones
100
+ const rightRotated: number[] = useFrom([1, 2, 3, 4, 5])
101
+ .translate(2) // Desplaza índices 2 posiciones a la derecha
102
+ .toOrdered()
103
+ .toArray(); // Resultado: [4, 5, 1, 2, 3]
104
+
105
+ // ====================================================================
106
+ // EJEMPLO 6: Evaluación diferida con rangos infinitos
107
+ // ====================================================================
108
+ // Procesa flujos teóricamente infinitos de forma diferida, calculando elementos solo cuando se necesitan.
109
+
110
+ const firstTenMultiples: bigint[] = useRange(0n, 1_000_000n)
111
+ .filter(n => n % 17n === 0n) // Conserva múltiplos de 17
112
+ .limit(10n) // Crítico: se detiene después de la décima coincidencia
113
+ .toUnordered() // No se requiere ordenación
114
+ .toArray(); // Resultado: [0, 17, 34, 51, 68, 85, 102, 119, 136, 153]
115
+
116
+ // Sin `.limit(10n)`, la canalización procesaría el millón de elementos.
117
+
118
+ // ====================================================================
119
+ // EJEMPLO 7: Composición de una canalización compleja
120
+ // ====================================================================
121
+ // Demuestra la composición secuencial de múltiples operaciones.
122
+
123
+ const complexResult: number[] = useRange(1n, 100n)
124
+ .map(n => Number(n) * 2)
125
+ .filter(n => n > 50)
126
+ .shuffle()
127
+ .limit(5n)
128
+ .translate(2)
129
+ .toOrdered()
130
+ .toArray();
59
131
 
60
- // Desde un arreglo estático
61
- const staticStream = useFrom([1, 2, 3, 4, 5]);
132
+ // ====================================================================
133
+ // EJEMPLO 8: Suscripción gestionada a eventos del DOM
134
+ // ====================================================================
135
+ // Escucha eventos del navegador con limpieza automática y a prueba de fugas.
136
+ // La llamada `.limit(n)` define el límite para la eliminación automática del oyente.
137
+
138
+ // Define un suscriptor para un objetivo Window
139
+ const windowSubscriber = {
140
+ mount: (target: Window): void => { /* Lógica de configuración */ },
141
+ subscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
142
+ target.addEventListener(event, handler);
143
+ },
144
+ unsubscribe: (target: Window, event: keyof WindowEventMap, handler: EventListener): void => {
145
+ target.removeEventListener(event, handler);
146
+ },
147
+ unmount: (): void => { /* Lógica de limpieza */ }
148
+ };
149
+
150
+ useSubscription(window, windowSubscriber, "resize")
151
+ .limit(5n) // Se da de baja automáticamente después de 5 eventos
152
+ .toUnordered()
153
+ .forEach((ev: Event, idx) =>
154
+ console.log(`Redimensión #${idx}: ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
155
+ );
62
156
 
63
- // Desde un generador asincrónico
64
- const asyncStream = useFrom(async function*() {
65
- yield 1;
66
- yield 2;
67
- });
157
+ // ====================================================================
158
+ // EJEMPLO 9: Procesamiento de cadenas por puntos de código Unicode
159
+ // ====================================================================
160
+ // Itera correctamente sobre una cadena, manejando caracteres Unicode de múltiples bytes.
68
161
 
69
- // Un flujo basado en tiempo
70
- const tickStream = useInterval(1000); // emite cada segundo
162
+ useText("My emotion now is: 😊, and semantic is 👍")
163
+ .toUnordered()
164
+ .log(); // Registra cada carácter (incluyendo emojis) en una nueva línea.
71
165
 
72
- // Un flujo de eventos DOM (ver nota crucial a continuación)
73
- const clickStream = useDocument('click');
74
- ```
166
+ // ====================================================================
167
+ // EJEMPLO 10: Transformación a cadena segura de referencias circulares
168
+ // ====================================================================
169
+ // Serializa de forma segura objetos que contienen referencias circulares.
75
170
 
76
- ### 2. Transformación de flujos (Operaciones intermedias)
77
- Las operaciones se encadenan de forma diferida para definir el pipeline.
78
- ```typescript
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
171
+ const obj = {
172
+ a: 1,
173
+ b: "texto"
174
+ };
175
+ (obj as any).c = [obj.a, obj.b, (obj as any).c]; // Introduce una referencia circular
84
176
 
85
- // Nada se ha ejecutado todavía
177
+ // const text: string = JSON.stringify(obj); // Lanza un error
178
+ const text: string = useStringify(obj); // Produce de forma segura `{a: 1, b: "texto", c: []}`
86
179
  ```
87
180
 
88
- ### 3. Ejecución de flujos (Operaciones terminales)
89
- Para obtener un resultado, debes obtener un Collectable e invocar una operación terminal.
90
- ```typescript
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
- );
105
- ```
181
+ ---
106
182
 
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.
109
- ```typescript
110
- import { useDocument } from 'semantic-typescript';
183
+ ### Conceptos principales
111
184
 
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();
185
+ | Concepto | Propósito | Caso de uso principal |
186
+ | :--- | :--- | :--- |
187
+ | `AsynchronousSemantic` | El constructor principal para flujos asíncronos, eventos y canalizaciones diferidas basadas en *push*. | Eventos en tiempo real, WebSockets, oyentes del DOM o cualquier flujo de larga duración/infinito. |
188
+ | `SynchronousSemantic` | El constructor para flujos síncronos, en memoria o basados en *pull* inmediatos (*eager*). | Datos estáticos, rangos finitos o tareas de iteración inmediata. |
189
+ | `toUnordered()` | El colector terminal más rápido, utiliza un Map para almacenar índices. | Rutas críticas de rendimiento donde el orden estable no es requerido (tiempo y espacio O(n)). |
190
+ | `toOrdered()` | Un colector terminal ordenado, estable en índices. | Cuando se debe preservar el orden de los elementos o se necesita acceso indexado. |
191
+ | `toNumericStatistics()` | Un colector que habilita análisis estadísticos completos en flujos de `number`. | Análisis de datos, métricas y cálculos estadísticos. |
192
+ | `toBigIntStatistics()` | Un colector que habilita análisis estadísticos completos en flujos de `bigint`. | Análisis y estadísticas para conjuntos de datos de enteros grandes. |
193
+ | `toWindow()` | Proporciona operaciones de ventana deslizante (*sliding*) y fija (*tumbling*) sobre un flujo. | Análisis de series temporales, procesamiento por lotes y agregaciones por ventanas. |
117
194
 
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();
195
+ ---
123
196
 
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();
129
- ```
197
+ **Reglas de uso esenciales**
130
198
 
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)`.
199
+ 1. **Los flujos de eventos** (creados a través de fábricas como `useSubscription`) devuelven un `AsynchronousSemantic`.
200
+ → Debes llamar a un método que defina un límite, como `.limit(n)`, `.sub(start, end)` o `.takeWhile(predicate)` para terminar el oyente. De lo contrario, la suscripción permanecerá activa.
132
201
 
133
- ### 5. Aprovechando las estadísticas
134
- ```typescript
135
- const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
202
+ 2. **Las operaciones terminales** (`.toArray()`, `.count()`, `.forEach()`, `.findFirst()`, etc.) solo están disponibles después de convertir la canalización en un colector:
203
+ ```typescript
204
+ .toUnordered() // Para máxima velocidad, sin garantía de orden.
205
+ // o
206
+ .toOrdered() // Para salida estable y ordenada.
207
+ // o
208
+ .toNumericStatistics() // Para métodos estadísticos.
209
+ ```
136
210
 
137
- const average = await numericStream.average();
138
- const median = await numericStream.median();
139
- const standardDeviation = await numericStream.standardDeviation();
140
- const skewness = await numericStream.skewness();
211
+ ---
141
212
 
142
- console.log(`Promedio: ${average}, Mediana: ${median}, DesvEst: ${standardDeviation}`);
143
- ```
213
+ ### Características de rendimiento
144
214
 
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
176
- ```typescript
177
- import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
178
-
179
- interface Transaction {
180
- id: number;
181
- amount: number;
182
- category: string;
183
- }
184
-
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
- );
215
+ | Colector | Complejidad temporal | Complejidad espacial | ¿Orden garantizado? | Escenario ideal |
216
+ | :--- | :--- | :--- | :--- | :--- |
217
+ | `toUnordered()` | O(n) | O(n) | No | El rendimiento bruto es clave; el orden final es irrelevante. |
218
+ | `toOrdered()` | O(n log n) | O(n) | Sí (ordenado) | Orden estable, acceso indexado o pre-ordenación para estadísticas. |
219
+ | `toNumericStatistics()` | O(n log n) | O(n) | (orden interno) | Realizar operaciones estadísticas que requieren datos ordenados. |
220
+ | `toBigIntStatistics()` | O(n log n) | O(n) | (orden interno) | Operaciones estadísticas en datos BigInt. |
221
+ | `toWindow()` | O(n log n) | O(n) | (orden interno) | Operaciones de ventana que se benefician de índices ordenados. |
202
222
 
203
- console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
204
- ```
223
+ Elige `toUnordered()` cuando la velocidad absoluta es primordial. Opta por `toOrdered()` o un colector de estadísticas solo cuando tu lógica dependa del orden de los elementos.
224
+
225
+ ---
226
+
227
+ **Análisis comparativo con bibliotecas modernas de flujos**
228
+
229
+ | Característica | Semantic‑TypeScript | RxJS | Async Iterators / Generators nativos | Most.js |
230
+ | :--- | :--- | :--- | :--- | :--- |
231
+ | **Integración TypeScript** | De primera clase, fuertemente tipado con conciencia de índice inherente. | Excelente, pero a menudo implica cadenas genéricas complejas. | Buena, pero requiere anotaciones de tipo manuales. | Fuerte, con un estilo de tipado funcional-*first*. |
232
+ | **Análisis estadístico integrado** | Soporte nativo completo para `number` y `bigint`. | No disponible de forma nativa (requiere operadores personalizados u otras bibliotecas). | Ninguno. | Ninguno. |
233
+ | **Indexación y conciencia de posición** | Indexación BigInt nativa y poderosa en cada elemento. | Requiere operadores personalizados (ej. `scan`, `withLatestFrom`). | Se requiere gestión manual de contadores. | Básica, sin propiedad de índice incorporada. |
234
+ | **Gestión de flujos de eventos** | Fábricas dedicadas, seguras en tipos, con control de ciclo de vida explícito y declarativo. | Poderosa pero requiere una gestión manual cuidadosa de las suscripciones para evitar fugas. | Adjuntar oyentes de eventos manualmente y gestionar tokens de cancelación. | Buen `fromEvent`, generalmente liviano. |
235
+ | **Rendimiento y memoria** | Excepcional: ofrece colectores optimizados `toUnordered()` y `toOrdered()`. | Muy buena, aunque las cadenas profundas de operadores pueden introducir sobrecarga. | Excelente (sobrecarga nativa mínima). | Excelente. |
236
+ | **Tamaño del paquete** | Muy liviano. | Sustancial (incluso con *tree-shaking*). | Cero (característica nativa del lenguaje). | Pequeño. |
237
+ | **Filosofía de diseño de API** | Patrón de colector funcional con semántica de índice explícita. | Patrón Observable reactivo. | Patrón Iterator imperativo / Generator declarativo. | Funcional, composición *point-free*. |
238
+ | **Control de flujo** | Explícito (`interrupt`, `.limit()`, `.takeWhile()`, `.sub()`). | Bueno (`take`, `takeUntil`, `first`). | Manual (`break` en bucles). | Bueno (`take`, `until`). |
239
+ | **Soporte síncrono y asíncrono** | API unificada: soporte de primera clase para ambos paradigmas. | Principalmente asíncrono. | Ambos soportados, pero con puente manual. | Principalmente asíncrono. |
240
+ | **Curva de aprendizaje** | Suave para desarrolladores familiarizados con canalizaciones de colecciones funcionales e indexadas. | Más pronunciada (amplio léxico de operadores, conceptos de Observable *hot/cold*). | Baja a media. | Media. |
241
+
242
+ **La ventaja de Semantic‑TypeScript**
243
+
244
+ * **Capacidades únicas:** Las características de estadística e indexación integradas eliminan la necesidad de operaciones manuales de `reduce` o bibliotecas de análisis de datos suplementarias.
245
+ * **Gestión de recursos predecible:** El control explícito sobre los flujos de eventos previene las fugas de memoria que pueden ser sutiles en las aplicaciones RxJS.
246
+ * **Diseño unificado:** Una API consistente para flujos de trabajo tanto síncronos como asíncronos reduce la carga cognitiva y la duplicación de código.
247
+
248
+ Esta comparación destaca por qué Semantic‑TypeScript es especialmente adecuado para aplicaciones TypeScript modernas que exigen alto rendimiento, solidez en la seguridad de tipos y amplias funciones de procesamiento de datos sin la complejidad de los marcos reactivos tradicionales.
249
+
250
+ ---
251
+
252
+ ### Comienza tu exploración
253
+
254
+ Semantic‑TypeScript transforma flujos de datos complejos en canalizaciones legibles, componibles y de alto rendimiento. Ya sea que estés manejando eventos de UI en tiempo real, procesando grandes conjuntos de datos o construyendo paneles de análisis, ofrece el poder de la indexación a nivel de base de datos con la elegancia de la programación funcional.
255
+
256
+ **Tus próximos pasos:**
257
+
258
+ * Explora la API completamente tipificada directamente en tu IDE (todas las exportaciones están disponibles desde el punto de entrada principal del paquete).
259
+ * Únete a la creciente comunidad de desarrolladores que han reemplazado iteradores asíncronos complejos y cadenas reactivas con canalizaciones Semantic claras e intencionales.
260
+
261
+ **Semantic‑TypeScript** – donde los flujos se encuentran con la estructura.
262
+
263
+ Comienza a construir hoy y experimenta la diferencia tangible que aporta un diseño de indexación reflexivo.
205
264
 
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.
265
+ **Construye con claridad, avanza con confianza y transforma datos con intención.**
207
266
 
208
- [![GitHub](./GitHub.png)](https://github.com/eloyhere/semantic-typescript) [![NPM](./NPM.png)](https://www.npmjs.com/package/semantic-typescript)
267
+ MIT © Eloy Kim