Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,7 @@ This ensures imports resolve correctly across different build environments and p
- Run `yarn check-types` regularly during development to catch type errors early. Prefer `yarn check-types` instead of `yarn build`.
- Use `tsx` CLI to execute TypeScript scripts directly (e.g., `tsx script.ts` instead of `node script.js`).
- Do not auto-commit changes

## 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`.
6 changes: 3 additions & 3 deletions docs/clients/python.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The RivetKit Python client provides a way to connect to and interact with worker
<CodeGroup>
```python Async
import asyncio
from worker_core_client import AsyncClient
from rivetkit_client import AsyncClient

async def main():
# Replace with your endpoint URL after deployment
Expand Down Expand Up @@ -77,7 +77,7 @@ The RivetKit Python client provides a way to connect to and interact with worker
```

```python Sync
from worker_core_client import Client
from rivetkit_client import Client

# Replace with your endpoint URL after deployment
client = Client("http://localhost:6420")
Expand Down Expand Up @@ -128,4 +128,4 @@ The RivetKit Python client provides a way to connect to and interact with worker
<StepDeploy />
</Steps>

<SetupNextSteps />
<SetupNextSteps />
2 changes: 1 addition & 1 deletion docs/clients/rust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The RivetKit Rust client provides a way to connect to and interact with workers
Modify `src/main.rs` to connect to your worker:

```rust src/main.rs
use worker_core_client::{Client, GetOptions, TransportKind, EncodingKind};
use rivetkit_client::{Client, GetOptions, TransportKind, EncodingKind};
use serde_json::json;
use std::time::Duration;

Expand Down
18 changes: 9 additions & 9 deletions docs/concepts/interacting-with-workers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const client = createClient<App>(/* CONNECTION ADDRESS */);
```

```rust Rust
use worker_core_client::{Client, TransportKind, EncodingKind};
use rivetkit_client::{Client, TransportKind, EncodingKind};

