room-kit 1.0.1 → 1.0.5
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 +3 -2
- package/changelog.md +32 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +83 -16
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/server.d.ts +4 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +158 -17
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +62 -11
- package/dist/types.d.ts.map +1 -1
- package/example/package-lock.json +1330 -0
- package/example/public/app.js +3988 -0
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/server.ts +31 -5
- package/src/types.ts +43 -16
- package/test/room.spec.ts +71 -0
package/README.md
CHANGED
|
@@ -201,11 +201,12 @@ Runtime presence mode is configured in the `defineRoomType` options:
|
|
|
201
201
|
|
|
202
202
|
`serveRoomType(socket, roomType, handlers, adapter?)` accepts:
|
|
203
203
|
|
|
204
|
-
- `onAuth(socket)`: optional
|
|
204
|
+
- `onAuth(socket)`: optional. Return `false` to reject the socket before room initialization.
|
|
205
205
|
- `onConnect(socket, auth)`: optional transport-connect hook attempted once when the socket handler is attached (after auth resolution).
|
|
206
206
|
- `revalidateAuth(socket, auth)`: optional per-request auth validation hook; return `{ kind: "ok", auth? }` to continue or `{ kind: "reject" }` to deny.
|
|
207
207
|
- `initState(joinRequest)`: initializes room server state on first join for a given room instance.
|
|
208
|
-
- `admit(joinRequest, ctx)`:
|
|
208
|
+
- `admit(joinRequest, ctx)`: optional admission gate. Return only the fields you want to override. Missing `roomId`, `memberId`, `memberProfile`, and `roomProfile` values are filled in by the server.
|
|
209
|
+
- `admit` is still validated: any returned `roomId` must match the join request room id, and any returned `roomProfile.roomId` must match the resolved room id.
|
|
209
210
|
- `onJoin(memberProfile, ctx)`: called after a successful join.
|
|
210
211
|
- `onLeave(memberProfile, ctx)`: called on leave and during socket disconnect cleanup for joined rooms when auth is available for cleanup.
|
|
211
212
|
- `onDisconnect(socket, auth)`: optional transport-disconnect hook.
|
package/changelog.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.5
|
|
4
|
+
|
|
5
|
+
- Made `onAuth` optional in server configs.
|
|
6
|
+
- Made `admit` optional and allowed it to return partial admission data.
|
|
7
|
+
- Added runtime defaults for missing admission fields and validation for room identity.
|
|
8
|
+
- Updated docs and tests for the new auth and admission behavior.
|
|
9
|
+
|
|
10
|
+
## 1.0.4
|
|
11
|
+
|
|
12
|
+
- Added `serveRoomType(...).cleanup()` as the explicit server-handle teardown API.
|
|
13
|
+
- Added `JoinedRoom.listen({ events, presence })` for batched subscription setup.
|
|
14
|
+
- Improved reconnect replay for joined rooms and transport state tracking.
|
|
15
|
+
|
|
16
|
+
## 1.0.3
|
|
17
|
+
|
|
18
|
+
- Hardened client and server event handling with payload validation and safe handler-name checks.
|
|
19
|
+
- Added acknowledgement timeouts and listener error isolation on the client.
|
|
20
|
+
- Added server-side request limits and safer wire-frame parsing.
|
|
21
|
+
|
|
22
|
+
## 1.0.2
|
|
23
|
+
|
|
24
|
+
- Hardened room-key comparison in the example server with timing-safe equality.
|
|
25
|
+
- Tightened server join validation and static file handling.
|
|
26
|
+
- Cleaned up the example server routing and path resolution.
|
|
27
|
+
|
|
28
|
+
## 1.0.1
|
|
29
|
+
|
|
30
|
+
- Updated package metadata for ESM publishing.
|
|
31
|
+
- Cleaned up the README packaging docs.
|
|
32
|
+
- Simplified the package and JSR metadata layout.
|
|
33
|
+
|
|
3
34
|
## 1.0.0
|
|
4
35
|
|
|
5
36
|
- Initial release of `room-kit`.
|
|
@@ -10,4 +41,4 @@
|
|
|
10
41
|
- Added reconnect replay for active stream subscriptions and room memberships.
|
|
11
42
|
- Added Socket.IO client and server adapters for room-aware sends and membership mutation.
|
|
12
43
|
- Added a JSR-ready package entrypoint via `jsr.json`.
|
|
13
|
-
- Expanded the README with current client, server, and JSR examples.
|
|
44
|
+
- Expanded the README with current client, server, and JSR examples.
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAER,gBAAgB,EAUhB,UAAU,EACV,cAAc,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAER,gBAAgB,EAUhB,UAAU,EACV,cAAc,EAMjB,MAAM,SAAS,CAAC;AAwCjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,cAAc,CAAC,GAAG,CAAC,EAC9D,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,KAAK,GACZ,UAAU,CAAC,KAAK,CAAC,CA6CnB"}
|
package/dist/client.js
CHANGED
|
@@ -5,6 +5,7 @@ const CLIENT_EVENT = "room-kit:client-event";
|
|
|
5
5
|
const SERVER_EVENT = "room-kit:server-event";
|
|
6
6
|
const PRESENCE_EVENT = "room-kit:presence";
|
|
7
7
|
const PRESENCE_QUERY_EVENT = "room-kit:presence-query";
|
|
8
|
+
const DEFAULT_ACK_TIMEOUT_MS = 30_000;
|
|
8
9
|
const clientRegistries = new WeakMap();
|
|
9
10
|
/**
|
|
10
11
|
* Binds a client socket to a room type and returns a typed room client.
|
|
@@ -95,18 +96,34 @@ function createJoinedRoom(socket, state) {
|
|
|
95
96
|
return undefined;
|
|
96
97
|
}
|
|
97
98
|
return (handler) => {
|
|
98
|
-
|
|
99
|
-
handlers.add(handler);
|
|
100
|
-
state.eventListeners.set(key, handlers);
|
|
101
|
-
return () => {
|
|
102
|
-
handlers.delete(handler);
|
|
103
|
-
if (handlers.size === 0) {
|
|
104
|
-
state.eventListeners.delete(key);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
99
|
+
return registerEventListener(state, key, handler);
|
|
107
100
|
};
|
|
108
101
|
},
|
|
109
102
|
});
|
|
103
|
+
const listen = (options) => {
|
|
104
|
+
const cleanups = [];
|
|
105
|
+
if (options.events) {
|
|
106
|
+
for (const [key, handler] of Object.entries(options.events)) {
|
|
107
|
+
if (typeof handler !== "function") {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
cleanups.push(registerEventListener(state, key, handler));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if ("presence" in options && options.presence?.onChange) {
|
|
114
|
+
cleanups.push(registerPresenceListener(state, options.presence.onChange));
|
|
115
|
+
}
|
|
116
|
+
let cleaned = false;
|
|
117
|
+
return () => {
|
|
118
|
+
if (cleaned) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
cleaned = true;
|
|
122
|
+
for (const cleanup of cleanups) {
|
|
123
|
+
cleanup();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
};
|
|
110
127
|
const base = {
|
|
111
128
|
name: state.name,
|
|
112
129
|
roomId: state.roomId,
|
|
@@ -115,6 +132,7 @@ function createJoinedRoom(socket, state) {
|
|
|
115
132
|
rpc,
|
|
116
133
|
emit,
|
|
117
134
|
on,
|
|
135
|
+
listen,
|
|
118
136
|
async leave() {
|
|
119
137
|
await emitAck(socket, LEAVE_EVENT, {
|
|
120
138
|
roomType: state.name,
|
|
@@ -132,10 +150,7 @@ function createJoinedRoom(socket, state) {
|
|
|
132
150
|
return state.presenceCurrent;
|
|
133
151
|
},
|
|
134
152
|
onChange(handler) {
|
|
135
|
-
state
|
|
136
|
-
return () => {
|
|
137
|
-
state.presenceListeners.delete(handler);
|
|
138
|
-
};
|
|
153
|
+
return registerPresenceListener(state, handler);
|
|
139
154
|
},
|
|
140
155
|
count() {
|
|
141
156
|
return emitAck(socket, PRESENCE_QUERY_EVENT, {
|
|
@@ -158,6 +173,23 @@ function createJoinedRoom(socket, state) {
|
|
|
158
173
|
},
|
|
159
174
|
});
|
|
160
175
|
}
|
|
176
|
+
function registerEventListener(state, key, handler) {
|
|
177
|
+
const handlers = state.eventListeners.get(key) ?? new Set();
|
|
178
|
+
handlers.add(handler);
|
|
179
|
+
state.eventListeners.set(key, handlers);
|
|
180
|
+
return () => {
|
|
181
|
+
handlers.delete(handler);
|
|
182
|
+
if (handlers.size === 0) {
|
|
183
|
+
state.eventListeners.delete(key);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function registerPresenceListener(state, handler) {
|
|
188
|
+
state.presenceListeners.add(handler);
|
|
189
|
+
return () => {
|
|
190
|
+
state.presenceListeners.delete(handler);
|
|
191
|
+
};
|
|
192
|
+
}
|
|
161
193
|
function getClientRegistry(socket) {
|
|
162
194
|
const existing = clientRegistries.get(socket);
|
|
163
195
|
if (existing) {
|
|
@@ -184,6 +216,16 @@ function getClientRegistry(socket) {
|
|
|
184
216
|
function installClientHandlers(socket, registry) {
|
|
185
217
|
if (!registry.serverHandlerInstalled) {
|
|
186
218
|
const onServerEvent = (frame) => {
|
|
219
|
+
if (!frame ||
|
|
220
|
+
typeof frame !== "object" ||
|
|
221
|
+
typeof frame.roomType !== "string" ||
|
|
222
|
+
typeof frame.roomId !== "string" ||
|
|
223
|
+
typeof frame.name !== "string" ||
|
|
224
|
+
!frame.meta ||
|
|
225
|
+
typeof frame.meta !== "object" ||
|
|
226
|
+
typeof frame.meta.sentAt !== "string") {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
187
229
|
const state = registry.joinedRooms.get(makeJoinedRoomKey(frame.roomType, frame.roomId));
|
|
188
230
|
if (!state) {
|
|
189
231
|
return;
|
|
@@ -197,7 +239,12 @@ function installClientHandlers(socket, registry) {
|
|
|
197
239
|
sentAt: new Date(frame.meta.sentAt),
|
|
198
240
|
};
|
|
199
241
|
for (const handler of handlers) {
|
|
200
|
-
|
|
242
|
+
try {
|
|
243
|
+
handler(frame.payload, meta);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// Swallow per-listener errors to avoid breaking the event loop
|
|
247
|
+
}
|
|
201
248
|
}
|
|
202
249
|
};
|
|
203
250
|
socket.on(SERVER_EVENT, onServerEvent);
|
|
@@ -205,6 +252,12 @@ function installClientHandlers(socket, registry) {
|
|
|
205
252
|
}
|
|
206
253
|
if (!registry.presenceHandlerInstalled) {
|
|
207
254
|
const onPresence = (frame) => {
|
|
255
|
+
if (!frame ||
|
|
256
|
+
typeof frame !== "object" ||
|
|
257
|
+
typeof frame.roomType !== "string" ||
|
|
258
|
+
typeof frame.roomId !== "string") {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
208
261
|
const state = registry.joinedRooms.get(makeJoinedRoomKey(frame.roomType, frame.roomId));
|
|
209
262
|
if (!state) {
|
|
210
263
|
return;
|
|
@@ -214,7 +267,12 @@ function installClientHandlers(socket, registry) {
|
|
|
214
267
|
return;
|
|
215
268
|
}
|
|
216
269
|
for (const handler of state.presenceListeners) {
|
|
217
|
-
|
|
270
|
+
try {
|
|
271
|
+
handler(state.presenceCurrent);
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// Swallow per-listener errors
|
|
275
|
+
}
|
|
218
276
|
}
|
|
219
277
|
};
|
|
220
278
|
socket.on(PRESENCE_EVENT, onPresence);
|
|
@@ -292,7 +350,11 @@ function makeJoinedRoomKey(name, roomId) {
|
|
|
292
350
|
}
|
|
293
351
|
function emitAck(socket, eventName, payload) {
|
|
294
352
|
return new Promise((resolve, reject) => {
|
|
353
|
+
const timer = setTimeout(() => {
|
|
354
|
+
reject(new Error(`Acknowledgement timeout for '${eventName}'`));
|
|
355
|
+
}, DEFAULT_ACK_TIMEOUT_MS);
|
|
295
356
|
socket.emit(eventName, payload, (result) => {
|
|
357
|
+
clearTimeout(timer);
|
|
296
358
|
if (!result || typeof result !== "object") {
|
|
297
359
|
reject(new Error("Invalid acknowledgement payload"));
|
|
298
360
|
return;
|
|
@@ -311,7 +373,12 @@ function setConnectionState(registry, next) {
|
|
|
311
373
|
}
|
|
312
374
|
registry.connectionState = next;
|
|
313
375
|
for (const listener of registry.connectionListeners) {
|
|
314
|
-
|
|
376
|
+
try {
|
|
377
|
+
listener(next);
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// Swallow per-listener errors
|
|
381
|
+
}
|
|
315
382
|
}
|
|
316
383
|
}
|
|
317
384
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,SAAS,GAAG,cAAc,CAAC;AACjC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAC7C,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAC7C,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAC3C,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AA4BvD,MAAM,gBAAgB,GAAG,IAAI,OAAO,EAAoC,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC5B,MAAwB,EACxB,IAAW;IAEX,OAAO;QACH,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,UAAU;YACV,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO;gBACH,IAAI,OAAO;oBACP,OAAO,QAAQ,CAAC,eAAe,CAAC;gBACpC,CAAC;gBACD,QAAQ,CAAC,OAA+C;oBACpD,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAC1C,OAAO,GAAG,EAAE;wBACR,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACjD,CAAC,CAAC;gBACN,CAAC;aACJ,CAAC;QACN,CAAC;QACD,IAAI,CAAC,OAA2B;YAC5B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAE3C,OAAO,OAAO,CAKX,MAAM,EAAE,UAAU,EAAE;gBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,OAAO;aACV,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBACd,MAAM,KAAK,GAA2B;oBAClC,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,eAAe,EAAE,KAAK,CAAC,QAAQ;oBAC/B,WAAW,EAAE,OAAO;oBACpB,cAAc,EAAE,IAAI,GAAG,EAAE;oBACzB,iBAAiB,EAAE,IAAI,GAAG,EAAE;iBAC/B,CAAC;gBAEF,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC5E,OAAO,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;QACP,CAAC;KACJ,CAAC;AACN,CAAC;AAED,SAAS,gBAAgB,CACrB,MAAwB,EACxB,KAA6B;IAE7B,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,EAAyB,EAAE;QAC7C,GAAG,CAAC,OAAO,EAAE,GAAG;YACZ,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;gBAC1B,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;oBAC9B,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,GAAG;oBACT,IAAI;iBACP,CAAC,CAAC;YACP,CAAC,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,EAAyB,EAAE;QAC9C,GAAG,CAAC,OAAO,EAAE,GAAG;YACZ,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,OAAO,CAAC,OAAgB,EAAE,EAAE;gBACxB,OAAO,OAAO,CAAO,MAAM,EAAE,YAAY,EAAE;oBACvC,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,GAAG;oBACT,OAAO;iBACV,CAAC,CAAC;YACP,CAAC,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,IAAI,KAAK,CAAC,EAA2B,EAAE;QAC9C,GAAG,CAAC,OAAO,EAAE,GAAG;YACZ,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,OAAO,CAAC,OAA8D,EAAE,EAAE;gBACtE,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;gBAC5D,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACtB,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBACxC,OAAO,GAAG,EAAE;oBACR,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACzB,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;wBACtB,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACrC,CAAC;gBACL,CAAC,CAAC;YACN,CAAC,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG;QACT,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG;QACH,IAAI;QACJ,EAAE;QACF,KAAK,CAAC,KAAK;YACP,MAAM,OAAO,CAAO,MAAM,EAAE,WAAW,EAAE;gBACrC,QAAQ,EAAE,KAAK,CAAC,IAAI;gBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7E,CAAC;KACJ,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;QACnB,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ;YACrB,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;gBACrB,OAAO;oBACH,IAAI,OAAO;wBACP,OAAO,KAAK,CAAC,eAAqC,CAAC;oBACvD,CAAC;oBACD,QAAQ,CAAC,OAA+C;wBACpD,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACrC,OAAO,GAAG,EAAE;4BACR,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBAC5C,CAAC,CAAC;oBACN,CAAC;oBACD,KAAK;wBACD,OAAO,OAAO,CAAS,MAAM,EAAE,oBAAoB,EAAE;4BACjD,QAAQ,EAAE,KAAK,CAAC,IAAI;4BACpB,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,IAAI,EAAE,OAAO;yBAChB,CAAC,CAAC;oBACP,CAAC;oBACD,IAAI,CAAC,QAA2B,EAAE;wBAC9B,OAAO,OAAO,CAAyB,MAAM,EAAE,oBAAoB,EAAE;4BACjE,QAAQ,EAAE,KAAK,CAAC,IAAI;4BACpB,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,IAAI,EAAE,MAAM;4BACZ,GAAG,KAAK;yBACX,CAAC,CAAC;oBACP,CAAC;iBACJ,CAAC;YACN,CAAC;YAED,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;KACJ,CAAsB,CAAC;AAC5B,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAwB;IAC/C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAmB;QAC5B,sBAAsB,EAAE,KAAK;QAC7B,wBAAwB,EAAE,KAAK;QAC/B,yBAAyB,EAAE,KAAK;QAChC,0BAA0B,EAAE,KAAK;QACjC,4BAA4B,EAAE,KAAK;QACnC,gCAAgC,EAAE,KAAK;QACvC,8BAA8B,EAAE,KAAK;QACrC,+BAA+B,EAAE,KAAK;QACtC,gBAAgB,EAAE,KAAK;QACvB,eAAe,EAAE,YAAY;QAC7B,mBAAmB,EAAE,IAAI,GAAG,EAAE;QAC9B,WAAW,EAAE,IAAI,GAAG,EAAE;KACzB,CAAC;IAEF,qBAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAwB,EAAE,QAAwB;IAC7E,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QACnC,MAAM,aAAa,GAAG,CAAC,KAUtB,EAAE,EAAE;YACD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACxF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO;YACX,CAAC;YAED,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACnC,OAAO;YACX,CAAC;YAED,MAAM,IAAI,GAAG;gBACT,GAAG,KAAK,CAAC,IAAI;gBACb,MAAM,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;aACjB,CAAC;YAEvB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC7B,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACjC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACvC,QAAQ,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,CAAC,KAA8D,EAAE,EAAE;YAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACxF,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO;YACX,CAAC;YAED,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,QAA4B,CAAC;YAC3D,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBACtC,OAAO;YACX,CAAC;YAED,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YACnC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACtC,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,GAAG,EAAE;YACnB,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAAC;YACjC,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC1C,KAAK,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChC,QAAQ,CAAC,yBAAyB,GAAG,IAAI,CAAC;IAC9C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,0BAA0B,EAAE,CAAC;QACvC,MAAM,YAAY,GAAG,GAAG,EAAE;YACtB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACtC,QAAQ,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,4BAA4B,EAAE,CAAC;QACzC,MAAM,cAAc,GAAG,GAAG,EAAE;YACxB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC5F,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;QAC3C,QAAQ,CAAC,4BAA4B,GAAG,IAAI,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,gCAAgC,EAAE,CAAC;QAC7C,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC5B,kBAAkB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;QACnD,QAAQ,CAAC,gCAAgC,GAAG,IAAI,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,+BAA+B,EAAE,CAAC;QAC5C,MAAM,iBAAiB,GAAG,GAAG,EAAE;YAC3B,kBAAkB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;QACjD,QAAQ,CAAC,+BAA+B,GAAG,IAAI,CAAC;IACpD,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,8BAA8B,EAAE,CAAC;QAC3C,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC1B,kBAAkB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACjD,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;QAC/C,QAAQ,CAAC,8BAA8B,GAAG,IAAI,CAAC;IACnD,CAAC;AACL,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,MAAwB,EAAE,QAAwB;IAC/E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAKxB,MAAM,EAAE,UAAU,EAAE;gBACnB,QAAQ,EAAE,KAAK,CAAC,IAAI;gBACpB,OAAO,EAAE,KAAK,CAAC,WAAW;aAC7B,CAAC,CAAC;YAEH,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC5B,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAChC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;YACtC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC;YAEvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjB,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;YACD,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACL,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,MAAc;IACnD,OAAO,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,OAAO,CAAS,MAAwB,EAAE,SAAiB,EAAE,OAAgB;IAClF,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,MAAkE,EAAE,EAAE;YACnG,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;gBACrD,OAAO;YACX,CAAC;YAED,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACtB,OAAO;YACX,CAAC;YAED,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAwB,EAAE,IAA2B;IAC7E,IAAI,QAAQ,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO;IACX,CAAC;IAED,QAAQ,CAAC,eAAe,GAAG,IAAI,CAAC;IAChC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { ClientSafeError } from "./types";
|
|
|
2
2
|
export { createRoomClient } from "./client";
|
|
3
3
|
export { defineRoomType } from "./room";
|
|
4
4
|
export { serveRoomType } from "./server";
|
|
5
|
-
export type { ClientConnectionState, ClientSocketLike, EventMetaFor, JoinRequest, JoinedRoom, MemberProfileFor, PresenceListQuery, PresenceFor, PresencePageFor, PresencePolicy, RoomMemberSnapshot, RoomClient, RoomDefinition, RoomEvents, RoomProfileFor, RoomRpc, RoomSchema, ServerStateFor, RoomServerAdapter, RoomServerBroadcastApi, RoomServerHandle, RoomServerContext, RoomServerHandlers, RoomSnapshot, ServerAdmission, ServerSocketLike, VisibleMemberFor, } from "./types";
|
|
5
|
+
export type { ClientConnectionState, ClientSocketLike, EventMetaFor, JoinRequest, JoinedRoom, MemberProfileFor, PresenceListQuery, PresenceFor, PresencePageFor, PresencePolicy, RoomMemberSnapshot, RoomClient, RoomDefinition, RoomEvents, RoomProfileFor, RoomRpc, RoomSchema, ServerStateFor, RoomServerAdapter, RoomServerBroadcastApi, RoomServerHandle, RoomServerContext, RoomServerHandlers, RoomSnapshot, ServerAdmission, ServerAdmissionInput, ServerSocketLike, VisibleMemberFor, } from "./types";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,YAAY,EACR,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,OAAO,EACP,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,YAAY,EACR,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,OAAO,EACP,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ import type { RoomDefinition, RoomServerAdapter, RoomServerHandle, RoomServerHan
|
|
|
2
2
|
/**
|
|
3
3
|
* Attaches room runtime handlers to a connected server socket.
|
|
4
4
|
*
|
|
5
|
-
* Returns a
|
|
6
|
-
*
|
|
5
|
+
* Returns a handle that unregisters all listeners for the bound socket via
|
|
6
|
+
* `cleanup()`, and exposes room introspection helpers.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
10
|
* io.on("connection", (socket) => {
|
|
11
|
-
* const
|
|
11
|
+
* const handle = serveRoomType(socket, chatRoomType, {
|
|
12
12
|
* onAuth: async () => ({ userId: socket.id }),
|
|
13
13
|
* admit: async (join, ctx) => ({
|
|
14
14
|
* roomId: join.roomId,
|
|
@@ -19,7 +19,7 @@ import type { RoomDefinition, RoomServerAdapter, RoomServerHandle, RoomServerHan
|
|
|
19
19
|
* });
|
|
20
20
|
*
|
|
21
21
|
* // Later if needed:
|
|
22
|
-
* //
|
|
22
|
+
* // handle.cleanup();
|
|
23
23
|
* });
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAWR,cAAc,EAGd,iBAAiB,EAEjB,gBAAgB,EAEhB,kBAAkB,EAElB,gBAAgB,EAKnB,MAAM,SAAS,CAAC;AAmKjB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,cAAc,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAC5E,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,EAC1C,OAAO,CAAC,EAAE,iBAAiB,GAC5B,gBAAgB,CAAC,KAAK,CAAC,CAsXzB"}
|
package/dist/server.js
CHANGED
|
@@ -6,17 +6,106 @@ const CLIENT_EVENT = "room-kit:client-event";
|
|
|
6
6
|
const SERVER_EVENT = "room-kit:server-event";
|
|
7
7
|
const PRESENCE_EVENT = "room-kit:presence";
|
|
8
8
|
const PRESENCE_QUERY_EVENT = "room-kit:presence-query";
|
|
9
|
+
function assertNonEmptyString(value, label) {
|
|
10
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
11
|
+
throw new ClientSafeError(`${label} must be a non-empty string`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function assertObject(value, label) {
|
|
15
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
16
|
+
throw new ClientSafeError(`${label} must be an object`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function assertArray(value, label) {
|
|
20
|
+
if (!Array.isArray(value)) {
|
|
21
|
+
throw new ClientSafeError(`${label} must be an array`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Validates and narrows a join frame from the wire. */
|
|
25
|
+
function validateJoinFrame(raw) {
|
|
26
|
+
assertObject(raw, "Join frame");
|
|
27
|
+
assertNonEmptyString(raw.roomType, "roomType");
|
|
28
|
+
assertObject(raw.payload, "payload");
|
|
29
|
+
return { roomType: raw.roomType, payload: raw.payload };
|
|
30
|
+
}
|
|
31
|
+
/** Validates and narrows a leave frame from the wire. */
|
|
32
|
+
function validateLeaveFrame(raw) {
|
|
33
|
+
assertObject(raw, "Leave frame");
|
|
34
|
+
assertNonEmptyString(raw.roomType, "roomType");
|
|
35
|
+
assertNonEmptyString(raw.roomId, "roomId");
|
|
36
|
+
return { roomType: raw.roomType, roomId: raw.roomId };
|
|
37
|
+
}
|
|
38
|
+
/** Validates and narrows an RPC frame from the wire. */
|
|
39
|
+
function validateRpcFrame(raw) {
|
|
40
|
+
assertObject(raw, "RPC frame");
|
|
41
|
+
assertNonEmptyString(raw.roomType, "roomType");
|
|
42
|
+
assertNonEmptyString(raw.roomId, "roomId");
|
|
43
|
+
assertNonEmptyString(raw.name, "name");
|
|
44
|
+
assertArray(raw.args, "args");
|
|
45
|
+
return { roomType: raw.roomType, roomId: raw.roomId, name: raw.name, args: raw.args };
|
|
46
|
+
}
|
|
47
|
+
/** Validates and narrows a client-event frame from the wire. */
|
|
48
|
+
function validateClientEventFrame(raw) {
|
|
49
|
+
assertObject(raw, "Client-event frame");
|
|
50
|
+
assertNonEmptyString(raw.roomType, "roomType");
|
|
51
|
+
assertNonEmptyString(raw.roomId, "roomId");
|
|
52
|
+
assertNonEmptyString(raw.name, "name");
|
|
53
|
+
return { roomType: raw.roomType, roomId: raw.roomId, name: raw.name, payload: raw.payload };
|
|
54
|
+
}
|
|
55
|
+
/** Validates and narrows a presence-query frame from the wire. */
|
|
56
|
+
function validatePresenceQueryFrame(raw) {
|
|
57
|
+
assertObject(raw, "Presence-query frame");
|
|
58
|
+
assertNonEmptyString(raw.roomType, "roomType");
|
|
59
|
+
assertNonEmptyString(raw.roomId, "roomId");
|
|
60
|
+
if (raw.kind !== "count" && raw.kind !== "list") {
|
|
61
|
+
throw new ClientSafeError("Presence query kind must be 'count' or 'list'");
|
|
62
|
+
}
|
|
63
|
+
const result = { roomType: raw.roomType, roomId: raw.roomId, kind: raw.kind };
|
|
64
|
+
if (raw.offset !== undefined) {
|
|
65
|
+
if (typeof raw.offset !== "number" || !Number.isFinite(raw.offset)) {
|
|
66
|
+
throw new ClientSafeError("offset must be a finite number");
|
|
67
|
+
}
|
|
68
|
+
result.offset = raw.offset;
|
|
69
|
+
}
|
|
70
|
+
if (raw.limit !== undefined) {
|
|
71
|
+
if (typeof raw.limit !== "number" || !Number.isFinite(raw.limit)) {
|
|
72
|
+
throw new ClientSafeError("limit must be a finite number");
|
|
73
|
+
}
|
|
74
|
+
result.limit = raw.limit;
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
const DANGEROUS_PROPERTY_NAMES = new Set([
|
|
79
|
+
"__proto__",
|
|
80
|
+
"constructor",
|
|
81
|
+
"prototype",
|
|
82
|
+
"toString",
|
|
83
|
+
"valueOf",
|
|
84
|
+
"hasOwnProperty",
|
|
85
|
+
"isPrototypeOf",
|
|
86
|
+
"propertyIsEnumerable",
|
|
87
|
+
"toLocaleString",
|
|
88
|
+
]);
|
|
89
|
+
function assertSafeHandlerName(name) {
|
|
90
|
+
if (DANGEROUS_PROPERTY_NAMES.has(name)) {
|
|
91
|
+
throw new ClientSafeError(`Disallowed handler name '${name}'`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Maximum number of rooms that can exist within a single namespace. */
|
|
95
|
+
const MAX_ROOMS_PER_NAMESPACE = 10_000;
|
|
96
|
+
/** Maximum number of socket connections tracked per room. */
|
|
97
|
+
const MAX_MEMBERS_PER_ROOM = 10_000;
|
|
9
98
|
const namespaceStates = new WeakMap();
|
|
10
99
|
/**
|
|
11
100
|
* Attaches room runtime handlers to a connected server socket.
|
|
12
101
|
*
|
|
13
|
-
* Returns a
|
|
14
|
-
*
|
|
102
|
+
* Returns a handle that unregisters all listeners for the bound socket via
|
|
103
|
+
* `cleanup()`, and exposes room introspection helpers.
|
|
15
104
|
*
|
|
16
105
|
* @example
|
|
17
106
|
* ```ts
|
|
18
107
|
* io.on("connection", (socket) => {
|
|
19
|
-
* const
|
|
108
|
+
* const handle = serveRoomType(socket, chatRoomType, {
|
|
20
109
|
* onAuth: async () => ({ userId: socket.id }),
|
|
21
110
|
* admit: async (join, ctx) => ({
|
|
22
111
|
* roomId: join.roomId,
|
|
@@ -27,22 +116,29 @@ const namespaceStates = new WeakMap();
|
|
|
27
116
|
* });
|
|
28
117
|
*
|
|
29
118
|
* // Later if needed:
|
|
30
|
-
* //
|
|
119
|
+
* // handle.cleanup();
|
|
31
120
|
* });
|
|
32
121
|
* ```
|
|
33
122
|
*/
|
|
34
123
|
export function serveRoomType(socket, _room, handlers, adapter) {
|
|
35
124
|
const namespaceState = getNamespaceState(socket);
|
|
36
125
|
const authCache = new WeakMap();
|
|
37
|
-
const onJoin = async (
|
|
126
|
+
const onJoin = async (raw, ack) => {
|
|
38
127
|
try {
|
|
128
|
+
if (ack !== undefined && typeof ack !== "function") {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const frame = validateJoinFrame(raw);
|
|
39
132
|
assertMatchingRoomName(_room, frame.roomType);
|
|
40
133
|
const requestedRoomId = extractRoomId(frame.payload);
|
|
41
134
|
const roomCollection = getOrCreateRoomCollection(namespaceState, frame.roomType);
|
|
135
|
+
if (!roomCollection.has(requestedRoomId) && roomCollection.size >= MAX_ROOMS_PER_NAMESPACE) {
|
|
136
|
+
throw new ClientSafeError("Maximum room limit reached for this namespace");
|
|
137
|
+
}
|
|
42
138
|
const existingRoomState = roomCollection.get(requestedRoomId);
|
|
139
|
+
const auth = await resolveSocketAuth(socket, handlers, authCache, true);
|
|
43
140
|
const initialState = (existingRoomState?.serverState ??
|
|
44
141
|
await Promise.resolve(handlers.initState?.(frame.payload) ?? {}));
|
|
45
|
-
const auth = await resolveSocketAuth(socket, handlers, authCache, true);
|
|
46
142
|
const provisional = createContext(socket, namespaceState, {
|
|
47
143
|
adapter,
|
|
48
144
|
name: frame.roomType,
|
|
@@ -53,8 +149,7 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
53
149
|
roomProfile: undefined,
|
|
54
150
|
serverState: initialState,
|
|
55
151
|
});
|
|
56
|
-
const admission = await handlers
|
|
57
|
-
assertMatchingRoomIds(requestedRoomId, admission.roomId, admission.roomProfile.roomId);
|
|
152
|
+
const admission = await resolveAdmission(socket, handlers, requestedRoomId, frame.payload, provisional);
|
|
58
153
|
const roomState = roomCollection.get(admission.roomId) ?? {
|
|
59
154
|
presence: _room.presence,
|
|
60
155
|
roomProfile: admission.roomProfile,
|
|
@@ -62,6 +157,9 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
62
157
|
membersBySocketId: new Map(),
|
|
63
158
|
socketIdsByMemberId: new Map(),
|
|
64
159
|
};
|
|
160
|
+
if (!roomState.membersBySocketId.has(socket.id) && roomState.membersBySocketId.size >= MAX_MEMBERS_PER_ROOM) {
|
|
161
|
+
throw new ClientSafeError("Room is full");
|
|
162
|
+
}
|
|
65
163
|
roomState.roomProfile = roomState.roomProfile ?? admission.roomProfile;
|
|
66
164
|
roomState.serverState = roomState.serverState ?? provisional.serverState;
|
|
67
165
|
roomState.membersBySocketId.set(socket.id, {
|
|
@@ -97,8 +195,12 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
97
195
|
ack?.({ ok: false, error: toErrorMessage(error) });
|
|
98
196
|
}
|
|
99
197
|
};
|
|
100
|
-
const onLeave = async (
|
|
198
|
+
const onLeave = async (raw, ack) => {
|
|
101
199
|
try {
|
|
200
|
+
if (ack !== undefined && typeof ack !== "function") {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const payload = validateLeaveFrame(raw);
|
|
102
204
|
assertMatchingRoomName(_room, payload.roomType);
|
|
103
205
|
const stored = getStoredMembership(namespaceState, payload.roomType, payload.roomId, socket.id);
|
|
104
206
|
if (!stored) {
|
|
@@ -125,9 +227,14 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
125
227
|
ack?.({ ok: false, error: toErrorMessage(error) });
|
|
126
228
|
}
|
|
127
229
|
};
|
|
128
|
-
const onRpc = async (
|
|
230
|
+
const onRpc = async (raw, ack) => {
|
|
129
231
|
try {
|
|
232
|
+
if (ack !== undefined && typeof ack !== "function") {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const frame = validateRpcFrame(raw);
|
|
130
236
|
assertMatchingRoomName(_room, frame.roomType);
|
|
237
|
+
assertSafeHandlerName(frame.name);
|
|
131
238
|
if (!handlers.rpc || !Object.hasOwn(handlers.rpc, frame.name)) {
|
|
132
239
|
throw new ClientSafeError(`Unknown RPC '${frame.name}'`);
|
|
133
240
|
}
|
|
@@ -150,6 +257,9 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
150
257
|
roomProfile: getRoomState(namespaceState, frame.roomType, frame.roomId).roomProfile,
|
|
151
258
|
serverState: getRoomState(namespaceState, frame.roomType, frame.roomId).serverState,
|
|
152
259
|
});
|
|
260
|
+
if (frame.args.length > 64) {
|
|
261
|
+
throw new ClientSafeError("Too many RPC arguments");
|
|
262
|
+
}
|
|
153
263
|
const result = await handler(...frame.args, ctx);
|
|
154
264
|
ack?.({ ok: true, value: result });
|
|
155
265
|
}
|
|
@@ -157,9 +267,14 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
157
267
|
ack?.({ ok: false, error: toErrorMessage(error) });
|
|
158
268
|
}
|
|
159
269
|
};
|
|
160
|
-
const onClientEvent = async (
|
|
270
|
+
const onClientEvent = async (raw, ack) => {
|
|
161
271
|
try {
|
|
272
|
+
if (ack !== undefined && typeof ack !== "function") {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const frame = validateClientEventFrame(raw);
|
|
162
276
|
assertMatchingRoomName(_room, frame.roomType);
|
|
277
|
+
assertSafeHandlerName(frame.name);
|
|
163
278
|
const stored = getStoredMembership(namespaceState, frame.roomType, frame.roomId, socket.id);
|
|
164
279
|
if (!stored) {
|
|
165
280
|
throw new ClientSafeError("Socket is not joined to that room");
|
|
@@ -194,8 +309,12 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
194
309
|
ack?.({ ok: false, error: toErrorMessage(error) });
|
|
195
310
|
}
|
|
196
311
|
};
|
|
197
|
-
const onPresenceQuery = async (
|
|
312
|
+
const onPresenceQuery = async (raw, ack) => {
|
|
198
313
|
try {
|
|
314
|
+
if (ack !== undefined && typeof ack !== "function") {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const frame = validatePresenceQueryFrame(raw);
|
|
199
318
|
assertMatchingRoomName(_room, frame.roomType);
|
|
200
319
|
const stored = getStoredMembership(namespaceState, frame.roomType, frame.roomId, socket.id);
|
|
201
320
|
if (!stored) {
|
|
@@ -297,7 +416,7 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
297
416
|
})
|
|
298
417
|
.catch(() => undefined);
|
|
299
418
|
}
|
|
300
|
-
const
|
|
419
|
+
const cleanup = () => {
|
|
301
420
|
socket.off(JOIN_EVENT, onJoin);
|
|
302
421
|
socket.off(LEAVE_EVENT, onLeave);
|
|
303
422
|
socket.off(RPC_EVENT, onRpc);
|
|
@@ -305,12 +424,13 @@ export function serveRoomType(socket, _room, handlers, adapter) {
|
|
|
305
424
|
socket.off(PRESENCE_QUERY_EVENT, onPresenceQuery);
|
|
306
425
|
socket.off("disconnect", onDisconnect);
|
|
307
426
|
};
|
|
308
|
-
return
|
|
427
|
+
return {
|
|
428
|
+
cleanup,
|
|
309
429
|
rooms: () => listRoomSnapshots(namespaceState, _room.name),
|
|
310
430
|
room: (roomId) => getRoomSnapshot(namespaceState, _room.name, roomId),
|
|
311
431
|
members: (roomId, query) => getPresenceMembersPage(namespaceState, _room.name, roomId, query),
|
|
312
432
|
count: (roomId) => getPresenceCount(namespaceState, _room.name, roomId),
|
|
313
|
-
}
|
|
433
|
+
};
|
|
314
434
|
}
|
|
315
435
|
function createContext(socket, namespaceState, ctxState) {
|
|
316
436
|
const emit = createEventEmitApi((eventName, payload) => {
|
|
@@ -353,11 +473,16 @@ async function resolveSocketAuth(socket, handlers, authCache, revalidate) {
|
|
|
353
473
|
if (entry.pending) {
|
|
354
474
|
return entry.pending;
|
|
355
475
|
}
|
|
356
|
-
if (entry.
|
|
476
|
+
if (!entry.hasValue) {
|
|
357
477
|
const pending = Promise.resolve(handlers.onAuth?.(socket))
|
|
358
478
|
.then((auth) => {
|
|
479
|
+
if (auth === false) {
|
|
480
|
+
authCache.delete(socket);
|
|
481
|
+
throw new ClientSafeError("Unauthorized");
|
|
482
|
+
}
|
|
359
483
|
const current = authCache.get(socket) ?? {};
|
|
360
484
|
current.value = auth;
|
|
485
|
+
current.hasValue = true;
|
|
361
486
|
current.pending = undefined;
|
|
362
487
|
authCache.set(socket, current);
|
|
363
488
|
return auth;
|
|
@@ -386,6 +511,18 @@ async function resolveSocketAuth(socket, handlers, authCache, revalidate) {
|
|
|
386
511
|
}
|
|
387
512
|
handleRejectedAuth(authCache, socket, decision);
|
|
388
513
|
}
|
|
514
|
+
async function resolveAdmission(socket, handlers, joinRoomId, join, ctx) {
|
|
515
|
+
const admission = handlers.admit ? await Promise.resolve(handlers.admit(join, ctx)) : {};
|
|
516
|
+
const roomId = admission.roomId ?? joinRoomId;
|
|
517
|
+
const roomProfile = admission.roomProfile ?? { roomId };
|
|
518
|
+
assertMatchingRoomIds(joinRoomId, roomId, roomProfile.roomId);
|
|
519
|
+
return {
|
|
520
|
+
roomId,
|
|
521
|
+
memberId: admission.memberId ?? socket.id,
|
|
522
|
+
memberProfile: admission.memberProfile ?? {},
|
|
523
|
+
roomProfile,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
389
526
|
function handleRejectedAuth(authCache, socket, decision) {
|
|
390
527
|
authCache.delete(socket);
|
|
391
528
|
throw new ClientSafeError(decision.message ?? "Unauthorized");
|
|
@@ -737,7 +874,11 @@ function extractRoomId(payload) {
|
|
|
737
874
|
if (!payload || typeof payload !== "object" || typeof payload.roomId !== "string") {
|
|
738
875
|
throw new ClientSafeError("Join request must include a string roomId");
|
|
739
876
|
}
|
|
740
|
-
|
|
877
|
+
const roomId = payload.roomId;
|
|
878
|
+
if (roomId.length === 0 || roomId.length > 256) {
|
|
879
|
+
throw new ClientSafeError("roomId must be between 1 and 256 characters");
|
|
880
|
+
}
|
|
881
|
+
return roomId;
|
|
741
882
|
}
|
|
742
883
|
function toErrorMessage(error) {
|
|
743
884
|
return error instanceof ClientSafeError ? error.message : "An internal server error occurred.";
|