@feng3d/cts 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,9 @@
6
6
 
7
7
  ## 特性
8
8
 
9
- - WebSocket 控制通道
9
+ - 三通道架构:WebSocket 控制通道 + TCP 二进制数据通道 + UDP 数据通道
10
+ - **每个代理端口同时支持 HTTP/WebSocket/TCP/UDP 四种协议**,自动识别协议类型
11
+ - 控制端口复用:同一端口处理 WebSocket 控制连接、TCP 数据通道和 UDP 数据通道
10
12
  - 动态端口分配
11
13
  - 自动心跳检测
12
14
  - 多客户端支持
@@ -140,10 +142,17 @@ npx @feng3d/cts start -t "client1-token,client2-token,client3-token"
140
142
  ## 架构
141
143
 
142
144
  ```
143
- 公网用户请求 -> 服务端监听端口 -> WebSocket 控制通道 -> 内网客户端 -> 本地服务
145
+ 控制端口(复用):
146
+ ├─ WebSocket 控制通道 ── JSON 消息(认证/注册/心跳/连接通知)
147
+ ├─ TCP 数据通道 ─────── 二进制帧(HTTP/WS/TCP 数据转发)
148
+ └─ UDP 数据通道 ─────── UDP 数据帧(UDP 数据转发)
149
+
150
+ 代理端口(每端口同时监听 TCP + UDP):
151
+ ├─ TCP 服务器 → 自动识别 HTTP/WebSocket/TCP 协议
152
+ └─ UDP 服务器 → 转发 UDP 数据
144
153
  ```
145
154
 
146
- **每个代理端口同时支持 HTTPWebSocket 协议**,客户端无需指定协议类型。
155
+ **每个代理端口同时支持 HTTP/WebSocket/TCP/UDP 四种协议**,客户端无需指定协议类型。
147
156
 
148
157
  ## 许可证
