@wooksjs/event-ws 0.7.25 → 0.7.27

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/dist/index.cjs CHANGED
@@ -147,6 +147,83 @@ const useWsRooms = (0, _wooksjs_event_core.defineWook)((ctx) => {
147
147
  };
148
148
  });
149
149
 
150
+ //#endregion
151
+ //#region packages/event-ws/src/ws-connection.ts
152
+ function pushMessage(event, path, data, params) {
153
+ const msg = {
154
+ event,
155
+ path
156
+ };
157
+ if (params) msg.params = params;
158
+ if (data !== void 0) msg.data = data;
159
+ return msg;
160
+ }
161
+ /** Internal class representing a connected WebSocket client. */
162
+ var WsConnection = class {
163
+ constructor(id, ws, ctx, serializer) {
164
+ this.id = id;
165
+ this.ws = ws;
166
+ this.ctx = ctx;
167
+ this.serializer = serializer;
168
+ this.rooms = /* @__PURE__ */ new Set();
169
+ this.alive = true;
170
+ }
171
+ /** Send a push message to this connection. */
172
+ send(event, path, data, params) {
173
+ if (this.ws.readyState !== 1) return;
174
+ this.ws.send(this.serializer(pushMessage(event, path, data, params)));
175
+ }
176
+ /**
177
+ * Send an already serialized frame (e.g. one push message serialized once for many recipients).
178
+ * Skipped when the socket is not open, like `send()`.
179
+ */
180
+ sendSerialized(payload) {
181
+ if (this.ws.readyState !== 1) return;
182
+ this.ws.send(payload);
183
+ }
184
+ /** Send a reply to a client request. */
185
+ reply(id, data) {
186
+ if (this.ws.readyState !== 1) return;
187
+ const msg = { id };
188
+ if (data !== void 0) msg.data = data;
189
+ this.ws.send(this.serializer(msg));
190
+ }
191
+ /** Send an error reply to a client request. */
192
+ replyError(id, code, message) {
193
+ if (this.ws.readyState !== 1) return;
194
+ const msg = {
195
+ id,
196
+ error: {
197
+ code,
198
+ message
199
+ }
200
+ };
201
+ this.ws.send(this.serializer(msg));
202
+ }
203
+ /**
204
+ * Sends one push message to many connections, serializing it once per distinct serializer
205
+ * (connections of one adapter share one) and only when an open recipient exists.
206
+ * @internal
207
+ */
208
+ static sendPushToMany(connections, skip, event, path, data, params) {
209
+ let msg;
210
+ let serializer;
211
+ let payload = "";
212
+ for (const conn of connections) {
213
+ if (conn.ws.readyState !== 1 || skip && skip(conn)) continue;
214
+ if (conn.serializer !== serializer) {
215
+ serializer = conn.serializer;
216
+ payload = serializer(msg ??= pushMessage(event, path, data, params));
217
+ }
218
+ conn.sendSerialized(payload);
219
+ }
220
+ }
221
+ /** Close the connection. */
222
+ close(code, reason) {
223
+ this.ws.close(code, reason);
224
+ }
225
+ };
226
+
150
227
  //#endregion
151
228
  //#region packages/event-ws/src/composables/server.ts