// Create a client with connection address and configuration
let client = Client::new(
Expand All @@ -30,7 +30,7 @@ let client = Client::new(
```

```python Python (Callbacks)
from worker_core_client import AsyncClient as WorkerClient
from rivetkit_client import AsyncClient as WorkerClient

# Create a client with the connection address
client = WorkerClient("http://localhost:6420")
Expand Down Expand Up @@ -60,7 +60,7 @@ await room.sendMessage("Alice", "Hello everyone!");
```

```rust Rust
use worker_core_client::GetOptions;
use rivetkit_client::GetOptions;
use serde_json::json;

// Connect to a chat room for the "general" channel
Expand Down Expand Up @@ -116,8 +116,8 @@ await doc.initializeDocument("My New Document");
```

```rust Rust
use worker_core_client::{CreateOptions};
use worker_core_client::client::CreateRequestMetadata;
use rivetkit_client::{CreateOptions};
use rivetkit_client::client::CreateRequestMetadata;
use serde_json::json;

// Create a new document worker
Expand Down Expand Up @@ -169,7 +169,7 @@ await doc.updateContent("Updated content");
```

```rust Rust
use worker_core_client::GetWithIdOptions;
use rivetkit_client::GetWithIdOptions;

// Connect to a specific worker by its ID
let my_worker_id = "55425f42-82f8-451f-82c1-6227c83c9372";
Expand Down Expand Up @@ -374,7 +374,7 @@ const chatRoom = await client.chatRoom.get({ channel: "super-secret" }, {

```rust Rust
use serde_json::json;
use worker_core_client::GetOptions;
use rivetkit_client::GetOptions;

let tags = vec![
("channel".to_string(), "super-secret".to_string()),
Expand Down Expand Up @@ -471,7 +471,7 @@ const client = createClient<App>(
```

```rust Rust
use worker_core_client::{Client, TransportKind, EncodingKind};
use rivetkit_client::{Client, TransportKind, EncodingKind};

// Create client with specific options
let client = Client::new(
Expand All @@ -484,7 +484,7 @@ let client = Client::new(
```

```python Python (Callbacks)
from worker_core_client import AsyncClient as WorkerClient
from rivetkit_client import AsyncClient as WorkerClient

# Example with all client options
client = WorkerClient(
Expand Down
21 changes: 0 additions & 21 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,27 +117,6 @@
},
"/workers/connect/websocket": {
"get": {
"parameters": [
{
"schema": {
"type": "string",
"description": "The encoding format to use for the response (json, cbor)",
"example": "json"
},
"required": true,
"name": "encoding",
"in": "query"
},
{
"schema": {
"type": "string",
"description": "Worker query information"
},
"required": true,
"name": "query",
"in": "query"
}
],
"responses": {
"101": {
"description": "WebSocket upgrade"
Expand Down
17 changes: 12 additions & 5 deletions docs/workers/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ description: Start building awesome documentation in under 5 minutes
```ts registry.ts
import { setup } from "rivetkit";
import { worker } from "rivetkit/worker";
import { workflow } from "rivetkit/workflow";
import { realtime } from "rivetkit/realtime";

const counter = worker({
onAuth: async () => {
// Allow public access
},
state: {
count: 0,
},
Expand All @@ -36,18 +37,24 @@ export type Registry = typeof registry;
```

```ts server.ts
// With router
import { registry } from "./registry";

const registry = new Hono();
app.route("/registry", registry.handler);
const app = new Hono();
app.route("/registry", c => registry.handler(c.req.raw));
serve(app);

// Without router
import { serve } from "@rivetkit/node";

serve(registry);
```

```ts client.ts
import { createClient } from "rivetkit/client";
import type { Registry } from "./registry";

const client = createClient<Registry>("http://localhost:8080/registry");
const client = createClient<Registry>("http://localhost:8080");
```

<Steps>
Expand Down
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/action-inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface State {

// Test worker that can capture input during creation
export const inputWorker = worker({
onAuth: () => {},
createState: (c, { input }): State => {
return {
initialInput: input,
Expand Down
4 changes: 4 additions & 0 deletions packages/core/fixtures/driver-test-suite/action-timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { worker } from "rivetkit";

// Short timeout worker
export const shortTimeoutWorker = worker({
onAuth: () => {},
state: { value: 0 },
options: {
action: {
Expand All @@ -22,6 +23,7 @@ export const shortTimeoutWorker = worker({

// Long timeout worker
export const longTimeoutWorker = worker({
onAuth: () => {},
state: { value: 0 },
options: {
action: {
Expand All @@ -39,6 +41,7 @@ export const longTimeoutWorker = worker({

// Default timeout worker
export const defaultTimeoutWorker = worker({
onAuth: () => {},
state: { value: 0 },
actions: {
normalAction: async (c) => {
Expand All @@ -50,6 +53,7 @@ export const defaultTimeoutWorker = worker({

// Sync worker (timeout shouldn't apply)
export const syncTimeoutWorker = worker({
onAuth: () => {},
state: { value: 0 },
options: {
action: {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/fixtures/driver-test-suite/action-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { worker, UserError } from "rivetkit";

// Worker with synchronous actions
export const syncActionWorker = worker({
onAuth: () => {},
state: { value: 0 },
actions: {
// Simple synchronous action that returns a value directly
Expand All @@ -25,6 +26,7 @@ export const syncActionWorker = worker({

// Worker with asynchronous actions
export const asyncActionWorker = worker({
onAuth: () => {},
state: { value: 0, data: null as any },
actions: {
// Async action with a delay
Expand Down Expand Up @@ -57,6 +59,7 @@ export const asyncActionWorker = worker({

// Worker with promise actions
export const promiseWorker = worker({
onAuth: () => {},
state: { results: [] as string[] },
actions: {
// Action that returns a resolved promise
Expand Down
105 changes: 105 additions & 0 deletions packages/core/fixtures/driver-test-suite/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { worker, UserError } from "rivetkit";

// Basic auth worker - requires API key
export const authWorker = worker({
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 worker - checks different permissions for different intents
export const intentAuthWorker = worker({
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 worker - empty onAuth to allow public access
export const publicWorker = worker({
state: { visitors: 0 },
onAuth: () => {
return null; // Allow public access
},
actions: {
visit: (c) => {
c.state.visitors++;
return c.state.visitors;
},
},
});

// No auth worker - should fail when accessed publicly (no onAuth defined)
export const noAuthWorker = worker({
state: { value: 42 },
actions: {
getValue: (c) => c.state.value,
},
});

// Async auth worker - tests promise-based authentication
export const asyncAuthWorker = worker({
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,
},
});
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/conn-params.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { worker } from "rivetkit";

export const counterWithParams = worker({
onAuth: () => {},
state: { count: 0, initializers: [] as string[] },
createConnState: (c, { params }: { params: { name?: string } }) => {
return {
Expand Down
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/conn-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type ConnState = {
};

export const connStateWorker = worker({
onAuth: () => {},
state: {
sharedCounter: 0,
disconnectionCount: 0,
Expand Down
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/counter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { worker } from "rivetkit";

export const counter = worker({
onAuth: () => {},
state: { count: 0 },
actions: {
increment: (c, x: number) => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/error-handling.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { worker, UserError } from "rivetkit";

export const errorHandlingWorker = worker({
onAuth: () => {},
state: {
errorLog: [] as string[],
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/fixtures/driver-test-suite/lifecycle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { worker } from "rivetkit";

export const counterWithLifecycle = worker({
onAuth: () => {},
state: {
count: 0,
events: [] as string[],
Expand Down
Loading
Loading