149
158
 
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @module data-channel
3
+ *
4
+ * 服务端数据通道管理器。
5
+ *
6
+ * 管理穿透客户端的 TCP 数据通道和 UDP 数据通道连接。
7
+ * TCP 数据通道用于高效传输 HTTP/WS/TCP 的原始二进制数据,
8
+ * UDP 数据通道用于保留 UDP 语义的数据转发。
9
+ */
10
+ import { Socket } from 'net';
11
+ import { Socket as UdpSocket, RemoteInfo } from 'dgram';
12
+ import { EventEmitter } from 'events';
13
+ import { SessionManager } from './session-manager.js';
14
+ /**
15
+ * 服务端数据通道管理器
16
+ *
17
+ * 管理所有客户端的 TCP 二进制数据通道和 UDP 数据通道。
18
+ *
19
+ * 事件:
20
+ * - `'data'(clientId, connectionId, data)` — 收到客户端 TCP 数据帧
21
+ * - `'udpData'(clientId, connectionId, data)` — 收到客户端 UDP 数据帧
22
+ */
23
+ export declare class DataChannelManager extends EventEmitter {
24
+ /** 客户端 TCP 数据通道:clientId → Socket */
25
+ private tcpChannels;
26
+ /** 客户端 TCP 帧解析器:clientId → FrameParser */
27
+ private frameParsers;
28
+ /** 客户端 UDP 地址:clientId → RemoteInfo */
29
+ private udpClients;
30
+ /** 服务端 UDP socket 引用 */
31
+ private udpSocket;
32
+ /** 会话管理器 */
33
+ private sessionManager;
34
+ constructor(sessionManager: SessionManager);
35
+ /**
36
+ * 设置 UDP socket 引用
37
+ */
38
+ setUdpSocket(socket: UdpSocket): void;
39
+ /**
40
+ * 处理新的 TCP 数据通道连接
41
+ *
42
+ * 解析认证帧,验证 clientId,建立关联。
43
+ *
44
+ * @param socket - 新的 TCP 连接
45
+ * @param initialData - 包含认证帧的初始数据
46
+ */
47
+ handleNewTcpConnection(socket: Socket, initialData: Buffer): void;
48
+ /**
49
+ * 处理 UDP 消息
50
+ *
51
+ * 区分控制帧(注册/保活)和数据帧。
52
+ *
53
+ * @param msg - 收到的 UDP 数据包
54
+ * @param rinfo - 发送方地址信息
55
+ */
56
+ handleUdpMessage(msg: Buffer, rinfo: RemoteInfo): void;
57
+ private handleUdpRegister;
58
+ /**
59
+ * 通过 TCP 数据通道发送数据帧给客户端
60
+ *
61
+ * @param clientId - 目标客户端 ID
62
+ * @param connectionId - 连接 ID
63
+ * @param data - 要发送的原始数据
64
+ * @returns 是否发送成功
65
+ */
66
+ sendToClient(clientId: string, connectionId: string, data: Buffer): boolean;
67
+ /**
68
+ * 通过 UDP 通道发送数据帧给客户端
69
+ *
70
+ * @param clientId - 目标客户端 ID
71
+ * @param connectionId - 连接 ID
72
+ * @param data - 要发送的原始数据
73
+ * @returns 是否发送成功
74
+ */
75
+ sendUdpToClient(clientId: string, connectionId: string, data: Buffer): boolean;
76
+ /**
77
+ * 检查客户端是否已建立 TCP 数据通道
78
+ */
79
+ hasDataChannel(clientId: string): boolean;
80
+ /**
81
+ * 检查客户端是否已注册 UDP 通道
82
+ */
83
+ hasUdpChannel(clientId: string): boolean;
84
+ /**
85
+ * 移除客户端的所有数据通道
86
+ */
87
+ removeClient(clientId: string): void;
88
+ /**
89
+ * 清理所有数据通道
90
+ */
91
+ clear(): void;
92
+ }
93
+ //# sourceMappingURL=data-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-channel.d.ts","sourceRoot":"","sources":["../src/data-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAWtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,qCAAqC;IACrC,OAAO,CAAC,WAAW,CAAkC;IACrD,0CAA0C;IAC1C,OAAO,CAAC,YAAY,CAAuC;IAC3D,uCAAuC;IACvC,OAAO,CAAC,UAAU,CAAsC;IACxD,wBAAwB;IACxB,OAAO,CAAC,SAAS,CAA0B;IAC3C,YAAY;IACZ,OAAO,CAAC,cAAc,CAAiB;gBAE3B,cAAc,EAAE,cAAc;IAK1C;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIrC;;;;;;;OAOG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAwDjE;;;;;;;OAOG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IA6BtD,OAAO,CAAC,iBAAiB;IAiBzB;;;;;;;OAOG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAS3E;;;;;;;OAOG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAU9E;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKzC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUpC;;OAEG;IACH,KAAK,IAAI,IAAI;CAQd"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * @module data-channel
3
+ *
4
+ * 服务端数据通道管理器。
5
+ *
6
+ * 管理穿透客户端的 TCP 数据通道和 UDP 数据通道连接。
7
+ * TCP 数据通道用于高效传输 HTTP/WS/TCP 的原始二进制数据,
8
+ * UDP 数据通道用于保留 UDP 语义的数据转发。
9
+ */
10
+ import { EventEmitter } from 'events';
11
+ import { parseTcpAuthFrame, parseUdpControlFrame, parseUdpDataFrame, writeDataFrame, writeUdpDataFrame, FrameParser, AUTH_RESPONSE, logger, } from '@feng3d/chuantou-shared';
12
+ /**
13
+ * 服务端数据通道管理器
14
+ *
15
+ * 管理所有客户端的 TCP 二进制数据通道和 UDP 数据通道。
16
+ *
17
+ * 事件:
18
+ * - `'data'(clientId, connectionId, data)` — 收到客户端 TCP 数据帧
19
+ * - `'udpData'(clientId, connectionId, data)` — 收到客户端 UDP 数据帧
20
+ */
21
+ export class DataChannelManager extends EventEmitter {
22
+ constructor(sessionManager) {
23
+ super();
24
+ /** 客户端 TCP 数据通道:clientId → Socket */
25
+ this.tcpChannels = new Map();
26
+ /** 客户端 TCP 帧解析器:clientId → FrameParser */
27
+ this.frameParsers = new Map();
28
+ /** 客户端 UDP 地址:clientId → RemoteInfo */
29
+ this.udpClients = new Map();
30
+ /** 服务端 UDP socket 引用 */
31
+ this.udpSocket = null;
32
+ this.sessionManager = sessionManager;
33
+ }
34
+ /**
35
+ * 设置 UDP socket 引用
36
+ */
37
+ setUdpSocket(socket) {
38
+ this.udpSocket = socket;
39
+ }
40
+ /**
41
+ * 处理新的 TCP 数据通道连接
42
+ *
43
+ * 解析认证帧,验证 clientId,建立关联。
44
+ *
45
+ * @param socket - 新的 TCP 连接
46
+ * @param initialData - 包含认证帧的初始数据
47
+ */
48
+ handleNewTcpConnection(socket, initialData) {
49
+ const clientId = parseTcpAuthFrame(initialData);
50
+ if (!clientId) {
51
+ logger.error('数据通道认证帧解析失败');
52
+ socket.write(AUTH_RESPONSE.FAILURE);
53
+ socket.destroy();
54
+ return;
55
+ }
56
+ // 验证 clientId 是否为已认证的客户端
57
+ const clientInfo = this.sessionManager.getClientInfo(clientId);
58
+ if (!clientInfo || !clientInfo.authenticated) {
59
+ logger.error(`数据通道认证失败: 客户端 ${clientId} 未认证`);
60
+ socket.write(AUTH_RESPONSE.FAILURE);
61
+ socket.destroy();
62
+ return;
63
+ }
64
+ // 关闭旧的数据通道(如果存在)
65
+ const oldSocket = this.tcpChannels.get(clientId);
66
+ if (oldSocket) {
67
+ oldSocket.destroy();
68
+ this.frameParsers.get(clientId)?.reset();
69
+ }
70
+ // 建立新的数据通道
71
+ socket.write(AUTH_RESPONSE.SUCCESS);
72
+ this.tcpChannels.set(clientId, socket);
73
+ const parser = new FrameParser();
74
+ this.frameParsers.set(clientId, parser);
75
+ parser.on('frame', (connectionId, data) => {
76
+ this.emit('data', clientId, connectionId, data);
77
+ });
78
+ socket.on('data', (chunk) => {
79
+ parser.push(chunk);
80
+ });
81
+ socket.on('close', () => {
82
+ logger.log(`客户端 ${clientId} 数据通道已关闭`);
83
+ this.tcpChannels.delete(clientId);
84
+ this.frameParsers.delete(clientId);
85
+ });
86
+ socket.on('error', (error) => {
87
+ logger.error(`客户端 ${clientId} 数据通道错误:`, error.message);
88
+ this.tcpChannels.delete(clientId);
89
+ this.frameParsers.delete(clientId);
90
+ });
91
+ logger.log(`客户端 ${clientId} 数据通道已建立`);
92
+ }
93
+ /**
94
+ * 处理 UDP 消息
95
+ *
96
+ * 区分控制帧(注册/保活)和数据帧。
97
+ *
98
+ * @param msg - 收到的 UDP 数据包
99
+ * @param rinfo - 发送方地址信息
100
+ */
101
+ handleUdpMessage(msg, rinfo) {
102
+ // 尝试解析为控制帧
103
+ const control = parseUdpControlFrame(msg);
104
+ if (control) {
105
+ if (control.type === 'register') {
106
+ this.handleUdpRegister(control.clientId, rinfo);
107
+ }
108
+ // keepalive 只需更新地址
109
+ if (control.type === 'keepalive') {
110
+ this.udpClients.set(control.clientId, rinfo);
111
+ }
112
+ return;
113
+ }
114
+ // 尝试解析为数据帧
115
+ const frame = parseUdpDataFrame(msg);
116
+ if (frame) {
117
+ // 查找此连接所属的客户端
118
+ // 通过遍历已注册的 UDP 客户端,匹配发送方地址
119
+ for (const [clientId, clientRinfo] of this.udpClients) {
120
+ if (clientRinfo.address === rinfo.address && clientRinfo.port === rinfo.port) {
121
+ this.emit('udpData', clientId, frame.connectionId, frame.data);
122
+ return;
123
+ }
124
+ }
125
+ logger.warn(`收到未知来源的 UDP 数据帧: ${rinfo.address}:${rinfo.port}`);
126
+ }
127
+ }
128
+ handleUdpRegister(clientId, rinfo) {
129
+ const clientInfo = this.sessionManager.getClientInfo(clientId);
130
+ if (!clientInfo || !clientInfo.authenticated) {
131
+ logger.error(`UDP 注册失败: 客户端 ${clientId} 未认证`);
132
+ return;
133
+ }
134
+ this.udpClients.set(clientId, rinfo);
135
+ // 发送确认
136
+ if (this.udpSocket) {
137
+ this.udpSocket.send(AUTH_RESPONSE.SUCCESS, rinfo.port, rinfo.address);
138
+ }
139
+ logger.log(`客户端 ${clientId} UDP 通道已注册 (${rinfo.address}:${rinfo.port})`);
140
+ }
141
+ /**
142
+ * 通过 TCP 数据通道发送数据帧给客户端
143
+ *
144
+ * @param clientId - 目标客户端 ID
145
+ * @param connectionId - 连接 ID
146
+ * @param data - 要发送的原始数据
147
+ * @returns 是否发送成功
148
+ */
149
+ sendToClient(clientId, connectionId, data) {
150
+ const socket = this.tcpChannels.get(clientId);
151
+ if (socket && !socket.destroyed) {
152
+ socket.write(writeDataFrame(connectionId, data));
153
+ return true;
154
+ }
155
+ return false;
156
+ }
157
+ /**
158
+ * 通过 UDP 通道发送数据帧给客户端
159
+ *
160
+ * @param clientId - 目标客户端 ID
161
+ * @param connectionId - 连接 ID
162
+ * @param data - 要发送的原始数据
163
+ * @returns 是否发送成功
164
+ */
165
+ sendUdpToClient(clientId, connectionId, data) {
166
+ const clientRinfo = this.udpClients.get(clientId);
167
+ if (clientRinfo && this.udpSocket) {
168
+ const frame = writeUdpDataFrame(connectionId, data);
169
+ this.udpSocket.send(frame, clientRinfo.port, clientRinfo.address);
170
+ return true;
171
+ }
172
+ return false;
173
+ }
174
+ /**
175
+ * 检查客户端是否已建立 TCP 数据通道
176
+ */
177
+ hasDataChannel(clientId) {
178
+ const socket = this.tcpChannels.get(clientId);
179
+ return !!socket && !socket.destroyed;
180
+ }
181
+ /**
182
+ * 检查客户端是否已注册 UDP 通道
183
+ */
184
+ hasUdpChannel(clientId) {
185
+ return this.udpClients.has(clientId);
186
+ }
187
+ /**
188
+ * 移除客户端的所有数据通道
189
+ */
190
+ removeClient(clientId) {
191
+ const socket = this.tcpChannels.get(clientId);
192
+ if (socket) {
193
+ socket.destroy();
194
+ this.tcpChannels.delete(clientId);
195
+ }
196
+ this.frameParsers.delete(clientId);
197
+ this.udpClients.delete(clientId);
198
+ }
199
+ /**
200
+ * 清理所有数据通道
201
+ */
202
+ clear() {
203
+ for (const socket of this.tcpChannels.values()) {
204
+ socket.destroy();
205
+ }
206
+ this.tcpChannels.clear();
207
+ this.frameParsers.clear();
208
+ this.udpClients.clear();
209
+ }
210
+ }
211
+ //# sourceMappingURL=data-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-channel.js","sourceRoot":"","sources":["../src/data-channel.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,11 @@
1
1
  /**
2
2
  * @module control-handler
3
- * @description 控制通道处理器模块,负责处理客户端通过 WebSocket 控制通道发送的各类控制消息。
4
- * 包括认证、端口注册/注销、心跳以及断开连接等消息的处理逻辑。
3
+ *
4
+ * 控制通道处理器模块。
5
+ *
6
+ * 负责处理客户端通过 WebSocket 控制通道发送的控制消息,
7
+ * 包括认证、端口注册/注销、心跳以及连接关闭等。
8
+ * 实际数据传输已移至独立的二进制数据通道。
5
9
  */
