@grest-ts/websocket 0.0.5
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/LICENSE +21 -0
- package/dist/src/adapter/BrowserSocketAdapter.d.ts +18 -0
- package/dist/src/adapter/BrowserSocketAdapter.d.ts.map +1 -0
- package/dist/src/adapter/BrowserSocketAdapter.js +51 -0
- package/dist/src/adapter/BrowserSocketAdapter.js.map +1 -0
- package/dist/src/adapter/NodeSocketAdapter.d.ts +21 -0
- package/dist/src/adapter/NodeSocketAdapter.d.ts.map +1 -0
- package/dist/src/adapter/NodeSocketAdapter.js +52 -0
- package/dist/src/adapter/NodeSocketAdapter.js.map +1 -0
- package/dist/src/adapter/getDefaultAdapter.d.ts +5 -0
- package/dist/src/adapter/getDefaultAdapter.d.ts.map +1 -0
- package/dist/src/adapter/getDefaultAdapter.js +15 -0
- package/dist/src/adapter/getDefaultAdapter.js.map +1 -0
- package/dist/src/client/GGSocketClient.d.ts +10 -0
- package/dist/src/client/GGSocketClient.d.ts.map +1 -0
- package/dist/src/client/GGSocketClient.js +17 -0
- package/dist/src/client/GGSocketClient.js.map +1 -0
- package/dist/src/client/GGSocketPool.d.ts +63 -0
- package/dist/src/client/GGSocketPool.d.ts.map +1 -0
- package/dist/src/client/GGSocketPool.js +203 -0
- package/dist/src/client/GGSocketPool.js.map +1 -0
- package/dist/src/index-browser.d.ts +11 -0
- package/dist/src/index-browser.d.ts.map +1 -0
- package/dist/src/index-browser.js +17 -0
- package/dist/src/index-browser.js.map +1 -0
- package/dist/src/index-node.d.ts +14 -0
- package/dist/src/index-node.d.ts.map +1 -0
- package/dist/src/index-node.js +22 -0
- package/dist/src/index-node.js.map +1 -0
- package/dist/src/schema/GGWebSocketMiddleware.d.ts +40 -0
- package/dist/src/schema/GGWebSocketMiddleware.d.ts.map +1 -0
- package/dist/src/schema/GGWebSocketMiddleware.js +6 -0
- package/dist/src/schema/GGWebSocketMiddleware.js.map +1 -0
- package/dist/src/schema/GGWebSocketSchema.d.ts +31 -0
- package/dist/src/schema/GGWebSocketSchema.d.ts.map +1 -0
- package/dist/src/schema/GGWebSocketSchema.js +32 -0
- package/dist/src/schema/GGWebSocketSchema.js.map +1 -0
- package/dist/src/schema/webSocketSchema.d.ts +52 -0
- package/dist/src/schema/webSocketSchema.d.ts.map +1 -0
- package/dist/src/schema/webSocketSchema.js +62 -0
- package/dist/src/schema/webSocketSchema.js.map +1 -0
- package/dist/src/server/GGSocketServer.d.ts +34 -0
- package/dist/src/server/GGSocketServer.d.ts.map +1 -0
- package/dist/src/server/GGSocketServer.js +186 -0
- package/dist/src/server/GGSocketServer.js.map +1 -0
- package/dist/src/server/GGWebSocketMetrics.d.ts +43 -0
- package/dist/src/server/GGWebSocketMetrics.d.ts.map +1 -0
- package/dist/src/server/GGWebSocketMetrics.js +38 -0
- package/dist/src/server/GGWebSocketMetrics.js.map +1 -0
- package/dist/src/server/GGWebSocketSchema.startServer.d.ts +33 -0
- package/dist/src/server/GGWebSocketSchema.startServer.d.ts.map +1 -0
- package/dist/src/server/GGWebSocketSchema.startServer.js +80 -0
- package/dist/src/server/GGWebSocketSchema.startServer.js.map +1 -0
- package/dist/src/server/GG_WS_CONNECTION.d.ts +12 -0
- package/dist/src/server/GG_WS_CONNECTION.d.ts.map +1 -0
- package/dist/src/server/GG_WS_CONNECTION.js +8 -0
- package/dist/src/server/GG_WS_CONNECTION.js.map +1 -0
- package/dist/src/server/GG_WS_MESSAGE.d.ts +10 -0
- package/dist/src/server/GG_WS_MESSAGE.d.ts.map +1 -0
- package/dist/src/server/GG_WS_MESSAGE.js +7 -0
- package/dist/src/server/GG_WS_MESSAGE.js.map +1 -0
- package/dist/src/socket/GGSocket.d.ts +81 -0
- package/dist/src/socket/GGSocket.d.ts.map +1 -0
- package/dist/src/socket/GGSocket.js +315 -0
- package/dist/src/socket/GGSocket.js.map +1 -0
- package/dist/src/socket/SocketAdapter.d.ts +13 -0
- package/dist/src/socket/SocketAdapter.d.ts.map +1 -0
- package/dist/src/socket/SocketAdapter.js +2 -0
- package/dist/src/socket/SocketAdapter.js.map +1 -0
- package/dist/src/socket/SocketMessage.d.ts +47 -0
- package/dist/src/socket/SocketMessage.d.ts.map +1 -0
- package/dist/src/socket/SocketMessage.js +51 -0
- package/dist/src/socket/SocketMessage.js.map +1 -0
- package/dist/src/socket/WebSocketTypes.d.ts +18 -0
- package/dist/src/socket/WebSocketTypes.d.ts.map +1 -0
- package/dist/src/socket/WebSocketTypes.js +5 -0
- package/dist/src/socket/WebSocketTypes.js.map +1 -0
- package/dist/src/socket/utils/PendingRequestsMap.d.ts +32 -0
- package/dist/src/socket/utils/PendingRequestsMap.d.ts.map +1 -0
- package/dist/src/socket/utils/PendingRequestsMap.js +104 -0
- package/dist/src/socket/utils/PendingRequestsMap.js.map +1 -0
- package/dist/src/tsconfig.json +17 -0
- package/dist/testkit/client/GGSocketCall.d.ts +37 -0
- package/dist/testkit/client/GGSocketCall.d.ts.map +1 -0
- package/dist/testkit/client/GGSocketCall.js +44 -0
- package/dist/testkit/client/GGSocketCall.js.map +1 -0
- package/dist/testkit/client/GGWebSocketSchema.callOn.d.ts +70 -0
- package/dist/testkit/client/GGWebSocketSchema.callOn.d.ts.map +1 -0
- package/dist/testkit/client/GGWebSocketSchema.callOn.js +135 -0
- package/dist/testkit/client/GGWebSocketSchema.callOn.js.map +1 -0
- package/dist/testkit/index-testkit.d.ts +4 -0
- package/dist/testkit/index-testkit.d.ts.map +1 -0
- package/dist/testkit/index-testkit.js +3 -0
- package/dist/testkit/index-testkit.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +74 -0
- package/src/adapter/BrowserSocketAdapter.ts +63 -0
- package/src/adapter/NodeSocketAdapter.ts +67 -0
- package/src/adapter/getDefaultAdapter.ts +14 -0
- package/src/client/GGSocketClient.ts +25 -0
- package/src/client/GGSocketPool.ts +244 -0
- package/src/index-browser.ts +21 -0
- package/src/index-node.ts +28 -0
- package/src/schema/GGWebSocketMiddleware.ts +43 -0
- package/src/schema/GGWebSocketSchema.ts +57 -0
- package/src/schema/webSocketSchema.ts +109 -0
- package/src/server/GGSocketServer.ts +217 -0
- package/src/server/GGWebSocketMetrics.ts +58 -0
- package/src/server/GGWebSocketSchema.startServer.ts +136 -0
- package/src/server/GG_WS_CONNECTION.ts +10 -0
- package/src/server/GG_WS_MESSAGE.ts +9 -0
- package/src/socket/GGSocket.ts +394 -0
- package/src/socket/SocketAdapter.ts +21 -0
- package/src/socket/SocketMessage.ts +97 -0
- package/src/socket/WebSocketTypes.ts +19 -0
- package/src/socket/utils/PendingRequestsMap.ts +128 -0
- package/src/tsconfig.json +17 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server extension for WebSocketSchema - adds startServer and register methods
|
|
3
|
+
* This file should only be imported in server (Node.js) context
|
|
4
|
+
*/
|
|
5
|
+
import { GGWebSocketSchema } from "../schema/GGWebSocketSchema.js";
|
|
6
|
+
import { GGSocketServer } from "./GGSocketServer.js";
|
|
7
|
+
import { GGLocator } from "@grest-ts/locator";
|
|
8
|
+
import { GG_HTTP_SERVER } from "@grest-ts/http";
|
|
9
|
+
GGWebSocketSchema.prototype.startServer = function (onConnection, config) {
|
|
10
|
+
const contract = this.contract;
|
|
11
|
+
if (!contract) {
|
|
12
|
+
throw new Error(`WebSocketSchema "${this.name}" has no contract.`);
|
|
13
|
+
}
|
|
14
|
+
const normalizedPath = this.path.startsWith('/') ? this.path : '/' + this.path;
|
|
15
|
+
const schemaName = this.name;
|
|
16
|
+
const http = config.http ?? GGLocator.getScope().get(GG_HTTP_SERVER);
|
|
17
|
+
// @TODO We might want some lookup here based on path/middlewares etc. If I use same socket for multiple paths, we need to reuse also same GGSocketServer.
|
|
18
|
+
const socketServer = new GGSocketServer(http, {
|
|
19
|
+
apiName: schemaName,
|
|
20
|
+
path: normalizedPath,
|
|
21
|
+
middlewares: [...this.middlewares, ...(config?.middlewares ?? [])]
|
|
22
|
+
});
|
|
23
|
+
socketServer.onConnection((socket) => {
|
|
24
|
+
const clientToServerContract = contract.clientToServer;
|
|
25
|
+
const serverToClientContract = contract.serverToClient;
|
|
26
|
+
const incoming = {
|
|
27
|
+
on(handlers) {
|
|
28
|
+
const impl = {};
|
|
29
|
+
for (const methodName of Object.keys(clientToServerContract.methods)) {
|
|
30
|
+
const methodDef = clientToServerContract.methods[methodName];
|
|
31
|
+
const params = methodDef.params;
|
|
32
|
+
impl[methodName] = (data) => {
|
|
33
|
+
// If method has params info, unpack data object to positional args
|
|
34
|
+
if (params && params.length > 0 && data && typeof data === 'object') {
|
|
35
|
+
const args = params.map((p) => data[p.name]);
|
|
36
|
+
return handlers[methodName](...args);
|
|
37
|
+
}
|
|
38
|
+
// Single or no parameter - pass directly
|
|
39
|
+
return handlers[methodName](data);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const incomingInstance = clientToServerContract.implement(impl);
|
|
43
|
+
for (const methodName of Object.keys(clientToServerContract.methods)) {
|
|
44
|
+
socket.registerHandler({
|
|
45
|
+
path: `${schemaName}.${methodName}`,
|
|
46
|
+
handler: incomingInstance[methodName]
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const impl = {};
|
|
52
|
+
for (const methodName of Object.keys(serverToClientContract.methods)) {
|
|
53
|
+
const method = serverToClientContract.methods[methodName];
|
|
54
|
+
const expectsResponse = 'success' in method;
|
|
55
|
+
impl[methodName] = (data) => {
|
|
56
|
+
return socket.send(`${schemaName}.${methodName}`, data, expectsResponse);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const outgoingInstance = serverToClientContract.implement(impl);
|
|
60
|
+
outgoingInstance.onClose = (callback) => {
|
|
61
|
+
socket.onClose(callback);
|
|
62
|
+
};
|
|
63
|
+
onConnection(incoming, outgoingInstance);
|
|
64
|
+
});
|
|
65
|
+
return socketServer;
|
|
66
|
+
};
|
|
67
|
+
GGWebSocketSchema.prototype.register = function (onConnection, config) {
|
|
68
|
+
let httpServer = config?.http;
|
|
69
|
+
if (!httpServer) {
|
|
70
|
+
httpServer = GGLocator.getScope().get(GG_HTTP_SERVER);
|
|
71
|
+
}
|
|
72
|
+
if (!httpServer) {
|
|
73
|
+
throw new Error(`No HTTP server found. Make sure to register GGHttpServerAdapter in the scope or pass it via config`);
|
|
74
|
+
}
|
|
75
|
+
this.startServer(onConnection, {
|
|
76
|
+
http: httpServer,
|
|
77
|
+
middlewares: config?.middlewares
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=GGWebSocketSchema.startServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGWebSocketSchema.startServer.js","sourceRoot":"","sources":["../../../src/server/GGWebSocketSchema.startServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
declare const IsWsConnectionContext: import("@grest-ts/schema").ObjectSchema<{
|
|
3
|
+
path: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
}>;
|
|
6
|
+
export type WsConnectionContext = typeof IsWsConnectionContext.infer;
|
|
7
|
+
export declare const GG_WS_CONNECTION: GGContextKey<{
|
|
8
|
+
path: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
}>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=GG_WS_CONNECTION.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GG_WS_CONNECTION.d.ts","sourceRoot":"","sources":["../../../src/server/GG_WS_CONNECTION.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAG/C,QAAA,MAAM,qBAAqB;;;EAGzB,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,qBAAqB,CAAC,KAAK,CAAC;AAErE,eAAO,MAAM,gBAAgB;;;EAAgF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
import { IsNumber, IsObject, IsString } from "@grest-ts/schema";
|
|
3
|
+
const IsWsConnectionContext = IsObject({
|
|
4
|
+
port: IsNumber.orUndefined,
|
|
5
|
+
path: IsString
|
|
6
|
+
});
|
|
7
|
+
export const GG_WS_CONNECTION = new GGContextKey('ws-connection', IsWsConnectionContext);
|
|
8
|
+
//# sourceMappingURL=GG_WS_CONNECTION.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GG_WS_CONNECTION.js","sourceRoot":"","sources":["../../../src/server/GG_WS_CONNECTION.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAE9D,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IACnC,IAAI,EAAE,QAAQ,CAAC,WAAW;IAC1B,IAAI,EAAE,QAAQ;CACjB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,YAAY,CAAsB,eAAe,EAAE,qBAAqB,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
declare const IsWsMessageContext: import("@grest-ts/schema").ObjectSchema<{
|
|
3
|
+
path: string;
|
|
4
|
+
}>;
|
|
5
|
+
export type WsMessageContext = typeof IsWsMessageContext.infer;
|
|
6
|
+
export declare const GG_WS_MESSAGE: GGContextKey<{
|
|
7
|
+
path: string;
|
|
8
|
+
}>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=GG_WS_MESSAGE.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GG_WS_MESSAGE.d.ts","sourceRoot":"","sources":["../../../src/server/GG_WS_MESSAGE.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAG/C,QAAA,MAAM,kBAAkB;;EAEtB,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,KAAK,CAAC;AAE/D,eAAO,MAAM,aAAa;;EAAuE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
import { IsObject, IsString } from "@grest-ts/schema";
|
|
3
|
+
const IsWsMessageContext = IsObject({
|
|
4
|
+
path: IsString
|
|
5
|
+
});
|
|
6
|
+
export const GG_WS_MESSAGE = new GGContextKey('ws-message', IsWsMessageContext);
|
|
7
|
+
//# sourceMappingURL=GG_WS_MESSAGE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GG_WS_MESSAGE.js","sourceRoot":"","sources":["../../../src/server/GG_WS_MESSAGE.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAEpD,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAChC,IAAI,EAAE,QAAQ;CACjB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,YAAY,CAAmB,YAAY,EAAE,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified WebSocket implementation for both client and server
|
|
3
|
+
* Handles messaging only - context is set from effects at connection time
|
|
4
|
+
*/
|
|
5
|
+
import { SocketAdapter } from "./SocketAdapter";
|
|
6
|
+
import { GGPromise } from "@grest-ts/schema";
|
|
7
|
+
import { GGContext } from "@grest-ts/context";
|
|
8
|
+
/**
|
|
9
|
+
* Handler configuration for socket messages.
|
|
10
|
+
* Handler is expected to be already wrapped with contract validation.
|
|
11
|
+
*/
|
|
12
|
+
export interface SocketHandlerConfig {
|
|
13
|
+
path: string;
|
|
14
|
+
handler: (data?: any) => GGPromise<any, any> | Promise<any> | void;
|
|
15
|
+
}
|
|
16
|
+
export interface GGSocketConfig {
|
|
17
|
+
apiName?: string;
|
|
18
|
+
socketPath?: string;
|
|
19
|
+
/** Optional wrapper that runs handlers in the context established at connection time */
|
|
20
|
+
connectionContext?: GGContext;
|
|
21
|
+
}
|
|
22
|
+
export declare class GGSocket {
|
|
23
|
+
private readonly socket;
|
|
24
|
+
private readonly handlers;
|
|
25
|
+
private readonly pendingRequests;
|
|
26
|
+
private unknownMessageHandler?;
|
|
27
|
+
private isActive;
|
|
28
|
+
private isCleanedUp;
|
|
29
|
+
private tearingDownPromise;
|
|
30
|
+
private readonly onTearDownCallbacks;
|
|
31
|
+
private readonly onCloseCallbacks;
|
|
32
|
+
private readonly onErrorCallbacks;
|
|
33
|
+
private readonly apiName;
|
|
34
|
+
private readonly socketPath;
|
|
35
|
+
private readonly connectionContext;
|
|
36
|
+
constructor(socket: SocketAdapter, config?: GGSocketConfig);
|
|
37
|
+
private handleIncomingMessage;
|
|
38
|
+
private handleMissingRoute;
|
|
39
|
+
private sendResponse;
|
|
40
|
+
private handleFireAndForgetResult;
|
|
41
|
+
/**
|
|
42
|
+
* Send a message over the socket (raw transport).
|
|
43
|
+
* Data is expected to be already validated by the contract layer.
|
|
44
|
+
*
|
|
45
|
+
* @param path - The message path/route
|
|
46
|
+
* @param body - The message data (already validated)
|
|
47
|
+
* @param expectsResponse - Whether to wait for a response
|
|
48
|
+
*/
|
|
49
|
+
send(path: string, body: any, expectsResponse: boolean): Promise<any>;
|
|
50
|
+
private recordInMetric;
|
|
51
|
+
private recordOutMetric;
|
|
52
|
+
registerHandler(config: SocketHandlerConfig): void;
|
|
53
|
+
unregisterHandler(path: string): void;
|
|
54
|
+
setUnknownMessageHandler(handler: (path: string, data: any) => void): void;
|
|
55
|
+
onError(onError: (error: Error) => void): this;
|
|
56
|
+
onTearDown(onClosing: () => Promise<void>): this;
|
|
57
|
+
onClose(onClose: () => void): this;
|
|
58
|
+
/**
|
|
59
|
+
* Get the number of pending outgoing requests
|
|
60
|
+
*/
|
|
61
|
+
get pendingRequestCount(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Starts the socket closing process gracefully.
|
|
64
|
+
* 1. First waits for pending outgoing requests to complete (up to pendingRequestsTimeoutMs)
|
|
65
|
+
* 2. Then runs user teardown handlers
|
|
66
|
+
* 3. Finally closes the socket
|
|
67
|
+
*
|
|
68
|
+
* @param pendingRequestsTimeoutMs - Max time to wait for pending requests (default: 5000ms)
|
|
69
|
+
* @param callbacksTimeoutMs - Max time to wait for teardown callbacks (default: 5000ms)
|
|
70
|
+
*/
|
|
71
|
+
teardown(pendingRequestsTimeoutMs?: number, callbacksTimeoutMs?: number): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Run all teardown callbacks concurrently with a timeout.
|
|
74
|
+
*/
|
|
75
|
+
private runTeardownCallbacks;
|
|
76
|
+
/**
|
|
77
|
+
* Immediately closes the socket.
|
|
78
|
+
*/
|
|
79
|
+
close(): void;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=GGSocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGSocket.d.ts","sourceRoot":"","sources":["../../../src/socket/GGSocket.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAK9C,OAAO,EAAQ,SAAS,EAAgC,MAAM,kBAAkB,CAAC;AAGjF,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAG5C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;CACtE;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,SAAS,CAAC;CACjC;AAQD,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;IACxE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAE5D,OAAO,CAAC,qBAAqB,CAAC,CAAoC;IAElE,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,kBAAkB,CAAgB;IAE1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkC;IACtE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyB;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;IAGtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAY;gBAElC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,cAAc;YA8D5C,qBAAqB;IA4BnC,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,yBAAyB;IAcjC;;;;;;;OAOG;IACU,IAAI,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,GAAG,EACT,eAAe,EAAE,OAAO,GACzB,OAAO,CAAC,GAAG,CAAC;IA2Bf,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,eAAe;IAahB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAIlD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrC,wBAAwB,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAQ1E,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAK9C,UAAU,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAKhD,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IASzC;;OAEG;IACH,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IAED;;;;;;;;OAQG;IACU,QAAQ,CAAC,wBAAwB,GAAE,MAAa,EAAE,kBAAkB,GAAE,MAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhH;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiC5B;;OAEG;IACI,KAAK,IAAI,IAAI;CAWvB"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified WebSocket implementation for both client and server
|
|
3
|
+
* Handles messaging only - context is set from effects at connection time
|
|
4
|
+
*/
|
|
5
|
+
import { Message, MessageType } from "./SocketMessage.js";
|
|
6
|
+
import { PendingRequestsMap } from "./utils/PendingRequestsMap.js";
|
|
7
|
+
import { GG_WS_MESSAGE } from "../server/GG_WS_MESSAGE.js";
|
|
8
|
+
import { GGWebSocketMetrics } from "../server/GGWebSocketMetrics.js";
|
|
9
|
+
import { GGLog } from "@grest-ts/logger";
|
|
10
|
+
import { ERROR, ROUTE_NOT_FOUND, SERVER_ERROR } from "@grest-ts/schema";
|
|
11
|
+
import { GG_METRICS } from "@grest-ts/metrics";
|
|
12
|
+
import { GGLocator } from "@grest-ts/locator";
|
|
13
|
+
import { GGContext } from "@grest-ts/context";
|
|
14
|
+
import { GG_TRACE } from "@grest-ts/trace";
|
|
15
|
+
export class GGSocket {
|
|
16
|
+
socket;
|
|
17
|
+
handlers = new Map();
|
|
18
|
+
pendingRequests = new PendingRequestsMap();
|
|
19
|
+
unknownMessageHandler;
|
|
20
|
+
isActive = true;
|
|
21
|
+
isCleanedUp = false;
|
|
22
|
+
tearingDownPromise;
|
|
23
|
+
onTearDownCallbacks = [];
|
|
24
|
+
onCloseCallbacks = [];
|
|
25
|
+
onErrorCallbacks = [];
|
|
26
|
+
// Metrics labels (optional - set when created by server)
|
|
27
|
+
apiName;
|
|
28
|
+
socketPath;
|
|
29
|
+
connectionContext;
|
|
30
|
+
constructor(socket, config) {
|
|
31
|
+
this.socket = socket;
|
|
32
|
+
this.apiName = config?.apiName ?? 'unknown';
|
|
33
|
+
this.socketPath = config?.socketPath ?? 'unknown';
|
|
34
|
+
// Default to passthrough if no context wrapper provided
|
|
35
|
+
this.connectionContext = config?.connectionContext ?? new GGContext('__unnamed_GGSocket_context');
|
|
36
|
+
// Capture contexts at construction - socket events lose AsyncLocalStorage context
|
|
37
|
+
const scope = GGLocator.getScope();
|
|
38
|
+
this.socket.onMessage(async (data) => {
|
|
39
|
+
scope.ensureEntered();
|
|
40
|
+
const context = new GGContext("ws-message", this.connectionContext);
|
|
41
|
+
await context.run(async () => {
|
|
42
|
+
GG_TRACE.init();
|
|
43
|
+
const msg = Message.parse(data);
|
|
44
|
+
if (!msg) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (this.isActive) {
|
|
48
|
+
if (msg.type === MessageType.MSG || msg.type === MessageType.REQ) {
|
|
49
|
+
GG_WS_MESSAGE.set({ path: msg.path });
|
|
50
|
+
await this.handleIncomingMessage(msg);
|
|
51
|
+
}
|
|
52
|
+
else if (msg.type === MessageType.RES) {
|
|
53
|
+
this.pendingRequests.resolve(msg.id, msg.data);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
this.socket.onClose(() => {
|
|
59
|
+
scope.ensureEntered();
|
|
60
|
+
this.connectionContext.run(() => {
|
|
61
|
+
this.isActive = false;
|
|
62
|
+
if (!this.isCleanedUp) {
|
|
63
|
+
this.isCleanedUp = true;
|
|
64
|
+
this.pendingRequests.rejectAll(new SERVER_ERROR({ displayMessage: "Socket connection closed!" }));
|
|
65
|
+
this.onCloseCallbacks.forEach((onClose) => {
|
|
66
|
+
try {
|
|
67
|
+
onClose?.();
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
this.onErrorCallbacks.forEach(cb => cb(e));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
this.socket.onError((error) => {
|
|
77
|
+
scope.ensureEntered();
|
|
78
|
+
this.connectionContext.run(() => {
|
|
79
|
+
this.onErrorCallbacks.forEach(cb => cb(error));
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// --------------------------------------------------------------------------------------
|
|
84
|
+
// Incoming message handling
|
|
85
|
+
// --------------------------------------------------------------------------------------
|
|
86
|
+
async handleIncomingMessage(msg) {
|
|
87
|
+
const startTime = performance.now();
|
|
88
|
+
const labels = { api: this.apiName, path: this.socketPath, method: msg.path };
|
|
89
|
+
const expectsResponse = msg.type === MessageType.REQ;
|
|
90
|
+
try {
|
|
91
|
+
const handlerDef = this.handlers.get(msg.path);
|
|
92
|
+
if (!handlerDef) {
|
|
93
|
+
this.handleMissingRoute(msg, labels, startTime, expectsResponse);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Handler returns GGPromise - use asResult() to get OK | ERROR
|
|
97
|
+
const ggPromise = handlerDef.handler(msg.data);
|
|
98
|
+
const res = await ggPromise.asResult();
|
|
99
|
+
if (expectsResponse) {
|
|
100
|
+
this.sendResponse(msg, res, labels, startTime);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.handleFireAndForgetResult(res, labels, startTime);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
GGLog.error(this, error);
|
|
108
|
+
this.onErrorCallbacks.forEach(cb => cb(error));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
handleMissingRoute(msg, labels, startTime, expectsResponse) {
|
|
112
|
+
if (expectsResponse) {
|
|
113
|
+
const error = new ROUTE_NOT_FOUND({ displayMessage: "Route not found: " + msg.path });
|
|
114
|
+
GGLog.error(this, error);
|
|
115
|
+
this.sendResponse(msg, error, labels, startTime);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
if (this.unknownMessageHandler) {
|
|
119
|
+
this.unknownMessageHandler(msg.path, msg.data);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
GGLog.warn(this, 'Unknown method ' + msg.path);
|
|
123
|
+
}
|
|
124
|
+
this.recordInMetric(labels, 'ROUTE_NOT_FOUND', startTime);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
sendResponse(msg, res, labels, startTime) {
|
|
128
|
+
const isError = res instanceof ERROR || (res && res.success === false);
|
|
129
|
+
const resultType = isError ? res.type : 'OK';
|
|
130
|
+
// res is OK_JSON or ERROR - send as-is (it's already in the right format)
|
|
131
|
+
const data = isError && res instanceof ERROR ? res.toJSON() : res;
|
|
132
|
+
this.recordInMetric(labels, resultType, startTime);
|
|
133
|
+
try {
|
|
134
|
+
this.socket.send(Message.create(MessageType.RES, msg.path, msg.id, data));
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
GGLog.error(this, "ERROR_SENDING_RESPONSE", ERROR.fromUnknown(error));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
handleFireAndForgetResult(res, labels, startTime) {
|
|
141
|
+
const isError = res instanceof ERROR || (res && res.success === false);
|
|
142
|
+
if (isError) {
|
|
143
|
+
this.recordInMetric(labels, res.type, startTime);
|
|
144
|
+
this.onErrorCallbacks.forEach(cb => cb(res));
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.recordInMetric(labels, 'OK', startTime);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// --------------------------------------------------------------------------------------
|
|
151
|
+
// Outgoing message handling
|
|
152
|
+
// --------------------------------------------------------------------------------------
|
|
153
|
+
/**
|
|
154
|
+
* Send a message over the socket (raw transport).
|
|
155
|
+
* Data is expected to be already validated by the contract layer.
|
|
156
|
+
*
|
|
157
|
+
* @param path - The message path/route
|
|
158
|
+
* @param body - The message data (already validated)
|
|
159
|
+
* @param expectsResponse - Whether to wait for a response
|
|
160
|
+
*/
|
|
161
|
+
async send(path, body, expectsResponse) {
|
|
162
|
+
const labels = { api: this.apiName, path: this.socketPath, method: path };
|
|
163
|
+
const startTime = performance.now();
|
|
164
|
+
if (!this.isActive) {
|
|
165
|
+
this.recordOutMetric(labels, 'CONNECTION_CLOSED');
|
|
166
|
+
throw new Error('Cannot send: WebSocket is not connected');
|
|
167
|
+
}
|
|
168
|
+
if (expectsResponse) {
|
|
169
|
+
return this.pendingRequests.create(path, 30000, async (id, waitForResponse) => {
|
|
170
|
+
this.socket.send(Message.create(MessageType.REQ, path, id, body));
|
|
171
|
+
const result = await waitForResponse;
|
|
172
|
+
const resultType = result?.success === true ? 'OK' : (result?.type ?? 'SERVER_ERROR');
|
|
173
|
+
this.recordOutMetric(labels, resultType, startTime);
|
|
174
|
+
return result;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
this.socket.send(Message.create(MessageType.MSG, path, "", body));
|
|
179
|
+
this.recordOutMetric(labels, 'OK');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// --------------------------------------------------------------------------------------
|
|
183
|
+
// Metrics helpers
|
|
184
|
+
// --------------------------------------------------------------------------------------
|
|
185
|
+
recordInMetric(labels, result, startTime) {
|
|
186
|
+
if (GG_METRICS.has()) {
|
|
187
|
+
GGWebSocketMetrics.requests.inc(1, { ...labels, result });
|
|
188
|
+
if (startTime !== undefined) {
|
|
189
|
+
GGWebSocketMetrics.requestDuration.observe(performance.now() - startTime, labels);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
recordOutMetric(labels, result, startTime) {
|
|
194
|
+
if (GG_METRICS.has()) {
|
|
195
|
+
GGWebSocketMetrics.outRequests.inc(1, { ...labels, result });
|
|
196
|
+
if (startTime !== undefined) {
|
|
197
|
+
GGWebSocketMetrics.outRequestDuration.observe(performance.now() - startTime, labels);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// --------------------------------------------------------------------------------------
|
|
202
|
+
// Handler registration
|
|
203
|
+
// --------------------------------------------------------------------------------------
|
|
204
|
+
registerHandler(config) {
|
|
205
|
+
this.handlers.set(config.path, config);
|
|
206
|
+
}
|
|
207
|
+
unregisterHandler(path) {
|
|
208
|
+
this.handlers.delete(path);
|
|
209
|
+
}
|
|
210
|
+
setUnknownMessageHandler(handler) {
|
|
211
|
+
this.unknownMessageHandler = handler;
|
|
212
|
+
}
|
|
213
|
+
// --------------------------------------------------------------------------------------
|
|
214
|
+
// Lifecycle callbacks
|
|
215
|
+
// --------------------------------------------------------------------------------------
|
|
216
|
+
onError(onError) {
|
|
217
|
+
this.onErrorCallbacks.push(onError);
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
onTearDown(onClosing) {
|
|
221
|
+
this.onTearDownCallbacks.push(onClosing);
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
onClose(onClose) {
|
|
225
|
+
this.onCloseCallbacks.push(onClose);
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
// --------------------------------------------------------------------------------------
|
|
229
|
+
// Teardown
|
|
230
|
+
// --------------------------------------------------------------------------------------
|
|
231
|
+
/**
|
|
232
|
+
* Get the number of pending outgoing requests
|
|
233
|
+
*/
|
|
234
|
+
get pendingRequestCount() {
|
|
235
|
+
return this.pendingRequests.size;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Starts the socket closing process gracefully.
|
|
239
|
+
* 1. First waits for pending outgoing requests to complete (up to pendingRequestsTimeoutMs)
|
|
240
|
+
* 2. Then runs user teardown handlers
|
|
241
|
+
* 3. Finally closes the socket
|
|
242
|
+
*
|
|
243
|
+
* @param pendingRequestsTimeoutMs - Max time to wait for pending requests (default: 5000ms)
|
|
244
|
+
* @param callbacksTimeoutMs - Max time to wait for teardown callbacks (default: 5000ms)
|
|
245
|
+
*/
|
|
246
|
+
async teardown(pendingRequestsTimeoutMs = 5000, callbacksTimeoutMs = 5000) {
|
|
247
|
+
if (this.tearingDownPromise) {
|
|
248
|
+
GGLog.warn(this, 'Already tearing down!');
|
|
249
|
+
return this.tearingDownPromise;
|
|
250
|
+
}
|
|
251
|
+
GGLog.debug(this, 'Teardown started');
|
|
252
|
+
this.tearingDownPromise = (async () => {
|
|
253
|
+
// Step 1: Wait for pending outgoing requests to complete
|
|
254
|
+
if (this.pendingRequests.hasPending()) {
|
|
255
|
+
GGLog.debug(this, `Waiting for ${this.pendingRequests.size} pending request(s) to complete...`);
|
|
256
|
+
await this.pendingRequests.waitForPending(pendingRequestsTimeoutMs);
|
|
257
|
+
if (this.pendingRequests.hasPending()) {
|
|
258
|
+
GGLog.warn(this, `Timeout waiting for pending requests, ${this.pendingRequests.size} request(s) still pending`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Step 2: Run user teardown callbacks with timeout
|
|
262
|
+
await this.runTeardownCallbacks(callbacksTimeoutMs);
|
|
263
|
+
// Step 3: Close the socket
|
|
264
|
+
this.close();
|
|
265
|
+
})();
|
|
266
|
+
return this.tearingDownPromise;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Run all teardown callbacks concurrently with a timeout.
|
|
270
|
+
*/
|
|
271
|
+
runTeardownCallbacks(timeoutMs) {
|
|
272
|
+
if (this.onTearDownCallbacks.length === 0) {
|
|
273
|
+
return Promise.resolve();
|
|
274
|
+
}
|
|
275
|
+
return new Promise((resolve) => {
|
|
276
|
+
let remaining = this.onTearDownCallbacks.length;
|
|
277
|
+
let resolved = false;
|
|
278
|
+
const finish = () => {
|
|
279
|
+
if (!resolved) {
|
|
280
|
+
resolved = true;
|
|
281
|
+
clearTimeout(timeout);
|
|
282
|
+
resolve();
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const timeout = setTimeout(() => {
|
|
286
|
+
GGLog.warn(this, `Teardown timeout - ${remaining} callback(s) still pending after ${timeoutMs}ms`);
|
|
287
|
+
finish();
|
|
288
|
+
}, timeoutMs);
|
|
289
|
+
for (const callback of this.onTearDownCallbacks) {
|
|
290
|
+
callback()
|
|
291
|
+
.catch((err) => GGLog.error(this, 'Error in teardown callback', err))
|
|
292
|
+
.finally(() => {
|
|
293
|
+
remaining--;
|
|
294
|
+
if (remaining === 0)
|
|
295
|
+
finish();
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Immediately closes the socket.
|
|
302
|
+
*/
|
|
303
|
+
close() {
|
|
304
|
+
if (this.isActive) {
|
|
305
|
+
this.isActive = false;
|
|
306
|
+
try {
|
|
307
|
+
this.socket.close();
|
|
308
|
+
}
|
|
309
|
+
catch (e) {
|
|
310
|
+
// Ignore close errors
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=GGSocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGSocket.js","sourceRoot":"","sources":["../../../src/socket/GGSocket.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,OAAO,EAAE,WAAW,EAAiC,MAAM,iBAAiB,CAAC;AAErF,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAC,KAAK,EAAa,eAAe,EAAE,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAwBzC,MAAM,OAAO,QAAQ;IAEA,MAAM,CAAgB;IACtB,QAAQ,GAAqC,IAAI,GAAG,EAAE,CAAC;IACvD,eAAe,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAEpD,qBAAqB,CAAqC;IAE1D,QAAQ,GAAG,IAAI,CAAC;IAChB,WAAW,GAAG,KAAK,CAAC;IACpB,kBAAkB,CAAgB;IAEzB,mBAAmB,GAA+B,EAAE,CAAC;IACrD,gBAAgB,GAAsB,EAAE,CAAC;IACzC,gBAAgB,GAAkC,EAAE,CAAC;IAEtE,yDAAyD;IACxC,OAAO,CAAS;IAChB,UAAU,CAAS;IACnB,iBAAiB,CAAY;IAE9C,YAAY,MAAqB,EAAE,MAAuB;QACtD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,SAAS,CAAC;QAC5C,IAAI,CAAC,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,SAAS,CAAC;QAClD,wDAAwD;QACxD,IAAI,CAAC,iBAAiB,GAAG,MAAM,EAAE,iBAAiB,IAAI,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAElG,kFAAkF;QAClF,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;YACzC,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpE,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;gBACzB,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAEhB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,GAAG,EAAE,CAAC;oBACP,OAAO;gBACX,CAAC;gBAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChB,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,GAAG,EAAE,CAAC;wBAC/D,aAAa,CAAC,GAAG,CAAC,EAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAC,CAAC,CAAC;wBACpC,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBAC1C,CAAC;yBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,GAAG,EAAE,CAAC;wBACtC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBACnD,CAAC;gBACL,CAAC;YACL,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YACrB,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;oBACxB,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,EAAC,cAAc,EAAE,2BAA2B,EAAC,CAAC,CAAC,CAAC;oBAChG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;wBACtC,IAAI,CAAC;4BACD,OAAO,EAAE,EAAE,CAAC;wBAChB,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACT,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC/C,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAY,EAAE,EAAE;YACjC,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,yFAAyF;IACzF,4BAA4B;IAC5B,yFAAyF;IAEjF,KAAK,CAAC,qBAAqB,CAAC,GAAoC;QACpE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,MAAM,GAAiB,EAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAC,CAAC;QAC1F,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,GAAG,CAAC;QAErD,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE/C,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;gBACjE,OAAO;YACX,CAAC;YAED,+DAA+D;YAC/D,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,MAAO,SAAiB,CAAC,QAAQ,EAAE,CAAC;YAEhD,IAAI,eAAe,EAAE,CAAC;gBAClB,IAAI,CAAC,YAAY,CAAC,GAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAc,CAAC,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;IAEO,kBAAkB,CACtB,GAAoC,EACpC,MAAoB,EACpB,SAAiB,EACjB,eAAwB;QAExB,IAAI,eAAe,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAC,cAAc,EAAE,mBAAmB,GAAG,GAAG,CAAC,IAAI,EAAC,CAAC,CAAC;YACpF,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,GAAqB,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACJ,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC7B,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IAEO,YAAY,CAChB,GAAmB,EACnB,GAAQ,EACR,MAAoB,EACpB,SAAiB;QAEjB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,0EAA0E;QAC1E,MAAM,IAAI,GAAG,OAAO,IAAI,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAElE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAEnD,IAAI,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,wBAAwB,EAAE,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1E,CAAC;IACL,CAAC;IAEO,yBAAyB,CAAC,GAAQ,EAAE,MAAoB,EAAE,SAAiB;QAC/E,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC;QACvE,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACjD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACjD,CAAC;IACL,CAAC;IAED,yFAAyF;IACzF,4BAA4B;IAC5B,yFAAyF;IAEzF;;;;;;;OAOG;IACI,KAAK,CAAC,IAAI,CACb,IAAY,EACZ,IAAS,EACT,eAAwB;QAExB,MAAM,MAAM,GAAiB,EAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC;QACtF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAEpC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC/D,CAAC;QAED,IAAI,eAAe,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE;gBAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;gBAClE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;gBACrC,MAAM,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,cAAc,CAAC,CAAC;gBACtF,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACpD,OAAO,MAAM,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YAClE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;IAED,yFAAyF;IACzF,kBAAkB;IAClB,yFAAyF;IAEjF,cAAc,CAAC,MAAoB,EAAE,MAAc,EAAE,SAAkB;QAC3E,IAAI,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC;YACnB,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAC,GAAG,MAAM,EAAE,MAAM,EAAC,CAAC,CAAC;YACxD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1B,kBAAkB,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC;YACtF,CAAC;QACL,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,MAAoB,EAAE,MAAc,EAAE,SAAkB;QAC5E,IAAI,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC;YACnB,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAC,GAAG,MAAM,EAAE,MAAM,EAAC,CAAC,CAAC;YAC3D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1B,kBAAkB,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC;YACzF,CAAC;QACL,CAAC;IACL,CAAC;IAED,yFAAyF;IACzF,uBAAuB;IACvB,yFAAyF;IAElF,eAAe,CAAC,MAA2B;QAC9C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEM,iBAAiB,CAAC,IAAY;QACjC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAEM,wBAAwB,CAAC,OAA0C;QACtE,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,yFAAyF;IACzF,sBAAsB;IACtB,yFAAyF;IAElF,OAAO,CAAC,OAA+B;QAC1C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,UAAU,CAAC,SAA8B;QAC5C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,OAAO,CAAC,OAAmB;QAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,yFAAyF;IACzF,WAAW;IACX,yFAAyF;IAEzF;;OAEG;IACH,IAAW,mBAAmB;QAC1B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;IACrC,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,QAAQ,CAAC,2BAAmC,IAAI,EAAE,qBAA6B,IAAI;QAC5F,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACnC,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QAEtC,IAAI,CAAC,kBAAkB,GAAG,CAAC,KAAK,IAAI,EAAE;YAClC,yDAAyD;YACzD,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC;gBACpC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,IAAI,CAAC,eAAe,CAAC,IAAI,oCAAoC,CAAC,CAAC;gBAChG,MAAM,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC;gBACpE,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC;oBACpC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,yCAAyC,IAAI,CAAC,eAAe,CAAC,IAAI,2BAA2B,CAAC,CAAC;gBACpH,CAAC;YACL,CAAC;YAED,mDAAmD;YACnD,MAAM,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;YAEpD,2BAA2B;YAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,SAAiB;QAC1C,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACjC,IAAI,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;YAChD,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,MAAM,MAAM,GAAG,GAAG,EAAE;gBAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACZ,QAAQ,GAAG,IAAI,CAAC;oBAChB,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,OAAO,EAAE,CAAC;gBACd,CAAC;YACL,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,SAAS,oCAAoC,SAAS,IAAI,CAAC,CAAC;gBACnG,MAAM,EAAE,CAAC;YACb,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC9C,QAAQ,EAAE;qBACL,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,4BAA4B,EAAE,GAAG,CAAC,CAAC;qBACpE,OAAO,CAAC,GAAG,EAAE;oBACV,SAAS,EAAE,CAAC;oBACZ,IAAI,SAAS,KAAK,CAAC;wBAAE,MAAM,EAAE,CAAC;gBAClC,CAAC,CAAC,CAAC;YACX,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,KAAK;QACR,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,sBAAsB;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;CAEJ"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SocketAdapter {
|
|
2
|
+
send(message: string): void;
|
|
3
|
+
close(): void;
|
|
4
|
+
onOpen(handler: () => void): void;
|
|
5
|
+
onMessage(handler: (data: string) => void): void;
|
|
6
|
+
onClose(handler: () => void): void;
|
|
7
|
+
onError(handler: (error: Error) => void): void;
|
|
8
|
+
offOpen(handler: () => void): void;
|
|
9
|
+
offMessage(handler: (data: string) => void): void;
|
|
10
|
+
offClose(handler: () => void): void;
|
|
11
|
+
offError(handler: (error: Error) => void): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=SocketAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocketAdapter.d.ts","sourceRoot":"","sources":["../../../src/socket/SocketAdapter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,KAAK,IAAI,IAAI,CAAC;IAEd,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAElC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAEjD,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEnC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAE/C,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEnC,UAAU,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAElD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEpC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CACnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocketAdapter.js","sourceRoot":"","sources":["../../../src/socket/SocketAdapter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { tPendingMessageId } from "./utils/PendingRequestsMap";
|
|
2
|
+
import { OK_JSON } from "@grest-ts/schema";
|
|
3
|
+
export declare const DELIMITER = ":";
|
|
4
|
+
export declare enum MessageType {
|
|
5
|
+
HANDSHAKE = "h",// Handshake request (client -> server with headers)
|
|
6
|
+
HANDSHAKE_OK = "k",// Handshake success (server -> client)
|
|
7
|
+
HANDSHAKE_ERR = "x",// Handshake error (server -> client)
|
|
8
|
+
MSG = "m",// Regular message (send-and-forget)
|
|
9
|
+
REQ = "r",// Request (expects response)
|
|
10
|
+
RES = "s"
|
|
11
|
+
}
|
|
12
|
+
export interface SocketMessage {
|
|
13
|
+
type: MessageType;
|
|
14
|
+
path: string;
|
|
15
|
+
data?: any;
|
|
16
|
+
}
|
|
17
|
+
export interface HandshakeMessage extends SocketMessage {
|
|
18
|
+
type: MessageType.HANDSHAKE;
|
|
19
|
+
data: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
export interface HandshakeOkMessage extends SocketMessage {
|
|
22
|
+
type: MessageType.HANDSHAKE_OK;
|
|
23
|
+
}
|
|
24
|
+
export interface HandshakeErrMessage extends SocketMessage {
|
|
25
|
+
type: MessageType.HANDSHAKE_ERR;
|
|
26
|
+
data: any;
|
|
27
|
+
}
|
|
28
|
+
export interface RegularMessage extends SocketMessage {
|
|
29
|
+
type: MessageType.MSG;
|
|
30
|
+
data?: any;
|
|
31
|
+
}
|
|
32
|
+
export interface RequestMessage extends SocketMessage {
|
|
33
|
+
type: MessageType.REQ;
|
|
34
|
+
id: tPendingMessageId;
|
|
35
|
+
data?: any;
|
|
36
|
+
}
|
|
37
|
+
export interface ResponseMessage extends SocketMessage {
|
|
38
|
+
type: MessageType.RES;
|
|
39
|
+
id: tPendingMessageId;
|
|
40
|
+
data: OK_JSON<any>;
|
|
41
|
+
}
|
|
42
|
+
export type AnyMessage = HandshakeMessage | HandshakeOkMessage | HandshakeErrMessage | RegularMessage | RequestMessage | ResponseMessage;
|
|
43
|
+
export declare class Message {
|
|
44
|
+
static create(type: MessageType, path: string, id: tPendingMessageId | "", data: any): string;
|
|
45
|
+
static parse(msg: unknown): AnyMessage | undefined;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=SocketMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SocketMessage.d.ts","sourceRoot":"","sources":["../../../src/socket/SocketMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAEzC,eAAO,MAAM,SAAS,MAAM,CAAA;AAG5B,oBAAY,WAAW;IACnB,SAAS,MAAM,CAAI,oDAAoD;IACvE,YAAY,MAAM,CAAE,uCAAuC;IAC3D,aAAa,MAAM,CAAE,qCAAqC;IAC1D,GAAG,MAAM,CAAU,oCAAoC;IACvD,GAAG,MAAM,CAAU,6BAA6B;IAChD,GAAG,MAAM;CACZ;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACnD,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACrD,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC;CAClC;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACtD,IAAI,EAAE,WAAW,CAAC,aAAa,CAAC;IAChC,IAAI,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACjD,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;IACtB,IAAI,CAAC,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACjD,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;IACtB,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,CAAC,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IAClD,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;IACtB,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,mBAAmB,GAAG,cAAc,GAAG,cAAc,GAAG,eAAe,CAAC;AAEzI,qBAAa,OAAO;WAEF,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,iBAAiB,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM;WAKtF,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS;CAmC5D"}
|