@taicode/common-base 3.1.0 → 3.1.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.
@@ -0,0 +1,213 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { EventEmitter } from './event-emitter';
3
+ describe('EventEmitter', () => {
4
+ let emitter;
5
+ beforeEach(() => {
6
+ emitter = new EventEmitter();
7
+ });
8
+ describe('on', () => {
9
+ it('应该能够订阅事件', () => {
10
+ const listener = vi.fn();
11
+ emitter.on('test', listener);
12
+ emitter.emit('test', 'hello');
13
+ expect(listener).toHaveBeenCalledOnce();
14
+ expect(listener).toHaveBeenCalledWith('hello');
15
+ });
16
+ it('应该能够订阅多个监听器', () => {
17
+ const listener1 = vi.fn();
18
+ const listener2 = vi.fn();
19
+ emitter.on('test', listener1);
20
+ emitter.on('test', listener2);
21
+ emitter.emit('test', 'hello');
22
+ expect(listener1).toHaveBeenCalledOnce();
23
+ expect(listener2).toHaveBeenCalledOnce();
24
+ expect(listener1).toHaveBeenCalledWith('hello');
25
+ expect(listener2).toHaveBeenCalledWith('hello');
26
+ });
27
+ it('应该返回取消订阅函数', () => {
28
+ const listener = vi.fn();
29
+ const off = emitter.on('test', listener);
30
+ emitter.emit('test', 'hello');
31
+ expect(listener).toHaveBeenCalledOnce();
32
+ off();
33
+ emitter.emit('test', 'world');
34
+ expect(listener).toHaveBeenCalledOnce();
35
+ });
36
+ it('应该支持不同类型的事件数据', () => {
37
+ const stringListener = vi.fn();
38
+ const numberListener = vi.fn();
39
+ const objectListener = vi.fn();
40
+ const voidListener = vi.fn();
41
+ emitter.on('test', stringListener);
42
+ emitter.on('number', numberListener);
43
+ emitter.on('object', objectListener);
44
+ emitter.on('noData', voidListener);
45
+ const testObject = { id: 1, name: 'test' };
46
+ emitter.emit('test', 'hello');
47
+ emitter.emit('number', 42);
48
+ emitter.emit('object', testObject);
49
+ emitter.emit('noData', undefined);
50
+ expect(stringListener).toHaveBeenCalledWith('hello');
51
+ expect(numberListener).toHaveBeenCalledWith(42);
52
+ expect(objectListener).toHaveBeenCalledWith(testObject);
53
+ expect(voidListener).toHaveBeenCalledWith(undefined);
54
+ });
55
+ });
56
+ describe('off', () => {
57
+ it('应该能够取消订阅特定监听器', () => {
58
+ const listener1 = vi.fn();
59
+ const listener2 = vi.fn();
60
+ emitter.on('test', listener1);
61
+ emitter.on('test', listener2);
62
+ emitter.off('test', listener1);
63
+ emitter.emit('test', 'hello');
64
+ expect(listener1).not.toHaveBeenCalled();
65
+ expect(listener2).toHaveBeenCalledOnce();
66
+ });
67
+ it('应该能够取消订阅所有监听器', () => {
68
+ const listener1 = vi.fn();
69
+ const listener2 = vi.fn();
70
+ emitter.on('test', listener1);
71
+ emitter.on('test', listener2);
72
+ emitter.off('test');
73
+ emitter.emit('test', 'hello');
74
+ expect(listener1).not.toHaveBeenCalled();
75
+ expect(listener2).not.toHaveBeenCalled();
76
+ });
77
+ it('应该忽略不存在的事件类型', () => {
78
+ expect(() => {
79
+ emitter.off('test');
80
+ }).not.toThrow();
81
+ });
82
+ it('应该忽略不存在的监听器', () => {
83
+ const listener = vi.fn();
84
+ const anotherListener = vi.fn();
85
+ emitter.on('test', listener);
86
+ expect(() => {
87
+ emitter.off('test', anotherListener);
88
+ }).not.toThrow();
89
+ emitter.emit('test', 'hello');
90
+ expect(listener).toHaveBeenCalledOnce();
91
+ });
92
+ });
93
+ describe('emit', () => {
94
+ it('应该能够触发事件', () => {
95
+ const listener = vi.fn();
96
+ emitter.on('test', listener);
97
+ emitter.emit('test', 'hello');
98
+ expect(listener).toHaveBeenCalledWith('hello');
99
+ });
100
+ it('应该不抛出错误当没有监听器时', () => {
101
+ expect(() => {
102
+ emitter.emit('test', 'hello');
103
+ }).not.toThrow();
104
+ });
105
+ it('应该按顺序调用监听器', () => {
106
+ const calls = [];
107
+ emitter.on('test', () => calls.push(1));
108
+ emitter.on('test', () => calls.push(2));
109
+ emitter.on('test', () => calls.push(3));
110
+ emitter.emit('test', 'hello');
111
+ expect(calls).toEqual([1, 2, 3]);
112
+ });
113
+ it('应该处理监听器中的错误', () => {
114
+ const workingListener = vi.fn();
115
+ const errorListener = vi.fn(() => {
116
+ throw new Error('Test error');
117
+ });
118
+ const anotherWorkingListener = vi.fn();
119
+ emitter.on('test', workingListener);
120
+ emitter.on('test', errorListener);
121
+ emitter.on('test', anotherWorkingListener);
122
+ expect(() => {
123
+ emitter.emit('test', 'hello');
124
+ }).toThrow('Test error');
125
+ expect(workingListener).toHaveBeenCalled();
126
+ expect(errorListener).toHaveBeenCalled();
127
+ // 由于错误,后续监听器可能不会被调用
128
+ });
129
+ it('应该防止监听器修改监听器列表时的遍历问题', () => {
130
+ const listener1 = vi.fn();
131
+ const listener2 = vi.fn(() => {
132
+ // 在回调中取消订阅
133
+ emitter.off('test', listener3);
134
+ });
135
+ const listener3 = vi.fn();
136
+ emitter.on('test', listener1);
137
+ emitter.on('test', listener2);
138
+ emitter.on('test', listener3);
139
+ emitter.emit('test', 'hello');
140
+ expect(listener1).toHaveBeenCalled();
141
+ expect(listener2).toHaveBeenCalled();
142
+ expect(listener3).toHaveBeenCalled(); // 应该仍然被调用,因为使用了 slice()
143
+ });
144
+ });
145
+ describe('once', () => {
146
+ it('应该只执行一次监听器', () => {
147
+ const listener = vi.fn();
148
+ emitter.once('test', listener);
149
+ emitter.emit('test', 'first');
150
+ emitter.emit('test', 'second');
151
+ expect(listener).toHaveBeenCalledOnce();
152
+ expect(listener).toHaveBeenCalledWith('first');
153
+ });
154
+ it('应该在执行后自动取消订阅', () => {
155
+ const listener = vi.fn();
156
+ emitter.once('test', listener);
157
+ emitter.emit('test', 'hello');
158
+ // 验证监听器已被移除
159
+ emitter.emit('test', 'world');
160
+ expect(listener).toHaveBeenCalledOnce();
161
+ });
162
+ it('应该与普通监听器一起工作', () => {
163
+ const onceListener = vi.fn();
164
+ const normalListener = vi.fn();
165
+ emitter.once('test', onceListener);
166
+ emitter.on('test', normalListener);
167
+ emitter.emit('test', 'first');
168
+ emitter.emit('test', 'second');
169
+ expect(onceListener).toHaveBeenCalledOnce();
170
+ expect(normalListener).toHaveBeenCalledTimes(2);
171
+ });
172
+ });
173
+ describe('cleanup', () => {
174
+ it('应该清空所有监听器', () => {
175
+ const listener1 = vi.fn();
176
+ const listener2 = vi.fn();
177
+ emitter.on('test', listener1);
178
+ emitter.on('number', listener2);
179
+ emitter.cleanup();
180
+ emitter.emit('test', 'hello');
181
+ emitter.emit('number', 42);
182
+ expect(listener1).not.toHaveBeenCalled();
183
+ expect(listener2).not.toHaveBeenCalled();
184
+ });
185
+ it('清理后应该能够重新添加监听器', () => {
186
+ const listener = vi.fn();
187
+ emitter.on('test', listener);
188
+ emitter.cleanup();
189
+ const newListener = vi.fn();
190
+ emitter.on('test', newListener);
191
+ emitter.emit('test', 'hello');
192
+ expect(listener).not.toHaveBeenCalled();
193
+ expect(newListener).toHaveBeenCalledWith('hello');
194
+ });
195
+ });
196
+ describe('方法绑定', () => {
197
+ it('方法应该绑定到实例', () => {
198
+ const { on, off, emit, once, cleanup } = emitter;
199
+ const listener = vi.fn();
200
+ on('test', listener);
201
+ emit('test', 'hello');
202
+ expect(listener).toHaveBeenCalledWith('hello');
203
+ off('test', listener);
204
+ emit('test', 'world');
205
+ expect(listener).toHaveBeenCalledOnce();
206
+ // 测试其他方法
207
+ once('test', listener);
208
+ emit('test', 'once');
209
+ expect(listener).toHaveBeenCalledTimes(2);
210
+ cleanup();
211
+ });
212
+ });
213
+ });
@@ -0,0 +1,3 @@
1
+ export * from './event-emitter';
2
+ export * from './disposer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/events/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ // 事件系统相关功能
2
+ export * from './event-emitter';
3
+ export * from './disposer';
@@ -1,5 +1,6 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
2
  import { FlowQueue } from './flow-queue.js';
