@zero-server/sdk 0.9.1 → 0.9.3
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/LICENSE +21 -21
- package/README.md +460 -443
- package/index.js +414 -412
- package/lib/app.js +1172 -1172
- package/lib/auth/authorize.js +399 -399
- package/lib/auth/enrollment.js +367 -367
- package/lib/auth/index.js +57 -57
- package/lib/auth/jwt.js +731 -731
- package/lib/auth/oauth.js +362 -362
- package/lib/auth/session.js +588 -588
- package/lib/auth/trustedDevice.js +409 -409
- package/lib/auth/twoFactor.js +1150 -1150
- package/lib/auth/webauthn.js +946 -946
- package/lib/body/index.js +14 -14
- package/lib/body/json.js +109 -109
- package/lib/body/multipart.js +440 -440
- package/lib/body/raw.js +71 -71
- package/lib/body/rawBuffer.js +160 -160
- package/lib/body/sendError.js +25 -25
- package/lib/body/text.js +75 -75
- package/lib/body/typeMatch.js +41 -41
- package/lib/body/urlencoded.js +235 -235
- package/lib/cli.js +845 -845
- package/lib/cluster.js +666 -666
- package/lib/debug.js +372 -372
- package/lib/env/index.js +465 -465
- package/lib/errors.js +683 -683
- package/lib/fetch/index.js +256 -256
- package/lib/grpc/balancer.js +378 -378
- package/lib/grpc/call.js +708 -708
- package/lib/grpc/client.js +764 -764
- package/lib/grpc/codec.js +1221 -1221
- package/lib/grpc/credentials.js +398 -398
- package/lib/grpc/frame.js +262 -262
- package/lib/grpc/health.js +287 -287
- package/lib/grpc/index.js +121 -121
- package/lib/grpc/metadata.js +461 -461
- package/lib/grpc/proto.js +821 -821
- package/lib/grpc/reflection.js +590 -590
- package/lib/grpc/server.js +445 -445
- package/lib/grpc/status.js +118 -118
- package/lib/grpc/watch.js +173 -173
- package/lib/http/index.js +10 -10
- package/lib/http/request.js +727 -727
- package/lib/http/response.js +799 -799
- package/lib/lifecycle.js +557 -557
- package/lib/middleware/compress.js +230 -230
- package/lib/middleware/cookieParser.js +237 -237
- package/lib/middleware/cors.js +93 -93
- package/lib/middleware/csrf.js +137 -137
- package/lib/middleware/errorHandler.js +101 -101
- package/lib/middleware/helmet.js +175 -175
- package/lib/middleware/index.js +19 -17
- package/lib/middleware/logger.js +74 -74
- package/lib/middleware/rateLimit.js +88 -88
- package/lib/middleware/requestId.js +53 -53
- package/lib/middleware/static.js +326 -326
- package/lib/middleware/timeout.js +71 -71
- package/lib/middleware/validator.js +255 -255
- package/lib/observe/health.js +326 -326
- package/lib/observe/index.js +50 -50
- package/lib/observe/logger.js +359 -359
- package/lib/observe/metrics.js +805 -805
- package/lib/observe/tracing.js +592 -592
- package/lib/orm/adapters/json.js +290 -290
- package/lib/orm/adapters/memory.js +764 -764
- package/lib/orm/adapters/mongo.js +764 -764
- package/lib/orm/adapters/mysql.js +933 -933
- package/lib/orm/adapters/postgres.js +1144 -1144
- package/lib/orm/adapters/redis.js +1534 -1534
- package/lib/orm/adapters/sql-base.js +212 -212
- package/lib/orm/adapters/sqlite.js +858 -858
- package/lib/orm/audit.js +649 -649
- package/lib/orm/cache.js +394 -394
- package/lib/orm/geo.js +387 -387
- package/lib/orm/index.js +784 -784
- package/lib/orm/migrate.js +432 -432
- package/lib/orm/model.js +1706 -1706
- package/lib/orm/plugin.js +375 -375
- package/lib/orm/procedures.js +836 -836
- package/lib/orm/profiler.js +233 -233
- package/lib/orm/query.js +1772 -1772
- package/lib/orm/replicas.js +241 -241
- package/lib/orm/schema.js +307 -307
- package/lib/orm/search.js +380 -380
- package/lib/orm/seed/data/commerce.js +136 -136
- package/lib/orm/seed/data/internet.js +111 -111
- package/lib/orm/seed/data/locations.js +204 -204
- package/lib/orm/seed/data/names.js +338 -338
- package/lib/orm/seed/data/person.js +128 -128
- package/lib/orm/seed/data/phone.js +211 -211
- package/lib/orm/seed/data/words.js +134 -134
- package/lib/orm/seed/factory.js +178 -178
- package/lib/orm/seed/fake.js +1186 -1186
- package/lib/orm/seed/index.js +18 -18
- package/lib/orm/seed/rng.js +70 -70
- package/lib/orm/seed/seeder.js +124 -124
- package/lib/orm/seed/unique.js +68 -68
- package/lib/orm/snapshot.js +366 -366
- package/lib/orm/tenancy.js +605 -605
- package/lib/orm/views.js +350 -350
- package/lib/router/index.js +436 -436
- package/lib/sse/index.js +8 -8
- package/lib/sse/stream.js +349 -349
- package/lib/ws/connection.js +451 -451
- package/lib/ws/handshake.js +125 -125
- package/lib/ws/index.js +14 -14
- package/lib/ws/room.js +223 -223
- package/package.json +73 -73
- package/types/app.d.ts +223 -223
- package/types/auth.d.ts +520 -520
- package/types/body.d.ts +14 -0
- package/types/cli.d.ts +2 -0
- package/types/cluster.d.ts +75 -75
- package/types/env.d.ts +80 -80
- package/types/errors.d.ts +316 -316
- package/types/fetch.d.ts +43 -43
- package/types/grpc.d.ts +432 -432
- package/types/index.d.ts +384 -384
- package/types/lifecycle.d.ts +60 -60
- package/types/middleware.d.ts +320 -320
- package/types/observe.d.ts +304 -304
- package/types/orm.d.ts +1887 -1887
- package/types/request.d.ts +109 -109
- package/types/response.d.ts +157 -157
- package/types/router.d.ts +78 -78
- package/types/sse.d.ts +78 -78
- package/types/websocket.d.ts +126 -126
package/lib/ws/room.js
CHANGED
|
@@ -1,223 +1,223 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module ws/room
|
|
3
|
-
* @description WebSocket room/channel manager.
|
|
4
|
-
* Provides broadcast, room-based messaging, and connection
|
|
5
|
-
* registry for WebSocket connections.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Manages a pool of WebSocket connections with room-based grouping.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* const pool = new WebSocketPool();
|
|
13
|
-
* app.ws('/chat', (ws, req) => {
|
|
14
|
-
* pool.add(ws);
|
|
15
|
-
* pool.join(ws, 'general');
|
|
16
|
-
* ws.on('message', msg => pool.toRoom('general', msg));
|
|
17
|
-
* ws.on('close', () => pool.remove(ws));
|
|
18
|
-
* });
|
|
19
|
-
*/
|
|
20
|
-
class WebSocketPool
|
|
21
|
-
{
|
|
22
|
-
/** @constructor */
|
|
23
|
-
constructor()
|
|
24
|
-
{
|
|
25
|
-
/** @type {Set<import('./connection')>} All active connections. */
|
|
26
|
-
this._connections = new Set();
|
|
27
|
-
/** @type {Map<string, Set<import('./connection')>>} Room → connection sets. */
|
|
28
|
-
this._rooms = new Map();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Add a connection to the pool.
|
|
33
|
-
* @param {import('./connection')} ws - WebSocket connection.
|
|
34
|
-
* @returns {WebSocketPool} this
|
|
35
|
-
*/
|
|
36
|
-
add(ws)
|
|
37
|
-
{
|
|
38
|
-
this._connections.add(ws);
|
|
39
|
-
|
|
40
|
-
// Auto-remove on close
|
|
41
|
-
ws.once('close', () => this.remove(ws));
|
|
42
|
-
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Remove a connection from the pool and all rooms.
|
|
48
|
-
* @param {import('./connection')} ws - WebSocket connection.
|
|
49
|
-
* @returns {WebSocketPool} this
|
|
50
|
-
*/
|
|
51
|
-
remove(ws)
|
|
52
|
-
{
|
|
53
|
-
this._connections.delete(ws);
|
|
54
|
-
for (const [room, members] of this._rooms)
|
|
55
|
-
{
|
|
56
|
-
members.delete(ws);
|
|
57
|
-
if (members.size === 0) this._rooms.delete(room);
|
|
58
|
-
}
|
|
59
|
-
return this;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Join a connection to a room.
|
|
64
|
-
* @param {import('./connection')} ws - WebSocket connection.
|
|
65
|
-
* @param {string} room - Room name.
|
|
66
|
-
* @returns {WebSocketPool} this
|
|
67
|
-
*/
|
|
68
|
-
join(ws, room)
|
|
69
|
-
{
|
|
70
|
-
if (!this._rooms.has(room)) this._rooms.set(room, new Set());
|
|
71
|
-
this._rooms.get(room).add(ws);
|
|
72
|
-
return this;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Remove a connection from a room.
|
|
77
|
-
* @param {import('./connection')} ws - WebSocket connection.
|
|
78
|
-
* @param {string} room - Room name.
|
|
79
|
-
* @returns {WebSocketPool} this
|
|
80
|
-
*/
|
|
81
|
-
leave(ws, room)
|
|
82
|
-
{
|
|
83
|
-
const members = this._rooms.get(room);
|
|
84
|
-
if (members)
|
|
85
|
-
{
|
|
86
|
-
members.delete(ws);
|
|
87
|
-
if (members.size === 0) this._rooms.delete(room);
|
|
88
|
-
}
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Get all rooms a connection belongs to.
|
|
94
|
-
* @param {import('./connection')} ws - WebSocket connection.
|
|
95
|
-
* @returns {string[]} Room names the connection belongs to.
|
|
96
|
-
*/
|
|
97
|
-
roomsOf(ws)
|
|
98
|
-
{
|
|
99
|
-
const result = [];
|
|
100
|
-
for (const [room, members] of this._rooms)
|
|
101
|
-
{
|
|
102
|
-
if (members.has(ws)) result.push(room);
|
|
103
|
-
}
|
|
104
|
-
return result;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Broadcast a message to ALL connected clients.
|
|
109
|
-
* @param {string|Buffer} data - Payload.
|
|
110
|
-
* @param {import('./connection')} [exclude] - Optional connection to exclude (e.g. the sender).
|
|
111
|
-
*/
|
|
112
|
-
broadcast(data, exclude)
|
|
113
|
-
{
|
|
114
|
-
for (const ws of this._connections)
|
|
115
|
-
{
|
|
116
|
-
if (ws !== exclude && ws.readyState === 1) ws.send(data);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Broadcast a JSON message to ALL connected clients.
|
|
122
|
-
* @param {*} obj - Value to serialise.
|
|
123
|
-
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
124
|
-
*/
|
|
125
|
-
broadcastJSON(obj, exclude)
|
|
126
|
-
{
|
|
127
|
-
const msg = JSON.stringify(obj);
|
|
128
|
-
this.broadcast(msg, exclude);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Send a message to all connections in a specific room.
|
|
133
|
-
* @param {string} room - Room name.
|
|
134
|
-
* @param {string|Buffer} data - Payload.
|
|
135
|
-
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
136
|
-
*/
|
|
137
|
-
toRoom(room, data, exclude)
|
|
138
|
-
{
|
|
139
|
-
const members = this._rooms.get(room);
|
|
140
|
-
if (!members) return;
|
|
141
|
-
for (const ws of members)
|
|
142
|
-
{
|
|
143
|
-
if (ws !== exclude && ws.readyState === 1) ws.send(data);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Send a JSON message to all connections in a specific room.
|
|
149
|
-
* @param {string} room - Room name.
|
|
150
|
-
* @param {*} obj - Data object to send.
|
|
151
|
-
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
152
|
-
*/
|
|
153
|
-
toRoomJSON(room, obj, exclude)
|
|
154
|
-
{
|
|
155
|
-
this.toRoom(room, JSON.stringify(obj), exclude);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Get all connections in a room.
|
|
160
|
-
* @param {string} room - Room name.
|
|
161
|
-
* @returns {import('./connection')[]} Connections in the room (empty array if the room does not exist).
|
|
162
|
-
*/
|
|
163
|
-
in(room)
|
|
164
|
-
{
|
|
165
|
-
const members = this._rooms.get(room);
|
|
166
|
-
return members ? Array.from(members) : [];
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Total number of active connections.
|
|
171
|
-
* @type {number}
|
|
172
|
-
*/
|
|
173
|
-
get size()
|
|
174
|
-
{
|
|
175
|
-
return this._connections.size;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Number of connections in a specific room.
|
|
180
|
-
* @param {string} room - Room name.
|
|
181
|
-
* @returns {number} Number of connections in the room.
|
|
182
|
-
*/
|
|
183
|
-
roomSize(room)
|
|
184
|
-
{
|
|
185
|
-
const members = this._rooms.get(room);
|
|
186
|
-
return members ? members.size : 0;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* List all active room names.
|
|
191
|
-
* @returns {string[]} Array of room names.
|
|
192
|
-
*/
|
|
193
|
-
get rooms()
|
|
194
|
-
{
|
|
195
|
-
return Array.from(this._rooms.keys());
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Get all active connections.
|
|
200
|
-
* @returns {import('./connection')[]} Array of connections in the pool.
|
|
201
|
-
*/
|
|
202
|
-
get clients()
|
|
203
|
-
{
|
|
204
|
-
return Array.from(this._connections);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Close all connections gracefully.
|
|
209
|
-
* @param {number} [code=1001] - Close code.
|
|
210
|
-
* @param {string} [reason] - Close reason.
|
|
211
|
-
*/
|
|
212
|
-
closeAll(code = 1001, reason = 'Server shutdown')
|
|
213
|
-
{
|
|
214
|
-
for (const ws of this._connections)
|
|
215
|
-
{
|
|
216
|
-
ws.close(code, reason);
|
|
217
|
-
}
|
|
218
|
-
this._connections.clear();
|
|
219
|
-
this._rooms.clear();
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
module.exports = WebSocketPool;
|
|
1
|
+
/**
|
|
2
|
+
* @module ws/room
|
|
3
|
+
* @description WebSocket room/channel manager.
|
|
4
|
+
* Provides broadcast, room-based messaging, and connection
|
|
5
|
+
* registry for WebSocket connections.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Manages a pool of WebSocket connections with room-based grouping.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const pool = new WebSocketPool();
|
|
13
|
+
* app.ws('/chat', (ws, req) => {
|
|
14
|
+
* pool.add(ws);
|
|
15
|
+
* pool.join(ws, 'general');
|
|
16
|
+
* ws.on('message', msg => pool.toRoom('general', msg));
|
|
17
|
+
* ws.on('close', () => pool.remove(ws));
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
class WebSocketPool
|
|
21
|
+
{
|
|
22
|
+
/** @constructor */
|
|
23
|
+
constructor()
|
|
24
|
+
{
|
|
25
|
+
/** @type {Set<import('./connection')>} All active connections. */
|
|
26
|
+
this._connections = new Set();
|
|
27
|
+
/** @type {Map<string, Set<import('./connection')>>} Room → connection sets. */
|
|
28
|
+
this._rooms = new Map();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Add a connection to the pool.
|
|
33
|
+
* @param {import('./connection')} ws - WebSocket connection.
|
|
34
|
+
* @returns {WebSocketPool} this
|
|
35
|
+
*/
|
|
36
|
+
add(ws)
|
|
37
|
+
{
|
|
38
|
+
this._connections.add(ws);
|
|
39
|
+
|
|
40
|
+
// Auto-remove on close
|
|
41
|
+
ws.once('close', () => this.remove(ws));
|
|
42
|
+
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Remove a connection from the pool and all rooms.
|
|
48
|
+
* @param {import('./connection')} ws - WebSocket connection.
|
|
49
|
+
* @returns {WebSocketPool} this
|
|
50
|
+
*/
|
|
51
|
+
remove(ws)
|
|
52
|
+
{
|
|
53
|
+
this._connections.delete(ws);
|
|
54
|
+
for (const [room, members] of this._rooms)
|
|
55
|
+
{
|
|
56
|
+
members.delete(ws);
|
|
57
|
+
if (members.size === 0) this._rooms.delete(room);
|
|
58
|
+
}
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Join a connection to a room.
|
|
64
|
+
* @param {import('./connection')} ws - WebSocket connection.
|
|
65
|
+
* @param {string} room - Room name.
|
|
66
|
+
* @returns {WebSocketPool} this
|
|
67
|
+
*/
|
|
68
|
+
join(ws, room)
|
|
69
|
+
{
|
|
70
|
+
if (!this._rooms.has(room)) this._rooms.set(room, new Set());
|
|
71
|
+
this._rooms.get(room).add(ws);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Remove a connection from a room.
|
|
77
|
+
* @param {import('./connection')} ws - WebSocket connection.
|
|
78
|
+
* @param {string} room - Room name.
|
|
79
|
+
* @returns {WebSocketPool} this
|
|
80
|
+
*/
|
|
81
|
+
leave(ws, room)
|
|
82
|
+
{
|
|
83
|
+
const members = this._rooms.get(room);
|
|
84
|
+
if (members)
|
|
85
|
+
{
|
|
86
|
+
members.delete(ws);
|
|
87
|
+
if (members.size === 0) this._rooms.delete(room);
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get all rooms a connection belongs to.
|
|
94
|
+
* @param {import('./connection')} ws - WebSocket connection.
|
|
95
|
+
* @returns {string[]} Room names the connection belongs to.
|
|
96
|
+
*/
|
|
97
|
+
roomsOf(ws)
|
|
98
|
+
{
|
|
99
|
+
const result = [];
|
|
100
|
+
for (const [room, members] of this._rooms)
|
|
101
|
+
{
|
|
102
|
+
if (members.has(ws)) result.push(room);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Broadcast a message to ALL connected clients.
|
|
109
|
+
* @param {string|Buffer} data - Payload.
|
|
110
|
+
* @param {import('./connection')} [exclude] - Optional connection to exclude (e.g. the sender).
|
|
111
|
+
*/
|
|
112
|
+
broadcast(data, exclude)
|
|
113
|
+
{
|
|
114
|
+
for (const ws of this._connections)
|
|
115
|
+
{
|
|
116
|
+
if (ws !== exclude && ws.readyState === 1) ws.send(data);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Broadcast a JSON message to ALL connected clients.
|
|
122
|
+
* @param {*} obj - Value to serialise.
|
|
123
|
+
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
124
|
+
*/
|
|
125
|
+
broadcastJSON(obj, exclude)
|
|
126
|
+
{
|
|
127
|
+
const msg = JSON.stringify(obj);
|
|
128
|
+
this.broadcast(msg, exclude);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Send a message to all connections in a specific room.
|
|
133
|
+
* @param {string} room - Room name.
|
|
134
|
+
* @param {string|Buffer} data - Payload.
|
|
135
|
+
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
136
|
+
*/
|
|
137
|
+
toRoom(room, data, exclude)
|
|
138
|
+
{
|
|
139
|
+
const members = this._rooms.get(room);
|
|
140
|
+
if (!members) return;
|
|
141
|
+
for (const ws of members)
|
|
142
|
+
{
|
|
143
|
+
if (ws !== exclude && ws.readyState === 1) ws.send(data);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Send a JSON message to all connections in a specific room.
|
|
149
|
+
* @param {string} room - Room name.
|
|
150
|
+
* @param {*} obj - Data object to send.
|
|
151
|
+
* @param {import('./connection')} [exclude] - Connection(s) to exclude.
|
|
152
|
+
*/
|
|
153
|
+
toRoomJSON(room, obj, exclude)
|
|
154
|
+
{
|
|
155
|
+
this.toRoom(room, JSON.stringify(obj), exclude);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get all connections in a room.
|
|
160
|
+
* @param {string} room - Room name.
|
|
161
|
+
* @returns {import('./connection')[]} Connections in the room (empty array if the room does not exist).
|
|
162
|
+
*/
|
|
163
|
+
in(room)
|
|
164
|
+
{
|
|
165
|
+
const members = this._rooms.get(room);
|
|
166
|
+
return members ? Array.from(members) : [];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Total number of active connections.
|
|
171
|
+
* @type {number}
|
|
172
|
+
*/
|
|
173
|
+
get size()
|
|
174
|
+
{
|
|
175
|
+
return this._connections.size;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Number of connections in a specific room.
|
|
180
|
+
* @param {string} room - Room name.
|
|
181
|
+
* @returns {number} Number of connections in the room.
|
|
182
|
+
*/
|
|
183
|
+
roomSize(room)
|
|
184
|
+
{
|
|
185
|
+
const members = this._rooms.get(room);
|
|
186
|
+
return members ? members.size : 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* List all active room names.
|
|
191
|
+
* @returns {string[]} Array of room names.
|
|
192
|
+
*/
|
|
193
|
+
get rooms()
|
|
194
|
+
{
|
|
195
|
+
return Array.from(this._rooms.keys());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get all active connections.
|
|
200
|
+
* @returns {import('./connection')[]} Array of connections in the pool.
|
|
201
|
+
*/
|
|
202
|
+
get clients()
|
|
203
|
+
{
|
|
204
|
+
return Array.from(this._connections);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Close all connections gracefully.
|
|
209
|
+
* @param {number} [code=1001] - Close code.
|
|
210
|
+
* @param {string} [reason] - Close reason.
|
|
211
|
+
*/
|
|
212
|
+
closeAll(code = 1001, reason = 'Server shutdown')
|
|
213
|
+
{
|
|
214
|
+
for (const ws of this._connections)
|
|
215
|
+
{
|
|
216
|
+
ws.close(code, reason);
|
|
217
|
+
}
|
|
218
|
+
this._connections.clear();
|
|
219
|
+
this._rooms.clear();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = WebSocketPool;
|
package/package.json
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@zero-server/sdk",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "Zero-dependency backend framework for Node.js — routing, ORM, auth, WebSocket, SSE, gRPC, observability, and 20+ middleware. Distributed as a single SDK and as scoped @zero-server/* packages.",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"zh": "lib/cli.js",
|
|
8
|
-
"zs": "lib/cli.js"
|
|
9
|
-
},
|
|
10
|
-
"types": "types/index.d.ts",
|
|
11
|
-
"files": [
|
|
12
|
-
"lib",
|
|
13
|
-
"types",
|
|
14
|
-
"index.js",
|
|
15
|
-
"README.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"start": "node website-docs/full-server.js",
|
|
20
|
-
"docs": "node website-docs/full-server.js",
|
|
21
|
-
"test": "vitest run",
|
|
22
|
-
"test:watch": "vitest",
|
|
23
|
-
"test:coverage": "vitest run --coverage",
|
|
24
|
-
"build": "node .tools/build.js",
|
|
25
|
-
"build:api": "node .tools/build-api-md.js",
|
|
26
|
-
"packages:generate": "node .tools/generate-package-stubs.js",
|
|
27
|
-
"packages:docs": "node .tools/generate-scope-docs.js",
|
|
28
|
-
"packages:publish": "node .tools/publish-package-stubs.js",
|
|
29
|
-
"ci": "npm test && npm run build && npm run packages:generate && npm run packages:docs"
|
|
30
|
-
},
|
|
31
|
-
"keywords": [
|
|
32
|
-
"http",
|
|
33
|
-
"server",
|
|
34
|
-
"router",
|
|
35
|
-
"middleware",
|
|
36
|
-
"fetch",
|
|
37
|
-
"multipart",
|
|
38
|
-
"static",
|
|
39
|
-
"websocket",
|
|
40
|
-
"sse",
|
|
41
|
-
"grpc",
|
|
42
|
-
"orm",
|
|
43
|
-
"jwt",
|
|
44
|
-
"oauth",
|
|
45
|
-
"zero-server",
|
|
46
|
-
"zero-server"
|
|
47
|
-
],
|
|
48
|
-
"author": "Anthony Wiedman",
|
|
49
|
-
"license": "MIT",
|
|
50
|
-
"repository": {
|
|
51
|
-
"type": "git",
|
|
52
|
-
"url": "git+https://github.com/tonywied17/zero-server.git"
|
|
53
|
-
},
|
|
54
|
-
"bugs": {
|
|
55
|
-
"url": "https://github.com/tonywied17/zero-server/issues"
|
|
56
|
-
},
|
|
57
|
-
"homepage": "https://z-server.dev",
|
|
58
|
-
"engines": {
|
|
59
|
-
"node": ">=18.0.0"
|
|
60
|
-
},
|
|
61
|
-
"publishConfig": {
|
|
62
|
-
"registry": "https://registry.npmjs.org/",
|
|
63
|
-
"access": "public"
|
|
64
|
-
},
|
|
65
|
-
"devDependencies": {
|
|
66
|
-
"@vitest/coverage-v8": "^4.1.2",
|
|
67
|
-
"better-sqlite3": "^12.8.0",
|
|
68
|
-
"mongodb": "^7.1.1",
|
|
69
|
-
"mysql2": "^3.20.0",
|
|
70
|
-
"pg": "^8.20.0",
|
|
71
|
-
"vitest": "^4.1.2"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@zero-server/sdk",
|
|
3
|
+
"version": "0.9.3",
|
|
4
|
+
"description": "Zero-dependency backend framework for Node.js — routing, ORM, auth, WebSocket, SSE, gRPC, observability, and 20+ middleware. Distributed as a single SDK and as scoped @zero-server/* packages.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"zh": "lib/cli.js",
|
|
8
|
+
"zs": "lib/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"types": "types/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"lib",
|
|
13
|
+
"types",
|
|
14
|
+
"index.js",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"start": "node website-docs/full-server.js",
|
|
20
|
+
"docs": "node website-docs/full-server.js",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"test:coverage": "vitest run --coverage",
|
|
24
|
+
"build": "node .tools/build.js",
|
|
25
|
+
"build:api": "node .tools/build-api-md.js",
|
|
26
|
+
"packages:generate": "node .tools/generate-package-stubs.js",
|
|
27
|
+
"packages:docs": "node .tools/generate-scope-docs.js",
|
|
28
|
+
"packages:publish": "node .tools/publish-package-stubs.js",
|
|
29
|
+
"ci": "npm test && npm run build && npm run packages:generate && npm run packages:docs"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"http",
|
|
33
|
+
"server",
|
|
34
|
+
"router",
|
|
35
|
+
"middleware",
|
|
36
|
+
"fetch",
|
|
37
|
+
"multipart",
|
|
38
|
+
"static",
|
|
39
|
+
"websocket",
|
|
40
|
+
"sse",
|
|
41
|
+
"grpc",
|
|
42
|
+
"orm",
|
|
43
|
+
"jwt",
|
|
44
|
+
"oauth",
|
|
45
|
+
"zero-server",
|
|
46
|
+
"zero-server"
|
|
47
|
+
],
|
|
48
|
+
"author": "Anthony Wiedman",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/tonywied17/zero-server.git"
|
|
53
|
+
},
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/tonywied17/zero-server/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://z-server.dev",
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"registry": "https://registry.npmjs.org/",
|
|
63
|
+
"access": "public"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
67
|
+
"better-sqlite3": "^12.8.0",
|
|
68
|
+
"mongodb": "^7.1.1",
|
|
69
|
+
"mysql2": "^3.20.0",
|
|
70
|
+
"pg": "^8.20.0",
|
|
71
|
+
"vitest": "^4.1.2"
|
|
72
|
+
}
|
|
73
|
+
}
|