@arcblock/ws 1.28.9 → 1.29.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/esm/_virtual/rolldown_runtime.mjs +7 -0
- package/esm/browser.d.mts +2 -0
- package/esm/browser.mjs +3 -0
- package/esm/client/base.d.mts +80 -0
- package/esm/client/base.mjs +118 -0
- package/esm/client/browser.d.mts +30 -0
- package/esm/client/browser.mjs +9 -0
- package/esm/client/index.d.mts +30 -0
- package/esm/client/index.mjs +10 -0
- package/esm/index.d.mts +3 -0
- package/esm/index.mjs +4 -0
- package/esm/logger.d.mts +13 -0
- package/esm/logger.mjs +16 -0
- package/esm/server/index.d.mts +138 -0
- package/esm/server/index.mjs +474 -0
- package/lib/_virtual/rolldown_runtime.cjs +29 -0
- package/lib/browser.cjs +3 -0
- package/lib/browser.d.cts +2 -0
- package/lib/client/base.cjs +119 -0
- package/lib/client/base.d.cts +80 -0
- package/lib/client/browser.cjs +12 -0
- package/lib/client/browser.d.cts +30 -0
- package/lib/client/index.cjs +14 -0
- package/lib/client/index.d.cts +30 -0
- package/lib/index.cjs +5 -0
- package/lib/index.d.cts +3 -0
- package/lib/logger.cjs +19 -0
- package/lib/logger.d.cts +13 -0
- package/lib/server/index.cjs +479 -0
- package/lib/server/index.d.cts +138 -0
- package/package.json +32 -10
- package/lib/browser.js +0 -5
- package/lib/client/base.js +0 -134
- package/lib/client/browser.js +0 -6
- package/lib/client/index.js +0 -7
- package/lib/index.js +0 -7
- package/lib/logger.js +0 -12
- package/lib/server/index.js +0 -442
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Logger } from "../logger.cjs";
|
|
2
|
+
import EventEmitter from "node:events";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
import { Duplex } from "node:stream";
|
|
5
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
6
|
+
|
|
7
|
+
//#region src/server/index.d.ts
|
|
8
|
+
interface WsSocket extends WebSocket {
|
|
9
|
+
id: string;
|
|
10
|
+
channel: Record<string, {
|
|
11
|
+
authInfo?: unknown;
|
|
12
|
+
}>;
|
|
13
|
+
heartbeatAt: number;
|
|
14
|
+
authInfo?: unknown;
|
|
15
|
+
}
|
|
16
|
+
interface HookParams {
|
|
17
|
+
socket: WsSocket;
|
|
18
|
+
joinRef: string;
|
|
19
|
+
ref: string;
|
|
20
|
+
topic: string;
|
|
21
|
+
event: string;
|
|
22
|
+
payload: unknown;
|
|
23
|
+
}
|
|
24
|
+
interface Hooks {
|
|
25
|
+
authenticateJoinChannel: (params: any) => unknown;
|
|
26
|
+
preJoinChannel: (params: any) => void | Promise<void>;
|
|
27
|
+
postJoinChannel: (params: any) => void | Promise<void>;
|
|
28
|
+
preLeaveChannel: (params: any) => void | Promise<void>;
|
|
29
|
+
postLeaveChannel: (params: any) => void | Promise<void>;
|
|
30
|
+
postBroadcast: (opts: BroadcastResult) => void | Promise<void>;
|
|
31
|
+
postSend: (opts: SendOptions) => void | Promise<void>;
|
|
32
|
+
receiveMessage: (params: any) => void | Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
interface WsServerOptions {
|
|
35
|
+
pathname?: string;
|
|
36
|
+
authenticate?: (req: http.IncomingMessage, cb: (err: Error | null, authInfo?: unknown) => void) => void;
|
|
37
|
+
hooks?: Partial<Hooks>;
|
|
38
|
+
logger?: Logger;
|
|
39
|
+
silent?: boolean;
|
|
40
|
+
skipLogOnHookError?: boolean;
|
|
41
|
+
broadcastEventName?: string;
|
|
42
|
+
heartbeatTimeout?: number;
|
|
43
|
+
}
|
|
44
|
+
interface BroadcastOptions {
|
|
45
|
+
enableLog?: boolean;
|
|
46
|
+
socketFilters?: Record<string, unknown>;
|
|
47
|
+
noCluster?: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface BroadcastResult {
|
|
50
|
+
count: number;
|
|
51
|
+
topic: string;
|
|
52
|
+
event: string;
|
|
53
|
+
data: unknown;
|
|
54
|
+
options: BroadcastOptions;
|
|
55
|
+
}
|
|
56
|
+
interface SendOptions {
|
|
57
|
+
topic: string;
|
|
58
|
+
event: string;
|
|
59
|
+
data: unknown;
|
|
60
|
+
options: {
|
|
61
|
+
enableLog?: boolean;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a websocket server
|
|
66
|
+
*
|
|
67
|
+
* @param {Object} opts
|
|
68
|
+
* @param {String} opts.pathname - which path to mount the socket server
|
|
69
|
+
* @param {Object} opts.authenticate - authentication function to be called on connection
|
|
70
|
+
* @param {Object} opts.hooks - hooks to be called on events
|
|
71
|
+
* @param {Object} opts.logger - logger used to log messages
|
|
72
|
+
* @param {Object} opts.broadcastEventName - used in cluster mode, default is '@arcblock/ws:broadcast'
|
|
73
|
+
* @param {Object} opts.heartbeatTimeout - maximum non-response time of a connection socket
|
|
74
|
+
* @class WsServer
|
|
75
|
+
* @extends {EventEmitter}
|
|
76
|
+
*/
|
|
77
|
+
declare class WsServer extends EventEmitter {
|
|
78
|
+
pathname?: string;
|
|
79
|
+
authenticate: WsServerOptions['authenticate'];
|
|
80
|
+
hooks: Hooks;
|
|
81
|
+
logger: Logger;
|
|
82
|
+
skipLogOnHookError: boolean;
|
|
83
|
+
heartbeatTimeout: number;
|
|
84
|
+
wss: WebSocketServer;
|
|
85
|
+
topics: Record<string, Set<WsSocket>>;
|
|
86
|
+
broadcastEventName: string;
|
|
87
|
+
constructor(opts?: WsServerOptions);
|
|
88
|
+
attach(server: http.Server): this;
|
|
89
|
+
onConnect(request: http.IncomingMessage, socket: Duplex, head: Buffer): void;
|
|
90
|
+
/**
|
|
91
|
+
* Broadcast message to all subscribers of a topic, can be used as
|
|
92
|
+
* - broadcast(event, data) ==> broadcast(event, event, data)
|
|
93
|
+
* - broadcast(topic, event, data)
|
|
94
|
+
* - broadcast(topic, event, data, options)
|
|
95
|
+
*/
|
|
96
|
+
broadcast(...args: unknown[]): Promise<void>;
|
|
97
|
+
_doBroadCast({
|
|
98
|
+
topic,
|
|
99
|
+
event,
|
|
100
|
+
data,
|
|
101
|
+
enableLog,
|
|
102
|
+
replyId,
|
|
103
|
+
socketFilters
|
|
104
|
+
}?: DoBroadcastParams): {
|
|
105
|
+
count: number;
|
|
106
|
+
error?: Error;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Send message to 1 subscriber of a topic, can be used as
|
|
110
|
+
* - send(socket, event, data)
|
|
111
|
+
* - send(socket, topic, event, data)
|
|
112
|
+
* - send(socket, topic, event, data, options)
|
|
113
|
+
*/
|
|
114
|
+
send(...args: unknown[]): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* private
|
|
117
|
+
*/
|
|
118
|
+
onWssConnection(socket: WebSocket): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* private
|
|
121
|
+
*/
|
|
122
|
+
onWssClose(): void;
|
|
123
|
+
/**
|
|
124
|
+
* private
|
|
125
|
+
*/
|
|
126
|
+
onWssError(error: Error): void;
|
|
127
|
+
_leaveChannel(socket: WsSocket, topic: string): void;
|
|
128
|
+
}
|
|
129
|
+
interface DoBroadcastParams {
|
|
130
|
+
topic: string;
|
|
131
|
+
event: string;
|
|
132
|
+
data: unknown;
|
|
133
|
+
enableLog?: boolean;
|
|
134
|
+
replyId?: string;
|
|
135
|
+
socketFilters?: Record<string, unknown>;
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
export { HookParams, Hooks, WsSocket, WsServer as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ws",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.0",
|
|
4
4
|
"description": "OCAP Chain websocket server and client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"websocket"
|
|
@@ -8,14 +8,31 @@
|
|
|
8
8
|
"author": "arcblock <engineer@arcblock.io>",
|
|
9
9
|
"homepage": "https://github.com/ArcBlock/blockchain#readme",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./lib/index.cjs",
|
|
13
|
+
"module": "./esm/index.mjs",
|
|
14
|
+
"types": "./esm/index.d.mts",
|
|
15
|
+
"browser": "./esm/browser.mjs",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./esm/index.d.mts",
|
|
19
|
+
"import": "./esm/index.mjs",
|
|
20
|
+
"default": "./lib/index.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./lib/*.js": {
|
|
23
|
+
"types": "./esm/*.d.mts",
|
|
24
|
+
"import": "./esm/*.mjs",
|
|
25
|
+
"default": "./lib/*.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./lib/*": {
|
|
28
|
+
"types": "./esm/*.d.mts",
|
|
29
|
+
"import": "./esm/*.mjs",
|
|
30
|
+
"default": "./lib/*.cjs"
|
|
31
|
+
}
|
|
16
32
|
},
|
|
17
33
|
"files": [
|
|
18
|
-
"lib"
|
|
34
|
+
"lib",
|
|
35
|
+
"esm"
|
|
19
36
|
],
|
|
20
37
|
"publishConfig": {
|
|
21
38
|
"access": "public"
|
|
@@ -25,6 +42,8 @@
|
|
|
25
42
|
"url": "git+https://github.com/ArcBlock/blockchain.git"
|
|
26
43
|
},
|
|
27
44
|
"scripts": {
|
|
45
|
+
"build": "tsdown",
|
|
46
|
+
"prebuild": "rm -rf lib esm",
|
|
28
47
|
"lint": "biome check",
|
|
29
48
|
"lint:fix": "biome check --write",
|
|
30
49
|
"test": "bun test",
|
|
@@ -34,14 +53,17 @@
|
|
|
34
53
|
"url": "https://github.com/ArcBlock/blockchain/issues"
|
|
35
54
|
},
|
|
36
55
|
"dependencies": {
|
|
37
|
-
"@arcblock/event-hub": "1.
|
|
38
|
-
"debug": "^4.3
|
|
56
|
+
"@arcblock/event-hub": "1.29.0",
|
|
57
|
+
"debug": "^4.4.3",
|
|
39
58
|
"eventemitter3": "^4.0.7",
|
|
40
|
-
"lodash": "^4.17.
|
|
59
|
+
"lodash": "^4.17.23",
|
|
41
60
|
"phoenix": "1.7.2",
|
|
42
61
|
"ws": "^8.18.0"
|
|
43
62
|
},
|
|
44
63
|
"devDependencies": {
|
|
64
|
+
"@types/debug": "^4.1.12",
|
|
65
|
+
"@types/lodash": "^4.17.15",
|
|
66
|
+
"@types/ws": "^8.5.13",
|
|
45
67
|
"get-port": "^5.1.1"
|
|
46
68
|
}
|
|
47
69
|
}
|
package/lib/browser.js
DELETED
package/lib/client/base.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
const createLogger = require('../logger');
|
|
2
|
-
|
|
3
|
-
module.exports = (Socket, EventEmitter, transport) => {
|
|
4
|
-
return class WsClient extends Socket {
|
|
5
|
-
constructor(endpoint, opts = {}) {
|
|
6
|
-
super(endpoint, { transport, ...opts });
|
|
7
|
-
|
|
8
|
-
this._logger = createLogger('client', opts.silent);
|
|
9
|
-
this.emitter = new EventEmitter();
|
|
10
|
-
|
|
11
|
-
this.onOpen(() => {
|
|
12
|
-
this._logger.debug('socket open', endpoint);
|
|
13
|
-
});
|
|
14
|
-
this.onClose(() => {
|
|
15
|
-
this._logger.debug('socket close', endpoint);
|
|
16
|
-
});
|
|
17
|
-
this.onError((err) => {
|
|
18
|
-
this._logger.error('socket error', err.error);
|
|
19
|
-
});
|
|
20
|
-
this.onMessage((message) => {
|
|
21
|
-
this._logger.debug('socket message', message);
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
on(event, handler, params = {}) {
|
|
26
|
-
this.ensureJoinChannel(event, params);
|
|
27
|
-
this.emitter.on(event, handler);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
off(event, handler) {
|
|
31
|
-
if (handler) {
|
|
32
|
-
this.emitter.off(event, handler);
|
|
33
|
-
} else {
|
|
34
|
-
this.emitter.removeAllListeners(event);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.ensureLeaveChannel(event);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
disconnect(callback, code, reason) {
|
|
41
|
-
this.emitter.eventNames().forEach((event) => {
|
|
42
|
-
this.emitter.removeAllListeners(event);
|
|
43
|
-
});
|
|
44
|
-
super.disconnect(callback, code, reason);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* private
|
|
49
|
-
*/
|
|
50
|
-
ensureJoinChannel(topic, params = {}) {
|
|
51
|
-
const count = this.emitter.listenerCount(topic);
|
|
52
|
-
if (count > 0) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const channel = this.channel(topic, params);
|
|
57
|
-
channel
|
|
58
|
-
.join()
|
|
59
|
-
.receive('ok', (message) => {
|
|
60
|
-
this._logger.debug('join success', { topic, message });
|
|
61
|
-
})
|
|
62
|
-
.receive('error', (error) => {
|
|
63
|
-
this._logger.error('join error', { topic, error });
|
|
64
|
-
})
|
|
65
|
-
.receive('timeout', () => {
|
|
66
|
-
this._logger.debug('join timeout', { topic });
|
|
67
|
-
});
|
|
68
|
-
channel.on(topic, ({ status, response: data }) => {
|
|
69
|
-
if (status === 'ok') {
|
|
70
|
-
this.emitter.emit(topic, data);
|
|
71
|
-
} else {
|
|
72
|
-
this._logger.debug('response error', { topic, status, data });
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* private
|
|
79
|
-
*/
|
|
80
|
-
ensureLeaveChannel(topic) {
|
|
81
|
-
const count = this.emitter.listenerCount(topic);
|
|
82
|
-
if (count > 0) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const channel = this.channels.find((c) => c.topic === topic);
|
|
87
|
-
if (!channel) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
this.remove(channel);
|
|
92
|
-
channel
|
|
93
|
-
.leave()
|
|
94
|
-
.receive('ok', (message) => {
|
|
95
|
-
this._logger.debug('leave success', { topic, message });
|
|
96
|
-
})
|
|
97
|
-
.receive('error', (err) => {
|
|
98
|
-
this._logger.error('leave error', { topic, err });
|
|
99
|
-
})
|
|
100
|
-
.receive('timeout', () => {
|
|
101
|
-
this._logger.debug('leave timeout', { topic });
|
|
102
|
-
});
|
|
103
|
-
channel.off(topic);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// More flexible subscribe
|
|
107
|
-
// Allow user to join a channel and listen to any POI events
|
|
108
|
-
subscribe(topic, params = {}) {
|
|
109
|
-
let channel = this.channels.find((c) => c.topic === topic);
|
|
110
|
-
if (channel) {
|
|
111
|
-
return channel;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
channel = this.channel(topic, params);
|
|
115
|
-
channel
|
|
116
|
-
.join()
|
|
117
|
-
.receive('ok', (message) => {
|
|
118
|
-
this._logger.debug('join success', { topic, message });
|
|
119
|
-
})
|
|
120
|
-
.receive('error', (error) => {
|
|
121
|
-
this._logger.error('join error', { topic, error });
|
|
122
|
-
})
|
|
123
|
-
.receive('timeout', () => {
|
|
124
|
-
this._logger.debug('join timeout', { topic });
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
return channel;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
unsubscribe(topic) {
|
|
131
|
-
this.ensureLeaveChannel(topic);
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
};
|
package/lib/client/browser.js
DELETED
package/lib/client/index.js
DELETED
package/lib/index.js
DELETED
package/lib/logger.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const debug = require('debug');
|
|
2
|
-
|
|
3
|
-
module.exports = (subModule, silent = false) => {
|
|
4
|
-
const d = debug(['@arcblock/ws', subModule].join(':'));
|
|
5
|
-
return {
|
|
6
|
-
debug: d,
|
|
7
|
-
warn: d,
|
|
8
|
-
info: d,
|
|
9
|
-
trace: silent ? d : console.error,
|
|
10
|
-
error: silent ? d : console.error,
|
|
11
|
-
};
|
|
12
|
-
};
|