@linebridge/engine-neo 1.0.2 → 1.0.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.
- package/lib/close.js +1 -1
- package/lib/engine.d.ts +11 -10
- package/lib/engine.js +6 -20
- package/lib/listen.js +1 -1
- package/lib/on_request.d.ts +5 -1
- package/lib/request.d.ts +4 -1
- package/lib/response.d.ts +2 -1
- package/lib/uws.d.ts +403 -0
- package/lib/uws.js +27 -0
- package/package.json +2 -2
package/lib/close.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Gracefully shuts down the uWS app: closes the WebSocket server
|
|
3
3
|
* and closes the TCP/unix listen socket.
|
|
4
4
|
*/
|
|
5
|
-
import uWebsockets from "
|
|
5
|
+
import uWebsockets from "./uws.js";
|
|
6
6
|
/**
|
|
7
7
|
* Closes the WebSocket server (if any) and the uWS listen socket.
|
|
8
8
|
*
|
package/lib/engine.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Neo engine - the uWebSockets
|
|
2
|
+
* @fileoverview Neo engine - the uWebSockets engine adaptor for Linebridge.
|
|
3
3
|
*
|
|
4
4
|
* This engine creates a uWS app (plain or SSL), optionally attaches a WebSocket
|
|
5
5
|
* server via RTEngine, and manages the HTTP request/response lifecycle.
|
|
@@ -11,7 +11,7 @@ import type { Server } from "linebridge/server";
|
|
|
11
11
|
import type { Handler, HandlerKind } from "linebridge/classes/Handler/index";
|
|
12
12
|
import type Request from "./request.js";
|
|
13
13
|
import type Response from "./response.js";
|
|
14
|
-
import type
|
|
14
|
+
import uws_wrapper, { type uWebsockets } from "./uws.js";
|
|
15
15
|
import RTEngine from "linebridge/classes/RtEngine/index";
|
|
16
16
|
import { EngineAdaptor } from "linebridge/classes/EngineAdaptor/index";
|
|
17
17
|
import { Route } from "linebridge/classes/Route/index";
|
|
@@ -32,13 +32,13 @@ export type EngineOptions = {
|
|
|
32
32
|
* etc. via bracket notation - needed because uWS itself uses dynamic methods
|
|
33
33
|
* for route registration.
|
|
34
34
|
*/
|
|
35
|
-
type uwsEngine =
|
|
36
|
-
[K in keyof
|
|
35
|
+
type uwsEngine = uWebsockets.TemplatedApp & {
|
|
36
|
+
[K in keyof uWebsockets.TemplatedApp]?: uWebsockets.TemplatedApp[K];
|
|
37
37
|
} & {
|
|
38
38
|
[key: string]: (...args: any[]) => any;
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
|
-
* The Neo engine is the uWebSockets
|
|
41
|
+
* The Neo engine is the uWebSockets adaptor.
|
|
42
42
|
*
|
|
43
43
|
* It handles app construction (plain or SSL), WebSocket setup, route registration,
|
|
44
44
|
* middleware registration, and the request/response pipeline.
|
|
@@ -47,7 +47,7 @@ export declare class NeoEngine extends EngineAdaptor {
|
|
|
47
47
|
/** WebSocket engine instance, set when websockets are enabled. */
|
|
48
48
|
ws: RTEngine | null;
|
|
49
49
|
/** The underlying uWS listen socket handle. */
|
|
50
|
-
listen_socket:
|
|
50
|
+
listen_socket: uWebsockets.us_listen_socket | null;
|
|
51
51
|
/** The uWS app instance (plain or SSL). */
|
|
52
52
|
uws: uwsEngine | null;
|
|
53
53
|
/** Number of in-flight HTTP requests. Tracked so the server knows when it is idle. */
|
|
@@ -65,7 +65,7 @@ export declare class NeoEngine extends EngineAdaptor {
|
|
|
65
65
|
/** Listening host, defaults to "0.0.0.0". */
|
|
66
66
|
host: string;
|
|
67
67
|
/** Engine-level options merged with uWS constructor options. */
|
|
68
|
-
options: EngineOptions &
|
|
68
|
+
options: EngineOptions & uWebsockets.AppOptions;
|
|
69
69
|
/**
|
|
70
70
|
* Initializes the engine: creates the uWS app, configures SSL if needed,
|
|
71
71
|
* attaches WebSocket support, and registers the default catch-all route.
|
|
@@ -83,13 +83,13 @@ export declare class NeoEngine extends EngineAdaptor {
|
|
|
83
83
|
* Publish a message to a topic in MQTT syntax to all WebSocket connections on this Server instance.
|
|
84
84
|
* You cannot publish using wildcards, only fully specified topics.
|
|
85
85
|
*/
|
|
86
|
-
publish(topic:
|
|
86
|
+
publish(topic: uWebsockets.RecognizedString, message: uWebsockets.RecognizedString, is_binary?: boolean, compress?: boolean): boolean | undefined;
|
|
87
87
|
/**
|
|
88
88
|
* Returns the number of subscribers to a topic across all WebSocket connections on this Server instance.
|
|
89
89
|
*/
|
|
90
|
-
num_of_subscribers(topic:
|
|
90
|
+
num_of_subscribers(topic: uWebsockets.RecognizedString): number | undefined;
|
|
91
91
|
/** Incoming HTTP request handler. Bound to the engine instance. */
|
|
92
|
-
on_request: (native_req: HttpRequest, native_res: HttpResponse, route: Route<any, "server"[]>, socket?:
|
|
92
|
+
on_request: (native_req: uWebsockets.HttpRequest, native_res: uWebsockets.HttpResponse, route: Route<any, "server"[]>, socket?: uWebsockets.us_socket_context_t | null | undefined) => any;
|
|
93
93
|
/** Middleware/route iteration loop. Bound to the engine instance. */
|
|
94
94
|
request_iterator: (request: Request<any>, response: Response<any>, route: Route<Server<"neo">, "server"[]>, allMiddlewares: Handler<HandlerKind>[], cursor?: number | undefined) => Promise<void>;
|
|
95
95
|
/**
|
|
@@ -102,4 +102,5 @@ export declare class NeoEngine extends EngineAdaptor {
|
|
|
102
102
|
*/
|
|
103
103
|
_defaultResponse(req: Request<Server>, res: Response<Server>): void;
|
|
104
104
|
}
|
|
105
|
+
export { uws_wrapper as uWebsockets };
|
|
105
106
|
export default NeoEngine;
|
package/lib/engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Neo engine - the uWebSockets
|
|
2
|
+
* @fileoverview Neo engine - the uWebSockets engine adaptor for Linebridge.
|
|
3
3
|
*
|
|
4
4
|
* This engine creates a uWS app (plain or SSL), optionally attaches a WebSocket
|
|
5
5
|
* server via RTEngine, and manages the HTTP request/response lifecycle.
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* It is the default and only built-in engine; other engines can be added by
|
|
8
8
|
* implementing the EngineAdaptor interface and registering them in `engines/index.ts`.
|
|
9
9
|
*/
|
|
10
|
+
import uws_wrapper from "./uws.js";
|
|
10
11
|
import fs from "node:fs";
|
|
11
12
|
import fs_promises from "node:fs/promises";
|
|
12
|
-
import { createRequire } from "node:module";
|
|
13
13
|
import toBoolean from "linebridge/utils/toBoolean";
|
|
14
14
|
import RTEngine from "linebridge/classes/RtEngine/index";
|
|
15
15
|
import { EngineAdaptor } from "linebridge/classes/EngineAdaptor/index";
|
|
@@ -21,23 +21,8 @@ import listen from "./listen.js";
|
|
|
21
21
|
import close from "./close.js";
|
|
22
22
|
import on_request from "./on_request.js";
|
|
23
23
|
import request_iterator from "./request_iterator.js";
|
|
24
|
-
let uWebsockets;
|
|
25
|
-
try {
|
|
26
|
-
// Try loading from the root (when executing from build/out/lib/index.js)
|
|
27
|
-
uWebsockets = createRequire(import.meta.url)("../uws-wrapper.node");
|
|
28
|
-
}
|
|
29
|
-
catch (e) {
|
|
30
|
-
try {
|
|
31
|
-
// Try loading from build/Release (when executing from src/index.ts in monorepo)
|
|
32
|
-
uWebsockets = createRequire(import.meta.url)("../build/Release/uws-wrapper.node");
|
|
33
|
-
}
|
|
34
|
-
catch (e2) {
|
|
35
|
-
// Try loading from build/out (when executing from src/index.ts in monorepo if already packaged)
|
|
36
|
-
uWebsockets = createRequire(import.meta.url)("../build/out/uws-wrapper.node");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
24
|
/**
|
|
40
|
-
* The Neo engine is the uWebSockets
|
|
25
|
+
* The Neo engine is the uWebSockets adaptor.
|
|
41
26
|
*
|
|
42
27
|
* It handles app construction (plain or SSL), WebSocket setup, route registration,
|
|
43
28
|
* middleware registration, and the request/response pipeline.
|
|
@@ -107,14 +92,14 @@ export class NeoEngine extends EngineAdaptor {
|
|
|
107
92
|
}
|
|
108
93
|
// initialize the uWebsockets app depending on SSL mode
|
|
109
94
|
if (this.options.is_ssl) {
|
|
110
|
-
this.uws =
|
|
95
|
+
this.uws = uws_wrapper.SSLApp({
|
|
111
96
|
...this.options,
|
|
112
97
|
key_file_name: this.server.ssl.key,
|
|
113
98
|
cert_file_name: this.server.ssl.cert,
|
|
114
99
|
});
|
|
115
100
|
}
|
|
116
101
|
else {
|
|
117
|
-
this.uws =
|
|
102
|
+
this.uws = uws_wrapper.App(this.options);
|
|
118
103
|
}
|
|
119
104
|
// if socket mode is enabled, use a unix socket path
|
|
120
105
|
if (toBoolean(process.env.LB_SOCKET_MODE)) {
|
|
@@ -218,4 +203,5 @@ export class NeoEngine extends EngineAdaptor {
|
|
|
218
203
|
res.status(404).json({ error: "Not found" });
|
|
219
204
|
}
|
|
220
205
|
}
|
|
206
|
+
export { uws_wrapper as uWebsockets };
|
|
221
207
|
export default NeoEngine;
|
package/lib/listen.js
CHANGED
|
@@ -30,7 +30,7 @@ export default async function () {
|
|
|
30
30
|
resolve();
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
reject("Server.listen(): No Socket Received From uWebsockets
|
|
33
|
+
reject("Server.listen(): No Socket Received From uWebsockets likely due to an invalid host or busy port.");
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
// use a unix socket when socket_path is set, otherwise bind to tcp
|
package/lib/on_request.d.ts
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* It creates Request and Response wrappers, runs the middleware + handler pipeline,
|
|
5
5
|
* and includes a "fast path" optimisation for routes with zero or one middleware.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { uWebsockets } from "./uws.js";
|
|
8
|
+
type us_socket_context_t = uWebsockets.us_socket_context_t;
|
|
9
|
+
type HttpRequest = uWebsockets.HttpRequest;
|
|
10
|
+
type HttpResponse = uWebsockets.HttpResponse;
|
|
8
11
|
import type { Route } from "linebridge/classes/Route/index";
|
|
9
12
|
import type Engine from "./engine.js";
|
|
10
13
|
/**
|
|
@@ -19,3 +22,4 @@ import type Engine from "./engine.js";
|
|
|
19
22
|
* @param socket - Upgrade socket context (only set for WebSocket upgrade requests).
|
|
20
23
|
*/
|
|
21
24
|
export default function (this: Engine, native_req: HttpRequest, native_res: HttpResponse, route: Route<any>, socket?: us_socket_context_t | null): any;
|
|
25
|
+
export {};
|
package/lib/request.d.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* body parsing (JSON, text, urlencoded, buffer), cookies, IP resolution,
|
|
6
6
|
* and path/query parameters.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { uWebsockets } from "./uws.js";
|
|
9
|
+
type HttpRequest = uWebsockets.HttpRequest;
|
|
10
|
+
type HttpResponse = uWebsockets.HttpResponse;
|
|
9
11
|
import type { Request as BaseHttpRequest } from "linebridge/classes/Handler/http";
|
|
10
12
|
import type { EngineAdaptor } from "linebridge/classes/EngineAdaptor/index";
|
|
11
13
|
import type { Route } from "linebridge/classes/Route/index";
|
|
@@ -166,3 +168,4 @@ export default class Request<TServer = Server<any>> implements BaseHttpRequest {
|
|
|
166
168
|
*/
|
|
167
169
|
get proxy_ip(): string;
|
|
168
170
|
}
|
|
171
|
+
export {};
|
package/lib/response.d.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* Server-Sent Events, redirects, and JSON/HTML shortcuts.
|
|
7
7
|
*/
|
|
8
8
|
import SSEventStream from "./SSEventStream.js";
|
|
9
|
-
import type {
|
|
9
|
+
import type { uWebsockets } from "./uws.js";
|
|
10
|
+
type HttpResponse = uWebsockets.HttpResponse;
|
|
10
11
|
import type { EngineAdaptor } from "linebridge/classes/EngineAdaptor/index";
|
|
11
12
|
import type { Route } from "linebridge/classes/Route/index";
|
|
12
13
|
import type { Server } from "linebridge/server";
|
package/lib/uws.d.ts
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
declare const _default: typeof uWebsockets;
|
|
2
|
+
export default _default;
|
|
3
|
+
export declare namespace uWebsockets {
|
|
4
|
+
/** Native type representing a raw uSockets struct us_listen_socket_t.
|
|
5
|
+
* Careful with this one, it is entirely unchecked and native so invalid usage will blow up.
|
|
6
|
+
*/
|
|
7
|
+
interface us_listen_socket {
|
|
8
|
+
}
|
|
9
|
+
/** Native type representing a raw uSockets struct us_socket_t.
|
|
10
|
+
* Careful with this one, it is entirely unchecked and native so invalid usage will blow up.
|
|
11
|
+
*/
|
|
12
|
+
interface us_socket {
|
|
13
|
+
}
|
|
14
|
+
/** Native type representing a raw uSockets struct us_socket_context_t.
|
|
15
|
+
* Used while upgrading a WebSocket manually. */
|
|
16
|
+
interface us_socket_context_t {
|
|
17
|
+
}
|
|
18
|
+
/** Native type representing a raw uWebSockets struct AppDescriptor.
|
|
19
|
+
* Used internally for worker thread distribution.
|
|
20
|
+
* Careful with this one, it is entirely unchecked and native so invalid usage will blow up.
|
|
21
|
+
*/
|
|
22
|
+
interface AppDescriptor {
|
|
23
|
+
}
|
|
24
|
+
/** Recognized string types, things C++ can read and understand as strings.
|
|
25
|
+
* "String" does not have to mean "text", it can also be "binary".
|
|
26
|
+
*
|
|
27
|
+
* Ironically, JavaScript strings are the least performant of all options, to pass or receive to/from C++.
|
|
28
|
+
* This because we expect UTF-8. JavaScript strings are Latin-1 or UTF-16 internally meaning extra copies and reinterpretation are required.
|
|
29
|
+
* That's why all events pass data by ArrayBuffer and not JavaScript strings, as they allow zero-copy data passing.
|
|
30
|
+
* You can always do Buffer.from(arrayBuffer).toString(), but keeping things binary and as ArrayBuffer is preferred.
|
|
31
|
+
*
|
|
32
|
+
* The ArrayBufferView type includes Node.js Buffer, DataView, and TypedArray (Uint8Array, Uint16Array, ...).
|
|
33
|
+
*/
|
|
34
|
+
type RecognizedString = string | ArrayBuffer | SharedArrayBuffer | ArrayBufferView;
|
|
35
|
+
/** A WebSocket connection that is valid from open to close event.
|
|
36
|
+
* Read more about this in the user manual.
|
|
37
|
+
*/
|
|
38
|
+
interface WebSocket<UserData> {
|
|
39
|
+
/** Sends a message. Returns 1 for success, 2 for dropped due to backpressure limit, and 0 for built up backpressure that will drain over time. You can check backpressure before or after sending by calling getBufferedAmount().
|
|
40
|
+
*
|
|
41
|
+
* Make sure you properly understand the concept of backpressure. Check the backpressure example file.
|
|
42
|
+
*/
|
|
43
|
+
send(message: RecognizedString, isBinary?: boolean, compress?: boolean): number;
|
|
44
|
+
/** Returns the bytes buffered in backpressure. This is similar to the bufferedAmount property in the browser counterpart.
|
|
45
|
+
* Check backpressure example.
|
|
46
|
+
*/
|
|
47
|
+
getBufferedAmount(): number;
|
|
48
|
+
/** Gracefully closes this WebSocket. Immediately calls the close handler.
|
|
49
|
+
* A WebSocket close message is sent with code and shortMessage, and
|
|
50
|
+
* messages already passed to send() are delivered before the close.
|
|
51
|
+
*/
|
|
52
|
+
end(code?: number, shortMessage?: RecognizedString): void;
|
|
53
|
+
/** Forcefully closes this WebSocket. Immediately calls the close handler.
|
|
54
|
+
* No WebSocket close message is sent. This maps to the close() syscall and
|
|
55
|
+
* inherits its effects, so messages already passed to send() are not
|
|
56
|
+
* delivered; use end() to send a last message before closing.
|
|
57
|
+
*/
|
|
58
|
+
close(): void;
|
|
59
|
+
/** Sends a ping control message. Returns sendStatus similar to WebSocket.send (regarding backpressure). This helper function correlates to WebSocket::send(message, uWS::OpCode::PING, ...) in C++. */
|
|
60
|
+
ping(message?: RecognizedString): number;
|
|
61
|
+
/** Subscribe to a topic. */
|
|
62
|
+
subscribe(topic: RecognizedString): boolean;
|
|
63
|
+
/** Unsubscribe from a topic. Returns true on success, if the WebSocket was subscribed. */
|
|
64
|
+
unsubscribe(topic: RecognizedString): boolean;
|
|
65
|
+
/** Returns whether this websocket is subscribed to topic. */
|
|
66
|
+
isSubscribed(topic: RecognizedString): boolean;
|
|
67
|
+
/** Returns a list of topics this websocket is subscribed to. */
|
|
68
|
+
getTopics(): string[];
|
|
69
|
+
/** Publish a message under topic. Backpressure is managed according to maxBackpressure, closeOnBackpressureLimit settings.
|
|
70
|
+
* Order is guaranteed since v20.
|
|
71
|
+
*/
|
|
72
|
+
publish(topic: RecognizedString, message: RecognizedString, isBinary?: boolean, compress?: boolean): boolean;
|
|
73
|
+
/** See HttpResponse.cork. Takes a function in which the socket is corked (packing many sends into one single syscall/SSL block) */
|
|
74
|
+
cork(cb: () => void): WebSocket<UserData>;
|
|
75
|
+
/** Returns the remote IP address. Note that the returned IP is binary, not text.
|
|
76
|
+
*
|
|
77
|
+
* IPv4 is 4 byte long and can be converted to text by printing every byte as a digit between 0 and 255.
|
|
78
|
+
* IPv6 is 16 byte long and can be converted to text in similar ways, but you typically print digits in HEX.
|
|
79
|
+
*
|
|
80
|
+
* See getRemoteAddressAsText() for a text version.
|
|
81
|
+
*/
|
|
82
|
+
getRemoteAddress(): ArrayBuffer;
|
|
83
|
+
/** Returns the remote IP address as text. See RecognizedString. */
|
|
84
|
+
getRemoteAddressAsText(): ArrayBuffer;
|
|
85
|
+
/** Returns the remote port number. */
|
|
86
|
+
getRemotePort(): number;
|
|
87
|
+
/** Returns the UserData object. */
|
|
88
|
+
getUserData(): UserData;
|
|
89
|
+
/** Sends the first fragment of a fragmented message. Use for sending large messages in chunks.
|
|
90
|
+
* Returns 1 for success, 2 for dropped due to backpressure limit, and 0 for built up backpressure.
|
|
91
|
+
*/
|
|
92
|
+
sendFirstFragment(message: RecognizedString, isBinary?: boolean, compress?: boolean): number;
|
|
93
|
+
/** Sends a middle fragment of a fragmented message.
|
|
94
|
+
* Returns 1 for success, 2 for dropped due to backpressure limit, and 0 for built up backpressure.
|
|
95
|
+
*/
|
|
96
|
+
sendFragment(message: RecognizedString, compress?: boolean): number;
|
|
97
|
+
/** Sends the last fragment of a fragmented message.
|
|
98
|
+
* Returns 1 for success, 2 for dropped due to backpressure limit, and 0 for built up backpressure.
|
|
99
|
+
*/
|
|
100
|
+
sendLastFragment(message: RecognizedString, compress?: boolean): number;
|
|
101
|
+
}
|
|
102
|
+
/** An HttpResponse is valid until either onAborted callback or any of the .end/.tryEnd calls succeed. You may attach user data to this object. */
|
|
103
|
+
interface HttpResponse {
|
|
104
|
+
/** Writes the HTTP status message such as "200 OK".
|
|
105
|
+
* This has to be called first in any response, otherwise
|
|
106
|
+
* it will be called automatically with "200 OK".
|
|
107
|
+
*
|
|
108
|
+
* If you want to send custom headers in a WebSocket
|
|
109
|
+
* upgrade response, you have to call writeStatus with
|
|
110
|
+
* "101 Switching Protocols" before you call writeHeader,
|
|
111
|
+
* otherwise your first call to writeHeader will call
|
|
112
|
+
* writeStatus with "200 OK" and the upgrade will fail.
|
|
113
|
+
*
|
|
114
|
+
* As you can imagine, we format outgoing responses in a linear
|
|
115
|
+
* buffer, not in a hash table. You can read about this in
|
|
116
|
+
* the user manual under "corking".
|
|
117
|
+
*/
|
|
118
|
+
writeStatus(status: RecognizedString): HttpResponse;
|
|
119
|
+
/** Writes key and value to HTTP response.
|
|
120
|
+
* See writeStatus and corking.
|
|
121
|
+
*/
|
|
122
|
+
writeHeader(key: RecognizedString, value: RecognizedString): HttpResponse;
|
|
123
|
+
/** Enters or continues chunked encoding mode. Writes part of the response. End with zero length write. Returns true if no backpressure was added. */
|
|
124
|
+
write(chunk: RecognizedString): boolean;
|
|
125
|
+
/** Begins chunked encoding mode and flushes headers immediately. */
|
|
126
|
+
beginWrite(): HttpResponse;
|
|
127
|
+
/** Ends this response by copying the contents of body. */
|
|
128
|
+
end(body?: RecognizedString, closeConnection?: boolean): HttpResponse;
|
|
129
|
+
/** Ends this response without a body. */
|
|
130
|
+
endWithoutBody(reportedContentLength?: number, closeConnection?: boolean): HttpResponse;
|
|
131
|
+
/** Ends this response, or tries to, by streaming appropriately sized chunks of body. Use in conjunction with onWritable. Returns tuple [ok, hasResponded].*/
|
|
132
|
+
tryEnd(fullBodyOrChunk: RecognizedString, totalSize: number): [boolean, boolean];
|
|
133
|
+
/** Immediately force closes the connection. Any onAborted callback will run. */
|
|
134
|
+
close(): HttpResponse;
|
|
135
|
+
/** Returns the global byte write offset for this response. Use with onWritable. */
|
|
136
|
+
getWriteOffset(): number;
|
|
137
|
+
/** Registers a handler for writable events. Continue failed write attempts in here.
|
|
138
|
+
* You MUST return true for success, false for failure.
|
|
139
|
+
* Writing nothing is always success, so by default you must return true.
|
|
140
|
+
*/
|
|
141
|
+
onWritable(handler: (offset: number) => boolean): HttpResponse;
|
|
142
|
+
/** Every HttpResponse MUST have an attached abort handler IF you do not respond
|
|
143
|
+
* to it immediately inside of the callback. Returning from an Http request handler
|
|
144
|
+
* without attaching (by calling onAborted) an abort handler is ill-use and will terminate.
|
|
145
|
+
* When this event emits, the response has been aborted and may not be used. */
|
|
146
|
+
onAborted(handler: () => void): HttpResponse;
|
|
147
|
+
/** Handler for reading HTTP request body data.
|
|
148
|
+
* Must be attached before performing any asynchronous operation, otherwise data may be lost.
|
|
149
|
+
* You MUST copy the data of chunk if isLast is not true. We Neuter ArrayBuffers on return, making them zero length. */
|
|
150
|
+
onData(handler: (chunk: ArrayBuffer, isLast: boolean) => void): HttpResponse;
|
|
151
|
+
/** Pause HTTP request body streaming (throttle).
|
|
152
|
+
* Some buffered data may still be sent to onData. */
|
|
153
|
+
pause(): void;
|
|
154
|
+
/** Resume HTTP request body streaming (unthrottle). */
|
|
155
|
+
resume(): void;
|
|
156
|
+
/** collectBody is a helper function making optimal use of the new onDataV2.
|
|
157
|
+
* It allows efficient and easy collection of smallish HTTP request body data into RAM.
|
|
158
|
+
* It accumulates all data chunks and calls handler with the complete body as an ArrayBuffer once all data has arrived.
|
|
159
|
+
* If the total body size exceeds maxSize bytes, handler is called with null instead. */
|
|
160
|
+
collectBody(maxSize: number, handler: (fullBody: ArrayBuffer | null) => void): HttpResponse;
|
|
161
|
+
/** Handler for reading HTTP request body data. V2.
|
|
162
|
+
* Must be attached before performing any asynchronous operation, otherwise data may be lost.
|
|
163
|
+
* You MUST copy the data of chunk if maxRemainingBodyLength is not 0n. We Neuter ArrayBuffers on return, making them zero length.
|
|
164
|
+
* maxRemainingBodyLength is the known maximum of the remaining body length. Can be used to preallocate a receive buffer.
|
|
165
|
+
*/
|
|
166
|
+
onDataV2(handler: (chunk: ArrayBuffer, maxRemainingBodyLength: bigint) => void): HttpResponse;
|
|
167
|
+
/** Returns the remote IP address in binary format (4 or 16 bytes). */
|
|
168
|
+
getRemoteAddress(): ArrayBuffer;
|
|
169
|
+
/** Returns the remote IP address as text. */
|
|
170
|
+
getRemoteAddressAsText(): ArrayBuffer;
|
|
171
|
+
/** Returns the remote port number. */
|
|
172
|
+
getRemotePort(): number;
|
|
173
|
+
/** Returns the remote IP address in binary format (4 or 16 bytes), as reported by the PROXY Protocol v2 compatible proxy. */
|
|
174
|
+
getProxiedRemoteAddress(): ArrayBuffer;
|
|
175
|
+
/** Returns the remote IP address as text, as reported by the PROXY Protocol v2 compatible proxy. */
|
|
176
|
+
getProxiedRemoteAddressAsText(): ArrayBuffer;
|
|
177
|
+
/** Returns the remote port number, as reported by the PROXY Protocol v2 compatible proxy. */
|
|
178
|
+
getProxiedRemotePort(): number;
|
|
179
|
+
/** Corking a response is a performance improvement in both CPU and network, as you ready the IO system for writing multiple chunks at once.
|
|
180
|
+
* By default, you're corked in the immediately executing top portion of the route handler. In all other cases, such as when returning from
|
|
181
|
+
* await, or when being called back from an async database request or anything that isn't directly executing in the route handler, you'll want
|
|
182
|
+
* to cork before calling writeStatus, writeHeader or just write. Corking takes a callback in which you execute the writeHeader, writeStatus and
|
|
183
|
+
* such calls, in one atomic IO operation. This is important, not only for TCP but definitely for TLS where each write would otherwise result
|
|
184
|
+
* in one TLS block being sent off, each with one send syscall.
|
|
185
|
+
*
|
|
186
|
+
* Example usage:
|
|
187
|
+
*
|
|
188
|
+
* ```
|
|
189
|
+
* res.cork(() => {
|
|
190
|
+
* res.writeStatus("200 OK").writeHeader("Some", "Value").write("Hello world!");
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
cork(cb: () => void): HttpResponse;
|
|
195
|
+
/** Upgrades a HttpResponse to a WebSocket. See UpgradeAsync, UpgradeSync example files. */
|
|
196
|
+
upgrade<UserData>(userData: UserData, secWebSocketKey: RecognizedString, secWebSocketProtocol: RecognizedString, secWebSocketExtensions: RecognizedString, context: us_socket_context_t): void;
|
|
197
|
+
/** Arbitrary user data may be attached to this object */
|
|
198
|
+
[key: string]: any;
|
|
199
|
+
}
|
|
200
|
+
/** An HttpRequest is stack allocated and only accessible during the callback invocation. */
|
|
201
|
+
interface HttpRequest {
|
|
202
|
+
/** Returns the lowercased header value or empty string. */
|
|
203
|
+
getHeader(lowerCaseKey: RecognizedString): string;
|
|
204
|
+
/** Returns the parsed parameter at index. Corresponds to route. Can also take the name of the parameter. */
|
|
205
|
+
getParameter(index: number | RecognizedString): string | undefined;
|
|
206
|
+
/** Returns the URL including initial /slash */
|
|
207
|
+
getUrl(): string;
|
|
208
|
+
/** Returns the lowercased HTTP method, useful for "any" routes. */
|
|
209
|
+
getMethod(): string;
|
|
210
|
+
/** Returns the HTTP method as-is. */
|
|
211
|
+
getCaseSensitiveMethod(): string;
|
|
212
|
+
/** Returns the raw querystring (the part of URL after ? sign) or empty string. */
|
|
213
|
+
getQuery(): string;
|
|
214
|
+
/** Returns a decoded query parameter value or undefined. */
|
|
215
|
+
getQuery(key: string): string | undefined;
|
|
216
|
+
/** Loops over all headers. */
|
|
217
|
+
forEach(cb: (key: string, value: string) => void): void;
|
|
218
|
+
/** Setting yield to true is to say that this route handler did not handle the route, causing the router to continue looking for a matching route handler, or fail. */
|
|
219
|
+
setYield(_yield: boolean): HttpRequest;
|
|
220
|
+
}
|
|
221
|
+
/** A structure holding settings and handlers for a WebSocket URL route handler. */
|
|
222
|
+
interface WebSocketBehavior<UserData> {
|
|
223
|
+
/** Maximum length of received message. If a client tries to send you a message larger than this, the connection is immediately closed. Defaults to 16 * 1024. */
|
|
224
|
+
maxPayloadLength?: number;
|
|
225
|
+
/** Whether or not we should automatically close the socket when a message is dropped due to backpressure. Defaults to false. */
|
|
226
|
+
closeOnBackpressureLimit?: boolean;
|
|
227
|
+
/** Maximum number of minutes a WebSocket may be connected before being closed by the server. 0 disables the feature. Valid values are 0 and 1-239. */
|
|
228
|
+
maxLifetime?: number;
|
|
229
|
+
/** Maximum amount of seconds that may pass without sending or getting a message. Connection is closed if this timeout passes. Resolution (granularity) for timeouts are typically 4 seconds, rounded to closest.
|
|
230
|
+
* Disable by using 0. Defaults to 120.
|
|
231
|
+
*/
|
|
232
|
+
idleTimeout?: number;
|
|
233
|
+
/** What permessage-deflate compression to use. uWS.DISABLED, uWS.SHARED_COMPRESSOR or any of the uWS.DEDICATED_COMPRESSOR_xxxKB. Defaults to uWS.DISABLED. */
|
|
234
|
+
compression?: CompressOptions;
|
|
235
|
+
/** Maximum length of allowed backpressure per socket when publishing or sending messages. Slow receivers with too high backpressure will be skipped until they catch up or timeout. Defaults to 64 * 1024. */
|
|
236
|
+
maxBackpressure?: number;
|
|
237
|
+
/** Whether or not we should automatically send pings to uphold a stable connection given whatever idleTimeout. */
|
|
238
|
+
sendPingsAutomatically?: boolean;
|
|
239
|
+
/** Upgrade handler used to intercept HTTP upgrade requests and potentially upgrade to WebSocket.
|
|
240
|
+
* See UpgradeAsync and UpgradeSync example files.
|
|
241
|
+
*/
|
|
242
|
+
upgrade?: (res: HttpResponse, req: HttpRequest, context: us_socket_context_t) => void | Promise<void>;
|
|
243
|
+
/** Handler for new WebSocket connection. WebSocket is valid from open to close, no errors. */
|
|
244
|
+
open?: (ws: WebSocket<UserData>) => void | Promise<void>;
|
|
245
|
+
/** Handler for a WebSocket message. Messages are given as ArrayBuffer no matter if they are binary or not. Given ArrayBuffer is valid during the lifetime of this callback (until first await or return) and will be neutered. */
|
|
246
|
+
message?: (ws: WebSocket<UserData>, message: ArrayBuffer, isBinary: boolean) => void | Promise<void>;
|
|
247
|
+
/** Handler for a dropped WebSocket message. Messages can be dropped due to specified backpressure settings. Messages are given as ArrayBuffer no matter if they are binary or not. Given ArrayBuffer is valid during the lifetime of this callback (until first await or return) and will be neutered. */
|
|
248
|
+
dropped?: (ws: WebSocket<UserData>, message: ArrayBuffer, isBinary: boolean) => void | Promise<void>;
|
|
249
|
+
/** Handler for when WebSocket backpressure drains. Check ws.getBufferedAmount(). Use this to guide / drive your backpressure throttling. */
|
|
250
|
+
drain?: (ws: WebSocket<UserData>) => void;
|
|
251
|
+
/** Handler for close event, no matter if error, timeout or graceful close. You may not use WebSocket after this event. Do not send on this WebSocket from within here, it is closed. */
|
|
252
|
+
close?: (ws: WebSocket<UserData>, code: number, message: ArrayBuffer) => void;
|
|
253
|
+
/** Handler for received ping control message. You do not need to handle this, pong messages are automatically sent as per the standard. */
|
|
254
|
+
ping?: (ws: WebSocket<UserData>, message: ArrayBuffer) => void;
|
|
255
|
+
/** Handler for received pong control message. */
|
|
256
|
+
pong?: (ws: WebSocket<UserData>, message: ArrayBuffer) => void;
|
|
257
|
+
/** Handler for subscription changes. */
|
|
258
|
+
subscription?: (ws: WebSocket<UserData>, topic: ArrayBuffer, newCount: number, oldCount: number) => void;
|
|
259
|
+
}
|
|
260
|
+
/** Options used when constructing an app. Especially for SSLApp.
|
|
261
|
+
* These are options passed directly to uSockets, C layer.
|
|
262
|
+
*/
|
|
263
|
+
interface AppOptions {
|
|
264
|
+
key_file_name?: RecognizedString;
|
|
265
|
+
cert_file_name?: RecognizedString;
|
|
266
|
+
ca_file_name?: RecognizedString;
|
|
267
|
+
passphrase?: RecognizedString;
|
|
268
|
+
dh_params_file_name?: RecognizedString;
|
|
269
|
+
ssl_ciphers?: RecognizedString;
|
|
270
|
+
/** This translates to SSL_MODE_RELEASE_BUFFERS */
|
|
271
|
+
ssl_prefer_low_memory_usage?: boolean;
|
|
272
|
+
}
|
|
273
|
+
enum ListenOptions {
|
|
274
|
+
LIBUS_LISTEN_DEFAULT = 0,
|
|
275
|
+
LIBUS_LISTEN_EXCLUSIVE_PORT = 1
|
|
276
|
+
}
|
|
277
|
+
/** TemplatedApp is either an SSL or non-SSL app. See App for more info, read user manual. */
|
|
278
|
+
interface TemplatedApp {
|
|
279
|
+
/** Listens to hostname & port. Callback hands either false or a listen socket. */
|
|
280
|
+
listen(host: RecognizedString, port: number, cb: (listenSocket: us_listen_socket | false) => void | Promise<void>): TemplatedApp;
|
|
281
|
+
/** Listens to hostname & port and sets Listen Options. Callback hands either false or a listen socket. */
|
|
282
|
+
listen(host: RecognizedString, port: number, options: ListenOptions, cb: (listenSocket: us_listen_socket | false) => void | Promise<void>): TemplatedApp;
|
|
283
|
+
/** Listens to port. Callback hands either false or a listen socket. */
|
|
284
|
+
listen(port: number, cb: (listenSocket: us_listen_socket | false) => void | Promise<void>): TemplatedApp;
|
|
285
|
+
/** Listens to port and sets Listen Options. Callback hands either false or a listen socket. */
|
|
286
|
+
listen(port: number, options: ListenOptions, cb: (listenSocket: us_listen_socket | false) => void | Promise<void>): TemplatedApp;
|
|
287
|
+
/** Listens to unix socket. Callback hands either false or a listen socket. */
|
|
288
|
+
listen_unix(cb: (listenSocket: us_listen_socket) => void | Promise<void>, path: RecognizedString): TemplatedApp;
|
|
289
|
+
/** Registers an HTTP GET handler matching specified URL pattern. */
|
|
290
|
+
get(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
291
|
+
/** Registers an HTTP POST handler matching specified URL pattern. */
|
|
292
|
+
post(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
293
|
+
/** Registers an HTTP OPTIONS handler matching specified URL pattern. */
|
|
294
|
+
options(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
295
|
+
/** Registers an HTTP DELETE handler matching specified URL pattern. */
|
|
296
|
+
del(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
297
|
+
/** Registers an HTTP PATCH handler matching specified URL pattern. */
|
|
298
|
+
patch(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
299
|
+
/** Registers an HTTP PUT handler matching specified URL pattern. */
|
|
300
|
+
put(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
301
|
+
/** Registers an HTTP HEAD handler matching specified URL pattern. */
|
|
302
|
+
head(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
303
|
+
/** Registers an HTTP CONNECT handler matching specified URL pattern. */
|
|
304
|
+
connect(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
305
|
+
/** Registers an HTTP TRACE handler matching specified URL pattern. */
|
|
306
|
+
trace(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
307
|
+
/** Registers an HTTP handler matching specified URL pattern on any HTTP method. */
|
|
308
|
+
any(pattern: RecognizedString, handler: (res: HttpResponse, req: HttpRequest) => void | Promise<void>): TemplatedApp;
|
|
309
|
+
/** Registers a handler matching specified URL pattern where WebSocket upgrade requests are caught. */
|
|
310
|
+
ws<UserData>(pattern: RecognizedString, behavior: WebSocketBehavior<UserData>): TemplatedApp;
|
|
311
|
+
/** Publishes a message under topic, for all WebSockets under this app. See WebSocket.publish. */
|
|
312
|
+
publish(topic: RecognizedString, message: RecognizedString, isBinary?: boolean, compress?: boolean): boolean;
|
|
313
|
+
/** Returns number of subscribers for this topic. */
|
|
314
|
+
numSubscribers(topic: RecognizedString): number;
|
|
315
|
+
/** Adds a server name. */
|
|
316
|
+
addServerName(hostname: string, options: AppOptions): TemplatedApp;
|
|
317
|
+
/** Browse to SNI domain. Used together with .get, .post and similar to attach routes under SNI domains. */
|
|
318
|
+
domain(domain: string): TemplatedApp;
|
|
319
|
+
/** Removes a server name. */
|
|
320
|
+
removeServerName(hostname: string): TemplatedApp;
|
|
321
|
+
/** Registers a synchronous callback on missing server names. See /examples/ServerName.js. */
|
|
322
|
+
missingServerName(cb: (hostname: string) => void): TemplatedApp;
|
|
323
|
+
/** Attaches a "filter" function to track socket connections / disconnections */
|
|
324
|
+
filter(cb: (res: HttpResponse, count: Number) => void | Promise<void>): TemplatedApp;
|
|
325
|
+
/** Closes all sockets including listen sockets. This will forcefully terminate all connections. */
|
|
326
|
+
close(): TemplatedApp;
|
|
327
|
+
/** Returns the app descriptor for worker thread distribution. */
|
|
328
|
+
getDescriptor(): AppDescriptor;
|
|
329
|
+
/** Add a child app descriptor for worker thread distribution. */
|
|
330
|
+
addChildAppDescriptor(descriptor: AppDescriptor): void;
|
|
331
|
+
/** Remove a child app descriptor. */
|
|
332
|
+
removeChildAppDescriptor(descriptor: AppDescriptor): void;
|
|
333
|
+
}
|
|
334
|
+
/** Constructs a non-SSL app. An app is your starting point where you attach behavior to URL routes.
|
|
335
|
+
* This is also where you listen and run your app, set any SSL options (in case of SSLApp) and the like.
|
|
336
|
+
*/
|
|
337
|
+
function App(options?: AppOptions): TemplatedApp;
|
|
338
|
+
/** Constructs an SSL app. See App. */
|
|
339
|
+
function SSLApp(options: AppOptions): TemplatedApp;
|
|
340
|
+
/** Closes a uSockets listen socket. */
|
|
341
|
+
function us_listen_socket_close(listenSocket: us_listen_socket): void;
|
|
342
|
+
/** Gets local port of socket (or listenSocket) or -1. */
|
|
343
|
+
function us_socket_local_port(socket: us_socket | us_listen_socket): number;
|
|
344
|
+
interface MultipartField {
|
|
345
|
+
data: ArrayBuffer;
|
|
346
|
+
name: string;
|
|
347
|
+
type?: string;
|
|
348
|
+
filename?: string;
|
|
349
|
+
}
|
|
350
|
+
/** Takes a POSTed body and contentType, and returns an array of parts if the request is a multipart request */
|
|
351
|
+
function getParts(body: RecognizedString, contentType: RecognizedString): MultipartField[] | undefined;
|
|
352
|
+
/** WebSocket compression options. Combine any compressor with any decompressor using bitwise OR. */
|
|
353
|
+
type CompressOptions = number;
|
|
354
|
+
/** No compression (always a good idea if you operate using an efficient binary protocol) */
|
|
355
|
+
var DISABLED: CompressOptions;
|
|
356
|
+
/** Zero memory overhead compression. */
|
|
357
|
+
var SHARED_COMPRESSOR: CompressOptions;
|
|
358
|
+
/** Zero memory overhead decompression. */
|
|
359
|
+
var SHARED_DECOMPRESSOR: CompressOptions;
|
|
360
|
+
/** Sliding dedicated compress window, requires 3KB of memory per socket */
|
|
361
|
+
var DEDICATED_COMPRESSOR_3KB: CompressOptions;
|
|
362
|
+
/** Sliding dedicated compress window, requires 4KB of memory per socket */
|
|
363
|
+
var DEDICATED_COMPRESSOR_4KB: CompressOptions;
|
|
364
|
+
/** Sliding dedicated compress window, requires 8KB of memory per socket */
|
|
365
|
+
var DEDICATED_COMPRESSOR_8KB: CompressOptions;
|
|
366
|
+
/** Sliding dedicated compress window, requires 16KB of memory per socket */
|
|
367
|
+
var DEDICATED_COMPRESSOR_16KB: CompressOptions;
|
|
368
|
+
/** Sliding dedicated compress window, requires 32KB of memory per socket */
|
|
369
|
+
var DEDICATED_COMPRESSOR_32KB: CompressOptions;
|
|
370
|
+
/** Sliding dedicated compress window, requires 64KB of memory per socket */
|
|
371
|
+
var DEDICATED_COMPRESSOR_64KB: CompressOptions;
|
|
372
|
+
/** Sliding dedicated compress window, requires 128KB of memory per socket */
|
|
373
|
+
var DEDICATED_COMPRESSOR_128KB: CompressOptions;
|
|
374
|
+
/** Sliding dedicated compress window, requires 256KB of memory per socket */
|
|
375
|
+
var DEDICATED_COMPRESSOR_256KB: CompressOptions;
|
|
376
|
+
/** Sliding dedicated decompress window, requires 32KB of memory per socket (plus about 23KB) */
|
|
377
|
+
var DEDICATED_DECOMPRESSOR_32KB: CompressOptions;
|
|
378
|
+
/** Sliding dedicated decompress window, requires 16KB of memory per socket (plus about 23KB) */
|
|
379
|
+
var DEDICATED_DECOMPRESSOR_16KB: CompressOptions;
|
|
380
|
+
/** Sliding dedicated decompress window, requires 8KB of memory per socket (plus about 23KB) */
|
|
381
|
+
var DEDICATED_DECOMPRESSOR_8KB: CompressOptions;
|
|
382
|
+
/** Sliding dedicated decompress window, requires 4KB of memory per socket (plus about 23KB) */
|
|
383
|
+
var DEDICATED_DECOMPRESSOR_4KB: CompressOptions;
|
|
384
|
+
/** Sliding dedicated decompress window, requires 2KB of memory per socket (plus about 23KB) */
|
|
385
|
+
var DEDICATED_DECOMPRESSOR_2KB: CompressOptions;
|
|
386
|
+
/** Sliding dedicated decompress window, requires 1KB of memory per socket (plus about 23KB) */
|
|
387
|
+
var DEDICATED_DECOMPRESSOR_1KB: CompressOptions;
|
|
388
|
+
/** Sliding dedicated decompress window, requires 512B of memory per socket (plus about 23KB) */
|
|
389
|
+
var DEDICATED_DECOMPRESSOR_512B: CompressOptions;
|
|
390
|
+
/** Sliding dedicated decompress window, requires 32KB of memory per socket (plus about 23KB) */
|
|
391
|
+
var DEDICATED_DECOMPRESSOR: CompressOptions;
|
|
392
|
+
/**
|
|
393
|
+
* Environment variables recognized by uWebSockets.js.
|
|
394
|
+
*
|
|
395
|
+
* These can be set in the process environment before starting the server.
|
|
396
|
+
*/
|
|
397
|
+
namespace EnvironmentVariables {
|
|
398
|
+
/** Maximum total byte size of HTTP request headers. This is a runtime env variable. Default: 4096. */
|
|
399
|
+
const UWS_HTTP_MAX_HEADERS_SIZE: string | undefined;
|
|
400
|
+
/** Maximum number of HTTP request headers. This is a compile-time define, not a runtime env variable. Default: 100. */
|
|
401
|
+
const UWS_HTTP_MAX_HEADERS_COUNT: string | undefined;
|
|
402
|
+
}
|
|
403
|
+
}
|
package/lib/uws.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Authored by Alex Hultman, 2018-2026.
|
|
3
|
+
* Intellectual property of third-party.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
import { createRequire } from "node:module";
|
|
15
|
+
let uws_wrapper;
|
|
16
|
+
try {
|
|
17
|
+
uws_wrapper = createRequire(import.meta.url)("../uws-wrapper.node");
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
try {
|
|
21
|
+
uws_wrapper = createRequire(import.meta.url)("../build/Release/uws-wrapper.node");
|
|
22
|
+
}
|
|
23
|
+
catch (e2) {
|
|
24
|
+
uws_wrapper = createRequire(import.meta.url)("../build/out/uws-wrapper.node");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export default uws_wrapper;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linebridge/engine-neo",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
"tseep": "^1.3.1"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
|
-
"
|
|
38
|
+
"postinstall": "node install.mjs"
|
|
39
39
|
}
|
|
40
40
|
}
|