rivetkit 2.0.24-rc.1 → 2.0.25-rc.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.
Files changed (231) hide show
  1. package/dist/schemas/actor-persist/v1.ts +6 -0
  2. package/dist/schemas/actor-persist/v2.ts +9 -3
  3. package/dist/schemas/actor-persist/v3.ts +280 -0
  4. package/dist/schemas/client-protocol/v1.ts +6 -0
  5. package/dist/schemas/client-protocol/v2.ts +438 -0
  6. package/dist/schemas/file-system-driver/v1.ts +6 -0
  7. package/dist/schemas/file-system-driver/v2.ts +142 -0
  8. package/dist/tsup/actor/errors.cjs +2 -4
  9. package/dist/tsup/actor/errors.cjs.map +1 -1
  10. package/dist/tsup/actor/errors.d.cts +7 -10
  11. package/dist/tsup/actor/errors.d.ts +7 -10
  12. package/dist/tsup/actor/errors.js +9 -11
  13. package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
  14. package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
  15. package/dist/tsup/{chunk-ZTH3KYFH.cjs → chunk-3FG5OJ3G.cjs} +3 -3
  16. package/dist/tsup/{chunk-ZTH3KYFH.cjs.map → chunk-3FG5OJ3G.cjs.map} +1 -1
  17. package/dist/tsup/{chunk-BLK27ES3.js → chunk-6JN6W6G3.js} +44 -56
  18. package/dist/tsup/chunk-6JN6W6G3.js.map +1 -0
  19. package/dist/tsup/chunk-7IBNNGQ2.js +514 -0
  20. package/dist/tsup/chunk-7IBNNGQ2.js.map +1 -0
  21. package/dist/tsup/{chunk-36JJ4IQB.cjs → chunk-AZATXPR4.cjs} +4 -8
  22. package/dist/tsup/chunk-AZATXPR4.cjs.map +1 -0
  23. package/dist/tsup/chunk-B7MENRD5.cjs +5694 -0
  24. package/dist/tsup/chunk-B7MENRD5.cjs.map +1 -0
  25. package/dist/tsup/{chunk-BOMZS2TJ.js → chunk-BBVFDEYD.js} +9 -9
  26. package/dist/tsup/chunk-BBVFDEYD.js.map +1 -0
  27. package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
  28. package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
  29. package/dist/tsup/{chunk-2JYPS5YM.cjs → chunk-E63WZNMR.cjs} +6 -6
  30. package/dist/tsup/chunk-E63WZNMR.cjs.map +1 -0
  31. package/dist/tsup/{chunk-YBG6R7LX.js → chunk-EDGN4OC7.js} +3 -7
  32. package/dist/tsup/chunk-EDGN4OC7.js.map +1 -0
  33. package/dist/tsup/{chunk-BYMKMOBS.js → chunk-FLOQ3UWM.js} +1844 -1681
  34. package/dist/tsup/chunk-FLOQ3UWM.js.map +1 -0
  35. package/dist/tsup/{chunk-7L65NNWP.cjs → chunk-H7GV5DIW.cjs} +187 -185
  36. package/dist/tsup/chunk-H7GV5DIW.cjs.map +1 -0
  37. package/dist/tsup/{chunk-227FEWMB.js → chunk-HZYZ7JSF.js} +3322 -2251
  38. package/dist/tsup/chunk-HZYZ7JSF.js.map +1 -0
  39. package/dist/tsup/{chunk-FX7TWFQR.js → chunk-IDJK7ILQ.js} +2 -6
  40. package/dist/tsup/chunk-IDJK7ILQ.js.map +1 -0
  41. package/dist/tsup/{chunk-VHGY7PU5.cjs → chunk-ILFXA4AL.cjs} +1900 -1737
  42. package/dist/tsup/chunk-ILFXA4AL.cjs.map +1 -0
  43. package/dist/tsup/chunk-MV6M3FDL.cjs +514 -0
  44. package/dist/tsup/chunk-MV6M3FDL.cjs.map +1 -0
  45. package/dist/tsup/{chunk-PLUN2NQT.js → chunk-NWBKMCWC.js} +189 -187
  46. package/dist/tsup/chunk-NWBKMCWC.js.map +1 -0
  47. package/dist/tsup/{chunk-CD33GT6Z.js → chunk-QIHBDXTO.js} +2 -2
  48. package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
  49. package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
  50. package/dist/tsup/{chunk-INNFK746.cjs → chunk-WQU4M4ZC.cjs} +10 -14
  51. package/dist/tsup/chunk-WQU4M4ZC.cjs.map +1 -0
  52. package/dist/tsup/{chunk-SHVX2QUR.cjs → chunk-XKZA47XS.cjs} +17 -17
  53. package/dist/tsup/chunk-XKZA47XS.cjs.map +1 -0
  54. package/dist/tsup/{chunk-HHFKKVLR.cjs → chunk-YHWIOWVA.cjs} +45 -57
  55. package/dist/tsup/chunk-YHWIOWVA.cjs.map +1 -0
  56. package/dist/tsup/{chunk-YBHYXIP6.js → chunk-YVL6IRUM.js} +3 -3
  57. package/dist/tsup/chunk-YVL6IRUM.js.map +1 -0
  58. package/dist/tsup/client/mod.cjs +9 -9
  59. package/dist/tsup/client/mod.d.cts +5 -7
  60. package/dist/tsup/client/mod.d.ts +5 -7
  61. package/dist/tsup/client/mod.js +8 -8
  62. package/dist/tsup/common/log.cjs +3 -3
  63. package/dist/tsup/common/log.js +2 -2
  64. package/dist/tsup/common/websocket.cjs +4 -4
  65. package/dist/tsup/common/websocket.js +3 -3
  66. package/dist/tsup/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
  67. package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
  68. package/dist/tsup/driver-helpers/mod.cjs +5 -13
  69. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  70. package/dist/tsup/driver-helpers/mod.d.cts +11 -9
  71. package/dist/tsup/driver-helpers/mod.d.ts +11 -9
  72. package/dist/tsup/driver-helpers/mod.js +14 -22
  73. package/dist/tsup/driver-test-suite/mod.cjs +474 -303
  74. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  75. package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
  76. package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
  77. package/dist/tsup/driver-test-suite/mod.js +1085 -914
  78. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  79. package/dist/tsup/inspector/mod.cjs +6 -6
  80. package/dist/tsup/inspector/mod.d.cts +5 -7
  81. package/dist/tsup/inspector/mod.d.ts +5 -7
  82. package/dist/tsup/inspector/mod.js +5 -5
  83. package/dist/tsup/mod.cjs +10 -16
  84. package/dist/tsup/mod.cjs.map +1 -1
  85. package/dist/tsup/mod.d.cts +23 -25
  86. package/dist/tsup/mod.d.ts +23 -25
  87. package/dist/tsup/mod.js +17 -23
  88. package/dist/tsup/test/mod.cjs +11 -11
  89. package/dist/tsup/test/mod.d.cts +4 -6
  90. package/dist/tsup/test/mod.d.ts +4 -6
  91. package/dist/tsup/test/mod.js +10 -10
  92. package/dist/tsup/utils.cjs +3 -5
  93. package/dist/tsup/utils.cjs.map +1 -1
  94. package/dist/tsup/utils.d.cts +1 -2
  95. package/dist/tsup/utils.d.ts +1 -2
  96. package/dist/tsup/utils.js +2 -4
  97. package/package.json +13 -6
  98. package/src/actor/config.ts +56 -44
  99. package/src/actor/conn/driver.ts +61 -0
  100. package/src/actor/conn/drivers/http.ts +17 -0
  101. package/src/actor/conn/drivers/raw-request.ts +24 -0
  102. package/src/actor/conn/drivers/raw-websocket.ts +65 -0
  103. package/src/actor/conn/drivers/websocket.ts +129 -0
  104. package/src/actor/conn/mod.ts +232 -0
  105. package/src/actor/conn/persisted.ts +81 -0
  106. package/src/actor/conn/state-manager.ts +196 -0
  107. package/src/actor/contexts/action.ts +23 -0
  108. package/src/actor/{context.ts → contexts/actor.ts} +19 -8
  109. package/src/actor/contexts/conn-init.ts +31 -0
  110. package/src/actor/contexts/conn.ts +48 -0
  111. package/src/actor/contexts/create-conn-state.ts +13 -0
  112. package/src/actor/contexts/on-before-connect.ts +13 -0
  113. package/src/actor/contexts/on-connect.ts +22 -0
  114. package/src/actor/contexts/request.ts +48 -0
  115. package/src/actor/contexts/websocket.ts +48 -0
  116. package/src/actor/definition.ts +3 -3
  117. package/src/actor/driver.ts +36 -5
  118. package/src/actor/errors.ts +19 -24
  119. package/src/actor/instance/connection-manager.ts +465 -0
  120. package/src/actor/instance/event-manager.ts +292 -0
  121. package/src/actor/instance/kv.ts +15 -0
  122. package/src/actor/instance/mod.ts +1107 -0
  123. package/src/actor/instance/persisted.ts +67 -0
  124. package/src/actor/instance/schedule-manager.ts +349 -0
  125. package/src/actor/instance/state-manager.ts +502 -0
  126. package/src/actor/mod.ts +13 -16
  127. package/src/actor/protocol/old.ts +131 -43
  128. package/src/actor/protocol/serde.ts +19 -4
  129. package/src/actor/router-endpoints.ts +61 -586
  130. package/src/actor/router-websocket-endpoints.ts +408 -0
  131. package/src/actor/router.ts +63 -197
  132. package/src/actor/schedule.ts +1 -1
  133. package/src/client/actor-conn.ts +183 -249
  134. package/src/client/actor-handle.ts +29 -6
  135. package/src/client/client.ts +0 -4
  136. package/src/client/config.ts +1 -4
  137. package/src/client/mod.ts +0 -1
  138. package/src/client/raw-utils.ts +3 -3
  139. package/src/client/utils.ts +85 -39
  140. package/src/common/actor-router-consts.ts +5 -12
  141. package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
  142. package/src/common/log.ts +1 -1
  143. package/src/common/router.ts +28 -17
  144. package/src/common/utils.ts +2 -0
  145. package/src/driver-helpers/mod.ts +7 -10
  146. package/src/driver-helpers/utils.ts +18 -9
  147. package/src/driver-test-suite/mod.ts +26 -50
  148. package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
  149. package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
  150. package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
  151. package/src/driver-test-suite/tests/actor-conn.ts +5 -9
  152. package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
  153. package/src/driver-test-suite/tests/actor-driver.ts +0 -7
  154. package/src/driver-test-suite/tests/actor-handle.ts +12 -12
  155. package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
  156. package/src/driver-test-suite/tests/manager-driver.ts +1 -1
  157. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
  158. package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
  159. package/src/driver-test-suite/tests/raw-http.ts +5 -5
  160. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
  161. package/src/driver-test-suite/tests/request-access.ts +4 -4
  162. package/src/driver-test-suite/utils.ts +6 -10
  163. package/src/drivers/engine/actor-driver.ts +614 -424
  164. package/src/drivers/engine/mod.ts +0 -1
  165. package/src/drivers/file-system/actor.ts +24 -12
  166. package/src/drivers/file-system/global-state.ts +427 -37
  167. package/src/drivers/file-system/manager.ts +71 -83
  168. package/src/drivers/file-system/mod.ts +3 -0
  169. package/src/drivers/file-system/utils.ts +18 -8
  170. package/src/engine-process/mod.ts +38 -38
  171. package/src/inspector/utils.ts +7 -5
  172. package/src/manager/driver.ts +11 -4
  173. package/src/manager/gateway.ts +4 -29
  174. package/src/manager/protocol/mod.ts +0 -2
  175. package/src/manager/protocol/query.ts +0 -4
  176. package/src/manager/router.ts +67 -64
  177. package/src/manager-api/actors.ts +13 -0
  178. package/src/mod.ts +1 -3
  179. package/src/registry/mod.ts +20 -20
  180. package/src/registry/serve.ts +9 -14
  181. package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
  182. package/src/remote-manager-driver/api-endpoints.ts +13 -1
  183. package/src/remote-manager-driver/api-utils.ts +8 -0
  184. package/src/remote-manager-driver/metadata.ts +58 -0
  185. package/src/remote-manager-driver/mod.ts +47 -62
  186. package/src/remote-manager-driver/ws-proxy.ts +1 -1
  187. package/src/schemas/actor-persist/mod.ts +1 -1
  188. package/src/schemas/actor-persist/versioned.ts +56 -31
  189. package/src/schemas/client-protocol/mod.ts +1 -1
  190. package/src/schemas/client-protocol/versioned.ts +41 -21
  191. package/src/schemas/client-protocol-zod/mod.ts +103 -0
  192. package/src/schemas/file-system-driver/mod.ts +1 -1
  193. package/src/schemas/file-system-driver/versioned.ts +42 -19
  194. package/src/serde.ts +33 -11
  195. package/src/test/mod.ts +7 -3
  196. package/src/utils/node.ts +173 -0
  197. package/src/utils.ts +0 -4
  198. package/dist/tsup/chunk-227FEWMB.js.map +0 -1
  199. package/dist/tsup/chunk-2JYPS5YM.cjs.map +0 -1
  200. package/dist/tsup/chunk-36JJ4IQB.cjs.map +0 -1
  201. package/dist/tsup/chunk-7L65NNWP.cjs.map +0 -1
  202. package/dist/tsup/chunk-BLK27ES3.js.map +0 -1
  203. package/dist/tsup/chunk-BOMZS2TJ.js.map +0 -1
  204. package/dist/tsup/chunk-BYMKMOBS.js.map +0 -1
  205. package/dist/tsup/chunk-FX7TWFQR.js.map +0 -1
  206. package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
  207. package/dist/tsup/chunk-HHFKKVLR.cjs.map +0 -1
  208. package/dist/tsup/chunk-INNFK746.cjs.map +0 -1
  209. package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
  210. package/dist/tsup/chunk-O44LFKSB.cjs +0 -4623
  211. package/dist/tsup/chunk-O44LFKSB.cjs.map +0 -1
  212. package/dist/tsup/chunk-PLUN2NQT.js.map +0 -1
  213. package/dist/tsup/chunk-S4UJG7ZE.js +0 -1119
  214. package/dist/tsup/chunk-S4UJG7ZE.js.map +0 -1
  215. package/dist/tsup/chunk-SHVX2QUR.cjs.map +0 -1
  216. package/dist/tsup/chunk-VFB23BYZ.cjs +0 -1119
  217. package/dist/tsup/chunk-VFB23BYZ.cjs.map +0 -1
  218. package/dist/tsup/chunk-VHGY7PU5.cjs.map +0 -1
  219. package/dist/tsup/chunk-YBG6R7LX.js.map +0 -1
  220. package/dist/tsup/chunk-YBHYXIP6.js.map +0 -1
  221. package/src/actor/action.ts +0 -178
  222. package/src/actor/conn-drivers.ts +0 -216
  223. package/src/actor/conn-socket.ts +0 -8
  224. package/src/actor/conn.ts +0 -272
  225. package/src/actor/instance.ts +0 -2336
  226. package/src/actor/persisted.ts +0 -49
  227. package/src/actor/unstable-react.ts +0 -110
  228. package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
  229. package/src/drivers/engine/kv.ts +0 -3
  230. package/src/manager/hono-websocket-adapter.ts +0 -393
  231. /package/dist/tsup/{chunk-CD33GT6Z.js.map → chunk-QIHBDXTO.js.map} +0 -0
