@liphium/neoroute-ts 0.1.0
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/.prettierignore +5 -0
- package/.prettierrc +8 -0
- package/.zed/settings.json +3 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +15 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/examples/http_client/src/main.d.ts +2 -0
- package/dist/examples/http_client/src/main.d.ts.map +1 -0
- package/dist/examples/http_client/src/main.js +51 -0
- package/dist/examples/http_client/src/main.js.map +1 -0
- package/dist/examples/http_client/src/messages.d.ts +9 -0
- package/dist/examples/http_client/src/messages.d.ts.map +1 -0
- package/dist/examples/http_client/src/messages.js +2 -0
- package/dist/examples/http_client/src/messages.js.map +1 -0
- package/dist/examples/http_client/src/requests.d.ts +5 -0
- package/dist/examples/http_client/src/requests.d.ts.map +1 -0
- package/dist/examples/http_client/src/requests.js +56 -0
- package/dist/examples/http_client/src/requests.js.map +1 -0
- package/dist/examples/web_socket_client/src/main.d.ts +2 -0
- package/dist/examples/web_socket_client/src/main.d.ts.map +1 -0
- package/dist/examples/web_socket_client/src/main.js +59 -0
- package/dist/examples/web_socket_client/src/main.js.map +1 -0
- package/dist/examples/web_socket_client/src/messages.d.ts +14 -0
- package/dist/examples/web_socket_client/src/messages.d.ts.map +1 -0
- package/dist/examples/web_socket_client/src/messages.js +3 -0
- package/dist/examples/web_socket_client/src/messages.js.map +1 -0
- package/dist/examples/web_socket_client/src/receiver.d.ts +3 -0
- package/dist/examples/web_socket_client/src/receiver.d.ts.map +1 -0
- package/dist/examples/web_socket_client/src/receiver.js +8 -0
- package/dist/examples/web_socket_client/src/receiver.js.map +1 -0
- package/dist/examples/web_socket_client/src/requests.d.ts +4 -0
- package/dist/examples/web_socket_client/src/requests.d.ts.map +1 -0
- package/dist/examples/web_socket_client/src/requests.js +32 -0
- package/dist/examples/web_socket_client/src/requests.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +24 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +7 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +11 -0
- package/dist/logger.js.map +1 -0
- package/dist/receiver.d.ts +12 -0
- package/dist/receiver.d.ts.map +1 -0
- package/dist/receiver.js +49 -0
- package/dist/receiver.js.map +1 -0
- package/dist/sender.d.ts +26 -0
- package/dist/sender.d.ts.map +1 -0
- package/dist/sender.js +135 -0
- package/dist/sender.js.map +1 -0
- package/dist/src/client.d.ts +8 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +15 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.d.ts +5 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +2 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces.d.ts +24 -0
- package/dist/src/interfaces.d.ts.map +1 -0
- package/dist/src/interfaces.js +7 -0
- package/dist/src/interfaces.js.map +1 -0
- package/dist/src/logger.d.ts +9 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +11 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/receiver.d.ts +12 -0
- package/dist/src/receiver.d.ts.map +1 -0
- package/dist/src/receiver.js +49 -0
- package/dist/src/receiver.js.map +1 -0
- package/dist/src/sender.d.ts +26 -0
- package/dist/src/sender.d.ts.map +1 -0
- package/dist/src/sender.js +135 -0
- package/dist/src/sender.js.map +1 -0
- package/dist/src/transporter/transporter_http.d.ts +6 -0
- package/dist/src/transporter/transporter_http.d.ts.map +1 -0
- package/dist/src/transporter/transporter_http.js +30 -0
- package/dist/src/transporter/transporter_http.js.map +1 -0
- package/dist/src/transporter/transporter_websocket.d.ts +17 -0
- package/dist/src/transporter/transporter_websocket.d.ts.map +1 -0
- package/dist/src/transporter/transporter_websocket.js +93 -0
- package/dist/src/transporter/transporter_websocket.js.map +1 -0
- package/dist/src/user_error.d.ts +4 -0
- package/dist/src/user_error.d.ts.map +1 -0
- package/dist/src/user_error.js +11 -0
- package/dist/src/user_error.js.map +1 -0
- package/dist/src/util.d.ts +9 -0
- package/dist/src/util.d.ts.map +1 -0
- package/dist/src/util.js +42 -0
- package/dist/src/util.js.map +1 -0
- package/dist/transporter/transporter_http.d.ts +6 -0
- package/dist/transporter/transporter_http.d.ts.map +1 -0
- package/dist/transporter/transporter_http.js +30 -0
- package/dist/transporter/transporter_http.js.map +1 -0
- package/dist/transporter/transporter_websocket.d.ts +17 -0
- package/dist/transporter/transporter_websocket.d.ts.map +1 -0
- package/dist/transporter/transporter_websocket.js +93 -0
- package/dist/transporter/transporter_websocket.js.map +1 -0
- package/dist/user_error.d.ts +4 -0
- package/dist/user_error.d.ts.map +1 -0
- package/dist/user_error.js +11 -0
- package/dist/user_error.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +42 -0
- package/dist/util.js.map +1 -0
- package/examples/http_client/package.json +20 -0
- package/examples/http_client/src/main.ts +59 -0
- package/examples/http_client/src/messages.ts +9 -0
- package/examples/http_client/src/requests.ts +64 -0
- package/examples/http_client/tsconfig.json +44 -0
- package/examples/web_socket_client/package.json +20 -0
- package/examples/web_socket_client/src/main.ts +72 -0
- package/examples/web_socket_client/src/messages.ts +22 -0
- package/examples/web_socket_client/src/receiver.ts +8 -0
- package/examples/web_socket_client/src/requests.ts +51 -0
- package/examples/web_socket_client/tsconfig.json +44 -0
- package/package.json +36 -0
- package/pnpm-workspace.yaml +5 -0
- package/readme.md +49 -0
- package/src/client.ts +17 -0
- package/src/config.ts +4 -0
- package/src/index.ts +13 -0
- package/src/interfaces.ts +31 -0
- package/src/logger.ts +18 -0
- package/src/receiver.ts +56 -0
- package/src/sender.ts +203 -0
- package/src/transporter/transporter_http.ts +37 -0
- package/src/transporter/transporter_websocket.ts +115 -0
- package/src/user_error.ts +21 -0
- package/src/util.ts +58 -0
- package/tsconfig.json +44 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { logger } from '../logger.js';
|
|
2
|
+
export class WebSocketTransporter {
|
|
3
|
+
conn = null;
|
|
4
|
+
receiver;
|
|
5
|
+
options;
|
|
6
|
+
connected = false;
|
|
7
|
+
queue = [];
|
|
8
|
+
constructor(receiver, options) {
|
|
9
|
+
this.receiver = receiver;
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
/// Will start a connection to the server. Will not block until the connection is open.
|
|
13
|
+
///
|
|
14
|
+
/// All things sent before the connection is open are queued, so feel free to send already after calling connect.
|
|
15
|
+
connect(url) {
|
|
16
|
+
if (this.connected || this.conn) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// Queue outgoing messages until connection is open
|
|
20
|
+
this.receiver.setSendFunc(async (data) => {
|
|
21
|
+
if (this.connected && this.conn?.readyState === WebSocket.OPEN) {
|
|
22
|
+
this.conn.send(data); // TODO: Find out if this is actually fine xd
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.queue.push(data);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
// Add a timeout to make sure the connection actually happens
|
|
29
|
+
const timeout = setTimeout(() => {
|
|
30
|
+
if (this.conn?.readyState !== WebSocket.OPEN) {
|
|
31
|
+
this.close('connection timeout');
|
|
32
|
+
}
|
|
33
|
+
}, this.options.connectionTimeout ?? 20000);
|
|
34
|
+
// Init WebSocket to open the actual connection
|
|
35
|
+
this.conn = new WebSocket(url);
|
|
36
|
+
this.conn.binaryType = 'arraybuffer';
|
|
37
|
+
this.conn.onopen = () => {
|
|
38
|
+
if (!this.conn)
|
|
39
|
+
return;
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
this.connected = true;
|
|
42
|
+
// Call onOpen callback
|
|
43
|
+
this.options.onOpen?.();
|
|
44
|
+
// Flush queue
|
|
45
|
+
while (this.queue.length > 0) {
|
|
46
|
+
const data = this.queue.shift();
|
|
47
|
+
if (data) {
|
|
48
|
+
this.conn.send(data);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
// When there is an error, we immediately disconnect
|
|
53
|
+
this.conn.onerror = () => {
|
|
54
|
+
if (this.conn) {
|
|
55
|
+
this.close('websocket error');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Even on a close, we want to quickly close the thingy to notify the event handler for onError and update internal state
|
|
59
|
+
this.conn.onclose = (event) => {
|
|
60
|
+
if (this.conn) {
|
|
61
|
+
this.close(`websocket connection closed: ${event.code} ${event.reason}`);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// Forward messages to the receiver
|
|
65
|
+
this.conn.onmessage = (event) => {
|
|
66
|
+
if (event.data instanceof ArrayBuffer) {
|
|
67
|
+
this.receiver.handle(new Uint8Array(event.data));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// If we get this, the browser is doing something weird
|
|
71
|
+
logger.error('wrong message type received:', typeof event.data);
|
|
72
|
+
this.close('wrong kind of message received');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/// Closes the connection to the server. Will not throw if the connection is already closed.
|
|
77
|
+
close(reason = 'Connection closed') {
|
|
78
|
+
const wasConnected = this.connected || !!this.conn;
|
|
79
|
+
this.connected = false;
|
|
80
|
+
if (this.conn) {
|
|
81
|
+
const c = this.conn;
|
|
82
|
+
this.conn = null;
|
|
83
|
+
c.close(1000, reason);
|
|
84
|
+
}
|
|
85
|
+
if (wasConnected) {
|
|
86
|
+
this.receiver.getConfig().errorHandler(new Error(reason));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
isConnected() {
|
|
90
|
+
return this.connected;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=transporter_websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transporter_websocket.js","sourceRoot":"","sources":["../../../src/transporter/transporter_websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_error.d.ts","sourceRoot":"","sources":["../../src/user_error.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAmB3B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class UserError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'UserError';
|
|
5
|
+
if (typeof Error
|
|
6
|
+
.captureStackTrace === 'function') {
|
|
7
|
+
Error.captureStackTrace(this, UserError);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=user_error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_error.js","sourceRoot":"","sources":["../../src/user_error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAU,SAAQ,KAAK;IACnC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QAExB,IACC,OAAQ,KAA4D;aAClE,iBAAiB,KAAK,UAAU,EACjC,CAAC;YAED,KAMA,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function newPromiseWithResolver<T>(): {
|
|
2
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
3
|
+
reject: (reason?: any) => void;
|
|
4
|
+
promise: Promise<T>;
|
|
5
|
+
};
|
|
6
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, onTimeout?: () => void): Promise<T>;
|
|
7
|
+
export declare function marshalRequestData<RQ>(req: RQ): Uint8Array;
|
|
8
|
+
export declare function unmarshalResponseData<RS>(respBytes: Uint8Array): RS;
|
|
9
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,CAAC,CAAC,KAAK;IAC5C,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC7C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpB,CAUA;AAGD,wBAAgB,WAAW,CAAC,CAAC,EAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,IAAI,GACpB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,UAAU,CAM1D;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,GAAG,EAAE,CAMnE"}
|
package/dist/src/util.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { decode, encode } from '@msgpack/msgpack';
|
|
2
|
+
// Creates a promise that can be resolved or rejected externally. This is useful for creating a promise that can be resolved or rejected at a later time, such as when waiting for an event to occur.
|
|
3
|
+
export function newPromiseWithResolver() {
|
|
4
|
+
let resolve;
|
|
5
|
+
let reject;
|
|
6
|
+
const promise = new Promise((res, rej) => {
|
|
7
|
+
resolve = res;
|
|
8
|
+
reject = rej;
|
|
9
|
+
});
|
|
10
|
+
return { resolve, reject, promise };
|
|
11
|
+
}
|
|
12
|
+
// Helper to create a timeout promise
|
|
13
|
+
export function withTimeout(promise, timeoutMs, onTimeout) {
|
|
14
|
+
let timeoutId;
|
|
15
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
16
|
+
timeoutId = setTimeout(() => {
|
|
17
|
+
onTimeout?.();
|
|
18
|
+
reject(new Error(`waiting for response timed out after ${timeoutMs}ms`));
|
|
19
|
+
}, timeoutMs);
|
|
20
|
+
});
|
|
21
|
+
return Promise.race([
|
|
22
|
+
promise.finally(() => clearTimeout(timeoutId)),
|
|
23
|
+
timeoutPromise,
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
export function marshalRequestData(req) {
|
|
27
|
+
try {
|
|
28
|
+
return encode(req);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`failed to marshal request data: ${error}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function unmarshalResponseData(respBytes) {
|
|
35
|
+
try {
|
|
36
|
+
return decode(respBytes);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`failed to unmarshal response data: ${error}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAElD,qMAAqM;AACrM,MAAM,UAAU,sBAAsB;IAKrC,IAAI,OAA6C,CAAC;IAClD,IAAI,MAA+B,CAAC;IAEpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,OAAO,GAAG,GAAG,CAAC;QACd,MAAM,GAAG,GAAG,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,WAAW,CAC1B,OAAmB,EACnB,SAAiB,EACjB,SAAsB;IAEtB,IAAI,SAAwC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACnD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,SAAS,EAAE,EAAE,CAAC;YACd,MAAM,CACL,IAAI,KAAK,CACR,wCAAwC,SAAS,IAAI,CACrD,CACD,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,IAAI,CAAC;QACnB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC9C,cAAc;KACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAK,GAAO;IAC7C,IAAI,CAAC;QACJ,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAK,SAAqB;IAC9D,IAAI,CAAC;QACJ,OAAO,MAAM,CAAC,SAAS,CAAO,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transporter_http.d.ts","sourceRoot":"","sources":["../../src/transporter/transporter_http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,qBAAa,eAAe;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAEX,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CA+BlD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class HTTPTransporter {
|
|
2
|
+
sender;
|
|
3
|
+
constructor(s, method, url) {
|
|
4
|
+
this.sender = s;
|
|
5
|
+
this.sender.setSendFunc(async (data) => {
|
|
6
|
+
const controller = new AbortController();
|
|
7
|
+
const timeout = setTimeout(() => controller.abort(), 20000);
|
|
8
|
+
try {
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: method,
|
|
11
|
+
body: data,
|
|
12
|
+
signal: controller.signal,
|
|
13
|
+
headers: {
|
|
14
|
+
'Content-Type': 'application/octet-stream',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
// Check for transporter errors
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(`received non ok status ${response.status} ${response.statusText}`);
|
|
20
|
+
}
|
|
21
|
+
// Let sender handle the response routing
|
|
22
|
+
this.sender.handle(await response.bytes());
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=transporter_http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transporter_http.js","sourceRoot":"","sources":["../../src/transporter/transporter_http.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,eAAe;IACnB,MAAM,CAAS;IAEvB,YAAY,CAAS,EAAE,MAAc,EAAE,GAAW;QACjD,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,IAAgB,EAAiB,EAAE;YACjE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YAE5D,IAAI,CAAC;gBACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBACjC,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,IAA2B;oBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,OAAO,EAAE;wBACR,cAAc,EAAE,0BAA0B;qBAC1C;iBACD,CAAC,CAAC;gBAEH,+BAA+B;gBAC/B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CACd,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAClE,CAAC;gBACH,CAAC;gBAED,yCAAyC;gBACzC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YAC5C,CAAC;oBAAS,CAAC;gBACV,YAAY,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Receiver } from '../receiver.js';
|
|
2
|
+
export interface WebSocketOptions {
|
|
3
|
+
connectionTimeout?: number;
|
|
4
|
+
onOpen?: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare class WebSocketTransporter {
|
|
7
|
+
private conn;
|
|
8
|
+
private receiver;
|
|
9
|
+
private options;
|
|
10
|
+
private connected;
|
|
11
|
+
private queue;
|
|
12
|
+
constructor(receiver: Receiver, options: WebSocketOptions);
|
|
13
|
+
connect(url: string): void;
|
|
14
|
+
close(reason?: string): void;
|
|
15
|
+
isConnected(): boolean;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=transporter_websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transporter_websocket.d.ts","sourceRoot":"","sources":["../../src/transporter/transporter_websocket.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAEhC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,qBAAa,oBAAoB;IAChC,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,KAAK,CAAoB;gBAErB,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB;IAQlD,OAAO,CAAC,GAAG,EAAE,MAAM;IAwEnB,KAAK,CAAC,MAAM,GAAE,MAA4B,GAAG,IAAI;IAajD,WAAW,IAAI,OAAO;CAG7B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { logger } from '../logger.js';
|
|
2
|
+
export class WebSocketTransporter {
|
|
3
|
+
conn = null;
|
|
4
|
+
receiver;
|
|
5
|
+
options;
|
|
6
|
+
connected = false;
|
|
7
|
+
queue = [];
|
|
8
|
+
constructor(receiver, options) {
|
|
9
|
+
this.receiver = receiver;
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
/// Will start a connection to the server. Will not block until the connection is open.
|
|
13
|
+
///
|
|
14
|
+
/// All things sent before the connection is open are queued, so feel free to send already after calling connect.
|
|
15
|
+
connect(url) {
|
|
16
|
+
if (this.connected || this.conn) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// Queue outgoing messages until connection is open
|
|
20
|
+
this.receiver.setSendFunc(async (data) => {
|
|
21
|
+
if (this.connected && this.conn?.readyState === WebSocket.OPEN) {
|
|
22
|
+
this.conn.send(data); // TODO: Find out if this is actually fine xd
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.queue.push(data);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
// Add a timeout to make sure the connection actually happens
|
|
29
|
+
const timeout = setTimeout(() => {
|
|
30
|
+
if (this.conn?.readyState !== WebSocket.OPEN) {
|
|
31
|
+
this.close('connection timeout');
|
|
32
|
+
}
|
|
33
|
+
}, this.options.connectionTimeout ?? 20000);
|
|
34
|
+
// Init WebSocket to open the actual connection
|
|
35
|
+
this.conn = new WebSocket(url);
|
|
36
|
+
this.conn.binaryType = 'arraybuffer';
|
|
37
|
+
this.conn.onopen = () => {
|
|
38
|
+
if (!this.conn)
|
|
39
|
+
return;
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
this.connected = true;
|
|
42
|
+
// Call onOpen callback
|
|
43
|
+
this.options.onOpen?.();
|
|
44
|
+
// Flush queue
|
|
45
|
+
while (this.queue.length > 0) {
|
|
46
|
+
const data = this.queue.shift();
|
|
47
|
+
if (data) {
|
|
48
|
+
this.conn.send(data);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
// When there is an error, we immediately disconnect
|
|
53
|
+
this.conn.onerror = () => {
|
|
54
|
+
if (this.conn) {
|
|
55
|
+
this.close('websocket error');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Even on a close, we want to quickly close the thingy to notify the event handler for onError and update internal state
|
|
59
|
+
this.conn.onclose = (event) => {
|
|
60
|
+
if (this.conn) {
|
|
61
|
+
this.close(`websocket connection closed: ${event.code} ${event.reason}`);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// Forward messages to the receiver
|
|
65
|
+
this.conn.onmessage = (event) => {
|
|
66
|
+
if (event.data instanceof ArrayBuffer) {
|
|
67
|
+
this.receiver.handle(new Uint8Array(event.data));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// If we get this, the browser is doing something weird
|
|
71
|
+
logger.error('wrong message type received:', typeof event.data);
|
|
72
|
+
this.close('wrong kind of message received');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/// Closes the connection to the server. Will not throw if the connection is already closed.
|
|
77
|
+
close(reason = 'Connection closed') {
|
|
78
|
+
const wasConnected = this.connected || !!this.conn;
|
|
79
|
+
this.connected = false;
|
|
80
|
+
if (this.conn) {
|
|
81
|
+
const c = this.conn;
|
|
82
|
+
this.conn = null;
|
|
83
|
+
c.close(1000, reason);
|
|
84
|
+
}
|
|
85
|
+
if (wasConnected) {
|
|
86
|
+
this.receiver.getConfig().errorHandler(new Error(reason));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
isConnected() {
|
|
90
|
+
return this.connected;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=transporter_websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transporter_websocket.js","sourceRoot":"","sources":["../../src/transporter/transporter_websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_error.d.ts","sourceRoot":"","sources":["../src/user_error.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAmB3B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class UserError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'UserError';
|
|
5
|
+
if (typeof Error
|
|
6
|
+
.captureStackTrace === 'function') {
|
|
7
|
+
Error.captureStackTrace(this, UserError);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=user_error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_error.js","sourceRoot":"","sources":["../src/user_error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAU,SAAQ,KAAK;IACnC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QAExB,IACC,OAAQ,KAA4D;aAClE,iBAAiB,KAAK,UAAU,EACjC,CAAC;YAED,KAMA,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;CACD"}
|
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function newPromiseWithResolver<T>(): {
|
|
2
|
+
resolve: (value: T | PromiseLike<T>) => void;
|
|
3
|
+
reject: (reason?: any) => void;
|
|
4
|
+
promise: Promise<T>;
|
|
5
|
+
};
|
|
6
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, onTimeout?: () => void): Promise<T>;
|
|
7
|
+
export declare function marshalRequestData<RQ>(req: RQ): Uint8Array;
|
|
8
|
+
export declare function unmarshalResponseData<RS>(respBytes: Uint8Array): RS;
|
|
9
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,CAAC,CAAC,KAAK;IAC5C,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC7C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpB,CAUA;AAGD,wBAAgB,WAAW,CAAC,CAAC,EAC5B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,IAAI,GACpB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,UAAU,CAM1D;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,GAAG,EAAE,CAMnE"}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { decode, encode } from '@msgpack/msgpack';
|
|
2
|
+
// Creates a promise that can be resolved or rejected externally. This is useful for creating a promise that can be resolved or rejected at a later time, such as when waiting for an event to occur.
|
|
3
|
+
export function newPromiseWithResolver() {
|
|
4
|
+
let resolve;
|
|
5
|
+
let reject;
|
|
6
|
+
const promise = new Promise((res, rej) => {
|
|
7
|
+
resolve = res;
|
|
8
|
+
reject = rej;
|
|
9
|
+
});
|
|
10
|
+
return { resolve, reject, promise };
|
|
11
|
+
}
|
|
12
|
+
// Helper to create a timeout promise
|
|
13
|
+
export function withTimeout(promise, timeoutMs, onTimeout) {
|
|
14
|
+
let timeoutId;
|
|
15
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
16
|
+
timeoutId = setTimeout(() => {
|
|
17
|
+
onTimeout?.();
|
|
18
|
+
reject(new Error(`waiting for response timed out after ${timeoutMs}ms`));
|
|
19
|
+
}, timeoutMs);
|
|
20
|
+
});
|
|
21
|
+
return Promise.race([
|
|
22
|
+
promise.finally(() => clearTimeout(timeoutId)),
|
|
23
|
+
timeoutPromise,
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
export function marshalRequestData(req) {
|
|
27
|
+
try {
|
|
28
|
+
return encode(req);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`failed to marshal request data: ${error}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function unmarshalResponseData(respBytes) {
|
|
35
|
+
try {
|
|
36
|
+
return decode(respBytes);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`failed to unmarshal response data: ${error}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAElD,qMAAqM;AACrM,MAAM,UAAU,sBAAsB;IAKrC,IAAI,OAA6C,CAAC;IAClD,IAAI,MAA+B,CAAC;IAEpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,OAAO,GAAG,GAAG,CAAC;QACd,MAAM,GAAG,GAAG,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,WAAW,CAC1B,OAAmB,EACnB,SAAiB,EACjB,SAAsB;IAEtB,IAAI,SAAwC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACnD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,SAAS,EAAE,EAAE,CAAC;YACd,MAAM,CACL,IAAI,KAAK,CACR,wCAAwC,SAAS,IAAI,CACrD,CACD,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,IAAI,CAAC;QACnB,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC9C,cAAc;KACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAK,GAAO;IAC7C,IAAI,CAAC;QACJ,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAK,SAAqB;IAC9D,IAAI,CAAC;QACJ,OAAO,MAAM,CAAC,SAAS,CAAO,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "http_example",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "How to use the HTTP client from neoroute-ts",
|
|
6
|
+
"main": "index.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node --loader ts-node/esm src/main.ts"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@liphium/neoroute-ts": "workspace:*"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "^26.0.1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"private": "true",
|
|
19
|
+
"packageManager": "pnpm@10.32.1"
|
|
20
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Receiver, HTTPTransporter } from '@liphium/neoroute-ts';
|
|
2
|
+
import { testHttpSimple, testHttpGroup1, testHttpGroup2 } from './requests.js';
|
|
3
|
+
import readline from 'node:readline';
|
|
4
|
+
|
|
5
|
+
async function main() {
|
|
6
|
+
// 1. Setup Receiver
|
|
7
|
+
const httpReceiver = new Receiver({
|
|
8
|
+
errorHandler: (err: Error) =>
|
|
9
|
+
console.log('Global HTTP receiver error:', err),
|
|
10
|
+
requestTimeout: 5000,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// 2. Setup HTTP Transporter with the required auth token
|
|
14
|
+
const httpTransporter = new HTTPTransporter(
|
|
15
|
+
httpReceiver,
|
|
16
|
+
'POST',
|
|
17
|
+
'http://localhost:6121/?token=secret_token',
|
|
18
|
+
);
|
|
19
|
+
console.log('HTTP Transporter initialized and ready.');
|
|
20
|
+
|
|
21
|
+
// 3. Setup console interface
|
|
22
|
+
const rl = readline.createInterface({
|
|
23
|
+
input: process.stdin,
|
|
24
|
+
output: process.stdout,
|
|
25
|
+
prompt: '> ',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log('\n--- HTTP Client Commands ---');
|
|
29
|
+
console.log("1: Test 'simple.route'");
|
|
30
|
+
console.log("2: Test 'group1.route1'");
|
|
31
|
+
console.log("3: Test 'group1.group2.route1'");
|
|
32
|
+
console.log('exit: Quit the program');
|
|
33
|
+
console.log('----------------------------\n');
|
|
34
|
+
rl.prompt();
|
|
35
|
+
|
|
36
|
+
rl.on('line', (line) => {
|
|
37
|
+
const input = line.trim();
|
|
38
|
+
|
|
39
|
+
if (input === '1') {
|
|
40
|
+
testHttpSimple(httpReceiver).then(() => rl.prompt());
|
|
41
|
+
} else if (input === '2') {
|
|
42
|
+
testHttpGroup1(httpReceiver, 10).then(() => rl.prompt());
|
|
43
|
+
} else if (input === '3') {
|
|
44
|
+
testHttpGroup2(httpReceiver, 42).then(() => rl.prompt());
|
|
45
|
+
} else if (input === 'exit') {
|
|
46
|
+
rl.close();
|
|
47
|
+
} else {
|
|
48
|
+
console.log('Unknown command.');
|
|
49
|
+
rl.prompt();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
rl.on('close', () => {
|
|
54
|
+
console.log('Shutting down HTTP client.');
|
|
55
|
+
process.exit(0);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main();
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Receiver, UserError } from '@liphium/neoroute-ts';
|
|
2
|
+
import { type TestRequest, type TestResponse } from './messages.js';
|
|
3
|
+
|
|
4
|
+
export async function testHttpSimple(receiver: Receiver): Promise<void> {
|
|
5
|
+
try {
|
|
6
|
+
console.log('Sending simple HTTP request...');
|
|
7
|
+
const resp = receiver.sendNoRequest<TestResponse>('simple.route');
|
|
8
|
+
console.log('Simple HTTP Response:', resp);
|
|
9
|
+
} catch (err) {
|
|
10
|
+
if (err instanceof UserError) {
|
|
11
|
+
console.log('UserError on simple route:', err.message);
|
|
12
|
+
} else {
|
|
13
|
+
console.log('System error on simple route:', err);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function testHttpGroup1(
|
|
19
|
+
receiver: Receiver,
|
|
20
|
+
numberValue: number,
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
try {
|
|
23
|
+
console.log('Sending group1 HTTP request...');
|
|
24
|
+
const req: TestRequest = {
|
|
25
|
+
field1: 'Testing Group 1',
|
|
26
|
+
field2: numberValue,
|
|
27
|
+
};
|
|
28
|
+
const resp = receiver.send<TestResponse, TestRequest>(
|
|
29
|
+
'group1.route1',
|
|
30
|
+
req,
|
|
31
|
+
);
|
|
32
|
+
console.log('Group 1 HTTP Response:', resp);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
if (err instanceof UserError) {
|
|
35
|
+
console.log('UserError on group1 route:', err.message);
|
|
36
|
+
} else {
|
|
37
|
+
console.log('System error on group1 route:', err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function testHttpGroup2(
|
|
43
|
+
receiver: Receiver,
|
|
44
|
+
numberValue: number,
|
|
45
|
+
): Promise<void> {
|
|
46
|
+
try {
|
|
47
|
+
console.log('Sending group2 HTTP request...');
|
|
48
|
+
const req: TestRequest = {
|
|
49
|
+
field1: 'Testing Group 2',
|
|
50
|
+
field2: numberValue,
|
|
51
|
+
};
|
|
52
|
+
const resp = await receiver.send<TestResponse, TestRequest>(
|
|
53
|
+
'group1.group2.route1',
|
|
54
|
+
req,
|
|
55
|
+
);
|
|
56
|
+
console.log('Group 2 HTTP Response:', resp);
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (err instanceof UserError) {
|
|
59
|
+
console.log('UserError on group2 route:', err.message);
|
|
60
|
+
} else {
|
|
61
|
+
console.log('System error on group2 route:', err);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
// Environment Settings
|
|
9
|
+
// See also https://aka.ms/tsconfig/module
|
|
10
|
+
"module": "nodenext",
|
|
11
|
+
"target": "esnext",
|
|
12
|
+
"types": ["node"],
|
|
13
|
+
// For nodejs:
|
|
14
|
+
// "lib": ["esnext"],
|
|
15
|
+
// "types": ["node"],
|
|
16
|
+
// and npm install -D @types/node
|
|
17
|
+
|
|
18
|
+
// Other Outputs
|
|
19
|
+
"sourceMap": true,
|
|
20
|
+
"declaration": true,
|
|
21
|
+
"declarationMap": true,
|
|
22
|
+
|
|
23
|
+
// Stricter Typechecking Options
|
|
24
|
+
"noUncheckedIndexedAccess": true,
|
|
25
|
+
"exactOptionalPropertyTypes": true,
|
|
26
|
+
|
|
27
|
+
// Style Options
|
|
28
|
+
// "noImplicitReturns": true,
|
|
29
|
+
// "noImplicitOverride": true,
|
|
30
|
+
// "noUnusedLocals": true,
|
|
31
|
+
// "noUnusedParameters": true,
|
|
32
|
+
// "noFallthroughCasesInSwitch": true,
|
|
33
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
34
|
+
|
|
35
|
+
// Recommended Options
|
|
36
|
+
"strict": true,
|
|
37
|
+
"jsx": "react-jsx",
|
|
38
|
+
"verbatimModuleSyntax": true,
|
|
39
|
+
"isolatedModules": true,
|
|
40
|
+
"noUncheckedSideEffectImports": true,
|
|
41
|
+
"moduleDetection": "force",
|
|
42
|
+
"skipLibCheck": true,
|
|
43
|
+
},
|
|
44
|
+
}
|