@pixelhue/event-controller-sdk 0.0.1

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.
Files changed (62) hide show
  1. package/README.md +76 -0
  2. package/dist/index.d.ts +17 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +18 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/packages/tcp/ConnectManager.d.ts +66 -0
  7. package/dist/packages/tcp/ConnectManager.d.ts.map +1 -0
  8. package/dist/packages/tcp/ConnectManager.js +176 -0
  9. package/dist/packages/tcp/ConnectManager.js.map +1 -0
  10. package/dist/packages/tcp/QueueManager.d.ts +41 -0
  11. package/dist/packages/tcp/QueueManager.d.ts.map +1 -0
  12. package/dist/packages/tcp/QueueManager.js +102 -0
  13. package/dist/packages/tcp/QueueManager.js.map +1 -0
  14. package/dist/packages/tcp/SocketWrapper.d.ts +106 -0
  15. package/dist/packages/tcp/SocketWrapper.d.ts.map +1 -0
  16. package/dist/packages/tcp/SocketWrapper.js +281 -0
  17. package/dist/packages/tcp/SocketWrapper.js.map +1 -0
  18. package/dist/packages/tcp/constants.d.ts +25 -0
  19. package/dist/packages/tcp/constants.d.ts.map +1 -0
  20. package/dist/packages/tcp/constants.js +27 -0
  21. package/dist/packages/tcp/constants.js.map +1 -0
  22. package/dist/packages/tcp/demo.d.ts +3 -0
  23. package/dist/packages/tcp/demo.d.ts.map +1 -0
  24. package/dist/packages/tcp/demo.js +164 -0
  25. package/dist/packages/tcp/demo.js.map +1 -0
  26. package/dist/packages/tcp/discoveryService.d.ts +42 -0
  27. package/dist/packages/tcp/discoveryService.d.ts.map +1 -0
  28. package/dist/packages/tcp/discoveryService.js +166 -0
  29. package/dist/packages/tcp/discoveryService.js.map +1 -0
  30. package/dist/packages/tcp/protocolHandler.d.ts +64 -0
  31. package/dist/packages/tcp/protocolHandler.d.ts.map +1 -0
  32. package/dist/packages/tcp/protocolHandler.js +96 -0
  33. package/dist/packages/tcp/protocolHandler.js.map +1 -0
  34. package/dist/packages/tcp/tcpWrapper.d.ts +168 -0
  35. package/dist/packages/tcp/tcpWrapper.d.ts.map +1 -0
  36. package/dist/packages/tcp/tcpWrapper.js +472 -0
  37. package/dist/packages/tcp/tcpWrapper.js.map +1 -0
  38. package/dist/packages/tcp/test-build-parse-debug.d.ts +2 -0
  39. package/dist/packages/tcp/test-build-parse-debug.d.ts.map +1 -0
  40. package/dist/packages/tcp/test-build-parse-debug.js +73 -0
  41. package/dist/packages/tcp/test-build-parse-debug.js.map +1 -0
  42. package/dist/packages/tcp/test-packet-split.d.ts +43 -0
  43. package/dist/packages/tcp/test-packet-split.d.ts.map +1 -0
  44. package/dist/packages/tcp/test-packet-split.js +417 -0
  45. package/dist/packages/tcp/test-packet-split.js.map +1 -0
  46. package/dist/packages/tcp/test-protocol-handler.d.ts +6 -0
  47. package/dist/packages/tcp/test-protocol-handler.d.ts.map +1 -0
  48. package/dist/packages/tcp/test-protocol-handler.js +225 -0
  49. package/dist/packages/tcp/test-protocol-handler.js.map +1 -0
  50. package/dist/packages/tcp/test-server.d.ts +54 -0
  51. package/dist/packages/tcp/test-server.d.ts.map +1 -0
  52. package/dist/packages/tcp/test-server.js +412 -0
  53. package/dist/packages/tcp/test-server.js.map +1 -0
  54. package/dist/packages/tcp/types.d.ts +232 -0
  55. package/dist/packages/tcp/types.d.ts.map +1 -0
  56. package/dist/packages/tcp/types.js +13 -0
  57. package/dist/packages/tcp/types.js.map +1 -0
  58. package/dist/packages/tcp/utils.d.ts +14 -0
  59. package/dist/packages/tcp/utils.d.ts.map +1 -0
  60. package/dist/packages/tcp/utils.js +47 -0
  61. package/dist/packages/tcp/utils.js.map +1 -0
  62. package/package.json +82 -0
