rivetkit 2.0.6 → 2.0.7

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 (170) hide show
  1. package/dist/schemas/actor-persist/v1.ts +0 -6
  2. package/dist/tsup/actor-router-consts-B3Lu87yJ.d.cts +28 -0
  3. package/dist/tsup/actor-router-consts-B3Lu87yJ.d.ts +28 -0
  4. package/dist/tsup/{chunk-7OUKNSTU.js → chunk-2NL3KGJ7.js} +17 -14
  5. package/dist/tsup/chunk-2NL3KGJ7.js.map +1 -0
  6. package/dist/tsup/{chunk-6P6RA47N.cjs → chunk-3ALZ7EGX.cjs} +14 -10
  7. package/dist/tsup/chunk-3ALZ7EGX.cjs.map +1 -0
  8. package/dist/tsup/chunk-4EXJ4ITR.cjs +102 -0
  9. package/dist/tsup/chunk-4EXJ4ITR.cjs.map +1 -0
  10. package/dist/tsup/{chunk-ZYLTS2EM.js → chunk-54MAHBLL.js} +2 -2
  11. package/dist/tsup/{chunk-NTCUGYSD.cjs → chunk-7OOBMCQI.cjs} +34 -31
  12. package/dist/tsup/chunk-7OOBMCQI.cjs.map +1 -0
  13. package/dist/tsup/{chunk-VCEHU56K.js → chunk-B6N6VM37.js} +2 -2
  14. package/dist/tsup/{chunk-VPV4MWXR.js → chunk-DIHKN7NM.js} +3 -3
  15. package/dist/tsup/{chunk-MRRT2CZD.cjs → chunk-ETDWYT2P.cjs} +7 -7
  16. package/dist/tsup/{chunk-MRRT2CZD.cjs.map → chunk-ETDWYT2P.cjs.map} +1 -1
  17. package/dist/tsup/{chunk-TWGATZ3X.cjs → chunk-F7YL5G7Q.cjs} +922 -872
  18. package/dist/tsup/chunk-F7YL5G7Q.cjs.map +1 -0
  19. package/dist/tsup/{chunk-UTI5NCES.cjs → chunk-GWJTWY3G.cjs} +6 -6
  20. package/dist/tsup/{chunk-UTI5NCES.cjs.map → chunk-GWJTWY3G.cjs.map} +1 -1
  21. package/dist/tsup/{chunk-W6LN7AF5.js → chunk-KHRZPP5T.js} +866 -816
  22. package/dist/tsup/chunk-KHRZPP5T.js.map +1 -0
  23. package/dist/tsup/{chunk-5JBFVV4C.cjs → chunk-LXAVET4A.cjs} +21 -7
  24. package/dist/tsup/chunk-LXAVET4A.cjs.map +1 -0
  25. package/dist/tsup/{chunk-TCUI5JFE.cjs → chunk-NDCVQZBS.cjs} +45 -18
  26. package/dist/tsup/chunk-NDCVQZBS.cjs.map +1 -0
  27. package/dist/tsup/{chunk-4CKHQRXG.js → chunk-NII4KKHD.js} +515 -240
  28. package/dist/tsup/chunk-NII4KKHD.js.map +1 -0
  29. package/dist/tsup/{chunk-2K3JMDAN.js → chunk-NRELKXIX.js} +40 -13
  30. package/dist/tsup/chunk-NRELKXIX.js.map +1 -0
  31. package/dist/tsup/{chunk-UFWAK3X2.cjs → chunk-NUA6LOOJ.cjs} +660 -385
  32. package/dist/tsup/chunk-NUA6LOOJ.cjs.map +1 -0
  33. package/dist/tsup/{chunk-DIAYNQTE.cjs → chunk-OSK2VSJF.cjs} +12 -12
  34. package/dist/tsup/{chunk-DIAYNQTE.cjs.map → chunk-OSK2VSJF.cjs.map} +1 -1
  35. package/dist/tsup/chunk-PD6HCAJE.js +102 -0
  36. package/dist/tsup/chunk-PD6HCAJE.js.map +1 -0
  37. package/dist/tsup/{chunk-RGQR2J7S.js → chunk-RLBM6D4L.js} +20 -6
  38. package/dist/tsup/chunk-RLBM6D4L.js.map +1 -0
  39. package/dist/tsup/{chunk-KG3C7MKR.cjs → chunk-VAF63BEI.cjs} +3 -3
  40. package/dist/tsup/{chunk-KG3C7MKR.cjs.map → chunk-VAF63BEI.cjs.map} +1 -1
  41. package/dist/tsup/{chunk-G75SVQON.js → chunk-WAT5AE7S.js} +9 -5
  42. package/dist/tsup/chunk-WAT5AE7S.js.map +1 -0
  43. package/dist/tsup/{chunk-WC2PSJWN.js → chunk-YL4VZMMT.js} +2 -2
  44. package/dist/tsup/client/mod.cjs +9 -9
  45. package/dist/tsup/client/mod.d.cts +7 -8
  46. package/dist/tsup/client/mod.d.ts +7 -8
  47. package/dist/tsup/client/mod.js +8 -8
  48. package/dist/tsup/common/log.cjs +3 -3
  49. package/dist/tsup/common/log.js +2 -2
  50. package/dist/tsup/common/websocket.cjs +4 -4
  51. package/dist/tsup/common/websocket.js +3 -3
  52. package/dist/tsup/{connection-BLemxi4f.d.ts → conn-DCSQgIlw.d.ts} +1605 -1353
  53. package/dist/tsup/{connection-CpDIydXf.d.cts → conn-DdzHTm2E.d.cts} +1605 -1353
  54. package/dist/tsup/driver-helpers/mod.cjs +31 -5
  55. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  56. package/dist/tsup/driver-helpers/mod.d.cts +7 -8
  57. package/dist/tsup/driver-helpers/mod.d.ts +7 -8
  58. package/dist/tsup/driver-helpers/mod.js +33 -7
  59. package/dist/tsup/driver-test-suite/mod.cjs +317 -222
  60. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  61. package/dist/tsup/driver-test-suite/mod.d.cts +7 -7
  62. package/dist/tsup/driver-test-suite/mod.d.ts +7 -7
  63. package/dist/tsup/driver-test-suite/mod.js +582 -487
  64. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  65. package/dist/tsup/inspector/mod.cjs +16 -6
  66. package/dist/tsup/inspector/mod.cjs.map +1 -1
  67. package/dist/tsup/inspector/mod.d.cts +34 -7
  68. package/dist/tsup/inspector/mod.d.ts +34 -7
  69. package/dist/tsup/inspector/mod.js +17 -7
  70. package/dist/tsup/mod.cjs +10 -20
  71. package/dist/tsup/mod.cjs.map +1 -1
  72. package/dist/tsup/mod.d.cts +9 -7
  73. package/dist/tsup/mod.d.ts +9 -7
  74. package/dist/tsup/mod.js +9 -19
  75. package/dist/tsup/test/mod.cjs +11 -11
  76. package/dist/tsup/test/mod.d.cts +6 -7
  77. package/dist/tsup/test/mod.d.ts +6 -7
  78. package/dist/tsup/test/mod.js +10 -10
  79. package/dist/tsup/utils.cjs +4 -2
  80. package/dist/tsup/utils.cjs.map +1 -1
  81. package/dist/tsup/utils.d.cts +11 -1
  82. package/dist/tsup/utils.d.ts +11 -1
  83. package/dist/tsup/utils.js +3 -1
  84. package/package.json +8 -4
  85. package/src/actor/action.ts +1 -1
  86. package/src/actor/config.ts +1 -1
  87. package/src/actor/conn-drivers.ts +205 -0
  88. package/src/actor/conn-socket.ts +6 -0
  89. package/src/actor/{connection.ts → conn.ts} +78 -84
  90. package/src/actor/context.ts +1 -1
  91. package/src/actor/driver.ts +4 -43
  92. package/src/actor/instance.ts +162 -86
  93. package/src/actor/mod.ts +1 -11
  94. package/src/actor/persisted.ts +2 -5
  95. package/src/actor/protocol/old.ts +1 -1
  96. package/src/actor/router-endpoints.ts +142 -106
  97. package/src/actor/router.ts +81 -45
  98. package/src/actor/utils.ts +5 -1
  99. package/src/client/actor-conn.ts +154 -23
  100. package/src/client/client.ts +1 -1
  101. package/src/client/config.ts +7 -0
  102. package/src/common/actor-router-consts.ts +29 -8
  103. package/src/common/router.ts +2 -1
  104. package/src/common/versioned-data.ts +5 -5
  105. package/src/driver-helpers/mod.ts +14 -1
  106. package/src/driver-test-suite/mod.ts +11 -2
  107. package/src/driver-test-suite/test-inline-client-driver.ts +36 -18
  108. package/src/driver-test-suite/tests/actor-conn-state.ts +66 -22
  109. package/src/driver-test-suite/tests/actor-conn.ts +65 -126
  110. package/src/driver-test-suite/tests/actor-reconnect.ts +160 -0
  111. package/src/driver-test-suite/tests/actor-sleep.ts +0 -1
  112. package/src/driver-test-suite/tests/raw-websocket.ts +0 -35
  113. package/src/driver-test-suite/utils.ts +3 -3
  114. package/src/drivers/default.ts +8 -7
  115. package/src/drivers/engine/actor-driver.ts +53 -31
  116. package/src/drivers/engine/config.ts +4 -0
  117. package/src/drivers/file-system/actor.ts +0 -6
  118. package/src/drivers/file-system/global-state.ts +3 -14
  119. package/src/drivers/file-system/manager.ts +12 -8
  120. package/src/inspector/actor.ts +4 -3
  121. package/src/inspector/config.ts +10 -1
  122. package/src/inspector/mod.ts +1 -0
  123. package/src/inspector/utils.ts +23 -4
  124. package/src/manager/driver.ts +11 -1
  125. package/src/manager/gateway.ts +407 -0
  126. package/src/manager/router.ts +269 -468
  127. package/src/manager-api/actors.ts +61 -0
  128. package/src/manager-api/common.ts +4 -0
  129. package/src/mod.ts +1 -1
  130. package/src/registry/mod.ts +119 -10
  131. package/src/remote-manager-driver/actor-http-client.ts +30 -19
  132. package/src/remote-manager-driver/actor-websocket-client.ts +43 -16
  133. package/src/remote-manager-driver/api-endpoints.ts +19 -21
  134. package/src/remote-manager-driver/api-utils.ts +10 -1
  135. package/src/remote-manager-driver/mod.ts +51 -48
  136. package/src/remote-manager-driver/ws-proxy.ts +2 -9
  137. package/src/test/mod.ts +6 -2
  138. package/src/utils.ts +21 -2
  139. package/dist/tsup/actor-router-consts-BK6arfy8.d.cts +0 -17
  140. package/dist/tsup/actor-router-consts-BK6arfy8.d.ts +0 -17
  141. package/dist/tsup/chunk-2K3JMDAN.js.map +0 -1
  142. package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
  143. package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
  144. package/dist/tsup/chunk-4CKHQRXG.js.map +0 -1
  145. package/dist/tsup/chunk-5JBFVV4C.cjs.map +0 -1
  146. package/dist/tsup/chunk-6P6RA47N.cjs.map +0 -1
  147. package/dist/tsup/chunk-7OUKNSTU.js.map +0 -1
  148. package/dist/tsup/chunk-G75SVQON.js.map +0 -1
  149. package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
  150. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
  151. package/dist/tsup/chunk-NTCUGYSD.cjs.map +0 -1
  152. package/dist/tsup/chunk-RGQR2J7S.js.map +0 -1
  153. package/dist/tsup/chunk-TCUI5JFE.cjs.map +0 -1
  154. package/dist/tsup/chunk-TWGATZ3X.cjs.map +0 -1
  155. package/dist/tsup/chunk-UFWAK3X2.cjs.map +0 -1
  156. package/dist/tsup/chunk-W6LN7AF5.js.map +0 -1
  157. package/dist/tsup/common-CXCe7s6i.d.cts +0 -218
  158. package/dist/tsup/common-CXCe7s6i.d.ts +0 -218
  159. package/src/actor/generic-conn-driver.ts +0 -246
  160. package/src/common/fake-event-source.ts +0 -267
  161. package/src/manager-api/routes/actors-create.ts +0 -16
  162. package/src/manager-api/routes/actors-delete.ts +0 -4
  163. package/src/manager-api/routes/actors-get-by-id.ts +0 -7
  164. package/src/manager-api/routes/actors-get-or-create-by-id.ts +0 -29
  165. package/src/manager-api/routes/actors-get.ts +0 -7
  166. package/src/manager-api/routes/common.ts +0 -18
  167. /package/dist/tsup/{chunk-ZYLTS2EM.js.map → chunk-54MAHBLL.js.map} +0 -0
  168. /package/dist/tsup/{chunk-VCEHU56K.js.map → chunk-B6N6VM37.js.map} +0 -0
  169. /package/dist/tsup/{chunk-VPV4MWXR.js.map → chunk-DIHKN7NM.js.map} +0 -0
  170. /package/dist/tsup/{chunk-WC2PSJWN.js.map → chunk-YL4VZMMT.js.map} +0 -0
