rivetkit 2.0.5 → 2.0.6

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 (116) hide show
  1. package/dist/tsup/actor-router-consts-BK6arfy8.d.cts +17 -0
  2. package/dist/tsup/actor-router-consts-BK6arfy8.d.ts +17 -0
  3. package/dist/tsup/chunk-2K3JMDAN.js +232 -0
  4. package/dist/tsup/chunk-2K3JMDAN.js.map +1 -0
  5. package/dist/tsup/chunk-42I3OZ3Q.js +15 -0
  6. package/dist/tsup/chunk-42I3OZ3Q.js.map +1 -0
  7. package/dist/tsup/{chunk-L7QRXNWP.js → chunk-4CKHQRXG.js} +1642 -4408
  8. package/dist/tsup/chunk-4CKHQRXG.js.map +1 -0
  9. package/dist/tsup/{chunk-WADSS5X4.cjs → chunk-5JBFVV4C.cjs} +2 -2
  10. package/dist/tsup/{chunk-WADSS5X4.cjs.map → chunk-5JBFVV4C.cjs.map} +1 -1
  11. package/dist/tsup/{chunk-FGFT4FVX.cjs → chunk-6P6RA47N.cjs} +9 -9
  12. package/dist/tsup/{chunk-FGFT4FVX.cjs.map → chunk-6P6RA47N.cjs.map} +1 -1
  13. package/dist/tsup/chunk-7OUKNSTU.js +1043 -0
  14. package/dist/tsup/chunk-7OUKNSTU.js.map +1 -0
  15. package/dist/tsup/{chunk-LZIBTLEY.cjs → chunk-DIAYNQTE.cjs} +13 -25
  16. package/dist/tsup/chunk-DIAYNQTE.cjs.map +1 -0
  17. package/dist/tsup/{chunk-YW6Y6VNE.js → chunk-G75SVQON.js} +4 -4
  18. package/dist/tsup/{chunk-PHSQJ6QI.cjs → chunk-KG3C7MKR.cjs} +3 -3
  19. package/dist/tsup/{chunk-PHSQJ6QI.cjs.map → chunk-KG3C7MKR.cjs.map} +1 -1
  20. package/dist/tsup/chunk-KUPQZYUQ.cjs +15 -0
  21. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +1 -0
  22. package/dist/tsup/{chunk-5YTI25C3.cjs → chunk-MRRT2CZD.cjs} +7 -7
  23. package/dist/tsup/{chunk-5YTI25C3.cjs.map → chunk-MRRT2CZD.cjs.map} +1 -1
  24. package/dist/tsup/chunk-NTCUGYSD.cjs +1043 -0
  25. package/dist/tsup/chunk-NTCUGYSD.cjs.map +1 -0
  26. package/dist/tsup/{chunk-CFFKMUYH.js → chunk-RGQR2J7S.js} +2 -2
  27. package/dist/tsup/{chunk-CFFKMUYH.js.map → chunk-RGQR2J7S.js.map} +1 -1
  28. package/dist/tsup/chunk-TCUI5JFE.cjs +232 -0
  29. package/dist/tsup/chunk-TCUI5JFE.cjs.map +1 -0
  30. package/dist/tsup/chunk-TWGATZ3X.cjs +3676 -0
  31. package/dist/tsup/chunk-TWGATZ3X.cjs.map +1 -0
  32. package/dist/tsup/chunk-UFWAK3X2.cjs +3796 -0
  33. package/dist/tsup/chunk-UFWAK3X2.cjs.map +1 -0
  34. package/dist/tsup/{chunk-D7NWUCRK.cjs → chunk-UTI5NCES.cjs} +6 -6
  35. package/dist/tsup/{chunk-D7NWUCRK.cjs.map → chunk-UTI5NCES.cjs.map} +1 -1
  36. package/dist/tsup/{chunk-PG3K2LI7.js → chunk-VCEHU56K.js} +2 -2
  37. package/dist/tsup/{chunk-I5VTWPHW.js → chunk-VPV4MWXR.js} +3 -3
  38. package/dist/tsup/chunk-W6LN7AF5.js +3676 -0
  39. package/dist/tsup/chunk-W6LN7AF5.js.map +1 -0
  40. package/dist/tsup/{chunk-WNGOBAA7.js → chunk-WC2PSJWN.js} +2 -2
  41. package/dist/tsup/{chunk-CKA54YQN.js → chunk-ZYLTS2EM.js} +3 -15
  42. package/dist/tsup/chunk-ZYLTS2EM.js.map +1 -0
  43. package/dist/tsup/client/mod.cjs +9 -9
  44. package/dist/tsup/client/mod.d.cts +2 -2
  45. package/dist/tsup/client/mod.d.ts +2 -2
  46. package/dist/tsup/client/mod.js +8 -8
  47. package/dist/tsup/common/log.cjs +3 -3
  48. package/dist/tsup/common/log.js +2 -2
  49. package/dist/tsup/common/websocket.cjs +4 -4
  50. package/dist/tsup/common/websocket.js +3 -3
  51. package/dist/tsup/{connection-BvE-Oq7t.d.ts → connection-BLemxi4f.d.ts} +1 -1
  52. package/dist/tsup/{connection-DTzmWwU5.d.cts → connection-CpDIydXf.d.cts} +1 -1
  53. package/dist/tsup/driver-helpers/mod.cjs +5 -5
  54. package/dist/tsup/driver-helpers/mod.d.cts +2 -2
  55. package/dist/tsup/driver-helpers/mod.d.ts +2 -2
  56. package/dist/tsup/driver-helpers/mod.js +4 -4
  57. package/dist/tsup/driver-test-suite/mod.cjs +66 -58
  58. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  59. package/dist/tsup/driver-test-suite/mod.d.cts +1 -1
  60. package/dist/tsup/driver-test-suite/mod.d.ts +1 -1
  61. package/dist/tsup/driver-test-suite/mod.js +24 -16
  62. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  63. package/dist/tsup/inspector/mod.cjs +7 -5
  64. package/dist/tsup/inspector/mod.cjs.map +1 -1
  65. package/dist/tsup/inspector/mod.js +9 -7
  66. package/dist/tsup/mod.cjs +11 -8
  67. package/dist/tsup/mod.cjs.map +1 -1
  68. package/dist/tsup/mod.d.cts +52 -7
  69. package/dist/tsup/mod.d.ts +52 -7
  70. package/dist/tsup/mod.js +17 -14
  71. package/dist/tsup/test/mod.cjs +11 -9
  72. package/dist/tsup/test/mod.cjs.map +1 -1
  73. package/dist/tsup/test/mod.d.cts +1 -1
  74. package/dist/tsup/test/mod.d.ts +1 -1
  75. package/dist/tsup/test/mod.js +10 -8
  76. package/dist/tsup/utils.cjs +2 -2
  77. package/dist/tsup/utils.js +1 -1
  78. package/package.json +1 -1
  79. package/src/actor/mod.ts +5 -3
  80. package/src/actor/router-endpoints.ts +5 -32
  81. package/src/actor/router.ts +9 -8
  82. package/src/client/actor-conn.ts +9 -8
  83. package/src/client/actor-handle.ts +0 -1
  84. package/src/client/client.ts +1 -1
  85. package/src/client/raw-utils.ts +1 -1
  86. package/src/client/utils.ts +1 -1
  87. package/src/common/actor-router-consts.ts +38 -0
  88. package/src/driver-helpers/mod.ts +1 -1
  89. package/src/driver-test-suite/test-inline-client-driver.ts +4 -4
  90. package/src/driver-test-suite/utils.ts +7 -2
  91. package/src/drivers/engine/actor-driver.ts +18 -17
  92. package/src/manager/driver.ts +1 -1
  93. package/src/manager/protocol/query.ts +1 -1
  94. package/src/registry/mod.ts +7 -2
  95. package/src/registry/serve.ts +8 -3
  96. package/src/remote-manager-driver/actor-websocket-client.ts +2 -2
  97. package/src/remote-manager-driver/mod.ts +2 -5
  98. package/dist/tsup/chunk-2MD57QF4.js +0 -1794
  99. package/dist/tsup/chunk-2MD57QF4.js.map +0 -1
  100. package/dist/tsup/chunk-B2QGJGZQ.js +0 -338
  101. package/dist/tsup/chunk-B2QGJGZQ.js.map +0 -1
  102. package/dist/tsup/chunk-CKA54YQN.js.map +0 -1
  103. package/dist/tsup/chunk-IRMBWX36.cjs +0 -1794
  104. package/dist/tsup/chunk-IRMBWX36.cjs.map +0 -1
  105. package/dist/tsup/chunk-L7QRXNWP.js.map +0 -1
  106. package/dist/tsup/chunk-LZIBTLEY.cjs.map +0 -1
  107. package/dist/tsup/chunk-MRZS2J4X.cjs +0 -6562
  108. package/dist/tsup/chunk-MRZS2J4X.cjs.map +0 -1
  109. package/dist/tsup/chunk-RM2SVURR.cjs +0 -338
  110. package/dist/tsup/chunk-RM2SVURR.cjs.map +0 -1
  111. package/dist/tsup/router-endpoints-CctffZNL.d.cts +0 -65
  112. package/dist/tsup/router-endpoints-DFm1BglJ.d.ts +0 -65
  113. /package/dist/tsup/{chunk-YW6Y6VNE.js.map → chunk-G75SVQON.js.map} +0 -0
  114. /package/dist/tsup/{chunk-PG3K2LI7.js.map → chunk-VCEHU56K.js.map} +0 -0
  115. /package/dist/tsup/{chunk-I5VTWPHW.js.map → chunk-VPV4MWXR.js.map} +0 -0
  116. /package/dist/tsup/{chunk-WNGOBAA7.js.map → chunk-WC2PSJWN.js.map} +0 -0