152
229
  /**
@@ -160,7 +237,7 @@ function useWsServer() {
160
237
  return state.connections;
161
238
  },
162
239
  broadcast(event, path, data, params) {
163
- for (const conn of state.connections.values()) conn.send(event, path, data, params);
240
+ WsConnection.sendPushToMany(state.connections.values(), void 0, event, path, data, params);
164
241
  },
165
242
  getConnection(id) {
166
243
  return state.connections.get(id);
@@ -201,54 +278,6 @@ function createDefaultWsServerAdapter() {
201
278
  } };
202
279
  }
203
280
 
204
- //#endregion
205
- //#region packages/event-ws/src/ws-connection.ts
206
- /** Internal class representing a connected WebSocket client. */
207
- var WsConnection = class {
208
- constructor(id, ws, ctx, serializer) {
209
- this.id = id;
210
- this.ws = ws;
211
- this.ctx = ctx;
212
- this.serializer = serializer;
213
- this.rooms = /* @__PURE__ */ new Set();
214
- this.alive = true;
215
- }
216
- /** Send a push message to this connection. */
217
- send(event, path, data, params) {
218
- if (this.ws.readyState !== 1) return;
219
- const msg = {
220
- event,
221
- path
222
- };
223
- if (params) msg.params = params;
224
- if (data !== void 0) msg.data = data;
225
- this.ws.send(this.serializer(msg));
226
- }
227
- /** Send a reply to a client request. */
228
- reply(id, data) {
229
- if (this.ws.readyState !== 1) return;
230
- const msg = { id };
231
- if (data !== void 0) msg.data = data;
232
- this.ws.send(this.serializer(msg));
233
- }
234
- /** Send an error reply to a client request. */
235
- replyError(id, code, message) {
236
- if (this.ws.readyState !== 1) return;
237
- const msg = {
238
- id,
239
- error: {
240
- code,
241
- message
242
- }
243
- };
244
- this.ws.send(this.serializer(msg));
245
- }
246
- /** Close the connection. */
247
- close(code, reason) {
248
- this.ws.close(code, reason);
249
- }
250
- };
251
-
252
281
  //#endregion
253
282
  //#region packages/event-ws/src/ws-error.ts
254
283
  /** WebSocket error with a numeric code following HTTP conventions (401, 403, 404, 500, etc.). */
