rivetkit 2.0.8 → 2.0.10

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 (125) hide show
  1. package/dist/tsup/{chunk-2FAWAPRT.js → chunk-346X2XU4.js} +2 -2
  2. package/dist/tsup/{chunk-SFRRXLRM.js → chunk-7E5K3375.js} +2 -2
  3. package/dist/tsup/{chunk-3WRAGTDC.cjs → chunk-CA3X5M6H.cjs} +92 -39
  4. package/dist/tsup/{chunk-PVKV2O2E.js.map → chunk-CA3X5M6H.cjs.map} +1 -1
  5. package/dist/tsup/{chunk-L5MHM6JJ.cjs → chunk-DVPXSB4B.cjs} +12 -12
  6. package/dist/tsup/{chunk-L5MHM6JJ.cjs.map → chunk-DVPXSB4B.cjs.map} +1 -1
  7. package/dist/tsup/{chunk-DQVVH5ZK.cjs → chunk-GIFHYL7A.cjs} +5 -6
  8. package/dist/tsup/chunk-GIFHYL7A.cjs.map +1 -0
  9. package/dist/tsup/{chunk-N7OVEOMU.js → chunk-H7E2UU23.js} +38 -15
  10. package/dist/tsup/chunk-H7E2UU23.js.map +1 -0
  11. package/dist/tsup/{chunk-A6TV3QU6.js → chunk-HI55LHM3.js} +5 -6
  12. package/dist/tsup/chunk-HI55LHM3.js.map +1 -0
  13. package/dist/tsup/{chunk-FGOZELKN.cjs → chunk-I3FB346I.cjs} +112 -58
  14. package/dist/tsup/chunk-I3FB346I.cjs.map +1 -0
  15. package/dist/tsup/{chunk-DOZBWJRI.js → chunk-KGDZYQYE.js} +2 -2
  16. package/dist/tsup/{chunk-KYEEAVJO.cjs → chunk-KH5WFDUK.cjs} +6 -6
  17. package/dist/tsup/{chunk-KYEEAVJO.cjs.map → chunk-KH5WFDUK.cjs.map} +1 -1
  18. package/dist/tsup/{chunk-WP7YG7S5.js → chunk-KL4V2ULR.js} +5 -4
  19. package/dist/tsup/chunk-KL4V2ULR.js.map +1 -0
  20. package/dist/tsup/{chunk-S6EAEZQA.js → chunk-MLQIYKAZ.js} +106 -52
  21. package/dist/tsup/chunk-MLQIYKAZ.js.map +1 -0
  22. package/dist/tsup/{chunk-3ZMJUIL3.js → chunk-N3A5GYJU.js} +3 -3
  23. package/dist/tsup/{chunk-CKSA7NOS.cjs → chunk-PDFL7FBL.cjs} +717 -380
  24. package/dist/tsup/chunk-PDFL7FBL.cjs.map +1 -0
  25. package/dist/tsup/{chunk-ESD2JX3L.cjs → chunk-PPLR53PP.cjs} +3 -3
  26. package/dist/tsup/{chunk-ESD2JX3L.cjs.map → chunk-PPLR53PP.cjs.map} +1 -1
  27. package/dist/tsup/{chunk-6INXQCH7.cjs → chunk-PSCDCEXM.cjs} +17 -12
  28. package/dist/tsup/chunk-PSCDCEXM.cjs.map +1 -0
  29. package/dist/tsup/{chunk-PVKV2O2E.js → chunk-QRFXXTLG.js} +96 -43
  30. package/dist/tsup/chunk-QRFXXTLG.js.map +1 -0
  31. package/dist/tsup/{chunk-RM2V2IRK.js → chunk-R2S45MO6.js} +14 -9
  32. package/dist/tsup/chunk-R2S45MO6.js.map +1 -0
  33. package/dist/tsup/{chunk-QGUQB3NC.cjs → chunk-SIWYIRXP.cjs} +7 -6
  34. package/dist/tsup/chunk-SIWYIRXP.cjs.map +1 -0
  35. package/dist/tsup/{chunk-E77RVI3P.js → chunk-VJRXZPTT.js} +601 -264
  36. package/dist/tsup/chunk-VJRXZPTT.js.map +1 -0
  37. package/dist/tsup/{chunk-KDNB2BQX.cjs → chunk-VZMXAZKC.cjs} +229 -206
  38. package/dist/tsup/chunk-VZMXAZKC.cjs.map +1 -0
  39. package/dist/tsup/{chunk-TPJNKVFB.cjs → chunk-YKVTF7MP.cjs} +7 -7
  40. package/dist/tsup/{chunk-TPJNKVFB.cjs.map → chunk-YKVTF7MP.cjs.map} +1 -1
  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-ChAuuTr0.d.cts → conn-Cc9WHuN4.d.cts} +196 -185
  50. package/dist/tsup/{conn-CjUkMEcm.d.ts → conn-DfPG71FA.d.ts} +196 -185
  51. package/dist/tsup/driver-helpers/mod.cjs +7 -5
  52. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  53. package/dist/tsup/driver-helpers/mod.d.cts +4 -2
  54. package/dist/tsup/driver-helpers/mod.d.ts +4 -2
  55. package/dist/tsup/driver-helpers/mod.js +9 -7
  56. package/dist/tsup/driver-test-suite/mod.cjs +116 -102
  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 +61 -47
  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/instance.ts +4 -4
  81. package/src/actor/protocol/serde.ts +75 -3
  82. package/src/actor/router-endpoints.ts +6 -6
  83. package/src/actor/router.ts +2 -2
  84. package/src/client/actor-conn.ts +24 -3
  85. package/src/client/config.ts +18 -25
  86. package/src/driver-helpers/mod.ts +5 -1
  87. package/src/driver-test-suite/mod.ts +65 -43
  88. package/src/driver-test-suite/utils.ts +4 -1
  89. package/src/drivers/default.ts +11 -9
  90. package/src/drivers/engine/actor-driver.ts +40 -39
  91. package/src/drivers/engine/config.ts +9 -22
  92. package/src/drivers/engine/mod.ts +9 -8
  93. package/src/drivers/file-system/global-state.ts +4 -4
  94. package/src/engine-process/log.ts +5 -0
  95. package/src/engine-process/mod.ts +316 -0
  96. package/src/inspector/utils.ts +6 -4
  97. package/src/manager/driver.ts +3 -3
  98. package/src/manager/gateway.ts +29 -11
  99. package/src/manager/router-schema.ts +20 -0
  100. package/src/manager/router.ts +139 -58
  101. package/src/registry/mod.ts +146 -120
  102. package/src/registry/run-config.ts +116 -47
  103. package/src/registry/serve.ts +3 -1
  104. package/src/remote-manager-driver/mod.ts +3 -2
  105. package/src/serde.ts +18 -3
  106. package/src/test/config.ts +2 -2
  107. package/src/test/mod.ts +6 -3
  108. package/src/utils.ts +2 -0
  109. package/dist/tsup/chunk-3WRAGTDC.cjs.map +0 -1
  110. package/dist/tsup/chunk-6INXQCH7.cjs.map +0 -1
  111. package/dist/tsup/chunk-A6TV3QU6.js.map +0 -1
  112. package/dist/tsup/chunk-CKSA7NOS.cjs.map +0 -1
  113. package/dist/tsup/chunk-DQVVH5ZK.cjs.map +0 -1
  114. package/dist/tsup/chunk-E77RVI3P.js.map +0 -1
  115. package/dist/tsup/chunk-FGOZELKN.cjs.map +0 -1
  116. package/dist/tsup/chunk-KDNB2BQX.cjs.map +0 -1
  117. package/dist/tsup/chunk-N7OVEOMU.js.map +0 -1
  118. package/dist/tsup/chunk-QGUQB3NC.cjs.map +0 -1
  119. package/dist/tsup/chunk-RM2V2IRK.js.map +0 -1
  120. package/dist/tsup/chunk-S6EAEZQA.js.map +0 -1
  121. package/dist/tsup/chunk-WP7YG7S5.js.map +0 -1
  122. /package/dist/tsup/{chunk-2FAWAPRT.js.map → chunk-346X2XU4.js.map} +0 -0
  123. /package/dist/tsup/{chunk-SFRRXLRM.js.map → chunk-7E5K3375.js.map} +0 -0
  124. /package/dist/tsup/{chunk-DOZBWJRI.js.map → chunk-KGDZYQYE.js.map} +0 -0
  125. /package/dist/tsup/{chunk-3ZMJUIL3.js.map → chunk-N3A5GYJU.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  inspectorLogger,
5
5
  isInspectorEnabled,
6
6
  secureInspector
7
- } from "./chunk-WP7YG7S5.js";
7
+ } from "./chunk-KL4V2ULR.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-N7OVEOMU.js";
18
+ } from "./chunk-H7E2UU23.js";
18
19
  import {
19
20
  CreateActorSchema
20
- } from "./chunk-DOZBWJRI.js";
21
+ } from "./chunk-KGDZYQYE.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-PVKV2O2E.js";
32
+ } from "./chunk-QRFXXTLG.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-S6EAEZQA.js";
58
+ } from "./chunk-MLQIYKAZ.js";
58
59
  import {
59
60
  configureBaseLogger,
60
61
  configureDefaultLogger,
61
62
  getLogger
62
- } from "./chunk-SFRRXLRM.js";
63
+ } from "./chunk-7E5K3375.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-A6TV3QU6.js";
74
+ } from "./chunk-HI55LHM3.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,
@@ -1720,33 +1720,14 @@ var EngineActorDriver = class {
1720
1720
  return streamSSE2(c, async (stream) => {
1721
1721
  const payload = this.#runner.getServerlessInitPacket();
1722
1722
  invariant3(payload, "runnerId not set");
1723
- stream.writeSSE({ data: payload });
1723
+ await stream.writeSSE({ data: payload });
1724
1724
  return this.#runnerStopped.promise;
1725
1725
  });
1726
1726
  }
