Skip to content

Commit f879623

Browse files
committed
chore(site): update docs on new lifecycle hooks (#2843)
<!-- Please make sure there is an issue that this PR is correlated to. --> ## Changes <!-- If there are frontend changes, please include screenshots. -->
1 parent 89519b9 commit f879623

File tree

11 files changed

+132
-78
lines changed

11 files changed

+132
-78
lines changed

site/src/content/docs/actors/authentication.mdx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ The `onAuth` hook runs on the HTTP server before clients can access actors. This
1414
import { actor, UserError } from "@rivetkit/actor";
1515

1616
const chatRoom = actor({
17-
onAuth: async (opts) => {
18-
const { req, params, intents } = opts;
17+
onAuth: async (params: { authToken?: string }, { request, intents }) => {
1918

2019
// Extract token from params or headers
21-
const token = params.authToken || req.headers.get("Authorization");
20+
const token = params.authToken || request.headers.get("Authorization");
2221

2322
if (!token) {
2423
throw new UserError("Authentication required");
@@ -83,8 +82,8 @@ const userProfileActor = actor({
8382
}
8483
},
8584

86-
createConnState: (c, opts) => {
87-
return { userId: opts.params.userId };
85+
createConnState: (c, opts, params: { userId: string }) => {
86+
return { userId: params.userId };
8887
},
8988

9089
actions: {
@@ -128,9 +127,7 @@ The `onAuth` hook receives an `intents` parameter indicating what the client wan
128127

129128
```typescript
130129
const secureActor = actor({
131-
onAuth: async (opts) => {
132-
const { intents, params } = opts;
133-
130+
onAuth: async (params: { token: string }, { intents }) => {
134131
// Different validation based on intent
135132
if (intents.has("action")) {
136133
// Requires higher privileges for actions
@@ -162,8 +159,8 @@ Use specific error types for different authentication failures:
162159
import { UserError, Unauthorized, Forbidden } from "@rivetkit/actor/errors";
163160

164161
const protectedActor = actor({
165-
onAuth: async (opts) => {
166-
const token = opts.params.authToken;
162+
onAuth: async (params: { authToken?: string }) => {
163+
const token = params.authToken;
167164

168165
if (!token) {
169166
throw new Unauthorized("Authentication token required");
@@ -226,9 +223,9 @@ import { actor, UserError } from "@rivetkit/actor";
226223
import jwt from "jsonwebtoken";
227224

228225
const jwtActor = actor({
229-
onAuth: async (opts) => {
230-
const token = opts.params.jwt ||
231-
opts.req.headers.get("Authorization")?.replace("Bearer ", "");
226+
onAuth: async (params: { jwt?: string }, { request }) => {
227+
const token = params.jwt ||
228+
request.headers.get("Authorization")?.replace("Bearer ", "");
232229

233230
if (!token) {
234231
throw new UserError("JWT token required");
@@ -265,9 +262,9 @@ const jwtActor = actor({
265262

266263
```typescript
267264
const apiActor = actor({
268-
onAuth: async (opts) => {
269-
const apiKey = opts.params.apiKey ||
270-
opts.req.headers.get("X-API-Key");
265+
onAuth: async (params: { apiKey?: string }, { request }) => {
266+
const apiKey = params.apiKey ||
267+
request.headers.get("X-API-Key");
271268

272269
if (!apiKey) {
273270
throw new UserError("API key required");
@@ -331,7 +328,7 @@ export function requirePermission(permission: string) {
331328

332329
// usage in actor
333330
const forumActor = actor({
334-
onAuth: async (opts) => {
331+
onAuth: async (params: { token: string }) => {
335332
// ... authenticate and return user with role/permissions
336333
},
337334

site/src/content/docs/actors/connections.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const gameRoom = actor({
2727
state: {},
2828

2929
// Handle connection setup
30-
createConnState: (c, { params }) => {
30+
createConnState: (c, opts, params: { authToken: string }) => {
3131
// Validate authentication token
3232
const authToken = params.authToken;
3333

site/src/content/docs/actors/ephemeral-variables.mdx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ This value will be cloned for every new actor using `structuredClone`.
4242
Create actor state dynamically on each actors' start:
4343

4444
```typescript
45-
import { actor } from "@rivetkit/actor";
45+
import { actor, ActorInitContext } from "@rivetkit/actor";
4646

4747
// Define vars with initialization logic
4848
const counter = actor({
4949
state: { count: 0 },
5050

5151
// Define vars using a creation function
52-
createVars: () => {
52+
createVars: (c: ActorInitContext, driver: any) => {
5353
return {
5454
lastAccessTime: Date.now(),
5555
emitter: createNanoEvents()
@@ -62,6 +62,12 @@ const counter = actor({
6262
});
6363
```
6464

65+
<Note>
66+
If accepting arguments to `createVars`, you **must** define the types: `createVars(c: ActorInitContext, driver: any)`
67+
68+
Otherwise, the return type will not be inferred and `c.vars` will be of type `unknown`.
69+
</Note>
70+
6571
</Tab>
6672

6773
</Tabs>

site/src/content/docs/actors/events.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const gameRoom = actor({
5050
players: {} as Record<string, {health: number, position: {x: number, y: number}}>
5151
},
5252

53-
createConnState: (c, { params }) => ({
53+
createConnState: (c, opts, params: { playerId: string, role?: string }) => ({
5454
playerId: params.playerId,
5555
role: params.role || "player"
5656
}),
@@ -86,7 +86,7 @@ const gameRoom = actor({
8686
players: {} as Record<string, {health: number, position: {x: number, y: number}}>
8787
},
8888

89-
createConnState: (c, { params }) => ({
89+
createConnState: (c, opts, params: { playerId: string, role?: string }) => ({
9090
playerId: params.playerId,
9191
role: params.role || "player"
9292
}),

site/src/content/docs/actors/external-sql.mdx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Here's a basic example of a user actor that creates a database record on start a
3636

3737
<CodeGroup>
3838
```typescript {{ "title": "registry.ts" }}
39-
import { actor, setup } from "@rivetkit/actor";
39+
import { actor, setup, ActorInitContext } from "@rivetkit/actor";
4040
import { Pool } from "pg";
4141

4242
interface ActorInput {
@@ -55,10 +55,10 @@ const pool = new Pool({
5555

5656
// Create the user actor
5757
export const userActor = actor({
58-
createState: (opts: { input: ActorInput }) => ({
58+
createState: (c: ActorInitContext, input: ActorInput) => ({
5959
requestCount: 0,
60-
username: opts.input.username,
61-
email: opts.input.email,
60+
username: input.username,
61+
email: input.email,
6262
lastActive: Date.now()
6363
}),
6464

@@ -140,7 +140,7 @@ Here's the same user actor pattern using Drizzle ORM for more type-safe database
140140

141141
<CodeGroup>
142142
```typescript {{ "title": "registry.ts" }}
143-
import { actor, setup } from "@rivetkit/actor";
143+
import { actor, setup, ActorInitContext } from "@rivetkit/actor";
144144
import { drizzle } from "drizzle-orm/node-postgres";
145145
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
146146
import { eq } from "drizzle-orm";
@@ -169,10 +169,10 @@ const db = drizzle(pool);
169169

170170
// Create the user actor
171171
export const userActor = actor({
172-
createState: (opts: { input: ActorInput }) => ({
172+
createState: (c: ActorInitContext, input: ActorInput) => ({
173173
requestCount: 0,
174-
username: opts.input.username,
175-
email: opts.input.email,
174+
username: input.username,
175+
email: input.email,
176176
lastActive: Date.now()
177177
}),
178178

site/src/content/docs/actors/helper-types.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
Rivet provides several TypeScript helper types to make it easier to work with actors in a type-safe way.
44

5+
56
## `Context` Types
67

7-
When working with actors, you often need to access the context object. Rivet provides helper types to extract the context types from actor definitions.
8+
When working with actors, you often need to access the context object outside of the actor's handlers. Rivet provides helper types to extract the context types from actor definitions.
89

910
### `ActorContextOf<ActorDefinition>`
1011

@@ -57,4 +58,3 @@ function processCounterAction(context: ActionContextOf<typeof counter>) {
5758
context.state.count++;
5859
}
5960
```
60-

site/src/content/docs/actors/input.mdx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,26 @@ const gameHandle = client.game.getOrCreate(["game-456"], {
3232
Input is available in lifecycle hooks via the `opts.input` parameter:
3333

3434
```typescript
35+
interface ChatRoomInput {
36+
roomName: string,
37+
isPrivate: boolean,
38+
}
39+
3540
const chatRoom = actor({
36-
createState: (c, opts) => ({
37-
name: opts.input?.roomName ?? "Unnamed Room",
38-
isPrivate: opts.input?.isPrivate ?? false,
39-
maxUsers: opts.input?.maxUsers ?? 50,
41+
createState: (c: ActorInitContext, input: ChatRoomInput) => ({
42+
name: input?.roomName ?? "Unnamed Room",
43+
isPrivate: input?.isPrivate ?? false,
44+
maxUsers: input?.maxUsers ?? 50,
4045
users: {},
4146
messages: [],
4247
}),
4348

44-
onCreate: (c, opts) => {
45-
console.log(`Creating room: ${opts.input?.roomName}`);
49+
onCreate: (c, opts, input: ChatRoomInput) => {
50+
console.log(`Creating room: ${input.roomName}`);
4651

4752
// Setup external services based on input
48-
if (opts.input?.isPrivate) {
49-
setupPrivateRoomLogging(opts.input.roomName);
53+
if (input.isPrivate) {
54+
setupPrivateRoomLogging(input.roomName);
5055
}
5156
},
5257

@@ -76,9 +81,9 @@ const GameInputSchema = z.object({
7681
});
7782

7883
const game = actor({
79-
createState: (c, opts) => {
84+
createState: (c: ActorInitContext, inputRaw: z.infer<typeof GameInputSchema>) => {
8085
// Validate input
81-
const input = GameInputSchema.parse(opts.input);
86+
const input = GameInputSchema.parse(inputRaw);
8287

8388
return {
8489
gameMode: input.gameMode,
@@ -142,10 +147,10 @@ interface GameInput {
142147
}
143148

144149
const game = actor({
145-
createState: (c, opts: { input?: GameInput }) => ({
146-
gameMode: opts.input?.gameMode ?? "casual",
147-
maxPlayers: opts.input?.maxPlayers ?? 4,
148-
difficulty: opts.input?.difficulty ?? "medium",
150+
createState: (c: ActorInitContext, input: GameInput) => ({
151+
gameMode: input.gameMode,
152+
maxPlayers: input.maxPlayers,
153+
difficulty: input.difficulty ?? "medium",
149154
}),
150155

151156
actions: {
@@ -160,12 +165,12 @@ If you need to access input data in actions, store it in the actor's state:
160165

161166
```typescript
162167
const game = actor({
163-
createState: (c, opts) => ({
168+
createState: (c: ActorInitContext, input: GameInput) => ({
164169
// Store input configuration in state
165170
config: {
166-
gameMode: opts.input?.gameMode ?? "casual",
167-
maxPlayers: opts.input?.maxPlayers ?? 4,
168-
difficulty: opts.input?.difficulty ?? "medium",
171+
gameMode: input.gameMode,
172+
maxPlayers: input.maxPlayers,
173+
difficulty: input?.difficulty ?? "medium",
169174
},
170175
// Runtime state
171176
players: {},

site/src/content/docs/actors/keys.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Use keys to provide basic actor configuration:
111111

112112
```typescript {{"title":"registry.ts"}}
113113
const userSession = actor({
114-
createState: (c) => ({
114+
createState: () => ({
115115
userId: c.key[0], // Extract user ID from key
116116
loginTime: Date.now(),
117117
preferences: {}

0 commit comments

Comments
 (0)