@@ -0,0 +1,292 @@
1
+ import * as cbor from "cbor-x";
2
+ import type * as protocol from "@/schemas/client-protocol/mod";
3
+ import { TO_CLIENT_VERSIONED } from "@/schemas/client-protocol/versioned";
4
+ import {
5
+ type ToClient as ToClientJson,
6
+ ToClientSchema,
7
+ } from "@/schemas/client-protocol-zod/mod";
8
+ import { bufferToArrayBuffer } from "@/utils";
9
+ import {
10
+ CONN_SEND_MESSAGE_SYMBOL,
11
+ CONN_SPEAKS_RIVETKIT_SYMBOL,
12
+ CONN_STATE_MANAGER_SYMBOL,
13
+ type Conn,
14
+ } from "../conn/mod";
15
+ import type { AnyDatabaseProvider } from "../database";
16
+ import { CachedSerializer } from "../protocol/serde";
17
+ import type { ActorInstance } from "./mod";
18
+
19
+ /**
20
+ * Manages event subscriptions and broadcasting for actor instances.
21
+ * Handles subscription tracking and efficient message distribution to connected clients.
22
+ */
23
+ export class EventManager<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
24
+ #actor: ActorInstance<S, CP, CS, V, I, DB>;
25
+ #subscriptionIndex = new Map<string, Set<Conn<S, CP, CS, V, I, DB>>>();
26
+
27
+ constructor(actor: ActorInstance<S, CP, CS, V, I, DB>) {
28
+ this.#actor = actor;
29
+ }
30
+
31
+ // MARK: - Public API
32
+
33
+ /**
34
+ * Adds a subscription for a connection to an event.
35
+ *
36
+ * @param eventName - The name of the event to subscribe to
37
+ * @param connection - The connection subscribing to the event
38
+ * @param fromPersist - Whether this subscription is being restored from persistence
39
+ */
40
+ addSubscription(
41
+ eventName: string,
42
+ connection: Conn<S, CP, CS, V, I, DB>,
43
+ fromPersist: boolean,
44
+ ) {
45
+ // Check if already subscribed
46
+ if (connection.subscriptions.has(eventName)) {
47
+ this.#actor.rLog.debug({
48
+ msg: "connection already has subscription",
49
+ eventName,
50
+ connId: connection.id,
51
+ });
52
+ return;
53
+ }
54
+
55
+ // Update connection's subscription list
56
+ connection.subscriptions.add(eventName);
57
+
58
+ // Update subscription index
59
+ let subscribers = this.#subscriptionIndex.get(eventName);
60
+ if (!subscribers) {
61
+ subscribers = new Set();
62
+ this.#subscriptionIndex.set(eventName, subscribers);
63
+ }
64
+ subscribers.add(connection);
65
+
66
+ // Persist subscription if not restoring from persistence
67
+ if (!fromPersist) {
68
+ connection[CONN_STATE_MANAGER_SYMBOL].addSubscription({
69
+ eventName,
70
+ });
71
+
72
+ // Save state immediately
73
+ this.#actor.stateManager.saveState({ immediate: true });
74
+ }
75
+
76
+ this.#actor.rLog.debug({
77
+ msg: "subscription added",
78
+ eventName,
79
+ connId: connection.id,
80
+ totalSubscribers: subscribers.size,
81
+ });
82
+ }
83
+
84
+ /**
85
+ * Removes a subscription for a connection from an event.
86
+ *
87
+ * @param eventName - The name of the event to unsubscribe from
88
+ * @param connection - The connection unsubscribing from the event
89
+ * @param fromRemoveConn - Whether this is being called as part of connection removal
90
+ */
91
+ removeSubscription(
92
+ eventName: string,
93
+ connection: Conn<S, CP, CS, V, I, DB>,
94
+ fromRemoveConn: boolean,
95
+ ) {
96
+ // Check if subscription exists
97
+ if (!connection.subscriptions.has(eventName)) {
98
+ this.#actor.rLog.warn({
99
+ msg: "connection does not have subscription",
100
+ eventName,
101
+ connId: connection.id,
102
+ });
103
+ return;
104
+ }
105
+
106
+ // Remove from connection's subscription list
107
+ connection.subscriptions.delete(eventName);
108
+
109
+ // Update subscription index
110
+ const subscribers = this.#subscriptionIndex.get(eventName);
111
+ if (subscribers) {
112
+ subscribers.delete(connection);
113
+ if (subscribers.size === 0) {
114
+ this.#subscriptionIndex.delete(eventName);
115
+ }
116
+ }
117
+
118
+ // Update persistence if not part of connection removal
119
+ if (!fromRemoveConn) {
120
+ // Remove from persisted subscriptions
121
+ const removed = connection[
122
+ CONN_STATE_MANAGER_SYMBOL
123
+ ].removeSubscription({ eventName });
124
+ if (!removed) {
125
+ this.#actor.rLog.warn({
126
+ msg: "subscription does not exist in persist",
127
+ eventName,
128
+ connId: connection.id,
129
+ });
130
+ }
131
+
132
+ // Save state immediately
133
+ this.#actor.stateManager.saveState({ immediate: true });
134
+ }
135
+
136
+ this.#actor.rLog.debug({
137
+ msg: "subscription removed",
138
+ eventName,
139
+ connId: connection.id,
140
+ remainingSubscribers: subscribers?.size || 0,
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Broadcasts an event to all subscribed connections.
146
+ *
147
+ * @param name - The name of the event to broadcast
148
+ * @param args - The arguments to send with the event
149
+ */
150
+ broadcast<Args extends Array<unknown>>(name: string, ...args: Args) {
151
+ this.#actor.assertReady();
152
+
153
+ // Emit to inspector
154
+ this.#actor.inspector.emitter.emit("eventFired", {
155
+ type: "broadcast",
156
+ eventName: name,
157
+ args,
158
+ });
159
+
160
+ // Get subscribers for this event
161
+ const subscribers = this.#subscriptionIndex.get(name);
162
+ if (!subscribers || subscribers.size === 0) {
163
+ this.#actor.rLog.debug({
164
+ msg: "no subscribers for event",
165
+ eventName: name,
166
+ });
167
+ return;
168
+ }
169
+
170
+ // Create serialized message
171
+ const eventData = { name, args };
172
+ const toClientSerializer = new CachedSerializer(
173
+ eventData,
174
+ TO_CLIENT_VERSIONED,
175
+ ToClientSchema,
176
+ // JSON: args is the raw value (array of arguments)
177
+ (value): ToClientJson => ({
178
+ body: {
179
+ tag: "Event" as const,
180
+ val: {
181
+ name: value.name,
182
+ args: value.args,
183
+ },
184
+ },
185
+ }),
186
+ // BARE/CBOR: args needs to be CBOR-encoded to ArrayBuffer
187
+ (value): protocol.ToClient => ({
188
+ body: {
189
+ tag: "Event" as const,
190
+ val: {
191
+ name: value.name,
192
+ args: bufferToArrayBuffer(cbor.encode(value.args)),
193
+ },
194
+ },
195
+ }),
196
+ );
197
+
198
+ // Send to all subscribers
199
+ let sentCount = 0;
200
+ for (const connection of subscribers) {
201
+ if (connection[CONN_SPEAKS_RIVETKIT_SYMBOL]) {
202
+ try {
203
+ connection[CONN_SEND_MESSAGE_SYMBOL](toClientSerializer);
204
+ sentCount++;
205
+ } catch (error) {
206
+ this.#actor.rLog.error({
207
+ msg: "failed to send event to connection",
208
+ eventName: name,
209
+ connId: connection.id,
210
+ error:
211
+ error instanceof Error
212
+ ? error.message
213
+ : String(error),
214
+ });
215
+ }
216
+ }
217
+ }
218
+
219
+ this.#actor.rLog.debug({
220
+ msg: "event broadcasted",
221
+ eventName: name,
222
+ subscriberCount: subscribers.size,
223
+ sentCount,
224
+ });
225
+ }
226
+
227
+ /**
228
+ * Gets all subscribers for a specific event.
229
+ *
230
+ * @param eventName - The name of the event
231
+ * @returns Set of connections subscribed to the event, or undefined if no subscribers
232
+ */
233
+ getSubscribers(
234
+ eventName: string,
235
+ ): Set<Conn<S, CP, CS, V, I, DB>> | undefined {
236
+ return this.#subscriptionIndex.get(eventName);
237
+ }
238
+
239
+ /**
240
+ * Gets all events and their subscriber counts.
241
+ *
242
+ * @returns Map of event names to subscriber counts
243
+ */
244
+ getEventStats(): Map<string, number> {
245
+ const stats = new Map<string, number>();
246
+ for (const [eventName, subscribers] of this.#subscriptionIndex) {
247
+ stats.set(eventName, subscribers.size);
248
+ }
249
+ return stats;
250
+ }
251
+
252
+ /**
253
+ * Clears all subscriptions for a connection.
254
+ * Used during connection cleanup.
255
+ *
256
+ * @param connection - The connection to clear subscriptions for
257
+ */
258
+ clearConnectionSubscriptions(connection: Conn<S, CP, CS, V, I, DB>) {
259
+ for (const eventName of [...connection.subscriptions.values()]) {
260
+ this.removeSubscription(eventName, connection, true);
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Gets the total number of unique events being subscribed to.
266
+ */
267
+ get eventCount(): number {
268
+ return this.#subscriptionIndex.size;
269
+ }
270
+
271
+ /**
272
+ * Gets the total number of subscriptions across all events.
273
+ */
274
+ get totalSubscriptionCount(): number {
275
+ let total = 0;
276
+ for (const subscribers of this.#subscriptionIndex.values()) {
277
+ total += subscribers.size;
278
+ }
279
+ return total;
280
+ }
281
+
282
+ /**
283
+ * Checks if an event has any subscribers.
284
+ *
285
+ * @param eventName - The name of the event to check
286
+ * @returns True if the event has at least one subscriber
287
+ */
288
+ hasSubscribers(eventName: string): boolean {
289
+ const subscribers = this.#subscriptionIndex.get(eventName);
290
+ return subscribers !== undefined && subscribers.size > 0;
291
+ }
292
+ }
@@ -0,0 +1,15 @@
1
+ export const KEYS = {
2
+ PERSIST_DATA: Uint8Array.from([1]),
3
+ CONN_PREFIX: Uint8Array.from([2]), // Prefix for connection keys
4
+ INSPECTOR_TOKEN: Uint8Array.from([3]), // Inspector token key
5
+ };
6
+
7
+ // Helper to create a connection key
8
+ export function makeConnKey(connId: string): Uint8Array {
9
+ const encoder = new TextEncoder();
10
+ const connIdBytes = encoder.encode(connId);
11
+ const key = new Uint8Array(KEYS.CONN_PREFIX.length + connIdBytes.length);
12
+ key.set(KEYS.CONN_PREFIX, 0);
13
+ key.set(connIdBytes, KEYS.CONN_PREFIX.length);
14
+ return key;
15
+ }