semantic-typescript 0.7.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/guard.d.ts CHANGED
@@ -37,6 +37,3 @@ export declare let isPromise: (target: unknown) => target is Promise<unknown>;
37
37
  export declare let isAsyncFunction: (target: unknown) => target is AsyncFunction;
38
38
  export declare let isGeneratorFunction: (target: unknown) => target is Generator<unknown, unknown, unknown>;
39
39
  export declare let isAsyncGeneratorFunction: (target: unknown) => target is AsyncGenerator<unknown, unknown, unknown>;
40
- export declare let isWindow: (target: unknown) => target is Window;
41
- export declare let isDocument: (target: unknown) => target is Document;
42
- export declare let isHTMLElemet: (target: unknown) => target is HTMLElement;
package/dist/guard.js CHANGED
@@ -173,22 +173,3 @@ export let isAsyncGeneratorFunction = (target) => {
173
173
  }
174
174
  return false;
175
175
  };
176
- export let isWindow = (target) => {
177
- if (isObject(target) && isObject(Reflect.get(target, "window"))) {
178
- return Object.prototype.toString.call(Reflect.get(target, "window")) === "[object Window]";
179
- }
180
- return false;
181
- };
182
- export let isDocument = (target) => {
183
- if (isObject(target) && isObject(Reflect.get(target, "document"))) {
184
- return Object.prototype.toString.call(Reflect.get(target, "document")) === "[object HTMLDocument]";
185
- }
186
- return false;
187
- };
188
- export let isHTMLElemet = (target) => {
189
- if (isObject(target)) {
190
- let regex = /^\[object HTML\w+Element\]$/;
191
- return regex.test(Object.prototype.toString.call(target));
192
- }
193
- return false;
194
- };
package/dist/hash.js CHANGED
@@ -70,6 +70,9 @@ register("number", (value) => {
70
70
  if (primitive.has(value)) {
71
71
  return primitive.get(value) || 0n;
72
72
  }
73
+ if (Number.isNaN(value)) {
74
+ return 0x7ff8000000000000n;
75
+ }
73
76
  let mask = maskOf("number");
74
77
  let bit = 0xffffffffffffffffn;
75
78
  let buffer = new ArrayBuffer(8);
@@ -25,6 +25,8 @@ export declare class SynchronousSemantic<E> {
25
25
  flatMap<R>(mapper: BiFunctional<E, bigint, SynchronousSemantic<R>>): SynchronousSemantic<R>;
26
26
  limit(count: number): SynchronousSemantic<E>;
27
27
  limit(count: bigint): SynchronousSemantic<E>;
28
+ map(mapper: Functional<E, E>): SynchronousSemantic<E>;
29
+ map(mapper: BiFunctional<E, bigint, E>): SynchronousSemantic<E>;
28
30
  map<R>(mapper: Functional<E, R>): SynchronousSemantic<R>;
29
31
  map<R>(mapper: BiFunctional<E, bigint, R>): SynchronousSemantic<R>;
30
32
  peek(consumer: Consumer<E>): SynchronousSemantic<E>;
@@ -106,6 +108,8 @@ export declare abstract class SynchronousCollectable<E> implements Iterable<E> {
106
108
  partition(count: bigint): Array<Array<E>>;
107
109
  partitionBy(classifier: Functional<E, bigint>): Array<Array<E>>;
108
110
  partitionBy(classifier: BiFunctional<E, bigint, bigint>): Array<Array<E>>;
111
+ pipe(conversion: Functional<SynchronousGenerator<E>, SynchronousSemantic<E>>): SynchronousSemantic<E>;
112
+ pipe<R>(conversion: Functional<SynchronousGenerator<E>, SynchronousSemantic<R>>): SynchronousSemantic<R>;
109
113
  reduce(accumulator: BiFunctional<E, E, E>): E;
110
114
  reduce(accumulator: TriFunctional<E, E, bigint, E>): E;
111
115
  reduce(identity: E, accumulator: BiFunctional<E, E, E>): E;
@@ -389,7 +389,7 @@ export class SynchronousSemantic {
389
389
  try {
390
390
  let stop = false;
391
391
  this.generator((element, index) => {
392
- if (predicate(element, index) && stop === false) {
392
+ if (predicate(element, index) && !stop) {
393
393
  accept(element, index);
394
394
  }
395
395
  else {
@@ -801,6 +801,9 @@ export class SynchronousCollectable {
801
801
  }
802
802
  throw new TypeError("Classifier must be a function.");
803
803
  }
804
+ pipe(conversion) {
805
+ return conversion(this.source());
806
+ }
804
807
  reduce(argument1, argument2, argument3) {
805
808
  if (isFunction(argument1) && invalidate(argument2) && invalidate(argument3)) {
806
809
  try {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/eloyhere"
7
7
  },
8
8
  "description": "A modern type-safe stream processing library inspired by JavaScript Generator, Java Stream, and MySQL Index. Supports lazy evaluation, async streams, statistics, and IO-like operations.",
9
- "version": "0.7.0",
9
+ "version": "0.7.1",
10
10
  "type": "module",
11
11
  "readme": "readme.md",
12
12
  "main": "dist/index.js",
package/readme.cn.md CHANGED
@@ -1,32 +1,34 @@
1
- # **Semantic-TypeScript**
2
- **流,索引化。** 您的数据,尽在掌控。
1
+ # **SemanticTypeScript**
2
+ **流处理,索引化。** 让您的数据处于精准控制之下。
3
3
 
4
4
  ---
5
5
 
6
6
  ### 概述
7
7
 
8
- Semantic-TypeScript 是流处理技术的一次重大飞跃,它**集大成**了 JavaScript `GeneratorFunction`、Java Streams 和 MySQL 式索引中最有效的概念。其核心理念既简单又强大:通过智能索引而非暴力迭代,来构建高效的数据处理管道。
8
+ SemanticTypeScript 代表了流处理领域的一次重大演进,它巧妙地**融合**了 JavaScript 生成器、Java Streams 和 MySQL 风格索引中最有效的范式。其核心理念强大而明确:通过智能索引而非传统的蛮力迭代,构建极其高效的数据处理管道。
9
9
 
10
- 当传统库强制使用同步循环或笨拙的 Promise 链时,Semantic-TypeScript 提供了一种**完全异步**、函数式纯粹且类型安全的体验,专为现代前端开发的需求而设计。
10
+ 传统的库通常强制使用同步循环或笨重的 Promise 链,而 SemanticTypeScript 则提供了一个**完全异步**、函数式纯正且类型绝对安全的体验,专为满足现代应用程序开发的需求而设计。
11
11
 
12
- 在其优雅的模型中,数据仅在上游管道显式调用 `accept`(以及可选的 `interrupt`)回调时才会抵达消费者。您完全掌控时机——就在您需要的时候。
12
+ 该模型体现了一种精炼的控制流:数据仅在上游管道显式调用 `accept` 回调时,才会传递给下游消费者。您可以对处理时机保持完全、细粒度的掌控——处理仅在需要时、且仅在要求的时刻发生。
13
13
 
14
14
  ---
15
15
 
16
- ### 开发者为何青睐它
16
+ ### 开发者为何选择 Semantic‑TypeScript
17
17
 
18
- - **零样板索引** 每个元素都携带其自然或自定义索引。
19
- - **函数式纯粹风格** 具备完整的 TypeScript 类型推断。
20
- - **防泄漏事件流** `useWindow`、`useDocument`、`useHTMLElement` `useWebSocket` 在设计时就考虑了安全性。您通过 `limit(n)`、`sub(start, end)` 或 `takeWhile(predicate)` 定义边界,库则负责清理。没有残留的监听器,没有内存泄漏。
21
- - **开箱即用的统计** 全面的数值和 bigint 分析,包括平均值、中位数、众数、方差、偏度和峰度。
22
- - **可预测的性能** 根据需求在有序和无序收集器之间选择。
23
- - **内存高效** 流采用惰性求值,无需担心内存问题。
24
- - **无未定义行为** TypeScript 保证类型安全和可空性。除非在回调函数中显式修改,否则输入数据保持不变。
18
+ - **零模板索引** 每个元素天生拥有其自然或自定义的索引,无需手动跟踪。
19
+ - **纯函数式与类型安全** 在支持不可变操作的同时,享受完整、地道的 TypeScript 类型推断。
20
+ - **无泄漏的事件流** `useSubscription` 模式将资源安全作为首要原则设计。您通过 `limit(n)`、`sub(start, end)` 或 `takeWhile(predicate)` 定义逻辑边界,库则管理完整的订阅生命周期,确保没有残留的监听器和内存泄漏。
21
+ - **内置统计套件** 无需外部依赖,即可访问针对 `number` 和 `bigint` 流的全面分析功能,包括平均值、中位数、众数、方差、偏度和峰度。
22
+ - **可预测、可调优的性能** 根据您对性能和顺序的精确需求,选择有序或无序收集器。
23
+ - **天然的内存高效** 流采用惰性求值,按需处理元素以减轻内存压力。
24
+ - **无未定义行为** TypeScript 保证完整的类型安全性和可空性。除非在回调函数中显式修改,否则您的源数据保持不变。
25
25
 
26
26
  ---
27
27
 
28
28
  ### 安装
29
29
 
30
+ 使用您偏好的包管理器将 Semantic‑TypeScript 集成到项目中:
31
+
30
32
  ```bash
31
33
  npm install semantic-typescript
32
34
  ```
@@ -37,177 +39,229 @@ yarn add semantic-typescript
37
39
 
38
40
  ---
39
41
 
40
- ### 快速开始
42
+ ### 快速入门
43
+
44
+ 以下示例演示了从基础转换到实际事件处理的核心概念。
41
45
 
42
46
  ```typescript
43
- import { useOf, useFrom, useRange, useWindow, useHTMLElement, useWebSocket, useText, useStringify } from "semantic-typescript";
44
-
45
- // 数值统计
46
- let summate: number = useOf(10, 20, 30, 40)
47
- .map((n: number): number => n * 2)
48
- .toNumericStatistics() // 终结操作前必需
49
- .summate(); // 200
50
-
51
- // Bigint 统计
52
- let summate: bigint = useOf(10n, 20n, 30n, 40n)
53
- .map((n: bigint): bigint => n * 2)
54
- .toBigIntStatistics() // 终结操作前必需
55
- .summate(); // 200n
56
-
57
- // 通过索引反转流
58
- useFrom([1, 2, 3, 4, 5])
59
- .redirect((element: E, index: bigint): bigint => -index) // 负索引以实现反转
60
- .toOrdered() // 调用 toOrdered() 以保持索引顺序
61
- .toArray(); // [5, 4, 3, 2, 1]
62
-
63
- // 打乱流
64
- useFrom([1, 2, 3, 4, 5])
65
- .shuffle()
47
+ import { useOf, useFrom, useRange, useSubscription, useText, useStringify } from "semantic-typescript";
48
+
49
+ // ====================================================================
50
+ // 示例 1: 基础操作与数值统计
51
+ // ====================================================================
52
+ // 演示映射和终端统计操作。转换后,管道必须转换为统计收集器才能调用 `.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: 流洗牌
86
+ // ====================================================================
87
+ // 使用原地洗牌算法随机置换元素索引。
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
66
102
  .toOrdered()
67
- .toArray(); // 例如:[2, 5, 1, 4, 3]
103
+ .toArray(); // 结果: [4, 5, 1, 2, 3]
68
104
 
69
- // 在流内平移元素
70
- useFrom([1, 2, 3, 4, 5])
71
- .translate(2) // 将元素向右移动 2 位
72
- .toOrdered()
73
- .toArray(); // [4, 5, 1, 2, 3]
105
+ // ====================================================================
106
+ // 示例 6: 无限范围的惰性求值
107
+ // ====================================================================
108
+ // 惰性地处理理论上的无限流,仅在需要时计算元素。
74
109
 
75
- useFrom([1, 2, 3, 4, 5])
76
- .translate(-2) // 将元素向左移动 2
77
- .toOrdered()
78
- .toArray(); // [3, 4, 5, 1, 2]
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]
79
115
 
80
- // 无限范围与提前终止
81
- useRange(0n, 1_000_000n)
82
- .filter(n => n % 17n === 0n)
83
- .limit(10n) // 10 个元素后停止
84
- .toUnordered()
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()
85
130
  .toArray();
86
131
 
87
- // 实时窗口大小调整(5 次事件后自动停止)
88
- useWindow("resize")
89
- .limit(5n) // 对事件流至关重要
90
- .toUnordered()
91
- .forEach((ev, idx) => console.log(`调整大小 #${idx}`));
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
+ };
92
149
 
93
- // 监听 HTML 元素
94
- // <input id="input" type="text"/>
95
- useHTMLElement("#input", "change")
96
- .limit(1)
150
+ useSubscription(window, windowSubscriber, "resize")
151
+ .limit(5n) // 5 个事件后自动取消订阅
97
152
  .toUnordered()
98
- .forEach((event: Event) => submit(event));
153
+ .forEach((ev: Event, idx) =>
154
+ console.log(`调整大小 #${idx}: ${(ev.target as Window).innerWidth}x${(ev.target as Window).innerHeight}`)
155
+ );
99
156
 
100
- // 监听多个元素和事件
101
- useHTMLElement("input", ["change", "keyup"])
102
- .takeWhile((event: Event): boolean => validate(event))
103
- .toUnordered()
104
- .forEach((event: Event) => submit(event));
105
-
106
- // 监听 WebSocket
107
- let webSocket = new WebSocket("ws://localhost:8080");
108
- webSocket.addEventListener("close", (): void => {
109
- webSocket.close(); // 需手动管理 WebSocket 生命周期
110
- });
111
- useWebSocket(webSocket, "message")
112
- .limit(1)
113
- .toUnordered()
114
- .forEach((message: MessageEvent) => console.log(message.data));
157
+ // ====================================================================
158
+ // 示例 9: 按 Unicode 码点处理字符串
159
+ // ====================================================================
160
+ // 正确遍历字符串,处理多字节 Unicode 字符。
115
161
 
116
- // 按码点迭代字符串
117
162
  useText("My emotion now is: 😊, and semantic is 👍")
118
163
  .toUnordered()
119
- .log(); // 输出字符串
164
+ .log(); // 将每个字符(包括表情符号)在新行打印。
120
165
 
121
- // 安全地字符串化包含循环引用的对象
122
- let o = {
166
+ // ====================================================================
167
+ // 示例 10: 安全的循环引用字符串化
168
+ // ====================================================================
169
+ // 安全地序列化包含循环引用的对象。
170
+
171
+ const obj = {
123
172
  a: 1,
124
- b: "text",
125
- c: [o.a, o.b, o.c] // 循环引用
173
+ b: "text"
126
174
  };
127
- // let text: string = JSON.stringify(o); // 抛出错误
128
- let text: string = useStringify(o); // 安全地生成 `{a: 1, b: "text", c: []}`
175
+ (obj as any).c = [obj.a, obj.b, (obj as any).c]; // 引入循环引用
176
+
177
+ // const text: string = JSON.stringify(obj); // 抛出错误
178
+ const text: string = useStringify(obj); // 安全地产生 `{a: 1, b: "text", c: []}`
129
179
  ```
130
180
 
131
181
  ---
132
182
 
133
183
  ### 核心概念
134
184
 
135
- | 概念 | 目的 | 何时使用 |
185
+ | 概念 | 目的 | 主要使用场景 |
136
186
  | :--- | :--- | :--- |
137
- | `AsynchronousSemantic` | 用于异步流、事件和惰性管道的核心构建器。 | 实时事件、WebSocket、DOM 监听器、长时间运行或无限流。 |
138
- | `SynchronousSemantic` | 用于同步、内存中或基于循环的流的构建器。 | 静态数据、范围、立即迭代。 |
139
- | `toUnordered()` | 最快的终结收集器(基于 Map 的索引)。 | 性能关键路径(O(n) 时间与空间,无排序)。 |
140
- | `toOrdered()` | 有序的、索引稳定的收集器。 | 当需要稳定排序或索引访问时。 |
141
- | `toNumericStatistics()` | 丰富的数值统计分析(均值、中位数、方差、偏度、峰度等)。 | 数据分析和统计计算。 |
142
- | `toBigIntStatistics()` | 丰富的 bigint 统计分析。 | 针对大整数的数据分析和统计计算。 |
143
- | `toWindow()` | 滑动和滚动窗口支持。 | 时间序列处理、批处理和窗口化操作。 |
187
+ | `AsynchronousSemantic` | 用于异步流、事件和基于推送的惰性管道的核心构建器。 | 实时事件、WebSockets、DOM 监听器或任何长时间运行/无限流。 |
188
+ | `SynchronousSemantic` | 用于同步、内存中或基于拉取的急切流的构建器。 | 静态数据、有限范围或需要立即迭代的任务。 |
189
+ | `toUnordered()` | 最快的终端收集器,使用 Map 存储索引。 | 性能关键路径,且不需要稳定顺序的场景(O(n) 时间和空间)。 |
190
+ | `toOrdered()` | 有序、索引稳定的终端收集器。 | 当需要保持元素顺序或需要索引访问时。 |
191
+ | `toNumericStatistics()` | 启用对 `number` 流进行丰富统计分析功能的收集器。 | 数据分析、指标和统计计算。 |
192
+ | `toBigIntStatistics()` | 启用对 `bigint` 流进行丰富统计分析功能的收集器。 | 大型整数数据集的分析和统计。 |
193
+ | `toWindow()` | 提供对流进行滑动和滚动窗口操作的功能。 | 时间序列分析、批处理和窗口聚合。 |
144
194
 
145
195
  ---
146
196
 
147
- **重要使用规则**
197
+ **基本使用规则**
148
198
 
149
- 1. **事件流**(`useWindow`、`useDocument`、`useHTMLElement`、`useWebSocket`……)返回一个 `AsynchronousSemantic`。
150
- 您**必须**调用 `.limit(n)`、`.sub(start, end)` 或 `.takeWhile()` 来停止监听。否则,监听器将保持活动状态。
199
+ 1. **事件流**(通过 `useSubscription` 等工厂函数创建)返回一个 `AsynchronousSemantic`。
200
+ 您**必须**调用一个定义边界的方法,如 `.limit(n)`、`.sub(start, end)` 或 `.takeWhile(predicate)` 来终止监听器。否则订阅将保持活动状态。
151
201
 
152
- 2. **终结操作**(`.toArray()`、`.count()`、`.average()`、`.reduce()`、`.findFirst()` 等)**仅在**转换为收集器**之后**可用:
202
+ 2. **终端操作**(`.toArray()`、`.count()`、`.forEach()`、`.findFirst()` 等)**仅在**将管道转换为收集器**之后**可用:
153
203
  ```typescript
154
- .toUnordered() // O(n) 时间与空间,无排序
204
+ .toUnordered() // 用于最大速度,不保证顺序。
155
205
  // 或
156
- .toOrdered() // 已排序,保持顺序
206
+ .toOrdered() // 用于稳定、有序的输出。
207
+ // 或
208
+ .toNumericStatistics() // 用于统计方法。
157
209
  ```
158
210
 
159
211
  ---
160
212
 
161
213
  ### 性能特征
162
214
 
163
- | 收集器 | 时间复杂度 | 空间复杂度 | 是否排序? | 最佳适用场景 |
215
+ | 收集器 | 时间复杂度 | 空间复杂度 | 保证顺序? | 理想场景 |
164
216
  | :--- | :--- | :--- | :--- | :--- |
165
- | `toUnordered()` | O(n) | O(n) | 否 | 追求原始速度,顺序不重要时。 |
166
- | `toOrdered()` | O(2n) | O(n) | | 需要稳定排序、索引访问或分析时。 |
167
- | `toNumericStatistics()` | O(2n) | O(n) | | 需要排序数据的统计操作。 |
168
- | `toBigIntStatistics()` | O(2n) | O(n) | | 针对 bigint 的统计操作。 |
169
- | `toWindow()` | O(2n) | O(n) | | 基于时间的窗口化操作。 |
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) | 是(内部排序) | 能从排序索引中受益的窗口操作。 |
170
222
 
171
- 当速度至上时,选择 `toUnordered()`。仅当您需要稳定排序或依赖于排序数据的统计方法时,才使用 `toOrdered()`。
223
+ 当绝对速度至关重要时,选择 `toUnordered()`。仅当您的逻辑依赖于元素顺序时,才选择 `toOrdered()` 或统计收集器。
172
224
 
173
225
  ---
174
226
 
175
- **与其他前端流处理器的对比**
227
+ **与现代流处理库的对比分析**
176
228
 
177
- | 特性 | Semantic-TypeScript | RxJS | 原生 Async Iterators / Generators | Most.js |
229
+ | 特性 | SemanticTypeScript | RxJS | 原生 Async Iterators / Generators | Most.js |
178
230
  | :--- | :--- | :--- | :--- | :--- |
179
- | **TypeScript 集成** | 一流的深度类型支持,具备原生索引感知。 | 优秀,但涉及复杂的泛型。 | 良好,需要手动类型标注。 | 强大,函数式优先风格。 |
180
- | **内置统计分析** | 对 `number` 和 `bigint` 的全面原生支持。 | 非原生支持(需要自定义操作符)。 | 无。 | 无。 |
181
- | **索引与位置感知** | 原生、强大的每个元素 bigint 索引。 | 需要自定义操作符(`scan`、`withLatestFrom`)。 | 需要手动计数器。 | 基础,无内置索引。 |
182
- | **事件流管理** | 专用的、类型安全的工厂函数,具备显式的提前停止控制。 | 强大但需要手动管理订阅。 | 手动事件监听器 + 取消。 | 良好的 `fromEvent`,轻量。 |
183
- | **性能与内存效率** | 卓越——优化的 `toUnordered()` 和 `toOrdered()` 收集器。 | 非常好,但操作符链会带来开销。 | 优秀(零开销)。 | 优秀。 |
184
- | **包体积** | 非常轻量。 | 较大(即使进行 Tree Shaking)。 | 零(原生)。 | 小。 |
185
- | **API 设计理念** | 函数式收集器模式,具有显式索引。 | 响应式 Observable 模式。 | 迭代器 / 生成器模式。 | 函数式,无点风格。 |
186
- | **提前终止与控制** | 显式(`interrupt`、`.limit()`、`.takeWhile()`、`.sub()`)。 | 良好(`take`、`takeUntil`、`first`)。 | 手动(在 `for await…of` 中使用 `break`)。 | 良好(`take`、`until`)。 |
187
- | **同步与异步支持** | 统一的 API——对两者都提供一流支持。 | 主要是异步。 | 两者都支持,但需手动处理。 | 主要是异步。 |
188
- | **学习曲线** | 对于熟悉函数式和索引管道的开发者来说很平缓。 | 较陡峭(众多操作符、热/冷 Observable)。 | 低。 | 中等。 |
231
+ | **TypeScript 集成** | 一等公民,深度类型化,具有固有的索引感知。 | 优秀,但通常涉及复杂的泛型链。 | 良好,但需要手动类型注解。 | 强大,采用函数优先的编码风格。 |
232
+ | **内置统计分析** | 对 `number` 和 `bigint` 提供全面的原生支持。 | 非原生支持(需要自定义操作符或其他库)。 | 无。 | 无。 |
233
+ | **索引与位置感知** | 原生、强大的 BigInt 索引,每个元素都具备。 | 需要自定义操作符(如 `scan`、`withLatestFrom`)。 | 需要手动管理计数器。 | 基础,无内置索引属性。 |
234
+ | **事件流管理** | 专用的、类型安全的工厂,具有显式、声明式的生命周期控制。 | 强大,但需要谨慎的手动订阅管理以防止泄漏。 | 手动事件监听器附加和取消令牌管理。 | 良好的 `fromEvent`,通常较轻量。 |
235
+ | **性能与内存** | 卓越 – 提供优化的 `toUnordered()` 和 `toOrdered()` 收集器。 | 非常好,但深度操作符链可能引入开销。 | 优秀(最小的原生开销)。 | 优秀。 |
236
+ | **包体积** | 非常轻量。 | 较大(即使有 tree-shaking)。 | 零(原生语言特性)。 | 小。 |
237
+ | **API 设计理念** | 具有显式索引语义的函数式收集器模式。 | 响应式 Observable 模式。 | 命令式 Iterator / 声明式 Generator 模式。 | 函数式、无点组合。 |
238
+ | **流控制** | 显式(`interrupt`、`.limit()`、`.takeWhile()`、`.sub()`)。 | 良好(`take`、`takeUntil`、`first`)。 | 手动(循环中的 `break`)。 | 良好(`take`、`until`)。 |
239
+ | **同步与异步支持** | 统一的 API – 对两种范式都提供一等公民支持。 | 主要面向异步。 | 两者都支持,但需要手动桥接。 | 主要面向异步。 |
240
+ | **学习曲线** | 对于熟悉函数式和索引集合管道的开发者来说较平缓。 | 较陡峭(大量的操作符词汇、热/冷 Observable 概念)。 | 低到中等。 | 中等。 |
189
241
 
190
- **Semantic-TypeScript 的主要优势**
242
+ **SemanticTypeScript 的优势**
191
243
 
192
- * 独特的内置统计和索引功能,无需手动 `reduce` 或外部库。
193
- * 对事件流的显式控制,防止了 RxJS 中常见的内存泄漏。
194
- * 统一的同步/异步设计,为多样化的用例提供了单一、一致的 API
244
+ * **独特能力:** 集成的统计和索引功能,无需手动 `reduce` 操作或辅助的数据分析库。
245
+ * **可预测的资源管理:** 对事件流的显式控制,防止了 RxJS 应用中可能出现的微妙内存泄漏。
246
+ * **统一设计:** 同步和异步工作流采用一致的 API,减少了认知负担和代码重复。
195
247
 
196
- 此对比说明了为何 Semantic-TypeScript 特别适合那些需要高性能、类型安全和丰富分析功能,而又不希望陷入传统响应式库繁琐仪式感的现代 TypeScript 前端应用。
248
+ 此对比凸显了为何 SemanticTypeScript 特别适合需要高性能、健壮的类型安全性和丰富数据处理功能,而又不希望引入传统响应式框架复杂性的现代 TypeScript 应用程序。
197
249
 
198
250
  ---
199
251
 
200
- ### 准备探索?
252
+ ### 开始探索
253
+
254
+ Semantic‑TypeScript 将复杂的数据流转化为可读、可组合且高性能的管道。无论您是在处理实时 UI 事件、处理大量数据集,还是构建分析仪表板,它都能提供数据库级索引的强大功能与函数式编程的优雅。
201
255
 
202
- Semantic-TypeScript 将复杂的数据流转化为可读、可组合且高性能的管道。无论您是处理实时 UI 事件、处理大型数据集还是构建分析仪表板,它都能提供数据库级索引的强大功能与函数式编程的优雅。
256
+ **您的后续步骤:**
203
257
 
204
- **下一步:**
258
+ * 直接在您的 IDE 中探索完全类型化的 API(所有导出都可在主包入口点找到)。
259
+ * 加入不断壮大的开发者社区,他们已用清晰、有意的 Semantic 管道替代了复杂的异步迭代器和响应式链。
205
260
 
206
- * 在您的 IDE 中浏览完整的类型化 API(所有导出均来自主包)。
207
- * 加入不断壮大的开发者社区,他们已用清晰的 Semantic 管道取代了复杂的异步迭代器。
261
+ **Semantic‑TypeScript** 流与结构的交汇点。
208
262
 
209
- **Semantic-TypeScript** — 流与结构的交汇点。
263
+ 立即开始构建,体验深思熟虑的索引设计所带来的切实差异。
210
264
 
211
- 立即开始构建,体验精心设计的索引所带来的不同。
265
+ **清晰构建,自信前行,以意图驱动数据转换。**
212
266
 
213
- **构建清晰,运行自信,让数据流转尽在掌控。**
267
+ MIT © Eloy Kim