owebjs 1.5.8-dev → 1.6.0-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 +25 -2
- package/dist/index.d.ts +1 -0
- package/dist/structures/Oweb.js +9 -1
- package/dist/utils/assignRoutes.js +73 -54
- package/dist/uwebsocket/server.js +22 -1
- package/package.json +1 -1
- package/0http.js +0 -8
- package/allahbeler2.png +0 -0
- package/allahbeyler.png +0 -0
- package/avatar.png +0 -0
- package/benchmark.txt +0 -191
- package/express.js +0 -14
- package/fasti.js +0 -14
- package/purehttp.js +0 -19
- package/uws.js +0 -16
package/README.md
CHANGED
|
@@ -99,6 +99,7 @@ import Oweb from 'owebjs';
|
|
|
99
99
|
const app = await new Oweb({
|
|
100
100
|
uWebSocketsEnabled: true,
|
|
101
101
|
poweredByHeader: false,
|
|
102
|
+
autoPreflight: true,
|
|
102
103
|
staticResponseHeaders: {
|
|
103
104
|
// CORS (set your real origin in production)
|
|
104
105
|
'access-control-allow-origin': 'https://yourdomain.com',
|
|
@@ -126,6 +127,28 @@ await app.loadRoutes({
|
|
|
126
127
|
await app.start({ port: 3000, host: '0.0.0.0' });
|
|
127
128
|
```
|
|
128
129
|
|
|
130
|
+
## CORS Configuration
|
|
131
|
+
|
|
132
|
+
Use `autoPreflight` to return `204` for preflight requests and set CORS headers through `staticResponseHeaders`.
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
import Oweb from 'owebjs';
|
|
136
|
+
|
|
137
|
+
const app = await new Oweb({
|
|
138
|
+
uWebSocketsEnabled: true,
|
|
139
|
+
autoPreflight: true,
|
|
140
|
+
poweredByHeader: false,
|
|
141
|
+
staticResponseHeaders: {
|
|
142
|
+
'access-control-allow-origin': 'https://yourdomain.com',
|
|
143
|
+
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
|
144
|
+
'access-control-allow-headers': 'Content-Type, Authorization',
|
|
145
|
+
vary: 'Origin',
|
|
146
|
+
},
|
|
147
|
+
}).setup();
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If you need credentials, do not use `*` for `access-control-allow-origin`; set an explicit origin.
|
|
151
|
+
|
|
129
152
|
## First App (2 Minutes)
|
|
130
153
|
|
|
131
154
|
Start with a minimal app, then we will add route conventions step by step.
|
|
@@ -167,7 +190,7 @@ routes/
|
|
|
167
190
|
[id].js
|
|
168
191
|
auth/
|
|
169
192
|
login.post.js
|
|
170
|
-
|
|
193
|
+
posts/
|
|
171
194
|
[id=integer].js
|
|
172
195
|
events/
|
|
173
196
|
sse.js
|
|
@@ -236,7 +259,7 @@ export default class LoginPostRoute extends Route {
|
|
|
236
259
|
|
|
237
260
|
Matcher params add filename-level validation.
|
|
238
261
|
|
|
239
|
-
`routes/
|
|
262
|
+
`routes/posts/[id=integer].js` + `matchers/integer.js`
|
|
240
263
|
|
|
241
264
|
```js
|
|
242
265
|
// matchers/integer.js
|
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
|
+
autoPreflight?: boolean;
|
|
24
25
|
staticResponseHeaders?: Record<string, string>;
|
|
25
26
|
OWEB_INTERNAL_ERROR_HANDLER?: Function;
|
|
26
27
|
}
|
package/dist/structures/Oweb.js
CHANGED
|
@@ -29,6 +29,7 @@ class Oweb extends _FastifyInstance {
|
|
|
29
29
|
this._options = options ?? {};
|
|
30
30
|
this._options.uWebSocketsEnabled ??= false;
|
|
31
31
|
this._options.poweredByHeader ??= true;
|
|
32
|
+
this._options.autoPreflight ??= false;
|
|
32
33
|
this._options.OWEB_INTERNAL_ERROR_HANDLER ??= (_, res, err) => {
|
|
33
34
|
return res.status(500).send({
|
|
34
35
|
error: err.message
|
|
@@ -62,7 +63,9 @@ class Oweb extends _FastifyInstance {
|
|
|
62
63
|
if (this._options.uWebSocketsEnabled) {
|
|
63
64
|
const serverimp = (await import("../uwebsocket/server.js")).default;
|
|
64
65
|
const server = await serverimp({
|
|
65
|
-
staticResponseHeaders: this._options.staticResponseHeaders
|
|
66
|
+
staticResponseHeaders: this._options.staticResponseHeaders,
|
|
67
|
+
autoPreflight: this._options.autoPreflight,
|
|
68
|
+
poweredByHeader: this._options.poweredByHeader
|
|
66
69
|
});
|
|
67
70
|
this.uServer = server;
|
|
68
71
|
this._options.serverFactory = (handler) => {
|
|
@@ -94,6 +97,11 @@ class Oweb extends _FastifyInstance {
|
|
|
94
97
|
done();
|
|
95
98
|
});
|
|
96
99
|
}
|
|
100
|
+
if (this._options.autoPreflight && !this._options.uWebSocketsEnabled) {
|
|
101
|
+
fastify.options("/*", (_req, res) => {
|
|
102
|
+
return res.status(204).send();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
97
105
|
const internalKV = this._internalKV;
|
|
98
106
|
fastify.addHook("onClose", async () => {
|
|
99
107
|
const watchers = internalKV.get(HMR_WATCHERS_KEY);
|
|
@@ -12,8 +12,8 @@ import { readdirSync } from "node:fs";
|
|
|
12
12
|
import { WebSocketRoute } from '../structures/WebSocketRoute.js';
|
|
13
13
|
import { FastifyWebSocketAdapter } from '../structures/FastifyWebSocketAdapter.js';
|
|
14
14
|
import { formatSSE } from './utils.js';
|
|
15
|
-
const websocketRoutes = {};
|
|
16
15
|
const WS_REGISTRY_KEY = "ws:registered-routes";
|
|
16
|
+
const runtimeStates = /* @__PURE__ */ new WeakMap();
|
|
17
17
|
const createMethodMap = /* @__PURE__ */ __name(() => ({
|
|
18
18
|
get: {},
|
|
19
19
|
post: {},
|
|
@@ -22,11 +22,26 @@ const createMethodMap = /* @__PURE__ */ __name(() => ({
|
|
|
22
22
|
patch: {},
|
|
23
23
|
options: {}
|
|
24
24
|
}), "createMethodMap");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
function createRuntimeState() {
|
|
26
|
+
return {
|
|
27
|
+
matcherOverrides: {},
|
|
28
|
+
routeFunctions: createMethodMap(),
|
|
29
|
+
temporaryRequests: createMethodMap(),
|
|
30
|
+
routesCache: [],
|
|
31
|
+
compiledRoutes: {},
|
|
32
|
+
websocketRoutes: {}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
__name(createRuntimeState, "createRuntimeState");
|
|
36
|
+
function getRuntimeState(oweb) {
|
|
37
|
+
let state = runtimeStates.get(oweb);
|
|
38
|
+
if (!state) {
|
|
39
|
+
state = createRuntimeState();
|
|
40
|
+
runtimeStates.set(oweb, state);
|
|
41
|
+
}
|
|
42
|
+
return state;
|
|
43
|
+
}
|
|
44
|
+
__name(getRuntimeState, "getRuntimeState");
|
|
30
45
|
function normalizeFsPath(filePath) {
|
|
31
46
|
return path.resolve(filePath).replaceAll("\\", "/").toLowerCase();
|
|
32
47
|
}
|
|
@@ -47,14 +62,13 @@ async function importFreshModule(filePath, source) {
|
|
|
47
62
|
}
|
|
48
63
|
__name(importFreshModule, "importFreshModule");
|
|
49
64
|
function resetRuntimeCaches(oweb) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
65
|
+
const state = getRuntimeState(oweb);
|
|
66
|
+
state.matcherOverrides = {};
|
|
67
|
+
state.routeFunctions = createMethodMap();
|
|
68
|
+
state.temporaryRequests = createMethodMap();
|
|
69
|
+
state.routesCache = [];
|
|
70
|
+
state.compiledRoutes = {};
|
|
71
|
+
state.websocketRoutes = {};
|
|
58
72
|
oweb._internalKV.delete(WS_REGISTRY_KEY);
|
|
59
73
|
}
|
|
60
74
|
__name(resetRuntimeCaches, "resetRuntimeCaches");
|
|
@@ -66,8 +80,8 @@ function removeExtension(filePath) {
|
|
|
66
80
|
return filePath;
|
|
67
81
|
}
|
|
68
82
|
__name(removeExtension, "removeExtension");
|
|
69
|
-
function createWebSocketProxy(url) {
|
|
70
|
-
const getHandler = /* @__PURE__ */ __name(() => websocketRoutes[url], "getHandler");
|
|
83
|
+
function createWebSocketProxy(oweb, url) {
|
|
84
|
+
const getHandler = /* @__PURE__ */ __name(() => getRuntimeState(oweb).websocketRoutes[url], "getHandler");
|
|
71
85
|
return {
|
|
72
86
|
compression: getHandler()?._options.compression,
|
|
73
87
|
maxPayloadLength: getHandler()?._options.maxPayloadLength,
|
|
@@ -101,10 +115,11 @@ function createWebSocketProxy(url) {
|
|
|
101
115
|
}
|
|
102
116
|
__name(createWebSocketProxy, "createWebSocketProxy");
|
|
103
117
|
const applyMatcherHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallbackDir, filePath, content) => {
|
|
118
|
+
const state = getRuntimeState(oweb);
|
|
104
119
|
let def;
|
|
105
120
|
const fileName = path.basename(filePath);
|
|
106
121
|
if (op === "delete-file") {
|
|
107
|
-
delete matcherOverrides[removeExtension(fileName)];
|
|
122
|
+
delete state.matcherOverrides[removeExtension(fileName)];
|
|
108
123
|
success(`Matcher ${filePath} removed in 0ms`, "HMR");
|
|
109
124
|
return;
|
|
110
125
|
}
|
|
@@ -122,10 +137,11 @@ const applyMatcherHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fall
|
|
|
122
137
|
success(`Matcher ${filePath} reloaded in ${end}ms`, "HMR");
|
|
123
138
|
}
|
|
124
139
|
if (def) {
|
|
125
|
-
matcherOverrides[removeExtension(fileName)] = def;
|
|
140
|
+
state.matcherOverrides[removeExtension(fileName)] = def;
|
|
126
141
|
}
|
|
127
142
|
}, "applyMatcherHMR");
|
|
128
143
|
const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallbackDir, path2, content) => {
|
|
144
|
+
const state = getRuntimeState(oweb);
|
|
129
145
|
const normalizedChangedPath = normalizeFsPath(path2);
|
|
130
146
|
if (path2.endsWith("hooks.js") || path2.endsWith("hooks.ts")) {
|
|
131
147
|
warn(`Hot Module Replacement is not supported for hooks. Restart the server for changes to take effect.`, "HMR");
|
|
@@ -133,15 +149,15 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
|
|
|
133
149
|
}
|
|
134
150
|
if (path2.endsWith(".ts")) {
|
|
135
151
|
const start = Date.now();
|
|
136
|
-
compiledRoutes[path2] = content.length ? await generateFunctionFromTypescript(content, path2) : void 0;
|
|
152
|
+
state.compiledRoutes[path2] = content.length ? await generateFunctionFromTypescript(content, path2) : void 0;
|
|
137
153
|
const end = Date.now() - start;
|
|
138
154
|
success(`File ${path2} compiled in ${end}ms`, "HMR");
|
|
139
155
|
}
|
|
140
156
|
if (op === "new-file") {
|
|
141
157
|
const start = Date.now();
|
|
142
158
|
const files = await walk(workingDir, [], fallbackDir);
|
|
143
|
-
const routes = await generateRoutes(files, path2);
|
|
144
|
-
routesCache = routes;
|
|
159
|
+
const routes = await generateRoutes(files, path2, state.compiledRoutes);
|
|
160
|
+
state.routesCache = routes;
|
|
145
161
|
const f = routes.find((x) => normalizeFsPath(x.fileInfo.filePath) === normalizedChangedPath);
|
|
146
162
|
if (!f) {
|
|
147
163
|
warn(`HMR could not resolve route metadata for file ${path2}`, "HMR");
|
|
@@ -161,18 +177,18 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
|
|
|
161
177
|
}
|
|
162
178
|
const method = f.method.toLowerCase();
|
|
163
179
|
const nextHandler = inner(oweb, f);
|
|
164
|
-
if (routeFunctions[method][f.url]) {
|
|
165
|
-
routeFunctions[method][f.url] = nextHandler;
|
|
180
|
+
if (state.routeFunctions[method][f.url]) {
|
|
181
|
+
state.routeFunctions[method][f.url] = nextHandler;
|
|
166
182
|
} else {
|
|
167
|
-
temporaryRequests[method][f.url] = nextHandler;
|
|
183
|
+
state.temporaryRequests[method][f.url] = nextHandler;
|
|
168
184
|
}
|
|
169
185
|
const end = Date.now() - start;
|
|
170
186
|
success(`Route ${f.method.toUpperCase()}:${f.url} created in ${end}ms`, "HMR");
|
|
171
187
|
} else if (op === "modify-file") {
|
|
172
188
|
const start = Date.now();
|
|
173
189
|
const files = await walk(workingDir, [], fallbackDir);
|
|
174
|
-
const routes = await generateRoutes(files, path2);
|
|
175
|
-
routesCache = routes;
|
|
190
|
+
const routes = await generateRoutes(files, path2, state.compiledRoutes);
|
|
191
|
+
state.routesCache = routes;
|
|
176
192
|
const f = routes.find((x) => normalizeFsPath(x.fileInfo.filePath) === normalizedChangedPath);
|
|
177
193
|
if (!f) {
|
|
178
194
|
warn(`HMR could not resolve route metadata for file ${path2}`, "HMR");
|
|
@@ -185,19 +201,19 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
|
|
|
185
201
|
}
|
|
186
202
|
}
|
|
187
203
|
if (f.fn?.prototype instanceof WebSocketRoute) {
|
|
188
|
-
websocketRoutes[f.url] = new f.fn();
|
|
204
|
+
state.websocketRoutes[f.url] = new f.fn();
|
|
189
205
|
const end2 = Date.now() - start;
|
|
190
206
|
success(`WebSocket Route ${f.url} reloaded in ${end2}ms`, "HMR");
|
|
191
207
|
return;
|
|
192
208
|
}
|
|
193
209
|
const method = f.method.toLowerCase();
|
|
194
210
|
const nextHandler = inner(oweb, f);
|
|
195
|
-
if (routeFunctions[method][f.url]) {
|
|
196
|
-
routeFunctions[method][f.url] = nextHandler;
|
|
197
|
-
} else if (f.url in temporaryRequests[method]) {
|
|
198
|
-
temporaryRequests[method][f.url] = nextHandler;
|
|
211
|
+
if (state.routeFunctions[method][f.url]) {
|
|
212
|
+
state.routeFunctions[method][f.url] = nextHandler;
|
|
213
|
+
} else if (f.url in state.temporaryRequests[method]) {
|
|
214
|
+
state.temporaryRequests[method][f.url] = nextHandler;
|
|
199
215
|
} else {
|
|
200
|
-
routeFunctions[method][f.url] = nextHandler;
|
|
216
|
+
state.routeFunctions[method][f.url] = nextHandler;
|
|
201
217
|
}
|
|
202
218
|
const end = Date.now() - start;
|
|
203
219
|
success(`Route ${f.method.toUpperCase()}:${f.url} reloaded in ${end}ms`, "HMR");
|
|
@@ -208,25 +224,25 @@ const applyRouteHMR = /* @__PURE__ */ __name(async (oweb, op, workingDir, fallba
|
|
|
208
224
|
if (builded.url.endsWith("/index")) {
|
|
209
225
|
builded.url = builded.url.slice(0, -"/index".length);
|
|
210
226
|
}
|
|
211
|
-
if (websocketRoutes[builded.url]) {
|
|
212
|
-
delete websocketRoutes[builded.url];
|
|
227
|
+
if (state.websocketRoutes[builded.url]) {
|
|
228
|
+
delete state.websocketRoutes[builded.url];
|
|
213
229
|
const end = Date.now() - start;
|
|
214
230
|
success(`WebSocket Route ${builded.url} removed (shimmed) in ${end}ms`, "HMR");
|
|
215
231
|
return;
|
|
216
232
|
}
|
|
217
|
-
const f = routesCache.find((x) => x.method == builded.method && x.url == builded.url);
|
|
233
|
+
const f = state.routesCache.find((x) => x.method == builded.method && x.url == builded.url);
|
|
218
234
|
if (f) {
|
|
219
|
-
if (f.url in temporaryRequests[f.method.toLowerCase()]) {
|
|
220
|
-
delete temporaryRequests[f.method.toLowerCase()][f.url];
|
|
235
|
+
if (f.url in state.temporaryRequests[f.method.toLowerCase()]) {
|
|
236
|
+
delete state.temporaryRequests[f.method.toLowerCase()][f.url];
|
|
221
237
|
} else {
|
|
222
|
-
delete routeFunctions[f.method.toLowerCase()][f.url];
|
|
238
|
+
delete state.routeFunctions[f.method.toLowerCase()][f.url];
|
|
223
239
|
}
|
|
224
240
|
const end = Date.now() - start;
|
|
225
241
|
success(`Route ${f.method.toUpperCase()}:${f.url} removed in ${end}ms`, "HMR");
|
|
226
242
|
}
|
|
227
243
|
}
|
|
228
244
|
}, "applyRouteHMR");
|
|
229
|
-
const generateRoutes = /* @__PURE__ */ __name(async (files, onlyGenerateFn) => {
|
|
245
|
+
const generateRoutes = /* @__PURE__ */ __name(async (files, onlyGenerateFn, compiledRoutes = {}) => {
|
|
230
246
|
const routes = [];
|
|
231
247
|
for (const file of files) {
|
|
232
248
|
const parsedFile = path.parse(file.rel);
|
|
@@ -272,11 +288,12 @@ function inner(oweb, route) {
|
|
|
272
288
|
const handleIsAsync = routeFunc.handle.constructor.name === "AsyncFunction";
|
|
273
289
|
const hasRouteErrorHandler = typeof routeFunc?.handleError === "function";
|
|
274
290
|
const hmrEnabled = !!oweb._internalKV.get("hmr");
|
|
291
|
+
const state = getRuntimeState(oweb);
|
|
275
292
|
const checkMatchers = /* @__PURE__ */ __name((req) => {
|
|
276
293
|
if (!hasMatchers) return true;
|
|
277
294
|
for (const matcher of matchers) {
|
|
278
295
|
const param = req.params[matcher.paramName];
|
|
279
|
-
const fun = matcherOverrides[matcher.matcherName];
|
|
296
|
+
const fun = state.matcherOverrides[matcher.matcherName];
|
|
280
297
|
if (fun) {
|
|
281
298
|
return fun(param);
|
|
282
299
|
}
|
|
@@ -432,7 +449,7 @@ function inner(oweb, route) {
|
|
|
432
449
|
if (hmrEnabled && isParametric) {
|
|
433
450
|
const currentPath = req.raw.url.split("?")[0];
|
|
434
451
|
const method = req.method.toLowerCase();
|
|
435
|
-
const specificHandler = temporaryRequests[method]?.[currentPath];
|
|
452
|
+
const specificHandler = state.temporaryRequests[method]?.[currentPath];
|
|
436
453
|
if (specificHandler) {
|
|
437
454
|
return specificHandler(req, res);
|
|
438
455
|
}
|
|
@@ -467,14 +484,15 @@ function getRegisteredWebSocketsForApp(oweb) {
|
|
|
467
484
|
__name(getRegisteredWebSocketsForApp, "getRegisteredWebSocketsForApp");
|
|
468
485
|
function assignSpecificRoute(oweb, route) {
|
|
469
486
|
if (!route?.fn) return;
|
|
487
|
+
const state = getRuntimeState(oweb);
|
|
470
488
|
if (route?.fn?.prototype instanceof WebSocketRoute) {
|
|
471
489
|
const wsInstance = new route.fn();
|
|
472
|
-
websocketRoutes[route.url] = wsInstance;
|
|
490
|
+
state.websocketRoutes[route.url] = wsInstance;
|
|
473
491
|
const registeredWebSockets = getRegisteredWebSocketsForApp(oweb);
|
|
474
492
|
if (!registeredWebSockets.has(route.url)) {
|
|
475
493
|
registeredWebSockets.add(route.url);
|
|
476
494
|
if (oweb._options.uWebSocketsEnabled && oweb.uServer) {
|
|
477
|
-
const proxy = createWebSocketProxy(route.url);
|
|
495
|
+
const proxy = createWebSocketProxy(oweb, route.url);
|
|
478
496
|
oweb.ws(route.url, proxy, route.fileInfo.hooks);
|
|
479
497
|
} else {
|
|
480
498
|
oweb.get(route.url, {
|
|
@@ -532,7 +550,7 @@ function assignSpecificRoute(oweb, route) {
|
|
|
532
550
|
}
|
|
533
551
|
return;
|
|
534
552
|
}
|
|
535
|
-
const getHandler = /* @__PURE__ */ __name(() => websocketRoutes[route.url], "getHandler");
|
|
553
|
+
const getHandler = /* @__PURE__ */ __name(() => state.websocketRoutes[route.url], "getHandler");
|
|
536
554
|
socket.on("message", (message, isBinary) => {
|
|
537
555
|
const h = getHandler();
|
|
538
556
|
if (h?.message) h.message(adapter, message, isBinary);
|
|
@@ -573,12 +591,12 @@ function assignSpecificRoute(oweb, route) {
|
|
|
573
591
|
if (!routeHandler) return;
|
|
574
592
|
const hmrEnabled = !!oweb._internalKV.get("hmr");
|
|
575
593
|
if (hmrEnabled) {
|
|
576
|
-
routeFunctions[route.method][route.url] = routeHandler;
|
|
594
|
+
state.routeFunctions[route.method][route.url] = routeHandler;
|
|
577
595
|
oweb[route.method](route.url, routeFunc._options || {}, function(req, res) {
|
|
578
|
-
if (routeFunctions[route.method][route.url]) {
|
|
579
|
-
return routeFunctions[route.method][route.url](req, res);
|
|
596
|
+
if (state.routeFunctions[route.method][route.url]) {
|
|
597
|
+
return state.routeFunctions[route.method][route.url](req, res);
|
|
580
598
|
} else {
|
|
581
|
-
const vals = temporaryRequests[route.method];
|
|
599
|
+
const vals = state.temporaryRequests[route.method];
|
|
582
600
|
const keys = Object.keys(vals);
|
|
583
601
|
if (!vals || !keys.length) {
|
|
584
602
|
return send404(req, res);
|
|
@@ -599,7 +617,7 @@ function assignSpecificRoute(oweb, route) {
|
|
|
599
617
|
oweb[route.method](route.url, routeFunc._options || {}, routeHandler);
|
|
600
618
|
}
|
|
601
619
|
__name(assignSpecificRoute, "assignSpecificRoute");
|
|
602
|
-
async function loadMatchers(directoryPath) {
|
|
620
|
+
async function loadMatchers(directoryPath, state) {
|
|
603
621
|
const files = readdirSync(directoryPath).filter((f) => [
|
|
604
622
|
".js",
|
|
605
623
|
".ts"
|
|
@@ -609,20 +627,21 @@ async function loadMatchers(directoryPath) {
|
|
|
609
627
|
const fileName = path.basename(filePath);
|
|
610
628
|
const packageURL = pathToFileURL(path.resolve(filePath)).href;
|
|
611
629
|
const def = await import(packageURL);
|
|
612
|
-
matcherOverrides[removeExtension(fileName)] = def.default;
|
|
630
|
+
state.matcherOverrides[removeExtension(fileName)] = def.default;
|
|
613
631
|
}
|
|
614
632
|
}
|
|
615
633
|
__name(loadMatchers, "loadMatchers");
|
|
616
634
|
const assignRoutes = /* @__PURE__ */ __name(async (oweb, directory, matchersDirectory) => {
|
|
617
635
|
resetRuntimeCaches(oweb);
|
|
636
|
+
const state = getRuntimeState(oweb);
|
|
618
637
|
if (matchersDirectory) {
|
|
619
|
-
await loadMatchers(matchersDirectory);
|
|
638
|
+
await loadMatchers(matchersDirectory, state);
|
|
620
639
|
}
|
|
621
640
|
const files = await walk(directory);
|
|
622
|
-
const routes = await generateRoutes(files);
|
|
623
|
-
routesCache = routes;
|
|
641
|
+
const routes = await generateRoutes(files, void 0, state.compiledRoutes);
|
|
642
|
+
state.routesCache = routes;
|
|
624
643
|
function fallbackHandle(req, res) {
|
|
625
|
-
const vals = temporaryRequests[req.method.toLowerCase()];
|
|
644
|
+
const vals = state.temporaryRequests[req.method.toLowerCase()];
|
|
626
645
|
const keys = Object.keys(vals);
|
|
627
646
|
if (!vals || !keys.length) {
|
|
628
647
|
return send404(req, res);
|
|
@@ -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, staticResponseHeaders }) {
|
|
9
|
+
async function server_default({ cert_file_name, key_file_name, staticResponseHeaders, autoPreflight, poweredByHeader }) {
|
|
10
10
|
let uWS;
|
|
11
11
|
uWS = (await import("uWebSockets.js")).default;
|
|
12
12
|
let appType = "App";
|
|
@@ -37,6 +37,27 @@ async function server_default({ cert_file_name, key_file_name, staticResponseHea
|
|
|
37
37
|
const query = req.getQuery();
|
|
38
38
|
const url = req.getUrl();
|
|
39
39
|
const requiresBody = method !== "HEAD" && method !== "GET";
|
|
40
|
+
if (autoPreflight && method === "OPTIONS") {
|
|
41
|
+
res.writeStatus("204 No Content");
|
|
42
|
+
let hasPoweredByHeader = false;
|
|
43
|
+
if (normalizedStaticHeaders?.length) {
|
|
44
|
+
for (let i = 0; i < normalizedStaticHeaders.length; i++) {
|
|
45
|
+
const [key, value] = normalizedStaticHeaders[i];
|
|
46
|
+
if (key === "content-length" || key === "transfer-encoding") {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (key === "x-powered-by") {
|
|
50
|
+
hasPoweredByHeader = true;
|
|
51
|
+
}
|
|
52
|
+
res.writeHeader(key, value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (poweredByHeader && !hasPoweredByHeader) {
|
|
56
|
+
res.writeHeader("x-powered-by", "Oweb");
|
|
57
|
+
}
|
|
58
|
+
res.end();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
40
61
|
res.finished = false;
|
|
41
62
|
res.aborted = false;
|
|
42
63
|
if (requiresBody) {
|
package/package.json
CHANGED
package/0http.js
DELETED
package/allahbeler2.png
DELETED
|
Binary file
|
package/allahbeyler.png
DELETED
|
Binary file
|
package/avatar.png
DELETED
|
Binary file
|
package/benchmark.txt
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
OWEB UWS:
|
|
2
|
-
|
|
3
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
4
|
-
Running 40s test @ http://localhost:3000
|
|
5
|
-
100 connections with 10 pipelining factor
|
|
6
|
-
|
|
7
|
-
running [=================== ] 95%
|
|
8
|
-
┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
|
9
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
10
|
-
├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
|
11
|
-
│ Latency │ 5 ms │ 12 ms │ 73 ms │ 98 ms │ 15.81 ms │ 15.73 ms │ 158 ms │
|
|
12
|
-
└─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
|
13
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
|
|
14
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
15
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
16
|
-
│ Req/Sec │ 57.087 │ 57.087 │ 64.991 │ 72.191 │ 64.785,27 │ 3.607,71 │ 57.060 │
|
|
17
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
18
|
-
│ Bytes/Sec │ 9.42 MB │ 9.42 MB │ 10.7 MB │ 11.9 MB │ 10.7 MB │ 596 kB │ 9.41 MB │
|
|
19
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
|
|
20
|
-
|
|
21
|
-
Req/Bytes counts sampled once per second.
|
|
22
|
-
# of samples: 38
|
|
23
|
-
|
|
24
|
-
2463k requests in 40.19s, 406 MB read
|
|
25
|
-
╭─ pwsh 40s 459ms⠀ 6,13:14
|
|
26
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
27
|
-
Running 40s test @ http://localhost:3000
|
|
28
|
-
100 connections with 10 pipelining factor
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
┌─────────┬──────┬───────┬───────┬───────┬─────────┬──────────┬────────┐
|
|
32
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
33
|
-
├─────────┼──────┼───────┼───────┼───────┼─────────┼──────────┼────────┤
|
|
34
|
-
│ Latency │ 5 ms │ 13 ms │ 72 ms │ 98 ms │ 15.9 ms │ 15.27 ms │ 262 ms │
|
|
35
|
-
└─────────┴──────┴───────┴───────┴───────┴─────────┴──────────┴────────┘
|
|
36
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
|
|
37
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
38
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
39
|
-
│ Req/Sec │ 48.959 │ 48.959 │ 64.447 │ 70.783 │ 63.949,54 │ 4.776,67 │ 48.930 │
|
|
40
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
41
|
-
│ Bytes/Sec │ 8.08 MB │ 8.08 MB │ 10.6 MB │ 11.7 MB │ 10.6 MB │ 789 kB │ 8.07 MB │
|
|
42
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
|
|
43
|
-
|
|
44
|
-
Req/Bytes counts sampled once per second.
|
|
45
|
-
# of samples: 39
|
|
46
|
-
|
|
47
|
-
2495k requests in 40.96s, 412 MB read
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
OWEB FASTIFY:
|
|
51
|
-
|
|
52
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
53
|
-
Running 40s test @ http://localhost:3000
|
|
54
|
-
100 connections with 10 pipelining factor
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
|
|
58
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
59
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
|
|
60
|
-
│ Latency │ 3 ms │ 21 ms │ 84 ms │ 110 ms │ 26.12 ms │ 20.65 ms │ 200 ms │
|
|
61
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
|
|
62
|
-
┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
|
|
63
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
64
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
65
|
-
│ Req/Sec │ 26.751 │ 26.751 │ 36.287 │ 45.503 │ 37.570,6 │ 4.606,09 │ 26.741 │
|
|
66
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
67
|
-
│ Bytes/Sec │ 4.76 MB │ 4.76 MB │ 6.46 MB │ 8.1 MB │ 6.69 MB │ 820 kB │ 4.76 MB │
|
|
68
|
-
└───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
|
|
69
|
-
|
|
70
|
-
Req/Bytes counts sampled once per second.
|
|
71
|
-
# of samples: 40
|
|
72
|
-
|
|
73
|
-
1504k requests in 40.05s, 268 MB read
|
|
74
|
-
╭─ pwsh 40s 334ms⠀ 6,13:16
|
|
75
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
76
|
-
Running 40s test @ http://localhost:3000
|
|
77
|
-
100 connections with 10 pipelining factor
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
|
|
81
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
82
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
|
|
83
|
-
│ Latency │ 4 ms │ 20 ms │ 93 ms │ 122 ms │ 24.03 ms │ 21.64 ms │ 209 ms │
|
|
84
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
|
|
85
|
-
┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
|
|
86
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
87
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
88
|
-
│ Req/Sec │ 29.759 │ 29.759 │ 41.343 │ 44.895 │ 40.765,81 │ 3.004,68 │ 29.750 │
|
|
89
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
90
|
-
│ Bytes/Sec │ 5.3 MB │ 5.3 MB │ 7.36 MB │ 7.99 MB │ 7.26 MB │ 535 kB │ 5.3 MB │
|
|
91
|
-
└───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
|
|
92
|
-
|
|
93
|
-
Req/Bytes counts sampled once per second.
|
|
94
|
-
# of samples: 40
|
|
95
|
-
|
|
96
|
-
1632k requests in 40.05s, 290 MB read
|
|
97
|
-
|
|
98
|
-
DÜZ FASTIFY:
|
|
99
|
-
|
|
100
|
-
Running 40s test @ http://localhost:3000
|
|
101
|
-
100 connections with 10 pipelining factor
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
|
105
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
106
|
-
├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
|
107
|
-
│ Latency │ 3 ms │ 18 ms │ 76 ms │ 97 ms │ 21.09 ms │ 17.82 ms │ 257 ms │
|
|
108
|
-
└─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
|
109
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬──────────┬─────────┐
|
|
110
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
111
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
|
|
112
|
-
│ Req/Sec │ 32.543 │ 32.543 │ 46.783 │ 49.695 │ 46.349,8 │ 2.964,89 │ 32.530 │
|
|
113
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
|
|
114
|
-
│ Bytes/Sec │ 5.79 MB │ 5.79 MB │ 8.33 MB │ 8.85 MB │ 8.25 MB │ 528 kB │ 5.79 MB │
|
|
115
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴──────────┴─────────┘
|
|
116
|
-
|
|
117
|
-
Req/Bytes counts sampled once per second.
|
|
118
|
-
# of samples: 40
|
|
119
|
-
|
|
120
|
-
1855k requests in 40.06s, 330 MB read
|
|
121
|
-
╭─ pwsh 40s 362ms⠀ 6,13:18
|
|
122
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
123
|
-
Running 40s test @ http://localhost:3000
|
|
124
|
-
100 connections with 10 pipelining factor
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬─────────┬────────┐
|
|
128
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
129
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼─────────┼────────┤
|
|
130
|
-
│ Latency │ 3 ms │ 18 ms │ 80 ms │ 102 ms │ 21.48 ms │ 18.3 ms │ 188 ms │
|
|
131
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴─────────┴────────┘
|
|
132
|
-
┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
|
|
133
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
134
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
135
|
-
│ Req/Sec │ 37.567 │ 37.567 │ 45.535 │ 48.863 │ 45.501,6 │ 2.214,24 │ 37.550 │
|
|
136
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
137
|
-
│ Bytes/Sec │ 6.68 MB │ 6.68 MB │ 8.11 MB │ 8.7 MB │ 8.1 MB │ 394 kB │ 6.68 MB │
|
|
138
|
-
└───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
|
|
139
|
-
|
|
140
|
-
Req/Bytes counts sampled once per second.
|
|
141
|
-
# of samples: 40
|
|
142
|
-
|
|
143
|
-
1821k requests in 40.05s, 324 MB read
|
|
144
|
-
|
|
145
|
-
DÜZ UWS:
|
|
146
|
-
|
|
147
|
-
Running 40s test @ http://localhost:3000
|
|
148
|
-
100 connections with 10 pipelining factor
|
|
149
|
-
|
|
150
|
-
running [=================== ] 95%
|
|
151
|
-
┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
|
|
152
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
153
|
-
├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
|
|
154
|
-
│ Latency │ 11 ms │ 12 ms │ 19 ms │ 22 ms │ 12.93 ms │ 3.39 ms │ 167 ms │
|
|
155
|
-
└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
|
|
156
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬─────────┬─────────┐
|
|
157
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
158
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
|
|
159
|
-
│ Req/Sec │ 71.743 │ 71.743 │ 80.831 │ 80.959 │ 79.149,48 │ 3.427,1 │ 71.730 │
|
|
160
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
|
|
161
|
-
│ Bytes/Sec │ 10.6 MB │ 10.6 MB │ 11.9 MB │ 11.9 MB │ 11.6 MB │ 503 kB │ 10.5 MB │
|
|
162
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴─────────┴─────────┘
|
|
163
|
-
|
|
164
|
-
Req/Bytes counts sampled once per second.
|
|
165
|
-
# of samples: 38
|
|
166
|
-
|
|
167
|
-
3009k requests in 40.43s, 442 MB read
|
|
168
|
-
╭─ pwsh 40s 739ms⠀ 6,13:20
|
|
169
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
170
|
-
Running 40s test @ http://localhost:3000
|
|
171
|
-
100 connections with 10 pipelining factor
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
|
|
175
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
176
|
-
├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
|
|
177
|
-
│ Latency │ 10 ms │ 12 ms │ 20 ms │ 22 ms │ 12.44 ms │ 3.35 ms │ 181 ms │
|
|
178
|
-
└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
|
|
179
|
-
┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
|
|
180
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
181
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
182
|
-
│ Req/Sec │ 68.287 │ 68.287 │ 80.831 │ 89.855 │ 81.377,65 │ 4.922,97 │ 68.284 │
|
|
183
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
184
|
-
│ Bytes/Sec │ 10 MB │ 10 MB │ 11.9 MB │ 13.2 MB │ 12 MB │ 724 kB │ 10 MB │
|
|
185
|
-
└───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
|
|
186
|
-
|
|
187
|
-
Req/Bytes counts sampled once per second.
|
|
188
|
-
# of samples: 39
|
|
189
|
-
|
|
190
|
-
3175k requests in 41.09s, 467 MB read
|
|
191
|
-
|
package/express.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
|
|
3
|
-
const app = express();
|
|
4
|
-
const port = 3000;
|
|
5
|
-
|
|
6
|
-
// Define a route for the root URL
|
|
7
|
-
app.get('/', (req, res) => {
|
|
8
|
-
res.send('Hello World from Express!');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
// Start the server
|
|
12
|
-
app.listen(port, () => {
|
|
13
|
-
console.log(`Express app listening at http://localhost:${port}`);
|
|
14
|
-
});
|
package/fasti.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import fastify from 'fastify';
|
|
2
|
-
|
|
3
|
-
const app = fastify();
|
|
4
|
-
|
|
5
|
-
app.get('/', async (request, reply) => {
|
|
6
|
-
return 'Hello, World!';
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
app.listen({ port: 3000, host: '0.0.0.0' }, (err) => {
|
|
10
|
-
if (err) {
|
|
11
|
-
console.error(err);
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
});
|
package/purehttp.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import http from 'node:http';
|
|
2
|
-
|
|
3
|
-
const hostname = '127.0.0.1';
|
|
4
|
-
const port = 3000;
|
|
5
|
-
|
|
6
|
-
// Create the server instance
|
|
7
|
-
const server = http.createServer((req, res) => {
|
|
8
|
-
// Set the response header with HTTP status and Content-Type
|
|
9
|
-
res.statusCode = 200;
|
|
10
|
-
res.setHeader('Content-Type', 'text/plain');
|
|
11
|
-
|
|
12
|
-
// Send the response body
|
|
13
|
-
res.end('Hello, World!\n');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// Start listening for requests
|
|
17
|
-
server.listen(port, hostname, () => {
|
|
18
|
-
console.log(`Server running at http://${hostname}:${port}/`);
|
|
19
|
-
});
|
package/uws.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import uWS from 'uwebsockets.js';
|
|
2
|
-
|
|
3
|
-
uWS.App()
|
|
4
|
-
.get('/', (res, req) => {
|
|
5
|
-
res.writeStatus('200 OK')
|
|
6
|
-
.writeHeader('Content-Type', 'text/plain; charset=utf-8')
|
|
7
|
-
.end('Hello, World!');
|
|
8
|
-
})
|
|
9
|
-
.listen('0.0.0.0', 3000, (listenSocket) => {
|
|
10
|
-
if (listenSocket) {
|
|
11
|
-
console.log('uWebSockets.js listening on http://localhost:3000');
|
|
12
|
-
} else {
|
|
13
|
-
console.error('Failed to listen on port 3000');
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
});
|