owebjs 1.5.5-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/0http.js +8 -0
- package/README.md +477 -270
- package/benchmark.txt +191 -0
- package/dist/index.d.ts +4 -0
- package/dist/structures/Oweb.js +67 -8
- package/dist/utils/assignRoutes.js +298 -180
- package/dist/utils/walk.js +5 -6
- package/dist/utils/watcher.js +21 -9
- package/dist/uwebsocket/request.js +59 -26
- package/dist/uwebsocket/response.js +34 -12
- package/dist/uwebsocket/responseSocket.js +5 -1
- package/dist/uwebsocket/server.js +84 -53
- package/express.js +14 -0
- package/fasti.js +14 -0
- package/package.json +6 -4
- package/purehttp.js +19 -0
- package/uws.js +16 -0
package/dist/utils/watcher.js
CHANGED
|
@@ -19,20 +19,32 @@ function watchDirectory(dir, ignoreInitial = true, onUpdate) {
|
|
|
19
19
|
".js",
|
|
20
20
|
".ts"
|
|
21
21
|
];
|
|
22
|
-
|
|
22
|
+
let operationQueue = Promise.resolve();
|
|
23
|
+
const enqueueUpdate = /* @__PURE__ */ __name((op, filePath) => {
|
|
23
24
|
if (!supportedExtensions.includes(extname(filePath))) return;
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
operationQueue = operationQueue.then(() => {
|
|
26
|
+
let content = "";
|
|
27
|
+
if (op !== "delete-file") {
|
|
28
|
+
try {
|
|
29
|
+
content = readFileSync(filePath, "utf-8");
|
|
30
|
+
} catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return onUpdate(op, filePath, content);
|
|
35
|
+
}).catch(() => {
|
|
36
|
+
});
|
|
37
|
+
}, "enqueueUpdate");
|
|
38
|
+
watcher.on("add", (filePath) => {
|
|
39
|
+
enqueueUpdate("new-file", filePath);
|
|
26
40
|
});
|
|
27
|
-
watcher.on("change",
|
|
28
|
-
|
|
29
|
-
const content = readFileSync(filePath, "utf-8");
|
|
30
|
-
onUpdate("modify-file", filePath, content);
|
|
41
|
+
watcher.on("change", (filePath) => {
|
|
42
|
+
enqueueUpdate("modify-file", filePath);
|
|
31
43
|
});
|
|
32
44
|
watcher.on("unlink", (filePath) => {
|
|
33
|
-
|
|
34
|
-
onUpdate("delete-file", filePath, "");
|
|
45
|
+
enqueueUpdate("delete-file", filePath);
|
|
35
46
|
});
|
|
47
|
+
return watcher;
|
|
36
48
|
}
|
|
37
49
|
__name(watchDirectory, "watchDirectory");
|
|
38
50
|
export {
|
|
@@ -3,6 +3,14 @@ import {
|
|
|
3
3
|
} from "../chunk-SHUYVCID.js";
|
|
4
4
|
import { Readable } from "stream";
|
|
5
5
|
import { forEach } from './utils/object.js';
|
|
6
|
+
const NOOP_SOCKET = Object.freeze({
|
|
7
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
8
|
+
}, "destroy"),
|
|
9
|
+
on: /* @__PURE__ */ __name(() => {
|
|
10
|
+
}, "on"),
|
|
11
|
+
removeListener: /* @__PURE__ */ __name(() => {
|
|
12
|
+
}, "removeListener")
|
|
13
|
+
});
|
|
6
14
|
class HttpRequest extends Readable {
|
|
7
15
|
static {
|
|
8
16
|
__name(this, "HttpRequest");
|
|
@@ -15,34 +23,55 @@ class HttpRequest extends Readable {
|
|
|
15
23
|
statusCode;
|
|
16
24
|
statusMessage;
|
|
17
25
|
body;
|
|
18
|
-
headers;
|
|
19
|
-
socket;
|
|
20
26
|
// https://nodejs.org/api/http.html#class-httpincomingmessage
|
|
21
27
|
complete = false;
|
|
22
28
|
connection;
|
|
23
|
-
|
|
29
|
+
resumeScheduled = false;
|
|
30
|
+
_headers = null;
|
|
31
|
+
_socket = NOOP_SOCKET;
|
|
32
|
+
_socketFactory;
|
|
33
|
+
get socket() {
|
|
34
|
+
if (this._socketFactory && this._socket === NOOP_SOCKET) {
|
|
35
|
+
this._socket = this._socketFactory();
|
|
36
|
+
this.connection = this._socket;
|
|
37
|
+
}
|
|
38
|
+
return this._socket;
|
|
39
|
+
}
|
|
40
|
+
set socket(value) {
|
|
41
|
+
this._socket = value || NOOP_SOCKET;
|
|
42
|
+
this.connection = this._socket;
|
|
43
|
+
this._socketFactory = void 0;
|
|
44
|
+
}
|
|
45
|
+
bindSocketFactory(factory) {
|
|
46
|
+
this._socketFactory = factory;
|
|
47
|
+
this._socket = NOOP_SOCKET;
|
|
48
|
+
this.connection = this._socket;
|
|
49
|
+
}
|
|
50
|
+
get headers() {
|
|
51
|
+
if (!this._headers) {
|
|
52
|
+
const headers = {};
|
|
53
|
+
this.req.forEach((header, value) => {
|
|
54
|
+
headers[header.toLowerCase()] = value;
|
|
55
|
+
});
|
|
56
|
+
this._headers = headers;
|
|
57
|
+
}
|
|
58
|
+
return this._headers;
|
|
59
|
+
}
|
|
60
|
+
set headers(value) {
|
|
61
|
+
this._headers = value;
|
|
62
|
+
}
|
|
63
|
+
constructor(uRequest, uResponse, prefetched) {
|
|
24
64
|
super({
|
|
25
65
|
highWaterMark: 64 * 1024
|
|
26
66
|
});
|
|
27
67
|
this.uResponse = uResponse;
|
|
28
68
|
this.req = uRequest;
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
this.
|
|
69
|
+
const query = prefetched?.query ?? uRequest.getQuery();
|
|
70
|
+
const url = prefetched?.url ?? uRequest.getUrl();
|
|
71
|
+
this.url = url + (query ? "?" + query : "");
|
|
72
|
+
this.method = prefetched?.method ?? uRequest.getMethod().toUpperCase();
|
|
32
73
|
this.body = {};
|
|
33
|
-
this.
|
|
34
|
-
this.socket = {
|
|
35
|
-
destroy: /* @__PURE__ */ __name(() => {
|
|
36
|
-
}, "destroy"),
|
|
37
|
-
on: /* @__PURE__ */ __name(() => {
|
|
38
|
-
}, "on"),
|
|
39
|
-
removeListener: /* @__PURE__ */ __name(() => {
|
|
40
|
-
}, "removeListener")
|
|
41
|
-
};
|
|
42
|
-
this.connection = this.socket;
|
|
43
|
-
uRequest.forEach((header, value) => {
|
|
44
|
-
this.headers[header.toLowerCase()] = value;
|
|
45
|
-
});
|
|
74
|
+
this.connection = this._socket;
|
|
46
75
|
}
|
|
47
76
|
getRawHeaders() {
|
|
48
77
|
const raw = [];
|
|
@@ -55,13 +84,17 @@ class HttpRequest extends Readable {
|
|
|
55
84
|
return this.req;
|
|
56
85
|
}
|
|
57
86
|
_read(_) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
87
|
+
const uRes = this.uResponse;
|
|
88
|
+
if (!uRes || uRes.aborted || uRes.finished || !uRes.isPaused) return;
|
|
89
|
+
if (this.resumeScheduled) return;
|
|
90
|
+
this.resumeScheduled = true;
|
|
91
|
+
setImmediate(() => {
|
|
92
|
+
this.resumeScheduled = false;
|
|
93
|
+
const res = this.uResponse;
|
|
94
|
+
if (res && !res.aborted && !res.finished && res.isPaused) {
|
|
95
|
+
res.resume();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
65
98
|
}
|
|
66
99
|
}
|
|
67
100
|
export {
|
|
@@ -16,9 +16,10 @@ class HttpResponse extends Writable {
|
|
|
16
16
|
statusMessage;
|
|
17
17
|
__headers;
|
|
18
18
|
headersSent;
|
|
19
|
-
socket;
|
|
20
19
|
finished;
|
|
21
|
-
|
|
20
|
+
staticHeaders;
|
|
21
|
+
_socket = null;
|
|
22
|
+
constructor(uResponse, uServer, staticHeaders) {
|
|
22
23
|
super();
|
|
23
24
|
this.res = uResponse;
|
|
24
25
|
this.server = uServer;
|
|
@@ -26,13 +27,20 @@ class HttpResponse extends Writable {
|
|
|
26
27
|
this.statusMessage = null;
|
|
27
28
|
this.__headers = {};
|
|
28
29
|
this.headersSent = false;
|
|
29
|
-
this.
|
|
30
|
-
this.
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
this.finished = false;
|
|
31
|
+
this.staticHeaders = staticHeaders;
|
|
32
|
+
}
|
|
33
|
+
get socket() {
|
|
34
|
+
if (!this._socket) {
|
|
35
|
+
this._socket = new HttpResponseSocket(this.res);
|
|
36
|
+
}
|
|
37
|
+
return this._socket;
|
|
38
|
+
}
|
|
39
|
+
isClosed() {
|
|
40
|
+
return this.finished || this.res.aborted || this.res.finished;
|
|
33
41
|
}
|
|
34
42
|
get sent() {
|
|
35
|
-
return this.
|
|
43
|
+
return this.isClosed();
|
|
36
44
|
}
|
|
37
45
|
setHeader(name, value) {
|
|
38
46
|
this.__headers[toLowerCase(name)] = value;
|
|
@@ -53,9 +61,21 @@ class HttpResponse extends Writable {
|
|
|
53
61
|
delete this.__headers[toLowerCase(name)];
|
|
54
62
|
}
|
|
55
63
|
_flushHeaders() {
|
|
56
|
-
if (this.headersSent) return;
|
|
64
|
+
if (this.headersSent || this.isClosed()) return;
|
|
57
65
|
const message = this.statusMessage || http.STATUS_CODES[this.statusCode] || "Unknown";
|
|
58
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
|
+
}
|
|
59
79
|
const keys = Object.keys(this.__headers);
|
|
60
80
|
for (let i = 0; i < keys.length; i++) {
|
|
61
81
|
const key = keys[i];
|
|
@@ -75,14 +95,16 @@ class HttpResponse extends Writable {
|
|
|
75
95
|
}
|
|
76
96
|
//@ts-ignore
|
|
77
97
|
write(data) {
|
|
78
|
-
if (this.
|
|
98
|
+
if (this.isClosed()) return;
|
|
79
99
|
this.res.cork(() => {
|
|
80
100
|
this._flushHeaders();
|
|
81
|
-
this.
|
|
101
|
+
if (!this.isClosed()) {
|
|
102
|
+
this.res.write(data);
|
|
103
|
+
}
|
|
82
104
|
});
|
|
83
105
|
}
|
|
84
106
|
writeHead(statusCode) {
|
|
85
|
-
if (this.
|
|
107
|
+
if (this.isClosed()) return;
|
|
86
108
|
this.statusCode = statusCode;
|
|
87
109
|
let headers;
|
|
88
110
|
if (arguments.length === 2) {
|
|
@@ -99,7 +121,7 @@ class HttpResponse extends Writable {
|
|
|
99
121
|
}
|
|
100
122
|
//@ts-ignore
|
|
101
123
|
end(data) {
|
|
102
|
-
if (this.
|
|
124
|
+
if (this.isClosed()) return;
|
|
103
125
|
this.res.cork(() => {
|
|
104
126
|
this._flushHeaders();
|
|
105
127
|
this.finished = true;
|
|
@@ -6,11 +6,15 @@ class HttpResponseSocket {
|
|
|
6
6
|
__name(this, "HttpResponseSocket");
|
|
7
7
|
}
|
|
8
8
|
uResponse;
|
|
9
|
+
_remoteAddress;
|
|
9
10
|
constructor(uResponse) {
|
|
10
11
|
this.uResponse = uResponse;
|
|
11
12
|
}
|
|
12
13
|
get remoteAddress() {
|
|
13
|
-
|
|
14
|
+
if (this._remoteAddress === void 0) {
|
|
15
|
+
this._remoteAddress = Buffer.from(this.uResponse.getRemoteAddressAsText()).toString();
|
|
16
|
+
}
|
|
17
|
+
return this._remoteAddress;
|
|
14
18
|
}
|
|
15
19
|
destroy() {
|
|
16
20
|
return this.uResponse.end();
|
|
@@ -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,41 +22,60 @@ 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;
|
|
29
|
+
const copyArrayBufferToBuffer = /* @__PURE__ */ __name((bytes) => {
|
|
30
|
+
const src = new Uint8Array(bytes);
|
|
31
|
+
const out = Buffer.allocUnsafe(src.byteLength);
|
|
32
|
+
out.set(src);
|
|
33
|
+
return out;
|
|
34
|
+
}, "copyArrayBufferToBuffer");
|
|
25
35
|
const uServer = uWS[appType](config).any("/*", (res, req) => {
|
|
36
|
+
const method = req.getMethod().toUpperCase();
|
|
37
|
+
const query = req.getQuery();
|
|
38
|
+
const url = req.getUrl();
|
|
39
|
+
const requiresBody = method !== "HEAD" && method !== "GET";
|
|
26
40
|
res.finished = false;
|
|
27
41
|
res.aborted = false;
|
|
28
|
-
|
|
42
|
+
if (requiresBody) {
|
|
43
|
+
res.isPaused = false;
|
|
44
|
+
}
|
|
29
45
|
res.onAborted(() => {
|
|
30
46
|
res.aborted = true;
|
|
31
47
|
res.finished = true;
|
|
32
48
|
});
|
|
33
|
-
const reqWrapper = new HttpRequest(req, res
|
|
34
|
-
|
|
49
|
+
const reqWrapper = new HttpRequest(req, res, {
|
|
50
|
+
method,
|
|
51
|
+
query,
|
|
52
|
+
url
|
|
53
|
+
});
|
|
54
|
+
const resWrapper = new HttpResponse(res, uServer, normalizedStaticHeaders);
|
|
35
55
|
reqWrapper.res = resWrapper;
|
|
36
56
|
resWrapper.req = reqWrapper;
|
|
37
|
-
reqWrapper.
|
|
38
|
-
const originalResume = res.resume;
|
|
39
|
-
res.resume = function() {
|
|
40
|
-
if (res.isPaused && !res.finished && !res.aborted) {
|
|
41
|
-
res.isPaused = false;
|
|
42
|
-
originalResume.call(res);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
57
|
+
reqWrapper.bindSocketFactory(() => resWrapper.socket);
|
|
45
58
|
handler(reqWrapper, resWrapper);
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
if (requiresBody && !resWrapper.finished) {
|
|
60
|
+
const originalResume = res.resume;
|
|
61
|
+
res.resume = function() {
|
|
62
|
+
if (res.isPaused && !res.finished && !res.aborted) {
|
|
63
|
+
res.isPaused = false;
|
|
64
|
+
originalResume.call(res);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
48
67
|
res.onData((bytes, isLast) => {
|
|
49
|
-
if (res.finished || res.aborted) return;
|
|
50
|
-
const chunk =
|
|
68
|
+
if (res.finished || res.aborted || reqWrapper.destroyed) return;
|
|
69
|
+
const chunk = copyArrayBufferToBuffer(bytes);
|
|
51
70
|
const streamReady = reqWrapper.push(chunk);
|
|
52
71
|
if (isLast) {
|
|
53
72
|
reqWrapper.complete = true;
|
|
54
73
|
reqWrapper.push(null);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!streamReady && !res.isPaused) {
|
|
77
|
+
res.isPaused = true;
|
|
78
|
+
res.pause();
|
|
60
79
|
}
|
|
61
80
|
});
|
|
62
81
|
} else if (!resWrapper.finished) {
|
|
@@ -208,40 +227,52 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
208
227
|
return this;
|
|
209
228
|
}
|
|
210
229
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
const sendUpgradeError = /* @__PURE__ */ __name((hookError) => {
|
|
231
|
+
if (aborted || resWrapper.finished) return;
|
|
232
|
+
const normalizedError = hookError instanceof Error ? hookError : new Error(String(hookError));
|
|
233
|
+
console.error("WebSocket Hook Error:", normalizedError);
|
|
234
|
+
res.writeStatus("500 Internal Server Error");
|
|
235
|
+
res.end(JSON.stringify({
|
|
236
|
+
error: "Internal Server Error",
|
|
237
|
+
message: normalizedError.message
|
|
238
|
+
}));
|
|
239
|
+
}, "sendUpgradeError");
|
|
240
|
+
const finishUpgrade = /* @__PURE__ */ __name(() => {
|
|
241
|
+
if (aborted || resWrapper.finished) return;
|
|
242
|
+
const reqData = {
|
|
243
|
+
...reqWrapper,
|
|
244
|
+
query
|
|
245
|
+
};
|
|
246
|
+
res.upgrade({
|
|
247
|
+
req: reqData
|
|
248
|
+
}, secKey, secProtocol, secExtensions, context);
|
|
249
|
+
}, "finishUpgrade");
|
|
250
|
+
let hookIndex = 0;
|
|
251
|
+
const runNextHook = /* @__PURE__ */ __name((hookError) => {
|
|
252
|
+
if (hookError) {
|
|
253
|
+
sendUpgradeError(hookError);
|
|
254
|
+
return;
|
|
225
255
|
}
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
res.end(JSON.stringify({
|
|
231
|
-
error: "Internal Server Error",
|
|
232
|
-
message: err.message
|
|
233
|
-
}));
|
|
256
|
+
if (aborted || resWrapper.finished) return;
|
|
257
|
+
if (hookIndex >= hooks.length) {
|
|
258
|
+
finishUpgrade();
|
|
259
|
+
return;
|
|
234
260
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
261
|
+
const HookClass = hooks[hookIndex++];
|
|
262
|
+
const hookInstance = typeof HookClass === "function" ? new HookClass() : HookClass;
|
|
263
|
+
let doneCalled = false;
|
|
264
|
+
const done = /* @__PURE__ */ __name((doneError) => {
|
|
265
|
+
if (doneCalled) return;
|
|
266
|
+
doneCalled = true;
|
|
267
|
+
runNextHook(doneError);
|
|
268
|
+
}, "done");
|
|
269
|
+
try {
|
|
270
|
+
hookInstance.handle(reqWrapper, resWrapper, done);
|
|
271
|
+
} catch (err) {
|
|
272
|
+
done(err);
|
|
273
|
+
}
|
|
274
|
+
}, "runNextHook");
|
|
275
|
+
runNextHook();
|
|
245
276
|
}, "upgrade"),
|
|
246
277
|
open: /* @__PURE__ */ __name((ws) => {
|
|
247
278
|
if (behaviors.open) {
|
package/express.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "owebjs",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.8-dev",
|
|
4
4
|
"description": "A flexible and modern web framework built on top of Fastify",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"start": "node .",
|
|
24
24
|
"build": "tsup",
|
|
25
|
-
"dev": "tsup && node .",
|
|
26
|
-
"test": "tsup &&
|
|
25
|
+
"dev": "tsup && node test/index.js",
|
|
26
|
+
"test": "tsup && vitest run --config test/vitest.config.mts",
|
|
27
|
+
"test:watch": "tsup && vitest --config test/vitest.config.mts",
|
|
27
28
|
"format": "prettier --write . --ignore-path .gitignore"
|
|
28
29
|
},
|
|
29
30
|
"homepage": "https://github.com/owebjs/oweb",
|
|
@@ -59,7 +60,8 @@
|
|
|
59
60
|
"prettier": "^3.0.3",
|
|
60
61
|
"tslib": "^2.6.2",
|
|
61
62
|
"tsup": "^8.5.0",
|
|
62
|
-
"typescript": "^5.2.2"
|
|
63
|
+
"typescript": "^5.2.2",
|
|
64
|
+
"vitest": "^3.2.4"
|
|
63
65
|
},
|
|
64
66
|
"type": "module",
|
|
65
67
|
"pnpm": {
|
package/purehttp.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
});
|