owebjs 1.5.7-dev → 1.5.8-dev
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 +45 -2
- package/dist/index.d.ts +1 -0
- package/dist/structures/Oweb.js +16 -2
- package/dist/uwebsocket/response.js +15 -1
- package/dist/uwebsocket/server.js +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,10 +72,10 @@ second average
|
|
|
72
72
|
| Runtime | Version | Requests/sec |
|
|
73
73
|
| ------------------------- | --------- | -----------: |
|
|
74
74
|
| uWebSockets.js | 20.52.0 | 79,149 |
|
|
75
|
-
| **Oweb (uWS)** | 1.5.
|
|
75
|
+
| **Oweb (uWS)** | 1.5.8-dev | 76,853 |
|
|
76
76
|
| 0http | 4.4.0 | 46,605 |
|
|
77
77
|
| Fastify | 4.23.2 | 46,238 |
|
|
78
|
-
| **Oweb (Fastify)** | 1.5.
|
|
78
|
+
| **Oweb (Fastify)** | 1.5.8-dev | 42,570 |
|
|
79
79
|
| Node.js http.createServer | 24.5.0 | 42,544 |
|
|
80
80
|
| Express | 5.2.1 | 24,913 |
|
|
81
81
|
|
|
@@ -83,6 +83,49 @@ This is a synthetic "Hello, Word!" benchmark that aims to evaluate the framework
|
|
|
83
83
|
The overhead that each framework has on your application depends on your application.
|
|
84
84
|
You should always benchmark if performance matters to you.
|
|
85
85
|
|
|
86
|
+
## Best Performance
|
|
87
|
+
|
|
88
|
+
For the highest throughput, use these defaults:
|
|
89
|
+
|
|
90
|
+
- Enable uWebSockets runtime: `uWebSocketsEnabled: true`
|
|
91
|
+
- Disable powered-by header: `poweredByHeader: false`
|
|
92
|
+
- For headers that should be sent on every request (for example CORS-related headers), use `staticResponseHeaders` instead of per-request hooks
|
|
93
|
+
|
|
94
|
+
Example (production-oriented):
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
import Oweb from 'owebjs';
|
|
98
|
+
|
|
99
|
+
const app = await new Oweb({
|
|
100
|
+
uWebSocketsEnabled: true,
|
|
101
|
+
poweredByHeader: false,
|
|
102
|
+
staticResponseHeaders: {
|
|
103
|
+
// CORS (set your real origin in production)
|
|
104
|
+
'access-control-allow-origin': 'https://yourdomain.com',
|
|
105
|
+
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
|
106
|
+
'access-control-allow-headers': 'Content-Type, Authorization',
|
|
107
|
+
vary: 'Origin',
|
|
108
|
+
|
|
109
|
+
// Security headers
|
|
110
|
+
'x-content-type-options': 'nosniff',
|
|
111
|
+
'x-frame-options': 'DENY',
|
|
112
|
+
'referrer-policy': 'strict-origin-when-cross-origin',
|
|
113
|
+
'permissions-policy': 'geolocation=(), microphone=(), camera=()',
|
|
114
|
+
'cross-origin-opener-policy': 'same-origin',
|
|
115
|
+
'cross-origin-resource-policy': 'same-site',
|
|
116
|
+
},
|
|
117
|
+
}).setup();
|
|
118
|
+
|
|
119
|
+
await app.loadRoutes({
|
|
120
|
+
directory: 'routes',
|
|
121
|
+
hmr: {
|
|
122
|
+
enabled: false,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await app.start({ port: 3000, host: '0.0.0.0' });
|
|
127
|
+
```
|
|
128
|
+
|
|
86
129
|
## First App (2 Minutes)
|
|
87
130
|
|
|
88
131
|
Start with a minimal app, then we will add route conventions step by step.
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { HTTPMethods } from 'fastify/types/utils';
|
|
|
21
21
|
interface OwebOptions extends FastifyServerOptions {
|
|
22
22
|
uWebSocketsEnabled?: boolean;
|
|
23
23
|
poweredByHeader?: boolean;
|
|
24
|
+
staticResponseHeaders?: Record<string, string>;
|
|
24
25
|
OWEB_INTERNAL_ERROR_HANDLER?: Function;
|
|
25
26
|
}
|
|
26
27
|
interface LoadRoutesOptions {
|
package/dist/structures/Oweb.js
CHANGED
|
@@ -61,7 +61,9 @@ class Oweb extends _FastifyInstance {
|
|
|
61
61
|
async setup() {
|
|
62
62
|
if (this._options.uWebSocketsEnabled) {
|
|
63
63
|
const serverimp = (await import("../uwebsocket/server.js")).default;
|
|
64
|
-
const server = await serverimp({
|
|
64
|
+
const server = await serverimp({
|
|
65
|
+
staticResponseHeaders: this._options.staticResponseHeaders
|
|
66
|
+
});
|
|
65
67
|
this.uServer = server;
|
|
66
68
|
this._options.serverFactory = (handler) => {
|
|
67
69
|
server.on("request", handler);
|
|
@@ -74,7 +76,19 @@ class Oweb extends _FastifyInstance {
|
|
|
74
76
|
if (!this._options.uWebSocketsEnabled) {
|
|
75
77
|
await fastify.register(websocketPlugin);
|
|
76
78
|
}
|
|
77
|
-
|
|
79
|
+
const staticHeaderEntries = this._options.staticResponseHeaders ? Object.entries(this._options.staticResponseHeaders) : [];
|
|
80
|
+
if (!this._options.uWebSocketsEnabled && (this._options.poweredByHeader || staticHeaderEntries.length)) {
|
|
81
|
+
fastify.addHook("onRequest", (_, res, done) => {
|
|
82
|
+
if (this._options.poweredByHeader) {
|
|
83
|
+
res.header("X-Powered-By", "Oweb");
|
|
84
|
+
}
|
|
85
|
+
for (let i = 0; i < staticHeaderEntries.length; i++) {
|
|
86
|
+
const [key, value] = staticHeaderEntries[i];
|
|
87
|
+
res.header(key, value);
|
|
88
|
+
}
|
|
89
|
+
done();
|
|
90
|
+
});
|
|
91
|
+
} else if (this._options.poweredByHeader) {
|
|
78
92
|
fastify.addHook("onRequest", (_, res, done) => {
|
|
79
93
|
res.header("X-Powered-By", "Oweb");
|
|
80
94
|
done();
|
|
@@ -17,8 +17,9 @@ class HttpResponse extends Writable {
|
|
|
17
17
|
__headers;
|
|
18
18
|
headersSent;
|
|
19
19
|
finished;
|
|
20
|
+
staticHeaders;
|
|
20
21
|
_socket = null;
|
|
21
|
-
constructor(uResponse, uServer) {
|
|
22
|
+
constructor(uResponse, uServer, staticHeaders) {
|
|
22
23
|
super();
|
|
23
24
|
this.res = uResponse;
|
|
24
25
|
this.server = uServer;
|
|
@@ -27,6 +28,7 @@ class HttpResponse extends Writable {
|
|
|
27
28
|
this.__headers = {};
|
|
28
29
|
this.headersSent = false;
|
|
29
30
|
this.finished = false;
|
|
31
|
+
this.staticHeaders = staticHeaders;
|
|
30
32
|
}
|
|
31
33
|
get socket() {
|
|
32
34
|
if (!this._socket) {
|
|
@@ -62,6 +64,18 @@ class HttpResponse extends Writable {
|
|
|
62
64
|
if (this.headersSent || this.isClosed()) return;
|
|
63
65
|
const message = this.statusMessage || http.STATUS_CODES[this.statusCode] || "Unknown";
|
|
64
66
|
this.res.writeStatus(`${this.statusCode} ${message}`);
|
|
67
|
+
if (this.staticHeaders?.length) {
|
|
68
|
+
for (let i = 0; i < this.staticHeaders.length; i++) {
|
|
69
|
+
const [key, value] = this.staticHeaders[i];
|
|
70
|
+
if (key === "content-length" || key === "transfer-encoding") {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (this.__headers[key] !== void 0) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
this.res.writeHeader(key, value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
65
79
|
const keys = Object.keys(this.__headers);
|
|
66
80
|
for (let i = 0; i < keys.length; i++) {
|
|
67
81
|
const key = keys[i];
|
|
@@ -6,7 +6,7 @@ const REQUEST_EVENT = "request";
|
|
|
6
6
|
import HttpRequest from './request.js';
|
|
7
7
|
import HttpResponse from './response.js';
|
|
8
8
|
import http from "node:http";
|
|
9
|
-
async function server_default({ cert_file_name, key_file_name }) {
|
|
9
|
+
async function server_default({ cert_file_name, key_file_name, staticResponseHeaders }) {
|
|
10
10
|
let uWS;
|
|
11
11
|
uWS = (await import("uWebSockets.js")).default;
|
|
12
12
|
let appType = "App";
|
|
@@ -22,6 +22,10 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
22
22
|
cert_file_name,
|
|
23
23
|
key_file_name
|
|
24
24
|
};
|
|
25
|
+
const normalizedStaticHeaders = staticResponseHeaders ? Object.entries(staticResponseHeaders).map(([k, v]) => [
|
|
26
|
+
k.toLowerCase(),
|
|
27
|
+
String(v)
|
|
28
|
+
]) : void 0;
|
|
25
29
|
const copyArrayBufferToBuffer = /* @__PURE__ */ __name((bytes) => {
|
|
26
30
|
const src = new Uint8Array(bytes);
|
|
27
31
|
const out = Buffer.allocUnsafe(src.byteLength);
|
|
@@ -47,7 +51,7 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
47
51
|
query,
|
|
48
52
|
url
|
|
49
53
|
});
|
|
50
|
-
const resWrapper = new HttpResponse(res, uServer);
|
|
54
|
+
const resWrapper = new HttpResponse(res, uServer, normalizedStaticHeaders);
|
|
51
55
|
reqWrapper.res = resWrapper;
|
|
52
56
|
resWrapper.req = reqWrapper;
|
|
53
57
|
reqWrapper.bindSocketFactory(() => resWrapper.socket);
|