@@ -0,0 +1,232 @@
1
+ import { EventEmitter } from 'events';
2
+ import type { SocketWrapper } from './SocketWrapper.js';
3
+ /**
4
+ * 连接选项
5
+ */
6
+ export interface SocketConnectOptions {
7
+ /** 服务器主机地址 */
8
+ host?: string;
9
+ /** 服务器端口号 */
10
+ port?: number;
11
+ /** 是否启用自动重连,默认 false */
12
+ autoReconnect?: boolean;
13
+ /** 重连间隔(毫秒),默认 5000 */
14
+ reconnectInterval?: number;
15
+ /** 是否启用心跳,默认 true */
16
+ enableHeartbeat?: boolean;
17
+ /** 心跳间隔(毫秒),默认 5000(5秒) */
18
+ heartbeatInterval?: number;
19
+ /** 心跳超时时间(毫秒),默认 5000(5秒),如果心跳发送后超过此时间未收到响应则关闭连接 */
20
+ heartbeatTimeout?: number;
21
+ /** 最大重连次数,默认 0 表示无限制 */
22
+ maxReconnectAttempts?: number;
23
+ /** 是否启用指数退避(重连间隔逐渐增加),默认 false */
24
+ enableExponentialBackoff?: boolean;
25
+ /** 指数退避的最大间隔(毫秒),默认 60000(60秒) */
26
+ maxReconnectInterval?: number;
27
+ }
28
+ /**
29
+ * 队列配置选项
30
+ */
31
+ export interface QueueOptions {
32
+ /** 最大队列长度,默认 1000 */
33
+ maxLength?: number;
34
+ /** 溢出策略 */
35
+ overflowStrategy?: 'drop-oldest' | 'drop-newest' | 'reject';
36
+ /** 单条数据处理超时时间(毫秒),默认 5000 */
37
+ processTimeout?: number;
38
+ }
39
+ /**
40
+ * 队列溢出策略
41
+ */
42
+ export declare enum QueueOverflowStrategy {
43
+ /** 丢弃最旧的数据 */
44
+ DROP_OLDEST = "drop-oldest",
45
+ /** 丢弃最新的数据 */
46
+ DROP_NEWEST = "drop-newest",
47
+ /** 拒绝新数据并触发错误 */
48
+ REJECT = "reject"
49
+ }
50
+ /**
51
+ * 队列监控指标
52
+ */
53
+ export interface QueueMetrics {
54
+ /** 总处理数量 */
55
+ totalProcessed: number;
56
+ /** 总错误数量 */
57
+ totalErrors: number;
58
+ /** 总丢弃数量 */
59
+ totalDropped: number;
60
+ /** 当前队列长度 */
61
+ currentLength: number;
62
+ /** 最大队列长度 */
63
+ maxLength: number;
64
+ /** 平均处理时间(毫秒) */
65
+ averageProcessTime: number;
66
+ /** 峰值长度 */
67
+ peakLength: number;
68
+ /** 最后处理时间戳 */
69
+ lastProcessTime: number;
70
+ }
71
+ /**
72
+ * 协议处理选项
73
+ */
74
+ export interface ProtocolHandlerOptions {
75
+ /** 是否启用协议解析(接收时自动解析) */
76
+ enableParsing?: boolean;
77
+ /** 是否启用协议构建(发送时自动构建) */
78
+ enableBuilding?: boolean;
79
+ /** 解析选项 */
80
+ parseOptions?: any;
81
+ /** 默认构建选项 */
82
+ defaultBuildOptions?: any;
83
+ }
84
+ /**
85
+ * 协议构建发送负载,用于统一的 send 接口
86
+ */
87
+ export interface ProtocolSendPayload {
88
+ /** 协议业务数据(TLV2 部分或等效结构) */
89
+ data: any;
90
+ /** 协议头数据(TLV1 部分,可选) */
91
+ header?: any;
92
+ /** 协议构建选项(会与默认构建选项合并) */
93
+ options?: any;
94
+ /** 是否作为响应包发送(部分协议需要显式设置) */
95
+ isResponse?: boolean;
96
+ }
97
+ /**
98
+ * 事件类型定义
99
+ */
100
+ export interface SocketWrapperEvents {
101
+ /** 连接成功时触发 */
102
+ connected: () => void;
103
+ /** 连接断开时触发(自动重连时会触发) */
104
+ disconnected: () => void;
105
+ /** 接收到数据时触发(原始数据) */
106
+ data: (data: Buffer, requestId: number) => void;
107
+ /** 接收到协议数据时触发(已解析) */
108
+ protocolData: (result: any, requestId: number) => void;
109
+ /** 发生错误时触发 */
110
+ error: (error: Error, requestId?: number) => void;
111
+ /** 连接关闭时触发 */
112
+ close: () => void;
113
+ }
114
+ /**
115
+ * SocketWrapper 接口
116
+ * 注意:on/emit/off/once 方法由 EventEmitter 继承提供,无需在接口中声明
117
+ */
118
+ export interface ISocketWrapper {
119
+ /**
120
+ * 连接到服务器
121
+ * @param host - 服务器主机地址
122
+ * @param port - 服务器端口号
123
+ * @param options - 连接选项
124
+ */
125
+ connect(host: string, port: number, options: SocketConnectOptions): void;
126
+ /**
127
+ * 断开连接
128
+ */
129
+ disconnect(): void;
130
+ /**
131
+ * 发送数据或协议包
132
+ * @param payload - 原始 Buffer 或协议负载对象
133
+ * @param requestId - 当发送原始 Buffer 时必须提供请求 ID
134
+ * @returns 实际发送所使用的请求 ID
135
+ */
136
+ send(payload: Buffer | ProtocolSendPayload): void;
137
+ /**
138
+ * 检查是否已连接
139
+ * @returns 如果已连接返回 true,否则返回 false
140
+ */
141
+ isConnected(): boolean;
142
+ /**
143
+ * 主动触发 error 事件
144
+ * 用于外部主动报告错误,例如业务逻辑错误、数据验证错误等
145
+ * @param error 错误对象
146
+ * @param requestId 可选的请求ID,用于关联特定的请求
147
+ */
148
+ emitError(error: Error, requestId?: number): void;
149
+ }
150
+ /**
151
+ * 内部响应队列项类型
152
+ */
153
+ export interface ResponseQueueItem {
154
+ /** 请求 ID */
155
+ requestId: number;
156
+ /** 响应数据 */
157
+ data: Buffer;
158
+ }
159
+ /**
160
+ * SocketWrapper 实例类型
161
+ */
162
+ export type SocketWrapperInstance = ISocketWrapper & EventEmitter;
163
+ /**
164
+ * requestId 提取函数类型
165
+ * 用于从接收到的数据中提取 requestId
166
+ * @param data - 接收到的数据缓冲区
167
+ * @returns 提取的 requestId (seqId)
168
+ */
169
+ export type RequestIdExtractor = (data: Buffer) => number;
170
+ /**
171
+ * 心跳包构建函数类型
172
+ * @returns 心跳包数据
173
+ */
174
+ export type HeartbeatBuilder = () => Buffer;
175
+ /**
176
+ * 心跳响应识别函数类型
177
+ * @param data 接收到的数据
178
+ * @returns 是否为心跳响应
179
+ */
180
+ export type HeartbeatResponseChecker = (data: Buffer) => boolean;
181
+ /**
182
+ * 连接管理器事件类型
183
+ */
184
+ export interface ConnectionManagerEvents {
185
+ /** 连接成功时触发 */
186
+ connected: (socketWrapper: SocketWrapper) => void;
187
+ /** 连接断开时触发 */
188
+ disconnected: (socketWrapper: SocketWrapper) => void;
189
+ /** 发生错误时触发 */
190
+ error: (error: string, socketWrapper?: SocketWrapper) => void;
191
+ }
192
+ /**
193
+ * 设备发现事件
194
+ */
195
+ export interface DiscoveryEvents {
196
+ up: [device: MiniDiscoveredDevice];
197
+ down: [device: MiniDiscoveredDevice];
198
+ }
199
+ /**
200
+ * 设备信息接口
201
+ */
202
+ export interface MiniDeviceInfo {
203
+ serialNumber: string;
204
+ version: string;
205
+ model?: string;
206
+ modelName?: string;
207
+ keyLayout: {
208
+ rows: number;
209
+ columns: number;
210
+ };
211
+ }
212
+ /**
213
+ * 发现的设备信息
214
+ */
215
+ export interface MiniDiscoveredDevice extends MiniDeviceInfo {
216
+ address: string;
217
+ port: number;
218
+ name: string;
219
+ lastSeen: Date;
220
+ }
221
+ /**
222
+ * 设备发现服务选项
223
+ */
224
+ export interface DiscoveryServiceOptions {
225
+ /** 查询间隔(毫秒) */
226
+ queryInterval?: number;
227
+ /** 服务类型 */
228
+ type?: string;
229
+ /** 服务协议 */
230
+ protocol?: string;
231
+ }
232
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 队列溢出策略
3
+ */
4
+ export var QueueOverflowStrategy;
5
+ (function (QueueOverflowStrategy) {
6
+ /** 丢弃最旧的数据 */
7
+ QueueOverflowStrategy["DROP_OLDEST"] = "drop-oldest";
8
+ /** 丢弃最新的数据 */
9
+ QueueOverflowStrategy["DROP_NEWEST"] = "drop-newest";
10
+ /** 拒绝新数据并触发错误 */
11
+ QueueOverflowStrategy["REJECT"] = "reject";
12
+ })(QueueOverflowStrategy || (QueueOverflowStrategy = {}));
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/packages/tcp/types.ts"],"names":[],"mappings":"AA2CA;;GAEG;AACH,MAAM,CAAN,IAAY,qBAOX;AAPD,WAAY,qBAAqB;IAChC,cAAc;IACd,oDAA2B,CAAA;IAC3B,cAAc;IACd,oDAA2B,CAAA;IAC3B,iBAAiB;IACjB,0CAAiB,CAAA;AAClB,CAAC,EAPW,qBAAqB,KAArB,qBAAqB,QAOhC","sourcesContent":["// ALL_CODE_LINE: 243\r\n// AI_CODE_LINE: 44\r\nimport { EventEmitter } from 'events';\r\nimport type { SocketWrapper } from './SocketWrapper.js';\r\n\r\n/**\r\n * 连接选项\r\n */\r\nexport interface SocketConnectOptions {\r\n\t/** 服务器主机地址 */\r\n\thost?: string;\r\n\t/** 服务器端口号 */\r\n\tport?: number;\r\n\t/** 是否启用自动重连,默认 false */\r\n\tautoReconnect?: boolean;\r\n\t/** 重连间隔(毫秒),默认 5000 */\r\n\treconnectInterval?: number;\r\n\t/** 是否启用心跳,默认 true */\r\n\tenableHeartbeat?: boolean;\r\n\t/** 心跳间隔(毫秒),默认 5000(5秒) */\r\n\theartbeatInterval?: number;\r\n\t/** 心跳超时时间(毫秒),默认 5000(5秒),如果心跳发送后超过此时间未收到响应则关闭连接 */\r\n\theartbeatTimeout?: number;\r\n\t/** 最大重连次数,默认 0 表示无限制 */\r\n\tmaxReconnectAttempts?: number;\r\n\t/** 是否启用指数退避(重连间隔逐渐增加),默认 false */\r\n\tenableExponentialBackoff?: boolean;\r\n\t/** 指数退避的最大间隔(毫秒),默认 60000(60秒) */\r\n\tmaxReconnectInterval?: number;\r\n}\r\n\r\n/**\r\n * 队列配置选项\r\n */\r\nexport interface QueueOptions {\r\n\t/** 最大队列长度,默认 1000 */\r\n\tmaxLength?: number;\r\n\t/** 溢出策略 */\r\n\toverflowStrategy?: 'drop-oldest' | 'drop-newest' | 'reject';\r\n\t/** 单条数据处理超时时间(毫秒),默认 5000 */\r\n\tprocessTimeout?: number;\r\n}\r\n\r\n/**\r\n * 队列溢出策略\r\n */\r\nexport enum QueueOverflowStrategy {\r\n\t/** 丢弃最旧的数据 */\r\n\tDROP_OLDEST = 'drop-oldest',\r\n\t/** 丢弃最新的数据 */\r\n\tDROP_NEWEST = 'drop-newest',\r\n\t/** 拒绝新数据并触发错误 */\r\n\tREJECT = 'reject',\r\n}\r\n\r\n/**\r\n * 队列监控指标\r\n */\r\nexport interface QueueMetrics {\r\n\t/** 总处理数量 */\r\n\ttotalProcessed: number;\r\n\t/** 总错误数量 */\r\n\ttotalErrors: number;\r\n\t/** 总丢弃数量 */\r\n\ttotalDropped: number;\r\n\t/** 当前队列长度 */\r\n\tcurrentLength: number;\r\n\t/** 最大队列长度 */\r\n\tmaxLength: number;\r\n\t/** 平均处理时间(毫秒) */\r\n\taverageProcessTime: number;\r\n\t/** 峰值长度 */\r\n\tpeakLength: number;\r\n\t/** 最后处理时间戳 */\r\n\tlastProcessTime: number;\r\n}\r\n\r\n/**\r\n * 协议处理选项\r\n */\r\nexport interface ProtocolHandlerOptions {\r\n\t/** 是否启用协议解析(接收时自动解析) */\r\n\tenableParsing?: boolean;\r\n\t/** 是否启用协议构建(发送时自动构建) */\r\n\tenableBuilding?: boolean;\r\n\t/** 解析选项 */\r\n\tparseOptions?: any;\r\n\t/** 默认构建选项 */\r\n\tdefaultBuildOptions?: any;\r\n}\r\n\r\n/**\r\n * 协议构建发送负载,用于统一的 send 接口\r\n */\r\nexport interface ProtocolSendPayload {\r\n\t/** 协议业务数据(TLV2 部分或等效结构) */\r\n\tdata: any;\r\n\t/** 协议头数据(TLV1 部分,可选) */\r\n\theader?: any;\r\n\t/** 协议构建选项(会与默认构建选项合并) */\r\n\toptions?: any;\r\n\t/** 是否作为响应包发送(部分协议需要显式设置) */\r\n\tisResponse?: boolean;\r\n}\r\n\r\n/**\r\n * 事件类型定义\r\n */\r\nexport interface SocketWrapperEvents {\r\n\t/** 连接成功时触发 */\r\n\tconnected: () => void;\r\n\t/** 连接断开时触发(自动重连时会触发) */\r\n\tdisconnected: () => void;\r\n\t/** 接收到数据时触发(原始数据) */\r\n\tdata: (data: Buffer, requestId: number) => void;\r\n\t/** 接收到协议数据时触发(已解析) */\r\n\tprotocolData: (result: any, requestId: number) => void;\r\n\t/** 发生错误时触发 */\r\n\terror: (error: Error, requestId?: number) => void;\r\n\t/** 连接关闭时触发 */\r\n\tclose: () => void;\r\n}\r\n\r\n/**\r\n * SocketWrapper 接口\r\n * 注意:on/emit/off/once 方法由 EventEmitter 继承提供,无需在接口中声明\r\n */\r\nexport interface ISocketWrapper {\r\n\t/**\r\n\t * 连接到服务器\r\n\t * @param host - 服务器主机地址\r\n\t * @param port - 服务器端口号\r\n\t * @param options - 连接选项\r\n\t */\r\n\tconnect(host: string, port: number, options: SocketConnectOptions): void;\r\n\t/**\r\n\t * 断开连接\r\n\t */\r\n\tdisconnect(): void;\r\n\r\n\t/**\r\n\t * 发送数据或协议包\r\n\t * @param payload - 原始 Buffer 或协议负载对象\r\n\t * @param requestId - 当发送原始 Buffer 时必须提供请求 ID\r\n\t * @returns 实际发送所使用的请求 ID\r\n\t */\r\n\tsend(payload: Buffer | ProtocolSendPayload): void;\r\n\r\n\t/**\r\n\t * 检查是否已连接\r\n\t * @returns 如果已连接返回 true,否则返回 false\r\n\t */\r\n\tisConnected(): boolean;\r\n\r\n\t/**\r\n\t * 主动触发 error 事件\r\n\t * 用于外部主动报告错误,例如业务逻辑错误、数据验证错误等\r\n\t * @param error 错误对象\r\n\t * @param requestId 可选的请求ID,用于关联特定的请求\r\n\t */\r\n\temitError(error: Error, requestId?: number): void;\r\n}\r\n\r\n/**\r\n * 内部响应队列项类型\r\n */\r\nexport interface ResponseQueueItem {\r\n\t/** 请求 ID */\r\n\trequestId: number;\r\n\t/** 响应数据 */\r\n\tdata: Buffer;\r\n}\r\n\r\n/**\r\n * SocketWrapper 实例类型\r\n */\r\nexport type SocketWrapperInstance = ISocketWrapper & EventEmitter;\r\n\r\n/**\r\n * requestId 提取函数类型\r\n * 用于从接收到的数据中提取 requestId\r\n * @param data - 接收到的数据缓冲区\r\n * @returns 提取的 requestId (seqId)\r\n */\r\nexport type RequestIdExtractor = (data: Buffer) => number;\r\n\r\n/**\r\n * 心跳包构建函数类型\r\n * @returns 心跳包数据\r\n */\r\nexport type HeartbeatBuilder = () => Buffer;\r\n\r\n/**\r\n * 心跳响应识别函数类型\r\n * @param data 接收到的数据\r\n * @returns 是否为心跳响应\r\n */\r\nexport type HeartbeatResponseChecker = (data: Buffer) => boolean;\r\n\r\n/**\r\n * 连接管理器事件类型\r\n */\r\nexport interface ConnectionManagerEvents {\r\n\t/** 连接成功时触发 */\r\n\tconnected: (socketWrapper: SocketWrapper) => void;\r\n\t/** 连接断开时触发 */\r\n\tdisconnected: (socketWrapper: SocketWrapper) => void;\r\n\t/** 发生错误时触发 */\r\n\terror: (error: string, socketWrapper?: SocketWrapper) => void;\r\n}\r\n\r\n/**\r\n * 设备发现事件\r\n */\r\nexport interface DiscoveryEvents {\r\n\t// 兼容 tcp 包的事件命名\r\n\tup: [device: MiniDiscoveredDevice];\r\n\tdown: [device: MiniDiscoveredDevice];\r\n}\r\n\r\n/**\r\n * 设备信息接口\r\n */\r\nexport interface MiniDeviceInfo {\r\n\tserialNumber: string; // 设备序列号,唯一标识设备\r\n\tversion: string; // 固件版本号\r\n\tmodel?: string; // 设备型号代码\r\n\tmodelName?: string; // 设备型号名称\r\n\tkeyLayout: { rows: number; columns: number }; // 按键布局(行数和列数)\r\n}\r\n\r\n/**\r\n * 发现的设备信息\r\n */\r\nexport interface MiniDiscoveredDevice extends MiniDeviceInfo {\r\n\taddress: string;\r\n\tport: number;\r\n\tname: string;\r\n\tlastSeen: Date;\r\n}\r\n\r\n/**\r\n * 设备发现服务选项\r\n */\r\nexport interface DiscoveryServiceOptions {\r\n\t/** 查询间隔(毫秒) */\r\n\tqueryInterval?: number;\r\n\t/** 服务类型 */\r\n\ttype?: string;\r\n\t/** 服务协议 */\r\n\tprotocol?: string;\r\n}\r\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 工具函数
3
+ */
4
+ /**
5
+ * 从 URL 解析主机地址
6
+ * @param url 连接地址
7
+ */
8
+ export declare function parseHost(url: string): string | null;
9
+ /**
10
+ * 从 URL 解析端口
11
+ * @param url 连接地址
12
+ */
13
+ export declare function parsePort(url: string): number | null;
14
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/packages/tcp/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAepD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBpD"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 工具函数
3
+ */
4
+ /**
5
+ * 从 URL 解析主机地址
6
+ * @param url 连接地址
7
+ */
8
+ export function parseHost(url) {
9
+ try {
10
+ // 尝试解析为 URL
11
+ if (url.includes('://')) {
12
+ const urlObj = new URL(url);
13
+ return urlObj.hostname;
14
+ }
15
+ // 尝试解析为 host:port 格式
16
+ if (url.includes(':')) {
17
+ return url.split(':')[0];
18
+ }
19
+ return url;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * 从 URL 解析端口
27
+ * @param url 连接地址
28
+ */
29
+ export function parsePort(url) {
30
+ try {
31
+ // 尝试解析为 URL
32
+ if (url.includes('://')) {
33
+ const urlObj = new URL(url);
34
+ return parseInt(urlObj.port, 10) || null;
35
+ }
36
+ // 尝试解析为 host:port 格式
37
+ if (url.includes(':')) {
38
+ const port = parseInt(url.split(':')[1], 10);
39
+ return isNaN(port) ? null : port;
40
+ }
41
+ return null;
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/packages/tcp/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACpC,IAAI,CAAC;QACJ,YAAY;QACZ,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC;QACxB,CAAC;QACD,qBAAqB;QACrB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACpC,IAAI,CAAC;QACJ,YAAY;QACZ,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QAC1C,CAAC;QACD,qBAAqB;QACrB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC","sourcesContent":["/**\r\n * 工具函数\r\n */\r\n\r\n/**\r\n * 从 URL 解析主机地址\r\n * @param url 连接地址\r\n */\r\nexport function parseHost(url: string): string | null {\r\n\ttry {\r\n\t\t// 尝试解析为 URL\r\n\t\tif (url.includes('://')) {\r\n\t\t\tconst urlObj = new URL(url);\r\n\t\t\treturn urlObj.hostname;\r\n\t\t}\r\n\t\t// 尝试解析为 host:port 格式\r\n\t\tif (url.includes(':')) {\r\n\t\t\treturn url.split(':')[0];\r\n\t\t}\r\n\t\treturn url;\r\n\t} catch {\r\n\t\treturn null;\r\n\t}\r\n}\r\n\r\n/**\r\n * 从 URL 解析端口\r\n * @param url 连接地址\r\n */\r\nexport function parsePort(url: string): number | null {\r\n\ttry {\r\n\t\t// 尝试解析为 URL\r\n\t\tif (url.includes('://')) {\r\n\t\t\tconst urlObj = new URL(url);\r\n\t\t\treturn parseInt(urlObj.port, 10) || null;\r\n\t\t}\r\n\t\t// 尝试解析为 host:port 格式\r\n\t\tif (url.includes(':')) {\r\n\t\t\tconst port = parseInt(url.split(':')[1], 10);\r\n\t\t\treturn isNaN(port) ? null : port;\r\n\t\t}\r\n\t\treturn null;\r\n\t} catch {\r\n\t\treturn null;\r\n\t}\r\n}\r\n"]}
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@pixelhue/event-controller-sdk",
3
+ "version": "0.0.1",
4
+ "description": "Node service for PixelHue Event Controller device",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "tsc --watch",
11
+ "start": "node dist/index.js",
12
+ "start:dev": "tsx src/index.ts",
13
+ "test": "jest",
14
+ "test:watch": "jest --watch",
15
+ "test:coverage": "jest --coverage",
16
+ "lint": "eslint src --ext .ts",
17
+ "lint:fix": "eslint src --ext .ts --fix",
18
+ "format": "prettier --write \"src/**/*.ts\"",
19
+ "format:check": "prettier --check \"src/**/*.ts\"",
20
+ "commit": "cz",
21
+ "prepare": "husky",
22
+ "mock:device": "node pixelhue-mock-device.js",
23
+ "changelog": "standard-version -a -n -r patch",
24
+ "changelog:minor": "standard-version -a -n -r minor",
25
+ "changelog:major": "standard-version -a -n -r major",
26
+ "release": "yarn run changelog && yarn run build && npm publish --access public",
27
+ "release:dry-run": "yarn run build && npm publish --dry-run"
28
+ },
29
+ "config": {
30
+ "commitizen": {
31
+ "path": "cz-customizable"
32
+ },
33
+ "cz-customizable": {
34
+ "config": "./.cz-config.cjs"
35
+ }
36
+ },
37
+ "keywords": [
38
+ "pixelhue",
39
+ "event-controller",
40
+ "u5-mini",
41
+ "device",
42
+ "service"
43
+ ],
44
+ "author": "pixelhue-service@novastar.tech",
45
+ "license": "MIT",
46
+ "publishConfig": {
47
+ "registry": "https://registry.npmjs.org/",
48
+ "access": "public"
49
+ },
50
+ "files": [
51
+ "dist"
52
+ ],
53
+ "devDependencies": {
54
+ "@commitlint/cli": "^18.6.0",
55
+ "@commitlint/config-conventional": "^18.6.0",
56
+ "@types/jest": "^29.5.11",
57
+ "@types/node": "^20.11.0",
58
+ "@typescript-eslint/eslint-plugin": "^6.19.0",
59
+ "@typescript-eslint/parser": "^6.19.0",
60
+ "commitizen": "^4.3.0",
61
+ "cz-customizable": "^7.0.0",
62
+ "eslint": "^8.56.0",
63
+ "eslint-config-prettier": "^9.1.0",
64
+ "eslint-import-resolver-typescript": "^3.6.1",
65
+ "eslint-plugin-import": "^2.29.1",
66
+ "eslint-plugin-simple-import-sort": "^12.0.0",
67
+ "husky": "^9.0.10",
68
+ "jest": "^29.7.0",
69
+ "prettier": "^3.2.4",
70
+ "standard-version": "^9.3.1",
71
+ "ts-jest": "^29.1.2",
72
+ "tsx": "^4.7.0",
73
+ "typescript": "^5.3.3"
74
+ },
75
+ "dependencies": {
76
+ "@julusian/bonjour-service": "^1.4.2",
77
+ "@unico/uniform-protocol-builder": "^1.0.0",
78
+ "@unico/uniform-protocol-parser": "^1.0.0",
79
+ "eventemitter3": "^5.0.1",
80
+ "p-queue": "^9.0.0"
81
+ }
82
+ }