iosignal 3.0.0 → 3.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.
- package/README.md +144 -1
- package/dist/io.d.ts +481 -0
- package/dist/io.js +3 -3
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +3 -3
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +543 -102
- package/dist/types/client/IOCore.d.ts +408 -0
- package/dist/types/client/browser/IOWebSocket.d.ts +75 -0
- package/dist/types/common/constants.d.ts +169 -0
- package/dist/types/common/payload.d.ts +6 -0
- package/dist/types/common/quotaTable.d.ts +47 -0
- package/docs/{README.kr.md → README.ko.md} +143 -2
- package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +56 -0
- package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +1 -0
- package/examples/react-chat-js/dist/index.html +14 -0
- package/examples/react-chat-js/index.html +13 -0
- package/examples/react-chat-js/package-lock.json +1628 -0
- package/examples/react-chat-js/package.json +20 -0
- package/examples/react-chat-js/src/App.css +61 -0
- package/examples/react-chat-js/src/App.jsx +125 -0
- package/examples/react-chat-js/src/index.css +13 -0
- package/examples/react-chat-js/src/main.jsx +13 -0
- package/examples/react-chat-js/src/shared_io.js +12 -0
- package/examples/react-chat-js/vite.config.js +7 -0
- package/examples/server/index.js +12 -0
- package/examples/server/package.json +12 -0
- package/package.json +9 -3
- package/rollup.config.js +11 -4
- package/src/client/IOCongSocket.js +20 -9
- package/src/client/IOCore.js +422 -77
- package/src/client/IOWS.js +12 -15
- package/src/client/browser/IOWebSocket.js +112 -13
- package/src/common/constants.js +91 -1
- package/tsconfig.json +24 -0
package/src/client/IOWS.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IOCore } from "./IOCore.js";
|
|
2
|
+
import { STATES } from "../common/constants.js";
|
|
2
3
|
import { WebSocket } from "ws";
|
|
3
4
|
|
|
4
5
|
// Node.js 'ws' websocket
|
|
@@ -10,32 +11,28 @@ export class IOWS extends IOCore {
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Closes ws WebSocket and cleans resources.
|
|
16
|
+
*/
|
|
13
17
|
close() {
|
|
14
18
|
if (this.socket) {
|
|
15
|
-
this.socket.
|
|
16
|
-
this.socket.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.socket = null;
|
|
19
|
+
this.socket.removeAllListeners();
|
|
20
|
+
if (this.socket.readyState !== WebSocket.CLOSED) {
|
|
21
|
+
this.socket.close();
|
|
22
|
+
}
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
super.close();
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
stop() {
|
|
27
|
-
this.close()
|
|
28
|
-
clearInterval(this.connectionCheckerIntervalID);
|
|
29
|
-
this.connectionCheckerIntervalID = null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
28
|
keepAlive() {
|
|
33
|
-
if (!this.
|
|
29
|
+
if (!this.autoReconnect) return;
|
|
30
|
+
// Reconnect only if the socket is closed and the state reflects that.
|
|
31
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) && this.state === STATES.CLOSED) {
|
|
34
32
|
this.open();
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
|
|
39
36
|
createConnection(url) {
|
|
40
37
|
// node WebSocket
|
|
41
38
|
this.socket = new WebSocket(url);
|
|
@@ -3,23 +3,79 @@ import { IOCore } from "../IOCore.js";
|
|
|
3
3
|
import Boho from 'boho'
|
|
4
4
|
import * as constants from '../../common/constants.js'
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import("boho").Boho} Boho
|
|
8
|
+
* @typedef {import("boho").MBP} MBP
|
|
9
|
+
* @typedef {import("boho").Buffer} Buffer
|
|
10
|
+
*/
|
|
11
|
+
|
|
6
12
|
const Buffer = Boho.Buffer
|
|
7
13
|
|
|
8
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Browser WebSocket client extending IOCore.
|
|
16
|
+
* @augments {IOCore}
|
|
17
|
+
*/
|
|
9
18
|
export default class IO extends IOCore {
|
|
19
|
+
/**
|
|
20
|
+
* The version of the client.
|
|
21
|
+
* @type {string}
|
|
22
|
+
*/
|
|
10
23
|
static version = version
|
|
24
|
+
/**
|
|
25
|
+
* The binary type for WebSocket messages.
|
|
26
|
+
* @type {string}
|
|
27
|
+
*/
|
|
11
28
|
static binaryType = "arraybuffer"
|
|
29
|
+
/**
|
|
30
|
+
* The Boho library instance.
|
|
31
|
+
* @type {Boho}
|
|
32
|
+
*/
|
|
12
33
|
static Boho = Boho;
|
|
34
|
+
/**
|
|
35
|
+
* The MBP (MessagePack-Boho) instance.
|
|
36
|
+
* @type {MBP}
|
|
37
|
+
*/
|
|
13
38
|
static MBP = Boho.MBP;
|
|
39
|
+
/**
|
|
40
|
+
* The Buffer class from Boho.
|
|
41
|
+
* @type {Buffer}
|
|
42
|
+
*/
|
|
14
43
|
static Buffer = Boho.Buffer;
|
|
44
|
+
/**
|
|
45
|
+
* Constants used by the client.
|
|
46
|
+
* @type {object}
|
|
47
|
+
*/
|
|
15
48
|
static constants = constants
|
|
16
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
|
+
*/
|
|
17
68
|
constructor(url) {
|
|
18
69
|
super(url);
|
|
19
|
-
|
|
70
|
+
IO.instanceCount++;
|
|
71
|
+
this.boundBrowserVisiblePing = this.browserVisiblePing.bind(this)
|
|
72
|
+
document.addEventListener('visibilitychange', this.boundBrowserVisiblePing);
|
|
20
73
|
if (url) this.open();
|
|
21
74
|
}
|
|
22
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Pings the server when the browser tab becomes visible.
|
|
78
|
+
*/
|
|
23
79
|
browserVisiblePing() {
|
|
24
80
|
if (document.visibilityState === 'visible') {
|
|
25
81
|
this.ping()
|
|
@@ -27,41 +83,72 @@ export default class IO extends IOCore {
|
|
|
27
83
|
}
|
|
28
84
|
|
|
29
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Closes the WebSocket connection and cleans up its event handlers.
|
|
88
|
+
* This is intended for temporary disconnections, and the connection might be re-established by keepAlive.
|
|
89
|
+
*/
|
|
30
90
|
close() {
|
|
31
91
|
if (this.socket) {
|
|
32
|
-
this.socket.
|
|
33
|
-
this.socket.
|
|
34
|
-
this.socket.
|
|
35
|
-
this.socket.
|
|
36
|
-
this.socket
|
|
92
|
+
this.socket.onopen = null;
|
|
93
|
+
this.socket.onclose = null;
|
|
94
|
+
this.socket.onmessage = null;
|
|
95
|
+
this.socket.onerror = null;
|
|
96
|
+
if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {
|
|
97
|
+
this.socket.close();
|
|
98
|
+
}
|
|
37
99
|
}
|
|
38
|
-
|
|
100
|
+
super.close();
|
|
39
101
|
}
|
|
40
102
|
|
|
41
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Permanently stops the connection and cleans up its specific resources.
|
|
105
|
+
* For complete cleanup and to make the instance unusable, use destroy().
|
|
106
|
+
*/
|
|
42
107
|
stop() {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
108
|
+
super.stop();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Permanently destroys the instance, cleaning up all resources including global event listeners.
|
|
113
|
+
* The instance will not be usable after this.
|
|
114
|
+
*/
|
|
115
|
+
destroy() {
|
|
116
|
+
document.removeEventListener('visibilitychange', this.boundBrowserVisiblePing);
|
|
117
|
+
super.destroy();
|
|
46
118
|
}
|
|
47
119
|
|
|
48
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Keeps the connection alive by re-opening if closed.
|
|
123
|
+
*/
|
|
49
124
|
keepAlive() {
|
|
50
|
-
if (!this.
|
|
125
|
+
if (!this.autoReconnect) return;
|
|
126
|
+
// Reconnect only if the socket is closed and the state reflects that.
|
|
127
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) && this.state === IO.constants.STATES.CLOSED) {
|
|
51
128
|
this.open();
|
|
52
129
|
}
|
|
53
130
|
}
|
|
54
131
|
|
|
55
132
|
|
|
56
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Creates a new WebSocket connection.
|
|
136
|
+
* @param {string} url - The WebSocket URL to connect to.
|
|
137
|
+
*/
|
|
57
138
|
createConnection(url) {
|
|
58
139
|
// Web Browser WebSocket
|
|
140
|
+
IO.webSocketCount++;
|
|
59
141
|
this.socket = new WebSocket(url);
|
|
60
142
|
this.socket.binaryType = IO.binaryType
|
|
61
143
|
|
|
62
144
|
this.stateChange('opening')
|
|
63
145
|
|
|
64
146
|
this.socket.onopen = () => {
|
|
147
|
+
|
|
148
|
+
if (!this.socket) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
65
152
|
if (this.socket.binaryType == "arraybuffer") {
|
|
66
153
|
this.socket.onmessage = this.onWebSocketMessage.bind(this);
|
|
67
154
|
} else { // blob
|
|
@@ -79,6 +166,10 @@ export default class IO extends IOCore {
|
|
|
79
166
|
}
|
|
80
167
|
}
|
|
81
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Handles incoming WebSocket messages (arraybuffer type).
|
|
171
|
+
* @param {MessageEvent} event - The WebSocket message event.
|
|
172
|
+
*/
|
|
82
173
|
onWebSocketMessage(event) {
|
|
83
174
|
// event.data is arrayBuffer or text_message
|
|
84
175
|
this.rxCounter++;
|
|
@@ -88,6 +179,10 @@ export default class IO extends IOCore {
|
|
|
88
179
|
this.emit('socket_data', buffer);
|
|
89
180
|
}
|
|
90
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Handles incoming WebSocket messages (blob type).
|
|
184
|
+
* @param {MessageEvent} event - The WebSocket message event.
|
|
185
|
+
*/
|
|
91
186
|
async onWebSocketMessageBlob(event) {
|
|
92
187
|
// event.data is Blob or text_message
|
|
93
188
|
this.rxCounter++;
|
|
@@ -103,6 +198,10 @@ export default class IO extends IOCore {
|
|
|
103
198
|
this.emit('socket_data', buffer);
|
|
104
199
|
}
|
|
105
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Sends data over the WebSocket.
|
|
203
|
+
* @param {BufferSource} data - The data to send.
|
|
204
|
+
*/
|
|
106
205
|
socket_send(data) {
|
|
107
206
|
if (this.socket?.readyState === 1) {
|
|
108
207
|
this.socket.send(data)
|
package/src/common/constants.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {object} STATES
|
|
4
|
+
* @property {number} OPENING
|
|
5
|
+
* @property {number} OPEN
|
|
6
|
+
* @property {number} CLOSING
|
|
7
|
+
* @property {number} CLOSED
|
|
8
|
+
* @property {number} SERVER_READY
|
|
9
|
+
* @property {number} AUTH_FAIL
|
|
10
|
+
* @property {number} AUTH_READY
|
|
11
|
+
* @property {number} READY
|
|
12
|
+
* @property {number} REDIRECTING
|
|
13
|
+
*/
|
|
2
14
|
// Client STATES: name and number
|
|
3
15
|
export const STATES = {
|
|
4
16
|
OPENING: 0,
|
|
@@ -13,7 +25,17 @@ export const STATES = {
|
|
|
13
25
|
}
|
|
14
26
|
for (let c in STATES) { STATES[STATES[c]] = c }
|
|
15
27
|
|
|
16
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {object} CLIENT_STATE
|
|
30
|
+
* @property {number} INIT
|
|
31
|
+
* @property {number} SENT_SERVER_READY
|
|
32
|
+
* @property {number} RECV_AUTH_REQ
|
|
33
|
+
* @property {number} SENT_SERVER_NONCE
|
|
34
|
+
* @property {number} RECV_AUTH_HMAC
|
|
35
|
+
* @property {number} AUTH_FAIL
|
|
36
|
+
* @property {number} AUTH_READY
|
|
37
|
+
* @property {number} CID_READY
|
|
38
|
+
*/
|
|
17
39
|
export const CLIENT_STATE = {
|
|
18
40
|
INIT: 0,
|
|
19
41
|
SENT_SERVER_READY: 1,
|
|
@@ -26,6 +48,12 @@ export const CLIENT_STATE = {
|
|
|
26
48
|
}
|
|
27
49
|
for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
|
|
28
50
|
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {object} ENC_MODE
|
|
53
|
+
* @property {number} NO
|
|
54
|
+
* @property {number} YES
|
|
55
|
+
* @property {number} AUTO
|
|
56
|
+
*/
|
|
29
57
|
export let ENC_MODE = {
|
|
30
58
|
NO: 0,
|
|
31
59
|
YES: 1,
|
|
@@ -35,6 +63,15 @@ export let ENC_MODE = {
|
|
|
35
63
|
for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
|
|
36
64
|
|
|
37
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @typedef {object} SIZE_LIMIT
|
|
68
|
+
* @property {number} TAG_LEN1
|
|
69
|
+
* @property {number} TAG_LEN2
|
|
70
|
+
* @property {number} CONNECTION_CHECKER_PERIOD
|
|
71
|
+
* @property {number} PROMISE_TIMEOUT
|
|
72
|
+
* @property {number} DID
|
|
73
|
+
* @property {number} CID
|
|
74
|
+
*/
|
|
38
75
|
export const SIZE_LIMIT = {
|
|
39
76
|
TAG_LEN1: 255,
|
|
40
77
|
TAG_LEN2: 65535,
|
|
@@ -44,6 +81,15 @@ export const SIZE_LIMIT = {
|
|
|
44
81
|
CID: 12
|
|
45
82
|
}
|
|
46
83
|
|
|
84
|
+
/**
|
|
85
|
+
* @typedef {object} PAYLOAD_TYPE
|
|
86
|
+
* @property {number} EMPTY
|
|
87
|
+
* @property {number} TEXT
|
|
88
|
+
* @property {number} BINARY
|
|
89
|
+
* @property {number} OBJECT
|
|
90
|
+
* @property {number} MJSON
|
|
91
|
+
* @property {number} MBA
|
|
92
|
+
*/
|
|
47
93
|
export let PAYLOAD_TYPE = {
|
|
48
94
|
EMPTY: 0,
|
|
49
95
|
TEXT: 1,
|
|
@@ -55,6 +101,40 @@ export let PAYLOAD_TYPE = {
|
|
|
55
101
|
for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
|
|
56
102
|
|
|
57
103
|
|
|
104
|
+
/**
|
|
105
|
+
* @typedef {object} IOMsg
|
|
106
|
+
* @property {number} SERVER_READY
|
|
107
|
+
* @property {number} CID_REQ
|
|
108
|
+
* @property {number} CID_RES
|
|
109
|
+
* @property {number} QUOTA_LEVEL
|
|
110
|
+
* @property {number} SERVER_CLEAR_AUTH
|
|
111
|
+
* @property {number} SERVER_REDIRECT
|
|
112
|
+
* @property {number} LOOP
|
|
113
|
+
* @property {number} ECHO
|
|
114
|
+
* @property {number} PING
|
|
115
|
+
* @property {number} PONG
|
|
116
|
+
* @property {number} CLOSE
|
|
117
|
+
* @property {number} SIGNAL
|
|
118
|
+
* @property {number} SIGNAL_REQ
|
|
119
|
+
* @property {number} SIGNAL_E2E
|
|
120
|
+
* @property {number} SUBSCRIBE
|
|
121
|
+
* @property {number} SUBSCRIBE_REQ
|
|
122
|
+
* @property {number} UNSUBSCRIBE
|
|
123
|
+
* @property {number} SERVER_SIGNAL
|
|
124
|
+
* @property {number} IAM
|
|
125
|
+
* @property {number} IAM_RES
|
|
126
|
+
* @property {number} SET
|
|
127
|
+
* @property {number} RESPONSE_CODE
|
|
128
|
+
* @property {number} RESPONSE_MBP
|
|
129
|
+
* @property {number} REQUEST
|
|
130
|
+
* @property {number} RESPONSE
|
|
131
|
+
* @property {number} FLOW_MODE
|
|
132
|
+
* @property {number} WAIT
|
|
133
|
+
* @property {number} RESUME
|
|
134
|
+
* @property {number} TIME_OUT
|
|
135
|
+
* @property {number} OVER_SIZE
|
|
136
|
+
* @property {number} OVER_FLOW
|
|
137
|
+
*/
|
|
58
138
|
// IO message's one-byte headers.
|
|
59
139
|
export let IOMsg = {
|
|
60
140
|
|
|
@@ -134,11 +214,21 @@ export let IOMsg = {
|
|
|
134
214
|
for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
|
|
135
215
|
// console.log( IOMsg );
|
|
136
216
|
|
|
217
|
+
/**
|
|
218
|
+
* @typedef {object} API_TYPE
|
|
219
|
+
* @property {string} REQUEST_RESPONSE
|
|
220
|
+
* @property {string} ONE_WAY
|
|
221
|
+
*/
|
|
137
222
|
export const API_TYPE = {
|
|
138
223
|
'REQUEST_RESPONSE': 'requet_response',
|
|
139
224
|
'ONE_WAY': 'one_way'
|
|
140
225
|
}
|
|
141
226
|
|
|
227
|
+
/**
|
|
228
|
+
* @typedef {object} STATUS
|
|
229
|
+
* @property {number} OK
|
|
230
|
+
* @property {number} ERROR
|
|
231
|
+
*/
|
|
142
232
|
// api response status code
|
|
143
233
|
export const STATUS = {
|
|
144
234
|
OK: 0,
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"declaration": true,
|
|
4
|
+
"emitDeclarationOnly": true,
|
|
5
|
+
"outDir": "./dist/types",
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"moduleResolution": "node",
|
|
8
|
+
"target": "es2015",
|
|
9
|
+
"lib": ["es2020", "dom"],
|
|
10
|
+
"baseUrl": ".",
|
|
11
|
+
"paths": {
|
|
12
|
+
"@src/*": ["src/*"]
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"include": [
|
|
16
|
+
"src/client/browser/IOWebSocket.js",
|
|
17
|
+
"src/client/IOCore.js",
|
|
18
|
+
"src/common/constants.js",
|
|
19
|
+
"package.json"
|
|
20
|
+
],
|
|
21
|
+
"exclude": [
|
|
22
|
+
"node_modules"
|
|
23
|
+
]
|
|
24
|
+
}
|