vafast 0.3.2 → 0.3.4

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 (136) hide show
  1. package/dist/auth/token.d.ts +13 -11
  2. package/dist/auth/token.js +118 -111
  3. package/dist/auth/token.js.map +1 -0
  4. package/dist/defineRoute.d.ts +5 -2
  5. package/dist/defineRoute.js +7 -2
  6. package/dist/defineRoute.js.map +1 -0
  7. package/dist/index.d.ts +30 -14
  8. package/dist/index.js +2247 -15
  9. package/dist/index.js.map +1 -0
  10. package/dist/middleware/auth.d.ts +8 -6
  11. package/dist/middleware/auth.js +198 -99
  12. package/dist/middleware/auth.js.map +1 -0
  13. package/dist/middleware/authMiddleware.d.ts +5 -2
  14. package/dist/middleware/authMiddleware.js +55 -11
  15. package/dist/middleware/authMiddleware.js.map +1 -0
  16. package/dist/middleware/component-renderer.d.ts +4 -2
  17. package/dist/middleware/component-renderer.js +87 -80
  18. package/dist/middleware/component-renderer.js.map +1 -0
  19. package/dist/middleware/component-router.d.ts +8 -3
  20. package/dist/middleware/component-router.js +33 -39
  21. package/dist/middleware/component-router.js.map +1 -0
  22. package/dist/middleware/cors.d.ts +6 -3
  23. package/dist/middleware/cors.js +42 -29
  24. package/dist/middleware/cors.js.map +1 -0
  25. package/dist/middleware/rateLimit.d.ts +5 -3
  26. package/dist/middleware/rateLimit.js +45 -29
  27. package/dist/middleware/rateLimit.js.map +1 -0
  28. package/dist/middleware.d.ts +6 -3
  29. package/dist/middleware.js +97 -51
  30. package/dist/middleware.js.map +1 -0
  31. package/dist/monitoring/index.d.ts +11 -4
  32. package/dist/monitoring/index.js +1299 -17
  33. package/dist/monitoring/index.js.map +1 -0
  34. package/dist/monitoring/native-monitor.d.ts +12 -6
  35. package/dist/monitoring/native-monitor.js +1258 -161
  36. package/dist/monitoring/native-monitor.js.map +1 -0
  37. package/dist/monitoring/types.d.ts +8 -6
  38. package/dist/monitoring/types.js +1 -1
  39. package/dist/monitoring/types.js.map +1 -0
  40. package/dist/node-server/index.d.ts +4 -22
  41. package/dist/node-server/index.js +254 -21
  42. package/dist/node-server/index.js.map +1 -0
  43. package/dist/node-server/request.d.ts +6 -2
  44. package/dist/node-server/request.js +102 -134
  45. package/dist/node-server/request.js.map +1 -0
  46. package/dist/node-server/response.d.ts +7 -3
  47. package/dist/node-server/response.js +67 -89
  48. package/dist/node-server/response.js.map +1 -0
  49. package/dist/node-server/serve.d.ts +11 -7
  50. package/dist/node-server/serve.js +231 -82
  51. package/dist/node-server/serve.js.map +1 -0
  52. package/dist/router/index.d.ts +3 -5
  53. package/dist/router/index.js +228 -7
  54. package/dist/router/index.js.map +1 -0
  55. package/dist/router/radix-tree.d.ts +7 -4
  56. package/dist/router/radix-tree.js +186 -218
  57. package/dist/router/radix-tree.js.map +1 -0
  58. package/dist/router.d.ts +7 -3
  59. package/dist/router.js +37 -83
  60. package/dist/router.js.map +1 -0
  61. package/dist/serve.d.ts +2 -12
  62. package/dist/serve.js +237 -11
  63. package/dist/serve.js.map +1 -0
  64. package/dist/server/base-server.d.ts +5 -2
  65. package/dist/server/base-server.js +124 -135
  66. package/dist/server/base-server.js.map +1 -0
  67. package/dist/server/component-server.d.ts +9 -4
  68. package/dist/server/component-server.js +481 -139
  69. package/dist/server/component-server.js.map +1 -0
  70. package/dist/server/index.d.ts +8 -7
  71. package/dist/server/index.js +985 -11
  72. package/dist/server/index.js.map +1 -0
  73. package/dist/server/server-factory.d.ts +11 -5
  74. package/dist/server/server-factory.js +979 -67
  75. package/dist/server/server-factory.js.map +1 -0
  76. package/dist/server/server.d.ts +7 -3
  77. package/dist/server/server.js +553 -112
  78. package/dist/server/server.js.map +1 -0
  79. package/dist/types/component-route.d.ts +8 -4
  80. package/dist/types/component-route.js +1 -1
  81. package/dist/types/component-route.js.map +1 -0
  82. package/dist/types/index.d.ts +5 -5
  83. package/dist/types/index.js +21 -4
  84. package/dist/types/index.js.map +1 -0
  85. package/dist/types/route.d.ts +13 -10
  86. package/dist/types/route.js +10 -9
  87. package/dist/types/route.js.map +1 -0
  88. package/dist/types/schema.d.ts +11 -7
  89. package/dist/types/schema.js +1 -1
  90. package/dist/types/schema.js.map +1 -0
  91. package/dist/types/types.d.ts +11 -9
  92. package/dist/types/types.js +1 -1
  93. package/dist/types/types.js.map +1 -0
  94. package/dist/utils/base64url.d.ts +4 -2
  95. package/dist/utils/base64url.js +12 -9
  96. package/dist/utils/base64url.js.map +1 -0
  97. package/dist/utils/create-handler.d.ts +11 -7
  98. package/dist/utils/create-handler.js +393 -217
  99. package/dist/utils/create-handler.js.map +1 -0
  100. package/dist/utils/dependency-manager.d.ts +3 -1
  101. package/dist/utils/dependency-manager.js +67 -69
  102. package/dist/utils/dependency-manager.js.map +1 -0
  103. package/dist/utils/go-await.d.ts +3 -1
  104. package/dist/utils/go-await.js +8 -22
  105. package/dist/utils/go-await.js.map +1 -0
  106. package/dist/utils/handle.d.ts +6 -4
  107. package/dist/utils/handle.js +44 -25
  108. package/dist/utils/handle.js.map +1 -0
  109. package/dist/utils/html-renderer.d.ts +3 -1
  110. package/dist/utils/html-renderer.js +25 -24
  111. package/dist/utils/html-renderer.js.map +1 -0
  112. package/dist/utils/index.d.ts +13 -13
  113. package/dist/utils/index.js +832 -21
  114. package/dist/utils/index.js.map +1 -0
  115. package/dist/utils/parsers.d.ts +15 -13
  116. package/dist/utils/parsers.js +138 -188
  117. package/dist/utils/parsers.js.map +1 -0
  118. package/dist/utils/path-matcher.d.ts +3 -1
  119. package/dist/utils/path-matcher.js +68 -78
  120. package/dist/utils/path-matcher.js.map +1 -0
  121. package/dist/utils/request-validator.d.ts +13 -10
  122. package/dist/utils/request-validator.js +234 -84
  123. package/dist/utils/request-validator.js.map +1 -0
  124. package/dist/utils/response.d.ts +9 -7
  125. package/dist/utils/response.js +93 -102
  126. package/dist/utils/response.js.map +1 -0
  127. package/dist/utils/validators/schema-validator.d.ts +13 -9
  128. package/dist/utils/validators/schema-validator.js +228 -209
  129. package/dist/utils/validators/schema-validator.js.map +1 -0
  130. package/dist/utils/validators/schema-validators-ultra.d.ts +15 -12
  131. package/dist/utils/validators/schema-validators-ultra.js +233 -256
  132. package/dist/utils/validators/schema-validators-ultra.js.map +1 -0
  133. package/dist/utils/validators/validators.d.ts +15 -12
  134. package/dist/utils/validators/validators.js +81 -122
  135. package/dist/utils/validators/validators.js.map +1 -0
  136. package/package.json +5 -4
