diff --git a/site/public/llms-full.txt b/site/public/llms-full.txt index 4731b1169c..24473de4b5 100644 --- a/site/public/llms-full.txt +++ b/site/public/llms-full.txt @@ -4468,6 +4468,14 @@ registry.runServer( If using a custom base logger, you must manually configure your own log level in the Pino logger. For more advanced Pino configuration options, see the [Pino API documentation](https://getpino.io/#/docs/api?id=export). + +### Disable Welcome Message + +You can disable the default RivetKit welcome message with: + +```typescript +registry.runServer() +``` ## Registry # Registry diff --git a/site/src/content/docs/actors/actions.mdx b/site/src/content/docs/actors/actions.mdx index 4ff5dc60a7..583185a328 100644 --- a/site/src/content/docs/actors/actions.mdx +++ b/site/src/content/docs/actors/actions.mdx @@ -50,21 +50,29 @@ console.log(result); // The value returned by the action Learn more about [communicating with actors from the frontend](/docs/actors/communicating-between-actors). - + ```typescript {{"title":"server.ts"}} import { setup } from "rivetkit"; +import { Hono } from "hono"; +import { serve } from "@hono/node-server"; const registry = setup({ use: { counter } }); -const { client, serve } = registry.runServer(); +const { client } = registry.start(); -// Use the client to call actions -const counter = await client.counter.getOrCreate(); -const result = await counter.increment(42); -console.log(result); +const app = new Hono(); + +// Use the client to call actions on a request +app.get("/foo", () => { + const counter = await client.counter.getOrCreate(); + const result = await counter.increment(42); + c.text(result); +}); + +serve(app); ``` Learn more about [communicating with actors from the backend](/docs/actors/communicating-between-actors). diff --git a/site/src/content/docs/actors/clients.mdx b/site/src/content/docs/actors/clients.mdx index d767ae4ad4..5abfc8f030 100644 --- a/site/src/content/docs/actors/clients.mdx +++ b/site/src/content/docs/actors/clients.mdx @@ -10,8 +10,8 @@ Rivet also supports [React](/docs/clients/react) and [Rust](/docs/clients/rust) Using the RivetKit client is completely optional. If you prefer to write your own networking logic, you can either: +- Write your own HTTP endpoints and use the client returned from `registry.start` (see below) - Make HTTP requests directly to the registry (see [OpenAPI spec](/docs/clients/openapi)) -- Write your own HTTP endpoints and use the client returned from `registry.runServer` (see below) ## Client Setup @@ -25,8 +25,10 @@ There are several ways to create a client for communicating with actors: ```typescript {{"title":"server.ts"}} import { registry } from "./registry"; + import { Hono } from "hono"; + import { serve } from "@hono/node-server"; - const { client, serve } = registry.createServer(); + const { client } = registry.start(); const app = new Hono(); diff --git a/site/src/content/docs/actors/fetch-and-websocket-handler.mdx b/site/src/content/docs/actors/fetch-and-websocket-handler.mdx index 5a2b23b769..a7ab0eb4ba 100644 --- a/site/src/content/docs/actors/fetch-and-websocket-handler.mdx +++ b/site/src/content/docs/actors/fetch-and-websocket-handler.mdx @@ -211,8 +211,9 @@ For more advanced use cases, you can forward requests to actor handlers from you ```typescript import { Hono } from "hono"; import { registry } from "./registry"; +import { serve } from "@hono/node-server"; -const { client, serve } = registry.createServer(); +const { client } = registry.start(); const app = new Hono(); @@ -241,9 +242,10 @@ serve(app); ```typescript import { Hono } from "hono"; import { upgradeWebSocket } from "hono/ws"; +import { serve } from "@hono/node-server"; import { registry } from "./registry"; -const { client, serve } = registry.createServer(); +const { client } = registry.start(); const app = new Hono(); diff --git a/site/src/content/docs/actors/quickstart/backend.mdx b/site/src/content/docs/actors/quickstart/backend.mdx index 5056d4870b..abc1669dc1 100644 --- a/site/src/content/docs/actors/quickstart/backend.mdx +++ b/site/src/content/docs/actors/quickstart/backend.mdx @@ -48,9 +48,10 @@ Choose your preferred web framework: ```ts {{"title":"Hono"}} import { registry } from "./registry"; import { Hono } from "hono"; +import { serve } from "@hono/node-server"; // Start Rivet with file system driver (for development) -const { client, serve } = registry.createServer(); +const { client } = registry.start(); // Setup Hono app const app = new Hono(); @@ -75,15 +76,12 @@ import { registry } from "./registry"; import express from "express"; // Start Rivet -const { client, handler } = registry.createServer(); +const { client } = registry.start(); // Setup Express app const app = express(); app.use(express.json()); -// Mount Rivet handler -app.use("/registry", handler); - // Example API endpoints app.post("/increment/:name", async (req, res) => { const { name } = req.params; @@ -104,7 +102,7 @@ import { registry } from "./registry"; import { Elysia } from "elysia"; // Start Rivet -const { client, handler } = registry.createServer(); +const { client } = registry.start(); // Setup Elysia app const app = new Elysia() diff --git a/site/src/content/docs/actors/quickstart/cloudflare-workers.mdx b/site/src/content/docs/actors/quickstart/cloudflare-workers.mdx new file mode 100644 index 0000000000..3ad614eee1 --- /dev/null +++ b/site/src/content/docs/actors/quickstart/cloudflare-workers.mdx @@ -0,0 +1,310 @@ +import { Hosting } from "@/components/docs/Hosting"; + +# Cloudflare Workers Quickstart + +Get started with Rivet Actors on Cloudflare Workers with Durable Objects + + + + +```sh +npm install rivetkit @rivetkit/cloudflare-workers +``` + + + + + +Create a simple counter actor: + +```ts {{"title":"registry.ts"}} +import { actor, setup } from "rivetkit"; + +export const counter = actor({ + state: { count: 0 }, + actions: { + increment: (c, amount: number = 1) => { + c.state.count += amount; + c.broadcast("countChanged", c.state.count); + return c.state.count; + }, + getCount: (c) => c.state.count, + }, +}); + +export const registry = setup({ + use: { counter }, +}); +``` + + + + + +Choose your preferred web framework: + + + +```ts {{"title":"Hono"}} +import { createHandler, type Client } from "@rivetkit/cloudflare-workers"; +import { Hono } from "hono"; +import { registry } from "./registry"; + +const app = new Hono<{ Bindings: { RIVET: Client } }>(); + +app.post("/increment/:name", async (c) => { + const client = c.env.RIVET; + const name = c.req.param("name"); + + // Get or create actor and call action + const counter = client.counter.getOrCreate(name); + const newCount = await counter.increment(1); + + return c.json({ count: newCount }); +}); + +const { handler, ActorHandler } = createHandler(registry, { fetch: app.fetch }); +export { handler as default, ActorHandler }; +``` + +```ts {{"title":"No Router"}} +import { createHandler } from "@rivetkit/cloudflare-workers"; +import { registry } from "./registry"; + +const { handler, ActorHandler } = createHandler(registry, { + fetch: async (request, env, ctx) => { + const url = new URL(request.url); + + if (url.pathname.startsWith("/increment/")) { + const name = url.pathname.split("/")[2]; + const client = env.RIVET; + + const counter = client.counter.getOrCreate(name); + const newCount = await counter.increment(1); + + return new Response(JSON.stringify({ count: newCount }), { + headers: { "Content-Type": "application/json" }, + }); + } + + return new Response("Not Found", { status: 404 }); + } +}); + +export { handler as default, ActorHandler }; +``` + + + + +The `/registry` endpoint is automatically mounted by Rivet and is required for client communication. The Cloudflare Workers driver handles this automatically. + + + + + + +Configure your `wrangler.json` for Cloudflare Workers: + +```json {{"title":"wrangler.json"}} +{ + "name": "my-rivetkit-app", + "main": "src/index.ts", + "compatibility_date": "2025-01-20", + "compatibility_flags": ["nodejs_compat"], + "migrations": [ + { + "tag": "v1", + "new_classes": ["ActorHandler"] + } + ], + "durable_objects": { + "bindings": [ + { + "name": "ACTOR_DO", + "class_name": "ActorHandler" + } + ] + }, + "kv_namespaces": [ + { + "binding": "ACTOR_KV", + "id": "your_namespace_id" + } + ] +} +``` + +Start the development server: + +```sh +wrangler dev +``` + +Your server is now running at `http://localhost:8787` + + + + + +Test your counter actor using HTTP requests: + + + +```ts {{"title":"JavaScript"}} +// Increment counter +const response = await fetch("http://localhost:8787/increment/my-counter", { + method: "POST" +}); + +const result = await response.json(); +console.log("Count:", result.count); // 1 +``` + +```sh curl +# Increment counter +curl -X POST http://localhost:8787/increment/my-counter +``` + + + + + + + +Deploy to Cloudflare's global edge network: + +```bash +wrangler deploy +``` + +Your actors will now run on Cloudflare's edge with persistent state backed by Durable Objects. + + + + + +## Configuration Options + +### Connect Frontend To The Rivet Actor + +Create a type-safe client to connect from your frontend: + + + + + +```ts {{"title":"client.ts"}} +import { createClient } from "rivetkit/client"; +import type { registry } from "./registry"; + +// Create typed client (use your deployed URL) +const client = createClient("https://your-app.workers.dev/rivet"); + +// Use the counter actor directly +const counter = client.counter.getOrCreate(["my-counter"]); + +// Call actions +const count = await counter.increment(3); +console.log("New count:", count); + +// Get current state +const currentCount = await counter.getCount(); +console.log("Current count:", currentCount); + +// Listen to real-time events +const connection = counter.connect(); +connection.on("countChanged", (newCount) => { + console.log("Count changed:", newCount); +}); + +// Increment through connection +await connection.increment(1); +``` + +See the [JavaScript client documentation](/clients/javascript) for more information. + + + + + +```tsx {{"title":"Counter.tsx"}} +import { useState } from "react"; +import { createClient, createRivetKit } from "@rivetkit/react"; +import type { registry } from "./registry"; + +const client = createClient("https://your-app.workers.dev/rivet"); +const { useActor } = createRivetKit(client); + +function Counter() { + const [count, setCount] = useState(0); + + const counter = useActor({ + name: "counter", + key: ["my-counter"] + }); + + counter.useEvent("countChanged", (newCount: number) => { + setCount(newCount); + }); + + const increment = async () => { + await counter.connection?.increment(1); + }; + + return ( +
+

Count: {count}

+ +
+ ); +} +``` + +See the [React documentation](/clients/react) for more information. + +
+ + + +```rust {{"title":"main.rs"}} +use rivetkit_client::{Client, EncodingKind, GetOrCreateOptions, TransportKind}; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new( + "https://your-app.workers.dev/rivet", + TransportKind::Sse, + EncodingKind::Json + ); + + // Get or create counter actor + let options = GetOrCreateOptions::default(); + let counter = client.get("counter", ["my-counter"].into(), options)? + .connect(); + + // Subscribe to events + counter.on_event("countChanged", |args| { + let count = args[0].as_i64().unwrap(); + println!("Count updated: {}", count); + }).await; + + // Call increment action + let result = counter.action("increment", vec![json!(1)]).await?; + println!("New count: {}", result); + + Ok(()) +} +``` + +See the [Rust client documentation](/clients/rust) for more information. + + + +
+ + + Cloudflare Workers mounts the Rivet endpoint on `/rivet` by default. + + diff --git a/site/src/content/docs/actors/quickstart/next-js.mdx b/site/src/content/docs/actors/quickstart/next-js.mdx index 20bc905fab..d60eb435e8 100644 --- a/site/src/content/docs/actors/quickstart/next-js.mdx +++ b/site/src/content/docs/actors/quickstart/next-js.mdx @@ -74,7 +74,7 @@ export const { useActor } = createRivetKit(client); import { toNextHandler } from "@rivetkit/next-js"; import { registry } from "@/rivet/registry"; -const server = registry.createServer({ +const server = registry.start({ // Use the same base path as the client // This is important for Next.js to route the API calls correctly basePath: "/api/registry", @@ -129,4 +129,4 @@ For more examples how to connect to your actors using React, check the [RivetKit - \ No newline at end of file + diff --git a/site/src/content/docs/actors/quickstart/react.mdx b/site/src/content/docs/actors/quickstart/react.mdx index e3dccc971d..a01ac89256 100644 --- a/site/src/content/docs/actors/quickstart/react.mdx +++ b/site/src/content/docs/actors/quickstart/react.mdx @@ -47,8 +47,8 @@ Start a server to run your actors: ```ts {{"title":"backend/server.ts"}} import { registry } from "./registry"; -// Run server with default configuration (port 8080) -registry.runServer(); +// Run server with default configuration +registry.start(); ``` diff --git a/site/src/content/docs/drivers/file-system.mdx b/site/src/content/docs/drivers/file-system.mdx index 4b2c7b31ea..1b02c90136 100644 --- a/site/src/content/docs/drivers/file-system.mdx +++ b/site/src/content/docs/drivers/file-system.mdx @@ -41,7 +41,7 @@ import { createFileSystemDriver } from "rivetkit"; import { registry } from "./registry"; const driver = createFileSystemDriver(); -const { serve, client } = registry.runServer({ driver }); +const { client } = registry.start({ driver }); // ...rest of your server... ``` @@ -61,7 +61,7 @@ import { registry } from "./registry"; const driver = createFileSystemDriver({ path: "/custom/path/to/actors" }); -const { serve, client } = registry.runServer({ driver }); +const { client } = registry.start({ driver }); // ...rest of your server... ``` diff --git a/site/src/content/docs/drivers/memory.mdx b/site/src/content/docs/drivers/memory.mdx index dca058817d..a20b473b5a 100644 --- a/site/src/content/docs/drivers/memory.mdx +++ b/site/src/content/docs/drivers/memory.mdx @@ -3,7 +3,7 @@ The Memory driver stores all actor state and communication in memory, making it ideal for testing, development, and prototyping scenarios where persistence is not required. -The Memory driver does not persist data between server restarts. For production applications that need to scale horizontally across multiple machines, use the [Redis driver](/docs/drivers/redis). +The Memory driver does not persist data between server restarts. For production applications that need to scale horizontally across multiple machines, see [self-hosting](/docs/self-hosting) ## Feature Support @@ -38,7 +38,7 @@ import { createMemoryDriver } from "rivetkit"; import { registry } from "./registry"; const driver = createMemoryDriver(); -const { serve, client } = registry.runServer({ driver }); +const { client } = registry.start({ driver }); // ...rest of your server... ``` diff --git a/site/src/content/docs/drivers/redis.mdx b/site/src/content/docs/drivers/redis.mdx deleted file mode 100644 index 647e81ba1d..0000000000 --- a/site/src/content/docs/drivers/redis.mdx +++ /dev/null @@ -1,170 +0,0 @@ -# Redis - -The Redis driver enables deploying scalable Rivet Actors using Redis as the backend for state management and inter-actor communication. - - -The Redis driver is currently in preview. We do not recommend shipping production applications with the Redis driver yet. - -If you want to take Redis to production, [contact us](/support) so we can help validate your setup is production ready and help resolve issues promptly. - - -## Feature Support - -| Feature | Supported | -| --- | --- | -| Horizontal scaling | Yes | -| WebSockets | Yes | -| SSE | Yes | -| Edge | No | -| Scheduling | [Not yet](https://github.com/rivet-gg/rivetkit/issues/1095) | - -## Setup - - - - -Install the required packages: - -```bash -npm install @rivetkit/redis ioredis@5 -``` - - - - - - - - -Configure your application using environment variables: - -```bash -REDIS_HOST=localhost -REDIS_PORT=6379 -REDIS_PASSWORD=your-password -REDIS_KEY_PREFIX=myproject -``` - -**Available Environment Variables:** - -- `REDIS_HOST` - Redis server hostname (default: `localhost`) -- `REDIS_PORT` - Redis server port (default: `6379`) -- `REDIS_PASSWORD` - Redis password (optional) -- `REDIS_KEY_PREFIX` - Key prefix for isolation when running multiple projects (optional) - -Then start your server: - -```typescript {{"title":"server.ts"}} -import { createRedisDriver } from "@rivetkit/redis"; -import { registry } from "./registry"; - -const driver = createRedisDriver(); -const { serve, client } = registry.runServer({ driver }); - -// ...rest of your server... -``` - - - - - -For advanced configuration, pass your own Redis instance: - -```typescript {{"title":"server.ts"}} -import { createRedisDriver } from "@rivetkit/redis"; -import { Redis } from "ioredis"; -import { registry } from "./registry"; - -const redis = new Redis({ - host: "localhost", - port: 6379, - password: "your-password", -}); - -const driver = createRedisDriver({ redis }); -const { serve, client } = registry.runServer({ driver }); - -// ...rest of your server... -``` - -**Configuration Options:** - -When passing a custom Redis instance, you have full control over the connection options. Common options include: - -- `host` - Redis server hostname -- `port` - Redis server port -- `password` - Redis password - -See the [ioredis documentation](https://github.com/luin/ioredis) for all available options. - - - - - - - - -To prevent data loss, ensure AOF (Append Only File) persistence is enabled on your Redis server. See the [Redis Persistence Documentation](https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/#append-only-file) for setup instructions. - - - -## Deploy - -Deploy your Redis-powered actors on these hosting providers: - - - -Deploy on Railway with automatic scaling and managed infrastructure. - - - -## Examples - - - -Example using Redis driver with Hono web framework. - - - -Basic Redis driver setup and configuration example. - - - -## Advanced - -### Driver Context - -The Redis driver provides access to the underlying Redis connection through the driver context in `createVars`. - -```typescript -import { actor, ActorInitContext } from "rivetkit"; -import type { DriverContext } from "@rivetkit/redis"; - -const myActor = actor({ - state: { count: 0 }, - - // Save the Redis driver context - createVars: (ctx: ActorInitContext, driver: DriverContext) => ({ redis: driver.redis }), - - actions: { - // Example: Access Redis directly (not recommended in practice) - getRedisValue: async (c, key: string) => { - // Use the Redis client from driver context - return await c.vars.redis.get(key); - }, - } -}); -``` - -The Redis driver context type is exported as `DriverContext` from `@rivetkit/redis`: - -```typescript -interface DriverContext { - redis: ioredis.Redis; - keyPrefix: string; // Key prefix that all RivetKit data is stored under -} -``` - - -While you have access to the Redis client, be cautious when directly modifying keys under the `keyPrefix`, as this may interfere with RivetKit's internal operations and potentially break actor functionality. - diff --git a/site/src/content/docs/general/cors.mdx b/site/src/content/docs/general/cors.mdx index db88c38d91..7fb8779003 100644 --- a/site/src/content/docs/general/cors.mdx +++ b/site/src/content/docs/general/cors.mdx @@ -14,13 +14,11 @@ Configure CORS directly in your registry setup for applications that do not requ ```typescript {{"title":"server.ts"}} import { registry } from "./registry"; -const { client, serve } = registry.createServer({ +const { client } = registry.start({ cors: { origin: "https://yourdomain.com", } }); - -serve(); ``` ### Configuration Options @@ -116,9 +114,11 @@ For applications that need to expose their own routes, configure CORS at the rou import { registry } from "./registry"; import { Hono } from "hono"; import { cors } from "hono/cors"; +import { serve } from "@hono/node-server"; import { ALLOWED_PUBLIC_HEADERS } from "rivetkit"; -const { serve } = registry.createServer(); +registry.start(); + const app = new Hono(); app.use("*", cors({ @@ -139,7 +139,8 @@ import cors from "cors"; import { ALLOWED_PUBLIC_HEADERS } from "rivetkit"; import { registry } from "./registry"; -const { handler } = registry.createServer(); +registry.start(); + const app = express(); app.use(cors({ @@ -173,7 +174,7 @@ const corsConfig = { }; ``` -These are automatically configured if using `registry.runServer({ cors })`. +These are automatically configured if using `registry.start({ cors })`. Without `ALLOWED_PUBLIC_HEADERS`, Rivet clients won't be able to communicate with your actors from the browser. diff --git a/site/src/content/docs/general/logging.mdx b/site/src/content/docs/general/logging.mdx index a12e7d9e3f..3e373e7e7e 100644 --- a/site/src/content/docs/general/logging.mdx +++ b/site/src/content/docs/general/logging.mdx @@ -68,7 +68,7 @@ LOG_LEVEL=debug LOG_TARGET=1 LOG_TIMESTAMP=1 node server.js You can configure the log level programmatically when running your server: ```typescript -registry.runServer({ +registry.start({ logging: { logLevel: "debug" } @@ -89,7 +89,7 @@ const customLogger = pino({ } }); -registry.runServer({ +registry.start({ logging: { baseLogger: customLogger, // Use your custom Pino logger } @@ -105,7 +105,7 @@ For more advanced Pino configuration options, see the [Pino API documentation](h You can disable the default RivetKit welcome message with: ```typescript -registry.runServer({ +registry.start({ noWelcome: true }) ``` diff --git a/site/src/content/docs/general/registry.mdx b/site/src/content/docs/general/registry.mdx deleted file mode 100644 index 605490ae71..0000000000 --- a/site/src/content/docs/general/registry.mdx +++ /dev/null @@ -1,291 +0,0 @@ -# Registry - -Configure and manage your actor registry - -The registry is the central configuration hub for your Rivet application. It defines which actors are available and how your application runs. - -## Basic Setup - -Create a registry by importing your actors and using the `setup` function: - -```typescript -import { setup } from "rivetkit"; -import { counterActor } from "./actors/counter"; -import { chatRoomActor } from "./actors/chat-room"; - -export const registry = setup({ - use: { - counter: counterActor, - chatRoom: chatRoomActor, - }, -}); -``` - -## Creating Servers - -### Development Server - -For development, create and run a server directly: - -```typescript -import { registry } from "./registry"; - -// Start a development server -registry.runServer({ - driver: { - topology: "standalone", - actor: { type: "memory" }, - manager: { type: "memory" }, - }, -}); -``` - -### Production Setup - -For production, get the handler and integrate with your framework: - -```typescript -import { registry } from "./registry"; -import { Hono } from "hono"; - -// Create server components -const { client, hono, handler, serve } = registry.createServer({ - driver: { - topology: "partition", - actor: { type: "redis", url: "redis://localhost:6379" }, - manager: { type: "redis", url: "redis://localhost:6379" }, - }, -}); - -// Use with Hono -const app = new Hono(); -app.route("/registry", hono); - -// Or use the handler directly -app.all("/registry/*", handler); - -// Start the server -serve(app); -``` - -## Configuration Options - -### Driver Configuration - -The driver configuration determines how actors are stored and managed: - -```typescript -const { client } = registry.createServer({ - driver: { - // Topology: how actors are distributed - topology: "standalone", // "standalone" | "partition" | "coordinate" - - // Actor storage - actor: { - type: "memory", // "memory" | "file-system" | "redis" | "rivet" - // Additional driver-specific options - }, - - // Manager coordination - manager: { - type: "memory", // "memory" | "redis" | "rivet" - // Additional driver-specific options - }, - }, -}); -``` - -### Topology Options - -- **`standalone`**: Single process, good for development -- **`partition`**: Distributed actors, good for production scaling -- **`coordinate`**: Peer-to-peer coordination, good for high availability - -### Storage Drivers - -- **`memory`**: In-memory storage, data lost on restart -- **`file-system`**: Persistent file-based storage -- **`redis`**: Redis-backed persistence and coordination -- **`rivet`**: Rivet platform integration - -### CORS Configuration - -Configure CORS for browser clients: - -```typescript -registry.runServer({ - cors: { - origin: ["https://myapp.com", "https://staging.myapp.com"], - credentials: true, - }, -}); -``` - -### Request Limits - -Configure request size limits: - -```typescript -registry.runServer({ - maxIncomingMessageSize: 1024 * 1024, // 1MB limit -}); -``` - -## Worker Mode - -For distributed topologies, you can create worker instances: - -```typescript -// Manager instance (handles routing) -const { hono: managerHono } = registry.createServer({ - driver: { topology: "partition", /* ... */ }, -}); - -// Worker instance (runs actors) -const { hono: workerHono } = registry.createWorker({ - driver: { topology: "partition", /* ... */ }, -}); -``` - -## Type Safety - -The registry provides full type safety for your client: - -```typescript -// TypeScript knows about your actors -const counter = client.counter.getOrCreate(["my-counter"]); -const chatRoom = client.chatRoom.getOrCreate(["general"]); - -// Action calls are type-checked -const count: number = await counter.increment(5); -``` - -## Testing Configuration - -Use memory drivers for testing: - -```typescript -// test-registry.ts -export const testRegistry = setup({ - use: { - counter: counterActor, - chatRoom: chatRoomActor, - }, -}); - -// In your tests -const { client } = testRegistry.createServer({ - driver: { - topology: "standalone", - actor: { type: "memory" }, - manager: { type: "memory" }, - }, -}); -``` - -## Environment-Specific Configuration - -Use environment variables to configure different environments: - -```typescript -const isProd = process.env.NODE_ENV === "production"; -const redisUrl = process.env.REDIS_URL || "redis://localhost:6379"; - -export const registry = setup({ - use: { - counter: counterActor, - chatRoom: chatRoomActor, - }, -}); - -// Environment-specific server creation -export function createAppServer() { - return registry.createServer({ - driver: isProd - ? { - topology: "partition", - actor: { type: "redis", url: redisUrl }, - manager: { type: "redis", url: redisUrl }, - } - : { - topology: "standalone", - actor: { type: "memory" }, - manager: { type: "memory" }, - }, - cors: { - origin: isProd ? "https://myapp.com" : "*", - }, - }); -} -``` - -## Best Practices - -### Registry Organization - -Keep your registry clean and organized: - -```typescript -// actors/index.ts - Export all actors -export { counterActor } from "./counter"; -export { chatRoomActor } from "./chat-room"; -export { gameActor } from "./game"; - -// registry.ts - Import and configure -import { setup } from "rivetkit"; -import * as actors from "./actors"; - -export const registry = setup({ - use: actors, -}); -``` - -### Actor Naming - -Use consistent naming conventions: - -```typescript -export const registry = setup({ - use: { - // Use camelCase for actor names - counter: counterActor, - chatRoom: chatRoomActor, - userProfile: userProfileActor, - - // Group related actors with prefixes - gameSession: gameSessionActor, - gameLobby: gameLobbyActor, - }, -}); -``` - -### Configuration Management - -Separate configuration from registry definition: - -```typescript -// config.ts -export const appConfig = { - redis: { - url: process.env.REDIS_URL || "redis://localhost:6379", - }, - cors: { - origin: process.env.ALLOWED_ORIGINS?.split(",") || ["*"], - }, -}; - -// server.ts -import { registry } from "./registry"; -import { appConfig } from "./config"; - -const { serve } = registry.createServer({ - driver: { - topology: "partition", - actor: { type: "redis", url: appConfig.redis.url }, - manager: { type: "redis", url: appConfig.redis.url }, - }, - cors: appConfig.cors, -}); - -serve(); -``` diff --git a/site/src/content/docs/general/studio.mdx b/site/src/content/docs/general/studio.mdx index e8b7b80fab..eb646b80d2 100644 --- a/site/src/content/docs/general/studio.mdx +++ b/site/src/content/docs/general/studio.mdx @@ -29,7 +29,7 @@ By default, Rivet Studio generates and stores a token automatically. You can con - **Environment variable**: Set `RIVETKIT_STUDIO_TOKEN` - **Code configuration**: ```typescript {{"title":"server.ts"}} - registry.runServer({ + registry.start({ studio: { token: () => "your-custom-token" } @@ -44,7 +44,7 @@ Disable Studio using any of these methods: - Set `NODE_ENV=production` - Configure in code: ```typescript {{"title":"server.ts"}} - registry.runServer({ + registry.start({ studio: { enabled: false } @@ -56,7 +56,7 @@ Disable Studio using any of these methods: Configure CORS for custom Studio deployments: ```typescript {{"title":"server.ts"}} -registry.runServer({ +registry.start({ studio: { cors: { origin: "https://my-studio-url.test" @@ -72,7 +72,7 @@ See the [CORS documentation](/docs/general/cors/) for more details. On startup, RivetKit prints a URL for connecting to Studio. By default, Studio connects to `localhost:8080` if no endpoint is provided. Override with: ```typescript {{"title":"server.ts"}} -registry.runServer({ +registry.start({ studio: { defaultEndpoint: "http://my-app:3000" } diff --git a/site/src/content/docs/hosting-providers/railway.mdx b/site/src/content/docs/hosting-providers/railway.mdx deleted file mode 100644 index bffe867f8f..0000000000 --- a/site/src/content/docs/hosting-providers/railway.mdx +++ /dev/null @@ -1,4 +0,0 @@ -# Railway - -_Coming Soon_ - diff --git a/site/src/content/docs/hosting-providers/rivet-cloud.mdx b/site/src/content/docs/hosting-providers/rivet-cloud.mdx deleted file mode 100644 index a0bdb1d6a2..0000000000 --- a/site/src/content/docs/hosting-providers/rivet-cloud.mdx +++ /dev/null @@ -1,21 +0,0 @@ -# Rivet Cloud (Enterprise) - -Rivet Cloud enables you to run Rivet applications at scale with the high performance, edge support, and monitoring. Rivet projects can be deployed to the Rivet Cloud or be self-hosted on-premise. - -To try Rivet Cloud, get in touch: - -- [Talk to an engineer](https://www.rivet.gg/talk-to-an-engineer) -- [Talk to sales](https://www.rivet.gg/sales) - -Rivet Engine — the core of Rivet Cloud — is [open-source on GitHub](https://github.com/rivet-gg/rivet). - -## Feature Support - -| Feature | Supported | -| --- | --- | -| Horizontal scaling | Yes | -| WebSockets | Yes | -| SSE | Yes | -| Edge | Yes | -| Scheduling | Yes | - diff --git a/site/src/content/docs/integrations/better-auth.mdx b/site/src/content/docs/integrations/better-auth.mdx index d61451c159..e4cff1b1d4 100644 --- a/site/src/content/docs/integrations/better-auth.mdx +++ b/site/src/content/docs/integrations/better-auth.mdx @@ -133,8 +133,9 @@ import { auth } from "./auth"; import { Hono } from "hono"; import { cors } from "hono/cors"; import { ALLOWED_PUBLIC_HEADERS } from "rivetkit"; +import { serve } from "@hono/node-server"; -const { serve } = registry.createServer(); +registry.start(); const app = new Hono(); // Configure CORS for Better Auth + Rivet diff --git a/site/src/content/docs/hosting-providers/cloudflare-workers.mdx b/site/src/content/docs/integrations/cloudflare-workers.mdx similarity index 86% rename from site/src/content/docs/hosting-providers/cloudflare-workers.mdx rename to site/src/content/docs/integrations/cloudflare-workers.mdx index 03b6549bb4..2ca873d281 100644 --- a/site/src/content/docs/hosting-providers/cloudflare-workers.mdx +++ b/site/src/content/docs/integrations/cloudflare-workers.mdx @@ -33,28 +33,27 @@ Update your server code to support Cloudflare Workers: ```typescript {{"title":"server.ts"}} -import { createServer } from "@rivetkit/cloudflare-workers"; +import { createHandler, type Client } from "@rivetkit/cloudflare-workers"; import { Hono } from "hono"; import { registry } from "./registry"; -const { client, createHandler } = createServer(registry); - // Setup router -const app = new Hono(); +const app = new Hono<{ Bindings: { RIVET: Client } }>(); -// Example API endpoint +// Example HTTP endpoint app.post("/increment/:name", async (c) => { - const name = c.req.param("name"); + console.log("env", c.env); + const client = c.env.RIVET; - // Get or create actor and call action - const counter = client.counter.getOrCreate(name); - const newCount = await counter.increment(1); + const name = c.req.param("name"); - return c.json({ count: newCount }); -}); + const counter = client.counter.getOrCreate(name); + const newCount = await counter.increment(1); -const { handler, ActorHandler } = createHandler(app); + return c.text(`New Count: ${newCount}`); +}); +const { handler, ActorHandler } = createHandler(registry, { fetch: app.fetch }); export { handler as default, ActorHandler }; ``` @@ -63,10 +62,10 @@ export { handler as default, ActorHandler }; ```typescript {{"title":"server.ts"}} -import { createServerHandler } from "@rivetkit/cloudflare-workers"; +import { createHandler } from "@rivetkit/cloudflare-workers"; import { registry } from "./registry"; -const { handler, ActorHandler } = createServerHandler(registry); +const { handler, ActorHandler } = createHandler(registry); export { handler as default, ActorHandler }; ``` @@ -142,6 +141,10 @@ Basic Cloudflare Workers setup and configuration example. + + Cloudflare Workers mounts the Rivet endpoint on `/rivet` by default. + + ## Advanced ### Accessing Environment Bindings diff --git a/site/src/content/docs/integrations/elysia.mdx b/site/src/content/docs/integrations/elysia.mdx index bf4bc576c4..9785b2f8c9 100644 --- a/site/src/content/docs/integrations/elysia.mdx +++ b/site/src/content/docs/integrations/elysia.mdx @@ -56,12 +56,10 @@ Mount Rivet into your Elysia application: import { registry } from "./registry"; import { Elysia } from "elysia"; -const { client, handler } = registry.createServer(); +const { client } = registry.start(); // Setup Elysia app const app = new Elysia() - // Mount Rivet handler - .mount("/registry", handler) // Add your API routes .post("/increment/:name", async ({ params }) => { const name = params.name; diff --git a/site/src/content/docs/integrations/express.mdx b/site/src/content/docs/integrations/express.mdx index d6fee07691..4e7544d21a 100644 --- a/site/src/content/docs/integrations/express.mdx +++ b/site/src/content/docs/integrations/express.mdx @@ -56,7 +56,7 @@ import { registry } from "./registry"; import express from "express"; // Start Rivet -const { client, handler } = registry.createServer(); +const { client } = registry.start(); // Setup Express app const app = express(); @@ -64,9 +64,6 @@ const app = express(); // Enable JSON parsing app.use(express.json()); -// Mount Rivet handler -app.use("/registry", handler); - // Add your API routes app.post("/increment/:name", async (req, res) => { const name = req.params.name; diff --git a/site/src/content/docs/integrations/hono.mdx b/site/src/content/docs/integrations/hono.mdx index ee387fa9c1..c4e80da45a 100644 --- a/site/src/content/docs/integrations/hono.mdx +++ b/site/src/content/docs/integrations/hono.mdx @@ -47,15 +47,14 @@ export const registry = setup({ -Use Rivet's `serve()` method with your Hono app: - ```typescript // server.ts import { registry } from "./registry"; import { Hono } from "hono"; +import { serve } from "@hono/node-server"; // Start Rivet -const { client, serve } = registry.createServer(); +const { client } = registry.start(); // Setup Hono app const app = new Hono(); @@ -95,7 +94,7 @@ app.get("/count/:name", async (c) => { } }); -// Start server with Rivet integration +// Start server serve(app); ``` diff --git a/site/src/content/docs/integrations/next-js.mdx b/site/src/content/docs/integrations/next-js.mdx index e99655e825..c4e950ec9e 100644 --- a/site/src/content/docs/integrations/next-js.mdx +++ b/site/src/content/docs/integrations/next-js.mdx @@ -57,7 +57,7 @@ export const registry = setup({ import { toNextHandler } from "@rivetkit/next-js"; import { registry } from "@/rivet/registry"; -const server = registry.createServer({ +const server = registry.start({ // Use the same base path as the client // This is important for Next.js to route the API calls correctly basePath: "/api/registry", @@ -94,7 +94,7 @@ const registry = setup({ use: { counter }, }); -const server = registry.createServer(); +const server = registry.start(); export const { GET, POST, HEAD, PATCH, OPTIONS } = toNextHandler(server); ``` @@ -103,4 +103,4 @@ export const { GET, POST, HEAD, PATCH, OPTIONS } = toNextHandler(server); - `server`: The RivetKit server instance created from your registry. #### Returns -- An object containing Next.js-compatible handlers for the HTTP methods. \ No newline at end of file +- An object containing Next.js-compatible handlers for the HTTP methods. diff --git a/site/src/content/docs/integrations/trpc.mdx b/site/src/content/docs/integrations/trpc.mdx index 0a7d0696bb..c05465a7e2 100644 --- a/site/src/content/docs/integrations/trpc.mdx +++ b/site/src/content/docs/integrations/trpc.mdx @@ -63,7 +63,7 @@ import { createHTTPServer } from "@trpc/server/adapters/standalone"; import { z } from "zod"; // Start Rivet -const { client } = registry.createServer(); +const { client } = registry.start(); // Initialize tRPC const t = initTRPC.create(); diff --git a/site/src/sitemap/mod.ts b/site/src/sitemap/mod.ts index cc557cfcbf..9dd1ec715e 100644 --- a/site/src/sitemap/mod.ts +++ b/site/src/sitemap/mod.ts @@ -56,6 +56,7 @@ import { faLayerGroup, faVercel, faSquareRootVariable, + faCloudflare, } from "@rivet-gg/icons"; // Goals: @@ -104,6 +105,11 @@ export const sitemap = [ href: "/docs/actors/quickstart/next-js", icon: nextjs, }, + { + title: "Cloudflare Workers", + href: "/docs/actors/quickstart/cloudflare-workers", + icon: faCloudflare, + }, ], }, { @@ -303,6 +309,10 @@ export const sitemap = [ title: "Next.js", href: "/docs/integrations/next-js", }, + { + title: "Cloudflare Workers", + href: "/docs/integrations/cloudflare-workers", + }, ], }, {