iosignal 5.2.0 → 6.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.
Files changed (40) hide show
  1. package/README.md +163 -0
  2. package/dist/browser/esm/io.d.ts +17 -12
  3. package/dist/browser/esm/io.js +5 -5
  4. package/dist/browser/esm/io.js.map +1 -1
  5. package/dist/browser/iife/io.js +5 -5
  6. package/dist/browser/iife/io.js.map +1 -1
  7. package/dist/node/iosignal.cjs +195 -550
  8. package/dist/node/iosignal.js +193 -548
  9. package/dist/types/client/IOCore.d.ts +11 -5
  10. package/dist/types/client/browser/IOWebSocket.d.ts +4 -4
  11. package/dist/types/common/payload.d.ts +2 -2
  12. package/package.json +22 -4
  13. package/.vscode/settings.json +0 -3
  14. package/index.js +0 -26
  15. package/rollup.config.js +0 -59
  16. package/src/auth/BohoAuth.js +0 -196
  17. package/src/auth/key_providers/FileKeyProvider.js +0 -59
  18. package/src/auth/key_providers/RedisKeyProvider.js +0 -46
  19. package/src/auth/key_providers/StringKeyProvider.js +0 -54
  20. package/src/client/CongPacket.js +0 -143
  21. package/src/client/IOCongSocket.js +0 -92
  22. package/src/client/IOCore.js +0 -1202
  23. package/src/client/IOWS.js +0 -78
  24. package/src/client/browser/IOWebSocket.js +0 -202
  25. package/src/common/constants.js +0 -210
  26. package/src/common/payload.js +0 -82
  27. package/src/common/quotaTable.js +0 -68
  28. package/src/common/util.js +0 -64
  29. package/src/server/FileLogger.js +0 -30
  30. package/src/server/Manager.js +0 -450
  31. package/src/server/Metrics.js +0 -155
  32. package/src/server/Remote.js +0 -216
  33. package/src/server/RemoteCore.js +0 -427
  34. package/src/server/Server.js +0 -236
  35. package/src/server/serverOption.js +0 -56
  36. package/src/services/RedisService.js +0 -53
  37. package/src/services/constant.js +0 -7
  38. package/src/services/replyService.js +0 -39
  39. package/src/services/sudoService.js +0 -85
  40. package/tsconfig.json +0 -25
