redweb 0.7.1 β†’ 0.7.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/README.md CHANGED
@@ -217,7 +217,6 @@ Useful for managing players, NPCs, chat members, rooms, etc.
217
217
  ### πŸ”§ Basic Usage
218
218
 
219
219
  ```js
220
- const { SocketRegistry } = require('redweb');
221
220
 
222
221
  class Player {
223
222
  constructor(socket, id) {
@@ -351,4 +350,4 @@ Here’s the updated `CHANGELOG.md` entry for **RedWeb v0.7.1**, written profess
351
350
 
352
351
  ## πŸͺͺ License
353
352
 
354
- MIT
353
+ MIT
package/index.d.ts CHANGED
@@ -113,26 +113,27 @@ declare module 'redweb' {
113
113
  };
114
114
 
115
115
  /** Generic event‑driven registry for socket objects */
116
- export class SocketRegistry<T extends SocketWrapper = SocketWrapper> {
117
- protected clients: T[];
118
-
119
- onCreate?: (client: T) => boolean | void;
120
- onRemove?: (client: T) => boolean | void;
116
+ /** Generic event-driven registry for socket objects */
117
+ export class SocketRegistry<T extends SocketWrapper = SocketWrapper> extends EventEmitter {
118
+ protected items: T[];
121
119
 
122
120
  constructor();
123
121
 
124
- setCreateValidator(fn: (client: T) => boolean | void): void;
125
- setRemoveValidator(fn: (client: T) => boolean | void): void;
122
+ /** Adds a socket-bound object to the registry */
123
+ add(item: T): void;
126
124
 
127
- add(client: T): boolean;
128
- removeById(id: string): boolean;
125
+ /**
126
+ * Removes a socket-bound object by reference or id (default key: 'id')
127
+ * @param itemOrId Object or ID string
128
+ * @param by Key name to match against (default is 'id')
129
+ */
130
+ remove(itemOrId: T | string, by?: keyof T): boolean;
129
131
 
130
- getById(id: string): T | undefined;
131
- getBySocket(socket: WebSocket): T | undefined;
132
- allWithout(socket: WebSocket): T[];
132
+ /** Returns a shallow copy of all registered items */
133
+ all(): T[];
133
134
 
134
- broadcast(message: SocketMessage, excludeSocket?: WebSocket | null): void;
135
- getSanitizedList(): Record<string, any>[];
135
+ /** Returns the number of registered items */
136
+ count(): number;
136
137
  }
137
138
 
138
139
  /** ─────────────────── CONCRETE SERVERS ─────────────────── */
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "redweb",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "A way to quickly set up an express server",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "node tester.js"
7
+ "test": "npx jest"
8
8
  },
9
9
  "files": [
10
10
  "src/*",
@@ -34,7 +34,21 @@ class BaseSocketServer {
34
34
  }
35
35
 
36
36
  handleUpgrade(req, sock, head) {
37
- const route = this.routes.find(r => r.path === req.url);
37
+ // Some websocket clients (e.g., certain UE plugins) are finicky about the
38
+ // HTTP upgrade path they send. Normalise the path and fall back to a default
39
+ // route so we can still complete the upgrade instead of tearing the socket down.
40
+ const path = (() => {
41
+ try {
42
+ return new URL(req.url, `http://${req.headers.host || 'localhost'}`).pathname;
43
+ } catch {
44
+ return req.url;
45
+ }
46
+ })();
47
+
48
+ const route =
49
+ this.routes.find(r => r.path === path) ||
50
+ this.routes.find(r => r.path === '/');
51
+
38
52
  if (!route) return sock.destroy();
39
53
 
40
54
  route.server.handleUpgrade(req, sock, head, (s, r) =>