6
10
  import { WebSocket } from 'ws';
7
11
  import { ServerConfig } from '@feng3d/chuantou-shared';
@@ -10,149 +14,33 @@ import { UnifiedProxyHandler } from './unified-proxy.js';
10
14
  /**
11
15
  * 控制通道处理器
12
16
  *
13
- * 处理客户端通过 WebSocket 控制通道发送的各类控制消息,包括:
17
+ * 处理客户端通过 WebSocket 控制通道发送的控制消息:
14
18
  * - 客户端认证(AUTH)
15
19
  * - 端口注册(REGISTER)与注销(UNREGISTER)
16
20
  * - 心跳保活(HEARTBEAT)
17
- * - 连接断开的清理工作
21
+ * - 连接关闭(CONNECTION_CLOSE)
18
22
  */
19
23
  export declare class ControlHandler {
20
- /** 会话管理器实例 */
21
24
  private sessionManager;
22
- /** 服务器配置 */
23
25
  private config;
24
- /** 统一代理处理器(同时支持 HTTP 和 WebSocket) */
25
26
  private proxyHandler;
26
- /**
27
- * 创建控制通道处理器实例
28
- *
29
- * @param sessionManager - 会话管理器,用于管理客户端会话
30
- * @param config - 服务器配置,包含认证令牌等信息
31
- * @param proxyHandler - 统一代理处理器,用于启停代理服务器
32
- */
33
27
  constructor(sessionManager: SessionManager, config: ServerConfig, proxyHandler: UnifiedProxyHandler);
34
28
  /**
35
29
  * 处理新的 WebSocket 控制通道连接
36
- *
37
- * 为新连接创建会话,设置消息处理、关闭处理和错误处理回调,
38
- * 并启动 30 秒认证超时计时器。
39
- *
40
- * @param socket - 新建立的 WebSocket 连接
41
30
  */
42
31
  handleConnection(socket: WebSocket): void;
43
32
  /**
44
- * 处理收到的控制消息
33
+ * 处理控制消息
45
34
  *
46
- * 解析 JSON 消息并根据消息类型分发到对应的处理方法。
47
- * 支持的消息类型包括:AUTH、REGISTER、UNREGISTER、HEARTBEAT。
48
- *
49
- * @param clientId - 发送消息的客户端 ID
50
- * @param socket - 客户端的 WebSocket 连接
51
- * @param data - 收到的原始消息数据
35
+ * 仅处理控制消息,数据传输由独立的二进制数据通道处理。
52
36
  */
53
37
  private handleMessage;
54
- /**
55
- * 处理认证消息
56
- *
57
- * 验证客户端提供的令牌是否在配置的有效令牌列表中。
58
- * 认证成功后清除认证超时计时器;认证失败则关闭连接。
59
- *
60
- * @param clientId - 客户端唯一标识 ID
61
- * @param socket - 客户端的 WebSocket 连接
62
- * @param message - 收到的认证消息
63
- */
64
38
  private handleAuth;
65
- /**
66
- * 处理端口注册消息
67
- *
68
- * 验证客户端认证状态和端口范围(1024-65535),检查端口是否已被占用,
69
- * 然后注册端口并启动代理服务器(同时支持 HTTP 和 WebSocket)。
70
- * 若启动失败则自动回滚端口注册。
71
- *
72
- * @param clientId - 客户端唯一标识 ID
73
- * @param socket - 客户端的 WebSocket 连接
74
- * @param message - 收到的端口注册消息
75
- */
76
39
  private handleRegister;
77
- /**
78
- * 处理端口注销消息
79
- *
80
- * 验证客户端认证状态和端口归属,停止代理服务器并注销端口。
81
- *
82
- * @param clientId - 客户端唯一标识 ID
83
- * @param socket - 客户端的 WebSocket 连接
84
- * @param message - 收到的端口注销消息
85
- */
86
40
  private handleUnregister;
87
- /**
88
- * 处理心跳消息
89
- *
90
- * 更新客户端的最后心跳时间并回复心跳响应。
91
- *
92
- * @param clientId - 客户端唯一标识 ID
93
- * @param socket - 客户端的 WebSocket 连接
94
- * @param message - 收到的心跳消息
95
- */
96
41
  private handleHeartbeat;
97
- /**
98
- * 处理客户端断开连接
99
- *
100
- * 停止该客户端注册的所有代理服务器,并移除其会话。
101
- *
102
- * @param clientId - 断开连接的客户端唯一标识 ID
103
- */
104
42
  private handleDisconnect;
105
- /**
106
- * 通过 WebSocket 发送消息
107
- *
108
- * 将消息对象序列化为 JSON 字符串后发送,仅在连接处于 OPEN 状态时发送。
109
- *
110
- * @param socket - 目标 WebSocket 连接
111
- * @param message - 需要发送的消息对象
112
- */
113
43
  private sendMessage;
114
- /**
115
- * 发送错误消息
116
- *
117
- * 构造并发送一条 CONNECTION_ERROR 类型的错误消息给客户端。
118
- *
119
- * @param socket - 目标 WebSocket 连接
120
- * @param error - 错误描述信息
121
- */
122
44
  private sendError;
123
- /**
124
- * 处理客户端返回的 HTTP 响应数据
125
- *
126
- * @param connectionId - 连接唯一标识 ID
127
- * @param data - 客户端返回的 HTTP 响应数据
128
- */
129
- handleClientResponse(connectionId: string, data: any): void;
130
- /**
131
- * 处理来自客户端的 WebSocket 数据
132
- *
133
- * @param connectionId - 连接唯一标识 ID
134
- * @param data - 客户端发送的数据
135
- */
136
- handleClientData(connectionId: string, data: Buffer): void;
137
- /**
138
- * 处理来自客户端的连接关闭请求
139
- *
140
- * @param connectionId - 需要关闭的连接唯一标识 ID
141
- * @param code - 可选的关闭状态码
142
- */
143
- handleClientClose(connectionId: string, code?: number): void;
144
- /**
145
- * 处理来自客户端的流式响应数据
146
- *
147
- * @param connectionId - 连接唯一标识 ID
148
- * @param data - 客户端发送的流式数据
149
- */
150
- handleClientStreamData(connectionId: string, data: Buffer): void;
151
- /**
152
- * 处理来自客户端的流式响应结束通知
153
- *
154
- * @param connectionId - 连接唯一标识 ID
155
- */
156
- handleClientStreamEnd(connectionId: string): void;
157
45
  }