@@ -1,78 +0,0 @@
1
- import { IOCore } from "./IOCore.js";
2
- import { SIZE_LIMIT } from "../common/constants.js";
3
- import { WebSocket } from "ws";
4
-
5
- // Node.js 'ws' websocket
6
- export class IOWS extends IOCore {
7
- constructor(url) {
8
- super(url);
9
- if (url) this.open();
10
- }
11
-
12
-
13
-
14
- /**
15
- * Closes ws WebSocket and cleans resources.
16
- */
17
- close() {
18
- if (this.socket) {
19
- this.socket.removeAllListeners();
20
- if (this.socket.readyState !== WebSocket.CLOSED) {
21
- this.socket.close();
22
- }
23
- }
24
- super.close();
25
- }
26
-
27
- keepConnection() {
28
- if (!this.autoReconnect) return;
29
- // Reconnect only if the socket is closed and the state reflects that.
30
- if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
31
- this.open();
32
- }
33
- }
34
-
35
-
36
-
37
- createConnection(url) {
38
- // node WebSocket
39
- this.socket = new WebSocket(url);
40
- this.stateChange('connecting','connecting')
41
-
42
- this.socket.onopen = () => {
43
- this.socket.on('message', this.onWebSocketMessage.bind(this));
44
- this.emit('open');
45
- };
46
-
47
- this.socket.onerror = (e) => {
48
- this.emit('error', e)
49
- }
50
-
51
- this.socket.onclose = () => {
52
- this.emit('close');
53
- }
54
- }
55
-
56
- onWebSocketMessage(data) {
57
- this.rxCounter++;
58
- this.lastTxRxTime = Date.now();
59
- this.rxBytes += data.byteLength
60
- this.emit('socket_data', data);
61
- }
62
-
63
- socket_send(data) {
64
- if (this.socket?.readyState === 1) {
65
- this.socket.send(data)
66
- this.txCounter++;
67
- this.txBytes += data.byteLength
68
- this.lastTxRxTime = Date.now();
69
- } else {
70
- console.log('.')
71
- }
72
- }
73
-
74
- }
75
-
76
-
77
-
78
-
@@ -1,202 +0,0 @@
1
- import {version} from "../../../package.json";
2
- import { IOCore } from "../IOCore.js";
3
- import Boho from 'boho'
4
- import * as constants from '../../common/constants.js'
5
-
6
- /**
7
- * @typedef {import("boho").Boho} Boho
8
- * @typedef {import("boho").MBP} MBP
9
- * @typedef {import("boho").Buffer} Buffer
10
- */
11
-
12
- const Buffer = Boho.Buffer
13
-
14
- /**
15
- * Browser WebSocket client extending IOCore.
16
- * @augments {IOCore}
17
- */
18
- export default class IO extends IOCore {
19
- /**
20
- * The version of the client.
21
- * @type {string}
22
- */
23
- static version = version
24
- /**
25
- * The binary type for WebSocket messages.
26
- * @type {string}
27
- */
28
- static binaryType = "arraybuffer"
29
- /**
30
- * The Boho library instance.
31
- * @type {Boho}
32
- */
33
- static Boho = Boho;
34
- /**
35
- * The MBP (MessagePack-Boho) instance.
36
- * @type {MBP}
37
- */
38
- static MBP = Boho.MBP;
39
- /**
40
- * The Buffer class from Boho.
41
- * @type {Buffer}
42
- */
43
- static Buffer = Boho.Buffer;
44
- /**
45
- * Constants used by the client.
46
- * @type {object}
47
- */
48
- static constants = constants
49
-
50
- /**
51
- * Tracks the number of IO instances created.
52
- * @type {number}
53
- */
54
- static instanceCount = 0;
55
-
56
- /**
57
- * Tracks the number of WebSocket objects created.
58
- * @type {number}
59
- */
60
- static webSocketCount = 0;
61
-
62
-
63
-
64
- /**
65
- * Creates an instance of IO.
66
- * @param {string} url - The WebSocket URL to connect to.
67
- */
68
- constructor(url) {
69
- super(url);
70
- IO.instanceCount++;
71
- this.boundBrowserVisiblePing = this.browserVisiblePing.bind(this)
72
- document.addEventListener('visibilitychange', this.boundBrowserVisiblePing);
73
- if (url) this.open();
74
- }
75
-
76
- /**
77
- * Pings the server when the browser tab becomes visible.
78
- */
79
- browserVisiblePing() {
80
- if (document.visibilityState === 'visible') {
81
- this.ping()
82
- }
83
- }
84
-
85
-
86
-
87
-
88
- /**
89
- * Permanently stops the connection and cleans up its specific resources.
90
- * For complete cleanup and to make the instance unusable, use destroy().
91
- */
92
- stop() {
93
- super.stop();
94
- }
95
-
96
- /**
97
- * Permanently destroys the instance, cleaning up all resources including global event listeners.
98
- * The instance will not be usable after this.
99
- */
100
- destroy() {
101
- document.removeEventListener('visibilitychange', this.boundBrowserVisiblePing);
102
- super.destroy();
103
- }
104
-
105
-
106
- /**
107
- * Keeps the connection alive by re-connecting if closed.
108
- */
109
- keepConnection() {
110
- if (!this.autoReconnect) return;
111
- // Reconnect only if the socket is closed and the state reflects that.
112
- if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
113
- this.open();
114
- }
115
- }
116
-
117
-
118
-
119
- /**
120
- * Creates a new WebSocket connection.
121
- * @param {string} url - The WebSocket URL to connect to.
122
- */
123
- createConnection(url) {
124
- // Web Browser WebSocket
125
- IO.webSocketCount++;
126
- this.socket = new WebSocket(url);
127
- this.socket.binaryType = IO.binaryType
128
-
129
- this.stateChange('connecting','connecting')
130
-
131
- this.socket.onopen = () => {
132
-
133
- if (!this.socket) {
134
- return;
135
- }
136
-
137
- if (this.socket.binaryType == "arraybuffer") {
138
- this.socket.onmessage = this.onWebSocketMessage.bind(this);
139
- } else { // blob
140
- this.socket.onmessage = this.onWebSocketMessageBlob.bind(this);
141
- }
142
- this.emit('open');
143
- };
144
-
145
- this.socket.onerror = (e) => {
146
- this.emit('error', e)
147
- }
148
-
149
- this.socket.onclose = () => {
150
- this.emit('close');
151
- }
152
- }
153
-
154
- /**
155
- * Handles incoming WebSocket messages (arraybuffer type).
156
- * @param {MessageEvent} event - The WebSocket message event.
157
- */
158
- onWebSocketMessage(event) {
159
- // event.data is arrayBuffer or text_message
160
- this.rxCounter++;
161
- this.lastTxRxTime = Date.now();
162
- let buffer = Buffer.from(event.data)
163
- this.rxBytes += buffer.byteLength
164
- this.emit('socket_data', buffer);
165
- }
166
-
167
- /**
168
- * Handles incoming WebSocket messages (blob type).
169
- * @param {MessageEvent} event - The WebSocket message event.
170
- */
171
- async onWebSocketMessageBlob(event) {
172
- // event.data is Blob or text_message
173
- this.rxCounter++;
174
- this.lastTxRxTime = Date.now();
175
- let buffer;
176
- if (event.data instanceof Blob) {
177
- let ab = await event.data.arrayBuffer()
178
- buffer = Buffer.from(ab)
179
- } else {
180
- buffer = Buffer.from(event.data)
181
- }
182
- this.rxBytes += buffer.byteLength
183
- this.emit('socket_data', buffer);
184
- }
185
-
186
- /**
187
- * Sends data over the WebSocket.
188
- * @param {BufferSource} data - The data to send.
189
- */
190
- socket_send(data) {
191
- if (this.socket?.readyState === 1) {
192
- this.socket.send(data)
193
- this.txCounter++;
194
- this.txBytes += data.byteLength
195
- this.lastTxRxTime = Date.now();
196
- } else {
197
- console.log('.')
198
- }
199
- }
200
-
201
- }
202
-
@@ -1,210 +0,0 @@
1
-
2
- /**
3
- * @typedef {object} STATE
4
- * @property {number} CONNECTING
5
- * @property {number} OPEN
6
- * @property {number} SERVER_READY
7
- * @property {number} AUTH_REQ
8
- * @property {number} AUTH_RES
9
- * @property {number} AUTH_FAIL
10
- * @property {number} AUTH_CLEAR
11
- * @property {number} CID_REQ
12
- * @property {number} CID_RES
13
- * @property {number} READY
14
- * @property {number} CLOSING
15
- * @property {number} CLOSED
16
- * @property {number} STOP
17
- * @property {number} REDIRECTING
18
- */
19
- // Client STATE: name and number
20
- export const STATE = {
21
- CONNECTING: 0,
22
- OPEN: 1,
23
- SERVER_READY: 10,
24
- AUTH_REQ: 11,
25
- AUTH_RES: 12,
26
- AUTH_FAIL: 13,
27
- AUTH_CLEAR: 14,
28
-
29
- CID_REQ: 17,
30
- CID_RES: 18,
31
- READY: 19,
32
- CLOSING: 2,
33
- CLOSED: 3,
34
- STOP: 4,
35
- REDIRECTING: 5
36
- }
37
- for (let c in STATE) { STATE[STATE[c]] = c }
38
-
39
-
40
- /**
41
- * @typedef {object} ENC_MODE
42
- * @property {number} NO
43
- * @property {number} YES
44
- * @property {number} AUTO
45
- */
46
- export let ENC_MODE = {
47
- NO: 0,
48
- YES: 1,
49
- AUTO: 2
50
- }
51
-
52
- for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
53
-
54
-
55
- /**
56
- * @typedef {object} SIZE_LIMIT
57
- * @property {number} TAG_LEN1
58
- * @property {number} TAG_LEN2
59
- * @property {number} CONNECTION_CHECKER_PERIOD
60
- * @property {number} CLIENT_PING_PERIOD
61
- * @property {number} PROMISE_TIMEOUT
62
- * @property {number} DID
63
- * @property {number} CID
64
- */
65
- export const SIZE_LIMIT = {
66
- TAG_LEN1: 255,
67
- TAG_LEN2: 65535,
68
- CONNECTION_CHECKER_PERIOD: 3000,
69
- CLIENT_PING_PERIOD: 40000,
70
- PROMISE_TIMEOUT: 5000,
71
- DID: 8,
72
- CID: 12
73
- }
74
-
75
- /**
76
- * @typedef {object} PAYLOAD_TYPE
77
- * @property {number} EMPTY
78
- * @property {number} TEXT
79
- * @property {number} BINARY
80
- * @property {number} OBJECT
81
- * @property {number} MJSON
82
- * @property {number} MBA
83
- */
84
- export let PAYLOAD_TYPE = {
85
- EMPTY: 0,
86
- TEXT: 1,
87
- BINARY: 2,
88
- OBJECT: 3, // one stringifiable object. it's string.
89
- MJSON: 4, // multiple stringifiable obejct. it's top-level array JSON string.
90
- MBA: 5 // "meta_buffer_arguments" arbitary types. it's meta-buffer-pack.
91
- }
92
- for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
93
-
94
-
95
- /**
96
- * @typedef {object} IOMsg
97
- * @property {number} SERVER_READY
98
- * @property {number} CID_REQ
99
- * @property {number} CID_RES
100
- * @property {number} QUOTA_LEVEL
101
- * @property {number} AUTH_CLEAR
102
- * @property {number} SERVER_REDIRECT
103
- * @property {number} LOOP
104
- * @property {number} ECHO
105
- * @property {number} PING
106
- * @property {number} PONG
107
- * @property {number} CLOSE
108
- * @property {number} SIGNAL
109
- * @property {number} SIGNAL_REQ
110
- * @property {number} SIGNAL_E2E
111
- * @property {number} SUBSCRIBE
112
- * @property {number} SUBSCRIBE_REQ
113
- * @property {number} UNSUBSCRIBE
114
- * @property {number} SERVER_SIGNAL
115
- * @property {number} IAM
116
- * @property {number} IAM_RES
117
- * @property {number} SET
118
- * @property {number} RESPONSE_CODE
119
- * @property {number} RESPONSE_MBP
120
- * @property {number} CALL
121
- * @property {number} RESPONSE
122
- * @property {number} FLOW_MODE
123
- * @property {number} WAIT
124
- * @property {number} RESUME
125
- * @property {number} TIME_OUT
126
- * @property {number} OVER_SIZE
127
- * @property {number} OVER_FLOW
128
- */
129
- // IO message's one-byte headers.
130
- export let IOMsg = {
131
-
132
- /*
133
- * 0~127dec. reserved. for text stream.
134
- * 0~31: control code
135
- * 32~126: ascii charactor
136
- * 127: DEL
137
- */
138
-
139
- // ADMIN_REQ: 0xA0,
140
-
141
- // DO NOT USE: 0xB0~ 0xBF
142
- // Boho module using this numbers.
143
-
144
- // reserved ~0xBF
145
-
146
- // C. IO status contorl.
147
- SERVER_READY: 0xC0,
148
- CID_REQ: 0xC1,
149
- CID_RES: 0xC2,
150
- QUOTA_LEVEL: 0xC3,
151
- AUTH_CLEAR: 0xC4,
152
- SERVER_REDIRECT: 0xC5,
153
- // ..
154
- LOOP: 0xCB,
155
- ECHO: 0xCC,
156
- PING: 0xCD,
157
- PONG: 0xCE,
158
- CLOSE: 0xCF,
159
- // ~CF
160
-
161
-
162
- // D. IO data signaling
163
- SIGNAL: 0xD0,
164
- SIGNAL_REQ: 0xD1,
165
- SIGNAL_E2E: 0xD2,
166
- SUBSCRIBE: 0xD3,
167
- SUBSCRIBE_REQ: 0xD4,
168
- UNSUBSCRIBE: 0xD5,
169
- SERVER_SIGNAL: 0xD6,
170
-
171
- // ..
172
- IAM: 0xD9,
173
- IAM_RES: 0xDA,
174
-
175
- //..
176
- SET: 0xDB, //
177
- // RESPONSE_CODE: 0xDC,
178
- RESPONSE_MBP: 0xDD,
179
- CALL: 0xDE, // rpc call
180
- // RESPONSE: 0xDF,
181
- // ~DF
182
-
183
-
184
- // F. Framing Flow control related framing protocol.(CongPacket)
185
- FLOW_MODE: 0xF0,
186
- WAIT: 0xF1,
187
- RESUME: 0xF2,
188
- //..
189
- TIME_OUT: 0xFD,
190
- OVER_SIZE: 0xFE,
191
- OVER_FLOW: 0xFF
192
-
193
- }
194
-
195
- for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
196
- // console.log( IOMsg );
197
-
198
-
199
- /**
200
- * @typedef {object} STATUS
201
- * @property {number} OK
202
- * @property {number} ERROR
203
- */
204
- // service response status code
205
- export const STATUS = {
206
- OK: 0,
207
- //0~127: success
208
- //128~255: fail
209
- ERROR: 255
210
- }
@@ -1,82 +0,0 @@
1
- import MBP from 'meta-buffer-pack'
2
- import { PAYLOAD_TYPE, IOMsg } from "./constants.js";
3
- const encoder = new TextEncoder()
4
-
5
-
6
- export function getSignalPack(tag, ...args) {
7
- if (typeof tag !== 'string') throw TypeError('tag should be string.')
8
- let tagEncoded = encoder.encode(tag)
9
- let payload = parsePayload(args)
10
-
11
- let sigPack;
12
- if (payload.type == PAYLOAD_TYPE.EMPTY) {
13
- sigPack = MBP.pack(
14
- MBP.MB('#MsgType', '8', IOMsg.SIGNAL),
15
- MBP.MB('#tagLen', '8', tagEncoded.byteLength),
16
- MBP.MB('#tag', tagEncoded),
17
- MBP.MB('#payloadType', '8', payload.type)
18
- )
19
- } else if (payload.type == PAYLOAD_TYPE.MBA) {
20
- let mbaBuffer = MBP.pack(MBP.MBA(...args))
21
- sigPack = MBP.pack(
22
- MBP.MB('#MsgType', '8', IOMsg.SIGNAL),
23
- MBP.MB('#tagLen', '8', tagEncoded.byteLength),
24
- MBP.MB('#tag', tagEncoded),
25
- MBP.MB('#payloadType', '8', payload.type),
26
- MBP.MB('#mbaBuffer', mbaBuffer)
27
- )
28
- } else {
29
- sigPack = MBP.pack(
30
- MBP.MB('#MsgType', '8', IOMsg.SIGNAL),
31
- MBP.MB('#tagLen', '8', tagEncoded.byteLength),
32
- MBP.MB('#tag', tagEncoded),
33
- MBP.MB('#payloadType', '8', payload.type),
34
- MBP.MB('#payload', payload.buffer)
35
- )
36
- }
37
- return sigPack
38
- }
39
-
40
-
41
- export function parsePayload(args) {
42
- let type, pack;
43
- if (args.length == 0) {
44
- type = PAYLOAD_TYPE.EMPTY
45
- pack = null
46
- } else if (args.length == 1) {
47
- if (typeof args[0] === 'string' || typeof args[0] === 'number') {
48
- type = PAYLOAD_TYPE.TEXT
49
- pack = encoder.encode(args[0] + ".") // add null byte area.
50
- pack[pack.byteLength - 1] = 0 // set byte-zero : '\0' in C/C++
51
-
52
- } else if (ArrayBuffer.isView(args[0]) || args[0] instanceof ArrayBuffer) {
53
- type = PAYLOAD_TYPE.BINARY
54
- pack = MBP.B8(args[0])
55
- } else if (typeof args[0] === 'object') {
56
- type = PAYLOAD_TYPE.OBJECT
57
- pack = encoder.encode(JSON.stringify(args[0]))
58
- } else {
59
- throw new Error('unknown payload arguments')
60
- }
61
- } else { // two or more arguments.
62
- let containsBuffer = false
63
- args.forEach(item => {
64
- if (ArrayBuffer.isView(item) || item instanceof ArrayBuffer) containsBuffer = true;
65
- })
66
-
67
- if (containsBuffer) {
68
- type = PAYLOAD_TYPE.MBA;
69
- } else {
70
- type = PAYLOAD_TYPE.MJSON;
71
- pack = encoder.encode(JSON.stringify(args))
72
- }
73
-
74
- }
75
-
76
- return { type: type, buffer: pack }
77
- }
78
-
79
- export function getPayloadFromSignalPack(signalPack) {
80
- let tagLen = signalPack.readUint8(1)
81
- return signalPack.subarray(3 + tagLen)
82
- }
@@ -1,68 +0,0 @@
1
- // table index related with:
2
- // - AUTH database level
3
- // - serverOption.defaultQuotaIndex
4
-
5
- // quota example
6
- // index range: 0~255.
7
- export let quotaTable = {
8
- // CongSocket
9
- 0: { // default. anonymouse:
10
- signalSize: 1500,
11
- publishCounter: 10,
12
- trafficRate: 10000
13
- },
14
- 1: { // auth_ultralight: eg. Arduino Uno.
15
- signalSize: 255,
16
- publishCounter: 10,
17
- trafficRate: 100000
18
- },
19
- 2: { // auth_light: eg. authorized ESP.
20
- signalSize: 65535,
21
- publishCounter: 10,
22
- trafficRate: 1048576
23
- },
24
-
25
- // WebSocket (browser and node app)
26
- 3: { // authorized basic.
27
- signalSize: 1048576,
28
- publishCounter: 10,
29
- trafficRate: 1048576 * 20
30
- },
31
-
32
- // WebSocket (browser and node app)
33
- 10: { // anonymouse
34
- signalSize: 1500,
35
- publishCounter: 5,
36
- trafficRate: 1048576 * 20
37
- },
38
-
39
- 11: { // authorized basic.
40
- signalSize: 65535,
41
- publishCounter: 10,
42
- trafficRate: 1048576 * 20
43
- },
44
-
45
- 12: { // authorized power.
46
- signalSize: 1048576,
47
- publishCounter: 100,
48
- trafficRate: 1048576 * 20
49
- },
50
-
51
- // you can add your custom quota levels.
52
-
53
- // Remote service node
54
- // High Quota, No root permission.
55
- 200: {
56
- signalSize: 1048576 * 20,
57
- publishCounter: 10000,
58
- trafficRate: 1048576 * 100
59
- },
60
- // super admin or root user.
61
- // to monitor, metric, sudo command, db access.
62
- 255: {
63
- signalSize: 1048576 * 20,
64
- publishCounter: 10000,
65
- trafficRate: 1048576 * 100
66
- }
67
- }
68
-
@@ -1,64 +0,0 @@
1
- import { networkInterfaces } from 'os';
2
-
3
- export function isPrivateIP(ip) {
4
- if (ip.indexOf("0.0.0.0") === 0) return true
5
- if (ip.indexOf("127.0.0.1") === 0) return true
6
- if (ip.indexOf("192.168.") === 0) return true
7
- if (ip.indexOf("10.") === 0) return true
8
- if (ip.indexOf("172.") === 0) {
9
- if (ip.indexOf("172.16.") === 0) return true
10
- if (ip.indexOf("172.17.") === 0) return true
11
- if (ip.indexOf("172.18.") === 0) return true
12
- if (ip.indexOf("172.19.") === 0) return true
13
- if (ip.indexOf("172.20.") === 0) return true
14
- if (ip.indexOf("172.21.") === 0) return true
15
- if (ip.indexOf("172.22.") === 0) return true
16
- if (ip.indexOf("172.23.") === 0) return true
17
- if (ip.indexOf("172.24.") === 0) return true
18
- if (ip.indexOf("172.25.") === 0) return true
19
- if (ip.indexOf("172.26.") === 0) return true
20
- if (ip.indexOf("172.27.") === 0) return true
21
- if (ip.indexOf("172.28.") === 0) return true
22
- if (ip.indexOf("172.29.") === 0) return true
23
- if (ip.indexOf("172.30.") === 0) return true
24
- if (ip.indexOf("172.31.") === 0) return true
25
- }
26
-
27
- return false
28
- }
29
-
30
- export function numberWithCommas(x) {
31
- return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
32
- }
33
-
34
- export function getIPv4HexString(ipStr) {
35
- let ipv4 = ipStr.split('.')
36
- return Buffer.from(ipv4).toString('hex')
37
- }
38
-
39
- export function getLocalAddress() {
40
- const nets = networkInterfaces();
41
- // console.log(nets)
42
- const results = Object.create(null); // Or just '{}', an empty object
43
- let localAddress = ''
44
- for (const name of Object.keys(nets)) {
45
- for (const net of nets[name]) {
46
- // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
47
- // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
48
- const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4
49
- if (net.family === familyV4Value && !net.internal) {
50
- if (!results[name]) {
51
- results[name] = [];
52
- }
53
- results[name].push(net.address);
54
- localAddress = net.address
55
- }
56
- }
57
- }
58
-
59
- // console.log('localAddress:', localAddress)
60
- return localAddress
61
- }
62
-
63
-
64
- export const delay = ms => new Promise(resolve => setTimeout(resolve, ms));