Skip to content

Commit

Permalink
docs: update code snippets to latest sdk version (#1746)
Browse files Browse the repository at this point in the history
Fixes RVT-4315
  • Loading branch information
NathanFlurry committed Dec 30, 2024
1 parent 05a7553 commit 8e114ca
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 109 deletions.
16 changes: 8 additions & 8 deletions site/src/content/docs/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ interface ConnectionState {
role: string;
}

class ExampleActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
export default class ExampleActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<ExampleActor>): Promise<ConnectionState> {
// Verify the token with your authentication system
const userData = await myValidateAuthToken(opts.parameters.authToken);
if (!userData) {
Expand All @@ -46,8 +46,8 @@ class ExampleActor extends Actor<State, ConnectionParams, ConnectionState> {
After authentication, you can access the connection state in any actor method using `rpc.connection.state`:

```typescript
class AuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
exampleAdminCommand(rpc: Rpc<this>) {
export default class AuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
exampleAdminCommand(rpc: Rpc<AuthenticatedActor>) {
// Example of validating admin access
if (rpc.connection.state.role !== 'admin') throw new Error('User must be an admin');

Expand All @@ -73,8 +73,8 @@ interface ConnectionState {
userId: string;
}

class APIAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
export default class APIAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<APIAuthenticatedActor>): Promise<ConnectionState> {
// Validate API key with your server
const response = await fetch('https://api.yourserver.com/validate', {
method: 'POST',
Expand Down Expand Up @@ -114,8 +114,8 @@ interface ConnectionState {
permissions: string[];
}

class JwtAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<this>): Promise<ConnectionState> {
export default class JwtAuthenticatedActor extends Actor<State, ConnectionParams, ConnectionState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<JwtAuthenticatedActor>): Promise<ConnectionState> {
// Verify JWT token (throws error for invalid tokens)
const decoded = jwt.verify(opts.parameters.jwt, JWT_SECRET);

Expand Down
3 changes: 0 additions & 3 deletions site/src/content/docs/cheatsheet.mdx

This file was deleted.

6 changes: 0 additions & 6 deletions site/src/content/docs/cli.mdx

This file was deleted.

18 changes: 9 additions & 9 deletions site/src/content/docs/connections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ interface ConnectionParams {
authToken: string;
}

class Example extends Actor<State, ConnectionParams> {
_onBeforeConnect(opts: OnBeforeConnectOptions<this>) {
export default class Example extends Actor<State, ConnectionParams> {
_onBeforeConnect(opts: OnBeforeConnectOptions<Example>) {
const authToken = opts.parameters.authToken;
// ...
}
Expand Down Expand Up @@ -46,9 +46,9 @@ interface ConnectionState {
role: string;
}

class Example extends Actor<State, ConnectionState> {
export default class Example extends Actor<State, ConnectionState> {
// The data returned from `_onBeforeConnect` will be assigned to the connection's state
_onBeforeConnect(opts: OnBeforeConnectOptions<this>): ConnectionState {
_onBeforeConnect(opts: OnBeforeConnectOptions<Example>): ConnectionState {
return { userId: 123, role: 'admin' };
}

Expand All @@ -66,17 +66,17 @@ See the documentation on the following lifecycle hooks:

## Connection List

All active connections can be accessed with `this.connections`. This is stored as `Map<number, Connection>` where the key is the connection ID.
All active connections can be accessed with `this._connections`. This is stored as `Map<number, Connection>` where the key is the connection ID.

This is frequently used with `conn.send(name, event)` to send messages directly to clients.

For example:

```typescript {{ "title": "actor.ts" }}
class ChatRoom extends Actor {
sendDirectMessage(rpc: Rpc<this>, recipient: number, message: string) {
this.connections.get(recipient, message).send('directMessage', {
from: rpc.id,
export default class ChatRoom extends Actor {
sendDirectMessage(rpc: Rpc<ChatRoom>, recipient: number, message: string) {
this._connections.get(recipient).send('directMessage', {
from: rpc.connection.id,
message: message
});
}
Expand Down
32 changes: 16 additions & 16 deletions site/src/content/docs/events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ Events are used for clients to receive realtime data from actors.

## Publishing from actors

Actors can publish events to clients using `this.broadcast` and `connection.send`.
Actors can publish events to clients using `this._broadcast` and `connection.send`.

### Broadcasting events

Actors can publish events to all connected clients with `this.broadcast(name, data)`. For example:
Actors can publish events to all connected clients with `this._broadcast(name, data)`. For example:

<CodeGroup>

```typescript {{ "title": "chat_room.ts" }}
class ChatRoom extends Actor {
sendMessage(rpc: Rpc<this>, message: string) {
this.broadcast('newMessage', { message });
export default class ChatRoom extends Actor {
sendMessage(rpc: Rpc<ChatRoom>, message: string) {
this._broadcast('newMessage', { message });
}
}
```
Expand All @@ -31,14 +31,14 @@ await actor.sendMessage('Hello, world!');

### Sending events to specific connections

Actors can send messages to specific client connections. All connections are available on the `this.connections` array. For example:
Actors can send messages to specific client connections. All connections are available on the `this._connections` array. For example:

<CodeGroup>

```typescript {{ "title": "chat_room.ts" }}
class ChatRoom extends Actor {
sendPrivateMessage(rpc: Rpc<this>, connectionId: number, message: string) {
const conn = this.connections.find(c => c.id == connectionId);
export default class ChatRoom extends Actor {
sendPrivateMessage(rpc: Rpc<ChatRoom>, connectionId: number, message: string) {
const conn = this._connections.find(c => c.id == connectionId);
conn.send('newMessage', { message });
}
}
Expand Down Expand Up @@ -71,9 +71,9 @@ actor.on('newMessage', ({ message }) => {
```

```typescript {{ "title": "chat_room.ts" }}
class ChatRoom extends Actor {
sendMessage(rpc: Rpc<this>, message: string) {
this.broadcast('newMessage', { message });
export default class ChatRoom extends Actor {
sendMessage(rpc: Rpc<ChatRoom>, message: string) {
this._broadcast('newMessage', { message });
}
}
```
Expand All @@ -98,13 +98,13 @@ await actor.requestJoin();
```

```typescript {{ "title": "chat_root.ts" }}
class ChatRoom extends Actor {
requestJoin(rpc: Rpc<this>) {
export default class ChatRoom extends Actor {
requestJoin(rpc: Rpc<ChatRoom>) {
// ...ask the admin to approve the request...
}

approveJoinRequest(rpc: Rpc<this>, connectionId: number) {
const conn = this.connections.find(c => c.id == connectionId);
approveJoinRequest(rpc: Rpc<ChatRoom>, connectionId: number) {
const conn = this._connections.get(c.id);
conn.send('joinRequestApproved');
}
}
Expand Down
3 changes: 0 additions & 3 deletions site/src/content/docs/godot.mdx

This file was deleted.

2 changes: 1 addition & 1 deletion site/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Rivet Actors offer several compelling advantages for building real-time applicat

- [**Remote Procedure Call**](/docs/rpc) (RPC) is how clients communicate with actors and how actors communicate with each other.
- [**State**](/docs/state) is the data belonging to each actor. State cannot be shared between actors. State is stored in memory (unless it's too large) for fast reads and writes. State is durable and will always survive a crash or upgrade. You can update state without having to do anything special.
- [**Events**](/docs/events) are used for real-time communication between clients and actors. Clients can subscribe to events with `actor.on("myEvent")`, and actors can publish events with `this.broadcast("myEvent")` or `connection.send("myEvent")`.
- [**Events**](/docs/events) are used for real-time communication between clients and actors. Clients can subscribe to events with `actor.on("myEvent")`, and actors can publish events with `this._broadcast("myEvent")` or `connection.send("myEvent")`.
- [**Connections**](/docs/connections) represent a client that's currently connected to the actor. Connections have their own state, e.g., `userId`. You can use `onConnect` to authenticate connections before they can communicate with the actor.

To read more about architecting actors for scale, see [here](/docs/scaling).
Expand Down
26 changes: 13 additions & 13 deletions site/src/content/docs/internals/design-decisions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ For example:

<CodeGroup>
```typescript {{ "title": "actor.ts" }}
class Example extends Actor {
export default class Example extends Actor {
// Fake event system
eventSystem: EventSystem;

Expand Down Expand Up @@ -60,9 +60,9 @@ This is significantly more difficult to understand than the equivalent in Rivet:

<CodeGroup>
```typescript {{ "title": "actor.ts" }}
class Example extends Actor {
publishPost(rpc: Rpc<this>, data: Post) {
this.broadcast("post", data)
export default class Example extends Actor {
publishPost(rpc: Rpc<Example>, data: Post) {
this._broadcast("post", data)
}
}
```
Expand Down Expand Up @@ -94,7 +94,7 @@ type Message =
| { type: "withdraw"; amount: number; replyTo: MessagePort }
| { type: "getBalance"; replyTo: MessagePort };

class UserActor extends Actor {
export default class UserActor extends Actor {
private balance = 0;

async run() {
Expand Down Expand Up @@ -126,23 +126,23 @@ class UserActor extends Actor {
```

```typescript {{ "title": "rpc_actor.ts" }}
class UserActor extends Actor {
export default class UserActor extends Actor {
private balance = 0;

async deposit(rpc: Rpc<this>, amount: number) {
async deposit(rpc: Rpc<UserActor>, amount: number) {
this.balance += amount;
return this.balance;
}

async withdraw(rpc: Rpc<this>, amount: number) {
async withdraw(rpc: Rpc<UserActor>, amount: number) {
if (amount > this.balance) {
throw new Error("Insufficient funds");
}
this.balance -= amount;
return this.balance;
}

async getBalance(rpc: Rpc<this>) {
async getBalance(rpc: Rpc<UserActor>) {
return this.balance;
}
}
Expand All @@ -156,7 +156,7 @@ The RPC version is much more straightforward to understand and maintain. It look
If developers use an `await` in an event loop, they'll unintentionally slow down their actor when they don't need to by taking a long time to receive the next message. For example, this code is deceivingly slow:

```typescript
class SlowActor extends Actor {
export default class SlowActor extends Actor {
private balance = 0;

async run() {
Expand Down Expand Up @@ -187,7 +187,7 @@ class SlowActor extends Actor {
It's still easy to opt-in to serial message handling if it makes sense. For example:

```typescript
class SerialActor extends Actor {
export default class SerialActor extends Actor {
private messageQueue = new AsyncQueue();
private balance = 0;

Expand All @@ -206,7 +206,7 @@ class SerialActor extends Actor {
}

// Wrap RPC handlers to be processed serially
async deposit(rpc: Rpc<this>, amount: number) {
async deposit(rpc: Rpc<SerialActor>, amount: number) {
return new Promise((resolve, reject) => {
this.messageQueue.enqueue(async () => {
this.balance += amount;
Expand All @@ -215,7 +215,7 @@ class SerialActor extends Actor {
});
}

async getBalance(rpc: Rpc<this>) {
async getBalance(rpc: Rpc<SerialActor>) {
return new Promise((resolve) => {
this.messageQueue.enqueue(async () => {
resolve(this.balance);
Expand Down
20 changes: 10 additions & 10 deletions site/src/content/docs/lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Called whenever the actor's state changes. This is often used to broadcast state

### `_onBeforeConnect`

`_onBeforeConnect?(opts: OnBeforeConnectOptions<this>): ConnState | Promise<ConnState>`
`_onBeforeConnect?(opts: OnBeforeConnectOptions<MyActor>): ConnState | Promise<ConnState>`

Called whenever a new client connects to the actor. Clients can pass parameters when connecting, accessible via `opts.parameters`.

Expand All @@ -34,7 +34,7 @@ Connections cannot interact with the actor until this method completes successfu

### `_onConnect`

`_onConnect?(connection: Connection<this>): void | Promise<void>`
`_onConnect?(connection: Connection<MyActor>): void | Promise<void>`

Executed after the client has successfully connected.

Expand All @@ -44,7 +44,7 @@ Errors thrown from this method will cause the client to disconnect.

### `_onDisconnect`

`_onDisconnect?(connection: Connection<this>): void | Promise<void>`
`_onDisconnect?(connection: Connection<MyActor>): void | Promise<void>`

Called when a client disconnects from the actor. Use this to clean up any connection-specific resources.

Expand All @@ -71,7 +71,7 @@ interface ConnState {
userId: string;
}

class CounterActor extends Actor<State, ConnParams, ConnState> {
export default class Counter extends Actor<State, ConnParams, ConnState> {
async _onInitialize(): Promise<State> {
// Initialize with a count of 0
return {
Expand All @@ -86,12 +86,12 @@ class CounterActor extends Actor<State, ConnParams, ConnState> {

async _onStateChange(newState: State): Promise<void> {
// Broadcast the new count to all connected clients
this.broadcast('countUpdated', {
this._broadcast('countUpdated', {
count: newState.count
});
}

async _onBeforeConnect(opts: OnBeforeConnectOptions<CounterActor>): Promise<ConnState> {
async _onBeforeConnect(opts: OnBeforeConnectOptions<Counter>): Promise<ConnState> {
// Validate auth token with your API and determine the user
const auth = await myValidateAuthToken(opts.parameters.authToken);
if (!auth) {
Expand All @@ -104,17 +104,17 @@ class CounterActor extends Actor<State, ConnParams, ConnState> {
};
}

async _onConnect(connection: Connection<this>): Promise<void> {
async _onConnect(connection: Connection<Counter>): Promise<void> {
console.log(`User ${connection.state.userId} connected`);
}

async _onDisconnect(connection: Connection<this>): Promise<void> {
async _onDisconnect(connection: Connection<Counter>): Promise<void> {
console.log(`User ${connection.state.userId} disconnected`);
}

// Example RPC method
async increment(rpc: Rpc<this>) {
this.state.count++;
async increment(rpc: Rpc<Counter>) {
this._state.count++;
}
}
```
Loading

0 comments on commit 8e114ca

Please sign in to comment.