rivetkit 2.0.24-rc.1 → 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-HHFKKVLR.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-ZTH3KYFH.cjs → chunk-5BZO5XPS.cjs} +3 -3
- package/dist/tsup/{chunk-ZTH3KYFH.cjs.map → chunk-5BZO5XPS.cjs.map} +1 -1
- package/dist/tsup/{chunk-PLUN2NQT.js → chunk-BAIGSF64.js} +189 -187
- package/dist/tsup/chunk-BAIGSF64.js.map +1 -0
- package/dist/tsup/{chunk-SHVX2QUR.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-7L65NNWP.cjs → chunk-DLK5YCTN.cjs} +187 -185
- package/dist/tsup/chunk-DLK5YCTN.cjs.map +1 -0
- package/dist/tsup/{chunk-YBG6R7LX.js → chunk-DUJQWGYD.js} +3 -7
- package/dist/tsup/chunk-DUJQWGYD.js.map +1 -0
- package/dist/tsup/{chunk-CD33GT6Z.js → chunk-EIPANQMF.js} +2 -2
- package/dist/tsup/{chunk-2JYPS5YM.cjs → chunk-ESMTDP7G.cjs} +6 -6
- package/dist/tsup/chunk-ESMTDP7G.cjs.map +1 -0
- package/dist/tsup/{chunk-VHGY7PU5.cjs → chunk-FVAKREFB.cjs} +1900 -1737
- package/dist/tsup/chunk-FVAKREFB.cjs.map +1 -0
- package/dist/tsup/{chunk-BLK27ES3.js → chunk-I3XT7WOF.js} +44 -56
- package/dist/tsup/chunk-I3XT7WOF.js.map +1 -0
- package/dist/tsup/{chunk-YBHYXIP6.js → chunk-IMDS5T42.js} +3 -3
- package/dist/tsup/chunk-IMDS5T42.js.map +1 -0
- package/dist/tsup/{chunk-INNFK746.cjs → chunk-J3HZJF2P.cjs} +10 -14
- package/dist/tsup/chunk-J3HZJF2P.cjs.map +1 -0
- package/dist/tsup/{chunk-BYMKMOBS.js → chunk-MBBJUHSP.js} +1844 -1681
- package/dist/tsup/chunk-MBBJUHSP.js.map +1 -0
- package/dist/tsup/{chunk-BOMZS2TJ.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-36JJ4IQB.cjs → chunk-YC5DUHPM.cjs} +4 -8
- package/dist/tsup/chunk-YC5DUHPM.cjs.map +1 -0
- package/dist/tsup/{chunk-FX7TWFQR.js → chunk-YC7YPM2T.js} +2 -6
- package/dist/tsup/chunk-YC7YPM2T.js.map +1 -0
- package/dist/tsup/{chunk-227FEWMB.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-227FEWMB.js.map +0 -1
- package/dist/tsup/chunk-2JYPS5YM.cjs.map +0 -1
- package/dist/tsup/chunk-36JJ4IQB.cjs.map +0 -1
- package/dist/tsup/chunk-7L65NNWP.cjs.map +0 -1
- package/dist/tsup/chunk-BLK27ES3.js.map +0 -1
- package/dist/tsup/chunk-BOMZS2TJ.js.map +0 -1
- package/dist/tsup/chunk-BYMKMOBS.js.map +0 -1
- package/dist/tsup/chunk-FX7TWFQR.js.map +0 -1
- package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
- package/dist/tsup/chunk-HHFKKVLR.cjs.map +0 -1
- package/dist/tsup/chunk-INNFK746.cjs.map +0 -1
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
- package/dist/tsup/chunk-O44LFKSB.cjs +0 -4623
- package/dist/tsup/chunk-O44LFKSB.cjs.map +0 -1
- package/dist/tsup/chunk-PLUN2NQT.js.map +0 -1
- package/dist/tsup/chunk-S4UJG7ZE.js +0 -1119
- package/dist/tsup/chunk-S4UJG7ZE.js.map +0 -1
- package/dist/tsup/chunk-SHVX2QUR.cjs.map +0 -1
- package/dist/tsup/chunk-VFB23BYZ.cjs +0 -1119
- package/dist/tsup/chunk-VFB23BYZ.cjs.map +0 -1
- package/dist/tsup/chunk-VHGY7PU5.cjs.map +0 -1
- package/dist/tsup/chunk-YBG6R7LX.js.map +0 -1
- package/dist/tsup/chunk-YBHYXIP6.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-CD33GT6Z.js.map → chunk-EIPANQMF.js.map} +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
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 type { AnyDatabaseProvider } from "../database";
|
|
10
|
+
import { InternalError } from "../errors";
|
|
11
|
+
import type { ActorInstance } from "../instance/mod";
|
|
12
|
+
import { CachedSerializer } from "../protocol/serde";
|
|
13
|
+
import type { ConnDriver } from "./driver";
|
|
14
|
+
import { type ConnDataInput, StateManager } from "./state-manager";
|
|
15
|
+
|
|
16
|
+
export type ConnId = string;
|
|
17
|
+
|
|
18
|
+
export type AnyConn = Conn<any, any, any, any, any, any>;
|
|
19
|
+
|
|
20
|
+
export const CONN_CONNECTED_SYMBOL = Symbol("connected");
|
|
21
|
+
export const CONN_SPEAKS_RIVETKIT_SYMBOL = Symbol("speaksRivetKit");
|
|
22
|
+
export const CONN_DRIVER_SYMBOL = Symbol("driver");
|
|
23
|
+
export const CONN_ACTOR_SYMBOL = Symbol("actor");
|
|
24
|
+
export const CONN_STATE_MANAGER_SYMBOL = Symbol("stateManager");
|
|
25
|
+
export const CONN_SEND_MESSAGE_SYMBOL = Symbol("sendMessage");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Represents a client connection to a actor.
|
|
29
|
+
*
|
|
30
|
+
* Manages connection-specific data and controls the connection lifecycle.
|
|
31
|
+
*
|
|
32
|
+
* @see {@link https://rivet.dev/docs/connections|Connection Documentation}
|
|
33
|
+
*/
|
|
34
|
+
export class Conn<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
|
|
35
|
+
#actor: ActorInstance<S, CP, CS, V, I, DB>;
|
|
36
|
+
|
|
37
|
+
get [CONN_ACTOR_SYMBOL](): ActorInstance<S, CP, CS, V, I, DB> {
|
|
38
|
+
return this.#actor;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#stateManager!: StateManager<CP, CS>;
|
|
42
|
+
|
|
43
|
+
get [CONN_STATE_MANAGER_SYMBOL]() {
|
|
44
|
+
return this.#stateManager;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Connections exist before being connected to an actor. If true, this
|
|
49
|
+
* connection has been connected.
|
|
50
|
+
**/
|
|
51
|
+
[CONN_CONNECTED_SYMBOL] = false;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* If undefined, then no socket is connected to this conn
|
|
55
|
+
*/
|
|
56
|
+
[CONN_DRIVER_SYMBOL]?: ConnDriver;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* If this connection is speaking the RivetKit protocol. If false, this is
|
|
60
|
+
* a raw connection for WebSocket or fetch or inspector.
|
|
61
|
+
**/
|
|
62
|
+
get [CONN_SPEAKS_RIVETKIT_SYMBOL](): boolean {
|
|
63
|
+
return this[CONN_DRIVER_SYMBOL]?.rivetKitProtocol !== undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
subscriptions: Set<string> = new Set<string>();
|
|
67
|
+
|
|
68
|
+
#assertConnected() {
|
|
69
|
+
if (!this[CONN_CONNECTED_SYMBOL])
|
|
70
|
+
throw new InternalError(
|
|
71
|
+
"Connection not connected yet. This happens when trying to use the connection in onBeforeConnect or createConnState.",
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// MARK: - Public Getters
|
|
76
|
+
get params(): CP {
|
|
77
|
+
return this.#stateManager.ephemeralData.parameters;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the current state of the connection.
|
|
82
|
+
*
|
|
83
|
+
* Throws an error if the state is not enabled.
|
|
84
|
+
*/
|
|
85
|
+
get state(): CS {
|
|
86
|
+
return this.#stateManager.state;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Sets the state of the connection.
|
|
91
|
+
*
|
|
92
|
+
* Throws an error if the state is not enabled.
|
|
93
|
+
*/
|
|
94
|
+
set state(value: CS) {
|
|
95
|
+
this.#stateManager.state = value;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Unique identifier for the connection.
|
|
100
|
+
*/
|
|
101
|
+
get id(): ConnId {
|
|
102
|
+
return this.#stateManager.ephemeralData.id;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @experimental
|
|
107
|
+
*
|
|
108
|
+
* If the underlying connection can hibernate.
|
|
109
|
+
*/
|
|
110
|
+
get isHibernatable(): boolean {
|
|
111
|
+
return this[CONN_DRIVER_SYMBOL]?.hibernatable !== undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Initializes a new instance of the Connection class.
|
|
116
|
+
*
|
|
117
|
+
* This should only be constructed by {@link Actor}.
|
|
118
|
+
*
|
|
119
|
+
* @protected
|
|
120
|
+
*/
|
|
121
|
+
constructor(
|
|
122
|
+
actor: ActorInstance<S, CP, CS, V, I, DB>,
|
|
123
|
+
data: ConnDataInput<CP, CS>,
|
|
124
|
+
) {
|
|
125
|
+
this.#actor = actor;
|
|
126
|
+
this.#stateManager = new StateManager(this, data);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Sends a raw message to the underlying connection.
|
|
131
|
+
*/
|
|
132
|
+
[CONN_SEND_MESSAGE_SYMBOL](message: CachedSerializer<any, any, any>) {
|
|
133
|
+
if (this[CONN_DRIVER_SYMBOL]) {
|
|
134
|
+
const driver = this[CONN_DRIVER_SYMBOL];
|
|
135
|
+
|
|
136
|
+
if (driver.rivetKitProtocol) {
|
|
137
|
+
driver.rivetKitProtocol.sendMessage(this.#actor, this, message);
|
|
138
|
+
} else {
|
|
139
|
+
this.#actor.rLog.warn({
|
|
140
|
+
msg: "attempting to send RivetKit protocol message to connection that does not support it",
|
|
141
|
+
conn: this.id,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
this.#actor.rLog.warn({
|
|
146
|
+
msg: "missing connection driver state for send message",
|
|
147
|
+
conn: this.id,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Sends an event with arguments to the client.
|
|
154
|
+
*
|
|
155
|
+
* @param eventName - The name of the event.
|
|
156
|
+
* @param args - The arguments for the event.
|
|
157
|
+
* @see {@link https://rivet.dev/docs/events|Events Documentation}
|
|
158
|
+
*/
|
|
159
|
+
send(eventName: string, ...args: unknown[]) {
|
|
160
|
+
this.#assertConnected();
|
|
161
|
+
if (!this[CONN_SPEAKS_RIVETKIT_SYMBOL]) {
|
|
162
|
+
this.#actor.rLog.warn({
|
|
163
|
+
msg: "cannot send messages to this connection type",
|
|
164
|
+
connId: this.id,
|
|
165
|
+
connType: this[CONN_DRIVER_SYMBOL]?.type,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
this.#actor.inspector.emitter.emit("eventFired", {
|
|
170
|
+
type: "event",
|
|
171
|
+
eventName,
|
|
172
|
+
args,
|
|
173
|
+
connId: this.id,
|
|
174
|
+
});
|
|
175
|
+
const eventData = { name: eventName, args };
|
|
176
|
+
this[CONN_SEND_MESSAGE_SYMBOL](
|
|
177
|
+
new CachedSerializer(
|
|
178
|
+
eventData,
|
|
179
|
+
TO_CLIENT_VERSIONED,
|
|
180
|
+
ToClientSchema,
|
|
181
|
+
// JSON: args is the raw value (array of arguments)
|
|
182
|
+
(value): ToClientJson => ({
|
|
183
|
+
body: {
|
|
184
|
+
tag: "Event" as const,
|
|
185
|
+
val: {
|
|
186
|
+
name: value.name,
|
|
187
|
+
args: value.args,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
}),
|
|
191
|
+
// BARE/CBOR: args needs to be CBOR-encoded to ArrayBuffer
|
|
192
|
+
(value): protocol.ToClient => ({
|
|
193
|
+
body: {
|
|
194
|
+
tag: "Event" as const,
|
|
195
|
+
val: {
|
|
196
|
+
name: value.name,
|
|
197
|
+
args: bufferToArrayBuffer(cbor.encode(value.args)),
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
}),
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Disconnects the client with an optional reason.
|
|
207
|
+
*
|
|
208
|
+
* @param reason - The reason for disconnection.
|
|
209
|
+
*/
|
|
210
|
+
async disconnect(reason?: string) {
|
|
211
|
+
if (this[CONN_DRIVER_SYMBOL]) {
|
|
212
|
+
const driver = this[CONN_DRIVER_SYMBOL];
|
|
213
|
+
if (driver.disconnect) {
|
|
214
|
+
driver.disconnect(this.#actor, this, reason);
|
|
215
|
+
} else {
|
|
216
|
+
this.#actor.rLog.debug({
|
|
217
|
+
msg: "no disconnect handler for conn driver",
|
|
218
|
+
conn: this.id,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.#actor.connectionManager.connDisconnected(this);
|
|
223
|
+
} else {
|
|
224
|
+
this.#actor.rLog.warn({
|
|
225
|
+
msg: "missing connection driver state for disconnect",
|
|
226
|
+
conn: this.id,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
this[CONN_DRIVER_SYMBOL] = undefined;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persisted data structures for connections.
|
|
3
|
+
*
|
|
4
|
+
* Keep this file in sync with the Connection section of rivetkit-typescript/packages/rivetkit/schemas/actor-persist/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as cbor from "cbor-x";
|
|
8
|
+
import type * as persistSchema from "@/schemas/actor-persist/mod";
|
|
9
|
+
import { bufferToArrayBuffer } from "@/utils";
|
|
10
|
+
|
|
11
|
+
export type GatewayId = ArrayBuffer;
|
|
12
|
+
export type RequestId = ArrayBuffer;
|
|
13
|
+
|
|
14
|
+
export type Cbor = ArrayBuffer;
|
|
15
|
+
|
|
16
|
+
// MARK: Connection
|
|
17
|
+
/** Event subscription for connection */
|
|
18
|
+
export interface PersistedSubscription {
|
|
19
|
+
eventName: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Connection associated with hibernatable WebSocket that should persist across lifecycles */
|
|
23
|
+
export interface PersistedConn<CP, CS> {
|
|
24
|
+
/** Connection ID generated by RivetKit */
|
|
25
|
+
id: string;
|
|
26
|
+
parameters: CP;
|
|
27
|
+
state: CS;
|
|
28
|
+
subscriptions: PersistedSubscription[];
|
|
29
|
+
gatewayId: GatewayId;
|
|
30
|
+
requestId: RequestId;
|
|
31
|
+
serverMessageIndex: number;
|
|
32
|
+
clientMessageIndex: number;
|
|
33
|
+
requestPath: string;
|
|
34
|
+
requestHeaders: Record<string, string>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Converts persisted connection data to BARE schema format for serialization.
|
|
39
|
+
* @throws {Error} If the connection is ephemeral (not hibernatable)
|
|
40
|
+
*/
|
|
41
|
+
export function convertConnToBarePersistedConn<CP, CS>(
|
|
42
|
+
persist: PersistedConn<CP, CS>,
|
|
43
|
+
): persistSchema.Conn {
|
|
44
|
+
return {
|
|
45
|
+
id: persist.id,
|
|
46
|
+
parameters: bufferToArrayBuffer(cbor.encode(persist.parameters)),
|
|
47
|
+
state: bufferToArrayBuffer(cbor.encode(persist.state)),
|
|
48
|
+
subscriptions: persist.subscriptions.map((sub) => ({
|
|
49
|
+
eventName: sub.eventName,
|
|
50
|
+
})),
|
|
51
|
+
gatewayId: persist.gatewayId,
|
|
52
|
+
requestId: persist.requestId,
|
|
53
|
+
serverMessageIndex: persist.serverMessageIndex,
|
|
54
|
+
clientMessageIndex: persist.clientMessageIndex,
|
|
55
|
+
requestPath: persist.requestPath,
|
|
56
|
+
requestHeaders: new Map(Object.entries(persist.requestHeaders)),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Converts BARE schema format to persisted connection data.
|
|
62
|
+
* @throws {Error} If the connection is ephemeral (not hibernatable)
|
|
63
|
+
*/
|
|
64
|
+
export function convertConnFromBarePersistedConn<CP, CS>(
|
|
65
|
+
bareData: persistSchema.Conn,
|
|
66
|
+
): PersistedConn<CP, CS> {
|
|
67
|
+
return {
|
|
68
|
+
id: bareData.id,
|
|
69
|
+
parameters: cbor.decode(new Uint8Array(bareData.parameters)),
|
|
70
|
+
state: cbor.decode(new Uint8Array(bareData.state)),
|
|
71
|
+
subscriptions: bareData.subscriptions.map((sub) => ({
|
|
72
|
+
eventName: sub.eventName,
|
|
73
|
+
})),
|
|
74
|
+
gatewayId: bareData.gatewayId,
|
|
75
|
+
requestId: bareData.requestId,
|
|
76
|
+
serverMessageIndex: bareData.serverMessageIndex,
|
|
77
|
+
clientMessageIndex: bareData.clientMessageIndex,
|
|
78
|
+
requestPath: bareData.requestPath,
|
|
79
|
+
requestHeaders: Object.fromEntries(bareData.requestHeaders),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import type { HibernatingWebSocketMetadata } from "@rivetkit/engine-runner";
|
|
2
|
+
import * as cbor from "cbor-x";
|
|
3
|
+
import invariant from "invariant";
|
|
4
|
+
import onChange from "on-change";
|
|
5
|
+
import { isCborSerializable } from "@/common/utils";
|
|
6
|
+
import * as errors from "../errors";
|
|
7
|
+
import { assertUnreachable } from "../utils";
|
|
8
|
+
import { CONN_ACTOR_SYMBOL, type Conn } from "./mod";
|
|
9
|
+
import type { PersistedConn } from "./persisted";
|
|
10
|
+
|
|
11
|
+
/** Pick a subset of persisted data used to represent ephemeral connections */
|
|
12
|
+
export type EphemeralConn<CP, CS> = Pick<
|
|
13
|
+
PersistedConn<CP, CS>,
|
|
14
|
+
"id" | "parameters" | "state"
|
|
15
|
+
>;
|
|
16
|
+
|
|
17
|
+
export type ConnDataInput<CP, CS> =
|
|
18
|
+
| { ephemeral: EphemeralConn<CP, CS> }
|
|
19
|
+
| { hibernatable: PersistedConn<CP, CS> };
|
|
20
|
+
|
|
21
|
+
export type ConnData<CP, CS> =
|
|
22
|
+
| {
|
|
23
|
+
ephemeral: {
|
|
24
|
+
/** In-memory data representing this connection */
|
|
25
|
+
data: EphemeralConn<CP, CS>;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
| {
|
|
29
|
+
hibernatable: {
|
|
30
|
+
/** Persisted data with on-change proxy */
|
|
31
|
+
data: PersistedConn<CP, CS>;
|
|
32
|
+
/** Raw persisted data without proxy */
|
|
33
|
+
dataRaw: PersistedConn<CP, CS>;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Manages connection state persistence, proxying, and change tracking.
|
|
39
|
+
* Handles automatic state change detection for connection-specific state.
|
|
40
|
+
*/
|
|
41
|
+
export class StateManager<CP, CS> {
|
|
42
|
+
#conn: Conn<any, CP, CS, any, any, any>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Data representing this connection.
|
|
46
|
+
*
|
|
47
|
+
* This is stored as a struct for both ephemeral and hibernatable conns in
|
|
48
|
+
* order to keep the separation clear between the two.
|
|
49
|
+
*/
|
|
50
|
+
#data!: ConnData<CP, CS>;
|
|
51
|
+
|
|
52
|
+
constructor(
|
|
53
|
+
conn: Conn<any, CP, CS, any, any, any>,
|
|
54
|
+
data: ConnDataInput<CP, CS>,
|
|
55
|
+
) {
|
|
56
|
+
this.#conn = conn;
|
|
57
|
+
|
|
58
|
+
if ("ephemeral" in data) {
|
|
59
|
+
this.#data = { ephemeral: { data: data.ephemeral } };
|
|
60
|
+
} else if ("hibernatable" in data) {
|
|
61
|
+
// Listen for changes to the object
|
|
62
|
+
const persistRaw = data.hibernatable;
|
|
63
|
+
const persist = onChange(
|
|
64
|
+
persistRaw,
|
|
65
|
+
(
|
|
66
|
+
path: string,
|
|
67
|
+
value: any,
|
|
68
|
+
_previousValue: any,
|
|
69
|
+
_applyData: any,
|
|
70
|
+
) => {
|
|
71
|
+
this.#handleChange(path, value);
|
|
72
|
+
},
|
|
73
|
+
{ ignoreDetached: true },
|
|
74
|
+
);
|
|
75
|
+
this.#data = {
|
|
76
|
+
hibernatable: { data: persist, dataRaw: persistRaw },
|
|
77
|
+
};
|
|
78
|
+
} else {
|
|
79
|
+
assertUnreachable(data);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns the ephemeral or persisted data for this connectioned.
|
|
85
|
+
*
|
|
86
|
+
* This property is used to be able to treat both memory & persist conns
|
|
87
|
+
* identical by looking up the correct underlying data structure.
|
|
88
|
+
*/
|
|
89
|
+
get ephemeralData(): EphemeralConn<CP, CS> {
|
|
90
|
+
if ("hibernatable" in this.#data) {
|
|
91
|
+
return this.#data.hibernatable.data;
|
|
92
|
+
} else if ("ephemeral" in this.#data) {
|
|
93
|
+
return this.#data.ephemeral.data;
|
|
94
|
+
} else {
|
|
95
|
+
return assertUnreachable(this.#data);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get hibernatableData(): PersistedConn<CP, CS> | undefined {
|
|
100
|
+
if ("hibernatable" in this.#data) {
|
|
101
|
+
return this.#data.hibernatable.data;
|
|
102
|
+
} else {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
hibernatableDataOrError(): PersistedConn<CP, CS> {
|
|
108
|
+
const hibernatable = this.hibernatableData;
|
|
109
|
+
invariant(hibernatable, "missing hibernatable data");
|
|
110
|
+
return hibernatable;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get hibernatableDataRaw(): PersistedConn<CP, CS> | undefined {
|
|
114
|
+
if ("hibernatable" in this.#data) {
|
|
115
|
+
return this.#data.hibernatable.dataRaw;
|
|
116
|
+
} else {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get stateEnabled(): boolean {
|
|
122
|
+
return this.#conn[CONN_ACTOR_SYMBOL].connStateEnabled;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get state(): CS {
|
|
126
|
+
this.#validateStateEnabled();
|
|
127
|
+
const state = this.ephemeralData.state;
|
|
128
|
+
if (!state) throw new Error("state should exists");
|
|
129
|
+
return state;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
set state(value: CS) {
|
|
133
|
+
this.#validateStateEnabled();
|
|
134
|
+
this.ephemeralData.state = value;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#validateStateEnabled() {
|
|
138
|
+
if (!this.#conn[CONN_ACTOR_SYMBOL].connStateEnabled) {
|
|
139
|
+
throw new errors.ConnStateNotEnabled();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#handleChange(path: string, value: any) {
|
|
144
|
+
// NOTE: This will only be called for hibernatable conns since only
|
|
145
|
+
// hibernatable conns have the on-change proxy
|
|
146
|
+
|
|
147
|
+
// Validate CBOR serializability for state changes
|
|
148
|
+
if (path.startsWith("state")) {
|
|
149
|
+
let invalidPath = "";
|
|
150
|
+
if (
|
|
151
|
+
!isCborSerializable(
|
|
152
|
+
value,
|
|
153
|
+
(invalidPathPart: string) => {
|
|
154
|
+
invalidPath = invalidPathPart;
|
|
155
|
+
},
|
|
156
|
+
"",
|
|
157
|
+
)
|
|
158
|
+
) {
|
|
159
|
+
throw new errors.InvalidStateType({
|
|
160
|
+
path: path + (invalidPath ? `.${invalidPath}` : ""),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.#conn[CONN_ACTOR_SYMBOL].rLog.debug({
|
|
166
|
+
msg: "conn onChange triggered",
|
|
167
|
+
connId: this.#conn.id,
|
|
168
|
+
path,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Notify actor that this connection has changed
|
|
172
|
+
this.#conn[
|
|
173
|
+
CONN_ACTOR_SYMBOL
|
|
174
|
+
].connectionManager.markConnWithPersistChanged(this.#conn);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
addSubscription({ eventName }: { eventName: string }) {
|
|
178
|
+
const hibernatable = this.hibernatableData;
|
|
179
|
+
if (!hibernatable) return;
|
|
180
|
+
hibernatable.subscriptions.push({
|
|
181
|
+
eventName,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
removeSubscription({ eventName }: { eventName: string }) {
|
|
186
|
+
const hibernatable = this.hibernatableData;
|
|
187
|
+
if (!hibernatable) return;
|
|
188
|
+
const subIdx = hibernatable.subscriptions.findIndex(
|
|
189
|
+
(s) => s.eventName === eventName,
|
|
190
|
+
);
|
|
191
|
+
if (subIdx !== -1) {
|
|
192
|
+
hibernatable.subscriptions.splice(subIdx, 1);
|
|
193
|
+
}
|
|
194
|
+
return subIdx !== -1;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Conn } from "../conn/mod";
|
|
2
|
+
import type { AnyDatabaseProvider } from "../database";
|
|
3
|
+
import type { ActorInstance } from "../instance/mod";
|
|
4
|
+
import { ConnContext } from "./conn";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Context for a remote procedure call.
|
|
8
|
+
*/
|
|
9
|
+
export class ActionContext<
|
|
10
|
+
TState,
|
|
11
|
+
TConnParams,
|
|
12
|
+
TConnState,
|
|
13
|
+
TVars,
|
|
14
|
+
TInput,
|
|
15
|
+
TDatabase extends AnyDatabaseProvider,
|
|
16
|
+
> extends ConnContext<
|
|
17
|
+
TState,
|
|
18
|
+
TConnParams,
|
|
19
|
+
TConnState,
|
|
20
|
+
TVars,
|
|
21
|
+
TInput,
|
|
22
|
+
TDatabase
|
|
23
|
+
> {}
|
|
@@ -2,10 +2,10 @@ import type { ActorKey } from "@/actor/mod";
|
|
|
2
2
|
import type { Client } from "@/client/client";
|
|
3
3
|
import type { Logger } from "@/common/log";
|
|
4
4
|
import type { Registry } from "@/registry/mod";
|
|
5
|
-
import type { Conn, ConnId } from "
|
|
6
|
-
import type { AnyDatabaseProvider, InferDatabaseClient } from "
|
|
7
|
-
import type { ActorInstance, SaveStateOptions } from "
|
|
8
|
-
import type { Schedule } from "
|
|
5
|
+
import type { Conn, ConnId } from "../conn/mod";
|
|
6
|
+
import type { AnyDatabaseProvider, InferDatabaseClient } from "../database";
|
|
7
|
+
import type { ActorInstance, SaveStateOptions } from "../instance/mod";
|
|
8
|
+
import type { Schedule } from "../schedule";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* ActorContext class that provides access to actor methods and state
|
|
@@ -60,7 +60,7 @@ export class ActorContext<
|
|
|
60
60
|
* @param args - The arguments to send with the event.
|
|
61
61
|
*/
|
|
62
62
|
broadcast<Args extends Array<unknown>>(name: string, ...args: Args): void {
|
|
63
|
-
this.#actor.
|
|
63
|
+
this.#actor.eventManager.broadcast(name, ...args);
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -138,14 +138,14 @@ export class ActorContext<
|
|
|
138
138
|
* @param opts - Options for saving the state.
|
|
139
139
|
*/
|
|
140
140
|
async saveState(opts: SaveStateOptions): Promise<void> {
|
|
141
|
-
return this.#actor.saveState(opts);
|
|
141
|
+
return this.#actor.stateManager.saveState(opts);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
145
|
* Prevents the actor from sleeping until promise is complete.
|
|
146
146
|
*/
|
|
147
147
|
waitUntil(promise: Promise<void>): void {
|
|
148
|
-
this.#actor.
|
|
148
|
+
this.#actor.waitUntil(promise);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
@@ -163,6 +163,17 @@ export class ActorContext<
|
|
|
163
163
|
* @experimental
|
|
164
164
|
*/
|
|
165
165
|
sleep() {
|
|
166
|
-
this.#actor.
|
|
166
|
+
this.#actor.startSleep();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Forces the actor to destroy.
|
|
171
|
+
*
|
|
172
|
+
* This will return immediately, then call `onStop` and `onDestroy`.
|
|
173
|
+
*
|
|
174
|
+
* @experimental
|
|
175
|
+
*/
|
|
176
|
+
destroy() {
|
|
177
|
+
this.#actor.startDestroy();
|
|
167
178
|
}
|
|
168
179
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AnyDatabaseProvider } from "../database";
|
|
2
|
+
import type { ActorInstance } from "../instance/mod";
|
|
3
|
+
import { ActorContext } from "./actor";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base context for connection initialization handlers.
|
|
7
|
+
* Extends ActorContext with request-specific functionality for connection lifecycle events.
|
|
8
|
+
*/
|
|
9
|
+
export abstract class ConnInitContext<
|
|
10
|
+
TState,
|
|
11
|
+
TVars,
|
|
12
|
+
TInput,
|
|
13
|
+
TDatabase extends AnyDatabaseProvider,
|
|
14
|
+
> extends ActorContext<TState, undefined, undefined, TVars, TInput, TDatabase> {
|
|
15
|
+
/**
|
|
16
|
+
* The incoming request that initiated the connection.
|
|
17
|
+
* May be undefined for connections initiated without a direct HTTP request.
|
|
18
|
+
*/
|
|
19
|
+
public readonly request: Request | undefined;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
constructor(
|
|
25
|
+
actor: ActorInstance<TState, any, any, TVars, TInput, TDatabase>,
|
|
26
|
+
request: Request | undefined,
|
|
27
|
+
) {
|
|
28
|
+
super(actor);
|
|
29
|
+
this.request = request;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Conn } from "../conn/mod";
|
|
2
|
+
import type { AnyDatabaseProvider } from "../database";
|
|
3
|
+
import type { ActorInstance } from "../instance/mod";
|
|
4
|
+
import { ActorContext } from "./actor";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base context for connection-based handlers.
|
|
8
|
+
* Extends ActorContext with connection-specific functionality.
|
|
9
|
+
*/
|
|
10
|
+
export abstract class ConnContext<
|
|
11
|
+
TState,
|
|
12
|
+
TConnParams,
|
|
13
|
+
TConnState,
|
|
14
|
+
TVars,
|
|
15
|
+
TInput,
|
|
16
|
+
TDatabase extends AnyDatabaseProvider,
|
|
17
|
+
> extends ActorContext<
|
|
18
|
+
TState,
|
|
19
|
+
TConnParams,
|
|
20
|
+
TConnState,
|
|
21
|
+
TVars,
|
|
22
|
+
TInput,
|
|
23
|
+
TDatabase
|
|
24
|
+
> {
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
constructor(
|
|
29
|
+
actor: ActorInstance<
|
|
30
|
+
TState,
|
|
31
|
+
TConnParams,
|
|
32
|
+
TConnState,
|
|
33
|
+
TVars,
|
|
34
|
+
TInput,
|
|
35
|
+
TDatabase
|
|
36
|
+
>,
|
|
37
|
+
public readonly conn: Conn<
|
|
38
|
+
TState,
|
|
39
|
+
TConnParams,
|
|
40
|
+
TConnState,
|
|
41
|
+
TVars,
|
|
42
|
+
TInput,
|
|
43
|
+
TDatabase
|
|
44
|
+
>,
|
|
45
|
+
) {
|
|
46
|
+
super(actor);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnyDatabaseProvider } from "../database";
|
|
2
|
+
import { ConnInitContext } from "./conn-init";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Context for the createConnState lifecycle hook.
|
|
6
|
+
* Called to initialize connection-specific state when a connection is created.
|
|
7
|
+
*/
|
|
8
|
+
export class CreateConnStateContext<
|
|
9
|
+
TState,
|
|
10
|
+
TVars,
|
|
11
|
+
TInput,
|
|
12
|
+
TDatabase extends AnyDatabaseProvider,
|
|
13
|
+
> extends ConnInitContext<TState, TVars, TInput, TDatabase> {}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnyDatabaseProvider } from "../database";
|
|
2
|
+
import { ConnInitContext } from "./conn-init";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Context for the onBeforeConnect lifecycle hook.
|
|
6
|
+
* Called before a connection is established, allowing for validation and early rejection.
|
|
7
|
+
*/
|
|
8
|
+
export class OnBeforeConnectContext<
|
|
9
|
+
TState,
|
|
10
|
+
TVars,
|
|
11
|
+
TInput,
|
|
12
|
+
TDatabase extends AnyDatabaseProvider,
|
|
13
|
+
> extends ConnInitContext<TState, TVars, TInput, TDatabase> {}
|