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.ru.md
CHANGED
|
@@ -1,205 +1,267 @@
|
|
|
1
|
-
# Semantic
|
|
1
|
+
# **Semantic‑TypeScript**
|
|
2
|
+
**Потоки, индексированные.** Ваши данные под точным контролем.
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
Semantic-TypeScript представляет собой значительный прогресс в технологии потоковой обработки, синтезируя наиболее эффективные концепции из JavaScript GeneratorFunctions, Java Streams и парадигм индексации баз данных. Его фундаментальный принцип проектирования сосредоточен на построении исключительно эффективных конвейеров обработки данных с помощью сложных вычислений с отложенным выполнением (lazy evaluation) и интеллектуальной индексации. Библиотека предоставляет строго типобезопасный, функционально чистый опыт работы с потоками, специально созданный для современной разработки на TypeScript и JavaScript.
|
|
4
|
+
---
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
* Потоки данных в реальном времени (события DOM, WebSockets, интервалы) с детерминированным управлением
|
|
8
|
-
* Большие наборы данных с помощью эффективных по памяти, "ленивых" (lazy) конвейеров
|
|
9
|
-
* Сложные преобразования данных с помощью беглого, декларативного API
|
|
6
|
+
### Обзор
|
|
10
7
|
|
|
11
|
-
|
|
8
|
+
Semantic‑TypeScript представляет значительный шаг вперёд в обработке потоков, элегантно **синтезируя** наиболее эффективные парадигмы из генераторов JavaScript, потоков Java и индексации в стиле MySQL. Его фундаментальная предпосылка одновременно мощна и продумана: создавать исключительно эффективные конвейеры обработки данных с помощью интеллектуальной индексации, а не посредством обычного полного перебора.
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
Ключевая архитектурная идея Semantic-TypeScript — это четкое разделение между определением потока и его выполнением:
|
|
15
|
-
* **Semantic<E>**: неизменяемый, "ленивый" (lazy) план конвейера преобразования данных. Он определяет, какие операции (filter, map и т.д.) будут выполнены.
|
|
16
|
-
* **Collectable<E>**: материализованное, исполняемое представление потока. Получается из Semantic и предоставляет все терминальные операции (collect, forEach и т.д.) для выполнения конвейера и получения результата.
|
|
10
|
+
В то время как типичные библиотеки навязывают синхронные циклы или громоздкие цепочки обещаний (Promise), Semantic‑TypeScript предоставляет **полностью асинхронный**, функционально чистый и строго типобезопасный опыт, разработанный специально для требований современной разработки приложений.
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
Эта модель воплощает утончённую форму управления потоком данных: данные передаются потребителю ниже по течению только тогда, когда вышестоящий конвейер явно вызывает обратный вызов `accept`. Вы сохраняете полный, детальный контроль над моментом обработки — она происходит именно тогда и только тогда, когда это необходимо.
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
Выбор подходящей библиотеки для обработки потоков данных предполагает баланс между производительностью, типобезопасностью и выразительностью. Semantic-TypeScript создан для превосходства по всем этим параметрам.
|
|
14
|
+
---
|
|
22
15
|
|
|
23
|
-
###
|
|
24
|
-
Он предоставляет единый, декларативный API для обработки любой последовательности данных — будь то статические массивы, события в реальном времени или асинхронные фрагменты (chunks) — при этом используя всю мощь TypeScript для обеспечения сквозной типобезопасности. Это устраняет целый класс ошибок времени выполнения и превращает манипуляции с потоками в предсказуемую, проверяемую компилятором деятельность.
|
|
16
|
+
### Почему разработчики выбирают Semantic‑TypeScript
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
- **Индексация без шаблонного кода** – Каждый элемент по своей природе обладает своим естественным или кастомным индексом, что устраняет необходимость ручного отслеживания.
|
|
19
|
+
- **Чисто функциональный и типобезопасный** – Наслаждайтесь полным, идиоматическим выводом типов TypeScript вместе с неизменяемыми операциями.
|
|
20
|
+
- **Потоки событий без утечек** – Паттерн `useSubscription` разработан с безопасностью ресурсов в качестве первого принципа. Вы определяете логическую границу — используя `limit(n)`, `sub(start, end)` или `takeWhile(predicate)` — а библиотека полностью управляет жизненным циклом подписки. Это гарантирует отсутствие зависших слушателей и утечек памяти.
|
|
21
|
+
- **Встроенный статистический набор** – Получайте доступ к комплексному анализу для потоков как `number`, так и `bigint`, включая средние значения, медианы, моду, дисперсию, асимметрию (скошенность) и эксцесс, без внешних зависимостей.
|
|
22
|
+
- **Предсказуемая, настраиваемая производительность** – Выбирайте между упорядоченными или неупорядоченными сборщиками в соответствии с вашими точными требованиями к производительности и порядку.
|
|
23
|
+
- **Внутренне эффективно по памяти** – Потоки вычисляются лениво, обрабатывая элементы по требованию, чтобы снизить нагрузку на память.
|
|
24
|
+
- **Никакого неопределённого поведения** – TypeScript гарантирует полную типобезопасность и null-безопасность. Ваши исходные данные остаются неизменными, если не модифицированы явно в ваших функциях обратного вызова.
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
Вдохновленный Java, паттерн Collector — это двигатель гибкости. Он отделяет спецификацию того, как накапливать элементы потока, от самого выполнения потока. Библиотека предоставляет богатый набор встроенных коллекторов (collectors) (toArray, groupBy, summate и т.д.) для повседневных задач, позволяя при этом с легкостью реализовывать собственную сложную, повторно используемую логику свёртки (reduction). Это намного мощнее и композируемее, чем фиксированный набор терминальных методов.
|
|
26
|
+
---
|
|
31
27
|
|
|
32
|
-
###
|
|
33
|
-
Semantic-TypeScript создан для современной разработки. Он предлагает нативные фабричные методы для современных веб-источников:
|
|
34
|
-
* `useFrom(iterable)`, `useRange()` для статических данных
|
|
35
|
-
* `useInterval()`, `useAnimationFrame()` для потоков, основанных на времени
|
|
36
|
-
* `useBlob()` для обработки бинарных данных фрагментами (chunked)
|
|
37
|
-
* `useWebSocket()`, `useDocument()`, `useWindow()` для потоков событий в реальном времени
|
|
28
|
+
### Установка
|
|
38
29
|
|
|
39
|
-
|
|
40
|
-
Выходите за рамки простых сумм и средних значений. Библиотека предоставляет специальные интерфейсы NumericStatistics и BigIntStatistics, предлагая немедленный доступ к расширенным статистическим показателям напрямую из ваших потоков — дисперсия, стандартное отклонение, медиана, асимметрия (skewness) и эксцесс (kurtosis). Это превращает сложный анализ данных в однострочник.
|
|
30
|
+
Интегрируйте Semantic‑TypeScript в ваш проект с помощью предпочитаемого менеджера пакетов:
|
|
41
31
|
|
|
42
|
-
### 6. Спроектирован с учетом эргономики разработчика
|
|
43
|
-
* **Беглый, цепочечный (chainable) API**: Пишите сложные конвейеры данных в виде читаемых, последовательных цепочек.
|
|
44
|
-
* **Комплексный набор утилит**: Включены основные защиты (isFunction, isIterable), утилиты (useCompare, useTraverse) и функциональные интерфейсы.
|
|
45
|
-
* **Интеграция с Optional<T>**: Безопасно моделирует отсутствие значения, устраняя проблемы с нулевыми указателями (null-pointer).
|
|
46
|
-
* **Рекомендации по производительности**: Четкие указания, когда использовать неупорядоченную (unordered) коллекцию для скорости, а когда упорядоченную (ordered) для последовательности.
|
|
47
|
-
|
|
48
|
-
## Установка
|
|
49
32
|
```bash
|
|
50
33
|
npm install semantic-typescript
|
|
51
34
|
```
|
|
35
|
+
или
|
|
36
|
+
```bash
|
|
37
|
+
yarn add semantic-typescript
|
|
38
|
+
```
|
|
52
39
|
|
|
53
|
-
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### Практическое введение
|
|
43
|
+
|
|
44
|
+
Следующие примеры демонстрируют ключевые концепции, от базовых преобразований до обработки событий в реальных условиях.
|
|
54
45
|
|
|
55
|
-
### 1. Создание потоков (Semantic)
|
|
56
|
-
Потоки можно создавать из различных источников с помощью фабричных функций.
|
|
57
46
|
```typescript
|
|
58
|
-
import { useFrom,
|
|
47
|
+
import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
|
|
48
|
+
|
|
49
|
+
// ====================================================================
|
|
50
|
+
// ПРИМЕР 1: Базовые операции и числовая статистика
|
|
51
|
+
// ====================================================================
|
|
52
|
+
// Демонстрирует операции отображения (map) и терминальные статистические операции. После преобразования конвейер должен быть преобразован в сборщик статистики, прежде чем можно будет вызывать терминальные методы, такие как `.summate()`.
|
|
53
|
+
|
|
54
|
+
const numericSum: number = useOf(10, 20, 30, 40)
|
|
55
|
+
.map((n: number): number => n * 2) // Удваивает каждый элемент: [20, 40, 60, 80]
|
|
56
|
+
.toNumericStatistics() // Преобразует в сборщик статистики
|
|
57
|
+
.summate(); // Терминальная операция: 200
|
|
58
|
+
|
|
59
|
+
// Другие статистические методы (доступны после `.toNumericStatistics()`):
|
|
60
|
+
// .average(), .median(), .mode(), .variance(), .skewness(), .kurtosis()
|
|
61
|
+
|
|
62
|
+
// ====================================================================
|
|
63
|
+
// ПРИМЕР 2: Статистика BigInt
|
|
64
|
+
// ====================================================================
|
|
65
|
+
// Работает идентично числовой статистике, но оптимизирован для данных BigInt.
|
|
66
|
+
|
|
67
|
+
const bigintSum: bigint = useOf(10n, 20n, 30n, 40n)
|
|
68
|
+
.map((n: bigint): bigint => n * 2n) // Арифметика BigInt
|
|
69
|
+
.toBigIntStatistics() // Преобразует в сборщик статистики BigInt
|
|
70
|
+
.summate(); // Терминальная операция: 200n
|
|
71
|
+
|
|
72
|
+
// ====================================================================
|
|
73
|
+
// ПРИМЕР 3: Манипуляции с индексами для обращения потока
|
|
74
|
+
// ====================================================================
|
|
75
|
+
// Иллюстрирует переупорядочивание элементов путём стратегического перераспределения их индексов с помощью метода `.redirect()`, позволяя создавать пользовательские шаблоны, такие как обращение.
|
|
76
|
+
|
|
77
|
+
const reversedArray: number[] = useFrom([1, 2, 3, 4, 5])
|
|
78
|
+
.redirect((_element: number, index: bigint): bigint => -index) // Отображает на отрицательные индексы
|
|
79
|
+
.toOrdered() // Важно: собирает элементы, отсортированные по их новым индексам
|
|
80
|
+
.toArray(); // Результат: [5, 4, 3, 2, 1]
|
|
81
|
+
|
|
82
|
+
// Для простого обращения также доступен `.reverse()`.
|
|
83
|
+
|
|
84
|
+
// ====================================================================
|
|
85
|
+
// ПРИМЕР 4: Перемешивание (Shuffle) потока
|
|
86
|
+
// ====================================================================
|
|
87
|
+
// Случайным образом переставляет индексы элементов, используя алгоритм перемешивания на месте (in‑place).
|
|
88
|
+
|
|
89
|
+
const shuffledArray: number[] = useFrom([1, 2, 3, 4, 5])
|
|
90
|
+
.shuffle() // Случайно перераспределяет индексы
|
|
91
|
+
.toOrdered() // Сортирует по новым случайным индексам
|
|
92
|
+
.toArray(); // Например: [2, 5, 1, 4, 3] (варьируется при каждом выполнении)
|
|
93
|
+
|
|
94
|
+
// ====================================================================
|
|
95
|
+
// ПРИМЕР 5: Циклический сдвиг потока
|
|
96
|
+
// ====================================================================
|
|
97
|
+
// Циклически сдвигает элементы. Положительные значения вращают вправо; отрицательные — влево.
|
|
98
|
+
|
|
99
|
+
// Вращение вправо на 2 позиции
|
|
100
|
+
const rightRotated: number[] = useFrom([1, 2, 3, 4, 5])
|
|
101
|
+
.translate(2) // Сдвигает индексы на 2 вправо
|
|
102
|
+
.toOrdered()
|
|
103
|
+
.toArray(); // Результат: [4, 5, 1, 2, 3]
|
|
104
|
+
|
|
105
|
+
// ====================================================================
|
|
106
|
+
// ПРИМЕР 6: Ленивое вычисление с бесконечными диапазонами
|
|
107
|
+
// ====================================================================
|
|
108
|
+
// Обрабатывает теоретически бесконечные потоки лениво, вычисляя элементы только тогда, когда они нужны.
|
|
109
|
+
|
|
110
|
+
const firstTenMultiples: bigint[] = useRange(0n, 1_000_000n)
|
|
111
|
+
.filter(n => n % 17n === 0n) // Сохраняет кратные 17
|
|
112
|
+
.limit(10n) // Критично: останавливается после 10-го совпадения
|
|
113
|
+
.toUnordered() // Сортировка не требуется
|
|
114
|
+
.toArray(); // Результат: [0, 17, 34, 51, 68, 85, 102, 119, 136, 153]
|
|
115
|
+
|
|
116
|
+
// Без `.limit(10n)` конвейер обработал бы все миллион элементов.
|
|
117
|
+
|
|
118
|
+
// ====================================================================
|
|
119
|
+
// ПРИМЕР 7: Компоновка сложного конвейера
|
|
120
|
+
// ====================================================================
|
|
121
|
+
// Демонстрирует последовательную композицию нескольких операций.
|
|
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
|
+
// ПРИМЕР 8: Управляемая подписка на события DOM
|
|
134
|
+
// ====================================================================
|
|
135
|
+
// Прослушивает события браузера с автоматической очисткой, защищённой от утечек.
|
|
136
|
+
// Вызов `.limit(n)` определяет границу для автоматического удаления слушателя.
|
|
137
|
+
|
|
138
|
+
// Определяем подписчика для цели Window
|
|
139
|
+
const windowSubscriber = {
|
|
140
|
+
mount: (target: Window): void => { /* Логика настройки */ },
|
|
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 => { /* Логика очистки */ }
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
useSubscription(window, windowSubscriber, "resize")
|
|
151
|
+
.limit(5n) // Автоматически отписывается после 5 событий
|
|
152
|
+
.toUnordered()
|
|
153
|
+
.forEach((ev: Event, idx) =>
|
|
154
|
+
console.log(`Изменение размера #${idx}: ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
|
|
155
|
+
);
|
|
62
156
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
});
|
|
157
|
+
// ====================================================================
|
|
158
|
+
// ПРИМЕР 9: Обработка строк по кодпоинтам Unicode
|
|
159
|
+
// ====================================================================
|
|
160
|
+
// Корректно перебирает строку, обрабатывая многобайтовые символы Unicode.
|
|
68
161
|
|
|
69
|
-
|
|
70
|
-
|
|
162
|
+
useText("My emotion now is: 😊, and semantic is 👍")
|
|
163
|
+
.toUnordered()
|
|
164
|
+
.log(); // Выводит каждый символ (включая эмодзи) с новой строки.
|
|
71
165
|
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
166
|
+
// ====================================================================
|
|
167
|
+
// ПРИМЕР 10: Безопасное строковое представление объектов с циклическими ссылками
|
|
168
|
+
// ====================================================================
|
|
169
|
+
// Безопасно сериализует объекты, содержащие циклические ссылки.
|
|
75
170
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.map(x => x * 10) // Умножаем на 10
|
|
82
|
-
.flatMap(x => [x, x + 1]) // Преобразуем каждый элемент в два
|
|
83
|
-
.distinct(); // Удаляем дубликаты
|
|
84
|
-
// Пока ничего не было выполнено
|
|
85
|
-
```
|
|
171
|
+
const obj = {
|
|
172
|
+
a: 1,
|
|
173
|
+
b: "текст"
|
|
174
|
+
};
|
|
175
|
+
(obj as any).c = [obj.a, obj.b, (obj as any).c]; // Вводит циклическую ссылку
|
|
86
176
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
// Получаем неупорядоченный collectable для производительности
|
|
91
|
-
const resultArray = await processedStream.toUnordered().toArray();
|
|
92
|
-
console.log(resultArray); // например, [20, 21, 40, 41]
|
|
93
|
-
|
|
94
|
-
// Используем встроенный коллектор
|
|
95
|
-
const sum = await processedStream.toUnordered().collect(useSummate());
|
|
96
|
-
console.log(sum);
|
|
97
|
-
|
|
98
|
-
// Или используем общий метод collect
|
|
99
|
-
const customResult = await processedStream.toOrdered().collect(
|
|
100
|
-
() => new Map<number, number>(),
|
|
101
|
-
(map, element, index) => map.set(index, element),
|
|
102
|
-
map => map
|
|
103
|
-
);
|
|
177
|
+
// const text: string = JSON.stringify(obj); // Выбрасывает ошибку
|
|
178
|
+
const text: string = useStringify(obj); // Безопасно выдаёт `{a: 1, b: "текст", c: []}`
|
|
104
179
|
```
|
|
105
180
|
|
|
106
|
-
|
|
107
|
-
Потоки событий (useDocument, useWindow, useHTMLElement, useWebSocket) по своей природе бесконечны. Вы должны использовать операции, такие как sub, takeWhile или limit, чтобы определить, когда прекратить сбор событий и завершить поток. В противном случае терминальная операция будет ждать неопределенно долго.
|
|
108
|
-
```typescript
|
|
109
|
-
import { useDocument } from 'semantic-typescript';
|
|
181
|
+
---
|
|
110
182
|
|
|
111
|
-
|
|
112
|
-
const first5Clicks = await useDocument('click')
|
|
113
|
-
.limit(5) // <- Важно: ограничивает поток 5 событиями
|
|
114
|
-
.toUnordered()
|
|
115
|
-
.toArray();
|
|
183
|
+
### Ключевые концепции
|
|
116
184
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
185
|
+
| Концепция | Цель | Основной вариант использования |
|
|
186
|
+
| :--- | :--- | :--- |
|
|
187
|
+
| `AsynchronousSemantic` | Основной построитель для асинхронных потоков, событий и ленивых конвейеров, основанных на проталкивании (push). | События в реальном времени, WebSockets, слушатели DOM или любые длительные/бесконечные потоки. |
|
|
188
|
+
| `SynchronousSemantic` | Построитель для синхронных, находящихся в памяти или основанных на вытягивании (pull) немедленных (eager) потоков. | Статические данные, конечные диапазоны или задачи немедленной итерации. |
|
|
189
|
+
| `toUnordered()` | Самый быстрый терминальный сборщик, использует Map для хранения индексов. | Критичные к производительности пути, где стабильный порядок не требуется (время и пространство O(n)). |
|
|
190
|
+
| `toOrdered()` | Упорядоченный, стабильный по индексам терминальный сборщик. | Когда порядок элементов должен быть сохранён или требуется доступ по индексу. |
|
|
191
|
+
| `toNumericStatistics()` | Сборщик, позволяющий проводить расширенный статистический анализ потоков типа `number`. | Анализ данных, метрики и статистические вычисления. |
|
|
192
|
+
| `toBigIntStatistics()` | Сборщик, позволяющий проводить расширенный статистический анализ потоков типа `bigint`. | Анализ и статистика для наборов данных с большими целыми числами. |
|
|
193
|
+
| `toWindow()` | Предоставляет операции скользящего (sliding) и фиксированного (tumbling) окна над потоком. | Анализ временных рядов, пакетная обработка и оконные агрегации. |
|
|
122
194
|
|
|
123
|
-
|
|
124
|
-
const specificClicks = await useDocument('click')
|
|
125
|
-
.sub(2n, 6n) // <- Берет элементы с индексами 2, 3, 4, 5
|
|
126
|
-
.toUnordered()
|
|
127
|
-
.toArray();
|
|
128
|
-
```
|
|
129
|
-
**Ключевое понимание**: Событие (например, MouseEvent) и его порядковый индекс срабатывания (в виде bigint) передаются вместе через конвейер с помощью обратного вызова `accept(event, index)`.
|
|
195
|
+
---
|
|
130
196
|
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
|
|
197
|
+
**Основные правила использования**
|
|
134
198
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const standardDeviation = await numericStream.standardDeviation();
|
|
138
|
-
const skewness = await numericStream.skewness();
|
|
199
|
+
1. **Потоки событий** (созданные через фабрики, такие как `useSubscription`) возвращают `AsynchronousSemantic`.
|
|
200
|
+
→ Вы **должны** вызвать метод, определяющий границу, такой как `.limit(n)`, `.sub(start, end)` или `.takeWhile(predicate)`, чтобы завершить прослушивание. В противном случае подписка останется активной.
|
|
139
201
|
|
|
140
|
-
|
|
141
|
-
```
|
|
202
|
+
2. **Терминальные операции** (`.toArray()`, `.count()`, `.forEach()`, `.findFirst()` и т.д.) доступны **только после** преобразования конвейера в сборщик:
|
|
203
|
+
```typescript
|
|
204
|
+
.toUnordered() // Для максимальной скорости, порядок не гарантируется.
|
|
205
|
+
// или
|
|
206
|
+
.toOrdered() // Для стабильного, отсортированного вывода.
|
|
207
|
+
// или
|
|
208
|
+
.toNumericStatistics() // Для статистических методов.
|
|
209
|
+
```
|
|
142
210
|
|
|
143
|
-
|
|
144
|
-
* **Двойные типы потоков**: Полная поддержка как SynchronousSemantic (для Iterable), так и AsynchronousSemantic (для AsyncIterable и событий)
|
|
145
|
-
* **Богатый набор операций**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
|
|
146
|
-
* **Гибкие терминальные операции**: collect (с пользовательскими коллекторами), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
|
|
147
|
-
* **Продвинутые коллекторы**: Встроенные коллекторы для joining, groupingBy, partitioningBy, summing, averaging, maxBy, minBy
|
|
148
|
-
* **Статистический модуль**: Готовые к использованию методы для mean, median, mode, variance, standardDeviation, range, quantiles, skewness, kurtosis для числовых/bigint потоков
|
|
149
|
-
* **Вспомогательные функции**: Защитники типов (type guards) (isPromise, isAsyncIterable), компараторы (useCompare), обход (useTraverse) и хуки преобразования
|
|
150
|
-
* **Optional<T>**: Монадический контейнер для нулабельных значений, интегрированный с операциями поиска (find)
|
|
151
|
-
|
|
152
|
-
## Обзор API
|
|
153
|
-
### Основные классы и интерфейсы
|
|
154
|
-
* `Semantic<E>` / `AsynchronousSemantic<E>`: Абстрактное определение потока
|
|
155
|
-
* `Collectable<E>` / `AsynchronousCollectable<E>`: Исполняемый поток с терминальными операциями
|
|
156
|
-
* `OrderedCollectable<E>` / `UnorderedCollectable<E>`: Материализованные версии, оптимизированные для операций, чувствительных или нечувствительных к порядку
|
|
157
|
-
* `Collector<E, A, R>`: Абстракция для изменяемых (mutable) операций свёртки (reduction)
|
|
158
|
-
|
|
159
|
-
### Фабричные функции (use*)
|
|
160
|
-
* **Из источников**: useFrom, useRange, useFill, useEmpty
|
|
161
|
-
* **Из времени**: useInterval, useAnimationFrame
|
|
162
|
-
* **Из веб-API**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
|
|
163
|
-
* **Коллекторы**: useToArray, useGroupBy, useSummate, useJoin и т.д.
|
|
164
|
-
|
|
165
|
-
## Примечания по производительности
|
|
166
|
-
* **Отложенное выполнение (Lazy Evaluation)**: Конвейеры составляются без выполнения до тех пор, пока не будет вызвана терминальная операция.
|
|
167
|
-
* **Короткое замыкание (Short-Circuiting)**: Операции, такие как limit, anyMatch и findFirst, остановят обработку элементов, как только результат будет определен.
|
|
168
|
-
* **Упорядоченное (Ordered) vs Неупорядоченное (Unordered)**:
|
|
169
|
-
* Используйте `.toUnordered()` для терминальных операций, когда порядок исходных элементов не имеет значения для вашего результата (например, для sum, max или toSet). Это может позволить внутренние оптимизации, пропускающие затратные шаги сортировки.
|
|
170
|
-
* Используйте `.toOrdered()`, когда важна последовательность (например, для toArray, где порядок должен быть сохранен).
|
|
171
|
-
|
|
172
|
-
## Пример для начала работы
|
|
173
|
-
```typescript
|
|
174
|
-
import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
|
|
175
|
-
|
|
176
|
-
interface Transaction {
|
|
177
|
-
id: number;
|
|
178
|
-
amount: number;
|
|
179
|
-
category: string;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const transactions: Transaction[] = [
|
|
183
|
-
{ id: 1, amount: 100, category: 'Food' },
|
|
184
|
-
{ id: 2, amount: 200, category: 'Electronics' },
|
|
185
|
-
{ id: 3, amount: 50, category: 'Food' },
|
|
186
|
-
{ id: 4, amount: 300, category: 'Electronics' },
|
|
187
|
-
];
|
|
188
|
-
|
|
189
|
-
// Вычисляем общую сумму по категориям
|
|
190
|
-
const totalsByCategory = await useFrom(transactions)
|
|
191
|
-
.toUnordered()
|
|
192
|
-
.collect(
|
|
193
|
-
useGroupBy(
|
|
194
|
-
t => t.category,
|
|
195
|
-
t => t.amount,
|
|
196
|
-
useSummate() // Коллектор для значений
|
|
197
|
-
)
|
|
198
|
-
);
|
|
211
|
+
---
|
|
199
212
|
|
|
200
|
-
|
|
201
|
-
|
|
213
|
+
### Характеристики производительности
|
|
214
|
+
|
|
215
|
+
| Сборщик | Временная сложность | Пространственная сложность | Порядок гарантирован? | Идеальный сценарий |
|
|
216
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
217
|
+
| `toUnordered()` | O(n) | O(n) | Нет | Важна необработанная пропускная способность; конечный порядок не важен. |
|
|
218
|
+
| `toOrdered()` | O(n log n) | O(n) | Да (отсортирован) | Стабильный порядок, доступ по индексу или предварительная сортировка для статистики. |
|
|
219
|
+
| `toNumericStatistics()` | O(n log n) | O(n) | Да (внутренняя сортировка) | Выполнение статистических операций, требующих отсортированных данных. |
|
|
220
|
+
| `toBigIntStatistics()` | O(n log n) | O(n) | Да (внутренняя сортировка) | Статистические операции над данными BigInt. |
|
|
221
|
+
| `toWindow()` | O(n log n) | O(n) | Да (внутренняя сортировка) | Оконные операции, выигрывающие от отсортированных индексов. |
|
|
222
|
+
|
|
223
|
+
Выбирайте `toUnordered()`, когда абсолютная скорость первостепенна. Выбирайте `toOrdered()` или статистический сборщик только в том случае, если ваша логика зависит от порядка элементов.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
**Сравнительный анализ с современными потоковыми библиотеками**
|
|
228
|
+
|
|
229
|
+
| Особенность | Semantic‑TypeScript | RxJS | Нативные Async Iterators / Generators | Most.js |
|
|
230
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
231
|
+
| **Интеграция с TypeScript** | Первоклассная, с глубокой типизацией и внутренней осведомлённостью об индексах. | Отличная, но часто связана со сложными цепочками обобщений (generics). | Хорошая, но требуются ручные аннотации типов. | Сильная, с функционально-ориентированным стилем типизации. |
|
|
232
|
+
| **Встроенный статистический анализ** | Полная встроенная поддержка для `number` и `bigint`. | Недоступна нативно (требует пользовательских операторов или других библиотек). | Отсутствует. | Отсутствует. |
|
|
233
|
+
| **Индексация и осведомлённость о позиции** | Встроенная, мощная индексация BigInt для каждого элемента. | Требует пользовательских операторов (напр., `scan`, `withLatestFrom`). | Требуется ручное управление счётчиком. | Базовая, без встроенного свойства индекса. |
|
|
234
|
+
| **Управление потоками событий** | Специализированные, типобезопасные фабрики с явным, декларативным управлением жизненным циклом. | Мощное, но требует тщательного ручного управления подписками для предотвращения утечек. | Ручное присоединение слушателей событий и управление токенами отмены. | Хороший `fromEvent`, как правило, лёгкий. |
|
|
235
|
+
| **Производительность и память** | Исключительная – предлагает оптимизированные сборщики `toUnordered()` и `toOrdered()`. | Очень хорошая, хотя глубокие цепочки операторов могут вносить накладные расходы. | Отличная (минимальные нативные накладные расходы). | Отличная. |
|
|
236
|
+
| **Размер сборки (bundle)** | Очень лёгкий. | Существенный (даже с tree-shaking). | Нулевой (нативная функция языка). | Малый. |
|
|
237
|
+
| **Философия дизайна API** | Функциональный паттерн сборщика с явной семантикой индексов. | Реактивный паттерн Observable. | Императивный Iterator / декларативный Generator паттерн. | Функциональный, бесточечная (point‑free) композиция. |
|
|
238
|
+
| **Управление потоком** | Явное (`interrupt`, `.limit()`, `.takeWhile()`, `.sub()`). | Хорошее (`take`, `takeUntil`, `first`). | Ручное (`break` в циклах). | Хорошее (`take`, `until`). |
|
|
239
|
+
| **Поддержка синхронных и асинхронных операций** | Унифицированный API – первоклассная поддержка обеих парадигм. | В основном асинхронный. | Оба поддерживаются, но требуется ручной мост. | В основном асинхронный. |
|
|
240
|
+
| **Кривая обучения** | Пологая для разработчиков, знакомых с функциональными и индексированными конвейерами коллекций. | Крутая (обширный словарь операторов, концепции горячих/холодных Observable). | Низкая до средней. | Средняя. |
|
|
241
|
+
|
|
242
|
+
**Преимущество Semantic‑TypeScript**
|
|
243
|
+
|
|
244
|
+
* **Уникальные возможности:** Встроенные функции статистики и индексации устраняют необходимость ручных операций `reduce` или дополнительных библиотек анализа данных.
|
|
245
|
+
* **Предсказуемое управление ресурсами:** Явный контроль над потоками событий предотвращает утечки памяти, которые могут быть незаметны в приложениях RxJS.
|
|
246
|
+
* **Унифицированный дизайн:** Единообразный API как для синхронных, так и для асинхронных рабочих процессов снижает когнитивную нагрузку и дублирование кода.
|
|
247
|
+
|
|
248
|
+
Это сравнение подчёркивает, почему Semantic‑TypeScript особенно хорошо подходит для современных TypeScript-приложений, требующих высокой производительности, надёжной типобезопасности и богатых возможностей обработки данных без сложности традиционных реактивных фреймворков.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### Начните исследование
|
|
253
|
+
|
|
254
|
+
Semantic‑TypeScript преобразует сложные потоки данных в читаемые, композируемые и высокопроизводительные конвейеры. Обрабатываете ли вы события пользовательского интерфейса в реальном времени, обрабатываете большие наборы данных или создаёте аналитические панели мониторинга – он предлагает мощь индексации уровня базы данных с элегантностью функционального программирования.
|
|
255
|
+
|
|
256
|
+
**Ваши следующие шаги:**
|
|
257
|
+
|
|
258
|
+
* Изучите полностью типизированный API прямо в вашей IDE (все экспорты доступны из основной точки входа пакета).
|
|
259
|
+
* Присоединяйтесь к растущему сообществу разработчиков, которые заменили сложные асинхронные итераторы и реактивные цепочки на ясные, целенаправленные конвейеры Semantic.
|
|
260
|
+
|
|
261
|
+
**Semantic‑TypeScript** – где потоки встречаются со структурой.
|
|
262
|
+
|
|
263
|
+
Начните строить сегодня и ощутите ощутимую разницу, которую приносит продуманное проектирование индексации.
|
|
202
264
|
|
|
203
|
-
|
|
265
|
+
**Стройте с ясностью, действуйте с уверенностью и преобразуйте данные с намерением.**
|
|
204
266
|
|
|
205
|
-
|
|
267
|
+
MIT © Eloy Kim
|