diff --git a/CLAUDE.md b/CLAUDE.md
index 2eeda6c49..a2da8668b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -14,7 +14,7 @@
Always include a README.md for new packages. The `README.md` should always follow this structure:
```md
- # RivetKit {subname, e.g. library: RivetKit Workers, driver and platform: RivetKit Redis Adapter, RivetKit Cloudflare Workers Adapter}
+ # RivetKit {subname, e.g. library: RivetKit Actors, driver and platform: RivetKit Redis Adapter, RivetKit Cloudflare Workers Adapter}
_Lightweight Libraries for Backends_
@@ -30,16 +30,16 @@ Always include a README.md for new packages. The `README.md` should always follo
## Common Terminology
-- **Worker**: A stateful, long-lived entity that processes messages and maintains state
-- **Manager**: Component responsible for creating, routing, and managing worker instances
-- **Remote Procedure Call (RPC)**: Method for an worker to expose callable functions to clients
-- **Event**: Asynchronous message sent from an worker to connected clients
+- **Actor**: A stateful, long-lived entity that processes messages and maintains state
+- **Manager**: Component responsible for creating, routing, and managing actor instances
+- **Remote Procedure Call (RPC)**: Method for an actor to expose callable functions to clients
+- **Event**: Asynchronous message sent from an actor to connected clients
- **Alarm**: Scheduled callback that triggers at a specific time
### Coordinated Topology Terminology
-- **Peer**: Individual worker instance in a coordinated network
-- **Node**: Physical or logical host running one or more worker peers
+- **Peer**: Individual actor instance in a coordinated network
+- **Node**: Physical or logical host running one or more actor peers
## Build Commands
@@ -56,19 +56,19 @@ Run these commands from the root of the project. They depend on Turborepo, so yo
### Topologies
-rivetkit supports three topologies that define how workers communicate and scale:
+rivetkit supports three topologies that define how actors communicate and scale:
-- **Singleton:** A single instance of an worker running in one location
-- **Partition:** Multiple instances of an worker type partitioned by ID, useful for horizontal scaling
-- **Coordinate:** Workers connected in a peer-to-peer network, sharing state between instances
+- **Singleton:** A single instance of an actor running in one location
+- **Partition:** Multiple instances of an actor type partitioned by ID, useful for horizontal scaling
+- **Coordinate:** Actors connected in a peer-to-peer network, sharing state between instances
### Driver Interfaces
Driver interfaces define the contract between rivetkit and various backends:
-- **WorkerDriver:** Manages worker state, lifecycle, and persistence
-- **ManagerDriver:** Manages worker discovery, routing, and scaling
-- **CoordinateDriver:** Handles peer-to-peer communication between worker instances
+- **ActorDriver:** Manages actor state, lifecycle, and persistence
+- **ManagerDriver:** Manages actor discovery, routing, and scaling
+- **CoordinateDriver:** Handles peer-to-peer communication between actor instances
- Only applicable in coordinate topologies
### Driver Implementations
@@ -110,7 +110,7 @@ This ensures imports resolve correctly across different build environments and p
- UPPER_CASE for constants
- Use `#` prefix for private class members (not `private` keyword)
- **Error Handling:**
- - Extend from `WorkerError` base class (packages/core/src/worker/errors.ts)
+ - Extend from `ActorError` base class (packages/core/src/actor/errors.ts)
- Use `UserError` for client-safe errors
- Use `InternalError` for internal errors
- Don't try to fix type issues by casting to unknown or any. If you need to do this, then stop and ask me to manually intervene.
@@ -119,7 +119,7 @@ This ensures imports resolve correctly across different build environments and p
- Do not store `logger()` as a variable, always call it using `logger().info("...")`
- Use structured logging where it makes sense, for example: `logger().info("foo", { bar: 5, baz: 10 })`
- Supported logging methods are: trace, debug, info, warn, error, critical
-- Instead of returning errors as raw HTTP responses with c.json, use or write an error in packages/rivetkit/src/worker/errors.ts and throw that instead. The middleware will automatically serialize the response for you.
+- Instead of returning errors as raw HTTP responses with c.json, use or write an error in packages/rivetkit/src/actor/errors.ts and throw that instead. The middleware will automatically serialize the response for you.
## Project Structure
@@ -140,7 +140,7 @@ This ensures imports resolve correctly across different build environments and p
## Test Guidelines
-- Do not check if errors are an instanceOf WorkerError in tests. Many error types do not have the same prototype chain when sent over the network, but still have the same properties so you can safely cast with `as`.
+- Do not check if errors are an instanceOf ActorError in tests. Many error types do not have the same prototype chain when sent over the network, but still have the same properties so you can safely cast with `as`.
## Examples
diff --git a/docs/clients/javascript.mdx b/docs/clients/javascript.mdx
index 7e9901d42..3d42dff86 100644
--- a/docs/clients/javascript.mdx
+++ b/docs/clients/javascript.mdx
@@ -4,12 +4,12 @@ icon: node-js
---
import MvpWarning from "/snippets/mvp-warning.mdx";
-import StepDefineWorker from "/snippets/step-define-worker.mdx";
+import StepDefineActor from "/snippets/step-define-actor.mdx";
import StepRunStudio from "/snippets/step-run-studio.mdx";
import StepDeploy from "/snippets/step-deploy.mdx";
import SetupNextSteps from "/snippets/setup-next-steps.mdx";
-The RivetKit JavaScript client allows you to connect to and interact with workers from browser and Node.js applications.
+The RivetKit JavaScript client allows you to connect to and interact with actors from browser and Node.js applications.
@@ -71,20 +71,20 @@ The RivetKit JavaScript client allows you to connect to and interact with worker
-
+
- Create a file `src/client.ts` in your project to connect to your worker:
+ Create a file `src/client.ts` in your project to connect to your actor:
```typescript src/client.ts
import { createClient } from "rivetkit/client";
- import type { App } from "../workers/app";
+ import type { App } from "../actors/app";
async function main() {
// Replace with your endpoint URL after deployment
const client = createClient("http://localhost:6420");
- // Get or create a worker instance
+ // Get or create a actor instance
const counter = await client.counter.get();
// Subscribe to events
@@ -139,5 +139,5 @@ The RivetKit JavaScript client allows you to connect to and interact with worker
## Next Steps
-See the [Interacting with Workers](/concepts/interacting-with-workers) documentation for information on how to use the client.
+See the [Interacting with Actors](/concepts/interacting-with-actors) documentation for information on how to use the client.
diff --git a/docs/clients/python.mdx b/docs/clients/python.mdx
index 3cf4f301f..4fd8e009b 100644
--- a/docs/clients/python.mdx
+++ b/docs/clients/python.mdx
@@ -4,12 +4,12 @@ icon: python
---
import MvpWarning from "/snippets/mvp-warning.mdx";
-import StepDefineWorker from "/snippets/step-define-worker.mdx";
+import StepDefineActor from "/snippets/step-define-actor.mdx";
import StepRunStudio from "/snippets/step-run-studio.mdx";
import StepDeploy from "/snippets/step-deploy.mdx";
import SetupNextSteps from "/snippets/setup-next-steps.mdx";
-The RivetKit Python client provides a way to connect to and interact with workers from Python applications.
+The RivetKit Python client provides a way to connect to and interact with actors from Python applications.
@@ -39,7 +39,7 @@ The RivetKit Python client provides a way to connect to and interact with worker
```
-
+
Create a new file `main.py`:
@@ -53,7 +53,7 @@ The RivetKit Python client provides a way to connect to and interact with worker
# Replace with your endpoint URL after deployment
client = AsyncClient("http://localhost:6420")
- # Get or create a worker instance
+ # Get or create a actor instance
counter = await client.get("counter")
# Subscribe to events using callback
@@ -82,7 +82,7 @@ The RivetKit Python client provides a way to connect to and interact with worker
# Replace with your endpoint URL after deployment
client = Client("http://localhost:6420")
- # Get or create a worker instance
+ # Get or create a actor instance
counter = client.get("counter")
# Subscribe to events using callback
diff --git a/docs/concepts/cors.mdx b/docs/concepts/cors.mdx
index 546ae19c9..118e96115 100644
--- a/docs/concepts/cors.mdx
+++ b/docs/concepts/cors.mdx
@@ -8,8 +8,8 @@ Cross-Origin Resource Sharing (CORS) is a security mechanism that allows a web a
You'll need to configure CORS when:
-- **Local Development**: You're developing locally and your client runs on a different port than your worker service
-- **Different Domain**: Your frontend application is hosted on a different domain than your worker service
+- **Local Development**: You're developing locally and your client runs on a different port than your actor service
+- **Different Domain**: Your frontend application is hosted on a different domain than your actor service
## Example
@@ -18,7 +18,7 @@ import { setup } from "rivetkit";
import counter from "./counter";
const registry = setup({
- workers: { counter },
+ actors: { counter },
// Change this to match your frontend's origin
cors: { origin: "https://yourdomain.com" }
});
diff --git a/docs/concepts/edge.mdx b/docs/concepts/edge.mdx
index 52d52b7ce..b6879433f 100644
--- a/docs/concepts/edge.mdx
+++ b/docs/concepts/edge.mdx
@@ -1,6 +1,6 @@
---
title: Edge Networking
-description: Workers run near your users on your provider's global network (if supported).
+description: Actors run near your users on your provider's global network (if supported).
icon: globe
---
@@ -8,7 +8,7 @@ icon: globe
### Automatic region selection
-By default, workers will choose the optimal region based on the client's location.
+By default, actors will choose the optimal region based on the client's location.
Under the hood, Rivet uses [Anycast routing](https://en.wikipedia.org/wiki/Anycast) to automatically find
@@ -17,7 +17,7 @@ By default, workers will choose the optimal region based on the client's locatio
### Manual region selection
-The region a worker is created in can be overridden using region options:
+The region a actor is created in can be overridden using region options:
```typescript client.ts
import { createClient } from "rivetkit/client";
@@ -25,8 +25,8 @@ import type { App } from "./src/index";
const client = createClient("http://localhost:6420");
-// Create worker in a specific region
-const worker = await client.example.get({
+// Create actor in a specific region
+const actor = await client.example.get({
options: {
create: {
region: "atl"
@@ -35,7 +35,7 @@ const worker = await client.example.get({
});
```
-See [Create & Manage Workers](/docs/manage) for more information.
+See [Create & Manage Actors](/docs/manage) for more information.
## Available regions
@@ -45,6 +45,6 @@ See available regions [here](/docs/regions).
It's common to need to display a list of available regions in your application.
-To fetch a full list of regions, you can use the `GET https://api.rivet.gg/regions` HTTP endpoint. See API documentation [here](/docs/api/worker/regions/list).
+To fetch a full list of regions, you can use the `GET https://api.rivet.gg/regions` HTTP endpoint. See API documentation [here](/docs/api/actor/regions/list).
We don't recommend hard-coding the region list. This allows you to develop your application with a local development cluster.
diff --git a/docs/concepts/external-sql.mdx b/docs/concepts/external-sql.mdx
index d0204b6cf..d30e88848 100644
--- a/docs/concepts/external-sql.mdx
+++ b/docs/concepts/external-sql.mdx
@@ -3,9 +3,9 @@ title: External SQL Database
icon: database
---
-While workers can serve as a complete database solution, they can also complement your existing databases. For example, you might use workers to handle frequently-changing data that needs real-time access, while keeping less frequently accessed data in your traditional database.
+While actors can serve as a complete database solution, they can also complement your existing databases. For example, you might use actors to handle frequently-changing data that needs real-time access, while keeping less frequently accessed data in your traditional database.
-Workers can be used with common SQL databases, such as PostgreSQL and MySQL.
+Actors can be used with common SQL databases, such as PostgreSQL and MySQL.
## Libraries
@@ -35,8 +35,8 @@ There are several options for places to host your SQL database:
Here's a basic example of how you might set up a connection to a PostgreSQL database using the `pg` library:
-```typescript worker.ts
-import { worker } from "rivetkit";
+```typescript actor.ts
+import { actor } from "rivetkit";
import { Pool } from "pg";
// Create a database connection pool
@@ -48,8 +48,8 @@ const pool = new Pool({
port: 5432,
});
-// Create the worker
-const databaseWorker = worker({
+// Create the actor
+const databaseActor = actor({
state: {
// Local state if needed
lastQueryTime: 0
@@ -57,7 +57,7 @@ const databaseWorker = worker({
// Initialize any resources
onStart: (c) => {
- console.log("Database worker started");
+ console.log("Database actor started");
},
// Clean up resources if needed
@@ -98,15 +98,15 @@ const databaseWorker = worker({
}
});
-export default databaseWorker;
+export default databaseActor;
```
## With Drizzle ORM
Here's an example using Drizzle ORM for more type-safe database operations:
-```typescript worker.ts
-import { worker } from "rivetkit";
+```typescript actor.ts
+import { actor } from "rivetkit";
import { drizzle } from "drizzle-orm/node-postgres";
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
import { Pool } from "pg";
@@ -127,10 +127,10 @@ const pool = new Pool({
// Initialize Drizzle with the pool
const db = drizzle(pool);
-// Create the worker
-const userWorker = worker({
+// Create the actor
+const userActor = actor({
state: {
- // Worker state (frequently accessed data can be cached here)
+ // Actor state (frequently accessed data can be cached here)
userCache: {}
},
@@ -169,5 +169,5 @@ const userWorker = worker({
}
});
-export default userWorker;
+export default userActor;
```
diff --git a/docs/concepts/logging.mdx b/docs/concepts/logging.mdx
index 92d5be2a1..ce10feb15 100644
--- a/docs/concepts/logging.mdx
+++ b/docs/concepts/logging.mdx
@@ -3,11 +3,11 @@ title: Logging
icon: list-ul
---
-Workers provide a built-in way to log complex data to the console.
+Actors provide a built-in way to log complex data to the console.
When dealing with lots of data, `console.log` often doesn't cut it. Using the context's log object (`c.log`) allows you to log complex data using structured logging.
-Using the worker logging API is completely optional.
+Using the actor logging API is completely optional.
## Log levels
@@ -46,9 +46,9 @@ Consider this example:
```typescript structured_logging.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
@@ -64,9 +64,9 @@ const counter = worker({
```
```typescript unstructured_logging.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
@@ -92,13 +92,13 @@ Additionally, structured logs can be parsed and queried at scale using tools lik
The logger is available in all lifecycle hooks:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const loggingExample = worker({
+const loggingExample = actor({
state: { events: [] },
onStart: (c) => {
- c.log.info('worker_started', { timestamp: Date.now() });
+ c.log.info('actor_started', { timestamp: Date.now() });
},
onBeforeConnect: (c, { params }) => {
@@ -137,7 +137,7 @@ const loggingExample = worker({
},
actions: {
- // Worker actions...
+ // Actor actions...
}
});
```
diff --git a/docs/concepts/overview.mdx b/docs/concepts/overview.mdx
index b15637a1b..82101aefb 100644
--- a/docs/concepts/overview.mdx
+++ b/docs/concepts/overview.mdx
@@ -3,26 +3,26 @@ title: Introduction
icon: square-info
---
-import CreateWorkerCli from "/snippets/create-worker-cli.mdx";
+import CreateActorCli from "/snippets/create-actor-cli.mdx";
-Workers combine compute and storage into unified entities for simplified architecture. Workers seamlessly integrate with your existing infrastructure or can serve as a complete standalone solution.
+Actors combine compute and storage into unified entities for simplified architecture. Actors seamlessly integrate with your existing infrastructure or can serve as a complete standalone solution.
## Quickstart
Run this to get started:
-
+
## Code Example
-Here's a complete chat room worker that maintains state and handles messages. We'll explore each component in depth throughout this document:
+Here's a complete chat room actor that maintains state and handles messages. We'll explore each component in depth throughout this document:
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-// Define a chat room worker
-const chatRoom = worker({
- // Initialize state when the worker is first created
+// Define a chat room actor
+const chatRoom = actor({
+ // Initialize state when the actor is first created
createState: () => ({
messages: []
}),
@@ -50,7 +50,7 @@ export default chatRoom;
## Using the App
-To start using your worker, create an app and serve it:
+To start using your actor, create an app and serve it:
```typescript app.ts
import { setup, serve } from "rivetkit";
@@ -58,7 +58,7 @@ import chatRoom from "./chat_room";
// Create the application
const registry = setup({
- workers: { chatRoom }
+ actors: { chatRoom }
});
// Start serving on default port
@@ -68,17 +68,17 @@ serve(registry);
export type Registry = typeof registry;
```
-## Key Worker Components
+## Key Actor Components
### State
-Workers maintain state that's stored in memory and automatically persisted. State is defined either as a constant or via a `createState` function:
+Actors maintain state that's stored in memory and automatically persisted. State is defined either as a constant or via a `createState` function:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Method 1: State constant
-const counter1 = worker({
+const counter1 = actor({
state: { count: 0 },
actions: {
// ...
@@ -86,7 +86,7 @@ const counter1 = worker({
});
// Method 2: CreateState function
-const counter2 = worker({
+const counter2 = actor({
createState: () => ({ count: 0 }),
actions: {
// ...
@@ -97,9 +97,9 @@ const counter2 = worker({
Update state by modifying `c.state` in your actions:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
// Example of state update in an action
@@ -117,12 +117,12 @@ Learn more about [state management](/concepts/state).
### Actions
-Actions are functions defined in your worker configuration that clients & other workers can call:
+Actions are functions defined in your actor configuration that clients & other actors can call:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const mathUtils = worker({
+const mathUtils = actor({
state: {},
actions: {
multiplyByTwo: (c, x) => {
@@ -138,12 +138,12 @@ Learn more about [actions](/concepts/actions).
### Events
-Workers can broadcast events to connected clients:
+Actors can broadcast events to connected clients:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const inventory = worker({
+const inventory = actor({
createState: () => ({
items: []
}),
@@ -163,9 +163,9 @@ const inventory = worker({
You can also send events to specific clients:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const messageService = worker({
+const messageService = actor({
state: {},
actions: {
sendPrivateMessage: (c, userId, text) => {
@@ -181,12 +181,12 @@ const messageService = worker({
Learn more about [events](/concepts/events).
-## Worker Tags
+## Actor Tags
-Tags are key-value pairs attached to workers that serve two purposes:
+Tags are key-value pairs attached to actors that serve two purposes:
-1. **Worker Discovery**: Find specific workers using `client.get(tags)`
-2. **Organization**: Group related workers for management purposes
+1. **Actor Discovery**: Find specific actors using `client.get(tags)`
+2. **Organization**: Group related actors for management purposes
For example, you can query chat rooms by tag like:
@@ -215,16 +215,16 @@ const document = await client.document.get({
});
```
-## Worker Lifecycle
+## Actor Lifecycle
-Workers are created automatically when needed and persist until explicitly shutdown.
+Actors are created automatically when needed and persist until explicitly shutdown.
-To shut down a worker, use `c.shutdown()` from within an action:
+To shut down a actor, use `c.shutdown()` from within an action:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
createState: () => ({
messages: []
}),
@@ -233,26 +233,26 @@ const chatRoom = worker({
// Do any cleanup needed
c.broadcast("roomClosed");
- // Shutdown the worker
+ // Shutdown the actor
c.shutdown();
}
}
});
```
-Learn more about the [worker lifecycle](/concepts/lifecycle).
+Learn more about the [actor lifecycle](/concepts/lifecycle).
## Next Steps
-
- Learn how to connect to workers from clients
+
+ Learn how to connect to actors from clients
- Deep dive into worker state management
+ Deep dive into actor state management
- Learn more about worker actions
+ Learn more about actor actions
Learn more about realtime events
diff --git a/docs/concepts/scaling.mdx b/docs/concepts/scaling.mdx
index 13c890c07..9922803d1 100644
--- a/docs/concepts/scaling.mdx
+++ b/docs/concepts/scaling.mdx
@@ -3,49 +3,49 @@ title: Scaling & Concurrency
icon: maximize
---
-This document covers how workers are able to scale better than traditional applications & provides tips on architecting your workers.
+This document covers how actors are able to scale better than traditional applications & provides tips on architecting your actors.
-## How workers scale
+## How actors scale
-Workers scale by design through these key properties:
+Actors scale by design through these key properties:
| Property | Description |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| **Independent State** | Each worker manages its own private data separately from other workers, so they never conflict with each other when running at the same time (i.e. using locking mechanisms). |
-| **Action- & Event-Based Communication** | Workers communicate through asynchronous [actions](/concepts/actions) or [events](/concepts/events), making it easy to distribute them across different machines. |
-| **Location Transparency** | Unlike traditional servers, workers don't need to know which machine other workers are running on in order to communicate with each other. They can run on the same machine, across a network, and across the world. Workers handle the network routing for you under the hood. |
-| **Horizontal Scaling** | Workers distribute workload by splitting responsibilities into small, focused units. Since each worker handles a limited scope (like a single user, document, or chat room), the system automatically spreads load across many independent workers rather than concentrating it in a single place. |
+| **Independent State** | Each actor manages its own private data separately from other actors, so they never conflict with each other when running at the same time (i.e. using locking mechanisms). |
+| **Action- & Event-Based Communication** | Actors communicate through asynchronous [actions](/concepts/actions) or [events](/concepts/events), making it easy to distribute them across different machines. |
+| **Location Transparency** | Unlike traditional servers, actors don't need to know which machine other actors are running on in order to communicate with each other. They can run on the same machine, across a network, and across the world. Actors handle the network routing for you under the hood. |
+| **Horizontal Scaling** | Actors distribute workload by splitting responsibilities into small, focused units. Since each actor handles a limited scope (like a single user, document, or chat room), the system automatically spreads load across many independent actors rather than concentrating it in a single place. |
-## Tips for architecting workers for scale
+## Tips for architecting actors for scale
-Here are key principles for architecting your worker system:
+Here are key principles for architecting your actor system:
**Single Responsibility**
-- Each worker should represent one specific entity or concept from your application (e.g., `User`, `Document`, `ChatRoom`).
-- This makes your system scale better, since workers have small scopes and do not conflict with each other.
+- Each actor should represent one specific entity or concept from your application (e.g., `User`, `Document`, `ChatRoom`).
+- This makes your system scale better, since actors have small scopes and do not conflict with each other.
**State Management**
-- Each worker owns and manages only its own state
-- Use [actions](/concepts/actions) to request data from other workers
-- Keep state minimal and relevant to the worker's core responsibility
+- Each actor owns and manages only its own state
+- Use [actions](/concepts/actions) to request data from other actors
+- Keep state minimal and relevant to the actor's core responsibility
**Granularity Guidelines**
-- Too coarse: Workers handling too many responsibilities become bottlenecks
-- Too fine: Excessive workers create unnecessary communication overhead
-- Aim for workers that can operate independently with minimal cross-worker communication
+- Too coarse: Actors handling too many responsibilities become bottlenecks
+- Too fine: Excessive actors create unnecessary communication overhead
+- Aim for actors that can operate independently with minimal cross-actor communication
### Examples
-**Good worker boundaries**
+**Good actor boundaries**
- `User`: Manages user profile, preferences, and authentication
- `Document`: Handles document content, metadata, and versioning
- `ChatRoom`: Manages participants and message history
-**Poor worker boundaries**
+**Poor actor boundaries**
- `Application`: Too broad, handles everything
-- `DocumentWordCount`: Too granular, should be part of DocumentWorker
+- `DocumentWordCount`: Too granular, should be part of DocumentActor
diff --git a/docs/concepts/testing.mdx b/docs/concepts/testing.mdx
index 7b0a37ee5..9b8730952 100644
--- a/docs/concepts/testing.mdx
+++ b/docs/concepts/testing.mdx
@@ -3,7 +3,7 @@ title: Testing
icon: vial-circle-check
---
-RivetKit provides a straightforward testing framework to build reliable and maintainable applications. This guide covers how to write effective tests for your worker-based services.
+RivetKit provides a straightforward testing framework to build reliable and maintainable applications. This guide covers how to write effective tests for your actor-based services.
## Setup
@@ -19,33 +19,33 @@ npm test
## Basic Testing Setup
-RivetKit includes a test helper called `setupTest` that configures a test environment with in-memory drivers for your workers. This allows for fast, isolated tests without external dependencies.
+RivetKit includes a test helper called `setupTest` that configures a test environment with in-memory drivers for your actors. This allows for fast, isolated tests without external dependencies.
-```ts tests/my-worker.test.ts
+```ts tests/my-actor.test.ts
import { test, expect } from "vitest";
import { setupTest } from "rivetkit/test";
import { app } from "../src/index";
-test("my worker test", async (test) => {
+test("my actor test", async (test) => {
const { client } = await setupTest(test, app);
- // Now you can interact with your worker through the client
- const myWorker = await client.myWorker.get();
+ // Now you can interact with your actor through the client
+ const myActor = await client.myActor.get();
- // Test your worker's functionality
- await myWorker.someAction();
+ // Test your actor's functionality
+ await myActor.someAction();
// Make assertions
- const result = await myWorker.getState();
+ const result = await myActor.getState();
expect(result).toEqual("updated");
});
```
```ts src/index.ts
-import { worker, setup } from "rivetkit";
+import { actor, setup } from "rivetkit";
-const myWorker = worker({
+const myActor = actor({
state: { value: "initial" },
actions: {
someAction: (c) => {
@@ -59,16 +59,16 @@ const myWorker = worker({
});
export const registry = setup({
- workers: { myWorker }
+ actors: { myActor }
});
export type Registry = typeof registry;
```
-## Testing Worker State
+## Testing Actor State
-The test framework uses in-memory drivers that persist state within each test, allowing you to verify that your worker correctly maintains state between operations.
+The test framework uses in-memory drivers that persist state within each test, allowing you to verify that your actor correctly maintains state between operations.
```ts tests/counter.test.ts
@@ -76,7 +76,7 @@ import { test, expect } from "vitest";
import { setupTest } from "rivetkit/test";
import { app } from "../src/index";
-test("worker should persist state", async (test) => {
+test("actor should persist state", async (test) => {
const { client } = await setupTest(test, app);
const counter = await client.counter.get();
@@ -94,7 +94,7 @@ test("worker should persist state", async (test) => {
```ts src/index.ts
import { setup } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c) => {
@@ -109,7 +109,7 @@ const counter = worker({
});
export const registry = setup({
- workers: { counter }
+ actors: { counter }
});
export type Registry = typeof registry;
@@ -118,7 +118,7 @@ export type Registry = typeof registry;
## Testing Events
-For workers that emit events, you can verify events are correctly triggered by subscribing to them:
+For actors that emit events, you can verify events are correctly triggered by subscribing to them:
```ts tests/chat-room.test.ts
@@ -126,7 +126,7 @@ import { test, expect, vi } from "vitest";
import { setupTest } from "rivetkit/test";
import { app } from "../src/index";
-test("worker should emit events", async (test) => {
+test("actor should emit events", async (test) => {
const { client } = await setupTest(test, app);
const chatRoom = await client.chatRoom.get();
@@ -145,9 +145,9 @@ test("worker should emit events", async (test) => {
```
```ts src/index.ts
-import { worker, setup } from "rivetkit";
+import { actor, setup } from "rivetkit";
-export const chatRoom = worker({
+export const chatRoom = actor({
state: {
messages: []
},
@@ -164,7 +164,7 @@ export const chatRoom = worker({
// Create and export the app
export const registry = setup({
- workers: { chatRoom }
+ actors: { chatRoom }
});
// Export type for client type checking
@@ -199,9 +199,9 @@ test("scheduled tasks should execute", async (test) => {
```
```ts src/index.ts
-import { worker, setup } from "rivetkit";
+import { actor, setup } from "rivetkit";
-const scheduler = worker({
+const scheduler = actor({
state: {
tasks: [],
completedTasks: []
@@ -225,7 +225,7 @@ const scheduler = worker({
});
export const registry = setup({
- workers: { scheduler }
+ actors: { scheduler }
});
export type Registry = typeof registry;
@@ -237,7 +237,7 @@ The `setupTest` function automatically calls `vi.useFakeTimers()`, allowing you
## Best Practices
1. **Isolate tests**: Each test should run independently, avoiding shared state.
-2. **Test edge cases**: Verify how your worker handles invalid inputs, concurrent operations, and error conditions.
+2. **Test edge cases**: Verify how your actor handles invalid inputs, concurrent operations, and error conditions.
3. **Mock time**: Use Vitest's timer mocks for testing scheduled operations.
4. **Use realistic data**: Test with data that resembles production scenarios.
diff --git a/docs/concepts/topology.mdx b/docs/concepts/topology.mdx
index 855c2e1a5..95ce856b7 100644
--- a/docs/concepts/topology.mdx
+++ b/docs/concepts/topology.mdx
@@ -3,7 +3,7 @@ title: Topologies
icon: list-tree
---
-RivetKit supports three topologies that define how workers are distributed and scale.
+RivetKit supports three topologies that define how actors are distributed and scale.
Each platform configures a default topology appropriate for that environment. In most cases, you can rely on these defaults unless you have specific distribution needs.
@@ -21,21 +21,21 @@ const config = {
### Standalone
-- **How it works**: Runs all workers in a single process
+- **How it works**: Runs all actors in a single process
- **When to use**: Development, testing, simple apps with low traffic
- **Limitations**: No horizontal scaling, single point of failure
- **Default on**: Node.js, Bun
### Partition
-- **How it works**: Each worker has its own isolated process. Clients connect directly to the worker for optimal performance.
+- **How it works**: Each actor has its own isolated process. Clients connect directly to the actor for optimal performance.
- **When to use**: Production environments needing horizontal scaling
- **Limitations**: Minimal - balanced performance and availability for most use cases
- **Default on**: Rivet, Cloudflare Workers
### Coordinate
-- **How it works**: Creates a peer-to-peer network between multiple servers with leader election with multiple workers running on each server. Clients connect to any server and data is transmitted to the leader over a pubsub server.
+- **How it works**: Creates a peer-to-peer network between multiple servers with leader election with multiple actors running on each server. Clients connect to any server and data is transmitted to the leader over a pubsub server.
- **When to use**: High-availability scenarios needing redundancy and failover
- **Limitations**: Added complexity, performance overhead, requires external data source
- **Default on**: _None_
diff --git a/docs/docs.json b/docs/docs.json
index c4bb8e139..362ac3e6d 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -46,33 +46,33 @@
]
},
{
- "group": "Workers",
+ "group": "Actors",
"pages": [
-"workers/overview",
+"actors/overview",
{
"group": "Quickstart",
"icon": "forward",
"pages": [
-"workers/quickstart",
-"workers/quickstart-frontend"
+"actors/quickstart",
+"actors/quickstart-frontend"
]
},
-"workers/state",
-"workers/actions",
-"workers/events",
+"actors/state",
+"actors/actions",
+"actors/events",
{
"group": "More",
"pages": [
-"workers/schedule",
+"actors/schedule",
-"workers/lifecycle",
-"workers/connections",
-"workers/authentication",
+"actors/lifecycle",
+"actors/connections",
+"actors/authentication",
{
"group": "Advanced",
"pages": [
-"workers/metadata",
-"workers/types"
+"actors/metadata",
+"actors/types"
]
}
@@ -137,7 +137,7 @@
"pages": [
"concepts/cors",
"concepts/external-sql",
- "concepts/interacting-with-workers",
+ "concepts/interacting-with-actors",
"concepts/logging",
"concepts/overview",
"concepts/scaling",
diff --git a/docs/drivers/build.mdx b/docs/drivers/build.mdx
index 2892f7217..5f325217f 100644
--- a/docs/drivers/build.mdx
+++ b/docs/drivers/build.mdx
@@ -4,17 +4,17 @@ title: Building Drivers
Each driver implements common interfaces defined by RivetKit, including:
-- **WorkerDriver**: Manages worker state, lifecycle, and persistence
-- **ManagerDriver**: Handles worker discovery, routing, and scaling
-- **CoordinateDriver**: Facilitates peer-to-peer communication between worker instances (only relevant for the coordinated topology)
+- **ActorDriver**: Manages actor state, lifecycle, and persistence
+- **ManagerDriver**: Handles actor discovery, routing, and scaling
+- **CoordinateDriver**: Facilitates peer-to-peer communication between actor instances (only relevant for the coordinated topology)
## Source Code Locations
Get started by looking at source code for the driver interfaces and existing drivers:
- **Driver Interfaces**
- - **WorkerDriver*** `packages/rivetkit/src/worker/runtime/driver.ts`
- - **ManagerDriver*** `packages/rivetkit/src/worker/runtime/driver.ts`
+ - **ActorDriver*** `packages/rivetkit/src/actor/runtime/driver.ts`
+ - **ManagerDriver*** `packages/rivetkit/src/actor/runtime/driver.ts`
- **CoordinateDriver**: `packages/rivetkit/src/topologies/coordinate/driver.ts`
- **Driver Implementations**
- **Memory driver**: `packages/drivers/memory/`
diff --git a/docs/drivers/cloudflare-workers.mdx b/docs/drivers/cloudflare-workers.mdx
index dd69b49d2..c1e522fd8 100644
--- a/docs/drivers/cloudflare-workers.mdx
+++ b/docs/drivers/cloudflare-workers.mdx
@@ -5,7 +5,7 @@ sidebarTitle: Durable Objects
import DriverNote from '/snippets/driver-note.mdx';
-The Cloudflare Workers Driver is an implementation that uses Cloudflare's Durable Objects for worker state persistence and coordination. It leverages Cloudflare's global network for low-latency, distributed worker systems that can scale automatically.
+The Cloudflare Workers Driver is an implementation that uses Cloudflare's Durable Objects for actor state persistence and coordination. It leverages Cloudflare's global network for low-latency, distributed actor systems that can scale automatically.
diff --git a/docs/drivers/file-system.mdx b/docs/drivers/file-system.mdx
index d2e35b4a9..cd2143994 100644
--- a/docs/drivers/file-system.mdx
+++ b/docs/drivers/file-system.mdx
@@ -4,7 +4,7 @@ title: File System
import DriverNote from '/snippets/driver-note.mdx';
-The File System Driver is a simple file-based implementation designed for development and testing environments. It stores all worker state in local files, providing persistence between application restarts.
+The File System Driver is a simple file-based implementation designed for development and testing environments. It stores all actor state in local files, providing persistence between application restarts.
@@ -56,14 +56,14 @@ The File System Driver is a simple file-based implementation designed for develo
```typescript src/index.ts
import { serve } from "@rivetkit/nodejs"
- import { FileSystemManagerDriver, FileSystemWorkerDriver, FileSystemGlobalState } from "@rivetkit/file-system";
+ import { FileSystemManagerDriver, FileSystemActorDriver, FileSystemGlobalState } from "@rivetkit/file-system";
const fsState = new FileSystemGlobalState();
serve(app, {
topology: "standalone",
drivers: {
manager: new FileSystemManagerDriver(app, fsState),
- worker: new FileSystemWorkerDriver(fsState),
+ actor: new FileSystemActorDriver(fsState),
},
});
```
@@ -101,7 +101,7 @@ The File System Driver is a simple file-based implementation designed for develo
The File System driver provides several benefits for development:
-- **Persistence**: Worker state is stored in files and persists between application restarts
+- **Persistence**: Actor state is stored in files and persists between application restarts
- **Durability**: Data is written to disk, providing protection against process crashes
- **Visibility**: State files can be inspected for debugging purposes
- **No External Dependencies**: Doesn't require additional services like Redis
diff --git a/docs/drivers/memory.mdx b/docs/drivers/memory.mdx
index e6ec08583..7d15b7a80 100644
--- a/docs/drivers/memory.mdx
+++ b/docs/drivers/memory.mdx
@@ -4,7 +4,7 @@ title: Memory
import DriverNote from '/snippets/driver-note.mdx';
-The Memory Driver is a simple in-memory implementation designed for development and testing environments. It stores all worker state in memory, which means data is not persisted between application restarts.
+The Memory Driver is a simple in-memory implementation designed for development and testing environments. It stores all actor state in memory, which means data is not persisted between application restarts.
@@ -56,14 +56,14 @@ The Memory Driver is a simple in-memory implementation designed for development
```typescript src/index.ts
import { serve } from "@rivetkit/nodejs"
- import { MemoryManagerDriver, MemoryWorkerDriver, MemoryGlobalState } from "@rivetkit/memory";
+ import { MemoryManagerDriver, MemoryActorDriver, MemoryGlobalState } from "@rivetkit/memory";
const memoryState = new MemoryGlobalState();
serve(app, {
topology: "standalone",
drivers: {
manager: new MemoryManagerDriver(app, memoryState),
- worker: new MemoryWorkerDriver(memoryState),
+ actor: new MemoryActorDriver(memoryState),
},
});
```
@@ -104,7 +104,7 @@ The Memory driver has several limitations to be aware of:
- **No Persistence**: All data is stored in memory and lost when the application restarts
- **Single Process**: Only works within a single process - not suitable for distributed environments
- **Scalability**: Cannot scale beyond a single instance
-- **Coordination**: Limited support for coordinated topology, as workers can only communicate within the same process
+- **Coordination**: Limited support for coordinated topology, as actors can only communicate within the same process
For production environments or applications requiring persistence and distributed capabilities, consider using the [Rivet](/platforms/rivet) or [Cloudflare Workers](/platforms/cloudflare-workers) instead.
diff --git a/docs/drivers/overview.mdx b/docs/drivers/overview.mdx
index 2dc7e29da..622da8e42 100644
--- a/docs/drivers/overview.mdx
+++ b/docs/drivers/overview.mdx
@@ -5,7 +5,7 @@ sidebarTitle: Overview
import DriverNote from '/snippets/driver-note.mdx';
-Drivers in RivetKit the infrastructure layer between your worker code and the underlying systems.
+Drivers in RivetKit the infrastructure layer between your actor code and the underlying systems.
@@ -19,7 +19,7 @@ Choose a driver based on your deployment needs - [Memory](/drivers/memory) for d
- Local file system driver for development and testing with persistent storage. Stores worker state in files for durability between restarts.
+ Local file system driver for development and testing with persistent storage. Stores actor state in files for durability between restarts.
In-memory driver for development and testing. Simple and lightweight with no external dependencies.
diff --git a/docs/drivers/redis.mdx b/docs/drivers/redis.mdx
index 648ef0c19..9d191d95b 100644
--- a/docs/drivers/redis.mdx
+++ b/docs/drivers/redis.mdx
@@ -4,7 +4,7 @@ title: Redis
import DriverNote from '/snippets/driver-note.mdx';
-The Redis Driver is a production-ready implementation that uses Redis for worker state persistence, coordination, and communication. It supports distributed worker systems and enables horizontal scaling across multiple instances.
+The Redis Driver is a production-ready implementation that uses Redis for actor state persistence, coordination, and communication. It supports distributed actor systems and enables horizontal scaling across multiple instances.
@@ -57,7 +57,7 @@ The Redis Driver is a production-ready implementation that uses Redis for worker
```typescript src/index.ts
import { serve } from "@rivetkit/nodejs"
import { RedisManagerDriver } from "@rivetkit/redis/manager";
- import { RedisWorkerDriver } from "@rivetkit/redis/worker";
+ import { RedisActorDriver } from "@rivetkit/redis/actor";
import { RedisCoordinateDriver } from "@rivetkit/redis/coordinate";
import Redis from "ioredis";
@@ -68,7 +68,7 @@ The Redis Driver is a production-ready implementation that uses Redis for worker
topology: "coordinate", // Can be "standalone" or "coordinate"
drivers: {
manager: new RedisManagerDriver(redis),
- worker: new RedisWorkerDriver(redis),
+ actor: new RedisActorDriver(redis),
coordinate: new RedisCoordinateDriver(redis),
},
});
@@ -110,7 +110,7 @@ The Redis driver requires an [ioredis](https://github.com/redis/ioredis) connect
```typescript
import Redis from "ioredis";
import { RedisManagerDriver } from "@rivetkit/redis/manager";
-import { RedisWorkerDriver } from "@rivetkit/redis/worker";
+import { RedisActorDriver } from "@rivetkit/redis/actor";
import { RedisCoordinateDriver } from "@rivetkit/redis/coordinate";
// Create a Redis connection
@@ -122,7 +122,7 @@ const redis = new Redis({
// Create the Redis drivers
const managerDriver = new RedisManagerDriver(redis);
-const workerDriver = new RedisWorkerDriver(redis);
+const actorDriver = new RedisActorDriver(redis);
const coordinateDriver = new RedisCoordinateDriver(redis);
```
diff --git a/docs/drivers/rivet.mdx b/docs/drivers/rivet.mdx
index 862cf1f09..84542ff77 100644
--- a/docs/drivers/rivet.mdx
+++ b/docs/drivers/rivet.mdx
@@ -4,7 +4,7 @@ title: Rivet
import DriverNote from '/snippets/driver-note.mdx';
-The Rivet Driver is a production-ready implementation that uses Rivet's managed infrastructure for worker state persistence, coordination, and communication. It provides a fully managed environment for RivetKit with built-in scaling, monitoring, and global distribution.
+The Rivet Driver is a production-ready implementation that uses Rivet's managed infrastructure for actor state persistence, coordination, and communication. It provides a fully managed environment for RivetKit with built-in scaling, monitoring, and global distribution.
@@ -28,7 +28,7 @@ See the [Rivet Platform](/platforms/rivet) documentation for complete setup inst
The Rivet driver offers several advantages:
- **Fully Managed**: No infrastructure to provision or maintain
-- **Global Distribution**: Deploy workers globally with automatic region selection
+- **Global Distribution**: Deploy actors globally with automatic region selection
- **Monitoring**: Built-in observability and performance metrics
- **Cost Efficiency**: Pay only for what you use with no upfront costs
- **Partition Topology Support**: Optimized for the Partition topology for efficient scaling
diff --git a/docs/frameworks/react.mdx b/docs/frameworks/react.mdx
index 8e21b0d6a..dbb148ec9 100644
--- a/docs/frameworks/react.mdx
+++ b/docs/frameworks/react.mdx
@@ -4,12 +4,12 @@ icon: react
---
import MvpWarning from "/snippets/mvp-warning.mdx";
-import StepDefineWorker from "/snippets/step-define-worker.mdx";
+import StepDefineActor from "/snippets/step-define-actor.mdx";
import StepRunStudio from "/snippets/step-run-studio.mdx";
import StepDeploy from "/snippets/step-deploy.mdx";
import SetupNextSteps from "/snippets/setup-next-steps.mdx";
-Learn how to create realtime, stateful React applications with RivetKit's worker model.
+Learn how to create realtime, stateful React applications with RivetKit's actor model.
@@ -64,7 +64,7 @@ Learn how to create realtime, stateful React applications with RivetKit's worker
-
+
Now modify your `src/App.tsx` file to connect to your RivetKit backend:
@@ -72,20 +72,20 @@ Learn how to create realtime, stateful React applications with RivetKit's worker
```tsx src/App.tsx
import { createClient } from "rivetkit/client";
import { createReactRivetKit } from "@rivetkit/react";
- import type { App } from "../workers/app";
+ import type { App } from "../actors/app";
import React, { useState } from "react";
// Replace with your endpoint URL after deployment
const client = createClient("http://localhost:6420");
- const { useWorker, useWorkerEvent } = createReactRivetKit(client);
+ const { useActor, useActorEvent } = createReactRivetKit(client);
function App() {
- // Connect to counter worker
- const [{ worker }] = useWorker("counter");
+ // Connect to counter actor
+ const [{ actor }] = useActor("counter");
const [count, setCount] = useState(0);
// Listen to count updates
- useWorkerEvent({ worker, event: "newCount" }, (newCount) => {
+ useActorEvent({ actor, event: "newCount" }, (newCount) => {
setCount(newCount);
});
@@ -93,8 +93,8 @@ Learn how to create realtime, stateful React applications with RivetKit's worker
Count: {count}
@@ -150,7 +150,7 @@ The React integration leverages React's hooks system to provide an idiomatic way
The main function that creates React hooks for interacting with RivetKit. It takes a client instance and returns hook functions.
```tsx
-const { useWorker, useWorkerEvent } = createReactRivetKit(client);
+const { useActor, useActorEvent } = createReactRivetKit(client);
```
#### Parameters
@@ -160,46 +160,46 @@ const { useWorker, useWorkerEvent } = createReactRivetKit(client);
#### Returns
An object containing React hooks:
-- `useWorker`: Hook for connecting to workers
-- `useWorkerEvent`: Hook for subscribing to worker events
+- `useActor`: Hook for connecting to actors
+- `useActorEvent`: Hook for subscribing to actor events
-### `useWorker`
+### `useActor`
-Hook that connects to a worker, creating it if necessary. It manages the worker connection and returns the worker handle.
+Hook that connects to a actor, creating it if necessary. It manages the actor connection and returns the actor handle.
```tsx
-const [{ worker, error, isLoading, state }] = useWorker(workerName, options);
+const [{ actor, error, isLoading, state }] = useActor(actorName, options);
```
#### Parameters
-- `workerName`: The name of the worker to connect to (string).
-- `options`: Optional connection options (same options as `client.workerName.get()`).
- - `id`: String identifier for the worker instance.
- - `tags`: Key-value pairs for worker identification.
+- `actorName`: The name of the actor to connect to (string).
+- `options`: Optional connection options (same options as `client.actorName.get()`).
+ - `id`: String identifier for the actor instance.
+ - `tags`: Key-value pairs for actor identification.
- `params`: Parameters to pass during connection.
- - `noCreate`: Boolean to prevent worker creation if it doesn't exist.
+ - `noCreate`: Boolean to prevent actor creation if it doesn't exist.
#### Returns
Returns an array with a single object containing:
-- `worker`: The worker handle if connected, or `undefined` if still connecting.
+- `actor`: The actor handle if connected, or `undefined` if still connecting.
- `error`: Any error that occurred during connection.
- `isLoading`: Boolean indicating if the connection is in progress.
- `state`: String representing the internal connection state ("init", "creating", "created", or "error").
-### `useWorkerEvent`
+### `useActorEvent`
-Hook that subscribes to events from a worker.
+Hook that subscribes to events from a actor.
```tsx
-useWorkerEvent({ worker, event }, cb);
+useActorEvent({ actor, event }, cb);
```
#### Parameters
- `opts`: Object containing:
- - `worker`: The worker handle from `useWorker`, or undefined.
+ - `actor`: The actor handle from `useActor`, or undefined.
- `event`: The name of the event to subscribe to.
- `cb`: Function called when the event is fired. The arguments passed to this function depend on the event type.
@@ -214,25 +214,25 @@ This hook doesn't return a value. The subscription is automatically managed by t
```tsx
import { createClient } from "rivetkit/client";
import { createReactRivetKit } from "@rivetkit/react";
-import type { App } from "../workers/app";
+import type { App } from "../actors/app";
import { useState } from "react";
// Connect to RivetKit
const client = createClient("http://localhost:6420");
-const { useWorker, useWorkerEvent } = createReactRivetKit(client);
+const { useActor, useActorEvent } = createReactRivetKit(client);
function Counter() {
- // Get worker and track count
- const [{ worker }] = useWorker("counter");
+ // Get actor and track count
+ const [{ actor }] = useActor("counter");
const [count, setCount] = useState(0);
// Listen for count updates
- useWorkerEvent({ worker, event: "newCount" }, setCount);
+ useActorEvent({ actor, event: "newCount" }, setCount);
return (
Count: {count}
-
diff --git a/docs/integrations/better-auth.mdx b/docs/integrations/better-auth.mdx
index c9711fedc..716cbdacf 100644
--- a/docs/integrations/better-auth.mdx
+++ b/docs/integrations/better-auth.mdx
@@ -66,10 +66,10 @@ _If you want to run without export fetch (i.e. standalone Node.js), see below._
-```ts Worker
-import { worker, setup } from "@rivetkit/worker";
+```ts Actor
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => { ... },
state: { count: 0 },
actions: {
@@ -81,7 +81,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
```
@@ -199,7 +199,7 @@ const { client, hono } = registry.run({
## Configuration Options
-### Connect your frontend to the Rivet Worker
+### Connect your frontend to the Rivet Actor
TODO: Quick summary of why you would want to connect your frontend
@@ -208,27 +208,27 @@ Connect your frontend:
```ts JavaScript
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import type { registry } from "./registry.js";
const client = createClient("http://localhost:8080/registry");
-const result = await client.myWorker.getOrCreate().myAction("Hello, world!");
+const result = await client.myActor.getOrCreate().myAction("Hello, world!");
```
```ts React
import { useState } from "react";
-import { createClient, createRivetKit } from "@@rivetkit/worker/react";
+import { createClient, createRivetKit } from "@@rivetkit/actor/react";
import type { registry } from "./registry";
const client = createClient(`http://localhost:8080/registry`);
-const { useWorker } = createRivetKit(client);
+const { useActor } = createRivetKit(client);
function App() {
const [count, setCount] = useState(0);
const [counterName, setCounterName] = useState("test-counter");
- const counter = useWorker({
+ const counter = useActor({
name: "counter",
key: [counterName],
});
@@ -296,7 +296,7 @@ TODO
-
+
diff --git a/docs/integrations/hono.mdx b/docs/integrations/hono.mdx
index 9993b4179..543c91904 100644
--- a/docs/integrations/hono.mdx
+++ b/docs/integrations/hono.mdx
@@ -11,19 +11,19 @@ When mounting the RivetKit router at a custom path, you **must** specify the sam
```typescript
// Setup the RivetKit app
const registry = setup({
- workers: { counter },
+ actors: { counter },
// IMPORTANT: Must specify the same basePath where your router is mounted
basePath: "/my-path"
});
// Create a router from the app
-const { router: workerRouter } = createRouter(app);
+const { router: actorRouter } = createRouter(app);
// Mount at the same path specified in basePath
-honoApp.route("/my-path", workerRouter);
+honoApp.route("/my-path", actorRouter);
```
-This ensures that WebSocket connections and other functionality work correctly when accessing your workers through the custom path.
+This ensures that WebSocket connections and other functionality work correctly when accessing your actors through the custom path.
## Platform-Specific Examples
@@ -46,22 +46,22 @@ honoApp.get("/hello", (c) => c.text("Hello, world!"));
// Setup the RivetKit app
const registry = setup({
- workers: { counter },
+ actors: { counter },
// IMPORTANT: Must specify the same basePath where your router is mounted
basePath: "/my-path"
});
// Create a router and handler from the app
-const { router: workerRouter, WorkerHandler } = createRouter(app);
+const { router: actorRouter, ActorHandler } = createRouter(app);
// Mount the RivetKit router at /my-path
-honoApp.route("/my-path", workerRouter);
+honoApp.route("/my-path", actorRouter);
// Export the app type for client usage
export type Registry = typeof registry;
-// IMPORTANT: Must export `WorkerHandler` as this exact name
-export { honoApp as default, WorkerHandler };
+// IMPORTANT: Must export `ActorHandler` as this exact name
+export { honoApp as default, ActorHandler };
```
Make sure to update your client connection URL to include the custom path:
@@ -71,7 +71,7 @@ Make sure to update your client connection URL to include the custom path:
import { createClient } from "rivetkit/client";
import type { App } from "./src/index";
-const client = createClient("https://your-worker.workers.dev/my-path");
+const client = createClient("https://your-actor.actors.dev/my-path");
```
For this to work with Cloudflare Workers, your `wrangler.json` **must** include specific Durable Object and KV namespace bindings with the exact names expected by RivetKit:
@@ -83,21 +83,21 @@ For this to work with Cloudflare Workers, your `wrangler.json` **must** include
"compatibility_date": "2025-01-29",
"migrations": [
{
- "new_classes": ["WorkerHandler"],
+ "new_classes": ["ActorHandler"],
"tag": "v1"
}
],
"durable_objects": {
"bindings": [
{
- "class_name": "WorkerHandler", // Must match exported class
- "name": "WORKER_DO" // Must use this exact name
+ "class_name": "ActorHandler", // Must match exported class
+ "name": "ACTOR_DO" // Must use this exact name
}
]
},
"kv_namespaces": [
{
- "binding": "WORKER_KV", // Must use this exact name
+ "binding": "ACTOR_KV", // Must use this exact name
"id": "YOUR_KV_NAMESPACE_ID" // Replace with your KV ID
}
]
@@ -122,16 +122,16 @@ honoApp.get("/hello", (c) => c.text("Hello, world!"));
// Setup the RivetKit app
const registry = setup({
- workers: { counter },
+ actors: { counter },
// IMPORTANT: Must specify the same basePath where your router is mounted
basePath: "/my-path"
});
// Create a router from the app
-const { router: workerRouter, injectWebSocket } = createRouter(app);
+const { router: actorRouter, injectWebSocket } = createRouter(app);
// Mount the RivetKit router at /my-path
-honoApp.route("/my-path", workerRouter);
+honoApp.route("/my-path", actorRouter);
// Export the app type for client usage
export type Registry = typeof registry;
@@ -174,16 +174,16 @@ honoApp.get("/hello", (c) => c.text("Hello, world!"));
// Setup the RivetKit app
const registry = setup({
- workers: { counter },
+ actors: { counter },
// IMPORTANT: Must specify the same basePath where your router is mounted
basePath: "/my-path"
});
// Create a router from the app
-const { router: workerRouter, webSocketHandler } = createRouter(app);
+const { router: actorRouter, webSocketHandler } = createRouter(app);
// Mount the RivetKit router at /my-path
-honoApp.route("/my-path", workerRouter);
+honoApp.route("/my-path", actorRouter);
// Export the app type for client usage
export type Registry = typeof registry;
diff --git a/docs/integrations/resend.mdx b/docs/integrations/resend.mdx
index 33276da5e..404ea6d05 100644
--- a/docs/integrations/resend.mdx
+++ b/docs/integrations/resend.mdx
@@ -19,14 +19,14 @@ npm install resend
```
-
-```typescript workers.ts
-import { worker, setup } from "rivetkit";
+
+```typescript actors.ts
+import { actor, setup } from "rivetkit";
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
-const user = worker({
+const user = actor({
state: {
email: null as string | null,
},
@@ -51,21 +51,21 @@ const user = worker({
},
});
-export const registry = setup({ workers: { user } });
+export const registry = setup({ actors: { user } });
export type Registry = typeof registry;
```
-
+
```typescript client.ts
import { createClient } from "rivetkit";
-import { App } from "./workers/app.ts";
+import { App } from "./actors/app.ts";
const client = createClient("http://localhost:8787");
-const userWorker = await client.user.get({ tags: { user: "user123" } });
+const userActor = await client.user.get({ tags: { user: "user123" } });
-await userWorker.register("user@example.com");
-await userWorker.sendExampleEmail();
+await userActor.register("user@example.com");
+await userActor.sendExampleEmail();
```
@@ -77,8 +77,8 @@ await userWorker.sendExampleEmail();
RivetKit's scheduling capabilities with Resend make it easy to send emails at specific times:
-```typescript workers.ts
-const emailScheduler = worker({
+```typescript actors.ts
+const emailScheduler = actor({
state: {
email: null as string | null,
},
@@ -115,8 +115,8 @@ await scheduler.scheduleEmail("user@example.com", 60000); // 1 minute
Send daily reminders to users based on their activity:
-```typescript workers.ts
-const reminder = worker({
+```typescript actors.ts
+const reminder = actor({
state: {
email: null as string | null,
lastActive: null as number | null,
@@ -163,8 +163,8 @@ await userReminder.trackActivity("user@example.com");
Monitor your systems and send alerts when issues are detected:
-```typescript workers.ts
-const monitor = worker({
+```typescript actors.ts
+const monitor = actor({
state: {
alertEmail: null as string | null,
isHealthy: true,
@@ -212,12 +212,12 @@ await systemMonitor.configure("admin@example.com");
## Testing
-When testing workers that use Resend, you should mock the Resend API to avoid sending real emails during tests. RivetKit's testing utilities combined with Vitest make this straightforward:
+When testing actors that use Resend, you should mock the Resend API to avoid sending real emails during tests. RivetKit's testing utilities combined with Vitest make this straightforward:
```typescript
import { test, expect, vi, beforeEach } from "vitest";
import { setupTest } from "rivetkit/test";
-import { app } from "../workers/app";
+import { app } from "../actors/app";
// Create mock for send method
const mockSendEmail = vi.fn().mockResolvedValue({ success: true });
@@ -242,10 +242,10 @@ beforeEach(() => {
test("email is sent when action is called", async (t) => {
const { client } = await setupTest(t, app);
- const worker = await client.user.get();
+ const actor = await client.user.get();
// Call the action that should send an email
- await worker.someActionThatSendsEmail("user@example.com");
+ await actor.someActionThatSendsEmail("user@example.com");
// Verify the email was sent with the right parameters
expect(mockSendEmail).toHaveBeenCalledWith(
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
index 286ff6df4..7a251d3bc 100644
--- a/docs/introduction.mdx
+++ b/docs/introduction.mdx
@@ -31,7 +31,7 @@ import FAQ from "/snippets/landing-faq.mdx";
{/*
- How is RivetKit different than Rivet Workers?
+ How is RivetKit different than Rivet Actors?
@@ -21,11 +21,11 @@ import { Icon } from "@/components/Icon";
- How does stateful serverless compare to the traditional worker model?
+ How does stateful serverless compare to the traditional actor model?
-
Stateful serverless is very similar to workers: it's essentially workers with persistence, and usually doesn't have as rigid constraints on message handling. This makes it more flexible while maintaining the core benefits of the worker model.
+
Stateful serverless is very similar to actors: it's essentially actors with persistence, and usually doesn't have as rigid constraints on message handling. This makes it more flexible while maintaining the core benefits of the actor model.
@@ -78,7 +78,7 @@ import { Icon } from "@/components/Icon";
-
Yes, but only as much as storing data in a single database row does. We're working on building out read replicas to allow you to perform read-only actions on workers.
+
Yes, but only as much as storing data in a single database row does. We're working on building out read replicas to allow you to perform read-only actions on actors.
diff --git a/docs/snippets/landing-manifesto.mdx b/docs/snippets/landing-manifesto.mdx
index d8f185826..68ba9d51b 100644
--- a/docs/snippets/landing-manifesto.mdx
+++ b/docs/snippets/landing-manifesto.mdx
@@ -4,7 +4,7 @@
Stateful serverless is the future of how applications will be architected.
- Startups increasingly build on stateful serverless to ship faster, achieve better performance, and outscale databases like Postgres. The worker model – closely related to stateful serverless – has an established history in frameworks like Elixir, Orleans, and Akka, though these typically involve steep learning curves and complex infrastructure. Cloudflare demonstrates the power of this approach, having built their entire infrastructure – including R2, Workflows, and Queues – on their stateful serverless engine called Durable Objects.
+ Startups increasingly build on stateful serverless to ship faster, achieve better performance, and outscale databases like Postgres. The actor model – closely related to stateful serverless – has an established history in frameworks like Elixir, Orleans, and Akka, though these typically involve steep learning curves and complex infrastructure. Cloudflare demonstrates the power of this approach, having built their entire infrastructure – including R2, Workflows, and Queues – on their stateful serverless engine called Durable Objects.
With years of experience in gaming infrastructure, we've seen firsthand how the stateful serverless model excels. After building numerous systems like matchmaking, chat, presence, and social networks using stateful serverless, we're convinced it's hands down the best way to build applications. However, the ecosystem lacks accessibility and resources.
diff --git a/docs/snippets/landing-snippets.mdx b/docs/snippets/landing-snippets.mdx
index f3ce0b059..c8066535a 100644
--- a/docs/snippets/landing-snippets.mdx
+++ b/docs/snippets/landing-snippets.mdx
@@ -102,7 +102,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -126,7 +126,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -151,7 +151,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -175,7 +175,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -200,7 +200,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -224,7 +224,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -249,7 +249,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -273,7 +273,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -298,7 +298,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -322,7 +322,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -347,7 +347,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -371,7 +371,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -396,7 +396,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -420,7 +420,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -445,7 +445,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -469,7 +469,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -494,7 +494,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -518,7 +518,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -543,7 +543,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
@@ -567,7 +567,7 @@ import RateReact from "/snippets/examples/rate-react.mdx";
- worker.ts
+ actor.tsRuns on the server
diff --git a/docs/snippets/platform-extra-notes.mdx b/docs/snippets/platform-extra-notes.mdx
index 7b2938e54..b88267b20 100644
--- a/docs/snippets/platform-extra-notes.mdx
+++ b/docs/snippets/platform-extra-notes.mdx
@@ -2,7 +2,7 @@
For security reasons, you should configure proper CORS settings in production. In the example above, we used `cors: { origin: "*" }` which allows requests from any domain.
-For production deployments, specify the exact domains that should be allowed to connect to your workers. Learn more in the [CORS documentation](/concepts/cors).
+For production deployments, specify the exact domains that should be allowed to connect to your actors. Learn more in the [CORS documentation](/concepts/cors).
## Integration with Existing Projects
diff --git a/docs/snippets/setup-actor.mdx b/docs/snippets/setup-actor.mdx
index e78ba7863..616e0755b 100644
--- a/docs/snippets/setup-actor.mdx
+++ b/docs/snippets/setup-actor.mdx
@@ -1,8 +1,8 @@
```typescript src/app.ts
-import { worker, setup } from "rivetkit";
+import { actor, setup } from "rivetkit";
-// Create worker
-const counter = worker({
+// Create actor
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
@@ -15,7 +15,7 @@ const counter = worker({
// Create the application
export const registry = setup({
- workers: { counter },
+ actors: { counter },
cors: { origin: "http://localhost:8080" }
});
diff --git a/docs/snippets/setup-next-steps.mdx b/docs/snippets/setup-next-steps.mdx
index 1003f3cb7..03229781a 100644
--- a/docs/snippets/setup-next-steps.mdx
+++ b/docs/snippets/setup-next-steps.mdx
@@ -2,7 +2,7 @@
-
+
diff --git a/docs/snippets/step-define-actor.mdx b/docs/snippets/step-define-actor.mdx
index 4241d157d..150dd8012 100644
--- a/docs/snippets/step-define-actor.mdx
+++ b/docs/snippets/step-define-actor.mdx
@@ -1,11 +1,11 @@
-
- Create a file `workers/app.ts` in your project with your worker definition:
+
+ Create a file `actors/app.ts` in your project with your actor definition:
- ```typescript workers/app.ts
- import { worker, setup } from "rivetkit";
+ ```typescript actors/app.ts
+ import { actor, setup } from "rivetkit";
- // Create worker
- const counter = worker({
+ // Create actor
+ const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
@@ -18,7 +18,7 @@
// Create the application
export const registry = setup({
- workers: { counter },
+ actors: { counter },
cors: { origin: "*" } // Configure CORS for your production domains in production
});
diff --git a/docs/snippets/step-run-studio.mdx b/docs/snippets/step-run-studio.mdx
index c06fc690f..38efd0d78 100644
--- a/docs/snippets/step-run-studio.mdx
+++ b/docs/snippets/step-run-studio.mdx
@@ -3,19 +3,19 @@
```sh npm
- npx rivetkit/cli@latest dev workers/app.ts
+ npx rivetkit/cli@latest dev actors/app.ts
```
```sh pnpm
- pnpm exec rivetkit/cli@latest dev workers/app.ts
+ pnpm exec rivetkit/cli@latest dev actors/app.ts
```
```sh yarn
- yarn rivetkit/cli@latest dev workers/app.ts
+ yarn rivetkit/cli@latest dev actors/app.ts
```
```sh bun
- bunx rivetkit/cli@latest dev workers/app.ts
+ bunx rivetkit/cli@latest dev actors/app.ts
```
diff --git a/docs/snippets/step-update-client.mdx b/docs/snippets/step-update-client.mdx
index fb2e09db8..091c5463b 100644
--- a/docs/snippets/step-update-client.mdx
+++ b/docs/snippets/step-update-client.mdx
@@ -12,7 +12,7 @@
```
```python Python
- client = WorkerClient(
+ client = ActorClient(
# FILL ME IN
)
```
diff --git a/docs/styles/cta.js b/docs/styles/cta.js
index 6c4dbcd58..b6bf9f7a3 100644
--- a/docs/styles/cta.js
+++ b/docs/styles/cta.js
@@ -1,22 +1,22 @@
// CTA titles array
const CTA_TITLES = [
- "Performance in every act - thanks to Rivet Workers.",
- "Scale without drama - only with Rivet Workers.",
- "It's time your backend took center-stage - with Rivet Workers.",
- "SQLite the spotlight on performance - with Rivet Workers.",
- "Backend scalability: the SQL - starring Rivet Workers.",
- "Take your state to the edge - Rivet Workers makes it easy.",
- "No state fright - just scalability with Rivet Workers.",
- "Act now, deploy at the edge - with Rivet Workers.",
- "Lights, camera, serverless - powered by Rivet Workers.",
- "Your backend deserves a standing ovation - Rivet Workers delivers.",
- "Cue your backend's best performance - enter Rivet Workers.",
- "Backend performance worth applauding - only with Rivet Workers.",
- "Put your backend center-stage - with Rivet Workers.",
- "Make your backend the main worker - with Rivet Workers.",
- "Give your backend its big break - use Rivet Workers.",
- "Serverless, with no intermissions - powered by Rivet Workers.",
- "Set the stage for serverless success - with Rivet Workers."
+ "Performance in every act - thanks to Rivet Actors.",
+ "Scale without drama - only with Rivet Actors.",
+ "It's time your backend took center-stage - with Rivet Actors.",
+ "SQLite the spotlight on performance - with Rivet Actors.",
+ "Backend scalability: the SQL - starring Rivet Actors.",
+ "Take your state to the edge - Rivet Actors makes it easy.",
+ "No state fright - just scalability with Rivet Actors.",
+ "Act now, deploy at the edge - with Rivet Actors.",
+ "Lights, camera, serverless - powered by Rivet Actors.",
+ "Your backend deserves a standing ovation - Rivet Actors delivers.",
+ "Cue your backend's best performance - enter Rivet Actors.",
+ "Backend performance worth applauding - only with Rivet Actors.",
+ "Put your backend center-stage - with Rivet Actors.",
+ "Make your backend the main actor - with Rivet Actors.",
+ "Give your backend its big break - use Rivet Actors.",
+ "Serverless, with no intermissions - powered by Rivet Actors.",
+ "Set the stage for serverless success - with Rivet Actors."
];
function initializeAllCTAs() {
diff --git a/docs/styles/particles.js b/docs/styles/particles.js
index a0c1a9810..edf9a925b 100644
--- a/docs/styles/particles.js
+++ b/docs/styles/particles.js
@@ -190,7 +190,7 @@
// // Size and opacity
// this.size = Particle.PARTICLE_RADIUS * 2;
// this.opacity = 1;
-// this.opacityFworker = Math.random();
+// this.opacityFactor = Math.random();
// this.opacityBase = Math.min(0, Math.random() - 0.5);
// }
//
@@ -220,7 +220,7 @@
// // Fade out between 600px and 1200px from center
// const minDistance = 600;
// const maxDistance = 1200;
-// this.opacity = this.opacityBase + Math.max(0, Math.min(1, 1 - (distance - minDistance) / (maxDistance - minDistance))) * this.opacityFworker;
+// this.opacity = this.opacityBase + Math.max(0, Math.min(1, 1 - (distance - minDistance) / (maxDistance - minDistance))) * this.opacityFactor;
//
// // Calculate velocity magnitude directly - simpler and more accurate
// const velocityMagnitude = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
@@ -454,8 +454,8 @@
// // Normalize mouse velocity to 0-1 range
// const normalizedSpeed = Math.min(mouseSpeed / PARTICLE_CONFIG.MAX_VELOCITY, 1);
//
-// // Calculate base force fworker with smoother distance falloff
-// const forceFworker = Math.pow(1 - distance / FORCE_RADIUS, 1.5) *
+// // Calculate base force factor with smoother distance falloff
+// const forceFactor = Math.pow(1 - distance / FORCE_RADIUS, 1.5) *
// normalizedSpeed *
// PARTICLE_CONFIG.BASE_PUSH_FORCE *
// PARTICLE_CONFIG.MOVEMENT_FORCE_MULTIPLIER *
@@ -477,8 +477,8 @@
// const moveForce = mouseSpeed * PARTICLE_CONFIG.MOVEMENT_FORCE_RATIO;
//
// // More emphasis on movement direction, less on repulsion
-// const fx = (repelDirX * repelForce * 0.5 + mvx * moveForce) * forceFworker * movementInfluence;
-// const fy = (repelDirY * repelForce * 0.5 + mvy * moveForce) * forceFworker * movementInfluence;
+// const fx = (repelDirX * repelForce * 0.5 + mvx * moveForce) * forceFactor * movementInfluence;
+// const fy = (repelDirY * repelForce * 0.5 + mvy * moveForce) * forceFactor * movementInfluence;
//
// particle.applyForce(fx, fy);
// }
diff --git a/docs/workers/actions.mdx b/docs/workers/actions.mdx
index 04fd2c7b3..5c764b660 100644
--- a/docs/workers/actions.mdx
+++ b/docs/workers/actions.mdx
@@ -3,23 +3,23 @@ title: Actions
icon: bolt
---
-Actions are how clients & other workers communicate with workers. Actions are defined as functions in the worker configuration and can be called from clients.
+Actions are how clients & other actors communicate with actors. Actions are defined as functions in the actor configuration and can be called from clients.
**Performance**
Actions are very lightweight. They can be called hundreds of times per second to send realtime data to the
-worker.
+actor.
## Writing Actions
-Actions are defined in the `actions` object when creating a worker:
+Actions are defined in the `actions` object when creating a actor:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const mathUtils = worker({
+const mathUtils = actor({
state: {},
actions: {
// This is an action
@@ -37,14 +37,14 @@ Each action receives a context object (commonly named `c`) as its first paramete
You can define helper functions outside the actions object to keep your code organized. These functions cannot be called directly by clients:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Private helper function - not callable by clients
const calculateFee = (amount) => {
return amount * 0.05;
};
-const paymentProcessor = worker({
+const paymentProcessor = actor({
state: {
transactions: []
},
@@ -84,7 +84,7 @@ Calling actions from the client are async and require an `await`, even if the ac
### Type Safety
-The worker client includes type safety out of the box. When you use `createClient()`, TypeScript automatically infers action parameter and return types:
+The actor client includes type safety out of the box. When you use `createClient()`, TypeScript automatically infers action parameter and return types:
@@ -92,7 +92,7 @@ The worker client includes type safety out of the box. When you use `createClien
import { setup } from "rivetkit";
// Create simple counter
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c, count: number) => {
@@ -104,7 +104,7 @@ const counter = worker({
// Create and export the app
const registry = setup({
- workers: { counter }
+ actors: { counter }
});
export type Registry = typeof registry;
@@ -127,7 +127,7 @@ await counter.nonexistentMethod(123); // TypeScript error
## Error Handling
-Workers provide robust error handling out of the box for actions.
+Actors provide robust error handling out of the box for actions.
### User Errors
@@ -141,10 +141,10 @@ For example:
-```typescript worker.ts
-import { worker, UserError } from "rivetkit";
+```typescript actor.ts
+import { actor, UserError } from "rivetkit";
-const user = worker({
+const user = actor({
state: { users: [] },
actions: {
registerUser: (c, username) => {
@@ -167,7 +167,7 @@ const user = worker({
```typescript client.ts
try {
- await userWorker.registerUser("extremely_long_username_that_exceeds_limit");
+ await userActor.registerUser("extremely_long_username_that_exceeds_limit");
} catch (error) {
console.log("Message", error.message); // "Invalid username"
console.log("Code", error.code); // "invalid_username"
@@ -177,7 +177,7 @@ try {
-{/* Read the documentation for `UserError` [here](https://jsr.io/@rivet-gg/worker/doc/~/UserError). */}
+{/* Read the documentation for `UserError` [here](https://jsr.io/@rivet-gg/actor/doc/~/UserError). */}
### Internal Errors
@@ -190,7 +190,7 @@ Data schemas are not validated by default. For production applications, use a li
For example, to validate action parameters:
```typescript
-import { worker, UserError } from "rivetkit";
+import { actor, UserError } from "rivetkit";
import { z } from "zod";
// Define schema for action parameters
@@ -198,7 +198,7 @@ const IncrementSchema = z.object({
count: z.number().int().positive()
});
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c, params) => {
@@ -224,7 +224,7 @@ const counter = worker({
## Authentication
-By default, clients can call all actions on a worker without restriction. Make sure to implement authentication if needed. Documentation on authentication is available [here](/concepts/authentication).
+By default, clients can call all actions on a actor without restriction. Make sure to implement authentication if needed. Documentation on authentication is available [here](/concepts/authentication).
## Using `ActionContext` Type Externally
@@ -233,9 +233,9 @@ When writing complex logic for actions, you may want to extract parts of your im
RivetKit provides the `ActionContextOf` utility type for exactly this purpose:
```typescript
-import { worker, ActionContextOf } from "rivetkit";
+import { actor, ActionContextOf } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
diff --git a/docs/workers/authentication.mdx b/docs/workers/authentication.mdx
index 5481ddeff..83927b854 100644
--- a/docs/workers/authentication.mdx
+++ b/docs/workers/authentication.mdx
@@ -3,22 +3,22 @@ title: Authentication
icon: fingerprint
---
-Authentication can be handled through the `onBeforeConnect` or `createConnState` lifecycle hook, which acts as middleware before allowing clients to interact with your worker.
+Authentication can be handled through the `onBeforeConnect` or `createConnState` lifecycle hook, which acts as middleware before allowing clients to interact with your actor.
## Using `onBeforeConnect` or `createConnState`
-The `onBeforeConnect` and `createConnState` hook is called whenever a new client attempts to connect to your worker. It receives a context object that contains the client's connection parameters. `createConnState` should return an object that will become the connection state.
+The `onBeforeConnect` and `createConnState` hook is called whenever a new client attempts to connect to your actor. It receives a context object that contains the client's connection parameters. `createConnState` should return an object that will become the connection state.
Throwing an error in `onBeforeConnect` or `createConnState` will abort the connection.
Here's a basic example:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const exampleWorker = worker({
+const exampleActor = actor({
state: {
- // Worker state...
+ // Actor state...
},
createConnState: async (c, { params }) => {
@@ -36,7 +36,7 @@ const exampleWorker = worker({
},
actions: {
- // Worker actions...
+ // Actor actions...
}
});
```
@@ -46,11 +46,11 @@ const exampleWorker = worker({
After authentication, you can access the connection state in any action through the context object:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const authenticatedWorker = worker({
+const authenticatedActor = actor({
state: {
- // Worker state...
+ // Actor state...
},
createConnState: (c) => {
@@ -80,11 +80,11 @@ const authenticatedWorker = worker({
### With API Server Authentication
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const apiAuthenticatedWorker = worker({
+const apiAuthenticatedActor = actor({
state: {
- // Worker state...
+ // Actor state...
},
createConnState: async (c, { params }) => {
@@ -108,7 +108,7 @@ const apiAuthenticatedWorker = worker({
},
actions: {
- // Worker actions...
+ // Actor actions...
}
});
```
@@ -118,14 +118,14 @@ When authentication fails, throwing an error in `createConnState` will prevent t
### With JWT Authentication
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
import jwt from "jsonwebtoken";
const JWT_SECRET = process.env.JWT_SECRET;
-const jwtAuthenticatedWorker = worker({
+const jwtAuthenticatedActor = actor({
state: {
- // Worker state...
+ // Actor state...
},
createConnState: (c, { params }) => {
diff --git a/docs/workers/connections.mdx b/docs/workers/connections.mdx
index 17cfc539c..92cd30b84 100644
--- a/docs/workers/connections.mdx
+++ b/docs/workers/connections.mdx
@@ -3,20 +3,20 @@ title: Connections
icon: network-wired
---
-Connections represent client connections to your worker. They provide a way to handle client authentication, manage connection-specific data, and control the connection lifecycle.
+Connections represent client connections to your actor. They provide a way to handle client authentication, manage connection-specific data, and control the connection lifecycle.
## Parameters
-When clients connect to a worker, they can pass connection parameters that are handled during the connection process.
+When clients connect to a actor, they can pass connection parameters that are handled during the connection process.
For example:
-```typescript worker.ts
-import { worker } from "rivetkit";
+```typescript actor.ts
+import { actor } from "rivetkit";
-const gameRoom = worker({
+const gameRoom = actor({
state: {},
// Handle connection setup
@@ -52,14 +52,14 @@ const gameRoom = await client.gameRoom.get({
## Connection State
-There are two ways to define a worker's connection state:
+There are two ways to define a actor's connection state:
### Method 1: `ConnState` constant
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { messages: [] },
// Define default connection state as a constant
@@ -84,9 +84,9 @@ const chatRoom = worker({
The data returned from `createConnState` is used as the initial state of the connection. The connection state can be accessed through `conn.state`.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { messages: [] },
// Create connection state dynamically
@@ -120,7 +120,7 @@ The connection lifecycle has several hooks:
- `onConnect`: Called when a client successfully connects
- `onDisconnect`: Called when a client disconnects
-See the documentation on [Worker Lifecycle](/concepts/lifecycle) for more details.
+See the documentation on [Actor Lifecycle](/concepts/lifecycle) for more details.
## Connection List
@@ -131,9 +131,9 @@ This is frequently used with `conn.send(name, event)` to send messages directly
For example:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { users: {} },
actions: {
@@ -158,9 +158,9 @@ const chatRoom = worker({
Connections can be disconnected from within an action:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const secureRoom = worker({
+const secureRoom = actor({
state: {},
actions: {
@@ -189,4 +189,4 @@ This ensures the underlying network connections close cleanly before continuing.
## Offline & Auto-Reconnection
-See [Interacting with Workers](/concepts/interacting-with-workers#offline-and-auto-reconnection) for details on reconnection behavior.
+See [Interacting with Actors](/concepts/interacting-with-actors#offline-and-auto-reconnection) for details on reconnection behavior.
diff --git a/docs/workers/events.mdx b/docs/workers/events.mdx
index bb1f65339..6a9572001 100644
--- a/docs/workers/events.mdx
+++ b/docs/workers/events.mdx
@@ -3,24 +3,24 @@ title: Events
icon: tower-broadcast
---
-Events are used for clients to receive realtime data from workers.
+Events are used for clients to receive realtime data from actors.
-Events are used for workers to publish updates to clients. Clients call actions to communicate with the worker.
+Events are used for actors to publish updates to clients. Clients call actions to communicate with the actor.
-## Publishing from workers
+## Publishing from actors
-Workers can publish events to clients using `c.broadcast` and `conn.send`.
+Actors can publish events to clients using `c.broadcast` and `conn.send`.
### Broadcasting events
-Workers can publish events to all connected clients with `c.broadcast(name, data)`. For example:
+Actors can publish events to all connected clients with `c.broadcast(name, data)`. For example:
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: {},
actions: {
sendMessage: (c, message) => {
@@ -43,14 +43,14 @@ await chatRoom.sendMessage('Hello, world!');
### Sending events to specific connections
-Workers can send messages to specific client connections. All connections are available through the context object. For example:
+Actors can send messages to specific client connections. All connections are available through the context object. For example:
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: {},
actions: {
sendPrivateMessage: (c, connId, message) => {
@@ -76,13 +76,13 @@ await chatRoom.sendPrivateMessage(123, 'Hello, world!');
## Subscribing from clients
-Clients can subscribe to events from workers using `on` and `once`.
+Clients can subscribe to events from actors using `on` and `once`.
### `on(eventName, callback)`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker-client/doc/~/WorkerHandleRaw.prototype.on.html) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor-client/doc/~/ActorHandleRaw.prototype.on.html) */}
-Clients can subscribe to events that will happen repeatedly using `worker.on(name, callback)`. For example:
+Clients can subscribe to events that will happen repeatedly using `actor.on(name, callback)`. For example:
@@ -99,9 +99,9 @@ chatRoom.on('newMessage', ({ message }) => {
```
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: {},
actions: {
sendMessage: (c, message) => {
@@ -115,9 +115,9 @@ const chatRoom = worker({
### `once(eventName, callback)`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker-client/doc/~/WorkerHandleRaw.prototype.once.html) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor-client/doc/~/ActorHandleRaw.prototype.once.html) */}
-Clients can listen for an event only one time with `worker.once(name, callback)`. For example:
+Clients can listen for an event only one time with `actor.once(name, callback)`. For example:
@@ -137,9 +137,9 @@ await chatRoom.requestJoin();
```
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: {
pendingJoinRequests: []
},
@@ -161,6 +161,6 @@ const chatRoom = worker({
## Connections
-Connections are used to communicate with clients from the worker.
+Connections are used to communicate with clients from the actor.
Read more about connections [here](/concepts/connections).
diff --git a/docs/workers/lifecycle.mdx b/docs/workers/lifecycle.mdx
index 9b20d9171..6ae357535 100644
--- a/docs/workers/lifecycle.mdx
+++ b/docs/workers/lifecycle.mdx
@@ -5,32 +5,32 @@ icon: rotate
## Lifecycle Hooks
-Worker lifecycle hooks are defined as functions in the worker configuration.
+Actor lifecycle hooks are defined as functions in the actor configuration.
### `createState` and `state`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onInitialize) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onInitialize) */}
-The `createState` function or `state` constant defines the initial state of the worker (see [state documentation](/concepts/state)). The `createState` function is called only once when the worker is first created.
+The `createState` function or `state` constant defines the initial state of the actor (see [state documentation](/concepts/state)). The `createState` function is called only once when the actor is first created.
### `createVars` and `vars`
-The `createVars` function or `vars` constant defines ephemeral variables for the worker (see [state documentation](/concepts/state)). These variables are not persisted and are useful for storing runtime-only objects or temporary data.
+The `createVars` function or `vars` constant defines ephemeral variables for the actor (see [state documentation](/concepts/state)). These variables are not persisted and are useful for storing runtime-only objects or temporary data.
The `createVars` function can also receive driver-specific context as its second parameter, allowing access to driver capabilities like Rivet KV or Cloudflare Durable Object storage.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Using vars constant
-const counter1 = worker({
+const counter1 = actor({
state: { count: 0 },
vars: { lastAccessTime: 0 },
actions: { /* ... */ }
});
// Using createVars function
-const counter2 = worker({
+const counter2 = actor({
state: { count: 0 },
createVars: () => {
// Initialize with non-serializable objects
@@ -43,7 +43,7 @@ const counter2 = worker({
});
// Access driver-specific context
-const exampleWorker = worker({
+const exampleActor = actor({
state: { count: 0 },
// Access driver context in createVars
createVars: (c, rivet) => ({
@@ -63,16 +63,16 @@ const exampleWorker = worker({
The `onCreate` hook is called at the same time as `createState`, but unlike `createState`, it doesn't return any value. Use this hook for initialization logic that doesn't affect the initial state.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Using state constant
-const counter1 = worker({
+const counter1 = actor({
state: { count: 0 },
actions: { /* ... */ }
});
// Using createState function
-const counter2 = worker({
+const counter2 = actor({
createState: () => {
// Initialize with a count of 0
return { count: 0 };
@@ -81,12 +81,12 @@ const counter2 = worker({
});
// Using onCreate
-const counter3 = worker({
+const counter3 = actor({
state: { count: 0 },
// Run initialization logic (logging, external service setup, etc.)
onCreate: (c) => {
- console.log("Counter worker initialized");
+ console.log("Counter actor initialized");
// Can perform async operations or setup
// No need to return anything
},
@@ -97,22 +97,22 @@ const counter3 = worker({
### `onStart`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onStart) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onStart) */}
-This hook is called any time the worker is started (e.g. after restarting, upgrading code, or crashing).
+This hook is called any time the actor is started (e.g. after restarting, upgrading code, or crashing).
-This is called after the worker has been initialized but before any connections are accepted.
+This is called after the actor has been initialized but before any connections are accepted.
Use this hook to set up any resources or start any background tasks, such as `setInterval`.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
onStart: (c) => {
- console.log('Worker started with count:', c.state.count);
+ console.log('Actor started with count:', c.state.count);
// Set up interval for automatic counting
const intervalId = setInterval(() => {
@@ -130,14 +130,14 @@ const counter = worker({
### `onStateChange`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onStateChange) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onStateChange) */}
-Called whenever the worker's state changes. This is often used to broadcast state updates.
+Called whenever the actor's state changes. This is often used to broadcast state updates.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
onStateChange: (c, newState) => {
@@ -158,7 +158,7 @@ const counter = worker({
### `createConnState` and `connState`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._createConnState) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._createConnState) */}
There are two ways to define the initial state for connections:
1. `connState`: Define a constant object that will be used as the initial state for all connections
@@ -166,16 +166,16 @@ There are two ways to define the initial state for connections:
### `onBeforeConnect`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onBeforeConnect) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onBeforeConnect) */}
-The `onBeforeConnect` hook is called whenever a new client connects to the worker. Clients can pass parameters when connecting, accessible via `params`. This hook is used for connection validation and can throw errors to reject connections.
+The `onBeforeConnect` hook is called whenever a new client connects to the actor. Clients can pass parameters when connecting, accessible via `params`. This hook is used for connection validation and can throw errors to reject connections.
The `onBeforeConnect` hook does NOT return connection state - it's used solely for validation.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { messages: [] },
// Method 1: Use a static default connection state
@@ -209,18 +209,18 @@ const chatRoom = worker({
});
```
-Connections cannot interact with the worker until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication - see [Authentication](/concepts/authentication) for details.
+Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication - see [Authentication](/concepts/authentication) for details.
### `onConnect`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onConnect) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onConnect) */}
Executed after the client has successfully connected.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { users: {}, messages: [] },
onConnect: (c) => {
@@ -241,18 +241,18 @@ const chatRoom = worker({
});
```
-Messages will not be processed for this worker until this hook succeeds. Errors thrown from this hook will cause the client to disconnect.
+Messages will not be processed for this actor until this hook succeeds. Errors thrown from this hook will cause the client to disconnect.
### `onDisconnect`
-{/* [Documentation](https://jsr.io/@rivet-gg/worker/doc/~/Worker.prototype._onDisconnect) */}
+{/* [Documentation](https://jsr.io/@rivet-gg/actor/doc/~/Actor.prototype._onDisconnect) */}
-Called when a client disconnects from the worker. Use this to clean up any connection-specific resources.
+Called when a client disconnects from the actor. Use this to clean up any connection-specific resources.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { users: {}, messages: [] },
onDisconnect: (c) => {
@@ -273,14 +273,14 @@ const chatRoom = worker({
});
```
-## Destroying Workers
+## Destroying Actors
-Workers can be shut down gracefully with `c.shutdown()`. Clients will be gracefully disconnected.
+Actors can be shut down gracefully with `c.shutdown()`. Clients will be gracefully disconnected.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const temporaryRoom = worker({
+const temporaryRoom = actor({
state: {
createdAt: 0,
expiresAfterMs: 3600000 // 1 hour
@@ -314,7 +314,7 @@ const temporaryRoom = worker({
// Notify all clients
c.broadcast("roomClosed", { reason: "Admin closed the room" });
- // Shutdown the worker
+ // Shutdown the actor
c.shutdown();
}
}
@@ -323,42 +323,42 @@ const temporaryRoom = worker({
This action is permanent and cannot be reverted.
-## Using `WorkerContext` Type Externally
+## Using `ActorContext` Type Externally
When extracting logic from lifecycle hooks or actions into external functions, you'll often need to define the type of the context parameter. RivetKit provides helper types that make it easy to extract and pass these context types to external functions.
```typescript
-import { worker, WorkerContextOf } from "rivetkit";
+import { actor, ActorContextOf } from "rivetkit";
-const myWorker = worker({
+const myActor = actor({
state: { count: 0 },
// Use external function in lifecycle hook
- onStart: (c) => logWorkerStarted(c)
+ onStart: (c) => logActorStarted(c)
});
// Simple external function with typed context
-function logWorkerStarted(c: WorkerContextOf) {
- console.log(`Worker started with count: ${c.state.count}`);
+function logActorStarted(c: ActorContextOf) {
+ console.log(`Actor started with count: ${c.state.count}`);
}
```
-See [Helper Types](/concepts/types) for more details on using `WorkerContextOf`.
+See [Helper Types](/concepts/types) for more details on using `ActorContextOf`.
## Full Example
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
// Initialize state
createState: () => ({
count: 0
}),
- // Initialize worker (run setup that doesn't affect initial state)
+ // Initialize actor (run setup that doesn't affect initial state)
onCreate: (c) => {
- console.log('Counter worker initialized');
+ console.log('Counter actor initialized');
// Set up external resources, etc.
},
diff --git a/docs/workers/metadata.mdx b/docs/workers/metadata.mdx
index 4df0ecfe0..fb5e37a01 100644
--- a/docs/workers/metadata.mdx
+++ b/docs/workers/metadata.mdx
@@ -3,7 +3,7 @@ title: Metadata
icon: tag
---
-Metadata provides information about the currently running worker.
+Metadata provides information about the currently running actor.
## Region
@@ -20,9 +20,9 @@ For example:
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: {
messages: []
},
@@ -74,12 +74,12 @@ const teamChannel = await client.chatRoom.get({
-## Worker Name
+## Actor Name
-You can access the worker name with:
+You can access the actor name with:
```typescript
-const workerName = c.name;
+const actorName = c.name;
```
-This is useful when you need to know which worker type is running, especially if you have generic utility functions that are shared between different worker implementations.
+This is useful when you need to know which actor type is running, especially if you have generic utility functions that are shared between different actor implementations.
diff --git a/docs/workers/overview.mdx b/docs/workers/overview.mdx
index 50b0a61c5..8c88b6015 100644
--- a/docs/workers/overview.mdx
+++ b/docs/workers/overview.mdx
@@ -1,13 +1,13 @@
---
-title: Rivet Workers
+title: Rivet Actors
icon: square-info
sidebarTitle: "Overview"
description: A library for building stateful, scalable, realtime backend applications.
---
-import CreateWorkerCli from "/snippets/create-worker-cli.mdx";
+import CreateActorCli from "/snippets/create-actor-cli.mdx";
-Workers combine compute and storage into unified entities for simplified architecture. Workers seamlessly integrate with your existing infrastructure or can serve as a complete standalone solution.
+Actors combine compute and storage into unified entities for simplified architecture. Actors seamlessly integrate with your existing infrastructure or can serve as a complete standalone solution.
## Quickstart
@@ -18,31 +18,31 @@ Workers combine compute and storage into unified entities for simplified archite
## Concepts
-The core concepts that power Rivet Worker applications:
+The core concepts that power Rivet Actor applications:
- **State Is Automatically Persisted**: State automatically persists between restarts, upgrades, & crashes
- **State Is Stored In-Memory**: State is stored in memory for high-performance reads/writes while also automatically persisted
-- **Isolated State Ownership**: Workers only manage their own state, which can only be modified by the worker itself
-- **Communicates via Actions**: How clients and other workers interact with a worker
+- **Isolated State Ownership**: Actors only manage their own state, which can only be modified by the actor itself
+- **Communicates via Actions**: How clients and other actors interact with a actor
- **Actions Are Low-Latency**: Actions provide WebSocket-like performance for time-sensitive operations
-- **Broadcast Updates With Events**: Workers can publish real-time updates to connected clients
+- **Broadcast Updates With Events**: Actors can publish real-time updates to connected clients
## Quickstart
Run this to get started:
-
+
## Code Example
-Here's a complete chat room worker that maintains state and handles messages. We'll explore each component in depth throughout this document:
+Here's a complete chat room actor that maintains state and handles messages. We'll explore each component in depth throughout this document:
```typescript chat_room.ts
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-// Define a chat room worker
-const chatRoom = worker({
- // Initialize state when the worker is first created
+// Define a chat room actor
+const chatRoom = actor({
+ // Initialize state when the actor is first created
createState: () => ({
messages: []
}),
@@ -70,7 +70,7 @@ export default chatRoom;
## Using the App
-To start using your worker, create an app and serve it:
+To start using your actor, create an app and serve it:
```typescript app.ts
import { setup, serve } from "rivetkit";
@@ -78,7 +78,7 @@ import chatRoom from "./chat_room";
// Create the application
const registry = setup({
- workers: { chatRoom }
+ actors: { chatRoom }
});
// Start serving on default port
@@ -88,17 +88,17 @@ serve(registry);
export type Registry = typeof registry;
```
-## Key Worker Components
+## Key Actor Components
### State
-Workers maintain state that's stored in memory and automatically persisted. State is defined either as a constant or via a `createState` function:
+Actors maintain state that's stored in memory and automatically persisted. State is defined either as a constant or via a `createState` function:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Method 1: State constant
-const counter1 = worker({
+const counter1 = actor({
state: { count: 0 },
actions: {
// ...
@@ -106,7 +106,7 @@ const counter1 = worker({
});
// Method 2: CreateState function
-const counter2 = worker({
+const counter2 = actor({
createState: () => ({ count: 0 }),
actions: {
// ...
@@ -117,9 +117,9 @@ const counter2 = worker({
Update state by modifying `c.state` in your actions:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
// Example of state update in an action
@@ -133,16 +133,16 @@ const counter = worker({
These changes are durable and are automatically persisted across updates, restarts, and crashes.
-Learn more about [state management](/worker/state).
+Learn more about [state management](/actor/state).
### Actions
-Actions are functions defined in your worker configuration that clients & other workers can call:
+Actions are functions defined in your actor configuration that clients & other actors can call:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const mathUtils = worker({
+const mathUtils = actor({
state: {},
actions: {
multiplyByTwo: (c, x) => {
@@ -154,16 +154,16 @@ const mathUtils = worker({
Each action receives a context object (commonly named `c`) as its first parameter, which provides access to state, connections, and other utilities.
-Learn more about [actions](/worker/actions).
+Learn more about [actions](/actor/actions).
### Events
-Workers can broadcast events to connected clients:
+Actors can broadcast events to connected clients:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const inventory = worker({
+const inventory = actor({
createState: () => ({
items: []
}),
@@ -183,9 +183,9 @@ const inventory = worker({
You can also send events to specific clients:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const messageService = worker({
+const messageService = actor({
state: {},
actions: {
sendPrivateMessage: (c, userId, text) => {
@@ -199,14 +199,14 @@ const messageService = worker({
});
```
-Learn more about [events](/worker/events).
+Learn more about [events](/actor/events).
-## Worker Tags
+## Actor Tags
-Tags are key-value pairs attached to workers that serve two purposes:
+Tags are key-value pairs attached to actors that serve two purposes:
-1. **Worker Discovery**: Find specific workers using `client.get(tags)`
-2. **Organization**: Group related workers for management purposes
+1. **Actor Discovery**: Find specific actors using `client.get(tags)`
+2. **Organization**: Group related actors for management purposes
For example, you can query chat rooms by tag like:
@@ -235,16 +235,16 @@ const document = await client.document.get({
});
```
-## Worker Lifecycle
+## Actor Lifecycle
-Workers are created automatically when needed and persist until explicitly shutdown.
+Actors are created automatically when needed and persist until explicitly shutdown.
-To shut down a worker, use `c.shutdown()` from within an action:
+To shut down a actor, use `c.shutdown()` from within an action:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
createState: () => ({
messages: []
}),
@@ -253,36 +253,36 @@ const chatRoom = worker({
// Do any cleanup needed
c.broadcast("roomClosed");
- // Shutdown the worker
+ // Shutdown the actor
c.shutdown();
}
}
});
```
-Learn more about the [worker lifecycle](/worker/lifecycle).
+Learn more about the [actor lifecycle](/actor/lifecycle).
## Documentation
-Learn more about Rivet Workers:
+Learn more about Rivet Actors:
-
- Get started with Rivet Workers in minutes
+
+ Get started with Rivet Actors in minutes
-
- Understand how worker state is managed, persisted, and accessed.
+
+ Understand how actor state is managed, persisted, and accessed.
-
- Define and implement worker actions (RPCs) for client interaction.
+
+ Define and implement actor actions (RPCs) for client interaction.
-
+
Real-time communication with events and broadcasts.
-
- Managing the creation, execution, and termination of workers.
+
+ Managing the creation, execution, and termination of actors.
-
- Schedule tasks and alarms with workers for time-based operations.
+
+ Schedule tasks and alarms with actors for time-based operations.
diff --git a/docs/workers/quickstart-frontend.mdx b/docs/workers/quickstart-frontend.mdx
index f0e98d32b..e174780b2 100644
--- a/docs/workers/quickstart-frontend.mdx
+++ b/docs/workers/quickstart-frontend.mdx
@@ -11,12 +11,12 @@ npm install rivetkit
```
-
+
```ts registry.ts
-import { worker, setup } from "rivetkit";
+import { actor, setup } from "rivetkit";
-export const counter = worker({
+export const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
@@ -27,7 +27,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
```
@@ -53,13 +53,13 @@ import { createClient, createRivetKit } from "@rivetkit/react";
import type { Registry } from "../backend/registry";
const client = createClient(`http://localhost:6420/registry`);
-const { useWorker } = createRivetKit(client);
+const { useActor } = createRivetKit(client);
function App() {
const [count, setCount] = useState(0);
const [counterName, setCounterName] = useState("test-counter");
- const counter = useWorker({
+ const counter = useActor({
name: "counter",
key: [counterName],
});
@@ -133,7 +133,7 @@ TODO: See backend
-
+
diff --git a/docs/workers/quickstart.mdx b/docs/workers/quickstart.mdx
index 04be06d7c..84394b223 100644
--- a/docs/workers/quickstart.mdx
+++ b/docs/workers/quickstart.mdx
@@ -7,16 +7,16 @@ icon: node-js
```sh
-npm install @rivetkit/worker
+npm install @rivetkit/actor
```
-
+
```ts registry.ts
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
@@ -27,7 +27,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
```
@@ -239,7 +239,7 @@ const { client, hono } = registry.run({
## Configuration Options
-### Connect your frontend to the Rivet Worker
+### Connect your frontend to the Rivet Actor
TODO: Quick summary of why you would want to connect your frontend
@@ -248,27 +248,27 @@ Connect your frontend:
```ts JavaScript
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import type { registry } from "./registry.js";
const client = createClient("http://localhost:8080/registry");
-const result = await client.myWorker.getOrCreate().myAction("Hello, world!");
+const result = await client.myActor.getOrCreate().myAction("Hello, world!");
```
```ts React
import { useState } from "react";
-import { createClient, createRivetKit } from "@@rivetkit/worker/react";
+import { createClient, createRivetKit } from "@@rivetkit/actor/react";
import type { registry } from "./registry";
const client = createClient(`http://localhost:8080/registry`);
-const { useWorker } = createRivetKit(client);
+const { useActor } = createRivetKit(client);
function App() {
const [count, setCount] = useState(0);
const [counterName, setCounterName] = useState("test-counter");
- const counter = useWorker({
+ const counter = useActor({
name: "counter",
key: [counterName],
});
@@ -336,7 +336,7 @@ TODO
-
+
diff --git a/docs/workers/schedule.mdx b/docs/workers/schedule.mdx
index 79c0b7a63..2f8c5ad60 100644
--- a/docs/workers/schedule.mdx
+++ b/docs/workers/schedule.mdx
@@ -3,7 +3,7 @@ title: Schedule
icon: clock
---
-Scheduling is used to trigger events in the future. The worker scheduler is like `setTimeout`, except the timeout will persist even if the worker restarts, upgrades, or crashes.
+Scheduling is used to trigger events in the future. The actor scheduler is like `setTimeout`, except the timeout will persist even if the actor restarts, upgrades, or crashes.
## Use Cases
@@ -13,7 +13,7 @@ Scheduling is helpful for long-running timeouts like month-long billing periods
### `c.schedule.after(duration, fn, ...args)`
-Schedules a function to be executed after a specified duration. This function persists across worker restarts, upgrades, or crashes.
+Schedules a function to be executed after a specified duration. This function persists across actor restarts, upgrades, or crashes.
Parameters:
@@ -23,7 +23,7 @@ Parameters:
### `c.schedule.at(timestamp, fn, ...args)`
-Schedules a function to be executed at a specific timestamp. This function persists across worker restarts, upgrades, or crashes.
+Schedules a function to be executed at a specific timestamp. This function persists across actor restarts, upgrades, or crashes.
Parameters:
@@ -38,9 +38,9 @@ Currently, scheduling can only trigger public actions. If the scheduled action i
## Full Example
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const reminderService = worker({
+const reminderService = actor({
state: {
reminders: {}
},
diff --git a/docs/workers/state.mdx b/docs/workers/state.mdx
index 5f644fdf7..7462c4764 100644
--- a/docs/workers/state.mdx
+++ b/docs/workers/state.mdx
@@ -3,26 +3,26 @@ title: State
icon: floppy-disk
---
-Worker state provides the best of both worlds: it's stored in-memory and persisted automatically. This lets you work with the data without added latency while still being able to survive crashes & upgrades.
+Actor state provides the best of both worlds: it's stored in-memory and persisted automatically. This lets you work with the data without added latency while still being able to survive crashes & upgrades.
**Using External SQL Databases**
-Workers can also be used with external SQL databases. This can be useful to integrate workers with existing
+Actors can also be used with external SQL databases. This can be useful to integrate actors with existing
applications or for storing relational data. Read more [here](/concepts/external-sql).
## Initializing State
-There are two ways to define a worker's initial state:
+There are two ways to define a actor's initial state:
**Method 1: Static Initial State**
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Simple state with a constant
-const counter = worker({
+const counter = actor({
// Define state as a constant
state: { count: 0 },
@@ -35,10 +35,10 @@ const counter = worker({
**Method 2: Dynamic Initial State**
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// State with initialization logic
-const counter = worker({
+const counter = actor({
// Define state using a creation function
createState: () => {
return { count: 0 };
@@ -50,16 +50,16 @@ const counter = worker({
});
```
-The `createState` function is called once when the worker is first created. See [Lifecycle](/concepts/lifecycle) for more details.
+The `createState` function is called once when the actor is first created. See [Lifecycle](/concepts/lifecycle) for more details.
## Modifying State
To update state, modify the `state` property on the context object (`c.state`) in your actions:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
@@ -84,14 +84,14 @@ Only state stored in the `state` object will be persisted. Any other variables o
## State Saves
-Workers automatically handle persisting state transparently. This happens at the end of every action if the state has changed.
+Actors automatically handle persisting state transparently. This happens at the end of every action if the state has changed.
In the rare occasion you need to force a state change mid-action, you can use `c.saveState()`. This should only be used if your action makes an important state change that needs to be persisted before the action completes.
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
-const criticalProcess = worker({
+const criticalProcess = actor({
state: {
steps: [],
currentStep: 0
@@ -120,34 +120,34 @@ const criticalProcess = worker({
## State Isolation
-Each worker's state is completely isolated, meaning it cannot be accessed directly by other workers or clients. This allows workers to maintain a high level of security and data integrity, ensuring that state changes are controlled and predictable.
+Each actor's state is completely isolated, meaning it cannot be accessed directly by other actors or clients. This allows actors to maintain a high level of security and data integrity, ensuring that state changes are controlled and predictable.
-To interact with a worker's state, you must use [Actions](/concepts/actions). Actions provide a controlled way to read from and write to the state.
+To interact with a actor's state, you must use [Actions](/concepts/actions). Actions provide a controlled way to read from and write to the state.
-## Sharing State Between Workers
+## Sharing State Between Actors
-If you need a shared state between multiple workers, you have two options:
+If you need a shared state between multiple actors, you have two options:
-1. Create a worker that holds the shared state that other workers can make action calls to
+1. Create a actor that holds the shared state that other actors can make action calls to
2. Use an external database, see [External SQL Databases](/concepts/external-sql)
## Ephemeral Variables
-In addition to persisted state, RivetKit provides a way to store ephemeral data that is not saved to permanent storage using `vars`. This is useful for temporary data that only needs to exist while the worker is running or data that cannot be serialized.
+In addition to persisted state, RivetKit provides a way to store ephemeral data that is not saved to permanent storage using `vars`. This is useful for temporary data that only needs to exist while the actor is running or data that cannot be serialized.
-`vars` is designed to complement `state`, not replace it. Most workers should use both: `state` for critical business data and `vars` for ephemeral or non-serializable data.
+`vars` is designed to complement `state`, not replace it. Most actors should use both: `state` for critical business data and `vars` for ephemeral or non-serializable data.
### Initializing Variables
-There are two ways to define a worker's initial vars:
+There are two ways to define a actor's initial vars:
**Method 1: Static Initial Variables**
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Define vars as a constant
-const counter = worker({
+const counter = actor({
state: { count: 0 },
// Define ephemeral variables
@@ -169,10 +169,10 @@ When using static `vars`, all values must be compatible with `structuredClone()`
**Method 2: Dynamic Initial Variables**
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
// Define vars with initialization logic
-const counter = worker({
+const counter = actor({
state: { count: 0 },
// Define vars using a creation function
@@ -194,10 +194,10 @@ const counter = worker({
Vars can be accessed and modified through the context object with `c.vars`:
```typescript
-import { worker } from "rivetkit";
+import { actor } from "rivetkit";
import { createNanoEvents } from "nanoevents";
-const counter = worker({
+const counter = actor({
// Persistent state - saved to storage
state: { count: 0 },
@@ -230,7 +230,7 @@ const counter = worker({
### When to Use `vars` vs `state`
-In practice, most workers will use both: `state` for critical business data and `vars` for ephemeral, non-serializable, or performance-sensitive data.
+In practice, most actors will use both: `state` for critical business data and `vars` for ephemeral, non-serializable, or performance-sensitive data.
Use `vars` when:
@@ -239,8 +239,8 @@ Use `vars` when:
Use `state` when:
-- The data must be preserved across worker sleeps, restarts, updates, or crashes
-- The information is essential to the worker's core functionality and business logic
+- The data must be preserved across actor sleeps, restarts, updates, or crashes
+- The information is essential to the actor's core functionality and business logic
## Limitations
diff --git a/docs/workers/types.mdx b/docs/workers/types.mdx
index 44a079705..95793a691 100644
--- a/docs/workers/types.mdx
+++ b/docs/workers/types.mdx
@@ -2,20 +2,20 @@
title: Helper Types
---
-RivetKit provides several TypeScript helper types to make it easier to work with workers in a type-safe way.
+RivetKit provides several TypeScript helper types to make it easier to work with actors in a type-safe way.
## `Context` Types
-When working with workers, you often need to access the context object. RivetKit provides helper types to extract the context types from worker definitions.
+When working with actors, you often need to access the context object. RivetKit provides helper types to extract the context types from actor definitions.
-### `WorkerContextOf`
+### `ActorContextOf`
-Extracts the full worker context type from a worker definition. This is the type of the context object (`c`) available in lifecycle hooks such as `onCreate`, `onStart`, etc.
+Extracts the full actor context type from a actor definition. This is the type of the context object (`c`) available in lifecycle hooks such as `onCreate`, `onStart`, etc.
```typescript
-import { worker, WorkerContextOf } from "rivetkit";
+import { actor, ActorContextOf } from "rivetkit";
-const chatRoom = worker({
+const chatRoom = actor({
state: { messages: [] },
actions: {
sendMessage: (c, message) => {
@@ -25,7 +25,7 @@ const chatRoom = worker({
});
// Extract the chat room context type
-type ChatRoomContext = WorkerContextOf;
+type ChatRoomContext = ActorContextOf;
// Now you can use this type elsewhere
function processChatRoomContext(context: ChatRoomContext) {
@@ -35,14 +35,14 @@ function processChatRoomContext(context: ChatRoomContext) {
}
```
-### `ActionContextOf`
+### `ActionContextOf`
-Extracts the action context type from a worker definition. This is the type of the context object (`c`) available in action handlers.
+Extracts the action context type from a actor definition. This is the type of the context object (`c`) available in action handlers.
```typescript
-import { worker, ActionContextOf } from "rivetkit";
+import { actor, ActionContextOf } from "rivetkit";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c) => {
diff --git a/examples/better-auth/README.md b/examples/better-auth/README.md
index 7f2594758..d4f52af4f 100644
--- a/examples/better-auth/README.md
+++ b/examples/better-auth/README.md
@@ -32,21 +32,21 @@ Open your browser to `http://localhost:5173` to see the frontend and the backend
## Features
- **Authentication**: Email/password authentication using Better Auth
-- **Protected Workers**: RivetKit workers with authentication via `onAuth` hook
+- **Protected Actors**: RivetKit actors with authentication via `onAuth` hook
- **Real-time Chat**: Authenticated chat room with real-time messaging
- **SQLite Database**: Persistent user data and session storage
## How It Works
1. **Better Auth Setup**: Configured with SQLite adapter for user storage
-2. **Protected Worker**: The `chatRoom` worker uses the `onAuth` hook to verify user sessions
+2. **Protected Actor**: The `chatRoom` actor uses the `onAuth` hook to verify user sessions
3. **Frontend Integration**: React components handle authentication flow and chat interface
4. **Session Management**: Better Auth handles session creation, validation, and cleanup
## Key Files
- `src/backend/auth.ts` - Better Auth configuration with SQLite
-- `src/backend/registry.ts` - RivetKit worker with authentication
+- `src/backend/registry.ts` - RivetKit actor with authentication
- `src/frontend/components/AuthForm.tsx` - Login/signup form
- `src/frontend/components/ChatRoom.tsx` - Authenticated chat interface
diff --git a/examples/better-auth/package.json b/examples/better-auth/package.json
index 600b9b8b4..108fd8437 100644
--- a/examples/better-auth/package.json
+++ b/examples/better-auth/package.json
@@ -17,7 +17,7 @@
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"concurrently": "^8.2.2",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2",
"vite": "^5.0.0",
diff --git a/examples/better-auth/src/backend/registry.ts b/examples/better-auth/src/backend/registry.ts
index daceb8bbd..14abfe73d 100644
--- a/examples/better-auth/src/backend/registry.ts
+++ b/examples/better-auth/src/backend/registry.ts
@@ -1,7 +1,7 @@
-// import { worker, setup } from "@rivetkit/worker";
+// import { actor, setup } from "@rivetkit/actor";
// import { auth, type Session, type User } from "./auth";
//
-// export const chatRoom = worker({
+// export const chatRoom = actor({
// onAuth: async (c) => {
// const authResult = await auth.api.getSession({
// headers: c.req.headers,
@@ -42,7 +42,7 @@
// });
//
// export const registry = setup({
-// workers: { chatRoom },
+// actors: { chatRoom },
// });
//
// export type Registry = typeof registry;
diff --git a/examples/better-auth/src/frontend/components/ChatRoom.tsx b/examples/better-auth/src/frontend/components/ChatRoom.tsx
index dcd0f86dc..e6d551a03 100644
--- a/examples/better-auth/src/frontend/components/ChatRoom.tsx
+++ b/examples/better-auth/src/frontend/components/ChatRoom.tsx
@@ -7,7 +7,7 @@ const client = createClient("http://localhost:6420/registry", {
transport: "sse",
});
-const { useWorker } = createRivetKit(client);
+const { useActor } = createRivetKit(client);
interface ChatRoomProps {
user: { id: string; email: string };
@@ -25,7 +25,7 @@ export function ChatRoom({ user, onSignOut }: ChatRoomProps) {
}>>([]);
const [roomId] = useState("general");
- const chatRoom = useWorker({
+ const chatRoom = useActor({
name: "chatRoom",
key: [roomId],
});
diff --git a/examples/chat-room/README.md b/examples/chat-room/README.md
index e7f7476d3..900d55045 100644
--- a/examples/chat-room/README.md
+++ b/examples/chat-room/README.md
@@ -1,6 +1,6 @@
# Chat Room for RivetKit
-Example project demonstrating real-time messaging and worker state management with [RivetKit](https://rivetkit.org).
+Example project demonstrating real-time messaging and actor state management with [RivetKit](https://rivetkit.org).
[Learn More →](https://github.com/rivet-gg/rivetkit)
diff --git a/examples/chat-room/package.json b/examples/chat-room/package.json
index 1924156ff..5e28cb919 100644
--- a/examples/chat-room/package.json
+++ b/examples/chat-room/package.json
@@ -12,7 +12,7 @@
"@types/node": "^22.13.9",
"@types/prompts": "^2",
"prompts": "^2.4.2",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2",
"vitest": "^3.1.1"
diff --git a/examples/chat-room/scripts/cli.ts b/examples/chat-room/scripts/cli.ts
index e22b876f1..f90d23c13 100644
--- a/examples/chat-room/scripts/cli.ts
+++ b/examples/chat-room/scripts/cli.ts
@@ -1,5 +1,5 @@
-import { createClient } from "@rivetkit/worker/client";
-import type { Registry } from "../workers/registry";
+import { createClient } from "@rivetkit/actor/client";
+import type { Registry } from "../actors/registry";
import prompts from "prompts";
async function main() {
diff --git a/examples/chat-room/scripts/connect.ts b/examples/chat-room/scripts/connect.ts
index 0fdd3e4f5..1ee9496c9 100644
--- a/examples/chat-room/scripts/connect.ts
+++ b/examples/chat-room/scripts/connect.ts
@@ -1,6 +1,6 @@
///
-import { createClient } from "@rivetkit/worker/client";
-import type { Registry } from "../workers/registry";
+import { createClient } from "@rivetkit/actor/client";
+import type { Registry } from "../actors/registry";
async function main() {
// Create type-aware client
diff --git a/examples/chat-room/src/server.ts b/examples/chat-room/src/server.ts
index d3235e055..a8ad753e1 100644
--- a/examples/chat-room/src/server.ts
+++ b/examples/chat-room/src/server.ts
@@ -1,4 +1,4 @@
// import { serve } from "@rivetkit/nodejs";
-// import { registry } from "./workers/registry";
+// import { registry } from "./actors/registry";
//
// serve(registry);
diff --git a/examples/chat-room/src/workers/registry.ts b/examples/chat-room/src/workers/registry.ts
index 634c3c0a9..16169e990 100644
--- a/examples/chat-room/src/workers/registry.ts
+++ b/examples/chat-room/src/workers/registry.ts
@@ -1,11 +1,11 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
// state managed by the actor
export interface State {
messages: { username: string; message: string }[];
}
-export const chatRoom = worker({
+export const chatRoom = actor({
// initialize state
state: { messages: [] } as State,
@@ -28,7 +28,7 @@ export const chatRoom = worker({
// Create and export the app
export const registry = setup({
- workers: { chatRoom },
+ actors: { chatRoom },
});
// Export type for client type checking
diff --git a/examples/chat-room/tests/chat-room.test.ts b/examples/chat-room/tests/chat-room.test.ts
index b14ea9592..9f6b2729f 100644
--- a/examples/chat-room/tests/chat-room.test.ts
+++ b/examples/chat-room/tests/chat-room.test.ts
@@ -1,6 +1,6 @@
import { test, expect } from "vitest";
-import { setupTest } from "@rivetkit/worker/test";
-import { registry } from "../src/workers/registry";
+import { setupTest } from "@rivetkit/actor/test";
+import { registry } from "../src/actors/registry";
test("chat room should handle messages", async (test) => {
const { client } = await setupTest(test, registry);
diff --git a/examples/cloudflare-workers/README.md b/examples/cloudflare-workers/README.md
index d05f1f95d..bf6cb3c63 100644
--- a/examples/cloudflare-workers/README.md
+++ b/examples/cloudflare-workers/README.md
@@ -11,7 +11,7 @@ Example project demonstrating Cloudflare Workers deployment with [RivetKit](http
### Prerequisites
- Node.js
-- Cloudflare account with Workers enabled
+- Cloudflare account with Actors enabled
- Wrangler CLI installed globally (`npm install -g wrangler`)
### Installation
@@ -32,7 +32,7 @@ This will start the Cloudflare Workers development server locally at http://loca
### Testing the Client
-In a separate terminal, run the client script to interact with your workers:
+In a separate terminal, run the client script to interact with your actors:
```sh
npm run client
@@ -54,4 +54,4 @@ npm run deploy
## License
-Apache 2.0
\ No newline at end of file
+Apache 2.0
diff --git a/examples/cloudflare-workers/package.json b/examples/cloudflare-workers/package.json
index 0ab187a3c..cf9eb867a 100644
--- a/examples/cloudflare-workers/package.json
+++ b/examples/cloudflare-workers/package.json
@@ -12,7 +12,7 @@
"devDependencies": {
"@cloudflare/workers-types": "^4.20250129.0",
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2",
"wrangler": "^3.0.0"
diff --git a/examples/cloudflare-workers/scripts/client.ts b/examples/cloudflare-workers/scripts/client.ts
index ef15618e2..8169bb478 100644
--- a/examples/cloudflare-workers/scripts/client.ts
+++ b/examples/cloudflare-workers/scripts/client.ts
@@ -1,4 +1,4 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import type { Registry } from "../src/registry.js";
// Create RivetKit client
diff --git a/examples/cloudflare-workers/src/index.ts b/examples/cloudflare-workers/src/index.ts
index 341b3fff9..134284ea2 100644
--- a/examples/cloudflare-workers/src/index.ts
+++ b/examples/cloudflare-workers/src/index.ts
@@ -1,6 +1,6 @@
-import { createHandler } from "@rivetkit/cloudflare-workers";
-import { registry } from "./registry";
-
-const { handler, WorkerHandler } = createHandler(registry);
-
-export { handler as default, WorkerHandler };
+// import { createHandler } from "@rivetkit/cloudflare-workers";
+// import { registry } from "./registry";
+//
+// const { handler, ActorHandler } = createHandler(registry);
+//
+// export { handler as default, ActorHandler };
diff --git a/examples/cloudflare-workers/src/registry.ts b/examples/cloudflare-workers/src/registry.ts
index 84f7d059b..4c0f83a0f 100644
--- a/examples/cloudflare-workers/src/registry.ts
+++ b/examples/cloudflare-workers/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,7 +14,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/cloudflare-workers/tsconfig.json b/examples/cloudflare-workers/tsconfig.json
index 681844dd9..b8a0a7676 100644
--- a/examples/cloudflare-workers/tsconfig.json
+++ b/examples/cloudflare-workers/tsconfig.json
@@ -40,4 +40,4 @@
"skipLibCheck": true
},
"include": ["src/**/*"]
-}
\ No newline at end of file
+}
diff --git a/examples/cloudflare-workers/wrangler.json b/examples/cloudflare-workers/wrangler.json
index 8791c7de9..29b055cf3 100644
--- a/examples/cloudflare-workers/wrangler.json
+++ b/examples/cloudflare-workers/wrangler.json
@@ -6,20 +6,20 @@
"migrations": [
{
"tag": "v1",
- "new_classes": ["WorkerHandler"]
+ "new_classes": ["ActorHandler"]
}
],
"durable_objects": {
"bindings": [
{
- "name": "WORKER_DO",
- "class_name": "WorkerHandler"
+ "name": "ACTOR_DO",
+ "class_name": "ActorHandler"
}
]
},
"kv_namespaces": [
{
- "binding": "WORKER_KV",
+ "binding": "ACTOR_KV",
"id": "example_namespace",
"preview_id": "example_namespace_preview"
}
@@ -27,4 +27,4 @@
"observability": {
"enabled": true
}
-}
\ No newline at end of file
+}
diff --git a/examples/counter/README.md b/examples/counter/README.md
index bcc6a476b..cac72debf 100644
--- a/examples/counter/README.md
+++ b/examples/counter/README.md
@@ -1,6 +1,6 @@
# Counter for RivetKit
-Example project demonstrating basic worker state management and RPC calls with [RivetKit](https://rivetkit.org).
+Example project demonstrating basic actor state management and RPC calls with [RivetKit](https://rivetkit.org).
[Learn More →](https://github.com/rivet-gg/rivetkit)
diff --git a/examples/counter/package.json b/examples/counter/package.json
index d1b6bf3f2..301b0aa6e 100644
--- a/examples/counter/package.json
+++ b/examples/counter/package.json
@@ -10,7 +10,7 @@
},
"devDependencies": {
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.7.3",
"vitest": "^3.1.1"
diff --git a/examples/counter/scripts/connect.ts b/examples/counter/scripts/connect.ts
index b8abc6cd7..0c85864c4 100644
--- a/examples/counter/scripts/connect.ts
+++ b/examples/counter/scripts/connect.ts
@@ -1,6 +1,6 @@
///
-import { createClient } from "@rivetkit/worker/client";
-import type { Registry } from "../src/workers/registry";
+import { createClient } from "@rivetkit/actor/client";
+import type { Registry } from "../src/actors/registry";
async function main() {
const client = createClient(
diff --git a/examples/counter/src/server.ts b/examples/counter/src/server.ts
index d3235e055..a8ad753e1 100644
--- a/examples/counter/src/server.ts
+++ b/examples/counter/src/server.ts
@@ -1,4 +1,4 @@
// import { serve } from "@rivetkit/nodejs";
-// import { registry } from "./workers/registry";
+// import { registry } from "./actors/registry";
//
// serve(registry);
diff --git a/examples/counter/src/workers/registry.ts b/examples/counter/src/workers/registry.ts
index 13f56c12b..e662d7e65 100644
--- a/examples/counter/src/workers/registry.ts
+++ b/examples/counter/src/workers/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-const counter = worker({
+const counter = actor({
state: { count: 0 },
actions: {
increment: (c, x: number) => {
@@ -15,7 +15,7 @@ const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/counter/tests/counter.test.ts b/examples/counter/tests/counter.test.ts
index 618096300..47988c8fe 100644
--- a/examples/counter/tests/counter.test.ts
+++ b/examples/counter/tests/counter.test.ts
@@ -1,35 +1,35 @@
-import { test, expect } from "vitest";
-import { setupTest } from "@rivetkit/worker/test";
-import { registry } from "../src/workers/registry";
-
-test("it should count", async (test) => {
- const { client } = await setupTest(test, registry);
- const counter = client.counter.getOrCreate().connect();
-
- // Test initial count
- expect(await counter.getCount()).toBe(0);
-
- // Test event emission
- let eventCount = -1;
- counter.on("newCount", (count: number) => {
- eventCount = count;
- });
-
- // Test increment
- const incrementAmount = 5;
- const result = await counter.increment(incrementAmount);
- expect(result).toBe(incrementAmount);
-
- // Verify event was emitted with correct count
- expect(eventCount).toBe(incrementAmount);
-
- // Test multiple increments
- for (let i = 1; i <= 3; i++) {
- const newCount = await counter.increment(incrementAmount);
- expect(newCount).toBe(incrementAmount * (i + 1));
- expect(eventCount).toBe(incrementAmount * (i + 1));
- }
-
- // Verify final count
- expect(await counter.getCount()).toBe(incrementAmount * 4);
-});
+// import { test, expect } from "vitest";
+// import { setupTest } from "@rivetkit/actor/test";
+// import { registry } from "../src/actors/registry";
+//
+// test("it should count", async (test) => {
+// const { client } = await setupTest(test, registry);
+// const counter = client.counter.getOrCreate().connect();
+//
+// // Test initial count
+// expect(await counter.getCount()).toBe(0);
+//
+// // Test event emission
+// let eventCount = -1;
+// counter.on("newCount", (count: number) => {
+// eventCount = count;
+// });
+//
+// // Test increment
+// const incrementAmount = 5;
+// const result = await counter.increment(incrementAmount);
+// expect(result).toBe(incrementAmount);
+//
+// // Verify event was emitted with correct count
+// expect(eventCount).toBe(incrementAmount);
+//
+// // Test multiple increments
+// for (let i = 1; i <= 3; i++) {
+// const newCount = await counter.increment(incrementAmount);
+// expect(newCount).toBe(incrementAmount * (i + 1));
+// expect(eventCount).toBe(incrementAmount * (i + 1));
+// }
+//
+// // Verify final count
+// expect(await counter.getCount()).toBe(incrementAmount * 4);
+// });
diff --git a/examples/drizzle/src/registry.ts b/examples/drizzle/src/registry.ts
index b7896048f..0398452d4 100644
--- a/examples/drizzle/src/registry.ts
+++ b/examples/drizzle/src/registry.ts
@@ -1,9 +1,9 @@
-// import { worker, setup } from "rivetkit";
+// import { actor, setup } from "rivetkit";
// import { db } from "@rivetkit/db/drizzle";
// import * as schema from "./db/schema";
// import migrations from "../drizzle/migrations";
-// export const counter = worker({
+// export const counter = actor({
// db: db({ schema, migrations }),
// state: {
// count: 0,
@@ -21,7 +21,7 @@
// });
// export const registry = setup({
-// workers: { counter },
+// actors: { counter },
// });
// export type Registry = typeof registry;
diff --git a/examples/elysia/package.json b/examples/elysia/package.json
index 4d96c884f..54f657136 100644
--- a/examples/elysia/package.json
+++ b/examples/elysia/package.json
@@ -9,7 +9,7 @@
},
"devDependencies": {
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"typescript": "^5.5.2"
},
"dependencies": {
diff --git a/examples/elysia/src/registry.ts b/examples/elysia/src/registry.ts
index 84f7d059b..4c0f83a0f 100644
--- a/examples/elysia/src/registry.ts
+++ b/examples/elysia/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,7 +14,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/express/package.json b/examples/express/package.json
index ae98f4809..5447bcd12 100644
--- a/examples/express/package.json
+++ b/examples/express/package.json
@@ -10,7 +10,7 @@
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2"
},
diff --git a/examples/express/src/registry.ts b/examples/express/src/registry.ts
index 84f7d059b..4c0f83a0f 100644
--- a/examples/express/src/registry.ts
+++ b/examples/express/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,7 +14,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/hono-react/README.md b/examples/hono-react/README.md
index 7833b6532..2accebca7 100644
--- a/examples/hono-react/README.md
+++ b/examples/hono-react/README.md
@@ -26,7 +26,7 @@ npm install
npm run dev
```
-This will start both the Hono backend server and Vite React frontend. Open your browser to http://localhost:5173 to see the React app connected to RivetKit workers.
+This will start both the Hono backend server and Vite React frontend. Open your browser to http://localhost:5173 to see the React app connected to RivetKit actors.
## License
diff --git a/examples/hono-react/package.json b/examples/hono-react/package.json
index aaa832e77..bf437ec27 100644
--- a/examples/hono-react/package.json
+++ b/examples/hono-react/package.json
@@ -17,7 +17,7 @@
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"concurrently": "^8.2.2",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2",
"vite": "^5.0.0",
diff --git a/examples/hono-react/src/backend/registry.ts b/examples/hono-react/src/backend/registry.ts
index de9d21a60..854e1bb74 100644
--- a/examples/hono-react/src/backend/registry.ts
+++ b/examples/hono-react/src/backend/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -15,7 +15,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/hono-react/src/frontend/App.tsx b/examples/hono-react/src/frontend/App.tsx
index d5aebce6a..fe27125ff 100644
--- a/examples/hono-react/src/frontend/App.tsx
+++ b/examples/hono-react/src/frontend/App.tsx
@@ -5,13 +5,13 @@
// const client = createClient("http://localhost:6420/registry", {
// transport: "sse",
// });
-// const { useWorker } = createRivetKit(client);
+// const { useActor } = createRivetKit(client);
//
// function App() {
// const [count, setCount] = useState(0);
// const [counterName, setCounterName] = useState("test-counter");
//
-// const counter = useWorker({
+// const counter = useActor({
// name: "counter",
// key: [counterName],
// });
diff --git a/examples/hono/package.json b/examples/hono/package.json
index 63c7d873a..ac4f77661 100644
--- a/examples/hono/package.json
+++ b/examples/hono/package.json
@@ -9,7 +9,7 @@
},
"devDependencies": {
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2"
},
diff --git a/examples/hono/src/registry.ts b/examples/hono/src/registry.ts
index 84f7d059b..4c0f83a0f 100644
--- a/examples/hono/src/registry.ts
+++ b/examples/hono/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,7 +14,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/react/README.md b/examples/react/README.md
index 7833b6532..2accebca7 100644
--- a/examples/react/README.md
+++ b/examples/react/README.md
@@ -26,7 +26,7 @@ npm install
npm run dev
```
-This will start both the Hono backend server and Vite React frontend. Open your browser to http://localhost:5173 to see the React app connected to RivetKit workers.
+This will start both the Hono backend server and Vite React frontend. Open your browser to http://localhost:5173 to see the React app connected to RivetKit actors.
## License
diff --git a/examples/react/package.json b/examples/react/package.json
index a37a14a74..97ea05fe1 100644
--- a/examples/react/package.json
+++ b/examples/react/package.json
@@ -17,7 +17,7 @@
"@types/react-dom": "^18.2.0",
"@vitejs/plugin-react": "^4.2.0",
"concurrently": "^8.2.2",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2",
"vite": "^5.0.0",
diff --git a/examples/react/src/backend/registry.ts b/examples/react/src/backend/registry.ts
index de9d21a60..854e1bb74 100644
--- a/examples/react/src/backend/registry.ts
+++ b/examples/react/src/backend/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -15,7 +15,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/examples/react/src/frontend/App.tsx b/examples/react/src/frontend/App.tsx
index a65a3cabf..97a1c0eef 100644
--- a/examples/react/src/frontend/App.tsx
+++ b/examples/react/src/frontend/App.tsx
@@ -3,13 +3,13 @@
// import type { Registry } from "../backend/registry";
//
// const client = createClient(`http://localhost:6420/registry`);
-// const { useWorker } = createRivetKit(client);
+// const { useActor } = createRivetKit(client);
//
// function App() {
// const [count, setCount] = useState(0);
// const [counterName, setCounterName] = useState("test-counter");
//
-// const counter = useWorker({
+// const counter = useActor({
// name: "counter",
// key: [counterName],
// });
diff --git a/examples/rivet/README.md b/examples/rivet/README.md
index 62a27648f..5b0bcd942 100644
--- a/examples/rivet/README.md
+++ b/examples/rivet/README.md
@@ -43,7 +43,7 @@ This will start the RivetKit server locally at http://localhost:6420.
### Testing the Client
-In a separate terminal, run the client script to interact with your workers:
+In a separate terminal, run the client script to interact with your actors:
```sh
npm run client
@@ -57,7 +57,7 @@ Deploy to Rivet Cloud:
rivet deploy
```
-Your RivetKit workers will be deployed as Rivet actors with automatic scaling and management.
+Your RivetKit actors will be deployed as Rivet actors with automatic scaling and management.
## License
diff --git a/examples/rivet/package.json b/examples/rivet/package.json
index 9999a8d03..01b508ddb 100644
--- a/examples/rivet/package.json
+++ b/examples/rivet/package.json
@@ -14,7 +14,7 @@
"typescript": "^5.5.2"
},
"dependencies": {
- "@rivetkit/worker": "https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/worker@38d8fca"
+ "@rivetkit/actor": "workspace:*"
},
"stableVersion": "0.8.0"
}
diff --git a/examples/rivet/scripts/client.ts b/examples/rivet/scripts/client.ts
index 860099971..9472eb28c 100644
--- a/examples/rivet/scripts/client.ts
+++ b/examples/rivet/scripts/client.ts
@@ -1,4 +1,4 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { execSync } from "node:child_process";
import type { registry } from "../src/registry.js";
diff --git a/examples/rivet/src/registry.ts b/examples/rivet/src/registry.ts
index bcb929459..4d0a85af7 100644
--- a/examples/rivet/src/registry.ts
+++ b/examples/rivet/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,6 +14,6 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
diff --git a/examples/snippets/ai-agent/App.tsx b/examples/snippets/ai-agent/App.tsx
index 39a31ef88..db1d67473 100644
--- a/examples/snippets/ai-agent/App.tsx
+++ b/examples/snippets/ai-agent/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
import type { Message } from "./actor";
const client = createClient("http://localhost:6420");
diff --git a/examples/snippets/ai-agent/actor-json.ts b/examples/snippets/ai-agent/actor-json.ts
index 5d5ede675..2588cb84e 100644
--- a/examples/snippets/ai-agent/actor-json.ts
+++ b/examples/snippets/ai-agent/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { getWeather } from "./my-utils";
diff --git a/examples/snippets/ai-agent/actor-sqlite.ts b/examples/snippets/ai-agent/actor-sqlite.ts
index 61ed3ce46..2877282cf 100644
--- a/examples/snippets/ai-agent/actor-sqlite.ts
+++ b/examples/snippets/ai-agent/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
diff --git a/examples/snippets/chat-room/App.tsx b/examples/snippets/chat-room/App.tsx
index 8735e5a96..8371e4589 100644
--- a/examples/snippets/chat-room/App.tsx
+++ b/examples/snippets/chat-room/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
import type { Message } from "./actor";
const client = createClient("http://localhost:6420");
diff --git a/examples/snippets/chat-room/actor-json.ts b/examples/snippets/chat-room/actor-json.ts
index b6c9e0b02..8b279f4f4 100644
--- a/examples/snippets/chat-room/actor-json.ts
+++ b/examples/snippets/chat-room/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
export type Message = { sender: string; text: string; timestamp: number; }
diff --git a/examples/snippets/chat-room/actor-sqlite.ts b/examples/snippets/chat-room/actor-sqlite.ts
index ad922290d..de9f9281a 100644
--- a/examples/snippets/chat-room/actor-sqlite.ts
+++ b/examples/snippets/chat-room/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { messages } from "./schema";
diff --git a/examples/snippets/crdt/App.tsx b/examples/snippets/crdt/App.tsx
index e37bc7b6d..a00dea4b4 100644
--- a/examples/snippets/crdt/App.tsx
+++ b/examples/snippets/crdt/App.tsx
@@ -1,9 +1,9 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect, useRef } from "react";
import * as Y from 'yjs';
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
const client = createClient("http://localhost:6420");
const { useActor, useActorEvent } = createReactRivetKit(client);
diff --git a/examples/snippets/crdt/actor-json.ts b/examples/snippets/crdt/actor-json.ts
index a50f34d6c..0ec15a6aa 100644
--- a/examples/snippets/crdt/actor-json.ts
+++ b/examples/snippets/crdt/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import * as Y from 'yjs';
import { encodeStateAsUpdate, applyUpdate } from 'yjs';
diff --git a/examples/snippets/crdt/actor-sqlite.ts b/examples/snippets/crdt/actor-sqlite.ts
index a99acde4c..0a6c20463 100644
--- a/examples/snippets/crdt/actor-sqlite.ts
+++ b/examples/snippets/crdt/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import * as Y from 'yjs';
import { encodeStateAsUpdate, applyUpdate } from 'yjs';
diff --git a/examples/snippets/database/App.tsx b/examples/snippets/database/App.tsx
index 637445f81..299e2344e 100644
--- a/examples/snippets/database/App.tsx
+++ b/examples/snippets/database/App.tsx
@@ -1,4 +1,4 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
diff --git a/examples/snippets/database/actor-json.ts b/examples/snippets/database/actor-json.ts
index 9761bdf35..3fe717717 100644
--- a/examples/snippets/database/actor-json.ts
+++ b/examples/snippets/database/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { authenticate } from "./my-utils";
export type Note = { id: string; content: string; updatedAt: number };
diff --git a/examples/snippets/database/actor-sqlite.ts b/examples/snippets/database/actor-sqlite.ts
index 41f1f974b..d316f2bfa 100644
--- a/examples/snippets/database/actor-sqlite.ts
+++ b/examples/snippets/database/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { notes } from "./schema";
import { authenticate } from "./my-utils";
diff --git a/examples/snippets/document/App.tsx b/examples/snippets/document/App.tsx
index 03f00c7ca..cb0031e7a 100644
--- a/examples/snippets/document/App.tsx
+++ b/examples/snippets/document/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
const client = createClient("http://localhost:6420");
const { useActor, useActorEvent } = createReactRivetKit(client);
diff --git a/examples/snippets/document/actor-json.ts b/examples/snippets/document/actor-json.ts
index 9fd4c668e..928835d46 100644
--- a/examples/snippets/document/actor-json.ts
+++ b/examples/snippets/document/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
export type Cursor = { x: number, y: number, userId: string };
diff --git a/examples/snippets/document/actor-sqlite.ts b/examples/snippets/document/actor-sqlite.ts
index a65d8a0a2..2c34de513 100644
--- a/examples/snippets/document/actor-sqlite.ts
+++ b/examples/snippets/document/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { documents, cursors } from "./schema";
diff --git a/examples/snippets/game/App.tsx b/examples/snippets/game/App.tsx
index 4122f81bc..43eea65bb 100644
--- a/examples/snippets/game/App.tsx
+++ b/examples/snippets/game/App.tsx
@@ -1,4 +1,4 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect, useRef } from "react";
import type { Player } from "./actor";
diff --git a/examples/snippets/game/actor-json.ts b/examples/snippets/game/actor-json.ts
index 739de59dd..088f20c42 100644
--- a/examples/snippets/game/actor-json.ts
+++ b/examples/snippets/game/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
export type Position = { x: number; y: number };
export type Input = { x: number; y: number };
diff --git a/examples/snippets/game/actor-sqlite.ts b/examples/snippets/game/actor-sqlite.ts
index 22e93635e..b58a4f88d 100644
--- a/examples/snippets/game/actor-sqlite.ts
+++ b/examples/snippets/game/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { players, gameSettings } from "./schema";
diff --git a/examples/snippets/rate/App.tsx b/examples/snippets/rate/App.tsx
index b54a99047..a21624c06 100644
--- a/examples/snippets/rate/App.tsx
+++ b/examples/snippets/rate/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
const client = createClient("http://localhost:6420");
const { useActor } = createReactRivetKit(client);
diff --git a/examples/snippets/rate/actor-json.ts b/examples/snippets/rate/actor-json.ts
index b06432d19..41570cfb8 100644
--- a/examples/snippets/rate/actor-json.ts
+++ b/examples/snippets/rate/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
// Simple rate limiter - allows 5 requests per minute
const rateLimiter = actor({
diff --git a/examples/snippets/rate/actor-sqlite.ts b/examples/snippets/rate/actor-sqlite.ts
index ace413872..374571216 100644
--- a/examples/snippets/rate/actor-sqlite.ts
+++ b/examples/snippets/rate/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { limiters } from "./schema";
diff --git a/examples/snippets/stream/App.tsx b/examples/snippets/stream/App.tsx
index 21f4de62f..ebd3a37b5 100644
--- a/examples/snippets/stream/App.tsx
+++ b/examples/snippets/stream/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
import type { StreamState } from "./actor"; // Import shared types from actor
const client = createClient("http://localhost:6420");
diff --git a/examples/snippets/stream/actor-json.ts b/examples/snippets/stream/actor-json.ts
index ba49b271e..63bfb3526 100644
--- a/examples/snippets/stream/actor-json.ts
+++ b/examples/snippets/stream/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
export type StreamState = {
topValues: number[];
diff --git a/examples/snippets/stream/actor-sqlite.ts b/examples/snippets/stream/actor-sqlite.ts
index ae7bd64f0..31356f685 100644
--- a/examples/snippets/stream/actor-sqlite.ts
+++ b/examples/snippets/stream/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { streams, streamValues } from "./schema";
diff --git a/examples/snippets/sync/App.tsx b/examples/snippets/sync/App.tsx
index ab6283ddb..0cb5a1300 100644
--- a/examples/snippets/sync/App.tsx
+++ b/examples/snippets/sync/App.tsx
@@ -1,4 +1,4 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect, useRef } from "react";
import type { Contact } from "./actor";
diff --git a/examples/snippets/sync/actor-json.ts b/examples/snippets/sync/actor-json.ts
index 656904868..a723d2c24 100644
--- a/examples/snippets/sync/actor-json.ts
+++ b/examples/snippets/sync/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
export type Contact = { id: string; name: string; email: string; phone: string; updatedAt: number; }
diff --git a/examples/snippets/sync/actor-sqlite.ts b/examples/snippets/sync/actor-sqlite.ts
index 25d88f81a..638ffeae0 100644
--- a/examples/snippets/sync/actor-sqlite.ts
+++ b/examples/snippets/sync/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { contacts } from "./schema";
diff --git a/examples/snippets/tenant/App.tsx b/examples/snippets/tenant/App.tsx
index 0f0cf9dc8..2f4b0971e 100644
--- a/examples/snippets/tenant/App.tsx
+++ b/examples/snippets/tenant/App.tsx
@@ -1,7 +1,7 @@
-import { createClient } from "@rivetkit/worker/client";
+import { createClient } from "@rivetkit/actor/client";
import { createReactRivetKit } from "@rivetkit/react";
import { useState, useEffect } from "react";
-import type { Registry } from "../workers/registry";
+import type { Registry } from "../actors/registry";
// Create client and hooks
const client = createClient("http://localhost:6420");
diff --git a/examples/snippets/tenant/actor-json.ts b/examples/snippets/tenant/actor-json.ts
index d09cf4ebb..1d6c54172 100644
--- a/examples/snippets/tenant/actor-json.ts
+++ b/examples/snippets/tenant/actor-json.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { authenticate } from "./my-utils";
// Simple tenant organization actor
diff --git a/examples/snippets/tenant/actor-sqlite.ts b/examples/snippets/tenant/actor-sqlite.ts
index eab708652..954ebf8ae 100644
--- a/examples/snippets/tenant/actor-sqlite.ts
+++ b/examples/snippets/tenant/actor-sqlite.ts
@@ -1,4 +1,4 @@
-import { actor } from "@rivetkit/worker";
+import { actor } from "@rivetkit/actor";
import { drizzle } from "@rivetkit/drizzle";
import { members, invoices } from "./schema";
import { authenticate } from "./my-utils";
diff --git a/examples/trpc/package.json b/examples/trpc/package.json
index 7a360d443..c9a7cb014 100644
--- a/examples/trpc/package.json
+++ b/examples/trpc/package.json
@@ -10,7 +10,7 @@
},
"devDependencies": {
"@types/node": "^22.13.9",
- "@rivetkit/worker": "workspace:*",
+ "@rivetkit/actor": "workspace:*",
"tsx": "^3.12.7",
"typescript": "^5.5.2"
},
diff --git a/examples/trpc/scripts/client.ts b/examples/trpc/scripts/client.ts
index fbbee233c..f87ec1703 100644
--- a/examples/trpc/scripts/client.ts
+++ b/examples/trpc/scripts/client.ts
@@ -1,34 +1,34 @@
-import { createTRPCClient, httpBatchLink } from "@trpc/client";
-import type { AppRouter } from "../src/server.js";
-
-// Create tRPC client
-const client = createTRPCClient({
- links: [
- httpBatchLink({
- url: "http://localhost:3001",
- }),
- ],
-});
-
-async function main() {
- console.log("🚀 tRPC Client Demo");
-
- try {
- // Increment counter
- console.log("Incrementing counter 'demo'...");
- const result = await client.increment.mutate({ name: "demo" });
- console.log("New count:", result);
-
- // Increment again
- console.log("Incrementing counter 'demo' again...");
- const result2 = await client.increment.mutate({ name: "demo" });
- console.log("New count:", result2);
-
- console.log("✅ Demo completed!");
- } catch (error) {
- console.error("❌ Error:", error);
- process.exit(1);
- }
-}
-
-main().catch(console.error);
+// import { createTRPCClient, httpBatchLink } from "@trpc/client";
+// import type { AppRouter } from "../src/server.js";
+//
+// // Create tRPC client
+// const client = createTRPCClient({
+// links: [
+// httpBatchLink({
+// url: "http://localhost:3001",
+// }),
+// ],
+// });
+//
+// async function main() {
+// console.log("🚀 tRPC Client Demo");
+//
+// try {
+// // Increment counter
+// console.log("Incrementing counter 'demo'...");
+// const result = await client.increment.mutate({ name: "demo" });
+// console.log("New count:", result);
+//
+// // Increment again
+// console.log("Incrementing counter 'demo' again...");
+// const result2 = await client.increment.mutate({ name: "demo" });
+// console.log("New count:", result2);
+//
+// console.log("✅ Demo completed!");
+// } catch (error) {
+// console.error("❌ Error:", error);
+// process.exit(1);
+// }
+// }
+//
+// main().catch(console.error);
diff --git a/examples/trpc/src/registry.ts b/examples/trpc/src/registry.ts
index 84f7d059b..4c0f83a0f 100644
--- a/examples/trpc/src/registry.ts
+++ b/examples/trpc/src/registry.ts
@@ -1,6 +1,6 @@
-import { worker, setup } from "@rivetkit/worker";
+import { actor, setup } from "@rivetkit/actor";
-export const counter = worker({
+export const counter = actor({
onAuth: () => {
// Configure auth here
},
@@ -14,7 +14,7 @@ export const counter = worker({
});
export const registry = setup({
- workers: { counter },
+ actors: { counter },
});
export type Registry = typeof registry;
diff --git a/packages/worker/package.json b/packages/actor/package.json
similarity index 97%
rename from packages/worker/package.json
rename to packages/actor/package.json
index 48b337b65..e5f8cf3b7 100644
--- a/packages/worker/package.json
+++ b/packages/actor/package.json
@@ -1,9 +1,9 @@
{
- "name": "@rivetkit/worker",
+ "name": "@rivetkit/actor",
"version": "0.9.0-rc.1",
"keywords": [
"rivetkit",
- "worker",
+ "actor",
"stateful",
"actor",
"rpc",
diff --git a/packages/worker/src/client.ts b/packages/actor/src/client.ts
similarity index 100%
rename from packages/worker/src/client.ts
rename to packages/actor/src/client.ts
diff --git a/packages/worker/src/drivers/rivet.ts b/packages/actor/src/drivers/rivet.ts
similarity index 100%
rename from packages/worker/src/drivers/rivet.ts
rename to packages/actor/src/drivers/rivet.ts
diff --git a/packages/worker/src/errors.ts b/packages/actor/src/errors.ts
similarity index 100%
rename from packages/worker/src/errors.ts
rename to packages/actor/src/errors.ts
diff --git a/packages/worker/src/log.ts b/packages/actor/src/log.ts
similarity index 100%
rename from packages/worker/src/log.ts
rename to packages/actor/src/log.ts
diff --git a/packages/worker/src/mod.ts b/packages/actor/src/mod.ts
similarity index 100%
rename from packages/worker/src/mod.ts
rename to packages/actor/src/mod.ts
diff --git a/packages/worker/src/test.ts b/packages/actor/src/test.ts
similarity index 100%
rename from packages/worker/src/test.ts
rename to packages/actor/src/test.ts
diff --git a/packages/worker/tsconfig.json b/packages/actor/tsconfig.json
similarity index 100%
rename from packages/worker/tsconfig.json
rename to packages/actor/tsconfig.json
diff --git a/packages/worker/tsup.config.ts b/packages/actor/tsup.config.ts
similarity index 100%
rename from packages/worker/tsup.config.ts
rename to packages/actor/tsup.config.ts
diff --git a/packages/worker/turbo.json b/packages/actor/turbo.json
similarity index 100%
rename from packages/worker/turbo.json
rename to packages/actor/turbo.json
diff --git a/packages/core/fixtures/driver-test-suite/action-inputs.ts b/packages/core/fixtures/driver-test-suite/action-inputs.ts
new file mode 100644
index 000000000..fd4caa654
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/action-inputs.ts
@@ -0,0 +1,31 @@
+import { actor } from "@rivetkit/core";
+
+export interface State {
+ initialInput?: unknown;
+ onCreateInput?: unknown;
+}
+
+// Test actor that can capture input during creation
+export const inputActor = actor({
+ onAuth: () => {},
+ createState: (c, { input }): State => {
+ return {
+ initialInput: input,
+ onCreateInput: undefined,
+ };
+ },
+
+ onCreate: (c, { input }) => {
+ c.state.onCreateInput = input;
+ },
+
+ actions: {
+ getInputs: (c) => {
+ return {
+ initialInput: c.state.initialInput,
+ onCreateInput: c.state.onCreateInput,
+ };
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/action-timeout.ts b/packages/core/fixtures/driver-test-suite/action-timeout.ts
index 598d47e8e..f3b32ffa7 100644
--- a/packages/core/fixtures/driver-test-suite/action-timeout.ts
+++ b/packages/core/fixtures/driver-test-suite/action-timeout.ts
@@ -1,7 +1,7 @@
-import { worker } from "rivetkit";
+import { actor } from "@rivetkit/core";
-// Short timeout worker
-export const shortTimeoutWorker = worker({
+// Short timeout actor
+export const shortTimeoutActor = actor({
onAuth: () => {},
state: { value: 0 },
options: {
@@ -21,8 +21,8 @@ export const shortTimeoutWorker = worker({
},
});
-// Long timeout worker
-export const longTimeoutWorker = worker({
+// Long timeout actor
+export const longTimeoutActor = actor({
onAuth: () => {},
state: { value: 0 },
options: {
@@ -39,8 +39,8 @@ export const longTimeoutWorker = worker({
},
});
-// Default timeout worker
-export const defaultTimeoutWorker = worker({
+// Default timeout actor
+export const defaultTimeoutActor = actor({
onAuth: () => {},
state: { value: 0 },
actions: {
@@ -51,8 +51,8 @@ export const defaultTimeoutWorker = worker({
},
});
-// Sync worker (timeout shouldn't apply)
-export const syncTimeoutWorker = worker({
+// Sync actor (timeout shouldn't apply)
+export const syncTimeoutActor = actor({
onAuth: () => {},
state: { value: 0 },
options: {
@@ -66,3 +66,5 @@ export const syncTimeoutWorker = worker({
},
},
});
+
+
diff --git a/packages/core/fixtures/driver-test-suite/action-types.ts b/packages/core/fixtures/driver-test-suite/action-types.ts
new file mode 100644
index 000000000..da34b99e7
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/action-types.ts
@@ -0,0 +1,86 @@
+import { actor, UserError } from "@rivetkit/core";
+
+// Actor with synchronous actions
+export const syncActionActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ actions: {
+ // Simple synchronous action that returns a value directly
+ increment: (c, amount: number = 1) => {
+ c.state.value += amount;
+ return c.state.value;
+ },
+ // Synchronous action that returns an object
+ getInfo: (c) => {
+ return {
+ currentValue: c.state.value,
+ timestamp: Date.now(),
+ };
+ },
+ // Synchronous action with no return value (void)
+ reset: (c) => {
+ c.state.value = 0;
+ },
+ },
+});
+
+// Actor with asynchronous actions
+export const asyncActionActor = actor({
+ onAuth: () => {},
+ state: { value: 0, data: null as any },
+ actions: {
+ // Async action with a delay
+ delayedIncrement: async (c, amount: number = 1) => {
+ await Promise.resolve();
+ c.state.value += amount;
+ return c.state.value;
+ },
+ // Async action that simulates an API call
+ fetchData: async (c, id: string) => {
+ await Promise.resolve();
+
+ // Simulate response data
+ const data = { id, timestamp: Date.now() };
+ c.state.data = data;
+ return data;
+ },
+ // Async action with error handling
+ asyncWithError: async (c, shouldError: boolean) => {
+ await Promise.resolve();
+
+ if (shouldError) {
+ throw new UserError("Intentional error");
+ }
+
+ return "Success";
+ },
+ },
+});
+
+// Actor with promise actions
+export const promiseActor = actor({
+ onAuth: () => {},
+ state: { results: [] as string[] },
+ actions: {
+ // Action that returns a resolved promise
+ resolvedPromise: (c) => {
+ return Promise.resolve("resolved value");
+ },
+ // Action that returns a promise that resolves after a delay
+ delayedPromise: (c): Promise => {
+ return new Promise((resolve) => {
+ c.state.results.push("delayed");
+ resolve("delayed value");
+ });
+ },
+ // Action that returns a rejected promise
+ rejectedPromise: (c) => {
+ return Promise.reject(new UserError("promised rejection"));
+ },
+ // Action to check the collected results
+ getResults: (c) => {
+ return c.state.results;
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/auth.ts b/packages/core/fixtures/driver-test-suite/auth.ts
new file mode 100644
index 000000000..b50ef8a0b
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/auth.ts
@@ -0,0 +1,105 @@
+import { actor, UserError } from "@rivetkit/core";
+
+// Basic auth actor - requires API key
+export const authActor = actor({
+ state: { requests: 0 },
+ onAuth: (opts) => {
+ const { req, intents, params } = opts;
+ const apiKey = (params as any)?.apiKey;
+ if (!apiKey) {
+ throw new UserError("API key required", { code: "missing_auth" });
+ }
+
+ if (apiKey !== "valid-api-key") {
+ throw new UserError("Invalid API key", { code: "invalid_auth" });
+ }
+
+ return { userId: "user123", token: apiKey };
+ },
+ actions: {
+ getRequests: (c) => {
+ c.state.requests++;
+ return c.state.requests;
+ },
+ getUserAuth: (c) => c.conn.auth,
+ },
+});
+
+// Intent-specific auth actor - checks different permissions for different intents
+export const intentAuthActor = actor({
+ state: { value: 0 },
+ onAuth: (opts) => {
+ const { req, intents, params } = opts;
+ console.log('intents', intents, params);
+ const role = (params as any)?.role;
+
+ if (intents.has("create") && role !== "admin") {
+ throw new UserError("Admin role required for create operations", { code: "insufficient_permissions" });
+ }
+
+ if (intents.has("action") && !["admin", "user"].includes(role || "")) {
+ throw new UserError("User or admin role required for actions", { code: "insufficient_permissions" });
+ }
+
+ return { role, timestamp: Date.now() };
+ },
+ actions: {
+ getValue: (c) => c.state.value,
+ setValue: (c, value: number) => {
+ c.state.value = value;
+ return value;
+ },
+ getAuth: (c) => c.conn.auth,
+ },
+});
+
+// Public actor - empty onAuth to allow public access
+export const publicActor = actor({
+ state: { visitors: 0 },
+ onAuth: () => {
+ return null; // Allow public access
+ },
+ actions: {
+ visit: (c) => {
+ c.state.visitors++;
+ return c.state.visitors;
+ },
+ },
+});
+
+// No auth actor - should fail when accessed publicly (no onAuth defined)
+export const noAuthActor = actor({
+ state: { value: 42 },
+ actions: {
+ getValue: (c) => c.state.value,
+ },
+});
+
+// Async auth actor - tests promise-based authentication
+export const asyncAuthActor = actor({
+ state: { count: 0 },
+ onAuth: async (opts) => {
+ const { req, intents, params } = opts;
+ // Simulate async auth check (e.g., database lookup)
+ await new Promise(resolve => setTimeout(resolve, 10));
+
+ const token = (params as any)?.token;
+ if (!token) {
+ throw new UserError("Token required", { code: "missing_token" });
+ }
+
+ // Simulate token validation
+ if (token === "invalid") {
+ throw new UserError("Token is invalid", { code: "invalid_token" });
+ }
+
+ return { userId: `user-${token}`, validated: true };
+ },
+ actions: {
+ increment: (c) => {
+ c.state.count++;
+ return c.state.count;
+ },
+ getAuthData: (c) => c.conn.auth,
+ },
+});
diff --git a/packages/core/fixtures/driver-test-suite/conn-params.ts b/packages/core/fixtures/driver-test-suite/conn-params.ts
new file mode 100644
index 000000000..352d3fc9c
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/conn-params.ts
@@ -0,0 +1,29 @@
+import { actor } from "@rivetkit/core";
+
+export const counterWithParams = actor({
+ onAuth: () => {},
+ state: { count: 0, initializers: [] as string[] },
+ createConnState: (c, { params }: { params: { name?: string } }) => {
+ return {
+ name: params?.name || "anonymous",
+ };
+ },
+ onConnect: (c, conn) => {
+ // Record connection name
+ c.state.initializers.push(conn.state.name);
+ },
+ actions: {
+ increment: (c, x: number) => {
+ c.state.count += x;
+ c.broadcast("newCount", {
+ count: c.state.count,
+ by: c.conn.state.name,
+ });
+ return c.state.count;
+ },
+ getInitializers: (c) => {
+ return c.state.initializers;
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/conn-state.ts b/packages/core/fixtures/driver-test-suite/conn-state.ts
new file mode 100644
index 000000000..8f7096936
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/conn-state.ts
@@ -0,0 +1,97 @@
+import { actor } from "@rivetkit/core";
+
+export type ConnState = {
+ username: string;
+ role: string;
+ counter: number;
+ createdAt: number;
+};
+
+export const connStateActor = actor({
+ onAuth: () => {},
+ state: {
+ sharedCounter: 0,
+ disconnectionCount: 0,
+ },
+ // Define connection state
+ createConnState: (
+ c,
+ { params }: { params?: { username?: string; role?: string } },
+ ): ConnState => {
+ return {
+ username: params?.username || "anonymous",
+ role: params?.role || "user",
+ counter: 0,
+ createdAt: Date.now(),
+ };
+ },
+ // Lifecycle hook when a connection is established
+ onConnect: (c, conn) => {
+ // Broadcast event about the new connection
+ c.broadcast("userConnected", {
+ id: conn.id,
+ username: "anonymous",
+ role: "user",
+ });
+ },
+ // Lifecycle hook when a connection is closed
+ onDisconnect: (c, conn) => {
+ c.state.disconnectionCount += 1;
+ c.broadcast("userDisconnected", {
+ id: conn.id,
+ });
+ },
+ actions: {
+ // Action to increment the connection's counter
+ incrementConnCounter: (c, amount: number = 1) => {
+ c.conn.state.counter += amount;
+ },
+
+ // Action to increment the shared counter
+ incrementSharedCounter: (c, amount: number = 1) => {
+ c.state.sharedCounter += amount;
+ return c.state.sharedCounter;
+ },
+
+ // Get the connection state
+ getConnectionState: (c) => {
+ return { id: c.conn.id, ...c.conn.state };
+ },
+
+ // Check all active connections
+ getConnectionIds: (c) => {
+ return c.conns.keys().toArray();
+ },
+
+ // Get disconnection count
+ getDisconnectionCount: (c) => {
+ return c.state.disconnectionCount;
+ },
+
+ // Get all active connection states
+ getAllConnectionStates: (c) => {
+ return c.conns.entries().map(([id, conn]) => ({ id, ...conn.state })).toArray();
+ },
+
+ // Send message to a specific connection with matching ID
+ sendToConnection: (c, targetId: string, message: string) => {
+ if (c.conns.has(targetId)) {
+ c.conns.get(targetId)!.send("directMessage", { from: c.conn.id, message });
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ // Update connection state (simulated for tests)
+ updateConnection: (
+ c,
+ updates: Partial<{ username: string; role: string }>,
+ ) => {
+ if (updates.username) c.conn.state.username = updates.username;
+ if (updates.role) c.conn.state.role = updates.role;
+ return c.conn.state;
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/counter.ts b/packages/core/fixtures/driver-test-suite/counter.ts
new file mode 100644
index 000000000..752aec3e4
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/counter.ts
@@ -0,0 +1,16 @@
+import { actor } from "@rivetkit/core";
+
+export const counter = actor({
+ onAuth: () => {},
+ state: { count: 0 },
+ actions: {
+ increment: (c, x: number) => {
+ c.state.count += x;
+ c.broadcast("newCount", c.state.count);
+ return c.state.count;
+ },
+ getCount: (c) => {
+ return c.state.count;
+ },
+ },
+});
diff --git a/packages/core/fixtures/driver-test-suite/error-handling.ts b/packages/core/fixtures/driver-test-suite/error-handling.ts
new file mode 100644
index 000000000..4f91c9a43
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/error-handling.ts
@@ -0,0 +1,98 @@
+import { actor, UserError } from "@rivetkit/core";
+
+export const errorHandlingActor = actor({
+ onAuth: () => {},
+ state: {
+ errorLog: [] as string[],
+ },
+ actions: {
+ // Action that throws a UserError with just a message
+ throwSimpleError: () => {
+ throw new UserError("Simple error message");
+ },
+
+ // Action that throws a UserError with code and metadata
+ throwDetailedError: () => {
+ throw new UserError("Detailed error message", {
+ code: "detailed_error",
+ metadata: {
+ reason: "test",
+ timestamp: Date.now(),
+ },
+ });
+ },
+
+ // Action that throws an internal error
+ throwInternalError: () => {
+ throw new Error("This is an internal error");
+ },
+
+ // Action that returns successfully
+ successfulAction: () => {
+ return "success";
+ },
+
+ // Action that times out (simulated with a long delay)
+ timeoutAction: async (c) => {
+ // This action should time out if the timeout is configured
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve("This should not be reached if timeout works");
+ }, 10000); // 10 seconds
+ });
+ },
+
+ // Action with configurable delay to test timeout edge cases
+ delayedAction: async (c, delayMs: number) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(`Completed after ${delayMs}ms`);
+ }, delayMs);
+ });
+ },
+
+ // Log an error for inspection
+ logError: (c, error: string) => {
+ c.state.errorLog.push(error);
+ return c.state.errorLog;
+ },
+
+ // Get the error log
+ getErrorLog: (c) => {
+ return c.state.errorLog;
+ },
+
+ // Clear the error log
+ clearErrorLog: (c) => {
+ c.state.errorLog = [];
+ return true;
+ },
+ },
+ options: {
+ // Set a short timeout for this actor's actions
+ action: {
+ timeout: 500, // 500ms timeout for actions
+ },
+ },
+});
+
+// Actor with custom timeout
+export const customTimeoutActor = actor({
+ state: {},
+ actions: {
+ quickAction: async () => {
+ await new Promise((resolve) => setTimeout(resolve, 50));
+ return "Quick action completed";
+ },
+ slowAction: async () => {
+ await new Promise((resolve) => setTimeout(resolve, 300));
+ return "Slow action completed";
+ },
+ },
+ options: {
+ action: {
+ timeout: 200, // 200ms timeout
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/lifecycle.ts b/packages/core/fixtures/driver-test-suite/lifecycle.ts
new file mode 100644
index 000000000..23faf6f8b
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/lifecycle.ts
@@ -0,0 +1,37 @@
+import { actor } from "@rivetkit/core";
+
+export const counterWithLifecycle = actor({
+ onAuth: () => {},
+ state: {
+ count: 0,
+ events: [] as string[],
+ },
+ createConnState: (
+ c,
+ opts: { params: { trackLifecycle?: boolean } | undefined },
+ ) => ({
+ joinTime: Date.now(),
+ }),
+ onStart: (c) => {
+ c.state.events.push("onStart");
+ },
+ onBeforeConnect: (c, conn) => {
+ if (conn.params?.trackLifecycle) c.state.events.push("onBeforeConnect");
+ },
+ onConnect: (c, conn) => {
+ if (conn.params?.trackLifecycle) c.state.events.push("onConnect");
+ },
+ onDisconnect: (c, conn) => {
+ if (conn.params?.trackLifecycle) c.state.events.push("onDisconnect");
+ },
+ actions: {
+ getEvents: (c) => {
+ return c.state.events;
+ },
+ increment: (c, x: number) => {
+ c.state.count += x;
+ return c.state.count;
+ },
+ },
+});
+
diff --git a/packages/core/fixtures/driver-test-suite/metadata.ts b/packages/core/fixtures/driver-test-suite/metadata.ts
new file mode 100644
index 000000000..ebba5e6cf
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/metadata.ts
@@ -0,0 +1,78 @@
+import { actor } from "@rivetkit/core";
+
+// Note: For testing only - metadata API will need to be mocked
+// in tests since this is implementation-specific
+export const metadataActor = actor({
+ onAuth: () => {},
+ state: {
+ lastMetadata: null as any,
+ actorName: "",
+ // Store tags and region in state for testing since they may not be
+ // available in the context in all environments
+ storedTags: {} as Record,
+ storedRegion: null as string | null,
+ },
+ onStart: (c) => {
+ // Store the actor name during initialization
+ c.state.actorName = c.name;
+ },
+ actions: {
+ // Set up test tags - this will be called by tests to simulate tags
+ setupTestTags: (c, tags: Record) => {
+ c.state.storedTags = tags;
+ return tags;
+ },
+
+ // Set up test region - this will be called by tests to simulate region
+ setupTestRegion: (c, region: string) => {
+ c.state.storedRegion = region;
+ return region;
+ },
+
+ // Get all available metadata
+ getMetadata: (c) => {
+ // Create metadata object from stored values
+ const metadata = {
+ name: c.name,
+ tags: c.state.storedTags,
+ region: c.state.storedRegion,
+ };
+
+ // Store for later inspection
+ c.state.lastMetadata = metadata;
+ return metadata;
+ },
+
+ // Get the actor name
+ getActorName: (c) => {
+ return c.name;
+ },
+
+ // Get a specific tag by key
+ getTag: (c, key: string) => {
+ return c.state.storedTags[key] || null;
+ },
+
+ // Get all tags
+ getTags: (c) => {
+ return c.state.storedTags;
+ },
+
+ // Get the region
+ getRegion: (c) => {
+ return c.state.storedRegion;
+ },
+
+ // Get the stored actor name (from onStart)
+ getStoredActorName: (c) => {
+ return c.state.actorName;
+ },
+
+ // Get last retrieved metadata
+ getLastMetadata: (c) => {
+ return c.state.lastMetadata;
+ },
+ },
+});
+
+
diff --git a/packages/core/fixtures/driver-test-suite/registry.ts b/packages/core/fixtures/driver-test-suite/registry.ts
new file mode 100644
index 000000000..06bdcca40
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/registry.ts
@@ -0,0 +1,82 @@
+import { setup } from "@rivetkit/core";
+
+// Import actors from individual files
+import { counter } from "./counter";
+import { counterWithLifecycle } from "./lifecycle";
+import { scheduled } from "./scheduled";
+import { errorHandlingActor, customTimeoutActor } from "./error-handling";
+import { inputActor } from "./action-inputs";
+import {
+ shortTimeoutActor,
+ longTimeoutActor,
+ defaultTimeoutActor,
+ syncTimeoutActor,
+} from "./action-timeout";
+import {
+ syncActionActor,
+ asyncActionActor,
+ promiseActor,
+} from "./action-types";
+import { counterWithParams } from "./conn-params";
+import { connStateActor } from "./conn-state";
+import { metadataActor } from "./metadata";
+import {
+ staticVarActor,
+ nestedVarActor,
+ dynamicVarActor,
+ uniqueVarActor,
+ driverCtxActor,
+} from "./vars";
+import {
+ authActor,
+ intentAuthActor,
+ publicActor,
+ noAuthActor,
+ asyncAuthActor,
+} from "./auth";
+
+// Consolidated setup with all actors
+export const registry = setup({
+ actors: {
+ // From counter.ts
+ counter,
+ // From lifecycle.ts
+ counterWithLifecycle,
+ // From scheduled.ts
+ scheduled,
+ // From error-handling.ts
+ errorHandlingActor,
+ customTimeoutActor,
+ // From action-inputs.ts
+ inputActor,
+ // From action-timeout.ts
+ shortTimeoutActor,
+ longTimeoutActor,
+ defaultTimeoutActor,
+ syncTimeoutActor,
+ // From action-types.ts
+ syncActionActor,
+ asyncActionActor,
+ promiseActor,
+ // From conn-params.ts
+ counterWithParams,
+ // From conn-state.ts
+ connStateActor,
+ // From metadata.ts
+ metadataActor,
+ // From vars.ts
+ staticVarActor,
+ nestedVarActor,
+ dynamicVarActor,
+ uniqueVarActor,
+ driverCtxActor,
+ // From auth.ts
+ authActor,
+ intentAuthActor,
+ publicActor,
+ noAuthActor,
+ asyncAuthActor,
+ },
+});
+
+export type Registry = typeof registry;
diff --git a/packages/core/fixtures/driver-test-suite/scheduled.ts b/packages/core/fixtures/driver-test-suite/scheduled.ts
new file mode 100644
index 000000000..58ce8b698
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/scheduled.ts
@@ -0,0 +1,79 @@
+import { actor } from "@rivetkit/core";
+
+export const scheduled = actor({
+ onAuth: () => {},
+ state: {
+ lastRun: 0,
+ scheduledCount: 0,
+ taskHistory: [] as string[],
+ },
+ actions: {
+ // Schedule using 'at' with specific timestamp
+ scheduleTaskAt: (c, timestamp: number) => {
+ c.schedule.at(timestamp, "onScheduledTask");
+ return timestamp;
+ },
+
+ // Schedule using 'after' with delay
+ scheduleTaskAfter: (c, delayMs: number) => {
+ c.schedule.after(delayMs, "onScheduledTask");
+ return Date.now() + delayMs;
+ },
+
+ // Schedule with a task ID for ordering tests
+ scheduleTaskAfterWithId: (c, taskId: string, delayMs: number) => {
+ c.schedule.after(delayMs, "onScheduledTaskWithId", taskId);
+ return { taskId, scheduledFor: Date.now() + delayMs };
+ },
+
+ // Original method for backward compatibility
+ scheduleTask: (c, delayMs: number) => {
+ const timestamp = Date.now() + delayMs;
+ c.schedule.at(timestamp, "onScheduledTask");
+ return timestamp;
+ },
+
+ // Getters for state
+ getLastRun: (c) => {
+ return c.state.lastRun;
+ },
+
+ getScheduledCount: (c) => {
+ return c.state.scheduledCount;
+ },
+
+ getTaskHistory: (c) => {
+ return c.state.taskHistory;
+ },
+
+ clearHistory: (c) => {
+ c.state.taskHistory = [];
+ c.state.scheduledCount = 0;
+ c.state.lastRun = 0;
+ return true;
+ },
+
+ // Scheduled task handlers
+ onScheduledTask: (c) => {
+ c.state.lastRun = Date.now();
+ c.state.scheduledCount++;
+ c.broadcast("scheduled", {
+ time: c.state.lastRun,
+ count: c.state.scheduledCount,
+ });
+ },
+
+ onScheduledTaskWithId: (c, taskId: string) => {
+ c.state.lastRun = Date.now();
+ c.state.scheduledCount++;
+ c.state.taskHistory.push(taskId);
+ c.broadcast("scheduledWithId", {
+ taskId,
+ time: c.state.lastRun,
+ count: c.state.scheduledCount,
+ });
+ },
+ },
+});
+
+
diff --git a/packages/core/fixtures/driver-test-suite/vars.ts b/packages/core/fixtures/driver-test-suite/vars.ts
new file mode 100644
index 000000000..e5deb77d6
--- /dev/null
+++ b/packages/core/fixtures/driver-test-suite/vars.ts
@@ -0,0 +1,98 @@
+import { actor } from "@rivetkit/core";
+
+// Actor with static vars
+export const staticVarActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ connState: { hello: "world" },
+ vars: { counter: 42, name: "test-actor" },
+ actions: {
+ getVars: (c) => {
+ return c.vars;
+ },
+ getName: (c) => {
+ return c.vars.name;
+ },
+ },
+});
+
+// Actor with nested vars
+export const nestedVarActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ connState: { hello: "world" },
+ vars: {
+ counter: 42,
+ nested: {
+ value: "original",
+ array: [1, 2, 3],
+ obj: { key: "value" },
+ },
+ },
+ actions: {
+ getVars: (c) => {
+ return c.vars;
+ },
+ modifyNested: (c) => {
+ // Attempt to modify the nested object
+ c.vars.nested.value = "modified";
+ c.vars.nested.array.push(4);
+ c.vars.nested.obj.key = "new-value";
+ return c.vars;
+ },
+ },
+});
+
+// Actor with dynamic vars
+export const dynamicVarActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ connState: { hello: "world" },
+ createVars: () => {
+ return {
+ random: Math.random(),
+ computed: `Actor-${Math.floor(Math.random() * 1000)}`,
+ };
+ },
+ actions: {
+ getVars: (c) => {
+ return c.vars;
+ },
+ },
+});
+
+// Actor with unique vars per instance
+export const uniqueVarActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ connState: { hello: "world" },
+ createVars: () => {
+ return {
+ id: Math.floor(Math.random() * 1000000),
+ };
+ },
+ actions: {
+ getVars: (c) => {
+ return c.vars;
+ },
+ },
+});
+
+// Actor that uses driver context
+export const driverCtxActor = actor({
+ onAuth: () => {},
+ state: { value: 0 },
+ connState: { hello: "world" },
+ createVars: (c, driverCtx: any) => {
+ return {
+ hasDriverCtx: Boolean(driverCtx?.isTest),
+ };
+ },
+ actions: {
+ getVars: (c) => {
+ return c.vars;
+ },
+ },
+});
+
+
diff --git a/packages/core/package.json b/packages/core/package.json
index e90a30375..1c66882af 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -6,7 +6,7 @@
"rivetkit",
"stateful",
"serverless",
- "workers",
+ "actors",
"agents",
"realtime",
"websocket",
@@ -48,12 +48,12 @@
},
"./errors": {
"import": {
- "types": "./dist/worker/errors.d.ts",
- "default": "./dist/worker/errors.js"
+ "types": "./dist/actor/errors.d.ts",
+ "default": "./dist/actor/errors.js"
},
"require": {
- "types": "./dist/worker/errors.d.cts",
- "default": "./dist/worker/errors.cjs"
+ "types": "./dist/actor/errors.d.cts",
+ "default": "./dist/actor/errors.cjs"
}
},
"./utils": {
@@ -143,7 +143,7 @@
"sideEffects": false,
"scripts": {
"dev": "pnpm build --watch",
- "build": "tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/worker/errors.ts src/topologies/coordinate/mod.ts src/topologies/partition/mod.ts src/utils.ts src/drivers/rivet/mod.ts src/driver-helpers/mod.ts src/driver-test-suite/mod.ts src/test/mod.ts",
+ "build": "tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/topologies/coordinate/mod.ts src/topologies/partition/mod.ts src/utils.ts src/drivers/rivet/mod.ts src/driver-helpers/mod.ts src/driver-test-suite/mod.ts src/test/mod.ts",
"check-types": "tsc --noEmit",
"boop": "tsc --outDir dist/test -d",
"test": "vitest run",
diff --git a/packages/core/scripts/dump-openapi.ts b/packages/core/scripts/dump-openapi.ts
index d77872eb9..66eb7642b 100644
--- a/packages/core/scripts/dump-openapi.ts
+++ b/packages/core/scripts/dump-openapi.ts
@@ -1,9 +1,9 @@
import { createManagerRouter } from "@/manager/router";
import { RegistryConfig, RegistryConfigSchema, Encoding, setup } from "@/mod";
-import { ConnectionHandlers } from "@/worker/router-endpoints";
+import { ConnectionHandlers } from "@/actor/router-endpoints";
import {
TestGlobalState,
- TestWorkerDriver,
+ TestActorDriver,
TestManagerDriver,
} from "@/test/driver/mod";
import { OpenAPIHono } from "@hono/zod-openapi";
@@ -11,8 +11,8 @@ import { VERSION } from "@/utils";
import * as fs from "node:fs/promises";
import { resolve } from "node:path";
import { ClientDriver } from "@/client/client";
-import { WorkerQuery } from "@/manager/protocol/query";
-import { ToServer } from "@/worker/protocol/message/to-server";
+import { ActorQuery } from "@/manager/protocol/query";
+import { ToServer } from "@/actor/protocol/message/to-server";
import { EventSource } from "eventsource";
import { Context } from "hono";
import {
@@ -23,7 +23,7 @@ import {
function main() {
const registryConfig: RegistryConfig = RegistryConfigSchema.parse({
- workers: {},
+ actors: {},
});
const registry = setup(registryConfig);
@@ -31,7 +31,7 @@ function main() {
const driverConfig: RunConfig = RunConfigSchema.parse({
driver: {
topology: "standalone",
- worker: new TestWorkerDriver(memoryState),
+ actor: new TestActorDriver(memoryState),
manager: new TestManagerDriver(memoryState),
},
getUpgradeWebSocket: () => () => unimplemented(),
@@ -54,7 +54,7 @@ function main() {
const inlineClientDriver: ClientDriver = {
action: unimplemented,
- resolveWorkerId: unimplemented,
+ resolveActorId: unimplemented,
connectWebSocket: unimplemented,
connectSse: unimplemented,
sendHttpMessage: unimplemented,
diff --git a/packages/core/src/worker/action.ts b/packages/core/src/actor/action.ts
similarity index 56%
rename from packages/core/src/worker/action.ts
rename to packages/core/src/actor/action.ts
index ed9f49119..d2addd431 100644
--- a/packages/core/src/worker/action.ts
+++ b/packages/core/src/actor/action.ts
@@ -1,120 +1,120 @@
import type { Conn } from "./connection";
import type { Logger } from "@/common/log";
-import type { WorkerKey } from "@/common/utils";
+import type { ActorKey } from "@/common/utils";
import type { Schedule } from "./schedule";
import type { ConnId } from "./connection";
import type { SaveStateOptions } from "./instance";
-import type { WorkerContext } from "./context";
+import type { ActorContext } from "./context";
/**
* Context for a remote procedure call.
*
- * @typeParam A Worker this action belongs to
+ * @typeParam A Actor this action belongs to
*/
export class ActionContext {
- #workerContext: WorkerContext;
+ #actorContext: ActorContext;
/**
* Should not be called directly.
*
- * @param workerContext - The worker context
+ * @param actorContext - The actor context
* @param conn - The connection associated with the action
*/
constructor(
- workerContext: WorkerContext,
+ actorContext: ActorContext,
public readonly conn: Conn,
) {
- this.#workerContext = workerContext;
+ this.#actorContext = actorContext;
}
/**
- * Get the worker state
+ * Get the actor state
*/
get state(): S {
- return this.#workerContext.state;
+ return this.#actorContext.state;
}
/**
- * Get the worker variables
+ * Get the actor variables
*/
get vars(): V {
- return this.#workerContext.vars;
+ return this.#actorContext.vars;
}
/**
* Broadcasts an event to all connected clients.
*/
broadcast(name: string, ...args: any[]): void {
- this.#workerContext.broadcast(name, ...args);
+ this.#actorContext.broadcast(name, ...args);
}
/**
* Gets the logger instance.
*/
get log(): Logger {
- return this.#workerContext.log;
+ return this.#actorContext.log;
}
/**
- * Gets worker ID.
+ * Gets actor ID.
*/
- get workerId(): string {
- return this.#workerContext.workerId;
+ get actorId(): string {
+ return this.#actorContext.actorId;
}
/**
- * Gets the worker name.
+ * Gets the actor name.
*/
get name(): string {
- return this.#workerContext.name;
+ return this.#actorContext.name;
}
/**
- * Gets the worker key.
+ * Gets the actor key.
*/
- get key(): WorkerKey {
- return this.#workerContext.key;
+ get key(): ActorKey {
+ return this.#actorContext.key;
}
/**
* Gets the region.
*/
get region(): string {
- return this.#workerContext.region;
+ return this.#actorContext.region;
}
/**
* Gets the scheduler.
*/
get schedule(): Schedule {
- return this.#workerContext.schedule;
+ return this.#actorContext.schedule;
}
/**
* Gets the map of connections.
*/
get conns(): Map> {
- return this.#workerContext.conns;
+ return this.#actorContext.conns;
}
/**
* @experimental
*/
get db(): DB {
- return this.#workerContext.db;
+ return this.#actorContext.db;
}
/**
* Forces the state to get saved.
*/
async saveState(opts: SaveStateOptions): Promise {
- return this.#workerContext.saveState(opts);
+ return this.#actorContext.saveState(opts);
}
/**
* Runs a promise in the background.
*/
runInBackground(promise: Promise): void {
- return this.#workerContext.runInBackground(promise);
+ return this.#actorContext.runInBackground(promise);
}
}
diff --git a/packages/core/src/worker/config.ts b/packages/core/src/actor/config.ts
similarity index 78%
rename from packages/core/src/worker/config.ts
rename to packages/core/src/actor/config.ts
index 8a6aeb917..cf178c500 100644
--- a/packages/core/src/worker/config.ts
+++ b/packages/core/src/actor/config.ts
@@ -1,14 +1,14 @@
import type { Conn } from "./connection";
import type { ActionContext } from "./action";
-import type { WorkerContext } from "./context";
+import type { ActorContext } from "./context";
import { z } from "zod";
-// This schema is used to validate the input at runtime. The generic types are defined below in `WorkerConfig`.
+// This schema is used to validate the input at runtime. The generic types are defined below in `ActorConfig`.
//
// We don't use Zod generics with `z.custom` because:
// (a) there seems to be a weird bug in either Zod, tsup, or TSC that causese external packages to have different types from `z.infer` than from within the same package and
// (b) it makes the type definitions incredibly difficult to read as opposed to vanilla TypeScript.
-export const WorkerConfigSchema = z
+export const ActorConfigSchema = z
.object({
onAuth: z.function().optional(),
onCreate: z.function().optional(),
@@ -103,7 +103,7 @@ type CreateState =
| { state: S }
| {
createState: (
- c: WorkerContext<
+ c: ActorContext<
undefined,
undefined,
undefined,
@@ -126,7 +126,7 @@ type CreateConnState =
| { connState: CS }
| {
createConnState: (
- c: WorkerContext<
+ c: ActorContext<
undefined,
undefined,
undefined,
@@ -158,7 +158,7 @@ type CreateVars =
* @experimental
*/
createVars: (
- c: WorkerContext<
+ c: ActorContext<
undefined,
undefined,
undefined,
@@ -179,8 +179,8 @@ export interface Actions {
) => any;
}
-//export type WorkerConfig = BaseWorkerConfig &
-// WorkerConfigLifecycle &
+//export type ActorConfig = BaseActorConfig &
+// ActorConfigLifecycle &
// CreateState &
// CreateConnState;
@@ -198,7 +198,7 @@ interface OnAuthOptions {
params: CP;
}
-interface BaseWorkerConfig<
+interface BaseActorConfig<
S,
CP,
CS,
@@ -209,55 +209,55 @@ interface BaseWorkerConfig<
R extends Actions,
> {
/**
- * Called on the HTTP server before clients can interact with the worker.
+ * Called on the HTTP server before clients can interact with the actor.
*
- * Only called for public endpoints. Calls to workers from within the backend
+ * Only called for public endpoints. Calls to actors from within the backend
* do not trigger this handler.
*
* Data returned from this handler will be available on `c.conn.auth`.
*
* This function is required for any public HTTP endpoint access. Use this hook
* to validate client credentials and return authentication data that will be
- * available on connections. This runs on the HTTP server (not the worker)
- * in order to reduce load on the worker & prevent denial of server attacks
- * against individual workers.
+ * available on connections. This runs on the HTTP server (not the actor)
+ * in order to reduce load on the actor & prevent denial of server attacks
+ * against individual actors.
*
- * If you need access to worker state for authentication, use onBeforeConnect
+ * If you need access to actor state for authentication, use onBeforeConnect
* with an empty onAuth function instead.
*
* You can also provide your own authentication middleware on your router if you
* choose, then use onAuth to pass the authentication data (e.g. user ID) to the
- * worker itself.
+ * actor itself.
*
* @param opts Authentication options including request and intent
* @returns Authentication data to attach to connections (must be serializable)
- * @throws Throw an error to deny access to the worker
+ * @throws Throw an error to deny access to the actor
*/
onAuth?: (opts: OnAuthOptions) => AD | Promise;
/**
- * Called when the worker is first initialized.
+ * Called when the actor is first initialized.
*
- * Use this hook to initialize your worker's state.
+ * Use this hook to initialize your actor's state.
* This is called before any other lifecycle hooks.
*/
onCreate?: (
- c: WorkerContext,
+ c: ActorContext,
opts: OnCreateOptions,
) => void | Promise;
/**
- * Called when the worker is started and ready to receive connections and action.
+ * Called when the actor is started and ready to receive connections and action.
*
- * Use this hook to initialize resources needed for the worker's operation
+ * Use this hook to initialize resources needed for the actor's operation
* (timers, external connections, etc.)
*
* @returns Void or a Promise that resolves when startup is complete
*/
- onStart?: (c: WorkerContext) => void | Promise;
+ onStart?: (c: ActorContext) => void | Promise;
/**
- * Called when the worker's state changes.
+ * Called when the actor's state changes.
*
* Use this hook to react to state changes, such as updating
* external systems or triggering events.
@@ -265,24 +265,24 @@ interface BaseWorkerConfig<
* @param newState The updated state
*/
onStateChange?: (
- c: WorkerContext,
+ c: ActorContext,
newState: S,
) => void;
/**
- * Called before a client connects to the worker.
+ * Called before a client connects to the actor.
*
* Unlike onAuth, this handler is still called for both internal and
* public clients.
*
* Use this hook to determine if a connection should be accepted
* and to initialize connection-specific state. Unlike onAuth, this runs
- * on the worker and has access to worker state, but uses slightly
- * more resources on the worker rather than authenticating with onAuth.
+ * on the actor and has access to actor state, but uses slightly
+ * more resources on the actor rather than authenticating with onAuth.
*
- * For authentication without worker state access, prefer onAuth.
+ * For authentication without actor state access, prefer onAuth.
*
- * For authentication with worker state, use onBeforeConnect with an empty
+ * For authentication with actor state, use onBeforeConnect with an empty
* onAuth handler.
*
* @param opts Connection parameters including client-provided data
@@ -290,35 +290,35 @@ interface BaseWorkerConfig<
* @throws Throw an error to reject the connection
*/
onBeforeConnect?: (
- c: WorkerContext,
+ c: ActorContext,
opts: OnConnectOptions,
) => void | Promise;
/**
- * Called when a client successfully connects to the worker.
+ * Called when a client successfully connects to the actor.
*
* Use this hook to perform actions when a connection is established,
- * such as sending initial data or updating the worker's state.
+ * such as sending initial data or updating the actor's state.
*
* @param conn The connection object
* @returns Void or a Promise that resolves when connection handling is complete
*/
onConnect?: (
- c: WorkerContext,
+ c: ActorContext,
conn: Conn,
) => void | Promise;
/**
- * Called when a client disconnects from the worker.
+ * Called when a client disconnects from the actor.
*
* Use this hook to clean up resources associated with the connection
- * or update the worker's state.
+ * or update the actor's state.
*
* @param conn The connection that is being closed
* @returns Void or a Promise that resolves when disconnect handling is complete
*/
onDisconnect?: (
- c: WorkerContext,
+ c: ActorContext,
conn: Conn,
) => void | Promise;
@@ -335,7 +335,7 @@ interface BaseWorkerConfig<
* @returns The modified output to send to the client
*/
onBeforeActionResponse?: (
- c: WorkerContext,
+ c: ActorContext,
name: string,
args: unknown[],
output: Out,
@@ -357,7 +357,7 @@ export type DatabaseFactory = (ctx: {
onMigrate?: () => void | Promise;
}>;
-type WorkerDatabaseConfig =
+type ActorDatabaseConfig =
| {
/**
* @experimental
@@ -369,8 +369,8 @@ type WorkerDatabaseConfig =
// 1. Infer schema
// 2. Omit keys that we'll manually define (because of generics)
// 3. Define our own types that have generic constraints
-export type WorkerConfig = Omit<
- z.infer,
+export type ActorConfig = Omit<
+ z.infer,
| "actions"
| "onAuth"
| "onCreate"
@@ -388,14 +388,14 @@ export type WorkerConfig = Omit<
| "createVars"
| "db"
> &
- BaseWorkerConfig> &
+ BaseActorConfig> &
CreateState &
CreateConnState &
CreateVars &
- WorkerDatabaseConfig;
+ ActorDatabaseConfig;
-// See description on `WorkerConfig`
-export type WorkerConfigInput<
+// See description on `ActorConfig`
+export type ActorConfigInput<
S,
CP,
CS,
@@ -405,7 +405,7 @@ export type WorkerConfigInput<
DB,
R extends Actions,
> = Omit<
- z.input,
+ z.input,
| "actions"
| "onAuth"
| "onCreate"
@@ -423,11 +423,11 @@ export type WorkerConfigInput<
| "createVars"
| "db"
> &
- BaseWorkerConfig &
+ BaseActorConfig &
CreateState &
CreateConnState &
CreateVars &
- WorkerDatabaseConfig;
+ ActorDatabaseConfig;
// For testing type definitions:
export function test<
@@ -440,9 +440,9 @@ export function test<
DB,
R extends Actions,
>(
- input: WorkerConfigInput,
-): WorkerConfig {
- const config = WorkerConfigSchema.parse(input) as WorkerConfig<
+ input: ActorConfigInput,
+): ActorConfig {
+ const config = ActorConfigSchema.parse(input) as ActorConfig<
S,
CP,
CS,
@@ -454,7 +454,7 @@ export function test<
return config;
}
-export const testWorker = test({
+export const testActor = test({
state: { count: 0 },
// createState: () => ({ count: 0 }),
actions: {
diff --git a/packages/core/src/worker/conn-routing-handler.ts b/packages/core/src/actor/conn-routing-handler.ts
similarity index 82%
rename from packages/core/src/worker/conn-routing-handler.ts
rename to packages/core/src/actor/conn-routing-handler.ts
index ac80d3e8a..6b82138f4 100644
--- a/packages/core/src/worker/conn-routing-handler.ts
+++ b/packages/core/src/actor/conn-routing-handler.ts
@@ -4,7 +4,7 @@ import type { ConnectionHandlers as ConnHandlers } from "./router-endpoints";
import type { Context as HonoContext } from "hono";
/**
- * Deterines how requests to workers should be routed.
+ * Deterines how requests to actors should be routed.
*
* Inline handlers calls the connection handlers directly.
*
@@ -27,29 +27,29 @@ export interface ConnRoutingHandlerCustom {
proxyWebSocket: ProxyWebSocketHandler;
}
-export type BuildProxyEndpoint = (c: HonoContext, workerId: string) => string;
+export type BuildProxyEndpoint = (c: HonoContext, actorId: string) => string;
export type SendRequestHandler = (
- workerId: string,
- workerRequest: Request,
+ actorId: string,
+ actorRequest: Request,
) => Promise;
export type OpenWebSocketHandler = (
- workerId: string,
+ actorId: string,
encodingKind: Encoding,
params: unknown
) => Promise;
export type ProxyRequestHandler = (
c: HonoContext,
- workerRequest: Request,
- workerId: string,
+ actorRequest: Request,
+ actorId: string,
) => Promise;
export type ProxyWebSocketHandler = (
c: HonoContext,
path: string,
- workerId: string,
+ actorId: string,
encoding: Encoding,
connParams: unknown,
authData: unknown,
diff --git a/packages/core/src/worker/connection.ts b/packages/core/src/actor/connection.ts
similarity index 86%
rename from packages/core/src/worker/connection.ts
rename to packages/core/src/actor/connection.ts
index 897f35c1a..e4f305585 100644
--- a/packages/core/src/worker/connection.ts
+++ b/packages/core/src/actor/connection.ts
@@ -1,11 +1,11 @@
-import type { WorkerInstance } from "./instance";
+import type { ActorInstance } from "./instance";
import * as errors from "./errors";
import { generateSecureToken } from "./utils";
import { CachedSerializer } from "./protocol/serde";
import type { ConnDriver } from "./driver";
-import type * as messageToClient from "@/worker/protocol/message/to-client";
+import type * as messageToClient from "@/actor/protocol/message/to-client";
import type { PersistedConn } from "./persisted";
-import type * as wsToClient from "@/worker/protocol/message/to-client";
+import type * as wsToClient from "@/actor/protocol/message/to-client";
export function generateConnId(): string {
return crypto.randomUUID();
@@ -20,7 +20,7 @@ export type ConnId = string;
export type AnyConn = Conn;
/**
- * Represents a client connection to a worker.
+ * Represents a client connection to a actor.
*
* Manages connection-specific data and controls the connection lifecycle.
*
@@ -32,7 +32,7 @@ export class Conn {
#stateEnabled: boolean;
// TODO: Remove this cyclical reference
- #worker: WorkerInstance;
+ #actor: ActorInstance;
/**
* The proxied state that notifies of changes automatically.
@@ -98,17 +98,17 @@ export class Conn {
/**
* Initializes a new instance of the Connection class.
*
- * This should only be constructed by {@link Worker}.
+ * This should only be constructed by {@link Actor}.
*
* @protected
*/
public constructor(
- worker: WorkerInstance,
+ actor: ActorInstance,
persist: PersistedConn,
driver: ConnDriver,
stateEnabled: boolean,
) {
- this.#worker = worker;
+ this.#actor = actor;
this.__persist = persist;
this.#driver = driver;
this.#stateEnabled = stateEnabled;
@@ -128,7 +128,7 @@ export class Conn {
* @protected
*/
public _sendMessage(message: CachedSerializer) {
- this.#driver.sendMessage?.(this.#worker, this, this.__persist.ds, message);
+ this.#driver.sendMessage?.(this.#actor, this, this.__persist.ds, message);
}
/**
@@ -158,7 +158,7 @@ export class Conn {
*/
public async disconnect(reason?: string) {
await this.#driver.disconnect(
- this.#worker,
+ this.#actor,
this,
this.__persist.ds,
reason,
diff --git a/packages/core/src/worker/context.ts b/packages/core/src/actor/context.ts
similarity index 57%
rename from packages/core/src/worker/context.ts
rename to packages/core/src/actor/context.ts
index 6363e2a4b..6d10aa036 100644
--- a/packages/core/src/worker/context.ts
+++ b/packages/core/src/actor/context.ts
@@ -1,31 +1,31 @@
import type { Logger } from "@/common/log";
-import type { WorkerInstance, SaveStateOptions } from "./instance";
+import type { ActorInstance, SaveStateOptions } from "./instance";
import type { Conn, ConnId } from "./connection";
-import type { WorkerKey } from "@/common/utils";
+import type { ActorKey } from "@/common/utils";
import type { Schedule } from "./schedule";
/**
- * WorkerContext class that provides access to worker methods and state
+ * ActorContext class that provides access to actor methods and state
*/
-export class WorkerContext {
- #worker: WorkerInstance;
+export class ActorContext {
+ #actor: ActorInstance;
- constructor(worker: WorkerInstance) {
- this.#worker = worker;
+ constructor(actor: ActorInstance) {
+ this.#actor = actor;
}
/**
- * Get the worker state
+ * Get the actor state
*/
get state(): S {
- return this.#worker.state;
+ return this.#actor.state;
}
/**
- * Get the worker variables
+ * Get the actor variables
*/
get vars(): V {
- return this.#worker.vars;
+ return this.#actor.vars;
}
/**
@@ -34,7 +34,7 @@ export class WorkerContext {
* @param args - The arguments to send with the event.
*/
broadcast>(name: string, ...args: Args): void {
- this.#worker._broadcast(name, ...args);
+ this.#actor._broadcast(name, ...args);
return;
}
@@ -42,49 +42,49 @@ export class WorkerContext {
* Gets the logger instance.
*/
get log(): Logger {
- return this.#worker.log;
+ return this.#actor.log;
}
/**
- * Gets worker ID.
+ * Gets actor ID.
*/
- get workerId(): string {
- return this.#worker.id;
+ get actorId(): string {
+ return this.#actor.id;
}
/**
- * Gets the worker name.
+ * Gets the actor name.
*/
get name(): string {
- return this.#worker.name;
+ return this.#actor.name;
}
/**
- * Gets the worker key.
+ * Gets the actor key.
*/
- get key(): WorkerKey {
- return this.#worker.key;
+ get key(): ActorKey {
+ return this.#actor.key;
}
/**
* Gets the region.
*/
get region(): string {
- return this.#worker.region;
+ return this.#actor.region;
}
/**
* Gets the scheduler.
*/
get schedule(): Schedule {
- return this.#worker.schedule;
+ return this.#actor.schedule;
}
/**
* Gets the map of connections.
*/
get conns(): Map> {
- return this.#worker.conns;
+ return this.#actor.conns;
}
/**
@@ -93,7 +93,7 @@ export class WorkerContext {
* @throws {DatabaseNotEnabled} If the database is not enabled.
*/
get db(): DB {
- return this.#worker.db;
+ return this.#actor.db;
}
/**
@@ -102,7 +102,7 @@ export class WorkerContext {
* @param opts - Options for saving the state.
*/
async saveState(opts: SaveStateOptions): Promise {
- return this.#worker.saveState(opts);
+ return this.#actor.saveState(opts);
}
/**
@@ -111,7 +111,7 @@ export class WorkerContext {
* @param promise - The promise to run in the background.
*/
runInBackground(promise: Promise): void {
- this.#worker._runInBackground(promise);
+ this.#actor._runInBackground(promise);
return;
}
}
diff --git a/packages/core/src/actor/definition.ts b/packages/core/src/actor/definition.ts
new file mode 100644
index 000000000..dd2d05fa0
--- /dev/null
+++ b/packages/core/src/actor/definition.ts
@@ -0,0 +1,74 @@
+import type { ActorConfig, Actions } from "./config";
+import { ActorInstance } from "./instance";
+import type { ActorContext } from "./context";
+import type { ActionContext } from "./action";
+
+export type AnyActorDefinition = ActorDefinition<
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any
+>;
+
+/**
+ * Extracts the context type from an ActorDefinition
+ */
+export type ActorContextOf =
+ AD extends ActorDefinition<
+ infer S,
+ infer CP,
+ infer CS,
+ infer V,
+ infer I,
+ infer AD,
+ infer DB,
+ any
+ >
+ ? ActorContext
+ : never;
+
+/**
+ * Extracts the context type from an ActorDefinition
+ */
+export type ActionContextOf =
+ AD extends ActorDefinition<
+ infer S,
+ infer CP,
+ infer CS,
+ infer V,
+ infer I,
+ infer AD,
+ infer DB,
+ any
+ >
+ ? ActionContext
+ : never;
+
+export class ActorDefinition<
+ S,
+ CP,
+ CS,
+ V,
+ I,
+ AD,
+ DB,
+ R extends Actions,
+> {
+ #config: ActorConfig;
+
+ constructor(config: ActorConfig) {
+ this.#config = config;
+ }
+
+ get config(): ActorConfig {
+ return this.#config;
+ }
+
+ instantiate(): ActorInstance {
+ return new ActorInstance(this.#config);
+ }
+}
diff --git a/packages/core/src/worker/driver.ts b/packages/core/src/actor/driver.ts
similarity index 53%
rename from packages/core/src/worker/driver.ts
rename to packages/core/src/actor/driver.ts
index ae51063fc..35873f05d 100644
--- a/packages/core/src/worker/driver.ts
+++ b/packages/core/src/actor/driver.ts
@@ -1,28 +1,28 @@
-import type * as messageToClient from "@/worker/protocol/message/to-client";
-import type { CachedSerializer } from "@/worker/protocol/serde";
-import type { AnyWorkerInstance } from "./instance";
+import type * as messageToClient from "@/actor/protocol/message/to-client";
+import type { CachedSerializer } from "@/actor/protocol/serde";
+import type { AnyActorInstance } from "./instance";
import { AnyConn } from "./connection";
export type ConnDrivers = Record;
-export interface WorkerDriver {
+export interface ActorDriver {
//load(): Promise;
- getContext(workerId: string): unknown;
+ getContext(actorId: string): unknown;
- readInput(workerId: string): Promise;
+ readInput(actorId: string): Promise;
- readPersistedData(workerId: string): Promise;
- writePersistedData(workerId: string, unknown: unknown): Promise;
+ readPersistedData(actorId: string): Promise;
+ writePersistedData(actorId: string, unknown: unknown): Promise;
// Schedule
- setAlarm(worker: AnyWorkerInstance, timestamp: number): Promise;
+ setAlarm(actor: AnyActorInstance, timestamp: number): Promise;
// Database
/**
* @experimental
* This is an experimental API that may change in the future.
*/
- getDatabase(workerId: string): Promise;
+ getDatabase(actorId: string): Promise;
// TODO:
//destroy(): Promise;
@@ -31,7 +31,7 @@ export interface WorkerDriver {
export interface ConnDriver {
sendMessage?(
- worker: AnyWorkerInstance,
+ actor: AnyActorInstance,
conn: AnyConn,
state: ConnDriverState,
message: CachedSerializer,
@@ -41,7 +41,7 @@ export interface ConnDriver {
* This returns a promise since we commonly disconnect at the end of a program, and not waiting will cause the socket to not close cleanly.
*/
disconnect(
- worker: AnyWorkerInstance,
+ actor: AnyActorInstance,
conn: AnyConn,
state: ConnDriverState,
reason?: string,
diff --git a/packages/core/src/worker/errors.ts b/packages/core/src/actor/errors.ts
similarity index 73%
rename from packages/core/src/worker/errors.ts
rename to packages/core/src/actor/errors.ts
index f97b600cd..4eb8cd02b 100644
--- a/packages/core/src/worker/errors.ts
+++ b/packages/core/src/actor/errors.ts
@@ -2,38 +2,38 @@ import { DeconstructedError } from "@/common/utils";
export const INTERNAL_ERROR_CODE = "internal_error";
export const INTERNAL_ERROR_DESCRIPTION =
- "Internal error. Read the worker logs for more details.";
+ "Internal error. Read the actor logs for more details.";
export type InternalErrorMetadata = {};
export const USER_ERROR_CODE = "user_error";
-interface WorkerErrorOptions extends ErrorOptions {
+interface ActorErrorOptions extends ErrorOptions {
/** Error data can safely be serialized in a response to the client. */
public?: boolean;
/** Metadata associated with this error. This will be sent to clients. */
metadata?: unknown;
}
-export class WorkerError extends Error {
- __type = "WorkerError";
+export class ActorError extends Error {
+ __type = "ActorError";
public public: boolean;
public metadata?: unknown;
public statusCode = 500;
- public static isWorkerError(
+ public static isActorError(
error: unknown,
- ): error is WorkerError | DeconstructedError {
+ ): error is ActorError | DeconstructedError {
return (
typeof error === "object" &&
- (error as WorkerError | DeconstructedError).__type === "WorkerError"
+ (error as ActorError | DeconstructedError).__type === "ActorError"
);
}
constructor(
public readonly code: string,
message: string,
- opts?: WorkerErrorOptions,
+ opts?: ActorErrorOptions,
) {
super(message, { cause: opts?.cause });
this.public = opts?.public ?? false;
@@ -62,7 +62,7 @@ export class WorkerError extends Error {
}
}
-export class InternalError extends WorkerError {
+export class InternalError extends ActorError {
constructor(message: string) {
super(INTERNAL_ERROR_CODE, message);
}
@@ -74,7 +74,7 @@ export class Unreachable extends InternalError {
}
}
-export class StateNotEnabled extends WorkerError {
+export class StateNotEnabled extends ActorError {
constructor() {
super(
"state_not_enabled",
@@ -83,7 +83,7 @@ export class StateNotEnabled extends WorkerError {
}
}
-export class ConnStateNotEnabled extends WorkerError {
+export class ConnStateNotEnabled extends ActorError {
constructor() {
super(
"conn_state_not_enabled",
@@ -92,7 +92,7 @@ export class ConnStateNotEnabled extends WorkerError {
}
}
-export class VarsNotEnabled extends WorkerError {
+export class VarsNotEnabled extends ActorError {
constructor() {
super(
"vars_not_enabled",
@@ -101,19 +101,19 @@ export class VarsNotEnabled extends WorkerError {
}
}
-export class ActionTimedOut extends WorkerError {
+export class ActionTimedOut extends ActorError {
constructor() {
super("action_timed_out", "Action timed out.", { public: true });
}
}
-export class ActionNotFound extends WorkerError {
+export class ActionNotFound extends ActorError {
constructor() {
super("action_not_found", "Action not found.", { public: true });
}
}
-export class InvalidEncoding extends WorkerError {
+export class InvalidEncoding extends ActorError {
constructor(format?: string) {
super("invalid_encoding", `Invalid encoding \`${format}\`.`, {
public: true,
@@ -121,7 +121,7 @@ export class InvalidEncoding extends WorkerError {
}
}
-export class ConnNotFound extends WorkerError {
+export class ConnNotFound extends ActorError {
constructor(id?: string) {
super("conn_not_found", `Connection not found for ID \`${id}\`.`, {
public: true,
@@ -129,7 +129,7 @@ export class ConnNotFound extends WorkerError {
}
}
-export class IncorrectConnToken extends WorkerError {
+export class IncorrectConnToken extends ActorError {
constructor() {
super("incorrect_conn_token", "Incorrect connection token.", {
public: true,
@@ -137,7 +137,7 @@ export class IncorrectConnToken extends WorkerError {
}
}
-export class ConnParamsTooLong extends WorkerError {
+export class ConnParamsTooLong extends ActorError {
constructor() {
super("conn_params_too_long", "Connection parameters too long.", {
public: true,
@@ -145,7 +145,7 @@ export class ConnParamsTooLong extends WorkerError {
}
}
-export class MalformedConnParams extends WorkerError {
+export class MalformedConnParams extends ActorError {
constructor(cause: unknown) {
super(
"malformed_conn_params",
@@ -155,13 +155,13 @@ export class MalformedConnParams extends WorkerError {
}
}
-export class MessageTooLong extends WorkerError {
+export class MessageTooLong extends ActorError {
constructor() {
super("message_too_long", "Message too long.", { public: true });
}
}
-export class MalformedMessage extends WorkerError {
+export class MalformedMessage extends ActorError {
constructor(cause?: unknown) {
super("malformed_message", `Malformed message: ${cause}`, {
public: true,
@@ -174,7 +174,7 @@ export interface InvalidStateTypeOptions {
path?: unknown;
}
-export class InvalidStateType extends WorkerError {
+export class InvalidStateType extends ActorError {
constructor(opts?: InvalidStateTypeOptions) {
let msg = "";
if (opts?.path) {
@@ -187,13 +187,13 @@ export class InvalidStateType extends WorkerError {
}
}
-export class StateTooLarge extends WorkerError {
+export class StateTooLarge extends ActorError {
constructor() {
super("state_too_large", "State too large.");
}
}
-export class Unsupported extends WorkerError {
+export class Unsupported extends ActorError {
constructor(feature: string) {
super("unsupported", `Unsupported feature: ${feature}`);
}
@@ -215,7 +215,7 @@ export interface UserErrorOptions extends ErrorOptions {
}
/** Error that can be safely returned to the user. */
-export class UserError extends WorkerError {
+export class UserError extends ActorError {
/**
* Constructs a new UserError instance.
*
@@ -230,7 +230,7 @@ export class UserError extends WorkerError {
}
}
-export class InvalidQueryJSON extends WorkerError {
+export class InvalidQueryJSON extends ActorError {
constructor(error?: unknown) {
super("invalid_query_json", `Invalid query JSON: ${error}`, {
public: true,
@@ -239,7 +239,7 @@ export class InvalidQueryJSON extends WorkerError {
}
}
-export class InvalidRequest extends WorkerError {
+export class InvalidRequest extends ActorError {
constructor(error?: unknown) {
super("invalid_request", `Invalid request: ${error}`, {
public: true,
@@ -248,27 +248,27 @@ export class InvalidRequest extends WorkerError {
}
}
-export class WorkerNotFound extends WorkerError {
+export class ActorNotFound extends ActorError {
constructor(identifier?: string) {
super(
- "worker_not_found",
- identifier ? `Worker not found: ${identifier}` : "Worker not found",
+ "actor_not_found",
+ identifier ? `Actor not found: ${identifier}` : "Actor not found",
{ public: true },
);
}
}
-export class WorkerAlreadyExists extends WorkerError {
+export class ActorAlreadyExists extends ActorError {
constructor(name: string, key: string[]) {
super(
- "worker_already_exists",
- `Worker already exists with name "${name}" and key ${JSON.stringify(key)}`,
+ "actor_already_exists",
+ `Actor already exists with name "${name}" and key ${JSON.stringify(key)}`,
{ public: true },
);
}
}
-export class ProxyError extends WorkerError {
+export class ProxyError extends ActorError {
constructor(operation: string, error?: unknown) {
super("proxy_error", `Error proxying ${operation}: ${error}`, {
public: true,
@@ -277,26 +277,26 @@ export class ProxyError extends WorkerError {
}
}
-export class InvalidActionRequest extends WorkerError {
+export class InvalidActionRequest extends ActorError {
constructor(message: string) {
super("invalid_action_request", message, { public: true });
}
}
-export class InvalidParams extends WorkerError {
+export class InvalidParams extends ActorError {
constructor(message: string) {
super("invalid_params", message, { public: true });
}
}
-export class Forbidden extends WorkerError {
+export class Forbidden extends ActorError {
constructor(message?: string) {
super("forbidden", message ?? "Access denied", { public: true });
this.statusCode = 403;
}
}
-export class DatabaseNotEnabled extends WorkerError {
+export class DatabaseNotEnabled extends ActorError {
constructor() {
super(
"database_not_enabled",
diff --git a/packages/core/src/worker/instance.ts b/packages/core/src/actor/instance.ts
similarity index 87%
rename from packages/core/src/worker/instance.ts
rename to packages/core/src/actor/instance.ts
index ab078b371..948ec711f 100644
--- a/packages/core/src/worker/instance.ts
+++ b/packages/core/src/actor/instance.ts
@@ -1,13 +1,13 @@
import type { Logger } from "@/common//log";
import {
- type WorkerKey,
+ type ActorKey,
isJsonSerializable,
stringifyError,
} from "@/common//utils";
import onChange from "on-change";
-import type { WorkerConfig } from "./config";
+import type { ActorConfig } from "./config";
import { Conn, type ConnId } from "./connection";
-import type { WorkerDriver, ConnDrivers } from "./driver";
+import type { ActorDriver, ConnDrivers } from "./driver";
import type { ConnDriver } from "./driver";
import * as errors from "./errors";
import { processMessage } from "./protocol/message/mod";
@@ -15,13 +15,13 @@ import { instanceLogger, logger } from "./log";
import type { ActionContext } from "./action";
import { DeadlineError, Lock, deadline } from "./utils";
import { Schedule } from "./schedule";
-import type * as wsToClient from "@/worker/protocol/message/to-client";
-import type * as wsToServer from "@/worker/protocol/message/to-server";
+import type * as wsToClient from "@/actor/protocol/message/to-client";
+import type * as wsToServer from "@/actor/protocol/message/to-server";
import { CachedSerializer } from "./protocol/serde";
-import { WorkerContext } from "./context";
+import { ActorContext } from "./context";
import invariant from "invariant";
import type {
- PersistedWorker,
+ PersistedActor,
PersistedConn,
PersistedScheduleEvents,
} from "./persisted";
@@ -36,8 +36,8 @@ export interface SaveStateOptions {
immediate?: boolean;
}
-/** Worker type alias with all `any` types. Used for `extends` in classes referencing this worker. */
-export type AnyWorkerInstance = WorkerInstance<
+/** Actor type alias with all `any` types. Used for `extends` in classes referencing this actor. */
+export type AnyActorInstance = ActorInstance<
// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`
any,
// biome-ignore lint/suspicious/noExplicitAny: Needs to be used in `extends`
@@ -54,8 +54,8 @@ export type AnyWorkerInstance = WorkerInstance<
any
>;
-export type ExtractWorkerState =
- A extends WorkerInstance<
+export type ExtractActorState =
+ A extends ActorInstance<
infer State,
// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`
any,
@@ -73,8 +73,8 @@ export type ExtractWorkerState =
? State
: never;
-export type ExtractWorkerConnParams =
- A extends WorkerInstance<
+export type ExtractActorConnParams =
+ A extends ActorInstance<
// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`
any,
infer ConnParams,
@@ -92,8 +92,8 @@ export type ExtractWorkerConnParams =
? ConnParams
: never;
-export type ExtractWorkerConnState =
- A extends WorkerInstance<
+export type ExtractActorConnState =
+ A extends ActorInstance<
// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`
any,
// biome-ignore lint/suspicious/noExplicitAny: Must be used for `extends`
@@ -111,9 +111,9 @@ export type ExtractWorkerConnState =
? ConnState
: never;
-export class WorkerInstance {
- // Shared worker context for this instance
- workerContext: WorkerContext;
+export class ActorInstance {
+ // Shared actor context for this instance
+ actorContext: ActorContext