@@ -1,7 +1,9 @@
1
1
  import * as cbor from "cbor-x";
2
+ import type { SSEStreamingApi } from "hono/streaming";
3
+ import type { WSContext } from "hono/ws";
2
4
  import invariant from "invariant";
3
5
  import onChange from "on-change";
4
- import type { ActorKey } from "@/actor/mod";
6
+ import type { ActorKey, Encoding } from "@/actor/mod";
5
7
  import type { Client } from "@/client/client";
6
8
  import { getBaseLogger, getIncludeTarget, type Logger } from "@/common/log";
7
9
  import { isCborSerializable, stringifyError } from "@/common/utils";
@@ -15,22 +17,24 @@ import { TO_CLIENT_VERSIONED } from "@/schemas/client-protocol/versioned";
15
17
  import {
16
18
  bufferToArrayBuffer,
17
19
  getEnvUniversal,
20
+ promiseWithResolvers,
18
21
  SinglePromiseQueue,
19
22
  } from "@/utils";
20
23
  import type { ActionContext } from "./action";
21
24
  import type { ActorConfig, OnConnectOptions } from "./config";
25
+ import { Conn, type ConnId, generateConnId, generateConnToken } from "./conn";
22
26
  import {
23
- CONNECTION_CHECK_LIVENESS_SYMBOL,
24
- Conn,
25
- type ConnectionDriver,
26
- type ConnId,
27
- } from "./connection";
27
+ CONN_DRIVERS,
28
+ type ConnDriver,
29
+ type ConnDriverState,
30
+ getConnDriverKindFromState,
31
+ } from "./conn-drivers";
32
+ import type { ConnSocket } from "./conn-socket";
28
33
  import { ActorContext } from "./context";
