room-kit 1.0.0 → 1.0.1
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 +25 -10
- package/example/public/app.ts +184 -187
- package/example/server.ts +173 -146
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/client.ts +105 -16
- package/src/server.ts +189 -25
- package/src/types.ts +28 -4
- package/test/room.spec.ts +241 -78
package/test/room.spec.ts
CHANGED
|
@@ -282,7 +282,7 @@ describe("room kit", () => {
|
|
|
282
282
|
|
|
283
283
|
expect(connection.serverSocket.joinedRooms).toEqual([]);
|
|
284
284
|
|
|
285
|
-
stop();
|
|
285
|
+
stop.cleanup();
|
|
286
286
|
connection.close();
|
|
287
287
|
});
|
|
288
288
|
|
|
@@ -317,8 +317,8 @@ describe("room kit", () => {
|
|
|
317
317
|
expect(seenA).toEqual(["only-a"]);
|
|
318
318
|
expect(seenB).toEqual([]);
|
|
319
319
|
|
|
320
|
-
stopA();
|
|
321
|
-
stopB();
|
|
320
|
+
stopA.cleanup();
|
|
321
|
+
stopB.cleanup();
|
|
322
322
|
connectionA.close();
|
|
323
323
|
connectionB.close();
|
|
324
324
|
});
|
|
@@ -357,8 +357,8 @@ describe("room kit", () => {
|
|
|
357
357
|
expect(aliceRoom.roomProfile.created).toBe("2026-03-23T00:00:00.000Z");
|
|
358
358
|
expect(bobRoom.roomProfile.created).toBe("2026-03-23T00:00:00.000Z");
|
|
359
359
|
|
|
360
|
-
first.stop();
|
|
361
|
-
second.stop();
|
|
360
|
+
first.stop.cleanup();
|
|
361
|
+
second.stop.cleanup();
|
|
362
362
|
first.connection.close();
|
|
363
363
|
second.connection.close();
|
|
364
364
|
});
|
|
@@ -396,8 +396,8 @@ describe("room kit", () => {
|
|
|
396
396
|
expect(aliceNotices).toEqual(["private hello"]);
|
|
397
397
|
expect(bobNotices).toEqual([]);
|
|
398
398
|
|
|
399
|
-
first.stop();
|
|
400
|
-
second.stop();
|
|
399
|
+
first.stop.cleanup();
|
|
400
|
+
second.stop.cleanup();
|
|
401
401
|
first.connection.close();
|
|
402
402
|
second.connection.close();
|
|
403
403
|
});
|
|
@@ -454,12 +454,105 @@ describe("room kit", () => {
|
|
|
454
454
|
expect(aliceRoomNotices).toEqual(["room scoped"]);
|
|
455
455
|
expect(bobRoomNotices).toEqual([]);
|
|
456
456
|
|
|
457
|
-
first.stop();
|
|
458
|
-
second.stop();
|
|
457
|
+
first.stop.cleanup();
|
|
458
|
+
second.stop.cleanup();
|
|
459
459
|
first.connection.close();
|
|
460
460
|
second.connection.close();
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
+
it("exposes a cleanup alias on the server handle", async () => {
|
|
464
|
+
const namespace = new MockNamespace();
|
|
465
|
+
const roomType = createRoomType("cleanup-alias", "list");
|
|
466
|
+
let onDisconnectCalls = 0;
|
|
467
|
+
const handlers = {
|
|
468
|
+
...createBaseHandlers(),
|
|
469
|
+
onDisconnect: async () => {
|
|
470
|
+
onDisconnectCalls += 1;
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
const pair = createClientPair(namespace, "alice-socket", roomType, handlers);
|
|
474
|
+
|
|
475
|
+
await pair.client.join({
|
|
476
|
+
roomId: "room-1",
|
|
477
|
+
roomKey: "shared-key",
|
|
478
|
+
userId: "alice",
|
|
479
|
+
userName: "Ada",
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
expect(typeof pair.stop.cleanup).toBe("function");
|
|
483
|
+
pair.stop.cleanup();
|
|
484
|
+
|
|
485
|
+
pair.connection.serverSocket.receive("disconnect", undefined);
|
|
486
|
+
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
487
|
+
|
|
488
|
+
expect(onDisconnectCalls).toBe(0);
|
|
489
|
+
|
|
490
|
+
pair.connection.close();
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it("supports batched listen handlers for events and presence", async () => {
|
|
494
|
+
const namespace = new MockNamespace();
|
|
495
|
+
const roomType = createRoomType("batched-listen", "list");
|
|
496
|
+
const handlers = createBaseHandlers();
|
|
497
|
+
const alice = createClientPair(namespace, "alice-socket", roomType, handlers);
|
|
498
|
+
const bob = createClientPair(namespace, "bob-socket", roomType, handlers);
|
|
499
|
+
const carol = createClientPair(namespace, "carol-socket", roomType, handlers);
|
|
500
|
+
|
|
501
|
+
const aliceRoom = await alice.client.join({
|
|
502
|
+
roomId: "room-1",
|
|
503
|
+
roomKey: "shared-key",
|
|
504
|
+
userId: "alice",
|
|
505
|
+
userName: "Ada",
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
const seenMessages: string[] = [];
|
|
509
|
+
const seenPresenceCounts: number[] = [];
|
|
510
|
+
const cleanup = aliceRoom.listen({
|
|
511
|
+
events: {
|
|
512
|
+
message: (payload) => {
|
|
513
|
+
seenMessages.push(payload.text);
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
presence: {
|
|
517
|
+
onChange: (presence) => {
|
|
518
|
+
seenPresenceCounts.push(presence.count);
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
const bobRoom = await bob.client.join({
|
|
524
|
+
roomId: "room-1",
|
|
525
|
+
roomKey: "shared-key",
|
|
526
|
+
userId: "bob",
|
|
527
|
+
userName: "Ben",
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
expect(seenPresenceCounts).toContain(2);
|
|
531
|
+
|
|
532
|
+
await bobRoom.rpc.sendMessage({ text: "hello" });
|
|
533
|
+
expect(seenMessages).toEqual(["hello"]);
|
|
534
|
+
|
|
535
|
+
cleanup();
|
|
536
|
+
|
|
537
|
+
const carolRoom = await carol.client.join({
|
|
538
|
+
roomId: "room-1",
|
|
539
|
+
roomKey: "shared-key",
|
|
540
|
+
userId: "carol",
|
|
541
|
+
userName: "Cid",
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
await carolRoom.rpc.sendMessage({ text: "after-cleanup" });
|
|
545
|
+
expect(seenMessages).toEqual(["hello"]);
|
|
546
|
+
expect(seenPresenceCounts).toEqual([2]);
|
|
547
|
+
|
|
548
|
+
alice.stop.cleanup();
|
|
549
|
+
bob.stop.cleanup();
|
|
550
|
+
carol.stop.cleanup();
|
|
551
|
+
alice.connection.close();
|
|
552
|
+
bob.connection.close();
|
|
553
|
+
carol.connection.close();
|
|
554
|
+
});
|
|
555
|
+
|
|
463
556
|
it("reports presence counts and paginated member lists", async () => {
|
|
464
557
|
const namespace = new MockNamespace();
|
|
465
558
|
const roomType = createRoomType("presence-pages", "list");
|
|
@@ -506,9 +599,9 @@ describe("room kit", () => {
|
|
|
506
599
|
],
|
|
507
600
|
});
|
|
508
601
|
|
|
509
|
-
first.stop();
|
|
510
|
-
second.stop();
|
|
511
|
-
third.stop();
|
|
602
|
+
first.stop.cleanup();
|
|
603
|
+
second.stop.cleanup();
|
|
604
|
+
third.stop.cleanup();
|
|
512
605
|
first.connection.close();
|
|
513
606
|
second.connection.close();
|
|
514
607
|
third.connection.close();
|
|
@@ -550,9 +643,9 @@ describe("room kit", () => {
|
|
|
550
643
|
],
|
|
551
644
|
});
|
|
552
645
|
|
|
553
|
-
first.stop();
|
|
554
|
-
second.stop();
|
|
555
|
-
third.stop();
|
|
646
|
+
first.stop.cleanup();
|
|
647
|
+
second.stop.cleanup();
|
|
648
|
+
third.stop.cleanup();
|
|
556
649
|
first.connection.close();
|
|
557
650
|
second.connection.close();
|
|
558
651
|
third.connection.close();
|
|
@@ -602,8 +695,8 @@ describe("room kit", () => {
|
|
|
602
695
|
await bobRoom.rpc.sendMessage({ text: "after-disconnect" });
|
|
603
696
|
expect(rejoinedSeen).toEqual([]);
|
|
604
697
|
|
|
605
|
-
first.stop();
|
|
606
|
-
second.stop();
|
|
698
|
+
first.stop.cleanup();
|
|
699
|
+
second.stop.cleanup();
|
|
607
700
|
first.connection.close();
|
|
608
701
|
second.connection.close();
|
|
609
702
|
});
|
|
@@ -642,8 +735,8 @@ describe("room kit", () => {
|
|
|
642
735
|
expect(seen).toEqual(["before reconnect", "after reconnect"]);
|
|
643
736
|
expect(first.connection.serverSocket.joinedRooms).toEqual(["room-1", "room-1"]);
|
|
644
737
|
|
|
645
|
-
first.stop();
|
|
646
|
-
second.stop();
|
|
738
|
+
first.stop.cleanup();
|
|
739
|
+
second.stop.cleanup();
|
|
647
740
|
first.connection.close();
|
|
648
741
|
second.connection.close();
|
|
649
742
|
});
|
|
@@ -687,8 +780,8 @@ describe("room kit", () => {
|
|
|
687
780
|
],
|
|
688
781
|
});
|
|
689
782
|
|
|
690
|
-
first.stop();
|
|
691
|
-
second.stop();
|
|
783
|
+
first.stop.cleanup();
|
|
784
|
+
second.stop.cleanup();
|
|
692
785
|
first.connection.close();
|
|
693
786
|
second.connection.close();
|
|
694
787
|
});
|
|
@@ -744,8 +837,8 @@ describe("room kit", () => {
|
|
|
744
837
|
},
|
|
745
838
|
]);
|
|
746
839
|
|
|
747
|
-
first.stop();
|
|
748
|
-
second.stop();
|
|
840
|
+
first.stop.cleanup();
|
|
841
|
+
second.stop.cleanup();
|
|
749
842
|
first.connection.close();
|
|
750
843
|
second.connection.close();
|
|
751
844
|
});
|
|
@@ -778,7 +871,7 @@ describe("room kit", () => {
|
|
|
778
871
|
}),
|
|
779
872
|
).rejects.toThrow("Admission roomId must match join request roomId");
|
|
780
873
|
|
|
781
|
-
stop();
|
|
874
|
+
stop.cleanup();
|
|
782
875
|
connection.close();
|
|
783
876
|
});
|
|
784
877
|
|
|
@@ -809,7 +902,41 @@ describe("room kit", () => {
|
|
|
809
902
|
}),
|
|
810
903
|
).rejects.toThrow("unauthorized");
|
|
811
904
|
|
|
812
|
-
stop();
|
|
905
|
+
stop.cleanup();
|
|
906
|
+
connection.close();
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
it("rejects when onAuth returns false before initState runs", async () => {
|
|
910
|
+
const namespace = new MockNamespace();
|
|
911
|
+
const roomType = createRoomType("reject-auth-false", "list");
|
|
912
|
+
let initCalls = 0;
|
|
913
|
+
const handlers: RoomServerHandlers<typeof roomType, { userId: string }> = {
|
|
914
|
+
onAuth: async () => false,
|
|
915
|
+
initState: async () => {
|
|
916
|
+
initCalls += 1;
|
|
917
|
+
return {
|
|
918
|
+
roomKey: "shared-key",
|
|
919
|
+
created: "2026-03-23T00:00:00.000Z",
|
|
920
|
+
history: [],
|
|
921
|
+
};
|
|
922
|
+
},
|
|
923
|
+
admit: async () => {
|
|
924
|
+
throw new ClientSafeError("should not admit");
|
|
925
|
+
},
|
|
926
|
+
};
|
|
927
|
+
const { client, connection, stop } = createClientPair(namespace, "alice-socket", roomType, handlers);
|
|
928
|
+
|
|
929
|
+
await expect(
|
|
930
|
+
client.join({
|
|
931
|
+
roomId: "room-1",
|
|
932
|
+
roomKey: "shared-key",
|
|
933
|
+
userId: "alice",
|
|
934
|
+
userName: "Ada",
|
|
935
|
+
}),
|
|
936
|
+
).rejects.toThrow("Unauthorized");
|
|
937
|
+
expect(initCalls).toBe(0);
|
|
938
|
+
|
|
939
|
+
stop.cleanup();
|
|
813
940
|
connection.close();
|
|
814
941
|
});
|
|
815
942
|
|
|
@@ -909,7 +1036,7 @@ describe("room kit", () => {
|
|
|
909
1036
|
|
|
910
1037
|
expect(authCalls).toBe(1);
|
|
911
1038
|
|
|
912
|
-
stop();
|
|
1039
|
+
stop.cleanup();
|
|
913
1040
|
connection.close();
|
|
914
1041
|
});
|
|
915
1042
|
|
|
@@ -958,7 +1085,7 @@ describe("room kit", () => {
|
|
|
958
1085
|
]);
|
|
959
1086
|
expect(authCalls).toBe(1);
|
|
960
1087
|
|
|
961
|
-
stop();
|
|
1088
|
+
stop.cleanup();
|
|
962
1089
|
connection.close();
|
|
963
1090
|
});
|
|
964
1091
|
|
|
@@ -1014,7 +1141,7 @@ describe("room kit", () => {
|
|
|
1014
1141
|
]);
|
|
1015
1142
|
expect(authCalls).toBe(1);
|
|
1016
1143
|
|
|
1017
|
-
stop();
|
|
1144
|
+
stop.cleanup();
|
|
1018
1145
|
connection.close();
|
|
1019
1146
|
});
|
|
1020
1147
|
|
|
@@ -1085,7 +1212,7 @@ describe("room kit", () => {
|
|
|
1085
1212
|
await expect(joined.rpc.sendMessage({ text: "hello" })).rejects.toThrow("session expired");
|
|
1086
1213
|
expect(revalidateCalls).toBe(2);
|
|
1087
1214
|
|
|
1088
|
-
stop();
|
|
1215
|
+
stop.cleanup();
|
|
1089
1216
|
connection.close();
|
|
1090
1217
|
});
|
|
1091
1218
|
|
|
@@ -1153,7 +1280,7 @@ describe("room kit", () => {
|
|
|
1153
1280
|
expect(revalidateCalls).toBe(2);
|
|
1154
1281
|
expect(observedRpcAuthVersion).toBe(3);
|
|
1155
1282
|
|
|
1156
|
-
stop();
|
|
1283
|
+
stop.cleanup();
|
|
1157
1284
|
connection.close();
|
|
1158
1285
|
});
|
|
1159
1286
|
|
|
@@ -1185,7 +1312,7 @@ describe("room kit", () => {
|
|
|
1185
1312
|
|
|
1186
1313
|
expect(revalidateCalls).toBe(3);
|
|
1187
1314
|
|
|
1188
|
-
pair.stop();
|
|
1315
|
+
pair.stop.cleanup();
|
|
1189
1316
|
pair.connection.close();
|
|
1190
1317
|
});
|
|
1191
1318
|
|
|
@@ -1229,7 +1356,7 @@ describe("room kit", () => {
|
|
|
1229
1356
|
await expect(room.emit.relay({ text: "blocked" })).rejects.toThrow("session expired");
|
|
1230
1357
|
expect(relayCalls).toBe(0);
|
|
1231
1358
|
|
|
1232
|
-
pair.stop();
|
|
1359
|
+
pair.stop.cleanup();
|
|
1233
1360
|
pair.connection.close();
|
|
1234
1361
|
});
|
|
1235
1362
|
|
|
@@ -1263,7 +1390,7 @@ describe("room kit", () => {
|
|
|
1263
1390
|
|
|
1264
1391
|
expect(sequence).toEqual(["onDisconnect", "onLeave:alice"]);
|
|
1265
1392
|
|
|
1266
|
-
pair.stop();
|
|
1393
|
+
pair.stop.cleanup();
|
|
1267
1394
|
pair.connection.close();
|
|
1268
1395
|
});
|
|
1269
1396
|
|
|
@@ -1303,8 +1430,8 @@ describe("room kit", () => {
|
|
|
1303
1430
|
expect(await bobRoom.presence.count()).toBe(1);
|
|
1304
1431
|
expect(bob.stop.count("room-1")).toBe(1);
|
|
1305
1432
|
|
|
1306
|
-
alice.stop();
|
|
1307
|
-
bob.stop();
|
|
1433
|
+
alice.stop.cleanup();
|
|
1434
|
+
bob.stop.cleanup();
|
|
1308
1435
|
alice.connection.close();
|
|
1309
1436
|
bob.connection.close();
|
|
1310
1437
|
});
|
|
@@ -1334,7 +1461,7 @@ describe("room kit", () => {
|
|
|
1334
1461
|
id: "message-1",
|
|
1335
1462
|
});
|
|
1336
1463
|
|
|
1337
|
-
pair.stop();
|
|
1464
|
+
pair.stop.cleanup();
|
|
1338
1465
|
pair.connection.close();
|
|
1339
1466
|
});
|
|
1340
1467
|
|
|
@@ -1402,7 +1529,7 @@ describe("room kit", () => {
|
|
|
1402
1529
|
});
|
|
1403
1530
|
expect(authCalls).toBe(2);
|
|
1404
1531
|
|
|
1405
|
-
pair.stop();
|
|
1532
|
+
pair.stop.cleanup();
|
|
1406
1533
|
pair.connection.close();
|
|
1407
1534
|
});
|
|
1408
1535
|
|
|
@@ -1444,7 +1571,7 @@ describe("room kit", () => {
|
|
|
1444
1571
|
expect(disconnectCalls).toBe(1);
|
|
1445
1572
|
expect(leftRoomIds.slice().sort()).toEqual(["room-1", "room-2"]);
|
|
1446
1573
|
|
|
1447
|
-
pair.stop();
|
|
1574
|
+
pair.stop.cleanup();
|
|
1448
1575
|
pair.connection.close();
|
|
1449
1576
|
});
|
|
1450
1577
|
|
|
@@ -1487,7 +1614,7 @@ describe("room kit", () => {
|
|
|
1487
1614
|
|
|
1488
1615
|
expect(disconnectVersion).toBe(4);
|
|
1489
1616
|
|
|
1490
|
-
pair.stop();
|
|
1617
|
+
pair.stop.cleanup();
|
|
1491
1618
|
pair.connection.close();
|
|
1492
1619
|
});
|
|
1493
1620
|
|
|
@@ -1525,7 +1652,7 @@ describe("room kit", () => {
|
|
|
1525
1652
|
revoked = true;
|
|
1526
1653
|
await expect(room.presence.list({ offset: 0, limit: 10 })).rejects.toThrow("presence list blocked");
|
|
1527
1654
|
|
|
1528
|
-
pair.stop();
|
|
1655
|
+
pair.stop.cleanup();
|
|
1529
1656
|
pair.connection.close();
|
|
1530
1657
|
});
|
|
1531
1658
|
|
|
@@ -1592,8 +1719,8 @@ describe("room kit", () => {
|
|
|
1592
1719
|
expect(await bobRoom.presence.count()).toBe(1);
|
|
1593
1720
|
expect(onLeaveCalls).toBe(0);
|
|
1594
1721
|
|
|
1595
|
-
alice.stop();
|
|
1596
|
-
bob.stop();
|
|
1722
|
+
alice.stop.cleanup();
|
|
1723
|
+
bob.stop.cleanup();
|
|
1597
1724
|
alice.connection.close();
|
|
1598
1725
|
bob.connection.close();
|
|
1599
1726
|
});
|
|
@@ -1634,7 +1761,7 @@ describe("room kit", () => {
|
|
|
1634
1761
|
mode = "generic";
|
|
1635
1762
|
await expect(room.rpc.sendMessage({ text: "generic" })).rejects.toThrow("An internal server error occurred.");
|
|
1636
1763
|
|
|
1637
|
-
pair.stop();
|
|
1764
|
+
pair.stop.cleanup();
|
|
1638
1765
|
pair.connection.close();
|
|
1639
1766
|
});
|
|
1640
1767
|
|
|
@@ -1707,11 +1834,11 @@ describe("room kit", () => {
|
|
|
1707
1834
|
expect(second.id).toBe("message-1");
|
|
1708
1835
|
expect(onAuthCalls).toBe(2);
|
|
1709
1836
|
|
|
1710
|
-
pair.stop();
|
|
1837
|
+
pair.stop.cleanup();
|
|
1711
1838
|
pair.connection.close();
|
|
1712
1839
|
});
|
|
1713
1840
|
|
|
1714
|
-
it("does not invoke lifecycle hooks after
|
|
1841
|
+
it("does not invoke lifecycle hooks after cleanup()", async () => {
|
|
1715
1842
|
const namespace = new MockNamespace();
|
|
1716
1843
|
type Auth = {
|
|
1717
1844
|
userId: string;
|
|
@@ -1738,7 +1865,7 @@ describe("room kit", () => {
|
|
|
1738
1865
|
userName: "Ada",
|
|
1739
1866
|
});
|
|
1740
1867
|
|
|
1741
|
-
pair.stop();
|
|
1868
|
+
pair.stop.cleanup();
|
|
1742
1869
|
pair.connection.serverSocket.receive("disconnect", undefined);
|
|
1743
1870
|
await new Promise<void>((resolve) => setTimeout(resolve, 0));
|
|
1744
1871
|
|
|
@@ -1787,9 +1914,9 @@ describe("room kit", () => {
|
|
|
1787
1914
|
await bobRoom.rpc.sendMessage({ text: "still-here" });
|
|
1788
1915
|
expect(seen).toEqual(["still-here"]);
|
|
1789
1916
|
|
|
1790
|
-
alicePrimary.stop();
|
|
1791
|
-
aliceSecondary.stop();
|
|
1792
|
-
bob.stop();
|
|
1917
|
+
alicePrimary.stop.cleanup();
|
|
1918
|
+
aliceSecondary.stop.cleanup();
|
|
1919
|
+
bob.stop.cleanup();
|
|
1793
1920
|
alicePrimary.connection.close();
|
|
1794
1921
|
aliceSecondary.connection.close();
|
|
1795
1922
|
bob.connection.close();
|
|
@@ -1866,7 +1993,7 @@ describe("room kit", () => {
|
|
|
1866
1993
|
expect(seen.presence).toEqual([2, 4]);
|
|
1867
1994
|
expect(seen.rpc).toEqual([3, 5]);
|
|
1868
1995
|
|
|
1869
|
-
pair.stop();
|
|
1996
|
+
pair.stop.cleanup();
|
|
1870
1997
|
pair.connection.close();
|
|
1871
1998
|
});
|
|
1872
1999
|
|
|
@@ -1903,7 +2030,7 @@ describe("room kit", () => {
|
|
|
1903
2030
|
await expect((room.presence as any).list()).rejects.toThrow("Presence is disabled for this room");
|
|
1904
2031
|
expect(() => stop.count("room-1")).toThrow("Presence is disabled for this room");
|
|
1905
2032
|
|
|
1906
|
-
stop();
|
|
2033
|
+
stop.cleanup();
|
|
1907
2034
|
connection.close();
|
|
1908
2035
|
});
|
|
1909
2036
|
|
|
@@ -1924,7 +2051,7 @@ describe("room kit", () => {
|
|
|
1924
2051
|
await expect((room.presence as any).list()).rejects.toThrow("Member lists are disabled for this room");
|
|
1925
2052
|
expect(() => stop.members("room-1")).toThrow("Member lists are disabled for this room");
|
|
1926
2053
|
|
|
1927
|
-
stop();
|
|
2054
|
+
stop.cleanup();
|
|
1928
2055
|
connection.close();
|
|
1929
2056
|
});
|
|
1930
2057
|
|
|
@@ -1943,7 +2070,7 @@ describe("room kit", () => {
|
|
|
1943
2070
|
|
|
1944
2071
|
await expect((room.emit as any).doesNotExist({ text: "nope" })).rejects.toThrow("Unknown event 'doesNotExist'");
|
|
1945
2072
|
|
|
1946
|
-
stop();
|
|
2073
|
+
stop.cleanup();
|
|
1947
2074
|
connection.close();
|
|
1948
2075
|
});
|
|
1949
2076
|
|
|
@@ -1984,8 +2111,8 @@ describe("room kit", () => {
|
|
|
1984
2111
|
await expect(bobRoom.presence.count()).resolves.toBe(2);
|
|
1985
2112
|
await expect((bobRoom.presence as any).list()).rejects.toThrow("Member lists are disabled for this room");
|
|
1986
2113
|
|
|
1987
|
-
alicePair.stop();
|
|
1988
|
-
bobPair.stop();
|
|
2114
|
+
alicePair.stop.cleanup();
|
|
2115
|
+
bobPair.stop.cleanup();
|
|
1989
2116
|
alicePair.connection.close();
|
|
1990
2117
|
bobPair.connection.close();
|
|
1991
2118
|
});
|
|
@@ -2017,8 +2144,8 @@ describe("room kit", () => {
|
|
|
2017
2144
|
await expect(aliceRoom.presence.count()).resolves.toBe(2);
|
|
2018
2145
|
await expect((aliceRoom.presence as any).list()).rejects.toThrow("Member lists are disabled for this room");
|
|
2019
2146
|
|
|
2020
|
-
alice.stop();
|
|
2021
|
-
bob.stop();
|
|
2147
|
+
alice.stop.cleanup();
|
|
2148
|
+
bob.stop.cleanup();
|
|
2022
2149
|
alice.connection.close();
|
|
2023
2150
|
bob.connection.close();
|
|
2024
2151
|
});
|
|
@@ -2047,7 +2174,7 @@ describe("room kit", () => {
|
|
|
2047
2174
|
await room.presence.count();
|
|
2048
2175
|
expect(calls).toBe(3);
|
|
2049
2176
|
|
|
2050
|
-
pair.stop();
|
|
2177
|
+
pair.stop.cleanup();
|
|
2051
2178
|
pair.connection.close();
|
|
2052
2179
|
});
|
|
2053
2180
|
|
|
@@ -2070,7 +2197,7 @@ describe("room kit", () => {
|
|
|
2070
2197
|
|
|
2071
2198
|
await expect(room.presence.count()).rejects.toThrow("presence blocked");
|
|
2072
2199
|
|
|
2073
|
-
pair.stop();
|
|
2200
|
+
pair.stop.cleanup();
|
|
2074
2201
|
pair.connection.close();
|
|
2075
2202
|
});
|
|
2076
2203
|
|
|
@@ -2093,7 +2220,7 @@ describe("room kit", () => {
|
|
|
2093
2220
|
|
|
2094
2221
|
await expect(room.presence.count()).rejects.toThrow("An internal server error occurred.");
|
|
2095
2222
|
|
|
2096
|
-
pair.stop();
|
|
2223
|
+
pair.stop.cleanup();
|
|
2097
2224
|
pair.connection.close();
|
|
2098
2225
|
});
|
|
2099
2226
|
|
|
@@ -2127,8 +2254,8 @@ describe("room kit", () => {
|
|
|
2127
2254
|
await expect(aliceRoom.presence.list()).resolves.toMatchObject({ count: 2 });
|
|
2128
2255
|
await expect((bobRoom.presence as any).list()).rejects.toThrow("Member lists are disabled for this room");
|
|
2129
2256
|
|
|
2130
|
-
alice.stop();
|
|
2131
|
-
bob.stop();
|
|
2257
|
+
alice.stop.cleanup();
|
|
2258
|
+
bob.stop.cleanup();
|
|
2132
2259
|
alice.connection.close();
|
|
2133
2260
|
bob.connection.close();
|
|
2134
2261
|
});
|
|
@@ -2145,10 +2272,10 @@ describe("room kit", () => {
|
|
|
2145
2272
|
userName: "Ada",
|
|
2146
2273
|
});
|
|
2147
2274
|
|
|
2148
|
-
await expect((room.emit as any)["__proto__"]({ text: "x" })).rejects.toThrow("
|
|
2149
|
-
await expect((room.emit as any)["toString"]({ text: "x" })).rejects.toThrow("
|
|
2275
|
+
await expect((room.emit as any)["__proto__"]({ text: "x" })).rejects.toThrow("Disallowed handler name '__proto__'");
|
|
2276
|
+
await expect((room.emit as any)["toString"]({ text: "x" })).rejects.toThrow("Disallowed handler name 'toString'");
|
|
2150
2277
|
|
|
2151
|
-
pair.stop();
|
|
2278
|
+
pair.stop.cleanup();
|
|
2152
2279
|
pair.connection.close();
|
|
2153
2280
|
});
|
|
2154
2281
|
|
|
@@ -2164,10 +2291,46 @@ describe("room kit", () => {
|
|
|
2164
2291
|
userName: "Ada",
|
|
2165
2292
|
});
|
|
2166
2293
|
|
|
2167
|
-
await expect((room.rpc as any)["__proto__"]()).rejects.toThrow("
|
|
2168
|
-
await expect((room.rpc as any)["toString"]()).rejects.toThrow("
|
|
2294
|
+
await expect((room.rpc as any)["__proto__"]()).rejects.toThrow("Disallowed handler name '__proto__'");
|
|
2295
|
+
await expect((room.rpc as any)["toString"]()).rejects.toThrow("Disallowed handler name 'toString'");
|
|
2296
|
+
|
|
2297
|
+
pair.stop.cleanup();
|
|
2298
|
+
pair.connection.close();
|
|
2299
|
+
});
|
|
2300
|
+
|
|
2301
|
+
it("does not run initState before auth resolves", async () => {
|
|
2302
|
+
const namespace = new MockNamespace();
|
|
2303
|
+
const roomType = createRoomType("init-before-auth", "count");
|
|
2304
|
+
let initCalls = 0;
|
|
2305
|
+
const handlers: RoomServerHandlers<typeof roomType, { userId: string }> = {
|
|
2306
|
+
onAuth: async () => {
|
|
2307
|
+
throw new ClientSafeError("unauthorized");
|
|
2308
|
+
},
|
|
2309
|
+
initState: async () => {
|
|
2310
|
+
initCalls += 1;
|
|
2311
|
+
return {
|
|
2312
|
+
roomKey: "shared-key",
|
|
2313
|
+
created: "2026-03-23T00:00:00.000Z",
|
|
2314
|
+
history: [],
|
|
2315
|
+
};
|
|
2316
|
+
},
|
|
2317
|
+
admit: async () => {
|
|
2318
|
+
throw new Error("should not reach admit");
|
|
2319
|
+
},
|
|
2320
|
+
};
|
|
2321
|
+
|
|
2322
|
+
const pair = createClientPair(namespace, "alice-socket", roomType, handlers);
|
|
2323
|
+
await expect(
|
|
2324
|
+
pair.client.join({
|
|
2325
|
+
roomId: "room-1",
|
|
2326
|
+
roomKey: "shared-key",
|
|
2327
|
+
userId: "alice",
|
|
2328
|
+
userName: "Ada",
|
|
2329
|
+
}),
|
|
2330
|
+
).rejects.toThrow("unauthorized");
|
|
2331
|
+
expect(initCalls).toBe(0);
|
|
2169
2332
|
|
|
2170
|
-
pair.stop();
|
|
2333
|
+
pair.stop.cleanup();
|
|
2171
2334
|
pair.connection.close();
|
|
2172
2335
|
});
|
|
2173
2336
|
|
|
@@ -2202,8 +2365,8 @@ describe("room kit", () => {
|
|
|
2202
2365
|
|
|
2203
2366
|
expect(adapterEvents).toContain("room-kit:presence");
|
|
2204
2367
|
|
|
2205
|
-
alice.stop();
|
|
2206
|
-
bob.stop();
|
|
2368
|
+
alice.stop.cleanup();
|
|
2369
|
+
bob.stop.cleanup();
|
|
2207
2370
|
alice.connection.close();
|
|
2208
2371
|
bob.connection.close();
|
|
2209
2372
|
});
|
|
@@ -2240,8 +2403,8 @@ describe("room kit", () => {
|
|
|
2240
2403
|
],
|
|
2241
2404
|
});
|
|
2242
2405
|
|
|
2243
|
-
first.stop();
|
|
2244
|
-
second.stop();
|
|
2406
|
+
first.stop.cleanup();
|
|
2407
|
+
second.stop.cleanup();
|
|
2245
2408
|
first.connection.close();
|
|
2246
2409
|
second.connection.close();
|
|
2247
2410
|
});
|
|
@@ -2283,9 +2446,9 @@ describe("room kit", () => {
|
|
|
2283
2446
|
expect(seenRoom1).toEqual([]);
|
|
2284
2447
|
expect(seenRoom2).toEqual(["hello-room-2"]);
|
|
2285
2448
|
|
|
2286
|
-
alice.stop();
|
|
2287
|
-
bob.stop();
|
|
2288
|
-
carol.stop();
|
|
2449
|
+
alice.stop.cleanup();
|
|
2450
|
+
bob.stop.cleanup();
|
|
2451
|
+
carol.stop.cleanup();
|
|
2289
2452
|
alice.connection.close();
|
|
2290
2453
|
bob.connection.close();
|
|
2291
2454
|
carol.connection.close();
|
|
@@ -2361,8 +2524,8 @@ describe("room kit", () => {
|
|
|
2361
2524
|
expect(seen).toEqual(["before"]);
|
|
2362
2525
|
expect(joinCalls.get("alice")).toBe(2);
|
|
2363
2526
|
|
|
2364
|
-
alice.stop();
|
|
2365
|
-
bob.stop();
|
|
2527
|
+
alice.stop.cleanup();
|
|
2528
|
+
bob.stop.cleanup();
|
|
2366
2529
|
alice.connection.close();
|
|
2367
2530
|
bob.connection.close();
|
|
2368
2531
|
});
|
|
@@ -2395,7 +2558,7 @@ describe("room kit", () => {
|
|
|
2395
2558
|
expect(states).toEqual(["connected", "reconnecting", "disconnected"]);
|
|
2396
2559
|
|
|
2397
2560
|
unsubscribe();
|
|
2398
|
-
pair.stop();
|
|
2561
|
+
pair.stop.cleanup();
|
|
2399
2562
|
pair.connection.close();
|
|
2400
2563
|
});
|
|
2401
2564
|
});
|