@dangao/bun-server 1.12.1 → 2.0.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.
Files changed (214) hide show
  1. package/README.md +32 -0
  2. package/dist/ai/ai-module.d.ts +24 -0
  3. package/dist/ai/ai-module.d.ts.map +1 -0
  4. package/dist/ai/decorators.d.ts +25 -0
  5. package/dist/ai/decorators.d.ts.map +1 -0
  6. package/dist/ai/errors.d.ts +39 -0
  7. package/dist/ai/errors.d.ts.map +1 -0
  8. package/dist/ai/index.d.ts +12 -0
  9. package/dist/ai/index.d.ts.map +1 -0
  10. package/dist/ai/providers/anthropic-provider.d.ts +23 -0
  11. package/dist/ai/providers/anthropic-provider.d.ts.map +1 -0
  12. package/dist/ai/providers/google-provider.d.ts +20 -0
  13. package/dist/ai/providers/google-provider.d.ts.map +1 -0
  14. package/dist/ai/providers/ollama-provider.d.ts +17 -0
  15. package/dist/ai/providers/ollama-provider.d.ts.map +1 -0
  16. package/dist/ai/providers/openai-provider.d.ts +28 -0
  17. package/dist/ai/providers/openai-provider.d.ts.map +1 -0
  18. package/dist/ai/service.d.ts +40 -0
  19. package/dist/ai/service.d.ts.map +1 -0
  20. package/dist/ai/tools/tool-executor.d.ts +15 -0
  21. package/dist/ai/tools/tool-executor.d.ts.map +1 -0
  22. package/dist/ai/tools/tool-registry.d.ts +39 -0
  23. package/dist/ai/tools/tool-registry.d.ts.map +1 -0
  24. package/dist/ai/types.d.ts +134 -0
  25. package/dist/ai/types.d.ts.map +1 -0
  26. package/dist/ai-guard/ai-guard-module.d.ts +18 -0
  27. package/dist/ai-guard/ai-guard-module.d.ts.map +1 -0
  28. package/dist/ai-guard/decorators.d.ts +16 -0
  29. package/dist/ai-guard/decorators.d.ts.map +1 -0
  30. package/dist/ai-guard/detectors/content-moderator.d.ts +26 -0
  31. package/dist/ai-guard/detectors/content-moderator.d.ts.map +1 -0
  32. package/dist/ai-guard/detectors/injection-detector.d.ts +13 -0
  33. package/dist/ai-guard/detectors/injection-detector.d.ts.map +1 -0
  34. package/dist/ai-guard/detectors/pii-detector.d.ts +11 -0
  35. package/dist/ai-guard/detectors/pii-detector.d.ts.map +1 -0
  36. package/dist/ai-guard/index.d.ts +8 -0
  37. package/dist/ai-guard/index.d.ts.map +1 -0
  38. package/dist/ai-guard/service.d.ts +21 -0
  39. package/dist/ai-guard/service.d.ts.map +1 -0
  40. package/dist/ai-guard/types.d.ts +59 -0
  41. package/dist/ai-guard/types.d.ts.map +1 -0
  42. package/dist/conversation/conversation-module.d.ts +25 -0
  43. package/dist/conversation/conversation-module.d.ts.map +1 -0
  44. package/dist/conversation/decorators.d.ts +28 -0
  45. package/dist/conversation/decorators.d.ts.map +1 -0
  46. package/dist/conversation/index.d.ts +8 -0
  47. package/dist/conversation/index.d.ts.map +1 -0
  48. package/dist/conversation/service.d.ts +43 -0
  49. package/dist/conversation/service.d.ts.map +1 -0
  50. package/dist/conversation/stores/database-store.d.ts +46 -0
  51. package/dist/conversation/stores/database-store.d.ts.map +1 -0
  52. package/dist/conversation/stores/memory-store.d.ts +17 -0
  53. package/dist/conversation/stores/memory-store.d.ts.map +1 -0
  54. package/dist/conversation/stores/redis-store.d.ts +39 -0
  55. package/dist/conversation/stores/redis-store.d.ts.map +1 -0
  56. package/dist/conversation/types.d.ts +64 -0
  57. package/dist/conversation/types.d.ts.map +1 -0
  58. package/dist/embedding/embedding-module.d.ts +20 -0
  59. package/dist/embedding/embedding-module.d.ts.map +1 -0
  60. package/dist/embedding/index.d.ts +6 -0
  61. package/dist/embedding/index.d.ts.map +1 -0
  62. package/dist/embedding/providers/ollama-embedding-provider.d.ts +18 -0
  63. package/dist/embedding/providers/ollama-embedding-provider.d.ts.map +1 -0
  64. package/dist/embedding/providers/openai-embedding-provider.d.ts +18 -0
  65. package/dist/embedding/providers/openai-embedding-provider.d.ts.map +1 -0
  66. package/dist/embedding/service.d.ts +27 -0
  67. package/dist/embedding/service.d.ts.map +1 -0
  68. package/dist/embedding/types.d.ts +25 -0
  69. package/dist/embedding/types.d.ts.map +1 -0
  70. package/dist/index.d.ts +8 -0
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +2638 -1
  73. package/dist/mcp/decorators.d.ts +42 -0
  74. package/dist/mcp/decorators.d.ts.map +1 -0
  75. package/dist/mcp/index.d.ts +6 -0
  76. package/dist/mcp/index.d.ts.map +1 -0
  77. package/dist/mcp/mcp-module.d.ts +22 -0
  78. package/dist/mcp/mcp-module.d.ts.map +1 -0
  79. package/dist/mcp/registry.d.ts +23 -0
  80. package/dist/mcp/registry.d.ts.map +1 -0
  81. package/dist/mcp/server.d.ts +29 -0
  82. package/dist/mcp/server.d.ts.map +1 -0
  83. package/dist/mcp/types.d.ts +60 -0
  84. package/dist/mcp/types.d.ts.map +1 -0
  85. package/dist/prompt/index.d.ts +6 -0
  86. package/dist/prompt/index.d.ts.map +1 -0
  87. package/dist/prompt/prompt-module.d.ts +23 -0
  88. package/dist/prompt/prompt-module.d.ts.map +1 -0
  89. package/dist/prompt/service.d.ts +47 -0
  90. package/dist/prompt/service.d.ts.map +1 -0
  91. package/dist/prompt/stores/file-store.d.ts +36 -0
  92. package/dist/prompt/stores/file-store.d.ts.map +1 -0
  93. package/dist/prompt/stores/memory-store.d.ts +17 -0
  94. package/dist/prompt/stores/memory-store.d.ts.map +1 -0
  95. package/dist/prompt/types.d.ts +68 -0
  96. package/dist/prompt/types.d.ts.map +1 -0
  97. package/dist/rag/chunkers/markdown-chunker.d.ts +11 -0
  98. package/dist/rag/chunkers/markdown-chunker.d.ts.map +1 -0
  99. package/dist/rag/chunkers/text-chunker.d.ts +11 -0
  100. package/dist/rag/chunkers/text-chunker.d.ts.map +1 -0
  101. package/dist/rag/decorators.d.ts +24 -0
  102. package/dist/rag/decorators.d.ts.map +1 -0
  103. package/dist/rag/index.d.ts +7 -0
  104. package/dist/rag/index.d.ts.map +1 -0
  105. package/dist/rag/rag-module.d.ts +23 -0
  106. package/dist/rag/rag-module.d.ts.map +1 -0
  107. package/dist/rag/service.d.ts +36 -0
  108. package/dist/rag/service.d.ts.map +1 -0
  109. package/dist/rag/types.d.ts +56 -0
  110. package/dist/rag/types.d.ts.map +1 -0
  111. package/dist/vector-store/index.d.ts +6 -0
  112. package/dist/vector-store/index.d.ts.map +1 -0
  113. package/dist/vector-store/stores/memory-store.d.ts +17 -0
  114. package/dist/vector-store/stores/memory-store.d.ts.map +1 -0
  115. package/dist/vector-store/stores/pinecone-store.d.ts +27 -0
  116. package/dist/vector-store/stores/pinecone-store.d.ts.map +1 -0
  117. package/dist/vector-store/stores/qdrant-store.d.ts +29 -0
  118. package/dist/vector-store/stores/qdrant-store.d.ts.map +1 -0
  119. package/dist/vector-store/types.d.ts +60 -0
  120. package/dist/vector-store/types.d.ts.map +1 -0
  121. package/dist/vector-store/vector-store-module.d.ts +20 -0
  122. package/dist/vector-store/vector-store-module.d.ts.map +1 -0
  123. package/docs/ai.md +500 -0
  124. package/docs/best-practices.md +83 -8
  125. package/docs/database.md +23 -0
  126. package/docs/guide.md +90 -27
  127. package/docs/migration.md +81 -7
  128. package/docs/security.md +23 -0
  129. package/docs/zh/ai.md +441 -0
  130. package/docs/zh/best-practices.md +43 -0
  131. package/docs/zh/database.md +23 -0
  132. package/docs/zh/guide.md +40 -1
  133. package/docs/zh/migration.md +39 -0
  134. package/docs/zh/security.md +23 -0
  135. package/package.json +3 -3
  136. package/src/ai/ai-module.ts +62 -0
  137. package/src/ai/decorators.ts +30 -0
  138. package/src/ai/errors.ts +71 -0
  139. package/src/ai/index.ts +11 -0
  140. package/src/ai/providers/anthropic-provider.ts +190 -0
  141. package/src/ai/providers/google-provider.ts +179 -0
  142. package/src/ai/providers/ollama-provider.ts +126 -0
  143. package/src/ai/providers/openai-provider.ts +242 -0
  144. package/src/ai/service.ts +155 -0
  145. package/src/ai/tools/tool-executor.ts +38 -0
  146. package/src/ai/tools/tool-registry.ts +91 -0
  147. package/src/ai/types.ts +145 -0
  148. package/src/ai-guard/ai-guard-module.ts +50 -0
  149. package/src/ai-guard/decorators.ts +21 -0
  150. package/src/ai-guard/detectors/content-moderator.ts +80 -0
  151. package/src/ai-guard/detectors/injection-detector.ts +48 -0
  152. package/src/ai-guard/detectors/pii-detector.ts +64 -0
  153. package/src/ai-guard/index.ts +7 -0
  154. package/src/ai-guard/service.ts +100 -0
  155. package/src/ai-guard/types.ts +61 -0
  156. package/src/conversation/conversation-module.ts +63 -0
  157. package/src/conversation/decorators.ts +47 -0
  158. package/src/conversation/index.ts +7 -0
  159. package/src/conversation/service.ts +133 -0
  160. package/src/conversation/stores/database-store.ts +125 -0
  161. package/src/conversation/stores/memory-store.ts +57 -0
  162. package/src/conversation/stores/redis-store.ts +101 -0
  163. package/src/conversation/types.ts +68 -0
  164. package/src/embedding/embedding-module.ts +52 -0
  165. package/src/embedding/index.ts +5 -0
  166. package/src/embedding/providers/ollama-embedding-provider.ts +39 -0
  167. package/src/embedding/providers/openai-embedding-provider.ts +47 -0
  168. package/src/embedding/service.ts +55 -0
  169. package/src/embedding/types.ts +27 -0
  170. package/src/index.ts +10 -0
  171. package/src/mcp/decorators.ts +60 -0
  172. package/src/mcp/index.ts +5 -0
  173. package/src/mcp/mcp-module.ts +58 -0
  174. package/src/mcp/registry.ts +72 -0
  175. package/src/mcp/server.ts +164 -0
  176. package/src/mcp/types.ts +63 -0
  177. package/src/prompt/index.ts +5 -0
  178. package/src/prompt/prompt-module.ts +61 -0
  179. package/src/prompt/service.ts +93 -0
  180. package/src/prompt/stores/file-store.ts +135 -0
  181. package/src/prompt/stores/memory-store.ts +82 -0
  182. package/src/prompt/types.ts +84 -0
  183. package/src/rag/chunkers/markdown-chunker.ts +40 -0
  184. package/src/rag/chunkers/text-chunker.ts +30 -0
  185. package/src/rag/decorators.ts +26 -0
  186. package/src/rag/index.ts +6 -0
  187. package/src/rag/rag-module.ts +78 -0
  188. package/src/rag/service.ts +134 -0
  189. package/src/rag/types.ts +47 -0
  190. package/src/vector-store/index.ts +5 -0
  191. package/src/vector-store/stores/memory-store.ts +69 -0
  192. package/src/vector-store/stores/pinecone-store.ts +123 -0
  193. package/src/vector-store/stores/qdrant-store.ts +147 -0
  194. package/src/vector-store/types.ts +77 -0
  195. package/src/vector-store/vector-store-module.ts +50 -0
  196. package/tests/ai/ai-module.test.ts +46 -0
  197. package/tests/ai/ai-service.test.ts +91 -0
  198. package/tests/ai/tool-registry.test.ts +57 -0
  199. package/tests/ai-guard/ai-guard-module.test.ts +23 -0
  200. package/tests/ai-guard/content-moderator.test.ts +65 -0
  201. package/tests/ai-guard/pii-detector.test.ts +41 -0
  202. package/tests/conversation/conversation-module.test.ts +26 -0
  203. package/tests/conversation/conversation-service.test.ts +64 -0
  204. package/tests/conversation/memory-store.test.ts +68 -0
  205. package/tests/embedding/embedding-service.test.ts +55 -0
  206. package/tests/mcp/mcp-server.test.ts +85 -0
  207. package/tests/prompt/prompt-module.test.ts +30 -0
  208. package/tests/prompt/prompt-service.test.ts +74 -0
  209. package/tests/rag/chunkers.test.ts +58 -0
  210. package/tests/rag/rag-service.test.ts +66 -0
  211. package/tests/vector-store/memory-vector-store.test.ts +84 -0
  212. package/tests/interceptor/perf/interceptor-performance.test.ts +0 -340
  213. package/tests/perf/optimization.test.ts +0 -182
  214. package/tests/perf/regression.test.ts +0 -120
