@bobfrankston/rmfudp 0.1.0 → 0.1.2
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/.gitattributes +5 -0
- package/address.d.ts.map +1 -1
- package/address.js +4 -1
- package/address.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +12 -4
- package/socket.d.ts.map +1 -1
- package/socket.js +15 -3
- package/socket.js.map +1 -1
- package/types.d.ts +2 -1
- package/types.d.ts.map +1 -1
- package/util.d.ts +16 -0
- package/util.d.ts.map +1 -0
- package/util.js +31 -0
- package/util.js.map +1 -0
- package/address.ts +0 -44
- package/index.ts +0 -3
- package/socket.ts +0 -147
- package/tsconfig.json +0 -20
- package/types.ts +0 -25
package/.gitattributes
ADDED
package/address.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,IAAI,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,IAAI,WAAW,EAAE,CAsBpD;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,gDAAgD;AAChD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD"}
|
package/address.js
CHANGED
|
@@ -4,7 +4,10 @@ export function getNetworkInterfaces() {
|
|
|
4
4
|
const result = [];
|
|
5
5
|
const netifs = os.networkInterfaces();
|
|
6
6
|
for (const name in netifs) {
|
|
7
|
-
|
|
7
|
+
const infos = netifs[name];
|
|
8
|
+
if (!infos)
|
|
9
|
+
continue;
|
|
10
|
+
for (const info of infos) {
|
|
8
11
|
if (info.family !== 'IPv4' || info.internal)
|
|
9
12
|
continue;
|
|
10
13
|
if (info.address.startsWith('169.254.'))
|
package/address.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.js","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAU9B,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB;IAChC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QACxB,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAU9B,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB;IAChC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACtD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;gBAAE,SAAS,CAAE,iBAAiB;YAErE,MAAM,CAAC,IAAI,CAAC;gBACR,IAAI;gBACJ,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC;gBACvD,GAAG,EAAE,IAAI,CAAC,GAAG;aAChB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAe;IAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,qBAAqB;IACjC,OAAO,oBAAoB,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AAC1D,CAAC"}
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './types.js';
|
|
2
2
|
export { UdpSocket } from './socket.js';
|
|
3
3
|
export { getNetworkInterfaces, getBroadcastAddresses, computeBroadcast, NetworkInfo } from './address.js';
|
|
4
|
+
export { textToBuffer, bufferToText, jsonToBuffer, bufferToJson, hexToBuffer, bufferToHex } from './util.js';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './types.js';
|
|
2
2
|
export { UdpSocket } from './socket.js';
|
|
3
3
|
export { getNetworkInterfaces, getBroadcastAddresses, computeBroadcast } from './address.js';
|
|
4
|
+
export { textToBuffer, bufferToText, jsonToBuffer, bufferToJson, hexToBuffer, bufferToHex } from './util.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAe,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAe,MAAM,cAAc,CAAC;AAC1G,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/rmfudp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Generic UDP transport with port sharing, retry logic, and configurable timeouts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -13,15 +13,23 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "tsc",
|
|
16
|
-
"watch": "tsc -w"
|
|
16
|
+
"watch": "tsc -w",
|
|
17
|
+
"preversion": "npm run build",
|
|
18
|
+
"postversion": "git push && git push --tags && npm publish",
|
|
19
|
+
"release": "git add -A && git diff-index --quiet HEAD || git commit -m 'Build for release' && npm version patch"
|
|
17
20
|
},
|
|
18
|
-
"keywords": [
|
|
21
|
+
"keywords": [
|
|
22
|
+
"udp",
|
|
23
|
+
"socket",
|
|
24
|
+
"retry",
|
|
25
|
+
"broadcast"
|
|
26
|
+
],
|
|
19
27
|
"license": "MIT",
|
|
20
28
|
"repository": {
|
|
21
29
|
"type": "git",
|
|
22
30
|
"url": "https://github.com/BobFrankston/rmfudp.git"
|
|
23
31
|
},
|
|
24
32
|
"devDependencies": {
|
|
25
|
-
"@types/node": "
|
|
33
|
+
"@types/node": "^25.0.6"
|
|
26
34
|
}
|
|
27
35
|
}
|
package/socket.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ3E,qBAAa,SAAU,SAAQ,YAAY;IACvC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAE/B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAoC;gBAE/C,OAAO,GAAE,gBAAqB;
|
|
1
|
+
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ3E,qBAAa,SAAU,SAAQ,YAAY;IACvC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,KAAK,CAAkB;IAE/B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAoC;gBAE/C,OAAO,GAAE,gBAAqB;IAsC1C,wCAAwC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBrB,mBAAmB;IACnB,KAAK,IAAI,IAAI;IAMb,qBAAqB;IACrB,OAAO,IAAI,MAAM;IAIjB,mCAAmC;IACnC,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAM/C,gCAAgC;IAChC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC;IAQ5C,sDAAsD;IACtD,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUlD,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5C,wEAAwE;IACxE,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;CAoC7H"}
|
package/socket.js
CHANGED
|
@@ -15,11 +15,23 @@ export class UdpSocket extends EventEmitter {
|
|
|
15
15
|
responseTimeout = DEFAULT_RESPONSE_TIMEOUT;
|
|
16
16
|
constructor(options = {}) {
|
|
17
17
|
super();
|
|
18
|
-
|
|
18
|
+
// Multi-instance handling: When reuseAddr is enabled and a non-zero port is requested,
|
|
19
|
+
// use ephemeral port (0) instead to ensure each instance can receive all responses.
|
|
20
|
+
// Windows doesn't reliably deliver unicast UDP to all sockets on same port.
|
|
21
|
+
const requestedPort = options.port ?? DEFAULT_PORT;
|
|
22
|
+
const enableMultiInstance = (options.reuseAddr ?? true) && requestedPort !== 0;
|
|
23
|
+
this.port = enableMultiInstance && options.multiInstance !== false ? 0 : requestedPort;
|
|
19
24
|
this.broadcastAddr = options.broadcastAddr ?? DEFAULT_BROADCAST;
|
|
25
|
+
// When using ephemeral ports (0), don't set reuseAddr/reusePort as they're not needed
|
|
26
|
+
// and cause ENOTSUP on Windows. Each instance gets a unique port automatically.
|
|
27
|
+
const usePortReuse = this.port !== 0 && (options.reuseAddr ?? true);
|
|
20
28
|
this.socket = dgram.createSocket({
|
|
21
29
|
type: 'udp4',
|
|
22
|
-
reuseAddr:
|
|
30
|
+
reuseAddr: usePortReuse,
|
|
31
|
+
// On Windows, SO_REUSEPORT is needed for multiple processes to receive
|
|
32
|
+
// UDP broadcasts/multicasts on the same port. Without it, only one process
|
|
33
|
+
// receives the packets even with reuseAddr enabled.
|
|
34
|
+
reusePort: usePortReuse
|
|
23
35
|
});
|
|
24
36
|
this.socket.on('message', (msg, rinfo) => {
|
|
25
37
|
this.emit('message', msg, rinfo);
|
|
@@ -112,7 +124,7 @@ export class UdpSocket extends EventEmitter {
|
|
|
112
124
|
attempts++;
|
|
113
125
|
if (attempts > this.retryCount) {
|
|
114
126
|
this.removeListener('message', onMessage);
|
|
115
|
-
reject(new Error(`No response after ${this.retryCount} retries`));
|
|
127
|
+
reject(new Error(`No response from ${ip}:${port} after ${this.retryCount} retries`));
|
|
116
128
|
return;
|
|
117
129
|
}
|
|
118
130
|
this.send(ip, port, data);
|
package/socket.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.js","sourceRoot":"","sources":["socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAC5C,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC,MAAM,OAAO,SAAU,SAAQ,YAAY;IAC/B,MAAM,CAAe;IACrB,IAAI,CAAS;IACb,aAAa,CAAS;IACtB,KAAK,GAAY,KAAK,CAAC;IAEvB,UAAU,GAAW,mBAAmB,CAAC;IACzC,UAAU,GAAW,mBAAmB,CAAC;IACzC,eAAe,GAAW,wBAAwB,CAAC;IAE3D,YAAY,UAA4B,EAAE;QACtC,KAAK,EAAE,CAAC;QACR,
|
|
1
|
+
{"version":3,"file":"socket.js","sourceRoot":"","sources":["socket.ts"],"names":[],"mappings":"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"}
|
package/types.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export interface UdpSocketOptions {
|
|
2
2
|
port?: number; /** default 0 (ephemeral) */
|
|
3
|
-
reuseAddr?: boolean; /** default true for port sharing */
|
|
3
|
+
reuseAddr?: boolean; /** default true for port sharing (also enables reusePort on supported platforms) */
|
|
4
4
|
broadcastAddr?: string; /** default "255.255.255.255" */
|
|
5
|
+
multiInstance?: boolean; /** default true - automatically use ephemeral ports when reuseAddr=true to ensure all instances receive responses (set false to force requested port) */
|
|
5
6
|
}
|
|
6
7
|
export interface UdpRetryOptions {
|
|
7
8
|
retryCount?: number; /** default 3 */
|
package/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,CAAE,4BAA4B;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC,CAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,CAAE,4BAA4B;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC,CAAE,oFAAoF;IAC1G,aAAa,CAAC,EAAE,MAAM,CAAC,CAAE,gCAAgC;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC,CAAE,yJAAyJ;CACtL;AAED,MAAM,WAAW,eAAe;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,CAAE,gBAAgB;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAE,sCAAsC;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC,CAAE,4CAA4C;CAC1E;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACnD,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CACrB"}
|
package/util.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for buffer/text conversion
|
|
3
|
+
*/
|
|
4
|
+
/** Convert string to Buffer (UTF-8) */
|
|
5
|
+
export declare function textToBuffer(text: string): Buffer;
|
|
6
|
+
/** Convert Buffer to string (UTF-8) */
|
|
7
|
+
export declare function bufferToText(buf: Buffer): string;
|
|
8
|
+
/** Convert JSON object to Buffer */
|
|
9
|
+
export declare function jsonToBuffer(obj: object): Buffer;
|
|
10
|
+
/** Parse Buffer as JSON object */
|
|
11
|
+
export declare function bufferToJson<T = object>(buf: Buffer): T;
|
|
12
|
+
/** Convert hex string to Buffer */
|
|
13
|
+
export declare function hexToBuffer(hex: string): Buffer;
|
|
14
|
+
/** Convert Buffer to hex string */
|
|
15
|
+
export declare function bufferToHex(buf: Buffer, separator?: string): string;
|
|
16
|
+
//# sourceMappingURL=util.d.ts.map
|
package/util.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,oCAAoC;AACpC,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,kCAAkC;AAClC,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAEvD;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,MAAM,CAIvE"}
|
package/util.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for buffer/text conversion
|
|
3
|
+
*/
|
|
4
|
+
/** Convert string to Buffer (UTF-8) */
|
|
5
|
+
export function textToBuffer(text) {
|
|
6
|
+
return Buffer.from(text, 'utf8');
|
|
7
|
+
}
|
|
8
|
+
/** Convert Buffer to string (UTF-8) */
|
|
9
|
+
export function bufferToText(buf) {
|
|
10
|
+
return buf.toString('utf8');
|
|
11
|
+
}
|
|
12
|
+
/** Convert JSON object to Buffer */
|
|
13
|
+
export function jsonToBuffer(obj) {
|
|
14
|
+
return textToBuffer(JSON.stringify(obj));
|
|
15
|
+
}
|
|
16
|
+
/** Parse Buffer as JSON object */
|
|
17
|
+
export function bufferToJson(buf) {
|
|
18
|
+
return JSON.parse(bufferToText(buf));
|
|
19
|
+
}
|
|
20
|
+
/** Convert hex string to Buffer */
|
|
21
|
+
export function hexToBuffer(hex) {
|
|
22
|
+
return Buffer.from(hex.replace(/[^0-9a-fA-F]/g, ''), 'hex');
|
|
23
|
+
}
|
|
24
|
+
/** Convert Buffer to hex string */
|
|
25
|
+
export function bufferToHex(buf, separator = '') {
|
|
26
|
+
const hex = buf.toString('hex');
|
|
27
|
+
if (!separator)
|
|
28
|
+
return hex;
|
|
29
|
+
return hex.match(/.{2}/g)?.join(separator) ?? '';
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=util.js.map
|
package/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,MAAM,UAAU,YAAY,CAAC,IAAY;IACrC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,YAAY,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,YAAY,CAAC,GAAW;IACpC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,YAAY,CAAa,GAAW;IAChD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,WAAW,CAAC,GAAW;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,YAAoB,EAAE;IAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,SAAS;QAAE,OAAO,GAAG,CAAC;IAC3B,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC"}
|
package/address.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as os from 'node:os';
|
|
2
|
-
|
|
3
|
-
export interface NetworkInfo {
|
|
4
|
-
name: string;
|
|
5
|
-
address: string;
|
|
6
|
-
netmask: string;
|
|
7
|
-
broadcast: string;
|
|
8
|
-
mac: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Get all IPv4 network interfaces with broadcast addresses */
|
|
12
|
-
export function getNetworkInterfaces(): NetworkInfo[] {
|
|
13
|
-
const result: NetworkInfo[] = [];
|
|
14
|
-
const netifs = os.networkInterfaces();
|
|
15
|
-
|
|
16
|
-
for (const name in netifs) {
|
|
17
|
-
for (const info of netifs[name]) {
|
|
18
|
-
if (info.family !== 'IPv4' || info.internal) continue;
|
|
19
|
-
if (info.address.startsWith('169.254.')) continue; /** link-local */
|
|
20
|
-
|
|
21
|
-
result.push({
|
|
22
|
-
name,
|
|
23
|
-
address: info.address,
|
|
24
|
-
netmask: info.netmask,
|
|
25
|
-
broadcast: computeBroadcast(info.address, info.netmask),
|
|
26
|
-
mac: info.mac
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Compute broadcast address from IP and netmask */
|
|
34
|
-
export function computeBroadcast(address: string, netmask: string): string {
|
|
35
|
-
const addrParts = address.split('.').map(n => parseInt(n, 10));
|
|
36
|
-
const maskParts = netmask.split('.').map(n => parseInt(n, 10));
|
|
37
|
-
const broadcastParts = addrParts.map((a, i) => (~maskParts[i] & 0xff) | a);
|
|
38
|
-
return broadcastParts.join('.');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Get all broadcast addresses for discovery */
|
|
42
|
-
export function getBroadcastAddresses(): string[] {
|
|
43
|
-
return getNetworkInterfaces().map(ni => ni.broadcast);
|
|
44
|
-
}
|
package/index.ts
DELETED
package/socket.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import dgram from 'node:dgram';
|
|
2
|
-
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { UdpSocketOptions, UdpRetryOptions, RemoteInfo } from './types.js';
|
|
4
|
-
|
|
5
|
-
const DEFAULT_PORT = 0;
|
|
6
|
-
const DEFAULT_BROADCAST = '255.255.255.255';
|
|
7
|
-
const DEFAULT_RETRY_COUNT = 3;
|
|
8
|
-
const DEFAULT_RETRY_DELAY = 100;
|
|
9
|
-
const DEFAULT_RESPONSE_TIMEOUT = 1000;
|
|
10
|
-
|
|
11
|
-
export class UdpSocket extends EventEmitter {
|
|
12
|
-
private socket: dgram.Socket;
|
|
13
|
-
private port: number;
|
|
14
|
-
private broadcastAddr: string;
|
|
15
|
-
private bound: boolean = false;
|
|
16
|
-
|
|
17
|
-
private retryCount: number = DEFAULT_RETRY_COUNT;
|
|
18
|
-
private retryDelay: number = DEFAULT_RETRY_DELAY;
|
|
19
|
-
private responseTimeout: number = DEFAULT_RESPONSE_TIMEOUT;
|
|
20
|
-
|
|
21
|
-
constructor(options: UdpSocketOptions = {}) {
|
|
22
|
-
super();
|
|
23
|
-
this.port = options.port ?? DEFAULT_PORT;
|
|
24
|
-
this.broadcastAddr = options.broadcastAddr ?? DEFAULT_BROADCAST;
|
|
25
|
-
|
|
26
|
-
this.socket = dgram.createSocket({
|
|
27
|
-
type: 'udp4',
|
|
28
|
-
reuseAddr: options.reuseAddr ?? true
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
this.socket.on('message', (msg: Buffer, rinfo: dgram.RemoteInfo) => {
|
|
32
|
-
this.emit('message', msg, rinfo as RemoteInfo);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
this.socket.on('error', (err: Error) => {
|
|
36
|
-
this.emit('error', err);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
this.socket.on('close', () => {
|
|
40
|
-
this.bound = false;
|
|
41
|
-
this.emit('close');
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Bind to port and enable broadcast */
|
|
46
|
-
bind(): Promise<void> {
|
|
47
|
-
return new Promise((resolve, reject) => {
|
|
48
|
-
if (this.bound) {
|
|
49
|
-
resolve();
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this.socket.once('error', reject);
|
|
54
|
-
|
|
55
|
-
this.socket.bind(this.port, () => {
|
|
56
|
-
this.socket.removeListener('error', reject);
|
|
57
|
-
this.socket.setBroadcast(true);
|
|
58
|
-
this.bound = true;
|
|
59
|
-
this.port = this.socket.address().port;
|
|
60
|
-
this.emit('bound');
|
|
61
|
-
resolve();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** Close socket */
|
|
67
|
-
close(): void {
|
|
68
|
-
if (this.bound) {
|
|
69
|
-
this.socket.close();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Get bound port */
|
|
74
|
-
getPort(): number {
|
|
75
|
-
return this.port;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Set retry options at runtime */
|
|
79
|
-
setRetryOptions(options: UdpRetryOptions): void {
|
|
80
|
-
if (options.retryCount !== undefined) this.retryCount = options.retryCount;
|
|
81
|
-
if (options.retryDelay !== undefined) this.retryDelay = options.retryDelay;
|
|
82
|
-
if (options.responseTimeout !== undefined) this.responseTimeout = options.responseTimeout;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** Get current retry options */
|
|
86
|
-
getRetryOptions(): Required<UdpRetryOptions> {
|
|
87
|
-
return {
|
|
88
|
-
retryCount: this.retryCount,
|
|
89
|
-
retryDelay: this.retryDelay,
|
|
90
|
-
responseTimeout: this.responseTimeout
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Send data to specific address (fire-and-forget) */
|
|
95
|
-
send(ip: string, port: number, data: Buffer): void {
|
|
96
|
-
if (!this.bound) {
|
|
97
|
-
this.emit('error', new Error('Socket not bound'));
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
this.socket.send(data, 0, data.length, port, ip, (err) => {
|
|
101
|
-
if (err) this.emit('error', err);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/** Broadcast data (fire-and-forget) */
|
|
106
|
-
broadcast(data: Buffer, port?: number): void {
|
|
107
|
-
this.send(this.broadcastAddr, port ?? this.port, data);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** Send with retry - resolves when ack received or retries exhausted */
|
|
111
|
-
sendWithRetry(ip: string, port: number, data: Buffer, isAck: (msg: Buffer, rinfo: RemoteInfo) => boolean): Promise<Buffer> {
|
|
112
|
-
return new Promise((resolve, reject) => {
|
|
113
|
-
let attempts = 0;
|
|
114
|
-
let timeoutHandle: NodeJS.Timeout;
|
|
115
|
-
let resolved = false;
|
|
116
|
-
|
|
117
|
-
const onMessage = (msg: Buffer, rinfo: RemoteInfo) => {
|
|
118
|
-
if (rinfo.address === ip && isAck(msg, rinfo)) {
|
|
119
|
-
resolved = true;
|
|
120
|
-
clearTimeout(timeoutHandle);
|
|
121
|
-
this.removeListener('message', onMessage);
|
|
122
|
-
resolve(msg);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const attempt = () => {
|
|
127
|
-
if (resolved) return;
|
|
128
|
-
|
|
129
|
-
attempts++;
|
|
130
|
-
if (attempts > this.retryCount) {
|
|
131
|
-
this.removeListener('message', onMessage);
|
|
132
|
-
reject(new Error(`No response after ${this.retryCount} retries`));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.send(ip, port, data);
|
|
137
|
-
|
|
138
|
-
timeoutHandle = setTimeout(() => {
|
|
139
|
-
if (!resolved) attempt();
|
|
140
|
-
}, attempts === 1 ? this.responseTimeout : this.retryDelay);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
this.on('message', onMessage);
|
|
144
|
-
attempt();
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "esnext",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"allowSyntheticDefaultImports": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"declarationMap": true,
|
|
13
|
-
"sourceMap": true,
|
|
14
|
-
"strictNullChecks": false,
|
|
15
|
-
"noImplicitAny": true,
|
|
16
|
-
"noImplicitThis": true,
|
|
17
|
-
"newLine": "lf"
|
|
18
|
-
},
|
|
19
|
-
"exclude": ["node_modules", "cruft", ".git", "tests", "prev"]
|
|
20
|
-
}
|
package/types.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export interface UdpSocketOptions {
|
|
2
|
-
port?: number; /** default 0 (ephemeral) */
|
|
3
|
-
reuseAddr?: boolean; /** default true for port sharing */
|
|
4
|
-
broadcastAddr?: string; /** default "255.255.255.255" */
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface UdpRetryOptions {
|
|
8
|
-
retryCount?: number; /** default 3 */
|
|
9
|
-
retryDelay?: number; /** ms between retries, default 100 */
|
|
10
|
-
responseTimeout?: number; /** ms to wait for response, default 1000 */
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface RemoteInfo {
|
|
14
|
-
address: string;
|
|
15
|
-
port: number;
|
|
16
|
-
family: 'IPv4' | 'IPv6';
|
|
17
|
-
size: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface UdpSocketEvents {
|
|
21
|
-
message: (data: Buffer, rinfo: RemoteInfo) => void;
|
|
22
|
-
error: (err: Error) => void;
|
|
23
|
-
bound: () => void;
|
|
24
|
-
close: () => void;
|
|
25
|
-
}
|