Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ iwr https://releases.rivet.gg/rivet/latest/install.ps1 -useb | iex

### Quickstart (TypeScript)

_See the [full quickstart guide](https://rivet.gg/docs/quickstart/typescript) for a comprehensive walkthrough._
_See the [full quickstart guide](https://rivet.gg/docs/actors) for a comprehensive walkthrough._

**Step 1: Create Actor**

Expand Down
18 changes: 15 additions & 3 deletions frontend/packages/components/src/actors/get-started.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Icon, faTs } from "@rivet-gg/icons";
import { Icon, faTs, faFunction, faServer, faActors } from "@rivet-gg/icons";
import { motion } from "framer-motion";
import type { ComponentProps } from "react";
import { Button } from "../ui/button";
Expand All @@ -15,8 +15,20 @@ export function ActorsResources() {
</CardHeader>
<CardContent className="grid md:grid-cols-2 gap-4">
<ExampleLink
href="docs/quickstart/typescript"
title="TypeScript"
href="docs/actors"
title="Rivet Actors"
size="md"
icon={faActors}
/>
<ExampleLink
href="docs/containers"
title="Rivet Containers"
size="md"
icon={faServer}
/>
<ExampleLink
href="docs/functions"
title="Rivet Functions"
size="md"
icon={faTs}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: using faTs icon for Functions section seems incorrect - should use faFunction icon instead

/>
Comment on lines 17 to 34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: grid layout with 3 items in 2 columns will result in uneven distribution - consider adjusting grid-cols-2 to grid-cols-3 or grid-cols-1

Expand Down
2 changes: 2 additions & 0 deletions site/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
/docs/html5/* https://opengamebackend.org/game-engines/html5 302
/docs/custom/* https://opengamebackend.org/game-engines/html5 302
/modules/* https://opengamebackend.org/modules 302
/docs/javascript-runtime /docs/actors 302
/docs/container-runtime /docs/containers 302
2 changes: 1 addition & 1 deletion site/scripts/generateApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function main() {
for (let method in SPEC.paths[pathName]) {
let specPath = SPEC.paths[pathName][method];

if (!/^(actors|builds|regions)_/.test(specPath.operationId)) continue;
if (!/^(actors|builds|regions|routes)_/.test(specPath.operationId)) continue;

console.log('Registering', method, pathName);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
# JavaScript Runtime
# Rivet Actors

The Rivet JavaScript runtime is built on lightweight JavaScript containers called V8 isolates, providing a high-performance, secure environment for your actor code.

It's designed to be widely compatible with Node.js and NPM dependencies, making it easy to use familiar libraries and tools.
Rivet Actors allows you to deploy resilient, stateful services that maintain their state between requests. Use them for websocket servers, game backends, real-time collaboration services, and more.

<Tip title="Get Started Faster With ActorCore">
For getting started quickly using JavaScript, we recommend trying [ActorCore](https://actorcore.org) – our full-stack framework for working with Rivet Actors.
</Tip>

## Basic Setup
## What are actors good for?

- **Stateful Services**: Applications where maintaining state across interactions is critical. For example, **Collaborative Apps** with shared editing and automatic persistence.
- **Realtime Systems**: Applications requiring fast, in-memory state modifications or push updates to connected clients. For example, **Multiplayer Games** with game rooms and player state.
- **Long-Running Processes**: Tasks that execute over extended periods or in multiple steps. For example, **AI Agents** with ongoing conversations and stateful tool calls.
- **Durability**: Processes that must survive crashes and restarts without data loss. For example, **Durable Execution** workflows that continue after system restarts.
- **Horizontal Scalability**: Systems that need to scale by distributing load across many instances. For example, **Realtime Stream Processing** for stateful event handling.
- **Local-First Architecture**: Systems that synchronize state between offline clients. For example, **Local-First Sync** between devices.

## Quickstart

### Step 1: Writing an actor

Expand All @@ -26,22 +33,20 @@ Every actor must export a default object with an async `start` function. Here's

```ts {{"file": "src/index.ts"}}
import type { ActorContext } from "@rivet-gg/actor";
import * as http from "http";
import { Hono } from "hono";

export default {
async start(ctx: ActorContext) {
// Get the port from environment variables or use a default
const port = parseInt(process.env.PORT_HTTP || "8080");
const port = parseInt(Deno.env.get("PORT_HTTP") || "8080");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Using Deno.env.get() but npm installing @rivet-gg/actor - need to clarify if this is a Deno or Node.js environment

console.log(`HTTP server running on port ${port}`);

// Create an HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Hello from Rivet Actor ${ctx.metadata.actor.id} running in ${ctx.metadata.region.id}!`);
const app = new Hono();

app.get("/", (c) => {
return c.text(`Hello from Rivet Actor ${ctx.metadata.actor.id} running in ${ctx.metadata.region.id}!`);
});

// Start listening on the specified port
server.listen(port);
Deno.serve({ port }, app.fetch);

// Keep the actor running until explicitly destroyed
await new Promise((resolve) => {});
Expand All @@ -50,8 +55,8 @@ export default {
```

What this code does:
- Sets up a simple HTTP server using Node.js's built-in http module
- Creates a response that includes the actor ID and region information
- Creates a simple HTTP server using Hono with Deno
- Sets up a route that returns the actor ID and region information
- Keeps the actor running indefinitely by returning a promise that never resolves

<Tip title="Using classes">
Expand All @@ -74,7 +79,7 @@ Specify the script in your `rivet.json`:

```json {{ "title": "rivet.json" }}
{
"builds": {
"actors": {
"my-actor": {
"script": "./src/index.ts"
}
Expand Down
37 changes: 37 additions & 0 deletions site/src/content/docs/api/routes/delete.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{/* This file is auto-generated by `generateApi.js`.
*
* Do not edit this file directly.
*/}

import { JsonSchemaPreview, PropertyLabel } from '@/components/JsonSchemaPreview';
import API_SCHEMA from './../spec.json';

# routes.delete

## Description
Deletes a route.

## Code Examples

<CodeGroup title='Request' tag='DELETE' label='https://api.rivet.gg/routes/{id}'>

```bash {{ "title": "cURL" }}
curl -X DELETE 'https://api.rivet.gg/routes/{id}'
```

```ts
// Create Rivet client
import { RivetClient } from '@rivet-gg/api';
const RIVET = new RivetClient({ token: '[YOUR TOKEN HERE]' });

// Make request
await RIVET.routes.delete({
// Add your request body here
});
Comment on lines +28 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Example code is missing required 'id' parameter which is marked as required in schema

Suggested change
await RIVET.routes.delete({
// Add your request body here
});
await RIVET.routes.delete({
id: "route-id", // Required: The ID of the route to delete
});

```

</CodeGroup>

## Schema
<JsonSchemaPreview className='not-prose mt-4' title='Request Parameters' schema={{"type":"object","properties":{"id":{"in":"path","type":"string"},"project":{"in":"query","type":"string"},"environment":{"in":"query","type":"string"}},"required":["id"]}} defs={API_SCHEMA.definitions}/>
<JsonSchemaPreview className='not-prose mt-4' title='Response' schema={{"$ref":"#/components/schemas/RoutesDeleteRouteResponse"}} defs={API_SCHEMA.definitions}/>
37 changes: 37 additions & 0 deletions site/src/content/docs/api/routes/list.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{/* This file is auto-generated by `generateApi.js`.
*
* Do not edit this file directly.
*/}

import { JsonSchemaPreview, PropertyLabel } from '@/components/JsonSchemaPreview';
import API_SCHEMA from './../spec.json';

# routes.list

## Description
Lists all routes of the given environment.

## Code Examples

<CodeGroup title='Request' tag='GET' label='https://api.rivet.gg/routes'>

```bash {{ "title": "cURL" }}
curl -X GET 'https://api.rivet.gg/routes'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Missing project and environment query parameters in cURL example

```

```ts
// Create Rivet client
import { RivetClient } from '@rivet-gg/api';
const RIVET = new RivetClient({ token: '[YOUR TOKEN HERE]' });

// Make request
await RIVET.routes.list({
// Add your request body here
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Example request body should be removed since this GET endpoint doesn't accept a request body

Suggested change
// Add your request body here
// Optional query parameters: project, environment

});
```

</CodeGroup>

## Schema
<JsonSchemaPreview className='not-prose mt-4' title='Request Parameters' schema={{"type":"object","properties":{"project":{"in":"query","type":"string"},"environment":{"in":"query","type":"string"}},"required":[]}} defs={API_SCHEMA.definitions}/>
<JsonSchemaPreview className='not-prose mt-4' title='Response' schema={{"$ref":"#/components/schemas/RoutesListRoutesResponse"}} defs={API_SCHEMA.definitions}/>
41 changes: 41 additions & 0 deletions site/src/content/docs/api/routes/update.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{/* This file is auto-generated by `generateApi.js`.
*
* Do not edit this file directly.
*/}

import { JsonSchemaPreview, PropertyLabel } from '@/components/JsonSchemaPreview';
import API_SCHEMA from './../spec.json';

# routes.update

## Description
Creates or updates a route.

## Code Examples

<CodeGroup title='Request' tag='PUT' label='https://api.rivet.gg/routes/{id}'>

```bash {{ "title": "cURL" }}
# Write the request body to body.json before running
curl -X PUT -d '@body.json' 'https://api.rivet.gg/routes/{id}'


```

```ts
// Create Rivet client
import { RivetClient } from '@rivet-gg/api';
const RIVET = new RivetClient({ token: '[YOUR TOKEN HERE]' });

// Make request
await RIVET.routes.update({
// Add your request body here
});
```

</CodeGroup>

## Schema
<JsonSchemaPreview className='not-prose mt-4' title='Request Parameters' schema={{"type":"object","properties":{"id":{"in":"path","type":"string"},"project":{"in":"query","type":"string"},"environment":{"in":"query","type":"string"}},"required":["id"]}} defs={API_SCHEMA.definitions}/>
<JsonSchemaPreview className='not-prose mt-4' title='Request' schema={{"$ref":"#/components/schemas/RoutesUpdateRouteBody"}} defs={API_SCHEMA.definitions}/>
<JsonSchemaPreview className='not-prose mt-4' title='Response' schema={{"$ref":"#/components/schemas/RoutesUpdateRouteResponse"}} defs={API_SCHEMA.definitions}/>
Loading
Loading