@taicode/common-base 3.7.7 → 3.7.8

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.
Files changed (166) hide show
  1. package/output/batching-buffer/batching-buffer.d.ts +133 -0
  2. package/output/batching-buffer/batching-buffer.d.ts.map +1 -0
  3. package/output/batching-buffer/batching-buffer.js +264 -0
  4. package/output/batching-buffer/batching-buffer.test.d.ts +2 -0
  5. package/output/batching-buffer/batching-buffer.test.d.ts.map +1 -0
  6. package/output/batching-buffer/batching-buffer.test.js +358 -0
  7. package/output/batching-buffer/index.d.ts +3 -0
  8. package/output/batching-buffer/index.d.ts.map +1 -0
  9. package/output/batching-buffer/index.js +1 -0
  10. package/output/catch/catch.d.ts +46 -0
  11. package/output/catch/catch.d.ts.map +1 -0
  12. package/output/catch/catch.js +48 -0
  13. package/output/catch/catch.test.d.ts +2 -0
  14. package/output/catch/catch.test.d.ts.map +1 -0
  15. package/output/catch/catch.test.js +43 -0
  16. package/output/catch/index.d.ts +2 -0
  17. package/output/catch/index.d.ts.map +1 -0
  18. package/output/catch/index.js +1 -0
  19. package/output/color/color.d.ts +6 -0
  20. package/output/color/color.d.ts.map +1 -0
  21. package/output/color/color.js +56 -0
  22. package/output/color/color.test.d.ts +2 -0
  23. package/output/color/color.test.d.ts.map +1 -0
  24. package/output/color/color.test.js +110 -0
  25. package/output/color/index.d.ts +2 -0
  26. package/output/color/index.d.ts.map +1 -0
  27. package/output/color/index.js +1 -0
  28. package/output/debounce/debounce.d.ts +7 -0
  29. package/output/debounce/debounce.d.ts.map +1 -0
  30. package/output/debounce/debounce.js +36 -0
  31. package/output/debounce/debounce.test.d.ts +2 -0
  32. package/output/debounce/debounce.test.d.ts.map +1 -0
  33. package/output/debounce/debounce.test.js +135 -0
  34. package/output/debounce/index.d.ts +2 -0
  35. package/output/debounce/index.d.ts.map +1 -0
  36. package/output/debounce/index.js +1 -0
  37. package/output/disposer/disposer.d.ts +8 -0
  38. package/output/disposer/disposer.d.ts.map +1 -0
  39. package/output/disposer/disposer.js +21 -0
  40. package/output/disposer/disposer.test.d.ts +2 -0
  41. package/output/disposer/disposer.test.d.ts.map +1 -0
  42. package/output/disposer/disposer.test.js +216 -0
  43. package/output/disposer/index.d.ts +2 -0
  44. package/output/disposer/index.d.ts.map +1 -0
  45. package/output/disposer/index.js +1 -0
  46. package/output/error/error.d.ts +128 -0
  47. package/output/error/error.d.ts.map +1 -0
  48. package/output/error/error.js +141 -0
  49. package/output/error/error.test.d.ts +2 -0
  50. package/output/error/error.test.d.ts.map +1 -0
  51. package/output/error/error.test.js +420 -0
  52. package/output/error/index.d.ts +3 -0
  53. package/output/error/index.d.ts.map +1 -0
  54. package/output/error/index.js +1 -0
  55. package/output/event-emitter/event-emitter.d.ts +33 -0
  56. package/output/event-emitter/event-emitter.d.ts.map +1 -0
  57. package/output/event-emitter/event-emitter.js +66 -0
  58. package/output/event-emitter/event-emitter.test.d.ts +2 -0
  59. package/output/event-emitter/event-emitter.test.d.ts.map +1 -0
  60. package/output/event-emitter/event-emitter.test.js +177 -0
  61. package/output/event-emitter/index.d.ts +2 -0
  62. package/output/event-emitter/index.d.ts.map +1 -0
  63. package/output/event-emitter/index.js +1 -0
  64. package/output/flow-queue/flow-queue.d.ts +486 -0
  65. package/output/flow-queue/flow-queue.d.ts.map +1 -0
  66. package/output/flow-queue/flow-queue.js +654 -0
  67. package/output/flow-queue/flow-queue.test.d.ts +2 -0
  68. package/output/flow-queue/flow-queue.test.d.ts.map +1 -0
  69. package/output/flow-queue/flow-queue.test.js +1205 -0
  70. package/output/flow-queue/index.d.ts +3 -0
  71. package/output/flow-queue/index.d.ts.map +1 -0
  72. package/output/flow-queue/index.js +3 -0
  73. package/output/index.d.ts +18 -0
  74. package/output/index.d.ts.map +1 -0
  75. package/output/index.js +26 -0
  76. package/output/logger/formatter.d.ts +70 -0
  77. package/output/logger/formatter.d.ts.map +1 -0
  78. package/output/logger/formatter.js +206 -0
  79. package/output/logger/formatter.test.d.ts +2 -0
  80. package/output/logger/formatter.test.d.ts.map +1 -0
  81. package/output/logger/formatter.test.js +296 -0
  82. package/output/logger/index.d.ts +4 -0
  83. package/output/logger/index.d.ts.map +1 -0
  84. package/output/logger/index.js +3 -0
  85. package/output/logger/logger.d.ts +64 -0
  86. package/output/logger/logger.d.ts.map +1 -0
  87. package/output/logger/logger.js +179 -0
  88. package/output/logger/logger.test.d.ts +2 -0
  89. package/output/logger/logger.test.d.ts.map +1 -0
  90. package/output/logger/logger.test.js +299 -0
  91. package/output/logger/transport.d.ts +124 -0
  92. package/output/logger/transport.d.ts.map +1 -0
  93. package/output/logger/transport.js +153 -0
  94. package/output/logger/transport.test.d.ts +2 -0
  95. package/output/logger/transport.test.d.ts.map +1 -0
  96. package/output/logger/transport.test.js +309 -0
  97. package/output/lru-cache/index.d.ts +2 -0
  98. package/output/lru-cache/index.d.ts.map +1 -0
  99. package/output/lru-cache/index.js +1 -0
  100. package/output/lru-cache/lru-cache.d.ts +22 -0
  101. package/output/lru-cache/lru-cache.d.ts.map +1 -0
  102. package/output/lru-cache/lru-cache.js +147 -0
  103. package/output/lru-cache/lru-cache.test.d.ts +2 -0
  104. package/output/lru-cache/lru-cache.test.d.ts.map +1 -0
  105. package/output/lru-cache/lru-cache.test.js +239 -0
  106. package/output/number/index.d.ts +2 -0
  107. package/output/number/index.d.ts.map +1 -0
  108. package/output/number/index.js +1 -0
  109. package/output/number/number.d.ts +2 -0
  110. package/output/number/number.d.ts.map +1 -0
  111. package/output/number/number.js +23 -0
  112. package/output/number/number.test.d.ts +2 -0
  113. package/output/number/number.test.d.ts.map +1 -0
  114. package/output/number/number.test.js +50 -0
  115. package/output/object/index.d.ts +2 -0
  116. package/output/object/index.d.ts.map +1 -0
  117. package/output/object/index.js +1 -0
  118. package/output/object/object.d.ts +7 -0
  119. package/output/object/object.d.ts.map +1 -0
  120. package/output/object/object.js +27 -0
  121. package/output/object/object.test.d.ts +2 -0
  122. package/output/object/object.test.d.ts.map +1 -0
  123. package/output/object/object.test.js +42 -0
  124. package/output/ring-cache/index.d.ts +6 -0
  125. package/output/ring-cache/index.d.ts.map +1 -0
  126. package/output/ring-cache/index.js +5 -0
  127. package/output/ring-cache/ring-cache.d.ts +125 -0
  128. package/output/ring-cache/ring-cache.d.ts.map +1 -0
  129. package/output/ring-cache/ring-cache.js +197 -0
  130. package/output/ring-cache/ring-cache.test.d.ts +2 -0
  131. package/output/ring-cache/ring-cache.test.d.ts.map +1 -0
  132. package/output/ring-cache/ring-cache.test.js +196 -0
  133. package/output/service/index.d.ts +2 -0
  134. package/output/service/index.d.ts.map +1 -0
  135. package/output/service/index.js +1 -0
  136. package/output/service/service.d.ts +6 -0
  137. package/output/service/service.d.ts.map +1 -0
  138. package/output/service/service.js +3 -0
  139. package/output/string/index.d.ts +2 -0
  140. package/output/string/index.d.ts.map +1 -0
  141. package/output/string/index.js +1 -0
  142. package/output/string/string.d.ts +3 -0
  143. package/output/string/string.d.ts.map +1 -0
  144. package/output/string/string.js +9 -0
  145. package/output/string/string.test.d.ts +2 -0
  146. package/output/string/string.test.d.ts.map +1 -0
  147. package/output/string/string.test.js +77 -0
  148. package/output/throttle/index.d.ts +2 -0
  149. package/output/throttle/index.d.ts.map +1 -0
  150. package/output/throttle/index.js +1 -0
  151. package/output/throttle/throttle.d.ts +12 -0
  152. package/output/throttle/throttle.d.ts.map +1 -0
  153. package/output/throttle/throttle.js +55 -0
  154. package/output/throttle/throttle.test.d.ts +2 -0
  155. package/output/throttle/throttle.test.d.ts.map +1 -0
  156. package/output/throttle/throttle.test.js +177 -0
  157. package/output/ttl-cache/index.d.ts +2 -0
  158. package/output/ttl-cache/index.d.ts.map +1 -0
  159. package/output/ttl-cache/index.js +1 -0
  160. package/output/ttl-cache/ttl-cache.d.ts +148 -0
  161. package/output/ttl-cache/ttl-cache.d.ts.map +1 -0
  162. package/output/ttl-cache/ttl-cache.js +313 -0
  163. package/output/ttl-cache/ttl-cache.test.d.ts +2 -0
  164. package/output/ttl-cache/ttl-cache.test.d.ts.map +1 -0
  165. package/output/ttl-cache/ttl-cache.test.js +222 -0
  166. package/package.json +1 -1