29
34
  import type { AnyDatabaseProvider, InferDatabaseClient } from "./database";
30
- import type { ActorDriver, ConnDriver, ConnectionDriversMap } from "./driver";
35
+ import type { ActorDriver } from "./driver";
31
36
  import * as errors from "./errors";
32
37
  import { serializeActorKey } from "./keys";
33
- import { loggerWithoutContext } from "./log";
34
38
  import type {
35
39
  PersistedActor,
36
40
  PersistedConn,
@@ -161,7 +165,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
161
165
  #backgroundPromises: Promise<void>[] = [];
162
166
  #abortController = new AbortController();
163
167
  #config: ActorConfig<S, CP, CS, V, I, DB>;
164
- #connectionDrivers!: ConnectionDriversMap;
165
168
  #actorDriver!: ActorDriver;
166
169
  #inlineClient!: Client<Registry<any>>;
167
170
  #actorId!: string;
@@ -206,9 +209,9 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
206
209
  getConnections: async () => {
207
210
  return Array.from(this.#connections.entries()).map(([id, conn]) => ({
208
211
  id,
209
- stateEnabled: conn._stateEnabled,
210
- params: conn.params as {},
211
- state: conn._stateEnabled ? conn.state : undefined,
212
+ stateEnabled: conn.__stateEnabled,
213
+ params: conn.params as any,
214
+ state: conn.__stateEnabled ? conn.state : undefined,
212
215
  }));