package/dist/serve.js CHANGED
@@ -1,11 +1,237 @@
1
- /**
2
- * 统一的 serve 函数
3
- * 使用 Node.js 原生 http 模块,兼容 Bun 和 Node.js
4
- *
5
- * 基准测试结果(Bun 环境):
6
- * - Bun.serve: 35,422 req/s
7
- * - node:http: 38,075 req/s
8
- *
9
- * node:http Bun 下性能甚至更好,无需使用 Bun API
10
- */
11
- export { serve, createAdaptorServer } from "./node-server/serve";
1
+ // src/node-server/serve.ts
2
+ import {
3
+ createServer
4
+ } from "http";
5
+
6
+ // src/node-server/request.ts
7
+ import { Readable } from "stream";
8
+ var requestCache = /* @__PURE__ */ Symbol("requestCache");
9
+ var incomingKey = /* @__PURE__ */ Symbol("incoming");
10
+ var urlKey = /* @__PURE__ */ Symbol("url");
11
+ var headersKey = /* @__PURE__ */ Symbol("headers");
12
+ function parseHeaders(rawHeaders) {
13
+ const headers = new Headers();
14
+ for (let i = 0; i < rawHeaders.length; i += 2) {
15
+ const key = rawHeaders[i];
16
+ const value = rawHeaders[i + 1];
17
+ if (key.charCodeAt(0) !== 58) {
18
+ headers.append(key, value);
19
+ }
20
+ }
21
+ return headers;
22
+ }
23
+ function toWebStream(nodeStream) {
24
+ return nodeStream;
25
+ }
26
+ function createRealRequest(proxy) {
27
+ const incoming = proxy[incomingKey];
28
+ const method = incoming.method || "GET";
29
+ const init = {
30
+ method,
31
+ headers: proxy[headersKey] || parseHeaders(incoming.rawHeaders)
32
+ };
33
+ if (method !== "GET" && method !== "HEAD") {
34
+ const nodeWebStream = Readable.toWeb(
35
+ incoming
36
+ );
37
+ init.body = toWebStream(nodeWebStream);
38
+ init.duplex = "half";
39
+ }
40
+ return new Request(proxy[urlKey], init);
41
+ }
42
+ var requestPrototype = {};
43
+ Object.defineProperty(requestPrototype, "method", {
44
+ get() {
45
+ const self = this;
46
+ return self[incomingKey].method || "GET";
47
+ },
48
+ enumerable: true
49
+ });
50
+ Object.defineProperty(requestPrototype, "url", {
51
+ get() {
52
+ const self = this;
53
+ return self[urlKey];
54
+ },
55
+ enumerable: true
56
+ });
57
+ Object.defineProperty(requestPrototype, "headers", {
58
+ get() {
59
+ const self = this;
60
+ if (!self[headersKey]) {
61
+ self[headersKey] = parseHeaders(self[incomingKey].rawHeaders);
62
+ }
63
+ return self[headersKey];
64
+ },
65
+ enumerable: true
66
+ });
67
+ Object.defineProperty(requestPrototype, "_getRequest", {
68
+ value: function() {
69
+ const self = this;
70
+ if (!self[requestCache]) {
71
+ self[requestCache] = createRealRequest(self);
72
+ }
73
+ return self[requestCache];
74
+ },
75
+ enumerable: false
76
+ });
77
+ var proxyGetters = [
78
+ "body",
79
+ "bodyUsed",
80
+ "signal",
81
+ "cache",
82
+ "credentials",
83
+ "destination",
84
+ "integrity",
85
+ "mode",
86
+ "redirect",
87
+ "referrer",
88
+ "referrerPolicy",
89
+ "keepalive"
90
+ ];
91
+ proxyGetters.forEach((key) => {
92
+ Object.defineProperty(requestPrototype, key, {
93
+ get() {
94
+ const self = this;
95
+ return self._getRequest()[key];
96
+ },
97
+ enumerable: true
98
+ });
99
+ });
100
+ var proxyMethods = [
101
+ "arrayBuffer",
102
+ "blob",
103
+ "clone",
104
+ "formData",
105
+ "json",
106
+ "text"
107
+ ];
108
+ proxyMethods.forEach((key) => {
109
+ Object.defineProperty(requestPrototype, key, {
110
+ value: function() {
111
+ const self = this;
112
+ const req = self._getRequest();
113
+ return req[key].call(req);
114
+ },
115
+ enumerable: true
116
+ });
117
+ });
118
+ Object.setPrototypeOf(requestPrototype, Request.prototype);
119
+ function createProxyRequest(incoming, defaultHost) {
120
+ const req = Object.create(requestPrototype);
121
+ req[incomingKey] = incoming;
122
+ const host = incoming.headers.host || defaultHost;
123
+ const protocol = incoming.socket.encrypted ? "https" : "http";
124
+ req[urlKey] = `${protocol}://${host}${incoming.url || "/"}`;
125
+ return req;
126
+ }
127
+
128
+ // src/node-server/response.ts
129
+ function buildOutgoingHeaders(headers) {
130
+ const result = {};
131
+ const cookies = [];
132
+ headers.forEach((value, key) => {
133
+ if (key === "set-cookie") {
134
+ cookies.push(value);
135
+ } else {
136
+ result[key] = value;
137
+ }
138
+ });
139
+ if (cookies.length > 0) {
140
+ result["set-cookie"] = cookies;
141
+ }
142
+ return result;
143
+ }
144
+ async function writeBodyStream(body, outgoing) {
145
+ const reader = body.getReader();
146
+ try {
147
+ while (true) {
148
+ const { done, value } = await reader.read();
149
+ if (done) {
150
+ break;
151
+ }
152
+ const canContinue = outgoing.write(value);
153
+ if (!canContinue) {
154
+ await new Promise((resolve) => {
155
+ outgoing.once("drain", resolve);
156
+ });
157
+ }
158
+ }
159
+ } finally {
160
+ reader.releaseLock();
161
+ }
162
+ }
163
+ async function writeResponse(response, outgoing) {
164
+ outgoing.statusCode = response.status;
165
+ const headers = buildOutgoingHeaders(response.headers);
166
+ for (const [key, value] of Object.entries(headers)) {
167
+ outgoing.setHeader(key, value);
168
+ }
169
+ const body = response.body;
170
+ if (!body) {
171
+ outgoing.end();
172
+ return;
173
+ }
174
+ try {
175
+ await writeBodyStream(body, outgoing);
176
+ outgoing.end();
177
+ } catch (error) {
178
+ if (!outgoing.destroyed) {
179
+ outgoing.destroy(
180
+ error instanceof Error ? error : new Error(String(error))
181
+ );
182
+ }
183
+ }
184
+ }
185
+
186
+ // src/node-server/serve.ts
187
+ function createRequestHandler(fetch, defaultHost, onError) {
188
+ return async (incoming, outgoing) => {
189
+ try {
190
+ const request = createProxyRequest(incoming, defaultHost);
191
+ const response = await fetch(request);
192
+ await writeResponse(response, outgoing);
193
+ } catch (error) {
194
+ const err = error instanceof Error ? error : new Error(String(error));
195
+ if (onError) {
196
+ try {
197
+ const errorResponse = await onError(err);
198
+ await writeResponse(errorResponse, outgoing);
199
+ return;
200
+ } catch {
201
+ }
202
+ }
203
+ if (!outgoing.headersSent) {
204
+ outgoing.statusCode = 500;
205
+ outgoing.setHeader("Content-Type", "text/plain");
206
+ outgoing.end("Internal Server Error");
207
+ }
208
+ }
209
+ };
210
+ }
211
+ function serve(options, callback) {
212
+ const { fetch, port = 3e3, hostname = "0.0.0.0", onError } = options;
213
+ const defaultHost = `${hostname === "0.0.0.0" ? "localhost" : hostname}:${port}`;
214
+ const handler = createRequestHandler(fetch, defaultHost, onError);
215
+ const server = createServer(handler);
216
+ server.listen(port, hostname, callback);
217
+ return {
218
+ server,
219
+ port,
220
+ hostname,
221
+ stop: () => new Promise((resolve, reject) => {
222
+ server.close((err) => {
223
+ if (err) reject(err);
224
+ else resolve();
225
+ });
226
+ })
227
+ };
228
+ }
229
+ function createAdaptorServer(fetch, onError) {
230
+ const handler = createRequestHandler(fetch, "localhost", onError);
231
+ return createServer(handler);
232
+ }
233
+ export {
234
+ createAdaptorServer,
235
+ serve
236
+ };
237
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/node-server/serve.ts","../src/node-server/request.ts","../src/node-server/response.ts"],"sourcesContent":["/**\n * Node.js 服务器适配器\n * 提供类似 Bun.serve 的 API\n */\n\nimport {\n createServer,\n type Server as HttpServer,\n type IncomingMessage,\n type ServerResponse,\n} from \"node:http\";\nimport { createProxyRequest } from \"./request\";\nimport { writeResponse } from \"./response\";\n\n/** fetch 函数类型 */\nexport type FetchHandler = (request: Request) => Response | Promise<Response>;\n\n/** serve 配置选项 */\nexport interface ServeOptions {\n /** fetch 处理函数 */\n fetch: FetchHandler;\n /** 端口号,默认 3000 */\n port?: number;\n /** 主机名,默认 0.0.0.0 */\n hostname?: string;\n /** 错误处理函数 */\n onError?: (error: Error) => Response | Promise<Response>;\n}\n\n/** serve 返回的服务器信息 */\nexport interface ServeResult {\n /** Node.js HTTP Server 实例 */\n server: HttpServer;\n /** 服务器端口 */\n port: number;\n /** 服务器主机名 */\n hostname: string;\n /** 关闭服务器 */\n stop: () => Promise<void>;\n}\n\n/**\n * 创建请求处理函数\n */\nfunction createRequestHandler(\n fetch: FetchHandler,\n defaultHost: string,\n onError?: (error: Error) => Response | Promise<Response>,\n) {\n return async (incoming: IncomingMessage, outgoing: ServerResponse) => {\n try {\n // 创建代理 Request(延迟创建真实 Request)\n const request = createProxyRequest(incoming, defaultHost);\n\n // 调用 fetch handler\n const response = await fetch(request);\n\n // 流式写入 Response\n await writeResponse(response, outgoing);\n } catch (error) {\n // 错误处理\n const err = error instanceof Error ? error : new Error(String(error));\n\n if (onError) {\n try {\n const errorResponse = await onError(err);\n await writeResponse(errorResponse, outgoing);\n return;\n } catch {\n // onError 也失败了,返回 500\n }\n }\n\n // 默认错误响应\n if (!outgoing.headersSent) {\n outgoing.statusCode = 500;\n outgoing.setHeader(\"Content-Type\", \"text/plain\");\n outgoing.end(\"Internal Server Error\");\n }\n }\n };\n}\n\n/**\n * 启动 HTTP 服务器\n *\n * @example\n * ```ts\n * import { serve } from \"@vafast/node-server\";\n * import { Server } from \"vafast\";\n *\n * const app = new Server([\n * { method: \"GET\", path: \"/\", handler: () => \"Hello World\" },\n * ]);\n *\n * serve({ fetch: app.fetch, port: 3000 }, () => {\n * console.log(\"Server running on http://localhost:3000\");\n * });\n * ```\n */\nexport function serve(\n options: ServeOptions,\n callback?: () => void,\n): ServeResult {\n const { fetch, port = 3000, hostname = \"0.0.0.0\", onError } = options;\n\n const defaultHost = `${hostname === \"0.0.0.0\" ? \"localhost\" : hostname}:${port}`;\n const handler = createRequestHandler(fetch, defaultHost, onError);\n\n const server = createServer(handler);\n\n // 启动服务器\n server.listen(port, hostname, callback);\n\n return {\n server,\n port,\n hostname,\n stop: () =>\n new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) reject(err);\n else resolve();\n });\n }),\n };\n}\n\n/**\n * 创建适配器服务器(不自动启动)\n * 用于需要更多控制的场景\n */\nexport function createAdaptorServer(\n fetch: FetchHandler,\n onError?: (error: Error) => Response | Promise<Response>,\n): HttpServer {\n const handler = createRequestHandler(fetch, \"localhost\", onError);\n return createServer(handler);\n}\n","/**\n * 优化的 Request 代理\n * 延迟创建真实 Request,减少不必要的对象分配\n */\n\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream as NodeReadableStream } from \"node:stream/web\";\nimport type { IncomingMessage } from \"node:http\";\n\n// 内部 Symbol\nconst requestCache = Symbol(\"requestCache\");\nconst incomingKey = Symbol(\"incoming\");\nconst urlKey = Symbol(\"url\");\nconst headersKey = Symbol(\"headers\");\n\n/**\n * 从 rawHeaders 高效解析 Headers\n */\nfunction parseHeaders(rawHeaders: string[]): Headers {\n const headers = new Headers();\n for (let i = 0; i < rawHeaders.length; i += 2) {\n const key = rawHeaders[i];\n const value = rawHeaders[i + 1];\n // 跳过 HTTP/2 伪头 (以 : 开头)\n if (key.charCodeAt(0) !== 58) {\n headers.append(key, value);\n }\n }\n return headers;\n}\n\n/**\n * 将 Node.js ReadableStream 转换为 Web 标准 ReadableStream\n * Node.js 和 Web 标准的 ReadableStream 在运行时兼容,但 TypeScript 类型不同\n */\nfunction toWebStream(\n nodeStream: NodeReadableStream<Uint8Array>,\n): ReadableStream<Uint8Array> {\n // Node.js ReadableStream 和 Web ReadableStream 在运行时是兼容的\n // 这里使用类型断言是安全的,因为 Node.js >= 18 的 stream/web 完全实现了 WHATWG Streams 标准\n return nodeStream as unknown as ReadableStream<Uint8Array>;\n}\n\n/** 代理 Request 内部接口 */\ninterface ProxyRequestInternal {\n [requestCache]?: Request;\n [incomingKey]: IncomingMessage;\n [urlKey]: string;\n [headersKey]?: Headers;\n _getRequest(): Request;\n}\n\n/**\n * 创建真实的 Request 对象\n */\nfunction createRealRequest(proxy: ProxyRequestInternal): Request {\n const incoming = proxy[incomingKey];\n const method = incoming.method || \"GET\";\n const init: RequestInit & { duplex?: string } = {\n method,\n headers: proxy[headersKey] || parseHeaders(incoming.rawHeaders),\n };\n\n // 只有非 GET/HEAD 请求才有 body\n if (method !== \"GET\" && method !== \"HEAD\") {\n // 使用 Node.js 原生流转换,避免收集 chunks\n const nodeWebStream = Readable.toWeb(\n incoming,\n ) as NodeReadableStream<Uint8Array>;\n init.body = toWebStream(nodeWebStream);\n init.duplex = \"half\";\n }\n\n return new Request(proxy[urlKey], init);\n}\n\n/**\n * Request 代理原型\n * 使用 Object.defineProperty 定义属性以支持 this 绑定\n */\nconst requestPrototype: object = {};\n\n// 定义 method 属性\nObject.defineProperty(requestPrototype, \"method\", {\n get() {\n const self = this as ProxyRequestInternal;\n return self[incomingKey].method || \"GET\";\n },\n enumerable: true,\n});\n\n// 定义 url 属性\nObject.defineProperty(requestPrototype, \"url\", {\n get() {\n const self = this as ProxyRequestInternal;\n return self[urlKey];\n },\n enumerable: true,\n});\n\n// 定义 headers 属性(延迟解析)\nObject.defineProperty(requestPrototype, \"headers\", {\n get() {\n const self = this as ProxyRequestInternal;\n if (!self[headersKey]) {\n self[headersKey] = parseHeaders(self[incomingKey].rawHeaders);\n }\n return self[headersKey];\n },\n enumerable: true,\n});\n\n// 定义 _getRequest 方法(获取或创建真实 Request)\nObject.defineProperty(requestPrototype, \"_getRequest\", {\n value: function () {\n const self = this as ProxyRequestInternal;\n if (!self[requestCache]) {\n self[requestCache] = createRealRequest(self);\n }\n return self[requestCache]!;\n },\n enumerable: false,\n});\n\n// 代理需要访问真实 Request 的属性\nconst proxyGetters = [\n \"body\",\n \"bodyUsed\",\n \"signal\",\n \"cache\",\n \"credentials\",\n \"destination\",\n \"integrity\",\n \"mode\",\n \"redirect\",\n \"referrer\",\n \"referrerPolicy\",\n \"keepalive\",\n];\n\nproxyGetters.forEach((key) => {\n Object.defineProperty(requestPrototype, key, {\n get() {\n const self = this as ProxyRequestInternal;\n return self._getRequest()[key as keyof Request];\n },\n enumerable: true,\n });\n});\n\n// 代理需要调用真实 Request 的方法\nconst proxyMethods = [\n \"arrayBuffer\",\n \"blob\",\n \"clone\",\n \"formData\",\n \"json\",\n \"text\",\n];\n\nproxyMethods.forEach((key) => {\n Object.defineProperty(requestPrototype, key, {\n value: function () {\n const self = this as ProxyRequestInternal;\n const req = self._getRequest();\n return (req[key as keyof Request] as () => Promise<unknown>).call(req);\n },\n enumerable: true,\n });\n});\n\n// 设置原型链\nObject.setPrototypeOf(requestPrototype, Request.prototype);\n\n/**\n * 创建代理 Request\n * @param incoming Node.js IncomingMessage\n * @param defaultHost 默认主机名\n */\nexport function createProxyRequest(\n incoming: IncomingMessage,\n defaultHost: string,\n): Request {\n const req = Object.create(requestPrototype) as ProxyRequestInternal;\n req[incomingKey] = incoming;\n\n // 构建 URL\n const host = incoming.headers.host || defaultHost;\n const protocol = (incoming.socket as { encrypted?: boolean }).encrypted\n ? \"https\"\n : \"http\";\n req[urlKey] = `${protocol}://${host}${incoming.url || \"/\"}`;\n\n return req as unknown as Request;\n}\n","/**\n * 优化的 Response 写入\n * 流式写入,避免内存拷贝\n */\n\nimport type { ServerResponse } from \"node:http\";\n\n/**\n * 构建 Node.js 响应头\n * 处理 set-cookie 多值情况\n */\nfunction buildOutgoingHeaders(\n headers: Headers,\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n const cookies: string[] = [];\n\n headers.forEach((value, key) => {\n if (key === \"set-cookie\") {\n cookies.push(value);\n } else {\n result[key] = value;\n }\n });\n\n if (cookies.length > 0) {\n result[\"set-cookie\"] = cookies;\n }\n\n return result;\n}\n\n/**\n * 流式写入 Response body 到 ServerResponse\n * 支持背压处理,避免内存溢出\n */\nasync function writeBodyStream(\n body: ReadableStream<Uint8Array>,\n outgoing: ServerResponse,\n): Promise<void> {\n const reader = body.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n // 背压处理:如果写入返回 false,等待 drain 事件\n const canContinue = outgoing.write(value);\n if (!canContinue) {\n await new Promise<void>((resolve) => {\n outgoing.once(\"drain\", resolve);\n });\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * 将 Web Response 写入 Node.js ServerResponse\n * 流式写入,零拷贝\n */\nexport async function writeResponse(\n response: Response,\n outgoing: ServerResponse,\n): Promise<void> {\n // 设置状态码\n outgoing.statusCode = response.status;\n\n // 设置响应头\n const headers = buildOutgoingHeaders(response.headers);\n for (const [key, value] of Object.entries(headers)) {\n outgoing.setHeader(key, value);\n }\n\n const body = response.body;\n\n // 无 body 的情况\n if (!body) {\n outgoing.end();\n return;\n }\n\n // 流式写入 body\n try {\n await writeBodyStream(body, outgoing);\n outgoing.end();\n } catch (error) {\n // 处理客户端提前断开等情况\n if (!outgoing.destroyed) {\n outgoing.destroy(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n}\n\n/**\n * 简化版写入(用于已知小体积响应)\n * 直接 arrayBuffer 转换,适用于确定的小响应\n */\nexport async function writeResponseSimple(\n response: Response,\n outgoing: ServerResponse,\n): Promise<void> {\n outgoing.statusCode = response.status;\n\n const headers = buildOutgoingHeaders(response.headers);\n for (const [key, value] of Object.entries(headers)) {\n outgoing.setHeader(key, value);\n }\n\n const body = response.body;\n if (!body) {\n outgoing.end();\n return;\n }\n\n // 对于小响应,直接读取全部内容\n const buffer = await response.arrayBuffer();\n outgoing.end(Buffer.from(buffer));\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,10 @@
1
- import type { Middleware } from "../types";
1
+ import { Middleware } from '../types/types.js';
2
+
2
3
  /**
3
4
  * 服务器基类
4
5
  * 包含所有服务器类型的公共逻辑
5
6
  */
