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
@@ -3,11 +3,11 @@ import {
3
3
  ForeignKeysSchema,
4
4
  PatchSchema,
5
5
  TablesSchema
6
- } from "./chunk-ZYLTS2EM.js";
6
+ } from "./chunk-54MAHBLL.js";
7
7
  import {
8
8
  importWebSocket,
9
9
  logger
10
- } from "./chunk-VCEHU56K.js";
10
+ } from "./chunk-B6N6VM37.js";
11
11
  import {
12
12
  HTTP_ACTION_REQUEST_VERSIONED,
13
13
  HTTP_ACTION_RESPONSE_VERSIONED,
@@ -17,31 +17,43 @@ import {
17
17
  TO_SERVER_VERSIONED,
18
18
  inputDataToBuffer,
19
19
  processMessage
20
- } from "./chunk-7OUKNSTU.js";
20
+ } from "./chunk-2NL3KGJ7.js";
21
21
  import {
22
22
  CachedSerializer,
23
23
  DeadlineError,
24
- HEADER_AUTH_DATA,
25
24
  HEADER_CONN_ID,
26
25
  HEADER_CONN_PARAMS,
27
26
  HEADER_CONN_TOKEN,
28
27
  HEADER_ENCODING,
28
+ HEADER_RIVET_ACTOR,
29
+ HEADER_RIVET_TARGET,
30
+ HEADER_RIVET_TOKEN,
29
31
  PATH_CONNECT_WEBSOCKET,
30
32
  PATH_RAW_WEBSOCKET_PREFIX,
33
+ WS_PROTOCOL_ACTOR,
34
+ WS_PROTOCOL_CONN_ID,
35
+ WS_PROTOCOL_CONN_PARAMS,
36
+ WS_PROTOCOL_CONN_TOKEN,
37
+ WS_PROTOCOL_ENCODING,
38
+ WS_PROTOCOL_STANDARD,
39
+ WS_PROTOCOL_TARGET,
40
+ WS_PROTOCOL_TOKEN,
31
41
  assertUnreachable as assertUnreachable2,
32
42
  contentTypeForEncoding,
33
43
  deadline,
34
44
  deserializeWithEncoding,
45
+ encodeDataToString,
35
46
  encodingIsBinary,
47
+ generateRandomString,
36
48
  generateSecureToken,
37
49
  jsonStringifyCompat,
38
50
  serializeWithEncoding
39
- } from "./chunk-2K3JMDAN.js";
51
+ } from "./chunk-NRELKXIX.js";
40
52
  import {
41
53
  getBaseLogger,
42
54
  getIncludeTarget,
43
55
  getLogger
44
- } from "./chunk-WC2PSJWN.js";
56
+ } from "./chunk-YL4VZMMT.js";
45
57
  import {
46
58
  SinglePromiseQueue,
47
59
  assertUnreachable,
@@ -52,8 +64,9 @@ import {
52
64
  httpUserAgent,
53
65
  isCborSerializable,
54
66
  noopNext,
67
+ promiseWithResolvers,
55
68
  stringifyError
56
- } from "./chunk-RGQR2J7S.js";
69
+ } from "./chunk-RLBM6D4L.js";
57
70
  import {
58
71
  ActionNotFound,
59
72
  ActionTimedOut,
@@ -69,44 +82,134 @@ import {
69
82
  VarsNotEnabled
70
83
  } from "./chunk-YPZFLUO6.js";
71
84
 
72
- // src/actor/connection.ts
85
+ // src/actor/conn.ts
73
86
  import * as cbor from "cbor-x";
87
+
88
+ // src/actor/conn-drivers.ts
89
+ var WEBSOCKET_DRIVER = {
90
+ sendMessage: (actor, _conn, state, message) => {
91
+ const serialized = message.serialize(state.encoding);
92
+ actor.rLog.debug({
93
+ msg: "sending websocket message",
94
+ encoding: state.encoding,
95
+ dataType: typeof serialized,
96
+ isUint8Array: serialized instanceof Uint8Array,
97
+ isArrayBuffer: serialized instanceof ArrayBuffer,
98
+ dataLength: serialized.byteLength || serialized.length
99
+ });
100
+ if (serialized instanceof Uint8Array) {
101
+ const buffer = serialized.buffer.slice(
102
+ serialized.byteOffset,
103
+ serialized.byteOffset + serialized.byteLength
104
+ );
105
+ if (buffer instanceof SharedArrayBuffer) {
106
+ const arrayBuffer = new ArrayBuffer(buffer.byteLength);
107
+ new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
108
+ actor.rLog.debug({
109
+ msg: "converted SharedArrayBuffer to ArrayBuffer",
110
+ byteLength: arrayBuffer.byteLength
111
+ });
112
+ state.websocket.send(arrayBuffer);
113
+ } else {
114
+ actor.rLog.debug({
115
+ msg: "sending ArrayBuffer",
116
+ byteLength: buffer.byteLength
117
+ });
118
+ state.websocket.send(buffer);
119
+ }
120
+ } else {
121
+ actor.rLog.debug({
122
+ msg: "sending string data",
123
+ length: serialized.length
124
+ });
125
+ state.websocket.send(serialized);
126
+ }
127
+ },
128
+ disconnect: async (_actor, _conn, state, reason) => {
129
+ state.websocket.close(1e3, reason);
130
+ await state.closePromise.promise;
131
+ },
132
+ getConnectionReadyState: (_actor, _conn, state) => {
133
+ return state.websocket.readyState;
134
+ }
135
+ };
136
+ var SSE_DRIVER = {
137
+ sendMessage: (_actor, _conn, state, message) => {
138
+ state.stream.writeSSE({
139
+ data: encodeDataToString(message.serialize(state.encoding))
140
+ });
141
+ },
142
+ disconnect: async (_actor, _conn, state, _reason) => {
143
+ state.stream.close();
144
+ },
145
+ getConnectionReadyState: (_actor, _conn, state) => {
146
+ if (state.stream.aborted || state.stream.closed) {
147
+ return 3 /* CLOSED */;
148
+ }
149
+ return 1 /* OPEN */;
150
+ }
151
+ };
152
+ var HTTP_DRIVER = {
153
+ getConnectionReadyState(_actor, _conn) {
154
+ return 1 /* OPEN */;
155
+ },
156
+ disconnect: async () => {
157
+ }
158
+ };
159
+ var CONN_DRIVERS = {
160
+ [0 /* WEBSOCKET */]: WEBSOCKET_DRIVER,
161
+ [1 /* SSE */]: SSE_DRIVER,
162
+ [2 /* HTTP */]: HTTP_DRIVER
163
+ };
164
+ function getConnDriverKindFromState(state) {
165
+ if (0 /* WEBSOCKET */ in state) return 0 /* WEBSOCKET */;
166
+ else if (1 /* SSE */ in state) return 1 /* SSE */;
167
+ else if (2 /* HTTP */ in state) return 2 /* HTTP */;
168
+ else assertUnreachable(state);
169
+ }
170
+
171
+ // src/actor/conn.ts
74
172
  function generateConnId() {
75
173
  return crypto.randomUUID();
76
174
  }
77
175
  function generateConnToken() {
78
176
  return generateSecureToken(32);
79
177
  }
80
- var CONNECTION_DRIVER_WEBSOCKET = "webSocket";
81
- var CONNECTION_DRIVER_SSE = "sse";
82
- var CONNECTION_DRIVER_HTTP = "http";
83
- var CONNECTION_CHECK_LIVENESS_SYMBOL = Symbol("checkLiveness");
178
+ function generateConnSocketId() {
179
+ return crypto.randomUUID();
180
+ }
84
181
  var Conn = class {
85
182
  subscriptions = /* @__PURE__ */ new Set();
86
- #stateEnabled;
87
183
  // TODO: Remove this cyclical reference
88
184
  #actor;
89
- #status = "connected";
90
185
  /**
91
186
  * The proxied state that notifies of changes automatically.
92
187
  *
93
188
  * Any data that should be stored indefinitely should be held within this object.
94
189
  */
95
190
  __persist;
191
+ get __driverState() {
192
+ var _a;
193
+ return (_a = this.__socket) == null ? void 0 : _a.driverState;
194
+ }
96
195
  /**
97
- * Driver used to manage realtime connection communication.
196
+ * Socket connected to this connection.
98
197
  *
99
- * @protected
198
+ * If undefined, then nothing is connected to this.
100
199
  */
101
- #driver;
200
+ __socket;
201
+ get __status() {
202
+ if (this.__socket) {
203
+ return "connected";
204
+ } else {
205
+ return "reconnecting";
206
+ }
207
+ }
102
208
  get params() {
103
209
  return this.__persist.params;
104
210
  }
105
- get driver() {
106
- return this.__persist.connDriver;
107
- }
108
- get _stateEnabled() {
109
- return this.#stateEnabled;
211
+ get __stateEnabled() {
212
+ return this.#actor.connStateEnabled;
110
213
  }
111
214
  /**
112
215
  * Gets the current state of the connection.
@@ -143,7 +246,7 @@ var Conn = class {
143
246
  * Status of the connection.
144
247
  */
145
248
  get status() {
146
- return this.#status;
249
+ return this.__status;
147
250
  }
148
251
  /**
149
252
  * Timestamp of the last time the connection was seen, i.e. the last time the connection was active and checked for liveness.
@@ -158,14 +261,12 @@ var Conn = class {
158
261
  *
159
262
  * @protected
160
263
  */
161
- constructor(actor, persist, driver, stateEnabled) {
264
+ constructor(actor, persist) {
162
265
  this.#actor = actor;
163
266
  this.__persist = persist;
164
- this.#driver = driver;
165
- this.#stateEnabled = stateEnabled;
166
267
  }
167
268
  #validateStateEnabled() {
168
- if (!this.#stateEnabled) {
269
+ if (!this.__stateEnabled) {
169
270
  throw new ConnStateNotEnabled();
170
271
  }
171
272
  }
@@ -177,14 +278,28 @@ var Conn = class {
177
278
  * @protected
178
279
  */
179
280
  _sendMessage(message) {
180
- var _a, _b;
181
- (_b = (_a = this.#driver).sendMessage) == null ? void 0 : _b.call(
182
- _a,
183
- this.#actor,
184
- this,
185
- this.__persist.connDriverState,
186
- message
187
- );
281
+ if (this.__driverState) {
282
+ const driverKind = getConnDriverKindFromState(this.__driverState);
283
+ const driver = CONN_DRIVERS[driverKind];
284
+ if (driver.sendMessage) {
285
+ driver.sendMessage(
286
+ this.#actor,
287
+ this,
288
+ this.__driverState[driverKind],
289
+ message
290
+ );
291
+ } else {
292
+ this.#actor.rLog.debug({
293
+ msg: "conn driver does not support sending messages",
294
+ conn: this.id
295
+ });
296
+ }
297
+ } else {
298
+ this.#actor.rLog.warn({
299
+ msg: "missing connection driver state for send message",
300
+ conn: this.id
301
+ });
302
+ }
188
303
  }
189
304
  /**
190
305
  * Sends an event with arguments to the client.
@@ -221,43 +336,30 @@ var Conn = class {
221
336
  * @param reason - The reason for disconnection.
222
337
  */
223
338
  async disconnect(reason) {
224
- this.#status = "reconnecting";
225
- await this.#driver.disconnect(
226
- this.#actor,
227
- this,
228
- this.__persist.connDriverState,
229
- reason
230
- );
231
- }
232
- /**
233
- * This method checks the connection's liveness by querying the driver for its ready state.
234
- * If the connection is not closed, it updates the last liveness timestamp and returns `true`.
235
- * Otherwise, it returns `false`.
236
- * @internal
237
- */
238
- [CONNECTION_CHECK_LIVENESS_SYMBOL]() {
239
- const readyState = this.#driver.getConnectionReadyState(this.#actor, this);
240
- const isConnectionClosed = readyState === 3 /* CLOSED */ || readyState === 2 /* CLOSING */ || readyState === void 0;
241
- const newLastSeen = Date.now();
242
- const newStatus = isConnectionClosed ? "reconnecting" : "connected";
243
- this.#actor.rLog.debug({
244
- msg: "liveness probe for connection",
245
- connId: this.id,
246
- actorId: this.#actor.id,
247
- readyState,
248
- status: this.#status,
249
- newStatus,
250
- lastSeen: this.__persist.lastSeen,
251
- currentTs: newLastSeen
252
- });
253
- if (!isConnectionClosed) {
254
- this.__persist.lastSeen = newLastSeen;
339
+ if (this.__socket && this.__driverState) {
340
+ const driverKind = getConnDriverKindFromState(this.__driverState);
341
+ const driver = CONN_DRIVERS[driverKind];
342
+ if (driver.disconnect) {
343
+ driver.disconnect(
344
+ this.#actor,
345
+ this,
346
+ this.__driverState[driverKind],
347
+ reason
348
+ );
349
+ } else {
350
+ this.#actor.rLog.debug({
351
+ msg: "no disconnect handler for conn driver",
352
+ conn: this.id
353
+ });
354
+ }
355
+ this.#actor.__connDisconnected(this, true, this.__socket.socketId);
356
+ } else {
357
+ this.#actor.rLog.warn({
358
+ msg: "missing connection driver state for disconnect",
359
+ conn: this.id
360
+ });
255
361
  }
