semantic-typescript 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/asynchronous/collector.d.ts +62 -58
- package/dist/asynchronous/collector.js +16 -5
- package/dist/asynchronous/semantic.d.ts +6 -2
- package/dist/asynchronous/semantic.js +19 -6
- package/dist/factory.d.ts +32 -71
- package/dist/factory.js +192 -603
- package/dist/guard.d.ts +0 -3
- package/dist/guard.js +0 -19
- package/dist/hash.js +3 -0
- package/dist/hook.d.ts +6 -1
- package/dist/hook.js +20 -3
- package/dist/synchronous/collector.d.ts +8 -4
- package/dist/synchronous/collector.js +74 -59
- package/dist/synchronous/semantic.d.ts +31 -23
- package/dist/synchronous/semantic.js +218 -286
- package/package.json +3 -2
- package/readme.cn.md +267 -214
- package/readme.de.md +225 -172
- package/readme.es.md +229 -170
- package/readme.fr.md +233 -170
- package/readme.jp.md +232 -169
- package/readme.kr.md +227 -169
- package/readme.md +270 -214
- package/readme.ru.md +231 -169
- package/readme.tw.md +225 -172
package/readme.es.md
CHANGED
|
@@ -1,208 +1,267 @@
|
|
|
1
|
-
# Semantic
|
|
1
|
+
# **Semantic‑TypeScript**
|
|
2
|
+
**Flujos, indexados.** Tus datos, bajo control preciso.
|
|
2
3
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
//
|
|
61
|
-
|
|
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
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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
|
-
//
|
|
73
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
119
|
-
const clicksIn10s = await useDocument('click')
|
|
120
|
-
.takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
|
|
121
|
-
.toUnordered()
|
|
122
|
-
.toArray();
|
|
195
|
+
---
|
|
123
196
|
|
|
124
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
|
|
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
|
-
|
|
138
|
-
const median = await numericStream.median();
|
|
139
|
-
const standardDeviation = await numericStream.standardDeviation();
|
|
140
|
-
const skewness = await numericStream.skewness();
|
|
211
|
+
---
|
|
141
212
|
|
|
142
|
-
|
|
143
|
-
```
|
|
213
|
+
### Características de rendimiento
|
|
144
214
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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) | Sí (orden interno) | Realizar operaciones estadísticas que requieren datos ordenados. |
|
|
220
|
+
| `toBigIntStatistics()` | O(n log n) | O(n) | Sí (orden interno) | Operaciones estadísticas en datos BigInt. |
|
|
221
|
+
| `toWindow()` | O(n log n) | O(n) | Sí (orden interno) | Operaciones de ventana que se benefician de índices ordenados. |
|
|
202
222
|
|
|
203
|
-
|
|
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
|
-
|
|
265
|
+
**Construye con claridad, avanza con confianza y transforma datos con intención.**
|
|
207
266
|
|
|
208
|
-
|
|
267
|
+
MIT © Eloy Kim
|