alepha 0.20.6 → 0.20.8

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.
Files changed (243) hide show
  1. package/AGENTS.md +0 -1
  2. package/CLAUDE.md +0 -1
  3. package/assets/agents-template.md +0 -1
  4. package/dist/api/audits/index.browser.js +1 -0
  5. package/dist/api/audits/index.browser.js.map +1 -1
  6. package/dist/api/audits/index.d.ts +370 -355
  7. package/dist/api/audits/index.d.ts.map +1 -1
  8. package/dist/api/audits/index.js +1 -0
  9. package/dist/api/audits/index.js.map +1 -1
  10. package/dist/api/files/index.browser.js +1 -0
  11. package/dist/api/files/index.browser.js.map +1 -1
  12. package/dist/api/files/index.d.ts +179 -170
  13. package/dist/api/files/index.d.ts.map +1 -1
  14. package/dist/api/files/index.js +1 -0
  15. package/dist/api/files/index.js.map +1 -1
  16. package/dist/api/jobs/index.browser.js +7 -0
  17. package/dist/api/jobs/index.browser.js.map +1 -1
  18. package/dist/api/jobs/index.d.ts +259 -250
  19. package/dist/api/jobs/index.d.ts.map +1 -1
  20. package/dist/api/jobs/index.js +21 -3
  21. package/dist/api/jobs/index.js.map +1 -1
  22. package/dist/api/keys/index.d.ts +198 -192
  23. package/dist/api/keys/index.d.ts.map +1 -1
  24. package/dist/api/keys/index.js +1 -0
  25. package/dist/api/keys/index.js.map +1 -1
  26. package/dist/api/notifications/index.d.ts +246 -245
  27. package/dist/api/notifications/index.d.ts.map +1 -1
  28. package/dist/api/organizations/index.d.ts +100 -97
  29. package/dist/api/organizations/index.d.ts.map +1 -1
  30. package/dist/api/parameters/index.d.ts +323 -320
  31. package/dist/api/parameters/index.d.ts.map +1 -1
  32. package/dist/api/payments/index.d.ts +431 -376
  33. package/dist/api/payments/index.d.ts.map +1 -1
  34. package/dist/api/payments/index.js +202 -87
  35. package/dist/api/payments/index.js.map +1 -1
  36. package/dist/api/subscriptions/index.d.ts +1695 -0
  37. package/dist/api/subscriptions/index.d.ts.map +1 -0
  38. package/dist/api/subscriptions/index.js +1919 -0
  39. package/dist/api/subscriptions/index.js.map +1 -0
  40. package/dist/api/users/index.d.ts +857 -841
  41. package/dist/api/users/index.d.ts.map +1 -1
  42. package/dist/api/verifications/index.d.ts +128 -127
  43. package/dist/api/verifications/index.d.ts.map +1 -1
  44. package/dist/bucket/index.d.ts +3 -2
  45. package/dist/bucket/index.d.ts.map +1 -1
  46. package/dist/cache/core/index.d.ts +114 -4
  47. package/dist/cache/core/index.d.ts.map +1 -1
  48. package/dist/cache/core/index.js +181 -15
  49. package/dist/cache/core/index.js.map +1 -1
  50. package/dist/cache/core/index.workerd.js +181 -15
  51. package/dist/cache/core/index.workerd.js.map +1 -1
  52. package/dist/cache/database/index.d.ts +20 -19
  53. package/dist/cache/database/index.d.ts.map +1 -1
  54. package/dist/cache/redis/index.d.ts +3 -2
  55. package/dist/cache/redis/index.d.ts.map +1 -1
  56. package/dist/cli/core/index.d.ts +116 -132
  57. package/dist/cli/core/index.d.ts.map +1 -1
  58. package/dist/cli/core/index.js +75 -7
  59. package/dist/cli/core/index.js.map +1 -1
  60. package/dist/cli/devtools/index.d.ts +3 -2
  61. package/dist/cli/devtools/index.d.ts.map +1 -1
  62. package/dist/cli/platform/index.d.ts +346 -290
  63. package/dist/cli/platform/index.d.ts.map +1 -1
  64. package/dist/cli/platform/index.js +105 -6
  65. package/dist/cli/platform/index.js.map +1 -1
  66. package/dist/cli/vendor/index.d.ts +12 -11
  67. package/dist/cli/vendor/index.d.ts.map +1 -1
  68. package/dist/command/index.d.ts +5 -4
  69. package/dist/command/index.d.ts.map +1 -1
  70. package/dist/core/index.browser.js +1 -1
  71. package/dist/core/index.browser.js.map +1 -1
  72. package/dist/core/index.d.ts +119 -118
  73. package/dist/core/index.d.ts.map +1 -1
  74. package/dist/core/index.js +1 -1
  75. package/dist/core/index.js.map +1 -1
  76. package/dist/core/index.native.js +1 -1
  77. package/dist/core/index.native.js.map +1 -1
  78. package/dist/core/index.workerd.js +1 -1
  79. package/dist/core/index.workerd.js.map +1 -1
  80. package/dist/crypto/index.d.ts +3 -2
  81. package/dist/crypto/index.d.ts.map +1 -1
  82. package/dist/email/core/index.d.ts +3 -2
  83. package/dist/email/core/index.d.ts.map +1 -1
  84. package/dist/email/smtp/index.d.ts +7 -6
  85. package/dist/email/smtp/index.d.ts.map +1 -1
  86. package/dist/lock/core/index.d.ts +5 -4
  87. package/dist/lock/core/index.d.ts.map +1 -1
  88. package/dist/logger/index.d.ts +10 -9
  89. package/dist/logger/index.d.ts.map +1 -1
  90. package/dist/mcp/index.d.ts +9 -8
  91. package/dist/mcp/index.d.ts.map +1 -1
  92. package/dist/mcp/index.js +1 -1
  93. package/dist/mcp/index.js.map +1 -1
  94. package/dist/orm/core/index.browser.js +9 -3
  95. package/dist/orm/core/index.browser.js.map +1 -1
  96. package/dist/orm/core/index.bun.js +31 -10
  97. package/dist/orm/core/index.bun.js.map +1 -1
  98. package/dist/orm/core/index.d.ts +33 -14
  99. package/dist/orm/core/index.d.ts.map +1 -1
  100. package/dist/orm/core/index.js +31 -10
  101. package/dist/orm/core/index.js.map +1 -1
  102. package/dist/orm/postgres/index.d.ts +6 -5
  103. package/dist/orm/postgres/index.d.ts.map +1 -1
  104. package/dist/queue/core/index.d.ts +5 -4
  105. package/dist/queue/core/index.d.ts.map +1 -1
  106. package/dist/queue/redis/index.d.ts +3 -2
  107. package/dist/queue/redis/index.d.ts.map +1 -1
  108. package/dist/react/form/index.d.ts +5 -0
  109. package/dist/react/form/index.d.ts.map +1 -1
  110. package/dist/react/form/index.js +6 -4
  111. package/dist/react/form/index.js.map +1 -1
  112. package/dist/react/i18n/index.d.ts +2 -1
  113. package/dist/react/i18n/index.d.ts.map +1 -1
  114. package/dist/react/router/index.d.ts +206 -205
  115. package/dist/react/router/index.d.ts.map +1 -1
  116. package/dist/react/ui/index.d.ts +11 -11
  117. package/dist/react/ui/index.d.ts.map +1 -1
  118. package/dist/scheduler/index.d.ts +3 -2
  119. package/dist/scheduler/index.d.ts.map +1 -1
  120. package/dist/security/index.browser.js +29 -1
  121. package/dist/security/index.browser.js.map +1 -1
  122. package/dist/security/index.d.ts +82 -35
  123. package/dist/security/index.d.ts.map +1 -1
  124. package/dist/security/index.js +56 -3
  125. package/dist/security/index.js.map +1 -1
  126. package/dist/server/auth/index.d.ts +163 -158
  127. package/dist/server/auth/index.d.ts.map +1 -1
  128. package/dist/server/auth/index.js +16 -4
  129. package/dist/server/auth/index.js.map +1 -1
  130. package/dist/server/core/index.d.ts +35 -34
  131. package/dist/server/core/index.d.ts.map +1 -1
  132. package/dist/server/cors/index.d.ts +7 -6
  133. package/dist/server/cors/index.d.ts.map +1 -1
  134. package/dist/server/health/index.d.ts +16 -15
  135. package/dist/server/health/index.d.ts.map +1 -1
  136. package/dist/server/links/index.d.ts +51 -50
  137. package/dist/server/links/index.d.ts.map +1 -1
  138. package/dist/server/rate-limit/index.d.ts +6 -5
  139. package/dist/server/rate-limit/index.d.ts.map +1 -1
  140. package/dist/server/swagger/index.d.ts +2 -1
  141. package/dist/server/swagger/index.d.ts.map +1 -1
  142. package/dist/topic/redis/index.d.ts +3 -2
  143. package/dist/topic/redis/index.d.ts.map +1 -1
  144. package/package.json +16 -32
  145. package/src/api/audits/entities/audits.ts +1 -0
  146. package/src/api/files/entities/files.ts +1 -0
  147. package/src/api/jobs/__tests__/$job.spec.ts +92 -40
  148. package/src/api/jobs/entities/jobExecutionEntity.ts +1 -0
  149. package/src/api/jobs/providers/JobProvider.ts +20 -5
  150. package/src/api/jobs/schemas/jobConfigAtom.ts +5 -0
  151. package/src/api/keys/entities/apiKeyEntity.ts +1 -0
  152. package/src/api/payments/controllers/MockCheckoutController.ts +146 -0
  153. package/src/api/payments/index.ts +3 -0
  154. package/src/api/payments/providers/MemoryPaymentProvider.ts +9 -4
  155. package/src/api/payments/providers/PaymentProvider.ts +25 -9
  156. package/src/api/payments/services/PaymentService.ts +3 -0
  157. package/src/api/subscriptions/__tests__/BillingService.spec.ts +218 -0
  158. package/src/api/subscriptions/__tests__/SubscriptionService.spec.ts +278 -0
  159. package/src/api/subscriptions/controllers/AdminSubscriptionController.ts +212 -0
  160. package/src/api/subscriptions/controllers/SubscriptionController.ts +189 -0
  161. package/src/api/subscriptions/entities/subscriptionEvents.ts +54 -0
  162. package/src/api/subscriptions/entities/subscriptions.ts +68 -0
  163. package/src/api/subscriptions/index.ts +133 -0
  164. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +382 -0
  165. package/src/api/subscriptions/middleware/$requireLimit.ts +50 -0
  166. package/src/api/subscriptions/middleware/$requirePlan.ts +49 -0
  167. package/src/api/subscriptions/notifications/SubscriptionNotifications.ts +110 -0
  168. package/src/api/subscriptions/schemas/cancelSubscriptionSchema.ts +8 -0
  169. package/src/api/subscriptions/schemas/changePlanSchema.ts +9 -0
  170. package/src/api/subscriptions/schemas/createSubscriptionSchema.ts +11 -0
  171. package/src/api/subscriptions/schemas/entitlementsSchema.ts +21 -0
  172. package/src/api/subscriptions/schemas/mrrSchema.ts +13 -0
  173. package/src/api/subscriptions/schemas/planDefinitionSchema.ts +71 -0
  174. package/src/api/subscriptions/schemas/planResourceSchema.ts +25 -0
  175. package/src/api/subscriptions/schemas/subscriptionEventResourceSchema.ts +8 -0
  176. package/src/api/subscriptions/schemas/subscriptionQuerySchema.ts +19 -0
  177. package/src/api/subscriptions/schemas/subscriptionResourceSchema.ts +6 -0
  178. package/src/api/subscriptions/schemas/subscriptionSettingsSchema.ts +32 -0
  179. package/src/api/subscriptions/schemas/subscriptionStatsSchema.ts +23 -0
  180. package/src/api/subscriptions/services/BillingService.ts +437 -0
  181. package/src/api/subscriptions/services/SubscriptionConfig.ts +56 -0
  182. package/src/api/subscriptions/services/SubscriptionService.ts +867 -0
  183. package/src/api/subscriptions/services/UsageService.ts +118 -0
  184. package/src/cache/core/__tests__/$cache.memory.spec.ts +450 -0
  185. package/src/cache/core/__tests__/$cache.swr.spec.ts +394 -0
  186. package/src/cache/core/index.ts +16 -0
  187. package/src/cache/core/primitives/$cache.ts +347 -21
  188. package/src/cli/core/tasks/BuildCloudflareTask.ts +16 -0
  189. package/src/cli/core/templates/agentMd.ts +39 -4
  190. package/src/cli/core/templates/biomeJson.ts +25 -1
  191. package/src/cli/core/templates/saasAdminLayoutTsx.ts +2 -2
  192. package/src/cli/platform/__tests__/CloudflareAdapter.spec.ts +117 -0
  193. package/src/cli/platform/adapters/CloudflareAdapter.ts +104 -7
  194. package/src/cli/platform/atoms/platformOptions.ts +13 -0
  195. package/src/cli/platform/schemas/platform.ts +1 -0
  196. package/src/cli/platform/services/CloudflareApi.ts +61 -0
  197. package/src/cli/platform/services/PlatformOrchestrator.ts +9 -4
  198. package/src/core/__tests__/$module.spec.ts +2 -2
  199. package/src/core/primitives/$module.ts +4 -4
  200. package/src/mcp/providers/McpServerProvider.ts +1 -1
  201. package/src/orm/core/providers/DatabaseTypeProvider.ts +9 -3
  202. package/src/orm/core/providers/drivers/DatabaseProvider.ts +1 -1
  203. package/src/orm/core/schemas/insertSchema.ts +10 -2
  204. package/src/orm/core/services/Repository.ts +27 -7
  205. package/src/react/form/hooks/useFormState.ts +8 -1
  206. package/src/react/form/index.ts +10 -1
  207. package/src/react/form/services/FormModel.ts +9 -3
  208. package/src/security/atoms/currentTenantAtom.ts +34 -0
  209. package/src/security/index.browser.ts +1 -0
  210. package/src/security/index.ts +12 -1
  211. package/src/security/primitives/$issuer.ts +17 -1
  212. package/src/security/providers/SecurityProvider.ts +37 -0
  213. package/src/server/auth/__tests__/validateRedirectUri.spec.ts +78 -0
  214. package/src/server/auth/providers/ServerAuthProvider.ts +21 -5
  215. package/tsconfig.base.json +2 -1
  216. package/dist/react/websocket/index.d.ts +0 -117
  217. package/dist/react/websocket/index.d.ts.map +0 -1
  218. package/dist/react/websocket/index.js +0 -108
  219. package/dist/react/websocket/index.js.map +0 -1
  220. package/dist/websocket/index.browser.js +0 -848
  221. package/dist/websocket/index.browser.js.map +0 -1
  222. package/dist/websocket/index.d.ts +0 -876
  223. package/dist/websocket/index.d.ts.map +0 -1
  224. package/dist/websocket/index.js +0 -1185
  225. package/dist/websocket/index.js.map +0 -1
  226. package/src/react/websocket/hooks/useRoom.tsx +0 -251
  227. package/src/react/websocket/index.ts +0 -7
  228. package/src/websocket/__tests__/$channel.spec.ts +0 -30
  229. package/src/websocket/__tests__/$websocket-new.spec.ts +0 -195
  230. package/src/websocket/__tests__/RoomManager.spec.ts +0 -146
  231. package/src/websocket/__tests__/websocket-integration.spec.ts +0 -951
  232. package/src/websocket/errors/WebSocketError.ts +0 -34
  233. package/src/websocket/index.browser.ts +0 -25
  234. package/src/websocket/index.shared.ts +0 -8
  235. package/src/websocket/index.ts +0 -85
  236. package/src/websocket/interfaces/WebSocketInterfaces.ts +0 -252
  237. package/src/websocket/primitives/$channel.ts +0 -131
  238. package/src/websocket/primitives/$websocket.ts +0 -107
  239. package/src/websocket/providers/NodeWebSocketServerProvider.ts +0 -617
  240. package/src/websocket/providers/WebSocketServerProvider.ts +0 -56
  241. package/src/websocket/services/RoomManager.ts +0 -160
  242. package/src/websocket/services/WebSocketClient.ts +0 -642
  243. package/src/websocket/services/WebSocketTopicService.ts +0 -108