158
46
  //# sourceMappingURL=control-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/control-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAOL,YAAY,EAEb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,cAAc;IACd,OAAO,CAAC,cAAc,CAAiB;IACvC,YAAY;IACZ,OAAO,CAAC,MAAM,CAAe;IAC7B,qCAAqC;IACrC,OAAO,CAAC,YAAY,CAAsB;IAE1C;;;;;;OAMG;gBAED,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,mBAAmB;IAOnC;;;;;;;OAOG;IACH,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAqCzC;;;;;;;;;OASG;YACW,aAAa;IA4D3B;;;;;;;;;OASG;YACW,UAAU;IA2CxB;;;;;;;;;;OAUG;YACW,cAAc;IA+D5B;;;;;;;;OAQG;YACW,gBAAgB;IA2B9B;;;;;;;;OAQG;YACW,eAAe;IAO7B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAMnB;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;OAKG;IACH,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAI3D;;;;;OAKG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1D;;;;;OAKG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5D;;;;;OAKG;IACH,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhE;;;;OAIG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;CAGlD"}
1
+ {"version":3,"file":"control-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/control-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAOL,YAAY,EAEb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAsB;gBAGxC,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,mBAAmB;IAOnC;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAiCzC;;;;OAIG;YACW,aAAa;YAsCb,UAAU;YA2CV,cAAc;YA0Dd,gBAAgB;YAuBhB,eAAe;IAO7B,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,SAAS;CAMlB"}