@furlow/pipes 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/dist/database/index.d.ts +3 -0
- package/dist/database/index.js +8 -0
- package/dist/database/index.js.map +1 -0
- package/dist/file/index.d.ts +3 -0
- package/dist/file/index.js +8 -0
- package/dist/file/index.js.map +1 -0
- package/dist/http/index.d.ts +61 -0
- package/dist/http/index.js +156 -0
- package/dist/http/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1282 -0
- package/dist/index.js.map +1 -0
- package/dist/mqtt/index.d.ts +82 -0
- package/dist/mqtt/index.js +277 -0
- package/dist/mqtt/index.js.map +1 -0
- package/dist/tcp/index.d.ts +167 -0
- package/dist/tcp/index.js +462 -0
- package/dist/tcp/index.js.map +1 -0
- package/dist/types-BW9r2ksN.d.ts +152 -0
- package/dist/webhook/index.d.ts +70 -0
- package/dist/webhook/index.js +169 -0
- package/dist/webhook/index.js.map +1 -0
- package/dist/websocket/index.d.ts +84 -0
- package/dist/websocket/index.js +226 -0
- package/dist/websocket/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { P as Pipe, U as UdpPipeConfig, f as PipeResponse, T as TcpPipeConfig } from '../types-BW9r2ksN.js';
|
|
2
|
+
import { RemoteInfo } from 'dgram';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* UDP pipe for datagram communication
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface UdpPipeOptions {
|
|
9
|
+
name: string;
|
|
10
|
+
config: UdpPipeConfig;
|
|
11
|
+
}
|
|
12
|
+
interface UdpMessage {
|
|
13
|
+
data: Buffer;
|
|
14
|
+
rinfo: RemoteInfo;
|
|
15
|
+
}
|
|
16
|
+
type UdpMessageHandler = (msg: UdpMessage) => void | Promise<void>;
|
|
17
|
+
type UdpEventHandler = (data?: unknown) => void | Promise<void>;
|
|
18
|
+
declare class UdpPipe implements Pipe {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly type = "udp";
|
|
21
|
+
private socket;
|
|
22
|
+
private config;
|
|
23
|
+
private bound;
|
|
24
|
+
private messageHandlers;
|
|
25
|
+
private eventHandlers;
|
|
26
|
+
constructor(options: UdpPipeOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Bind to a port to receive messages
|
|
29
|
+
*/
|
|
30
|
+
bind(port?: number): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Close the socket
|
|
33
|
+
*/
|
|
34
|
+
disconnect(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Check if bound
|
|
37
|
+
*/
|
|
38
|
+
isConnected(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Send data to a specific host and port
|
|
41
|
+
*/
|
|
42
|
+
send(data: Buffer | string, host: string, port: number): Promise<PipeResponse>;
|
|
43
|
+
/**
|
|
44
|
+
* Broadcast data to all hosts on the network
|
|
45
|
+
*/
|
|
46
|
+
broadcast(data: Buffer | string, port: number, address?: string): Promise<PipeResponse>;
|
|
47
|
+
/**
|
|
48
|
+
* Send to multicast group
|
|
49
|
+
*/
|
|
50
|
+
multicast(data: Buffer | string, port: number, group?: string): Promise<PipeResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Register a message handler
|
|
53
|
+
*/
|
|
54
|
+
onMessage(handler: UdpMessageHandler): void;
|
|
55
|
+
/**
|
|
56
|
+
* Remove a message handler
|
|
57
|
+
*/
|
|
58
|
+
offMessage(handler: UdpMessageHandler): void;
|
|
59
|
+
/**
|
|
60
|
+
* Register an event handler
|
|
61
|
+
*/
|
|
62
|
+
on(event: string, handler: UdpEventHandler): void;
|
|
63
|
+
/**
|
|
64
|
+
* Remove an event handler
|
|
65
|
+
*/
|
|
66
|
+
off(event: string, handler: UdpEventHandler): void;
|
|
67
|
+
/**
|
|
68
|
+
* Emit an event
|
|
69
|
+
*/
|
|
70
|
+
private emit;
|
|
71
|
+
/**
|
|
72
|
+
* Handle incoming messages
|
|
73
|
+
*/
|
|
74
|
+
private handleMessage;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a UDP pipe
|
|
78
|
+
*/
|
|
79
|
+
declare function createUdpPipe(options: UdpPipeOptions): UdpPipe;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* TCP pipe for raw socket communication
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
interface TcpPipeOptions {
|
|
86
|
+
name: string;
|
|
87
|
+
config: TcpPipeConfig;
|
|
88
|
+
}
|
|
89
|
+
type TcpDataHandler = (data: Buffer | string) => void | Promise<void>;
|
|
90
|
+
type TcpEventHandler = (data?: unknown) => void | Promise<void>;
|
|
91
|
+
declare class TcpPipe implements Pipe {
|
|
92
|
+
readonly name: string;
|
|
93
|
+
readonly type = "tcp";
|
|
94
|
+
private socket;
|
|
95
|
+
private server;
|
|
96
|
+
private config;
|
|
97
|
+
private connected;
|
|
98
|
+
private reconnectAttempts;
|
|
99
|
+
private reconnecting;
|
|
100
|
+
private dataHandlers;
|
|
101
|
+
private eventHandlers;
|
|
102
|
+
constructor(options: TcpPipeOptions);
|
|
103
|
+
/**
|
|
104
|
+
* Connect to a TCP server (client mode)
|
|
105
|
+
*/
|
|
106
|
+
connect(): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Start a TCP server (server mode)
|
|
109
|
+
*/
|
|
110
|
+
listen(port?: number): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Disconnect / close
|
|
113
|
+
*/
|
|
114
|
+
disconnect(): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Check if connected
|
|
117
|
+
*/
|
|
118
|
+
isConnected(): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Send data
|
|
121
|
+
*/
|
|
122
|
+
send(data: Buffer | string): Promise<PipeResponse>;
|
|
123
|
+
/**
|
|
124
|
+
* Send and wait for response (request-response pattern)
|
|
125
|
+
*/
|
|
126
|
+
request<T = string>(data: Buffer | string, options?: {
|
|
127
|
+
timeout?: number;
|
|
128
|
+
}): Promise<PipeResponse<T>>;
|
|
129
|
+
/**
|
|
130
|
+
* Register a data handler
|
|
131
|
+
*/
|
|
132
|
+
onData(handler: TcpDataHandler): void;
|
|
133
|
+
/**
|
|
134
|
+
* Remove a data handler
|
|
135
|
+
*/
|
|
136
|
+
offData(handler: TcpDataHandler): void;
|
|
137
|
+
/**
|
|
138
|
+
* Register an event handler
|
|
139
|
+
*/
|
|
140
|
+
on(event: string, handler: TcpEventHandler): void;
|
|
141
|
+
/**
|
|
142
|
+
* Remove an event handler
|
|
143
|
+
*/
|
|
144
|
+
off(event: string, handler: TcpEventHandler): void;
|
|
145
|
+
/**
|
|
146
|
+
* Emit an event
|
|
147
|
+
*/
|
|
148
|
+
private emit;
|
|
149
|
+
/**
|
|
150
|
+
* Handle incoming data
|
|
151
|
+
*/
|
|
152
|
+
private handleData;
|
|
153
|
+
/**
|
|
154
|
+
* Handle disconnection with reconnect logic
|
|
155
|
+
*/
|
|
156
|
+
private handleDisconnect;
|
|
157
|
+
/**
|
|
158
|
+
* Parse duration string to milliseconds
|
|
159
|
+
*/
|
|
160
|
+
private parseDuration;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create a TCP pipe
|
|
164
|
+
*/
|
|
165
|
+
declare function createTcpPipe(options: TcpPipeOptions): TcpPipe;
|
|
166
|
+
|
|
167
|
+
export { type TcpDataHandler, type TcpEventHandler, TcpPipe, type TcpPipeOptions, type UdpEventHandler, type UdpMessage, type UdpMessageHandler, UdpPipe, type UdpPipeOptions, createTcpPipe, createUdpPipe };
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
// src/tcp/index.ts
|
|
2
|
+
import { createConnection, createServer } from "net";
|
|
3
|
+
|
|
4
|
+
// src/tcp/udp.ts
|
|
5
|
+
import { createSocket } from "dgram";
|
|
6
|
+
var UdpPipe = class {
|
|
7
|
+
name;
|
|
8
|
+
type = "udp";
|
|
9
|
+
socket = null;
|
|
10
|
+
config;
|
|
11
|
+
bound = false;
|
|
12
|
+
messageHandlers = [];
|
|
13
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.name = options.name;
|
|
16
|
+
this.config = options.config;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Bind to a port to receive messages
|
|
20
|
+
*/
|
|
21
|
+
async bind(port) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
try {
|
|
24
|
+
this.socket = createSocket("udp4");
|
|
25
|
+
this.socket.on("message", (msg, rinfo) => {
|
|
26
|
+
this.handleMessage(msg, rinfo);
|
|
27
|
+
});
|
|
28
|
+
this.socket.on("error", (error) => {
|
|
29
|
+
if (!this.bound) {
|
|
30
|
+
reject(error);
|
|
31
|
+
}
|
|
32
|
+
this.emit("error", error);
|
|
33
|
+
});
|
|
34
|
+
this.socket.on("listening", () => {
|
|
35
|
+
this.bound = true;
|
|
36
|
+
const address = this.socket.address();
|
|
37
|
+
this.emit("listening", address);
|
|
38
|
+
resolve();
|
|
39
|
+
});
|
|
40
|
+
if (this.config.broadcast) {
|
|
41
|
+
this.socket.setBroadcast(true);
|
|
42
|
+
}
|
|
43
|
+
const bindPort = port ?? this.config.port;
|
|
44
|
+
const bindHost = this.config.host ?? "0.0.0.0";
|
|
45
|
+
this.socket.bind(bindPort, bindHost, () => {
|
|
46
|
+
if (this.config.multicast) {
|
|
47
|
+
this.socket.addMembership(this.config.multicast);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
reject(error);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Close the socket
|
|
57
|
+
*/
|
|
58
|
+
async disconnect() {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
if (this.socket) {
|
|
61
|
+
this.socket.close(() => {
|
|
62
|
+
this.socket = null;
|
|
63
|
+
this.bound = false;
|
|
64
|
+
resolve();
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
resolve();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if bound
|
|
73
|
+
*/
|
|
74
|
+
isConnected() {
|
|
75
|
+
return this.bound;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Send data to a specific host and port
|
|
79
|
+
*/
|
|
80
|
+
async send(data, host, port) {
|
|
81
|
+
if (!this.socket) {
|
|
82
|
+
this.socket = createSocket("udp4");
|
|
83
|
+
if (this.config.broadcast) {
|
|
84
|
+
this.socket.setBroadcast(true);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const buffer = typeof data === "string" ? Buffer.from(data) : data;
|
|
88
|
+
return new Promise((resolve) => {
|
|
89
|
+
this.socket.send(buffer, port, host, (error) => {
|
|
90
|
+
if (error) {
|
|
91
|
+
resolve({ success: false, error: error.message });
|
|
92
|
+
} else {
|
|
93
|
+
resolve({ success: true });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Broadcast data to all hosts on the network
|
|
100
|
+
*/
|
|
101
|
+
async broadcast(data, port, address = "255.255.255.255") {
|
|
102
|
+
if (!this.socket) {
|
|
103
|
+
this.socket = createSocket("udp4");
|
|
104
|
+
this.socket.setBroadcast(true);
|
|
105
|
+
}
|
|
106
|
+
const buffer = typeof data === "string" ? Buffer.from(data) : data;
|
|
107
|
+
return new Promise((resolve) => {
|
|
108
|
+
this.socket.send(buffer, port, address, (error) => {
|
|
109
|
+
if (error) {
|
|
110
|
+
resolve({ success: false, error: error.message });
|
|
111
|
+
} else {
|
|
112
|
+
resolve({ success: true });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Send to multicast group
|
|
119
|
+
*/
|
|
120
|
+
async multicast(data, port, group) {
|
|
121
|
+
const multicastGroup = group ?? this.config.multicast;
|
|
122
|
+
if (!multicastGroup) {
|
|
123
|
+
return { success: false, error: "No multicast group configured" };
|
|
124
|
+
}
|
|
125
|
+
return this.send(data, multicastGroup, port);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Register a message handler
|
|
129
|
+
*/
|
|
130
|
+
onMessage(handler) {
|
|
131
|
+
this.messageHandlers.push(handler);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Remove a message handler
|
|
135
|
+
*/
|
|
136
|
+
offMessage(handler) {
|
|
137
|
+
const index = this.messageHandlers.indexOf(handler);
|
|
138
|
+
if (index !== -1) {
|
|
139
|
+
this.messageHandlers.splice(index, 1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Register an event handler
|
|
144
|
+
*/
|
|
145
|
+
on(event, handler) {
|
|
146
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
147
|
+
handlers.push(handler);
|
|
148
|
+
this.eventHandlers.set(event, handlers);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Remove an event handler
|
|
152
|
+
*/
|
|
153
|
+
off(event, handler) {
|
|
154
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
155
|
+
const index = handlers.indexOf(handler);
|
|
156
|
+
if (index !== -1) {
|
|
157
|
+
handlers.splice(index, 1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Emit an event
|
|
162
|
+
*/
|
|
163
|
+
emit(event, data) {
|
|
164
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
165
|
+
for (const handler of handlers) {
|
|
166
|
+
try {
|
|
167
|
+
handler(data);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error(`UDP handler error for "${event}":`, error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Handle incoming messages
|
|
175
|
+
*/
|
|
176
|
+
handleMessage(data, rinfo) {
|
|
177
|
+
const msg = { data, rinfo };
|
|
178
|
+
for (const handler of this.messageHandlers) {
|
|
179
|
+
try {
|
|
180
|
+
handler(msg);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error("UDP message handler error:", error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
this.emit("message", msg);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
function createUdpPipe(options) {
|
|
189
|
+
return new UdpPipe(options);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/tcp/index.ts
|
|
193
|
+
var TcpPipe = class {
|
|
194
|
+
name;
|
|
195
|
+
type = "tcp";
|
|
196
|
+
socket = null;
|
|
197
|
+
server = null;
|
|
198
|
+
config;
|
|
199
|
+
connected = false;
|
|
200
|
+
reconnectAttempts = 0;
|
|
201
|
+
reconnecting = false;
|
|
202
|
+
dataHandlers = [];
|
|
203
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
204
|
+
constructor(options) {
|
|
205
|
+
this.name = options.name;
|
|
206
|
+
this.config = options.config;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Connect to a TCP server (client mode)
|
|
210
|
+
*/
|
|
211
|
+
async connect() {
|
|
212
|
+
return new Promise((resolve, reject) => {
|
|
213
|
+
try {
|
|
214
|
+
this.socket = createConnection({
|
|
215
|
+
host: this.config.host,
|
|
216
|
+
port: this.config.port
|
|
217
|
+
});
|
|
218
|
+
this.socket.setEncoding(this.config.encoding ?? "utf8");
|
|
219
|
+
this.socket.on("connect", () => {
|
|
220
|
+
this.connected = true;
|
|
221
|
+
this.reconnectAttempts = 0;
|
|
222
|
+
this.reconnecting = false;
|
|
223
|
+
this.emit("connected");
|
|
224
|
+
resolve();
|
|
225
|
+
});
|
|
226
|
+
this.socket.on("data", (data) => {
|
|
227
|
+
this.handleData(data);
|
|
228
|
+
});
|
|
229
|
+
this.socket.on("close", () => {
|
|
230
|
+
this.connected = false;
|
|
231
|
+
this.emit("disconnected");
|
|
232
|
+
this.handleDisconnect();
|
|
233
|
+
});
|
|
234
|
+
this.socket.on("error", (error) => {
|
|
235
|
+
if (!this.connected) {
|
|
236
|
+
reject(error);
|
|
237
|
+
}
|
|
238
|
+
this.emit("error", error);
|
|
239
|
+
});
|
|
240
|
+
this.socket.on("end", () => {
|
|
241
|
+
this.connected = false;
|
|
242
|
+
this.emit("end");
|
|
243
|
+
});
|
|
244
|
+
} catch (error) {
|
|
245
|
+
reject(error);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Start a TCP server (server mode)
|
|
251
|
+
*/
|
|
252
|
+
async listen(port) {
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
try {
|
|
255
|
+
this.server = createServer((socket) => {
|
|
256
|
+
socket.setEncoding(this.config.encoding ?? "utf8");
|
|
257
|
+
socket.on("data", (data) => {
|
|
258
|
+
this.handleData(data);
|
|
259
|
+
});
|
|
260
|
+
socket.on("error", (error) => {
|
|
261
|
+
this.emit("client_error", error);
|
|
262
|
+
});
|
|
263
|
+
this.emit("connection", socket);
|
|
264
|
+
});
|
|
265
|
+
this.server.on("error", (error) => {
|
|
266
|
+
reject(error);
|
|
267
|
+
});
|
|
268
|
+
this.server.listen(port ?? this.config.port, () => {
|
|
269
|
+
this.connected = true;
|
|
270
|
+
this.emit("listening");
|
|
271
|
+
resolve();
|
|
272
|
+
});
|
|
273
|
+
} catch (error) {
|
|
274
|
+
reject(error);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Disconnect / close
|
|
280
|
+
*/
|
|
281
|
+
async disconnect() {
|
|
282
|
+
this.reconnecting = false;
|
|
283
|
+
return new Promise((resolve) => {
|
|
284
|
+
if (this.socket) {
|
|
285
|
+
this.socket.end(() => {
|
|
286
|
+
this.socket?.destroy();
|
|
287
|
+
this.socket = null;
|
|
288
|
+
this.connected = false;
|
|
289
|
+
resolve();
|
|
290
|
+
});
|
|
291
|
+
} else if (this.server) {
|
|
292
|
+
this.server.close(() => {
|
|
293
|
+
this.server = null;
|
|
294
|
+
this.connected = false;
|
|
295
|
+
resolve();
|
|
296
|
+
});
|
|
297
|
+
} else {
|
|
298
|
+
resolve();
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Check if connected
|
|
304
|
+
*/
|
|
305
|
+
isConnected() {
|
|
306
|
+
return this.connected;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Send data
|
|
310
|
+
*/
|
|
311
|
+
async send(data) {
|
|
312
|
+
if (!this.socket || !this.connected) {
|
|
313
|
+
return { success: false, error: "Not connected" };
|
|
314
|
+
}
|
|
315
|
+
return new Promise((resolve) => {
|
|
316
|
+
this.socket.write(data, (error) => {
|
|
317
|
+
if (error) {
|
|
318
|
+
resolve({ success: false, error: error.message });
|
|
319
|
+
} else {
|
|
320
|
+
resolve({ success: true });
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Send and wait for response (request-response pattern)
|
|
327
|
+
*/
|
|
328
|
+
async request(data, options = {}) {
|
|
329
|
+
const { timeout = 3e4 } = options;
|
|
330
|
+
if (!this.socket || !this.connected) {
|
|
331
|
+
return { success: false, error: "Not connected" };
|
|
332
|
+
}
|
|
333
|
+
return new Promise((resolve) => {
|
|
334
|
+
const timer = setTimeout(() => {
|
|
335
|
+
this.offData(handler);
|
|
336
|
+
resolve({ success: false, error: "Request timeout" });
|
|
337
|
+
}, timeout);
|
|
338
|
+
const handler = (response) => {
|
|
339
|
+
clearTimeout(timer);
|
|
340
|
+
this.offData(handler);
|
|
341
|
+
resolve({ success: true, data: response });
|
|
342
|
+
};
|
|
343
|
+
this.onData(handler);
|
|
344
|
+
this.send(data);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Register a data handler
|
|
349
|
+
*/
|
|
350
|
+
onData(handler) {
|
|
351
|
+
this.dataHandlers.push(handler);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Remove a data handler
|
|
355
|
+
*/
|
|
356
|
+
offData(handler) {
|
|
357
|
+
const index = this.dataHandlers.indexOf(handler);
|
|
358
|
+
if (index !== -1) {
|
|
359
|
+
this.dataHandlers.splice(index, 1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Register an event handler
|
|
364
|
+
*/
|
|
365
|
+
on(event, handler) {
|
|
366
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
367
|
+
handlers.push(handler);
|
|
368
|
+
this.eventHandlers.set(event, handlers);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Remove an event handler
|
|
372
|
+
*/
|
|
373
|
+
off(event, handler) {
|
|
374
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
375
|
+
const index = handlers.indexOf(handler);
|
|
376
|
+
if (index !== -1) {
|
|
377
|
+
handlers.splice(index, 1);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Emit an event
|
|
382
|
+
*/
|
|
383
|
+
emit(event, data) {
|
|
384
|
+
const handlers = this.eventHandlers.get(event) ?? [];
|
|
385
|
+
for (const handler of handlers) {
|
|
386
|
+
try {
|
|
387
|
+
handler(data);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
console.error(`TCP handler error for "${event}":`, error);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Handle incoming data
|
|
395
|
+
*/
|
|
396
|
+
handleData(data) {
|
|
397
|
+
for (const handler of this.dataHandlers) {
|
|
398
|
+
try {
|
|
399
|
+
handler(data);
|
|
400
|
+
} catch (error) {
|
|
401
|
+
console.error("TCP data handler error:", error);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
this.emit("data", data);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Handle disconnection with reconnect logic
|
|
408
|
+
*/
|
|
409
|
+
handleDisconnect() {
|
|
410
|
+
if (!this.config.reconnect?.enabled || this.reconnecting) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const maxAttempts = this.config.reconnect.max_attempts ?? 10;
|
|
414
|
+
const delay = this.parseDuration(this.config.reconnect.delay ?? "5s");
|
|
415
|
+
if (this.reconnectAttempts >= maxAttempts) {
|
|
416
|
+
this.emit("reconnect_failed", { attempts: this.reconnectAttempts });
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
this.reconnecting = true;
|
|
420
|
+
this.reconnectAttempts++;
|
|
421
|
+
setTimeout(async () => {
|
|
422
|
+
try {
|
|
423
|
+
await this.connect();
|
|
424
|
+
this.emit("reconnected", { attempts: this.reconnectAttempts });
|
|
425
|
+
} catch {
|
|
426
|
+
this.reconnecting = false;
|
|
427
|
+
this.handleDisconnect();
|
|
428
|
+
}
|
|
429
|
+
}, delay);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Parse duration string to milliseconds
|
|
433
|
+
*/
|
|
434
|
+
parseDuration(duration) {
|
|
435
|
+
const match = duration.match(/^(\d+)(ms|s|m|h)?$/);
|
|
436
|
+
if (!match) return 5e3;
|
|
437
|
+
const value = parseInt(match[1], 10);
|
|
438
|
+
const unit = match[2] ?? "s";
|
|
439
|
+
switch (unit) {
|
|
440
|
+
case "ms":
|
|
441
|
+
return value;
|
|
442
|
+
case "s":
|
|
443
|
+
return value * 1e3;
|
|
444
|
+
case "m":
|
|
445
|
+
return value * 60 * 1e3;
|
|
446
|
+
case "h":
|
|
447
|
+
return value * 60 * 60 * 1e3;
|
|
448
|
+
default:
|
|
449
|
+
return value * 1e3;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
function createTcpPipe(options) {
|
|
454
|
+
return new TcpPipe(options);
|
|
455
|
+
}
|
|
456
|
+
export {
|
|
457
|
+
TcpPipe,
|
|
458
|
+
UdpPipe,
|
|
459
|
+
createTcpPipe,
|
|
460
|
+
createUdpPipe
|
|
461
|
+
};
|
|
462
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/tcp/index.ts","../../src/tcp/udp.ts"],"sourcesContent":["/**\n * TCP pipe for raw socket communication\n */\n\nimport { Socket, createConnection, createServer, Server } from 'net';\nimport type { Pipe, PipeResponse, TcpPipeConfig } from '../types.js';\n\nexport interface TcpPipeOptions {\n name: string;\n config: TcpPipeConfig;\n}\n\nexport type TcpDataHandler = (data: Buffer | string) => void | Promise<void>;\nexport type TcpEventHandler = (data?: unknown) => void | Promise<void>;\n\nexport class TcpPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'tcp';\n private socket: Socket | null = null;\n private server: Server | null = null;\n private config: TcpPipeConfig;\n private connected = false;\n private reconnectAttempts = 0;\n private reconnecting = false;\n private dataHandlers: TcpDataHandler[] = [];\n private eventHandlers: Map<string, TcpEventHandler[]> = new Map();\n\n constructor(options: TcpPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to a TCP server (client mode)\n */\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.socket = createConnection({\n host: this.config.host,\n port: this.config.port,\n });\n\n this.socket.setEncoding(this.config.encoding ?? 'utf8');\n\n this.socket.on('connect', () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.reconnecting = false;\n this.emit('connected');\n resolve();\n });\n\n this.socket.on('data', (data) => {\n this.handleData(data);\n });\n\n this.socket.on('close', () => {\n this.connected = false;\n this.emit('disconnected');\n this.handleDisconnect();\n });\n\n this.socket.on('error', (error) => {\n if (!this.connected) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.socket.on('end', () => {\n this.connected = false;\n this.emit('end');\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Start a TCP server (server mode)\n */\n async listen(port?: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.server = createServer((socket) => {\n socket.setEncoding(this.config.encoding ?? 'utf8');\n\n socket.on('data', (data) => {\n this.handleData(data);\n });\n\n socket.on('error', (error) => {\n this.emit('client_error', error);\n });\n\n this.emit('connection', socket);\n });\n\n this.server.on('error', (error) => {\n reject(error);\n });\n\n this.server.listen(port ?? this.config.port, () => {\n this.connected = true;\n this.emit('listening');\n resolve();\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect / close\n */\n async disconnect(): Promise<void> {\n this.reconnecting = false;\n\n return new Promise((resolve) => {\n if (this.socket) {\n this.socket.end(() => {\n this.socket?.destroy();\n this.socket = null;\n this.connected = false;\n resolve();\n });\n } else if (this.server) {\n this.server.close(() => {\n this.server = null;\n this.connected = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Send data\n */\n async send(data: Buffer | string): Promise<PipeResponse> {\n if (!this.socket || !this.connected) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.socket!.write(data, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Send and wait for response (request-response pattern)\n */\n async request<T = string>(\n data: Buffer | string,\n options: { timeout?: number } = {}\n ): Promise<PipeResponse<T>> {\n const { timeout = 30000 } = options;\n\n if (!this.socket || !this.connected) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n this.offData(handler);\n resolve({ success: false, error: 'Request timeout' });\n }, timeout);\n\n const handler = (response: Buffer | string) => {\n clearTimeout(timer);\n this.offData(handler);\n resolve({ success: true, data: response as T });\n };\n\n this.onData(handler);\n this.send(data);\n });\n }\n\n /**\n * Register a data handler\n */\n onData(handler: TcpDataHandler): void {\n this.dataHandlers.push(handler);\n }\n\n /**\n * Remove a data handler\n */\n offData(handler: TcpDataHandler): void {\n const index = this.dataHandlers.indexOf(handler);\n if (index !== -1) {\n this.dataHandlers.splice(index, 1);\n }\n }\n\n /**\n * Register an event handler\n */\n on(event: string, handler: TcpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: string, handler: TcpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data?: unknown): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`TCP handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming data\n */\n private handleData(data: Buffer | string): void {\n for (const handler of this.dataHandlers) {\n try {\n handler(data);\n } catch (error) {\n console.error('TCP data handler error:', error);\n }\n }\n this.emit('data', data);\n }\n\n /**\n * Handle disconnection with reconnect logic\n */\n private handleDisconnect(): void {\n if (!this.config.reconnect?.enabled || this.reconnecting) {\n return;\n }\n\n const maxAttempts = this.config.reconnect.max_attempts ?? 10;\n const delay = this.parseDuration(this.config.reconnect.delay ?? '5s');\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.emit('reconnect_failed', { attempts: this.reconnectAttempts });\n return;\n }\n\n this.reconnecting = true;\n this.reconnectAttempts++;\n\n setTimeout(async () => {\n try {\n await this.connect();\n this.emit('reconnected', { attempts: this.reconnectAttempts });\n } catch {\n this.reconnecting = false;\n this.handleDisconnect();\n }\n }, delay);\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 5000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create a TCP pipe\n */\nexport function createTcpPipe(options: TcpPipeOptions): TcpPipe {\n return new TcpPipe(options);\n}\n\n// Re-export UDP pipe\nexport * from './udp.js';\n","/**\n * UDP pipe for datagram communication\n */\n\nimport { createSocket, Socket, RemoteInfo } from 'dgram';\nimport type { Pipe, PipeResponse, UdpPipeConfig } from '../types.js';\n\nexport interface UdpPipeOptions {\n name: string;\n config: UdpPipeConfig;\n}\n\nexport interface UdpMessage {\n data: Buffer;\n rinfo: RemoteInfo;\n}\n\nexport type UdpMessageHandler = (msg: UdpMessage) => void | Promise<void>;\nexport type UdpEventHandler = (data?: unknown) => void | Promise<void>;\n\nexport class UdpPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'udp';\n private socket: Socket | null = null;\n private config: UdpPipeConfig;\n private bound = false;\n private messageHandlers: UdpMessageHandler[] = [];\n private eventHandlers: Map<string, UdpEventHandler[]> = new Map();\n\n constructor(options: UdpPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Bind to a port to receive messages\n */\n async bind(port?: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.socket = createSocket('udp4');\n\n this.socket.on('message', (msg, rinfo) => {\n this.handleMessage(msg, rinfo);\n });\n\n this.socket.on('error', (error) => {\n if (!this.bound) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.socket.on('listening', () => {\n this.bound = true;\n const address = this.socket!.address();\n this.emit('listening', address);\n resolve();\n });\n\n // Setup broadcast if configured\n if (this.config.broadcast) {\n this.socket.setBroadcast(true);\n }\n\n // Bind to port\n const bindPort = port ?? this.config.port;\n const bindHost = this.config.host ?? '0.0.0.0';\n this.socket.bind(bindPort, bindHost, () => {\n // Join multicast group if configured\n if (this.config.multicast) {\n this.socket!.addMembership(this.config.multicast);\n }\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Close the socket\n */\n async disconnect(): Promise<void> {\n return new Promise((resolve) => {\n if (this.socket) {\n this.socket.close(() => {\n this.socket = null;\n this.bound = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if bound\n */\n isConnected(): boolean {\n return this.bound;\n }\n\n /**\n * Send data to a specific host and port\n */\n async send(\n data: Buffer | string,\n host: string,\n port: number\n ): Promise<PipeResponse> {\n if (!this.socket) {\n // Create socket if not exists (for send-only mode)\n this.socket = createSocket('udp4');\n if (this.config.broadcast) {\n this.socket.setBroadcast(true);\n }\n }\n\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n\n return new Promise((resolve) => {\n this.socket!.send(buffer, port, host, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Broadcast data to all hosts on the network\n */\n async broadcast(\n data: Buffer | string,\n port: number,\n address = '255.255.255.255'\n ): Promise<PipeResponse> {\n if (!this.socket) {\n this.socket = createSocket('udp4');\n this.socket.setBroadcast(true);\n }\n\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n\n return new Promise((resolve) => {\n this.socket!.send(buffer, port, address, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Send to multicast group\n */\n async multicast(\n data: Buffer | string,\n port: number,\n group?: string\n ): Promise<PipeResponse> {\n const multicastGroup = group ?? this.config.multicast;\n if (!multicastGroup) {\n return { success: false, error: 'No multicast group configured' };\n }\n\n return this.send(data, multicastGroup, port);\n }\n\n /**\n * Register a message handler\n */\n onMessage(handler: UdpMessageHandler): void {\n this.messageHandlers.push(handler);\n }\n\n /**\n * Remove a message handler\n */\n offMessage(handler: UdpMessageHandler): void {\n const index = this.messageHandlers.indexOf(handler);\n if (index !== -1) {\n this.messageHandlers.splice(index, 1);\n }\n }\n\n /**\n * Register an event handler\n */\n on(event: string, handler: UdpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: string, handler: UdpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data?: unknown): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`UDP handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming messages\n */\n private handleMessage(data: Buffer, rinfo: RemoteInfo): void {\n const msg: UdpMessage = { data, rinfo };\n\n for (const handler of this.messageHandlers) {\n try {\n handler(msg);\n } catch (error) {\n console.error('UDP message handler error:', error);\n }\n }\n\n this.emit('message', msg);\n }\n}\n\n/**\n * Create a UDP pipe\n */\nexport function createUdpPipe(options: UdpPipeOptions): UdpPipe {\n return new UdpPipe(options);\n}\n"],"mappings":"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","names":[]}
|