213
216
  },
214
217
  setState: async (state: unknown) => {
@@ -254,7 +257,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
254
257
  }
255
258
 
256
259
  async start(
257
- connectionDrivers: ConnectionDriversMap,
258
260
  actorDriver: ActorDriver,
259
261
  inlineClient: Client<Registry<any>>,
260
262
  actorId: string,
@@ -278,7 +280,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
278
280
  ),
279
281
  );
280
282
 
281
- this.#connectionDrivers = connectionDrivers;
282
283
  this.#actorDriver = actorDriver;
283
284
  this.#inlineClient = inlineClient;
284
285
  this.#actorId = actorId;
@@ -528,7 +529,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
528
529
  }
529
530
  }
530
531
 
531
- get #connStateEnabled() {
532
+ get connStateEnabled() {
532
533
  return "createConnState" in this.#config || "connState" in this.#config;
533
534
  }
534
535
 
@@ -543,7 +544,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
543
544
  }
544
545
 
545
546
  /** Promise used to wait for a save to complete. This is required since you cannot await `#saveStateThrottled`. */
546
- #onPersistSavedPromise?: PromiseWithResolvers<void>;
547
+ #onPersistSavedPromise?: ReturnType<typeof promiseWithResolvers<void>>;
547
548
 
548
549
  /** Throttled save state method. Used to write to KV at a reasonable cadence. */