@@ -1,195 +0,0 @@
1
- import { Alepha, t } from "alepha";
2
- import { NodeHttpServerProvider } from "alepha/server";
3
- import { test } from "vitest";
4
- import WebSocket from "ws";
5
- import { AlephaWebSocket } from "../index.ts";
6
- import { $channel } from "../primitives/$channel.ts";
7
- import { $websocket } from "../primitives/$websocket.ts";
8
-
9
- test("$websocket with channel-based architecture", async ({ expect }) => {
10
- const alepha = Alepha.create().with(AlephaWebSocket);
11
-
12
- const messages: any[] = [];
13
-
14
- class ChatController {
15
- // Define channel inside the class
16
- chatChannel = $channel({
17
- path: "/ws/chat",
18
- schema: {
19
- // Server → Client messages
20
- in: t.union([
21
- t.object({
22
- type: t.const("append"),
23
- content: t.text(),
24
- username: t.text(),
25
- }),
26
- t.object({
27
- type: t.const("system"),
28
- message: t.text(),
29
- }),
30
- ]),
31
- // Client → Server messages
32
- out: t.object({
33
- content: t.text(),
34
- }),
35
- },
36
- });
37
-
38
- chat = $websocket({
39
- channel: this.chatChannel,
40
- handler: async ({ connectionId, roomId, message, reply }) => {
41
- // Broadcast to all in room except sender
42
- await reply({
43
- message: {
44
- type: "append",
45
- content: message.content,
46
- username: connectionId,
47
- },
48
- exceptSelf: true,
49
- });
50
- },
51
- });
52
- }
53
-
54
- const controller = alepha.inject(ChatController);
55
- await alepha.start();
56
-
57
- const httpServer = alepha.inject(NodeHttpServerProvider);
58
- const hostname = httpServer.hostname.replace("http://", "ws://");
59
-
60
- // Connect two clients to the same room
61
- const ws1 = new WebSocket(`${hostname}/ws/chat?roomId=room-1`);
62
- const ws2 = new WebSocket(`${hostname}/ws/chat?roomId=room-1`);
63
-
64
- await Promise.all([
65
- new Promise((resolve) => ws1.on("open", resolve)),
66
- new Promise((resolve) => ws2.on("open", resolve)),
67
- ]);
68
-
69
- // Listen for messages on ws2
70
- ws2.on("message", (data) => {
71
- const message = JSON.parse(data.toString());
72
- messages.push(message);
73
- });
74
-
75
- // Wait a bit for connections to be established
76
- await new Promise((resolve) => setTimeout(resolve, 100));
77
-
78
- // Send message from ws1
79
- ws1.send(
80
- JSON.stringify({
81
- roomId: "room-1",
82
- message: {
83
- content: "Hello from client 1!",
84
- },
85
- }),
86
- );
87
-
88
- // Wait for message to be received
89
- await new Promise((resolve) => setTimeout(resolve, 200));
90
-
91
- // ws2 should receive the message, but not ws1 (exceptSelf)
92
- expect(messages.length).toBe(1);
93
- expect(messages[0].type).toBe("append");
94
- expect(messages[0].content).toBe("Hello from client 1!");
95
- expect(messages[0].username).toContain("ws-");
96
-
97
- // Test emit API from server
98
- await controller.chat.emit({
99
- roomId: "room-1",
100
- message: {
101
- type: "system",
102
- message: "Server announcement",
103
- },
104
- });
105
-
106
- await new Promise((resolve) => setTimeout(resolve, 200));
107
-
108
- // Both clients should receive the system message
109
- expect(messages.length).toBe(2);
110
- expect(messages[1].type).toBe("system");
111
- expect(messages[1].message).toBe("Server announcement");
112
-
113
- ws1.close();
114
- ws2.close();
115
- await alepha.stop();
116
- });
117
-
118
- test("$websocket room isolation", async ({ expect }) => {
119
- const alepha = Alepha.create().with(AlephaWebSocket);
120
-
121
- class ChatController {
122
- chatChannel = $channel({
123
- path: "/ws/chat",
124
- schema: {
125
- in: t.object({
126
- type: t.const("message"),
127
- content: t.text(),
128
- }),
129
- out: t.object({
130
- content: t.text(),
131
- }),
132
- },
133
- });
134
-
135
- chat = $websocket({
136
- channel: this.chatChannel,
137
- handler: async ({ roomId, message, reply }) => {
138
- await reply({
139
- message: {
140
- type: "message",
141
- content: message.content,
142
- },
143
- });
144
- },
145
- });
146
- }
147
-
148
- const controller = alepha.inject(ChatController);
149
- await alepha.start();
150
-
151
- const httpServer = alepha.inject(NodeHttpServerProvider);
152
- const hostname = httpServer.hostname.replace("http://", "ws://");
153
-
154
- // Connect clients to different rooms
155
- const room1Client = new WebSocket(`${hostname}/ws/chat?roomId=room-1`);
156
- const room2Client = new WebSocket(`${hostname}/ws/chat?roomId=room-2`);
157
-
158
- await Promise.all([
159
- new Promise((resolve) => room1Client.on("open", resolve)),
160
- new Promise((resolve) => room2Client.on("open", resolve)),
161
- ]);
162
-
163
- const room1Messages: any[] = [];
164
- const room2Messages: any[] = [];
165
-
166
- room1Client.on("message", (data) => {
167
- room1Messages.push(JSON.parse(data.toString()));
168
- });
169
-
170
- room2Client.on("message", (data) => {
171
- room2Messages.push(JSON.parse(data.toString()));
172
- });
173
-
174
- await new Promise((resolve) => setTimeout(resolve, 100));
175
-
176
- // Send to room-1 only
177
- await controller.chat.emit({
178
- roomId: "room-1",
179
- message: {
180
- type: "message",
181
- content: "Message for room 1",
182
- },
183
- });
184
-
185
- await new Promise((resolve) => setTimeout(resolve, 200));
186
-
187
- // Only room1Client should receive the message
188
- expect(room1Messages.length).toBe(1);
189
- expect(room1Messages[0].content).toBe("Message for room 1");
190
- expect(room2Messages.length).toBe(0);
191
-
192
- room1Client.close();
193
- room2Client.close();
194
- await alepha.stop();
195
- });
@@ -1,146 +0,0 @@
1
- import { Alepha } from "alepha";
2
- import { describe, expect, it } from "vitest";
3
- import { AlephaWebSocket } from "../index.ts";
4
- import { RoomManager } from "../services/RoomManager.ts";
5
-
6
- describe("RoomManager", () => {
7
- const createRoomManager = () => {
8
- const alepha = Alepha.create().with(AlephaWebSocket);
9
- return alepha.inject(RoomManager);
10
- };
11
-
12
- describe("joinRoom / joinRooms", () => {
13
- it("should add connection to a room", () => {
14
- const rm = createRoomManager();
15
- rm.joinRoom("conn-1", "room-a");
16
-
17
- expect(rm.getRoomConnections("room-a")).toEqual(["conn-1"]);
18
- expect(rm.getConnectionRooms("conn-1")).toEqual(["room-a"]);
19
- });
20
-
21
- it("should add connection to multiple rooms", () => {
22
- const rm = createRoomManager();
23
- rm.joinRooms("conn-1", ["room-a", "room-b", "room-c"]);
24
-
25
- expect(rm.getConnectionRooms("conn-1")).toEqual(
26
- expect.arrayContaining(["room-a", "room-b", "room-c"]),
27
- );
28
- expect(rm.getRoomConnections("room-a")).toEqual(["conn-1"]);
29
- expect(rm.getRoomConnections("room-b")).toEqual(["conn-1"]);
30
- });
31
-
32
- it("should allow multiple connections in the same room", () => {
33
- const rm = createRoomManager();
34
- rm.joinRoom("conn-1", "room-a");
35
- rm.joinRoom("conn-2", "room-a");
36
- rm.joinRoom("conn-3", "room-a");
37
-
38
- expect(rm.getRoomConnections("room-a")).toHaveLength(3);
39
- });
40
- });
41
-
42
- describe("leaveRoom", () => {
43
- it("should remove connection from room", () => {
44
- const rm = createRoomManager();
45
- rm.joinRoom("conn-1", "room-a");
46
- rm.leaveRoom("conn-1", "room-a");
47
-
48
- expect(rm.getRoomConnections("room-a")).toEqual([]);
49
- expect(rm.getConnectionRooms("conn-1")).toEqual([]);
50
- });
51
-
52
- it("should clean up empty rooms", () => {
53
- const rm = createRoomManager();
54
- rm.joinRoom("conn-1", "room-a");
55
- rm.leaveRoom("conn-1", "room-a");
56
-
57
- expect(rm.getAllRooms()).toEqual([]);
58
- });
59
-
60
- it("should not affect other connections in the same room", () => {
61
- const rm = createRoomManager();
62
- rm.joinRoom("conn-1", "room-a");
63
- rm.joinRoom("conn-2", "room-a");
64
- rm.leaveRoom("conn-1", "room-a");
65
-
66
- expect(rm.getRoomConnections("room-a")).toEqual(["conn-2"]);
67
- });
68
-
69
- it("should handle leaving a room the connection is not in", () => {
70
- const rm = createRoomManager();
71
- rm.leaveRoom("conn-1", "room-a");
72
-
73
- expect(rm.getAllRooms()).toEqual([]);
74
- });
75
- });
76
-
77
- describe("leaveAllRooms", () => {
78
- it("should remove connection from all rooms", () => {
79
- const rm = createRoomManager();
80
- rm.joinRooms("conn-1", ["room-a", "room-b", "room-c"]);
81
- rm.leaveAllRooms("conn-1");
82
-
83
- expect(rm.getConnectionRooms("conn-1")).toEqual([]);
84
- expect(rm.getAllRooms()).toEqual([]);
85
- });
86
-
87
- it("should not affect other connections", () => {
88
- const rm = createRoomManager();
89
- rm.joinRoom("conn-1", "room-a");
90
- rm.joinRoom("conn-2", "room-a");
91
- rm.joinRoom("conn-1", "room-b");
92
- rm.leaveAllRooms("conn-1");
93
-
94
- expect(rm.getRoomConnections("room-a")).toEqual(["conn-2"]);
95
- expect(rm.getConnectionRooms("conn-2")).toEqual(["room-a"]);
96
- });
97
-
98
- it("should be a no-op for unknown connection", () => {
99
- const rm = createRoomManager();
100
- rm.leaveAllRooms("unknown");
101
- expect(rm.getTotalConnections()).toBe(0);
102
- });
103
- });
104
-
105
- describe("isInRoom", () => {
106
- it("should return true when connection is in room", () => {
107
- const rm = createRoomManager();
108
- rm.joinRoom("conn-1", "room-a");
109
- expect(rm.isInRoom("conn-1", "room-a")).toBe(true);
110
- });
111
-
112
- it("should return false when connection is not in room", () => {
113
- const rm = createRoomManager();
114
- rm.joinRoom("conn-1", "room-a");
115
- expect(rm.isInRoom("conn-1", "room-b")).toBe(false);
116
- });
117
-
118
- it("should return false for unknown connection", () => {
119
- const rm = createRoomManager();
120
- expect(rm.isInRoom("unknown", "room-a")).toBe(false);
121
- });
122
- });
123
-
124
- describe("getStats", () => {
125
- it("should return correct statistics", () => {
126
- const rm = createRoomManager();
127
- rm.joinRooms("conn-1", ["room-a", "room-b"]);
128
- rm.joinRoom("conn-2", "room-a");
129
- rm.joinRoom("conn-3", "room-b");
130
-
131
- const stats = rm.getStats();
132
- expect(stats.totalRooms).toBe(2);
133
- expect(stats.totalConnections).toBe(3);
134
- expect(stats.roomSizes.get("room-a")).toBe(2);
135
- expect(stats.roomSizes.get("room-b")).toBe(2);
136
- });
137
-
138
- it("should return empty stats when no connections", () => {
139
- const rm = createRoomManager();
140
- const stats = rm.getStats();
141
- expect(stats.totalRooms).toBe(0);
142
- expect(stats.totalConnections).toBe(0);
143
- expect(stats.roomSizes.size).toBe(0);
144
- });
145
- });
146
- });