Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions rivetkit-typescript/packages/rivetkit/src/registry/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getRivetNamespace,
getRivetRunEngine,
getRivetRunEngineVersion,
getRivetRuntimeMode,
getRivetToken,
isDev,
} from "@/utils/env-vars";
Expand Down Expand Up @@ -151,6 +152,8 @@ export const RegistryConfigSchema = z
* @experimental
*
* Runtime mode to use when `registry.start()` is called.
*
* Can also be set via RIVET_RUNTIME_MODE.
*/
mode: RuntimeModeSchema.optional(),
/**
Expand Down Expand Up @@ -225,11 +228,31 @@ export const RegistryConfigSchema = z
const isDevEnv = isDev();
const isProductionEnv = getNodeEnv() === "production";
const envStartEngine = getRivetRunEngine();
const envRuntimeMode =
config.mode === undefined ? getRivetRuntimeMode() : undefined;
const parsedEnvRuntimeMode =
envRuntimeMode === undefined
? undefined
: RuntimeModeSchema.safeParse(envRuntimeMode);
const configuredRuntimeMode =
config.mode ??
(parsedEnvRuntimeMode?.success
? parsedEnvRuntimeMode.data
: undefined);
const explicitStartEngine =
config.startEngine !== undefined || envStartEngine;
let startEngine = true;
let runtimeMode: RuntimeMode = "envoy";

if (parsedEnvRuntimeMode && !parsedEnvRuntimeMode.success) {
ctx.addIssue({
code: "custom",
message:
"RIVET_RUNTIME_MODE must be either envoy or serverless",
path: ["mode"],
});
}

// Parse endpoint string (env var fallback is applied via transform above)
const parsedEndpoint = config.endpoint
? tryParseEndpoint(ctx, {
Expand All @@ -250,10 +273,10 @@ export const RegistryConfigSchema = z
runtimeMode = "serverless";
}

if (config.mode === "envoy") {
if (configuredRuntimeMode === "envoy") {
startEngine = false;
runtimeMode = "envoy";
} else if (config.mode === "serverless") {
} else if (configuredRuntimeMode === "serverless") {
startEngine = false;
runtimeMode = "serverless";
}
Expand Down Expand Up @@ -580,7 +603,7 @@ export const DocRegistryConfigSchema = z
.optional()
.describe("Host to bind the local HTTP server to."),
mode: RuntimeModeSchema.optional().describe(
"Runtime mode for registry.start(). Defaults to 'envoy' for local development and 'serverless' when a Rivet endpoint or production environment is configured.",
"Runtime mode for registry.start(). Can also be set via RIVET_RUNTIME_MODE. Defaults to 'envoy' for local development and 'serverless' when a Rivet endpoint or production environment is configured.",
),
startEngine: z
.boolean()
Expand Down
2 changes: 2 additions & 0 deletions rivetkit-typescript/packages/rivetkit/src/utils/env-vars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const getRivetRunEngine = (): boolean =>
getEnvUniversal("RIVET_RUN_ENGINE") === "1";
export const getRivetRunEngineVersion = (): string | undefined =>
getEnvUniversal("RIVET_RUN_ENGINE_VERSION");
export const getRivetRuntimeMode = (): string | undefined =>
getEnvUniversal("RIVET_RUNTIME_MODE");
export const getRivetEnvoyKind = (): string | undefined =>
getEnvUniversal("RIVET_ENVOY_KIND");
export const getRivetEnvoyVersion = (): number | undefined => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const ENV_KEYS = [
"RIVET_ENGINE",
"RIVET_ENVOY_VERSION",
"RIVET_RUN_ENGINE",
"RIVET_RUNTIME_MODE",
] as const;

type BunGlobal = typeof globalThis & {
Expand Down Expand Up @@ -129,6 +130,39 @@ describe("registry start mode config", () => {
expect(config.endpoint).toBe("https://api.rivet.dev/");
});

test("RIVET_RUNTIME_MODE overrides endpoint inference", () => {
process.env.RIVET_ENDPOINT = "https://api.rivet.dev";
process.env.RIVET_RUNTIME_MODE = "envoy";

const config = parseRegistryConfig();

expect(config.startEngine).toBe(false);
expect(config.runtimeMode).toBe("envoy");
expect(config.endpoint).toBe("https://api.rivet.dev/");
});

test("explicit mode overrides RIVET_RUNTIME_MODE", () => {
process.env.RIVET_ENDPOINT = "https://api.rivet.dev";
process.env.RIVET_RUNTIME_MODE = "local";

const config = parseRegistryConfig({
mode: "envoy",
});

expect(config.startEngine).toBe(false);
expect(config.runtimeMode).toBe("envoy");
expect(config.endpoint).toBe("https://api.rivet.dev/");
});

test("invalid RIVET_RUNTIME_MODE is rejected", () => {
process.env.RIVET_ENDPOINT = "https://api.rivet.dev";
process.env.RIVET_RUNTIME_MODE = "local";

expect(() => parseRegistryConfig()).toThrow(
/RIVET_RUNTIME_MODE must be either envoy or serverless/,
);
});

test("explicit envoy mode disables local engine startup", () => {
const config = parseRegistryConfig({
endpoint: "https://api.rivet.dev",
Expand Down
1 change: 1 addition & 0 deletions website/src/content/docs/general/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ These variables configure how clients connect to your actors.

| Environment Variable | Description |
|---------------------|-------------|
| `RIVET_RUNTIME_MODE` | Runtime mode for `registry.start()`: `envoy` or `serverless`. |
| `RIVET_RUN_ENGINE` | Set to `1` to spawn the engine process |
| `RIVET_RUN_ENGINE_VERSION` | Version of engine to download |

Expand Down
Loading