rivetkit 2.0.6 → 2.0.7-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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-MRRT2CZD.cjs → chunk-3MBP4WNC.cjs} +7 -7
  5. package/dist/tsup/{chunk-MRRT2CZD.cjs.map → chunk-3MBP4WNC.cjs.map} +1 -1
  6. package/dist/tsup/{chunk-TWGATZ3X.cjs → chunk-3Y45CIF4.cjs} +922 -872
  7. package/dist/tsup/chunk-3Y45CIF4.cjs.map +1 -0
  8. package/dist/tsup/chunk-4GP7BZSR.js +102 -0
  9. package/dist/tsup/chunk-4GP7BZSR.js.map +1 -0
  10. package/dist/tsup/{chunk-UFWAK3X2.cjs → chunk-5ZOHIKWG.cjs} +660 -385
  11. package/dist/tsup/chunk-5ZOHIKWG.cjs.map +1 -0
  12. package/dist/tsup/{chunk-5JBFVV4C.cjs → chunk-6EUWRXLT.cjs} +21 -7
  13. package/dist/tsup/chunk-6EUWRXLT.cjs.map +1 -0
  14. package/dist/tsup/{chunk-UTI5NCES.cjs → chunk-6OVKCDSH.cjs} +6 -6
  15. package/dist/tsup/{chunk-UTI5NCES.cjs.map → chunk-6OVKCDSH.cjs.map} +1 -1
  16. package/dist/tsup/{chunk-VPV4MWXR.js → chunk-7N56ZUC7.js} +3 -3
  17. package/dist/tsup/{chunk-DIAYNQTE.cjs → chunk-B3TLRM4Q.cjs} +12 -12
  18. package/dist/tsup/{chunk-DIAYNQTE.cjs.map → chunk-B3TLRM4Q.cjs.map} +1 -1
  19. package/dist/tsup/{chunk-4CKHQRXG.js → chunk-BW5DPM6Z.js} +515 -240
  20. package/dist/tsup/chunk-BW5DPM6Z.js.map +1 -0
  21. package/dist/tsup/{chunk-NTCUGYSD.cjs → chunk-DFS77KAA.cjs} +34 -31
  22. package/dist/tsup/chunk-DFS77KAA.cjs.map +1 -0
  23. package/dist/tsup/{chunk-VCEHU56K.js → chunk-E4UVJKSV.js} +2 -2
  24. package/dist/tsup/chunk-G4ABMAQY.cjs +102 -0
  25. package/dist/tsup/chunk-G4ABMAQY.cjs.map +1 -0
  26. package/dist/tsup/{chunk-ZYLTS2EM.js → chunk-GZVBFXBI.js} +2 -2
  27. package/dist/tsup/{chunk-W6LN7AF5.js → chunk-HPT3I7UU.js} +866 -816
  28. package/dist/tsup/chunk-HPT3I7UU.js.map +1 -0
  29. package/dist/tsup/{chunk-7OUKNSTU.js → chunk-JD54PXWP.js} +17 -14
  30. package/dist/tsup/chunk-JD54PXWP.js.map +1 -0
  31. package/dist/tsup/{chunk-KG3C7MKR.cjs → chunk-K4ENQCC4.cjs} +3 -3
  32. package/dist/tsup/{chunk-KG3C7MKR.cjs.map → chunk-K4ENQCC4.cjs.map} +1 -1
  33. package/dist/tsup/{chunk-WC2PSJWN.js → chunk-PUSQNDJG.js} +2 -2
  34. package/dist/tsup/{chunk-RGQR2J7S.js → chunk-RVP5RUSC.js} +20 -6
  35. package/dist/tsup/chunk-RVP5RUSC.js.map +1 -0
  36. package/dist/tsup/{chunk-TCUI5JFE.cjs → chunk-SAZCNSVY.cjs} +45 -18
  37. package/dist/tsup/chunk-SAZCNSVY.cjs.map +1 -0
  38. package/dist/tsup/{chunk-G75SVQON.js → chunk-SBKRVQS2.js} +9 -5
  39. package/dist/tsup/chunk-SBKRVQS2.js.map +1 -0
  40. package/dist/tsup/{chunk-6P6RA47N.cjs → chunk-TZGUSEIJ.cjs} +14 -10
  41. package/dist/tsup/chunk-TZGUSEIJ.cjs.map +1 -0
  42. package/dist/tsup/{chunk-2K3JMDAN.js → chunk-YQ4XQYPM.js} +40 -13
  43. package/dist/tsup/chunk-YQ4XQYPM.js.map +1 -0
  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-VPV4MWXR.js.map → chunk-7N56ZUC7.js.map} +0 -0
  168. /package/dist/tsup/{chunk-VCEHU56K.js.map → chunk-E4UVJKSV.js.map} +0 -0
  169. /package/dist/tsup/{chunk-ZYLTS2EM.js.map → chunk-GZVBFXBI.js.map} +0 -0
  170. /package/dist/tsup/{chunk-WC2PSJWN.js.map → chunk-PUSQNDJG.js.map} +0 -0
@@ -1,19 +1,23 @@
1
+ import {
2
+ configureInspectorAccessToken,
3
+ getInspectorUrl,
4
+ inspectorLogger,
5
+ isInspectorEnabled,
6
+ secureInspector
7
+ } from "./chunk-4GP7BZSR.js";
1
8
  import {
2
9
  ActorDefinition,
3
- CONNECTION_DRIVER_HTTP,
4
- CONNECTION_DRIVER_SSE,
5
- CONNECTION_DRIVER_WEBSOCKET,
6
10
  RemoteManagerDriver,
7
11
  createActorInspectorRouter,
8
12
  createClientWithDriver,
9
13
  deserializeActorKey,
10
- generateConnId,
11
- generateConnToken,
12
- lookupInRegistry
13
- } from "./chunk-4CKHQRXG.js";
14
+ generateConnSocketId,
15
+ lookupInRegistry,
16
+ serializeActorKey
17
+ } from "./chunk-BW5DPM6Z.js";
14
18
  import {
15
19
  CreateActorSchema
16
- } from "./chunk-ZYLTS2EM.js";
20
+ } from "./chunk-GZVBFXBI.js";
17
21
  import {
18
22
  ActionContext,
19
23
  HTTP_ACTION_REQUEST_VERSIONED,
@@ -24,42 +28,50 @@ import {
24
28
  createVersionedDataHandler,
25
29
  parseMessage,
26
30
  serializeEmptyPersistData
27
- } from "./chunk-7OUKNSTU.js";
31
+ } from "./chunk-JD54PXWP.js";
28
32
  import {
29
33
  EncodingSchema,
30
34
  HEADER_ACTOR_ID,
31
- HEADER_AUTH_DATA,
32
35
  HEADER_CONN_ID,
33
36
  HEADER_CONN_PARAMS,
34
37
  HEADER_CONN_TOKEN,
35
38
  HEADER_ENCODING,
39
+ HEADER_RIVET_ACTOR,
40
+ HEADER_RIVET_TARGET,
36
41
  PATH_CONNECT_WEBSOCKET,
37
42
  PATH_RAW_WEBSOCKET_PREFIX,
43
+ WS_PROTOCOL_ACTOR,
44
+ WS_PROTOCOL_CONN_ID,
45
+ WS_PROTOCOL_CONN_PARAMS,
46
+ WS_PROTOCOL_CONN_TOKEN,
47
+ WS_PROTOCOL_ENCODING,
48
+ WS_PROTOCOL_PATH,
49
+ WS_PROTOCOL_TARGET,
50
+ WS_PROTOCOL_TRANSPORT,
38
51
  contentTypeForEncoding,
39
52
  deserializeWithEncoding,
40
- encodeDataToString,
41
53
  encodingIsBinary,
42
54
  generateRandomString,
43
55
  loggerWithoutContext,
44
56
  serializeWithEncoding
45
- } from "./chunk-2K3JMDAN.js";
57
+ } from "./chunk-YQ4XQYPM.js";
46
58
  import {
47
59
  configureBaseLogger,
48
60
  configureDefaultLogger,
49
61
  getLogger
50
- } from "./chunk-WC2PSJWN.js";
62
+ } from "./chunk-PUSQNDJG.js";
51
63
  import {
52
64
  bufferToArrayBuffer,
53
65
  deconstructError,
54
66
  getEnvUniversal,
55
67
  noopNext,
56
68
  package_default,
69
+ promiseWithResolvers,
57
70
  setLongTimeout,
58
71
  stringifyError
59
- } from "./chunk-RGQR2J7S.js";
72
+ } from "./chunk-RVP5RUSC.js";
60
73
  import {
61
74
  ActorAlreadyExists,
62
- ActorNotFound,
63
75
  ConnNotFound,
64
76
  IncorrectConnToken,
65
77
  InternalError,
@@ -127,163 +139,15 @@ var ActorConfigSchema = z.object({
127
139
  }
128
140
  );
129
141
 
130
- // src/actor/generic-conn-driver.ts
131
- var GenericConnGlobalState = class {
132
- websockets = /* @__PURE__ */ new Map();
133
- sseStreams = /* @__PURE__ */ new Map();
134
- };
135
- function createGenericConnDrivers(globalState) {
136
- return {
137
- [CONNECTION_DRIVER_WEBSOCKET]: createGenericWebSocketDriver(globalState),
138
- [CONNECTION_DRIVER_SSE]: createGenericSseDriver(globalState),
139
- [CONNECTION_DRIVER_HTTP]: createGenericHttpDriver()
140
- };
141
- }
142
- function createGenericWebSocketDriver(globalState) {
143
- return {
144
- sendMessage: (actor2, conn, state, message) => {
145
- const ws = globalState.websockets.get(conn.id);
146
- if (!ws) {
147
- actor2.rLog.warn({
148
- msg: "missing ws for sendMessage",
149
- actorId: actor2.id,
150
- connId: conn.id,
151
- totalCount: globalState.websockets.size
152
- });
153
- return;
154
- }
155
- const serialized = message.serialize(state.encoding);
156
- actor2.rLog.debug({
157
- msg: "sending websocket message",
158
- encoding: state.encoding,
159
- dataType: typeof serialized,
160
- isUint8Array: serialized instanceof Uint8Array,
161
- isArrayBuffer: serialized instanceof ArrayBuffer,
162
- dataLength: serialized.byteLength || serialized.length
163
- });
164
- if (serialized instanceof Uint8Array) {
165
- const buffer = serialized.buffer.slice(
166
- serialized.byteOffset,
167
- serialized.byteOffset + serialized.byteLength
168
- );
169
- if (buffer instanceof SharedArrayBuffer) {
170
- const arrayBuffer = new ArrayBuffer(buffer.byteLength);
171
- new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
172
- actor2.rLog.debug({
173
- msg: "converted SharedArrayBuffer to ArrayBuffer",
174
- byteLength: arrayBuffer.byteLength
175
- });
176
- ws.send(arrayBuffer);
177
- } else {
178
- actor2.rLog.debug({
179
- msg: "sending ArrayBuffer",
180
- byteLength: buffer.byteLength
181
- });
182
- ws.send(buffer);
183
- }
184
- } else {
185
- actor2.rLog.debug({
186
- msg: "sending string data",
187
- length: serialized.length
188
- });
189
- ws.send(serialized);
190
- }
191
- },
192
- disconnect: async (actor2, conn, _state, reason) => {
193
- const ws = globalState.websockets.get(conn.id);
194
- if (!ws) {
195
- actor2.rLog.warn({
196
- msg: "missing ws for disconnect",
197
- actorId: actor2.id,
198
- connId: conn.id,
199
- totalCount: globalState.websockets.size
200
- });
201
- return;
202
- }
203
- const raw = ws.raw;
204
- if (!raw) {
205
- actor2.rLog.warn({ msg: "ws.raw does not exist" });
206
- return;
207
- }
208
- const { promise, resolve } = Promise.withResolvers();
209
- raw.addEventListener("close", () => resolve());
210
- ws.close(1e3, reason);
211
- await promise;
212
- },
213
- getConnectionReadyState: (actor2, conn) => {
214
- const ws = globalState.websockets.get(conn.id);
215
- if (!ws) {
216
- actor2.rLog.warn({
217
- msg: "missing ws for getConnectionReadyState",
218
- connId: conn.id
219
- });
220
- return void 0;
221
- }
222
- const raw = ws.raw;
223
- return raw.readyState;
224
- }
225
- };
226
- }
227
- function createGenericSseDriver(globalState) {
228
- return {
229
- sendMessage: (actor2, conn, state, message) => {
230
- const stream = globalState.sseStreams.get(conn.id);
231
- if (!stream) {
232
- actor2.rLog.warn({
233
- msg: "missing sse stream for sendMessage",
234
- connId: conn.id
235
- });
236
- return;
237
- }
238
- stream.writeSSE({
239
- data: encodeDataToString(message.serialize(state.encoding))
240
- });
241
- },
242
- disconnect: async (actor2, conn, _state, _reason) => {
243
- const stream = globalState.sseStreams.get(conn.id);
244
- if (!stream) {
245
- actor2.rLog.warn({
246
- msg: "missing sse stream for disconnect",
247
- connId: conn.id
248
- });
249
- return;
250
- }
251
- stream.close();
252
- },
253
- getConnectionReadyState: (actor2, conn) => {
254
- const stream = globalState.sseStreams.get(conn.id);
255
- if (!stream) {
256
- actor2.rLog.warn({
257
- msg: "missing sse stream for getConnectionReadyState",
258
- connId: conn.id
259
- });
260
- return void 0;
261
- }
262
- if (stream.aborted || stream.closed) {
263
- return 3 /* CLOSED */;
264
- }
265
- return 1 /* OPEN */;
266
- }
267
- };
268
- }
269
- function createGenericHttpDriver() {
270
- return {
271
- getConnectionReadyState(_actor, _conn) {
272
- return 1 /* OPEN */;
273
- },
274
- disconnect: async () => {
275
- }
276
- };
277
- }
278
-
279
142
  // src/actor/router.ts
280
143
  import { Hono } from "hono";
281
144
  import { cors } from "hono/cors";
282
- import invariant from "invariant";
145
+ import invariant2 from "invariant";
283
146
 
284
147
  // src/actor/router-endpoints.ts
285
148
  import * as cbor from "cbor-x";
286
149
  import { streamSSE } from "hono/streaming";
150
+ import invariant from "invariant";
287
151
 
288
152
  // src/manager/log.ts
289
153
  function logger() {
@@ -568,13 +432,14 @@ var HonoWebSocketAdapter = class {
568
432
  };
569
433
 
570
434
  // src/actor/router-endpoints.ts
571
- async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, encoding, parameters, authData) {
435
+ var SSE_PING_INTERVAL = 1e3;
436
+ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, encoding, parameters, connId, connToken) {
572
437
  const exposeInternalError = req ? getRequestExposeInternalError(req) : false;
573
438
  const {
574
439
  promise: handlersPromise,
575
440
  resolve: handlersResolve,
576
441
  reject: handlersReject
577
- } = Promise.withResolvers();
442
+ } = promiseWithResolvers();
578
443
  let actor2;
579
444
  try {
580
445
  actor2 = await actorDriver.loadActor(actorId);
@@ -600,31 +465,36 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
600
465
  }
601
466
  };