@@ -0,0 +1,222 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { TtlCache } from './ttl-cache.js';
3
+ describe('TtlCache', () => {
4
+ let cache;
5
+ beforeEach(() => {
6
+ vi.useFakeTimers();
7
+ cache = new TtlCache({ defaultTtl: 1000, enableCleanup: false });
8
+ });
9
+ afterEach(() => {
10
+ cache.destroy();
11
+ vi.useRealTimers();
12
+ });
13
+ describe('基础功能', () => {
14
+ it('应该能够设置和获取缓存项', () => {
15
+ cache.set('key1', 'value1');
16
+ expect(cache.get('key1')).toBe('value1');
17
+ });
18
+ it('应该能够检查缓存项是否存在', () => {
19
+ cache.set('key1', 'value1');
20
+ expect(cache.has('key1')).toBe(true);
21
+ expect(cache.has('nonexistent')).toBe(false);
22
+ });
23
+ it('应该能够删除缓存项', () => {
24
+ cache.set('key1', 'value1');
25
+ expect(cache.delete('key1')).toBe(true);
26
+ expect(cache.get('key1')).toBeUndefined();
27
+ expect(cache.delete('nonexistent')).toBe(false);
28
+ });
29
+ it('应该能够清空所有缓存', () => {
30
+ cache.set('key1', 'value1');
31
+ cache.set('key2', 'value2');
32
+ cache.clear();
33
+ expect(cache.size).toBe(0);
34
+ expect(cache.get('key1')).toBeUndefined();
35
+ expect(cache.get('key2')).toBeUndefined();
36
+ });
37
+ it('应该能够获取缓存大小', () => {
38
+ expect(cache.size).toBe(0);
39
+ cache.set('key1', 'value1');
40
+ expect(cache.size).toBe(1);
41
+ cache.set('key2', 'value2');
42
+ expect(cache.size).toBe(2);
43
+ });
44
+ });
45
+ describe('TTL 功能', () => {
46
+ it('应该在 TTL 过期后删除缓存项', () => {
47
+ cache.set('key1', 'value1', 500);
48
+ expect(cache.get('key1')).toBe('value1');
49
+ // 前进 600ms,超过 TTL
50
+ vi.advanceTimersByTime(600);
51
+ expect(cache.get('key1')).toBeUndefined();
52
+ });
53
+ it('应该使用默认 TTL', () => {
54
+ cache.set('key1', 'value1');
55
+ expect(cache.get('key1')).toBe('value1');
56
+ // 前进 1100ms,超过默认 TTL (1000ms)
57
+ vi.advanceTimersByTime(1100);
58
+ expect(cache.get('key1')).toBeUndefined();
59
+ });
60
+ it('应该能够获取剩余 TTL 时间', () => {
61
+ cache.set('key1', 'value1', 1000);
62
+ expect(cache.getTtl('key1')).toBe(1000);
63
+ vi.advanceTimersByTime(500);
64
+ expect(cache.getTtl('key1')).toBe(500);
65
+ vi.advanceTimersByTime(600);
66
+ expect(cache.getTtl('key1')).toBe(-1); // 已过期
67
+ });
68
+ it('不存在的键应该返回 -1 的 TTL', () => {
69
+ expect(cache.getTtl('nonexistent')).toBe(-1);
70
+ });
71
+ });
72
+ describe('容量限制', () => {
73
+ beforeEach(() => {
74
+ cache.destroy();
75
+ cache = new TtlCache({ maxSize: 2, enableCleanup: false });
76
+ });
77
+ it('应该遵守最大容量限制', () => {
78
+ cache.set('key1', 'value1');
79
+ cache.set('key2', 'value2');
80
+ cache.set('key3', 'value3'); // 应该驱逐最旧的条目
81
+ expect(cache.size).toBe(2);
82
+ expect(cache.get('key1')).toBeUndefined(); // 最旧的条目被驱逐
83
+ expect(cache.get('key2')).toBe('value2');
84
+ expect(cache.get('key3')).toBe('value3');
85
+ });
86
+ it('应该能够获取容量信息', () => {
87
+ expect(cache.capacity).toBe(2);
88
+ });
89
+ });
90
+ describe('getOrSet 功能', () => {
91
+ it('应该返回已存在的缓存值', async () => {
92
+ cache.set('key1', 'existing');
93
+ const factory = vi.fn(() => Promise.resolve('new'));
94
+ const result = await cache.getOrSet('key1', factory);
95
+ expect(result).toBe('existing');
96
+ expect(factory).not.toHaveBeenCalled();
97
+ });
98
+ it('应该在缓存不存在时调用工厂函数并缓存结果', async () => {
99
+ const factory = vi.fn(() => Promise.resolve('new'));
100
+ const result = await cache.getOrSet('key1', factory);
101
+ expect(result).toBe('new');
102
+ expect(factory).toHaveBeenCalledOnce();
103
+ expect(cache.get('key1')).toBe('new');
104
+ });
105
+ it('应该支持同步工厂函数', () => {
106
+ const factory = vi.fn(() => 'sync-value');
107
+ const result = cache.getOrSet('key1', factory);
108
+ expect(result).toBe('sync-value');
109
+ expect(factory).toHaveBeenCalledOnce();
110
+ expect(cache.get('key1')).toBe('sync-value');
111
+ });
112
+ });
113
+ describe('集合操作', () => {
114
+ beforeEach(() => {
115
+ cache.set('key1', 'value1');
116
+ cache.set('key2', 'value2');
117
+ cache.set('expired', 'expired-value', 100);
118
+ vi.advanceTimersByTime(200); // 使 'expired' 过期
119
+ });
120
+ it('应该返回所有未过期的键', () => {
121
+ const keys = cache.keys();
122
+ expect(keys).toContain('key1');
123
+ expect(keys).toContain('key2');
124
+ expect(keys).not.toContain('expired');
125
+ });
126
+ it('应该返回所有未过期的值', () => {
127
+ const values = cache.values();
128
+ expect(values).toContain('value1');
129
+ expect(values).toContain('value2');
130
+ expect(values).not.toContain('expired-value');
131
+ });
132
+ it('应该返回所有未过期的键值对', () => {
133
+ const entries = cache.entries();
134
+ expect(entries).toContainEqual(['key1', 'value1']);
135
+ expect(entries).toContainEqual(['key2', 'value2']);
136
+ expect(entries).not.toContainEqual(['expired', 'expired-value']);
137
+ });
138
+ });
139
+ describe('统计功能', () => {
140
+ it('应该跟踪命中和未命中', () => {
141
+ cache.set('key1', 'value1');
142
+ // 命中
143
+ cache.get('key1');
144
+ cache.get('key1');
145
+ // 未命中
146
+ cache.get('nonexistent');
147
+ const stats = cache.getStats();
148
+ expect(stats.hits).toBe(2);
149
+ expect(stats.misses).toBe(1);
150
+ expect(stats.hitRate).toBeCloseTo(2 / 3);
151
+ });
152
+ it('应该跟踪过期次数', () => {
153
+ cache.set('key1', 'value1', 100);
154
+ vi.advanceTimersByTime(200);
155
+ cache.get('key1'); // 触发过期
156
+ const stats = cache.getStats();
157
+ expect(stats.expiredCount).toBe(1);
158
+ });
159
+ it('应该能够重置统计信息', () => {
160
+ cache.get('nonexistent'); // 创建一些统计数据
161
+ cache.resetStats();
162
+ const stats = cache.getStats();
163
+ expect(stats.hits).toBe(0);
164
+ expect(stats.misses).toBe(0);
165
+ expect(stats.expiredCount).toBe(0);
166
+ expect(stats.hitRate).toBe(0);
167
+ });
168
+ });
169
+ describe('清理功能', () => {
170
+ it('应该手动清理过期条目', () => {
171
+ cache.set('key1', 'value1', 100);
172
+ cache.set('key2', 'value2', 1000);
173
+ vi.advanceTimersByTime(200);
174
+ const cleaned = cache.cleanup();
175
+ expect(cleaned).toBe(1);
176
+ expect(cache.size).toBe(1);
177
+ expect(cache.get('key1')).toBeUndefined();
178
+ expect(cache.get('key2')).toBe('value2');
179
+ });
180
+ it('应该启用自动清理', () => {
181
+ cache.destroy();
182
+ cache = new TtlCache({
183
+ defaultTtl: 1000,
184
+ cleanupInterval: 500,
185
+ enableCleanup: true
186
+ });
187
+ cache.set('key1', 'value1', 100);
188
+ vi.advanceTimersByTime(600); // 触发清理
189
+ expect(cache.size).toBe(0);
190
+ });
191
+ });
192
+ describe('配置验证', () => {
193
+ it('应该拒绝无效的默认 TTL', () => {
194
+ expect(() => new TtlCache({ defaultTtl: 0 })).toThrow('defaultTtl must be greater than 0');
195
+ expect(() => new TtlCache({ defaultTtl: -1 })).toThrow('defaultTtl must be greater than 0');
196
+ });
197
+ it('应该拒绝无效的清理间隔', () => {
198
+ expect(() => new TtlCache({ cleanupInterval: 0 })).toThrow('cleanupInterval must be greater than 0');
199
+ expect(() => new TtlCache({ cleanupInterval: -1 })).toThrow('cleanupInterval must be greater than 0');
200
+ });
201
+ it('应该拒绝无效的最大容量', () => {
202
+ expect(() => new TtlCache({ maxSize: 0 })).toThrow('maxSize must be greater than 0');
203
+ expect(() => new TtlCache({ maxSize: -1 })).toThrow('maxSize must be greater than 0');
204
+ });
205
+ });
206
+ describe('边界情况', () => {
207
+ it('应该处理空字符串键', () => {
208
+ cache.set('', 'empty-key-value');
209
+ expect(cache.get('')).toBe('empty-key-value');
210
+ });
211
+ it('应该处理 undefined 值', () => {
212
+ cache.set('key1', undefined);
213
+ expect(cache.get('key1')).toBeUndefined();
214
+ expect(cache.has('key1')).toBe(true); // 值虽然是 undefined,但键存在
215
+ });
216
+ it('应该处理非常短的 TTL', () => {
217
+ cache.set('key1', 'value1', 1);
218
+ vi.advanceTimersByTime(2);
219
+ expect(cache.get('key1')).toBeUndefined();
220
+ });
221
+ });
222
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-base",
3
- "version": "3.7.7",
3
+ "version": "3.7.8",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",