tspace-spear 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -4
- package/dist/lib/core/server/index.d.ts +12 -2
- package/dist/lib/core/server/index.js +310 -127
- package/dist/lib/core/server/index.js.map +1 -1
- package/dist/lib/core/server/parser-factory.d.ts +17 -8
- package/dist/lib/core/server/parser-factory.js +269 -4
- package/dist/lib/core/server/parser-factory.js.map +1 -1
- package/dist/lib/core/server/router.d.ts +10 -0
- package/dist/lib/core/server/router.js +12 -0
- package/dist/lib/core/server/router.js.map +1 -1
- package/dist/lib/core/types/index.d.ts +25 -5
- package/package.json +18 -7
- package/dist/tests/benchmark.test.d.ts +0 -1
- package/dist/tests/benchmark.test.js +0 -145
- package/dist/tests/benchmark.test.js.map +0 -1
|
@@ -74,6 +74,16 @@ declare class Router {
|
|
|
74
74
|
* @returns {this}
|
|
75
75
|
*/
|
|
76
76
|
all(path: `/${string}`, ...handlers: ((ctx: T.Context, next: T.NextFunction) => any)[]): this;
|
|
77
|
+
/**
|
|
78
|
+
* The 'any' method is used to add the request handler to the router for 'GET' 'POST' 'PUT' 'PATCH' 'DELETE' methods.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} path
|
|
81
|
+
* @callback {...Function[]} handlers of the middlewares
|
|
82
|
+
* @property {object} ctx - context { req , res , query , params , cookies , files , body}
|
|
83
|
+
* @property {function} next - go to next function
|
|
84
|
+
* @returns {this}
|
|
85
|
+
*/
|
|
86
|
+
any(path: `/${string}`, ...handlers: ((ctx: T.Context, next: T.NextFunction) => any)[]): this;
|
|
77
87
|
/**
|
|
78
88
|
* The 'head' method is used to add the request handler to the router for the 'HEAD' method.
|
|
79
89
|
*
|
|
@@ -122,6 +122,18 @@ class Router {
|
|
|
122
122
|
});
|
|
123
123
|
return this;
|
|
124
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* The 'any' method is used to add the request handler to the router for 'GET' 'POST' 'PUT' 'PATCH' 'DELETE' methods.
|
|
127
|
+
*
|
|
128
|
+
* @param {string} path
|
|
129
|
+
* @callback {...Function[]} handlers of the middlewares
|
|
130
|
+
* @property {object} ctx - context { req , res , query , params , cookies , files , body}
|
|
131
|
+
* @property {function} next - go to next function
|
|
132
|
+
* @returns {this}
|
|
133
|
+
*/
|
|
134
|
+
any(path, ...handlers) {
|
|
135
|
+
return this.all(path, ...handlers);
|
|
136
|
+
}
|
|
125
137
|
/**
|
|
126
138
|
* The 'head' method is used to add the request handler to the router for the 'HEAD' method.
|
|
127
139
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/router.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/router.ts"],"names":[],"mappings":";;;AACA,MAAM,MAAM;IAEA,OAAO,GAIT,EAAE,CAAA;IAER,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAE,MAAqB,EAAE,MAAoC;QACtE,MAAM,MAAM,GAAI,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC,CAAA;QACpC,KAAI,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;YAC1D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAC/F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,KAAK;YACd,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAChG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,MAAM;YACf,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAC/F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,KAAK;YACd,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,IAAmB,EAAG,GAAG,QAA+D;QACjG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,OAAO;YAChB,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAEA;;;;;;;;MAQE;IACI,MAAM,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAClG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,QAAQ;YACjB,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAC/F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,KAAK;YACd,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAC/F,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAC,GAAG,QAAQ,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAmB,EAAG,GAAG,QAA+D;QAChG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,MAAM;YACf,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO,CAAC,IAAmB,EAAG,GAAG,QAA+D;QACnG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,MAAM,EAAG,SAAS;YAClB,QAAQ;SACX,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACf,CAAC;CACJ;AAEQ,wBAAM;AACf,kBAAe,MAAM,CAAA"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
1
|
+
import http, { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
2
|
import WebSocket from "ws";
|
|
3
|
-
type TDeepExpand<T> = T extends Date ? T : T extends Function ? T : T extends (infer U)[] ? TDeepExpand<U>[] : T extends object ? {
|
|
4
|
-
[K in keyof T]: TDeepExpand<T[K]>;
|
|
5
|
-
} : T;
|
|
6
3
|
type TContext = {
|
|
7
4
|
req: TRequest;
|
|
8
5
|
res: TResponse;
|
|
@@ -12,7 +9,9 @@ type TContext = {
|
|
|
12
9
|
body: TBody;
|
|
13
10
|
files: TFileUpload;
|
|
14
11
|
cookies: TCookies;
|
|
12
|
+
ip: TIp;
|
|
15
13
|
};
|
|
14
|
+
type TIp = string | null;
|
|
16
15
|
type THeaders<T = IncomingHttpHeaders> = {
|
|
17
16
|
[K in keyof T]: T[K];
|
|
18
17
|
};
|
|
@@ -36,7 +35,7 @@ type TFile = {
|
|
|
36
35
|
write: (to: string) => Promise<void>;
|
|
37
36
|
remove: () => Promise<void>;
|
|
38
37
|
};
|
|
39
|
-
type TFileUpload = Record<string,
|
|
38
|
+
type TFileUpload = Record<string, TFile[] | undefined>;
|
|
40
39
|
type TNextFunction<T = any> = (err?: Error) => T | Promise<T>;
|
|
41
40
|
type TRequest = IncomingMessage & Partial<any>;
|
|
42
41
|
type THttpResponder = {
|
|
@@ -90,6 +89,25 @@ type TRoute = {
|
|
|
90
89
|
};
|
|
91
90
|
type TMethod = 'get' | 'post' | 'patch' | 'put' | 'delete' | 'all' | 'head' | 'options';
|
|
92
91
|
type TMethodInput = Uppercase<TMethod>;
|
|
92
|
+
type Handler = (res: unknown, req: unknown) => void | Promise<void>;
|
|
93
|
+
type UWS = {
|
|
94
|
+
App: () => {
|
|
95
|
+
get: (path: string, handler: Handler) => any;
|
|
96
|
+
post: (path: string, handler: Handler) => any;
|
|
97
|
+
patch: (path: string, handler: Handler) => any;
|
|
98
|
+
put: (path: string, handler: Handler) => any;
|
|
99
|
+
del: (path: string, handler: Handler) => any;
|
|
100
|
+
any: (path: string, handler: Handler) => any;
|
|
101
|
+
options: (path: string, handler: Handler) => any;
|
|
102
|
+
listen: (...args: any[]) => any;
|
|
103
|
+
ws: (path: string, options: {
|
|
104
|
+
open?: (ws: any) => void;
|
|
105
|
+
message?: (ws: any, message: ArrayBuffer, isBinary: boolean) => void;
|
|
106
|
+
close?: (ws: any, code: number, message: ArrayBuffer) => void;
|
|
107
|
+
}) => any;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
type TAdapter = UWS | typeof http;
|
|
93
111
|
type TApplication = {
|
|
94
112
|
controllers?: (new () => any)[] | {
|
|
95
113
|
folder: string;
|
|
@@ -102,6 +120,7 @@ type TApplication = {
|
|
|
102
120
|
globalPrefix?: string;
|
|
103
121
|
logger?: boolean;
|
|
104
122
|
cluster?: boolean | number;
|
|
123
|
+
adapter?: TAdapter;
|
|
105
124
|
};
|
|
106
125
|
type TRequestFunction = (ctx: TContext, next: TNextFunction) => any;
|
|
107
126
|
type TErrorFunction = (err: Error, ctx: TContext) => any;
|
|
@@ -198,6 +217,7 @@ type TWSHandler = {
|
|
|
198
217
|
error: (ws: WebSocket, error: Error) => void;
|
|
199
218
|
};
|
|
200
219
|
export declare namespace T {
|
|
220
|
+
type Adapter = TAdapter;
|
|
201
221
|
type Application = TApplication;
|
|
202
222
|
type NextFunction = TNextFunction;
|
|
203
223
|
type File = TFile;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tspace-spear",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "tspace-spear is a lightweight API framework for Node.js that
|
|
3
|
+
"version": "1.2.3",
|
|
4
|
+
"description": "tspace-spear is a lightweight, high-performance API framework for Node.js that leverages the native HTTP server and supports uWebSockets.js (C++) for maximum speed and efficiency.",
|
|
5
5
|
"main": "./dist/lib/index.js",
|
|
6
6
|
"types": "./dist/lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -18,7 +18,11 @@
|
|
|
18
18
|
"api",
|
|
19
19
|
"rest api",
|
|
20
20
|
"fast",
|
|
21
|
-
"low overhead"
|
|
21
|
+
"low overhead",
|
|
22
|
+
"http",
|
|
23
|
+
"uWS",
|
|
24
|
+
"uWebSockets",
|
|
25
|
+
"uWebSockets.js"
|
|
22
26
|
],
|
|
23
27
|
"author": "Thanathip (https://github.com/thanathip41)",
|
|
24
28
|
"license": "MIT",
|
|
@@ -31,8 +35,9 @@
|
|
|
31
35
|
"prepare": "npm run build",
|
|
32
36
|
"release": "npm run build && npm publish",
|
|
33
37
|
"beta": "npm run build && npm publish --tag beta",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
38
|
+
"benchmark": "npm run build && ts-node __tests__/benchmark.test.ts",
|
|
39
|
+
"test": "mocha dist/tests/**/0*.test.js",
|
|
40
|
+
"load": "autocannon -c 100 -d 30 -p 10 localhost:3000",
|
|
36
41
|
"docs": "npx docsify-cli serve docs"
|
|
37
42
|
},
|
|
38
43
|
"engines": {
|
|
@@ -44,25 +49,31 @@
|
|
|
44
49
|
"mime-types": "2.1.35",
|
|
45
50
|
"on-finished": "2.4.1",
|
|
46
51
|
"reflect-metadata": "0.2.2",
|
|
47
|
-
"swagger-ui-dist": "5.32.0"
|
|
52
|
+
"swagger-ui-dist": "5.32.0",
|
|
53
|
+
"ws": "8.19.0"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
50
56
|
"@types/autocannon": "7.12.5",
|
|
51
57
|
"@types/busboy": "1.5.4",
|
|
58
|
+
"@types/chai": "5.2.3",
|
|
59
|
+
"@types/chai-http": "4.2.4",
|
|
52
60
|
"@types/express": "4.17.21",
|
|
61
|
+
"@types/jest": "30.0.0",
|
|
53
62
|
"@types/mime-types": "2.1.4",
|
|
63
|
+
"@types/mocha": "10.0.10",
|
|
54
64
|
"@types/node": "16.4.0",
|
|
55
65
|
"@types/on-finished": "2.3.4",
|
|
56
66
|
"@types/swagger-ui-dist": "3.30.4",
|
|
57
67
|
"@types/ws": "8.18.1",
|
|
58
68
|
"@types/yargs": "17.0.32",
|
|
59
69
|
"autocannon": "7.15.0",
|
|
70
|
+
"chai": "4.5.0",
|
|
71
|
+
"chai-http": "5.1.2",
|
|
60
72
|
"docsify-cli": "4.4.4",
|
|
61
73
|
"express": "4.19.2",
|
|
62
74
|
"fastify": "4.28.1",
|
|
63
75
|
"ts-node": "10.9.2",
|
|
64
76
|
"typescript": "5.9.3",
|
|
65
|
-
"ws": "8.18.3",
|
|
66
77
|
"yargs": "17.7.2",
|
|
67
78
|
"zod": "4.3.6"
|
|
68
79
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const autocannon_1 = __importDefault(require("autocannon"));
|
|
7
|
-
const fastify_1 = __importDefault(require("fastify"));
|
|
8
|
-
const express_1 = __importDefault(require("express"));
|
|
9
|
-
const http_1 = __importDefault(require("http"));
|
|
10
|
-
const yargs_1 = __importDefault(require("yargs"));
|
|
11
|
-
const lib_1 = __importDefault(require("../lib"));
|
|
12
|
-
const MESSAGE = 'Hello world!';
|
|
13
|
-
const { argv } = (0, yargs_1.default)(process.argv.slice(2));
|
|
14
|
-
let duration = argv.d || argv.duration;
|
|
15
|
-
let connections = argv.c || argv.connections;
|
|
16
|
-
let pipelining = argv.p || argv.pipelining;
|
|
17
|
-
connections = connections == null ? 100 : Number(connections);
|
|
18
|
-
pipelining = pipelining == null ? 10 : Number(pipelining);
|
|
19
|
-
duration = duration == null ? 10 : Number(duration);
|
|
20
|
-
function runExpress() {
|
|
21
|
-
const port = 3000;
|
|
22
|
-
(0, express_1.default)()
|
|
23
|
-
.get('/', (req, res) => {
|
|
24
|
-
res.setHeader('Content-Type', 'text/plain');
|
|
25
|
-
return res.send(MESSAGE);
|
|
26
|
-
})
|
|
27
|
-
.listen(port, () => {
|
|
28
|
-
console.log(`Server 'Express' running at http://localhost:${port}`);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function runHttp() {
|
|
32
|
-
const port = 3001;
|
|
33
|
-
const server = http_1.default.createServer((req, res) => {
|
|
34
|
-
res.statusCode = 200;
|
|
35
|
-
res.setHeader('Content-Type', 'text/plain');
|
|
36
|
-
res.end(MESSAGE);
|
|
37
|
-
});
|
|
38
|
-
server.listen(port, () => {
|
|
39
|
-
console.log(`Server 'Http' running at http://localhost:${port}`);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
function runFastify() {
|
|
43
|
-
const port = 3002;
|
|
44
|
-
(0, fastify_1.default)()
|
|
45
|
-
.get('/', (request, reply) => {
|
|
46
|
-
return reply
|
|
47
|
-
.header('Content-Type', 'text/plain')
|
|
48
|
-
.send(MESSAGE);
|
|
49
|
-
})
|
|
50
|
-
.listen({ port }, (err, address) => {
|
|
51
|
-
if (err)
|
|
52
|
-
throw err;
|
|
53
|
-
console.log(`server 'Fastify' running at : http://localhost:${port}`);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
function runSpear() {
|
|
57
|
-
const port = 3003;
|
|
58
|
-
new lib_1.default()
|
|
59
|
-
.get('/', () => MESSAGE)
|
|
60
|
-
.listen(port, () => console.log(`server 'Spear' running at : http://localhost:${port}`));
|
|
61
|
-
}
|
|
62
|
-
const url = (port) => `http://localhost:${port}`;
|
|
63
|
-
const urls = [
|
|
64
|
-
{ name: 'express', url: url(3000) },
|
|
65
|
-
{ name: 'http', url: url(3001) },
|
|
66
|
-
{ name: 'fastify', url: url(3002) },
|
|
67
|
-
{ name: 'tspace-spear', url: url(3003) }
|
|
68
|
-
];
|
|
69
|
-
const sleep = (ms) => {
|
|
70
|
-
return new Promise(resolve => setTimeout(resolve, ms, null));
|
|
71
|
-
};
|
|
72
|
-
const runBenchmark = async () => {
|
|
73
|
-
const results = [];
|
|
74
|
-
const randomized = shuffle(urls);
|
|
75
|
-
await new Promise((resolve, reject) => {
|
|
76
|
-
(0, autocannon_1.default)({
|
|
77
|
-
url: randomized[0].url,
|
|
78
|
-
connections,
|
|
79
|
-
duration: 3
|
|
80
|
-
}, (err) => {
|
|
81
|
-
if (err)
|
|
82
|
-
return reject(err);
|
|
83
|
-
resolve(null);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
for (const { name, url } of randomized) {
|
|
87
|
-
const result = await new Promise((resolve, reject) => {
|
|
88
|
-
(0, autocannon_1.default)({
|
|
89
|
-
url,
|
|
90
|
-
connections,
|
|
91
|
-
duration,
|
|
92
|
-
pipelining
|
|
93
|
-
}, (err, result) => {
|
|
94
|
-
if (err)
|
|
95
|
-
return reject(err);
|
|
96
|
-
return resolve(result);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
const toMs = (v) => Number((v / 1000).toFixed(3));
|
|
100
|
-
const latency = result.latency;
|
|
101
|
-
results.push({
|
|
102
|
-
name,
|
|
103
|
-
url,
|
|
104
|
-
"req/sec": Number(result.requests.average.toFixed(0)),
|
|
105
|
-
"avg(ms)": toMs(latency.average),
|
|
106
|
-
"p50(ms)": toMs(latency.p50),
|
|
107
|
-
"p90(ms)": toMs(latency.p90),
|
|
108
|
-
"p97(ms)": toMs(latency.p97_5),
|
|
109
|
-
"p99(ms)": toMs(latency.p99),
|
|
110
|
-
"max(ms)": toMs(latency.max),
|
|
111
|
-
"stddev": Number(latency.stddev.toFixed(2)),
|
|
112
|
-
"requests": result.requests.total
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
// sort ตาม performance
|
|
116
|
-
results.sort((a, b) => Number(b["req/sec"]) - Number(a["req/sec"]));
|
|
117
|
-
console.log({
|
|
118
|
-
connections,
|
|
119
|
-
duration,
|
|
120
|
-
pipelining
|
|
121
|
-
});
|
|
122
|
-
console.table(results);
|
|
123
|
-
};
|
|
124
|
-
const shuffle = (arr) => {
|
|
125
|
-
const a = [...arr];
|
|
126
|
-
for (let i = a.length - 1; i > 0; i--) {
|
|
127
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
128
|
-
[a[i], a[j]] = [a[j], a[i]];
|
|
129
|
-
}
|
|
130
|
-
return a;
|
|
131
|
-
};
|
|
132
|
-
async function runApps() {
|
|
133
|
-
await Promise.all([
|
|
134
|
-
runSpear,
|
|
135
|
-
runFastify,
|
|
136
|
-
runExpress,
|
|
137
|
-
runHttp
|
|
138
|
-
].map(v => v()));
|
|
139
|
-
await sleep(5000);
|
|
140
|
-
console.log('benchmarking !!');
|
|
141
|
-
await runBenchmark();
|
|
142
|
-
console.log('benchmarking done !!');
|
|
143
|
-
}
|
|
144
|
-
runApps();
|
|
145
|
-
//# sourceMappingURL=benchmark.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark.test.js","sourceRoot":"","sources":["../../src/tests/benchmark.test.ts"],"names":[],"mappings":"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"}
|