256
- this.#status = newStatus;
257
- return {
258
- status: this.#status,
259
- lastSeen: this.__persist.lastSeen
260
- };
362
+ this.__socket = void 0;
261
363
  }
262
364
  };
263
365
 
@@ -335,7 +437,7 @@ function createActorInspectorRouter() {
335
437
  id: String(id++)
336
438
  });
337
439
  });
338
- const { promise } = Promise.withResolvers();
440
+ const { promise } = promiseWithResolvers();
339
441
  return promise;
340
442
  },
341
443
  async () => {
@@ -360,7 +462,7 @@ function createActorInspectorRouter() {
360
462
  id: String(id++)
361
463
  });
362
464
  });
363
- const { promise } = Promise.withResolvers();
465
+ const { promise } = promiseWithResolvers();
364
466
  return promise;
365
467
  },
366
468
  async () => {
@@ -386,7 +488,7 @@ function createActorInspectorRouter() {
386
488
  id: String(id++)
387
489
  });
388
490
  });
389
- const { promise } = Promise.withResolvers();
491
+ const { promise } = promiseWithResolvers();
390
492
  return promise;
391
493
  },
392
494
  async () => {
@@ -703,7 +805,6 @@ var ActorInstance = class {
703
805
  #backgroundPromises = [];
704
806
  #abortController = new AbortController();
705
807
  #config;
706
- #connectionDrivers;
707
808
  #actorDriver;
708
809
  #inlineClient;
709
810
  #actorId;
@@ -741,9 +842,9 @@ var ActorInstance = class {
741
842
  getConnections: async () => {
742
843
  return Array.from(this.#connections.entries()).map(([id, conn]) => ({
743
844
  id,
744
- stateEnabled: conn._stateEnabled,
845
+ stateEnabled: conn.__stateEnabled,
745
846
  params: conn.params,
746
- state: conn._stateEnabled ? conn.state : void 0
847
+ state: conn.__stateEnabled ? conn.state : void 0
747
848
  }));
748
849
  },
749
850
  setState: async (state) => {
@@ -776,7 +877,7 @@ var ActorInstance = class {
776
877
  this.#config = config;
777
878
  this.actorContext = new ActorContext(this);
778
879
  }
779
- async start(connectionDrivers, actorDriver, inlineClient, actorId, name, key, region) {
880
+ async start(actorDriver, inlineClient, actorId, name, key, region) {
780
881
  var _a, _b;
781
882
  const logParams = {
782
883
  actor: name,
@@ -792,7 +893,6 @@ var ActorInstance = class {
792
893
  logParams
793
894
  )
794
895
  );
795
- this.#connectionDrivers = connectionDrivers;
796
896
  this.#actorDriver = actorDriver;
797
897
  this.#inlineClient = inlineClient;
798
898
  this.#actorId = actorId;
@@ -971,7 +1071,7 @@ var ActorInstance = class {
971
1071
  throw new StateNotEnabled();
972
1072
  }
973
1073
  }
974
- get #connStateEnabled() {
1074
+ get connStateEnabled() {
975
1075
  return "createConnState" in this.#config || "connState" in this.#config;
976
1076
  }
977
1077
  get #varsEnabled() {
@@ -1110,13 +1210,7 @@ var ActorInstance = class {
1110
1210
  });
1111
1211
  this.#setPersist(persistData);
1112
1212
  for (const connPersist of this.#persist.connections) {
1113
- const driver = this.__getConnDriver(connPersist.connDriver);
1114
- const conn = new Conn(
1115
- this,
1116
- connPersist,
1117
- driver,
1118
- this.#connStateEnabled
1119
- );
1213
+ const conn = new Conn(this, connPersist);
1120
1214
  this.#connections.set(conn.id, conn);
1121
1215
  for (const sub of connPersist.subscriptions) {
1122
1216
  this.#addSubscription(sub.eventName, conn, true);
@@ -1159,13 +1253,36 @@ var ActorInstance = class {
1159
1253
  return this.#connections.get(id);
1160
1254
  }
1161
1255
  /**
1162
- * Removes a connection and cleans up its resources.
1256
+ * Connection disconnected.
1257
+ *
1258
+ * If a clean diconnect, will be removed immediately.
1259
+ *
1260
+ * If not a clean disconnect, will keep the connection alive for a given interval to wait for reconnect.
1163
1261
  */
1164
- __removeConn(conn) {
1165
- if (!conn) {
1166
- this.#rLog.warn({ msg: "`conn` does not exist" });
1262
+ __connDisconnected(conn, wasClean, socketId) {
1263
+ if (socketId && conn.__socket && socketId !== conn.__socket.socketId) {
1264
+ this.rLog.debug({
1265
+ msg: "ignoring stale disconnect event",
1266
+ connId: conn.id,
1267
+ eventSocketId: socketId,
1268
+ currentSocketId: conn.__socket.socketId
1269
+ });
1167
1270
  return;
1168
1271
  }
1272
+ if (wasClean) {
1273
+ this.#removeConn(conn);
1274
+ } else {
1275
+ if (!conn.__driverState) {
1276
+ this.rLog.warn("called conn disconnected without driver state");
1277
+ }
1278
+ conn.__persist.lastSeen = Date.now();
1279
+ conn.__socket = void 0;
1280
+ }
1281
+ }
1282
+ /**
1283
+ * Removes a connection and cleans up its resources.
1284
+ */
1285
+ #removeConn(conn) {
1169
1286
  const connIdx = this.#persist.connections.findIndex(
1170
1287
  (c) => c.connId === conn.id
1171
1288
  );
@@ -1203,7 +1320,67 @@ var ActorInstance = class {
1203
1320
  }
1204
1321
  this.#resetSleepTimer();
1205
1322
  }
1206
- async prepareConn(params, request) {
1323
+ /**
1324
+ * Called to create a new connection or reconnect an existing one.
1325
+ */
1326
+ async createConn(socket, params, request, connectionId, connectionToken) {
1327
+ this.#assertReady();
1328
+ if (connectionId && connectionToken) {
1329
+ this.rLog.debug({
1330
+ msg: "checking for existing connection",
1331
+ connectionId
1332
+ });
1333
+ const existingConn = this.#connections.get(connectionId);
1334
+ if (existingConn && existingConn._token === connectionToken) {
1335
+ this.rLog.debug({
1336
+ msg: "reconnecting existing connection",
1337
+ connectionId
1338
+ });
1339
+ if (existingConn.__driverState) {
1340
+ const driverKind = getConnDriverKindFromState(
1341
+ existingConn.__driverState
1342
+ );
1343
+ const driver = CONN_DRIVERS[driverKind];
1344
+ if (driver.disconnect) {
1345
+ driver.disconnect(
1346
+ this,
1347
+ existingConn,
1348
+ existingConn.__driverState[driverKind],
1349
+ "Reconnecting with new driver state"
1350
+ );
1351
+ }
1352
+ }
1353
+ existingConn.__socket = socket;
1354
+ existingConn.__persist.lastSeen = Date.now();
1355
+ this.#resetSleepTimer();
1356
+ this.inspector.emitter.emit("connectionUpdated");
1357
+ existingConn._sendMessage(
1358
+ new CachedSerializer(
1359
+ {
1360
+ body: {
1361
+ tag: "Init",
1362
+ val: {
1363
+ actorId: this.id,
1364
+ connectionId: existingConn.id,
1365
+ connectionToken: existingConn._token
1366
+ }
1367
+ }
1368
+ },
1369
+ TO_CLIENT_VERSIONED
1370
+ )
1371
+ );
1372
+ return existingConn;
1373
+ }
1374
+ this.rLog.debug({
1375
+ msg: "connection not found or token mismatch, creating new connection",
1376
+ connectionId
1377
+ });
1378
+ }
1379
+ const newConnId = generateConnId();
1380
+ const newConnToken = generateConnToken();
1381
+ if (this.#connections.has(newConnId)) {
1382
+ throw new Error(`Connection already exists: ${newConnId}`);
1383
+ }
1207
1384
  let connState;
1208
1385
  const onBeforeConnectOpts = {
1209
1386
  request
@@ -1215,7 +1392,7 @@ var ActorInstance = class {
1215
1392
  params
1216
1393
  );
1217
1394
  }
1218
- if (this.#connStateEnabled) {
1395
+ if (this.connStateEnabled) {
1219
1396
  if ("createConnState" in this.#config) {
1220
1397
  const dataOrPromise = this.#config.createConnState(
1221
1398
  this.actorContext,
@@ -1238,39 +1415,16 @@ var ActorInstance = class {
1238
1415
  );
1239
1416
  }
1240
1417
  }
1241
- return connState;
1242
- }
1243
- __getConnDriver(driverId) {
1244
- const driver = this.#connectionDrivers[driverId];
1245
- if (!driver) throw new Error(`No connection driver: ${driverId}`);
1246
- return driver;
1247
- }
1248
- /**
1249
- * Called after establishing a connection handshake.
1250
- */
1251
- async createConn(connectionId, connectionToken, params, state, driverId, driverState, authData) {
1252
- this.#assertReady();
1253
- if (this.#connections.has(connectionId)) {
1254
- throw new Error(`Connection already exists: ${connectionId}`);
1255
- }
1256
- const driver = this.__getConnDriver(driverId);
1257
1418
  const persist = {
1258
- connId: connectionId,
1259
- token: connectionToken,
1260
- connDriver: driverId,
1261
- connDriverState: driverState,
1419
+ connId: newConnId,
1420
+ token: newConnToken,
1262
1421
  params,
1263
- state,
1264
- authData,
1422
+ state: connState,
1265
1423
  lastSeen: Date.now(),
1266
1424
  subscriptions: []
1267
1425
  };
1268
- const conn = new Conn(
1269
- this,
1270
- persist,
1271
- driver,
1272
- this.#connStateEnabled
1273
- );
1426
+ const conn = new Conn(this, persist);
1427
+ conn.__socket = socket;
1274
1428
  this.#connections.set(conn.id, conn);
1275
1429
  this.#resetSleepTimer();
1276
1430
  this.#persist.connections.push(persist);
@@ -1411,11 +1565,10 @@ var ActorInstance = class {
1411
1565
  #checkConnectionsLiveness() {
1412
1566
  this.#rLog.debug({ msg: "checking connections liveness" });
1413
1567
  for (const conn of this.#connections.values()) {
1414
- const liveness = conn[CONNECTION_CHECK_LIVENESS_SYMBOL]();
1415
- if (liveness.status === "connected") {
1568
+ if (conn.__status === "connected") {
1416
1569
  this.#rLog.debug({ msg: "connection is alive", connId: conn.id });
1417
1570
  } else {
1418
- const lastSeen = liveness.lastSeen;
1571
+ const lastSeen = conn.__persist.lastSeen;
1419
1572
  const sinceLastSeen = Date.now() - lastSeen;
1420
1573
  if (sinceLastSeen < this.#config.options.connectionLivenessTimeout) {
1421
1574
  this.#rLog.debug({
@@ -1431,7 +1584,7 @@ var ActorInstance = class {
1431
1584
  connId: conn.id,
1432
1585
  lastSeen
1433
1586
  });
1434
- this.__removeConn(conn);
1587
+ this.#removeConn(conn);
1435
1588
  }
1436
1589
  }
1437
1590
  }
@@ -1761,7 +1914,7 @@ var ActorInstance = class {
1761
1914
  await this.#savePersistInner();
1762
1915
  } else {
1763
1916
  if (!this.#onPersistSavedPromise) {
1764
- this.#onPersistSavedPromise = Promise.withResolvers();
1917
+ this.#onPersistSavedPromise = promiseWithResolvers();
1765
1918
  }
1766
1919
  this.#savePersistThrottled();
1767
1920
  await this.#onPersistSavedPromise.promise;
@@ -1925,10 +2078,6 @@ var ActorInstance = class {
1925
2078
  connections: persist.connections.map((conn) => ({
1926
2079
  id: conn.connId,
1927
2080
  token: conn.token,
1928
- driver: conn.connDriver,
1929
- driverState: bufferToArrayBuffer(
1930
- cbor2.encode(conn.connDriverState || {})
1931
- ),
1932
2081
  parameters: bufferToArrayBuffer(cbor2.encode(conn.params || {})),
1933
2082
  state: bufferToArrayBuffer(cbor2.encode(conn.state || {})),
1934
2083
  subscriptions: conn.subscriptions.map((sub) => ({
@@ -1957,8 +2106,6 @@ var ActorInstance = class {
1957
2106
  connections: bareData.connections.map((conn) => ({
1958
2107
  connId: conn.id,
1959
2108
  token: conn.token,
1960
- connDriver: conn.driver,
1961
- connDriverState: cbor2.decode(new Uint8Array(conn.driverState)),
1962
2109
  params: cbor2.decode(new Uint8Array(conn.parameters)),
1963
2110
  state: cbor2.decode(new Uint8Array(conn.state)),
1964
2111
  subscriptions: conn.subscriptions.map((sub) => ({
@@ -2699,7 +2846,7 @@ function createActorProxy(handle) {
2699
2846
  return Reflect.get(target, prop, receiver);
2700
2847
  }
2701
2848
  if (prop === "constructor" || prop in target) {
2702
- const value = Reflect.get(target, prop, receiver);
2849
+ const value = Reflect.get(target, prop, target);
2703
2850
  if (typeof value === "function") {
2704
2851
  return value.bind(target);
2705
2852
  }
@@ -2757,7 +2904,7 @@ var ActorConnRaw = class {
2757
2904
  #abortController = new AbortController();
2758
2905
  /** If attempting to connect. Helpful for knowing if in a retry loop when reconnecting. */
2759
2906
  #connecting = false;
2760
- // These will only be set on SSE driver
2907
+ // Connection info, used for reconnection and HTTP requests
2761
2908
  #actorId;
2762
2909
  #connectionId;
2763
2910
  #connectionToken;
@@ -2811,7 +2958,7 @@ var ActorConnRaw = class {
2811
2958
  logger().debug({ msg: "action", name: opts.name, args: opts.args });
2812
2959
  const actionId = this.#actionIdCounter;
2813
2960
  this.#actionIdCounter += 1;
2814
- const { promise, resolve, reject } = Promise.withResolvers();
2961
+ const { promise, resolve, reject } = promiseWithResolvers();
2815
2962
  this.#actionsInFlight.set(actionId, { name: opts.name, resolve, reject });
2816
2963
  this.#sendMessage({
2817
2964
  body: {
@@ -2871,7 +3018,7 @@ var ActorConnRaw = class {
2871
3018
  try {
2872
3019
  if (this.#onOpenPromise)
2873
3020
  throw new Error("#onOpenPromise already defined");
2874
- this.#onOpenPromise = Promise.withResolvers();
3021
+ this.#onOpenPromise = promiseWithResolvers();
2875
3022
  if (this.#client[TRANSPORT_SYMBOL] === "websocket") {
2876
3023
  await this.#connectWebSocket();
2877
3024
  } else if (this.#client[TRANSPORT_SYMBOL] === "sse") {
@@ -2890,15 +3037,34 @@ var ActorConnRaw = class {
2890
3037
  this.#actorQuery,
2891
3038
  this.#driver
2892
3039
  );
3040
+ const isReconnection = this.#connectionId && this.#connectionToken;
3041
+ if (isReconnection) {
3042
+ logger().debug({
3043
+ msg: "attempting websocket reconnection",
3044
+ connectionId: this.#connectionId
3045
+ });
3046
+ }
2893
3047
  const ws = await this.#driver.openWebSocket(
2894
3048
  PATH_CONNECT_WEBSOCKET,
2895
3049
  actorId,
2896
3050
  this.#encoding,
2897
- this.#params
3051
+ this.#params,
3052
+ // Pass connection ID and token for reconnection if available
3053
+ isReconnection ? this.#connectionId : void 0,
3054
+ isReconnection ? this.#connectionToken : void 0
2898
3055
  );
3056
+ logger().debug({
3057
+ msg: "transport set to new websocket",
3058
+ connectionId: this.#connectionId,
3059
+ readyState: ws.readyState,
3060
+ messageQueueLength: this.#messageQueue.length
3061
+ });
2899
3062
  this.#transport = { websocket: ws };
2900
3063
  ws.addEventListener("open", () => {
2901
- logger().debug({ msg: "websocket open" });
3064
+ logger().debug({
3065
+ msg: "client websocket open",
3066
+ connectionId: this.#connectionId
3067
+ });
2902
3068
  });
2903
3069
  ws.addEventListener("message", async (ev) => {
2904
3070
  this.#handleOnMessage(ev.data);
@@ -2924,6 +3090,7 @@ var ActorConnRaw = class {
2924
3090
  actorId,
2925
3091
  encoding: this.#encoding
2926
3092
  });
3093
+ const isReconnection = this.#connectionId && this.#connectionToken;
2927
3094
  const eventSource = new EventSource("http://actor/connect/sse", {
2928
3095
  fetch: (input, init) => {
2929
3096
  return this.#driver.sendRequest(
@@ -2934,7 +3101,11 @@ var ActorConnRaw = class {
2934
3101
  ...init == null ? void 0 : init.headers,
2935
3102
  "User-Agent": httpUserAgent(),
2936
3103
  [HEADER_ENCODING]: this.#encoding,
2937
- ...this.#params !== void 0 ? { [HEADER_CONN_PARAMS]: JSON.stringify(this.#params) } : {}
3104
+ ...this.#params !== void 0 ? { [HEADER_CONN_PARAMS]: JSON.stringify(this.#params) } : {},
3105
+ ...isReconnection ? {
3106
+ [HEADER_CONN_ID]: this.#connectionId,
3107
+ [HEADER_CONN_TOKEN]: this.#connectionToken
3108
+ } : {}
2938
3109
  }
2939
3110
  })
2940
3111
  );
@@ -2942,6 +3113,7 @@ var ActorConnRaw = class {
2942
3113
  });
2943
3114
  this.#transport = { sse: eventSource };
2944
3115
  eventSource.addEventListener("message", (ev) => {
3116
+ if (ev.type === "ping") return;
2945
3117
  this.#handleOnMessage(ev.data);
2946
3118
  });
2947
3119
  eventSource.addEventListener("error", (ev) => {
@@ -2952,7 +3124,8 @@ var ActorConnRaw = class {
2952
3124
  #handleOnOpen() {
2953
3125
  logger().debug({
2954
3126
  msg: "socket open",
2955
- messageQueueLength: this.#messageQueue.length
3127
+ messageQueueLength: this.#messageQueue.length,
3128
+ connectionId: this.#connectionId
2956
3129
  });
2957
3130
  if (this.#onOpenPromise) {
2958
3131
  this.#onOpenPromise.resolve(void 0);
@@ -2964,6 +3137,10 @@ var ActorConnRaw = class {
2964
3137
  }
2965
3138
  const queue = this.#messageQueue;
2966
3139
  this.#messageQueue = [];
3140
+ logger().debug({
3141
+ msg: "flushing message queue",
3142
+ queueLength: queue.length
3143
+ });
2967
3144
  for (const msg of queue) {
2968
3145
  this.#sendMessage(msg);
2969
3146
  }
@@ -3056,23 +3233,38 @@ var ActorConnRaw = class {
3056
3233
  this.#onOpenPromise.reject(new Error("Closed"));
3057
3234
  }
3058
3235
  const closeEvent = event;
3059
- if (closeEvent.wasClean) {
3060
- logger().info({
3061
- msg: "socket closed",
3062
- code: closeEvent.code,
3063
- reason: closeEvent.reason,
3064
- wasClean: closeEvent.wasClean
3065
- });
3066
- } else {
3067
- logger().warn({
3068
- msg: "socket closed",
3069
- code: closeEvent.code,
3070
- reason: closeEvent.reason,
3071
- wasClean: closeEvent.wasClean
3236
+ const wasClean = closeEvent.wasClean;
3237
+ logger().info({
3238
+ msg: "socket closed",
3239
+ code: closeEvent.code,
3240
+ reason: closeEvent.reason,
3241
+ wasClean,
3242
+ connectionId: this.#connectionId,
3243
+ messageQueueLength: this.#messageQueue.length,
3244
+ actionsInFlight: this.#actionsInFlight.size
3245
+ });
3246
+ if (this.#actionsInFlight.size > 0) {
3247
+ logger().debug({
3248
+ msg: "rejecting in-flight actions after disconnect",
3249
+ count: this.#actionsInFlight.size,
3250
+ connectionId: this.#connectionId,
3251
+ wasClean
3072
3252
  });
3253
+ const disconnectError = new Error(
3254
+ wasClean ? "Connection closed" : "Connection lost"
3255
+ );
3256
+ for (const actionInfo of this.#actionsInFlight.values()) {
3257
+ actionInfo.reject(disconnectError);
3258
+ }
3259
+ this.#actionsInFlight.clear();
3073
3260
  }
3074
3261
  this.#transport = void 0;
3075
3262
  if (!this.#disposed && !this.#connecting) {
3263
+ logger().debug({
3264
+ msg: "triggering reconnect",
3265
+ connectionId: this.#connectionId,
3266
+ messageQueueLength: this.#messageQueue.length
3267
+ });
3076
3268
  this.#connectWithRetry();
3077
3269
  }
3078
3270
  }
@@ -3176,14 +3368,25 @@ var ActorConnRaw = class {
3176
3368
  };
3177
3369
  }
3178
3370
  #sendMessage(message, opts) {
3371
+ var _a, _b;
3179
3372
  if (this.#disposed) {
3180
3373
  throw new ActorConnDisposed();
3181
3374
  }
3182
3375
  let queueMessage = false;
3183
3376
  if (!this.#transport) {
3377
+ logger().debug({ msg: "no transport, queueing message" });
3184
3378
  queueMessage = true;
3185
3379
  } else if ("websocket" in this.#transport) {
3186
- if (this.#transport.websocket.readyState === 1) {
3380
+ const readyState = this.#transport.websocket.readyState;
3381
+ logger().debug({
3382
+ msg: "websocket send attempt",
3383
+ readyState,
3384
+ readyStateString: readyState === 0 ? "CONNECTING" : readyState === 1 ? "OPEN" : readyState === 2 ? "CLOSING" : "CLOSED",
3385
+ connectionId: this.#connectionId,
3386
+ messageType: message.body.tag,
3387
+ actionName: (_a = message.body.val) == null ? void 0 : _a.name
3388
+ });
3389
+ if (readyState === 1) {
3187
3390
  try {
3188
3391
  const messageSerialized = serializeWithEncoding(
3189
3392
  this.#encoding,
@@ -3198,11 +3401,16 @@ var ActorConnRaw = class {
3198
3401
  } catch (error) {
3199
3402
  logger().warn({
3200
3403
  msg: "failed to send message, added to queue",
3201
- error
3404
+ error,
3405
+ connectionId: this.#connectionId
3202
3406
  });
3203
3407
  queueMessage = true;
3204
3408
  }
3205
3409
  } else {
3410
+ logger().debug({
3411
+ msg: "websocket not open, queueing message",
3412
+ readyState
3413
+ });
3206
3414
  queueMessage = true;
3207
3415
  }
3208
3416
  } else if ("sse" in this.#transport) {
@@ -3216,7 +3424,13 @@ var ActorConnRaw = class {
3216
3424
  }
3217
3425
  if (!(opts == null ? void 0 : opts.ephemeral) && queueMessage) {
3218
3426
  this.#messageQueue.push(message);
3219
- logger().debug({ msg: "queued connection message" });
3427
+ logger().debug({
3428
+ msg: "queued connection message",
3429
+ queueLength: this.#messageQueue.length,
3430
+ connectionId: this.#connectionId,
3431
+ messageType: message.body.tag,
3432
+ actionName: (_b = message.body.val) == null ? void 0 : _b.name
3433
+ });
3220
3434
  }
3221
3435
  }
3222
3436
  async #sendHttpMessage(message, opts) {
@@ -3273,6 +3487,20 @@ var ActorConnRaw = class {
3273
3487
  const buffer = await inputDataToBuffer(data);
3274
3488
  return deserializeWithEncoding(this.#encoding, buffer, TO_CLIENT_VERSIONED);
3275
3489
  }
3490
+ /**
3491
+ * Get the actor ID (for testing purposes).
3492
+ * @internal
3493
+ */
3494
+ get actorId() {
3495
+ return this.#actorId;
3496
+ }
3497
+ /**
3498
+ * Get the connection ID (for testing purposes).
3499
+ * @internal
3500
+ */
3501
+ get connectionId() {
3502
+ return this.#connectionId;
3503
+ }
3276
3504
  /**
3277
3505
  * Disconnects from the actor.
3278
3506
  *
@@ -3294,7 +3522,7 @@ var ActorConnRaw = class {
3294
3522
  if (ws.readyState === 2 || ws.readyState === 3) {
3295
3523
  logger().debug({ msg: "ws already closed or closing" });
3296
3524
  } else {
3297
- const { promise, resolve } = Promise.withResolvers();
3525
+ const { promise, resolve } = promiseWithResolvers();
3298
3526
  ws.addEventListener("close", () => {
3299
3527
  logger().debug({ msg: "ws closed" });
3300
3528
  resolve(void 0);
@@ -3303,6 +3531,28 @@ var ActorConnRaw = class {
3303
3531
  await promise;
3304
3532
  }
3305
3533
  } else if ("sse" in this.#transport) {
3534
+ if (this.#connectionId && this.#connectionToken) {
3535
+ try {
3536
+ await sendHttpRequest({
3537
+ url: "http://actor/connections/close",
3538
+ method: "POST",
3539
+ headers: {
3540
+ [HEADER_CONN_ID]: this.#connectionId,
3541
+ [HEADER_CONN_TOKEN]: this.#connectionToken
3542
+ },
3543
+ encoding: this.#encoding,
3544
+ skipParseResponse: true,
3545
+ customFetch: this.#driver.sendRequest.bind(
3546
+ this.#driver,
3547
+ this.#actorId
3548
+ ),
3549
+ requestVersionedDataHandler: TO_SERVER_VERSIONED,
3550
+ responseVersionedDataHandler: TO_CLIENT_VERSIONED
3551
+ });
3552
+ } catch (error) {
3553
+ logger().warn({ msg: "failed to send close request", error });
3554
+ }
3555
+ }
3306
3556
  this.#transport.sse.close();
3307
3557
  } else {
3308
3558
  assertUnreachable(this.#transport);
@@ -3352,10 +3602,16 @@ async function apiCall(config, method, path, body) {
3352
3602
  namespace: config.namespace
3353
3603
  });
3354
3604
  logger2().debug({ msg: "making api call", method, url });
3605
+ const headers = {
3606
+ ...config.headers
3607
+ };
3608
+ if (config.token) {
3609
+ headers.Authorization = `Bearer ${config.token}`;
3610
+ }
3355
3611
  return await sendHttpRequest({
3356
3612
  method,
3357
3613
  url,
3358
- headers: {},
3614
+ headers,
3359
3615
  body,
3360
3616
  encoding: "json",
3361
3617
  skipParseResponse: false,
@@ -3370,18 +3626,21 @@ async function sendHttpRequestToActor(runConfig, actorId, actorRequest) {
3370
3626
  const endpoint = getEndpoint(runConfig);
3371
3627
  const guardUrl = combineUrlPath(endpoint, url.pathname + url.search);
3372
3628
  let bodyToSend = null;
3373
- const guardHeaders = buildGuardHeadersForHttp(actorRequest, actorId);
3374
- if (actorRequest.body && actorRequest.method !== "GET" && actorRequest.method !== "HEAD") {
3629
+ const guardHeaders = buildGuardHeadersForHttp(
3630
+ runConfig,
3631
+ actorRequest,
3632
+ actorId
3633
+ );
3634
+ if (actorRequest.method !== "GET" && actorRequest.method !== "HEAD") {
3375
3635
  if (actorRequest.bodyUsed) {
3376
3636
  throw new Error("Request body has already been consumed");
3377
3637
  }
3378
- const clonedRequest = actorRequest.clone();
3379
- bodyToSend = await clonedRequest.arrayBuffer();
3380
- guardHeaders.delete("transfer-encoding");
3381
- guardHeaders.set(
3382
- "content-length",
3383
- String(bodyToSend.byteLength)
3384
- );
3638
+ const reqBody = await actorRequest.arrayBuffer();
3639
+ if (reqBody.byteLength !== 0) {
3640
+ bodyToSend = reqBody;
3641
+ guardHeaders.delete("transfer-encoding");
3642
+ guardHeaders.set("content-length", String(bodyToSend.byteLength));
3643
+ }
3385
3644
  }
3386
3645
  const guardRequest = new Request(guardUrl, {
3387
3646
  method: actorRequest.method,
@@ -3394,19 +3653,24 @@ async function sendHttpRequestToActor(runConfig, actorId, actorRequest) {
3394
3653
  function mutableResponse(fetchRes) {
3395
3654
  return new Response(fetchRes.body, fetchRes);
3396
3655
  }
3397
- function buildGuardHeadersForHttp(actorRequest, actorId) {
3656
+ function buildGuardHeadersForHttp(runConfig, actorRequest, actorId) {
3398
3657
  const headers = new Headers();
3399
3658
  for (const [key, value] of actorRequest.headers.entries()) {
3400
3659
  headers.set(key, value);
3401
3660
  }
3402
- headers.set("x-rivet-target", "actor");
3403
- headers.set("x-rivet-actor", actorId);
3404
- headers.set("x-rivet-port", "main");
3661
+ for (const [key, value] of Object.entries(runConfig.headers)) {
3662
+ headers.set(key, value);
3663
+ }
3664
+ headers.set(HEADER_RIVET_TARGET, "actor");
3665
+ headers.set(HEADER_RIVET_ACTOR, actorId);
3666
+ if (runConfig.token) {
3667
+ headers.set(HEADER_RIVET_TOKEN, runConfig.token);
3668
+ }
3405
3669
  return headers;
3406
3670
  }
3407
3671
 
3408
3672
  // src/remote-manager-driver/actor-websocket-client.ts
3409
- async function openWebSocketToActor(runConfig, path, actorId, encoding, params) {
3673
+ async function openWebSocketToActor(runConfig, path, actorId, encoding, params, connId, connToken) {
3410
3674
  const WebSocket2 = await importWebSocket();
3411
3675
  const endpoint = getEndpoint(runConfig);
3412
3676
  const guardUrl = combineUrlPath(endpoint, path);
@@ -3416,49 +3680,65 @@ async function openWebSocketToActor(runConfig, path, actorId, encoding, params)
3416
3680
  path,
3417
3681
  guardUrl
3418
3682
  });
3419
- const ws = new WebSocket2(guardUrl, {
3420
- headers: buildGuardHeadersForWebSocket(actorId, encoding, params)
3421
- });
3683
+ const ws = new WebSocket2(
3684
+ guardUrl,
3685
+ buildWebSocketProtocols(
3686
+ runConfig,
3687
+ actorId,
3688
+ encoding,
3689
+ params,
3690
+ connId,
3691
+ connToken
3692
+ )
3693
+ );
3422
3694
  ws.binaryType = "arraybuffer";
3423
3695
  logger2().debug({ msg: "websocket connection opened", actorId });
3424
3696
  return ws;
3425
3697
  }
3426
- function buildGuardHeadersForWebSocket(actorId, encoding, params, authData) {
3427
- const headers = {};
3428
- headers["x-rivet-target"] = "actor";
3429
- headers["x-rivet-actor"] = actorId;
3430
- headers["x-rivet-port"] = "main";
3431
- headers[HEADER_ENCODING] = encoding;
3698
+ function buildWebSocketProtocols(runConfig, actorId, encoding, params, connId, connToken) {
3699
+ const protocols = [];
3700
+ protocols.push(WS_PROTOCOL_STANDARD);
3701
+ protocols.push(`${WS_PROTOCOL_TARGET}actor`);
3702
+ protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
3703
+ protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
3704
+ if (runConfig.token) {
3705
+ protocols.push(`${WS_PROTOCOL_TOKEN}${runConfig.token}`);
3706
+ }
3432
3707
  if (params) {
3433
- headers[HEADER_CONN_PARAMS] = JSON.stringify(params);
3708
+ protocols.push(
3709
+ `${WS_PROTOCOL_CONN_PARAMS}${encodeURIComponent(JSON.stringify(params))}`
3710
+ );
3434
3711
  }
3435
- if (authData) {
3436
- headers[HEADER_AUTH_DATA] = JSON.stringify(authData);
3712
+ if (connId) {
3713
+ protocols.push(`${WS_PROTOCOL_CONN_ID}${connId}`);
3437
3714
  }
3438
- return headers;
3715
+ if (connToken) {
3716
+ protocols.push(`${WS_PROTOCOL_CONN_TOKEN}${connToken}`);
3717
+ }
3718
+ return protocols;
3439
3719
  }
3440
3720
 
3441
3721
  // src/remote-manager-driver/api-endpoints.ts
3442
- async function getActor(config, actorId) {
3722
+ async function getActor(config, name, actorId) {
3443
3723
  return apiCall(
3444
3724
  config,
3445
3725
  "GET",
3446
- `/actors/${encodeURIComponent(actorId)}`
3726
+ `/actors?name=${name}&actor_ids=${encodeURIComponent(actorId)}`
3447
3727
  );
3448
3728
  }
3449
- async function getActorById(config, name, key) {
3729
+ async function getActorByKey(config, name, key) {
3450
3730
  const serializedKey = serializeActorKey(key);
3451
3731
  return apiCall(
3452
3732
  config,
3453
3733
  "GET",
3454
- `/actors/by-id?name=${encodeURIComponent(name)}&key=${encodeURIComponent(serializedKey)}`
3734
+ `/actors?name=${encodeURIComponent(name)}&key=${encodeURIComponent(serializedKey)}`
3455
3735
  );
3456
3736
  }
3457
- async function getOrCreateActorById(config, request) {
3737
+ async function getOrCreateActor(config, request) {
3458
3738
  return apiCall(
3459
3739
  config,
3460
3740
  "PUT",
3461
- `/actors/by-id`,
3741
+ `/actors`,
3462
3742
  request
3463
3743
  );
3464
3744
  }
@@ -3479,13 +3759,8 @@ async function destroyActor(config, actorId) {
3479
3759
  }
3480
3760
 
3481
3761
  // src/remote-manager-driver/ws-proxy.ts
3482
- async function createWebSocketProxy(c, targetUrl, headers) {
3762
+ async function createWebSocketProxy(c, targetUrl, protocols) {
3483
3763
  const WebSocket2 = await importWebSocket();
3484
- for (const [k, v] of c.req.raw.headers.entries()) {
3485
- if (!k.startsWith("sec-") && k !== "connection" && k !== "upgrade") {
3486
- headers[k] = v;
3487
- }
3488
- }
3489
3764
  const state = {};
3490
3765
  return {
3491
3766
  onOpen: async (event, clientWs) => {
@@ -3498,7 +3773,7 @@ async function createWebSocketProxy(c, targetUrl, headers) {
3498
3773
  });
3499
3774
  return;
3500
3775
  }
3501
- const targetWs = new WebSocket2(targetUrl, { headers });
3776
+ const targetWs = new WebSocket2(targetUrl, protocols);
3502
3777
  state.targetWs = targetWs;
3503
3778
  state.connectPromise = new Promise((resolve, reject) => {
3504
3779
  targetWs.addEventListener("open", () => {
@@ -3620,31 +3895,26 @@ var RemoteManagerDriver = class {
3620
3895
  name,
3621
3896
  actorId
3622
3897
  }) {
3623
- try {
3624
- const response = await getActor(this.#config, actorId);
3625
- if (response.actor.name !== name) {
3626
- logger2().debug({
3627
- msg: "actor name mismatch from api",
3628
- actorId,
3629
- apiName: response.actor.name,
3630
- requestedName: name
3631
- });
3632
- return void 0;
3633
- }
3634
- const keyRaw = response.actor.key;
3635
- invariant6(keyRaw, `actor ${actorId} should have key`);
3636
- const key = deserializeActorKey(keyRaw);
3637
- return {
3898
+ const response = await getActor(this.#config, name, actorId);
3899
+ const actor = response.actors[0];
3900
+ if (!actor) return void 0;
3901
+ if (actor.name !== name) {
3902
+ logger2().debug({
3903
+ msg: "actor name mismatch from api",
3638
3904
  actorId,
3639
- name,
3640
- key
3641
- };
3642
- } catch (error) {
3643
- if (error instanceof EngineApiError && error.group === "actor" && error.code === "not_found") {
3644
- return void 0;
3645
- }
3646
- throw error;
3905
+ apiName: actor.name,
3906
+ requestedName: name
3907
+ });
3908
+ return void 0;
3647
3909
  }
3910
+ const keyRaw = actor.key;
3911
+ invariant6(keyRaw, `actor ${actorId} should have key`);
3912
+ const key = deserializeActorKey(keyRaw);
3913
+ return {
3914
+ actorId,
3915
+ name,
3916
+ key
3917
+ };
3648
3918
  }
3649
3919
  async getWithKey({
3650
3920
  c,
@@ -3653,11 +3923,10 @@ var RemoteManagerDriver = class {
3653
3923
  }) {
3654
3924
  logger2().debug({ msg: "getWithKey: searching for actor", name, key });
3655
3925
  try {
3656
- const response = await getActorById(this.#config, name, key);
3657
- if (!response.actor_id) {
3658
- return void 0;
3659
- }
3660
- const actorId = response.actor_id;
3926
+ const response = await getActorByKey(this.#config, name, key);
3927
+ const actor = response.actors[0];
3928
+ if (!actor) return void 0;
3929
+ const actorId = actor.actor_id;
3661
3930
  logger2().debug({
3662
3931
  msg: "getWithKey: found actor via api",
3663
3932
  actorId,
@@ -3683,20 +3952,20 @@ var RemoteManagerDriver = class {
3683
3952
  name,
3684
3953
  key
3685
3954
  });
3686
- const response = await getOrCreateActorById(this.#config, {
3955
+ const { actor, created } = await getOrCreateActor(this.#config, {
3687
3956
  name,
3688
3957
  key: serializeActorKey(key),
3689
3958
  runner_name_selector: this.#config.runnerName,
3690
- input: input ? cbor6.encode(actorInput).toString("base64") : void 0,
3959
+ input: actorInput ? cbor6.encode(actorInput).toString("base64") : void 0,
3691
3960
  crash_policy: "sleep"
3692
3961
  });
3693
- const actorId = response.actor_id;
3962
+ const actorId = actor.actor_id;
3694
3963
  logger2().info({
3695
3964
  msg: "getOrCreateWithKey: actor ready",
3696
3965
  actorId,
3697
3966
  name,
3698
3967
  key,
3699
- created: response.created
3968
+ created
3700
3969
  });
3701
3970
  return {
3702
3971
  actorId,
@@ -3734,19 +4003,21 @@ var RemoteManagerDriver = class {
3734
4003
  async sendRequest(actorId, actorRequest) {
3735
4004
  return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
3736
4005
  }
3737
- async openWebSocket(path, actorId, encoding, params) {
4006
+ async openWebSocket(path, actorId, encoding, params, connId, connToken) {
3738
4007
  return await openWebSocketToActor(
3739
4008
  this.#config,
3740
4009
  path,
3741
4010
  actorId,
3742
4011
  encoding,
3743
- params
4012
+ params,
4013
+ connId,
4014
+ connToken
3744
4015
  );
3745
4016
  }
3746
4017
  async proxyRequest(_c, actorRequest, actorId) {
3747
4018
  return await sendHttpRequestToActor(this.#config, actorId, actorRequest);
3748
4019
  }
3749
- async proxyWebSocket(c, path, actorId, encoding, params, authData) {
4020
+ async proxyWebSocket(c, path, actorId, encoding, params, connId, connToken) {
3750
4021
  var _a, _b;
3751
4022
  const upgradeWebSocket = (_b = (_a = this.#config).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
3752
4023
  invariant6(upgradeWebSocket, "missing getUpgradeWebSocket");
@@ -3759,27 +4030,31 @@ var RemoteManagerDriver = class {
3759
4030
  path,
3760
4031
  guardUrl
3761
4032
  });
3762
- const headers = buildGuardHeadersForWebSocket(
4033
+ const protocols = buildWebSocketProtocols(
4034
+ this.#config,
3763
4035
  actorId,
3764
4036
  encoding,
3765
4037
  params,
3766
- authData
4038
+ connId,
4039
+ connToken
3767
4040
  );
3768
- const args = await createWebSocketProxy(c, wsGuardUrl, headers);
4041
+ const args = await createWebSocketProxy(c, wsGuardUrl, protocols);
3769
4042
  return await upgradeWebSocket(() => args)(c, noopNext());
3770
4043
  }
3771
4044
  displayInformation() {
3772
4045
  return { name: "Remote", properties: {} };
3773
4046
  }
4047
+ getOrCreateInspectorAccessToken() {
4048
+ return generateRandomString();
4049
+ }
3774
4050
  };
3775
4051
 
3776
4052
  export {
3777
4053
  generateConnId,
3778
4054
  generateConnToken,
3779
- CONNECTION_DRIVER_WEBSOCKET,
3780
- CONNECTION_DRIVER_SSE,
3781
- CONNECTION_DRIVER_HTTP,
4055
+ generateConnSocketId,
3782
4056
  createActorInspectorRouter,
4057
+ serializeActorKey,
3783
4058
  deserializeActorKey,
3784
4059
  ActorDefinition,
3785
4060
  lookupInRegistry,
@@ -3793,4 +4068,4 @@ export {
3793
4068
  createClientWithDriver,
3794
4069
  RemoteManagerDriver
3795
4070
  };
3796
- //# sourceMappingURL=chunk-4CKHQRXG.js.map
4071
+ //# sourceMappingURL=chunk-NII4KKHD.js.map