@@ -314,9 +343,7 @@ var WsRoomManager = class {
314
343
  /** Broadcast to all connections in a room. */
315
344
  broadcast(room, event, path, data, params, exclude) {
316
345
  const set = this.rooms.get(room);
317
- if (set) {
318
- for (const conn of set) if (conn !== exclude) conn.send(event, path, data, params);
319
- }
346
+ if (set) WsConnection.sendPushToMany(set, exclude && ((conn) => conn === exclude), event, path, data, params);
320
347
  if (this.transport) {
321
348
  const payload = JSON.stringify({
322
349
  event,
@@ -334,7 +361,7 @@ var WsRoomManager = class {
334
361
  if (!set || set.size === 0) return;
335
362
  try {
336
363
  const { event, path, data, params, excludeId } = JSON.parse(payload);
337
- for (const conn of set) if (conn.id !== excludeId) conn.send(event, path, data, params);
364
+ WsConnection.sendPushToMany(set, excludeId === void 0 ? void 0 : (conn) => conn.id === excludeId, event, path, data, params);
338
365
  } catch {}
339
366
  }
340
367
  };
package/dist/index.d.ts CHANGED
@@ -152,6 +152,7 @@ interface TWooksWsOptions {
152
152
  broadcastTransport?: WsBroadcastTransport;
153
153
  }
154
154
 
155
+ type TWsSerializer = (msg: WsReplyMessage | WsPushMessage) => string | Buffer;
155
156
  /** Internal class representing a connected WebSocket client. */
156
157
  declare class WsConnection {
157
158
  readonly id: string;
@@ -160,13 +161,24 @@ declare class WsConnection {
160
161
  private readonly serializer;
161
162
  readonly rooms: Set<string>;
162
163
  alive: boolean;
163
- constructor(id: string, ws: WsSocket, ctx: EventContext, serializer: (msg: WsReplyMessage | WsPushMessage) => string | Buffer);
164
+ constructor(id: string, ws: WsSocket, ctx: EventContext, serializer: TWsSerializer);
164
165
  /** Send a push message to this connection. */
165
166
  send(event: string, path: string, data?: unknown, params?: Record<string, string>): void;
167
+ /**
168
+ * Send an already serialized frame (e.g. one push message serialized once for many recipients).
169
+ * Skipped when the socket is not open, like `send()`.
170
+ */
171
+ sendSerialized(payload: string | Buffer): void;
166
172
  /** Send a reply to a client request. */
167
173
  reply(id: string | number, data?: unknown): void;
168
174
  /** Send an error reply to a client request. */
169
175
  replyError(id: string | number, code: number, message: string): void;
176
+ /**
177
+ * Sends one push message to many connections, serializing it once per distinct serializer
178
+ * (connections of one adapter share one) and only when an open recipient exists.
179
+ * @internal
180
+ */
181
+ static sendPushToMany(connections: Iterable<WsConnection>, skip: ((conn: WsConnection) => boolean) | undefined, event: string, path: string, data?: unknown, params?: Record<string, string>): void;
170
182
  /** Close the connection. */
171
183
  close(code?: number, reason?: string): void;
172
184
  }
package/dist/index.mjs CHANGED
@@ -118,6 +118,83 @@ const useWsRooms = defineWook((ctx) => {
118
118
  };
119
119
  });
120
120
 
121
+ //#endregion
122
+ //#region packages/event-ws/src/ws-connection.ts
123
+ function pushMessage(event, path, data, params) {
124
+ const msg = {
125
+ event,
126
+ path
127
+ };
128
+ if (params) msg.params = params;
129
+ if (data !== void 0) msg.data = data;
130
+ return msg;
131
+ }
132
+ /** Internal class representing a connected WebSocket client. */
133
+ var WsConnection = class {
134
+ constructor(id, ws, ctx, serializer) {
135
+ this.id = id;
136
+ this.ws = ws;
137
+ this.ctx = ctx;
138
+ this.serializer = serializer;
139
+ this.rooms = /* @__PURE__ */ new Set();
140
+ this.alive = true;
141
+ }
142
+ /** Send a push message to this connection. */
143
+ send(event, path, data, params) {
144
+ if (this.ws.readyState !== 1) return;
145
+ this.ws.send(this.serializer(pushMessage(event, path, data, params)));
146
+ }
147
+ /**
148
+ * Send an already serialized frame (e.g. one push message serialized once for many recipients).
149
+ * Skipped when the socket is not open, like `send()`.
150
+ */
151
+ sendSerialized(payload) {
152
+ if (this.ws.readyState !== 1) return;
153
+ this.ws.send(payload);
154
+ }
155
+ /** Send a reply to a client request. */
156
+ reply(id, data) {
157
+ if (this.ws.readyState !== 1) return;
158
+ const msg = { id };
159
+ if (data !== void 0) msg.data = data;
160
+ this.ws.send(this.serializer(msg));
161
+ }
162
+ /** Send an error reply to a client request. */
163
+ replyError(id, code, message) {
164
+ if (this.ws.readyState !== 1) return;
165
+ const msg = {
166
+ id,
167
+ error: {
168
+ code,
169
+ message
170
+ }
171
+ };
172
+ this.ws.send(this.serializer(msg));
173
+ }
174
+ /**
175
+ * Sends one push message to many connections, serializing it once per distinct serializer
176
+ * (connections of one adapter share one) and only when an open recipient exists.
177
+ * @internal
178
+ */
179
+ static sendPushToMany(connections, skip, event, path, data, params) {
180
+ let msg;
181
+ let serializer;
182
+ let payload = "";
183
+ for (const conn of connections) {
184
+ if (conn.ws.readyState !== 1 || skip && skip(conn)) continue;
185
+ if (conn.serializer !== serializer) {
186
+ serializer = conn.serializer;
187
+ payload = serializer(msg ??= pushMessage(event, path, data, params));
188
+ }
189
+ conn.sendSerialized(payload);
190
+ }
191
+ }
192
+ /** Close the connection. */
193
+ close(code, reason) {
194
+ this.ws.close(code, reason);
195
+ }
196
+ };
197
+
121
198
  //#endregion
122
199
  //#region packages/event-ws/src/composables/server.ts
123
200
  /**
@@ -131,7 +208,7 @@ function useWsServer() {
131
208
  return state.connections;
132
209
  },
133
210
  broadcast(event, path, data, params) {
134
- for (const conn of state.connections.values()) conn.send(event, path, data, params);
211
+ WsConnection.sendPushToMany(state.connections.values(), void 0, event, path, data, params);
135
212
  },
136
213
  getConnection(id) {
137
214
  return state.connections.get(id);
@@ -172,54 +249,6 @@ function createDefaultWsServerAdapter() {
172
249
  } };
173
250
  }
174
251
 
175
- //#endregion
176
- //#region packages/event-ws/src/ws-connection.ts
177
- /** Internal class representing a connected WebSocket client. */
178
- var WsConnection = class {
179
- constructor(id, ws, ctx, serializer) {
180
- this.id = id;
181
- this.ws = ws;
182
- this.ctx = ctx;
183
- this.serializer = serializer;
184
- this.rooms = /* @__PURE__ */ new Set();
185
- this.alive = true;
186
- }
187
- /** Send a push message to this connection. */
188
- send(event, path, data, params) {
189
- if (this.ws.readyState !== 1) return;
190
- const msg = {
191
- event,
192
- path
193
- };
194
- if (params) msg.params = params;
195
- if (data !== void 0) msg.data = data;
196
- this.ws.send(this.serializer(msg));
197
- }
198
- /** Send a reply to a client request. */
199
- reply(id, data) {
200
- if (this.ws.readyState !== 1) return;
201
- const msg = { id };
202
- if (data !== void 0) msg.data = data;
203
- this.ws.send(this.serializer(msg));
204
- }
205
- /** Send an error reply to a client request. */
206
- replyError(id, code, message) {
207
- if (this.ws.readyState !== 1) return;
208
- const msg = {
209
- id,
210
- error: {
211
- code,
212
- message
213
- }
214
- };
215
- this.ws.send(this.serializer(msg));
216
- }
217
- /** Close the connection. */
218
- close(code, reason) {
219
- this.ws.close(code, reason);
220
- }
221
- };
222
-
223
252
  //#endregion
224
253
  //#region packages/event-ws/src/ws-error.ts
225
254
  /** WebSocket error with a numeric code following HTTP conventions (401, 403, 404, 500, etc.). */
@@ -285,9 +314,7 @@ var WsRoomManager = class {
285
314
  /** Broadcast to all connections in a room. */
286
315
  broadcast(room, event, path, data, params, exclude) {
287
316
  const set = this.rooms.get(room);
288
- if (set) {
289
- for (const conn of set) if (conn !== exclude) conn.send(event, path, data, params);
290
- }
317
+ if (set) WsConnection.sendPushToMany(set, exclude && ((conn) => conn === exclude), event, path, data, params);
291
318
  if (this.transport) {
292
319
  const payload = JSON.stringify({
293
320
  event,
@@ -305,7 +332,7 @@ var WsRoomManager = class {
305
332
  if (!set || set.size === 0) return;
306
333
  try {
307
334
  const { event, path, data, params, excludeId } = JSON.parse(payload);
308
- for (const conn of set) if (conn.id !== excludeId) conn.send(event, path, data, params);
335
+ WsConnection.sendPushToMany(set, excludeId === void 0 ? void 0 : (conn) => conn.id === excludeId, event, path, data, params);
309
336
  } catch {}
310
337
  }
311
338
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wooksjs/event-ws",
3
- "version": "0.7.25",
3
+ "version": "0.7.27",
4
4
  "description": "WebSocket adapter for Wooks with path-based message routing, rooms, and broadcasting",
5
5
  "keywords": [
6
6
  "api",
@@ -42,15 +42,15 @@
42
42
  "@types/ws": "^8.18.1",
43
43
  "typescript": "^5.9.3",
44
44
  "vitest": "^3.2.7",
45
- "@wooksjs/event-core": "^0.7.25",
46
- "wooks": "^0.7.25"
45
+ "wooks": "^0.7.27",
46
+ "@wooksjs/event-core": "^0.7.27"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@prostojs/logger": "^0.4.3",
50
- "@prostojs/router": "^0.3.4",
50
+ "@prostojs/router": "^0.3.5",
51
51
  "ws": "^8.21.0",
52
- "@wooksjs/event-core": "^0.7.25",
53
- "wooks": "^0.7.25"
52
+ "wooks": "^0.7.27",
53
+ "@wooksjs/event-core": "^0.7.27"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "rolldown -c ../../rolldown.config.mjs"