@@ -1,340 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import { PerformanceHarness } from '../../../src/testing/harness';
4
- import { InterceptorRegistry } from '../../../src/interceptor/interceptor-registry';
5
- import { InterceptorChain } from '../../../src/interceptor/interceptor-chain';
6
- import type { Interceptor } from '../../../src/interceptor/types';
7
- import type { Container } from '../../../src/di/container';
8
- import type { Context } from '../../../src/core/context';
9
- import { Container as DIContainer } from '../../../src/di/container';
10
-
11
- /**
12
- * 简单的无操作拦截器,用于性能测试
13
- */
14
- class NoOpInterceptor implements Interceptor {
15
- public async execute<T>(
16
- target: unknown,
17
- propertyKey: string | symbol,
18
- originalMethod: (...args: unknown[]) => T | Promise<T>,
19
- args: unknown[],
20
- container: Container,
21
- context?: Context,
22
- ): Promise<T> {
23
- return await Promise.resolve(originalMethod.apply(target, args));
24
- }
25
- }
26
-
27
- /**
28
- * 简单的同步拦截器,用于性能测试
29
- */
30
- class SyncInterceptor implements Interceptor {
31
- public async execute<T>(
32
- target: unknown,
33
- propertyKey: string | symbol,
34
- originalMethod: (...args: unknown[]) => T | Promise<T>,
35
- args: unknown[],
36
- container: Container,
37
- context?: Context,
38
- ): Promise<T> {
39
- // 简单的同步操作
40
- const _ = propertyKey.toString();
41
- return await Promise.resolve(originalMethod.apply(target, args));
42
- }
43
- }
44
-
45
- /**
46
- * 测试目标类
47
- */
48
- class TestTarget {
49
- public value = 0;
50
-
51
- public async method(arg: number): Promise<number> {
52
- this.value += arg;
53
- return this.value;
54
- }
55
-
56
- public syncMethod(arg: number): number {
57
- this.value += arg;
58
- return this.value;
59
- }
60
- }
61
-
62
- describe('Interceptor Performance', () => {
63
- const container = new DIContainer();
64
- const registry = new InterceptorRegistry();
65
- const metadataKey = Symbol('test');
66
-
67
- describe('Single Interceptor Performance', () => {
68
- test('should benchmark single interceptor execution', async () => {
69
- const interceptor = new NoOpInterceptor();
70
- const target = new TestTarget();
71
- const originalMethod = target.method.bind(target);
72
-
73
- const result = await PerformanceHarness.benchmark(
74
- 'single-interceptor',
75
- 10000,
76
- async () => {
77
- await interceptor.execute(
78
- target,
79
- 'method',
80
- originalMethod,
81
- [1],
82
- container,
83
- );
84
- },
85
- );
86
-
87
- expect(result.iterations).toBe(10000);
88
- expect(result.opsPerSecond).toBeGreaterThan(1000);
89
- expect(result.durationMs).toBeLessThan(10000);
90
-
91
- console.log(`Single Interceptor: ${result.opsPerSecond.toFixed(2)} ops/sec`);
92
- });
93
-
94
- test('should benchmark interceptor chain with 1 interceptor', async () => {
95
- const interceptor = new NoOpInterceptor();
96
- const target = new TestTarget();
97
- const originalMethod = target.method.bind(target);
98
-
99
- const result = await PerformanceHarness.benchmark(
100
- 'chain-1-interceptor',
101
- 10000,
102
- async () => {
103
- await InterceptorChain.execute(
104
- [interceptor],
105
- target,
106
- 'method',
107
- originalMethod,
108
- [1],
109
- container,
110
- );
111
- },
112
- );
113
-
114
- expect(result.iterations).toBe(10000);
115
- expect(result.opsPerSecond).toBeGreaterThan(1000);
116
- expect(result.durationMs).toBeLessThan(10000);
117
-
118
- console.log(`Chain (1 interceptor): ${result.opsPerSecond.toFixed(2)} ops/sec`);
119
- });
120
- });
121
-
122
- describe('Interceptor Chain Performance', () => {
123
- test('should benchmark interceptor chain with 3 interceptors', async () => {
124
- const interceptors = [
125
- new NoOpInterceptor(),
126
- new NoOpInterceptor(),
127
- new NoOpInterceptor(),
128
- ];
129
- const target = new TestTarget();
130
- const originalMethod = target.method.bind(target);
131
-
132
- const result = await PerformanceHarness.benchmark(
133
- 'chain-3-interceptors',
134
- 10000,
135
- async () => {
136
- await InterceptorChain.execute(
137
- interceptors,
138
- target,
139
- 'method',
140
- originalMethod,
141
- [1],
142
- container,
143
- );
144
- },
145
- );
146
-
147
- expect(result.iterations).toBe(10000);
148
- expect(result.opsPerSecond).toBeGreaterThan(500);
149
- expect(result.durationMs).toBeLessThan(20000);
150
-
151
- console.log(`Chain (3 interceptors): ${result.opsPerSecond.toFixed(2)} ops/sec`);
152
- });
153
-
154
- test('should benchmark interceptor chain with 5 interceptors', async () => {
155
- const interceptors = Array.from({ length: 5 }, () => new NoOpInterceptor());
156
- const target = new TestTarget();
157
- const originalMethod = target.method.bind(target);
158
-
159
- const result = await PerformanceHarness.benchmark(
160
- 'chain-5-interceptors',
161
- 10000,
162
- async () => {
163
- await InterceptorChain.execute(
164
- interceptors,
165
- target,
166
- 'method',
167
- originalMethod,
168
- [1],
169
- container,
170
- );
171
- },
172
- );
173
-
174
- expect(result.iterations).toBe(10000);
175
- expect(result.opsPerSecond).toBeGreaterThan(300);
176
- expect(result.durationMs).toBeLessThan(35000);
177
-
178
- console.log(`Chain (5 interceptors): ${result.opsPerSecond.toFixed(2)} ops/sec`);
179
- });
180
-
181
- test('should benchmark interceptor chain with 10 interceptors', async () => {
182
- const interceptors = Array.from({ length: 10 }, () => new NoOpInterceptor());
183
- const target = new TestTarget();
184
- const originalMethod = target.method.bind(target);
185
-
186
- const result = await PerformanceHarness.benchmark(
187
- 'chain-10-interceptors',
188
- 10000,
189
- async () => {
190
- await InterceptorChain.execute(
191
- interceptors,
192
- target,
193
- 'method',
194
- originalMethod,
195
- [1],
196
- container,
197
- );
198
- },
199
- );
200
-
201
- expect(result.iterations).toBe(10000);
202
- expect(result.opsPerSecond).toBeGreaterThan(200);
203
- expect(result.durationMs).toBeLessThan(50000);
204
-
205
- console.log(`Chain (10 interceptors): ${result.opsPerSecond.toFixed(2)} ops/sec`);
206
- });
207
- });
208
-
209
- describe('Performance Comparison', () => {
210
- test('should compare direct method call vs interceptor chain', async () => {
211
- const target = new TestTarget();
212
- const originalMethod = target.method.bind(target);
213
- const interceptors = [new NoOpInterceptor()];
214
-
215
- // 直接方法调用
216
- const directResult = await PerformanceHarness.benchmark(
217
- 'direct-method-call',
218
- 10000,
219
- async () => {
220
- await originalMethod(1);
221
- },
222
- );
223
-
224
- // 拦截器链调用
225
- const interceptorResult = await PerformanceHarness.benchmark(
226
- 'interceptor-chain',
227
- 10000,
228
- async () => {
229
- await InterceptorChain.execute(
230
- interceptors,
231
- target,
232
- 'method',
233
- originalMethod,
234
- [1],
235
- container,
236
- );
237
- },
238
- );
239
-
240
- expect(directResult.iterations).toBe(10000);
241
- expect(interceptorResult.iterations).toBe(10000);
242
-
243
- const overhead = (interceptorResult.durationMs / directResult.durationMs - 1) * 100;
244
-
245
- console.log(`Direct call: ${directResult.opsPerSecond.toFixed(2)} ops/sec`);
246
- console.log(`Interceptor chain: ${interceptorResult.opsPerSecond.toFixed(2)} ops/sec`);
247
- console.log(`Overhead: ${overhead.toFixed(2)}%`);
248
-
249
- // 拦截器开销应该小于 400%(即不超过 5 倍)
250
- // 实际测试显示开销约为 275%,这是合理的,因为需要额外的函数调用和参数传递
251
- expect(overhead).toBeLessThan(400);
252
- });
253
-
254
- test('should compare sync method call vs interceptor chain', async () => {
255
- const target = new TestTarget();
256
- const originalMethod = target.syncMethod.bind(target);
257
- const interceptors = [new SyncInterceptor()];
258
-
259
- // 直接方法调用
260
- const directResult = await PerformanceHarness.benchmark(
261
- 'direct-sync-call',
262
- 100000,
263
- async () => {
264
- originalMethod(1);
265
- },
266
- );
267
-
268
- // 拦截器链调用
269
- const interceptorResult = await PerformanceHarness.benchmark(
270
- 'interceptor-sync-chain',
271
- 100000,
272
- async () => {
273
- await InterceptorChain.execute(
274
- interceptors,
275
- target,
276
- 'syncMethod',
277
- originalMethod,
278
- [1],
279
- container,
280
- );
281
- },
282
- );
283
-
284
- expect(directResult.iterations).toBe(100000);
285
- expect(interceptorResult.iterations).toBe(100000);
286
-
287
- const overhead = (interceptorResult.durationMs / directResult.durationMs - 1) * 100;
288
-
289
- console.log(`Direct sync call: ${directResult.opsPerSecond.toFixed(2)} ops/sec`);
290
- console.log(`Interceptor sync chain: ${interceptorResult.opsPerSecond.toFixed(2)} ops/sec`);
291
- console.log(`Overhead: ${overhead.toFixed(2)}%`);
292
-
293
- // 拦截器开销应该小于 1000%(即不超过 11 倍)
294
- // 同步方法转换为异步会有额外开销,实际测试显示开销约为 656-870%
295
- // 性能测试结果可能有波动,使用更宽松的阈值以确保测试稳定性
296
- expect(overhead).toBeLessThan(1000);
297
- });
298
- });
299
-
300
- describe('Registry Performance', () => {
301
- test('should benchmark interceptor registry operations', async () => {
302
- const result = await PerformanceHarness.benchmark(
303
- 'registry-register',
304
- 10000,
305
- async (iteration) => {
306
- const key = Symbol(`test-${iteration}`);
307
- registry.register(key, new NoOpInterceptor(), 100);
308
- },
309
- );
310
-
311
- expect(result.iterations).toBe(10000);
312
- expect(result.opsPerSecond).toBeGreaterThan(1000);
313
-
314
- console.log(`Registry register: ${result.opsPerSecond.toFixed(2)} ops/sec`);
315
- });
316
-
317
- test('should benchmark interceptor registry lookup', async () => {
318
- // 预先注册一些拦截器
319
- const keys = Array.from({ length: 100 }, (_, i) => Symbol(`key-${i}`));
320
- for (const key of keys) {
321
- registry.register(key, new NoOpInterceptor(), 100);
322
- }
323
-
324
- const result = await PerformanceHarness.benchmark(
325
- 'registry-lookup',
326
- 10000,
327
- async (iteration) => {
328
- const key = keys[iteration % keys.length];
329
- registry.getInterceptors(key);
330
- },
331
- );
332
-
333
- expect(result.iterations).toBe(10000);
334
- expect(result.opsPerSecond).toBeGreaterThan(5000);
335
-
336
- console.log(`Registry lookup: ${result.opsPerSecond.toFixed(2)} ops/sec`);
337
- });
338
- });
339
- });
340
-
@@ -1,182 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { Router } from '../../src/router/router';
3
- import { Context } from '../../src/core/context';
4
- import { MiddlewarePipeline } from '../../src/middleware/pipeline';
5
- import { Container } from '../../src/di/container';
6
- import { Injectable, Inject } from '../../src/di/decorators';
7
- import { PerformanceHarness } from '../../src/testing/harness';
8
-
9
- /**
10
- * 性能优化验证测试
11
- * 验证路由匹配缓存、中间件管道优化、DI 容器优化的效果
12
- */
13
-
14
- describe('Performance Optimization Tests', () => {
15
- test('route matching cache should improve performance', async () => {
16
- // 创建两个独立的 router 实例,确保测试准确性
17
- const createRouter = () => {
18
- const r = new Router();
19
- // 注册多个路由
20
- for (let i = 0; i < 100; i++) {
21
- r.get(`/api/users/${i}`, (ctx: Context) => ctx.createResponse({ id: i }));
22
- }
23
- // 注册动态路由(这个路由会在最后匹配,因为前面有100个静态路由)
24
- r.get('/api/users/:id', (ctx: Context) => ctx.createResponse({ id: ctx.getParam('id') }));
25
- return r;
26
- };
27
-
28
- // 第一次匹配(无缓存)- 每次迭代都创建新的 router,确保没有缓存
29
- const result1 = await PerformanceHarness.benchmark(
30
- 'route match (first, no cache)',
31
- 10000,
32
- async () => {
33
- const r = createRouter();
34
- return r.findRoute('GET', '/api/users/123');
35
- },
36
- );
37
-
38
- // 第二次匹配(有缓存)- 使用同一个 router 实例,缓存已建立
39
- const router2 = createRouter();
40
- // 预热缓存
41
- router2.findRoute('GET', '/api/users/123');
42
-
43
- const result2 = await PerformanceHarness.benchmark(
44
- 'route match (cached)',
45
- 10000,
46
- async () => {
47
- return router2.findRoute('GET', '/api/users/123');
48
- },
49
- );
50
-
51
- // 缓存后的性能应该更好或至少相当(允许一定的性能波动)
52
- // 使用更宽松的断言:缓存版本不应该明显更慢(允许15%的性能波动)
53
- // 因为性能测试本身存在波动性,特别是在高频操作时
54
- const performanceRatio = result2.durationMs / result1.durationMs;
55
- expect(performanceRatio).toBeLessThanOrEqual(1.15); // 缓存版本不应该比无缓存版本慢超过15%
56
-
57
- // 验证缓存确实被使用:缓存版本的性能应该至少相当
58
- expect(result2.opsPerSecond).toBeGreaterThan(result1.opsPerSecond * 0.85);
59
- });
60
-
61
- test('middleware pipeline optimization should reduce memory allocation', async () => {
62
- const pipeline = new MiddlewarePipeline();
63
-
64
- // 添加多个中间件
65
- for (let i = 0; i < 50; i++) {
66
- pipeline.use(async (ctx, next) => {
67
- return await next();
68
- });
69
- }
70
-
71
- const context = new Context(new Request('http://localhost:3000/test'));
72
-
73
- const result = await PerformanceHarness.benchmark(
74
- 'middleware pipeline',
75
- 1000,
76
- async () => {
77
- return await pipeline.run(context, async () => {
78
- return new Response('ok');
79
- });
80
- },
81
- );
82
-
83
- // 优化后的中间件管道应该快速执行
84
- expect(result.durationMs).toBeLessThan(1000); // 1000次操作应该在1秒内完成
85
- expect(result.opsPerSecond).toBeGreaterThan(1000);
86
- });
87
-
88
- test('DI container dependency plan cache should improve resolution', async () => {
89
- @Injectable()
90
- class Level1 {
91
- public name = 'level1';
92
- }
93
-
94
- @Injectable()
95
- class Level2 {
96
- public constructor(@Inject(Level1) public level1: Level1) {}
97
- }
98
-
99
- @Injectable()
100
- class Level3 {
101
- public constructor(@Inject(Level2) public level2: Level2) {}
102
- }
103
-
104
- const container = new Container();
105
- container.register(Level1);
106
- container.register(Level2);
107
- container.register(Level3);
108
-
109
- // 第一次解析(构建依赖计划)
110
- const result1 = await PerformanceHarness.benchmark(
111
- 'DI resolve (first, build plan)',
112
- 1000,
113
- () => {
114
- return container.resolve(Level3);
115
- },
116
- );
117
-
118
- // 第二次解析(使用缓存的依赖计划)
119
- const result2 = await PerformanceHarness.benchmark(
120
- 'DI resolve (cached plan)',
121
- 1000,
122
- () => {
123
- return container.resolve(Level3);
124
- },
125
- );
126
-
127
- // 使用缓存计划后的性能应该更好(虽然单例也会影响)
128
- // 主要验证不会退化
129
- expect(result2.durationMs).toBeLessThanOrEqual(result1.durationMs * 1.5);
130
- expect(result2.opsPerSecond).toBeGreaterThan(5000);
131
- });
132
-
133
- test('router should handle many routes efficiently', async () => {
134
- const router = new Router();
135
-
136
- // 注册大量路由
137
- for (let i = 0; i < 1000; i++) {
138
- router.get(`/api/items/${i}`, (ctx: Context) => ctx.createResponse({ id: i }));
139
- }
140
-
141
- const context = new Context(new Request('http://localhost:3000/api/items/500'));
142
-
143
- const result = await PerformanceHarness.benchmark(
144
- 'router with many routes',
145
- 100,
146
- async () => {
147
- return router.findRoute('GET', '/api/items/500');
148
- },
149
- );
150
-
151
- // 即使有大量路由,匹配应该快速完成
152
- expect(result.durationMs).toBeLessThan(500); // 100次操作应该在500ms内完成
153
- expect(result.opsPerSecond).toBeGreaterThan(200);
154
- });
155
-
156
- test('middleware pipeline should handle many middlewares efficiently', async () => {
157
- const pipeline = new MiddlewarePipeline();
158
-
159
- // 添加大量中间件
160
- for (let i = 0; i < 200; i++) {
161
- pipeline.use(async (ctx, next) => {
162
- return await next();
163
- });
164
- }
165
-
166
- const context = new Context(new Request('http://localhost:3000/test'));
167
-
168
- const result = await PerformanceHarness.benchmark(
169
- 'middleware pipeline (many middlewares)',
170
- 100,
171
- async () => {
172
- return await pipeline.run(context, async () => {
173
- return new Response('ok');
174
- });
175
- },
176
- );
177
-
178
- // 即使有大量中间件,执行应该快速完成
179
- expect(result.durationMs).toBeLessThan(2000); // 100次操作应该在2秒内完成
180
- expect(result.opsPerSecond).toBeGreaterThan(50);
181
- });
182
- });
@@ -1,120 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { Application } from '../../src/core/application';
3
- import { RouteRegistry } from '../../src/router/registry';
4
- import { Context } from '../../src/core/context';
5
- import { PerformanceHarness } from '../../src/testing/harness';
6
- import { getTestPort } from '../utils/test-port';
7
-
8
- /**
9
- * 性能回归测试
10
- * 确保关键路径的性能不会退化
11
- */
12
- describe('Performance Regression Tests', () => {
13
- test('router handle should be fast', async () => {
14
- const registry = RouteRegistry.getInstance();
15
- registry.get('/api/test', (ctx: Context) => {
16
- return ctx.createResponse({ message: 'ok' });
17
- });
18
-
19
- const router = registry.getRouter();
20
- const context = new Context(
21
- new Request('http://localhost:3000/api/test'),
22
- );
23
- context.params = {};
24
-
25
- const result = await PerformanceHarness.benchmark(
26
- 'router handle',
27
- 1000,
28
- async () => {
29
- await router.preHandle(context);
30
- return await router.handle(context);
31
- },
32
- );
33
-
34
- // 路由处理应该快速完成
35
- expect(result.durationMs).toBeLessThan(1000); // 1000次操作应该在1秒内完成
36
- expect(result.opsPerSecond).toBeGreaterThan(1000);
37
- });
38
-
39
- test('application request handling should be fast', async () => {
40
- const port = getTestPort();
41
- const app = new Application({ port });
42
- const registry = RouteRegistry.getInstance();
43
- registry.get('/api/ping', (ctx: Context) => {
44
- return ctx.createResponse({ status: 'ok' });
45
- });
46
-
47
- await app.listen();
48
-
49
- try {
50
- const result = await PerformanceHarness.benchmark(
51
- 'application request',
52
- 100,
53
- async () => {
54
- const response = await fetch(`http://localhost:${port}/api/ping`);
55
- await response.text();
56
- return response;
57
- },
58
- );
59
-
60
- // HTTP 请求处理应该快速完成(包含网络开销)
61
- expect(result.durationMs).toBeLessThan(2000); // 100次请求应该在2秒内完成
62
- expect(result.opsPerSecond).toBeGreaterThan(50);
63
- } finally {
64
- await app.stop();
65
- }
66
- });
67
-
68
- test('DI container resolve should be fast', async () => {
69
- const { Container } = await import('../../src/di/container');
70
- const { Injectable } = await import('../../src/di/decorators');
71
-
72
- @Injectable()
73
- class TestService {
74
- public value = 'test';
75
- }
76
-
77
- const container = new Container();
78
- container.register(TestService);
79
-
80
- const result = await PerformanceHarness.benchmark(
81
- 'DI resolve',
82
- 10000,
83
- () => {
84
- return container.resolve(TestService);
85
- },
86
- );
87
-
88
- // DI 解析应该非常快(单例缓存)
89
- expect(result.durationMs).toBeLessThan(100); // 10000次解析应该在100ms内完成
90
- expect(result.opsPerSecond).toBeGreaterThan(10000);
91
- });
92
-
93
- test('middleware pipeline should be fast', async () => {
94
- const { MiddlewarePipeline } = await import('../../src/middleware/pipeline');
95
- const { Context } = await import('../../src/core/context');
96
-
97
- const pipeline = new MiddlewarePipeline();
98
- pipeline.use(async (ctx, next) => {
99
- return await next();
100
- });
101
- pipeline.use(async (ctx, next) => {
102
- return await next();
103
- });
104
-
105
- const context = new Context(new Request('http://localhost:3000/test'));
106
- const result = await PerformanceHarness.benchmark(
107
- 'middleware pipeline',
108
- 1000,
109
- async () => {
110
- return await pipeline.run(context, async () => {
111
- return new Response('ok');
112
- });
113
- },
114
- );
115
-
116
- // 中间件管道应该快速完成
117
- expect(result.durationMs).toBeLessThan(500); // 1000次操作应该在500ms内完成
118
- expect(result.opsPerSecond).toBeGreaterThan(1000);
119
- });
120
- });