@@ -0,0 +1,3676 @@
1
+ import {
2
+ ActorDefinition,
3
+ CONNECTION_DRIVER_HTTP,
4
+ CONNECTION_DRIVER_SSE,
5
+ CONNECTION_DRIVER_WEBSOCKET,
6
+ RemoteManagerDriver,
7
+ createActorInspectorRouter,
8
+ createClientWithDriver,
9
+ deserializeActorKey,
10
+ generateConnId,
11
+ generateConnToken,
12
+ lookupInRegistry
13
+ } from "./chunk-4CKHQRXG.js";
14
+ import {
15
+ CreateActorSchema
16
+ } from "./chunk-ZYLTS2EM.js";
17
+ import {
18
+ ActionContext,
19
+ HTTP_ACTION_REQUEST_VERSIONED,
20
+ HTTP_ACTION_RESPONSE_VERSIONED,
21
+ HTTP_RESPONSE_ERROR_VERSIONED,
22
+ RunConfigSchema,
23
+ TO_SERVER_VERSIONED,
24
+ createVersionedDataHandler,
25
+ parseMessage,
26
+ serializeEmptyPersistData
27
+ } from "./chunk-7OUKNSTU.js";
28
+ import {
29
+ EncodingSchema,
30
+ HEADER_ACTOR_ID,
31
+ HEADER_AUTH_DATA,
32
+ HEADER_CONN_ID,
33
+ HEADER_CONN_PARAMS,
34
+ HEADER_CONN_TOKEN,
35
+ HEADER_ENCODING,
36
+ PATH_CONNECT_WEBSOCKET,
37
+ PATH_RAW_WEBSOCKET_PREFIX,
38
+ contentTypeForEncoding,
39
+ deserializeWithEncoding,
40
+ encodeDataToString,
41
+ encodingIsBinary,
42
+ generateRandomString,
43
+ loggerWithoutContext,
44
+ serializeWithEncoding
45
+ } from "./chunk-2K3JMDAN.js";
46
+ import {
47
+ configureBaseLogger,
48
+ configureDefaultLogger,
49
+ getLogger
50
+ } from "./chunk-WC2PSJWN.js";
51
+ import {
52
+ bufferToArrayBuffer,
53
+ deconstructError,
54
+ getEnvUniversal,
55
+ noopNext,
56
+ package_default,
57
+ setLongTimeout,
58
+ stringifyError
59
+ } from "./chunk-RGQR2J7S.js";
60
+ import {
61
+ ActorAlreadyExists,
62
+ ActorNotFound,
63
+ ConnNotFound,
64
+ IncorrectConnToken,
65
+ InternalError,
66
+ InvalidEncoding,
67
+ InvalidParams,
68
+ MissingActorHeader,
69
+ Unsupported,
70
+ UserError,
71
+ WebSocketsNotEnabled
72
+ } from "./chunk-YPZFLUO6.js";
73
+
74
+ // src/actor/config.ts
75
+ import { z } from "zod";
76
+ var ActorConfigSchema = z.object({
77
+ onCreate: z.function().optional(),
78
+ onStart: z.function().optional(),
79
+ onStop: z.function().optional(),
80
+ onStateChange: z.function().optional(),
81
+ onBeforeConnect: z.function().optional(),
82
+ onConnect: z.function().optional(),
83
+ onDisconnect: z.function().optional(),
84
+ onBeforeActionResponse: z.function().optional(),
85
+ onFetch: z.function().optional(),
86
+ onWebSocket: z.function().optional(),
87
+ actions: z.record(z.function()).default({}),
88
+ state: z.any().optional(),
89
+ createState: z.function().optional(),
90
+ connState: z.any().optional(),
91
+ createConnState: z.function().optional(),
92
+ vars: z.any().optional(),
93
+ db: z.any().optional(),
94
+ createVars: z.function().optional(),
95
+ options: z.object({
96
+ createVarsTimeout: z.number().positive().default(5e3),
97
+ createConnStateTimeout: z.number().positive().default(5e3),
98
+ onConnectTimeout: z.number().positive().default(5e3),
99
+ // This must be less than ACTOR_STOP_THRESHOLD_MS
100
+ onStopTimeout: z.number().positive().default(5e3),
101
+ stateSaveInterval: z.number().positive().default(1e4),
102
+ actionTimeout: z.number().positive().default(6e4),
103
+ // Max time to wait for waitUntil background promises during shutdown
104
+ waitUntilTimeout: z.number().positive().default(15e3),
105
+ connectionLivenessTimeout: z.number().positive().default(2500),
106
+ connectionLivenessInterval: z.number().positive().default(5e3),
107
+ noSleep: z.boolean().default(false),
108
+ sleepTimeout: z.number().positive().default(3e4)
109
+ }).strict().default({})
110
+ }).strict().refine(
111
+ (data) => !(data.state !== void 0 && data.createState !== void 0),
112
+ {
113
+ message: "Cannot define both 'state' and 'createState'",
114
+ path: ["state"]
115
+ }
116
+ ).refine(
117
+ (data) => !(data.connState !== void 0 && data.createConnState !== void 0),
118
+ {
119
+ message: "Cannot define both 'connState' and 'createConnState'",
120
+ path: ["connState"]
121
+ }
122
+ ).refine(
123
+ (data) => !(data.vars !== void 0 && data.createVars !== void 0),
124
+ {
125
+ message: "Cannot define both 'vars' and 'createVars'",
126
+ path: ["vars"]
127
+ }
128
+ );
129
+
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
+ // src/actor/router.ts
280
+ import { Hono } from "hono";
281
+ import { cors } from "hono/cors";
282
+ import invariant from "invariant";
283
+
284
+ // src/actor/router-endpoints.ts
285
+ import * as cbor from "cbor-x";
286
+ import { streamSSE } from "hono/streaming";
287
+
288
+ // src/manager/log.ts
289
+ function logger() {
290
+ return getLogger("actor-manager");
291
+ }
292
+
293
+ // src/manager/hono-websocket-adapter.ts
294
+ var HonoWebSocketAdapter = class {
295
+ // WebSocket readyState values
296
+ CONNECTING = 0;
297
+ OPEN = 1;
298
+ CLOSING = 2;
299
+ CLOSED = 3;
300
+ #ws;
301
+ #readyState = 1;
302
+ // Start as OPEN since WSContext is already connected
303
+ #eventListeners = /* @__PURE__ */ new Map();
304
+ #closeCode;
305
+ #closeReason;
306
+ constructor(ws) {
307
+ this.#ws = ws;
308
+ this.#readyState = this.OPEN;
309
+ setTimeout(() => {
310
+ this.#fireEvent("open", { type: "open", target: this });
311
+ }, 0);
312
+ }
313
+ get readyState() {
314
+ return this.#readyState;
315
+ }
316
+ get binaryType() {
317
+ return "arraybuffer";
318
+ }
319
+ set binaryType(value) {
320
+ }
321
+ get bufferedAmount() {
322
+ return 0;
323
+ }
324
+ get extensions() {
325
+ return "";
326
+ }
327
+ get protocol() {
328
+ return "";
329
+ }
330
+ get url() {
331
+ return "";
332
+ }
333
+ send(data) {
334
+ if (this.readyState !== this.OPEN) {
335
+ throw new Error("WebSocket is not open");
336
+ }
337
+ try {
338
+ logger().debug({
339
+ msg: "bridge sending data",
340
+ dataType: typeof data,
341
+ isString: typeof data === "string",
342
+ isArrayBuffer: data instanceof ArrayBuffer,
343
+ dataStr: typeof data === "string" ? data.substring(0, 100) : "<non-string>"
344
+ });
345
+ if (typeof data === "string") {
346
+ this.#ws.send(data);
347
+ } else if (data instanceof ArrayBuffer) {
348
+ this.#ws.send(data);
349
+ } else if (ArrayBuffer.isView(data)) {
350
+ const buffer = data.buffer.slice(
351
+ data.byteOffset,
352
+ data.byteOffset + data.byteLength
353
+ );
354
+ if (buffer instanceof SharedArrayBuffer) {
355
+ const arrayBuffer = new ArrayBuffer(buffer.byteLength);
356
+ new Uint8Array(arrayBuffer).set(new Uint8Array(buffer));
357
+ this.#ws.send(arrayBuffer);
358
+ } else {
359
+ this.#ws.send(buffer);
360
+ }
361
+ } else if (data instanceof Blob) {
362
+ data.arrayBuffer().then((buffer) => {
363
+ this.#ws.send(buffer);
364
+ }).catch((error) => {
365
+ logger().error({
366
+ msg: "failed to convert blob to arraybuffer",
367
+ error
368
+ });
369
+ this.#fireEvent("error", { type: "error", target: this, error });
370
+ });
371
+ } else {
372
+ logger().warn({
373
+ msg: "unsupported data type, converting to string",
374
+ dataType: typeof data,
375
+ data
376
+ });
377
+ this.#ws.send(String(data));
378
+ }
379
+ } catch (error) {
380
+ logger().error({ msg: "error sending websocket data", error });
381
+ this.#fireEvent("error", { type: "error", target: this, error });
382
+ throw error;
383
+ }
384
+ }
385
+ close(code = 1e3, reason = "") {
386
+ if (this.readyState === this.CLOSING || this.readyState === this.CLOSED) {
387
+ return;
388
+ }
389
+ this.#readyState = this.CLOSING;
390
+ this.#closeCode = code;
391
+ this.#closeReason = reason;
392
+ try {
393
+ this.#ws.close(code, reason);
394
+ this.#readyState = this.CLOSED;
395
+ this.#fireEvent("close", {
396
+ type: "close",
397
+ target: this,
398
+ code,
399
+ reason,
400
+ wasClean: code === 1e3
401
+ });
402
+ } catch (error) {
403
+ logger().error({ msg: "error closing websocket", error });
404
+ this.#readyState = this.CLOSED;
405
+ this.#fireEvent("close", {
406
+ type: "close",
407
+ target: this,
408
+ code: 1006,
409
+ reason: "Abnormal closure",
410
+ wasClean: false
411
+ });
412
+ }
413
+ }
414
+ addEventListener(type, listener) {
415
+ if (!this.#eventListeners.has(type)) {
416
+ this.#eventListeners.set(type, /* @__PURE__ */ new Set());
417
+ }
418
+ this.#eventListeners.get(type).add(listener);
419
+ }
420
+ removeEventListener(type, listener) {
421
+ const listeners = this.#eventListeners.get(type);
422
+ if (listeners) {
423
+ listeners.delete(listener);
424
+ }
425
+ }
426
+ dispatchEvent(event) {
427
+ const listeners = this.#eventListeners.get(event.type);
428
+ if (listeners) {
429
+ for (const listener of listeners) {
430
+ try {
431
+ listener(event);
432
+ } catch (error) {
433
+ logger().error({
434
+ msg: `error in ${event.type} event listener`,
435
+ error
436
+ });
437
+ }
438
+ }
439
+ }
440
+ return true;
441
+ }
442
+ // Internal method to handle incoming messages from WSContext
443
+ _handleMessage(data) {
444
+ let messageData;
445
+ if (typeof data === "string") {
446
+ messageData = data;
447
+ } else if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
448
+ messageData = data;
449
+ } else if (data && typeof data === "object" && "data" in data) {
450
+ messageData = data.data;
451
+ } else {
452
+ messageData = String(data);
453
+ }
454
+ logger().debug({
455
+ msg: "bridge handling message",
456
+ dataType: typeof messageData,
457
+ isArrayBuffer: messageData instanceof ArrayBuffer,
458
+ dataStr: typeof messageData === "string" ? messageData : "<binary>"
459
+ });
460
+ this.#fireEvent("message", {
461
+ type: "message",
462
+ target: this,
463
+ data: messageData
464
+ });
465
+ }
466
+ // Internal method to handle close from WSContext
467
+ _handleClose(code, reason) {
468
+ this.#ws.close(1e3, "hack_force_close");
469
+ if (this.readyState === this.CLOSED) return;
470
+ this.#readyState = this.CLOSED;
471
+ this.#closeCode = code;
472
+ this.#closeReason = reason;
473
+ this.#fireEvent("close", {
474
+ type: "close",
475
+ target: this,
476
+ code,
477
+ reason,
478
+ wasClean: code === 1e3
479
+ });
480
+ }
481
+ // Internal method to handle errors from WSContext
482
+ _handleError(error) {
483
+ this.#fireEvent("error", {
484
+ type: "error",
485
+ target: this,
486
+ error
487
+ });
488
+ }
489
+ #fireEvent(type, event) {
490
+ const listeners = this.#eventListeners.get(type);
491
+ if (listeners) {
492
+ for (const listener of listeners) {
493
+ try {
494
+ listener(event);
495
+ } catch (error) {
496
+ logger().error({ msg: `error in ${type} event listener`, error });
497
+ }
498
+ }
499
+ }
500
+ switch (type) {
501
+ case "open":
502
+ if (this.#onopen) {
503
+ try {
504
+ this.#onopen(event);
505
+ } catch (error) {
506
+ logger().error({ msg: "error in onopen handler", error });
507
+ }
508
+ }
509
+ break;
510
+ case "close":
511
+ if (this.#onclose) {
512
+ try {
513
+ this.#onclose(event);
514
+ } catch (error) {
515
+ logger().error({ msg: "error in onclose handler", error });
516
+ }
517
+ }
518
+ break;
519
+ case "error":
520
+ if (this.#onerror) {
521
+ try {
522
+ this.#onerror(event);
523
+ } catch (error) {
524
+ logger().error({ msg: "error in onerror handler", error });
525
+ }
526
+ }
527
+ break;
528
+ case "message":
529
+ if (this.#onmessage) {
530
+ try {
531
+ this.#onmessage(event);
532
+ } catch (error) {
533
+ logger().error({ msg: "error in onmessage handler", error });
534
+ }
535
+ }
536
+ break;
537
+ }
538
+ }
539
+ // Event handler properties with getters/setters
540
+ #onopen = null;
541
+ #onclose = null;
542
+ #onerror = null;
543
+ #onmessage = null;
544
+ get onopen() {
545
+ return this.#onopen;
546
+ }
547
+ set onopen(handler) {
548
+ this.#onopen = handler;
549
+ }
550
+ get onclose() {
551
+ return this.#onclose;
552
+ }
553
+ set onclose(handler) {
554
+ this.#onclose = handler;
555
+ }
556
+ get onerror() {
557
+ return this.#onerror;
558
+ }
559
+ set onerror(handler) {
560
+ this.#onerror = handler;
561
+ }
562
+ get onmessage() {
563
+ return this.#onmessage;
564
+ }
565
+ set onmessage(handler) {
566
+ this.#onmessage = handler;
567
+ }
568
+ };
569
+
570
+ // src/actor/router-endpoints.ts
571
+ async function handleWebSocketConnect(req, runConfig, actorDriver, actorId, encoding, parameters, authData) {
572
+ const exposeInternalError = req ? getRequestExposeInternalError(req) : false;
573
+ const {
574
+ promise: handlersPromise,
575
+ resolve: handlersResolve,
576
+ reject: handlersReject
577
+ } = Promise.withResolvers();
578
+ let actor2;
579
+ try {
580
+ actor2 = await actorDriver.loadActor(actorId);
581
+ } catch (error) {
582
+ return {
583
+ onOpen: (_evt, ws) => {
584
+ const { code } = deconstructError(
585
+ error,
586
+ actor2.rLog,
587
+ {
588
+ wsEvent: "open"
589
+ },
590
+ exposeInternalError
591
+ );
592
+ ws.close(1011, code);
593
+ },
594
+ onMessage: (_evt, ws) => {
595
+ ws.close(1011, "Actor not loaded");
596
+ },
597
+ onClose: (_event, _ws) => {
598
+ },
599
+ onError: (_error) => {
600
+ }
601
+ };
602
+ }
603
+ return {
604
+ onOpen: (_evt, ws) => {
605
+ actor2.rLog.debug("websocket open");
606
+ (async () => {
607
+ 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);
613
+ actor2.rLog.debug({
614
+ msg: "registered websocket for conn",
615
+ actorId,
616
+ totalCount: connGlobalState.websockets.size
617
+ });
618
+ const conn = await actor2.createConn(
619
+ connId,
620
+ connToken,
621
+ parameters,
622
+ connState,
623
+ CONNECTION_DRIVER_WEBSOCKET,
624
+ { encoding },
625
+ authData
626
+ );
627
+ handlersResolve({ conn, actor: actor2, connId });
628
+ } catch (error) {
629
+ handlersReject(error);
630
+ const { code } = deconstructError(
631
+ error,
632
+ actor2.rLog,
633
+ {
634
+ wsEvent: "open"
635
+ },
636
+ exposeInternalError
637
+ );
638
+ ws.close(1011, code);
639
+ }
640
+ })();
641
+ },
642
+ onMessage: (evt, ws) => {
643
+ handlersPromise.then(({ conn, actor: actor3 }) => {
644
+ actor3.rLog.debug({ msg: "received message" });
645
+ const value = evt.data.valueOf();
646
+ parseMessage(value, {
647
+ encoding,
648
+ maxIncomingMessageSize: runConfig.maxIncomingMessageSize
649
+ }).then((message) => {
650
+ actor3.processMessage(message, conn).catch((error) => {
651
+ const { code } = deconstructError(
652
+ error,
653
+ actor3.rLog,
654
+ {
655
+ wsEvent: "message"
656
+ },
657
+ exposeInternalError
658
+ );
659
+ ws.close(1011, code);
660
+ });
661
+ }).catch((error) => {
662
+ const { code } = deconstructError(
663
+ error,
664
+ actor3.rLog,
665
+ {
666
+ wsEvent: "message"
667
+ },
668
+ exposeInternalError
669
+ );
670
+ ws.close(1011, code);
671
+ });
672
+ }).catch((error) => {
673
+ const { code } = deconstructError(
674
+ error,
675
+ actor2.rLog,
676
+ {
677
+ wsEvent: "message"
678
+ },
679
+ exposeInternalError
680
+ );
681
+ ws.close(1011, code);
682
+ });
683
+ },
684
+ onClose: (event, ws) => {
685
+ if (event.wasClean) {
686
+ actor2.rLog.info({
687
+ msg: "websocket closed",
688
+ code: event.code,
689
+ reason: event.reason,
690
+ wasClean: event.wasClean
691
+ });
692
+ } else {
693
+ actor2.rLog.warn({
694
+ msg: "websocket closed",
695
+ code: event.code,
696
+ reason: event.reason,
697
+ wasClean: event.wasClean
698
+ });
699
+ }
700
+ 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);
717
+ }).catch((error) => {
718
+ deconstructError(
719
+ error,
720
+ actor2.rLog,
721
+ { wsEvent: "close" },
722
+ exposeInternalError
723
+ );
724
+ });
725
+ },
726
+ onError: (_error) => {
727
+ try {
728
+ actor2.rLog.warn({ msg: "websocket error" });
729
+ } catch (error) {
730
+ deconstructError(
731
+ error,
732
+ actor2.rLog,
733
+ { wsEvent: "error" },
734
+ exposeInternalError
735
+ );
736
+ }
737
+ }
738
+ };
739
+ }
740
+ async function handleSseConnect(c, _runConfig, actorDriver, actorId, authData) {
741
+ const encoding = getRequestEncoding(c.req);
742
+ const parameters = getRequestConnParams(c.req);
743
+ return streamSSE(c, async (stream) => {
744
+ let actor2;
745
+ let connId;
746
+ let connToken;
747
+ let connState;
748
+ let conn;
749
+ try {
750
+ 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);
756
+ conn = await actor2.createConn(
757
+ connId,
758
+ connToken,
759
+ parameters,
760
+ connState,
761
+ CONNECTION_DRIVER_SSE,
762
+ { encoding },
763
+ authData
764
+ );
765
+ const abortResolver = Promise.withResolvers();
766
+ stream.onAbort(() => {
767
+ });
768
+ c.req.raw.signal.addEventListener("abort", async () => {
769
+ const rLog = (actor2 == null ? void 0 : actor2.rLog) ?? loggerWithoutContext();
770
+ try {
771
+ rLog.debug("sse stream aborted");
772
+ if (connId) {
773
+ actorDriver.getGenericConnGlobalState(actorId).sseStreams.delete(connId);
774
+ }
775
+ if (conn && actor2) {
776
+ actor2.__removeConn(conn);
777
+ }
778
+ abortResolver.resolve(void 0);
779
+ } catch (error) {
780
+ rLog.error({ msg: "error closing sse connection", error });
781
+ abortResolver.resolve(void 0);
782
+ }
783
+ });
784
+ try {
785
+ c.executionCtx.waitUntil(abortResolver.promise);
786
+ } catch {
787
+ }
788
+ await abortResolver.promise;
789
+ } catch (error) {
790
+ loggerWithoutContext().error({ msg: "error in sse connection", error });
791
+ if (connId !== void 0) {
792
+ actorDriver.getGenericConnGlobalState(actorId).sseStreams.delete(connId);
793
+ }
794
+ if (conn && actor2 !== void 0) {
795
+ actor2.__removeConn(conn);
796
+ }
797
+ stream.close();
798
+ }
799
+ });
800
+ }
801
+ async function handleAction(c, _runConfig, actorDriver, actionName, actorId, authData) {
802
+ const encoding = getRequestEncoding(c.req);
803
+ const parameters = getRequestConnParams(c.req);
804
+ const arrayBuffer = await c.req.arrayBuffer();
805
+ const request = deserializeWithEncoding(
806
+ encoding,
807
+ new Uint8Array(arrayBuffer),
808
+ HTTP_ACTION_REQUEST_VERSIONED
809
+ );
810
+ const actionArgs = cbor.decode(new Uint8Array(request.args));
811
+ let actor2;
812
+ let conn;
813
+ let output;
814
+ try {
815
+ actor2 = await actorDriver.loadActor(actorId);
816
+ actor2.rLog.debug({ msg: "handling action", actionName, encoding });
817
+ const connState = await actor2.prepareConn(parameters, c.req.raw);
818
+ conn = await actor2.createConn(
819
+ generateConnId(),
820
+ generateConnToken(),
821
+ parameters,
822
+ connState,
823
+ CONNECTION_DRIVER_HTTP,
824
+ {},
825
+ authData
826
+ );
827
+ const ctx = new ActionContext(actor2.actorContext, conn);
828
+ output = await actor2.executeAction(ctx, actionName, actionArgs);
829
+ } finally {
830
+ if (conn) {
831
+ actor2 == null ? void 0 : actor2.__removeConn(conn);
832
+ }
833
+ }
834
+ const responseData = {
835
+ output: bufferToArrayBuffer(cbor.encode(output))
836
+ };
837
+ const serialized = serializeWithEncoding(
838
+ encoding,
839
+ responseData,
840
+ HTTP_ACTION_RESPONSE_VERSIONED
841
+ );
842
+ return c.body(serialized, 200, {
843
+ "Content-Type": contentTypeForEncoding(encoding)
844
+ });
845
+ }
846
+ async function handleConnectionMessage(c, _runConfig, actorDriver, connId, connToken, actorId) {
847
+ const encoding = getRequestEncoding(c.req);
848
+ const arrayBuffer = await c.req.arrayBuffer();
849
+ const message = deserializeWithEncoding(
850
+ encoding,
851
+ new Uint8Array(arrayBuffer),
852
+ TO_SERVER_VERSIONED
853
+ );
854
+ const actor2 = await actorDriver.loadActor(actorId);
855
+ const conn = actor2.conns.get(connId);
856
+ if (!conn) {
857
+ throw new ConnNotFound(connId);
858
+ }
859
+ if (conn._token !== connToken) {
860
+ throw new IncorrectConnToken();
861
+ }
862
+ await actor2.processMessage(message, conn);
863
+ return c.json({});
864
+ }
865
+ async function handleRawWebSocketHandler(req, path3, actorDriver, actorId, authData) {
866
+ const actor2 = await actorDriver.loadActor(actorId);
867
+ return {
868
+ onOpen: (_evt, ws) => {
869
+ const adapter = new HonoWebSocketAdapter(ws);
870
+ ws.__adapter = adapter;
871
+ const url = new URL(path3, "http://actor");
872
+ const pathname = url.pathname.replace(/^\/raw\/websocket\/?/, "") || "/";
873
+ const normalizedPath = (pathname.startsWith("/") ? pathname : "/" + pathname) + url.search;
874
+ let newRequest;
875
+ if (req) {
876
+ newRequest = new Request(`http://actor${normalizedPath}`, req);
877
+ } else {
878
+ newRequest = new Request(`http://actor${normalizedPath}`, {
879
+ method: "GET"
880
+ });
881
+ }
882
+ actor2.rLog.debug({
883
+ msg: "rewriting websocket url",
884
+ from: path3,
885
+ to: newRequest.url,
886
+ pathname: url.pathname,
887
+ search: url.search,
888
+ normalizedPath
889
+ });
890
+ actor2.handleWebSocket(adapter, {
891
+ request: newRequest
892
+ });
893
+ },
894
+ onMessage: (event, ws) => {
895
+ const adapter = ws.__adapter;
896
+ if (adapter) {
897
+ adapter._handleMessage(event);
898
+ }
899
+ },
900
+ onClose: (evt, ws) => {
901
+ const adapter = ws.__adapter;
902
+ if (adapter) {
903
+ adapter._handleClose((evt == null ? void 0 : evt.code) || 1006, (evt == null ? void 0 : evt.reason) || "");
904
+ }
905
+ },
906
+ onError: (error, ws) => {
907
+ const adapter = ws.__adapter;
908
+ if (adapter) {
909
+ adapter._handleError(error);
910
+ }
911
+ }
912
+ };
913
+ }
914
+ function getRequestEncoding(req) {
915
+ const encodingParam = req.header(HEADER_ENCODING);
916
+ if (!encodingParam) {
917
+ throw new InvalidEncoding("undefined");
918
+ }
919
+ const result = EncodingSchema.safeParse(encodingParam);
920
+ if (!result.success) {
921
+ throw new InvalidEncoding(encodingParam);
922
+ }
923
+ return result.data;
924
+ }
925
+ function getRequestExposeInternalError(_req) {
926
+ return false;
927
+ }
928
+ function getRequestConnParams(req) {
929
+ const paramsParam = req.header(HEADER_CONN_PARAMS);
930
+ if (!paramsParam) {
931
+ return null;
932
+ }
933
+ try {
934
+ return JSON.parse(paramsParam);
935
+ } catch (err) {
936
+ throw new InvalidParams(
937
+ `Invalid params JSON: ${stringifyError(err)}`
938
+ );
939
+ }
940
+ }
941
+
942
+ // src/common/router.ts
943
+ import * as cbor2 from "cbor-x";
944
+ function logger2() {
945
+ return getLogger("router");
946
+ }
947
+ function loggerMiddleware(logger7) {
948
+ return async (c, next) => {
949
+ const method = c.req.method;
950
+ const path3 = c.req.path;
951
+ const startTime = Date.now();
952
+ await next();
953
+ const duration = Date.now() - startTime;
954
+ logger7.debug({
955
+ msg: "http request",
956
+ method,
957
+ path: path3,
958
+ status: c.res.status,
959
+ dt: `${duration}ms`,
960
+ reqSize: c.req.header("content-length"),
961
+ resSize: c.res.headers.get("content-length"),
962
+ userAgent: c.req.header("user-agent")
963
+ });
964
+ };
965
+ }
966
+ function handleRouteNotFound(c) {
967
+ return c.text("Not Found (RivetKit)", 404);
968
+ }
969
+ function handleRouteError(error, c) {
970
+ const exposeInternalError = getRequestExposeInternalError(c.req.raw);
971
+ const { statusCode, group, code, message, metadata } = deconstructError(
972
+ error,
973
+ logger2(),
974
+ {
975
+ method: c.req.method,
976
+ path: c.req.path
977
+ },
978
+ exposeInternalError
979
+ );
980
+ let encoding;
981
+ try {
982
+ encoding = getRequestEncoding(c.req);
983
+ } catch (_) {
984
+ encoding = "json";
985
+ }
986
+ const output = serializeWithEncoding(
987
+ encoding,
988
+ {
989
+ group,
990
+ code,
991
+ message,
992
+ // TODO: Cannot serialize non-binary meta since it requires ArrayBuffer atm
993
+ metadata: encodingIsBinary(encoding) ? bufferToArrayBuffer(cbor2.encode(metadata)) : null
994
+ },
995
+ HTTP_RESPONSE_ERROR_VERSIONED
996
+ );
997
+ return c.body(output, { status: statusCode });
998
+ }
999
+
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
+ // src/actor/router.ts
1065
+ function createActorRouter(runConfig, actorDriver) {
1066
+ const router = new Hono({ strict: false });
1067
+ router.use("*", loggerMiddleware(loggerWithoutContext()));
1068
+ router.get("/", (c) => {
1069
+ return c.text(
1070
+ "This is an RivetKit actor.\n\nLearn more at https://rivetkit.org"
1071
+ );
1072
+ });
1073
+ router.get("/health", (c) => {
1074
+ return c.text("ok");
1075
+ });
1076
+ router.get(PATH_CONNECT_WEBSOCKET, async (c) => {
1077
+ var _a;
1078
+ const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
1079
+ if (upgradeWebSocket) {
1080
+ 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);
1084
+ const encoding = EncodingSchema.parse(encodingRaw);
1085
+ const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1086
+ const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1087
+ return await handleWebSocketConnect(
1088
+ c2.req.raw,
1089
+ runConfig,
1090
+ actorDriver,
1091
+ c2.env.actorId,
1092
+ encoding,
1093
+ connParams,
1094
+ authData
1095
+ );
1096
+ })(c, noopNext());
1097
+ } else {
1098
+ return c.text(
1099
+ "WebSockets are not enabled for this driver. Use SSE instead.",
1100
+ 400
1101
+ );
1102
+ }
1103
+ });
1104
+ 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);
1111
+ });
1112
+ router.post("/action/:action", async (c) => {
1113
+ 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);
1118
+ }
1119
+ return handleAction(
1120
+ c,
1121
+ runConfig,
1122
+ actorDriver,
1123
+ actionName,
1124
+ c.env.actorId,
1125
+ authData
1126
+ );
1127
+ });
1128
+ router.post("/connections/message", async (c) => {
1129
+ const connId = c.req.header(HEADER_CONN_ID);
1130
+ const connToken = c.req.header(HEADER_CONN_TOKEN);
1131
+ if (!connId || !connToken) {
1132
+ throw new Error("Missing required parameters");
1133
+ }
1134
+ return handleConnectionMessage(
1135
+ c,
1136
+ runConfig,
1137
+ actorDriver,
1138
+ connId,
1139
+ connToken,
1140
+ c.env.actorId
1141
+ );
1142
+ });
1143
+ 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
+ const actor2 = await actorDriver.loadActor(c.env.actorId);
1150
+ const url = new URL(c.req.url);
1151
+ const originalPath = url.pathname.replace(/^\/raw\/http/, "") || "/";
1152
+ const correctedUrl = new URL(originalPath + url.search, url.origin);
1153
+ const correctedRequest = new Request(correctedUrl, {
1154
+ method: c.req.method,
1155
+ headers: c.req.raw.headers,
1156
+ body: c.req.raw.body,
1157
+ duplex: "half"
1158
+ });
1159
+ loggerWithoutContext().debug({
1160
+ msg: "rewriting http url",
1161
+ from: c.req.url,
1162
+ to: correctedRequest.url
1163
+ });
1164
+ const response = await actor2.handleFetch(correctedRequest, {
1165
+ auth: authData
1166
+ });
1167
+ if (!response) {
1168
+ throw new InternalError("handleFetch returned void unexpectedly");
1169
+ }
1170
+ return response;
1171
+ });
1172
+ router.get(`${PATH_RAW_WEBSOCKET_PREFIX}*`, async (c) => {
1173
+ var _a;
1174
+ const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
1175
+ if (upgradeWebSocket) {
1176
+ 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
+ const url = new URL(c2.req.url);
1184
+ const pathWithQuery = c2.req.path + url.search;
1185
+ loggerWithoutContext().debug({
1186
+ msg: "actor router raw websocket",
1187
+ path: c2.req.path,
1188
+ url: c2.req.url,
1189
+ search: url.search,
1190
+ pathWithQuery
1191
+ });
1192
+ return await handleRawWebSocketHandler(
1193
+ c2.req.raw,
1194
+ pathWithQuery,
1195
+ actorDriver,
1196
+ c2.env.actorId,
1197
+ authData
1198
+ );
1199
+ })(c, noopNext());
1200
+ } else {
1201
+ return c.text(
1202
+ "WebSockets are not enabled for this driver. Use SSE instead.",
1203
+ 400
1204
+ );
1205
+ }
1206
+ });
1207
+ if (runConfig.inspector.enabled) {
1208
+ router.route(
1209
+ "/inspect",
1210
+ new Hono().use(
1211
+ cors(runConfig.inspector.cors),
1212
+ secureInspector(runConfig),
1213
+ async (c, next) => {
1214
+ const inspector = (await actorDriver.loadActor(c.env.actorId)).inspector;
1215
+ invariant(inspector, "inspector not supported on this platform");
1216
+ c.set("inspector", inspector);
1217
+ return next();
1218
+ }
1219
+ ).route("/", createActorInspectorRouter())
1220
+ );
1221
+ }
1222
+ router.notFound(handleRouteNotFound);
1223
+ router.onError(handleRouteError);
1224
+ return router;
1225
+ }
1226
+
1227
+ // src/actor/mod.ts
1228
+ function actor(input) {
1229
+ const config2 = ActorConfigSchema.parse(input);
1230
+ return new ActorDefinition(config2);
1231
+ }
1232
+
1233
+ // src/common/inline-websocket-adapter2.ts
1234
+ import { WSContext } from "hono/ws";
1235
+ function logger3() {
1236
+ return getLogger("fake-event-source2");
1237
+ }
1238
+ var InlineWebSocketAdapter2 = class {
1239
+ // WebSocket readyState values
1240
+ CONNECTING = 0;
1241
+ OPEN = 1;
1242
+ CLOSING = 2;
1243
+ CLOSED = 3;
1244
+ // Private properties
1245
+ #handler;
1246
+ #wsContext;
1247
+ #readyState = 0;
1248
+ // Start in CONNECTING state
1249
+ #queuedMessages = [];
1250
+ // Event buffering is needed since events can be fired
1251
+ // before JavaScript has a chance to add event listeners (e.g. within the same tick)
1252
+ #bufferedEvents = [];
1253
+ // Event listeners with buffering
1254
+ #eventListeners = /* @__PURE__ */ new Map();
1255
+ constructor(handler) {
1256
+ this.#handler = handler;
1257
+ this.#wsContext = new WSContext({
1258
+ raw: this,
1259
+ send: (data) => {
1260
+ logger3().debug({ msg: "WSContext.send called" });
1261
+ this.#handleMessage(data);
1262
+ },
1263
+ close: (code, reason) => {
1264
+ logger3().debug({ msg: "WSContext.close called", code, reason });
1265
+ this.#handleClose(code || 1e3, reason || "");
1266
+ },
1267
+ // Set readyState to 1 (OPEN) since handlers expect an open connection
1268
+ readyState: 1
1269
+ });
1270
+ this.#initialize();
1271
+ }
1272
+ get readyState() {
1273
+ return this.#readyState;
1274
+ }
1275
+ get binaryType() {
1276
+ return "arraybuffer";
1277
+ }
1278
+ set binaryType(value) {
1279
+ }
1280
+ get bufferedAmount() {
1281
+ return 0;
1282
+ }
1283
+ get extensions() {
1284
+ return "";
1285
+ }
1286
+ get protocol() {
1287
+ return "";
1288
+ }
1289
+ get url() {
1290
+ return "";
1291
+ }
1292
+ send(data) {
1293
+ logger3().debug({ msg: "send called", readyState: this.readyState });
1294
+ if (this.readyState !== this.OPEN) {
1295
+ const error = new Error("WebSocket is not open");
1296
+ logger3().warn({
1297
+ msg: "cannot send message, websocket not open",
1298
+ readyState: this.readyState,
1299
+ dataType: typeof data,
1300
+ dataLength: typeof data === "string" ? data.length : "binary",
1301
+ error
1302
+ });
1303
+ this.#fireError(error);
1304
+ return;
1305
+ }
1306
+ this.#handler.onMessage({ data }, this.#wsContext);
1307
+ }
1308
+ /**
1309
+ * Closes the connection
1310
+ */
1311
+ close(code = 1e3, reason = "") {
1312
+ if (this.readyState === this.CLOSED || this.readyState === this.CLOSING) {
1313
+ return;
1314
+ }
1315
+ logger3().debug({ msg: "closing fake websocket", code, reason });
1316
+ this.#readyState = this.CLOSING;
1317
+ try {
1318
+ this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
1319
+ } catch (err) {
1320
+ logger3().error({ msg: "error closing websocket", error: err });
1321
+ } finally {
1322
+ this.#readyState = this.CLOSED;
1323
+ const closeEvent = {
1324
+ type: "close",
1325
+ wasClean: code === 1e3,
1326
+ code,
1327
+ reason,
1328
+ target: this,
1329
+ currentTarget: this
1330
+ };
1331
+ this.#fireClose(closeEvent);
1332
+ }
1333
+ }
1334
+ /**
1335
+ * Initialize the connection with the handler
1336
+ */
1337
+ async #initialize() {
1338
+ try {
1339
+ logger3().debug({ msg: "fake websocket initializing" });
1340
+ logger3().debug({ msg: "calling handler.onOpen with WSContext" });
1341
+ this.#handler.onOpen(void 0, this.#wsContext);
1342
+ this.#readyState = this.OPEN;
1343
+ logger3().debug({ msg: "fake websocket initialized and now OPEN" });
1344
+ this.#fireOpen();
1345
+ if (this.#queuedMessages.length > 0) {
1346
+ if (this.readyState !== this.OPEN) {
1347
+ logger3().warn({
1348
+ msg: "socket no longer open, dropping queued messages"
1349
+ });
1350
+ return;
1351
+ }
1352
+ logger3().debug({
1353
+ msg: `now processing ${this.#queuedMessages.length} queued messages`
1354
+ });
1355
+ const messagesToProcess = [...this.#queuedMessages];
1356
+ this.#queuedMessages = [];
1357
+ for (const message of messagesToProcess) {
1358
+ logger3().debug({ msg: "processing queued message" });
1359
+ this.#handleMessage(message);
1360
+ }
1361
+ }
1362
+ } catch (err) {
1363
+ logger3().error({
1364
+ msg: "error opening fake websocket",
1365
+ error: err,
1366
+ errorMessage: err instanceof Error ? err.message : String(err),
1367
+ stack: err instanceof Error ? err.stack : void 0
1368
+ });
1369
+ this.#fireError(err);
1370
+ this.close(1011, "Internal error during initialization");
1371
+ }
1372
+ }
1373
+ /**
1374
+ * Handle messages received from the server via the WSContext
1375
+ */
1376
+ #handleMessage(data) {
1377
+ if (this.readyState !== this.OPEN) {
1378
+ logger3().debug({
1379
+ msg: "message received before socket is OPEN, queuing",
1380
+ readyState: this.readyState,
1381
+ dataType: typeof data,
1382
+ dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
1383
+ });
1384
+ this.#queuedMessages.push(data);
1385
+ return;
1386
+ }
1387
+ logger3().debug({
1388
+ msg: "fake websocket received message from server",
1389
+ dataType: typeof data,
1390
+ dataLength: typeof data === "string" ? data.length : data instanceof ArrayBuffer ? data.byteLength : data instanceof Uint8Array ? data.byteLength : "unknown"
1391
+ });
1392
+ const event = {
1393
+ type: "message",
1394
+ data,
1395
+ target: this,
1396
+ currentTarget: this
1397
+ };
1398
+ this.#dispatchEvent("message", event);
1399
+ }
1400
+ #handleClose(code, reason) {
1401
+ if (this.readyState === this.CLOSED) return;
1402
+ this.#readyState = this.CLOSED;
1403
+ const event = {
1404
+ type: "close",
1405
+ code,
1406
+ reason,
1407
+ wasClean: code === 1e3,
1408
+ target: this,
1409
+ currentTarget: this
1410
+ };
1411
+ this.#dispatchEvent("close", event);
1412
+ }
1413
+ addEventListener(type, listener) {
1414
+ if (!this.#eventListeners.has(type)) {
1415
+ this.#eventListeners.set(type, []);
1416
+ }
1417
+ this.#eventListeners.get(type).push(listener);
1418
+ this.#flushBufferedEvents(type);
1419
+ }
1420
+ removeEventListener(type, listener) {
1421
+ const listeners = this.#eventListeners.get(type);
1422
+ if (listeners) {
1423
+ const index = listeners.indexOf(listener);
1424
+ if (index !== -1) {
1425
+ listeners.splice(index, 1);
1426
+ }
1427
+ }
1428
+ }
1429
+ #dispatchEvent(type, event) {
1430
+ const listeners = this.#eventListeners.get(type);
1431
+ if (listeners && listeners.length > 0) {
1432
+ logger3().debug(
1433
+ `dispatching ${type} event to ${listeners.length} listeners`
1434
+ );
1435
+ for (const listener of listeners) {
1436
+ try {
1437
+ listener(event);
1438
+ } catch (err) {
1439
+ logger3().error({
1440
+ msg: `error in ${type} event listener`,
1441
+ error: err
1442
+ });
1443
+ }
1444
+ }
1445
+ } else {
1446
+ logger3().debug({
1447
+ msg: `no ${type} listeners registered, buffering event`
1448
+ });
1449
+ this.#bufferedEvents.push({ type, event });
1450
+ }
1451
+ switch (type) {
1452
+ case "open":
1453
+ if (this.#onopen) {
1454
+ try {
1455
+ this.#onopen(event);
1456
+ } catch (error) {
1457
+ logger3().error({ msg: "error in onopen handler", error });
1458
+ }
1459
+ }
1460
+ break;
1461
+ case "close":
1462
+ if (this.#onclose) {
1463
+ try {
1464
+ this.#onclose(event);
1465
+ } catch (error) {
1466
+ logger3().error({ msg: "error in onclose handler", error });
1467
+ }
1468
+ }
1469
+ break;
1470
+ case "error":
1471
+ if (this.#onerror) {
1472
+ try {
1473
+ this.#onerror(event);
1474
+ } catch (error) {
1475
+ logger3().error({ msg: "error in onerror handler", error });
1476
+ }
1477
+ }
1478
+ break;
1479
+ case "message":
1480
+ if (this.#onmessage) {
1481
+ try {
1482
+ this.#onmessage(event);
1483
+ } catch (error) {
1484
+ logger3().error({ msg: "error in onmessage handler", error });
1485
+ }
1486
+ }
1487
+ break;
1488
+ }
1489
+ }
1490
+ dispatchEvent(event) {
1491
+ this.#dispatchEvent(event.type, event);
1492
+ return true;
1493
+ }
1494
+ #flushBufferedEvents(type) {
1495
+ const eventsToFlush = this.#bufferedEvents.filter(
1496
+ (buffered) => buffered.type === type
1497
+ );
1498
+ this.#bufferedEvents = this.#bufferedEvents.filter(
1499
+ (buffered) => buffered.type !== type
1500
+ );
1501
+ for (const { event } of eventsToFlush) {
1502
+ this.#dispatchEvent(type, event);
1503
+ }
1504
+ }
1505
+ #fireOpen() {
1506
+ try {
1507
+ const event = {
1508
+ type: "open",
1509
+ target: this,
1510
+ currentTarget: this
1511
+ };
1512
+ this.#dispatchEvent("open", event);
1513
+ } catch (err) {
1514
+ logger3().error({ msg: "error in open event", error: err });
1515
+ }
1516
+ }
1517
+ #fireClose(event) {
1518
+ try {
1519
+ this.#dispatchEvent("close", event);
1520
+ } catch (err) {
1521
+ logger3().error({ msg: "error in close event", error: err });
1522
+ }
1523
+ }
1524
+ #fireError(error) {
1525
+ try {
1526
+ const event = {
1527
+ type: "error",
1528
+ target: this,
1529
+ currentTarget: this,
1530
+ error,
1531
+ message: error instanceof Error ? error.message : String(error)
1532
+ };
1533
+ this.#dispatchEvent("error", event);
1534
+ } catch (err) {
1535
+ logger3().error({ msg: "error in error event", error: err });
1536
+ }
1537
+ logger3().error({ msg: "websocket error", error });
1538
+ }
1539
+ // Event handler properties with getters/setters
1540
+ #onopen = null;
1541
+ #onclose = null;
1542
+ #onerror = null;
1543
+ #onmessage = null;
1544
+ get onopen() {
1545
+ return this.#onopen;
1546
+ }
1547
+ set onopen(handler) {
1548
+ this.#onopen = handler;
1549
+ }
1550
+ get onclose() {
1551
+ return this.#onclose;
1552
+ }
1553
+ set onclose(handler) {
1554
+ this.#onclose = handler;
1555
+ }
1556
+ get onerror() {
1557
+ return this.#onerror;
1558
+ }
1559
+ set onerror(handler) {
1560
+ this.#onerror = handler;
1561
+ }
1562
+ get onmessage() {
1563
+ return this.#onmessage;
1564
+ }
1565
+ set onmessage(handler) {
1566
+ this.#onmessage = handler;
1567
+ }
1568
+ };
1569
+
1570
+ // src/drivers/engine/actor-driver.ts
1571
+ import { Runner } from "@rivetkit/engine-runner";
1572
+ import * as cbor3 from "cbor-x";
1573
+ import { WSContext as WSContext2 } from "hono/ws";
1574
+ import invariant2 from "invariant";
1575
+
1576
+ // src/drivers/engine/kv.ts
1577
+ var KEYS = {
1578
+ PERSIST_DATA: Uint8Array.from([1])
1579
+ };
1580
+
1581
+ // src/drivers/engine/log.ts
1582
+ function logger4() {
1583
+ return getLogger("driver-engine");
1584
+ }
1585
+
1586
+ // src/drivers/engine/actor-driver.ts
1587
+ var EngineActorDriver = class {
1588
+ #registryConfig;
1589
+ #runConfig;
1590
+ #managerDriver;
1591
+ #inlineClient;
1592
+ #config;
1593
+ #runner;
1594
+ #actors = /* @__PURE__ */ new Map();
1595
+ #actorRouter;
1596
+ #version = 1;
1597
+ // Version for the runner protocol
1598
+ constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
1599
+ this.#registryConfig = registryConfig;
1600
+ this.#runConfig = runConfig;
1601
+ this.#managerDriver = managerDriver;
1602
+ this.#inlineClient = inlineClient;
1603
+ this.#config = config2;
1604
+ this.#actorRouter = createActorRouter(runConfig, this);
1605
+ let hasDisconnected = false;
1606
+ const runnerConfig = {
1607
+ version: this.#version,
1608
+ endpoint: config2.endpoint,
1609
+ pegboardEndpoint: config2.pegboardEndpoint,
1610
+ namespace: config2.namespace,
1611
+ totalSlots: config2.totalSlots,
1612
+ runnerName: config2.runnerName,
1613
+ runnerKey: config2.runnerKey,
1614
+ metadata: {
1615
+ inspectorToken: this.#runConfig.inspector.token()
1616
+ },
1617
+ prepopulateActorNames: Object.fromEntries(
1618
+ Object.keys(this.#registryConfig.use).map((name) => [
1619
+ name,
1620
+ { metadata: {} }
1621
+ ])
1622
+ ),
1623
+ onConnected: () => {
1624
+ if (hasDisconnected) {
1625
+ logger4().info({
1626
+ msg: "runner reconnected",
1627
+ namespace: this.#config.namespace,
1628
+ runnerName: this.#config.runnerName
1629
+ });
1630
+ } else {
1631
+ logger4().debug({
1632
+ msg: "runner connected",
1633
+ namespace: this.#config.namespace,
1634
+ runnerName: this.#config.runnerName
1635
+ });
1636
+ }
1637
+ },
1638
+ onDisconnected: () => {
1639
+ logger4().warn({
1640
+ msg: "runner disconnected",
1641
+ namespace: this.#config.namespace,
1642
+ runnerName: this.#config.runnerName
1643
+ });
1644
+ hasDisconnected = true;
1645
+ },
1646
+ onShutdown: () => {
1647
+ },
1648
+ fetch: this.#runnerFetch.bind(this),
1649
+ websocket: this.#runnerWebSocket.bind(this),
1650
+ onActorStart: this.#runnerOnActorStart.bind(this),
1651
+ onActorStop: this.#runnerOnActorStop.bind(this),
1652
+ logger: getLogger("engine-runner")
1653
+ };
1654
+ this.#runner = new Runner(runnerConfig);
1655
+ this.#runner.start();
1656
+ logger4().debug({
1657
+ msg: "engine runner started",
1658
+ endpoint: config2.endpoint,
1659
+ namespace: config2.namespace,
1660
+ runnerName: config2.runnerName
1661
+ });
1662
+ }
1663
+ async #loadActorHandler(actorId) {
1664
+ const handler = this.#actors.get(actorId);
1665
+ if (!handler) throw new Error(`Actor handler does not exist ${actorId}`);
1666
+ if (handler.actorStartPromise) await handler.actorStartPromise.promise;
1667
+ if (!handler.actor) throw new Error("Actor should be loaded");
1668
+ return handler;
1669
+ }
1670
+ async loadActor(actorId) {
1671
+ const handler = await this.#loadActorHandler(actorId);
1672
+ if (!handler.actor) throw new Error(`Actor ${actorId} failed to load`);
1673
+ return handler.actor;
1674
+ }
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
+ getContext(actorId) {
1683
+ return {};
1684
+ }
1685
+ async readPersistedData(actorId) {
1686
+ const handler = this.#actors.get(actorId);
1687
+ if (!handler) throw new Error(`Actor ${actorId} not loaded`);
1688
+ if (handler.persistedData) return handler.persistedData;
1689
+ const [value] = await this.#runner.kvGet(actorId, [KEYS.PERSIST_DATA]);
1690
+ if (value !== null) {
1691
+ handler.persistedData = value;
1692
+ return value;
1693
+ } else {
1694
+ return void 0;
1695
+ }
1696
+ }
1697
+ async writePersistedData(actorId, data) {
1698
+ const handler = this.#actors.get(actorId);
1699
+ if (!handler) throw new Error(`Actor ${actorId} not loaded`);
1700
+ handler.persistedData = data;
1701
+ await this.#runner.kvPut(actorId, [[KEYS.PERSIST_DATA, data]]);
1702
+ }
1703
+ async setAlarm(actor2, timestamp) {
1704
+ }
1705
+ async getDatabase(_actorId) {
1706
+ return void 0;
1707
+ }
1708
+ // Runner lifecycle callbacks
1709
+ async #runnerOnActorStart(actorId, generation, config2) {
1710
+ var _a;
1711
+ logger4().debug({
1712
+ msg: "runner actor starting",
1713
+ actorId,
1714
+ name: config2.name,
1715
+ key: config2.key,
1716
+ generation
1717
+ });
1718
+ let input;
1719
+ if (config2.input) {
1720
+ input = cbor3.decode(config2.input);
1721
+ }
1722
+ let handler = this.#actors.get(actorId);
1723
+ if (!handler) {
1724
+ handler = {
1725
+ genericConnGlobalState: new GenericConnGlobalState(),
1726
+ actorStartPromise: Promise.withResolvers(),
1727
+ persistedData: serializeEmptyPersistData(input)
1728
+ };
1729
+ this.#actors.set(actorId, handler);
1730
+ }
1731
+ const name = config2.name;
1732
+ invariant2(config2.key, "actor should have a key");
1733
+ const key = deserializeActorKey(config2.key);
1734
+ const definition = lookupInRegistry(
1735
+ this.#registryConfig,
1736
+ config2.name
1737
+ // TODO: Remove cast
1738
+ );
1739
+ handler.actor = definition.instantiate();
1740
+ const connDrivers = createGenericConnDrivers(
1741
+ handler.genericConnGlobalState
1742
+ );
1743
+ await handler.actor.start(
1744
+ connDrivers,
1745
+ this,
1746
+ this.#inlineClient,
1747
+ actorId,
1748
+ name,
1749
+ key,
1750
+ "unknown"
1751
+ // TODO: Add regions
1752
+ );
1753
+ (_a = handler.actorStartPromise) == null ? void 0 : _a.resolve();
1754
+ handler.actorStartPromise = void 0;
1755
+ logger4().debug({ msg: "runner actor started", actorId, name, key });
1756
+ }
1757
+ async #runnerOnActorStop(actorId, generation) {
1758
+ logger4().debug({ msg: "runner actor stopping", actorId, generation });
1759
+ const handler = this.#actors.get(actorId);
1760
+ if (handler == null ? void 0 : handler.actor) {
1761
+ await handler.actor._stop();
1762
+ this.#actors.delete(actorId);
1763
+ }
1764
+ logger4().debug({ msg: "runner actor stopped", actorId });
1765
+ }
1766
+ async #runnerFetch(actorId, request) {
1767
+ logger4().debug({
1768
+ msg: "runner fetch",
1769
+ actorId,
1770
+ url: request.url,
1771
+ method: request.method
1772
+ });
1773
+ return await this.#actorRouter.fetch(request, { actorId });
1774
+ }
1775
+ async #runnerWebSocket(actorId, websocketRaw, request) {
1776
+ const websocket = websocketRaw;
1777
+ logger4().debug({ msg: "runner websocket", actorId, url: request.url });
1778
+ 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);
1782
+ const encoding = EncodingSchema.parse(encodingRaw);
1783
+ const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
1784
+ const authData = authDataRaw ? JSON.parse(authDataRaw) : void 0;
1785
+ let wsHandlerPromise;
1786
+ if (url.pathname === PATH_CONNECT_WEBSOCKET) {
1787
+ wsHandlerPromise = handleWebSocketConnect(
1788
+ request,
1789
+ this.#runConfig,
1790
+ this,
1791
+ actorId,
1792
+ encoding,
1793
+ connParams,
1794
+ authData
1795
+ );
1796
+ } else if (url.pathname.startsWith(PATH_RAW_WEBSOCKET_PREFIX)) {
1797
+ wsHandlerPromise = handleRawWebSocketHandler(
1798
+ request,
1799
+ url.pathname + url.search,
1800
+ this,
1801
+ actorId,
1802
+ authData
1803
+ );
1804
+ } else {
1805
+ throw new Error(`Unreachable path: ${url.pathname}`);
1806
+ }
1807
+ const wsContext = new WSContext2(websocket);
1808
+ wsHandlerPromise.catch((err) => {
1809
+ logger4().error({ msg: "building websocket handlers errored", err });
1810
+ wsContext.close(1011, `${err}`);
1811
+ });
1812
+ if (websocket.readyState === 1) {
1813
+ wsHandlerPromise.then((x) => {
1814
+ var _a;
1815
+ return (_a = x.onOpen) == null ? void 0 : _a.call(x, new Event("open"), wsContext);
1816
+ });
1817
+ } else {
1818
+ websocket.addEventListener("open", (event) => {
1819
+ wsHandlerPromise.then((x) => {
1820
+ var _a;
1821
+ return (_a = x.onOpen) == null ? void 0 : _a.call(x, event, wsContext);
1822
+ });
1823
+ });
1824
+ }
1825
+ websocket.addEventListener("message", (event) => {
1826
+ wsHandlerPromise.then((x) => {
1827
+ var _a;
1828
+ return (_a = x.onMessage) == null ? void 0 : _a.call(x, event, wsContext);
1829
+ });
1830
+ });
1831
+ websocket.addEventListener("close", (event) => {
1832
+ wsHandlerPromise.then((x) => {
1833
+ var _a;
1834
+ return (_a = x.onClose) == null ? void 0 : _a.call(x, event, wsContext);
1835
+ });
1836
+ });
1837
+ websocket.addEventListener("error", (event) => {
1838
+ wsHandlerPromise.then((x) => {
1839
+ var _a;
1840
+ return (_a = x.onError) == null ? void 0 : _a.call(x, event, wsContext);
1841
+ });
1842
+ });
1843
+ }
1844
+ async sleep(actorId) {
1845
+ this.#runner.sleepActor(actorId);
1846
+ }
1847
+ async shutdown(immediate) {
1848
+ logger4().info({ msg: "stopping engine actor driver" });
1849
+ await this.#runner.shutdown(immediate);
1850
+ }
1851
+ };
1852
+
1853
+ // src/drivers/engine/config.ts
1854
+ import { z as z2 } from "zod";
1855
+ var ConfigSchema = z2.object({
1856
+ app: z2.custom().optional(),
1857
+ endpoint: z2.string().default(
1858
+ () => getEnvUniversal("RIVET_ENGINE") ?? "http://localhost:6420"
1859
+ ),
1860
+ pegboardEndpoint: z2.string().optional(),
1861
+ namespace: z2.string().default(() => getEnvUniversal("RIVET_NAMESPACE") ?? "default"),
1862
+ runnerName: z2.string().default(() => getEnvUniversal("RIVET_RUNNER") ?? "rivetkit"),
1863
+ // TODO: Automatically attempt to determine key by common env vars (e.g. k8s pod name)
1864
+ runnerKey: z2.string().default(
1865
+ () => getEnvUniversal("RIVET_RUNNER_KEY") ?? crypto.randomUUID()
1866
+ ),
1867
+ totalSlots: z2.number().default(1e5)
1868
+ }).default({});
1869
+
1870
+ // src/drivers/engine/mod.ts
1871
+ function createEngineDriver(inputConfig) {
1872
+ const config2 = ConfigSchema.parse(inputConfig);
1873
+ return {
1874
+ name: "engine",
1875
+ manager: (_registryConfig, runConfig) => {
1876
+ return new RemoteManagerDriver(runConfig);
1877
+ },
1878
+ actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
1879
+ return new EngineActorDriver(
1880
+ registryConfig,
1881
+ runConfig,
1882
+ managerDriver,
1883
+ inlineClient,
1884
+ config2
1885
+ );
1886
+ }
1887
+ };
1888
+ }
1889
+
1890
+ // src/drivers/file-system/actor.ts
1891
+ var FileSystemActorDriver = class {
1892
+ #registryConfig;
1893
+ #runConfig;
1894
+ #managerDriver;
1895
+ #inlineClient;
1896
+ #state;
1897
+ constructor(registryConfig, runConfig, managerDriver, inlineClient, state) {
1898
+ this.#registryConfig = registryConfig;
1899
+ this.#runConfig = runConfig;
1900
+ this.#managerDriver = managerDriver;
1901
+ this.#inlineClient = inlineClient;
1902
+ this.#state = state;
1903
+ }
1904
+ async loadActor(actorId) {
1905
+ return this.#state.startActor(
1906
+ this.#registryConfig,
1907
+ this.#runConfig,
1908
+ this.#inlineClient,
1909
+ this,
1910
+ actorId
1911
+ );
1912
+ }
1913
+ getGenericConnGlobalState(actorId) {
1914
+ return this.#state.getActorOrError(actorId).genericConnGlobalState;
1915
+ }
1916
+ /**
1917
+ * Get the current storage directory path
1918
+ */
1919
+ get storagePath() {
1920
+ return this.#state.storagePath;
1921
+ }
1922
+ getContext(_actorId) {
1923
+ return {};
1924
+ }
1925
+ async readPersistedData(actorId) {
1926
+ return new Uint8Array(
1927
+ (await this.#state.loadActorStateOrError(actorId)).persistedData
1928
+ );
1929
+ }
1930
+ async writePersistedData(actorId, data) {
1931
+ const state = await this.#state.loadActorStateOrError(actorId);
1932
+ await this.#state.writeActor(actorId, {
1933
+ ...state,
1934
+ persistedData: bufferToArrayBuffer(data)
1935
+ });
1936
+ }
1937
+ async setAlarm(actor2, timestamp) {
1938
+ await this.#state.setActorAlarm(actor2.id, timestamp);
1939
+ }
1940
+ getDatabase(actorId) {
1941
+ return this.#state.createDatabase(actorId);
1942
+ }
1943
+ sleep(actorId) {
1944
+ return this.#state.sleepActor(actorId);
1945
+ }
1946
+ };
1947
+
1948
+ // src/drivers/file-system/global-state.ts
1949
+ import * as crypto4 from "crypto";
1950
+ import * as fsSync2 from "fs";
1951
+ import * as fs2 from "fs/promises";
1952
+ import * as path2 from "path";
1953
+ import invariant3 from "invariant";
1954
+
1955
+ // dist/schemas/file-system-driver/v1.ts
1956
+ import * as bare from "@bare-ts/lib";
1957
+ var config = /* @__PURE__ */ bare.Config({});
1958
+ function read0(bc) {
1959
+ const len = bare.readUintSafe(bc);
1960
+ if (len === 0) {
1961
+ return [];
1962
+ }
1963
+ const result = [bare.readString(bc)];
1964
+ for (let i = 1; i < len; i++) {
1965
+ result[i] = bare.readString(bc);
1966
+ }
1967
+ return result;
1968
+ }
1969
+ function write0(bc, x) {
1970
+ bare.writeUintSafe(bc, x.length);
1971
+ for (let i = 0; i < x.length; i++) {
1972
+ bare.writeString(bc, x[i]);
1973
+ }
1974
+ }
1975
+ function readActorState(bc) {
1976
+ return {
1977
+ actorId: bare.readString(bc),
1978
+ name: bare.readString(bc),
1979
+ key: read0(bc),
1980
+ persistedData: bare.readData(bc),
1981
+ createdAt: bare.readU64(bc)
1982
+ };
1983
+ }
1984
+ function writeActorState(bc, x) {
1985
+ bare.writeString(bc, x.actorId);
1986
+ bare.writeString(bc, x.name);
1987
+ write0(bc, x.key);
1988
+ bare.writeData(bc, x.persistedData);
1989
+ bare.writeU64(bc, x.createdAt);
1990
+ }
1991
+ function encodeActorState(x) {
1992
+ const bc = new bare.ByteCursor(
1993
+ new Uint8Array(config.initialBufferLength),
1994
+ config
1995
+ );
1996
+ writeActorState(bc, x);
1997
+ return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
1998
+ }
1999
+ function decodeActorState(bytes) {
2000
+ const bc = new bare.ByteCursor(bytes, config);
2001
+ const result = readActorState(bc);
2002
+ if (bc.offset < bc.view.byteLength) {
2003
+ throw new bare.BareError(bc.offset, "remaining bytes");
2004
+ }
2005
+ return result;
2006
+ }
2007
+ function readActorAlarm(bc) {
2008
+ return {
2009
+ actorId: bare.readString(bc),
2010
+ timestamp: bare.readUint(bc)
2011
+ };
2012
+ }
2013
+ function writeActorAlarm(bc, x) {
2014
+ bare.writeString(bc, x.actorId);
2015
+ bare.writeUint(bc, x.timestamp);
2016
+ }
2017
+ function encodeActorAlarm(x) {
2018
+ const bc = new bare.ByteCursor(
2019
+ new Uint8Array(config.initialBufferLength),
2020
+ config
2021
+ );
2022
+ writeActorAlarm(bc, x);
2023
+ return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset);
2024
+ }
2025
+ function decodeActorAlarm(bytes) {
2026
+ const bc = new bare.ByteCursor(bytes, config);
2027
+ const result = readActorAlarm(bc);
2028
+ if (bc.offset < bc.view.byteLength) {
2029
+ throw new bare.BareError(bc.offset, "remaining bytes");
2030
+ }
2031
+ return result;
2032
+ }
2033
+
2034
+ // src/schemas/file-system-driver/versioned.ts
2035
+ var CURRENT_VERSION = 1;
2036
+ var migrations = /* @__PURE__ */ new Map();
2037
+ var ACTOR_STATE_VERSIONED = createVersionedDataHandler({
2038
+ currentVersion: CURRENT_VERSION,
2039
+ migrations,
2040
+ serializeVersion: (data) => encodeActorState(data),
2041
+ deserializeVersion: (bytes) => decodeActorState(bytes)
2042
+ });
2043
+ var ACTOR_ALARM_VERSIONED = createVersionedDataHandler({
2044
+ currentVersion: CURRENT_VERSION,
2045
+ migrations,
2046
+ serializeVersion: (data) => encodeActorAlarm(data),
2047
+ deserializeVersion: (bytes) => decodeActorAlarm(bytes)
2048
+ });
2049
+
2050
+ // src/drivers/file-system/log.ts
2051
+ function logger5() {
2052
+ return getLogger("driver-fs");
2053
+ }
2054
+
2055
+ // src/drivers/file-system/utils.ts
2056
+ import * as crypto3 from "crypto";
2057
+ import * as fsSync from "fs";
2058
+ import * as fs from "fs/promises";
2059
+ import * as os from "os";
2060
+ import * as path from "path";
2061
+ function generateActorId(name, key) {
2062
+ const jsonString = JSON.stringify([name, key]);
2063
+ const hash = crypto3.createHash("sha256").update(jsonString).digest("hex").substring(0, 16);
2064
+ return hash;
2065
+ }
2066
+ function createHashForPath(dirPath) {
2067
+ const normalizedPath = path.normalize(dirPath);
2068
+ const lastComponent = path.basename(normalizedPath);
2069
+ const hash = crypto3.createHash("sha256").update(normalizedPath).digest("hex").substring(0, 8);
2070
+ return `${lastComponent}-${hash}`;
2071
+ }
2072
+ function getStoragePath(customPath) {
2073
+ const dataPath = getDataPath("rivetkit");
2074
+ const pathToHash = customPath || process.cwd();
2075
+ const dirHash = createHashForPath(pathToHash);
2076
+ return path.join(dataPath, dirHash);
2077
+ }
2078
+ async function pathExists(path3) {
2079
+ try {
2080
+ await fs.access(path3);
2081
+ return true;
2082
+ } catch {
2083
+ return false;
2084
+ }
2085
+ }
2086
+ async function ensureDirectoryExists(directoryPath) {
2087
+ if (!await pathExists(directoryPath)) {
2088
+ await fs.mkdir(directoryPath, { recursive: true });
2089
+ }
2090
+ }
2091
+ function ensureDirectoryExistsSync(directoryPath) {
2092
+ if (!fsSync.existsSync(directoryPath)) {
2093
+ fsSync.mkdirSync(directoryPath, { recursive: true });
2094
+ }
2095
+ }
2096
+ function getDataPath(appName) {
2097
+ const platform = process.platform;
2098
+ const homeDir = os.homedir();
2099
+ switch (platform) {
2100
+ case "win32":
2101
+ return path.join(
2102
+ process.env.APPDATA || path.join(homeDir, "AppData", "Roaming"),
2103
+ appName
2104
+ );
2105
+ case "darwin":
2106
+ return path.join(homeDir, "Library", "Application Support", appName);
2107
+ default:
2108
+ return path.join(
2109
+ process.env.XDG_DATA_HOME || path.join(homeDir, ".local", "share"),
2110
+ appName
2111
+ );
2112
+ }
2113
+ }
2114
+
2115
+ // src/drivers/file-system/global-state.ts
2116
+ var FileSystemGlobalState = class {
2117
+ #storagePath;
2118
+ #stateDir;
2119
+ #dbsDir;
2120
+ #alarmsDir;
2121
+ #persist;
2122
+ #actors = /* @__PURE__ */ new Map();
2123
+ #actorCountOnStartup = 0;
2124
+ #runnerParams;
2125
+ get persist() {
2126
+ return this.#persist;
2127
+ }
2128
+ get storagePath() {
2129
+ return this.#storagePath;
2130
+ }
2131
+ get actorCountOnStartup() {
2132
+ return this.#actorCountOnStartup;
2133
+ }
2134
+ constructor(persist = true, customPath) {
2135
+ this.#persist = persist;
2136
+ this.#storagePath = persist ? getStoragePath(customPath) : "/tmp";
2137
+ this.#stateDir = path2.join(this.#storagePath, "state");
2138
+ this.#dbsDir = path2.join(this.#storagePath, "databases");
2139
+ this.#alarmsDir = path2.join(this.#storagePath, "alarms");
2140
+ if (this.#persist) {
2141
+ ensureDirectoryExistsSync(this.#stateDir);
2142
+ ensureDirectoryExistsSync(this.#dbsDir);
2143
+ ensureDirectoryExistsSync(this.#alarmsDir);
2144
+ try {
2145
+ const actorIds = fsSync2.readdirSync(this.#stateDir);
2146
+ this.#actorCountOnStartup = actorIds.length;
2147
+ } catch (error) {
2148
+ logger5().error({ msg: "failed to count actors", error });
2149
+ }
2150
+ logger5().debug({
2151
+ msg: "file system driver ready",
2152
+ dir: this.#storagePath,
2153
+ actorCount: this.#actorCountOnStartup
2154
+ });
2155
+ try {
2156
+ this.#cleanupTempFilesSync();
2157
+ } catch (err) {
2158
+ logger5().error({ msg: "failed to cleanup temp files", error: err });
2159
+ }
2160
+ } else {
2161
+ logger5().debug({ msg: "memory driver ready" });
2162
+ }
2163
+ }
2164
+ getActorStatePath(actorId) {
2165
+ return path2.join(this.#stateDir, actorId);
2166
+ }
2167
+ getActorDbPath(actorId) {
2168
+ return path2.join(this.#dbsDir, `${actorId}.db`);
2169
+ }
2170
+ getActorAlarmPath(actorId) {
2171
+ return path2.join(this.#alarmsDir, actorId);
2172
+ }
2173
+ async *getActorsIterator(params) {
2174
+ let actorIds = Array.from(this.#actors.keys()).sort();
2175
+ if (fsSync2.existsSync(this.#stateDir)) {
2176
+ actorIds = fsSync2.readdirSync(this.#stateDir).filter((id) => !id.includes(".tmp")).sort();
2177
+ }
2178
+ const startIndex = params.cursor ? actorIds.indexOf(params.cursor) + 1 : 0;
2179
+ for (let i = startIndex; i < actorIds.length; i++) {
2180
+ const actorId = actorIds[i];
2181
+ if (!actorId) {
2182
+ continue;
2183
+ }
2184
+ try {
2185
+ const state = await this.loadActorStateOrError(actorId);
2186
+ yield state;
2187
+ } catch (error) {
2188
+ logger5().error({ msg: "failed to load actor state", actorId, error });
2189
+ }
2190
+ }
2191
+ }
2192
+ /**
2193
+ * Ensures an entry exists for this actor.
2194
+ *
2195
+ * Used for #createActor and #loadActor.
2196
+ */
2197
+ #upsertEntry(actorId) {
2198
+ let entry = this.#actors.get(actorId);
2199
+ if (entry) {
2200
+ return entry;
2201
+ }
2202
+ entry = {
2203
+ id: actorId,
2204
+ genericConnGlobalState: new GenericConnGlobalState(),
2205
+ removed: false
2206
+ };
2207
+ this.#actors.set(actorId, entry);
2208
+ return entry;
2209
+ }
2210
+ /**
2211
+ * Creates a new actor and writes to file system.
2212
+ */
2213
+ async createActor(actorId, name, key, input) {
2214
+ if (this.#actors.has(actorId)) {
2215
+ throw new ActorAlreadyExists(name, key);
2216
+ }
2217
+ const entry = this.#upsertEntry(actorId);
2218
+ entry.state = {
2219
+ actorId,
2220
+ name,
2221
+ key,
2222
+ createdAt: BigInt(Date.now()),
2223
+ persistedData: bufferToArrayBuffer(serializeEmptyPersistData(input))
2224
+ };
2225
+ await this.writeActor(actorId, entry.state);
2226
+ return entry;
2227
+ }
2228
+ /**
2229
+ * Loads the actor from disk or returns the existing actor entry. This will return an entry even if the actor does not actually exist.
2230
+ */
2231
+ async loadActor(actorId) {
2232
+ const entry = this.#upsertEntry(actorId);
2233
+ if (entry.state) {
2234
+ return entry;
2235
+ }
2236
+ if (!this.#persist) {
2237
+ return entry;
2238
+ }
2239
+ if (entry.loadPromise) {
2240
+ await entry.loadPromise;
2241
+ return entry;
2242
+ }
2243
+ entry.loadPromise = this.loadActorState(entry);
2244
+ return entry.loadPromise;
2245
+ }
2246
+ async loadActorState(entry) {
2247
+ const stateFilePath = this.getActorStatePath(entry.id);
2248
+ try {
2249
+ const stateData = await fs2.readFile(stateFilePath);
2250
+ entry.state = ACTOR_STATE_VERSIONED.deserializeWithEmbeddedVersion(
2251
+ new Uint8Array(stateData)
2252
+ );
2253
+ return entry;
2254
+ } catch (innerError) {
2255
+ if (innerError.code === "ENOENT") {
2256
+ entry.loadPromise = void 0;
2257
+ return entry;
2258
+ }
2259
+ const error = new Error(`Failed to load actor state: ${innerError}`);
2260
+ throw error;
2261
+ }
2262
+ }
2263
+ async loadOrCreateActor(actorId, name, key, input) {
2264
+ const entry = await this.loadActor(actorId);
2265
+ if (!entry.state) {
2266
+ entry.state = {
2267
+ actorId,
2268
+ name,
2269
+ key,
2270
+ createdAt: BigInt(Date.now()),
2271
+ persistedData: bufferToArrayBuffer(serializeEmptyPersistData(input))
2272
+ };
2273
+ await this.writeActor(actorId, entry.state);
2274
+ }
2275
+ return entry;
2276
+ }
2277
+ async sleepActor(actorId) {
2278
+ var _a;
2279
+ invariant3(
2280
+ this.#persist,
2281
+ "cannot sleep actor with memory driver, must use file system driver"
2282
+ );
2283
+ const actor2 = this.#actors.get(actorId);
2284
+ invariant3(actor2, `tried to sleep ${actorId}, does not exist`);
2285
+ if (actor2.loadPromise) await actor2.loadPromise.catch();
2286
+ if ((_a = actor2.startPromise) == null ? void 0 : _a.promise) await actor2.startPromise.promise.catch();
2287
+ actor2.removed = true;
2288
+ invariant3(actor2.actor, "actor should be loaded");
2289
+ await actor2.actor._stop();
2290
+ this.#actors.delete(actorId);
2291
+ }
2292
+ /**
2293
+ * Save actor state to disk.
2294
+ */
2295
+ async writeActor(actorId, state) {
2296
+ if (!this.#persist) {
2297
+ return;
2298
+ }
2299
+ const entry = this.#actors.get(actorId);
2300
+ invariant3(entry, "actor entry does not exist");
2301
+ await this.#performWrite(actorId, state);
2302
+ }
2303
+ async setActorAlarm(actorId, timestamp) {
2304
+ const entry = this.#actors.get(actorId);
2305
+ invariant3(entry, "actor entry does not exist");
2306
+ if (this.#persist) {
2307
+ const alarmPath = this.getActorAlarmPath(actorId);
2308
+ const tempPath = `${alarmPath}.tmp.${crypto4.randomUUID()}`;
2309
+ try {
2310
+ await ensureDirectoryExists(path2.dirname(alarmPath));
2311
+ const alarmData = {
2312
+ actorId,
2313
+ timestamp: BigInt(timestamp)
2314
+ };
2315
+ const data = ACTOR_ALARM_VERSIONED.serializeWithEmbeddedVersion(alarmData);
2316
+ await fs2.writeFile(tempPath, data);
2317
+ await fs2.rename(tempPath, alarmPath);
2318
+ } catch (error) {
2319
+ try {
2320
+ await fs2.unlink(tempPath);
2321
+ } catch {
2322
+ }
2323
+ logger5().error({ msg: "failed to write alarm", actorId, error });
2324
+ throw new Error(`Failed to write alarm: ${error}`);
2325
+ }
2326
+ }
2327
+ this.#scheduleAlarmTimeout(actorId, timestamp);
2328
+ }
2329
+ /**
2330
+ * Perform the actual write operation with atomic writes
2331
+ */
2332
+ async #performWrite(actorId, state) {
2333
+ const dataPath = this.getActorStatePath(actorId);
2334
+ const tempPath = `${dataPath}.tmp.${crypto4.randomUUID()}`;
2335
+ try {
2336
+ await ensureDirectoryExists(path2.dirname(dataPath));
2337
+ const bareState = {
2338
+ actorId: state.actorId,
2339
+ name: state.name,
2340
+ key: state.key,
2341
+ createdAt: state.createdAt,
2342
+ persistedData: state.persistedData
2343
+ };
2344
+ const serializedState = ACTOR_STATE_VERSIONED.serializeWithEmbeddedVersion(bareState);
2345
+ await fs2.writeFile(tempPath, serializedState);
2346
+ await fs2.rename(tempPath, dataPath);
2347
+ } catch (error) {
2348
+ try {
2349
+ await fs2.unlink(tempPath);
2350
+ } catch {
2351
+ }
2352
+ logger5().error({ msg: "failed to save actor state", actorId, error });
2353
+ throw new Error(`Failed to save actor state: ${error}`);
2354
+ }
2355
+ }
2356
+ /**
2357
+ * Call this method after the actor driver has been initiated.
2358
+ *
2359
+ * This will trigger all initial alarms from the file system.
2360
+ *
2361
+ * This needs to be sync since DriverConfig.actor is sync
2362
+ */
2363
+ onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver) {
2364
+ if (this.#runnerParams) {
2365
+ return;
2366
+ }
2367
+ this.#runnerParams = {
2368
+ registryConfig,
2369
+ runConfig,
2370
+ inlineClient,
2371
+ actorDriver
2372
+ };
2373
+ try {
2374
+ this.#loadAlarmsSync();
2375
+ } catch (err) {
2376
+ logger5().error({ msg: "failed to load alarms on startup", error: err });
2377
+ }
2378
+ }
2379
+ async startActor(registryConfig, runConfig, inlineClient, actorDriver, actorId) {
2380
+ var _a;
2381
+ const entry = await this.loadActor(actorId);
2382
+ if (!entry.state) {
2383
+ throw new Error(
2384
+ `Actor does not exist and cannot be started: "${actorId}"`
2385
+ );
2386
+ }
2387
+ if (entry.startPromise) {
2388
+ await entry.startPromise.promise;
2389
+ invariant3(entry.actor, "actor should have loaded");
2390
+ return entry.actor;
2391
+ }
2392
+ if (entry.actor) {
2393
+ return entry.actor;
2394
+ }
2395
+ entry.startPromise = Promise.withResolvers();
2396
+ try {
2397
+ const definition = lookupInRegistry(registryConfig, entry.state.name);
2398
+ entry.actor = definition.instantiate();
2399
+ const connDrivers = createGenericConnDrivers(
2400
+ entry.genericConnGlobalState
2401
+ );
2402
+ await entry.actor.start(
2403
+ connDrivers,
2404
+ actorDriver,
2405
+ inlineClient,
2406
+ actorId,
2407
+ entry.state.name,
2408
+ entry.state.key,
2409
+ "unknown"
2410
+ );
2411
+ entry.startPromise.resolve();
2412
+ entry.startPromise = void 0;
2413
+ return entry.actor;
2414
+ } catch (innerError) {
2415
+ const error = new Error(
2416
+ `Failed to start actor ${actorId}: ${innerError}`,
2417
+ { cause: innerError }
2418
+ );
2419
+ (_a = entry.startPromise) == null ? void 0 : _a.reject(error);
2420
+ entry.startPromise = void 0;
2421
+ throw error;
2422
+ }
2423
+ }
2424
+ async loadActorStateOrError(actorId) {
2425
+ const state = (await this.loadActor(actorId)).state;
2426
+ if (!state) throw new Error(`Actor does not exist: ${actorId}`);
2427
+ return state;
2428
+ }
2429
+ getActorOrError(actorId) {
2430
+ const entry = this.#actors.get(actorId);
2431
+ if (!entry) throw new Error(`No entry for actor: ${actorId}`);
2432
+ return entry;
2433
+ }
2434
+ async createDatabase(actorId) {
2435
+ return this.getActorDbPath(actorId);
2436
+ }
2437
+ /**
2438
+ * Load all persisted alarms from disk and schedule their timers.
2439
+ */
2440
+ #loadAlarmsSync() {
2441
+ try {
2442
+ const files = fsSync2.existsSync(this.#alarmsDir) ? fsSync2.readdirSync(this.#alarmsDir) : [];
2443
+ for (const file of files) {
2444
+ if (file.includes(".tmp.")) continue;
2445
+ const fullPath = path2.join(this.#alarmsDir, file);
2446
+ try {
2447
+ const buf = fsSync2.readFileSync(fullPath);
2448
+ const alarmData = ACTOR_ALARM_VERSIONED.deserializeWithEmbeddedVersion(
2449
+ new Uint8Array(buf)
2450
+ );
2451
+ const timestamp = Number(alarmData.timestamp);
2452
+ if (Number.isFinite(timestamp)) {
2453
+ this.#scheduleAlarmTimeout(alarmData.actorId, timestamp);
2454
+ } else {
2455
+ logger5().debug({ msg: "invalid alarm file contents", file });
2456
+ }
2457
+ } catch (err) {
2458
+ logger5().error({
2459
+ msg: "failed to read alarm file",
2460
+ file,
2461
+ error: stringifyError(err)
2462
+ });
2463
+ }
2464
+ }
2465
+ } catch (err) {
2466
+ logger5().error({ msg: "failed to list alarms directory", error: err });
2467
+ }
2468
+ }
2469
+ /**
2470
+ * Schedule an alarm timer for an actor without writing to disk.
2471
+ */
2472
+ #scheduleAlarmTimeout(actorId, timestamp) {
2473
+ var _a;
2474
+ const entry = this.#upsertEntry(actorId);
2475
+ if (entry.alarmTimestamp !== void 0 && timestamp >= entry.alarmTimestamp) {
2476
+ logger5().debug({
2477
+ msg: "skipping alarm schedule (later than existing)",
2478
+ actorId,
2479
+ timestamp,
2480
+ current: entry.alarmTimestamp
2481
+ });
2482
+ return;
2483
+ }
2484
+ logger5().debug({ msg: "scheduling alarm", actorId, timestamp });
2485
+ (_a = entry.alarmTimeout) == null ? void 0 : _a.abort();
2486
+ entry.alarmTimestamp = timestamp;
2487
+ const delay = Math.max(0, timestamp - Date.now());
2488
+ entry.alarmTimeout = setLongTimeout(async () => {
2489
+ entry.alarmTimestamp = void 0;
2490
+ if (this.#persist) {
2491
+ try {
2492
+ await fs2.unlink(this.getActorAlarmPath(actorId));
2493
+ } catch (err) {
2494
+ if ((err == null ? void 0 : err.code) !== "ENOENT") {
2495
+ logger5().debug({
2496
+ msg: "failed to remove alarm file",
2497
+ actorId,
2498
+ error: stringifyError(err)
2499
+ });
2500
+ }
2501
+ }
2502
+ }
2503
+ try {
2504
+ logger5().debug({ msg: "triggering alarm", actorId, timestamp });
2505
+ const loaded = await this.loadActor(actorId);
2506
+ if (!loaded.state) throw new Error(`Actor does not exist: ${actorId}`);
2507
+ const runnerParams = this.#runnerParams;
2508
+ invariant3(runnerParams, "missing runner params");
2509
+ if (!loaded.actor) {
2510
+ await this.startActor(
2511
+ runnerParams.registryConfig,
2512
+ runnerParams.runConfig,
2513
+ runnerParams.inlineClient,
2514
+ runnerParams.actorDriver,
2515
+ actorId
2516
+ );
2517
+ }
2518
+ invariant3(loaded.actor, "actor should be loaded after wake");
2519
+ await loaded.actor._onAlarm();
2520
+ } catch (err) {
2521
+ logger5().error({
2522
+ msg: "failed to handle alarm",
2523
+ actorId,
2524
+ error: stringifyError(err)
2525
+ });
2526
+ }
2527
+ }, delay);
2528
+ }
2529
+ getOrCreateInspectorAccessToken() {
2530
+ const tokenPath = path2.join(this.#storagePath, "inspector-token");
2531
+ if (fsSync2.existsSync(tokenPath)) {
2532
+ return fsSync2.readFileSync(tokenPath, "utf-8");
2533
+ }
2534
+ const newToken = generateRandomString();
2535
+ fsSync2.writeFileSync(tokenPath, newToken);
2536
+ return newToken;
2537
+ }
2538
+ /**
2539
+ * Cleanup stale temp files on startup (synchronous)
2540
+ */
2541
+ #cleanupTempFilesSync() {
2542
+ try {
2543
+ const files = fsSync2.readdirSync(this.#stateDir);
2544
+ const tempFiles = files.filter((f) => f.includes(".tmp."));
2545
+ const oneHourAgo = Date.now() - 36e5;
2546
+ for (const tempFile of tempFiles) {
2547
+ try {
2548
+ const fullPath = path2.join(this.#stateDir, tempFile);
2549
+ const stat = fsSync2.statSync(fullPath);
2550
+ if (stat.mtimeMs < oneHourAgo) {
2551
+ fsSync2.unlinkSync(fullPath);
2552
+ logger5().info({
2553
+ msg: "cleaned up stale temp file",
2554
+ file: tempFile
2555
+ });
2556
+ }
2557
+ } catch (err) {
2558
+ logger5().debug({
2559
+ msg: "failed to cleanup temp file",
2560
+ file: tempFile,
2561
+ error: err
2562
+ });
2563
+ }
2564
+ }
2565
+ } catch (err) {
2566
+ logger5().error({
2567
+ msg: "failed to read actors directory for cleanup",
2568
+ error: err
2569
+ });
2570
+ }
2571
+ }
2572
+ };
2573
+
2574
+ // src/drivers/file-system/manager.ts
2575
+ import invariant4 from "invariant";
2576
+
2577
+ // src/inspector/manager.ts
2578
+ import { sValidator } from "@hono/standard-validator";
2579
+ import { Hono as Hono2 } from "hono";
2580
+ function createManagerInspectorRouter() {
2581
+ return new Hono2().get("/ping", (c) => {
2582
+ return c.json({ message: "pong" }, 200);
2583
+ }).get("/actors", async (c) => {
2584
+ const limit = Number.parseInt(c.req.query("limit") ?? "") || void 0;
2585
+ const cursor = c.req.query("cursor") || void 0;
2586
+ if (!limit || limit && limit <= 0) {
2587
+ return c.json("Invalid limit", 400);
2588
+ }
2589
+ try {
2590
+ const actors = await c.var.inspector.accessors.getAllActors({
2591
+ limit,
2592
+ cursor
2593
+ });
2594
+ return c.json(actors, 200);
2595
+ } catch (error) {
2596
+ inspectorLogger().error({ msg: "Failed to fetch actors", error });
2597
+ return c.json("Failed to fetch actors", 500);
2598
+ }
2599
+ }).post("/actors", sValidator("json", CreateActorSchema), async (c) => {
2600
+ const actor2 = await c.var.inspector.accessors.createActor(
2601
+ c.req.valid("json")
2602
+ );
2603
+ return c.json(actor2, 201);
2604
+ }).get("/builds", async (c) => {
2605
+ const builds = await c.var.inspector.accessors.getBuilds();
2606
+ return c.json(builds, 200);
2607
+ }).get("/actor/:id", async (c) => {
2608
+ const id = c.req.param("id");
2609
+ const actor2 = await c.var.inspector.accessors.getActorById(id);
2610
+ if (!actor2) {
2611
+ return c.json({ error: "Actor not found" }, 404);
2612
+ }
2613
+ return c.json(actor2, 200);
2614
+ }).get("/bootstrap", async (c) => {
2615
+ const actors = await c.var.inspector.accessors.getAllActors({
2616
+ limit: 10
2617
+ });
2618
+ return c.json({ actors }, 200);
2619
+ });
2620
+ }
2621
+ var ManagerInspector = class {
2622
+ accessors;
2623
+ constructor(accessors) {
2624
+ this.accessors = accessors();
2625
+ inspectorLogger().debug({ msg: "Manager Inspector enabled and ready" });
2626
+ }
2627
+ };
2628
+
2629
+ // src/drivers/file-system/manager.ts
2630
+ var FileSystemManagerDriver = class {
2631
+ #registryConfig;
2632
+ #runConfig;
2633
+ #state;
2634
+ #driverConfig;
2635
+ #actorDriver;
2636
+ #actorRouter;
2637
+ inspector;
2638
+ constructor(registryConfig, runConfig, state, driverConfig) {
2639
+ this.#registryConfig = registryConfig;
2640
+ this.#runConfig = runConfig;
2641
+ this.#state = state;
2642
+ this.#driverConfig = driverConfig;
2643
+ if (runConfig.inspector.enabled) {
2644
+ let transformActor2 = function(actorState) {
2645
+ return {
2646
+ id: actorState.actorId,
2647
+ name: actorState.name,
2648
+ key: actorState.key,
2649
+ startedAt,
2650
+ createdAt: new Date(Number(actorState.createdAt)).toISOString(),
2651
+ features: [
2652
+ "state" /* State */,
2653
+ "connections" /* Connections */,
2654
+ "console" /* Console */,
2655
+ "events-monitoring" /* EventsMonitoring */,
2656
+ "database" /* Database */
2657
+ ]
2658
+ };
2659
+ };
2660
+ var transformActor = transformActor2;
2661
+ if (!this.#runConfig.inspector.token()) {
2662
+ this.#runConfig.inspector.token = () => this.#state.getOrCreateInspectorAccessToken();
2663
+ }
2664
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2665
+ this.inspector = new ManagerInspector(() => {
2666
+ return {
2667
+ getAllActors: async ({ cursor, limit }) => {
2668
+ const itr = this.#state.getActorsIterator({ cursor });
2669
+ const actors = [];
2670
+ for await (const actor2 of itr) {
2671
+ actors.push(transformActor2(actor2));
2672
+ if (limit && actors.length >= limit) {
2673
+ break;
2674
+ }
2675
+ }
2676
+ return actors;
2677
+ },
2678
+ getActorById: async (id) => {
2679
+ try {
2680
+ const result = await this.#state.loadActorStateOrError(id);
2681
+ return transformActor2(result);
2682
+ } catch {
2683
+ return null;
2684
+ }
2685
+ },
2686
+ getBuilds: async () => {
2687
+ return Object.keys(this.#registryConfig.use).map((name) => ({
2688
+ name
2689
+ }));
2690
+ },
2691
+ createActor: async (input) => {
2692
+ const { actorId } = await this.createActor(input);
2693
+ try {
2694
+ const result = await this.#state.loadActorStateOrError(actorId);
2695
+ return transformActor2(result);
2696
+ } catch {
2697
+ return null;
2698
+ }
2699
+ }
2700
+ };
2701
+ });
2702
+ }
2703
+ const inlineClient = createClientWithDriver(this);
2704
+ this.#actorDriver = this.#driverConfig.actor(
2705
+ registryConfig,
2706
+ runConfig,
2707
+ this,
2708
+ inlineClient
2709
+ );
2710
+ this.#actorRouter = createActorRouter(this.#runConfig, this.#actorDriver);
2711
+ }
2712
+ async sendRequest(actorId, actorRequest) {
2713
+ return await this.#actorRouter.fetch(actorRequest, {
2714
+ actorId
2715
+ });
2716
+ }
2717
+ async openWebSocket(path3, actorId, encoding, params) {
2718
+ const pathOnly = path3.split("?")[0];
2719
+ const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2720
+ if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2721
+ const wsHandler = await handleWebSocketConnect(
2722
+ void 0,
2723
+ this.#runConfig,
2724
+ this.#actorDriver,
2725
+ actorId,
2726
+ encoding,
2727
+ params,
2728
+ void 0
2729
+ );
2730
+ return new InlineWebSocketAdapter2(wsHandler);
2731
+ } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2732
+ const wsHandler = await handleRawWebSocketHandler(
2733
+ void 0,
2734
+ path3,
2735
+ this.#actorDriver,
2736
+ actorId,
2737
+ void 0
2738
+ );
2739
+ return new InlineWebSocketAdapter2(wsHandler);
2740
+ } else {
2741
+ throw new Error(`Unreachable path: ${path3}`);
2742
+ }
2743
+ }
2744
+ async proxyRequest(c, actorRequest, actorId) {
2745
+ return await this.#actorRouter.fetch(actorRequest, {
2746
+ actorId
2747
+ });
2748
+ }
2749
+ async proxyWebSocket(c, path3, actorId, encoding, connParams) {
2750
+ var _a, _b;
2751
+ const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
2752
+ invariant4(upgradeWebSocket, "missing getUpgradeWebSocket");
2753
+ const pathOnly = path3.split("?")[0];
2754
+ const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2755
+ if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2756
+ const wsHandler = await handleWebSocketConnect(
2757
+ c.req.raw,
2758
+ this.#runConfig,
2759
+ this.#actorDriver,
2760
+ actorId,
2761
+ encoding,
2762
+ connParams,
2763
+ void 0
2764
+ );
2765
+ return upgradeWebSocket(() => wsHandler)(c, noopNext());
2766
+ } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2767
+ const wsHandler = await handleRawWebSocketHandler(
2768
+ c.req.raw,
2769
+ path3,
2770
+ this.#actorDriver,
2771
+ actorId,
2772
+ void 0
2773
+ );
2774
+ return upgradeWebSocket(() => wsHandler)(c, noopNext());
2775
+ } else {
2776
+ throw new Error(`Unreachable path: ${path3}`);
2777
+ }
2778
+ }
2779
+ async getForId({ actorId }) {
2780
+ const actor2 = await this.#state.loadActor(actorId);
2781
+ if (!actor2.state) {
2782
+ return void 0;
2783
+ }
2784
+ try {
2785
+ return {
2786
+ actorId,
2787
+ name: actor2.state.name,
2788
+ key: actor2.state.key
2789
+ };
2790
+ } catch (error) {
2791
+ logger5().error({ msg: "failed to read actor state", actorId, error });
2792
+ return void 0;
2793
+ }
2794
+ }
2795
+ async getWithKey({
2796
+ name,
2797
+ key
2798
+ }) {
2799
+ const actorId = generateActorId(name, key);
2800
+ const actor2 = await this.#state.loadActor(actorId);
2801
+ if (actor2.state) {
2802
+ return {
2803
+ actorId,
2804
+ name,
2805
+ key
2806
+ };
2807
+ }
2808
+ return void 0;
2809
+ }
2810
+ async getOrCreateWithKey(input) {
2811
+ const actorId = generateActorId(input.name, input.key);
2812
+ const actorEntry = await this.#state.loadOrCreateActor(
2813
+ actorId,
2814
+ input.name,
2815
+ input.key,
2816
+ input.input
2817
+ );
2818
+ invariant4(actorEntry.state, "must have state");
2819
+ return {
2820
+ actorId: actorEntry.state.actorId,
2821
+ name: actorEntry.state.name,
2822
+ key: actorEntry.state.key
2823
+ };
2824
+ }
2825
+ async createActor({ name, key, input }) {
2826
+ const actorId = generateActorId(name, key);
2827
+ await this.#state.createActor(actorId, name, key, input);
2828
+ return {
2829
+ actorId,
2830
+ name,
2831
+ key
2832
+ };
2833
+ }
2834
+ displayInformation() {
2835
+ return {
2836
+ name: this.#state.persist ? "File System" : "Memory",
2837
+ properties: {
2838
+ ...this.#state.persist ? { Data: this.#state.storagePath } : {},
2839
+ Instances: this.#state.actorCountOnStartup.toString()
2840
+ }
2841
+ };
2842
+ }
2843
+ extraStartupLog() {
2844
+ return {
2845
+ instances: this.#state.actorCountOnStartup,
2846
+ data: this.#state.storagePath
2847
+ };
2848
+ }
2849
+ };
2850
+
2851
+ // src/drivers/file-system/mod.ts
2852
+ function createFileSystemOrMemoryDriver(persist = true, customPath) {
2853
+ const state = new FileSystemGlobalState(persist, customPath);
2854
+ const driverConfig = {
2855
+ name: persist ? "file-system" : "memory",
2856
+ manager: (registryConfig, runConfig) => new FileSystemManagerDriver(
2857
+ registryConfig,
2858
+ runConfig,
2859
+ state,
2860
+ driverConfig
2861
+ ),
2862
+ actor: (registryConfig, runConfig, managerDriver, inlineClient) => {
2863
+ const actorDriver = new FileSystemActorDriver(
2864
+ registryConfig,
2865
+ runConfig,
2866
+ managerDriver,
2867
+ inlineClient,
2868
+ state
2869
+ );
2870
+ state.onRunnerStart(registryConfig, runConfig, inlineClient, actorDriver);
2871
+ return actorDriver;
2872
+ }
2873
+ };
2874
+ return driverConfig;
2875
+ }
2876
+ function createFileSystemDriver(opts) {
2877
+ return createFileSystemOrMemoryDriver(true, opts == null ? void 0 : opts.path);
2878
+ }
2879
+ function createMemoryDriver() {
2880
+ return createFileSystemOrMemoryDriver(false);
2881
+ }
2882
+
2883
+ // src/drivers/default.ts
2884
+ function chooseDefaultDriver(runConfig) {
2885
+ const engineEndpoint = runConfig.endpoint ?? getEnvUniversal("RIVET_ENGINE");
2886
+ if (engineEndpoint && runConfig.driver) {
2887
+ throw new UserError(
2888
+ "Cannot specify both 'engine' and 'driver' in configuration"
2889
+ );
2890
+ }
2891
+ if (runConfig.driver) {
2892
+ return runConfig.driver;
2893
+ }
2894
+ if (engineEndpoint) {
2895
+ loggerWithoutContext().debug({
2896
+ msg: "using rivet engine driver",
2897
+ endpoint: engineEndpoint
2898
+ });
2899
+ return createEngineDriver({ endpoint: engineEndpoint });
2900
+ }
2901
+ loggerWithoutContext().debug({ msg: "using default file system driver" });
2902
+ return createFileSystemOrMemoryDriver(true);
2903
+ }
2904
+
2905
+ // src/manager/router.ts
2906
+ import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2907
+ import * as cbor4 from "cbor-x";
2908
+ import { Hono as Hono3 } from "hono";
2909
+ 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";
2913
+
2914
+ // src/manager-api/routes/actors-create.ts
2915
+ import { z as z4 } from "zod";
2916
+
2917
+ // src/manager-api/routes/common.ts
2918
+ import { z as z3 } from "zod";
2919
+ var RivetIdSchema = z3.string();
2920
+ var ActorSchema = z3.object({
2921
+ actor_id: RivetIdSchema,
2922
+ name: z3.string(),
2923
+ key: z3.string(),
2924
+ 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()
2931
+ });
2932
+
2933
+ // src/manager-api/routes/actors-create.ts
2934
+ var ActorsCreateRequestSchema = z4.object({
2935
+ name: z4.string(),
2936
+ runner_name_selector: z4.string(),
2937
+ crash_policy: z4.string(),
2938
+ key: z4.string().nullable().optional(),
2939
+ input: z4.string().nullable().optional()
2940
+ });
2941
+ var ActorsCreateResponseSchema = z4.object({
2942
+ actor: ActorSchema
2943
+ });
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()
2955
+ });
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({
2960
+ 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()
2973
+ });
2974
+
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
+ };
2993
+ }
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
3032
+ );
3033
+ }
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
+ }
3047
+ return next();
3048
+ });
3049
+ router.get("/", cors2, (c) => {
3050
+ return c.text(
3051
+ "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3052
+ );
3053
+ });
3054
+ {
3055
+ const route = createRoute({
3056
+ middleware: [cors2],
3057
+ method: "get",
3058
+ path: "/actors/by-id",
3059
+ request: {
3060
+ query: z8.object({
3061
+ name: z8.string(),
3062
+ key: z8.string()
3063
+ })
3064
+ },
3065
+ responses: buildOpenApiResponses(
3066
+ ActorsGetByIdResponseSchema,
3067
+ validateBody
3068
+ )
3069
+ });
3070
+ 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
+ });
3078
+ return c.json({
3079
+ actor_id: (actorOutput == null ? void 0 : actorOutput.actorId) || null
3080
+ });
3081
+ });
3082
+ }
3083
+ {
3084
+ const route = createRoute({
3085
+ cors: [cors2],
3086
+ method: "put",
3087
+ path: "/actors/by-id",
3088
+ request: {
3089
+ body: {
3090
+ content: validateBody ? {
3091
+ "application/json": {
3092
+ schema: ActorsGetOrCreateByIdRequestSchema
3093
+ }
3094
+ } : {}
3095
+ }
3096
+ },
3097
+ responses: buildOpenApiResponses(
3098
+ ActorsGetOrCreateByIdResponseSchema,
3099
+ validateBody
3100
+ )
3101
+ });
3102
+ 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
+ }
3107
+ const existingActor = await managerDriver.getWithKey({
3108
+ c,
3109
+ name: body.name,
3110
+ key: [body.key]
3111
+ // Convert string to ActorKey array
3112
+ });
3113
+ if (existingActor) {
3114
+ return c.json({
3115
+ actor_id: existingActor.actorId,
3116
+ created: false
3117
+ });
3118
+ }
3119
+ const newActor = await managerDriver.getOrCreateWithKey({
3120
+ c,
3121
+ name: body.name,
3122
+ key: [body.key],
3123
+ // Convert string to ActorKey array
3124
+ input: body.input ? cbor4.decode(Buffer.from(body.input, "base64")) : void 0,
3125
+ region: void 0
3126
+ // Not provided in the request schema
3127
+ });
3128
+ return c.json({
3129
+ actor_id: newActor.actorId,
3130
+ created: true
3131
+ });
3132
+ });
3133
+ }
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
+ {
3176
+ const route = createRoute({
3177
+ middleware: [cors2],
3178
+ method: "post",
3179
+ path: "/actors",
3180
+ request: {
3181
+ body: {
3182
+ content: validateBody ? {
3183
+ "application/json": {
3184
+ schema: ActorsCreateRequestSchema
3185
+ }
3186
+ } : {}
3187
+ }
3188
+ },
3189
+ responses: buildOpenApiResponses(
3190
+ ActorsCreateResponseSchema,
3191
+ validateBody
3192
+ )
3193
+ });
3194
+ 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
+ }
3199
+ const actorOutput = await managerDriver.createActor({
3200
+ c,
3201
+ name: body.name,
3202
+ key: [body.key || crypto.randomUUID()],
3203
+ // Generate key if not provided, convert to ActorKey array
3204
+ input: body.input ? cbor4.decode(Buffer.from(body.input, "base64")) : void 0,
3205
+ region: void 0
3206
+ // Not provided in the request schema
3207
+ });
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
+ };
3222
+ return c.json({ actor: actor2 });
3223
+ });
3224
+ }
3225
+ if (registryConfig.test.enabled) {
3226
+ router.post(".test/inline-driver/call", async (c) => {
3227
+ const buffer = await c.req.arrayBuffer();
3228
+ const { encoding, transport, method, args } = cbor4.decode(new Uint8Array(buffer));
3229
+ logger().debug({
3230
+ msg: "received inline request",
3231
+ encoding,
3232
+ transport,
3233
+ method,
3234
+ args
3235
+ });
3236
+ let response;
3237
+ try {
3238
+ const output = await managerDriver[method](...args);
3239
+ response = { ok: output };
3240
+ } catch (rawErr) {
3241
+ const err = deconstructError(rawErr, logger(), {}, true);
3242
+ response = { err };
3243
+ }
3244
+ return c.body(cbor4.encode(response));
3245
+ });
3246
+ router.get(".test/inline-driver/connect-websocket/*", async (c) => {
3247
+ var _a2;
3248
+ const upgradeWebSocket = (_a2 = runConfig.getUpgradeWebSocket) == null ? void 0 : _a2.call(runConfig);
3249
+ invariant5(upgradeWebSocket, "websockets not supported on this platform");
3250
+ 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;
3258
+ logger().debug({
3259
+ msg: "received test inline driver websocket",
3260
+ actorId,
3261
+ params,
3262
+ encodingKind,
3263
+ path: path3
3264
+ });
3265
+ const clientWsPromise = managerDriver.openWebSocket(
3266
+ path3,
3267
+ actorId,
3268
+ encodingKind,
3269
+ params
3270
+ );
3271
+ return await createTestWebSocketProxy(clientWsPromise, "standard");
3272
+ })(c, noopNext());
3273
+ });
3274
+ router.all(".test/inline-driver/send-request/*", async (c) => {
3275
+ const actorId = c.req.header(HEADER_ACTOR_ID);
3276
+ if (!actorId) {
3277
+ return c.text("Missing required headers", 400);
3278
+ }
3279
+ const pathOnly = c.req.path.split("/.test/inline-driver/send-request/")[1] || "";
3280
+ const url = new URL(c.req.url);
3281
+ const pathWithQuery = pathOnly + url.search;
3282
+ logger().debug({
3283
+ msg: "received test inline driver raw http",
3284
+ actorId,
3285
+ path: pathWithQuery,
3286
+ method: c.req.method
3287
+ });
3288
+ try {
3289
+ const response = await managerDriver.sendRequest(
3290
+ actorId,
3291
+ new Request(`http://actor/${pathWithQuery}`, {
3292
+ method: c.req.method,
3293
+ headers: c.req.raw.headers,
3294
+ body: c.req.raw.body
3295
+ })
3296
+ );
3297
+ return response;
3298
+ } catch (error) {
3299
+ logger().error({
3300
+ msg: "error in test inline raw http",
3301
+ error: stringifyError(error)
3302
+ });
3303
+ const err = deconstructError(error, logger(), {}, true);
3304
+ return c.json(
3305
+ {
3306
+ error: {
3307
+ code: err.code,
3308
+ message: err.message,
3309
+ metadata: err.metadata
3310
+ }
3311
+ },
3312
+ err.statusCode
3313
+ );
3314
+ }
3315
+ });
3316
+ }
3317
+ (_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
3318
+ managerDriver,
3319
+ registryConfig,
3320
+ router
3321
+ );
3322
+ if ((_b = runConfig.inspector) == null ? void 0 : _b.enabled) {
3323
+ if (!managerDriver.inspector) {
3324
+ throw new Unsupported("inspector");
3325
+ }
3326
+ router.route(
3327
+ "/inspect",
3328
+ new Hono3().use(corsMiddleware(runConfig.inspector.cors)).use(secureInspector(runConfig)).use((c, next) => {
3329
+ c.set("inspector", managerDriver.inspector);
3330
+ return next();
3331
+ }).route("/", createManagerInspectorRouter())
3332
+ );
3333
+ }
3334
+ router.notFound(handleRouteNotFound);
3335
+ router.onError(handleRouteError);
3336
+ return { router, openapi: router };
3337
+ }
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
+ }
3379
+ 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
+ }
3496
+ };
3497
+ }
3498
+
3499
+ // src/registry/config.ts
3500
+ import { z as z9 } from "zod";
3501
+ var ActorsSchema = z9.record(
3502
+ z9.string(),
3503
+ z9.custom()
3504
+ );
3505
+ var TestConfigSchema = z9.object({ enabled: z9.boolean() });
3506
+ var RegistryConfigSchema = z9.object({
3507
+ use: z9.record(z9.string(), z9.custom()),
3508
+ // TODO: Find a better way of passing around the test config
3509
+ /**
3510
+ * Test configuration.
3511
+ *
3512
+ * DO NOT MANUALLY ENABLE. THIS IS USED INTERNALLY.
3513
+ * @internal
3514
+ **/
3515
+ test: TestConfigSchema.optional().default({ enabled: false })
3516
+ });
3517
+
3518
+ // src/registry/log.ts
3519
+ function logger6() {
3520
+ return getLogger("registry");
3521
+ }
3522
+
3523
+ // src/registry/serve.ts
3524
+ import { Hono as Hono4 } from "hono";
3525
+ async function crossPlatformServe(rivetKitRouter, userRouter) {
3526
+ const app = userRouter ?? new Hono4();
3527
+ let serve;
3528
+ try {
3529
+ const dep = await import(
3530
+ /* webpackIgnore: true */
3531
+ "@hono/node-server"
3532
+ );
3533
+ serve = dep.serve;
3534
+ } catch (err) {
3535
+ logger6().error(
3536
+ "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'"
3537
+ );
3538
+ process.exit(1);
3539
+ }
3540
+ app.route("/", rivetKitRouter);
3541
+ let createNodeWebSocket;
3542
+ try {
3543
+ const dep = await import(
3544
+ /* webpackIgnore: true */
3545
+ "@hono/node-ws"
3546
+ );
3547
+ createNodeWebSocket = dep.createNodeWebSocket;
3548
+ } catch (err) {
3549
+ logger6().error(
3550
+ "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'"
3551
+ );
3552
+ process.exit(1);
3553
+ }
3554
+ const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
3555
+ app
3556
+ });
3557
+ const port = 6420;
3558
+ const server = serve(
3559
+ { fetch: app.fetch, port },
3560
+ () => logger6().info({ msg: "server listening", port })
3561
+ );
3562
+ injectWebSocket(server);
3563
+ return { upgradeWebSocket };
3564
+ }
3565
+
3566
+ // src/registry/mod.ts
3567
+ var Registry = class {
3568
+ #config;
3569
+ get config() {
3570
+ return this.#config;
3571
+ }
3572
+ constructor(config2) {
3573
+ this.#config = config2;
3574
+ }
3575
+ /**
3576
+ * Runs the registry for a server.
3577
+ */
3578
+ start(inputConfig) {
3579
+ var _a, _b, _c, _d, _e;
3580
+ const config2 = RunConfigSchema.parse(inputConfig);
3581
+ if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3582
+ configureBaseLogger(config2.logging.baseLogger);
3583
+ } else {
3584
+ configureDefaultLogger((_b = config2.logging) == null ? void 0 : _b.level);
3585
+ }
3586
+ const driver = chooseDefaultDriver(config2);
3587
+ if (driver.name === "engine") {
3588
+ config2.inspector.enabled = false;
3589
+ config2.disableServer = true;
3590
+ }
3591
+ if (driver.name === "cloudflare-workers") {
3592
+ config2.inspector.enabled = false;
3593
+ config2.disableServer = true;
3594
+ config2.disableActorDriver = true;
3595
+ config2.noWelcome = true;
3596
+ }
3597
+ let upgradeWebSocket;
3598
+ if (!config2.getUpgradeWebSocket) {
3599
+ config2.getUpgradeWebSocket = () => upgradeWebSocket;
3600
+ }
3601
+ const managerDriver = driver.manager(this.#config, config2);
3602
+ const { router: hono } = createManagerRouter(
3603
+ this.#config,
3604
+ config2,
3605
+ managerDriver,
3606
+ false
3607
+ );
3608
+ const client = createClientWithDriver(managerDriver, config2);
3609
+ const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3610
+ logger6().info({
3611
+ msg: "rivetkit ready",
3612
+ driver: driver.name,
3613
+ definitions: Object.keys(this.#config.use).length,
3614
+ ...driverLog
3615
+ });
3616
+ if (((_d = config2.inspector) == null ? void 0 : _d.enabled) && managerDriver.inspector) {
3617
+ logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3618
+ }
3619
+ if (!config2.noWelcome) {
3620
+ const displayInfo = managerDriver.displayInformation();
3621
+ console.log();
3622
+ console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3623
+ console.log(` - Endpoint: http://127.0.0.1:6420`);
3624
+ for (const [k, v] of Object.entries(displayInfo.properties)) {
3625
+ const padding = " ".repeat(Math.max(0, 13 - k.length));
3626
+ console.log(` - ${k}:${padding}${v}`);
3627
+ }
3628
+ if (((_e = config2.inspector) == null ? void 0 : _e.enabled) && managerDriver.inspector) {
3629
+ console.log(` - Inspector: ${getInspectorUrl(config2)}`);
3630
+ }
3631
+ console.log();
3632
+ }
3633
+ if (!config2.disableActorDriver) {
3634
+ const _actorDriver = driver.actor(
3635
+ this.#config,
3636
+ config2,
3637
+ managerDriver,
3638
+ client
3639
+ );
3640
+ }
3641
+ if (!config2.disableServer) {
3642
+ (async () => {
3643
+ const out = await crossPlatformServe(hono, void 0);
3644
+ upgradeWebSocket = out.upgradeWebSocket;
3645
+ })();
3646
+ }
3647
+ return {
3648
+ client,
3649
+ fetch: hono.fetch.bind(hono)
3650
+ };
3651
+ }
3652
+ };
3653
+ function setup(input) {
3654
+ const config2 = RegistryConfigSchema.parse(input);
3655
+ return new Registry(config2);
3656
+ }
3657
+
3658
+ export {
3659
+ GenericConnGlobalState,
3660
+ createGenericConnDrivers,
3661
+ handleWebSocketConnect,
3662
+ handleRawWebSocketHandler,
3663
+ createActorRouter,
3664
+ actor,
3665
+ InlineWebSocketAdapter2,
3666
+ createEngineDriver,
3667
+ createFileSystemOrMemoryDriver,
3668
+ createFileSystemDriver,
3669
+ createMemoryDriver,
3670
+ createManagerRouter,
3671
+ RegistryConfigSchema,
3672
+ Registry,
3673
+ setup
3674
+ };
3675
+ //! These configs configs hold anything that's not platform-specific about running actors.
3676
+ //# sourceMappingURL=chunk-W6LN7AF5.js.map