rivetkit 2.0.9 → 2.0.11

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 (123) hide show
  1. package/dist/tsup/{chunk-F2YZNUPU.js → chunk-3JUN3IEH.js} +3 -3
  2. package/dist/tsup/{chunk-DL7TPF63.cjs → chunk-5ABUOI3V.cjs} +7 -7
  3. package/dist/tsup/{chunk-DL7TPF63.cjs.map → chunk-5ABUOI3V.cjs.map} +1 -1
  4. package/dist/tsup/{chunk-SDXTJDDR.cjs → chunk-5JZPEJVJ.cjs} +58 -14
  5. package/dist/tsup/chunk-5JZPEJVJ.cjs.map +1 -0
  6. package/dist/tsup/{chunk-SOC4HWCG.cjs → chunk-6PORXHSQ.cjs} +92 -39
  7. package/dist/tsup/chunk-6PORXHSQ.cjs.map +1 -0
  8. package/dist/tsup/{chunk-QGRYH6TU.cjs → chunk-765F7ILI.cjs} +7 -6
  9. package/dist/tsup/chunk-765F7ILI.cjs.map +1 -0
  10. package/dist/tsup/{chunk-DLPIL3VC.js → chunk-7DCESQ4O.js} +2 -2
  11. package/dist/tsup/{chunk-R7OP5N25.js → chunk-AZI2T6UF.js} +53 -9
  12. package/dist/tsup/chunk-AZI2T6UF.js.map +1 -0
  13. package/dist/tsup/{chunk-A44TWAS5.cjs → chunk-GGIW54I2.cjs} +6 -6
  14. package/dist/tsup/{chunk-A44TWAS5.cjs.map → chunk-GGIW54I2.cjs.map} +1 -1
  15. package/dist/tsup/{chunk-7OMMIAWP.cjs → chunk-HDCLOVOE.cjs} +17 -12
  16. package/dist/tsup/chunk-HDCLOVOE.cjs.map +1 -0
  17. package/dist/tsup/{chunk-2MJYYF2Q.cjs → chunk-I6AVFIVY.cjs} +12 -12
  18. package/dist/tsup/{chunk-2MJYYF2Q.cjs.map → chunk-I6AVFIVY.cjs.map} +1 -1
  19. package/dist/tsup/{chunk-WBSPHV5V.js → chunk-JTWD6ZT2.js} +2 -2
  20. package/dist/tsup/{chunk-4YV6RDZL.cjs → chunk-LXFOO25H.cjs} +722 -359
  21. package/dist/tsup/chunk-LXFOO25H.cjs.map +1 -0
  22. package/dist/tsup/{chunk-YR2VY4XS.js → chunk-MIP4PYTD.js} +5 -4
  23. package/dist/tsup/chunk-MIP4PYTD.js.map +1 -0
  24. package/dist/tsup/{chunk-KHZ2QSQ4.js → chunk-MT5ES4XD.js} +32 -10
  25. package/dist/tsup/chunk-MT5ES4XD.js.map +1 -0
  26. package/dist/tsup/{chunk-U2IXX6DY.cjs → chunk-NLYAKGML.cjs} +5 -6
  27. package/dist/tsup/chunk-NLYAKGML.cjs.map +1 -0
  28. package/dist/tsup/{chunk-FZP2IBIX.js → chunk-NOXYAPM2.js} +603 -240
  29. package/dist/tsup/chunk-NOXYAPM2.js.map +1 -0
  30. package/dist/tsup/{chunk-E63WU5PL.js → chunk-NQFIZSTR.js} +5 -6
  31. package/dist/tsup/chunk-NQFIZSTR.js.map +1 -0
  32. package/dist/tsup/{chunk-4PSLOAXR.cjs → chunk-O7BIBANW.cjs} +226 -204
  33. package/dist/tsup/chunk-O7BIBANW.cjs.map +1 -0
  34. package/dist/tsup/{chunk-VVCL5DXN.js → chunk-OHSP4BUE.js} +97 -44
  35. package/dist/tsup/{chunk-VVCL5DXN.js.map → chunk-OHSP4BUE.js.map} +1 -1
  36. package/dist/tsup/{chunk-APHV6WXU.js → chunk-SBUJ3KIM.js} +2 -2
  37. package/dist/tsup/{chunk-DZZQG7VH.cjs → chunk-WYTLLIJM.cjs} +3 -3
  38. package/dist/tsup/{chunk-DZZQG7VH.cjs.map → chunk-WYTLLIJM.cjs.map} +1 -1
  39. package/dist/tsup/{chunk-WRSWUDFA.js → chunk-XO7VX4MN.js} +14 -9
  40. package/dist/tsup/chunk-XO7VX4MN.js.map +1 -0
  41. package/dist/tsup/client/mod.cjs +9 -9
  42. package/dist/tsup/client/mod.d.cts +2 -2
  43. package/dist/tsup/client/mod.d.ts +2 -2
  44. package/dist/tsup/client/mod.js +8 -8
  45. package/dist/tsup/common/log.cjs +3 -3
  46. package/dist/tsup/common/log.js +2 -2
  47. package/dist/tsup/common/websocket.cjs +4 -4
  48. package/dist/tsup/common/websocket.js +3 -3
  49. package/dist/tsup/{conn-CEh3WKbA.d.cts → conn-CT_8ZBT_.d.cts} +204 -199
  50. package/dist/tsup/{conn-Bt8rkUzm.d.ts → conn-d5F0M95s.d.ts} +204 -199
  51. package/dist/tsup/driver-helpers/mod.cjs +5 -5
  52. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  53. package/dist/tsup/driver-helpers/mod.d.cts +1 -1
  54. package/dist/tsup/driver-helpers/mod.d.ts +1 -1
  55. package/dist/tsup/driver-helpers/mod.js +6 -6
  56. package/dist/tsup/driver-test-suite/mod.cjs +117 -103
  57. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  58. package/dist/tsup/driver-test-suite/mod.d.cts +3 -2
  59. package/dist/tsup/driver-test-suite/mod.d.ts +3 -2
  60. package/dist/tsup/driver-test-suite/mod.js +62 -48
  61. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  62. package/dist/tsup/inspector/mod.cjs +6 -6
  63. package/dist/tsup/inspector/mod.d.cts +6 -6
  64. package/dist/tsup/inspector/mod.d.ts +6 -6
  65. package/dist/tsup/inspector/mod.js +5 -5
  66. package/dist/tsup/mod.cjs +10 -10
  67. package/dist/tsup/mod.d.cts +8 -39
  68. package/dist/tsup/mod.d.ts +8 -39
  69. package/dist/tsup/mod.js +9 -9
  70. package/dist/tsup/test/mod.cjs +11 -11
  71. package/dist/tsup/test/mod.d.cts +1 -1
  72. package/dist/tsup/test/mod.d.ts +1 -1
  73. package/dist/tsup/test/mod.js +10 -10
  74. package/dist/tsup/utils.cjs +2 -2
  75. package/dist/tsup/utils.d.cts +2 -1
  76. package/dist/tsup/utils.d.ts +2 -1
  77. package/dist/tsup/utils.js +1 -1
  78. package/package.json +4 -5
  79. package/src/actor/driver.ts +2 -2
  80. package/src/actor/protocol/serde.ts +75 -3
  81. package/src/actor/router-endpoints.ts +6 -6
  82. package/src/actor/router.ts +2 -2
  83. package/src/client/actor-conn.ts +24 -3
  84. package/src/client/config.ts +19 -26
  85. package/src/driver-helpers/mod.ts +4 -1
  86. package/src/driver-test-suite/mod.ts +66 -44
  87. package/src/driver-test-suite/utils.ts +4 -1
  88. package/src/drivers/default.ts +11 -9
  89. package/src/drivers/engine/actor-driver.ts +42 -39
  90. package/src/drivers/engine/config.ts +9 -22
  91. package/src/drivers/engine/mod.ts +9 -8
  92. package/src/drivers/file-system/global-state.ts +4 -4
  93. package/src/engine-process/log.ts +5 -0
  94. package/src/engine-process/mod.ts +316 -0
  95. package/src/inspector/utils.ts +6 -4
  96. package/src/manager/driver.ts +2 -2
  97. package/src/manager/gateway.ts +29 -11
  98. package/src/manager/router-schema.ts +20 -0
  99. package/src/manager/router.ts +116 -29
  100. package/src/registry/mod.ts +168 -113
  101. package/src/registry/run-config.ts +116 -47
  102. package/src/registry/serve.ts +3 -1
  103. package/src/serde.ts +3 -3
  104. package/src/test/config.ts +2 -2
  105. package/src/test/mod.ts +6 -3
  106. package/src/utils.ts +2 -0
  107. package/dist/tsup/chunk-4PSLOAXR.cjs.map +0 -1
  108. package/dist/tsup/chunk-4YV6RDZL.cjs.map +0 -1
  109. package/dist/tsup/chunk-7OMMIAWP.cjs.map +0 -1
  110. package/dist/tsup/chunk-E63WU5PL.js.map +0 -1
  111. package/dist/tsup/chunk-FZP2IBIX.js.map +0 -1
  112. package/dist/tsup/chunk-KHZ2QSQ4.js.map +0 -1
  113. package/dist/tsup/chunk-QGRYH6TU.cjs.map +0 -1
  114. package/dist/tsup/chunk-R7OP5N25.js.map +0 -1
  115. package/dist/tsup/chunk-SDXTJDDR.cjs.map +0 -1
  116. package/dist/tsup/chunk-SOC4HWCG.cjs.map +0 -1
  117. package/dist/tsup/chunk-U2IXX6DY.cjs.map +0 -1
  118. package/dist/tsup/chunk-WRSWUDFA.js.map +0 -1
  119. package/dist/tsup/chunk-YR2VY4XS.js.map +0 -1
  120. /package/dist/tsup/{chunk-F2YZNUPU.js.map → chunk-3JUN3IEH.js.map} +0 -0
  121. /package/dist/tsup/{chunk-DLPIL3VC.js.map → chunk-7DCESQ4O.js.map} +0 -0
  122. /package/dist/tsup/{chunk-WBSPHV5V.js.map → chunk-JTWD6ZT2.js.map} +0 -0
  123. /package/dist/tsup/{chunk-APHV6WXU.js.map → chunk-SBUJ3KIM.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  inspectorLogger,
5
5
  isInspectorEnabled,
6
6
  secureInspector
7
- } from "./chunk-YR2VY4XS.js";
7
+ } from "./chunk-MIP4PYTD.js";
8
8
  import {
9
9
  ActorDefinition,
10
10
  RemoteManagerDriver,
@@ -12,23 +12,24 @@ import {
12
12
  createClientWithDriver,
13
13
  deserializeActorKey,
14
14
  generateConnSocketId,
15
+ getEndpoint,
15
16
  lookupInRegistry,
16
17
  serializeActorKey
17
- } from "./chunk-KHZ2QSQ4.js";
18
+ } from "./chunk-MT5ES4XD.js";
18
19
  import {
19
20
  CreateActorSchema
20
- } from "./chunk-WBSPHV5V.js";
21
+ } from "./chunk-JTWD6ZT2.js";
21
22
  import {
22
23
  ActionContext,
23
24
  HTTP_ACTION_REQUEST_VERSIONED,
24
25
  HTTP_ACTION_RESPONSE_VERSIONED,
25
26
  HTTP_RESPONSE_ERROR_VERSIONED,
26
- RunConfigSchema,
27
+ RunnerConfigSchema,
27
28
  TO_SERVER_VERSIONED,
28
29
  createVersionedDataHandler,
29
30
  parseMessage,
30
31
  serializeEmptyPersistData
31
- } from "./chunk-VVCL5DXN.js";
32
+ } from "./chunk-OHSP4BUE.js";
32
33
  import {
33
34
  EncodingSchema,
34
35
  HEADER_ACTOR_ID,
@@ -54,22 +55,23 @@ import {
54
55
  generateRandomString,
55
56
  loggerWithoutContext,
56
57
  serializeWithEncoding
57
- } from "./chunk-R7OP5N25.js";
58
+ } from "./chunk-AZI2T6UF.js";
58
59
  import {
59
60
  configureBaseLogger,
60
61
  configureDefaultLogger,
61
62
  getLogger
62
- } from "./chunk-DLPIL3VC.js";
63
+ } from "./chunk-7DCESQ4O.js";
63
64
  import {
65
+ VERSION,
66
+ assertUnreachable,
64
67
  bufferToArrayBuffer,
65
68
  deconstructError,
66
- getEnvUniversal,
67
69
  noopNext,
68
70
  package_default,
69
71
  promiseWithResolvers,
70
72
  setLongTimeout,
71
73
  stringifyError
72
- } from "./chunk-E63WU5PL.js";
74
+ } from "./chunk-NQFIZSTR.js";
73
75
  import {
74
76
  ActorAlreadyExists,
75
77
  ConnNotFound,
@@ -77,6 +79,7 @@ import {
77
79
  InternalError,
78
80
  InvalidEncoding,
79
81
  InvalidParams,
82
+ InvalidRequest,
80
83
  MissingActorHeader,
81
84
  Unsupported,
82
85
  UserError,
@@ -746,13 +749,13 @@ async function handleConnectionClose(c, _runConfig, actorDriver, connId, connTok
746
749
  await conn.disconnect("Connection closed by client request");
747
750
  return c.json({});
748
751
  }
749
- async function handleRawWebSocketHandler(req, path3, actorDriver, actorId) {
752
+ async function handleRawWebSocketHandler(req, path4, actorDriver, actorId) {
750
753
  const actor2 = await actorDriver.loadActor(actorId);
751
754
  return {
752
755
  onOpen: (_evt, ws) => {
753
756
  const adapter = new HonoWebSocketAdapter(ws);
754
757
  ws.__adapter = adapter;
755
- const url = new URL(path3, "http://actor");
758
+ const url = new URL(path4, "http://actor");
756
759
  const pathname = url.pathname.replace(/^\/raw\/websocket\/?/, "") || "/";
757
760
  const normalizedPath = (pathname.startsWith("/") ? pathname : "/" + pathname) + url.search;
758
761
  let newRequest;
@@ -765,7 +768,7 @@ async function handleRawWebSocketHandler(req, path3, actorDriver, actorId) {
765
768
  }
766
769
  actor2.rLog.debug({
767
770
  msg: "rewriting websocket url",
768
- from: path3,
771
+ from: path4,
769
772
  to: newRequest.url,
770
773
  pathname: url.pathname,
771
774
  search: url.search,
@@ -828,17 +831,17 @@ import * as cbor2 from "cbor-x";
828
831
  function logger2() {
829
832
  return getLogger("router");
830
833
  }
831
- function loggerMiddleware(logger7) {
834
+ function loggerMiddleware(logger8) {
832
835
  return async (c, next) => {
833
836
  const method = c.req.method;
834
- const path3 = c.req.path;
837
+ const path4 = c.req.path;
835
838
  const startTime = Date.now();
836
839
  await next();
837
840
  const duration = Date.now() - startTime;
838
- logger7.debug({
841
+ logger8.debug({
839
842
  msg: "http request",
840
843
  method,
841
- path: path3,
844
+ path: path4,
842
845
  status: c.res.status,
843
846
  dt: `${duration}ms`,
844
847
  reqSize: c.req.header("content-length"),
@@ -1434,7 +1437,6 @@ var EngineActorDriver = class {
1434
1437
  #runConfig;
1435
1438
  #managerDriver;
1436
1439
  #inlineClient;
1437
- #config;
1438
1440
  #runner;
1439
1441
  #actors = /* @__PURE__ */ new Map();
1440
1442
  #actorRouter;
@@ -1443,27 +1445,29 @@ var EngineActorDriver = class {
1443
1445
  #alarmTimeout;
1444
1446
  #runnerStarted = Promise.withResolvers();
1445
1447
  #runnerStopped = Promise.withResolvers();
1446
- constructor(registryConfig, runConfig, managerDriver, inlineClient, config2) {
1448
+ constructor(registryConfig, runConfig, managerDriver, inlineClient) {
1447
1449
  this.#registryConfig = registryConfig;
1448
1450
  this.#runConfig = runConfig;
1449
1451
  this.#managerDriver = managerDriver;
1450
1452
  this.#inlineClient = inlineClient;
1451
- this.#config = config2;
1453
+ const token = runConfig.token ?? runConfig.token;
1454
+ if (token && runConfig.inspector && runConfig.inspector.enabled) {
1455
+ runConfig.inspector.token = () => token;
1456
+ }
1452
1457
  this.#actorRouter = createActorRouter(
1453
1458
  runConfig,
1454
1459
  this,
1455
1460
  registryConfig.test.enabled
1456
1461
  );
1457
1462
  let hasDisconnected = false;
1458
- const runnerConfig = {
1463
+ const engineRunnerConfig = {
1459
1464
  version: this.#version,
1460
- endpoint: config2.endpoint,
1461
- token: runConfig.token ?? config2.token,
1462
- pegboardEndpoint: config2.pegboardEndpoint,
1463
- namespace: config2.namespace,
1464
- totalSlots: runConfig.totalSlots ?? config2.totalSlots,
1465
- runnerName: config2.runnerName,
1466
- runnerKey: config2.runnerKey,
1465
+ endpoint: getEndpoint(runConfig),
1466
+ token,
1467
+ namespace: runConfig.namespace ?? runConfig.namespace,
1468
+ totalSlots: runConfig.totalSlots ?? runConfig.totalSlots,
1469
+ runnerName: runConfig.runnerName ?? runConfig.runnerName,
1470
+ runnerKey: runConfig.runnerKey,
1467
1471
  metadata: {
1468
1472
  inspectorToken: this.#runConfig.inspector.token()
1469
1473
  },
@@ -1477,14 +1481,14 @@ var EngineActorDriver = class {
1477
1481
  if (hasDisconnected) {
1478
1482
  logger4().info({
1479
1483
  msg: "runner reconnected",
1480
- namespace: this.#config.namespace,
1481
- runnerName: this.#config.runnerName
1484
+ namespace: this.#runConfig.namespace,
1485
+ runnerName: this.#runConfig.runnerName
1482
1486
  });
1483
1487
  } else {
1484
1488
  logger4().debug({
1485
1489
  msg: "runner connected",
1486
- namespace: this.#config.namespace,
1487
- runnerName: this.#config.runnerName
1490
+ namespace: this.#runConfig.namespace,
1491
+ runnerName: this.#runConfig.runnerName
1488
1492
  });
1489
1493
  }
1490
1494
  this.#runnerStarted.resolve(void 0);
@@ -1492,8 +1496,8 @@ var EngineActorDriver = class {
1492
1496
  onDisconnected: () => {
1493
1497
  logger4().warn({
1494
1498
  msg: "runner disconnected",
1495
- namespace: this.#config.namespace,
1496
- runnerName: this.#config.runnerName
1499
+ namespace: this.#runConfig.namespace,
1500
+ runnerName: this.#runConfig.runnerName
1497
1501
  });
1498
1502
  hasDisconnected = true;
1499
1503
  },
@@ -1506,13 +1510,13 @@ var EngineActorDriver = class {
1506
1510
  onActorStop: this.#runnerOnActorStop.bind(this),
1507
1511
  logger: getLogger("engine-runner")
1508
1512
  };
1509
- this.#runner = new Runner(runnerConfig);
1513
+ this.#runner = new Runner(engineRunnerConfig);
1510
1514
  this.#runner.start();
1511
1515
  logger4().debug({
1512
1516
  msg: "engine runner started",
1513
- endpoint: config2.endpoint,
1514
- namespace: config2.namespace,
1515
- runnerName: config2.runnerName
1517
+ endpoint: runConfig.endpoint,
1518
+ namespace: runConfig.namespace,
1519
+ runnerName: runConfig.runnerName
1516
1520
  });
1517
1521
  }
1518
1522
  async #loadActorHandler(actorId) {
@@ -1564,18 +1568,18 @@ var EngineActorDriver = class {
1564
1568
  return void 0;
1565
1569
  }
1566
1570
  // Runner lifecycle callbacks
1567
- async #runnerOnActorStart(actorId, generation, config2) {
1571
+ async #runnerOnActorStart(actorId, generation, runConfig) {
1568
1572
  var _a;
1569
1573
  logger4().debug({
1570
1574
  msg: "runner actor starting",
1571
1575
  actorId,
1572
- name: config2.name,
1573
- key: config2.key,
1576
+ name: runConfig.name,
1577
+ key: runConfig.key,
1574
1578
  generation
1575
1579
  });
1576
1580
  let input;
1577
- if (config2.input) {
1578
- input = cbor3.decode(config2.input);
1581
+ if (runConfig.input) {
1582
+ input = cbor3.decode(runConfig.input);
1579
1583
  }
1580
1584
  let handler = this.#actors.get(actorId);
1581
1585
  if (!handler) {
@@ -1585,14 +1589,10 @@ var EngineActorDriver = class {
1585
1589
  };
1586
1590
  this.#actors.set(actorId, handler);
1587
1591
  }
1588
- const name = config2.name;
1589
- invariant3(config2.key, "actor should have a key");
1590
- const key = deserializeActorKey(config2.key);
1591
- const definition = lookupInRegistry(
1592
- this.#registryConfig,
1593
- config2.name
1594
- // TODO: Remove cast
1595
- );
1592
+ const name = runConfig.name;
1593
+ invariant3(runConfig.key, "actor should have a key");
1594
+ const key = deserializeActorKey(runConfig.key);
1595
+ const definition = lookupInRegistry(this.#registryConfig, runConfig.name);
1596
1596
  handler.actor = definition.instantiate();
1597
1597
  await handler.actor.start(
1598
1598
  this,
@@ -1718,35 +1718,17 @@ var EngineActorDriver = class {
1718
1718
  async serverlessHandleStart(c) {
1719
1719
  await this.#runnerStarted.promise;
1720
1720
  return streamSSE2(c, async (stream) => {
1721
+ stream.onAbort(() => this.shutdown(true));
1721
1722
  const payload = this.#runner.getServerlessInitPacket();
1722
1723
  invariant3(payload, "runnerId not set");
1723
- stream.writeSSE({ data: payload });
1724
+ await stream.writeSSE({ data: payload });
1724
1725
  return this.#runnerStopped.promise;
1725
1726
  });
1726
1727
  }
1727
1728
  };
1728
1729
 
1729
- // src/drivers/engine/config.ts
1730
- import { z as z2 } from "zod";
1731
- var ConfigSchema = z2.object({
1732
- app: z2.custom().optional(),
1733
- endpoint: z2.string().default(
1734
- () => getEnvUniversal("RIVET_ENGINE") ?? "http://localhost:6420"
1735
- ),
1736
- token: z2.string().optional().transform((val) => val ?? getEnvUniversal("RIVET_TOKEN")),
1737
- pegboardEndpoint: z2.string().optional(),
1738
- namespace: z2.string().default(() => getEnvUniversal("RIVET_NAMESPACE") ?? "default"),
1739
- runnerName: z2.string().default(() => getEnvUniversal("RIVET_RUNNER") ?? "rivetkit"),
1740
- // TODO: Automatically attempt to determine key by common env vars (e.g. k8s pod name)
1741
- runnerKey: z2.string().default(
1742
- () => getEnvUniversal("RIVET_RUNNER_KEY") ?? crypto.randomUUID()
1743
- ),
1744
- totalSlots: z2.number().default(1e5)
1745
- }).default({});
1746
-
1747
1730
  // src/drivers/engine/mod.ts
1748
- function createEngineDriver(inputConfig) {
1749
- const config2 = ConfigSchema.parse(inputConfig);
1731
+ function createEngineDriver() {
1750
1732
  return {
1751
1733
  name: "engine",
1752
1734
  manager: (_registryConfig, runConfig) => {
@@ -1757,8 +1739,7 @@ function createEngineDriver(inputConfig) {
1757
1739
  registryConfig,
1758
1740
  runConfig,
1759
1741
  managerDriver,
1760
- inlineClient,
1761
- config2
1742
+ inlineClient
1762
1743
  );
1763
1744
  }
1764
1745
  };
@@ -1949,9 +1930,9 @@ function getStoragePath(customPath) {
1949
1930
  const dirHash = createHashForPath(pathToHash);
1950
1931
  return path.join(dataPath, dirHash);
1951
1932
  }
1952
- async function pathExists(path3) {
1933
+ async function pathExists(path4) {
1953
1934
  try {
1954
- await fs.access(path3);
1935
+ await fs.access(path4);
1955
1936
  return true;
1956
1937
  } catch {
1957
1938
  return false;
@@ -2584,8 +2565,8 @@ var FileSystemManagerDriver = class {
2584
2565
  actorId
2585
2566
  });
2586
2567
  }
2587
- async openWebSocket(path3, actorId, encoding, params, connId, connToken) {
2588
- const pathOnly = path3.split("?")[0];
2568
+ async openWebSocket(path4, actorId, encoding, params, connId, connToken) {
2569
+ const pathOnly = path4.split("?")[0];
2589
2570
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2590
2571
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2591
2572
  const wsHandler = await handleWebSocketConnect(
@@ -2602,13 +2583,13 @@ var FileSystemManagerDriver = class {
2602
2583
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2603
2584
  const wsHandler = await handleRawWebSocketHandler(
2604
2585
  void 0,
2605
- path3,
2586
+ path4,
2606
2587
  this.#actorDriver,
2607
2588
  actorId
2608
2589
  );
2609
2590
  return new InlineWebSocketAdapter2(wsHandler);
2610
2591
  } else {
2611
- throw new Error(`Unreachable path: ${path3}`);
2592
+ throw new Error(`Unreachable path: ${path4}`);
2612
2593
  }
2613
2594
  }
2614
2595
  async proxyRequest(c, actorRequest, actorId) {
@@ -2616,11 +2597,11 @@ var FileSystemManagerDriver = class {
2616
2597
  actorId
2617
2598
  });
2618
2599
  }
2619
- async proxyWebSocket(c, path3, actorId, encoding, connParams, connId, connToken) {
2600
+ async proxyWebSocket(c, path4, actorId, encoding, connParams, connId, connToken) {
2620
2601
  var _a, _b;
2621
2602
  const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
2622
2603
  invariant5(upgradeWebSocket, "missing getUpgradeWebSocket");
2623
- const pathOnly = path3.split("?")[0];
2604
+ const pathOnly = path4.split("?")[0];
2624
2605
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2625
2606
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2626
2607
  const wsHandler = await handleWebSocketConnect(
@@ -2637,13 +2618,13 @@ var FileSystemManagerDriver = class {
2637
2618
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2638
2619
  const wsHandler = await handleRawWebSocketHandler(
2639
2620
  c.req.raw,
2640
- path3,
2621
+ path4,
2641
2622
  this.#actorDriver,
2642
2623
  actorId
2643
2624
  );
2644
2625
  return upgradeWebSocket(() => wsHandler)(c, noopNext());
2645
2626
  } else {
2646
- throw new Error(`Unreachable path: ${path3}`);
2627
+ throw new Error(`Unreachable path: ${path4}`);
2647
2628
  }
2648
2629
  }
2649
2630
  async getForId({ actorId }) {
@@ -2753,30 +2734,284 @@ function createMemoryDriver() {
2753
2734
  return createFileSystemOrMemoryDriver(false);
2754
2735
  }
2755
2736
 
2737
+ // src/registry/mod.ts
2738
+ import invariant7 from "invariant";
2739
+
2756
2740
  // src/drivers/default.ts
2757
2741
  function chooseDefaultDriver(runConfig) {
2758
2742
  if (runConfig.endpoint && runConfig.driver) {
2759
2743
  throw new UserError(
2760
- "Cannot specify both 'engine' and 'driver' in configuration"
2744
+ "Cannot specify both 'endpoint' and 'driver' in configuration"
2745
+ );
2746
+ }
2747
+ if (runConfig.runnerKind === "serverless" && !runConfig.endpoint) {
2748
+ throw new UserError(
2749
+ "Cannot use 'serverless' runnerKind without the 'endpoint' config set."
2761
2750
  );
2762
2751
  }
2763
2752
  if (runConfig.driver) {
2764
2753
  return runConfig.driver;
2765
2754
  }
2766
- if (runConfig.endpoint) {
2755
+ if (runConfig.endpoint || runConfig.token) {
2767
2756
  loggerWithoutContext().debug({
2768
2757
  msg: "using rivet engine driver",
2769
2758
  endpoint: runConfig.endpoint
2770
2759
  });
2771
- return createEngineDriver({
2772
- endpoint: runConfig.endpoint,
2773
- token: runConfig.token
2774
- });
2760
+ return createEngineDriver();
2775
2761
  }
2776
2762
  loggerWithoutContext().debug({ msg: "using default file system driver" });
2777
2763
  return createFileSystemOrMemoryDriver(true);
2778
2764
  }
2779
2765
 
2766
+ // src/engine-process/mod.ts
2767
+ import { spawn } from "child_process";
2768
+ import { createWriteStream } from "fs";
2769
+ import * as fs3 from "fs/promises";
2770
+ import * as path3 from "path";
2771
+ import { pipeline } from "stream/promises";
2772
+
2773
+ // src/engine-process/log.ts
2774
+ function logger6() {
2775
+ return getLogger("engine-process");
2776
+ }
2777
+
2778
+ // src/engine-process/mod.ts
2779
+ var ENGINE_PORT = 6420;
2780
+ var ENGINE_ENDPOINT = `http://localhost:${ENGINE_PORT}`;
2781
+ var ENGINE_BASE_URL = "https://releases.rivet.gg/engine";
2782
+ var ENGINE_BINARY_NAME = "rivet-engine";
2783
+ async function ensureEngineProcess(options) {
2784
+ logger6().debug({ msg: "ensuring engine process", version: options.version });
2785
+ const storageRoot = getStoragePath();
2786
+ const binDir = path3.join(storageRoot, "bin");
2787
+ const varDir = path3.join(storageRoot, "var");
2788
+ const logsDir = path3.join(varDir, "logs", "rivet-engine");
2789
+ await ensureDirectoryExists(binDir);
2790
+ await ensureDirectoryExists(varDir);
2791
+ await ensureDirectoryExists(logsDir);
2792
+ const executableName = process.platform === "win32" ? `${ENGINE_BINARY_NAME}-${options.version}.exe` : `${ENGINE_BINARY_NAME}-${options.version}`;
2793
+ const binaryPath = path3.join(binDir, executableName);
2794
+ await downloadEngineBinaryIfNeeded(binaryPath, options.version, varDir);
2795
+ if (await isEngineRunning()) {
2796
+ try {
2797
+ await waitForEngineHealth();
2798
+ logger6().debug({
2799
+ msg: "engine already running and healthy",
2800
+ version: options.version
2801
+ });
2802
+ return;
2803
+ } catch (error) {
2804
+ logger6().warn({
2805
+ msg: "existing engine process not healthy, cannot restart automatically",
2806
+ error
2807
+ });
2808
+ throw new Error(
2809
+ "Engine process exists but is not healthy. Please manually stop the process on port 6420 and retry."
2810
+ );
2811
+ }
2812
+ }
2813
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").replace(/\./g, "-");
2814
+ const stdoutLogPath = path3.join(logsDir, `engine-${timestamp}-stdout.log`);
2815
+ const stderrLogPath = path3.join(logsDir, `engine-${timestamp}-stderr.log`);
2816
+ const stdoutStream = createWriteStream(stdoutLogPath, { flags: "a" });
2817
+ const stderrStream = createWriteStream(stderrLogPath, { flags: "a" });
2818
+ logger6().debug({
2819
+ msg: "creating engine log files",
2820
+ stdout: stdoutLogPath,
2821
+ stderr: stderrLogPath
2822
+ });
2823
+ const child = spawn(binaryPath, ["start"], {
2824
+ cwd: path3.dirname(binaryPath),
2825
+ stdio: ["inherit", "pipe", "pipe"],
2826
+ env: {
2827
+ ...process.env
2828
+ }
2829
+ });
2830
+ if (!child.pid) {
2831
+ throw new Error("failed to spawn rivet engine process");
2832
+ }
2833
+ if (child.stdout) {
2834
+ child.stdout.pipe(stdoutStream);
2835
+ }
2836
+ if (child.stderr) {
2837
+ child.stderr.pipe(stderrStream);
2838
+ }
2839
+ logger6().debug({
2840
+ msg: "spawned engine process",
2841
+ pid: child.pid,
2842
+ cwd: path3.dirname(binaryPath)
2843
+ });
2844
+ child.once("exit", (code, signal) => {
2845
+ logger6().warn({
2846
+ msg: "engine process exited",
2847
+ code,
2848
+ signal
2849
+ });
2850
+ stdoutStream.end();
2851
+ stderrStream.end();
2852
+ });
2853
+ child.once("error", (error) => {
2854
+ logger6().error({
2855
+ msg: "engine process failed",
2856
+ error
2857
+ });
2858
+ stdoutStream.end();
2859
+ stderrStream.end();
2860
+ });
2861
+ await waitForEngineHealth();
2862
+ logger6().info({
2863
+ msg: "engine process started",
2864
+ pid: child.pid,
2865
+ version: options.version,
2866
+ logs: {
2867
+ stdout: stdoutLogPath,
2868
+ stderr: stderrLogPath
2869
+ }
2870
+ });
2871
+ }
2872
+ async function downloadEngineBinaryIfNeeded(binaryPath, version, varDir) {
2873
+ const binaryExists = await fileExists(binaryPath);
2874
+ if (binaryExists) {
2875
+ logger6().debug({
2876
+ msg: "engine binary already cached",
2877
+ version,
2878
+ path: binaryPath
2879
+ });
2880
+ return;
2881
+ }
2882
+ const { targetTriplet, extension } = resolveTargetTriplet();
2883
+ const remoteFile = `${ENGINE_BINARY_NAME}-${targetTriplet}${extension}`;
2884
+ const downloadUrl = `${ENGINE_BASE_URL}/${version}/${remoteFile}`;
2885
+ logger6().info({
2886
+ msg: "downloading engine binary",
2887
+ url: downloadUrl,
2888
+ path: binaryPath,
2889
+ version
2890
+ });
2891
+ const response = await fetch(downloadUrl);
2892
+ if (!response.ok || !response.body) {
2893
+ throw new Error(
2894
+ `failed to download rivet engine binary from ${downloadUrl}: ${response.status} ${response.statusText}`
2895
+ );
2896
+ }
2897
+ const tempPath = `${binaryPath}.${process.pid}.tmp`;
2898
+ await pipeline(response.body, createWriteStream(tempPath));
2899
+ if (process.platform !== "win32") {
2900
+ await fs3.chmod(tempPath, 493);
2901
+ }
2902
+ await fs3.rename(tempPath, binaryPath);
2903
+ logger6().debug({
2904
+ msg: "engine binary download complete",
2905
+ version,
2906
+ path: binaryPath
2907
+ });
2908
+ logger6().info({
2909
+ msg: "engine binary downloaded",
2910
+ version,
2911
+ path: binaryPath
2912
+ });
2913
+ }
2914
+ function resolveTargetTriplet() {
2915
+ return resolveTargetTripletFor(process.platform, process.arch);
2916
+ }
2917
+ function resolveTargetTripletFor(platform, arch) {
2918
+ switch (platform) {
2919
+ case "darwin":
2920
+ if (arch === "arm64") {
2921
+ return { targetTriplet: "aarch64-apple-darwin", extension: "" };
2922
+ }
2923
+ if (arch === "x64") {
2924
+ return { targetTriplet: "x86_64-apple-darwin", extension: "" };
2925
+ }
2926
+ break;
2927
+ case "linux":
2928
+ if (arch === "x64") {
2929
+ return { targetTriplet: "x86_64-unknown-linux-musl", extension: "" };
2930
+ }
2931
+ break;
2932
+ case "win32":
2933
+ if (arch === "x64") {
2934
+ return { targetTriplet: "x86_64-pc-windows-gnu", extension: ".exe" };
2935
+ }
2936
+ break;
2937
+ }
2938
+ throw new Error(
2939
+ `unsupported platform for rivet engine binary: ${platform}/${arch}`
2940
+ );
2941
+ }
2942
+ async function isEngineRunning() {
2943
+ return await checkIfEngineAlreadyRunningOnPort(ENGINE_PORT);
2944
+ }
2945
+ async function checkIfEngineAlreadyRunningOnPort(port) {
2946
+ let response;
2947
+ try {
2948
+ response = await fetch(`http://localhost:${port}/health`);
2949
+ } catch (err) {
2950
+ return false;
2951
+ }
2952
+ if (response.ok) {
2953
+ const health = await response.json();
2954
+ if (health.runtime === "engine") {
2955
+ logger6().debug({
2956
+ msg: "rivet engine already running on port",
2957
+ port
2958
+ });
2959
+ return true;
2960
+ } else if (health.runtime === "rivetkit") {
2961
+ logger6().error({
2962
+ msg: "another rivetkit process is already running on port",
2963
+ port
2964
+ });
2965
+ throw new Error(
2966
+ "RivetKit process already running on port 6420, stop that process and restart this."
2967
+ );
2968
+ } else {
2969
+ throw new Error(
2970
+ "Unknown process running on port 6420, cannot identify what it is."
2971
+ );
2972
+ }
2973
+ }
2974
+ return false;
2975
+ }
2976
+ async function fileExists(filePath) {
2977
+ try {
2978
+ await fs3.access(filePath);
2979
+ return true;
2980
+ } catch {
2981
+ return false;
2982
+ }
2983
+ }
2984
+ var HEALTH_MAX_WAIT = 1e4;
2985
+ var HEALTH_INTERVAL = 100;
2986
+ async function waitForEngineHealth() {
2987
+ const maxRetries = Math.ceil(HEALTH_MAX_WAIT / HEALTH_INTERVAL);
2988
+ logger6().debug({ msg: "waiting for engine health check" });
2989
+ for (let i = 0; i < maxRetries; i++) {
2990
+ try {
2991
+ const response = await fetch(`${ENGINE_ENDPOINT}/health`);
2992
+ if (response.ok) {
2993
+ logger6().debug({ msg: "engine health check passed" });
2994
+ return;
2995
+ }
2996
+ } catch (error) {
2997
+ if (i === maxRetries - 1) {
2998
+ throw new Error(
2999
+ `engine health check failed after ${maxRetries} retries: ${error}`
3000
+ );
3001
+ }
3002
+ }
3003
+ if (i < maxRetries - 1) {
3004
+ logger6().trace({
3005
+ msg: "engine not ready, retrying",
3006
+ attempt: i + 1,
3007
+ maxRetries
3008
+ });
3009
+ await new Promise((resolve) => setTimeout(resolve, HEALTH_INTERVAL));
3010
+ }
3011
+ }
3012
+ throw new Error(`engine health check failed after ${maxRetries} retries`);
3013
+ }
3014
+
2780
3015
  // src/manager/router.ts
2781
3016
  import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2782
3017
  import * as cbor4 from "cbor-x";
@@ -2784,66 +3019,79 @@ import {
2784
3019
  Hono as Hono3
2785
3020
  } from "hono";
2786
3021
  import { cors as corsMiddleware } from "hono/cors";
3022
+ import { createMiddleware } from "hono/factory";
2787
3023
  import invariant6 from "invariant";
2788
3024
  import { z as z5 } from "zod";
2789
3025
 
2790
3026
  // src/manager-api/actors.ts
2791
- import { z as z4 } from "zod";
3027
+ import { z as z3 } from "zod";
2792
3028
 
2793
3029
  // src/manager-api/common.ts
2794
- import { z as z3 } from "zod";
2795
- var RivetIdSchema = z3.string();
3030
+ import { z as z2 } from "zod";
3031
+ var RivetIdSchema = z2.string();
2796
3032
 
2797
3033
  // src/manager-api/actors.ts
2798
- var ActorSchema = z4.object({
3034
+ var ActorSchema = z3.object({
2799
3035
  actor_id: RivetIdSchema,
2800
- name: z4.string(),
2801
- key: z4.string(),
3036
+ name: z3.string(),
3037
+ key: z3.string(),
2802
3038
  namespace_id: RivetIdSchema,
2803
- runner_name_selector: z4.string(),
2804
- create_ts: z4.number(),
2805
- connectable_ts: z4.number().nullable().optional(),
2806
- destroy_ts: z4.number().nullable().optional(),
2807
- sleep_ts: z4.number().nullable().optional(),
2808
- start_ts: z4.number().nullable().optional()
3039
+ runner_name_selector: z3.string(),
3040
+ create_ts: z3.number(),
3041
+ connectable_ts: z3.number().nullable().optional(),
3042
+ destroy_ts: z3.number().nullable().optional(),
3043
+ sleep_ts: z3.number().nullable().optional(),
3044
+ start_ts: z3.number().nullable().optional()
2809
3045
  });
2810
- var ActorsListResponseSchema = z4.object({
2811
- actors: z4.array(ActorSchema)
3046
+ var ActorsListResponseSchema = z3.object({
3047
+ actors: z3.array(ActorSchema)
2812
3048
  });
2813
- var ActorsCreateRequestSchema = z4.object({
2814
- name: z4.string(),
2815
- runner_name_selector: z4.string(),
2816
- crash_policy: z4.string(),
2817
- key: z4.string().nullable().optional(),
2818
- input: z4.string().nullable().optional()
3049
+ var ActorsCreateRequestSchema = z3.object({
3050
+ name: z3.string(),
3051
+ runner_name_selector: z3.string(),
3052
+ crash_policy: z3.string(),
3053
+ key: z3.string().nullable().optional(),
3054
+ input: z3.string().nullable().optional()
2819
3055
  });
2820
- var ActorsCreateResponseSchema = z4.object({
3056
+ var ActorsCreateResponseSchema = z3.object({
2821
3057
  actor: ActorSchema
2822
3058
  });
2823
- var ActorsGetOrCreateRequestSchema = z4.object({
2824
- name: z4.string(),
2825
- key: z4.string(),
2826
- runner_name_selector: z4.string(),
2827
- crash_policy: z4.string(),
2828
- input: z4.string().nullable().optional()
3059
+ var ActorsGetOrCreateRequestSchema = z3.object({
3060
+ name: z3.string(),
3061
+ key: z3.string(),
3062
+ runner_name_selector: z3.string(),
3063
+ crash_policy: z3.string(),
3064
+ input: z3.string().nullable().optional()
2829
3065
  });
2830
- var ActorsGetOrCreateResponseSchema = z4.object({
3066
+ var ActorsGetOrCreateResponseSchema = z3.object({
2831
3067
  actor: ActorSchema,
2832
- created: z4.boolean()
3068
+ created: z3.boolean()
2833
3069
  });
2834
- var ActorsDeleteResponseSchema = z4.object({});
3070
+ var ActorsDeleteResponseSchema = z3.object({});
2835
3071
 
2836
3072
  // src/manager/gateway.ts
2837
3073
  async function actorGateway(runConfig, managerDriver, c, next) {
2838
3074
  if (c.req.path.startsWith("/.test/")) {
2839
3075
  return next();
2840
3076
  }
3077
+ let strippedPath = c.req.path;
3078
+ if (runConfig.basePath && strippedPath.startsWith(runConfig.basePath)) {
3079
+ strippedPath = strippedPath.slice(runConfig.basePath.length);
3080
+ if (!strippedPath.startsWith("/")) {
3081
+ strippedPath = "/" + strippedPath;
3082
+ }
3083
+ }
2841
3084
  if (c.req.header("upgrade") === "websocket") {
2842
- return await handleWebSocketGateway(runConfig, managerDriver, c);
3085
+ return await handleWebSocketGateway(
3086
+ runConfig,
3087
+ managerDriver,
3088
+ c,
3089
+ strippedPath
3090
+ );
2843
3091
  }
2844
- return await handleHttpGateway(managerDriver, c, next);
3092
+ return await handleHttpGateway(managerDriver, c, next, strippedPath);
2845
3093
  }
2846
- async function handleWebSocketGateway(runConfig, managerDriver, c) {
3094
+ async function handleWebSocketGateway(runConfig, managerDriver, c, strippedPath) {
2847
3095
  var _a;
2848
3096
  const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
2849
3097
  if (!upgradeWebSocket) {
@@ -2885,12 +3133,12 @@ async function handleWebSocketGateway(runConfig, managerDriver, c) {
2885
3133
  logger().debug({
2886
3134
  msg: "proxying websocket to actor",
2887
3135
  actorId,
2888
- path: c.req.path,
3136
+ path: strippedPath,
2889
3137
  encoding: encodingRaw
2890
3138
  });
2891
3139
  const encoding = encodingRaw || "json";
2892
3140
  const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
2893
- const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
3141
+ const pathWithQuery = c.req.url.includes("?") ? strippedPath + c.req.url.substring(c.req.url.indexOf("?")) : strippedPath;
2894
3142
  return await managerDriver.proxyWebSocket(
2895
3143
  c,
2896
3144
  pathWithQuery,
@@ -2902,7 +3150,7 @@ async function handleWebSocketGateway(runConfig, managerDriver, c) {
2902
3150
  connTokenRaw
2903
3151
  );
2904
3152
  }
2905
- async function handleHttpGateway(managerDriver, c, next) {
3153
+ async function handleHttpGateway(managerDriver, c, next, strippedPath) {
2906
3154
  const target = c.req.header(HEADER_RIVET_TARGET);
2907
3155
  const actorId = c.req.header(HEADER_RIVET_ACTOR);
2908
3156
  if (target !== "actor") {
@@ -2914,19 +3162,20 @@ async function handleHttpGateway(managerDriver, c, next) {
2914
3162
  logger().debug({
2915
3163
  msg: "proxying request to actor",
2916
3164
  actorId,
2917
- path: c.req.path,
3165
+ path: strippedPath,
2918
3166
  method: c.req.method
2919
3167
  });
2920
3168
  const proxyHeaders = new Headers(c.req.raw.headers);
2921
3169
  proxyHeaders.delete(HEADER_RIVET_TARGET);
2922
3170
  proxyHeaders.delete(HEADER_RIVET_ACTOR);
2923
3171
  const url = new URL(c.req.url);
2924
- const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
3172
+ const proxyUrl = new URL(`http://actor${strippedPath}${url.search}`);
2925
3173
  const proxyRequest = new Request(proxyUrl, {
2926
3174
  method: c.req.raw.method,
2927
3175
  headers: proxyHeaders,
2928
3176
  body: c.req.raw.body,
2929
- signal: c.req.raw.signal
3177
+ signal: c.req.raw.signal,
3178
+ duplex: "half"
2930
3179
  });
2931
3180
  return await managerDriver.proxyRequest(c, proxyRequest, actorId);
2932
3181
  }
@@ -3102,6 +3351,22 @@ async function createTestWebSocketProxy(clientWsPromise) {
3102
3351
  };
3103
3352
  }
3104
3353
 
3354
+ // src/manager/router-schema.ts
3355
+ import { z as z4 } from "zod";
3356
+ var ServerlessStartHeadersSchema = z4.object({
3357
+ endpoint: z4.string({ required_error: "x-rivet-endpoint header is required" }),
3358
+ token: z4.string({ invalid_type_error: "x-rivet-token header must be a string" }).optional(),
3359
+ totalSlots: z4.coerce.number({
3360
+ invalid_type_error: "x-rivet-total-slots header must be a number"
3361
+ }).int("x-rivet-total-slots header must be an integer").gte(1, "x-rivet-total-slots header must be positive"),
3362
+ runnerName: z4.string({
3363
+ required_error: "x-rivet-runner-name header is required"
3364
+ }),
3365
+ namespace: z4.string({
3366
+ required_error: "x-rivet-namespace-id header is required"
3367
+ })
3368
+ });
3369
+
3105
3370
  // src/manager/router.ts
3106
3371
  function buildOpenApiResponses(schema) {
3107
3372
  return {
@@ -3121,21 +3386,42 @@ function buildOpenApiResponses(schema) {
3121
3386
  }
3122
3387
  };
3123
3388
  }
3124
- function createManagerRouter(registryConfig, runConfig, managerDriver, serverlessActorDriverBuilder) {
3389
+ function createManagerRouter(registryConfig, runConfig, managerDriver, driverConfig, client) {
3125
3390
  const router = new OpenAPIHono({ strict: false }).basePath(
3126
3391
  runConfig.basePath
3127
3392
  );
3128
3393
  router.use("*", loggerMiddleware(logger()));
3129
- if (serverlessActorDriverBuilder) {
3130
- addServerlessRoutes(runConfig, serverlessActorDriverBuilder, router);
3131
- } else {
3394
+ router.use(
3395
+ "*",
3396
+ createMiddleware(async (c, next) => {
3397
+ const upgrade = c.req.header("upgrade");
3398
+ const isWebSocket = (upgrade == null ? void 0 : upgrade.toLowerCase()) === "websocket";
3399
+ const isGet = c.req.method === "GET";
3400
+ if (isGet && isWebSocket) {
3401
+ c.header("Sec-WebSocket-Protocol", "rivet");
3402
+ }
3403
+ await next();
3404
+ })
3405
+ );
3406
+ if (runConfig.runnerKind === "serverless") {
3407
+ addServerlessRoutes(
3408
+ driverConfig,
3409
+ registryConfig,
3410
+ runConfig,
3411
+ managerDriver,
3412
+ client,
3413
+ router
3414
+ );
3415
+ } else if (runConfig.runnerKind === "normal") {
3132
3416
  addManagerRoutes(registryConfig, runConfig, managerDriver, router);
3417
+ } else {
3418
+ assertUnreachable(runConfig.runnerKind);
3133
3419
  }
3134
3420
  router.notFound(handleRouteNotFound);
3135
3421
  router.onError(handleRouteError);
3136
3422
  return { router, openapi: router };
3137
3423
  }
3138
- function addServerlessRoutes(runConfig, serverlessActorDriverBuilder, router) {
3424
+ function addServerlessRoutes(driverConfig, registryConfig, runConfig, managerDriver, client, router) {
3139
3425
  if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
3140
3426
  router.get("/", (c) => {
3141
3427
  return c.text(
@@ -3143,12 +3429,39 @@ function addServerlessRoutes(runConfig, serverlessActorDriverBuilder, router) {
3143
3429
  );
3144
3430
  });
3145
3431
  router.get("/start", async (c) => {
3146
- const token = c.req.header("x-rivet-token");
3147
- let totalSlots = parseInt(
3148
- c.req.header("x-rivetkit-total-slots")
3432
+ var _a;
3433
+ const parseResult = ServerlessStartHeadersSchema.safeParse({
3434
+ endpoint: c.req.header("x-rivet-endpoint"),
3435
+ token: c.req.header("x-rivet-token") ?? void 0,
3436
+ totalSlots: c.req.header("x-rivet-total-slots"),
3437
+ runnerName: c.req.header("x-rivet-runner-name"),
3438
+ namespace: c.req.header("x-rivet-namespace-id")
3439
+ });
3440
+ if (!parseResult.success) {
3441
+ throw new InvalidRequest(
3442
+ ((_a = parseResult.error.issues[0]) == null ? void 0 : _a.message) ?? "invalid serverless start headers"
3443
+ );
3444
+ }
3445
+ const { endpoint, token, totalSlots, runnerName, namespace } = parseResult.data;
3446
+ logger().debug({
3447
+ msg: "received serverless runner start request",
3448
+ endpoint,
3449
+ totalSlots,
3450
+ runnerName,
3451
+ namespace
3452
+ });
3453
+ const newRunConfig = Object.assign({}, runConfig);
3454
+ newRunConfig.endpoint = endpoint;
3455
+ newRunConfig.token = token;
3456
+ newRunConfig.totalSlots = totalSlots;
3457
+ newRunConfig.runnerName = runnerName;
3458
+ newRunConfig.namespace = namespace;
3459
+ const actorDriver = driverConfig.actor(
3460
+ registryConfig,
3461
+ newRunConfig,
3462
+ managerDriver,
3463
+ client
3149
3464
  );
3150
- if (isNaN(totalSlots)) totalSlots = void 0;
3151
- const actorDriver = serverlessActorDriverBuilder(token, totalSlots);
3152
3465
  invariant6(
3153
3466
  actorDriver.serverlessHandleStart,
3154
3467
  "missing serverlessHandleStart on ActorDriver"
@@ -3156,7 +3469,11 @@ function addServerlessRoutes(runConfig, serverlessActorDriverBuilder, router) {
3156
3469
  return await actorDriver.serverlessHandleStart(c);
3157
3470
  });
3158
3471
  router.get("/health", (c) => {
3159
- return c.text("ok");
3472
+ return c.json({
3473
+ status: "ok",
3474
+ runtime: "rivetkit",
3475
+ version: VERSION
3476
+ });
3160
3477
  });
3161
3478
  }
3162
3479
  function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
@@ -3235,7 +3552,9 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3235
3552
  }
3236
3553
  }
3237
3554
  return c.json({
3238
- actors: actors.map(createApiActor)
3555
+ actors: actors.map(
3556
+ (actor2) => createApiActor(actor2, runConfig.runnerName)
3557
+ )
3239
3558
  });
3240
3559
  });
3241
3560
  }
@@ -3264,7 +3583,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3264
3583
  });
3265
3584
  if (existingActor) {
3266
3585
  return c.json({
3267
- actor: createApiActor(existingActor),
3586
+ actor: createApiActor(existingActor, runConfig.runnerName),
3268
3587
  created: false
3269
3588
  });
3270
3589
  }
@@ -3278,7 +3597,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3278
3597
  // Not provided in the request schema
3279
3598
  });
3280
3599
  return c.json({
3281
- actor: createApiActor(newActor),
3600
+ actor: createApiActor(newActor, runConfig.runnerName),
3282
3601
  created: true
3283
3602
  });
3284
3603
  });
@@ -3309,7 +3628,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3309
3628
  region: void 0
3310
3629
  // Not provided in the request schema
3311
3630
  });
3312
- const actor2 = createApiActor(actorOutput);
3631
+ const actor2 = createApiActor(actorOutput, runConfig.runnerName);
3313
3632
  return c.json({ actor: actor2 });
3314
3633
  });
3315
3634
  }
@@ -3344,7 +3663,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3344
3663
  let actorId = "";
3345
3664
  let encoding = "bare";
3346
3665
  let transport = "websocket";
3347
- let path3 = "";
3666
+ let path4 = "";
3348
3667
  let params;
3349
3668
  let connId;
3350
3669
  let connToken;
@@ -3360,7 +3679,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3360
3679
  WS_PROTOCOL_TRANSPORT.length
3361
3680
  );
3362
3681
  } else if (protocol.startsWith(WS_PROTOCOL_PATH)) {
3363
- path3 = decodeURIComponent(
3682
+ path4 = decodeURIComponent(
3364
3683
  protocol.substring(WS_PROTOCOL_PATH.length)
3365
3684
  );
3366
3685
  } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
@@ -3380,10 +3699,10 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3380
3699
  params,
3381
3700
  encodingKind: encoding,
3382
3701
  transport,
3383
- path: path3
3702
+ path: path4
3384
3703
  });
3385
3704
  const clientWsPromise = managerDriver.openWebSocket(
3386
- path3,
3705
+ path4,
3387
3706
  actorId,
3388
3707
  encoding,
3389
3708
  params,
@@ -3472,7 +3791,12 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3472
3791
  });
3473
3792
  }
3474
3793
  router.get("/health", (c) => {
3475
- return c.text("ok");
3794
+ return c.json({
3795
+ status: "ok",
3796
+ rivetkit: {
3797
+ version: VERSION
3798
+ }
3799
+ });
3476
3800
  });
3477
3801
  (_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
3478
3802
  managerDriver,
@@ -3480,15 +3804,14 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3480
3804
  router
3481
3805
  );
3482
3806
  }
3483
- function createApiActor(actor2) {
3807
+ function createApiActor(actor2, runnerName = "default") {
3484
3808
  return {
3485
3809
  actor_id: actor2.actorId,
3486
3810
  name: actor2.name,
3487
3811
  key: serializeActorKey(actor2.key),
3488
3812
  namespace_id: "default",
3489
3813
  // Assert default namespace
3490
- runner_name_selector: "rivetkit",
3491
- // Assert rivetkit runner
3814
+ runner_name_selector: runnerName,
3492
3815
  create_ts: Date.now(),
3493
3816
  connectable_ts: null,
3494
3817
  destroy_ts: null,
@@ -3517,13 +3840,13 @@ var RegistryConfigSchema = z6.object({
3517
3840
  });
3518
3841
 
3519
3842
  // src/registry/log.ts
3520
- function logger6() {
3843
+ function logger7() {
3521
3844
  return getLogger("registry");
3522
3845
  }
3523
3846
 
3524
3847
  // src/registry/serve.ts
3525
3848
  import { Hono as Hono4 } from "hono";
3526
- async function crossPlatformServe(rivetKitRouter, userRouter) {
3849
+ async function crossPlatformServe(runConfig, rivetKitRouter, userRouter) {
3527
3850
  const app = userRouter ?? new Hono4();
3528
3851
  let serve;
3529
3852
  try {
@@ -3533,7 +3856,7 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3533
3856
  );
3534
3857
  serve = dep.serve;
3535
3858
  } catch (err) {
3536
- logger6().error(
3859
+ logger7().error(
3537
3860
  "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'"
3538
3861
  );
3539
3862
  process.exit(1);
@@ -3547,7 +3870,7 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3547
3870
  );
3548
3871
  createNodeWebSocket = dep.createNodeWebSocket;
3549
3872
  } catch (err) {
3550
- logger6().error(
3873
+ logger7().error(
3551
3874
  "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'"
3552
3875
  );
3553
3876
  process.exit(1);
@@ -3555,10 +3878,10 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3555
3878
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
3556
3879
  app
3557
3880
  });
3558
- const port = 6420;
3881
+ const port = runConfig.defaultServerPort;
3559
3882
  const server = serve(
3560
3883
  { fetch: app.fetch, port },
3561
- () => logger6().info({ msg: "server listening", port })
3884
+ () => logger7().info({ msg: "server listening", port })
3562
3885
  );
3563
3886
  injectWebSocket(server);
3564
3887
  return { upgradeWebSocket };
@@ -3578,7 +3901,34 @@ var Registry = class {
3578
3901
  */
3579
3902
  start(inputConfig) {
3580
3903
  var _a, _b, _c;
3581
- const config2 = RunConfigSchema.parse(inputConfig);
3904
+ const config2 = RunnerConfigSchema.parse(inputConfig);
3905
+ if (config2.autoConfigureServerless && config2.runnerKind !== "serverless") {
3906
+ throw new Error(
3907
+ "autoConfigureServerless can only be configured when runnerKind is 'serverless'"
3908
+ );
3909
+ }
3910
+ const readyPromises = [];
3911
+ if (config2.runEngine) {
3912
+ logger7().debug({
3913
+ msg: "run engine requested",
3914
+ version: config2.runEngineVersion
3915
+ });
3916
+ invariant7(
3917
+ config2.endpoint === void 0,
3918
+ "cannot specify 'endpoint' with 'runEngine'"
3919
+ );
3920
+ config2.endpoint = ENGINE_ENDPOINT;
3921
+ config2.disableActorDriver = true;
3922
+ const engineProcessPromise = ensureEngineProcess({
3923
+ version: config2.runEngineVersion
3924
+ });
3925
+ readyPromises.push(engineProcessPromise);
3926
+ }
3927
+ if (config2.runnerKind === "serverless") {
3928
+ config2.defaultServerPort = 8080;
3929
+ config2.overrideServerAddress = config2.endpoint;
3930
+ config2.disableActorDriver = true;
3931
+ }
3582
3932
  if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3583
3933
  configureBaseLogger(config2.logging.baseLogger);
3584
3934
  } else {
@@ -3587,11 +3937,13 @@ var Registry = class {
3587
3937
  const driver = chooseDefaultDriver(config2);
3588
3938
  if (driver.name === "engine") {
3589
3939
  config2.inspector.enabled = { manager: false, actor: true };
3590
- config2.disableServer = true;
3940
+ if (config2.runnerKind !== "serverless") {
3941
+ config2.disableDefaultServer = true;
3942
+ }
3591
3943
  }
3592
3944
  if (driver.name === "cloudflare-workers") {
3593
3945
  config2.inspector.enabled = { manager: false, actor: true };
3594
- config2.disableServer = true;
3946
+ config2.disableDefaultServer = true;
3595
3947
  config2.disableActorDriver = true;
3596
3948
  config2.noWelcome = true;
3597
3949
  }
@@ -3603,20 +3955,28 @@ var Registry = class {
3603
3955
  configureInspectorAccessToken(config2, managerDriver);
3604
3956
  const client = createClientWithDriver(managerDriver, config2);
3605
3957
  const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3606
- logger6().info({
3958
+ logger7().info({
3607
3959
  msg: "rivetkit ready",
3608
3960
  driver: driver.name,
3609
3961
  definitions: Object.keys(this.#config.use).length,
3610
3962
  ...driverLog
3611
3963
  });
3612
3964
  if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
3613
- logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3965
+ logger7().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3614
3966
  }
3615
3967
  if (!config2.noWelcome) {
3616
3968
  const displayInfo = managerDriver.displayInformation();
3617
3969
  console.log();
3618
3970
  console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3619
- console.log(` - Endpoint: http://127.0.0.1:6420`);
3971
+ if (!config2.disableDefaultServer) {
3972
+ console.log(` - Endpoint: ${config2.endpoint}`);
3973
+ } else if (config2.overrideServerAddress) {
3974
+ console.log(` - Endpoint: ${config2.overrideServerAddress}`);
3975
+ }
3976
+ if (config2.runEngine) {
3977
+ const padding = " ".repeat(Math.max(0, 13 - "Engine".length));
3978
+ console.log(` - Engine:${padding}v${config2.runEngineVersion}`);
3979
+ }
3620
3980
  for (const [k, v] of Object.entries(displayInfo.properties)) {
3621
3981
  const padding = " ".repeat(Math.max(0, 13 - k.length));
3622
3982
  console.log(` - ${k}:${padding}${v}`);
@@ -3627,22 +3987,25 @@ var Registry = class {
3627
3987
  console.log();
3628
3988
  }
3629
3989
  if (!config2.disableActorDriver) {
3630
- const _actorDriver = driver.actor(
3631
- this.#config,
3632
- config2,
3633
- managerDriver,
3634
- client
3635
- );
3990
+ Promise.all(readyPromises).then(async () => {
3991
+ driver.actor(this.#config, config2, managerDriver, client);
3992
+ });
3993
+ }
3994
+ if (config2.runnerKind === "serverless" && config2.autoConfigureServerless) {
3995
+ Promise.all(readyPromises).then(async () => {
3996
+ await configureServerlessRunner(config2);
3997
+ });
3636
3998
  }
3637
3999
  const { router: hono } = createManagerRouter(
3638
4000
  this.#config,
3639
4001
  config2,
3640
4002
  managerDriver,
3641
- void 0
4003
+ driver,
4004
+ client
3642
4005
  );
3643
- if (!config2.disableServer) {
4006
+ if (!config2.disableDefaultServer) {
3644
4007
  (async () => {
3645
- const out = await crossPlatformServe(hono, void 0);
4008
+ const out = await crossPlatformServe(config2, hono, void 0);
3646
4009
  upgradeWebSocket = out.upgradeWebSocket;
3647
4010
  })();
3648
4011
  }
@@ -3651,83 +4014,83 @@ var Registry = class {
3651
4014
  fetch: hono.fetch.bind(hono)
3652
4015
  };
3653
4016
  }
3654
- startServerless(inputConfig) {
3655
- var _a, _b, _c, _d, _e;
3656
- const config2 = RunConfigSchema.parse(inputConfig);
3657
- if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3658
- configureBaseLogger(config2.logging.baseLogger);
3659
- } else {
3660
- configureDefaultLogger((_b = config2.logging) == null ? void 0 : _b.level);
3661
- }
3662
- const driver = chooseDefaultDriver(config2);
3663
- if (driver.name === "engine") {
3664
- config2.inspector.enabled = false;
3665
- config2.disableServer = true;
3666
- config2.disableActorDriver = true;
4017
+ };
4018
+ async function configureServerlessRunner(config2) {
4019
+ try {
4020
+ if (!config2.runnerName) {
4021
+ throw new Error("runnerName is required for serverless configuration");
3667
4022
  }
3668
- if (driver.name === "cloudflare-workers") {
3669
- config2.inspector.enabled = false;
3670
- config2.disableServer = true;
3671
- config2.disableActorDriver = true;
3672
- config2.noWelcome = true;
4023
+ if (!config2.namespace) {
4024
+ throw new Error("namespace is required for serverless configuration");
3673
4025
  }
3674
- let upgradeWebSocket;
3675
- if (!config2.getUpgradeWebSocket) {
3676
- config2.getUpgradeWebSocket = () => upgradeWebSocket;
4026
+ if (!config2.endpoint) {
4027
+ throw new Error("endpoint is required for serverless configuration");
3677
4028
  }
3678
- const managerDriver = driver.manager(this.#config, config2);
3679
- const client = createClientWithDriver(managerDriver, config2);
3680
- const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3681
- logger6().info({
3682
- msg: "rivetkit ready",
3683
- driver: driver.name,
3684
- definitions: Object.keys(this.#config.use).length,
3685
- ...driverLog
4029
+ const customConfig = typeof config2.autoConfigureServerless === "object" ? config2.autoConfigureServerless : {};
4030
+ const dcsUrl = `${config2.endpoint}/datacenters`;
4031
+ logger7().debug({
4032
+ msg: "fetching datacenters",
4033
+ url: dcsUrl
3686
4034
  });
3687
- if (((_d = config2.inspector) == null ? void 0 : _d.enabled) && managerDriver.inspector) {
3688
- logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3689
- }
3690
- if (!config2.noWelcome) {
3691
- const displayInfo = managerDriver.displayInformation();
3692
- console.log();
3693
- console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3694
- console.log(` - Endpoint: http://127.0.0.1:6420`);
3695
- for (const [k, v] of Object.entries(displayInfo.properties)) {
3696
- const padding = " ".repeat(Math.max(0, 13 - k.length));
3697
- console.log(` - ${k}:${padding}${v}`);
3698
- }
3699
- if (((_e = config2.inspector) == null ? void 0 : _e.enabled) && managerDriver.inspector) {
3700
- console.log(` - Inspector: ${getInspectorUrl(config2)}`);
4035
+ const dcsResponse = await fetch(dcsUrl, {
4036
+ headers: {
4037
+ ...config2.token ? { Authorization: `Bearer ${config2.token}` } : {}
3701
4038
  }
3702
- console.log();
4039
+ });
4040
+ if (!dcsResponse.ok) {
4041
+ const errorText = await dcsResponse.text();
4042
+ throw new Error(
4043
+ `failed to configure serverless runner: ${dcsResponse.status} ${dcsResponse.statusText} - ${errorText}`
4044
+ );
3703
4045
  }
3704
- let serverlessActorDriverBuilder = (token, totalSlots) => {
3705
- if (token) config2.token = token;
3706
- if (totalSlots) config2.totalSlots = totalSlots;
3707
- return driver.actor(this.#config, config2, managerDriver, client);
4046
+ const dcsRes = await dcsResponse.json();
4047
+ const serverlessConfig = {
4048
+ serverless: {
4049
+ url: customConfig.url || `http://localhost:${config2.defaultServerPort}/start`,
4050
+ headers: customConfig.headers || {},
4051
+ max_runners: customConfig.maxRunners ?? 100,
4052
+ min_runners: customConfig.minRunners ?? 0,
4053
+ request_lifespan: customConfig.requestLifespan ?? 15 * 60,
4054
+ runners_margin: customConfig.runnersMargin ?? 0,
4055
+ slots_per_runner: customConfig.slotsPerRunner ?? config2.totalSlots ?? 1e3
4056
+ }
3708
4057
  };
3709
- if (!config2.disableActorDriver) {
3710
- const _actorDriver = serverlessActorDriverBuilder();
3711
- serverlessActorDriverBuilder = void 0;
3712
- }
3713
- const { router: hono } = createManagerRouter(
3714
- this.#config,
3715
- config2,
3716
- managerDriver,
3717
- serverlessActorDriverBuilder
4058
+ const requestBody = Object.fromEntries(
4059
+ dcsRes.datacenters.map((dc) => [dc.name, serverlessConfig])
3718
4060
  );
3719
- if (!config2.disableServer) {
3720
- (async () => {
3721
- const out = await crossPlatformServe(hono, void 0);
3722
- upgradeWebSocket = out.upgradeWebSocket;
3723
- })();
4061
+ const configUrl = `${config2.endpoint}/runner-configs/${config2.runnerName}?namespace=${config2.namespace}`;
4062
+ logger7().debug({
4063
+ msg: "configuring serverless runner",
4064
+ url: configUrl,
4065
+ config: serverlessConfig.serverless
4066
+ });
4067
+ const response = await fetch(configUrl, {
4068
+ method: "PUT",
4069
+ headers: {
4070
+ "Content-Type": "application/json",
4071
+ ...config2.token ? { Authorization: `Bearer ${config2.token}` } : {}
4072
+ },
4073
+ body: JSON.stringify(requestBody)
4074
+ });
4075
+ if (!response.ok) {
4076
+ const errorText = await response.text();
4077
+ throw new Error(
4078
+ `failed to configure serverless runner: ${response.status} ${response.statusText} - ${errorText}`
4079
+ );
3724
4080
  }
3725
- return {
3726
- client,
3727
- fetch: hono.fetch.bind(hono)
3728
- };
4081
+ logger7().info({
4082
+ msg: "serverless runner configured successfully",
4083
+ runnerName: config2.runnerName,
4084
+ namespace: config2.namespace
4085
+ });
4086
+ } catch (error) {
4087
+ logger7().error({
4088
+ msg: "failed to configure serverless runner",
4089
+ error
4090
+ });
4091
+ throw error;
3729
4092
  }
3730
- };
4093
+ }
3731
4094
  function setup(input) {
3732
4095
  const config2 = RegistryConfigSchema.parse(input);
3733
4096
  return new Registry(config2);
@@ -3749,4 +4112,4 @@ export {
3749
4112
  setup
3750
4113
  };
3751
4114
  //! These configs configs hold anything that's not platform-specific about running actors.
3752
- //# sourceMappingURL=chunk-FZP2IBIX.js.map
4115
+ //# sourceMappingURL=chunk-NOXYAPM2.js.map