6
- export declare abstract class BaseServer {
7
+ declare abstract class BaseServer {
7
8
  protected globalMiddleware: Middleware[];
8
9
  use(mw: Middleware): void;
9
10
  /**
@@ -32,3 +33,5 @@ export declare abstract class BaseServer {
32
33
  */
33
34
  protected extractParams(pattern: string, path: string): Record<string, string>;
34
35
  }
36
+
37
+ export { BaseServer };
@@ -1,145 +1,134 @@
1
- /**
2
- * 服务器基类
3
- * 包含所有服务器类型的公共逻辑
4
- */
5
- export class BaseServer {
6
- globalMiddleware = [];
7
- use(mw) {
8
- this.globalMiddleware.push(mw);
1
+ // src/server/base-server.ts
2
+ var BaseServer = class {
3
+ globalMiddleware = [];
4
+ use(mw) {
5
+ this.globalMiddleware.push(mw);
6
+ }
7
+ /**
8
+ * 打印扁平化后的路由信息,用于调试
9
+ */
10
+ logFlattenedRoutes(routes, type = "\u8DEF\u7531") {
11
+ console.log(`\u{1F680} \u6241\u5E73\u5316\u540E\u7684${type}:`);
12
+ for (const route of routes) {
13
+ const method = route.method || "GET";
14
+ const path = route.fullPath || route.path;
15
+ console.log(` ${method} ${path}`);
16
+ if (route.middlewareChain && route.middlewareChain.length > 0) {
17
+ console.log(` \u4E2D\u95F4\u4EF6\u94FE: ${route.middlewareChain.length} \u4E2A`);
18
+ }
9
19
  }
10
- /**
11
- * 打印扁平化后的路由信息,用于调试
12
- */
13
- logFlattenedRoutes(routes, type = "路由") {
14
- console.log(`🚀 扁平化后的${type}:`);
15
- for (const route of routes) {
16
- const method = route.method || "GET";
17
- const path = route.fullPath || route.path;
18
- console.log(` ${method} ${path}`);
19
- if (route.middlewareChain && route.middlewareChain.length > 0) {
20
- console.log(` 中间件链: ${route.middlewareChain.length} 个`);
21
- }
22
- }
23
- console.log("");
20
+ console.log("");
21
+ }
22
+ /**
23
+ * 检测路由冲突
24
+ * 检查是否有路径相同但方法不同的路由,以及潜在的路径冲突
25
+ */
26
+ detectRouteConflicts(routes) {
27
+ const pathGroups = /* @__PURE__ */ new Map();
28
+ for (const route of routes) {
29
+ const path = route.fullPath || route.path;
30
+ const method = route.method || "GET";
31
+ if (!pathGroups.has(path)) {
32
+ pathGroups.set(path, []);
33
+ }
34
+ pathGroups.get(path).push({ ...route, method });
24
35
  }
25
- /**
26
- * 检测路由冲突
27
- * 检查是否有路径相同但方法不同的路由,以及潜在的路径冲突
28
- */
29
- detectRouteConflicts(routes) {
30
- const pathGroups = new Map();
31
- // 按路径分组
32
- for (const route of routes) {
33
- const path = route.fullPath || route.path;
34
- const method = route.method || "GET";
35
- if (!pathGroups.has(path)) {
36
- pathGroups.set(path, []);
37
- }
38
- pathGroups.get(path).push({ ...route, method });
39
- }
40
- // 检查冲突
41
- for (const [path, routeList] of pathGroups) {
42
- if (routeList.length > 1) {
43
- const methods = routeList.map((r) => r.method);
44
- const uniqueMethods = [...new Set(methods)];
45
- if (uniqueMethods.length === 1) {
46
- // 相同路径、相同方法 - 这是冲突!
47
- console.warn(`⚠️ 路由冲突: ${uniqueMethods[0]} ${path} 定义了 ${routeList.length} 次`);
48
- routeList.forEach((route, index) => {
49
- console.warn(` ${index + 1}. ${route.method} ${path}`);
50
- });
51
- }
52
- else {
53
- // 相同路径、不同方法 - 这是正常的
54
- console.log(`ℹ️ 路径 ${path} 支持方法: ${uniqueMethods.join(", ")}`);
55
- }
56
- }
36
+ for (const [path, routeList] of pathGroups) {
37
+ if (routeList.length > 1) {
38
+ const methods = routeList.map((r) => r.method);
39
+ const uniqueMethods = [...new Set(methods)];
40
+ if (uniqueMethods.length === 1) {
41
+ console.warn(
42
+ `\u26A0\uFE0F \u8DEF\u7531\u51B2\u7A81: ${uniqueMethods[0]} ${path} \u5B9A\u4E49\u4E86 ${routeList.length} \u6B21`
43
+ );
44
+ routeList.forEach((route, index) => {
45
+ console.warn(` ${index + 1}. ${route.method} ${path}`);
46
+ });
47
+ } else {
48
+ console.log(`\u2139\uFE0F \u8DEF\u5F84 ${path} \u652F\u6301\u65B9\u6CD5: ${uniqueMethods.join(", ")}`);
57
49
  }
58
- // 检查潜在的路径冲突(动态路由可能冲突)
59
- this.detectDynamicRouteConflicts(routes);
50
+ }
60
51
  }
61
- /**
62
- * 检测动态路由的潜在冲突
63
- */
64
- detectDynamicRouteConflicts(routes) {
65
- const dynamicRoutes = routes.filter((r) => {
66
- const path = r.fullPath || r.path;
67
- return path.includes(":") || path.includes("*");
68
- });
69
- for (let i = 0; i < dynamicRoutes.length; i++) {
70
- for (let j = i + 1; j < dynamicRoutes.length; j++) {
71
- const route1 = dynamicRoutes[i];
72
- const route2 = dynamicRoutes[j];
73
- const method1 = route1.method || "GET";
74
- const method2 = route2.method || "GET";
75
- if (method1 === method2) {
76
- const path1 = route1.fullPath || route1.path;
77
- const path2 = route2.fullPath || route2.path;
78
- // 检查路径是否可能冲突
79
- if (this.pathsMayConflict(path1, path2)) {
80
- console.warn(`⚠️ 潜在路由冲突: ${method1} ${path1} 可能与 ${path2} 冲突`);
81
- }
82
- }
83
- }
52
+ this.detectDynamicRouteConflicts(routes);
53
+ }
54
+ /**
55
+ * 检测动态路由的潜在冲突
56
+ */
57
+ detectDynamicRouteConflicts(routes) {
58
+ const dynamicRoutes = routes.filter((r) => {
59
+ const path = r.fullPath || r.path;
60
+ return path.includes(":") || path.includes("*");
61
+ });
62
+ for (let i = 0; i < dynamicRoutes.length; i++) {
63
+ for (let j = i + 1; j < dynamicRoutes.length; j++) {
64
+ const route1 = dynamicRoutes[i];
65
+ const route2 = dynamicRoutes[j];
66
+ const method1 = route1.method || "GET";
67
+ const method2 = route2.method || "GET";
68
+ if (method1 === method2) {
69
+ const path1 = route1.fullPath || route1.path;
70
+ const path2 = route2.fullPath || route2.path;
71
+ if (this.pathsMayConflict(path1, path2)) {
72
+ console.warn(
73
+ `\u26A0\uFE0F \u6F5C\u5728\u8DEF\u7531\u51B2\u7A81: ${method1} ${path1} \u53EF\u80FD\u4E0E ${path2} \u51B2\u7A81`
74
+ );
75
+ }
84
76
  }
77
+ }
85
78
  }
86
- /**
87
- * 判断两个路径是否可能冲突
88
- */
89
- pathsMayConflict(path1, path2) {
90
- const parts1 = path1.split("/").filter(Boolean);
91
- const parts2 = path2.split("/").filter(Boolean);
92
- if (parts1.length !== parts2.length)
93
- return false;
94
- for (let i = 0; i < parts1.length; i++) {
95
- const p1 = parts1[i];
96
- const p2 = parts2[i];
97
- // 如果两个部分都是静态的且不同,则不会冲突
98
- if (!p1.startsWith(":") &&
99
- !p1.startsWith("*") &&
100
- !p2.startsWith(":") &&
101
- !p2.startsWith("*") &&
102
- p1 !== p2) {
103
- return false;
104
- }
105
- // 如果一个是通配符,另一个是动态参数,可能冲突
106
- if ((p1 === "*" && p2.startsWith(":")) ||
107
- (p2 === "*" && p1.startsWith(":"))) {
108
- return true;
109
- }
110
- }
79
+ }
80
+ /**
81
+ * 判断两个路径是否可能冲突
82
+ */
83
+ pathsMayConflict(path1, path2) {
84
+ const parts1 = path1.split("/").filter(Boolean);
85
+ const parts2 = path2.split("/").filter(Boolean);
86
+ if (parts1.length !== parts2.length) return false;
87
+ for (let i = 0; i < parts1.length; i++) {
88
+ const p1 = parts1[i];
89
+ const p2 = parts2[i];
90
+ if (!p1.startsWith(":") && !p1.startsWith("*") && !p2.startsWith(":") && !p2.startsWith("*") && p1 !== p2) {
111
91
  return false;
112
- }
113
- /**
114
- * 路径匹配
115
- */
116
- matchPath(pattern, path) {
117
- const patternParts = pattern.split("/").filter(Boolean);
118
- const pathParts = path.split("/").filter(Boolean);
119
- if (patternParts.length !== pathParts.length) {
120
- return false;
121
- }
122
- for (let i = 0; i < patternParts.length; i++) {
123
- if (patternParts[i] !== pathParts[i] &&
124
- !patternParts[i].startsWith(":")) {
125
- return false;
126
- }
127
- }
92
+ }
93
+ if (p1 === "*" && p2.startsWith(":") || p2 === "*" && p1.startsWith(":")) {
128
94
  return true;
95
+ }
129
96
  }
130
- /**
131
- * 提取路径参数
132
- */
133
- extractParams(pattern, path) {
134
- const params = {};
135
- const patternParts = pattern.split("/").filter(Boolean);
136
- const pathParts = path.split("/").filter(Boolean);
137
- for (let i = 0; i < patternParts.length; i++) {
138
- if (patternParts[i].startsWith(":")) {
139
- const paramName = patternParts[i].slice(1);
140
- params[paramName] = pathParts[i];
141
- }
142
- }
143
- return params;
97
+ return false;
98
+ }
99
+ /**
100
+ * 路径匹配
101
+ */
102
+ matchPath(pattern, path) {
103
+ const patternParts = pattern.split("/").filter(Boolean);
104
+ const pathParts = path.split("/").filter(Boolean);
105
+ if (patternParts.length !== pathParts.length) {
106
+ return false;
107
+ }
108
+ for (let i = 0; i < patternParts.length; i++) {
109
+ if (patternParts[i] !== pathParts[i] && !patternParts[i].startsWith(":")) {
110
+ return false;
111
+ }
112
+ }
113
+ return true;
114
+ }
115
+ /**
116
+ * 提取路径参数
117
+ */
118
+ extractParams(pattern, path) {
119
+ const params = {};
120
+ const patternParts = pattern.split("/").filter(Boolean);
121
+ const pathParts = path.split("/").filter(Boolean);
122
+ for (let i = 0; i < patternParts.length; i++) {
123
+ if (patternParts[i].startsWith(":")) {
124
+ const paramName = patternParts[i].slice(1);
125
+ params[paramName] = pathParts[i];
126
+ }
144
127
  }
145
- }
128
+ return params;
129
+ }
130
+ };
131
+ export {
132
+ BaseServer
133
+ };
134
+ //# sourceMappingURL=base-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/base-server.ts"],"sourcesContent":["import type { Middleware } from \"../types\";\n\n/**\n * 服务器基类\n * 包含所有服务器类型的公共逻辑\n */\nexport abstract class BaseServer {\n protected globalMiddleware: Middleware[] = [];\n\n use(mw: Middleware) {\n this.globalMiddleware.push(mw);\n }\n\n /**\n * 打印扁平化后的路由信息,用于调试\n */\n protected logFlattenedRoutes(routes: any[], type: string = \"路由\"): void {\n console.log(`🚀 扁平化后的${type}:`);\n for (const route of routes) {\n const method = route.method || \"GET\";\n const path = route.fullPath || route.path;\n console.log(` ${method} ${path}`);\n if (route.middlewareChain && route.middlewareChain.length > 0) {\n console.log(` 中间件链: ${route.middlewareChain.length} 个`);\n }\n }\n console.log(\"\");\n }\n\n /**\n * 检测路由冲突\n * 检查是否有路径相同但方法不同的路由,以及潜在的路径冲突\n */\n protected detectRouteConflicts(routes: any[]): void {\n const pathGroups = new Map<string, any[]>();\n\n // 按路径分组\n for (const route of routes) {\n const path = route.fullPath || route.path;\n const method = route.method || \"GET\";\n if (!pathGroups.has(path)) {\n pathGroups.set(path, []);\n }\n pathGroups.get(path)!.push({ ...route, method });\n }\n\n // 检查冲突\n for (const [path, routeList] of pathGroups) {\n if (routeList.length > 1) {\n const methods = routeList.map((r) => r.method);\n const uniqueMethods = [...new Set(methods)];\n\n if (uniqueMethods.length === 1) {\n // 相同路径、相同方法 - 这是冲突!\n console.warn(\n `⚠️ 路由冲突: ${uniqueMethods[0]} ${path} 定义了 ${routeList.length} 次`,\n );\n routeList.forEach((route, index) => {\n console.warn(` ${index + 1}. ${route.method} ${path}`);\n });\n } else {\n // 相同路径、不同方法 - 这是正常的\n console.log(`ℹ️ 路径 ${path} 支持方法: ${uniqueMethods.join(\", \")}`);\n }\n }\n }\n\n // 检查潜在的路径冲突(动态路由可能冲突)\n this.detectDynamicRouteConflicts(routes);\n }\n\n /**\n * 检测动态路由的潜在冲突\n */\n private detectDynamicRouteConflicts(routes: any[]): void {\n const dynamicRoutes = routes.filter((r) => {\n const path = r.fullPath || r.path;\n return path.includes(\":\") || path.includes(\"*\");\n });\n\n for (let i = 0; i < dynamicRoutes.length; i++) {\n for (let j = i + 1; j < dynamicRoutes.length; j++) {\n const route1 = dynamicRoutes[i];\n const route2 = dynamicRoutes[j];\n const method1 = route1.method || \"GET\";\n const method2 = route2.method || \"GET\";\n\n if (method1 === method2) {\n const path1 = route1.fullPath || route1.path;\n const path2 = route2.fullPath || route2.path;\n // 检查路径是否可能冲突\n if (this.pathsMayConflict(path1, path2)) {\n console.warn(\n `⚠️ 潜在路由冲突: ${method1} ${path1} 可能与 ${path2} 冲突`,\n );\n }\n }\n }\n }\n }\n\n /**\n * 判断两个路径是否可能冲突\n */\n private pathsMayConflict(path1: string, path2: string): boolean {\n const parts1 = path1.split(\"/\").filter(Boolean);\n const parts2 = path2.split(\"/\").filter(Boolean);\n\n if (parts1.length !== parts2.length) return false;\n\n for (let i = 0; i < parts1.length; i++) {\n const p1 = parts1[i];\n const p2 = parts2[i];\n\n // 如果两个部分都是静态的且不同,则不会冲突\n if (\n !p1.startsWith(\":\") &&\n !p1.startsWith(\"*\") &&\n !p2.startsWith(\":\") &&\n !p2.startsWith(\"*\") &&\n p1 !== p2\n ) {\n return false;\n }\n\n // 如果一个是通配符,另一个是动态参数,可能冲突\n if (\n (p1 === \"*\" && p2.startsWith(\":\")) ||\n (p2 === \"*\" && p1.startsWith(\":\"))\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * 路径匹配\n */\n protected matchPath(pattern: string, path: string): boolean {\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const pathParts = path.split(\"/\").filter(Boolean);\n\n if (patternParts.length !== pathParts.length) {\n return false;\n }\n\n for (let i = 0; i < patternParts.length; i++) {\n if (\n patternParts[i] !== pathParts[i] &&\n !patternParts[i].startsWith(\":\")\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * 提取路径参数\n */\n protected extractParams(\n pattern: string,\n path: string,\n ): Record<string, string> {\n const params: Record<string, string> = {};\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const pathParts = path.split(\"/\").filter(Boolean);\n\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i].startsWith(\":\")) {\n const paramName = patternParts[i].slice(1);\n params[paramName] = pathParts[i];\n }\n }\n\n return params;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,14 @@
1
- import type { ComponentRoute, NestedComponentRoute } from "../types/component-route";
2
- import { BaseServer } from "./base-server";
3
- import { DependencyManager } from "../utils/dependency-manager";
1
+ import { ComponentRoute, NestedComponentRoute } from '../types/component-route.js';
2
+ import { BaseServer } from './base-server.js';
3
+ import { DependencyManager } from '../utils/dependency-manager.js';
4
+ import '../types/route.js';
5
+ import '../types/types.js';
6
+
4
7
  /**
5
8
  * 组件路由服务器
6
9
  * 专门处理声明式组件路由
7
10
  */
8
- export declare class ComponentServer extends BaseServer {
11
+ declare class ComponentServer extends BaseServer {
9
12
  private routes;
10
13
  private dependencyManager;
11
14
  constructor(routes: (ComponentRoute | NestedComponentRoute)[]);
@@ -30,3 +33,5 @@ export declare class ComponentServer extends BaseServer {
30
33
  */
31
34
  getDependencyManager(): DependencyManager;
32
35
  }
36
+
37
+ export { ComponentServer };