1727
1727
  };
1728
1728
 
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
1729
  // src/drivers/engine/mod.ts
1748
- function createEngineDriver(inputConfig) {
1749
- const config2 = ConfigSchema.parse(inputConfig);
1730
+ function createEngineDriver() {
1750
1731
  return {
1751
1732
  name: "engine",
1752
1733
  manager: (_registryConfig, runConfig) => {
@@ -1757,8 +1738,7 @@ function createEngineDriver(inputConfig) {
1757
1738
  registryConfig,
1758
1739
  runConfig,
1759
1740
  managerDriver,
1760
- inlineClient,
1761
- config2
1741
+ inlineClient
1762
1742
  );
1763
1743
  }
1764
1744
  };
@@ -1949,9 +1929,9 @@ function getStoragePath(customPath) {
1949
1929
  const dirHash = createHashForPath(pathToHash);
1950
1930
  return path.join(dataPath, dirHash);
1951
1931
  }
1952
- async function pathExists(path3) {
1932
+ async function pathExists(path4) {
1953
1933
  try {
1954
- await fs.access(path3);
1934
+ await fs.access(path4);
1955
1935
  return true;
1956
1936
  } catch {
1957
1937
  return false;
@@ -2584,8 +2564,8 @@ var FileSystemManagerDriver = class {
2584
2564
  actorId
2585
2565
  });
2586
2566
  }
2587
- async openWebSocket(path3, actorId, encoding, params, connId, connToken) {
2588
- const pathOnly = path3.split("?")[0];
2567
+ async openWebSocket(path4, actorId, encoding, params, connId, connToken) {
2568
+ const pathOnly = path4.split("?")[0];
2589
2569
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2590
2570
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2591
2571
  const wsHandler = await handleWebSocketConnect(
@@ -2602,13 +2582,13 @@ var FileSystemManagerDriver = class {
2602
2582
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2603
2583
  const wsHandler = await handleRawWebSocketHandler(
2604
2584
  void 0,
2605
- path3,
2585
+ path4,
2606
2586
  this.#actorDriver,
2607
2587
  actorId
2608
2588
  );
2609
2589
  return new InlineWebSocketAdapter2(wsHandler);
2610
2590
  } else {
2611
- throw new Error(`Unreachable path: ${path3}`);
2591
+ throw new Error(`Unreachable path: ${path4}`);
2612
2592
  }
2613
2593
  }
2614
2594
  async proxyRequest(c, actorRequest, actorId) {
@@ -2616,11 +2596,11 @@ var FileSystemManagerDriver = class {
2616
2596
  actorId
2617
2597
  });
2618
2598
  }
2619
- async proxyWebSocket(c, path3, actorId, encoding, connParams, connId, connToken) {
2599
+ async proxyWebSocket(c, path4, actorId, encoding, connParams, connId, connToken) {
2620
2600
  var _a, _b;
2621
2601
  const upgradeWebSocket = (_b = (_a = this.#runConfig).getUpgradeWebSocket) == null ? void 0 : _b.call(_a);
2622
2602
  invariant5(upgradeWebSocket, "missing getUpgradeWebSocket");
2623
- const pathOnly = path3.split("?")[0];
2603
+ const pathOnly = path4.split("?")[0];
2624
2604
  const normalizedPath = pathOnly.startsWith("/") ? pathOnly : `/${pathOnly}`;
2625
2605
  if (normalizedPath === PATH_CONNECT_WEBSOCKET) {
2626
2606
  const wsHandler = await handleWebSocketConnect(
@@ -2637,13 +2617,13 @@ var FileSystemManagerDriver = class {
2637
2617
  } else if (normalizedPath.startsWith(PATH_RAW_WEBSOCKET_PREFIX) || normalizedPath === "/raw/websocket") {
2638
2618
  const wsHandler = await handleRawWebSocketHandler(
2639
2619
  c.req.raw,
2640
- path3,
2620
+ path4,
2641
2621
  this.#actorDriver,
2642
2622
  actorId
2643
2623
  );
2644
2624
  return upgradeWebSocket(() => wsHandler)(c, noopNext());
2645
2625
  } else {
2646
- throw new Error(`Unreachable path: ${path3}`);
2626
+ throw new Error(`Unreachable path: ${path4}`);
2647
2627
  }
2648
2628
  }
2649
2629
  async getForId({ actorId }) {
@@ -2753,30 +2733,284 @@ function createMemoryDriver() {
2753
2733
  return createFileSystemOrMemoryDriver(false);
2754
2734
  }
2755
2735
 
2736
+ // src/registry/mod.ts
2737
+ import invariant7 from "invariant";
2738
+
2756
2739
  // src/drivers/default.ts
2757
2740
  function chooseDefaultDriver(runConfig) {
2758
2741
  if (runConfig.endpoint && runConfig.driver) {
2759
2742
  throw new UserError(
2760
- "Cannot specify both 'engine' and 'driver' in configuration"
2743
+ "Cannot specify both 'endpoint' and 'driver' in configuration"
2744
+ );
2745
+ }
2746
+ if (runConfig.runnerKind === "serverless" && !runConfig.endpoint) {
2747
+ throw new UserError(
2748
+ "Cannot use 'serverless' runnerKind without the 'endpoint' config set."
2761
2749
  );
2762
2750
  }
2763
2751
  if (runConfig.driver) {
2764
2752
  return runConfig.driver;
2765
2753
  }
2766
- if (runConfig.endpoint) {
2754
+ if (runConfig.endpoint || runConfig.token) {
2767
2755
  loggerWithoutContext().debug({
2768
2756
  msg: "using rivet engine driver",
2769
2757
  endpoint: runConfig.endpoint
2770
2758
  });
2771
- return createEngineDriver({
2772
- endpoint: runConfig.endpoint,
2773
- token: runConfig.token
2774
- });
2759
+ return createEngineDriver();
2775
2760
  }
2776
2761
  loggerWithoutContext().debug({ msg: "using default file system driver" });
2777
2762
  return createFileSystemOrMemoryDriver(true);
2778
2763
  }
2779
2764
 
2765
+ // src/engine-process/mod.ts
2766
+ import { spawn } from "child_process";
2767
+ import { createWriteStream } from "fs";
2768
+ import * as fs3 from "fs/promises";
2769
+ import * as path3 from "path";
2770
+ import { pipeline } from "stream/promises";
2771
+
2772
+ // src/engine-process/log.ts
2773
+ function logger6() {
2774
+ return getLogger("engine-process");
2775
+ }
2776
+
2777
+ // src/engine-process/mod.ts
2778
+ var ENGINE_PORT = 6420;
2779
+ var ENGINE_ENDPOINT = `http://localhost:${ENGINE_PORT}`;
2780
+ var ENGINE_BASE_URL = "https://releases.rivet.gg/engine";
2781
+ var ENGINE_BINARY_NAME = "rivet-engine";
2782
+ async function ensureEngineProcess(options) {
2783
+ logger6().debug({ msg: "ensuring engine process", version: options.version });
2784
+ const storageRoot = getStoragePath();
2785
+ const binDir = path3.join(storageRoot, "bin");
2786
+ const varDir = path3.join(storageRoot, "var");
2787
+ const logsDir = path3.join(varDir, "logs", "rivet-engine");
2788
+ await ensureDirectoryExists(binDir);
2789
+ await ensureDirectoryExists(varDir);
2790
+ await ensureDirectoryExists(logsDir);
2791
+ const executableName = process.platform === "win32" ? `${ENGINE_BINARY_NAME}-${options.version}.exe` : `${ENGINE_BINARY_NAME}-${options.version}`;
2792
+ const binaryPath = path3.join(binDir, executableName);
2793
+ await downloadEngineBinaryIfNeeded(binaryPath, options.version, varDir);
2794
+ if (await isEngineRunning()) {
2795
+ try {
2796
+ await waitForEngineHealth();
2797
+ logger6().debug({
2798
+ msg: "engine already running and healthy",
2799
+ version: options.version
2800
+ });
2801
+ return;
2802
+ } catch (error) {
2803
+ logger6().warn({
2804
+ msg: "existing engine process not healthy, cannot restart automatically",
2805
+ error
2806
+ });
2807
+ throw new Error(
2808
+ "Engine process exists but is not healthy. Please manually stop the process on port 6420 and retry."
2809
+ );
2810
+ }
2811
+ }
2812
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").replace(/\./g, "-");
2813
+ const stdoutLogPath = path3.join(logsDir, `engine-${timestamp}-stdout.log`);
2814
+ const stderrLogPath = path3.join(logsDir, `engine-${timestamp}-stderr.log`);
2815
+ const stdoutStream = createWriteStream(stdoutLogPath, { flags: "a" });
2816
+ const stderrStream = createWriteStream(stderrLogPath, { flags: "a" });
2817
+ logger6().debug({
2818
+ msg: "creating engine log files",
2819
+ stdout: stdoutLogPath,
2820
+ stderr: stderrLogPath
2821
+ });
2822
+ const child = spawn(binaryPath, ["start"], {
2823
+ cwd: path3.dirname(binaryPath),
2824
+ stdio: ["inherit", "pipe", "pipe"],
2825
+ env: {
2826
+ ...process.env
2827
+ }
2828
+ });
2829
+ if (!child.pid) {
2830
+ throw new Error("failed to spawn rivet engine process");
2831
+ }
2832
+ if (child.stdout) {
2833
+ child.stdout.pipe(stdoutStream);
2834
+ }
2835
+ if (child.stderr) {
2836
+ child.stderr.pipe(stderrStream);
2837
+ }
2838
+ logger6().debug({
2839
+ msg: "spawned engine process",
2840
+ pid: child.pid,
2841
+ cwd: path3.dirname(binaryPath)
2842
+ });
2843
+ child.once("exit", (code, signal) => {
2844
+ logger6().warn({
2845
+ msg: "engine process exited",
2846
+ code,
2847
+ signal
2848
+ });
2849
+ stdoutStream.end();
2850
+ stderrStream.end();
2851
+ });
2852
+ child.once("error", (error) => {
2853
+ logger6().error({
2854
+ msg: "engine process failed",
2855
+ error
2856
+ });
2857
+ stdoutStream.end();
2858
+ stderrStream.end();
2859
+ });
2860
+ await waitForEngineHealth();
2861
+ logger6().info({
2862
+ msg: "engine process started",
2863
+ pid: child.pid,
2864
+ version: options.version,
2865
+ logs: {
2866
+ stdout: stdoutLogPath,
2867
+ stderr: stderrLogPath
2868
+ }
2869
+ });
2870
+ }
2871
+ async function downloadEngineBinaryIfNeeded(binaryPath, version, varDir) {
2872
+ const binaryExists = await fileExists(binaryPath);
2873
+ if (binaryExists) {
2874
+ logger6().debug({
2875
+ msg: "engine binary already cached",
2876
+ version,
2877
+ path: binaryPath
2878
+ });
2879
+ return;
2880
+ }
2881
+ const { targetTriplet, extension } = resolveTargetTriplet();
2882
+ const remoteFile = `${ENGINE_BINARY_NAME}-${targetTriplet}${extension}`;
2883
+ const downloadUrl = `${ENGINE_BASE_URL}/${version}/${remoteFile}`;
2884
+ logger6().info({
2885
+ msg: "downloading engine binary",
2886
+ url: downloadUrl,
2887
+ path: binaryPath,
2888
+ version
2889
+ });
2890
+ const response = await fetch(downloadUrl);
2891
+ if (!response.ok || !response.body) {
2892
+ throw new Error(
2893
+ `failed to download rivet engine binary from ${downloadUrl}: ${response.status} ${response.statusText}`
2894
+ );
2895
+ }
2896
+ const tempPath = `${binaryPath}.${process.pid}.tmp`;
2897
+ await pipeline(response.body, createWriteStream(tempPath));
2898
+ if (process.platform !== "win32") {
2899
+ await fs3.chmod(tempPath, 493);
2900
+ }
2901
+ await fs3.rename(tempPath, binaryPath);
2902
+ logger6().debug({
2903
+ msg: "engine binary download complete",
2904
+ version,
2905
+ path: binaryPath
2906
+ });
2907
+ logger6().info({
2908
+ msg: "engine binary downloaded",
2909
+ version,
2910
+ path: binaryPath
2911
+ });
2912
+ }
2913
+ function resolveTargetTriplet() {
2914
+ return resolveTargetTripletFor(process.platform, process.arch);
2915
+ }
2916
+ function resolveTargetTripletFor(platform, arch) {
2917
+ switch (platform) {
2918
+ case "darwin":
2919
+ if (arch === "arm64") {
2920
+ return { targetTriplet: "aarch64-apple-darwin", extension: "" };
2921
+ }
2922
+ if (arch === "x64") {
2923
+ return { targetTriplet: "x86_64-apple-darwin", extension: "" };
2924
+ }
2925
+ break;
2926
+ case "linux":
2927
+ if (arch === "x64") {
2928
+ return { targetTriplet: "x86_64-unknown-linux-musl", extension: "" };
2929
+ }
2930
+ break;
2931
+ case "win32":
2932
+ if (arch === "x64") {
2933
+ return { targetTriplet: "x86_64-pc-windows-gnu", extension: ".exe" };
2934
+ }
2935
+ break;
2936
+ }
2937
+ throw new Error(
2938
+ `unsupported platform for rivet engine binary: ${platform}/${arch}`
2939
+ );
2940
+ }
2941
+ async function isEngineRunning() {
2942
+ return await checkIfEngineAlreadyRunningOnPort(ENGINE_PORT);
2943
+ }
2944
+ async function checkIfEngineAlreadyRunningOnPort(port) {
2945
+ let response;
2946
+ try {
2947
+ response = await fetch(`http://localhost:${port}/health`);
2948
+ } catch (err) {
2949
+ return false;
2950
+ }
2951
+ if (response.ok) {
2952
+ const health = await response.json();
2953
+ if (health.runtime === "engine") {
2954
+ logger6().debug({
2955
+ msg: "rivet engine already running on port",
2956
+ port
2957
+ });
2958
+ return true;
2959
+ } else if (health.runtime === "rivetkit") {
2960
+ logger6().error({
2961
+ msg: "another rivetkit process is already running on port",
2962
+ port
2963
+ });
2964
+ throw new Error(
2965
+ "RivetKit process already running on port 6420, stop that process and restart this."
2966
+ );
2967
+ } else {
2968
+ throw new Error(
2969
+ "Unknown process running on port 6420, cannot identify what it is."
2970
+ );
2971
+ }
2972
+ }
2973
+ return false;
2974
+ }
2975
+ async function fileExists(filePath) {
2976
+ try {
2977
+ await fs3.access(filePath);
2978
+ return true;
2979
+ } catch {
2980
+ return false;
2981
+ }
2982
+ }
2983
+ var HEALTH_MAX_WAIT = 1e4;
2984
+ var HEALTH_INTERVAL = 100;
2985
+ async function waitForEngineHealth() {
2986
+ const maxRetries = Math.ceil(HEALTH_MAX_WAIT / HEALTH_INTERVAL);
2987
+ logger6().debug({ msg: "waiting for engine health check" });
2988
+ for (let i = 0; i < maxRetries; i++) {
2989
+ try {
2990
+ const response = await fetch(`${ENGINE_ENDPOINT}/health`);
2991
+ if (response.ok) {
2992
+ logger6().debug({ msg: "engine health check passed" });
2993
+ return;
2994
+ }
2995
+ } catch (error) {
2996
+ if (i === maxRetries - 1) {
2997
+ throw new Error(
2998
+ `engine health check failed after ${maxRetries} retries: ${error}`
2999
+ );
3000
+ }
3001
+ }
3002
+ if (i < maxRetries - 1) {
3003
+ logger6().trace({
3004
+ msg: "engine not ready, retrying",
3005
+ attempt: i + 1,
3006
+ maxRetries
3007
+ });
3008
+ await new Promise((resolve) => setTimeout(resolve, HEALTH_INTERVAL));
3009
+ }
3010
+ }
3011
+ throw new Error(`engine health check failed after ${maxRetries} retries`);
3012
+ }
3013
+
2780
3014
  // src/manager/router.ts
2781
3015
  import { createRoute, OpenAPIHono } from "@hono/zod-openapi";
2782
3016
  import * as cbor4 from "cbor-x";
@@ -2789,62 +3023,74 @@ import invariant6 from "invariant";
2789
3023
  import { z as z5 } from "zod";
2790
3024
 
2791
3025
  // src/manager-api/actors.ts
2792
- import { z as z4 } from "zod";
3026
+ import { z as z3 } from "zod";
2793
3027
 
2794
3028
  // src/manager-api/common.ts
2795
- import { z as z3 } from "zod";
2796
- var RivetIdSchema = z3.string();
3029
+ import { z as z2 } from "zod";
3030
+ var RivetIdSchema = z2.string();
2797
3031
 
2798
3032
  // src/manager-api/actors.ts
2799
- var ActorSchema = z4.object({
3033
+ var ActorSchema = z3.object({
2800
3034
  actor_id: RivetIdSchema,
2801
- name: z4.string(),
2802
- key: z4.string(),
3035
+ name: z3.string(),
3036
+ key: z3.string(),
2803
3037
  namespace_id: RivetIdSchema,
2804
- runner_name_selector: z4.string(),
2805
- create_ts: z4.number(),
2806
- connectable_ts: z4.number().nullable().optional(),
2807
- destroy_ts: z4.number().nullable().optional(),
2808
- sleep_ts: z4.number().nullable().optional(),
2809
- start_ts: z4.number().nullable().optional()
3038
+ runner_name_selector: z3.string(),
3039
+ create_ts: z3.number(),
3040
+ connectable_ts: z3.number().nullable().optional(),
3041
+ destroy_ts: z3.number().nullable().optional(),
3042
+ sleep_ts: z3.number().nullable().optional(),
3043
+ start_ts: z3.number().nullable().optional()
2810
3044
  });
2811
- var ActorsListResponseSchema = z4.object({
2812
- actors: z4.array(ActorSchema)
3045
+ var ActorsListResponseSchema = z3.object({
3046
+ actors: z3.array(ActorSchema)
2813
3047
  });
2814
- var ActorsCreateRequestSchema = z4.object({
2815
- name: z4.string(),
2816
- runner_name_selector: z4.string(),
2817
- crash_policy: z4.string(),
2818
- key: z4.string().nullable().optional(),
2819
- input: z4.string().nullable().optional()
3048
+ var ActorsCreateRequestSchema = z3.object({
3049
+ name: z3.string(),
3050
+ runner_name_selector: z3.string(),
3051
+ crash_policy: z3.string(),
3052
+ key: z3.string().nullable().optional(),
3053
+ input: z3.string().nullable().optional()
2820
3054
  });
2821
- var ActorsCreateResponseSchema = z4.object({
3055
+ var ActorsCreateResponseSchema = z3.object({
2822
3056
  actor: ActorSchema
2823
3057
  });
2824
- var ActorsGetOrCreateRequestSchema = z4.object({
2825
- name: z4.string(),
2826
- key: z4.string(),
2827
- runner_name_selector: z4.string(),
2828
- crash_policy: z4.string(),
2829
- input: z4.string().nullable().optional()
3058
+ var ActorsGetOrCreateRequestSchema = z3.object({
3059
+ name: z3.string(),
3060
+ key: z3.string(),
3061
+ runner_name_selector: z3.string(),
3062
+ crash_policy: z3.string(),
3063
+ input: z3.string().nullable().optional()
2830
3064
  });
2831
- var ActorsGetOrCreateResponseSchema = z4.object({
3065
+ var ActorsGetOrCreateResponseSchema = z3.object({
2832
3066
  actor: ActorSchema,
2833
- created: z4.boolean()
3067
+ created: z3.boolean()
2834
3068
  });
2835
- var ActorsDeleteResponseSchema = z4.object({});
3069
+ var ActorsDeleteResponseSchema = z3.object({});
2836
3070
 
2837
3071
  // src/manager/gateway.ts
2838
3072
  async function actorGateway(runConfig, managerDriver, c, next) {
2839
3073
  if (c.req.path.startsWith("/.test/")) {
2840
3074
  return next();
2841
3075
  }
3076
+ let strippedPath = c.req.path;
3077
+ if (runConfig.basePath && strippedPath.startsWith(runConfig.basePath)) {
3078
+ strippedPath = strippedPath.slice(runConfig.basePath.length);
3079
+ if (!strippedPath.startsWith("/")) {
3080
+ strippedPath = "/" + strippedPath;
3081
+ }
3082
+ }
2842
3083
  if (c.req.header("upgrade") === "websocket") {
2843
- return await handleWebSocketGateway(runConfig, managerDriver, c);
3084
+ return await handleWebSocketGateway(
3085
+ runConfig,
3086
+ managerDriver,
3087
+ c,
3088
+ strippedPath
3089
+ );
2844
3090
  }
2845
- return await handleHttpGateway(managerDriver, c, next);
3091
+ return await handleHttpGateway(managerDriver, c, next, strippedPath);
2846
3092
  }
2847
- async function handleWebSocketGateway(runConfig, managerDriver, c) {
3093
+ async function handleWebSocketGateway(runConfig, managerDriver, c, strippedPath) {
2848
3094
  var _a;
2849
3095
  const upgradeWebSocket = (_a = runConfig.getUpgradeWebSocket) == null ? void 0 : _a.call(runConfig);
2850
3096
  if (!upgradeWebSocket) {
@@ -2886,12 +3132,12 @@ async function handleWebSocketGateway(runConfig, managerDriver, c) {
2886
3132
  logger().debug({
2887
3133
  msg: "proxying websocket to actor",
2888
3134
  actorId,
2889
- path: c.req.path,
3135
+ path: strippedPath,
2890
3136
  encoding: encodingRaw
2891
3137
  });
2892
3138
  const encoding = encodingRaw || "json";
2893
3139
  const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : void 0;
2894
- const pathWithQuery = c.req.url.includes("?") ? c.req.path + c.req.url.substring(c.req.url.indexOf("?")) : c.req.path;
3140
+ const pathWithQuery = c.req.url.includes("?") ? strippedPath + c.req.url.substring(c.req.url.indexOf("?")) : strippedPath;
2895
3141
  return await managerDriver.proxyWebSocket(
2896
3142
  c,
2897
3143
  pathWithQuery,
@@ -2903,7 +3149,7 @@ async function handleWebSocketGateway(runConfig, managerDriver, c) {
2903
3149
  connTokenRaw
2904
3150
  );
2905
3151
  }
2906
- async function handleHttpGateway(managerDriver, c, next) {
3152
+ async function handleHttpGateway(managerDriver, c, next, strippedPath) {
2907
3153
  const target = c.req.header(HEADER_RIVET_TARGET);
2908
3154
  const actorId = c.req.header(HEADER_RIVET_ACTOR);
2909
3155
  if (target !== "actor") {
@@ -2915,19 +3161,20 @@ async function handleHttpGateway(managerDriver, c, next) {
2915
3161
  logger().debug({
2916
3162
  msg: "proxying request to actor",
2917
3163
  actorId,
2918
- path: c.req.path,
3164
+ path: strippedPath,
2919
3165
  method: c.req.method
2920
3166
  });
2921
3167
  const proxyHeaders = new Headers(c.req.raw.headers);
2922
3168
  proxyHeaders.delete(HEADER_RIVET_TARGET);
2923
3169
  proxyHeaders.delete(HEADER_RIVET_ACTOR);
2924
3170
  const url = new URL(c.req.url);
2925
- const proxyUrl = new URL(`http://actor${url.pathname}${url.search}`);
3171
+ const proxyUrl = new URL(`http://actor${strippedPath}${url.search}`);
2926
3172
  const proxyRequest = new Request(proxyUrl, {
2927
3173
  method: c.req.raw.method,
2928
3174
  headers: proxyHeaders,
2929
3175
  body: c.req.raw.body,
2930
- signal: c.req.raw.signal
3176
+ signal: c.req.raw.signal,
3177
+ duplex: "half"
2931
3178
  });
2932
3179
  return await managerDriver.proxyRequest(c, proxyRequest, actorId);
2933
3180
  }
@@ -3103,6 +3350,22 @@ async function createTestWebSocketProxy(clientWsPromise) {
3103
3350
  };
3104
3351
  }
3105
3352
 
3353
+ // src/manager/router-schema.ts
3354
+ import { z as z4 } from "zod";
3355
+ var ServerlessStartHeadersSchema = z4.object({
3356
+ endpoint: z4.string({ required_error: "x-rivet-endpoint header is required" }),
3357
+ token: z4.string({ invalid_type_error: "x-rivet-token header must be a string" }).optional(),
3358
+ totalSlots: z4.coerce.number({
3359
+ invalid_type_error: "x-rivet-total-slots header must be a number"
3360
+ }).int("x-rivet-total-slots header must be an integer").gte(1, "x-rivet-total-slots header must be positive"),
3361
+ runnerName: z4.string({
3362
+ required_error: "x-rivet-runner-name header is required"
3363
+ }),
3364
+ namespace: z4.string({
3365
+ required_error: "x-rivet-namespace-id header is required"
3366
+ })
3367
+ });
3368
+
3106
3369
  // src/manager/router.ts
3107
3370
  function buildOpenApiResponses(schema) {
3108
3371
  return {
@@ -3122,55 +3385,119 @@ function buildOpenApiResponses(schema) {
3122
3385
  }
3123
3386
  };
3124
3387
  }
3125
- function createManagerRouter(registryConfig, runConfig, managerDriver, serverlessActorDriverBuilder) {
3388
+ function createManagerRouter(registryConfig, runConfig, managerDriver, driverConfig, client) {
3126
3389
  const router = new OpenAPIHono({ strict: false }).basePath(
3127
3390
  runConfig.basePath
3128
3391
  );
3129
3392
  router.use("*", loggerMiddleware(logger()));
3130
- const cors2 = runConfig.cors ? corsMiddleware(runConfig.cors) : createMiddleware((_c, next) => next());
3131
- if (serverlessActorDriverBuilder) {
3132
- addServerlessRoutes(serverlessActorDriverBuilder, router, cors2);
3393
+ router.use(
3394
+ "*",
3395
+ createMiddleware(async (c, next) => {
3396
+ const upgrade = c.req.header("upgrade");
3397
+ const isWebSocket = (upgrade == null ? void 0 : upgrade.toLowerCase()) === "websocket";
3398
+ const isGet = c.req.method === "GET";
3399
+ if (isGet && isWebSocket) {
3400
+ c.header("Sec-WebSocket-Protocol", "rivet");
3401
+ }
3402
+ await next();
3403
+ })
3404
+ );
3405
+ if (runConfig.runnerKind === "serverless") {
3406
+ addServerlessRoutes(
3407
+ driverConfig,
3408
+ registryConfig,
3409
+ runConfig,
3410
+ managerDriver,
3411
+ client,
3412
+ router
3413
+ );
3414
+ } else if (runConfig.runnerKind === "normal") {
3415
+ addManagerRoutes(registryConfig, runConfig, managerDriver, router);
3133
3416
  } else {
3134
- addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2);
3417
+ assertUnreachable(runConfig.runnerKind);
3135
3418
  }
3136
3419
  router.notFound(handleRouteNotFound);
3137
3420
  router.onError(handleRouteError);
3138
- return { router, openapi: router, cors: cors2 };
3421
+ return { router, openapi: router };
3139
3422
  }
3140
- function addServerlessRoutes(serverlessActorDriverBuilder, router, cors2) {
3141
- router.get("/", cors2, (c) => {
3423
+ function addServerlessRoutes(driverConfig, registryConfig, runConfig, managerDriver, client, router) {
3424
+ if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
3425
+ router.get("/", (c) => {
3142
3426
  return c.text(
3143
3427
  "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3144
3428
  );
3145
3429
  });
3146
- router.get("/start", cors2, async (c) => {
3147
- const token = c.req.header("x-rivet-token");
3148
- let totalSlots = parseInt(
3149
- c.req.header("x-rivetkit-total-slots")
3430
+ router.get("/start", async (c) => {
3431
+ var _a;
3432
+ const parseResult = ServerlessStartHeadersSchema.safeParse({
3433
+ endpoint: c.req.header("x-rivet-endpoint"),
3434
+ token: c.req.header("x-rivet-token") ?? void 0,
3435
+ totalSlots: c.req.header("x-rivet-total-slots"),
3436
+ runnerName: c.req.header("x-rivet-runner-name"),
3437
+ namespace: c.req.header("x-rivet-namespace-id")
3438
+ });
3439
+ if (!parseResult.success) {
3440
+ throw new InvalidRequest(
3441
+ ((_a = parseResult.error.issues[0]) == null ? void 0 : _a.message) ?? "invalid serverless start headers"
3442
+ );
3443
+ }
3444
+ const { endpoint, token, totalSlots, runnerName, namespace } = parseResult.data;
3445
+ logger().debug({
3446
+ msg: "received serverless runner start request",
3447
+ endpoint,
3448
+ totalSlots,
3449
+ runnerName,
3450
+ namespace
3451
+ });
3452
+ const newRunConfig = Object.assign({}, runConfig);
3453
+ newRunConfig.endpoint = endpoint;
3454
+ newRunConfig.token = token;
3455
+ newRunConfig.totalSlots = totalSlots;
3456
+ newRunConfig.runnerName = runnerName;
3457
+ newRunConfig.namespace = namespace;
3458
+ const actorDriver = driverConfig.actor(
3459
+ registryConfig,
3460
+ newRunConfig,
3461
+ managerDriver,
3462
+ client
3150
3463
  );
3151
- if (isNaN(totalSlots)) totalSlots = void 0;
3152
- const actorDriver = serverlessActorDriverBuilder(token, totalSlots);
3153
3464
  invariant6(
3154
3465
  actorDriver.serverlessHandleStart,
3155
3466
  "missing serverlessHandleStart on ActorDriver"
3156
3467
  );
3157
3468
  return await actorDriver.serverlessHandleStart(c);
3158
3469
  });
3159
- router.get("/health", cors2, (c) => {
3160
- return c.text("ok");
3470
+ router.get("/health", (c) => {
3471
+ return c.json({
3472
+ status: "ok",
3473
+ runtime: "rivetkit",
3474
+ version: VERSION
3475
+ });
3161
3476
  });
3162
3477
  }
3163
- function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors2) {
3478
+ function addManagerRoutes(registryConfig, runConfig, managerDriver, router) {
3164
3479
  var _a;
3165
- router.use("*", cors2, actorGateway.bind(void 0, runConfig, managerDriver));
3166
- router.get("/", cors2, (c) => {
3480
+ if (isInspectorEnabled(runConfig, "manager")) {
3481
+ if (!managerDriver.inspector) {
3482
+ throw new Unsupported("inspector");
3483
+ }
3484
+ router.route(
3485
+ "/inspect",
3486
+ new Hono3().use(corsMiddleware(runConfig.inspector.cors)).use(secureInspector(runConfig)).use((c, next) => {
3487
+ c.set("inspector", managerDriver.inspector);
3488
+ return next();
3489
+ }).route("/", createManagerInspectorRouter())
3490
+ );
3491
+ }
3492
+ if (runConfig.cors) router.use("*", corsMiddleware(runConfig.cors));
3493
+ router.use("*", actorGateway.bind(void 0, runConfig, managerDriver));
3494
+ router.get("/", (c) => {
3167
3495
  return c.text(
3168
3496
  "This is a RivetKit server.\n\nLearn more at https://rivetkit.org"
3169
3497
  );
3170
3498
  });
3171
3499
  {
3172
3500
  const route = createRoute({
3173
- middleware: [cors2],
3174
3501
  method: "get",
3175
3502
  path: "/actors",
3176
3503
  request: {
@@ -3230,7 +3557,6 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3230
3557
  }
3231
3558
  {
3232
3559
  const route = createRoute({
3233
- middleware: [cors2],
3234
3560
  method: "put",
3235
3561
  path: "/actors",
3236
3562
  request: {
@@ -3275,7 +3601,6 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3275
3601
  }
3276
3602
  {
3277
3603
  const route = createRoute({
3278
- middleware: [cors2],
3279
3604
  method: "post",
3280
3605
  path: "/actors",
3281
3606
  request: {
@@ -3335,7 +3660,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3335
3660
  let actorId = "";
3336
3661
  let encoding = "bare";
3337
3662
  let transport = "websocket";
3338
- let path3 = "";
3663
+ let path4 = "";
3339
3664
  let params;
3340
3665
  let connId;
3341
3666
  let connToken;
@@ -3351,7 +3676,7 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3351
3676
  WS_PROTOCOL_TRANSPORT.length
3352
3677
  );
3353
3678
  } else if (protocol.startsWith(WS_PROTOCOL_PATH)) {
3354
- path3 = decodeURIComponent(
3679
+ path4 = decodeURIComponent(
3355
3680
  protocol.substring(WS_PROTOCOL_PATH.length)
3356
3681
  );
3357
3682
  } else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {
@@ -3371,10 +3696,10 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3371
3696
  params,
3372
3697
  encodingKind: encoding,
3373
3698
  transport,
3374
- path: path3
3699
+ path: path4
3375
3700
  });
3376
3701
  const clientWsPromise = managerDriver.openWebSocket(
3377
- path3,
3702
+ path4,
3378
3703
  actorId,
3379
3704
  encoding,
3380
3705
  params,
@@ -3462,26 +3787,19 @@ function addManagerRoutes(registryConfig, runConfig, managerDriver, router, cors
3462
3787
  }
3463
3788
  });
3464
3789
  }
3465
- router.get("/health", cors2, (c) => {
3466
- return c.text("ok");
3790
+ router.get("/health", (c) => {
3791
+ return c.json({
3792
+ status: "ok",
3793
+ rivetkit: {
3794
+ version: VERSION
3795
+ }
3796
+ });
3467
3797
  });
3468
3798
  (_a = managerDriver.modifyManagerRouter) == null ? void 0 : _a.call(
3469
3799
  managerDriver,
3470
3800
  registryConfig,
3471
3801
  router
3472
3802
  );
3473
- if (isInspectorEnabled(runConfig, "manager")) {
3474
- if (!managerDriver.inspector) {
3475
- throw new Unsupported("inspector");
3476
- }
3477
- router.route(
3478
- "/inspect",
3479
- new Hono3().use(corsMiddleware(runConfig.inspector.cors)).use(secureInspector(runConfig)).use((c, next) => {
3480
- c.set("inspector", managerDriver.inspector);
3481
- return next();
3482
- }).route("/", createManagerInspectorRouter())
3483
- );
3484
- }
3485
3803
  }
3486
3804
  function createApiActor(actor2) {
3487
3805
  return {
@@ -3520,13 +3838,13 @@ var RegistryConfigSchema = z6.object({
3520
3838
  });
3521
3839
 
3522
3840
  // src/registry/log.ts
3523
- function logger6() {
3841
+ function logger7() {
3524
3842
  return getLogger("registry");
3525
3843
  }
3526
3844
 
3527
3845
  // src/registry/serve.ts
3528
3846
  import { Hono as Hono4 } from "hono";
3529
- async function crossPlatformServe(rivetKitRouter, userRouter) {
3847
+ async function crossPlatformServe(runConfig, rivetKitRouter, userRouter) {
3530
3848
  const app = userRouter ?? new Hono4();
3531
3849
  let serve;
3532
3850
  try {
@@ -3536,7 +3854,7 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3536
3854
  );
3537
3855
  serve = dep.serve;
3538
3856
  } catch (err) {
3539
- logger6().error(
3857
+ logger7().error(
3540
3858
  "failed to import @hono/node-server. please run 'npm install @hono/node-server @hono/node-ws'"
3541
3859
  );
3542
3860
  process.exit(1);
@@ -3550,7 +3868,7 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3550
3868
  );
3551
3869
  createNodeWebSocket = dep.createNodeWebSocket;
3552
3870
  } catch (err) {
3553
- logger6().error(
3871
+ logger7().error(
3554
3872
  "failed to import @hono/node-ws. please run 'npm install @hono/node-server @hono/node-ws'"
3555
3873
  );
3556
3874
  process.exit(1);
@@ -3558,10 +3876,10 @@ async function crossPlatformServe(rivetKitRouter, userRouter) {
3558
3876
  const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({
3559
3877
  app
3560
3878
  });
3561
- const port = 6420;
3879
+ const port = runConfig.defaultServerPort;
3562
3880
  const server = serve(
3563
3881
  { fetch: app.fetch, port },
3564
- () => logger6().info({ msg: "server listening", port })
3882
+ () => logger7().info({ msg: "server listening", port })
3565
3883
  );
3566
3884
  injectWebSocket(server);
3567
3885
  return { upgradeWebSocket };
@@ -3581,7 +3899,33 @@ var Registry = class {
3581
3899
  */
3582
3900
  start(inputConfig) {
3583
3901
  var _a, _b, _c;
3584
- const config2 = RunConfigSchema.parse(inputConfig);
3902
+ const config2 = RunnerConfigSchema.parse(inputConfig);
3903
+ if (config2.autoConfigureServerless && config2.runnerKind !== "serverless") {
3904
+ throw new Error(
3905
+ "autoConfigureServerless can only be configured when runnerKind is 'serverless'"
3906
+ );
3907
+ }
3908
+ const readyPromises = [];
3909
+ if (config2.runEngine) {
3910
+ logger7().debug({
3911
+ msg: "run engine requested",
3912
+ version: config2.runEngineVersion
3913
+ });
3914
+ invariant7(
3915
+ config2.endpoint === void 0,
3916
+ "cannot specify 'endpoint' with 'runEngine'"
3917
+ );
3918
+ config2.endpoint = ENGINE_ENDPOINT;
3919
+ config2.disableActorDriver = true;
3920
+ const engineProcessPromise = ensureEngineProcess({
3921
+ version: config2.runEngineVersion
3922
+ });
3923
+ readyPromises.push(engineProcessPromise);
3924
+ }
3925
+ if (config2.runnerKind === "serverless") {
3926
+ config2.defaultServerPort = 8080;
3927
+ config2.overrideServerAddress = config2.endpoint;
3928
+ }
3585
3929
  if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3586
3930
  configureBaseLogger(config2.logging.baseLogger);
3587
3931
  } else {
@@ -3590,11 +3934,13 @@ var Registry = class {
3590
3934
  const driver = chooseDefaultDriver(config2);
3591
3935
  if (driver.name === "engine") {
3592
3936
  config2.inspector.enabled = { manager: false, actor: true };
3593
- config2.disableServer = true;
3937
+ if (config2.runnerKind !== "serverless") {
3938
+ config2.disableDefaultServer = true;
3939
+ }
3594
3940
  }
3595
3941
  if (driver.name === "cloudflare-workers") {
3596
3942
  config2.inspector.enabled = { manager: false, actor: true };
3597
- config2.disableServer = true;
3943
+ config2.disableDefaultServer = true;
3598
3944
  config2.disableActorDriver = true;
3599
3945
  config2.noWelcome = true;
3600
3946
  }
@@ -3606,46 +3952,57 @@ var Registry = class {
3606
3952
  configureInspectorAccessToken(config2, managerDriver);
3607
3953
  const client = createClientWithDriver(managerDriver, config2);
3608
3954
  const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3609
- logger6().info({
3955
+ logger7().info({
3610
3956
  msg: "rivetkit ready",
3611
3957
  driver: driver.name,
3612
3958
  definitions: Object.keys(this.#config.use).length,
3613
3959
  ...driverLog
3614
3960
  });
3615
3961
  if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
3616
- logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3962
+ logger7().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3617
3963
  }
3618
3964
  if (!config2.noWelcome) {
3619
3965
  const displayInfo = managerDriver.displayInformation();
3620
3966
  console.log();
3621
3967
  console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3622
- console.log(` - Endpoint: http://127.0.0.1:6420`);
3968
+ if (!config2.disableDefaultServer) {
3969
+ console.log(` - Endpoint: ${config2.endpoint}`);
3970
+ } else if (config2.overrideServerAddress) {
3971
+ console.log(` - Endpoint: ${config2.overrideServerAddress}`);
3972
+ }
3973
+ if (config2.runEngine) {
3974
+ const padding = " ".repeat(Math.max(0, 13 - "Engine".length));
3975
+ console.log(` - Engine:${padding}v${config2.runEngineVersion}`);
3976
+ }
3623
3977
  for (const [k, v] of Object.entries(displayInfo.properties)) {
3624
3978
  const padding = " ".repeat(Math.max(0, 13 - k.length));
3625
3979
  console.log(` - ${k}:${padding}${v}`);
3626
3980
  }
3627
3981
  if (isInspectorEnabled(config2, "manager") && managerDriver.inspector) {
3628
- console.log(` - Inspector: ${getInspectorUrl(config2)}`);
3982
+ console.log(` - Inspector: ${getInspectorUrl(config2)}`);
3629
3983
  }
3630
3984
  console.log();
3631
3985
  }
3632
3986
  if (!config2.disableActorDriver) {
3633
- const _actorDriver = driver.actor(
3634
- this.#config,
3635
- config2,
3636
- managerDriver,
3637
- client
3638
- );
3987
+ Promise.all(readyPromises).then(async () => {
3988
+ driver.actor(this.#config, config2, managerDriver, client);
3989
+ });
3990
+ }
3991
+ if (config2.runnerKind === "serverless" && config2.autoConfigureServerless) {
3992
+ Promise.all(readyPromises).then(async () => {
3993
+ await configureServerlessRunner(config2);
3994
+ });
3639
3995
  }
3640
3996
  const { router: hono } = createManagerRouter(
3641
3997
  this.#config,
3642
3998
  config2,
3643
3999
  managerDriver,
3644
- void 0
4000
+ driver,
4001
+ client
3645
4002
  );
3646
- if (!config2.disableServer) {
4003
+ if (!config2.disableDefaultServer) {
3647
4004
  (async () => {
3648
- const out = await crossPlatformServe(hono, void 0);
4005
+ const out = await crossPlatformServe(config2, hono, void 0);
3649
4006
  upgradeWebSocket = out.upgradeWebSocket;
3650
4007
  })();
3651
4008
  }
@@ -3654,83 +4011,63 @@ var Registry = class {
3654
4011
  fetch: hono.fetch.bind(hono)
3655
4012
  };
3656
4013
  }
3657
- startServerless(inputConfig) {
3658
- var _a, _b, _c, _d, _e;
3659
- const config2 = RunConfigSchema.parse(inputConfig);
3660
- if ((_a = config2.logging) == null ? void 0 : _a.baseLogger) {
3661
- configureBaseLogger(config2.logging.baseLogger);
3662
- } else {
3663
- configureDefaultLogger((_b = config2.logging) == null ? void 0 : _b.level);
3664
- }
3665
- const driver = chooseDefaultDriver(config2);
3666
- if (driver.name === "engine") {
3667
- config2.inspector.enabled = false;
3668
- config2.disableServer = true;
3669
- config2.disableActorDriver = true;
3670
- }
3671
- if (driver.name === "cloudflare-workers") {
3672
- config2.inspector.enabled = false;
3673
- config2.disableServer = true;
3674
- config2.disableActorDriver = true;
3675
- config2.noWelcome = true;
3676
- }
3677
- let upgradeWebSocket;
3678
- if (!config2.getUpgradeWebSocket) {
3679
- config2.getUpgradeWebSocket = () => upgradeWebSocket;
3680
- }
3681
- const managerDriver = driver.manager(this.#config, config2);
3682
- const client = createClientWithDriver(managerDriver, config2);
3683
- const driverLog = ((_c = managerDriver.extraStartupLog) == null ? void 0 : _c.call(managerDriver)) ?? {};
3684
- logger6().info({
3685
- msg: "rivetkit ready",
3686
- driver: driver.name,
3687
- definitions: Object.keys(this.#config.use).length,
3688
- ...driverLog
3689
- });
3690
- if (((_d = config2.inspector) == null ? void 0 : _d.enabled) && managerDriver.inspector) {
3691
- logger6().info({ msg: "inspector ready", url: getInspectorUrl(config2) });
3692
- }
3693
- if (!config2.noWelcome) {
3694
- const displayInfo = managerDriver.displayInformation();
3695
- console.log();
3696
- console.log(` RivetKit ${package_default.version} (${displayInfo.name})`);
3697
- console.log(` - Endpoint: http://127.0.0.1:6420`);
3698
- for (const [k, v] of Object.entries(displayInfo.properties)) {
3699
- const padding = " ".repeat(Math.max(0, 13 - k.length));
3700
- console.log(` - ${k}:${padding}${v}`);
3701
- }
3702
- if (((_e = config2.inspector) == null ? void 0 : _e.enabled) && managerDriver.inspector) {
3703
- console.log(` - Inspector: ${getInspectorUrl(config2)}`);
4014
+ };
4015
+ async function configureServerlessRunner(config2) {
4016
+ try {
4017
+ if (!config2.runnerName) {
4018
+ throw new Error("runnerName is required for serverless configuration");
4019
+ }
4020
+ if (!config2.namespace) {
4021
+ throw new Error("namespace is required for serverless configuration");
4022
+ }
4023
+ if (!config2.endpoint) {
4024
+ throw new Error("endpoint is required for serverless configuration");
4025
+ }
4026
+ const customConfig = typeof config2.autoConfigureServerless === "object" ? config2.autoConfigureServerless : {};
4027
+ const requestBody = {
4028
+ serverless: {
4029
+ url: customConfig.url || `http://localhost:${config2.defaultServerPort}/start`,
4030
+ headers: customConfig.headers || {},
4031
+ max_runners: customConfig.maxRunners ?? 100,
4032
+ min_runners: customConfig.minRunners ?? 0,
4033
+ request_lifespan: customConfig.requestLifespan ?? 15 * 60,
4034
+ runners_margin: customConfig.runnersMargin ?? 0,
4035
+ slots_per_runner: customConfig.slotsPerRunner ?? config2.totalSlots ?? 1e3
3704
4036
  }
3705
- console.log();
3706
- }
3707
- let serverlessActorDriverBuilder = (token, totalSlots) => {
3708
- if (token) config2.token = token;
3709
- if (totalSlots) config2.totalSlots = totalSlots;
3710
- return driver.actor(this.#config, config2, managerDriver, client);
3711
4037
  };
3712
- if (!config2.disableActorDriver) {
3713
- const _actorDriver = serverlessActorDriverBuilder();
3714
- serverlessActorDriverBuilder = void 0;
3715
- }
3716
- const { router: hono } = createManagerRouter(
3717
- this.#config,
3718
- config2,
3719
- managerDriver,
3720
- serverlessActorDriverBuilder
3721
- );
3722
- if (!config2.disableServer) {
3723
- (async () => {
3724
- const out = await crossPlatformServe(hono, void 0);
3725
- upgradeWebSocket = out.upgradeWebSocket;
3726
- })();
4038
+ const configUrl = `${config2.endpoint}/runner-configs/${config2.runnerName}?namespace=${config2.namespace}`;
4039
+ logger7().debug({
4040
+ msg: "configuring serverless runner",
4041
+ url: configUrl,
4042
+ config: requestBody.serverless
4043
+ });
4044
+ const response = await fetch(configUrl, {
4045
+ method: "PUT",
4046
+ headers: {
4047
+ "Content-Type": "application/json",
4048
+ ...config2.token ? { Authorization: `Bearer ${config2.token}` } : {}
4049
+ },
4050
+ body: JSON.stringify(requestBody)
4051
+ });
4052
+ if (!response.ok) {
4053
+ const errorText = await response.text();
4054
+ throw new Error(
4055
+ `failed to configure serverless runner: ${response.status} ${response.statusText} - ${errorText}`
4056
+ );
3727
4057
  }
3728
- return {
3729
- client,
3730
- fetch: hono.fetch.bind(hono)
3731
- };
4058
+ logger7().info({
4059
+ msg: "serverless runner configured successfully",
4060
+ runnerName: config2.runnerName,
4061
+ namespace: config2.namespace
4062
+ });
4063
+ } catch (error) {
4064
+ logger7().error({
4065
+ msg: "failed to configure serverless runner",
4066
+ error
4067
+ });
4068
+ throw error;
3732
4069
  }
3733
- };
4070
+ }
3734
4071
  function setup(input) {
3735
4072
  const config2 = RegistryConfigSchema.parse(input);
3736
4073
  return new Registry(config2);
@@ -3752,4 +4089,4 @@ export {
3752
4089
  setup
3753
4090
  };
3754
4091
  //! These configs configs hold anything that's not platform-specific about running actors.
3755
- //# sourceMappingURL=chunk-E77RVI3P.js.map
4092
+ //# sourceMappingURL=chunk-VJRXZPTT.js.map