602
467
  }
468
+ const closePromise = promiseWithResolvers();
469
+ const socketId = generateConnSocketId();
603
470
  return {
604
471
  onOpen: (_evt, ws) => {
605
- actor2.rLog.debug("websocket open");
472
+ actor2.rLog.debug("actor websocket open");
606
473
  (async () => {
607
474
  try {
608
- const connId = generateConnId();
609
- const connToken = generateConnToken();
610
- const connState = await actor2.prepareConn(parameters, req);
611
- const connGlobalState = actorDriver.getGenericConnGlobalState(actorId);
612
- connGlobalState.websockets.set(connId, ws);
475
+ let conn;
613
476
  actor2.rLog.debug({
614
- msg: "registered websocket for conn",
615
- actorId,
616
- totalCount: connGlobalState.websockets.size
617
- });
618
- const conn = await actor2.createConn(
477
+ msg: connId ? "websocket reconnection attempt" : "new websocket connection",
619
478
  connId,
620
- connToken,
479
+ actorId
480
+ });
481
+ conn = await actor2.createConn(
482
+ {
483
+ socketId,
484
+ driverState: {
485
+ [0 /* WEBSOCKET */]: {
486
+ encoding,
487
+ websocket: ws,
488
+ closePromise
489
+ }
490
+ }
491
+ },
621
492
  parameters,
622
- connState,
623
- CONNECTION_DRIVER_WEBSOCKET,
624
- { encoding },
625
- authData
493
+ req,
494
+ connId,
495
+ connToken
626
496
  );
627
- handlersResolve({ conn, actor: actor2, connId });
497
+ handlersResolve({ conn, actor: actor2, connId: conn.id });
628
498
  } catch (error) {
629
499
  handlersReject(error);
630
500
  const { code } = deconstructError(
@@ -682,6 +552,8 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
682
552
  });
683
553
  },
684
554
  onClose: (event, ws) => {
555
+ handlersReject(`WebSocket closed (${event.code}): ${event.reason}`);
556
+ closePromise.resolve();
685
557
  if (event.wasClean) {
686
558
  actor2.rLog.info({
687
559
  msg: "websocket closed",
@@ -698,22 +570,8 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
698
570
  });
699
571
  }
700
572
  ws.close(1e3, "hack_force_close");
701
- handlersPromise.then(({ conn, actor: actor3, connId }) => {
702
- const connGlobalState = actorDriver.getGenericConnGlobalState(actorId);
703
- const didDelete = connGlobalState.websockets.delete(connId);
704
- if (didDelete) {
705
- actor3.rLog.info({
706
- msg: "removing websocket for conn",
707
- totalCount: connGlobalState.websockets.size
708
- });
709
- } else {
710
- actor3.rLog.warn({
711
- msg: "websocket does not exist for conn",
712
- actorId,
713
- totalCount: connGlobalState.websockets.size
714
- });
715
- }
716
- actor3.__removeConn(conn);
573
+ handlersPromise.then(({ conn, actor: actor3 }) => {
574
+ actor3.__connDisconnected(conn, event.wasClean, socketId);
717
575
  }).catch((error) => {
718
576
  deconstructError(
719
577
  error,
@@ -737,43 +595,47 @@ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, enco
737
595
  }
738
596
  };
739
597
  }
740
- async function handleSseConnect(c, _runConfig, actorDriver, actorId, authData) {
598
+ async function handleSseConnect(c, _runConfig, actorDriver, actorId) {
599
+ c.header("Content-Encoding", "Identity");
741
600
  const encoding = getRequestEncoding(c.req);
742
601
  const parameters = getRequestConnParams(c.req);
602
+ const socketId = generateConnSocketId();
603
+ const connId = c.req.header(HEADER_CONN_ID);
604
+ const connToken = c.req.header(HEADER_CONN_TOKEN);
743
605
  return streamSSE(c, async (stream) => {
744
606
  let actor2;
745
- let connId;
746
- let connToken;
747
- let connState;
748
607
  let conn;
749
608
  try {
750
609
  actor2 = await actorDriver.loadActor(actorId);
751
- connId = generateConnId();
752
- connToken = generateConnToken();
753
- connState = await actor2.prepareConn(parameters, c.req.raw);
754
- actor2.rLog.debug("sse open");
755
- actorDriver.getGenericConnGlobalState(actorId).sseStreams.set(connId, stream);
610
+ actor2.rLog.debug({
611
+ msg: connId ? "sse reconnection attempt" : "sse open",
612
+ connId
613
+ });
756
614
  conn = await actor2.createConn(
757
- connId,
758
- connToken,
615
+ {
616
+ socketId,
617
+ driverState: {
618
+ [1 /* SSE */]: {
619
+ encoding,
620
+ stream
621
+ }
622
+ }
623
+ },
759
624
  parameters,
760
- connState,
761
- CONNECTION_DRIVER_SSE,
762
- { encoding },
763
- authData
625
+ c.req.raw,
626
+ connId,
627
+ connToken
764
628
  );
765
- const abortResolver = Promise.withResolvers();
629
+ const abortResolver = promiseWithResolvers();
766
630
  stream.onAbort(() => {
767
631
  });
768
632
  c.req.raw.signal.addEventListener("abort", async () => {
769
- const rLog = (actor2 == null ? void 0 : actor2.rLog) ?? loggerWithoutContext();
633
+ invariant(actor2, "actor should exist");
634
+ const rLog = actor2.rLog ?? loggerWithoutContext();
770
635
  try {
771
636
  rLog.debug("sse stream aborted");
772
- if (connId) {
773
- actorDriver.getGenericConnGlobalState(actorId).sseStreams.delete(connId);
774
- }
775
- if (conn && actor2) {
776
- actor2.__removeConn(conn);
637
+ if (conn) {
638
+ actor2.__connDisconnected(conn, false, socketId);
777
639
  }
778
640
  abortResolver.resolve(void 0);
779
641
  } catch (error) {
@@ -781,24 +643,28 @@ async function handleSseConnect(c, _runConfig, actorDriver, actorId, authData) {
781
643
  abortResolver.resolve(void 0);
782
644
  }
783
645
  });
784
- try {
785
- c.executionCtx.waitUntil(abortResolver.promise);
786
- } catch {
646
+ while (true) {
647
+ if (stream.closed || stream.aborted) {
648
+ actor2 == null ? void 0 : actor2.rLog.debug({
649
+ msg: "sse stream closed",
650
+ closed: stream.closed,
651
+ aborted: stream.aborted
652
+ });
653
+ break;
654
+ }
655
+ await stream.writeSSE({ event: "ping", data: "" });
656
+ await stream.sleep(SSE_PING_INTERVAL);
787
657
  }
788
- await abortResolver.promise;
789
658
  } catch (error) {
790
659
  loggerWithoutContext().error({ msg: "error in sse connection", error });
791
- if (connId !== void 0) {
792
- actorDriver.getGenericConnGlobalState(actorId).sseStreams.delete(connId);
793
- }
794
660
  if (conn && actor2 !== void 0) {
795
- actor2.__removeConn(conn);
661
+ actor2.__connDisconnected(conn, false, socketId);
796
662
  }
797
663
  stream.close();
798
664
  }
799
665
  });
800
666
  }
801
- async function handleAction(c, _runConfig, actorDriver, actionName, actorId, authData) {
667
+ async function handleAction(c, _runConfig, actorDriver, actionName, actorId) {
802
668
  const encoding = getRequestEncoding(c.req);
803
669
  const parameters = getRequestConnParams(c.req);
804
670
  const arrayBuffer = await c.req.arrayBuffer();
@@ -808,27 +674,26 @@ async function handleAction(c, _runConfig, actorDriver, actionName, actorId, aut
808
674
  HTTP_ACTION_REQUEST_VERSIONED
809
675
  );
810
676
  const actionArgs = cbor.decode(new Uint8Array(request.args));
677
+ const socketId = generateConnSocketId();
811
678
  let actor2;
812
679
  let conn;
813
680
  let output;
814
681
  try {
815
682
  actor2 = await actorDriver.loadActor(actorId);
816
683
  actor2.rLog.debug({ msg: "handling action", actionName, encoding });
817
- const connState = await actor2.prepareConn(parameters, c.req.raw);
818
684
  conn = await actor2.createConn(
819
- generateConnId(),
820
- generateConnToken(),
685
+ {
686
+ socketId,
687
+ driverState: { [2 /* HTTP */]: {} }
688
+ },
821
689
  parameters,
822
- connState,
823
- CONNECTION_DRIVER_HTTP,
824
- {},
825
- authData
690
+ c.req.raw
826
691
  );
827
692
  const ctx = new ActionContext(actor2.actorContext, conn);
828
693
  output = await actor2.executeAction(ctx, actionName, actionArgs);
829
694
  } finally {
830
695
  if (conn) {
831
- actor2 == null ? void 0 : actor2.__removeConn(conn);
696
+ actor2 == null ? void 0 : actor2.__connDisconnected(conn, true, socketId);
832
697
  }
833
698
  }
834
699
  const responseData = {
@@ -862,7 +727,25 @@ async function handleConnectionMessage(c, _runConfig, actorDriver, connId, connT
862
727
  await actor2.processMessage(message, conn);
863
728
  return c.json({});
864
729
  }
865
- async function handleRawWebSocketHandler(req, path3, actorDriver, actorId, authData) {
730
+ async function handleConnectionClose(c, _runConfig, actorDriver, connId, connToken, actorId) {
731
+ var _a;
732
+ const actor2 = await actorDriver.loadActor(actorId);
733
+ const conn = actor2.conns.get(connId);
734
+ if (!conn) {
735
+ throw new ConnNotFound(connId);
736
+ }
737
+ if (conn._token !== connToken) {
738
+ throw new IncorrectConnToken();
739
+ }
740
+ if (!((_a = conn.__socket) == null ? void 0 : _a.driverState) || !(1 /* SSE */ in conn.__socket.driverState)) {
741
+ throw new UserError(
742
+ "Connection close is only supported for SSE connections"
743
+ );
744
+ }
745
+ await conn.disconnect("Connection closed by client request");
746
+ return c.json({});
747
+ }
748
+ async function handleRawWebSocketHandler(req, path3, actorDriver, actorId) {
866
749
  const actor2 = await actorDriver.loadActor(actorId);
867
750
  return {
868
751
  onOpen: (_evt, ws) => {
@@ -997,70 +880,6 @@ function handleRouteError(error, c) {
997
880
  return c.body(output, { status: statusCode });
998
881
  }
999
882
 
1000
- // src/inspector/utils.ts
1001
- import crypto2 from "crypto";
1002
- import { createMiddleware } from "hono/factory";
1003
-
1004
- // src/inspector/log.ts
1005
- function inspectorLogger() {
1006
- return getLogger("inspector");
1007
- }
1008
-
1009
- // src/inspector/utils.ts
1010
- function compareSecrets(providedSecret, validSecret) {
1011
- if (providedSecret.length !== validSecret.length) {
1012
- return false;
1013
- }
1014
- const encoder = new TextEncoder();
1015
- const a = encoder.encode(providedSecret);
1016
- const b = encoder.encode(validSecret);
1017
- if (a.byteLength !== b.byteLength) {
1018
- return false;
1019
- }
1020
- if (!crypto2.timingSafeEqual(a, b)) {
1021
- return false;
1022
- }
1023
- return true;
1024
- }
1025
- var secureInspector = (runConfig) => createMiddleware(async (c, next) => {
1026
- var _a, _b, _c;
1027
- if (!runConfig.inspector.enabled) {
1028
- return c.text("Inspector is not enabled", 503);
1029
- }
1030
- const userToken = (_a = c.req.header("Authorization")) == null ? void 0 : _a.replace("Bearer ", "");
1031
- if (!userToken) {
1032
- return c.text("Unauthorized", 401);
1033
- }
1034
- const inspectorToken = (_c = (_b = runConfig.inspector).token) == null ? void 0 : _c.call(_b);
1035
- if (!inspectorToken) {
1036
- return c.text("Unauthorized", 401);
1037
- }
1038
- const isValid = compareSecrets(userToken, inspectorToken);
1039
- if (!isValid) {
1040
- return c.text("Unauthorized", 401);
1041
- }
1042
- await next();
1043
- });
1044
- function getInspectorUrl(runConfig) {
1045
- var _a, _b, _c, _d;
1046
- if (!((_a = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _a.enabled)) {
1047
- return "disabled";
1048
- }
1049
- const accessToken = (_c = (_b = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _b.token) == null ? void 0 : _c.call(_b);
1050
- if (!accessToken) {
1051
- inspectorLogger().warn(
1052
- "Inspector Token is not set, but Inspector is enabled. Please set it in the run configuration `inspector.token` or via `RIVETKIT_INSPECTOR_TOKEN` environment variable. Inspector will not be accessible."
1053
- );
1054
- return "disabled";
1055
- }
1056
- const url = new URL("https://inspect.rivet.dev");
1057
- url.searchParams.set("t", accessToken);
1058
- if ((_d = runConfig == null ? void 0 : runConfig.inspector) == null ? void 0 : _d.defaultEndpoint) {
1059
- url.searchParams.set("u", runConfig.inspector.defaultEndpoint);
1060
- }
1061
- return url.href;
1062
- }
1063
-
1064
883
  // src/actor/router.ts
1065
884
  function createActorRouter(runConfig, actorDriver) {
1066
885
  const router = new Hono({ strict: false });
@@ -1073,17 +892,54 @@ function createActorRouter(runConfig, actorDriver) {
1073
892
  router.get("/health", (c) => {
1074
893
  return c.text("ok");
1075
894
  });
895
+ router.post("/.test/force-disconnect", async (c) => {
896
+ const connId = c.req.query("conn");
897
+ if (!connId) {
898
+ return c.text("Missing conn query parameter", 400);
899
+ }
900
+ const actor2 = await actorDriver.loadActor(c.env.actorId);
901
+ const conn = actor2.__getConnForId(connId);
902
+ if (!conn) {
903
+ return c.text(`Connection not found: ${connId}`, 404);
904
+ }
905
+ const driverState = conn.__driverState;
906
+ if (driverState && 0 /* WEBSOCKET */ in driverState) {
907
+ const ws = driverState[0 /* WEBSOCKET */].websocket;
908
+ ws.raw.terminate();
909
+ } else if (driverState && 1 /* SSE */ in driverState) {
910
+ const stream = driverState[1 /* SSE */].stream;
911
+ stream.abort();
912
+ }
913
+ return c.json({ success: true });
914
+ });
1076
915
  router.get(PATH_CONNECT_WEBSOCKET, async (c) => {
1077
916
  var _a;
1078
917
  const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
1079
918
  if (upgradeWebSocket) {
1080
919
  return upgradeWebSocket(async (c2) => {
1081
- const encodingRaw = c2.req.header(HEADER_ENCODING);
1082
- const connParamsRaw = c2.req.header(HEADER_CONN_PARAMS);
1083
- const authDataRaw = c2.req.header(HEADER_AUTH_DATA);
920
+ const protocols = c2.req.header("sec-websocket-protocol");
921
+ let encodingRaw;
922
+ let connParamsRaw;
923
+ let connIdRaw;
924
+ let connTokenRaw;
925
+ if (protocols) {
926
+ const protocolList = protocols.split(",").map((p) => p.trim());
927
+ for (const protocol of protocolList) {
928
+ if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
929
+ encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
930
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
931
+ connParamsRaw = decodeURIComponent(
932
+ protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
933
+ );
934
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
935
+ connIdRaw = protocol.substring(WS_PROTOCOL_CONN_ID.length);
936
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
937
+ connTokenRaw = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
938
+ }
939
+ }
940
+ }
1084
941
  const encoding = EncodingSchema.parse(encodingRaw);
1085
942
  const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1086
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1087
943
  return await handleWebSocketConnect(
1088
944
  c2.req.raw,
1089
945
  runConfig,
@@ -1091,7 +947,8 @@ function createActorRouter(runConfig, actorDriver) {
1091
947
  c2.env.actorId,
1092
948
  encoding,
1093
949
  connParams,
1094
- authData
950
+ connIdRaw,
951
+ connTokenRaw
1095
952
  );
1096
953
  })(c, noopNext());
1097
954
  } else {
@@ -1102,36 +959,34 @@ function createActorRouter(runConfig, actorDriver) {
1102
959
  }
1103
960
  });
1104
961
  router.get("/connect/sse", async (c) => {
1105
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
1106
- let authData;
1107
- if (authDataRaw) {
1108
- authData = JSON.parse(authDataRaw);
1109
- }
1110
- return handleSseConnect(c, runConfig, actorDriver, c.env.actorId, authData);
962
+ return handleSseConnect(c, runConfig, actorDriver, c.env.actorId);
1111
963
  });
1112
964
  router.post("/action/:action", async (c) => {
1113
965
  const actionName = c.req.param("action");
1114
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
1115
- let authData;
1116
- if (authDataRaw) {
1117
- authData = JSON.parse(authDataRaw);
966
+ return handleAction(c, runConfig, actorDriver, actionName, c.env.actorId);
967
+ });
968
+ router.post("/connections/message", async (c) => {
969
+ const connId = c.req.header(HEADER_CONN_ID);
970
+ const connToken = c.req.header(HEADER_CONN_TOKEN);
971
+ if (!connId || !connToken) {
972
+ throw new Error("Missing required parameters");
1118
973
  }
1119
- return handleAction(
974
+ return handleConnectionMessage(
1120
975
  c,
1121
976
  runConfig,
1122
977
  actorDriver,
1123
- actionName,
1124
- c.env.actorId,
1125
- authData
978
+ connId,
979
+ connToken,
980
+ c.env.actorId
1126
981
  );
1127
982
  });
1128
- router.post("/connections/message", async (c) => {
983
+ router.post("/connections/close", async (c) => {
1129
984
  const connId = c.req.header(HEADER_CONN_ID);
1130
985
  const connToken = c.req.header(HEADER_CONN_TOKEN);
1131
986
  if (!connId || !connToken) {
1132
987
  throw new Error("Missing required parameters");
1133
988
  }
1134
- return handleConnectionMessage(
989
+ return handleConnectionClose(
1135
990
  c,
1136
991
  runConfig,
1137
992
  actorDriver,
@@ -1141,11 +996,6 @@ function createActorRouter(runConfig, actorDriver) {
1141
996
  );
1142
997
  });
1143
998
  router.all("/raw/http/*", async (c) => {
1144
- const authDataRaw = c.req.header(HEADER_AUTH_DATA);
1145
- let authData;
1146
- if (authDataRaw) {
1147
- authData = JSON.parse(authDataRaw);
1148
- }
1149
999
  const actor2 = await actorDriver.loadActor(c.env.actorId);
1150
1000
  const url = new URL(c.req.url);
1151
1001
  const originalPath = url.pathname.replace(/^\/raw\/http/, "") || "/";
@@ -1161,9 +1011,7 @@ function createActorRouter(runConfig, actorDriver) {
1161
1011
  from: c.req.url,
1162
1012
  to: correctedRequest.url
1163
1013
  });
1164
- const response = await actor2.handleFetch(correctedRequest, {
1165
- auth: authData
1166
- });
1014
+ const response = await actor2.handleFetch(correctedRequest, {});
1167
1015
  if (!response) {
1168
1016
  throw new InternalError("handleFetch returned void unexpectedly");
1169
1017
  }
@@ -1174,12 +1022,6 @@ function createActorRouter(runConfig, actorDriver) {
1174
1022
  const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
1175
1023
  if (upgradeWebSocket) {
1176
1024
  return upgradeWebSocket(async (c2) => {
1177
- const encodingRaw = c2.req.header(HEADER_ENCODING);
1178
- const connParamsRaw = c2.req.header(HEADER_CONN_PARAMS);
1179
- const authDataRaw = c2.req.header(HEADER_AUTH_DATA);
1180
- const encoding = EncodingSchema.parse(encodingRaw);
1181
- const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1182
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1183
1025
  const url = new URL(c2.req.url);
1184
1026
  const pathWithQuery = c2.req.path + url.search;
1185
1027
  loggerWithoutContext().debug({
@@ -1193,8 +1035,7 @@ function createActorRouter(runConfig, actorDriver) {
1193
1035
  c2.req.raw,
1194
1036
  pathWithQuery,
1195
1037
  actorDriver,
1196
- c2.env.actorId,
1197
- authData
1038
+ c2.env.actorId
1198
1039
  );
1199
1040
  })(c, noopNext());
1200
1041
  } else {
@@ -1204,7 +1045,7 @@ function createActorRouter(runConfig, actorDriver) {
1204
1045
  );
1205
1046
  }
1206
1047
  });
1207
- if (runConfig.inspector.enabled) {
1048
+ if (isInspectorEnabled(runConfig, "actor")) {
1208
1049
  router.route(
1209
1050
  "/inspect",
1210
1051
  new Hono().use(
@@ -1212,7 +1053,7 @@ function createActorRouter(runConfig, actorDriver) {
1212
1053
  secureInspector(runConfig),
1213
1054
  async (c, next) => {
1214
1055
  const inspector = (await actorDriver.loadActor(c.env.actorId)).inspector;
1215
- invariant(inspector, "inspector not supported on this platform");
1056
+ invariant2(inspector, "inspector not supported on this platform");
1216
1057
  c.set("inspector", inspector);
1217
1058
  return next();
1218
1059
  }
@@ -1570,8 +1411,9 @@ var InlineWebSocketAdapter2 = class {
1570
1411
  // src/drivers/engine/actor-driver.ts
1571
1412
  import { Runner } from "@rivetkit/engine-runner";
1572
1413
  import * as cbor3 from "cbor-x";
1414
+ import { streamSSE as streamSSE2 } from "hono/streaming";
1573
1415
  import { WSContext as WSContext2 } from "hono/ws";
1574
- import invariant2 from "invariant";
1416
+ import invariant3 from "invariant";
1575
1417
 
1576
1418
  // src/drivers/engine/kv.ts
1577
1419
  var KEYS = {
@@ -1595,6 +1437,8 @@ var EngineActorDriver = class {
1595
1437
  #actorRouter;
1596
1438
  #version = 1;
1597
1439
  // Version for the runner protocol
1440
+ #runnerStarted = Promise.withResolvers();
1441
+ #runnerStopped = Promise.withResolvers();
1598
1442
  constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
1599
1443
  this.#registryConfig = registryConfig;
1600
1444
  this.#runConfig = runConfig;
@@ -1606,6 +1450,7 @@ var EngineActorDriver = class {
1606
1450
  const runnerConfig = {
1607
1451
  version: this.#version,
1608
1452
  endpoint: config2.endpoint,
1453
+ token: config2.token,
1609
1454
  pegboardEndpoint: config2.pegboardEndpoint,
1610
1455
  namespace: config2.namespace,
1611
1456
  totalSlots: config2.totalSlots,
@@ -1634,6 +1479,7 @@ var EngineActorDriver = class {
1634
1479
  runnerName: this.#config.runnerName
1635
1480
  });
1636
1481
  }
1482
+ this.#runnerStarted.resolve(void 0);
1637
1483
  },
1638
1484
  onDisconnected: () => {
1639
1485
  logger4().warn({
@@ -1644,6 +1490,7 @@ var EngineActorDriver = class {
1644
1490
  hasDisconnected = true;
1645
1491
  },
1646
1492
  onShutdown: () => {
1493
+ this.#runnerStopped.resolve(void 0);
1647
1494
  },
1648
1495
  fetch: this.#runnerFetch.bind(this),
1649
1496
  websocket: this.#runnerWebSocket.bind(this),
@@ -1672,13 +1519,6 @@ var EngineActorDriver = class {
1672
1519
  if (!handler.actor) throw new Error(`Actor ${actorId} failed to load`);
1673
1520
  return handler.actor;
1674
1521
  }
1675
- getGenericConnGlobalState(actorId) {
1676
- const handler = this.#actors.get(actorId);
1677
- if (!handler) {
1678
- throw new Error(`Actor ${actorId} not loaded`);
1679
- }
1680
- return handler.genericConnGlobalState;
1681
- }
1682
1522
  getContext(actorId) {
1683
1523
  return {};
1684
1524
  }
@@ -1722,14 +1562,13 @@ var EngineActorDriver = class {
1722
1562
  let handler = this.#actors.get(actorId);
1723
1563
  if (!handler) {
1724
1564
  handler = {
1725
- genericConnGlobalState: new GenericConnGlobalState(),
1726
- actorStartPromise: Promise.withResolvers(),
1565
+ actorStartPromise: promiseWithResolvers(),
1727
1566
  persistedData: serializeEmptyPersistData(input)
1728
1567
  };
1729
1568
  this.#actors.set(actorId, handler);
1730
1569
  }
1731
1570
  const name = config2.name;
1732
- invariant2(config2.key, "actor should have a key");
1571
+ invariant3(config2.key, "actor should have a key");
1733
1572
  const key = deserializeActorKey(config2.key);
1734
1573
  const definition = lookupInRegistry(
1735
1574
  this.#registryConfig,
@@ -1737,11 +1576,7 @@ var EngineActorDriver = class {
1737
1576
  // TODO: Remove cast
1738
1577
  );
1739
1578
  handler.actor = definition.instantiate();
1740
- const connDrivers = createGenericConnDrivers(
1741
- handler.genericConnGlobalState
1742
- );
1743
1579
  await handler.actor.start(
1744
- connDrivers,
1745
1580
  this,
1746
1581
  this.#inlineClient,
1747
1582
  actorId,
@@ -1776,12 +1611,25 @@ var EngineActorDriver = class {
1776
1611
  const websocket = websocketRaw;
1777
1612
  logger4().debug({ msg: "runner websocket", actorId, url: request.url });
1778
1613
  const url = new URL(request.url);
1779
- const encodingRaw = request.headers.get(HEADER_ENCODING);
1780
- const connParamsRaw = request.headers.get(HEADER_CONN_PARAMS);
1781
- const authDataRaw = request.headers.get(HEADER_AUTH_DATA);
1614
+ const protocols = request.headers.get("sec-websocket-protocol");
1615
+ if (protocols === null)
1616
+ throw new Error(`Missing sec-websocket-protocol header`);
1617
+ let encodingRaw;
1618
+ let connParamsRaw;
1619
+ if (protocols) {
1620
+ const protocolList = protocols.split(",").map((p) => p.trim());
1621
+ for (const protocol of protocolList) {
1622
+ if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
1623
+ encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
1624
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
1625
+ connParamsRaw = decodeURIComponent(
1626
+ protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
1627
+ );
1628
+ }
1629
+ }
1630
+ }
1782
1631
  const encoding = EncodingSchema.parse(encodingRaw);
1783
1632
  const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1784
- const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1785
1633
  let wsHandlerPromise;
1786
1634
  if (url.pathname === PATH_CONNECT_WEBSOCKET) {
1787
1635
  wsHandlerPromise = handleWebSocketConnect(
@@ -1791,15 +1639,16 @@ var EngineActorDriver = class {
1791
1639
  actorId,
1792
1640
  encoding,
1793
1641
  connParams,
1794
- authData
1642
+ // Extract connId and connToken from protocols if needed
1643
+ void 0,
1644
+ void 0
1795
1645
  );
1796
1646
  } else if (url.pathname.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
1797
1647
  wsHandlerPromise = handleRawWebSocketHandler(
1798
1648
  request,
1799
1649
  url.pathname + url.search,
1800
1650
  this,
1801
- actorId,
1802
- authData
1651
+ actorId
1803
1652
  );
1804
1653
  } else {
1805
1654
  throw new Error(`Unreachable path: ${url.pathname}`);
@@ -1848,6 +1697,15 @@ var EngineActorDriver = class {
1848
1697
  logger4().info({ msg: "stopping engine actor driver" });
1849
1698
  await this.#runner.shutdown(immediate);
1850
1699
  }
1700
+ async serverlessHandleStart(c) {
1701
+ await this.#runnerStarted.promise;
1702
+ return streamSSE2(c, async (stream) => {
1703
+ const runnerId = this.#runner.runnerId;
1704
+ invariant3(runnerId, "runnerId not set");
1705
+ stream.writeSSE({ data: runnerId });
1706
+ return this.#runnerStopped.promise;
1707
+ });
1708
+ }
1851
1709
  };
1852
1710
 
1853
1711
  // src/drivers/engine/config.ts
@@ -1857,6 +1715,7 @@ var ConfigSchema = z2.object({
1857
1715
  endpoint: z2.string().default(
1858
1716
  () => getEnvUniversal("RIVET_ENGINE") ?? "http://localhost:6420"
1859
1717
  ),
1718
+ token: z2.string().optional().transform((val) => val ?? getEnvUniversal("RIVET_TOKEN")),
1860
1719
  pegboardEndpoint: z2.string().optional(),
1861
1720
  namespace: z2.string().default(() => getEnvUniversal("RIVET_NAMESPACE") ?? "default"),
1862
1721
  runnerName: z2.string().default(() => getEnvUniversal("RIVET_RUNNER") ?? "rivetkit"),
@@ -1910,9 +1769,6 @@ var FileSystemActorDriver = class {
1910
1769
  actorId
1911
1770
  );
1912
1771
  }
1913
- getGenericConnGlobalState(actorId) {
1914
- return this.#state.getActorOrError(actorId).genericConnGlobalState;
1915
- }
1916
1772
  /**
1917
1773
  * Get the current storage directory path
1918
1774
  */
@@ -1946,11 +1802,11 @@ var FileSystemActorDriver = class {
1946
1802
  };
1947
1803
 
1948
1804
  // src/drivers/file-system/global-state.ts
1949
- import * as crypto4 from "crypto";
1805
+ import * as crypto3 from "crypto";
1950
1806
  import * as fsSync2 from "fs";
1951
1807
  import * as fs2 from "fs/promises";
1952
1808
  import * as path2 from "path";
1953
- import invariant3 from "invariant";
1809
+ import invariant4 from "invariant";
1954
1810
 
1955
1811
  // dist/schemas/file-system-driver/v1.ts
1956
1812
  import * as bare from "@bare-ts/lib";
@@ -2053,20 +1909,20 @@ function logger5() {
2053
1909
  }
2054
1910
 
2055
1911
  // src/drivers/file-system/utils.ts
2056
- import * as crypto3 from "crypto";
1912
+ import * as crypto2 from "crypto";
2057
1913
  import * as fsSync from "fs";
2058
1914
  import * as fs from "fs/promises";
2059
1915
  import * as os from "os";
2060
1916
  import * as path from "path";
2061
1917
  function generateActorId(name, key) {
2062
1918
  const jsonString = JSON.stringify([name, key]);
2063
- const hash = crypto3.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
1919
+ const hash = crypto2.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
2064
1920
  return hash;
2065
1921
  }
2066
1922
  function createHashForPath(dirPath) {
2067
1923
  const normalizedPath = path.normalize(dirPath);
2068
1924
  const lastComponent = path.basename(normalizedPath);
2069
- const hash = crypto3.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
1925
+ const hash = crypto2.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
2070
1926
  return `${lastComponent}-${hash}`;
2071
1927
  }
2072
1928
  function getStoragePath(customPath) {
@@ -2201,7 +2057,6 @@ var FileSystemGlobalState = class {
2201
2057
  }
2202
2058
  entry = {
2203
2059
  id: actorId,
2204
- genericConnGlobalState: new GenericConnGlobalState(),
2205
2060
  removed: false
2206
2061
  };
2207
2062
  this.#actors.set(actorId, entry);
@@ -2276,16 +2131,16 @@ var FileSystemGlobalState = class {
2276
2131
  }
2277
2132
  async sleepActor(actorId) {
2278
2133
  var _a;
2279
- invariant3(
2134
+ invariant4(
2280
2135
  this.#persist,
2281
2136
  "cannot sleep actor with memory driver, must use file system driver"
2282
2137
  );
2283
2138
  const actor2 = this.#actors.get(actorId);
2284
- invariant3(actor2, `tried to sleep ${actorId}, does not exist`);
2139
+ invariant4(actor2, `tried to sleep ${actorId}, does not exist`);
2285
2140
  if (actor2.loadPromise) await actor2.loadPromise.catch();
2286
2141
  if ((_a = actor2.startPromise) == null ? void 0 : _a.promise) await actor2.startPromise.promise.catch();
2287
2142
  actor2.removed = true;
2288
- invariant3(actor2.actor, "actor should be loaded");
2143
+ invariant4(actor2.actor, "actor should be loaded");
2289
2144
  await actor2.actor._stop();
2290
2145
  this.#actors.delete(actorId);
2291
2146
  }
@@ -2297,15 +2152,15 @@ var FileSystemGlobalState = class {
2297
2152
  return;
2298
2153
  }
2299
2154
  const entry = this.#actors.get(actorId);
2300
- invariant3(entry, "actor entry does not exist");
2155
+ invariant4(entry, "actor entry does not exist");
2301
2156
  await this.#performWrite(actorId, state);
2302
2157
  }
2303
2158
  async setActorAlarm(actorId, timestamp) {
2304
2159
  const entry = this.#actors.get(actorId);
2305
- invariant3(entry, "actor entry does not exist");
2160
+ invariant4(entry, "actor entry does not exist");
2306
2161
  if (this.#persist) {
2307
2162
  const alarmPath = this.getActorAlarmPath(actorId);
2308
- const tempPath = `${alarmPath}.tmp.${crypto4.randomUUID()}`;
2163
+ const tempPath = `${alarmPath}.tmp.${crypto3.randomUUID()}`;
2309
2164
  try {
2310
2165
  await ensureDirectoryExists(path2.dirname(alarmPath));
2311
2166
  const alarmData = {
@@ -2331,7 +2186,7 @@ var FileSystemGlobalState = class {
2331
2186
  */
2332
2187
  async #performWrite(actorId, state) {
2333
2188
  const dataPath = this.getActorStatePath(actorId);
2334
- const tempPath = `${dataPath}.tmp.${crypto4.randomUUID()}`;
2189
+ const tempPath = `${dataPath}.tmp.${crypto3.randomUUID()}`;
2335
2190
  try {
2336
2191
  await ensureDirectoryExists(path2.dirname(dataPath));
2337
2192
  const bareState = {
@@ -2386,21 +2241,17 @@ var FileSystemGlobalState = class {
2386
2241
  }
2387
2242
  if (entry.startPromise) {
2388
2243
  await entry.startPromise.promise;
2389
- invariant3(entry.actor, "actor should have loaded");
2244
+ invariant4(entry.actor, "actor should have loaded");
2390
2245
  return entry.actor;
2391
2246
  }
2392
2247
  if (entry.actor) {
2393
2248
  return entry.actor;
2394
2249
  }
2395
- entry.startPromise = Promise.withResolvers();
2250
+ entry.startPromise = promiseWithResolvers();
2396
2251
  try {
2397
2252
  const definition = lookupInRegistry(registryConfig, entry.state.name);
2398
2253
  entry.actor = definition.instantiate();
2399
- const connDrivers = createGenericConnDrivers(
2400
- entry.genericConnGlobalState
2401
- );
2402
2254
  await entry.actor.start(
2403
- connDrivers,
2404
2255
  actorDriver,
2405
2256
  inlineClient,
2406
2257
  actorId,
@@ -2505,7 +2356,7 @@ var FileSystemGlobalState = class {
2505
2356
  const loaded = await this.loadActor(actorId);
2506
2357
  if (!loaded.state) throw new Error(`Actor does not exist: ${actorId}`);
2507
2358
  const runnerParams = this.#runnerParams;
2508
- invariant3(runnerParams, "missing runner params");
2359
+ invariant4(runnerParams, "missing runner params");
2509
2360
  if (!loaded.actor) {
2510
2361
  await this.startActor(
2511
2362
  runnerParams.registryConfig,
@@ -2515,7 +2366,7 @@ var FileSystemGlobalState = class {
2515
2366
  actorId
2516
2367
  );
2517
2368
  }
2518
- invariant3(loaded.actor, "actor should be loaded after wake");
2369
+ invariant4(loaded.actor, "actor should be loaded after wake");
2519
2370
  await loaded.actor._onAlarm();
2520
2371
  } catch (err) {
2521
2372
  logger5().error({
@@ -2572,7 +2423,7 @@ var FileSystemGlobalState = class {
2572
2423
  };
2573
2424
 
2574
2425
  // src/drivers/file-system/manager.ts
2575
- import invariant4 from "invariant";
2426
+ import invariant5 from "invariant";
2576
2427
 
2577
2428
  // src/inspector/manager.ts
2578
2429
  import { sValidator } from "@hono/standard-validator";
@@ -2658,9 +2509,6 @@ var FileSystemManagerDriver = class {
2658
2509
  };
2659
2510
  };
2660
2511
  var transformActor = transformActor2;
2661
- if (!this.#runConfig.inspector.token()) {
2662
- this.#runConfig.inspector.token = () => this.#state.getOrCreateInspectorAccessToken();
2663
- }
2664
2512
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2665
2513
  this.inspector = new ManagerInspector(() => {
2666
2514
  return {
@@ -2714,7 +2562,7 @@ var FileSystemManagerDriver = class {
2714
2562
  actorId
2715
2563
  });
2716
2564
  }
2717
- async openWebSocket(path3, actorId, encoding, params) {
2565
+ async openWebSocket(path3, actorId, encoding, params, connId, connToken) {
2718
2566
  const pathOnly = path3.split("?")[0];
2719
2567
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2720
2568
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
@@ -2725,7 +2573,8 @@ var FileSystemManagerDriver = class {
2725
2573
  actorId,
2726
2574
  encoding,
2727
2575
  params,
2728
- void 0
2576
+ connId,
2577
+ connToken
2729
2578
  );
2730
2579
  return new InlineWebSocketAdapter2(wsHandler);
2731
2580
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
@@ -2733,8 +2582,7 @@ var FileSystemManagerDriver = class {
2733
2582
  void 0,
2734
2583
  path3,
2735
2584
  this.#actorDriver,
2736
- actorId,
2737
- void 0
2585
+ actorId
2738
2586
  );
2739
2587
  return new InlineWebSocketAdapter2(wsHandler);
2740
2588
  } else {
@@ -2746,10 +2594,10 @@ var FileSystemManagerDriver = class {
2746
2594
  actorId
2747
2595
  });
2748
2596
  }
2749
- async proxyWebSocket(c, path3, actorId, encoding, connParams) {
2597
+ async proxyWebSocket(c, path3, actorId, encoding, connParams, connId, connToken) {
2750
2598
  var _a, _b;
2751
2599
  const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
2752
- invariant4(upgradeWebSocket, "missing getUpgradeWebSocket");
2600
+ invariant5(upgradeWebSocket, "missing getUpgradeWebSocket");
2753
2601
  const pathOnly = path3.split("?")[0];
2754
2602
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2755
2603
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
@@ -2760,7 +2608,8 @@ var FileSystemManagerDriver = class {
2760
2608
  actorId,
2761
2609
  encoding,
2762
2610
  connParams,
2763
- void 0
2611
+ connId,
2612
+ connToken
2764
2613
  );
2765
2614
  return upgradeWebSocket(() => wsHandler)(c, noopNext());
2766
2615
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
@@ -2768,8 +2617,7 @@ var FileSystemManagerDriver = class {
2768
2617
  c.req.raw,
2769
2618
  path3,
2770
2619
  this.#actorDriver,
2771
- actorId,
2772
- void 0
2620
+ actorId
2773
2621
  );
2774
2622
  return upgradeWebSocket(() => wsHandler)(c, noopNext());
2775
2623
  } else {
@@ -2815,7 +2663,7 @@ var FileSystemManagerDriver = class {
2815
2663
  input.key,
2816
2664
  input.input
2817
2665
  );
2818
- invariant4(actorEntry.state, "must have state");
2666
+ invariant5(actorEntry.state, "must have state");
2819
2667
  return {
2820
2668
  actorId: actorEntry.state.actorId,
2821
2669
  name: actorEntry.state.name,
@@ -2846,6 +2694,9 @@ var FileSystemManagerDriver = class {
2846
2694
  data: this.#state.storagePath
2847
2695
  };
2848
2696
  }
2697
+ getOrCreateInspectorAccessToken() {
2698
+ return this.#state.getOrCreateInspectorAccessToken();
2699
+ }
2849
2700
  };
2850
2701
 
2851
2702
  // src/drivers/file-system/mod.ts
@@ -2882,8 +2733,7 @@ function createMemoryDriver() {
2882
2733
 
2883
2734
  // src/drivers/default.ts
2884
2735
  function chooseDefaultDriver(runConfig) {
2885
- const engineEndpoint = runConfig.endpoint ?? getEnvUniversal("RIVET_ENGINE");
2886
- if (engineEndpoint && runConfig.driver) {
2736
+ if (runConfig.endpoint && runConfig.driver) {
2887
2737
  throw new UserError(
2888
2738
  "Cannot specify both 'engine' and 'driver' in configuration"
2889
2739
  );
@@ -2891,12 +2741,15 @@ function chooseDefaultDriver(runConfig) {
2891
2741
  if (runConfig.driver) {
2892
2742
  return runConfig.driver;
2893
2743
  }
2894
- if (engineEndpoint) {
2744
+ if (runConfig.endpoint) {
2895
2745
  loggerWithoutContext().debug({
2896
2746
  msg: "using rivet engine driver",
2897
- endpoint: engineEndpoint
2747
+ endpoint: runConfig.endpoint
2748
+ });
2749
+ return createEngineDriver({
2750
+ endpoint: runConfig.endpoint,
2751
+ token: runConfig.token
2898
2752
  });
2899
- return createEngineDriver({ endpoint: engineEndpoint });
2900
2753
  }
2901
2754
  loggerWithoutContext().debug({ msg: "using default file system driver" });
2902
2755
  return createFileSystemOrMemoryDriver(true);
@@ -2905,32 +2758,37 @@ function chooseDefaultDriver(runConfig) {
2905
2758
  // src/manager/router.ts
2906
2759
  import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2907
2760
  import * as cbor4 from "cbor-x";
2908
- import { Hono as Hono3 } from "hono";
2761
+ import {
2762
+ Hono as Hono3
2763
+ } from "hono";
2909
2764
  import { cors as corsMiddleware } from "hono/cors";
2910
- import { createMiddleware as createMiddleware2 } from "hono/factory";
2911
- import invariant5 from "invariant";
2912
- import { z as z8 } from "zod";
2765
+ import { createMiddleware } from "hono/factory";
2766
+ import invariant6 from "invariant";
2767
+ import { z as z5 } from "zod";
2913
2768
 
2914
- // src/manager-api/routes/actors-create.ts
2769
+ // src/manager-api/actors.ts
2915
2770
  import { z as z4 } from "zod";
2916
2771
 
2917
- // src/manager-api/routes/common.ts
2772
+ // src/manager-api/common.ts
2918
2773
  import { z as z3 } from "zod";
2919
2774
  var RivetIdSchema = z3.string();
2920
- var ActorSchema = z3.object({
2775
+
2776
+ // src/manager-api/actors.ts
2777
+ var ActorSchema = z4.object({
2921
2778
  actor_id: RivetIdSchema,
2922
- name: z3.string(),
2923
- key: z3.string(),
2779
+ name: z4.string(),
2780
+ key: z4.string(),
2924
2781
  namespace_id: RivetIdSchema,
2925
- runner_name_selector: z3.string(),
2926
- create_ts: z3.number(),
2927
- connectable_ts: z3.number().nullable().optional(),
2928
- destroy_ts: z3.number().nullable().optional(),
2929
- sleep_ts: z3.number().nullable().optional(),
2930
- start_ts: z3.number().nullable().optional()
2782
+ runner_name_selector: z4.string(),
2783
+ create_ts: z4.number(),
2784
+ connectable_ts: z4.number().nullable().optional(),
2785
+ destroy_ts: z4.number().nullable().optional(),
2786
+ sleep_ts: z4.number().nullable().optional(),
2787
+ start_ts: z4.number().nullable().optional()
2788
+ });
2789
+ var ActorsListResponseSchema = z4.object({
2790
+ actors: z4.array(ActorSchema)
2931
2791
  });
2932
-
2933
- // src/manager-api/routes/actors-create.ts
2934
2792
  var ActorsCreateRequestSchema = z4.object({
2935
2793
  name: z4.string(),
2936
2794
  runner_name_selector: z4.string(),
@@ -2941,169 +2799,426 @@ var ActorsCreateRequestSchema = z4.object({
2941
2799
  var ActorsCreateResponseSchema = z4.object({
2942
2800
  actor: ActorSchema
2943
2801
  });
2944
-
2945
- // src/manager-api/routes/actors-get.ts
2946
- import { z as z5 } from "zod";
2947
- var ActorsGetResponseSchema = z5.object({
2948
- actor: ActorSchema
2949
- });
2950
-
2951
- // src/manager-api/routes/actors-get-by-id.ts
2952
- import { z as z6 } from "zod";
2953
- var ActorsGetByIdResponseSchema = z6.object({
2954
- actor_id: RivetIdSchema.nullable().optional()
2802
+ var ActorsGetOrCreateRequestSchema = z4.object({
2803
+ name: z4.string(),
2804
+ key: z4.string(),
2805
+ runner_name_selector: z4.string(),
2806
+ crash_policy: z4.string(),
2807
+ input: z4.string().nullable().optional()
2955
2808
  });
2956
-
2957
- // src/manager-api/routes/actors-get-or-create-by-id.ts
2958
- import { z as z7 } from "zod";
2959
- var ActorsGetOrCreateResponseSchema = z7.object({
2809
+ var ActorsGetOrCreateResponseSchema = z4.object({
2960
2810
  actor: ActorSchema,
2961
- created: z7.boolean()
2962
- });
2963
- var ActorsGetOrCreateByIdResponseSchema = z7.object({
2964
- actor_id: RivetIdSchema,
2965
- created: z7.boolean()
2966
- });
2967
- var ActorsGetOrCreateByIdRequestSchema = z7.object({
2968
- name: z7.string(),
2969
- key: z7.string(),
2970
- runner_name_selector: z7.string(),
2971
- crash_policy: z7.string(),
2972
- input: z7.string().nullable().optional()
2811
+ created: z4.boolean()
2973
2812
  });
2813
+ var ActorsDeleteResponseSchema = z4.object({});
2974
2814
 
2975
- // src/manager/router.ts
2976
- function buildOpenApiResponses(schema, validateBody) {
2977
- return {
2978
- 200: {
2979
- description: "Success",
2980
- content: validateBody ? {
2981
- "application/json": {
2982
- schema
2983
- }
2984
- } : {}
2985
- },
2986
- 400: {
2987
- description: "User error"
2988
- },
2989
- 500: {
2990
- description: "Internal error"
2991
- }
2992
- };
2815
+ // src/manager/gateway.ts
2816
+ async function actorGateway(runConfig, managerDriver, c, next) {
2817
+ if (c.req.path.startsWith("/.test/")) {
2818
+ return next();
2819
+ }
2820
+ if (c.req.header("upgrade") === "websocket") {
2821
+ return await handleWebSocketGateway(runConfig, managerDriver, c);
2822
+ }
2823
+ return await handleHttpGateway(managerDriver, c, next);
2993
2824
  }
2994
- function createManagerRouter(registryConfig, runConfig, managerDriver, validateBody) {
2995
- var _a, _b;
2996
- const router = new OpenAPIHono({ strict: false }).basePath(
2997
- runConfig.basePath
2998
- );
2999
- router.use("*", loggerMiddleware(logger()));
3000
- const cors2 = runConfig.cors ? corsMiddleware(runConfig.cors) : createMiddleware2((_c, next) => next());
3001
- router.use("*", cors2, async (c, next) => {
3002
- var _a2;
3003
- const target = c.req.header("x-rivet-target");
3004
- const actorId = c.req.header("x-rivet-actor");
3005
- if (target === "actor") {
3006
- if (!actorId) {
3007
- throw new MissingActorHeader();
3008
- }
3009
- logger().debug({
3010
- msg: "proxying request to actor",
3011
- actorId,
3012
- path: c.req.path,
3013
- method: c.req.method
3014
- });
3015
- if (c.req.header("upgrade") === "websocket") {
3016
- const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
3017
- if (!upgradeWebSocket) {
3018
- throw new WebSocketsNotEnabled();
3019
- }
3020
- const encoding = c.req.header("X-RivetKit-Encoding") || c.req.header("x-rivet-encoding") || "json";
3021
- const connParams = c.req.header("X-RivetKit-Conn-Params") || c.req.header("x-rivet-conn-params");
3022
- const authData = c.req.header("X-RivetKit-Auth-Data") || c.req.header("x-rivet-auth-data");
3023
- const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
3024
- return await managerDriver.proxyWebSocket(
3025
- c,
3026
- pathWithQuery,
3027
- actorId,
3028
- encoding,
3029
- // Will be validated by driver
3030
- connParams ? JSON.parse(connParams) : void 0,
3031
- authData ? JSON.parse(authData) : void 0
2825
+ async function handleWebSocketGateway(runConfig, managerDriver, c) {
2826
+ var _a;
2827
+ const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
2828
+ if (!upgradeWebSocket) {
2829
+ throw new WebSocketsNotEnabled();
2830
+ }
2831
+ const protocols = c.req.header("sec-websocket-protocol");
2832
+ let target;
2833
+ let actorId;
2834
+ let encodingRaw;
2835
+ let connParamsRaw;
2836
+ let connIdRaw;
2837
+ let connTokenRaw;
2838
+ if (protocols) {
2839
+ const protocolList = protocols.split(",").map((p) => p.trim());
2840
+ for (const protocol of protocolList) {
2841
+ if (protocol.startsWith(WS_PROTOCOL_TARGET)) {
2842
+ target = protocol.substring(WS_PROTOCOL_TARGET.length);
2843
+ } else if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
2844
+ actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
2845
+ } else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
2846
+ encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
2847
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
2848
+ connParamsRaw = decodeURIComponent(
2849
+ protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
3032
2850
  );
2851
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
2852
+ connIdRaw = protocol.substring(WS_PROTOCOL_CONN_ID.length);
2853
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
2854
+ connTokenRaw = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
3033
2855
  }
3034
- const proxyHeaders = new Headers(c.req.raw.headers);
3035
- proxyHeaders.delete("x-rivet-target");
3036
- proxyHeaders.delete("x-rivet-actor");
3037
- const url = new URL(c.req.url);
3038
- const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
3039
- const proxyRequest = new Request(proxyUrl, {
3040
- method: c.req.raw.method,
3041
- headers: proxyHeaders,
3042
- body: c.req.raw.body,
3043
- signal: c.req.raw.signal
3044
- });
3045
- return await managerDriver.proxyRequest(c, proxyRequest, actorId);
3046
2856
  }
2857
+ }
2858
+ if (target !== "actor") {
2859
+ return c.text("WebSocket upgrade requires target.actor protocol", 400);
2860
+ }
2861
+ if (!actorId) {
2862
+ throw new MissingActorHeader();
2863
+ }
2864
+ logger().debug({
2865
+ msg: "proxying websocket to actor",
2866
+ actorId,
2867
+ path: c.req.path,
2868
+ encoding: encodingRaw
2869
+ });
2870
+ const encoding = encodingRaw || "json";
2871
+ const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
2872
+ const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
2873
+ return await managerDriver.proxyWebSocket(
2874
+ c,
2875
+ pathWithQuery,
2876
+ actorId,
2877
+ encoding,
2878
+ // Will be validated by driver
2879
+ connParams,
2880
+ connIdRaw,
2881
+ connTokenRaw
2882
+ );
2883
+ }
2884
+ async function handleHttpGateway(managerDriver, c, next) {
2885
+ const target = c.req.header(HEADER_RIVET_TARGET);
2886
+ const actorId = c.req.header(HEADER_RIVET_ACTOR);
2887
+ if (target !== "actor") {
3047
2888
  return next();
2889
+ }
2890
+ if (!actorId) {
2891
+ throw new MissingActorHeader();
2892
+ }
2893
+ logger().debug({
2894
+ msg: "proxying request to actor",
2895
+ actorId,
2896
+ path: c.req.path,
2897
+ method: c.req.method
3048
2898
  });
3049
- router.get("/", cors2, (c) => {
3050
- return c.text(
3051
- "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3052
- );
2899
+ const proxyHeaders = new Headers(c.req.raw.headers);
2900
+ proxyHeaders.delete(HEADER_RIVET_TARGET);
2901
+ proxyHeaders.delete(HEADER_RIVET_ACTOR);
2902
+ const url = new URL(c.req.url);
2903
+ const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
2904
+ const proxyRequest = new Request(proxyUrl, {
2905
+ method: c.req.raw.method,
2906
+ headers: proxyHeaders,
2907
+ body: c.req.raw.body,
2908
+ signal: c.req.raw.signal
3053
2909
  });
3054
- {
3055
- const route = createRoute({
2910
+ return await managerDriver.proxyRequest(c, proxyRequest, actorId);
2911
+ }
2912
+ async function createTestWebSocketProxy(clientWsPromise) {
2913
+ let clientWs = null;
2914
+ const {
2915
+ promise: serverWsPromise,
2916
+ resolve: serverWsResolve,
2917
+ reject: serverWsReject
2918
+ } = promiseWithResolvers();
2919
+ try {
2920
+ logger().debug({ msg: "awaiting client websocket promise" });
2921
+ const ws = await clientWsPromise;
2922
+ clientWs = ws;
2923
+ logger().debug({
2924
+ msg: "client websocket promise resolved",
2925
+ constructor: ws == null ? void 0 : ws.constructor.name
2926
+ });
2927
+ await new Promise((resolve, reject) => {
2928
+ const onOpen = () => {
2929
+ logger().debug({ msg: "test websocket connection to actor opened" });
2930
+ resolve();
2931
+ };
2932
+ const onError = (error) => {
2933
+ logger().error({ msg: "test websocket connection failed", error });
2934
+ reject(
2935
+ new Error(`Failed to open WebSocket: ${error.message || error}`)
2936
+ );
2937
+ serverWsReject();
2938
+ };
2939
+ ws.addEventListener("open", onOpen);
2940
+ ws.addEventListener("error", onError);
2941
+ ws.addEventListener("message", async (clientEvt) => {
2942
+ var _a, _b;
2943
+ const serverWs = await serverWsPromise;
2944
+ logger().debug({
2945
+ msg: `test websocket connection message from client`,
2946
+ dataType: typeof clientEvt.data,
2947
+ isBlob: clientEvt.data instanceof Blob,
2948
+ isArrayBuffer: clientEvt.data instanceof ArrayBuffer,
2949
+ dataConstructor: (_b = (_a = clientEvt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
2950
+ dataStr: typeof clientEvt.data === "string" ? clientEvt.data.substring(0, 100) : void 0
2951
+ });
2952
+ if (serverWs.readyState === 1) {
2953
+ if (clientEvt.data instanceof Blob) {
2954
+ clientEvt.data.arrayBuffer().then((buffer) => {
2955
+ logger().debug({
2956
+ msg: "converted client blob to arraybuffer, sending to server",
2957
+ bufferSize: buffer.byteLength
2958
+ });
2959
+ serverWs.send(buffer);
2960
+ }).catch((error) => {
2961
+ logger().error({
2962
+ msg: "failed to convert blob to arraybuffer",
2963
+ error
2964
+ });
2965
+ });
2966
+ } else {
2967
+ logger().debug({
2968
+ msg: "sending client data directly to server",
2969
+ dataType: typeof clientEvt.data,
2970
+ dataLength: typeof clientEvt.data === "string" ? clientEvt.data.length : void 0
2971
+ });
2972
+ serverWs.send(clientEvt.data);
2973
+ }
2974
+ }
2975
+ });
2976
+ ws.addEventListener("close", async (clientEvt) => {
2977
+ const serverWs = await serverWsPromise;
2978
+ logger().debug({
2979
+ msg: `test websocket connection closed`
2980
+ });
2981
+ if (serverWs.readyState !== 3) {
2982
+ serverWs.close(clientEvt.code, clientEvt.reason);
2983
+ }
2984
+ });
2985
+ ws.addEventListener("error", async () => {
2986
+ const serverWs = await serverWsPromise;
2987
+ logger().debug({
2988
+ msg: `test websocket connection error`
2989
+ });
2990
+ if (serverWs.readyState !== 3) {
2991
+ serverWs.close(1011, "Error in client websocket");
2992
+ }
2993
+ });
2994
+ });
2995
+ } catch (error) {
2996
+ logger().error({
2997
+ msg: `failed to establish client websocket connection`,
2998
+ error
2999
+ });
3000
+ return {
3001
+ onOpen: (_evt, serverWs) => {
3002
+ serverWs.close(1011, "Failed to establish connection");
3003
+ },
3004
+ onMessage: () => {
3005
+ },
3006
+ onError: () => {
3007
+ },
3008
+ onClose: () => {
3009
+ }
3010
+ };
3011
+ }
3012
+ return {
3013
+ onOpen: (_evt, serverWs) => {
3014
+ logger().debug({
3015
+ msg: `test websocket connection from client opened`
3016
+ });
3017
+ logger().debug({
3018
+ msg: "clientWs info",
3019
+ constructor: clientWs.constructor.name,
3020
+ hasAddEventListener: typeof clientWs.addEventListener === "function",
3021
+ readyState: clientWs.readyState
3022
+ });
3023
+ serverWsResolve(serverWs);
3024
+ },
3025
+ onMessage: (evt) => {
3026
+ var _a, _b;
3027
+ logger().debug({
3028
+ msg: "received message from server",
3029
+ dataType: typeof evt.data,
3030
+ isBlob: evt.data instanceof Blob,
3031
+ isArrayBuffer: evt.data instanceof ArrayBuffer,
3032
+ dataConstructor: (_b = (_a = evt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
3033
+ dataStr: typeof evt.data === "string" ? evt.data.substring(0, 100) : void 0
3034
+ });
3035
+ if (clientWs.readyState === 1) {
3036
+ if (evt.data instanceof Blob) {
3037
+ evt.data.arrayBuffer().then((buffer) => {
3038
+ logger().debug({
3039
+ msg: "converted blob to arraybuffer, sending",
3040
+ bufferSize: buffer.byteLength
3041
+ });
3042
+ clientWs.send(buffer);
3043
+ }).catch((error) => {
3044
+ logger().error({
3045
+ msg: "failed to convert blob to arraybuffer",
3046
+ error
3047
+ });
3048
+ });
3049
+ } else {
3050
+ logger().debug({
3051
+ msg: "sending data directly",
3052
+ dataType: typeof evt.data,
3053
+ dataLength: typeof evt.data === "string" ? evt.data.length : void 0
3054
+ });
3055
+ clientWs.send(evt.data);
3056
+ }
3057
+ }
3058
+ },
3059
+ onClose: (event, serverWs) => {
3060
+ logger().debug({
3061
+ msg: `server websocket closed`,
3062
+ wasClean: event.wasClean,
3063
+ code: event.code,
3064
+ reason: event.reason
3065
+ });
3066
+ serverWs.close(1e3, "hack_force_close");
3067
+ if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3068
+ clientWs.close(1e3, event.reason);
3069
+ }
3070
+ },
3071
+ onError: (error) => {
3072
+ logger().error({
3073
+ msg: `error in server websocket`,
3074
+ error
3075
+ });
3076
+ if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3077
+ clientWs.close(1011, "Error in server websocket");
3078
+ }
3079
+ serverWsReject();
3080
+ }
3081
+ };
3082
+ }
3083
+
3084
+ // src/manager/router.ts
3085
+ function buildOpenApiResponses(schema) {
3086
+ return {
3087
+ 200: {
3088
+ description: "Success",
3089
+ content: {
3090
+ "application/json": {
3091
+ schema
3092
+ }
3093
+ }
3094
+ },
3095
+ 400: {
3096
+ description: "User error"
3097
+ },
3098
+ 500: {
3099
+ description: "Internal error"
3100
+ }
3101
+ };
3102
+ }
3103
+ function createManagerRouter(registryConfig, runConfig, managerDriver, serverlessActorDriverBuilder) {
3104
+ const router = new OpenAPIHono({ strict: false }).basePath(
3105
+ runConfig.basePath
3106
+ );
3107
+ router.use("*", loggerMiddleware(logger()));
3108
+ const cors2 = runConfig.cors ? corsMiddleware(runConfig.cors) : createMiddleware((_c, next) => next());
3109
+ if (serverlessActorDriverBuilder) {
3110
+ addServerlessRoutes(serverlessActorDriverBuilder, router, cors2);
3111
+ } else {
3112
+ addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2);
3113
+ }
3114
+ router.notFound(handleRouteNotFound);
3115
+ router.onError(handleRouteError);
3116
+ return { router, openapi: router, cors: cors2 };
3117
+ }
3118
+ function addServerlessRoutes(serverlessActorDriverBuilder, router, cors2) {
3119
+ router.get("/", cors2, (c) => {
3120
+ return c.text(
3121
+ "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3122
+ );
3123
+ });
3124
+ router.get("/start", cors2, async (c) => {
3125
+ const actorDriver = serverlessActorDriverBuilder();
3126
+ invariant6(
3127
+ actorDriver.serverlessHandleStart,
3128
+ "missing serverlessHandleStart on ActorDriver"
3129
+ );
3130
+ return await actorDriver.serverlessHandleStart(c);
3131
+ });
3132
+ router.get("/health", cors2, (c) => {
3133
+ return c.text("ok");
3134
+ });
3135
+ }
3136
+ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2) {
3137
+ var _a;
3138
+ router.use("*", cors2, actorGateway.bind(void 0, runConfig, managerDriver));
3139
+ router.get("/", cors2, (c) => {
3140
+ return c.text(
3141
+ "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3142
+ );
3143
+ });
3144
+ {
3145
+ const route = createRoute({
3056
3146
  middleware: [cors2],
3057
3147
  method: "get",
3058
- path: "/actors/by-id",
3148
+ path: "/actors",
3059
3149
  request: {
3060
- query: z8.object({
3061
- name: z8.string(),
3062
- key: z8.string()
3150
+ query: z5.object({
3151
+ name: z5.string(),
3152
+ actor_ids: z5.string().optional(),
3153
+ key: z5.string().optional()
3063
3154
  })
3064
3155
  },
3065
- responses: buildOpenApiResponses(
3066
- ActorsGetByIdResponseSchema,
3067
- validateBody
3068
- )
3156
+ responses: buildOpenApiResponses(ActorsListResponseSchema)
3069
3157
  });
3070
3158
  router.openapi(route, async (c) => {
3071
- const { name, key } = c.req.valid("query");
3072
- const actorOutput = await managerDriver.getWithKey({
3073
- c,
3074
- name,
3075
- key: [key]
3076
- // Convert string to ActorKey array
3077
- });
3159
+ const { name, actor_ids, key } = c.req.valid("query");
3160
+ const actorIdsParsed = actor_ids ? actor_ids.split(",").map((id) => id.trim()).filter((id) => id.length > 0) : void 0;
3161
+ const actors = [];
3162
+ if (actorIdsParsed) {
3163
+ if (actorIdsParsed.length > 32) {
3164
+ return c.json(
3165
+ {
3166
+ error: `Too many actor IDs. Maximum is 32, got ${actorIdsParsed.length}.`
3167
+ },
3168
+ 400
3169
+ );
3170
+ }
3171
+ if (actorIdsParsed.length === 0) {
3172
+ return c.json({
3173
+ actors: []
3174
+ });
3175
+ }
3176
+ for (const actorId of actorIdsParsed) {
3177
+ if (name) {
3178
+ const actorOutput = await managerDriver.getForId({
3179
+ c,
3180
+ name,
3181
+ actorId
3182
+ });
3183
+ if (actorOutput) {
3184
+ actors.push(actorOutput);
3185
+ }
3186
+ }
3187
+ }
3188
+ } else if (key) {
3189
+ const actorOutput = await managerDriver.getWithKey({
3190
+ c,
3191
+ name,
3192
+ key: [key]
3193
+ // Convert string to ActorKey array
3194
+ });
3195
+ if (actorOutput) {
3196
+ actors.push(actorOutput);
3197
+ }
3198
+ }
3078
3199
  return c.json({
3079
- actor_id: (actorOutput == null ? void 0 : actorOutput.actorId) || null
3200
+ actors: actors.map(createApiActor)
3080
3201
  });
3081
3202
  });
3082
3203
  }
3083
3204
  {
3084
3205
  const route = createRoute({
3085
- cors: [cors2],
3206
+ middleware: [cors2],
3086
3207
  method: "put",
3087
- path: "/actors/by-id",
3208
+ path: "/actors",
3088
3209
  request: {
3089
3210
  body: {
3090
- content: validateBody ? {
3211
+ content: {
3091
3212
  "application/json": {
3092
- schema: ActorsGetOrCreateByIdRequestSchema
3213
+ schema: ActorsGetOrCreateRequestSchema
3093
3214
  }
3094
- } : {}
3215
+ }
3095
3216
  }
3096
3217
  },
3097
- responses: buildOpenApiResponses(
3098
- ActorsGetOrCreateByIdResponseSchema,
3099
- validateBody
3100
- )
3218
+ responses: buildOpenApiResponses(ActorsGetOrCreateResponseSchema)
3101
3219
  });
3102
3220
  router.openapi(route, async (c) => {
3103
- const body = validateBody ? await c.req.json() : await c.req.json();
3104
- if (validateBody) {
3105
- ActorsGetOrCreateByIdRequestSchema.parse(body);
3106
- }
3221
+ const body = c.req.valid("json");
3107
3222
  const existingActor = await managerDriver.getWithKey({
3108
3223
  c,
3109
3224
  name: body.name,
@@ -3112,7 +3227,7 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3112
3227
  });
3113
3228
  if (existingActor) {
3114
3229
  return c.json({
3115
- actor_id: existingActor.actorId,
3230
+ actor: createApiActor(existingActor),
3116
3231
  created: false
3117
3232
  });
3118
3233
  }
@@ -3126,52 +3241,11 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3126
3241
  // Not provided in the request schema
3127
3242
  });
3128
3243
  return c.json({
3129
- actor_id: newActor.actorId,
3244
+ actor: createApiActor(newActor),
3130
3245
  created: true
3131
3246
  });
3132
3247
  });
3133
3248
  }
3134
- {
3135
- const route = createRoute({
3136
- middleware: [cors2],
3137
- method: "get",
3138
- path: "/actors/{actor_id}",
3139
- request: {
3140
- params: z8.object({
3141
- actor_id: RivetIdSchema
3142
- })
3143
- },
3144
- responses: buildOpenApiResponses(ActorsGetResponseSchema, validateBody)
3145
- });
3146
- router.openapi(route, async (c) => {
3147
- const { actor_id } = c.req.valid("param");
3148
- const actorOutput = await managerDriver.getForId({
3149
- c,
3150
- name: "",
3151
- // TODO: The API doesn't provide the name, this may need to be resolved
3152
- actorId: actor_id
3153
- });
3154
- if (!actorOutput) {
3155
- throw new ActorNotFound(actor_id);
3156
- }
3157
- const actor2 = {
3158
- actor_id: actorOutput.actorId,
3159
- name: actorOutput.name,
3160
- key: actorOutput.key,
3161
- namespace_id: "default",
3162
- // Assert default namespace
3163
- runner_name_selector: "rivetkit",
3164
- // Assert rivetkit runner
3165
- create_ts: Date.now(),
3166
- // Not available from driver
3167
- connectable_ts: null,
3168
- destroy_ts: null,
3169
- sleep_ts: null,
3170
- start_ts: null
3171
- };
3172
- return c.json({ actor: actor2 });
3173
- });
3174
- }
3175
3249
  {
3176
3250
  const route = createRoute({
3177
3251
  middleware: [cors2],
@@ -3179,23 +3253,17 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3179
3253
  path: "/actors",
3180
3254
  request: {
3181
3255
  body: {
3182
- content: validateBody ? {
3256
+ content: {
3183
3257
  "application/json": {
3184
3258
  schema: ActorsCreateRequestSchema
3185
3259
  }
3186
- } : {}
3260
+ }
3187
3261
  }
3188
3262
  },
3189
- responses: buildOpenApiResponses(
3190
- ActorsCreateResponseSchema,
3191
- validateBody
3192
- )
3263
+ responses: buildOpenApiResponses(ActorsCreateResponseSchema)
3193
3264
  });
3194
3265
  router.openapi(route, async (c) => {
3195
- const body = validateBody ? await c.req.json() : await c.req.json();
3196
- if (validateBody) {
3197
- ActorsCreateRequestSchema.parse(body);
3198
- }
3266
+ const body = c.req.valid("json");
3199
3267
  const actorOutput = await managerDriver.createActor({
3200
3268
  c,
3201
3269
  name: body.name,
@@ -3205,20 +3273,7 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3205
3273
  region: void 0
3206
3274
  // Not provided in the request schema
3207
3275
  });
3208
- const actor2 = {
3209
- actor_id: actorOutput.actorId,
3210
- name: actorOutput.name,
3211
- key: actorOutput.key,
3212
- namespace_id: "default",
3213
- // Assert default namespace
3214
- runner_name_selector: "rivetkit",
3215
- // Assert rivetkit runner
3216
- create_ts: Date.now(),
3217
- connectable_ts: null,
3218
- destroy_ts: null,
3219
- sleep_ts: null,
3220
- start_ts: null
3221
- };
3276
+ const actor2 = createApiActor(actorOutput);
3222
3277
  return c.json({ actor: actor2 });
3223
3278
  });
3224
3279
  }
@@ -3246,29 +3301,60 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3246
3301
  router.get(".test/inline-driver/connect-websocket/*", async (c) => {
3247
3302
  var _a2;
3248
3303
  const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
3249
- invariant5(upgradeWebSocket, "websockets not supported on this platform");
3304
+ invariant6(upgradeWebSocket, "websockets not supported on this platform");
3250
3305
  return upgradeWebSocket(async (c2) => {
3251
- const {
3252
- path: path3,
3253
- actorId,
3254
- params: paramsRaw,
3255
- encodingKind
3256
- } = c2.req.query();
3257
- const params = paramsRaw !== void 0 ? JSON.parse(paramsRaw) : void 0;
3306
+ const protocolHeader = c2.req.header("sec-websocket-protocol") || "";
3307
+ const protocols = protocolHeader.split(/,\s*/);
3308
+ let actorId = "";
3309
+ let encoding = "bare";
3310
+ let transport = "websocket";
3311
+ let path3 = "";
3312
+ let params;
3313
+ let connId;
3314
+ let connToken;
3315
+ for (const protocol of protocols) {
3316
+ if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
3317
+ actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
3318
+ } else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
3319
+ encoding = protocol.substring(
3320
+ WS_PROTOCOL_ENCODING.length
3321
+ );
3322
+ } else if (protocol.startsWith(WS_PROTOCOL_TRANSPORT)) {
3323
+ transport = protocol.substring(
3324
+ WS_PROTOCOL_TRANSPORT.length
3325
+ );
3326
+ } else if (protocol.startsWith(WS_PROTOCOL_PATH)) {
3327
+ path3 = decodeURIComponent(
3328
+ protocol.substring(WS_PROTOCOL_PATH.length)
3329
+ );
3330
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
3331
+ const paramsRaw = decodeURIComponent(
3332
+ protocol.substring(WS_PROTOCOL_CONN_PARAMS.length)
3333
+ );
3334
+ params = JSON.parse(paramsRaw);
3335
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_ID)) {
3336
+ connId = protocol.substring(WS_PROTOCOL_CONN_ID.length);
3337
+ } else if (protocol.startsWith(WS_PROTOCOL_CONN_TOKEN)) {
3338
+ connToken = protocol.substring(WS_PROTOCOL_CONN_TOKEN.length);
3339
+ }
3340
+ }
3258
3341
  logger().debug({
3259
3342
  msg: "received test inline driver websocket",
3260
3343
  actorId,
3261
3344
  params,
3262
- encodingKind,
3345
+ encodingKind: encoding,
3346
+ transport,
3263
3347
  path: path3
3264
3348
  });
3265
3349
  const clientWsPromise = managerDriver.openWebSocket(
3266
3350
  path3,
3267
3351
  actorId,
3268
- encodingKind,
3269
- params
3352
+ encoding,
3353
+ params,
3354
+ connId,
3355
+ connToken
3270
3356
  );
3271
- return await createTestWebSocketProxy(clientWsPromise, "standard");
3357
+ return await createTestWebSocketProxy(clientWsPromise);
3272
3358
  })(c, noopNext());
3273
3359
  });
3274
3360
  router.all(".test/inline-driver/send-request/*", async (c) => {
@@ -3291,7 +3377,8 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3291
3377
  new Request(`http://actor/${pathWithQuery}`, {
3292
3378
  method: c.req.method,
3293
3379
  headers: c.req.raw.headers,
3294
- body: c.req.raw.body
3380
+ body: c.req.raw.body,
3381
+ duplex: "half"
3295
3382
  })
3296
3383
  );
3297
3384
  return response;
@@ -3313,13 +3400,50 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3313
3400
  );
3314
3401
  }
3315
3402
  });
3403
+ router.post("/.test/force-disconnect", async (c) => {
3404
+ const actorId = c.req.query("actor");
3405
+ const connId = c.req.query("conn");
3406
+ if (!actorId || !connId) {
3407
+ return c.text("Missing actor or conn query parameters", 400);
3408
+ }
3409
+ logger().debug({
3410
+ msg: "forcing unclean disconnect",
3411
+ actorId,
3412
+ connId
3413
+ });
3414
+ try {
3415
+ const response = await managerDriver.sendRequest(
3416
+ actorId,
3417
+ new Request(`http://actor/.test/force-disconnect?conn=${connId}`, {
3418
+ method: "POST"
3419
+ })
3420
+ );
3421
+ if (!response.ok) {
3422
+ const text = await response.text();
3423
+ return c.text(
3424
+ `Failed to force disconnect: ${text}`,
3425
+ response.status
3426
+ );
3427
+ }
3428
+ return c.json({ success: true });
3429
+ } catch (error) {
3430
+ logger().error({
3431
+ msg: "error forcing disconnect",
3432
+ error: stringifyError(error)
3433
+ });
3434
+ return c.text(`Error: ${error}`, 500);
3435
+ }
3436
+ });
3316
3437
  }
3438
+ router.get("/health", cors2, (c) => {
3439
+ return c.text("ok");
3440
+ });
3317
3441
  (_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
3318
3442
  managerDriver,
3319
3443
  registryConfig,
3320
3444
  router
3321
3445
  );
3322
- if ((_b = runConfig.inspector) == null ? void 0 : _b.enabled) {
3446
+ if (isInspectorEnabled(runConfig, "manager")) {
3323
3447
  if (!managerDriver.inspector) {
3324
3448
  throw new Unsupported("inspector");
3325
3449
  }
@@ -3331,180 +3455,33 @@ function createManagerRouter(registryConfig, runConfig, managerDriver, validateB
3331
3455
  }).route("/", createManagerInspectorRouter())
3332
3456
  );
3333
3457
  }
3334
- router.notFound(handleRouteNotFound);
3335
- router.onError(handleRouteError);
3336
- return { router, openapi: router };
3337
3458
  }
3338
- async function createTestWebSocketProxy(clientWsPromise, connectionType) {
3339
- let clientWs = null;
3340
- try {
3341
- logger().debug({ msg: "awaiting client websocket promise" });
3342
- const ws = await clientWsPromise;
3343
- clientWs = ws;
3344
- logger().debug({
3345
- msg: "client websocket promise resolved",
3346
- constructor: ws == null ? void 0 : ws.constructor.name
3347
- });
3348
- await new Promise((resolve, reject) => {
3349
- const onOpen = () => {
3350
- logger().debug({ msg: "test websocket connection opened" });
3351
- resolve();
3352
- };
3353
- const onError = (error) => {
3354
- logger().error({ msg: "test websocket connection failed", error });
3355
- reject(
3356
- new Error(`Failed to open WebSocket: ${error.message || error}`)
3357
- );
3358
- };
3359
- ws.addEventListener("open", onOpen);
3360
- ws.addEventListener("error", onError);
3361
- });
3362
- } catch (error) {
3363
- logger().error({
3364
- msg: `failed to establish client ${connectionType} websocket connection`,
3365
- error
3366
- });
3367
- return {
3368
- onOpen: (_evt, serverWs) => {
3369
- serverWs.close(1011, "Failed to establish connection");
3370
- },
3371
- onMessage: () => {
3372
- },
3373
- onError: () => {
3374
- },
3375
- onClose: () => {
3376
- }
3377
- };
3378
- }
3459
+ function createApiActor(actor2) {
3379
3460
  return {
3380
- onOpen: (_evt, serverWs) => {
3381
- logger().debug({
3382
- msg: `test ${connectionType} websocket connection opened`
3383
- });
3384
- logger().debug({
3385
- msg: "clientWs info",
3386
- constructor: clientWs.constructor.name,
3387
- hasAddEventListener: typeof clientWs.addEventListener === "function",
3388
- readyState: clientWs.readyState
3389
- });
3390
- clientWs.addEventListener("message", (clientEvt) => {
3391
- var _a, _b;
3392
- logger().debug({
3393
- msg: `test ${connectionType} websocket connection message from client`,
3394
- dataType: typeof clientEvt.data,
3395
- isBlob: clientEvt.data instanceof Blob,
3396
- isArrayBuffer: clientEvt.data instanceof ArrayBuffer,
3397
- dataConstructor: (_b = (_a = clientEvt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
3398
- dataStr: typeof clientEvt.data === "string" ? clientEvt.data.substring(0, 100) : void 0
3399
- });
3400
- if (serverWs.readyState === 1) {
3401
- if (clientEvt.data instanceof Blob) {
3402
- clientEvt.data.arrayBuffer().then((buffer) => {
3403
- logger().debug({
3404
- msg: "converted client blob to arraybuffer, sending to server",
3405
- bufferSize: buffer.byteLength
3406
- });
3407
- serverWs.send(buffer);
3408
- }).catch((error) => {
3409
- logger().error({
3410
- msg: "failed to convert blob to arraybuffer",
3411
- error
3412
- });
3413
- });
3414
- } else {
3415
- logger().debug({
3416
- msg: "sending client data directly to server",
3417
- dataType: typeof clientEvt.data,
3418
- dataLength: typeof clientEvt.data === "string" ? clientEvt.data.length : void 0
3419
- });
3420
- serverWs.send(clientEvt.data);
3421
- }
3422
- }
3423
- });
3424
- clientWs.addEventListener("close", (clientEvt) => {
3425
- logger().debug({
3426
- msg: `test ${connectionType} websocket connection closed`
3427
- });
3428
- if (serverWs.readyState !== 3) {
3429
- serverWs.close(clientEvt.code, clientEvt.reason);
3430
- }
3431
- });
3432
- clientWs.addEventListener("error", () => {
3433
- logger().debug({
3434
- msg: `test ${connectionType} websocket connection error`
3435
- });
3436
- if (serverWs.readyState !== 3) {
3437
- serverWs.close(1011, "Error in client websocket");
3438
- }
3439
- });
3440
- },
3441
- onMessage: (evt) => {
3442
- var _a, _b;
3443
- logger().debug({
3444
- msg: "received message from server",
3445
- dataType: typeof evt.data,
3446
- isBlob: evt.data instanceof Blob,
3447
- isArrayBuffer: evt.data instanceof ArrayBuffer,
3448
- dataConstructor: (_b = (_a = evt.data) == null ? void 0 : _a.constructor) == null ? void 0 : _b.name,
3449
- dataStr: typeof evt.data === "string" ? evt.data.substring(0, 100) : void 0
3450
- });
3451
- if (clientWs.readyState === 1) {
3452
- if (evt.data instanceof Blob) {
3453
- evt.data.arrayBuffer().then((buffer) => {
3454
- logger().debug({
3455
- msg: "converted blob to arraybuffer, sending",
3456
- bufferSize: buffer.byteLength
3457
- });
3458
- clientWs.send(buffer);
3459
- }).catch((error) => {
3460
- logger().error({
3461
- msg: "failed to convert blob to arraybuffer",
3462
- error
3463
- });
3464
- });
3465
- } else {
3466
- logger().debug({
3467
- msg: "sending data directly",
3468
- dataType: typeof evt.data,
3469
- dataLength: typeof evt.data === "string" ? evt.data.length : void 0
3470
- });
3471
- clientWs.send(evt.data);
3472
- }
3473
- }
3474
- },
3475
- onClose: (event, serverWs) => {
3476
- logger().debug({
3477
- msg: `server ${connectionType} websocket closed`,
3478
- wasClean: event.wasClean,
3479
- code: event.code,
3480
- reason: event.reason
3481
- });
3482
- serverWs.close(1e3, "hack_force_close");
3483
- if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3484
- clientWs.close(1e3, event.reason);
3485
- }
3486
- },
3487
- onError: (error) => {
3488
- logger().error({
3489
- msg: `error in server ${connectionType} websocket`,
3490
- error
3491
- });
3492
- if (clientWs && clientWs.readyState !== clientWs.CLOSED && clientWs.readyState !== clientWs.CLOSING) {
3493
- clientWs.close(1011, "Error in server websocket");
3494
- }
3495
- }
3461
+ actor_id: actor2.actorId,
3462
+ name: actor2.name,
3463
+ key: serializeActorKey(actor2.key),
3464
+ namespace_id: "default",
3465
+ // Assert default namespace
3466
+ runner_name_selector: "rivetkit",
3467
+ // Assert rivetkit runner
3468
+ create_ts: Date.now(),
3469
+ connectable_ts: null,
3470
+ destroy_ts: null,
3471
+ sleep_ts: null,
3472
+ start_ts: null
3496
3473
  };
3497
3474
  }
3498
3475
 
3499
3476
  // src/registry/config.ts
3500
- import { z as z9 } from "zod";
3501
- var ActorsSchema = z9.record(
3502
- z9.string(),
3503
- z9.custom()
3477
+ import { z as z6 } from "zod";
3478
+ var ActorsSchema = z6.record(
3479
+ z6.string(),
3480
+ z6.custom()
3504
3481
  );
3505
- var TestConfigSchema = z9.object({ enabled: z9.boolean() });
3506
- var RegistryConfigSchema = z9.object({
3507
- use: z9.record(z9.string(), z9.custom()),
3482
+ var TestConfigSchema = z6.object({ enabled: z6.boolean() });
3483
+ var RegistryConfigSchema = z6.object({
3484
+ use: z6.record(z6.string(), z6.custom()),
3508
3485
  // TODO: Find a better way of passing around the test config
3509
3486
  /**
3510
3487
  * Test configuration.
@@ -3576,7 +3553,7 @@ var Registry = class {
3576
3553
  * Runs the registry for a server.
3577
3554
  */
3578
3555
  start(inputConfig) {
3579
- var _a, _b, _c, _d, _e;
3556
+ var _a, _b, _c;
3580
3557
  const config2 = RunConfigSchema.parse(inputConfig);
3581
3558
  if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3582
3559
  configureBaseLogger(config2.logging.baseLogger);
@@ -3585,11 +3562,11 @@ var Registry = class {
3585
3562
  }
3586
3563
  const driver = chooseDefaultDriver(config2);
3587
3564
  if (driver.name === "engine") {
3588
- config2.inspector.enabled = false;
3565
+ config2.inspector.enabled = { manager: false, actor: true };
3589
3566
  config2.disableServer = true;
3590
3567
  }
3591
3568
  if (driver.name === "cloudflare-workers") {
3592
- config2.inspector.enabled = false;
3569
+ config2.inspector.enabled = { manager: false, actor: true };
3593
3570
  config2.disableServer = true;
3594
3571
  config2.disableActorDriver = true;
3595
3572
  config2.noWelcome = true;
@@ -3599,12 +3576,82 @@ var Registry = class {
3599
3576
  config2.getUpgradeWebSocket = () => upgradeWebSocket;
3600
3577
  }
3601
3578
  const managerDriver = driver.manager(this.#config, config2);
3579
+ configureInspectorAccessToken(config2, managerDriver);
3580
+ const client = createClientWithDriver(managerDriver, config2);
3581
+ const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3582
+ logger6().info({
3583
+ msg: "rivetkit ready",
3584
+ driver: driver.name,
3585
+ definitions: Object.keys(this.#config.use).length,
3586
+ ...driverLog
3587
+ });
3588
+ if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
3589
+ logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3590
+ }
3591
+ if (!config2.noWelcome) {
3592
+ const displayInfo = managerDriver.displayInformation();
3593
+ console.log();
3594
+ console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3595
+ console.log(` - Endpoint: http://127.0.0.1:6420`);
3596
+ for (const [k, v] of Object.entries(displayInfo.properties)) {
3597
+ const padding = " ".repeat(Math.max(0, 13 - k.length));
3598
+ console.log(` - ${k}:${padding}${v}`);
3599
+ }
3600
+ if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
3601
+ console.log(` - Inspector: ${getInspectorUrl(config2)}`);
3602
+ }
3603
+ console.log();
3604
+ }
3605
+ if (!config2.disableActorDriver) {
3606
+ const _actorDriver = driver.actor(
3607
+ this.#config,
3608
+ config2,
3609
+ managerDriver,
3610
+ client
3611
+ );
3612
+ }
3602
3613
  const { router: hono } = createManagerRouter(
3603
3614
  this.#config,
3604
3615
  config2,
3605
3616
  managerDriver,
3606
- false
3617
+ void 0
3607
3618
  );
3619
+ if (!config2.disableServer) {
3620
+ (async () => {
3621
+ const out = await crossPlatformServe(hono, void 0);
3622
+ upgradeWebSocket = out.upgradeWebSocket;
3623
+ })();
3624
+ }
3625
+ return {
3626
+ client,
3627
+ fetch: hono.fetch.bind(hono)
3628
+ };
3629
+ }
3630
+ startServerless(inputConfig) {
3631
+ var _a, _b, _c, _d, _e;
3632
+ const config2 = RunConfigSchema.parse(inputConfig);
3633
+ if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3634
+ configureBaseLogger(config2.logging.baseLogger);
3635
+ } else {
3636
+ configureDefaultLogger((_b = config2.logging) == null ? void 0 : _b.level);
3637
+ }
3638
+ const driver = chooseDefaultDriver(config2);
3639
+ if (driver.name === "engine") {
3640
+ config2.inspector.enabled = false;
3641
+ config2.disableServer = true;
3642
+ config2.disableActorDriver = true;
3643
+ }
3644
+ if (driver.name === "cloudflare-workers") {
3645
+ config2.inspector.enabled = false;
3646
+ config2.disableServer = true;
3647
+ config2.disableActorDriver = true;
3648
+ config2.noWelcome = true;
3649
+ }
3650
+ let upgradeWebSocket;
3651
+ if (!config2.getUpgradeWebSocket) {
3652
+ config2.getUpgradeWebSocket = () => upgradeWebSocket;
3653
+ }
3654
+ const managerDriver = driver.manager(this.#config, config2);
3608
3655
  const client = createClientWithDriver(managerDriver, config2);
3609
3656
  const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3610
3657
  logger6().info({
@@ -3630,14 +3677,19 @@ var Registry = class {
3630
3677
  }
3631
3678
  console.log();
3632
3679
  }
3680
+ let serverlessActorDriverBuilder = () => {
3681
+ return driver.actor(this.#config, config2, managerDriver, client);
3682
+ };
3633
3683
  if (!config2.disableActorDriver) {
3634
- const _actorDriver = driver.actor(
3635
- this.#config,
3636
- config2,
3637
- managerDriver,
3638
- client
3639
- );
3684
+ const _actorDriver = serverlessActorDriverBuilder();
3685
+ serverlessActorDriverBuilder = void 0;
3640
3686
  }
3687
+ const { router: hono } = createManagerRouter(
3688
+ this.#config,
3689
+ config2,
3690
+ managerDriver,
3691
+ serverlessActorDriverBuilder
3692
+ );
3641
3693
  if (!config2.disableServer) {
3642
3694
  (async () => {
3643
3695
  const out = await crossPlatformServe(hono, void 0);
@@ -3656,8 +3708,6 @@ function setup(input) {
3656
3708
  }
3657
3709
 
3658
3710
  export {
3659
- GenericConnGlobalState,
3660
- createGenericConnDrivers,
3661
3711
  handleWebSocketConnect,
3662
3712
  handleRawWebSocketHandler,
3663
3713
  createActorRouter,
@@ -3673,4 +3723,4 @@ export {
3673
3723
  setup
3674
3724
  };
3675
3725
  //! These configs configs hold anything that's not platform-specific about running actors.
3676
- //# sourceMappingURL=chunk-W6LN7AF5.js.map
3726
+ //# sourceMappingURL=chunk-HPT3I7UU.js.map