549
550
  #savePersistThrottled() {
@@ -719,13 +720,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
719
720
  // Load connections
720
721
  for (const connPersist of this.#persist.connections) {
721
722
  // Create connections
722
- const driver = this.__getConnDriver(connPersist.connDriver);
723
- const conn = new Conn<S, CP, CS, V, I, DB>(
724
- this,
725
- connPersist,
726
- driver,
727
- this.#connStateEnabled,
728
- );
723
+ const conn = new Conn<S, CP, CS, V, I, DB>(this, connPersist);
729
724
  this.#connections.set(conn.id, conn);
730
725
 
731
726
  // Register event subscriptions
@@ -791,14 +786,52 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
791
786
  }
792
787
 
793
788
  /**
794
- * Removes a connection and cleans up its resources.
789
+ * Connection disconnected.
790
+ *
791
+ * If a clean diconnect, will be removed immediately.
792
+ *
793
+ * If not a clean disconnect, will keep the connection alive for a given interval to wait for reconnect.
795
794
  */
796
- __removeConn(conn: Conn<S, CP, CS, V, I, DB> | undefined) {
797
- if (!conn) {
798
- this.#rLog.warn({ msg: "`conn` does not exist" });
795
+ __connDisconnected(
796
+ conn: Conn<S, CP, CS, V, I, DB>,
797
+ wasClean: boolean,
798
+ socketId: string,
799
+ ) {
800
+ // If socket ID is provided, check if it matches the current socket ID
801
+ // If it doesn't match, this is a stale disconnect event from an old socket
802
+ if (socketId && conn.__socket && socketId !== conn.__socket.socketId) {
803
+ this.rLog.debug({
804
+ msg: "ignoring stale disconnect event",
805
+ connId: conn.id,
806
+ eventSocketId: socketId,
807
+ currentSocketId: conn.__socket.socketId,
808
+ });
799
809
  return;
800
810
  }
801
811
 
812
+ if (wasClean) {
813
+ // Disconnected cleanly, remove the conn
814
+
815
+ this.#removeConn(conn);
816
+ } else {
817
+ // Disconnected uncleanly, allow reconnection
818
+
819
+ if (!conn.__driverState) {
820
+ this.rLog.warn("called conn disconnected without driver state");
821
+ }
822
+
823
+ // Update last seen so we know when to clean it up
824
+ conn.__persist.lastSeen = Date.now();
825
+
826
+ // Remove socket
827
+ conn.__socket = undefined;
828
+ }
829
+ }
830
+
831
+ /**
832
+ * Removes a connection and cleans up its resources.
833
+ */
834
+ #removeConn(conn: Conn<S, CP, CS, V, I, DB>) {
802
835
  // Remove from persist & save immediately
803
836
  const connIdx = this.#persist.connections.findIndex(
804
837
  (c) => c.connId === conn.id,
@@ -846,12 +879,96 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
846
879
  this.#resetSleepTimer();
847
880
  }
848
881
 
849
- async prepareConn(
882
+ /**
883
+ * Called to create a new connection or reconnect an existing one.
884
+ */
885
+ async createConn(
886
+ socket: ConnSocket,
850
887
  // biome-ignore lint/suspicious/noExplicitAny: TypeScript bug with ExtractActorConnParams<this>,
851
888
  params: any,
852
889
  request?: Request,
853
- ): Promise<CS> {
854
- // Authenticate connection
890
+ connectionId?: string,
891
+ connectionToken?: string,
892
+ ): Promise<Conn<S, CP, CS, V, I, DB>> {
893
+ this.#assertReady();
894
+
895
+ // If connection ID and token are provided, try to reconnect
896
+ if (connectionId && connectionToken) {
897
+ this.rLog.debug({
898
+ msg: "checking for existing connection",
899
+ connectionId,
900
+ });
901
+ const existingConn = this.#connections.get(connectionId);
902
+ if (existingConn && existingConn._token === connectionToken) {
903
+ // This is a valid reconnection
904
+ this.rLog.debug({
905
+ msg: "reconnecting existing connection",
906
+ connectionId,
907
+ });
908
+
909
+ // If there's an existing driver state, clean it up without marking as clean disconnect
910
+ if (existingConn.__driverState) {
911
+ const driverKind = getConnDriverKindFromState(
912
+ existingConn.__driverState,
913
+ );
914
+ const driver = CONN_DRIVERS[driverKind];
915
+ if (driver.disconnect) {
916
+ // Call driver disconnect to clean up directly. Don't use Conn.disconnect since that will remove the connection entirely.
917
+ driver.disconnect(
918
+ this,
919
+ existingConn,
920
+ (existingConn.__driverState as any)[driverKind],
921
+ "Reconnecting with new driver state",
922
+ );
923
+ }
924
+ }
925
+
926
+ // Update with new driver state
927
+ existingConn.__socket = socket;
928
+ existingConn.__persist.lastSeen = Date.now();
929
+
930
+ // Update sleep timer since connection is now active
931
+ this.#resetSleepTimer();
932
+
933
+ this.inspector.emitter.emit("connectionUpdated");
934
+
935
+ // Send init message for reconnection
936
+ existingConn._sendMessage(
937
+ new CachedSerializer<protocol.ToClient>(
938
+ {
939
+ body: {
940
+ tag: "Init",
941
+ val: {
942
+ actorId: this.id,
943
+ connectionId: existingConn.id,
944
+ connectionToken: existingConn._token,
945
+ },
946
+ },
947
+ },
948
+ TO_CLIENT_VERSIONED,
949
+ ),
950
+ );
951
+
952
+ return existingConn;
953
+ }
954
+
955
+ // If we get here, either connection doesn't exist or token doesn't match
956
+ // Fall through to create new connection with new IDs
957
+ this.rLog.debug({
958
+ msg: "connection not found or token mismatch, creating new connection",
959
+ connectionId,
960
+ });
961
+ }
962
+
963
+ // Generate new connection ID and token if not provided or if reconnection failed
964
+ const newConnId = generateConnId();
965
+ const newConnToken = generateConnToken();
966
+
967
+ if (this.#connections.has(newConnId)) {
968
+ throw new Error(`Connection already exists: ${newConnId}`);
969
+ }
970
+
971
+ // Prepare connection state
855
972
  let connState: CS | undefined;
856
973
 
857
974
  const onBeforeConnectOpts = {
@@ -866,7 +983,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
866
983
  );
867
984
  }
868
985
 
869
- if (this.#connStateEnabled) {
986
+ if (this.connStateEnabled) {
870
987
  if ("createConnState" in this.#config) {
871
988
  const dataOrPromise = this.#config.createConnState(
872
989
  this.actorContext as unknown as ActorContext<
@@ -897,53 +1014,17 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
897
1014
  }
898
1015
  }
899
1016
 
900
- return connState as CS;
901
- }
902
-
903
- __getConnDriver(driverId: ConnectionDriver): ConnDriver {
904
- // Get driver
905
- const driver = this.#connectionDrivers[driverId];
906
- if (!driver) throw new Error(`No connection driver: ${driverId}`);
907
- return driver;
908
- }
909
-
910
- /**
911
- * Called after establishing a connection handshake.
912
- */
913
- async createConn(
914
- connectionId: string,
915
- connectionToken: string,
916
- params: CP,
917
- state: CS,
918
- driverId: ConnectionDriver,
919
- driverState: unknown,
920
- authData: unknown,
921
- ): Promise<Conn<S, CP, CS, V, I, DB>> {
922
- this.#assertReady();
923
-
924
- if (this.#connections.has(connectionId)) {
925
- throw new Error(`Connection already exists: ${connectionId}`);
926
- }
927
-
928
1017
  // Create connection
929
- const driver = this.__getConnDriver(driverId);
930
1018
  const persist: PersistedConn<CP, CS> = {
931
- connId: connectionId,
932
- token: connectionToken,
933
- connDriver: driverId,
934
- connDriverState: driverState,
1019
+ connId: newConnId,
1020
+ token: newConnToken,
935
1021
  params: params,
936
- state: state,
937
- authData: authData,
1022
+ state: connState as CS,
938
1023
  lastSeen: Date.now(),
939
1024
  subscriptions: [],
940
1025
  };
941
- const conn = new Conn<S, CP, CS, V, I, DB>(
942
- this,
943
- persist,
944
- driver,
945
- this.#connStateEnabled,
946
- );
1026
+ const conn = new Conn<S, CP, CS, V, I, DB>(this, persist);
1027
+ conn.__socket = socket;
947
1028
  this.#connections.set(conn.id, conn);
948
1029
 
949
1030
  // Update sleep
@@ -1129,11 +1210,10 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1129
1210
  this.#rLog.debug({ msg: "checking connections liveness" });
1130
1211
 
1131
1212
  for (const conn of this.#connections.values()) {
1132
- const liveness = conn[CONNECTION_CHECK_LIVENESS_SYMBOL]();
1133
- if (liveness.status === "connected") {
1213
+ if (conn.__status === "connected") {
1134
1214
  this.#rLog.debug({ msg: "connection is alive", connId: conn.id });
1135
1215
  } else {
1136
- const lastSeen = liveness.lastSeen;
1216
+ const lastSeen = conn.__persist.lastSeen;
1137
1217
  const sinceLastSeen = Date.now() - lastSeen;
1138
1218
  if (sinceLastSeen < this.#config.options.connectionLivenessTimeout) {
1139
1219
  this.#rLog.debug({
@@ -1152,9 +1232,8 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1152
1232
  lastSeen,
1153
1233
  });
1154
1234
 
1155
- // TODO: Do we need to force disconnect the connection here?
1156
-
1157
- this.__removeConn(conn);
1235
+ // Assume that the connection is dead here, no need to disconnect anything
1236
+ this.#removeConn(conn);
1158
1237
  }
1159
1238
  }
1160
1239
  }
@@ -1309,7 +1388,10 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1309
1388
  /**
1310
1389
  * Handles raw HTTP requests to the actor.
1311
1390
  */
1312
- async handleFetch(request: Request, opts: {}): Promise<Response> {
1391
+ async handleFetch(
1392
+ request: Request,
1393
+ opts: Record<never, never>,
1394
+ ): Promise<Response> {
1313
1395
  this.#assertReady();
1314
1396
 
1315
1397
  if (!this.#config.onFetch) {
@@ -1562,7 +1644,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1562
1644
  } else {
1563
1645
  // Create callback
1564
1646
  if (!this.#onPersistSavedPromise) {
1565
- this.#onPersistSavedPromise = Promise.withResolvers();
1647
+ this.#onPersistSavedPromise = promiseWithResolvers();
1566
1648
  }
1567
1649
 
1568
1650
  // Save state throttled
@@ -1783,10 +1865,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1783
1865
  connections: persist.connections.map((conn) => ({
1784
1866
  id: conn.connId,
1785
1867
  token: conn.token,
1786
- driver: conn.connDriver as string,
1787
- driverState: bufferToArrayBuffer(
1788
- cbor.encode(conn.connDriverState || {}),
1789
- ),
1790
1868
  parameters: bufferToArrayBuffer(cbor.encode(conn.params || {})),
1791
1869
  state: bufferToArrayBuffer(cbor.encode(conn.state || {})),
1792
1870
  subscriptions: conn.subscriptions.map((sub) => ({
@@ -1820,8 +1898,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
1820
1898
  connections: bareData.connections.map((conn) => ({
1821
1899
  connId: conn.id,
1822
1900
  token: conn.token,
1823
- connDriver: conn.driver as ConnectionDriver,
1824
- connDriverState: cbor.decode(new Uint8Array(conn.driverState)),
1825
1901
  params: cbor.decode(new Uint8Array(conn.parameters)),
1826
1902
  state: cbor.decode(new Uint8Array(conn.state)),
1827
1903
  subscriptions: conn.subscriptions.map((sub) => ({
package/src/actor/mod.ts CHANGED
@@ -76,16 +76,10 @@ export type { ActionContext } from "./action";
76
76
  export type * from "./config";
77
77
  export type {
78
78
  Conn,
79
- ConnectionDriver,
80
79
  ConnectionStatus,
81
80
  generateConnId,
82
81
  generateConnToken,
83
- } from "./connection";
84
- export {
85
- CONNECTION_DRIVER_HTTP,
86
- CONNECTION_DRIVER_SSE,
87
- CONNECTION_DRIVER_WEBSOCKET,
88
- } from "./connection";
82
+ } from "./conn";
89
83
  export type { ActorContext } from "./context";
90
84
  export type {
91
85
  ActionContextOf,
@@ -95,10 +89,6 @@ export type {
95
89
  } from "./definition";
96
90
  export { lookupInRegistry } from "./definition";
97
91
  export { UserError, type UserErrorOptions } from "./errors";
98
- export {
99
- createGenericConnDrivers,
100
- GenericConnGlobalState,
101
- } from "./generic-conn-driver";
102
92
  export type { AnyActorInstance } from "./instance";
103
93
  export {
104
94
  type ActorRouter,
@@ -1,5 +1,3 @@
1
- import type { ConnectionDriver } from "./connection";
2
-
3
1
  /** State object that gets automatically persisted to storage. */
4
2
  export interface PersistedActor<S, CP, CS, I> {
5
3
  input?: I;
@@ -13,12 +11,11 @@ export interface PersistedActor<S, CP, CS, I> {
13
11
  export interface PersistedConn<CP, CS> {
14
12
  connId: string;
15
13
  token: string;
16
- connDriver: ConnectionDriver;
17
- connDriverState: unknown;
18
14
  params: CP;
19
15
  state: CS;
20
- authData?: unknown;
21
16
  subscriptions: PersistedSubscription[];
17
+
18
+ /** Last time the socket was seen. This is set when disconencted so we can determine when we need to clean this up. */
22
19
  lastSeen: number;
23
20
  }
24
21
 
@@ -16,7 +16,7 @@ import {
16
16
  import { deserializeWithEncoding } from "@/serde";
17
17
  import { assertUnreachable, bufferToArrayBuffer } from "../../utils";
18
18
  import { ActionContext } from "../action";
19
- import type { Conn } from "../connection";
19
+ import type { Conn } from "../conn";
20
20
  import type { ActorInstance } from "../instance";
21
21
 
22
22
  export const TransportSchema = z.enum(["websocket", "sse"]);