3
+ import { logger } from '../logger/index.js';
3
4
  describe('FlowQueue', () => {
4
5
  let flowQueue;
5
6
  let mockProcessor;
@@ -158,8 +159,8 @@ describe('FlowQueue', () => {
158
159
  throw new Error('Callback error');
159
160
  });
160
161
  const normalCallback = vi.fn();
161
- // Mock console.error 来验证错误被正确记录
162
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
162
+ // Mock logger.error 来验证错误被正确记录
163
+ const loggerErrorSpy = vi.spyOn(logger, 'error').mockImplementation(() => { });
163
164
  mockProcessor = vi.fn().mockResolvedValue(expectedOutput);
164
165
  flowQueue = new FlowQueue({ retry: { maxRetries: 3 } }, mockProcessor);
165
166
  flowQueue.onGenerate(faultyCallback);
@@ -168,8 +169,8 @@ describe('FlowQueue', () => {
168
169
  await new Promise(resolve => setTimeout(resolve, 50));
169
170
  expect(faultyCallback).toHaveBeenCalled();
170
171
  expect(normalCallback).toHaveBeenCalledWith(expectedOutput);
171
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in onGenerate callback:', expect.any(Error));
172
- consoleErrorSpy.mockRestore();
172
+ expect(loggerErrorSpy).toHaveBeenCalledWith('Error in onGenerate callback:', expect.any(Error));
173
+ loggerErrorSpy.mockRestore();
173
174
  });
174
175
  it('失败的处理不应该触发回调', async () => {
175
176
  const testInput = { id: 1, data: 'test' };
@@ -77,9 +77,10 @@ describe('RingCache', () => {
77
77
  expect(results.map(e => e.data)).toEqual(['apple', 'apricot']);
78
78
  });
79
79
  it('应该支持时间范围搜索', () => {
80
- const now = new Date();
81
- const future = new Date(now.getTime() + 1000);
82
- const results = cache.getByTimeRange(now, future);
80
+ const entries = cache.getAll();
81
+ const start = new Date(entries[0].timestamp.getTime() - 1);
82
+ const end = new Date(entries[entries.length - 1].timestamp.getTime() + 1);
83
+ const results = cache.getByTimeRange(start, end);
83
84
  expect(results.length).toBe(3);
84
85
  });
85
86
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-base",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",
@@ -22,15 +22,15 @@
22
22
  },
23
23
  "scripts": {
24
24
  "test": "vitest run",
25
- "build": "tsc -p tsconfig.json",
25
+ "build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json",
26
26
  "prepublishOnly": "npm run build",
27
- "dev": "tsc -p tsconfig.json --watch"
27
+ "dev": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json --watch"
28
28
  },
29
29
  "files": [
30
30
  "output"
31
31
  ],
32
32
  "devDependencies": {
33
33
  "vitest": "^3.2.4",
34
- "mobx": "^6.0.0"
34
+ "mobx": "^6.15.0"
35
35
  }
36
36
  }
@@ -1,2 +0,0 @@
1
- export * from './scheduler';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/scheduler/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
@@ -1 +0,0 @@
1
- export * from './scheduler';
@@ -1,222 +0,0 @@
1
- import { EventEmitter } from '../event-emitter';
2
- import { type CatchResult } from '../catch';
3
- /**
4
- * 定时任务配置
5
- */
6
- export interface ScheduledTaskConfig {
7
- /**
8
- * 任务唯一标识
9
- */
10
- id: string;
11
- /**
12
- * 任务执行间隔(秒),必须是 10 的倍数
13
- */
14
- interval: number;
15
- /**
16
- * 任务处理函数
17
- */
18
- handler: () => Promise<void> | void;
19
- /**
20
- * 最大重试次数,默认 3
21
- */
22
- maxRetries?: number;
23
- /**
24
- * 重试间隔(毫秒),默认 1000
25
- */
26
- retryDelay?: number;
27
- /**
28
- * 是否在启动时立即执行一次,默认 false
29
- */
30
- immediate?: boolean;
31
- /**
32
- * 是否启用,默认 true
33
- */
34
- enabled?: boolean;
35
- }
36
- /**
37
- * 任务执行记录
38
- */
39
- export interface TaskExecution {
40
- taskId: string;
41
- startTime: number;
42
- endTime?: number;
43
- success: boolean;
44
- error?: Error;
45
- retryCount: number;
46
- }
47
- /**
48
- * 调度器事件
49
- */
50
- export interface SchedulerEvents {
51
- 'task:start': {
52
- taskId: string;
53
- };
54
- 'task:success': {
55
- taskId: string;
56
- duration: number;
57
- };
58
- 'task:error': {
59
- taskId: string;
60
- error: Error;
61
- retryCount: number;
62
- };
63
- 'task:retry': {
64
- taskId: string;
65
- retryCount: number;
66
- maxRetries: number;
67
- };
68
- 'task:failed': {
69
- taskId: string;
70
- error: Error;
71
- };
72
- 'scheduler:start': void;
73
- 'scheduler:stop': void;
74
- 'scheduler:tick': {
75
- tick: number;
76
- };
77
- }
78
- /**
79
- * 内部任务状态
80
- */
81
- interface TaskState {
82
- config: Required<ScheduledTaskConfig>;
83
- nextTick: number;
84
- running: boolean;
85
- retryCount: number;
86
- lastError?: Error;
87
- executions: TaskExecution[];
88
- }
89
- /**
90
- * 定时任务调度器
91
- *
92
- * 以 10 秒为基本时间单位,支持多个不同间隔的定时任务
93
- *
94
- * @example
95
- * ```ts
96
- * const scheduler = new Scheduler()
97
- *
98
- * // 添加每 30 秒执行一次的任务
99
- * scheduler.addTask({
100
- * id: 'sync-data',
101
- * interval: 30,
102
- * handler: async () => {
103
- * await syncDataToServer()
104
- * },
105
- * maxRetries: 3
106
- * })
107
- *
108
- * // 添加每 60 秒执行一次的任务
109
- * scheduler.addTask({
110
- * id: 'cleanup',
111
- * interval: 60,
112
- * handler: async () => {
113
- * await cleanupTempFiles()
114
- * }
115
- * })
116
- *
117
- * // 启动调度器
118
- * scheduler.start()
119
- *
120
- * // 监听事件
121
- * scheduler.on('task:error', (taskId, error) => {
122
- * console.error(`Task ${taskId} failed:`, error)
123
- * })
124
- *
125
- * // 停止调度器
126
- * scheduler.stop()
127
- * ```
128
- */
129
- export declare class Scheduler extends EventEmitter<SchedulerEvents> {
130
- /**
131
- * 基本时间单位(秒)
132
- */
133
- private static readonly TICK_INTERVAL;
134
- /**
135
- * 当前 tick 计数
136
- */
137
- private currentTick;
138
- /**
139
- * 定时器 ID
140
- */
141
- private timerId;
142
- /**
143
- * 是否正在运行
144
- */
145
- private running;
146
- /**
147
- * 任务状态映射
148
- */
149
- private tasks;
150
- /**
151
- * 添加定时任务
152
- */
153
- addTask(config: ScheduledTaskConfig): void;
154
- /**
155
- * 移除定时任务
156
- */
157
- removeTask(taskId: string): boolean;
158
- /**
159
- * 启用任务
160
- */
161
- enableTask(taskId: string): boolean;
162
- /**
163
- * 禁用任务
164
- */
165
- disableTask(taskId: string): boolean;
166
- /**
167
- * 获取任务状态
168
- */
169
- getTaskState(taskId: string): Readonly<TaskState> | undefined;
170
- /**
171
- * 获取所有任务 ID
172
- */
173
- getTaskIds(): string[];
174
- /**
175
- * 启动调度器
176
- */
177
- start(): void;
178
- /**
179
- * 停止调度器
180
- */
181
- stop(): void;
182
- /**
183
- * 是否正在运行
184
- */
185
- isRunning(): boolean;
186
- /**
187
- * 获取当前 tick
188
- */
189
- getCurrentTick(): number;
190
- /**
191
- * 手动触发任务执行(忽略时间间隔)
192
- */
193
- triggerTask(taskId: string): Promise<CatchResult<void, string>>;
194
- /**
195
- * 执行 tick
196
- */
197
- private tick;
198
- /**
199
- * 执行任务
200
- */
201
- private executeTask;
202
- /**
203
- * 获取任务执行历史
204
- */
205
- getTaskExecutions(taskId: string, limit?: number): TaskExecution[];
206
- /**
207
- * 获取调度器统计信息
208
- */
209
- getStats(): {
210
- running: boolean;
211
- currentTick: number;
212
- totalTasks: number;
213
- enabledTasks: number;
214
- runningTasks: number;
215
- };
216
- /**
217
- * 清理所有任务
218
- */
219
- clear(): void;
220
- }
221
- export {};
222
- //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../source/scheduler/scheduler.ts"],"names":[],"mappings":"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"}