rivetkit 2.0.23 → 2.0.24
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/dist/schemas/actor-persist/v2.ts +3 -3
- package/dist/schemas/actor-persist/v3.ts +274 -0
- package/dist/schemas/client-protocol/v2.ts +432 -0
- package/dist/schemas/file-system-driver/v2.ts +136 -0
- package/dist/tsup/actor/errors.cjs +2 -4
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +7 -10
- package/dist/tsup/actor/errors.d.ts +7 -10
- package/dist/tsup/actor/errors.js +9 -11
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
- package/dist/tsup/{chunk-3JYSUFET.cjs → chunk-3543NCSN.cjs} +45 -57
- package/dist/tsup/chunk-3543NCSN.cjs.map +1 -0
- package/dist/tsup/chunk-4SHILYS5.cjs +5694 -0
- package/dist/tsup/chunk-4SHILYS5.cjs.map +1 -0
- package/dist/tsup/{chunk-NCUALX2Q.cjs → chunk-5BZO5XPS.cjs} +3 -3
- package/dist/tsup/{chunk-NCUALX2Q.cjs.map → chunk-5BZO5XPS.cjs.map} +1 -1
- package/dist/tsup/{chunk-5PKKNNNS.js → chunk-BAIGSF64.js} +189 -187
- package/dist/tsup/chunk-BAIGSF64.js.map +1 -0
- package/dist/tsup/{chunk-HNYF4T36.cjs → chunk-CHLZBSI2.cjs} +17 -17
- package/dist/tsup/chunk-CHLZBSI2.cjs.map +1 -0
- package/dist/tsup/chunk-D3SLADUD.cjs +512 -0
- package/dist/tsup/chunk-D3SLADUD.cjs.map +1 -0
- package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
- package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
- package/dist/tsup/{chunk-C56XVVV4.cjs → chunk-DLK5YCTN.cjs} +187 -185
- package/dist/tsup/chunk-DLK5YCTN.cjs.map +1 -0
- package/dist/tsup/{chunk-DLYZKFRY.js → chunk-DUJQWGYD.js} +3 -7
- package/dist/tsup/chunk-DUJQWGYD.js.map +1 -0
- package/dist/tsup/{chunk-5UJQWWO3.js → chunk-EIPANQMF.js} +2 -2
- package/dist/tsup/{chunk-54DVMQPT.cjs → chunk-ESMTDP7G.cjs} +6 -6
- package/dist/tsup/chunk-ESMTDP7G.cjs.map +1 -0
- package/dist/tsup/{chunk-XYK5PY3B.cjs → chunk-FVAKREFB.cjs} +1900 -1737
- package/dist/tsup/chunk-FVAKREFB.cjs.map +1 -0
- package/dist/tsup/{chunk-PHNIVSG5.js → chunk-I3XT7WOF.js} +44 -56
- package/dist/tsup/chunk-I3XT7WOF.js.map +1 -0
- package/dist/tsup/{chunk-3I6ZIJVJ.js → chunk-IMDS5T42.js} +3 -3
- package/dist/tsup/chunk-IMDS5T42.js.map +1 -0
- package/dist/tsup/{chunk-SN4KWTRA.cjs → chunk-J3HZJF2P.cjs} +10 -14
- package/dist/tsup/chunk-J3HZJF2P.cjs.map +1 -0
- package/dist/tsup/{chunk-NOZSCUPQ.js → chunk-MBBJUHSP.js} +1844 -1681
- package/dist/tsup/chunk-MBBJUHSP.js.map +1 -0
- package/dist/tsup/{chunk-RVVUS4X6.js → chunk-MO5CB6MD.js} +9 -9
- package/dist/tsup/chunk-MO5CB6MD.js.map +1 -0
- package/dist/tsup/chunk-OFOTPKAH.js +512 -0
- package/dist/tsup/chunk-OFOTPKAH.js.map +1 -0
- package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
- package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
- package/dist/tsup/{chunk-XSDSNHSE.cjs → chunk-YC5DUHPM.cjs} +4 -8
- package/dist/tsup/chunk-YC5DUHPM.cjs.map +1 -0
- package/dist/tsup/{chunk-YAYNBR37.js → chunk-YC7YPM2T.js} +2 -6
- package/dist/tsup/chunk-YC7YPM2T.js.map +1 -0
- package/dist/tsup/{chunk-FTQ62XTN.js → chunk-ZSPU5R4C.js} +3322 -2251
- package/dist/tsup/chunk-ZSPU5R4C.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -7
- package/dist/tsup/client/mod.d.ts +5 -7
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
- package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
- package/dist/tsup/driver-helpers/mod.cjs +5 -13
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +11 -9
- package/dist/tsup/driver-helpers/mod.d.ts +11 -9
- package/dist/tsup/driver-helpers/mod.js +14 -22
- package/dist/tsup/driver-test-suite/mod.cjs +474 -303
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
- package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
- package/dist/tsup/driver-test-suite/mod.js +1085 -914
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.d.cts +5 -7
- package/dist/tsup/inspector/mod.d.ts +5 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -16
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +23 -25
- package/dist/tsup/mod.d.ts +23 -25
- package/dist/tsup/mod.js +17 -23
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.d.cts +4 -6
- package/dist/tsup/test/mod.d.ts +4 -6
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +3 -5
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +1 -2
- package/dist/tsup/utils.d.ts +1 -2
- package/dist/tsup/utils.js +2 -4
- package/package.json +13 -6
- package/src/actor/config.ts +56 -44
- package/src/actor/conn/driver.ts +61 -0
- package/src/actor/conn/drivers/http.ts +17 -0
- package/src/actor/conn/drivers/raw-request.ts +24 -0
- package/src/actor/conn/drivers/raw-websocket.ts +65 -0
- package/src/actor/conn/drivers/websocket.ts +129 -0
- package/src/actor/conn/mod.ts +232 -0
- package/src/actor/conn/persisted.ts +81 -0
- package/src/actor/conn/state-manager.ts +196 -0
- package/src/actor/contexts/action.ts +23 -0
- package/src/actor/{context.ts → contexts/actor.ts} +19 -8
- package/src/actor/contexts/conn-init.ts +31 -0
- package/src/actor/contexts/conn.ts +48 -0
- package/src/actor/contexts/create-conn-state.ts +13 -0
- package/src/actor/contexts/on-before-connect.ts +13 -0
- package/src/actor/contexts/on-connect.ts +22 -0
- package/src/actor/contexts/request.ts +48 -0
- package/src/actor/contexts/websocket.ts +48 -0
- package/src/actor/definition.ts +3 -3
- package/src/actor/driver.ts +36 -5
- package/src/actor/errors.ts +19 -24
- package/src/actor/instance/connection-manager.ts +465 -0
- package/src/actor/instance/event-manager.ts +292 -0
- package/src/actor/instance/kv.ts +15 -0
- package/src/actor/instance/mod.ts +1107 -0
- package/src/actor/instance/persisted.ts +67 -0
- package/src/actor/instance/schedule-manager.ts +349 -0
- package/src/actor/instance/state-manager.ts +502 -0
- package/src/actor/mod.ts +13 -16
- package/src/actor/protocol/old.ts +131 -43
- package/src/actor/protocol/serde.ts +19 -4
- package/src/actor/router-endpoints.ts +61 -586
- package/src/actor/router-websocket-endpoints.ts +408 -0
- package/src/actor/router.ts +63 -197
- package/src/actor/schedule.ts +1 -1
- package/src/client/actor-conn.ts +183 -249
- package/src/client/actor-handle.ts +29 -6
- package/src/client/client.ts +0 -4
- package/src/client/config.ts +1 -4
- package/src/client/mod.ts +0 -1
- package/src/client/raw-utils.ts +3 -3
- package/src/client/utils.ts +85 -39
- package/src/common/actor-router-consts.ts +5 -12
- package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
- package/src/common/log.ts +1 -1
- package/src/common/router.ts +28 -17
- package/src/common/utils.ts +2 -0
- package/src/driver-helpers/mod.ts +7 -10
- package/src/driver-helpers/utils.ts +18 -9
- package/src/driver-test-suite/mod.ts +26 -50
- package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
- package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
- package/src/driver-test-suite/tests/actor-conn.ts +5 -9
- package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
- package/src/driver-test-suite/tests/actor-driver.ts +0 -7
- package/src/driver-test-suite/tests/actor-handle.ts +12 -12
- package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
- package/src/driver-test-suite/tests/manager-driver.ts +1 -1
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
- package/src/driver-test-suite/tests/raw-http.ts +5 -5
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
- package/src/driver-test-suite/tests/request-access.ts +4 -4
- package/src/driver-test-suite/utils.ts +6 -10
- package/src/drivers/engine/actor-driver.ts +614 -424
- package/src/drivers/engine/mod.ts +0 -1
- package/src/drivers/file-system/actor.ts +24 -12
- package/src/drivers/file-system/global-state.ts +427 -37
- package/src/drivers/file-system/manager.ts +71 -83
- package/src/drivers/file-system/mod.ts +3 -0
- package/src/drivers/file-system/utils.ts +18 -8
- package/src/engine-process/mod.ts +38 -38
- package/src/inspector/utils.ts +7 -5
- package/src/manager/driver.ts +11 -4
- package/src/manager/gateway.ts +4 -29
- package/src/manager/protocol/mod.ts +0 -2
- package/src/manager/protocol/query.ts +0 -4
- package/src/manager/router.ts +67 -64
- package/src/manager-api/actors.ts +13 -0
- package/src/mod.ts +1 -3
- package/src/registry/mod.ts +20 -20
- package/src/registry/serve.ts +9 -14
- package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
- package/src/remote-manager-driver/api-endpoints.ts +13 -1
- package/src/remote-manager-driver/api-utils.ts +8 -0
- package/src/remote-manager-driver/metadata.ts +58 -0
- package/src/remote-manager-driver/mod.ts +47 -62
- package/src/remote-manager-driver/ws-proxy.ts +1 -1
- package/src/schemas/actor-persist/mod.ts +1 -1
- package/src/schemas/actor-persist/versioned.ts +56 -31
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +41 -21
- package/src/schemas/client-protocol-zod/mod.ts +103 -0
- package/src/schemas/file-system-driver/mod.ts +1 -1
- package/src/schemas/file-system-driver/versioned.ts +42 -19
- package/src/serde.ts +33 -11
- package/src/test/mod.ts +7 -3
- package/src/utils/node.ts +173 -0
- package/src/utils.ts +0 -4
- package/dist/tsup/chunk-3I6ZIJVJ.js.map +0 -1
- package/dist/tsup/chunk-3JYSUFET.cjs.map +0 -1
- package/dist/tsup/chunk-54DVMQPT.cjs.map +0 -1
- package/dist/tsup/chunk-5PKKNNNS.js.map +0 -1
- package/dist/tsup/chunk-C56XVVV4.cjs.map +0 -1
- package/dist/tsup/chunk-D6PCH7FR.cjs +0 -4623
- package/dist/tsup/chunk-D6PCH7FR.cjs.map +0 -1
- package/dist/tsup/chunk-DLYZKFRY.js.map +0 -1
- package/dist/tsup/chunk-FTQ62XTN.js.map +0 -1
- package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
- package/dist/tsup/chunk-HNYF4T36.cjs.map +0 -1
- package/dist/tsup/chunk-JMLTKMJ7.cjs +0 -1119
- package/dist/tsup/chunk-JMLTKMJ7.cjs.map +0 -1
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
- package/dist/tsup/chunk-NOZSCUPQ.js.map +0 -1
- package/dist/tsup/chunk-PHNIVSG5.js.map +0 -1
- package/dist/tsup/chunk-RUTBXBRR.js +0 -1119
- package/dist/tsup/chunk-RUTBXBRR.js.map +0 -1
- package/dist/tsup/chunk-RVVUS4X6.js.map +0 -1
- package/dist/tsup/chunk-SN4KWTRA.cjs.map +0 -1
- package/dist/tsup/chunk-XSDSNHSE.cjs.map +0 -1
- package/dist/tsup/chunk-XYK5PY3B.cjs.map +0 -1
- package/dist/tsup/chunk-YAYNBR37.js.map +0 -1
- package/src/actor/action.ts +0 -178
- package/src/actor/conn-drivers.ts +0 -216
- package/src/actor/conn-socket.ts +0 -8
- package/src/actor/conn.ts +0 -272
- package/src/actor/instance.ts +0 -2336
- package/src/actor/persisted.ts +0 -49
- package/src/actor/unstable-react.ts +0 -110
- package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
- package/src/drivers/engine/kv.ts +0 -3
- package/src/manager/hono-websocket-adapter.ts +0 -393
- /package/dist/tsup/{chunk-5UJQWWO3.js.map → chunk-EIPANQMF.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
|
+
}
|